Funktionen und Rückgabewerte

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.
Antworten
Toad
User
Beiträge: 13
Registriert: Montag 18. April 2011, 07:50

Hallo ich bin noch sehr neu in der Python Welt, und bin nun nach ersten erfolgreichen Programmen an ein Problem gestoßen.

Code: Alles auswählen

r = tuple (input("(x,y,w,h): "))

def rechteck(r):

	if (x == w) and (y == h):
		print "Das Rechteck ueberlappt sich nicht"
		return "True"
	elif (x < w) or (x > w):
		print "Das Rechteck ueberlappt sich in der Breite"
		return "False"
	elif (y> h) or (y < h):
		print "Das Rechteck ueberlappt sich in der Hoehe" 
		return "False"
Das Programm läuft ohne Fehler durch, ich bekomme jedoch keine Ausgabe, fehlt mir sowas wie eine main Methode, oder wie muss ich das angehen?
Ich hoffe ihr könnt mir helfen komme irgendwie nicht auf die Lösung
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

Wo kommen deine Variablen x, y, w, h denn her? - Du hast nur "r" übergeben und musst das so wie das aussieht noch aufteilen "x, y, w, h = r"
Im übrigen kannst du dir bei if-Anweisungen in Python die Klammern sparen.
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
Toad
User
Beiträge: 13
Registriert: Montag 18. April 2011, 07:50

Ahh super danke ich hatte das so probiert hab es aber in Funktion geschrieben, deswegen nahm ich an das es falsch ist. Vielen Dank für den Tipp

Was die Klammern angeht ich finde es so lesbarer :)
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Hallo Toad, willkommen im Forum.

1. Was soll dein Programm überhaupt leisten? Ein Satz wie "Das Rechteck überlappt sich (nicht)" ist in sich völlig sinnlos. Was soll den "ein sich überlappendes Rechteck" sein? Du müsstest für dich zunächst einmal klären, was dein Programm leisten soll.

2. Davon abgesehen fehlen dir offenbar Python-Grundkenntnisse. Das ist nicht weiter schlimm, jeder hat mal klein angefangen. Sinnvoll wäre in dem Fall eine Lektüre (der ersten Kapitel) des Python-Tutorials.
Toad
User
Beiträge: 13
Registriert: Montag 18. April 2011, 07:50

vielen dank, ich wollte einfach quasi beide linien vergleichen die horizontal und waagerecht liegen vergleichen. Sind sie nicht gleich kommt es zu einer Überlappung.
Aber das funktioniert jetzt.

Ich werde mir das Tutorial nochmal anlesen. Vielen Dank für diesen freundlichen Empfang und ich hoffe ich kann bald etwas für die anderen User beitragen.
BlackJack

@Toad: Eine Bedingung ``a < b or a > b`` ist eine recht umständliche Art um ``a != b`` zu schreiben. Zumindest sofern man eine "normale", totale Ordnung auf dem Typ von `a` und `b` annimmt.

Python hat für Wahrheitswerte einen eigenen Datentyp `bool` und die beiden Exemplare `True` und `False`. Da sollte man keine Zeichenketten für missbrauchen. Denn die beiden Zeichenketten ``'True'`` und ``'False'`` sind als Wahrheitswerte betrachtet beide "Wahr", weil in dem Kontext nur die leere Zeichenkette von Python als "Falsch" angesehen wird.

`rechteck()` ist ein schlechter Name für eine Funktion. Funktionen sollten mit Tätigkeiten bezeichnet werden, denn sie tun ja etwas. Bezeichnungen für "Dinge" sind eher für Klassennamen geeignet, denn mit einer Klasse modelliert man in der Regel "Dinge".

Von `input()` solltest Du die Finger lassen, weil der eingegebene Ausdruck von Python interpretiert wird. Der Benutzer kann da alles mögliche eingeben was zu Sicherheitsproblemen führen kann. Ausserdem kann an Ausnahmen ebenfalls so ziemlich alles ausgelöst werden, was es schwieriger macht eine robuste Eingabe damit zu schreiben.

Eine `main()`-Funktion ist nicht unüblich, und zwar nach folgendem Muster:

Code: Alles auswählen

def main():
    """Die Hauptfunktion…"""


if __name__ == '__main__':
    main()
Dann kann man das Modul als Programm ausführen *und* auch als Modul importieren ohne dass die `main()`-Funktion ausgeführt wird. Zum Beispiel um Funktionen oder Klassen aus dem Modul in anderen Modulen zu verwenden, oder um einzelne Teile des Moduls manuell oder automatisiert zu testen.
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

@Toad
Wenn du "elif" nutzt, dann auch richtig, dein Rechteck kann theoretisch auch ein Punkt sein und dann überlappen sich Breite und Höhe.

Wie numerix schon sagte deine Angaben sind ziemlich verwirrend, denn normalerweise werden Höhe und Breite als Wert von der Position und nicht als zweite Position angegeben, da würde man eher x0, y0, x1, y1 nehmen. Wenn allerdings die Namen so stimmen, dann ist deine Funktion schlicht falsch, denn die Kanten würden sich nur überlappen wenn h und w gleich 0 sind. Alles ziemlich merkwürdig, vieleicht kannst du das noch mal näher erklären.
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Toad hat geschrieben:Ich werde mir das Tutorial nochmal anlesen.
Das klingt nicht gut. "Anlesen" ist definitiv zu wenig. "Durcharbeiten" wäre eine sinnvolle Sache.
Toad
User
Beiträge: 13
Registriert: Montag 18. April 2011, 07:50

Ich habe jetzt schon mit ein bisschen mehr wissen das ganze geschrieben, und es funktioniert bei mir python 2.7 unter mac auch wunderbar. Bei einem kollegen jedoch mit Python 3.2 unter Windows meckert er bei der Übergabe von dem Tupel in die Einzelnen Werte.

Code: Alles auswählen

#Funktion um zu pruefen ob die Koordinaten in dem Rechteck r liegen

def check(r,x1,y1):	
	if (x1 < x) or (x1 > x+w):
		return False
	if (y1 < y) or (y1 > y+h):
		return False
	return True

#Funktion zum Erhoehen der Koordinaten aus S, mit uebergabe der 
#Koordinaten an die Check - Funktion.

def overlap(r,s):
	for x2 in range (x1,x1+w1,+1):
		for y2 in range (y1,y1+h1,+1):
			if check(r,x2,y2) == True:
				return True
	return False
	
#Main - Methode

r = tuple (input("(x,y,w,h): "))
s = tuple (input("(x,y,w,h): "))
x,y,w,h = r
x1,y1,w1,h1 = s
print(overlap(r,s))
Also er meckert bei:
r = tuple (input("(x,y,w,h): "))
s = tuple (input("(x,y,w,h): "))

das scheint es nichtmehr zu geben.

Das gleiche Problem habe ich mit raw_input bei einem anderen Programm wo es auch bei mir funktioniert bei ihm jedoch nicht. Hat jemand ne Ahnung warum das so sein kann?

Code: Alles auswählen

# Bitte um Eingabe des Textes
text = raw_input("Text: ")


#Aus dem String text, wird eine Liste mit den einzelnen 
#Buchstaben gemacht
li = []
for element in text:
    li.append(element)

dic = {} # Leeres Woerterbuch

# For Schleife, um die Liste
for wort in text:
	if not(dic.has_key(wort)):
		dic[wort] = 1
	else:
		dic[wort] = dic[wort] + 1
# Nach Ende Ausgabe des Woerterbuchs

print dic
Ich hoffe ich mache nicht zu viele Umstände hab schon über Google geschaut ob ich was finde, allerdings keine erfolgreichen Ergebnisse.
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

In Python 3.x ist "raw_input" zu "input" geworden. Deshalb geht es in beiden Fällen nicht. Hier bekommst du einen String, diesen musst du, wenn du die Eingabe so beibehalten willst, mit der ".split(',')"-Methode teilen und dann die einzelnen Eingaben in Integer Variablen umwandeln.
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
Toad
User
Beiträge: 13
Registriert: Montag 18. April 2011, 07:50

Und das erkennt auch meine 2.7er Version noch?

Hat sich das mit dem Tupel dann auch verändert?
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

Nein, an "tuple()" hat sich nichts geändert, nur braucht tuple eine Sequenz, welches bei dir unter Python 2.x noch mit "input" geliefert bekommen hast. Mit dem "raw_input" bekommst du nur einen String, zB. "1, 1, 50, 50" vorher hattest du aber (1, 1, 50, 50) bekommen. Also musst du den String erst sauber verarbeiten.

Im übrigen überleg mal wie du dein Funktionen oben noch kompakter schreiben kannst. Beispiel, deine "check"-Funktion lässt sich auch so schreiben:

Code: Alles auswählen

def point_in_rect(rect, point):
    x, y, w, h = rect
    x1, y1 = point
    return x < x1 < x + w and y < y1 < y + h
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
Toad
User
Beiträge: 13
Registriert: Montag 18. April 2011, 07:50

Ich war mit der so ganz zufrieden, aber mal gucken was man noch optimieren kann.

Was nun bedeutet unter 3.2 gibt input keine tuple Sequenz mehr zurück, wenn ich:

Code: Alles auswählen

r = tuple (input("(x,y,w,h): "))
eingeben lasse?

Bekomm ich also bei 3.2 erst einen String und muss diesen in ein Tupel umwandeln?
hab ich das richtig verstanden?
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

Ließ dir mal folgenden Abschnitt durch und sag mir dann warum es nicht so Funktionieren kann, wenn du an tuple("1, 1, 50, 50") übergibst. :) tuple() und wenn du es dann verstanden hast, wird das für dich interessant sein .split()
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

1. Das "tuple" vor dem input() ist bei Python2.x sowieso überflüssig. Das "alte" input() beinhaltet ein eval(), das wertet deine Eingabe als Python-Ausdruck aus und liefert das Ergebnis zurück. Gibst du "(1,2,3,4)" ein (die Klammern sind ebenfalls überflüssig), dann kommt automatisch ein Tupel heraus.

2. Das solltest du so nicht machen, sondern stattdessen die Eingabe als Zeichenkette aufnehmen und selbst umwandeln.

Code: Alles auswählen

eingabe = raw_input("a,b,c,d")
a,b,c,d = map(int,eingabe.split(","))
3. Mit Python 3.x funktioniert es genauso (schlecht) wie oben unter 1. beschrieben, wenn du ein eval() um das input() setzt.

4. Mach es auch mit Python 3 so wie unter 2. beschrieben. Ersetze nur raw_input() durch input().
Antworten