Python

if (question.about(PowerPoint, C++, LaTeX, Word, Excel...) == true) then question.answered(here);
Antworten
Benutzeravatar

Themenstarter
Libby Weiblich
Beiträge: 1979
Registriert: Sa 28. Nov 2015, 19:34

Python

Beitrag von Libby »

Ich lese gerade eines der von codecademy empfohlenen external readings und las, dass die Variable in Python meist lokal sind und eher weniger global. Ist das nicht mega unpraktisch? Oder ist das irgendwie vorteilhaft, weil man dann die Variable in irgendeiner Funktion benutzen kann, aber die alte global erhalten bleibt?
Benutzeravatar

Knopfloch Weiblich
Administrator
Beiträge: 4914
Registriert: Mi 18. Nov 2015, 21:49

Re: Python

Beitrag von Knopfloch »

Globale Variablen sind allgemein out, weil man einfach keinen Überblick hat, wer da den Wert ändert, und es immer nur einen einzigen Wert gibt, man also nicht denselben Code parallel verwenden kann. Ganz lokale variablen sind aber natürlich auch doof, man müsste sie ja immer von einer zur nächsten Funktion durchreichen.
Python ist eine (zumindest halbwegs) objektorientierte Scriptsprache, neben lokalen Variablen und globalen Variablen gibt es in diesen Member-Variablen/Instanz-Variablen/Felder.
Du hast dann eine Klasse, die mehrere Funktionen/Methoden enthält, die alle Zugriff auf einen gemeinsamen Container ("self") haben, und dort Variablen speichern und auslesen können. Von dieser Klasse gibt es mehrere Instanzen, Objekte genannt, die jeweils einen eigenen Variablenkontext haben, auf den sie aus all ihren Methoden zugreifen können, der aber den Wert nicht für andere Objekte ändert.

Sowas zum Beispiel, völlig sinnloses Beispiel, aber zeigt zumindest, wie man hier Variablen setzen und in verschiedenen Methoden verwenden kann, ohne dass sie aber global sind und für alle Berechnungen verwendet würden:

Code: Alles auswählen

class Test:
	def __init__(self, y):
		self.x = 1
		self.y = y
	
	def setX(self, x):
		self.x = x
	
	def calcSum(self):
		return self.x + self.y
	
	def calcProd(self):
		return self.x * self.y
	
	def calcMore(self, z):
		return self.x + self.y - z
	
test1 = Test(5)
test2 = Test(3)
print(test1.calcSum())   #1+5=6
test1.setX(2)
print(test2.calcSum())   #1+3=4
print(test1.calcProd())  #2*5=10
print(test2.calcProd())  #1*3=3
print(test1.calcMore(7)) #2+5-7=0
sollte ergeben:

Code: Alles auswählen

6
4
10
3
0
test1 verwendet also y=5 für seine Berechnungen, test2 verwendet y=3 (und nach dem setX-Aufruf außerdem x=2).
(das self muss man nicht als Parameter mitübergeben, Python setzt dafür automatisch das self ein, das man im __init__ [nennt sich Konstruktor] verwendet hat.)
Benutzeravatar

Themenstarter
Libby Weiblich
Beiträge: 1979
Registriert: Sa 28. Nov 2015, 19:34

Re: Python

Beitrag von Libby »

Haha. Das ist zu hoch für mich, aber danke, Knopfi. Ich les das einfach nochmal in der Zukunft irgendwann.
Benutzeravatar

Themenstarter
Libby Weiblich
Beiträge: 1979
Registriert: Sa 28. Nov 2015, 19:34

Re: Python

Beitrag von Libby »

Nachdem ich den Python-Kurs auf Codecademy abgeschlossen habe, hab ich mir das, was du schriebst, Knopfi, nochmal durchgelesen und es ergibt schon etwas mehr Sinn (y) =) Ich verstehe zwar dieses ganze Klassen-Ding immer noch nicht, aber ich kann deinen Code nachvollziehen und die Ausgabe verstehen und weiß schon mal, dass es Klassen gibt und self wichtig ist ;) Vielleicht muss ich mir dazu noch ein reading vornehmen.
Benutzeravatar

Themenstarter
Libby Weiblich
Beiträge: 1979
Registriert: Sa 28. Nov 2015, 19:34

Re: Python

Beitrag von Libby »

Meine erste Wochen(!)hausaufgabe lautet:
Schreiben Sie ein Programm, das eine Zufallszahl zwischen 1 und 100 erzeugt, die Sie dann erraten müssen. Dabei sagt Ihnen das Programm nach jedem Rateschritt, ob die gesuchte Zahl größer oder kleiner ist als die eingegebene Zahl. Wenn die Zahl richtig ist, soll das Programm beendet werden und die Anzahl der Rateversuche wird ausgegeben.
Mein Code:

Code: Alles auswählen

import numpy as np   #Import spezieller Funktion

random_num = np.random.randint(1, 101) #Generierung der Zufallszahl
print(random_num) #natürlich nur zum Testen

guess = 0 #Initialisierung der Variable guess als 0, weil 0 nicht im Zufallsintervall

count = 0 #Initialisierung der Variable count fürs Zählen der Versuche

while random_num != guess:  #Schleife für die Rateversuche
    guess = int(input('Gib deinen Vorschlag für die Zufallszahl ein:'))
    count +=1 #Zählt Rateversuche 
    #Überprüfung des Rateversuchs
    if random_num == guess:  
        print('Yay! You win! Das waren  %s Versuche.' % count)
    elif guess < random_num: 
        print('Leider daneben! Die gesuchte Zahl ist größer als die geratene Zahl.')
    elif guess > random_num: 
        print('Leder daneben! Die gesuchte Zahl ist kleiner als die geratene Zahl.')
Mir kommt es gerade zu einfach vor. Die Installation der Entwicklerumgebung war schwieriger! Und das ganze als PDF mit Screenshots und meinem Namen wird bestimmt auch ätzend.
Findet ihr, ich sollte noch eine Fehlermeldung ausgeben, falls die Zahl nicht zwischen 1 und 100 ist oder gar keine Zahl ist, einbauen?
Benutzeravatar

Knopfloch Weiblich
Administrator
Beiträge: 4914
Registriert: Mi 18. Nov 2015, 21:49

Re: Python

Beitrag von Knopfloch »

Brauchen tust du's wohl nicht mit der Fehlermeldung, aber probieren kannst du's ja mal, wenn's bis da zu einfach war! :)
Entweder gibt's Bonus oder du hast was dabei gelernt.

Was du auch noch machen könntest wär ne große Schleife drumrum, sodass man am Ende gefragt wird, ob man nochmal spielen möchte, und dann wird ne neue Zufallszahl gezogen.
Benutzeravatar

Themenstarter
Libby Weiblich
Beiträge: 1979
Registriert: Sa 28. Nov 2015, 19:34

Re: Python

Beitrag von Libby »

@Knopfi, sag mal, kann man noch irgendwas machen, dass es eine Fehlermeldung für eingegebene Buchstaben gibt? Also input nimmt ja immer Strings, oder? Deswegen hab ich das ja in int() geschrieben. Oder nimmt input alles?
Benutzeravatar

Knopfloch Weiblich
Administrator
Beiträge: 4914
Registriert: Mi 18. Nov 2015, 21:49

Re: Python

Beitrag von Knopfloch »

Welches Python nutzt du, 2.x oder 3.x?

Für 2.x gilt:

input erlaubt erstmal vieles, nämlich Python-Ausdrücke, die interpretiert werden. Gib mal in deinem Programm "random_num" als Guess ein (ohne Anführungszeichen). Oder 2*50 oder guess+1.
Und wenn du "hallo" eingibst, nimmt es auch Strings, bei nur hallo ohne Anführungszeichen dürfts nen Fehler geben. Bei "hallo" gibt es aber auch ne fehler, weiles zwar einen Text einliest, du den dann aber mit dem int() versuchst in einen Integer umzuwandeln (typecast), was nicht funktioniert. Bei "50" (in Anführungszeichen) dagegen sollte es funktionieren.

Ob da tatsächlich ein Integer vorliegt, kannst du prüfen (if type(x) != int: print "fehler!"), oder du nimmst stattdessen nicht den interpretierten Input, sondern den rohen Input mit der Funktion raw_input() statt input(), der immer erstmal String ist, und prüfst dann entweder, ob der nur aus Ziffern besteht (if x.isdigit(): guess = int(x) else: print "fehler!") oder versuchst ihn einfach in einen int zu casten und fängst aber die evtl. entstehende Fehlermeldung ab (try: guess = int(x) except: print "fehler!").

In Python 3.x liefert input() immer String, verhält sich also wie raw_input() in Python 2.x, entsprechend gilt dann der letzte Teil von gerade.
Benutzeravatar

Themenstarter
Libby Weiblich
Beiträge: 1979
Registriert: Sa 28. Nov 2015, 19:34

Re: Python

Beitrag von Libby »

In der Uni jetzt 3.5 oder so... aber ich glaube bei codecademy wars tatsächlich 2.7 oder so.
Doof, dass bei 3.x die erste Variante nicht geht. Auf die kam ich nämlich gerade beim Zähneputzen auch selber :)
Ich denk morgen oder übermorgen nochmal ein bisschen nach, "muss" ja eh erst nächste Woche abgeben.
Danke dir <3
Benutzeravatar

Knopfloch Weiblich
Administrator
Beiträge: 4914
Registriert: Mi 18. Nov 2015, 21:49

Re: Python

Beitrag von Knopfloch »

Achso doch, die geht auch bei 3.x: eval(s) interpretiert den string s als Python-Ausdruck, kannst du also ums input rum setzen und hast wieder das 2.x-er input()
Benutzeravatar

Themenstarter
Libby Weiblich
Beiträge: 1979
Registriert: Sa 28. Nov 2015, 19:34

Re: Python

Beitrag von Libby »

@Knopfloch, ich bin gerade bei Codewars am Üben, weil wir diese Woche gar nichts in der Uni programmiert haben... ich scheitere hieran:
Check to see if a string has the same amount of 'x's and 'o's. The method must return a boolean and be case insensitive. The string can contains any char.
meins:

Code: Alles auswählen

def xo(s):
    x = 0
    o = 0
    s = s.lower()
    for i in s:
        if i == x: 
            x += 1
        elif i == o: 
            o += 1
    if x == o:
        return True
    else: 
        return False
diese komischen Tests:

Code: Alles auswählen

Test.expect(xo('xo'))
Test.expect(xo('xo0'))
Test.expect(not xo('xxxoo'))
Für die ersten beiden Tests gehts auch, aber für den letzten nicht... ich verstehe aber auch dieses not nicht :( Kannst du den letzten Test erklären? Vll. versteh ich dann, was ich noch einbauen muss :)
Benutzeravatar

Knopfloch Weiblich
Administrator
Beiträge: 4914
Registriert: Mi 18. Nov 2015, 21:49

Re: Python

Beitrag von Knopfloch »

not negiert den Boolean-Wert, also wird false zu true und umgekehrt, es wird also erwartet, dass xo('xxxoo') not True, also False ergibt (bzw. es wird erwartet dass not xo(...) True ergibt, was ja das gleiche bedeutet: nicht Falsch = Wahr <=> Falsch = nicht Wahr

Ich kann dir aber sagen, dass es daran nicht liegt, sondern dass es Zufall ist, dass die ersten beiden Tests richtig sind, weil dein xo() immer True zurückgibt.
Das Problem solltest du leicht finden, wenn du deine Variablen mal umbenennst in "anzahl_x" und "anzahl_o"
Benutzeravatar

Themenstarter
Libby Weiblich
Beiträge: 1979
Registriert: Sa 28. Nov 2015, 19:34

Re: Python

Beitrag von Libby »

Danke fürs Erklären! Das heißt, ich will beim Testen immer True bekommen und, wenn ich was testen will, was falsch ist, muss ich not machen, damit es true ist?

Ich find irgendwie diesen Editor auf Codewars doof! Pyzo for the win! Da kann man sich zwischendurch alles printen und dann wird es oft klarer :)
Benutzeravatar

Knopfloch Weiblich
Administrator
Beiträge: 4914
Registriert: Mi 18. Nov 2015, 21:49

Re: Python

Beitrag von Knopfloch »

genau, dieses Test.expect() erwartet einen wahren Ausdruck, ansonsten gilt der Test als fehlgeschlagen. Daher negiert mans, wenn man False erwartet (oder man schreibt Test.expect(xo(...)==False), vllt. sieht das logischer aus)

Und deinen Fehler schon gefunden?
Benutzeravatar

Themenstarter
Libby Weiblich
Beiträge: 1979
Registriert: Sa 28. Nov 2015, 19:34

Re: Python

Beitrag von Libby »

Ja. Ziemlich schnell nachdem ich es in pyzo hatte und geprintet habe :)
Antworten