Forum | | | | - Seite 1 - |
|  Julian Schmidt | Hallo, bin gerade dabei aus Just for Fun einen Taschenrechner zuschreiben. Häng allerdings noch an den Punkt wie man an besten das Ergebnis ausrechnet. Bräucht eine gute Strategie wie man eine in eine Editierbox eingebene Matheaufgabe, gelöst in eine Variable speichert und dann in der besagten Editierbox ausgibt Weiß jetzt nicht wie ich das genau anstellen soll. Hoffe ihr könnt mir sagen wie ich das anstelle
DEF GetSysColor(1)!"USER32","GetSysColor"
declare Edit&,e%,eins&,zwei&,drei&,vier&,fünf&,sechs&,sieben&,acht&,neun&,null&
declare komma&,plus&,minus&,mal&,geteilt&,gleich&,clear&,off&,del&,info&,ans$,ergebnis!
WindowStyle 24
Window 10,10-250,250
cls GetSysColor(15)
WindowTitle "Taschenrechner"
Edit& = Create("Edit",%HWnd,"",20,20,200,20)
eins& = Create("Button",%HWnd,"1",20,60,30,25)
zwei& = Create("Button",%HWnd,"2",60,60,30,25)
drei& = Create("Button",%HWnd,"3",100,60,30,25)
vier& = Create("Button",%HWnd,"4",20,100,30,25)
fünf& = Create("Button",%HWnd,"5",60,100,30,25)
sechs& = Create("Button",%HWnd,"6",100,100,30,25)
sieben& = Create("Button",%HWnd,"7",20,140,30,25)
acht& = Create("Button",%HWnd,"8",60,140,30,25)
neun& = Create("Button",%HWnd,"9",100,140,30,25)
null& = Create("Button",%HWnd,"0",20,180,30,25)
komma& = Create("Button",%HWnd,".",60,180,30,25)
plus& = Create("Button",%HWnd,"+",140,60,30,25)
minus& = Create("Button",%HWnd,"-",140,100,30,25)
mal& = Create("Button",%HWnd,"*",140,140,30,25)
geteilt& = Create("Button",%HWnd,":",140,180,30,25)
gleich& = Create("Button",%HWnd,"=",100,180,30,25)
clear& = Create("Button",%HWnd,"C",180,100,40,25)
del& = Create("Button",%HWnd,"Del",180,140,40,25)
off& = Create("Button",%HWnd,"Off",180,60,40,25)
info& = Create("Button",%HWnd,"?",180,180,40,25)
whilenot e%
waitinput
waitinput
if getfocus(eins&)
ans$ = Val(GetText$(Edit&))
SetText Edit&,ans$ + "1"
elseif getfocus(zwei&)
ans$ = Val(GetText$(Edit&))
SetText Edit&,ans$ + "2"
elseif getfocus(drei&)
ans$ = Val(GetText$(Edit&))
SetText Edit&,ans$ + "3"
elseif getfocus(vier&)
ans$ = Val(GetText$(Edit&))
SetText Edit&,ans$ + "4"
elseif getfocus(fünf&)
ans$ = Val(GetText$(Edit&))
SetText Edit&,ans$ + "5"
elseif getfocus(sechs&)
ans$ = Val(GetText$(Edit&))
SetText Edit&,ans$ + "6"
elseif getfocus(sieben&)
ans$ = Val(GetText$(Edit&))
SetText Edit&,ans$ + "7"
elseif getfocus(acht&)
ans$ = Val(GetText$(Edit&))
SetText Edit&,ans$ + "8"
elseif getfocus(neun&)
ans$ = Val(GetText$(Edit&))
SetText Edit&,ans$ + "9"
elseif getfocus(null&)
ans$ = Val(GetText$(Edit&))
SetText Edit&,ans$ + "0"
elseif getfocus(plus&)
ans$ = Val(GetText$(Edit&))
SetText Edit&,ans$ + "+"
elseif getfocus(minus&)
ans$ = Val(GetText$(Edit&))
SetText Edit&,ans$ + "-"
elseif getfocus(mal&)
ans$ = Val(GetText$(Edit&))
SetText Edit&,ans$ + "*"
elseif getfocus(geteilt&)
ans$ = Val(GetText$(Edit&))
SetText Edit&,ans$ + "/"
elseif getfocus(komma&)
ans$ = Val(GetText$(Edit&))
SetText Edit&,ans$ + "."
elseif getfocus(clear&)
SetText Edit&,""
elseIf Getfocus(off&)
end
elseif getfocus(info&)
MessageBox("Title:\t\tTaschenrechner\t\nAutor:\t\tJulian Schmidt\nVersion:\t\t1.0\nErstellungsdatum:\t5.11.2010","I N F O",64)
elseif getfocus(del&)
SetText Edit&,ans$
elseif getfocus(gleich&)
ergebnis! = Val(GetText$(Edit&))
ans$ = ergebnis!
SetText Edit&,ans$
endif
endwhile
Außerdem würde ich gerne die Del-Funktion verbessern. Kann bisher nur ein Zeichen entfernen. Man müsste also aus einer Variable ein Zeichen abschneiden und den Wert dann neu übergeben. Für andere Verbesserungsvorschläge bin natürlich offen Naja Hoffe ihr könnnt mir bei meinen zwei anliegen einwenig helfen

mfg
Julian57 |
| | | ˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗ Webseite [...]  | 07.11.2010 ▲ |
| |
| | | | - Seite 3 - |
|  | « Dieser Beitrag wurde als Lösung gekennzeichnet. » | | - Seite 4 - |
|  Peter Max Müller |  
DEF CTStr(2) if(len($(2))=0,0,(len($(1))-len(translate$($(1),$(2),"")))/len($(2)))'zählt wie oft $2 in $1 vorkommt
DEF InStrExt(3) int(instr($(2),mid$($(1),&(3),len($(1))))+&(3))'sucht in $1 ab &3 nach $2
DEF InStrLast(3) if(instrext($(1),$(2),&(3))>&(3),instrlast($(1),$(2),instrext($(1),$(2),&(3))),int(&(3)-1))'sucht in $1 ab &3 nach dem letzen vorkommen von $2, arbeitet Rekursiv.
'Wenn man die Operatorzeichen ändern möchte braucht man nur die entsprechenden Zeichen ändern in den 2 folgenden Funktionen ändern
DEF MathTabs(2) translate$(translate$(translate$(translate$($(1),"+",$(2)),"-",$(2)),"*",$(2)),"/",$(2))
DEF GetMath(1) if($(1)="+",1,if($(1)="-",2,if($(1)="*",3,if($(1)="/",4,0))))
'Das Kernstück, so klein und doch ein ganzer Taschenrechner
'Funktioniert nur alleine wenn die Variablen aus Math Global gesetzt wurden (Ergebnis immer in ma_v1& !)
proc mathcore
parameters ma_cmd$
ma_s2$="«Æ»"'MathTabs-Zeichen = Beliebige Zeichenfolge die nicht im Ausdruck vorkommen sollte, sonst falsche Berechnung !
ma_s4$=mathtabs(ma_cmd$,ma_s2$)'MathTabs setzen
ma_s3$=""
ma_v1&=0
ma_v2&=1
whileloop ctstr(ma_s4$,ma_s2$)+1
ma_s3$=substr$(ma_s4$,&loop,ma_s2$)'Wert erfassen - Hier könnte man den Ausdruck zB. auf einen bestimmten Namen prüfen (für Variablen in Skriptsprachen).
ma_v1&=if(ma_v2&=0,ma_v1&,if(ma_v2&=1,ma_v1&+val(ma_s3$),if(ma_v2&=2,ma_v1&-val(ma_s3$),if(ma_v2&=3,ma_v1&*val(ma_s3$),if(val(ma_s3$)<1,ma_v3&,ma_v1&/val(ma_s3$))))))
ma_v2&=GetMath(mid$(ma_cmd$,len(ma_s3$)+1,1))
ma_cmd$=del$(ma_cmd$,1,len(ma_s3$)+1)
wend
endproc
'Berechnung mit Klammern
'Haupt-Prozedur die automatisch erst alle Klammern ausrechnet (wenn welche vorkommen)
proc math
parameters ma_prio$
declare ma_s1$,ma_s2$,ma_s3$,ma_s4$,ma_v1&,ma_v2&,ma_v3&,ma_v4&'bei häufiger Benutztung Global setzen (Ergebnis immer in ma_v1& !)
case or(instr(")",ma_prio$)<instr("(",ma_prio$),neq(ctstr(ma_prio$,"("),ctstr(ma_prio$,")"))):ma_prio$="0"'ungültige Klammersetzung: Wert auf Null setzen
whilenot ctstr(ma_prio$,"(")=0
ma_v3&=instr("(",ma_prio$)+1
ma_v4&=instrext(ma_prio$,")",ma_v3&)-1
ma_v3&=ma_v3&+instrlast(mid$(ma_prio$,ma_v3&,ma_v4&-ma_v3&),"(",1)'Klammern von Innen nach Außen auflösen
mathcore mid$(ma_prio$,ma_v3&,ma_v4&-ma_v3&)
ma_prio$=del$(ma_prio$,ma_v3&-1,ma_v4&-ma_v3&+2)
ma_prio$=ins$(str$(ma_v1&),ma_prio$,ma_v3&-1)
wend
mathcore ma_prio$
return ma_v1&
endproc
declare ed1%,bt1%
window 20,20-420,150
drawtext 5,5,"Berechnung eingeben... (+ Add ; - Sub ; / Div ; * Mul ; ( ) Prio)"
ed1%=create("edit",%hwnd,"5+(30*(4/2)+10)",5,25,400,21)'5+((10/2)*10)-30
bt1%=create("button",%hwnd,"Berechnen",5,50,400,40)
whilenot %key=2
waitinput
'XProfan
case getfocus(bt1%):messagebox("Ergebnis: "+str$(math(gettext$(ed1%))),"Ergebnis:",0)
''Profan 7:
'case getfocus(bt1%):math gettext$(ed1%)
'case getfocus(bt1%):messagebox("Ergebnis: "+str$(&(0)),"Ergebnis:",0)
wend
end
Das ganze ist in 2 Module aufgeteilt: Mathcore berechnet einen Ausdruck, Math rechnet zusätzlich zuerst alle Klammern aus.
Die Prozedur Math aufrufen !
Parameter: $ (Formel) Rückgabe: & (Ergebnis) |
| | | | |  |
| |  Dieter Zornow | In der Hilfe für 11.2 ist ein Taschenrechner als Beispiel. Lade die Hilfe runter wenn du sie nicht hast und gebe in der Suche Taschenrechner ein, da kannst du einiges abschauen. |
| | | Er ist ein Mann wie ein Baum. Sie nennen ihn Bonsai., Win 7 32 bit und Win 7 64 bit, mit XProfan X2 | 07.11.2010 ▲ |
| |
| |  Julian Schmidt | Danke schön werds mir mal anschauen |
| | | ˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗ Webseite [...]  | 07.11.2010 ▲ |
| |
| |  | Wobei ich jetzt aber nicht weiß ob Dieter weiß dasses Julian eher ums eval geht - was aber so oder so keine Sprolle ielt. ^^ |
| | | | |
| |  Julian Schmidt | Hallo hab mir jetzt mal den Taschenrechner in Hilfe angeschaut. Bin von den Teil allerdings nich sonderlich überzeugt. Rechnet so gut wie alle Aufgaben falsch. Beispiele Ich geb die Aufgabe 5*5+25 in den Rechner ein. Dann kommt komischerweise 30 raus, obwohl 50 richtig wäre. Bei leichten Aufgaben funzt es allerding (5+5 oder 60/3...) Außerdem hängt er sich öfters auf
Werd meinen dann doch mit dem Parsen schreiben. Wäre lieb wenn die die schon mal was mit Parsen gemacht haben einfach mal ihren Quellcode posten könnten.
Werde wenn ich fertig bin auch den Taschenrechner-Quellcode poste
mfg
Julian57 |
| | | ˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗ Webseite [...]  | 08.11.2010 ▲ |
| |
| |  | Wie ich das verstehe möchtest Du gerne den Code für einen Taschenrechner statt einen zu programmieren ... um dann den Code wiederum zu posten?! ^^
Gehe Stück für Stück vor und frage halt nach wenn Du nicht weiterkommst. |
| | | | |
| |  Julian Schmidt | nein, ich hätte nur gern ein Beispiel zum parsen |
| | | ˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗ Webseite [...]  | 08.11.2010 ▲ |
| |
| |  | Achso... KompilierenMarkierenSeparieren ... wäre vlt. die einfachste Variante.
Kann man bis ins "Unendliche" toppen und beschleunigen... aber für ein einfaches Eval... |
| | | | |
| |  Julian Schmidt | Hallo, in diesen post will ich erst mal alle Fragen stellen wo noch etwas unklar für mich ist
1. Wie findet man heraus an welcher Position der Operator(+,-./,*) liegt?
2. Wie kann man das machen das er von dem Rechenoperator nun solange es Ziffern sind nachrechts geht
und die Position des Zeichen vor dem Operator zwei in einer Variable speichern?
3. Wie kann man nun den ersten Part von Zeichen eins bis zum den Zeichen vor dem zweiten Operator auslesen?Und dann noch von Position des zweiten Operator bis ganz hinten?
4. Wie rechnet man Anschließend den ersten Teil der Aufgabe aus, und Hängt den Rest widerum dran und gibt das Ergebnis aus?
Ich hab mir das ganze dann so gedacht (Programm ist nur der Pasen Block, und funktioniert natürlich nicht. Habs nur geschrieben um schon mal eine Struktur zu haben) KompilierenMarkierenSeparieren
proc parsen
whilenot e%
waitinput
if getfocus(clear&)
SetText Edit&,""
rechnen
Elseif getfocus(off&)
Windowtitle "Auf Wiedersehen..."
Sleep 800
end
Else ifNot instr("*",ans$)=0
op1%=Position des ersten Operators(*)
Nun finde das Operator ab op1% und und und setze es als op2%
op2%=op2%-1
Teil1$=Del$(ans$,op2%,99)
op2%=op2%+1
Teil2$=Del$(ans$,1,op2%)
Nun rechne noch Teil1$ aus und überschreibe Teil1$
ans$=Teil1$ + Teil1$
ElseIF instr("*",ans$)=0 or instr("/",ans$)=0 or instr("-",ans$)=0 pr instr("+",ans$)=0
rechnen
Endif
parsen
Else ifNot instr("+",ans$)=0
op1%=Position des ersten Operators(+)
Nun finde das Operator ab op1% und und und setze es als op2%
op2%=op2%-1
Teil1$=Del$(ans$,op2%,99)
op2%=op2%+1
Teil2$=Del$(ans$,1,op2%)
Nun rechne noch Teil1$ aus und überschreibe Teil1$
ans$=Teil1$ + Teil1$
ElseIF instr("*",ans$)=0 or instr("/",ans$)=0 or instr("-",ans$)=0 pr instr("+",ans$)=0
rechnen
Endif
parsen
Else ifNot instr("/",ans$)=0
op1%=Position des ersten Operators(/)
Nun finde das Operator ab op1% und und und setze es als op2%
op2%=op2%-1
Teil1$=Del$(ans$,op2%,99)
op2%=op2%+1
Teil2$=Del$(ans$,1,op2%)
Nun rechne noch Teil1$ aus und überschreibe Teil1$
ans$=Teil1$ + Teil1$
ElseIF instr("*",ans$)=0 or instr("/",ans$)=0 or instr("-",ans$)=0 pr instr("+",ans$)=0
rechnen
Endif
parsen
Else ifNot instr("-",ans$)=0
op1%=Position des ersten Operators(-)
Nun finde das Operator ab op1% und und und setze es als op2%
op2%=op2%-1
Teil1$=Del$(ans$,op2%,99)
op2%=op2%+1
Teil2$=Del$(ans$,1,op2%)
Nun rechne noch Teil1$ aus und überschreibe Teil1$
ans$=Teil1$ + Teil1$
ElseIF instr("*",ans$)=0 or instr("/",ans$)=0 or instr("-",ans$)=0 pr instr("+",ans$)=0
rechnen
Endif
parsen
end
ElseIF instr("*",ans$)=0 or instr("/",ans$)=0 or instr("-",ans$)=0 pr instr("+",ans$)=0
rechnen//gehe zu Proc Rechnen
endIF
Endwhile
Endproc
Wenn irgendetwas falsch seien sollte bitte einfach posten. Hoffe ihr entfindet es nich als unhöflich das ich so viele Fragen stelle, oder so viele antworten erwarte. Es würd mir auch schon reichen wenn ihr mir einfach sagt mit welchen Befehl ich was anstellen kann.
mfg
Julian57 |
| | | ˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗ Webseite [...]  | 08.11.2010 ▲ |
| |
| |  | Zu 1: Wie schon oft geschrieben: Funktion Instr. Genaueres einfach der Hilfe entnehmen.
Zu 2: Z.B. per Vergleich des Ord-Wertes eines Zeichens, siehe hierzu Funktion Ord.
Zu 3: Mit einer Schleife wie oben.
Zu 4: Vlt. erstmal 1,2 & 3 erledigen.
Dein Code von eben scheint mir sinnlos zusammengewürfelt, setze Dir doch kleine Ziele und erstelle Funktionen die kleine Aufgaben erledigen damit Du die Übersicht bewahrst. KompilierenMarkierenSeparieren |
| | | | |
| |  Julian Schmidt | 1. Ok , habs jetzt verstanden das das Ergebnis also die Position ist 2. Zur Funktion "Ord" findet man in der Hilfe nicht sehr viel nur:
@Ord(S) S : String Ergebnis: Integer
Der ANSI-Code des ersten Zeichens von S. (Die Funktion entspricht der BASIC-Funktion Asc)
Wäre nett wenn du ein Beispiel postest (bitte mit Kommentaren arbeiten) 3. Hab ich ja schon so ziemlich oben gelöst^^. War mir nur nich ganz sicher ob es so geht
Dein Code von eben scheint mir sinnlos zusammengewürfelt, setze Dir doch kleine Ziele und erstelle Funktionen die kleine Aufgaben erledigen damit Du die Übersicht bewahrst.
Wollte nur erstmal eine Struktur erstellen um mich daran zu orientieren was ich mir für Ziele setzten kann |
| | | ˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗˗ Webseite [...]  | 08.11.2010 ▲ |
| |
| |  | | | | | |
| |  | Siehe auch Ansi-Tabelle: [...]  |
| | | | |
|
AntwortenThemenoptionen | 33.872 Betrachtungen |
ThemeninformationenDieses Thema hat 8 Teilnehmer: |