finde den Fehler in der Schlaufe nicht

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
duli
Beiträge: 75
Registriert: 17.04.2007 11:39

finde den Fehler in der Schlaufe nicht

Beitrag von duli »

Hallo hier bin ich wieder, mein Sohn und ich habe das kleine einmal eins Programm noch was verändert, so das es immer mit Enter weiterspringt.
Wir haben auch einen Zähler eingebaut welcher mitzählt wieviel richtige man hatte.
Doch zum einem bleibt der Zähler bei der zahl 2 einmal hängen so das zweimal 2 Richtige angezeigt werden.

Zum anderen ist es so das nach einer Falschen Rechnung die nächste auch noch als Falsch bezeichnet wird, auch wenn diese richtig war.

Code: Alles auswählen

#ButtonPlus = 0
#ButtonMinus = 1
#ButtonMal = 2
#ButtonDurch = 3
#StringZahl1 = 4
#StringZahl2 = 5
#StringZahl3 = 6
#StringErgebnis = 7
#MainWindow = 0
#neu = 0
Anzahl_Richtig = 0
falsche = 0

Procedure FillGadget()
  SetGadgetText(#StringZahl1,Str(Random(12)))
  SetGadgetText(#StringZahl2,Str(Random(12)))
  SetGadgetText(#StringZahl3,"")
EndProcedure


Procedure rechne()
 
  val1.s = GetGadgetText(#StringZahl1)
  val2.s = GetGadgetText(#StringZahl2)
  result = Val(val1)*Val(val2)
  SetGadgetText(#StringErgebnis,Str(result))
  
  If result = Val(GetGadgetText(#StringZahl3))
    ProcedureReturn #True
  EndIf
 
EndProcedure


If OpenWindow(#MainWindow,0,0,200,400,"Taschenrechner",#PB_Window_ScreenCentered | #PB_Window_SystemMenu | #PB_Window_MinimizeGadget)
 
  If CreateGadgetList(WindowID(0))
      
    TextGadget(#PB_Any, 0, 10, 100, 20, "Erste Zahl")
   
    StringGadget(#StringZahl1,0,30,100,20,Str(Random(12)),#PB_String_Numeric)
   
    TextGadget(#PB_Any, 0, 60, 100, 20, "Zweite Zahl")
   
    StringGadget(#StringZahl2,0,80,100,20,Str(Random(12)),#PB_String_Numeric)
   
    TextGadget(#PB_Any, 0, 135, 150, 20, "Resultat eingeben")
   
    StringGadget(#StringZahl3,0,150,100,20,"",#PB_String_Numeric)
   
   ; TextGadget(#PB_Any, 0, 175, 300 20, "Resultat Richtig")
       
    TextGadget(#PB_Any, 0, 230, 150, 20, "Neue Rechnung mit Enter")

    StringGadget(#StringErgebnis,0,320,100,20,"",#PB_String_Numeric | #PB_String_ReadOnly)
      
    AddKeyboardShortcut(#MainWindow,#PB_Shortcut_Return,#neu)
    
    SetActiveGadget(#StringZahl3)
    
  EndIf
EndIf


Repeat
  EventID = WaitWindowEvent()
  
  Select EventID
  
    Case #PB_Event_Menu
      If EventMenu() = #neu       
        rechne()
        Anzahl_Richtig = Anzahl_Richtig +1
           If rechne()
              TextGadget(#PB_Any, 0, 260, 150, 60, "Richtig")
              TextGadget(#PB_Any, 160, 260, 30, 20, Str(Anzahl_Richtig))
          Else
            TextGadget(#PB_Any, 0, 260, 150, 60, "Aber aber so was auch, das richtige Resultat lautet")
            
          EndIf
          
          FillGadget() 
        SetActiveGadget(#StringZahl3) 
      EndIf

    Case #PB_Event_CloseWindow
      End
     
    Case #PB_Event_Gadget

  EndSelect
 Until EventID = #PB_Event_CloseWindow
End 
Man kann nicht wissen was man nicht weiss..
Benutzeravatar
edel
Beiträge: 3667
Registriert: 28.07.2005 12:39
Computerausstattung: GameBoy
Kontaktdaten:

Beitrag von edel »

Code: Alles auswählen

      If EventMenu() = #neu               
        If rechne() 
          Anzahl_Richtig = Anzahl_Richtig + 1
          TextGadget(#PB_Any, 0, 260, 150, 60, "Richtig")
          TextGadget(#PB_Any, 160, 260, 30, 20, Str(Anzahl_Richtig))
        Else
          TextGadget(#PB_Any, 0, 260, 150, 60, "Aber aber so was auch, das richtige Resultat lautet") 
        EndIf
        
        FillGadget()
        SetActiveGadget(#StringZahl3)
      EndIf
Tu dir aber selber einen Gefallen und lass das mit dem Fenster, das lenkt
eh nur ab, versucht es ersteinmal mit der Konsole. Der eine oder andere
wird jetzt zwar mit den Augen rollen, aber mit der Konsole lernt man
schneller.
Benutzeravatar
Kiffi
Beiträge: 10714
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: finde den Fehler in der Schlaufe nicht

Beitrag von Kiffi »

Hai duli,

in Deinem Code hast Du ein paar grundsätzliche Gedankenfehler.
Ich versuche mal, Dich auf den richtigen Weg zu bringen.

Code: Alles auswählen

  If CreateGadgetList(WindowID(0))
    TextGadget(#PB_Any, 0, 10, 100, 20, "Erste Zahl")
    [...]
ist erstmal korrekt. Wenn man ein Textgadget nur zur Anzeige eines
Textes benötigt, den man später nicht mehr verändern muss, kann man
#PB_Any verwenden.

Allerdings möchtest Du ja auch später in ein bestimmtes Textgadget
innerhalb des Programmablaufes einen neuen Text reinschreiben. Hier
musst Du dann eine Konstante verwenden.

Code: Alles auswählen

  TextGadget(#RichtigOderFalsch, 0, 260, 150, 60, "")
  TextGadget(#Resultat, 160, 260, 30, 20, "")
und diese Konstanten kannst Du dann verwenden, um den Inhalt des
TextGadgets mit SetGadgetText() zu verändern.

Code: Alles auswählen

If rechne()
 SetGadgetText(#RichtigOderFalsch, "Richtig")
Else
 SetGadgetText(#RichtigOderFalsch, "Falsch")
EndIf
Kleiner Tipp noch:

Code: Alles auswählen

#ButtonPlus = 0
#ButtonMinus = 1
#ButtonMal = 2
#ButtonDurch = 3
#StringZahl1 = 4
#StringZahl2 = 5
#StringZahl3 = 6
#StringErgebnis = 7 
Wenn Du obiges in einer Enumeration einfügst, dann musst Du die Konstanten nicht mehr manuell durchnummerieren. Das macht dann die Enumeration für Dich.

Code: Alles auswählen

Enumeration
 #ButtonPlus 
 #ButtonMinus
 #ButtonMal
 #ButtonDurch
 #StringZahl1
 #StringZahl2
 #StringZahl3
 #StringErgebnis
EndEnumeration
Grüße ... Kiffi
a²+b²=mc²
Benutzeravatar
duli
Beiträge: 75
Registriert: 17.04.2007 11:39

Beitrag von duli »

:o

Man jetzt wirds ernst, ja Edel ich könnte es in einer Console machen. Aber alle beispiele wo ich es abgeleitet habe waren eben im Windowsmodus. Und zum anderen bin ich ja gerade für mich daran interesiert es eben mit der Windowsoberfläche zu verbinden. Obwohl Du sicher recht hast es einfacher ist das nur von der Struktur her zu verstehen.

Bis ich, das was ihr geschrieben habt, verdaut habe, werde ich noch ein wenig brauchen, aber vielen dank einmal fürs erste.

gruss Duli :allright:
Man kann nicht wissen was man nicht weiss..
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

mit dem consolen-modus kannst du erstmal überhaupt das benutzen von schleifen und variablen üben.
das nachher auch nochmal im windowmodus umzusetzen, steht dir ja frei.

natürlich kannst du direkt im windowmodus anfangen,
dann hast du aber halt zwei grundlegende "kapitel" gleichzeitig zu üben.


falls du beim fenstermodus bleibst, die tipps von Kiffi sind schon sehr hilfreich.

mach auf jedenfall mit irgendwas weiter. :allright:
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
duli
Beiträge: 75
Registriert: 17.04.2007 11:39

Beitrag von duli »

Danke für die Ermutigung Kaeru Gaman, werde ich bestimmt machen. Es ist so, dass ich für das meiste was ich entwickle, die Datenbank Filemaker pro verwende. Das geschah eigentlich daher weil ich einfach nicht die Zeit hatte mich um die vielen extras im Hintergrund zu kümmern. Da nun mein Sohn das Programmieren lernen möchte, wobei hier eher vom zugucken gesprochen werden kann. Bin ich mich am reinknien. Und zumal ich einige Projekte offen habe die ich ich verwircklichen möchte in den nächsten Monaten. Eines ist zB. ein Explorer mit zwei Treefenstern damit ich einfacher die Mp3 daten hin und her schieben kann. Alles was ich kenne, ist viel zu überladen, und die darstellungen sind oft nur per ID Tags angezeigt.
Für mich ist das anzeigen von IDTag unbrachbar, den eine Geschichte die von einer Kassette auf den PC gespielt ist, dann in mp3 umgewandelt und noch gesplittet wurde. Immer noch alle IDTags in alle Formaten nachzuführen ist ein Zeitaufwand den ich mir nicht leisten kann.

Weiter werden mein Sohn und ich noch einige kleine Helfer für die Schule schreiben, zuerst so wie jetzt mal nur eine gute Grundstruktur, dann noch etwas kreativität dazu, möglichst witzig und freche. Aber eben eines nach dem anderen.
Ich finde es nätürlich super das wir hier so gut beraten werden, so lerne ich und mein Bub es grundsätzlich wie man es richtig macht. Aber es ist gar nicht so einfach. Doch so schnell geben wir eh nicht auf.

Wie ist das, wenn nun, auch dank eurer Hilfe, einige Codes herauskommen die brauchbar sind für andere Anfänger hat da jemand interesse oder ist es nur ein überladen der bereits bestehenden Code Sammlungen?

Auf jedenfall liebe Grüsse und nun versuche in aller ruhe das zu verstehen was ihr mir am Nachmittag geschrieben habt. :roll:

Gruss Duli
Man kann nicht wissen was man nicht weiss..
Benutzeravatar
duli
Beiträge: 75
Registriert: 17.04.2007 11:39

Beitrag von duli »

So :mrgreen: ja ich glaube ich habe es geschnallt.

Ich habe es nun verstanden am Anfang werden, wie Platzhalter erzeugt, welche dann im verlauf des Programmes nur noch Wert zugeführt werden, die Positionierung und Formatierung wird im Hauptprogrammteil zugeteilt.
Habe auch noch einen Zähler für die Anzahl der Falsch gelösten Rechungen gemacht.

Jetzt ruhe ich mich ein wenig aus, denn mein Kopf raucht schon. Aber ich weiss schon was ich als nächste möchte. Das es noch die Laufende Zeit angibt. Werde da mal in der Hilfe nachsehen und zu dem gehört die Frage nicht mehr in dieses Thema, wenn ich nicht weiter komme hört ihr wieder von mir, eigentlich bin ich sicher das ihr wieder von mir hört.

Gruss Duli


Schaut mal her hier der überarbeitet Code

Code: Alles auswählen

; Mit Eneumeritation wird den Konstanten eine Fortlaufende Nummer vergeben anstelle dies von Hand zu machen.
Enumeration
#StringZahl1
#StringZahl2
#StringZahl3
#StringErgebnis
#MainWindow
#neu
#RichtigOderFalschText
#AnzahlRichtigeText
#AnzahlRichtigeWert
#AnzahlFalscherText
#AnzahlFalscherWert
EndEnumeration

Anzahl_Richtig = 0
Anzahl_Falsche = 0

Procedure FillGadget()
  SetGadgetText(#StringZahl1,Str(Random(10)))
  SetGadgetText(#StringZahl2,Str(Random(10)))
  SetGadgetText(#StringZahl3,"")
EndProcedure


Procedure rechne()
 
  val1.s = GetGadgetText(#StringZahl1)
  val2.s = GetGadgetText(#StringZahl2)
  result = Val(val1)*Val(val2)
  SetGadgetText(#StringErgebnis,Str(result))
  
  If result = Val(GetGadgetText(#StringZahl3))
    ProcedureReturn #True
  EndIf
 
EndProcedure


If OpenWindow(#MainWindow,0,0,200,400,"Taschenrechner",#PB_Window_ScreenCentered | #PB_Window_SystemMenu | #PB_Window_MinimizeGadget)
 
  If CreateGadgetList(WindowID(#MainWindow))
      
    TextGadget(#PB_Any, 0, 10, 100, 20, "Erste Zahl")
   
    StringGadget(#StringZahl1,0,30,100,20,Str(Random(10)),#PB_String_Numeric)
   
    TextGadget(#PB_Any, 0, 60, 100, 20, "Zweite Zahl")
   
    StringGadget(#StringZahl2,0,80,100,20,Str(Random(10)),#PB_String_Numeric)
   
    TextGadget(#PB_Any, 0, 135, 150, 20, "Resultat eingeben")
   
    StringGadget(#StringZahl3,0,150,100,20,"",#PB_String_Numeric)
   
    TextGadget(#PB_Any, 0, 180, 150, 20, "Neue Rechnung mit Enter")
    
    TextGadget(#RichtigOderFalschText, 0, 260, 150, 60, "")
    
    TextGadget(#StringErgebnis,160,260,100,20,"")
    
    TextGadget(#AnzahlRichtigeText, 0, 330, 150, 20, "Anzahl Richtige")
            
    TextGadget(#AnzahlRichtigeWert, 160, 330, 30, 20, "")
    
    TextGadget(#AnzahlFalscherText, 0, 350, 150, 20, "Anzahl Falsche")
            
    TextGadget(#AnzahlFalscherWert, 160, 350, 30, 20, "")
      
    AddKeyboardShortcut(#MainWindow,#PB_Shortcut_Return,#neu)
    
    SetActiveGadget(#StringZahl3)
    
  EndIf
EndIf


Repeat
  EventID = WaitWindowEvent()
  
  Select EventID
  
    Case #PB_Event_Menu
      If EventMenu() = #neu       
        rechne()
        
         If rechne()
            Anzahl_Richtig = Anzahl_Richtig +1             
            SetGadgetText(#RichtigOderFalschText, "Richtig das Resultat war")
            SetGadgetText(#AnzahlRichtigeWert, Str(Anzahl_Richtig))
            
          Else
          
            Anzahl_Falsch = Anzahl_Falsch +1
            SetGadgetText(#RichtigOderFalschText, "Aber aber so was auch, das richtige Resultat lautet")
            SetGadgetText(#AnzahlFalscherWert,Str(Anzahl_Falsch))
            SetGadgetText(#StringErgebnis, "")
          EndIf
          
        FillGadget() 
        SetActiveGadget(#StringZahl3) 
      EndIf

    Case #PB_Event_CloseWindow
      End
     
    Case #PB_Event_Gadget

  EndSelect
 Until EventID = #PB_Event_CloseWindow
End 
Man kann nicht wissen was man nicht weiss..
Benutzeravatar
Kiffi
Beiträge: 10714
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Beitrag von Kiffi »

duli hat geschrieben:Schaut mal her hier der überarbeitet Code
schon mal nicht übel, aber noch ein wenig verbesserungswürdig ;-)

Schön, dass Du meinen Verbesserungsvorschlag mit der Enumeration
angenommen hast. Was Du jedoch nicht wusstest (um meines Wissens
auch so nicht in der Hilfe steht): Du solltest in der Enumeration nach
Gadgets, Windows und Menüitems unterscheiden, das Du sonst
überflüssigen Speicher beanspruchst. Im Klartext sähe das dann so aus:

Code: Alles auswählen

Enumeration ; hier kommen alle Windows rein
  #MainWindow
EndEnumeration
  
Enumeration ; hier kommen alle Menüitems rein
  #neu
EndEnumeration

Enumeration ; hier kommen alle Gadgets rein
  #StringZahl1
  #StringZahl2
  #StringZahl3
  #StringErgebnis
  #RichtigOderFalschText
  #AnzahlRichtigeText
  #AnzahlRichtigeWert
  #AnzahlFalscherText
  #AnzahlFalscherWert
EndEnumeration


des weiteren hast Du ein rechne() zuviel in Deinem Code:

Code: Alles auswählen

If EventMenu() = #neu       
  rechne()
  If rechne() 
und bei einer falschen Antwort löscht Du mit SetGadgetText(#StringErgebnis, "")
das Ergebnis, noch bevor es der Anwender zu Gesicht bekommt. Wo bleibt
denn da der Lerneffekt? ;-)

Grüße ... Kiffi
a²+b²=mc²
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

Code: Alles auswählen

If EventMenu() = #neu       
  rechne()
  If rechne()
zum tieferen verständnis.

Code: Alles auswählen

If Prozedur() 
ruft an genau dieser stelle die Prozedur auf,
und verarbeitet unmittelbar den rückgabewert in dem If.

man kann das auch logisch trennen:

Code: Alles auswählen

Ergebnis =  rechne()
If Ergebnis
möglicherweise hast du gedacht, du rufst zuerst die Prozedur wie einen befehl auf,
und danach kannst du das ergebnis prüfen, indem du den Prozedurnamen ins IF schreibst.

das ist nicht nötig/möglich,
der Prozedurname erfüllt dort wo er steht zwei funktionen:
a) die Prozedur wird aufgerufen,
b) wenn er in eine Rechnung/Überprüfung eingebettet ist,
wird der rückgabewert an genau dieser stelle in die rechnung übernommen.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
duli
Beiträge: 75
Registriert: 17.04.2007 11:39

Beitrag von duli »

Habt danke für die guten Verbesserungsvorschläge. <)

Habe sie wie folgt angewendet.

Code: Alles auswählen

Enumeration ; hier kommen alle Windows rein
  #MainWindow
EndEnumeration
 
Enumeration ; hier kommen alle Menüitems rein
  #neu
EndEnumeration

Enumeration ; hier kommen alle Gadgets rein
  #StringZahl1
  #StringZahl2
  #StringZahl3
  #StringErgebnis
  #RichtigOderFalschText
  #AnzahlRichtigeText
  #AnzahlRichtigeWert
  #AnzahlFalscherText
  #AnzahlFalscherWert
  #AktuelleDauer
EndEnumeration
Und das mit dem zweiten Aufrufender Prozedur rechne() hätte mir nicht träumen lassen, dass es so einfach ist und man beides in einem machen kann. Das sieht nun so aus bei mir.

Code: Alles auswählen



Repeat
  EventID = WaitWindowEvent()

  Select EventID

    Case #PB_Event_Menu
      If EventMenu() = #neu       

          If rechne()
            Anzahl_Richtig = Anzahl_Richtig +1             
            SetGadgetText(#RichtigOderFalschText, "Richtig das Resultat war")
            SetGadgetText(#AnzahlRichtigeWert, Str(Anzahl_Richtig))
            
          Else
          
            Anzahl_Falsch = Anzahl_Falsch +1
            SetGadgetText(#RichtigOderFalschText, "Aber aber so was auch, das richtige Resultat lautet")
            SetGadgetText(#AnzahlFalscherWert,Str(Anzahl_Falsch))
          EndIf
          
        FillGadget() 
        SetActiveGadget(#StringZahl3) 
      EndIf

    Case #PB_Event_CloseWindow
      End
     
    Case #PB_Event_Gadget

  EndSelect
 Until EventID = #PB_Event_CloseWindow
Man kann nicht wissen was man nicht weiss..
Antworten