Seite 1 von 2
Warum boolsche Ergebnisse gemischt mit Integer?
Verfasst: Dienstag 19. November 2013, 16:34
von siggi
Hallo,
ich benutze Python 3.2.3 und habe das Problem, dass ich auf Vegleichsoperationen mal boolsche mal integer Antworten bekomme.
Konkret, z.B.:
Das folgende Programm
Code: Alles auswählen
for a in range(0, 2):
for b in range(0, 2):
r = not a or b
print("a:",a,"b:",b, "r:",r, "class:", type(r))
liefert als Ausgabe:
a: 0 b: 0 r: True class: <class 'bool'>
a: 0 b: 1 r: True class: <class 'bool'>
a: 1 b: 0 r: 0 class: <class 'int'>
a: 1 b: 1 r: 1 class: <class 'int'>
Ich hätte aber gerne nur boolsche Antworten, True of False, und nicht Class "Bool" und Klasse "Int" gemischt. Im simplen BASIC geht das ja auch.
Wie mache ich das bitte?
Danke, siggi
P.S. Ich meine jetzt nicht einen Umweg, wie z.B. "if r == 1: r = True", sondern direkt ohne Umwege!
Re: Warum boolsche Ergebnisse gemischt mit Integer?
Verfasst: Dienstag 19. November 2013, 16:42
von BlackJack
@siggi: Erstmal: Du hast dort nirgends eine Vergleichsoperation! ``not`` liefert immer einen Wert vom Typ `bool()` daher kommen Deine Wahrheitswerte. ``or`` dagegen liefert den ersten Operanden wenn der „wahr” ist, und sonst den zweiten Operanden. Der Typ vom Ergebnis hängt also vom Typ der Operanden ab, beziehungsweise des Operanden der zurückgegeben wird.
Lösung für Deine Anforderung ist die `bool()`-Funktion: ``r = bool(not a or b)``.
Re: Warum boolsche Ergebnisse gemischt mit Integer?
Verfasst: Dienstag 19. November 2013, 18:38
von siggi
Danke BlackJack für die schnelle Aufklärung! Jetzt klappt's

War halt in BASIC einfacher: ich versuche nämlich ein paar BASIC Programme für Python umzusetzen. Ist noch ein dorniger Weg
Gruss,
siggi
Re: Warum boolsche Ergebnisse gemischt mit Integer?
Verfasst: Dienstag 19. November 2013, 22:09
von BlackJack
@siggi: Ich denke nicht das es in BASIC einfacher war. Es ist halt *anders*. Aber das ``and`` und ``or`` nicht zwingend ``True`` oder ``False`` liefern habe ich in Python noch nie als Problem empfunden. Andererseits habe ich in BASIC früher öfter mal ausgenutzt das „wahr” den Wert -1 und „falsch” den Wert 0 hat. Zumindest bei CBM BASIC. Und wo Du vielleicht auch noch Überraschungen erleben kannst, ist das viele BASIC-Dialekte Ausdrücke mit ``AND`` und ``OR`` komplett auswerten, auch wenn das Ergebnis nach einem Teilausdruck eigentlich schon fest steht.
Vielleicht übersetzt Du einfach zu „wörtlich” wenn Du Probleme hast, statt den Sinn des Programms in echtes Python zu übersetzen. Also das am Ende kein Python sondern BASIC in Python-Syntax heraus kommt.
Re: Warum boolsche Ergebnisse gemischt mit Integer?
Verfasst: Donnerstag 21. November 2013, 21:51
von siggi
@BlackJack: Danke nochmal, BlackJack! Es ging um eine Knoblei "Wenn a fernsieht, will auch b fernsehen..." usw. Insgesamt 5 Jungs mit verschiedenen Wünschen. Frage: "Wer darf Fernsehen ohne eine der Aussagen zu verletzen?". Ich kannte das Programm aus meinen BASIC-Zeiten her.
Nachdem ich in Python jetzt alle Vergleichsoperationen "geboolt" habe, klappt's auch in Python.
Mit "einfacher" meinte ich, hier z.B:
BASIC
s = (b and not c) or (not b and c)
Python
s = bool((b and not c) or (not b and c))
Halt immer "bool" und 2 Klammern mehr. Dafür fallen in Python die "next"s nach den 5 for-Schleifen weg
Ich habe mir dazu jetzt das kleine SmallBasic von Sourceforge.net auf mein Ubuntu 64bit installiert, damit ich eine Referenz habe, um die schönen BASIC-Programme aus Löthe/Quehl (Systematisches Arbeiten mit BASIC, 1982) zu "übersetzen" bzw. "nachzuempfinden". Jetzt kann ich Knobelaufgaben auch mit Python lösen, halt ge"bool"t, aber es klappt.
Noch zu deiner Bemerkung:
Vielleicht übersetzt Du einfach zu „wörtlich” wenn Du Probleme hast, statt den Sinn des Programms in echtes Python zu übersetzen. Also das am Ende kein Python sondern BASIC in Python-Syntax heraus kommt.
Also, was das oben angesprochene Fernsehproblem betrifft, wüsste ich nicht was ich in Python anders machen könnte als in BASIC, ausser dem Ge"bool"e und dem Wegfall der "next"s. Davon abgesehen, sehen die Programme haargenau gleich aus.
Gruss, siggi
Re: Warum boolsche Ergebnisse gemischt mit Integer?
Verfasst: Donnerstag 21. November 2013, 22:03
von EyDu
siggi hat geschrieben:Vielleicht übersetzt Du einfach zu „wörtlich” wenn Du Probleme hast, statt den Sinn des Programms in echtes Python zu übersetzen. Also das am Ende kein Python sondern BASIC in Python-Syntax heraus kommt.
Also, was das oben angesprochene Fernsehproblem betrifft, wüsste ich nicht was ich in Python anders machen könnte als in BASIC, ausser dem Ge"bool"e und dem Wegfall der "next"s. Davon abgesehen, sehen die Programme haargenau gleich aus.
Darauf wollte BlackJack hinaus. Wenn du nicht extrem kurze Programme schreibst und diese in Python genau so aussehen wie in BASIC, dann machst du etwas falsch. Python ist viel ausdrucksstärker und das solltest du auch ausnutzen. Wenn du die Vorteile nicht verwendest, dann kannst du auch gleich aufhören Python zu programmieren und bei BASIC bleiben.
Re: Warum boolsche Ergebnisse gemischt mit Integer?
Verfasst: Donnerstag 21. November 2013, 22:30
von BlackJack
@siggi: Wahrscheinlich sind weder die 5 Schleifen noch das `bool()` wirklich nötig.
Re: Warum boolsche Ergebnisse gemischt mit Integer?
Verfasst: Donnerstag 21. November 2013, 22:51
von Hyperion
@siggi: Poste doch mal die Problemstellung und Deine Lösung hier - ich wette, wir können Dir einige Ansätze zeigen, die das ganze deutlich anders aussehen lassen, als eine BASIC-Variante...

Re: Warum boolsche Ergebnisse gemischt mit Integer?
Verfasst: Freitag 22. November 2013, 00:37
von BlackJack
Falls es um so etwas hier geht
http://www.flashforum.de/forum/am-rande ... 71758.html:
Fünf Mädchen A,B,C,D,E wollen unter folg Bedingungen fernsehen:
-Mit A möchte auch B fernsehen
-B und C wollen nicht zugleich fernsehen, jedoch mindestens eine
-Wenn Doro nicht fernsieht will Emilie fernsehen
-Clara und Emilie wollen beide zusammen oder beide nicht fernsehen
-Wenn Doro fernsieht, wollen auch Anne und Emilie zusammen fernsehen
Dann braucht man weder fünf Schleifen noch `bool()`:
Code: Alles auswählen
#!/usr/bin/env python
from itertools import product
def main():
for a, b, c, d, e in product(*([[True, False]] * 5)):
if (
((a and b) or (not a))
and ((b and not c) or (not b and c))
and (not d and e)
and ((c and e) or (not c and not e))
and ((d and (a and e)) or (not d))
):
print a, b, c, d, e
if __name__ == '__main__':
main()
Re: Warum boolsche Ergebnisse gemischt mit Integer?
Verfasst: Freitag 22. November 2013, 08:12
von siggi
Ja, BlackJack, ist so ähnlich, aus "Löthe/Quehl. Systematisches Arbeiten mit BASIC. Teubner, Stuttgart, 19822". Hier jetzt meine Lösung und die Frage: warum muss ich bei mir bool verwenden und du nicht? Die logischen Teile sind doch sehr ähnlich!
Code: Alles auswählen
#!/usr/bin/env python3
# fersehproblem.py
# Loethe/Quehl: systematisches arbeiten mit basic, S. 92
for a in range(0, 2):
for b in range(0, 2):
for c in range(0, 2):
for d in range(0, 2):
for e in range(0, 2):
# Verarbeitungsteil
r = bool(not a or b)
s = bool((b and not c) or (not b and c))
t = bool(d or e)
u = bool((c and e) or (not c and not e))
v = bool(not d or (a and e))
y = bool(r and s and t and u and v)
# Ausgabe
if y == True:
print("y:",y,"a",a,"b",b,"c",c,"d",d,"e",e)
Re: Warum boolsche Ergebnisse gemischt mit Integer?
Verfasst: Freitag 22. November 2013, 08:44
von Hyperion
Weil Du keine Wahrheitswerte verwendest, sondern Integer Werte!
Wenn Du Deine Menge in den Schleifen auf Boolesche Werte umstellst, geht es auch ohne.
Code: Alles auswählen
for a in (True, False):
for b in (True, False):
# usw ...
Wobei der Ansatz mit dermaßen vielen verschachtelten Schleifen kein guter ist - BlackJack hat Dir ja schon gezeigt, wie man das pythonisch angehen würde; eben mit einer Generator-Funktion, die einem die passenden Tupel erzeugt (``itertools.product``).
Die Kommentare im Code sind übrigens wenig sinnvoll - dass etwas ausgegeben wird *sieht* man sofort. Und laut Onkel Bob sollte man Dinge, die man erklären muss, sowieso umschreiben

Re: Warum boolsche Ergebnisse gemischt mit Integer?
Verfasst: Freitag 22. November 2013, 10:47
von BlackJack
@siggi: Aus welchem Buch die Aufgabe ist hattest Du ja schon mal gesagt — das hat nur nicht jeder griffbereit.
Edit: Wobei auch bei Dir eigentlich nur ein einziger `bool()`-Aufruf nötig wäre, nämlich beim `print()`, denn nur da möchtest Du anscheinend `True` ausgegeben haben. Du müsstest dann nur noch beim ``if`` den unsinnigen ``== True``-Vergleich weg lassen und nur ``if y:`` schreiben. Denn `y` soll an der Stelle ja selbst als Wahrheitswert verwendet werden. Durch einen Vergleich mit `True` ändert sich an dem Wahrheitsgehalt nichts.
SmallBasic kannte ich übrigens noch nicht. Wenn ich BASIC-Programme für den PC aus der Zeit zum laufen bringen möchte, nehme ich immer FreeBASIC (
http://freebasic.net/). Das wurde mal als freie Implementierung für QBasic/QuickBASIC angefangen (das ist das BASIC was bei MS-DOS nach GW-BASIC dabei war), wurde aber mittlerweile auch um einige Spracheigenschaften erweitert.
Da es nur *ein* Ergebnis gibt, hätte man da auch ohne Programm durch vereinfachen des boole'schen Ausdrucks drauf kommen können.

Re: Warum boolsche Ergebnisse gemischt mit Integer?
Verfasst: Freitag 22. November 2013, 11:39
von snafu
Im Übrigen kann man die hier benötigte Ausgabe von `product()` alternativ auch unter Nutzung des `repeat`-Arguments erhalten:
Code: Alles auswählen
for a, b, c, d, e in product([True, False], repeat=5):
# usw
Code: Alles auswählen
>>> p1 = product(*([[True, False]] * 5))
>>> p2 = product([True, False], repeat=5)
>>> list(p1) == list(p2)
True
Re: Warum boolsche Ergebnisse gemischt mit Integer?
Verfasst: Freitag 22. November 2013, 12:22
von BlackJack
Zu der Zeit wo das Buch aktuell war hätte ich das noch in CBM BASIC gelöst. Hier mal eine Variante in so einem antiken BASIC die auch mit nur einer Schleife auskommt:
Code: Alles auswählen
10 FOR I=0 TO 31
20 A=(I AND 1)=0:B=(I AND 2)=0:C=(I AND 4)=0:D=(I AND 8)=0:E=(I AND 16)=0
30 R1=(A AND B)OR(NOT A)
40 R2=(B AND NOT C)OR(NOT B AND C)
50 R3=NOT D AND E
60 R4=(C AND E)OR(NOT C AND NOT E)
70 R5=(D AND A AND E)OR(NOT D)
80 IF NOT(R1 AND R2 AND R3 AND R4 AND R5) THEN 100
90 PRINT "A:";-A;" B:";-B;" C:";-C;" D:";-D;" E:";-E
100 NEXT
Re: Warum boolsche Ergebnisse gemischt mit Integer?
Verfasst: Freitag 22. November 2013, 19:31
von siggi
Danke für eure vielen Tipps hier! Als nur gelegentlicher Hobby-Programmier (hauptsächlich um was mit den Enkeln zu machen), habe ich jetzt viel gelernt
Gruss,
siggi
Re: Warum boolsche Ergebnisse gemischt mit Integer?
Verfasst: Freitag 22. November 2013, 20:18
von siggi
BlackJack hat geschrieben:@siggi: Aus welchem Buch die Aufgabe ist hattest Du ja schon mal gesagt — das hat nur nicht jeder griffbereit.

Ich sehe schon, ich werde halt alt. Ich leihe das Buch gerne aus, löst sich aber langsam auf
BlackJack hat geschrieben:SmallBasic kannte ich übrigens noch nicht. Wenn ich BASIC-Programme für den PC aus der Zeit zum laufen bringen möchte, nehme ich immer FreeBASIC (
http://freebasic.net/). Das wurde mal als freie Implementierung für QBasic/QuickBASIC angefangen (das ist das BASIC was bei MS-DOS nach GW-BASIC dabei war), wurde aber mittlerweile auch um einige Spracheigenschaften erweitert.
Bis gestern kannte ich SmallBasic (nicht zu verwechseln mit Microsofts quälendem Small Basic) auch noch nicht, hab's genommen, weil ich auf die Schnelle nichts einfacheres für 64bit finden konnte, um kurz was zu überprüfen; seit Jahren kommt mir nämlich kein BASIC mehr auf meinen PC. QBasic und Freebasic habe ich früher auch benutzt, ebenso C64 Basic, Basic und Pascal auf der PDP-11, Turbobasic und Turbopascal, Delphi, Lazarus, Lochstreifen auf einer Adler-Rechenmaschine (die Reihenfolge stimmt so nicht), aber Python gefällt mir am besten.
A propos SmallBASIC: ich hoffe das passt noch hierher: wie setze ich das folgende einfache smallbasic Plotprogramm ebenfalls möglichst einfach in Python um?
Ich habe das natürlich mit Python-Pygame, Python-Tkinter und VPython auch gemacht, aber halt komplizierter, aber die Einfachheit mit SmallBasic verblüfft mich doch. Es geht um einen Funktionsplot mit SIN oder auch TAN, oder was auch immer. Hier das SmallBasic Programm, ist nur eine Zeile:
Der Plot liegt richtig im Fenster, sieht gut aus, die Fenstehöhe passt sich automatisch an. Kriegt man das in Python auch so einfach oder vergleichbar einfach hin?
BlackJack hat geschrieben:Da es nur *ein* Ergebnis gibt, hätte man da auch ohne Programm durch vereinfachen des boole'schen Ausdrucks drauf kommen können.

Klar, mir ging's nur ums Prinzip, um auch kompliziertere Knobeleien lösen zu können.
Noch etwas, da hier Python-Kobelexperten zugegen sind: in unserer Schulzeit hatten wir uns mit dem ehrlichen und lügenhaften Bewohner beschäftigt; die einfachste Version kennt ihr bestimmt lautet etwa so: "Wanderer kommt an Wegegabelung, ein Männeken steht dort. Wanderer weiss nur, dass derjenige entweder zur Spezies gehört, die immer die Wahrheit sagt oder zur Spezies, die immer lügt. Wie und wieoft muss er also fragen, um den richtigen Weg zu finden?" Ich weiss schon, dass man das mit einer einzigen Frage lösen kann, aber ein gewiefte Mitschüler hat das damals mit Bleistift, Papier und logischen Verknüpfungen ausgerechnet. Wie müsste ich denn in Python vorgehen, um die Lösung zu finden, also mit "brute force"?
Gruss, siggi
Re: Warum boolsche Ergebnisse gemischt mit Integer?
Verfasst: Freitag 22. November 2013, 20:53
von BlackJack
@siggi: Am meisten wird zum Plotten wohl `matplotlib` verwendet. Das ist ein externes Modul und hat Numpy als Abhängigkeit. Damit kann man wesentlich mehr machen als einen Sinus zu plotten. Also ist das vielleicht ein wenig übertrieben.
Code: Alles auswählen
import numpy as np
from matplotlib import pyplot
def main():
x_values = np.linspace(0, 2 * np.pi, 100)
pyplot.plot(x_values, np.sin(x_values))
pyplot.show()
if __name__ == '__main__':
main()
Die erste Zeile in der `main()`-Funktion erstellt ein Array mit 100 Werten die von 0 bis 2π gehen — beide Endpunkte. Die `plot()`-Funktion möchte nämlich zwei Werte (zumindest wenn man die X-Achse in diesem Fall richtig beschriftet haben möchte): die X-Werte und die dazugehörigen Y-Werte.
Re: Warum boolsche Ergebnisse gemischt mit Integer?
Verfasst: Samstag 23. November 2013, 16:17
von siggi
@BlackJack: sieht nicht übel aus, aber jetzt muss ich erst mal herausfinden wie ich matplotlib auf mein Ubuntu 12.04/Windows 8 bekomme! Per default ist es jedenfalls nicht da. Vielleicht finde ich hier im Forum was.
Re: Warum boolsche Ergebnisse gemischt mit Integer?
Verfasst: Samstag 23. November 2013, 16:41
von BlackJack
@siggi: Also bei Ubuntu ist das über die Paketverwaltung kein Problem.
Re: Warum boolsche Ergebnisse gemischt mit Integer?
Verfasst: Samstag 23. November 2013, 17:03
von siggi
@BlackJack: danke BlackJack, Probleme gibt's auch mit Ubuntu. Für Python2 kein Problem, hatte ich kurz zuvor auch gefunden, aber für Python3 (das ich hauptsächlich benutze) habe ich es nicht gefunden.
Zu pyplot-python2: sieht ja ganz gut aus, mit Achsen und so. Allerdings tritt z.B. bei TAN das Problem auf, dass matplotlib die Funktion ziemlich unschön und ungenau plottet: wo es gegen unendlich geht, verschwindet die Funktion nicht am oberen bzw. unteren Bildrand und die senkrechten Linien sind rundweg falsch. Wer jetzt die Tangens-Funktion nicht kennt, hat eine falsche Vorstellung von der Funktion!
Mit Python-Tkinter habe ich das so einigermaßen hingekriegt, mit "Trick 17"*
Die Fragen sind also mit matplotlib:
1) wie kriege ich mit matplotlib eine Funktion, die gegen +/- unendlich geht, wenigstens bis zum oberen/unteren Fensterrand
2) wie vermeide ich die hässlichen senkrechten Linien?*
*: mit tkinter kriege ich das mit dem "unendlich aussehen" hin und ich lasse ich die "Asymptoten" einfach in anderer Farbe zeichnen, z.B. Hintergrundfarbe (unsichtbar) oder rot (wenn der Plot z.B. schwarz ist), dann sind's halt Asymptoten. Aber es ist schon eine Fitzelei
Edit: smallbasic plottet mit Punkten, da sieht man sofort, was Sache ist! Könnte ich denn mit pyplot in erster Annäherung statt mit Linien mit Punkten plotten? Wäre zwar nicht ganz das Wahre, aber immer noch besser als der jetzige witzige Linienplot!