Neueinsteiger plant Dart-Software

Du hast eine Idee für ein Projekt?
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@NewJoX: Die Namen sind teilweise sehr schlecht gewählt. Ein Name soll dem Leser vermitteln was der Wert dahinter bedeutet. Einbuchstabige Namen oder irgendwelche supergenerischen nummerierten Namen tun das so überhaupt nicht.

Du bindest auch deutlich zu viele belanglose Zwischenergebnisse an Namen. Nehmen wir mal `berechne2()`. Da wird `a` an den Inhalt von `outputLabel5` in eine Zahl gewandelt gebunden, dann `d` wieder an eine Zeichenkettendarstellung dieser Zahl, um die dann wieder in dem Label anzuzeigen. Da wird also die Zahl angezeigt die da sowieso schon angezeigt wurde. Warum? Wenn man das und die ganzen Zwischenergebnisse weglässt:

Code: Alles auswählen

    def berechne2(self):
        a = int(self.root.ids.outputLabel5.text)
        b = int(self.root.ids.outputLabel1.text)
        c = b-a
        c = str(c)
        d = str(a)
        f = int(self.root.ids.outputLabel2.text)
        g = f+a
        h = str(g)

        self.root.ids.outputLabel1.text = c
        self.root.ids.outputLabel5.text = d
        self.root.ids.outputLabel2.text = h
    
    # =>
    
    def berechne2(self):
        a = int(self.root.ids.outputLabel5.text)
        self.root.ids.outputLabel1.text = str(
            int(self.root.ids.outputLabel1.text) - a
        )
        self.root.ids.outputLabel2.text = str(
            int(self.root.ids.outputLabel2.text) + a
        )
Selbst mit den bescheidenen Namen sieht man hier leichter was passiert. Und das man da theoretisch eine Methode herausziehen könnte die eine Zahl in einem Textlabel um einen Betrag verändert. Aaaber, das was da passiert ist nicht gut. Man verwendet eine GUI zur Ein- und Ausgabe von Werten, nicht um Zahlwerte in Textlabeln zu speichern. Das ist furchtbar umständlich und man hat so überhaupt gar keine Trennung zwischen GUI und Programmlogik.

Funktions- und Methodennamen beschreiben üblicherweise die Tätigkeit die sie durchführen. Auch damit sie einfacher von eher passiven Werten unterscheiden kann. `average` wäre ein guter Name für einen Durchschnitts*wert*, aber nicht für eine Methode die den berechnet.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
NewJoX
User
Beiträge: 10
Registriert: Samstag 30. Januar 2021, 17:04

Danke für die Kritik, mir ist bewusst das dort unnötige Schritte drin sind.
Ich weiß das es so ist kann es aber nicht beheben, da mir einfach noch das Wissen fehlt.

Ich hab meinen groben Fehler selber entdeckt das mit der Liste hat nicht geklappt da es nur local in der Funktion war und deswegen wurden die Daten nicht behalten. (Böser Anfängerfehler) Jetzt kann ich mir das mit den meisten Labels sparen und arbeite mit der Liste.

Zur meiner Person ich mache beruflich was anderes als programmieren und bin auch kein Informatikstudent oder sonstiges . Ich lerne das programmieren mit einer App und mir macht es viel Spaß dies zu lernen. Leider fehlt mir dadurch das ich beruflich was anderes mache, die Möglichkeit mich mit anderen auszutauschen deswegen benutze ich dieses Forum.

In den meisten Sachen muss ich mich einfach noch reinfuchsen doch vielleicht könntet ihr mir noch bei einem Problem helfen und zwar wie ich die Ergebnisse speichern kann. Dies wurde in der App nicht beschrieben und bei Google habe ich dazu nichts passendes gefunden. Ich müsste dazu ja irgendwie eine externe Datei kreieren um dort Ergebnisse abspeichern zu können, denn ich möchte die Ergebnisse natürlich behalten, wenn ich die App schließe.
Benutzeravatar
Dennis89
User
Beiträge: 1124
Registriert: Freitag 11. Dezember 2020, 15:13

Hallo,

wie wäre es mit einer *.csv-Datei?
https://docs.python.org/3/library/csv.html
NewJoX hat geschrieben: Mittwoch 10. März 2021, 05:01 Zur meiner Person ich mache beruflich was anderes als programmieren und bin auch kein Informatikstudent oder sonstiges .
Dito, "einfach" am Ball bleiben. Ich hatte auch schon einige "Nervenzusammenbrüche" :lol:


Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Falls 2D-Daten/eine Tabelle nicht ausreicht zur Strukturierung kommt oft auch das JSON-Format in Betracht, mit dem `json`-Modul aus der Standardbibliothek.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
NewJoX
User
Beiträge: 10
Registriert: Samstag 30. Januar 2021, 17:04

Moinsen,
leider benötige ich nochmal eure Hilfe , denn ich komm nicht weiter. Da ich mehrere Screens benötige habe ich nun mit Screenmanager mehrere Screens erschaffen doch das Problem ist nun das ich auf den einzelnen Screens einfach keinen Zugriff mehr auf die Id´s finde.
Ich habe dafür ein Testprogramm erschaffen um dort herumzuprobieren ob ich Zugriff finde, doch es klappt nicht.

class ScreenOne(Screen):
pass


class ScreenTwo(Screen):
pass


class ScreenThree(Screen):
pass


class ScreenFour(Screen):
pass


class ScreenFive(Screen):
pass

screen_manager = ScreenManager()

screen_manager.add_widget(ScreenOne(name="screen_one"))
screen_manager.add_widget(ScreenTwo(name="screen_two"))
screen_manager.add_widget(ScreenThree(name="screen_three"))
screen_manager.add_widget(ScreenFour(name="screen_four"))
screen_manager.add_widget(ScreenFive(name="screen_five"))

class ScreenApp(App):

def build(self):
return screen_manager

def reset(self):
self.root.OutputLabel.text = "1"

def Definition(a,b,c,d):
for x in [a,b,c,d]:
print(x)

<ScreenFive>:
BoxLayout:
Label:
id: OutputLabel
text: "500"
Button:
text: "Go to Screen 1"
background_color : 1, 0, 0, 1
on_press:
root.manager.transition.direction = 'right'
root.manager.current = 'screen_one'
TextInput:
id: my_textinput
Button:
text: "Test"
on_release: app.Definition(self,root,app)

<__main__.ScreenApp object at 0x00000203752C6908>
<kivy.uix.button.Button object at 0x00000203752C66D8>
<Screen name='screen_five'>
<__main__.ScreenApp object at 0x00000203752C6908>

das wäre die Ausgabe für app.Definition. Das Problem liegt wohl das root (Screen name='screen_five') zurück gibt was vorher nicht der Fall war.
Benutzeravatar
Dennis89
User
Beiträge: 1124
Registriert: Freitag 11. Dezember 2020, 15:13

Hallo,

setz doch den Code bitte in Code-Tags (</> Button) und achte auf die Einrückungen.
Schau mal, im folgendem Link habe ich ein Projekt von mir mit Code veröffentlicht. Da greife benutze ich auch den Screenmanager, vielleicht hilft dir das weiter.
https://forum-raspberrypi.de/forum/thre ... hgeraeten/

Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
NewJoX
User
Beiträge: 10
Registriert: Samstag 30. Januar 2021, 17:04

NewJoX hat geschrieben: Montag 15. März 2021, 10:34 Moinsen,
leider benötige ich nochmal eure Hilfe , denn ich komm nicht weiter. Da ich mehrere Screens benötige habe ich nun mit Screenmanager mehrere Screens erschaffen doch das Problem ist nun das ich auf den einzelnen Screens einfach keinen Zugriff mehr auf die Id´s finde.
Ich habe dafür ein Testprogramm erschaffen um dort herumzuprobieren ob ich Zugriff finde, doch es klappt nicht.

Code: Alles auswählen

class ScreenOne(Screen):
    pass


class ScreenTwo(Screen):
    pass


class ScreenThree(Screen):
    pass


class ScreenFour(Screen):
    pass


class ScreenFive(Screen):
    pass

screen_manager = ScreenManager()

screen_manager.add_widget(ScreenOne(name="screen_one"))
screen_manager.add_widget(ScreenTwo(name="screen_two"))
screen_manager.add_widget(ScreenThree(name="screen_three"))
screen_manager.add_widget(ScreenFour(name="screen_four"))
screen_manager.add_widget(ScreenFive(name="screen_five"))

class ScreenApp(App):

    def build(self):
        return screen_manager

    def reset(self):
        self.root.OutputLabel.text = "1"

    def Definition(a,b,c,d):
        for x in [a,b,c,d]:
            print(x)
Das wäre die kv.file

Code: Alles auswählen

<ScreenFive>: 
    BoxLayout:
        Label:
            id: OutputLabel
            text: "500"
        Button: 
            text: "Go to Screen 1" 
            background_color : 1, 0, 0, 1 
            on_press: 
                root.manager.transition.direction = 'right' 
                root.manager.current = 'screen_one'
        TextInput:
            id: my_textinput
        Button:
            text: "Test"
            on_release: app.Definition(self,root,app)
<__main__.ScreenApp object at 0x00000203752C6908>
<kivy.uix.button.Button object at 0x00000203752C66D8>
<Screen name='screen_five'>
<__main__.ScreenApp object at 0x00000203752C6908>

das wäre die Ausgabe für app.Definition. Das Problem liegt wohl das root (Screen name='screen_five') zurück gibt was vorher nicht der Fall war.
Benutzeravatar
Dennis89
User
Beiträge: 1124
Registriert: Freitag 11. Dezember 2020, 15:13

Hallo,

in deiner *.kv-Datei musst du 'screen_one' auch definieren und deine Klasse 'ScreenApp' muss den ScreenManager enthalten.

Code: Alles auswählen

class ScreenApp(App):
    def build(self):
        screen_manager = ScreenManager()

        screen_manager.add_widget(ScreenOne(name="screen_one"))
        screen_manager.add_widget(ScreenTwo(name="screen_two"))
        screen_manager.add_widget(ScreenThree(name="screen_three"))
        screen_manager.add_widget(ScreenFour(name="screen_four"))
        screen_manager.add_widget(ScreenFive(name="screen_five"))
        return screen_manager
Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
NewJoX
User
Beiträge: 10
Registriert: Samstag 30. Januar 2021, 17:04

Moinsen, ich bräuchte leider nochmal eure Hilfe.
Ich habe mehrere Screens und wenn ich in dem Screen von "Spiel erstellen" bin und verschiedene Spieler auswähle werde ich zu einem der anderen 4 Screens weiter geleitet ( Screens für 1,2,3 oder 4 Spieler). In diesem Fall 4 Spieler.
Ich möchte wenn ich in dem Screen bin das die Spieler sofort angezeigt werden. Aktuell ist es so gelöst das ich auf einem Button drücken muss und dann werden die Spielernamen und Punkte angegeben.

Methode für Spielstarten.

Code: Alles auswählen

    def Spielbeginnen(self):
        global Spielerliste
        global Spieler_dran
        self.ids.Nameplayer1.text = Spielerliste[0]
        self.ids.Nameplayer2.text = Spielerliste[1]
        self.ids.Nameplayer3.text = Spielerliste[2]
        self.ids.Nameplayer4.text = Spielerliste[3]
        self.ids.Restplayer1.text = str(Start_player1)
        self.ids.Restplayer2.text = str(Start_player2)
        self.ids.Restplayer3.text = str(Start_player3)
        self.ids.Restplayer4.text = str(Start_player4)
        Spieler_dran.append(5)
Methode für den Screenwechsel.

Code: Alles auswählen

class SpielerstellenWindow(Screen):
    def checkbox_click(self, instance, value, Spieler):
        global Spielerliste
        if value == True:
            Spielerliste.append(Spieler)
            self.ids.AusgabeSpieler.text = f"{Spielerliste}"
        else:
            Spielerliste.remove(Spieler)
            self.ids.AusgabeSpieler.text = f"{Spielerliste}"
    def checkbox_click2(self):
        pass
    def Spielstarten(self):
        global Spielerliste
        if len(Spielerliste) == 1:
            self.manager.current = "Spiel"
        elif len(Spielerliste) == 2:
            self.manager.current = "Spiel2"
        elif len(Spielerliste) == 3:
            self.manager.current = "Spiel3"
        elif len(Spielerliste) == 4:
            self.manager.current = "Spiel4"
Ich kriege keine Verbindung zwischen den 2 Screens hin, wie bekomme ich dies hin?
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@NewJoX: Ich sehe da Klassen und ``global``, eine Kombination die falsch ist. Auch ohne Klassen sollte man ``global`` nicht verwenden, aber mit Klassen gibt es dafür überhaupt keine Ausrede.

Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (PascalCase).

Man nummeriert keine Namen. Dann möchte man entweder passendere Namen verwenden, oder gar keine Einzelnamen sondern eine Datenstruktur. Oft eine Liste.

Grunddatentypen haben in Namen nichts zu suchen. Womit wir dann zu einem Problem mit deutschsprachigen Bezeichnern kommen: `spieler` ist sowohl Einzahl als auch Mehrzahl. Im Englischen gibt es das Problem nicht, da kann man `player` und `players` einfach unterscheiden.

Man vergleicht keine Wahrheitswerte mit literalen Wahrheitswerten. Da kommt doch nur wieder ein Wahrheitswert bei heraus. Entweder der den man sowieso schon hatte, dann hätte man den auch gleich verwenden können, oder dessen Gegenteil, dafür gibt es ``not``.

Wenn man am Anfang oder am Ende von allen Zweigen das gleiche macht, dann gehört das entweder vor oder nach die Zweige und nicht in jedem Zweig wiederholt.

In der Methode zum Spielstarten wird recht umständlich eine Zeichenkette aufgrund der Länge einer Liste ausgewählt.

Code: Alles auswählen

class CreateGameWindow(Screen):
    def checkbox_click(self, players, _instance, value, player):
        (players.append if value else players.remove)(player)
        self.ids.AusgabeSpieler.text = f"{players}"

    def start_game(self, players):
        self.manager.current = ["Spiel", "Spiel2", "Spiel3", "Spiel4"][
            len(players) - 1
        ]
Wenn die Zeichenkettewerte nicht so komisch asymmetrisch wären, ginge es noch einfacher:

Code: Alles auswählen

    def start_game(self, players):
        self.manager.current = f"Spiel{len(players)}"
Wobei ich es ein bisschen komisch finde für verschiedene Spieleranzahlen wirklich komplett unterschiedliche Screens zu haben.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
NewJoX
User
Beiträge: 10
Registriert: Samstag 30. Januar 2021, 17:04

Danke dir für deine Konstruktive Kritik.

Ich lese mir das morgen nochmal genauer durch um dies wirklich zu verstehen.

Das GridLayout in dem jeweiligen Screen ist so angepasst für die jeweilige Spieleranzahl oder wie würdest du dies lösen?

Ich habe die unterschiedlichen Labels mit ID`s nummeriert, denn diese müssen ja ständig angepasst werden und durch ausbullen wird vor dem Spiel die Reihenfolge bestimmt deswegen wollte ich auch das der erste den man in der Checkbox auswählt auch als player1 gelistet ist im oberen Label usw.


Bild

Bild
Antworten