Blutiger Anfänger, verzweifelt, ledig, alt

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.
Benutzeravatar
Lebensretter
User
Beiträge: 8
Registriert: Montag 12. Januar 2015, 15:56
Wohnort: CGN

Ein herzliches Servus :)

Ich bin blutiger python-Anfänger und möchte die Sprache lernen und iiiirgendwann beherrschen.

Ich lerne mit dem Buch "Einstieg in Pyhton" - Ideal für Programmieranfänger geeignet. 3.Auflage von Thomas Theis. Von Galileo Computing. Bin übrigens für andere Buchvorschläge offen.

Ich hab ein Problem mit meinem Anfänger-Code und ich bin so langsam genervt. Was ich über googlen und auch querlesen hier im Forum verstanden haben, ist es wohl ein Problem mit den Einrückungen. Aber schon sind wir beim Hauptproblem. Wenn ich den Code so schreibe wie im Buch angegeben und auch der Editor gibt mir doch die Einrückungen vor...dann krieg ich immer wieder Probleme und ich weiss langsam nicht wer wie und wo anzusetzen ist.
Manchmal klappt es, wenn ich selbst die Einrückungen entferne bzw. verändere...frei nach dem try-and-error-Prinzip.

Bei dem Code - lacht jetzt bitte nicht, bin echt total am Anfang - sagt er mir z.B. bei continue, dass irgendwas mit der Einrückung nicht passt. Aber ich hab schon zig Varianten durch. Könnt ihr mir bitte einen Tipp geben ?

Code: Alles auswählen

# Zufallsgenerator
import random
random.seed()

# Werte und Brechnung
a = random.randint(1,10)
b = random. randint(1,10)
c = a + b

print("Die Aufgabe:", a, "+", b)

# Schleife und Anzahl initialisieren
zahl = c + 1
versuch = 0

# Schleife mit while
while zahl != c:
# Anzahl Versuche
    versuch = versuch + 1

# Eingabe
print("Bitte eine Zahl eingeben:")
z = input()

# Versuch einer Umwandlung
try:
    zahl = int(z)
except:
# Falls Umwandlung nicht erfolgreich
    print("Sie haben keine Zahl eingegeben")
#Schleife unmittelbar fortsetzen
continue

# Verzweigung
if zahl == c:
    print(zahl, "ist richtig")
else:
    print(zahl, "ist falsch")
#Anzahl Versuche
print("Ergebnis: ", c)
print("Anzahl Versuche:", versuch)
Benutzeravatar
Lebensretter
User
Beiträge: 8
Registriert: Montag 12. Januar 2015, 15:56
Wohnort: CGN

continue not properly in loop. Das kommt wieder und wieder. Mal davon abgesehen, dass ich - bis ich überhaupt mal dort ankam - zig andere Einrückungsprobleme korrigieren musste.
Sirius3
User
Beiträge: 17761
Registriert: Sonntag 21. Oktober 2012, 17:20

@Lebensretter: alles was innerhalb der Schleife ausgeführt werden soll, muß eingerückt werden, also, die Schleife beginnt in Zeile 18, und wo hört sie auf?
garreth
User
Beiträge: 41
Registriert: Donnerstag 23. Oktober 2014, 12:04

Hallo Lebensretter,

anbei mal der Code wie er funktionieren sollte.

Code: Alles auswählen

# Zufallsgenerator
import random
     
# Werte und Berechnung
a = random.randint(1,10)
b = random. randint(1,10)
c = a + b
     
print("Die Aufgabe:", a, "+", b)
     
# Schleife initialisieren
zahl = c + 1

# Anzahl initialisieren
versuch = 0
     
# Schleife mit while
while zahl != c:
    # Anzahl Versuche
    versuch = versuch + 1
     
    # Eingabe
    print("Bitte eine Zahl eingeben:")
    z = input()
     
    # Versuch einer Umwandlung
    try:
        zahl = int(z)
    except:
        # Falls Umwandlung nicht erfolgreich
        print("Sie haben keine Zahl eingegeben")
        #Schleife unmittelbar fortsetzen
        continue
     
    # Verzweigung
    if zahl == c:
        print(zahl, "ist richtig")
    else:
        print(zahl, "ist falsch")

#Anzahl Versuche
print("Ergebnis: ", c)
print("Anzahl Versuche:", versuch)
Als kleines übersichtliches Beispiel wie man einrückt:

Code: Alles auswählen

# 1. Befehl Hauptprogramm
# 2. Befehl Hauptprogramm
while True: # 3. Befehl Hauptprogramm
    # 1. Befehl 1. Schleife
    # 2. Befehl 1. Schleife
    # 3. Befehl 1. Schleife
    while True:
        # 1. Befehl 2. Schleife
        # 2. Befehl 2. Schleife
        # 3. Befehl 2. Schleife
        break # Nur zur Sicherheit falls jemand den Code interpretiert
    # 4. Befehl 1. Schleife
    # 5. Befehl 1. Schleife
    # 6. Befehl 1. Schleife
    break # Nur zur Sicherheit falls jemand den Code interpretiert
#4. Befehl Hauptprogramm
Hier kannst du schön sehen wie man die Einrückungen benutzt. Wie du siehst schreibst du die ersten Befehle ohne Einrückung. Nach der ersten "while"-Schleife musst du alles, was nur in dieser Schleife ausgeführt werden soll einrücken. In der ersten "while"-Schleife habe ich noch eine zweite Eingebaut. Diese muss nach dem Doppelpunkt insgesamt zwei mal Eingerückt werden, wobei dir IDLE diese Arbeit meistens abnimmt. Bist du mit der Schleife fertig und willst wieder in die vorherige löscht du einfach eine Einrückung. Um wieder ins Hauptprogramm zurück zu kommen schreibst du ohne Einrückungen weiter.

Dies ist ein sehr wichtiges Thema, dass du als Grundlage für die weitere Nutzung von Python benötigst.
Zuletzt geändert von garreth am Montag 12. Januar 2015, 22:02, insgesamt 1-mal geändert.
BlackJack

@all (die es betrifft): `random.seed()` sollte man nicht aufrufen, zumindest nicht ohne ein Argument und das braucht man eher selten. Der Aufruf ist nicht nur unnötig, sondern kann unter gewissen Umständen sogar für *weniger* ”Zufall” sorgen.
garreth
User
Beiträge: 41
Registriert: Donnerstag 23. Oktober 2014, 12:04

@BlackJack Danke für den Hinweis. Ich werde dies in meinem Beispiel entfernen. Übrigens ist dieser "Schnitzer" auch in der 4. Auflage des Buches noch so drinnen.
Benutzeravatar
Lebensretter
User
Beiträge: 8
Registriert: Montag 12. Januar 2015, 15:56
Wohnort: CGN

Vielen lieben Dank für euren tollen Rückmeldungen. Klasse Hilfe :)

Ich gucke mir das später mal genau an bzw. probiere es aus.

Verstehe ich das richtig, dass in dem Buch, dass ich habe Fehler drin sind ?

Aber so oder so..ich betrachte das Buch eh nur als Wegstück auf einer langen seltsamen Reise :D

Werde mich durchbeissen, auch wenn der Weg gerade anfangs etwas beschwerlich ist.
garreth
User
Beiträge: 41
Registriert: Donnerstag 23. Oktober 2014, 12:04

Hallo Lebensretter,

das Buch ist schon gut. Es gibt nur einige Sachen, die unsauber sind. Ob dies so gewollt ist, um einen blutigen Anfänger nicht zu sehr zu verwirren, kann ich nicht beurteilen.

1. Man sollte es unterlassen mit "except" alle Fehlermeldungen abzufangen. Du willst ausschließlich einen "ValueError" abfangen. Dieser wird nur ausgegeben, wenn der Nutzer keine Zahl eingegeben hat.
2. continue sollte man unterlassen
3. Der besprochene Einsatz von "random.seed()"

Ist alles nicht wirklich ein Fehler, aber sehr unsauber.

Gruß
garreth
Benutzeravatar
pillmuncher
User
Beiträge: 1484
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

garreth hat geschrieben:2. continue sollte man unterlassen
Wie kommst du denn da drauf?
In specifications, Murphy's Law supersedes Ohm's.
BlackJack

@pillmuncher: Also ich vermeide das auch wo ich kann, also immer. Das ist ein unbedingter Sprung a.k.a. GOTO an den Schleifenanfang der sich nicht in der Struktur/Einrückung des Quelltextes wiederspiegelt → schlechter lesbar. Es verhindert das man einfach nachträglich noch etwas in den Schleifenkörper einfügen kann was am Ende von jedem Schleifendurchlauf ausgeführt wird. Und es erschwert es den Schleifenkörper oder Teile davon in eigene Funktionen herauszuziehen. IMHO macht es mehr Probleme als es Wert ist.
Benutzeravatar
pillmuncher
User
Beiträge: 1484
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

@BlackJack: Solche imperativen low level Sprachelemente wie continue haben IMO ihren Platz, wenn man sie mit Geschmack und Verstand einsetzt, aber das gilt wohl für alles beim Programmieren. Spaghetticode kann man auch gut ohne goto/break/continue/... schreiben, man könnte ja zB. Funktionen als Sprungmarken missbrauchen, indem man sie als bloße benannte Codestücke verwendet. Das Problem ist also weniger das konkrete Sprachelement, das man einsetzt, als die mangelnde Ahnung und Disziplin beim Programieren.

Ich habe spaßeshalber ein Projekt von mir (ca. 1750 XLOC) durchgegrept, und habe lediglich ein einziges continue gefunden:

Code: Alles auswählen

    def choice_point(self, db):
        trail = []
        for term in db.find_all(self.indicator):
            try:
                term.head.unify(self, trail)
            except UnificationFailed:
                continue
            else:
                yield term.body
            finally:
                while trail:
                    trail.pop().undo()
Wenn ich so darüber nachdenke, wäre pass hier sogar besser, weil weniger redundant. Werde ich gleich ändern.
In specifications, Murphy's Law supersedes Ohm's.
Sirius3
User
Beiträge: 17761
Registriert: Sonntag 21. Oktober 2012, 17:20

Ups. Über 1500 continues in 4500 Dateien. :oops:
Benutzeravatar
Lebensretter
User
Beiträge: 8
Registriert: Montag 12. Januar 2015, 15:56
Wohnort: CGN

Würdet ihr mir - speziell von meinem Standpunkt aus gesehen - ein anderes Buch empfehlen als das mit dem ich gerade lerne ?

Ich hab mir parallel auch "Java für Dummies" gekauft. Gucke mir also gleichzeitig etwas Java an. Da finde ich - was ich bisher las - recht witzig und gut erklärt.

Bin mir bewusst, dass es Online-Tutorials gibt, aber ich hab auch gerne was Festes in der Hand zum Blättern. Das riecht und sich anfassen lässt :D
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Lebensretter hat geschrieben: Bin mir bewusst, dass es Online-Tutorials gibt, aber ich hab auch gerne was Festes in der Hand zum Blättern. Das riecht und sich anfassen lässt :D
Dann drucke / kauf Dir doch "Learn python the hard way". Das ist für (Programmier-)Anfänger gut geeignet (nicht vom Titel abschrecken lassen).

Richtig gute Python-Bücher sind rar gesäht; für solche in Deutsch gilt das umso mehr...

Evtl. wäre das Python Buch aus der Reihe "Head first" (auf Deutsch "von Kopf bis Fuß") etwas für Dich?
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
Lebensretter
User
Beiträge: 8
Registriert: Montag 12. Januar 2015, 15:56
Wohnort: CGN

Herzlichen Dank für den Buchtipp. Habe es mir bestellt :-)
bb1898
User
Beiträge: 200
Registriert: Mittwoch 12. Juli 2006, 14:28

garreth hat geschrieben: das Buch ist schon gut. Es gibt nur einige Sachen, die unsauber sind. Ob dies so gewollt ist, um einen blutigen Anfänger nicht zu sehr zu verwirren, kann ich nicht beurteilen.
Ein Buch, das für Python-Anfänger geeignet sein soll und dann einen Anfänger ausgerechnet in Sachen Einrückung so im Regen stehen lässt? Ich kenne es nicht, aber allein das lässt mich doch arg zweifeln (allerdings zusammen mit schlechten Erfahrungen mit andern Galileo-Büchern).
Benutzeravatar
Lebensretter
User
Beiträge: 8
Registriert: Montag 12. Januar 2015, 15:56
Wohnort: CGN

Also das mit den Einrückungen ist echt so ne Sache. Sowohl das IDLE-Programm, als auch das Buch geben mir diese falsch an. Ich muss selbst rumprobieren und mithilfe des Feedbacks hier das Ding zurechtfummeln. Aber ich beiss mich schon durch. Im Grunde komme ich gut voran. Bin gerade bei Tupeln angelangt. Insgesamt versteh ich die Logik ganz gut. Woran es immer wieder hakt, sind diese "Kinderkrankheiten".
Beispiel: Ich schreibe Code und während ich tippe, sehe ich wie es funktioniert. Ich speichere ab und starte und er meldet mir direkt in der ersten Line einen Fehler. Das hab ich öfter gehabt, obwohl der Code so getippt wurde wie im Buch..

Eine Frage: Wie bekomme ich "kaputten code" aus dem IDLE-programm wieder raus ? Ich hab schon mehrfach Sachen probiert das rauszuschneiden bzw. ungeschehen zu machen. Nix klappt. Ich will print(Mehrf. ZUweisung:", x, y, z) rauskriegen. Aber es will einfach nicht raus. Weiter unten sieht man auch meine Probleme mit den Einrückungen. Freue mich auf kurzes Feedback eurerseits :-)

Beispiel:

Code: Alles auswählen

>>> #1: Mehrfache Zuweisung
>>> x, y, z = 3, 5.2, "hallo"
>>> print(Mehrf. ZUweisung:", x, y, z)
      
SyntaxError: invalid syntax
>>> print("Mehrf. Zuweisung:", x, y, z)
Mehrf. Zuweisung: 3 5.2 hallo
>>> #2: Auswirkungen erst danach
>>> a= 12
>>> b = 15
>>> c = 22
>>> a, b, c = c, a a+b
SyntaxError: invalid syntax
>>> a, b, c = c, a, a+b
>>> print("Auswirkung:", a, b, c)
Auswirkung: 22 12 27
>>> 
>>> # Verpacken eines Tupels
>>> p = 3, 4
>>> print("Verpackt:", p)
Verpackt: (3, 4)
>>> 
>>> #4: Entpacken eines Tupels
>>> m, n = p
>>> print("Entpackt: m:", m, "n:", n)
Entpackt: m: 3 n: 4
>>> #5: Falsche Zuweisung eines Tupels
>>> try:
	s, t = 3, 4, 12
	print(s, t)
    except:
	    
SyntaxError: unindent does not match any outer indentation level
>>> try:
	s, t = 3, 4, 12
	except:
		
SyntaxError: invalid syntax
>>> try:
	s, t = 3, 4, 12
	print(s, t)
except:
	print("Fehler")

	
Fehler
>>> #6: Rest in Liste
>>> print()

>>> x, *y, z = 3, 5.2, "hallo", 7.3, 2.9
>>> print(x)
3
>>> print(y)
[5.2, 'hallo', 7.3]
>>> print(z)
2.9
>>> 

Benutzeravatar
Lebensretter
User
Beiträge: 8
Registriert: Montag 12. Januar 2015, 15:56
Wohnort: CGN

Es ist halt echt frustrierend. Weil es anfängt Spass zu machen und immer wieder wird man ausgebremst.
Sirius3
User
Beiträge: 17761
Registriert: Sonntag 21. Oktober 2012, 17:20

@Lebensretter: was Du da siehst, ist der interaktive Modus, da was rauslöschen zu wollen, widerspricht sich, weil es ja schon ausgeführt wurde und damit futsch ist. Auch ist der interaktive Modus nicht dafür geeignet längere Programmteile einzugeben, sondern nur Einzeiler. Für längere Dinge nimmt man am besten einen Editor, der die Einrückung automatisch beherrscht, da wirst Du durch ">>>" dann auch nicht irritiert. Aber Du hast ja schon die wichtigste Lektion gelernt: einfach mal ausprobieren und sich nicht entmutigen lassen.
Serpens66
User
Beiträge: 259
Registriert: Montag 15. Dezember 2014, 00:31

hi :)
auch wenn ich absoluter Anfänger bin, möchte ich dennoch was zu den Einrückschwierigkeiten sagen, falls es sich um das Problem handelt, was ich auch oft hatte ;)

1. Auch #Kommentare müssen korrekt eingerückt sein (hat bei mir auch ne weile gedauert bis ich das akzeptieren konnte :D)
2. Ich verwende oft die TAB-Taste um die Einrückung von 4 Leerzeichen vorzunehmen. Dazu muss aber der genutzte Editor so eingestellt sein, dass er kein Tabulatorzeichen macht, sondern stattdessen halt 4 Leerzeichen. Wenn du Tabulatorzeichen und Leerzeichen mischst, kommt eig immer eine Fehlermeldung diesbezüglich. In Notepad++ (den editor kann ich weiterempfehlen), kannst du alle Tabulatorzeichen durch Leerzeichen ersetzen lassen :)

Ja, das sind die 2 Punkte die ich am Anfang oft falsch gemacht habe, vllt hilfts ja :)
Antworten