Hallo, ein Neuling steckt in Schwierigkeiten :)

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Natürlich kannst du jede for-Schleife durch eine while-Schleife ersetzen, oft ist eine for-Schleife aber eben besser geeignet. Sowohl konzeptionell als auch von der Länge des Codes. Wenn du jedes Element einer Liste nacheinander anpackst und eine Elemente löscht oder hinzufügst, dann ist eine for-Schleife immer die richtige Wahl.

Dass du bei einer nahenden Klausur nicht alle Hinweise umsetzen kannst ist verständlich, die meisten sachen, wie zum Beispiel die Benennung, solltest du aber schon beachten. Das wird dir auch in der Klausur helfen (und der Person, die sich deine Arbeit anschauen muss). Auf jeden Fall sieht die Klausur fair und gut schaffbar aus. Auf jeden Fall schon mal viel Erfolg.
Das Leben ist wie ein Tennisball.
hoola
User
Beiträge: 18
Registriert: Samstag 7. Juli 2012, 08:44

@EyDu
Dein Lösungsvorschlag mit der Funktion enumerate() ist zwar gut und schön, allerdings hatten wir sowas z.B. nie in der Vorlesung. Ich denke, dass der Prof beabsichtigt sich nur auf das nötigste Vokabular zu beschränken. Sicher gibt es noch 1000 andere tolle Funktionen mit denen man Aufgaben ganz einfach und geschickt lösen kann. Allerdings würde das sicher unsere 3 Semester Wochenstunden sprengen.

Kann man das mit dem enumerate() nicht auch anders lösen?

Ok und das mit der Benennung werde ich mir mal versuchen anzugewöhnen bzw. mehr darüber nachdenken. Bisher habe ich einfach die erst beste Bezeichnung verwendet, die mir beim lesen der Aufgabe in den Kopf geschossen kam. :)

EDIT:
Hab meinen nun Code verändert, nur funktioniert das ersetzen des None nicht mehr. :(

Code: Alles auswählen

def werteAus(liste):

    m = w = n = 0
    
    for zeichen in liste:
        if zeichen == 'm':
            m +=1
        elif zeichen == 'w':
            w += 1
        else:
            zeichen = None
            n += 1
Was stimmt denn jetzt wieder nicht?
Er hat Probleme mit dem "zeichen = None", das ist klar.
Nun ist die for-Schleife an allen 'm' und 'w' vorbei gekommen bis sie auf das 's' stößt. Dann müsste die Schleife doch in den else: Zweig gehen oder etwa nicht?
Zuletzt geändert von Hyperion am Samstag 7. Juli 2012, 16:33, insgesamt 1-mal geändert.
Grund: Code in Python-Code Tags gesetzt.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

@hoola: Bitte setze Python-Code doch in die speziellen Python-Code-Tags: [ code=python ] Dein Code [ /code ] (natürlich ohne die Leerzeichen) Damit wird der Code hübsch mit Syntax Highlighting verschönert :-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
hoola
User
Beiträge: 18
Registriert: Samstag 7. Juli 2012, 08:44

Oh man ich dreh durch!
Bin bei der 2. Teilaufgabe und krieg es einfach nicht hin, eine Fehleingabe abzufangen.
Den Neugeborenen werden jetzt Name, Vorname und Geschlecht zugeordnet.
Eine Fehleingabe des Geschlechts soll abgefangen werden .. so schwer kann das doch nicht sein!
Könnt ihr mir ein paar Tipps geben? (bitte keine Code .. nur nen Denkansatz)

Code: Alles auswählen

def neuesKind(kinderliste):
    name = vorname = geschlecht = ''
    while name == '':
        name = input('Nachname: ')
    while vorname == '':
        vorname = input('Vorname: ')
    
[b]AB HIER sollen wir selber weiter programmieren.[/b]
        
    kinderliste = [name, vorname, geschlecht.lower()]
    
    return kinderliste

liste = []
print(neuesKind(liste))
@Hyperion: done :)
BlackJack

@hoola: Wenn man Element *und* Index benötigt ist `enumerate()` der vorgesehene Weg. Es geht auch anders, aber eigentlich nicht einfacher. Es gibt in der Tat tausende Funktionen, aber `enumerate()` gehört zu denen, die ohne explizit importiert werden zu müssen zur Verfügung stehen. Das gehört also zum Kernbereich der Sprache. Sind in den 3 SWS schon die Stunden inbegriffen, die ihr euch ausserhalb der Vorlesung/Übung damit beschäftigt? Bei uns (Uni) wurde immer betont dass die Veranstaltungen nicht die Programmiersprachen lehren sollen, sondern dass man sich das selbst aneignen muss.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Naja, es fehlt zunächst die Eingabe des Geschlechts ;-)

Und dann suchst Du die Methode `list.append()`; damit kannst Du ein Element zu einer Liste hinzufügen. Dieses Element ist laut Aufgabenstellung auch wieder eine Liste, wobei diese eben genau drei Element hat: Die Namen und das Kürzel für das Geschlecht.

Das `return` ist hier überflüssig, da Du ein bereits bestehendes Objekt änderst. Ich demonstriere das hier mal:

Code: Alles auswählen

data = []

def modify(data):
    data.append(["Python", 42])

modify(data)

print data
#-> [['Python', 42]]

modify(data)

print data
#-> [['Python', 42], ['Python', 42]]
Wie Du siehst wird das Objekt hinter dem Namen `data` innerhalb der Funktion `modify` geändert, da es der Funktion als Parameter übergeben wird. Ich muss es nicht zurückgeben, wie man es bei einer Kopie oder einem neuen Objekt tun würde.

Edit: Ok, nach mehrmaligen Lesens der Aufgabe sehe ich es auch so, dass man wohl falsche Eingaben beim Geschlecht abfangen soll. Prinzipiell regelt man so etwas gerne über `while`-Schleifen. Entweder durch eine Endlosschleife (`while True: ...`), aus der nur heraus gesprungen wird (z.B. via `break`), wenn eine korrekte Eingabe erfolgt ist, oder durch das Testen auf eine korrekte Eingabe im Kopf der Schleife.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
hoola
User
Beiträge: 18
Registriert: Samstag 7. Juli 2012, 08:44

BlackJack hat geschrieben:@hoola: Wenn man Element *und* Index benötigt ist `enumerate()` der vorgesehene Weg. Es geht auch anders, aber eigentlich nicht einfacher. Es gibt in der Tat tausende Funktionen, aber `enumerate()` gehört zu denen, die ohne explizit importiert werden zu müssen zur Verfügung stehen. Das gehört also zum Kernbereich der Sprache. Sind in den 3 SWS schon die Stunden inbegriffen, die ihr euch ausserhalb der Vorlesung/Übung damit beschäftigt? Bei uns (Uni) wurde immer betont dass die Veranstaltungen nicht die Programmiersprachen lehren sollen, sondern dass man sich das selbst aneignen muss.
Ist natürlich richtig .. außerhalb des Infokurses soll man auf jede SWS ungefähr 2 Stunden nacharbeiten. Aber das gleiche erwartet auch jeder andere Prof. von dir und das dann in Fächern, die für mein Eigentliches Ziel (nämlich Betriebsingenieur zu werden) von wesentlich größerer Bedeutung sind.
Irgendwo muss man leider immer Abstriche machen .. und so ist das bei Informatik der Fall gewesen. Andere Module hatten für mich Priorität.
Aber enumerate() werde ich mir wohl noch merken können, zumal es eine sehr schöne Funktion zu sein scheint. Aber mich würde rein aus Interesse doch noch interessieren, wie man die Geschichte ohne enumerate() löst. Irgendwie muss ich ja an den Index des gerade bearbeiteten Elementes rankommen. Da würde mir index() einfallen .. allerdings bekommt man da ja nur den Index des ersten Zeichens in der Liste .. ist ja doof, wenn das Zeichen mehrmals existiert.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

hoola hat geschrieben: Aber mich würde rein aus Interesse doch noch interessieren, wie man die Geschichte ohne enumerate() löst. Irgendwie muss ich ja an den Index des gerade bearbeiteten Elementes rankommen.
Es gibt keine Methode, mit der Du an den aktuellen Index herankommst - was ist auch schon der "aktuelle" Index? ;-)

Da `enumerate` das Mittel der Wahl ist, hier nur einige Workarounds:

- Du kannst einfach eine Zählvariable mitlaufen lassen (`i += 1` im Schleifenrumpf)

- Du kannst `enumerate` mittels `itertools.count` emulieren:

Code: Alles auswählen

from itertools import count, izip

l = ["a", "b", "c"]

for index, item in izip(l, count()):
    print index, item

# ->
# a 0
# b 1
# c 2
- Du kannst Dein eigenes `enumerate` schreiben:

Code: Alles auswählen

def my_enumerate(iterable, start=0):
    for index, item in izip(l, count(start)):
        yield index, item
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
hoola
User
Beiträge: 18
Registriert: Samstag 7. Juli 2012, 08:44

Code: Alles auswählen

while geschlecht != ('m','w'):
        geschlecht = input('Geschlecht: ')
Wo ist denn hier der Fehler?
Ich check es einfach nicht. :(
Er will nach einer Eingabe, egal ob rictig oder falsch, einfach nicht aus der Schleife springen.
Kann ja nur an "geschlecht != ('m','w')" liegen ..

Oder kann ich "geschlecht != ('m','w')" nur in einer if-Anweisung benutzen? :K

EDIT:
Also mal zur Fehleingabe .. ich muss zuerst prüfen, ob in Geschlecht etwas drin steht bzw. ob 'm' oder 'w' drin steht. Wenn das nicht der Fall ist, soll nochmal eine Eingabe erfolgen. Das kann doch nun wirklich nich so schwer sein oder was?
Zuletzt geändert von hoola am Samstag 7. Juli 2012, 17:44, insgesamt 1-mal geändert.
hoola
User
Beiträge: 18
Registriert: Samstag 7. Juli 2012, 08:44

Hyperion hat geschrieben: - Du kannst einfach eine Zählvariable mitlaufen lassen (`i += 1` im Schleifenrumpf)
Nach sowas hab ich gesucht .. danke.
Auch wenn die anderen Lösungen super sind .. sowas allgemeines wie Zählvariable im Schleifenrumpf mitlaufen lassen kann ich mir bis zur Prüfung auf jeden Fall merken und vielfach anwenden.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Du meinst: Solange geschlecht nicht "m" oder "w" ist. Geschrieben hast du aber: solange geschlecht nicht ("m", "w"). Wie soll denn die Eingabe zu einem Tupel werden? Was du meinst ist:

Code: Alles auswählen

while geschlecht not in ("m", "w")
Das Leben ist wie ein Tennisball.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Des weiteren fehlt da ein `str.lower()` ;-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

hoola hat geschrieben:
Hyperion hat geschrieben: - Du kannst einfach eine Zählvariable mitlaufen lassen (`i += 1` im Schleifenrumpf)
Nach sowas hab ich gesucht .. danke.
Auch wenn die anderen Lösungen super sind .. sowas allgemeines wie Zählvariable im Schleifenrumpf mitlaufen lassen kann ich mir bis zur Prüfung auf jeden Fall merken und vielfach anwenden.
Ich kann ehrlich nicht verstehen, wass an einem

Code: Alles auswählen

index = 0
for x in xs:
    ...
    index +=1
leichter zu merken sein soll, als das sprechende

Code: Alles auswählen

for index, x in enumerate(xs):
    ...
Es ist ja nicht so, dass es da etwas zu verstehen gibt.
Das Leben ist wie ein Tennisball.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

@EyDu: Tja, diese Frage haben wir doch einem ehemaligen Forenmitglied so gefühlte einhundert Mal gestellt... :mrgreen:
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
BlackJack

@hoola: Falls die zuletzt gezeigte `werteAus()`-Funktion der aktuelle Stand ist, dann erfüllt sie nicht die Aufgabenstellung. Ganz so schlecht ist die nämlich nicht gestellt.
hoola
User
Beiträge: 18
Registriert: Samstag 7. Juli 2012, 08:44

Nein, stellt sie nicht. Das ist im moment die 2. Teilaufgabe und ich befinde mich in der Funktion neuesKind(kinderliste).

Zu enumerate() .. warscheinlich tu ich mich so schwer damit, weil man mir vor längerer Zeit schonmal das mit dem Laufindex eingeprügelt hat und dieser einen Widererkennungswert hat. Mein Hirn versucht an Sachen anzuknüpfen, die es schon kennt und nicht erst verstehen muss .. auch wenn es zugegebenermaßen bei enumerate() nicht viel zu verstehen gibt. :P Das Hirn muss trotzdem einmal drüber schlafen um es ordentlich abzuspeichern. :D

Das str.lower() hatte ich weiter unten in meinem Code, sollte ich das schon während der Eingabe einbauen?

Code: Alles auswählen

geschlecht = input('Geschlecht: ')
    while geschlecht not in ('m','w'):
        geschlecht = input('Nochmal das Geschlecht eingeben: ')
Das ist jetzt der Code, funktioniert erstmal dank des Tipps mit "not in" statt "!=" ... allerdings fängt er jetzt auch die Großbuchstaben W und M ab .. also muss ich lower() wohl doch schon bei der Eingabe einbauen.

@BlackJack:

Code: Alles auswählen

def werteAus(liste):
    i = 0
    m = w = n = 0
    
    for zeichen in liste:
        
        if zeichen == 'm':
            m +=1
        elif zeichen == 'w':
            w += 1
        else:
            liste[i] = None
            n += 1
        i += 1
Das ist der aktuelle Stand.

EDIT: Wie anstrengend es ist zwischen Programmierung und Forenbeiträgen lesen hin und her zu springen glaubt echt kein Mensch! :D

EDIT2:
So sieht der Code "neuesKind(kinderliste)" jetzt aus.

Code: Alles auswählen

def neuesKind(kinderliste):
    name = vorname = geschlecht = ''
    while name == '':
        name = input('Nachname: ')
    while vorname == '':
        vorname = input('Vorname: ')
    geschlecht = input('Geschlecht: ')
    while geschlecht.lower() not in ('m','w'):
        geschlecht = input('Nochmal das Geschlecht eingeben: ')
            

        
    kinderliste.append([name, vorname, geschlecht.lower()])
    
    return kinderliste

liste = []
print(neuesKind(liste))
Die Aufgabe wäre damit ja erledigt wenn ich das richtig sehe.
Noch irgendwelche Anmerkungen zu Sachen die unnütz oder doppelt gemoppelt sind wie z.B. die lower() Funktion? Ich würde (wenn ich könnte) die ja gleich in die Eingabe mit einbinden. Ich probier mal rum.

EDIT3:
Ok der Tipp von Hyperion mit dem "str.lower()" hat gefruchet.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

hoola hat geschrieben: EDIT3:
Ok der Tipp von Hyperion mit dem "str.lower()" hat gefruchet.
Hm... nur bedingt! Du musst das nun zweimal anwenden... wieso manipulierst Du nicht das Ergebnis der Eingabe *direkt*? (Da Du vor der Schleife ein imho unnötigs `input` durchführst, sparst Du so noch nichts - aber wenn Du das eliminierst, dann wird es effizienter!)

So sähe meine Lösung aus:

Code: Alles auswählen

    while True:
        geschlecht = input("Geschlecht: ").lower()
        if geschlecht in ("m", "w"):
            break
    kinderliste.append([name, vorname, geschlecht])
Und das `return` ist immer noch unnütz - auch wenn in der Aufgabenstellung dies bezüglich etwas uneindeutiges steht...
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

@hoola: Deine Funktion zu Aufgabe 2.a ist so noch nicht "fertig"...

Ich habe mal einen Gist erzeugt, in dem ich die Klausur gelöst habe: Link

Aufgabe 2.a löse ich aber auch nicht exakt, wie gewollt. Da "schlampe" ich ein wenig ;-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
hoola
User
Beiträge: 18
Registriert: Samstag 7. Juli 2012, 08:44

Also zu dem str.lower(), ich habe das in meinen Code "eingepflegt", nur noch nicht hier reingestellt.
Aber du hast recht, ich muss es 2 mal benutzen .. bei der ersten Eingabe und bei der Fehlereingabe.
Deine Lösung ist da natürlich wesentlich eleganter.
Statt "while True" hättest auch irgendetwas anderes schreiben können a la "while 3<4" oder so .. da soll einfach irgendwas stehen um die Schleife ewig durchlaufen zu lassen. Beendet wird sie lediglich durch break, versteh ich das richtig?

Hauptsache du hast die Klausur gelöst .. nur gut, dass mir die meisten Lösungen nicht all zu viel bringen .. dann kann ich mich nicht so gut selbst bescheißen :P

Hab nochmal eine Frage zu Aufgabe 3.
Das habe ich bisher programmiert:

Code: Alles auswählen

#Aufgabe 3
def kuerze(string, n):
    string.split(' ')
    for wort in string:
        wort = wort[:n]
        
    return string.join(' ')

text = 'Kuchen Torte Mezzoforte'
kuerze(text, 3)
print(text)
Ich schätze mal diese Zeile wird falsch sein "wort = wort[:n]". Jemand einen klugen Ratschlag? Sitz jetzt schon wieder seit über einer Stunde an diesem Problem ... -_-
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

hoola hat geschrieben: Statt "while True" hättest auch irgendetwas anderes schreiben können a la "while 3<4" oder so .. da soll einfach irgendwas stehen um die Schleife ewig durchlaufen zu lassen. Beendet wird sie lediglich durch break, versteh ich das richtig?
Genau. Aber `3<4` ergibt auch `True`. `while` wertet den folgenden Ausdruck bezüglich seines Wahrheitswertes aus. Daher kann man anstatt irgend wie umständlich eine immer wahre Bedingung zu formulieren auch einfach den direkten Weg nehmen und `while True` schreiben.
hoola hat geschrieben: Hauptsache du hast die Klausur gelöst .. nur gut, dass mir die meisten Lösungen nicht all zu viel bringen .. dann kann ich mich nicht so gut selbst bescheißen :P
Du musst ja nicht spicken :-P
hoola hat geschrieben: Hab nochmal eine Frage zu Aufgabe 3.
Ich schreibe mal Kommentare in Deinen Code:

Code: Alles auswählen

#Aufgabe 3
def kuerze(string, n):
    # Du bindest das Ergebnis von `str.split` an keinen Namen!
    # Damit "wirfst" Du das Ergebnis de facto weg.
    string.split(' ')
    # hier musst Du Dich auf eben diesen Rückgabewert (also die Liste mit Wörtern!) beziehen
    for wort in string:
        # Du merkst Dir hier nur pro Durchlauf der Schleife *ein* gekürztes Wort
        # Du musst Dir aber *alle* gekürzten Wörter merken.
        # Also brauchst Du noch z.B. ein Listenobjekt, in dem Du das erledigen kanns
        wort = wort[:n]
    # das hier geht komplett in die Hose. `join` ist eine *Methode* auf einem
    # String-Objekt. Wenn Du also eine Liste von Strings zusammensetzen willst, dann lege einen String fest, der als Verbindungselement dient.
    # Du willst dafür ein einzelnes Space: `" ".join(Listenobjekt)`
    return string.join(' ')
Ich hoffe das hilft Dir als Denkanstoß weiter. Meine Lösung macht im übrigen genau das beschriebene - ich nutze nur eine kompaktere Schreibweise dafür (aka Generatorausdruck).

Du musst Dir besser klar machen, wann man "neue" Objekte durch eine Funktion erhält und wann bestehende Objekte verändert werden. Das ist wirklich elementar und wichtig.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Antworten