Projekterstellung mit GUI

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.
matze1708
User
Beiträge: 112
Registriert: Dienstag 12. März 2019, 11:49

__blackjack__ hat geschrieben: Donnerstag 21. März 2019, 10:30 @matze1708: Das schliessen der Datenbankverbindung muss da stehen wo Du weisst das Du sie nicht mehr brauchst. Und wenn man ``with`` verwendet, üblicherweise in der Funktion/Methode in der die Verbindung auch hergestellt wird. Du hattest es ja dort bereits in einem ``finally`` stehen.
Das wäre doch dann am Ende der main() weil, da ab da brauche ich es ja nicht mehr. Bis sich ein User neu anmeldet.
__blackjack__ hat geschrieben: Donnerstag 21. März 2019, 10:30 Die Abfrage der Benutzerdaten von der Datenbank wäre eine eigene Funktion. Denn das ist ja der Teil der bei Terminal und GUI gleich bleibt. Die Anzeige selbst ist unterschiedlich. Beim Terminal verwendet man ``print()`` dafür. Bei einer GUI könnte man die Daten beispielsweise in einem Drop-Down-Menü zur Auswahl zur Verfügung stellen.
Also muss ich das Ergebnis aus

Code: Alles auswählen

def kaliber_anzeigen(db, stand_id):
    print()
    with closing(db.cursor()) as cursor:
        cursor.execute("""Select tbl_Kaliber.ID, tbl_Kaliber.KaliberLang
            From tbl_Stand INNER JOIN tbl_Kaliber ON tbl_Stand.ID = tbl_Kaliber.StandID
            Where tbl_Stand.ID = %s""", (stand_id,))
        for row in cursor:
            print( row["ID"], row["KaliberLang"])
sprich den Cursor execute in eine Variable schreiben und die weiterverwenden in der Anzeige. Oder reicht das ab dem Bereich for row etc.
__blackjack__ hat geschrieben: Donnerstag 21. März 2019, 10:30 Wenn Du die Benutzereingabe auf gültige Werte einschränken möchtest, müsstest Du Funktionen bereit stellen die Dir die Möglichkeiten von der Datenbank abfragen und entsprechen die Eingabe überprüfen. Du machst das ja jetzt bereits zum Teil, nämlich ob die Eingabe eine Zahl ist. Da muss dann noch dazu kommen ob es eine Zahl aus einer Menge von vorgegebenen Zahlen ist. Und die bekommst Du ja mit der Abfrage der Kaliber.
Genau diese Menge an Zahlen muss ich verarbeiten. Diese Frage stelle ich mir gerade.
Habe dazu erstmal die tbl_Stand erweitert mit der Maximalen Anzahl der Plätze. Somit kann niemand Platz 30 eingeben wenn es nur 20 gibt.
Dann hatte ich übeleget über ein SELECT zu schauen welche Plätze aktuell belegt sind. Das kann ich ja ausgeben über for row, aber ich muss das ja dann in eine Variable packen oder? Die row´s sind ja Vertikal und die Variable müsste ja Horizontal sein. Da habe ich noch nix zu gefunden wie ich das "drehe"
__blackjack__ hat geschrieben: Donnerstag 21. März 2019, 10:30
Bei den Rückgaben von den Funktionen kannst Du Listen mit den Datenbankergebnissen zurück geben, oder Du fängst an hier zwischen der Datenhaltung und Objekten im Programm zu trennen und die Ergebnisse ”umzupacken”, beispielsweise in `collections.namedtuple` oder Klassen, damit das alles mehr nach Python aussieht und man nicht die Wörterbücher mit den unpytonischen Schlüsselnamen von der Datenbank hat. Alternativ könnte man die Spaltennamen in der Datenbank an die Python-Konventionen anpassen und die Ergebnisse in `addict.Dict`-Objekte verpacken. Oder sich mit dem SQLAlchemy-ORM beschäftigen.
Ok hier erklärst du das ich das auf Listen Element umsetzten kann.

Aber was mache ich mit diesem colections.namedtuple? Für das addict.Dict fällt mir gerade noch der Verstand.
matze1708
User
Beiträge: 112
Registriert: Dienstag 12. März 2019, 11:49

Ich habe da mal weiter gespielt:

Code: Alles auswählen

def freierPlatz(db, stand_id):
    with closing(db.cursor()) as cursor:
        cursor.execute("""SELECT Platz FROM tbl_Schiesstand WHERE Ende is Null And StandID =%s """, (stand_id))
        return list(cursor)
Würde mir jetzt rein vom SQL die Plätze ausgeben die belegt sind.

nur das list(Cursor) ist mir nicht so recht.

Da kommt dann sowas raus:
Traceback (most recent call last):
File "schuetzeanlegen.py", line 208, in <module>
main()
File "schuetzeanlegen.py", line 191, in main
print(freierPlatz(db, stand_id))
File "schuetzeanlegen.py", line 95, in freierPlatz
cursor.execute("""SELECT Platz FROM tbl_Schiesstand WHERE Ende is Null And StandID =%s """, (stand_id))
File "/usr/local/lib/python3.5/dist-packages/MySQLdb/cursors.py", line 199, in execute
args = tuple(map(db.literal, args))
TypeError: 'int' object is not iterable
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@matze1708: `collections.namedtuple` oder `addict.Dict` wären dazu da um aus Wörterbüchern mit festen Schlüsseln (Anzahl und Wert) Werte zu machen die eigene Datentypen mit Attributen und in Python üblicher Namensgebung sind. `Dict` wäre da eher ”Kosmetik”/syntaktischer Zucker und man müsste auch die Datenbankfelder umbenennen, damit das funktioniert/Sinn macht. Im Moment hantierst Du mit Wörterbüchern die feste Datensätze darstellen. Das ist eigentlich nicht der Einsatzzweck für Wörterbücher. Die verwendet man eher wenn die Anzahl der Schlüssel/Wert-Paare dynamisch sind, und alle im Grunde die gleiche Bedeutung haben. Als Datensätze eigentlich nur für Zwischenergebnisse an den ”Rändern” des Programms, wo die Daten das Programm betreten oder verlassen. Also hier zum Beispiel das sie in der Form das Programm über die Datenbankabfrage betreten.

Du musst keine Variablen ”drehen” sondern Teile aus einer Sequenz in eine neue Sequenz oder Menge heraus ziehen. Du hast ja beim Kaliber für die Auswahl beispielsweise Paare von IDs und Beschreibung zur ID und brauchst nur die IDs. Ich weiss jetzt nicht was Du denkst was Du da suchst, aber das ist eine Schleife über die Paare in der man sich dann die IDs nimmt und in einer anderen Datenstruktur speichert. Entweder tatsächlich eine Schleife oder eine „list comprehension“ oder „set comprehension“.

Warum ist Dir das `list()` nicht recht? An der Stelle könnte man natürlich schon die Platznummern aus den Wörterbüchern holen die ja jeweils nur ein Element enthalten. Versuch Dich bei den Rückgabewerten schon mal so ein bisschen von der Datenbank zu trennen und zu überlegen was denn Deine Programmlogik da eigentlich braucht. Das wäre eine Sequenz oder Menge von freien Platznummern. Die sollte man dann auch liefern und nicht dem Aufrufer das Auspacken aus den Wörterbüchern aufbürden.

Der Funktionsname entspricht übrigens nicht den Konventionen. Schreibweise wäre `freier_platz`. Und inhaltlich sollten Namen für Funktionen und Methoden eine Tätigkeit beschreiben, also `hole_freien_platz()`. Das holt aber gar nicht die freien Plätze sondern die belegten. Und *Plätze* – Mehrzahl. Also `hole_belegte_plaetze()`. Ich würde auch noch so pedantisch sein und `hole_belegte_platznummern()` schreiben, damit klar ist, das es sich bei den Plätzen um Nummern handelt und nicht um komplexere Objekte die jeweils einen Platz beschreiben. Also *eigentlich* auch in Englisch – `get_occupied_place_numbers()`.

Code: Alles auswählen

def get_occupied_place_numbers(db, range_id):
    with closing(db.cursor()) as cursor:
        cursor.execute(
            'SELECT Platz FROM tbl_Schiesstand'
            ' WHERE Ende IS NULL AND StandID = %s',
            (range_id,)
        )
        return [row['Platz'] for row in cursor]
Die Ausnahme bekommst Du weil Du das Komma beim zweiten Argument von `execute()` vergessen hast, damit das ein Tupel wird und nicht einfach nur eine Zahl ist.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
matze1708
User
Beiträge: 112
Registriert: Dienstag 12. März 2019, 11:49

Warum ist Dir das `list()` nicht recht? An der Stelle könnte man natürlich schon die Platznummern aus den Wörterbüchern holen die ja jeweils nur ein Element enthalten. Versuch Dich bei den Rückgabewerten schon mal so ein bisschen von der Datenbank zu trennen und zu überlegen was denn Deine Programmlogik da eigentlich braucht. Das wäre eine Sequenz oder Menge von freien Platznummern. Die sollte man dann auch liefern und nicht dem Aufrufer das Auspacken aus den Wörterbüchern aufbürden.
Weil ich wahrscheinlich das falsche dazu gefunden habe und es dann auch noch falsch zusammen gebaut habe.... :-(

Ich müsste das doch dann umrechnen, um noch die freien Plätze zu bekommen.

Gut ich könnte ja mit dieser Info auf einer GUI dann die belegten Plätze ausblenden. Wenn ich mir vorstelle, dass ich Buttons dynamisch darstelle.

Aber es wäre dennoch interessant zu wissen wie ich von der Maximalen Anzahl und der bereits belegten Plätze auf alle freien Plätze komme.
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@matze1708: Du zählst halt alle Plätze auf und lässt die bereits belegten aus.

Code: Alles auswählen

    occupied_place_numbers = set(get_occupied_place_numbers(db, range_id))
    max_place_number = get_max_place_number(db, range_id)
    free_place_numbers = [
        place_number
        for place_number in range(1, max_place_number + 1)
        if place_number not in occupied_place_numbers
    ]
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
matze1708
User
Beiträge: 112
Registriert: Dienstag 12. März 2019, 11:49

Das wäre dann sowas?

Code: Alles auswählen



def zeige_belegte_Plaetze(db, stand_id):
    with closing(db.cursor()) as cursor:
        cursor.execute("""SELECT Platz FROM tbl_Schiesstand WHERE Ende is Null And StandID =%s """, (stand_id,))
        return [row['Platz'] for row in cursor]
    

def zeige_max_plaetze_nummer(db, stand_id):
    with closing(db.cursor()) as cursor:
        cursor.execute("""SELECT PlaetzeMax FROM tbl_Stand WHERE ID =%s """, (stand_id,))
        return [row['PlaetzeMax'] for row in cursor]



def zeige_freie_Plaetze_nummer = set(zeige_belegte_Plaetze(db, stand_id))
    max_place_number = zeige_max_plaetze_nummer(db, stand_id)
    free_place_numbers = [
        place_number
        for place_number in range(1, max_place_number + 1)
        if place_number not in zeige_freie_Plaetze_nummer
    ]

Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@matze1708: `zeige_*` ist falsch. Da wird nichts gezeigt. Ich würde wirklich empfehlen Englische Namen zu verwenden. Die Spracheelemente sind Englisch, die Namen in der Standardbibliothek sind Englisch, die Dokumentation ist Englisch, und das gilt auch für so ziemlich jede Bibliothek von Drittanbietern. Es gibt auch bestimmte Konventionen bei der Namensgebung, wie beispielsweise `get_something()` oder `is_something()`/`has_something()` die beim Leser bestimmte Erwartungen wecken, die bei Übersetzungen vielleicht nicht so deutlich sind. Zudem hat man im Englischen wesentlich weniger häufig das Einzahl und Mehrzahl gleich geschrieben werden. Das macht es einfacher Namen für einzelne Elemente und Sequenzen/Container mit den Elementen zu finden: man hängt beim Container einfach das Mehrzahl-”s” an, und gut ist.

Warum gibt `zeige_max_plaetze_nummer()` eine Liste mit genau einem Wert zurück? Was passiert wenn Du versuchst eine Liste und eine 1 als Operanden für ``+`` zu verwenden‽

Bei der letzten Funktion ist die Syntax falsch. Und die hat letztlich keinen Effekt, weil einfach nur das Ergebnis berechnet, aber nichts damit gemacht wird. Der Name ist auch nicht nur wegen dem `zeige_*` falsch, sondern weil die ja nicht nur *eine* Nummer ermittelt.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
matze1708
User
Beiträge: 112
Registriert: Dienstag 12. März 2019, 11:49

Ok. Dann passe ich dad alles mal auf englisch an.

Den Rest muss ich mir gleich nochmal ansehen
matze1708
User
Beiträge: 112
Registriert: Dienstag 12. März 2019, 11:49

Hallo,

habe mal den Code überarbeitet.
Ich habe versucht aus dem deutschen was englisches zu machen, denke aber hier nicht die Python Konvention getroffen zu haben.

Dass errechnen der freien Plätze klappt noch nicht.
Traceback (most recent call last):
File "schuetzeanlegen.py", line 190, in <module>
main()
File "schuetzeanlegen.py", line 167, in main
for place_number in range(1, max_place_number + 1)
TypeError: can only concatenate list (not "int") to list

Code: Alles auswählen

#!/usr/bin/python3

import os
import RPi.GPIO as gpio
import MFRC522
import MySQLdb
import MySQLdb.cursors
from contextlib import closing
import time
import signal

DB_HOST = "XXXX"
DB_USER = "XXXX"
DB_PASSWORD = "XXXX"

ablaufaktiv = True

def connect():
        
            conn = MySQLdb.connect(host=DB_HOST, port=3307,
            user=DB_USER , passwd=DB_PASSWORD, db="Schiessbuch",
            cursorclass=MySQLdb.cursors.DictCursor)
            return conn
        
            
            
def keyboardInterruptHandler(signal, frame):
    print("Abbruch durch Benutzer (ID: {}) wurde gedrückt.".format(signal))
    exit(0)

signal.signal(signal.SIGINT, keyboardInterruptHandler)




def get_Users(db):
    print()
    with closing(db.cursor()) as cursor:
        cursor.execute("""Select tbl_Benutzer.ID, tbl_Benutzer.UName, tbl_Benutzer.UVorname
            FROM tbl_Benutzer INNER JOIN tbl_Karten ON tbl_Benutzer.ID = tbl_Karten.UserID""")
        for row in cursor:
           print( row["ID"], row["UName"], row["UVorname"])


def check_User_registration(db, user_id):
    print()
    with closing(db.cursor()) as cursor:
        cursor.execute("""SELECT tbl_Schiesstand.UserID
                        FROM tbl_Schiesstand
                        Where  tbl_Schiesstand.UserID = %s AND  tbl_Schiesstand.Ende IS NULL""", (user_id,))
        
        if cursor.fetchone():
            return False
        else: 
            return True
            

def get_range(db):
    print()
    with closing(db.cursor()) as cursor:
        cursor.execute("Select ID, StandLang From tbl_Stand") 
        for row in cursor:
            print( row["ID"], row["StandLang"])



def get_caliber(db, range_id):
    print()
    with closing(db.cursor()) as cursor:
        cursor.execute("""Select tbl_Kaliber.ID, tbl_Kaliber.KaliberLang
            From tbl_Stand INNER JOIN tbl_Kaliber ON tbl_Stand.ID = tbl_Kaliber.StandID
            Where tbl_Stand.ID = %s""", (range_id,))
        for row in cursor:
            print( row["ID"], row["KaliberLang"])



def insert_rifleman(db, user_id, range_id, place, caliber_id, standaufsicht):
    print()
    with closing(db.cursor()) as cursor:
        sql_query = """INSERT INTO `tbl_Schiesstand` (`UserID`, `StandID`, `Platz`, `KaliberID`, `Beginn`, `Standaufsicht`) VALUES (%s, %s, %s, %s, NOW(), %s)"""
        data = (user_id, range_id, place, caliber_id, standaufsicht) 
        cursor.execute(sql_query, data) 
        db.commit()
        
        
    print("Du wurdest erfolgreich registriert") 
    time.sleep(5)



def get_occupied_place_numbers(db, range_id):
    with closing(db.cursor()) as cursor:
        cursor.execute(
            'SELECT Platz FROM tbl_Schiesstand'
            ' WHERE Ende IS NULL AND StandID = %s',
            (range_id,)
        )
        return [row['Platz'] for row in cursor]


def get_max_place_number(db, range_id):
    with closing(db.cursor()) as cursor:
        cursor.execute("""SELECT PlaetzeMax FROM tbl_Stand WHERE ID =%s """, (range_id,))
        return [row['PlaetzeMax'] for row in cursor]


def kartenid_Userid(db, cardID):
    print()
    with closing(db.cursor()) as cursor:
            cursor.execute("""SELECT tbl_Benutzer.ID
                            FROM tbl_Benutzer INNER JOIN tbl_Karten ON tbl_Benutzer.ID = tbl_Karten.UserID
                            WHERE tbl_Karten.KartenNummer=%s """, (cardID,))
            for row in cursor:
                print( row["ID"])
                return row["ID"]


def input_int(prompt):
    while True:
        try:
            print()
            return int(input(prompt))
        except ValueError:
            print("Fehler: Keine Zahl eingegeben.")
            


def main():
   while ablaufaktiv:
        try:
            os.system('clear')
            print("Schiessbuch")
            print()
            print("Bitte erfasse deine Daten!")
            
            db = connect()


            #print(karte_erkennen())
            
            
            
            get_Users(db)
            user_id = input_int("Bitte deine User ID eingeben: ")
                
            if not check_User_registration(db, user_id):
                print("Du bist bereits registriert")
                time.sleep(5)
                continue
            
            get_range(db)
            range_id = input_int("Bitte Stand eingeben: ")
            
            get_caliber(db, range_id)
            caliber_id = input_int("Bitte Kaliber eingeben: ")
            
            print()
            print("Folgende Plätze sind belegt: ")
            print(get_occupied_place_numbers(db, range_id))
            print(get_max_place_number(db, range_id))
            
            occupied_place_numbers = set(get_occupied_place_numbers(db, range_id))
            max_place_number = get_max_place_number(db, range_id)
            free_place_numbers = [
                place_number
                for place_number in range(1, max_place_number + 1)
                if place_number not in occupied_place_numbers
            ]       
            
            
            
            
            
            place = input_int("Auf welchem Stand schiesst du?: ")
            
            standaufsicht = 0
            insert_rifleman(db, user_id, range_id, place, caliber_id, standaufsicht)
        
        except KeyboardInterrupt:
            print("Abbruch")
            
        finally: 
            print("Ende")
       
        
        

if __name__ == '__main__':
    main()
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

`ablaufaktiv` ist immer noch da und wird nicht gebraucht.
In `connect` und `main` sind die Einrückungen nicht in Ordnung.
Der Signal-Handler hat in einem normalen Programm nichts verloren.
Die schlechten Tabellennamen sind immer noch nicht verbessert.
Der Name `get_Users` ist falsch geschrieben und auch noch falsch, weil hier nichts geholt wird, sondern nur etwas ausgegeben wird.
`check_User_registration` sollte auch besser `is_user_registered` heißen. Die letzten 4 Zeilen lassen sich zu `return cursor.fetchone() is None` zusammenfassen.
`get_range` und `get_caliber` geben auch nur etwas aus.
Was soll das sleep in `insert_rifleman`? Das würde niemand dort erwarten.
`get_max_place_number` liefert eine Liste, obwohl der Funktionsname eine Zahl erwarten lassen würde. Die Liste besteht auch immer nur aus einem Element.
`kartenid_Userid` ist kein Funktionsname. Die for-Schleife sieht falsch aus, weil es immer beim ersten Durchlauf per `return` verlassen wird. fetchone wäre da besser.
`main` enthält zu viele Leerzeilen, als dass das noch lesbar wäre.
matze1708
User
Beiträge: 112
Registriert: Dienstag 12. März 2019, 11:49

Ich habe mal versucht, das umzusetzten was ich kann und verstehe.

an die Tabellen wollte ich jetzt erstmal nicht ran. Erst wenn ich daraus die Produktive DB mache, oder muss ich das jetzt schon zum testen und lernen mache?

was soll ich für get_rang etc nehmen?

Code: Alles auswählen

#!/usr/bin/python3

import os
import RPi.GPIO as gpio
import MFRC522
import MySQLdb
import MySQLdb.cursors
from contextlib import closing
import time
import signal

DB_HOST = "XXX"
DB_USER = "XXX"
DB_PASSWORD = "XXX"


def connect():
    conn = MySQLdb.connect(host=DB_HOST, port=3307,
    user=DB_USER , passwd=DB_PASSWORD, db="Schiessbuch",
    cursorclass=MySQLdb.cursors.DictCursor)
    return conn
        
            
            
def keyboardInterruptHandler(signal, frame):
    print("Abbruch durch Benutzer (ID: {}) wurde gedrückt.".format(signal))
    exit(0)


signal.signal(signal.SIGINT, keyboardInterruptHandler)




def get_Users(db):
    print()
    with closing(db.cursor()) as cursor:
        cursor.execute("""Select tbl_Benutzer.ID, tbl_Benutzer.UName, tbl_Benutzer.UVorname
            FROM tbl_Benutzer INNER JOIN tbl_Karten ON tbl_Benutzer.ID = tbl_Karten.UserID""")
        for row in cursor:
           print( row["ID"], row["UName"], row["UVorname"])


def is_user_registered(db, user_id):
    print()
    with closing(db.cursor()) as cursor:
        cursor.execute("""SELECT tbl_Schiesstand.UserID
                        FROM tbl_Schiesstand
                        Where  tbl_Schiesstand.UserID = %s AND  tbl_Schiesstand.Ende IS NULL""", (user_id,))
       return cursor.fetchone() is None 
       
            

def get_range(db):
    print()
    with closing(db.cursor()) as cursor:
        cursor.execute("Select ID, StandLang From tbl_Stand") 
        for row in cursor:
            print( row["ID"], row["StandLang"])



def get_caliber(db, range_id):
    print()
    with closing(db.cursor()) as cursor:
        cursor.execute("""Select tbl_Kaliber.ID, tbl_Kaliber.KaliberLang
            From tbl_Stand INNER JOIN tbl_Kaliber ON tbl_Stand.ID = tbl_Kaliber.StandID
            Where tbl_Stand.ID = %s""", (range_id,))
        for row in cursor:
            print( row["ID"], row["KaliberLang"])



def insert_rifleman(db, user_id, range_id, place, caliber_id, standaufsicht):
    print()
    with closing(db.cursor()) as cursor:
        sql_query = """INSERT INTO `tbl_Schiesstand` (`UserID`, `StandID`, `Platz`, `KaliberID`, `Beginn`, `Standaufsicht`) VALUES (%s, %s, %s, %s, NOW(), %s)"""
        data = (user_id, range_id, place, caliber_id, standaufsicht) 
        cursor.execute(sql_query, data) 
        db.commit()
        
        
    print("Du wurdest erfolgreich registriert") 
    



def get_occupied_place_numbers(db, range_id):
    with closing(db.cursor()) as cursor:
        cursor.execute(
            'SELECT Platz FROM tbl_Schiesstand'
            ' WHERE Ende IS NULL AND StandID = %s',
            (range_id,)
        )
        return [row['Platz'] for row in cursor]


def get_max_place_number(db, range_id):
    with closing(db.cursor()) as cursor:
        cursor.execute("""SELECT PlaetzeMax FROM tbl_Stand WHERE ID =%s """, (range_id,))
        return [row['PlaetzeMax'] for row in cursor]



def input_int(prompt):
    while True:
        try:
            print()
            return int(input(prompt))
        except ValueError:
            print("Fehler: Keine Zahl eingegeben.")
            


def main():
   while ablaufaktiv:
        try:
            os.system('clear')
            print("Schiessbuch")
            print()
            print("Bitte erfasse deine Daten!")
            
            db = connect()
            
            get_Users(db)
            user_id = input_int("Bitte deine User ID eingeben: ")
                
            if not is_user_registered(db, user_id):
                print("Du bist bereits registriert")
                time.sleep(5)
                continue
            
            get_range(db)
            range_id = input_int("Bitte Stand eingeben: ")
            
            get_caliber(db, range_id)
            caliber_id = input_int("Bitte Kaliber eingeben: ")
            
            print()
            print("Folgende Plätze sind belegt: ")
            print(get_occupied_place_numbers(db, range_id))
            print(get_max_place_number(db, range_id))
                                  
            place = input_int("Auf welchem Stand schiesst du?: ")
            
            standaufsicht = 0
            insert_rifleman(db, user_id, range_id, place, caliber_id, standaufsicht)
            time.sleep(5)
        
        except KeyboardInterrupt:
            print("Abbruch")
            
        finally: 
            print("Ende")
       
        
        

if __name__ == '__main__':
    main()

matze1708
User
Beiträge: 112
Registriert: Dienstag 12. März 2019, 11:49

ich habe mal interessehalber die Ausgabe einer Funktion in eine Liste umgeleitet. Diese Liste gebe ich als return aus

Code: Alles auswählen

def get_Users2(db):
    print()
    with closing(db.cursor()) as cursor:
        cursor.execute("""Select tbl_Benutzer.ID, tbl_Benutzer.UName, tbl_Benutzer.UVorname
            FROM tbl_Benutzer INNER JOIN tbl_Karten ON tbl_Benutzer.ID = tbl_Karten.UserID""")
        data = cursor.fetchall()
        resultList = []  
        for data_out in data:  
            resultList.append(data_out["ID"])
            resultList.append(data_out["UName"]) 
            resultList.append(data_out["UVorname"]) 


        return resultList
Interessant wäre nun wie ich auf diese Elemente zugreifen kann

Bsp.:

Code: Alles auswählen

#!/usr/bin/python3

from tkinter import *
import schuetzeanlegen

db = schuetzeanlegen.connect()

root = Tk()

w = schuetzeanlegen.get_Users2(db)


for i in w:
	#print(i)

	Label(root, 
			text=i,
			fg = "red",
			font = "Times").pack()


root.mainloop()


Hier wird alle untereinander geschrieben logisch ! Hätte es gern aber pro Zeile die ID Name und VOrname
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@matze1708: Die Namen enthalten schon wieder Grossbuchstaben…

Es macht wenig Sinn die einzelnen Werte in eine Liste zu stecken. Bei Listen sollte jedes Element die gleiche Bedeutung haben, und nicht das erste eine ID, das zweite einen Benutzernamen, und so weiter. Warum steckst Du nicht einfach `data_out` in die Liste? Oder noch einfacher: ``cursor.fetchall()`` liefert doch bereits eine Liste. Und warum heisst `row` jetzt `data_out`?
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
matze1708
User
Beiträge: 112
Registriert: Dienstag 12. März 2019, 11:49

das heißt aktuell nur so, weil ich zum Test was kopiert hatte... Um es etwas zu verstehen.

Ich ändere die Buchstaben direkt ab.
matze1708
User
Beiträge: 112
Registriert: Dienstag 12. März 2019, 11:49

Code: Alles auswählen

def get_users2(db):
    print()
    with closing(db.cursor()) as cursor:
        cursor.execute("""Select tbl_Benutzer.ID, tbl_Benutzer.UName, tbl_Benutzer.UVorname
            FROM tbl_Benutzer INNER JOIN tbl_Karten ON tbl_Benutzer.ID = tbl_Karten.UserID""")
        return cursor.fetchall()

Code: Alles auswählen

#!/usr/bin/python3

from tkinter import *
import schuetzeanlegen

db = schuetzeanlegen.connect()

root = Tk()

w = schuetzeanlegen.get_users2(db)


for row in w:
          
	Label(root,
			text= (row["ID"], row["UName"], row["UVorname"]),
			fg = "red",
			font = "Times").pack()



root.mainloop()
Aha.... damit klappt es besser.

Ich schätze das ist auch das was du letztens gemeint hast, wie die Ausgaben der Funktionen sein sollen
matze1708
User
Beiträge: 112
Registriert: Dienstag 12. März 2019, 11:49

Habe mal weiter rum gespielt:

Code: Alles auswählen

from tkinter import *
import schuetzeanlegen

db = schuetzeanlegen.connect()

root = Tk()
frame1 = Frame(root)
frame1.pack()

frame2 = Frame(root)
frame2.pack()

frame3 = Frame(root)
frame3.pack(side = BOTTOM)


w = schuetzeanlegen.get_users2(db)

Label(frame1, text = "Schiessbuch", font = "Arial 14 bold").pack()
Label(frame1, text = "Bitte wähle deine ID aus: ").pack()

for row in w:
          
	Label(frame2,
			text= (row["ID"], row["UName"], row["UVorname"]),
			fg = "red",
			font = "Arial").pack(fill=X,pady=10)


e1 = Entry(frame3)
e1.pack(padx=5, pady=20, side=LEFT)

Buttonchoice= Button(frame3, text ="OK")
Buttonchoice.pack(padx=5, pady=20, side=LEFT)

root.title("Schiessbuch")
root.geometry("500x500")
root.mainloop()
Was ja dann erstmal heißt, dass ich alles was als print() rauskommt aus schuetzeanlegen.py in Returns umgebaut werden muss.

Dann muss ich irgendwie die Programmlogik in tkinter bringen.

in diesem Beispiel hier müsse der User jetzt seine Zahl eingeben und dann muss irgendwie auf die nächste Abfrage gesprungen werden.

Im Endausbau soll aber die Userauswahl per RFID funktionieren.


EDIT:

Kleines Update. DIe Abfragen in Module verschoben:

Code: Alles auswählen

#!/usr/bin/python3

from tkinter import *
import schuetzeanlegen


def show_users(db, frame):
	w = schuetzeanlegen.get_users2(db)
	for row in w:
		Label(frame,
				text= (row["ID"], row["UName"], row["UVorname"]),
				fg = "red",
				font = "Arial").pack(fill=X,pady=10)

def entry_box(frame):
	e1 = Entry(frame)
	e1.pack(padx=5, pady=20, side=LEFT)

	Buttonchoice= Button(frame, text ="OK")
	Buttonchoice.pack(padx=5, pady=20, side=LEFT)


def main():

	db = schuetzeanlegen.connect()

	root = Tk()
	frame1 = Frame(root)
	frame1.pack()

	frame2 = Frame(root)
	frame2.pack()

	frame3 = Frame(root)
	frame3.pack(side = BOTTOM)
	
	Label(frame1, text = "Schiessbuch", font = "Arial 14 bold").pack()
	Label(frame1, text = "Bitte wähle deine ID aus: ").pack()


	show_users(db, frame2)
	
	entry_box(frame3)

	

	root.title("Schiessbuch")
	root.geometry("500x500")
	root.mainloop()

if __name__ == '__main__':
    main()

Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Sternchenimporte sind böse. Tkinter wird üblicherweise per `import tkinter as tk` eingebunden und alle Namen per tk.xyz referenziert.
Auch hier solltest Du alles, was jetzt auf oberster Ebene steht, in eine `main`-Funktion packen.
matze1708
User
Beiträge: 112
Registriert: Dienstag 12. März 2019, 11:49

Habe schon ein Teil in Main gepackt,
Poste morgen mal den aktuellen Code.

Bin da grade am schauen wegen der Rückgabe eines Entrys.

Will aber noch eine Prüfung und eingabe für die Standaufsicht machen.

Weil man nur schiessen darf wenn eine Standaufsicht da ist.
Da mag ich noch was vorschalten.


EDIT: das ist auch erstmal nur gebastelt, um auch den Zusammenhang zu verstehen.
Daher die ganzen Fragen.
Google, weiss auch schon gleich was ich will😂😂
matze1708
User
Beiträge: 112
Registriert: Dienstag 12. März 2019, 11:49

Guten Morgen,

das ist der aktuelle Stand:

Code: Alles auswählen

#!/usr/bin/python3

from tkinter import *
import schuetzeanlegen


def show_users(db, frame):
	w = schuetzeanlegen.get_users2(db)
	for row in w:
		Label(frame,
				text= (row["ID"], row["UName"], row["UVorname"]),
				fg = "red",
				font = "Arial").pack(fill=X,pady=10)



def entry_box(frame):
	e1 = Entry(frame)
	e1.pack(padx=5, pady=20, side=LEFT)
	print(e1.get())
	

def entry_button(frame):
	Buttonchoice= Button(frame, text ="OK")
	Buttonchoice.pack(padx=5, pady=20, side=LEFT)


def main():

	db = schuetzeanlegen.connect()

	root = Tk()
	frame1 = Frame(root)
	frame1.pack()

	frame2 = Frame(root)
	frame2.pack()

	frame3 = Frame(root)
	frame3.pack(side = BOTTOM)
	
	Label(frame1, text = "Schiessbuch", font = "Arial 14 bold").pack()
	Label(frame1, text = "Bitte wähle deine ID aus: ").pack()


	show_users(db, frame2)
	
	entry_box(frame3)
	entry_button(frame3)
	

	root.title("Schiessbuch")
	root.geometry("500x500")
	root.mainloop()

if __name__ == '__main__':
    main()

matze1708
User
Beiträge: 112
Registriert: Dienstag 12. März 2019, 11:49

Wie müsste ich vorgehen um die Rückmeldungen zuverarbeiten?

Sprich den Entry verarbeiten und dann damit auf die nächste Abfrage kommen. Dann soll sich ja auch der INhalt des UI ändern für die darauf folgende Abfrage.
Antworten