Jump to content

Python, die verpasste Chance?


Recommended Posts

Am 6.7.2018 um 18:39 schrieb Silberdollar:

Auch mit Python lässt sich das Roulette nicht bezwingen

Am 6.7.2018 um 17:53 schrieb sachse:

, der Bastler glaubt, mit seinem erfolgreich

konstruierten Hilfsmittel auch das Roulette nun zu bezwingen.

Sieht jemand Ähnlichkeiten mit "Python"?

 

bearbeitet von wiensschlechtester
Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 2 Stunden schrieb wiensschlechtester:

Will noch wer die Endlosschleife intellektuell Überforderter fortsetzen?

(siehe obige Postings)

 

Nicht doch Wiener,

 

die paar Fragen stören doch (zumindest mich) nicht wirklich.

 

Was ich mir aber mehr wünschen würde, wären Rückmeldungen, an welchen Stellen bei Euch Schwierigkeiten auftreten.

Dann könnten die anderen evtl  weiterhelfen.

Noch schöner wären natürlich Eure Erfolgsmeldungen über bisher geschaffte Testprogrämmchen.

 

------------------------------X8----------------- wegen Postingverbot.....

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich sehe mich gezwungen meinen langen Beitrag zu zerstückeln, um das "forbidden..." zu umgehen:

 

 

Ich war heute zum Beispiel faul und habe nichts neues geschafft, weil ich am Strand war.

Vielleicht kann ich das noch etwas ausbügeln.

 

Wir brauchen immer wieder Permanenzen, seien sie nun schon bekannt, oder lägen sie noch in der Zukunft, egal.

Alle sollten bestimmte Eigenschaften haben, die für eine spätere Verwendung (Suche, Auswertung, Gruppierung etc)

wichtig sein könnten.

 

Eine essentielle und immer bekannte Eigenschaft ist der Ort der Entstehung.

Wobei der Ort nicht immer eine feste Stelle im Universum sein muss (RNG, Laptop von Hein-Blöd im Zug von Hamburg nach Hannover).

Link zu diesem Kommentar
Auf anderen Seiten teilen

Am 21.7.2018 um 22:48 schrieb Egoist:

Nachdem Teil 1 dankenswerterweise von der Forensoft angenommen wurde, gehts jetzt weiter.

 

In meinem letzten Codebeispiel hatte ich folgende Passage:


e = Entry(frame1, width=20, bg="yellow")
e.bind("<Return>", set_in)
e.pack(side=LEFT)

e ist das Eingabe-Widget vom Typ "Entry"

frame1 das übrgeordnete Layoutelement

da das kein Gridlayout war, kam e.pack Methode zum Einsatz, um es in Erscheinung zu bringen.

 

e.bind ruft jedesmal wenn die Return-Taste dort gedrückt wird, die Funktion "set_in" auf (Achtung hier immer ohne Klammern!).

 

Schreiben wir nun eine neue, einfache Version der Funktion "set_in":

 


def set_in(event):
    print(e.get())

Falls gewünscht, kann man e.get() in einem String zwischenspeichern und den dann an eine Liste anhängen usw...

Die Angabe von "event" als Parameter soll nötig zu sein, auch wenn wir den nicht auswerten (Hörensagen).

 

 

Viel Spass mit Python

wünscht Euch Ego

 

 

Hallo Ego,

dieses Beispiel aus dem Internet macht genau dasselbe wie Du:

 

import tkinter as tk
#import os

root = tk.Tk()

def on_change(entry):
    inp = entry.get()
    print (inp)

entry = tk.Entry(root)
entry.pack(side='left')
entry.bind("<Return>", on_change)
entry.grid(row=2, column=2)
entry.focus()


def entry_delete(evt):
    entry.delete(0, 'end')

entry.bind("<Return>", entry_delete)

root.mainloop()

1.

Bei "Run" erscheint auch ein kleines Fenster mit dem Entry-Feld darin.

Wenn man dort etwas eingibt und die Enter-Taste drückt, verschwindet die Eingabe, aber es wird nichts geprinted!

Die Übergabe an die on_change-Funktion klappt also nicht.

Wie schaut's bei Dir aus, wenn Du den obigen Test machst?

 

2.

Wenn ich genau dieselbe Chose in mein Testprogrämmchen übertrage, dann kommt bei entry.pack und entry.bind ein "SyntaxError: invalid character in identifier".

Bis zu dem unter 1. beschriebenen Effekt komme ich gar nicht erst, egal, ob die .bind-Funktion vor oder hinter die Entry-Definition gesetzt wird.

 

3.

Dein Vorschlag, mit 

combo_1['values'] = click_FillPermFiles()

in der "Fill Combo"-Callback-Funktion die Combobox zu füllen hat nicht geklappt, aber immerhin wurde die Funktion click_FillPermFiles sauber ausgeführt.

In der Combobox ist nichts angekommen, egal, ob sie vorbelegt oder jungfräulich angesprochen wurde.

Aber nach einigen Code-Umstellungen ging auch click_FillPermFiles nicht mehr

 

4.

Ich vermute, man muss sich gründlich mit mit den namespaces befassen, dann kommt man vielleicht einigen Fehlern auf die Schliche.

Zitat aus meiner Python-Bibel (1540 Seiten):

"Python's universal first-class object model and lack of type declarations make for an incredibly flexible programming language."

 

Jawohl, die einfachsten Sachen sind hier incredibly schwierig.

 

Viel Frust mit Python!

Albert

 

 

 

bearbeitet von Dr. Manque
Ergänzung
Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 19 Minuten schrieb Dr. Manque:

entry.bind("<Return>", entry_delete)

Hallo Albert,

 

wenn Du entry_delete aufrufst, dann löscht Du doch alles, sobald RETURN gedrückt wird...

 

vor 19 Minuten schrieb Dr. Manque:

Jawohl, die einfachsten Sachen sind hier incredeibly schwierig.

 

Viel Frust mit Python!

Albert

 

Man muss nicht emotional werden, wenn man eine neue Sprache lernt, sonst hat man bald gar kein Haar mehr auf dem Kopf.

Aber 4 Augen sehen bekanntlich immer mehr als 2...

 

Mich nervt mal wieder die Forensoft wie Hulle, denn mein Artikel ging nicht durch, das wichtigste fehlt noch...

 

 

Gruss vom Ego

bearbeitet von Egoist
Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 13 Minuten schrieb Dr. Manque:

2.

Wenn ich genau dieselbe Chose in mein Testprogrämmchen übertrage, dann kommt bei entry.pack und entry.bind ein "SyntaxError: invalid character in identifier".

Bis zu dem unter 1. beschriebenen Effekt komme ich gar nicht erst, egal, ob die .bind-Funktion vor oder hinter die Entry-Definition gesetzt wird.

 

 

Aus Deiner Beschreibung werde ich auf die Schnelle nicht schlau, lösche bitte alles aus Deinem Code, was überflüssig ist und poste dann alles.

Ich wette "Das Schwein werden wir schon schlachten, wenn ihm auch quiekt."

 

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 22 Minuten schrieb Dr. Manque:

4.

Ich vermute, man muss sich gründlich mit mit den namespaces befassen, dann kommt man vielleicht einigen Fehlern auf die Schliche.

Zitat aus meiner Python-Bibel (1540 Seiten):

 

Ich lese solche Bücher nicht, weiss aber, dass sie ganz hervorragende Nachschlagewerke sein können.

 

Es ist schon mindestens seit meinem letzten Staatsexamen (ewig her) so, dass man nicht alles wissen muss.

Man muss nur wissen, wo man es möglichst schnell nachschlagen kann.

Damals gab es noch kein Internet, wohl aber sehr gute Nachschlagewerke...

 

vor 22 Minuten schrieb Dr. Manque:

"Python's universal first-class object model and lack of type declarations make for an incredibly flexible programming language."

 

Jawohl, die einfachsten Sachen sind hier incredeibly schwierig.

 

Nicht selten sind wir das Problem und nicht der Computer.

Erst mit der Erfahrung (was nun mal dauert) kehrt sich dann das Verhältnis langsam um.

 

Wenn wir sagen können, das Problem ist der Computer, sind wir schon fast Experten.

 

 

Ich kann Dein Leiden sehr gut nachvollziehen, das kenne ich zur Genüge aus eigener Erfahrung.

Vielleicht ist es bei Dir noch schmerzhafter, weil Du sehr viel länger ohne Objekte gearbeitet hast.

Ich gestehe das Brimborium um Klassen selbst erst jetzt langsam zu begreifen, weil ich Python anwede.

 

Früher habe ich in C (ohne ++) meinen Strukturen Pointer auf Funktionen verpasst, damit ich sowas wie OOP hinkriegte.

Programmiererhölle...

 

Dagegen ist Python ein Zäpfchen

 

 

Gruss vom Ego

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hier wieder ein Fitzel meiner vorherigen Überlegungen. Die Forensoftware nervt wie Sau!

 

 

  • Optional könnten beliebig viele weitere Eigenschaften der  Permanenz festgehalten werden, wie
  • Art der Kugel
  • Kessel Marke, Typ, Baujahr, Seriennummer usw.
  • Wartungszustand
  • Wetterverhältnisse
  • Drehgeschwindigkeiten
  • Info ob Rechts- Linkslauf erfasst wurde
  • Fehlermeldungen
  • bisher unzuordenbare Informationen, wie Getränkepreise und/oder Scherze des Personals
bearbeitet von Egoist
Link zu diesem Kommentar
Auf anderen Seiten teilen

Noch ein Happen:

 

 

  • Praktischerweise erweitern sich die Eigenschaften einer Permanenz später jedes Mal, wenn sie jemand auswertet.
  • Dazu bräuchte es eine Liste, die in der Perm geführt wird, in die alles hineinkommt, was man später noch abrufen möchte.
    zB Gespielt nach SystemX ergab sich am Freitag folgender Kapitalverlauf, Einzelheiten: a, b, c als Unterliste
    oder der längste Ausbleiber war 23 und so weiter...
     
  • ----------------------
     
  • Standardauswertungen wie Trefferzahlen je Einzelplein, Treffer auf Rot oder Schwarz, was Euch einfällt.
  • Etwas ausgefallenere Standardauswertungen wie Anzahl 1er 2er... Xer Serien/Ausbleiber auf Rot, D3, TVS3, Cheval 1-2 ...
  • Indikatorverläufe wie Favorator und was es noch alles geben wird...

 

Das ist schon eine Menge Holz, aber man sollte im Hinterkopf behalten, es ist erst der Anfang einer Überlegung.

 

Prinzipiell gibt es Python her, dass man einer vordefinierten Permanenz-Klasse zur Laufzeit beliebige Elemente hinzufügt,

die dann nur in der einzelnen Permanenz gespeichert werden.

Da dürfte dann aber das Wegschreiben auf Massenspeicher und das Zurückladen richtig lustig werden.

 

 

Erstmal, Spass mit Python,

Gruss vom Ego

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 2 Stunden schrieb Dr. Manque:

Wie schaut's bei Dir aus, wenn Du den obigen Test machst?

 

Nunja, scheinbar hattest Du Dir noch einen ungültigen, nicht druckbaren Charakter eingefangen.

Solche Fehler kann das menschliche Auge einfach nicht finden, da muss dann der Verstand ran.

 

Natürlich lande ich hier auch auf dem Bauch, weil es Probleme in der Logik gibt.

 

Ich habe Dir mal den Code entwanzt, nun sollte es arbeiten, wie gewünscht.

Return gibt den eingegebenen String aus, jeder neue Buchstabe wird angehängt und auch ausgegeben.

Allerdings laggt hier mein Terminal, die Ausgaben werden zwischengepuffert und verspätet ausgegeben.

 

Zum Löschen des Eingabefeldes drücke ESC,

Dann sollte alles hinhauen, wie gewünscht.

 

import tkinter as tk


root = tk.Tk()

def on_change(event):       # Wichtig, alle Definitionen oben schreiben
    inp = entry.get()
    print (inp)

def entry_del(event):       # entry_delete fand ich, lag zu nah an entry.delete, umbenannt
    entry.delete(0, 'end')

entry = tk.Entry(root)
entry.pack(side='left')
entry.bind("<Key>", on_change)      # Sonst knallt es, wenn man sie später benutzen will.
entry.bind("<Escape>", entry_del)   # Man kann durchaus für alle Tasten individuelle Funktionen anbinden, toll...
entry.grid(row=2, column=2)
entry.focus()

root.mainloop()

 

bearbeitet von Egoist
Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 12 Stunden schrieb Egoist:

 

Nunja, scheinbar hattest Du Dir noch einen ungültigen, nicht druckbaren Charakter eingefangen.

Solche Fehler kann das menschliche Auge einfach nicht finden, da muss dann der Verstand ran.

 

Natürlich lande ich hier auch auf dem Bauch, weil es Probleme in der Logik gibt.

 

Ich habe Dir mal den Code entwanzt, nun sollte es arbeiten, wie gewünscht.

Return gibt den eingegebenen String aus, jeder neue Buchstabe wird angehängt und auch ausgegeben.

Allerdings laggt hier mein Terminal, die Ausgaben werden zwischengepuffert und verspätet ausgegeben.

 

Zum Löschen des Eingabefeldes drücke ESC,

Dann sollte alles hinhauen, wie gewünscht.

 


import tkinter as tk


root = tk.Tk()

def on_change(event):       # Wichtig, alle Definitionen oben schreiben
    inp = entry.get()
    print (inp)

def entry_del(event):       # entry_delete fand ich, lag zu nah an entry.delete, umbenannt
    entry.delete(0, 'end')

entry = tk.Entry(root)
entry.pack(side='left')
entry.bind("<Key>", on_change)      # Sonst knallt es, wenn man sie später benutzen will.
entry.bind("<Escape>", entry_del)   # Man kann durchaus für alle Tasten individuelle Funktionen anbinden, toll...
entry.grid(row=2, column=2)
entry.focus()

root.mainloop()

 

Hallo Ego,

 

ich wusste gar nicht, dass man mehrere Entry.bind-Funktionen definieren und auf einzelne Tasten legen kann.

Die Escape-Funktion ist sehr nützlich.

Für die Pleinzahlen-Eingabe ist entry.bind("<Return>", on_change) geeigneter. Das funktioniert auch im obigen Kontext.

 

In meinem Testprogramm erzeugt entry.bind("<Return>", on_change) einen SyntaxError: invalid character in identifier.

Der Editor schreibt schon vor dem "Run" einen roten Marker an die Zeile:

entry_bind.gif.f57b1b657b79940f0fca6b30dd3ea2c5.gif

 

Gott sei Dank kann ich aber die Permzahl in der Callback-Funktion "click_Ok" mit ...get() abfangen:

 

click_Ok_get.gif.ee3d7818f584316990127bda20122117.gif

 

Plötzlich funktioniert das Befüllen der Combobox!

Hier die ganz einfache Definition der Combobox:

 

146813871_defCombo.gif.533a8504e54cc19ddb517611d14c2c5b.gif

 

Und hier die ebenfalls ganz einfache Callback-Funktion:

 

1532245320_FillCombo.gif.c09695adb1919a6196503feb34d28ce3.gif

Genau entsprechend Deinem Vorschlag!!!

 

Die Liste "txtfiles" muss vorher gefüllt werden. Das geschieht mit diesem Callback:

 

460878676_Permfileslesen.gif.0a5e512602a78401cb4d129c2faad020.gif

 

"click_PermFilesLesen" funktioniert auch, wenn man "txtfiles = [] in die Funktion hineinnimmt.

Aber dann erkennt "click_FillCombo" die Liste "txtfiles" nicht mehr.

Wenn man aber "zz = 0" aus "click_PermFilesLesen" herausnimmt und sozusagen global macht, dann gibt es einen Syntaxfehler.

 

Es wird noch lange brauchen, bevor ich Python verstehe.

 

Als Nächstes liegen an:

1. Die Callback-Funktion für die Klicks in die Combobox.

2. Die Klassen "Coup" und "Perm".

 

Albert

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 21 Minuten schrieb Dr. Manque:

 

In meinem Testprogramm erzeugt entry.bind("<Return>", on_change) einen SyntaxError: invalid character in identifier.

Der Editor schreibt schon vor dem "Run" einen roten Marker an die Zeile:

 

Hallo Albert,

 

ich vermute es nur, weil ich nicht an Deinem Rechner sitze und hatte die Erklärung gestern schon geschrieben:

 

"Nunja, scheinbar hattest Du Dir noch einen ungültigen, nicht druckbaren Charakter eingefangen.

Solche Fehler kann das menschliche Auge einfach nicht finden, da muss dann der Verstand ran."

 

Wenn dem so ist, löschst Du einfach die kaputte Zeile komplett und schreibst sie neu hin.

Um das genauer zu untersuchen kannst Du auch die Zeile mit Copy auslesen und in einen HEX-Editor einfügen.

 

 

Ich fasse mich lieber kurz, wegen der "forbidden" Meldung...  Ff

bearbeitet von Egoist
Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 26 Minuten schrieb Dr. Manque:

Die Liste "txtfiles" muss vorher gefüllt werden. Das geschieht mit diesem Callback:

 

460878676_Permfileslesen.gif.0a5e512602a78401cb4d129c2faad020.gif

 

Ich finde das sehr unschön, denn txtfiles[] wird ja sonst gar nicht gebraucht.

Wenn Du daraus eine globale Variable machst und uU auch noch tausende Namen speicherst,

obwohl sie schon in Deiner ComboBox stehen, ist das Platzverschwendung.

 

Ausserdem sind globale Variable GIFT, die in komplexen Programmen später Probleme machen können.

 

Du hast bisher ein Entryfeld in dem Dein Pfad eingegeben wurde.

Sofort wenn Du dort RETURN drückst, sollte der Eintrag auf Gültigkeit geprüft werden.

Ist er gültig, kann sofort mit der Konstruktion der Combobox begonnen werden.

Das ist ein Abwasch, also nur eine Funktion.

 

vor 26 Minuten schrieb Dr. Manque:

Es wird noch lange brauchen, bevor ich Python verstehe.

 

Das glaube ich nicht. Es wird Dir in ein paar Tagen alles sehr viel leichter fallen.

 

Fortsetzung folgt...

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo nochmal,

 

hier die Überarbeitung von Alberts Formular, es sollte alles jetzt laufen.

 

# tkTest04.py
# basiert auf dem Code von Dr. Manque
# geändert am 23.07.2018
# Egoist www.roulette-forum.de

# ========================
# imports
# ========================
import tkinter as tk
from tkinter import ttk
import glob
import os

hinweis01 = ["(Bitte Pfad oben eingeben)"]
fehler01 = ["Pfad ist üngültig!"]

# Erzeuge eine Instanz
win = tk.Tk()

# Füge einen Titel hinzu
win.title("Combobox Übung")

# Enable resizing x-dimension, disable y-dimension
win.resizable(True, True)
win.geometry('800x300')

# Die Liste [txtfiles] initialisieren
'''
txtfiles = []                   # kann weg
txtfiles.append('file 1')       # die Defaultwerte führen ins Nichts
txtfiles.append('file 2')       # also auch weg
'''

# 2 Überschriftszeilen
label2 = ttk.Label(win, text="* User Interface für Roulette-Tests *")
label2.grid(column=1, row=0)
label3 = ttk.Label(win, text="*************************************")
label3.grid(column=1, row=1)

# Button Click Event Function
# Kopierstring für das Irectory-Eingabefeld: "D:\4All\Roulette\Edgar\Wien_F1_1992"
def read_Directory(path):
    txtfiles = []   # leere Liste der Dateinamen, wird nur lokal erzeugt!
    try:
        for filename in os.listdir(path):
            txtfiles.append(filename)
            print(filename)
    except:
        print('Not found: Dir=' + path)
        txtfiles = fehler01
    return txtfiles     # Dateiliste zurückgeben (ist leer für ungültige und leere Pfade).

def click_FillCombo(entry):
    fileliste = read_Directory(dirtext.get()) #ruft Dateiliste für aktuellen dirtext ab
    combo_1['values'] = fileliste  # Die Combobox befüllen
    combo_1.current(0)

def print_filename():
    fn = "Folgende Datei wurde ausgesucht: \""
    fn += dirtext.get()
    fn += combo_1.get()
    fn += "\""
    print(fn)

def callback(entry):    # universelle Ausgabe, als temporäre Debugfunktion
    print(entry)        # kann man überall einsetzen, wo Baustelle ist.


# Einen Button hinzufügen, neue Funktion, wählt den eingestellten Pfad aus dirtext und combo_1 aus
action1 = ttk.Button(win, text="Ok!", command=print_filename)
action1.grid(column=2, row=2)

# Label hinzufügen
label5 = ttk.Label(win, text="Permpool-Pfad:")
label5.grid(column=1, row=3)

# Eingabefeld für dirname
dirtext = ttk.Entry(win, width=40)
dirtext.grid(column=2, row=3)
dirtext.bind("<Return>", click_FillCombo)
# optional die Pfadeingabe schon während der laufenden Eingabe prüfen:
dirtext.bind("<Key>", click_FillCombo) # gibt eine Menge Müll auf der Console 


# Label hinzufügen
label4 = ttk.Label(win, text="Click on an entry:")
label4.grid(column=1, row=4)

# Eine ComboBox hinzufügen
combo_1 = ttk.Combobox(win, width=38, values=hinweis01)
combo_1.grid(column=2, row=4)
combo_1.current(0)
combo_1.bind("<<ComboboxSelected>>", callback)  # callback als Baustellenschild :)

# ==================
#  GUI-Start
# ==================
win.mainloop()

 

Viel Spass mit Python,

wünscht Ego

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 12 Stunden schrieb Dr. Manque:

Leider kann ich erst heute am Abend weitermachen, muss 150 m Hecken schneiden.

 

Ohje, armer Albert,

 

hätte ich das heute gemacht, bei voller Sonneneinstrahlung, müsste ich jetzt sicher in die "Eistonne".

 

vor 12 Stunden schrieb Dr. Manque:

Ich muss mir den Code genauer anschauen.

 

Es war nicht sonderlich ausgearbeitet, das ginge sicherlich eleganter.

Ein wichtiger Punkt ist der Verzicht auf globale Variablen, das erleichtert alles sehr.

 

Dann wurde die Funktion read_Directory() aus der Reihe der Click-Funktionen entfernt und selbständig gemacht.

Man übergibt jetzt einfach einen Path als String und erhält eine Liste der Dateien und Unterverzeichnisse zurück.

 

Die Clickfunktionen sind eher nur zum Eventhandling zu gebrauchen, weil sie immer bloss den Parameter (event) erhalten.

Ich würde diese möglichst kurz halten und die eigentliche  Arbeit in vollwertigen Funktionen mit Input und Output erledigen.

 

 

Fasse mich wieder kurz, wegen Forenproblemen.

Gruss vom Ego

 

bearbeitet von Egoist
Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 12 Stunden schrieb Dr. Manque:

- wenn auch anders als erwartet

 

Dein Konzept mit der ComboBox ist für den Durchschnittanwender auch eher überraschend.

Normal erwartet man links ein Dateimenü mit dem Eintrag "Lade Pool-Permanenz(en)..."

gefolgt von einem normalen Dateidialog, das geht mit tk bzw ttk durchaus auch.

 

Willst Du die Dateien länger im Blick behalten, böte sich ein "Treeview" an.

Darf ich fragen, was danach passieren soll?

 

Vermutlich wird die Datei erstmal eingelesen und weil Du sie quasi mit einem Mausklick austauschen kannst,

vermute ich weiter, dass die ganze Auswertung danach sofort erfolgt.

So könnte man mit der ComboBox die Auswertegrafiken fast wie im Daumenkino durchflippen.

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Am 23.7.2018 um 19:59 schrieb Egoist:

Hallo nochmal,

 

hier die Überarbeitung von Alberts Formular, es sollte alles jetzt laufen.

 


# tkTest04.py
# basiert auf dem Code von Dr. Manque
# geändert am 23.07.2018
# Egoist www.roulette-forum.de

# ========================
# imports
# ========================
import tkinter as tk
from tkinter import ttk
import glob
import os

hinweis01 = ["(Bitte Pfad oben eingeben)"]
fehler01 = ["Pfad ist üngültig!"]

# Erzeuge eine Instanz
win = tk.Tk()

# Füge einen Titel hinzu
win.title("Combobox Übung")

# Enable resizing x-dimension, disable y-dimension
win.resizable(True, True)
win.geometry('800x300')

# Die Liste [txtfiles] initialisieren
'''
txtfiles = []                   # kann weg
txtfiles.append('file 1')       # die Defaultwerte führen ins Nichts
txtfiles.append('file 2')       # also auch weg
'''

# 2 Überschriftszeilen
label2 = ttk.Label(win, text="* User Interface für Roulette-Tests *")
label2.grid(column=1, row=0)
label3 = ttk.Label(win, text="*************************************")
label3.grid(column=1, row=1)

# Button Click Event Function
# Kopierstring für das Irectory-Eingabefeld: "D:\4All\Roulette\Edgar\Wien_F1_1992"
def read_Directory(path):
    txtfiles = []   # leere Liste der Dateinamen, wird nur lokal erzeugt!
    try:
        for filename in os.listdir(path):
            txtfiles.append(filename)
            print(filename)
    except:
        print('Not found: Dir=' + path)
        txtfiles = fehler01
    return txtfiles     # Dateiliste zurückgeben (ist leer für ungültige und leere Pfade).

def click_FillCombo(entry):
    fileliste = read_Directory(dirtext.get()) #ruft Dateiliste für aktuellen dirtext ab
    combo_1['values'] = fileliste  # Die Combobox befüllen
    combo_1.current(0)

def print_filename():
    fn = "Folgende Datei wurde ausgesucht: \""
    fn += dirtext.get()
    fn += combo_1.get()
    fn += "\""
    print(fn)

def callback(entry):    # universelle Ausgabe, als temporäre Debugfunktion
    print(entry)        # kann man überall einsetzen, wo Baustelle ist.


# Einen Button hinzufügen, neue Funktion, wählt den eingestellten Pfad aus dirtext und combo_1 aus
action1 = ttk.Button(win, text="Ok!", command=print_filename)
action1.grid(column=2, row=2)

# Label hinzufügen
label5 = ttk.Label(win, text="Permpool-Pfad:")
label5.grid(column=1, row=3)

# Eingabefeld für dirname
dirtext = ttk.Entry(win, width=40)
dirtext.grid(column=2, row=3)
dirtext.bind("<Return>", click_FillCombo)
# optional die Pfadeingabe schon während der laufenden Eingabe prüfen:
dirtext.bind("<Key>", click_FillCombo) # gibt eine Menge Müll auf der Console 


# Label hinzufügen
label4 = ttk.Label(win, text="Click on an entry:")
label4.grid(column=1, row=4)

# Eine ComboBox hinzufügen
combo_1 = ttk.Combobox(win, width=38, values=hinweis01)
combo_1.grid(column=2, row=4)
combo_1.current(0)
combo_1.bind("<<ComboboxSelected>>", callback)  # callback als Baustellenschild :)

# ==================
#  GUI-Start
# ==================
win.mainloop()

 

Viel Spass mit Python,

wünscht Ego

 

Hallo Ego,

 

Also es funktioniert perfekt!

Wenn man den PermPool-Pfad in das Entry-Feld einkopiert hat und man drückt die Taste 'Enter', dann zack im Bruchteil einer Sek. ist alles fertig.

Die Combobox ist mit 348 Filenamen gefüllt.

Das Tolle ist, wenn man im Pfadnamen nur 1 Zeichen austauscht und der neue Pfadname ist gültig und man drückt 'Enter', zack, sind die neuen Filenamen in der Combobox.

Ohne dass man es codieren musste, wurde die Combobox vor der Neubeladung 'gecleared'.

Dann habe ich den Pfadnamen meines 3000er Pools eingegeben und nach 'Enter' zack, waren 3035 Filenamen in der Combobox - auch im Bruchteil einer Sekunde, Wahnsinn!!!

 

By the way: in "read_Directory (path)" habe ich "print(filename)' durch einen Zähler zz = zz + 1 ersetzt und den vor dem 'Return' geprinted - klappt!

 

Es ist schon ein komischer Mechanismus:

Die Enter-Taste löst über "dirtext.bind("<Return>", click_FillCombo)" den Aufruf von 'click_FillCombo(entry) mit 'entry' als Argument aus.

'click_fillCombo' ermittelt  mit 'fileliste = read_Directory(dirtext.get())' die Liste 'txtfiles'  und kopiert sie zur Liste 'fileliste'.

Mit 'combo_1['values'] = fileliste' wird dann die Combobox befüllt.

 

'callback' mit dem Parameter 'entry' bewirkt also, dass die Funktion mit dem Argument 'entry' wiederholt wird?

Kann man mehrere callback's mit verschiedenen 'entry'-Parametern anlegen?

 

Mannomann, ist Python geheimnisvoll und verzwickt!

 

Also vielen Dank, dass Du das Combobox-Problem gelöst hast!

 

Albert

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 5 Minuten schrieb Dr. Manque:

Dann habe ich den Pfadnamen meines 3000er Pools eingegeben und nach 'Enter' zack, waren 3035 Filenamen in der Combobox - auch im Bruchteil einer Sekunde, Wahnsinn!!!

 

 

Hallo Albert,

 

schmeiss mal den ganzen "print"-Krempel raus, der ist nur zum lernen und visualisieren drin.

Dann aktualisiert sich die Combo im Bruchteil einer Millisekunde. Selbst auf einem VanillaPC.

 

vor 9 Minuten schrieb Dr. Manque:

Ohne dass man es codieren musste, wurde die Combobox vor der Neubeladung 'gecleared'.

 

Jupp, es genügt, der Combo eine neue Liste unterzuschieben.

 

vor 12 Minuten schrieb Dr. Manque:

'callback' mit dem Parameter 'entry' bewirkt also, dass die Funktion mit dem Argument 'entry' wiederholt wird?

Kann man mehrere callback's mit verschiedenen 'entry'-Parametern anlegen?

 

Der Parameter (entry) ist Vorschrift. Er wird aus dem aufrufenden Objekt und dem dort definierten Trigger (zB "<Return>") generiert.

Da wird nix wiederholt, sondern einmal abgefeuert, wenn das Inputereignis erschienen ist.

 

Manche Ereignisse feuern aber kontinuierlich, wie eine durchgedrückte Taste, das kennst Du aus einem Texteditor.

Hier können aber auch  Sachen wie die Shift-Taste Dauerfeuer liefern.

 

Normal rufst Du zu jedem Bildschirmobjekt seine eigen Funktion auf, wenn RETURN oder was anderes gedrückt wurde.

Die Funktion callback hatte ich nur als Dummy eingetragen.

 

vor 22 Minuten schrieb Dr. Manque:

Mannomann, ist Python geheimnisvoll und verzwickt!

 

Das Gefühl wird sich bald legen, danach wirst Du die gewaltige Power erleben, die dahinter schlummert.

Bye, bye VBA, das war letztes Jahrhundert, selbst wenn Python genau so alt ist.

Aber Python war immer visionär und hat sich kontinuierlich weiter entwickelt.

 

 

 

 

 

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 3 Stunden schrieb Egoist:

 

Dein Konzept mit der ComboBox ist für den Durchschnittanwender auch eher überraschend.

Normal erwartet man links ein Dateimenü mit dem Eintrag "Lade Pool-Permanenz(en)..."

gefolgt von einem normalen Dateidialog, das geht mit tk bzw ttk durchaus auch.

 

Willst Du die Dateien länger im Blick behalten, böte sich ein "Treeview" an.

Darf ich fragen, was danach passieren soll?

 

Vermutlich wird die Datei erstmal eingelesen und weil Du sie quasi mit einem Mausklick austauschen kannst,

vermute ich weiter, dass die ganze Auswertung danach sofort erfolgt.

So könnte man mit der ComboBox die Auswertegrafiken fast wie im Daumenkino durchflippen.

 

Hallo Ego,

 

mit dem letzten Satz zeigst Du, dass Du das Konzept verstanden hast.

Ich hab's seit 12 Jahren in jedem Rouletteprogramm drin und nie einen Anlass gesehen, es durch ein Menü zu ersetzen.

 

Also der Klick auf ein Combobox-Entry bewirkt "Lade diese Permanenz".

Die Zahlen sollen in eine integer-Liste und gleichzeitig in eine Liste von Instanzen der Klasse 'COUP' gehen. Letztere Liste wäre dann eine Instanz der Klasse 'PERM'.

Das ist jetzt die nächste Aktion, die codiert werden muss.

Das Laden einer Perm (- wenn CC-Perm, dann bis zu 2.880 Coups -) dauert sicherlich nur Millisekunden.

 

Wenn eine Perm geladen ist, kann sie mit 1000 verschiedenen Verfahren verarbeitet werden. Das ist der "Permtest"

Die Combobox hat den Vorteil, dass man in einer Schleife über die Combobox-Entries "Pooltests" fahren kann.

 

Zum Simulationsgerüst gehört noch die Anzeige der Satzanweisungen, die von den verschiedenen Verfahren erzeugt werden und deren Abrechnung - pro Perm und pro Pool.

Und die Eingabe einer Zahl zur Erweiterung oder zum Aufbau einer Perm gehört auch noch zum Gerüst.

 

60 m Heckenschnitt habe ich heute geschafft. Morgen sind noch ca. 90 m zu machen.

 

Gute Nacht!

Albert

 

 

 

 

 

 

 

 

 

 

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 10 Minuten schrieb Dr. Manque:

Zum Simulationsgerüst gehört noch die Anzeige der Satzanweisungen, die von den verschiedenen Verfahren erzeugt werden und deren Abrechnung - pro Perm und pro Pool.

 

Bitte verzeihe mir, wenn ich nicht weiss, was bei Dir ein Pool ist.

 

So wie Deine Oberfläche strukturiert ist, bestünde ein Pool aus dem kompletten Inhalt eines Verzeichnisses.

Es gäbe keine Möglichkeit aus dieser Grundgesamtheit zu selektieren.

 

Die Anzeige einzelner Sätze würde ich weglassen, solange sie niemand ansehen will, denn graphische Ausgaben kosten Zeit.

Vielleicht interessiert nur die Kapitalkurve und die ganzen Einzelcoups werden ohne Beachtung zu erhalten gerendert.

Es genügt, Coups zu rendern, wenn man sie sehen will. Das geht sehr viel rascher (Faktor 100 oder mehr).

 

Ich würde einen Filepicker für mehrfache Dateiauswahl bevorzugen, wo man mit STRG-Klick alle Permdateien einzeln auswählen kann,

oder mit SHIFT-Klick ganze Serien etc.

 

 

vor 24 Minuten schrieb Dr. Manque:

Das ist jetzt die nächste Aktion, die codiert werden muss.

Das Laden einer Perm (- wenn CC-Perm, dann bis zu 2.880 Coups -) dauert sicherlich nur Millisekunden.

 

Von der Platte ja, je nach Performance Deiner Platte.

Holst Du die Daten live vom bossmediaserver dauert es natürlich.

 

Das Problem des Permanenzimportes reduziert sich auf das Finden des Anfangs und des Endes einer Permanenz,

dazwischen macht das Python schon locker von selbst.

 

Ich habe hier Permanenzen aus Wiesbaden, da kommt ein Kopf vor jedem Tag.

Danach kommen noch Tisch und Datum und ein fester string "N  Z  R" oder so...

das geht dann bis zu einer leeren Zeile.

"-- -- --" kommen zwischdrin als Handwechsel und Bemerkungen über Boni.

 

Nach der Leerzeile kommt evtl eine Auswertung und danach eine Tagwechsel-Markierung.

 

Stehen mehrere Tage hintereinander kommt dann wieder eine Kopf-Markierung.

Wir brauche also einen Parser...

 

 

 

 

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Kleines Codefragment:

import re

parsePermFile = ["Spielbank Wiesbaden", "Tisch:", "Datum:", "N  Z  R"]
sizePF = len(parsePermFile)
print(sizePF)


file = open('d:\\Temp\\Permanenzen_SBWB_2018-01-01_Tisch 2.txt')
lines = file.readlines()
print(len(lines))
file.close()

status = 0
x = 0
perm = []

for each in lines:
    if re.match(parsePermFile[status],lines[x]):
        temp = lines[x].split(" ")
        print(x, temp)
        perm.append(x)
    x += 1
sizePerm = len(perm)
print("Gefunden",sizePerm,"\n",perm)

 

Es setzt eine gültige Permanenzdatei vorraus und auch den angegebenen Pfad.

Dann separiert Python aber die Datei mit vielen Tagen in Zeilen, wo die Tage starten...

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Wie ist deine Meinung dazu?

Du kannst jetzt schreiben und dich später registrieren. Bereits registrierter Teilnehmer? Dann melde dich jetzt an, um einen Kommentar zu schreiben.
Hinweis: Dein Beitrag wird nicht sofort sichtbar sein.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung jetzt entfernen

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Neu erstellen...