Anwenderprogramm

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
haeuslermartin
User
Beiträge: 66
Registriert: Sonntag 21. April 2013, 10:12

hallo Gemeinde, eine kleine Anfängerfrage:
wenn ich ein kleines Anwenderprogramm geschrieben habe, (läuft bis jetzt nur in der shell), wie kann ich es machen, dass die Arbeit damit nicht verloren ist,
wenn ich das Programm beende? -wie halt bei jedem Schreib,- oder Grafikprogramm, -wenn ich am nächsten Tag weiterarbeiten will ... sollte die Arbeit
vom Vortag nicht weg sein ... :?: :K
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Indem du die Arbeit auf der Festplatte speicherst?

Mehr laesst sich bei den Infos leider nicht sagen ..
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

@haeuslermartin: dafür gibt es Dateien. Beim Beenden schreibst Du alles, was Du zum Weiterarbeiten brauchst, in eine Datei und beim Programmstart liest Du diese Datei. Je nach Daten, die Du hast, gibt es vielleicht schon passende Datenformate. Wenn Du keine großen Mengen an Binär-Daten hast, würde sich z.B. json als universelles Datenformat anbieten.
haeuslermartin
User
Beiträge: 66
Registriert: Sonntag 21. April 2013, 10:12

hallo, Anfänger meldet sich nochmal:
ich hab mir jetzt eine andere Lösung überlegt, die auch noch einen Vorteil hat.
Es handelt sich um die Aufzeichnung von Roulettezahlen der Kategorien manque und passe, (1 -18 und 19 -36)
- wenn ich am Anfang eine Reihe von Zahlen eingeben kann und im Anschluss daran dann einzelne Zahlen, kann ich erstens mal
eine Reihe von gefallenen Zahlen beobachten, und die dann insgesamt eingeben, - und- ich kann bequem an einem anderen Tag
die history nachvollziehen (wenn ich die Zahlen vom Vortag noch habe) (der Zufallsreihe ist es nämlich egal, von welchem Tag die Zahlen sind ...)
der Grafikteil wurde mit turtle gemacht, mit tkinter bin ich noch nicht so fit ..
die erste Kurve stellt den "Trendverlauf " dar, die zweite ist eine ganz traditionelle Art der Buchführung von Roulettespielern.

das Programm:

Code: Alles auswählen

from math import ceil
from itertools import accumulate
from turtle import*

#Buchführung für manque(1 bis 18) und passe(19 bis 36) beim Roulette
#mit turtle-Grafik

setup(width=1.0, height=0.5, startx=None,starty=None)
screensize(canvwidth=1620, canvheight=200)
speed(0)
color("blue")

jack=Turtle()
jack.hideturtle()
jack.color("black")
jack.speed(0)

tina=Turtle()
tina.hideturtle()
tina.color("red")
tina.speed(0)

olga=Turtle()
olga.hideturtle()
olga.color("blue")
olga.speed(1)

up();home();goto(800,0);down();back(1550);
jack.up();jack.home();jack.goto(800,-150);jack.down();jack.back(1550);
    
def quadrat_a():
    up()
    right(90)
    fd(9)
    left(90)
    down()
    fillcolor("black")
    begin_fill()
    for i in range (4):
        fd(8)
        left(90)
    up()
    fd(10)
    down()
    end_fill()

    
def quadrat_b():
    up()
    left(90)
    fd(9)
    right(90)
    down()
    fillcolor("black")
    begin_fill()
    for i in range (4):
          fd(8)
          left(90)
    up()
    fd(10)
    down()
    end_fill()


def quadrat_c():
    jack.up()
    jack.sety(s)
    jack.down()
    jack.fillcolor("black")
    jack.begin_fill()
    for i in range (4):
          jack.fd(8)
          jack.left(90)
    jack.up()
    jack.fd(10)
    jack.down()
    jack.end_fill()   

#der erste Block des Programmes:
#Zuerst eine beliebig lange Reihe von Roulettezahlen, die grafisch dargestellt werden
#Zahlen ohne Komma mit Leerzeichen eingeben

print()
alle = list([]) 
for i in input("number: ").split(): #eine Reihe von Roulettezahlen!
        alle.append(int(i))

if alle[0]<19:
    quadrat_a()
else:
    up();right(90);fd(8);left(90);down();
    quadrat_b()
 
if alle[0]<19:
    s = -160
    quadrat_c()
    
else:
    s = -148
    quadrat_c()


print()
allezahlen =len(alle)
print('das sind ', allezahlen,"zahlen")
print()

for i in alle[1:]:
    i = i
        
    if i <19:
        quadrat_a()
    else:
        quadrat_b()

for i in alle[1:]:
    if  i<19:
        s = -160 
    else:
        s = -148 
    quadrat_c()

translate = list(map(lambda x: ceil(x/18), alle))
print("manque/passe: ",translate)    
print()    
passe=[] #die Prozente
counted = accumulate(1 if m == 2 else 0 for m in translate)
for i, (n, translate) in enumerate(zip(translate, counted), start=1):
    passe.append(translate)
print("passe: ",passe)
print()


tina.up();tina.goto(-746,0);tina.down();
for i,v in enumerate(passe):
    tina.goto(-746+i*10, v*3)    

trans = list(map(lambda x: ceil(x/18), alle))

manque=[]

counted = accumulate(1 if m == 1 else 0 for m in trans)
for i, (n, trans) in enumerate(zip(trans, counted), start=1):
    manque.append(trans)
print("manque: ",manque)
print()
print(len(manque))
   
olga.up();olga.goto(-746,0);olga.down();
for i,v in enumerate(manque):
    olga.goto(-746+i*10, v*3)

    

#der zweite Block des Programmes:
#ab hier sollen die Zahlen einzeln hinzugefügt und die Grafik ergänzt werden!!!


    
def main():
        
    global alle

    for i in input("number: ").split(): #eine einzelne Zahl!!
        alle.append(int(i))
        i = i
        
    if i <19:
        quadrat_a() 
    else:
        quadrat_b() 


    global s  #set(y), positionierung der turtle
    for i in alle[1:]:
        if  i<19:
            s = -160
        else:
            s = -148 
    quadrat_c() 
    
    print("das sind",len(alle),"Zahlen: ",alle) #die gefallenen Roulettezahlen
    
    print()
    
    translate = list(map(lambda x: ceil(x/18), alle))
    print("manque/passe: ",translate)#die gefallenen Zahlen, nach passe oder manque übersetzt
    print()

    passe = [] #fortlaufende Anzahl von passe (2 in translate)
    
    counted = accumulate(1 if m == 2 else 0 for m in translate)
    for i, (n, translate) in enumerate(zip(translate, counted), start=1):
        passe.append(translate)
    print("passe: ",passe)
    
    tina.up();tina.goto(-746,0);tina.down();
    for i,v in enumerate(passe):
        tina.goto(-746+i*10, v*3)
        
     
    print()


    trans = list(map(lambda x: ceil(x/18), alle)) 
    print()

    manque = [] #fortlaufende Anzahl von manque (1 in trans)
    
    counted = accumulate(1 if m == 1 else 0 for m in trans)
    for i, (n, trans) in enumerate(zip(trans, counted), start=1):
        manque.append(trans)
    print("manque: ", manque)
 
    olga.up();olga.goto(-746,0);olga.down();
    for i,v in enumerate(manque):
        olga.goto(-746+i*10, v*3)
        
    print()
    print()
    print()
    
    main()
    

    
main()
jetzt kommt die Fehlermeldung in der shell:

>>> ================================ RESTART ================================
>>>

number: 3 25 34 19 6 9 29

das sind 7 zahlen

manque/passe: [1, 2, 2, 2, 1, 1, 2]

passe: [0, 1, 2, 3, 3, 3, 4]

manque: [1, 1, 1, 1, 2, 3, 3]

7

number: 12

Traceback (most recent call last):
File "C:/Users/schnuggler/Desktop/Roulette/Arbeit/m_p_nominalversuch_4.py", line 244, in <module>
main()
File "C:/Users/schnuggler/Desktop/Roulette/Arbeit/m_p_nominalversuch_4.py", line 185, in main
if i <19:
TypeError: unorderable types: str() < int()
>>>

der erste Block wird abgearbeitet, beim zweiten der input abgelehnt, es ist doch das gleiche list objekt,
und ebenfalls .append(int()), -ich glaub ich hab ein Brett vorm Kopf ...
lasst es mal bei Euch laufen, wahrscheinlich übersehe ich da konsequent etwas einfaches ... :K :K :)
Zuletzt geändert von Anonymous am Montag 8. Juni 2015, 13:00, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Code-Tags gesetzt.
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

@haeuslermartin: du hast jetzt schon 32 Beiträge geschrieben und noch nicht die Code-Tags gefunden ?!?

Schau Dir halt mal an, wohler das "i" kommt. Die Anweisung zwei Zeilen darüber ist ziemlich sinnfrei.
Benutzeravatar
bwbg
User
Beiträge: 407
Registriert: Mittwoch 23. Januar 2008, 13:35

Eine main-Funktion ist schonmal ein guter Anfang aber alles in Allem ist das Programm ein ziemliches Geschwurbel.

Du solltest
  • keinen Code auf Modulebene ausführen. Außer Konstanten, Funktionen, Klassen und der Bedingung aus dem main-Idiom[1] sollte nichts auf Modulebene ausgeführt werden.
  • keine globalen veränderlichen Objekte ("Variablen") verwenden. Das Schlüsselwort global brauchst Du nicht.
Dies hat den Vorteil, dass Du die Teile (Funktionen, Klassen, etc.) aus Deinem Programm separat z. B. im interaktiven Interpreter testen kannst. Das Schlüsselwort import führt alle Anweisungen im importierten Modul aus. In Deinem Fall würde das Programm vollständig ausgeführt werden, auch wenn Du nur eine einzige Funktion testen wolltest.

Logik und Ein-/Ausgabe sollten getrennt werden. Definiere sinnvolle Funktionen für Deine numerische Akrobatik (Statistik), z. B. für die prozentuale Verteilung der Zahlen in den verschiedenen Kategorien. Das gleiche gilt für die Abfrage von Werten vom Benutzer. Turtle solltest Du erstmal verbannen und das Ganze ausschließlich auf der Konsole lösen. Wenn Du sinnvoll getrennt hast, lässt sich die Präsentation mit Turtle oder auch z. B. mit tkinter später nachschieben.

Du verwendest auch magic-literals (1, 2, 3, 4) bei denen nicht sofort ersichtlich ist, was diese bedeuten. Hier böten sich zum Beispiel die Eingangs genannten Konstanten an.

Sinnvoll benannte Funktionen sind besser als zusätzliche Kommentare:

Code: Alles auswählen

def is_zero(x):
    return x == 0

def is_manque(x):
    return 0 < x <= 18
    
def is_passe(x):
    return 18 < x <= 36
[1]Main Idiom:

Code: Alles auswählen

def main():
    pass

if __name__ == '__main__':
    main()
"Du bist der Messias! Und ich muss es wissen, denn ich bin schon einigen gefolgt!"
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

@haeuslermartin: Wenn Du tatsächlich einen statistisch signifikanten "Trendverlauf" ermitteln kannst, dann sag uns doch bitte, wo der betreffende Roulette-Tisch steht. Aber ich tippe schon mal: Rot und Schwarz langfristig beide unter 50% :)
Benutzeravatar
bwbg
User
Beiträge: 407
Registriert: Mittwoch 23. Januar 2008, 13:35

Langfristig werden sich die Treffer (bei einem idealen Roulette-Tisch) auch bei Passe/Manque bei rund 48,65% einpendeln. ;)
"Du bist der Messias! Und ich muss es wissen, denn ich bin schon einigen gefolgt!"
haeuslermartin
User
Beiträge: 66
Registriert: Sonntag 21. April 2013, 10:12

mit "Trendverlauf" ist nur der durch Ungleichverteilung bei endlichen Ereignisreihen entstehende Verlauf gemeint, Gleichverteilung findet nur im Unendlichen statt.
Es ist ja ein bekannter Irrtum, dass Ergebnisse, die lange in der Minderzahl waren, bald wieder vermehrt auftauchen, weil es einen Ausgleich geben muß.
Kann es, müssen aber erst im Unendlichen...
Ein Vorteil für den Spieler ergibt sich aus dieser Tatsache nicht, weil er den Verlauf nie vorhersagen kann.
Aber eine Art von "Buchführung", die zumindest anzeigt, wohin die Reise bis zum letzten Spiel gegangen ist ...

Ich habe das Programm eben mit den einfachen Mitteln gemacht, die mir zur Verfügung standen, ich weiß, daß das eleganter geht, aber immerhin funktionieren
die beiden Blöcke für sich einwandfrei und auch die grafische Darstellung, ich wollte jetzt nur die Eingabe einer Reihe von Zahlen mit der Eingabe von
einzelnen Zahlen kombinieren...
haeuslermartin
User
Beiträge: 66
Registriert: Sonntag 21. April 2013, 10:12

nochmal "Langfristig werden sich die Treffer (bei einem idealen Roulette-Tisch) auch bei Passe/Manque bei rund 48,65% einpendeln" ist nicht g a n z richtig,
es kann durchaus sein, dass irgendwann kurzfristig genau dieses Verhältnis ensteht, -um sich gleich darauf wieder zu ändern- es kann aber genauso gut sein, dass über 10.000 Ereignisse "passe" 300 mal öfter fällt als "manque", -zwingend stellt sich das genannte Verhältnis eben erst in einer unendlichen Reihe ein.

zum Code:
meint Ihr:

for i in input("number: ").split():
alle.append(int(i))
i = i ????????????????????????

wen ich das weglasse, muss ich die nachfolgenden Bedingungen einrücken, dann fängt er aber jedesmal von vorne an, da ich ja durch die funktion main()
schon eine Rekursion habe ..
im ersten Block funktioniert das gleiche einwandfrei ...
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

@haeuslermartin: Du mußt "was" einrücken? Einrückungen sind in Python essentiell. Die ergibt sich aus der Logik. Für mich sieht der Code so aus, als ob Du den Überblick verloren hättest. Viel kopierter Code, einiges wird mehrfach gemacht. Versuch mal den Code besser zu strukturieren. Füge Funktionen ein, die die Logik in sinnvolle Blöcke strukturiert. Auf Modulebene sollte kein Code stehen. Doppelungen sollten nicht mehr vorkommen, globale Variablen erst recht nicht.
BlackJack

@haeuslermartin: Ähm doch der Satz ist richtig, Du wiederholst das geschriebene dem Du dann gleich selbst ”wiedersprichst” im Grunde dann nur noch mal mit anderen Worten ohne tatsächlich zu wiedersprechen. Langfristig wird sich das auf den Wert einpendeln. Und nein da muss man nicht tatsächlich bis unendlich gehen. Einpendeln != exakt und dauerhaft den Wert haben. Es wird sich dem Wert nähern und immer unwahrscheinlicher davon deutlich abweichen.

Edit: Die Rekursion von `main()` ist übrigens ein Programmfehler denn das wird zwangsläufig zum Programmende mit einer Ausnahme führen. Rekursionen sollte/darf man in Programmiersprachen die keine „tail call optimization” garantieren nicht einfach so als Ersatz für einfache Schleifen verwenden.
haeuslermartin
User
Beiträge: 66
Registriert: Sonntag 21. April 2013, 10:12

moderator, Du bringst da was durcheinander, die prozentuale Entwicklung gleicht sich bis ins Unendliche immer mehr den Mittelwerten an, das ist richtig, aber die n o m i n a l e Abweichung eben nicht, da kann die "Schere" immer weiter auseinander driften, das ist ganz einfache Mathematik, je länger die Reihe ums... kleiner der Quotient , aber im Verhältnis dazu immer grösser der nominale Unterschied, und der ist es, den der Spieler in der Praxis im Auge hat, und den er mit dem prozentualen verwechselt, - weshalb er so oft mit dem Einsatz auf "zurückliegende" Chancen scheitert, im Programmieren bin ich Anfänger, aber von Stochastik versteh ich ein bisschen was.

was ist denn so falsch daran, wenn das Programm einfach abgebrochen wird, ist doch für den Anwender egal, -wenn ich wieder damit arbeiten will, dann rufe ich es wieder auf und fange damit wieder an, kein Problem, oder???
ich habe keine Ahnung, was Programme mit „tail call optimization” sind ich habe ein Lehrbuch "python for kids" und mit den Sachen, die da drin stehen, versuche ich ein Programm zu basteln, nicht nach den goldenen Regeln der Handwerkskunst, sondern learning by doing- Hauptsache ich habe erstmal ein Programm das mir das Ergebnis liefert, das ich haben will !!! Wenns funzt, freue ich mich erst mal, auch wenn mir Experten gleich mein Unvermögen vorhalten...

wie soll ich denn, in Gottes Namen, ohne Rekursion eine unbestimmte Anzahl Wiederholungen von input und Anschluss an das vorhergehende Ergebnis erreichen??

holt mich mal da ab, wo ich bin...
Benutzeravatar
bwbg
User
Beiträge: 407
Registriert: Mittwoch 23. Januar 2008, 13:35

haeuslermartin hat geschrieben:was ist denn so falsch daran, wenn das Programm einfach abgebrochen wird, ist doch für den Anwender egal, -wenn ich wieder damit arbeiten will, dann rufe ich es wieder auf und fange damit an, kein Problem, oder???
Es ist ein klassischer Bug. Wenn Du einen Programmteil wiederholen möchtest, verwende Schleifen (while).

Wie bereits erwähnt, besitzt Python keine tail-call-optimization (TCO), bietet aber Schleifen, um entsprechende Verhalten zu ermöglichen. Haskell, als Gegenentwurf, besitzt keine Schleifen, kann jedoch TCO und ermöglicht somit Endlosrekursionen.
"Du bist der Messias! Und ich muss es wissen, denn ich bin schon einigen gefolgt!"
BlackJack

@haeuslermartin: Ich denke nicht das ich da etwas durcheinander bringe und in der Praxis ist das Problem das Spieler sich überhaupt diese Art von Zahlenreihen anschauen weil sie irgendeine diffuse Hoffnung haben es gäbe so etwas wie Karma. Der einzige Grund sich das anzuschauen währe ein tatsächlich manipulierter Tisch, ansonsten sollte man einfach mit der entsprechenden Wahrscheinlichkeit rechnen ohne sich konkrete zurückliegende Ereignisse anzuschauen weil die keinen Einfluss auf die folgenden Ereignisse haben.

Falsch an dem Programm ist es mittendrin ungeplant mit einer Ausnahme abbricht. Das ist wie gesagt schlicht ein Fehler. Stell Dir mal vor eine Textverarbeitung bricht einfach mitten während Du an einem Text arbeitest ohne zu speichern ab und der Autor sagt Dir das sei doch kein Problem, starte das Programm einfach neu. Ich würde so etwas nicht benutzen wollen.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

haeuslermartin hat geschrieben:wie soll ich denn, in Gottes Namen, ohne Rekursion eine unbestimmte Anzahl Wiederholungen von input und Anschluss an das vorhergehende Ergebnis erreichen??

holt mich mal da ab, wo ich bin...
Weil es wohl unterging: Mit einer Schleife. Konkret werden die Zeilen 223-227 zu (sofern ich nichts uebersehen habe):

Code: Alles auswählen

while True:
    main()
Nur da dein Programm nun tatsaechlich endlos laeuft, solltest du dir ueber eine Abbruchbedingung Gedanken machen.
haeuslermartin
User
Beiträge: 66
Registriert: Sonntag 21. April 2013, 10:12

hallo blackjack,

ich glaub Dir als Experten das natürlich mit dem Fehler und werde mich dahingehend damit befassen.
obwohl: ich hab das schon hundertemal getestet und es hat noch nie vorzeitig abgebrochen ...

aber nochmal : die Seite eines Würfels hat die Wahrscheinlichkeit 1/6, das bestimmt ihr Erscheinen in exakt zwei Fällen, nämlich dem Einzelereignis
und der unendlichen Reihe und nennt sich Gleichverteilung. dazwischen gibt es permanent Abweichungen davon, mit denen es der Spieler zu tun hat.
Er hat es mit einer endlichen Reihe zu tun, und in der gibt es keine Gleichverteilung, sondern nur Ungleichverteilung, dh. Binominalverteilung, (Binominalfunktion), im Fall von Lottozahlen z.B. eine hypergeometrische...Natürlich bringt das keinen Vorhersagevorteil, aber mit "Karma" hat es auch nichts zu tun ...

Aber eigentlich interessiert mich hier nur Python, nicht das Glücksspiel, das ist nur Aufhänger für ein Programmchen mit didaktischem Zweck.

ich beschäftige mich auch nicht täglich damit, es ist nur aus Spaß und Freude, ein bisschen wie Schach, Top-Entwickler will ich mit meinen 64 Jahren
nicht mehr werden ...

Warum sollte man keine globale Variable verwenden? in "python for kids" wird z.B. auf den Seiten 113, 114 die globale Variable "seite" eingeführt,
um sie vor dem Aufruf von dreieck() definieren zu können, da steht aber nicht, warum man das nicht machen sollte??
haeuslermartin
User
Beiträge: 66
Registriert: Sonntag 21. April 2013, 10:12

hallo cofi, danke für den Tipp!
BlackJack

@haeuslermartin: Ich kenne das Buch nicht, aber wenn das Anfängern tatsächlich ``global`` erklärt und das dann auch noch verwendet wird, würde ich mal sagen das ist kein Buch das ich empfehlen würde. Globale Variablen machen Programme schwer durchschaubar weil zwischen Funktionen Abhängigkeiten bestehen die nicht an der Schnittstelle sichtbar sind. Man muss dafür die ganze Funktion kennen und auf Programmebene alle Funktionen im Detail um zu verstehen wie der Programmablauf funktioniert. Solche Funktionen sind schlechter testbar und wiederverwendbar.
Antworten