Taschenrechner

  • HeyHo,

    habe mal nur so aus Spaß nen Taschenrechner programmiert.
    Über Tipps, Feedback und Verbesserungsvorschläge würde ich mich freuen :)


    €: Habe den Code von 700+ ( ich weiß nicht mehr genau, wieviel es waren ) jetzt auf 255 Zeilen ( mit Leerzeilen ) gekürzt, :thumbup: bei gleichem Funktionsumfang 8o .


    €²: Soviele Besucher und Downloads, und so wenig Kommentare?? Kommt Leute, ich beiß nicht.


    Größte Änderungen:

    -mit Arrays gearbeitet ( DANKE an Bug-Fix für sein Tutorial :thumbup: )
    -alle Memory-Funktionen in eine Func gepackt
    -sqrt gibt jetzt direkt Ergebnis zurück ( zuvor wurde "sqrt(" ins Display geschrieben :S )
    -keine MsgBoxen mehr am Ende
    -Die Werte der Memory-Slots werden jetzt auch im Menü angezeigt


    Spoiler anzeigen
    [autoit]


    #include <GUIConstantsEx.au3>
    #include <String.au3>
    #include <GUIConstants.au3>
    #include <EditConstants.au3>
    #include <Array.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Global $hBlue = 0x003366 ; Hintergrundfarbe
    Global $nErgebnis, $bErsetzen, $iMode
    Global Const $nPi = 3.14159265
    Global $anMem[6], $anValue[6], $aSave[6], $aInsert[6], $aCopy[6], $AccelKeys[1][1]
    Global $arZiffern[10]
    Global $ar2D[10][2] = [["31", "225"],["31", "75"],["84", "75"], _
    ["137", "75"],["31", "125"],["84", "125"],["137", "125"],["31", "175"], _
    ["84", "175"],["137", "175"]]
    #Region GUI
    $main = GUICreate("Calculator", 300, 335)
    #Region Menu
    $memmenu = GUICtrlCreateMenu("Memory Functions")
    $memvaluemenu = GUICtrlCreateMenu("Value", $memmenu)
    For $i=1 to 5
    $anValue[$i]=GUICtrlCreateMenuItem("NOT in use", $memvaluemenu)
    Next
    $memselection = GUICtrlCreateMenu("Save into slot", $memmenu)
    For $i=1 to 5
    $aSave[$i]=GUICtrlCreateMenuItem($i, $memselection)
    Next
    $meminsert = GUICtrlCreateMenu("Insert", $memmenu)
    For $i=1 to 5
    $aInsert[$i] = GUICtrlCreateMenuItem($i, $meminsert)
    Next
    $memcopy = GUICtrlCreateMenu("Copy value to Clipboard", $memmenu)
    For $i=1 to 5
    $aCopy[$i] = GUICtrlCreateMenuItem($i, $memcopy)
    Next
    $memclear = GUICtrlCreateMenuItem("Clear all slots", $memmenu)
    $moremenu = GUICtrlCreateMenu("More")
    $sqrt = GUICtrlCreateMenuItem("Square root (sqrt)", $moremenu)
    $inscopy = GUICtrlCreateMenuItem("Copy value to clipboard", $moremenu)
    $insclip = GUICtrlCreateMenuItem("Insert content of clipboard ", $moremenu)
    $inspi = GUICtrlCreateMenuItem("Insert ' pi ' ", $moremenu)
    $aboutmenu = GUICtrlCreateMenu("About")
    $about = GUICtrlCreateMenuItem("About this program", $aboutmenu)
    #EndRegion Menu
    #Region Zahlen
    For $i = 0 To 9
    $arZiffern[$i] = GUICtrlCreateButton($i, $ar2D[$i][0], $ar2D[$i][1], 35, 35)
    Next
    #EndRegion Zahlen

    [/autoit] [autoit][/autoit] [autoit]

    #Region Sonstiges
    $del = GUICtrlCreateButton("DEL", 236, 30, 30, 30)
    $komma = GUICtrlCreateButton(",", 84, 225, 35, 35)
    $vorzeichen = GUICtrlCreateButton("±", 137, 225, 35, 35)
    $geteilt = GUICtrlCreateButton("÷", 196, 76, 30, 30)
    $mal = GUICtrlCreateButton("×", 196, 116, 30, 30)
    $minus = GUICtrlCreateButton("-", 196, 156, 30, 30)
    $plus = GUICtrlCreateButton("+", 196, 196, 30, 30)
    $clear = GUICtrlCreateButton("CLR", 196, 236, 30, 30)
    $hoch = GUICtrlCreateButton("^", 236, 76, 30, 30)
    $klammerauf = GUICtrlCreateButton("(", 236, 116, 30, 30)
    $klammerzu = GUICtrlCreateButton(")", 236, 156, 30, 30)
    $hoch2 = GUICtrlCreateButton("x²", 236, 196, 30, 30)
    $gleich = GUICtrlCreateButton("=", 236, 236, 30, 30)
    $rahmencopy = GUICtrlCreateLabel("0", 32, 275, 130, 34, 0x07)
    $copyright = GUICtrlCreateLabel("(c) by Mario Eckert", 50, 280, 100, 25)
    $disp = GUICtrlCreateInput("", 50, 25, 165, 30, $GUI_SS_DEFAULT_INPUT)
    #EndRegion Sonstiges
    GUISetState(@SW_SHOW)
    $font = "Comic Sans MS"
    GUICtrlSetFont($disp, "16", 400, "", $font)
    GUICtrlSetFont($copyright, 14, 400, 4, $font)
    GUISetBkColor($hBlue)
    GUICtrlSetState($disp, $GUI_FOCUS)
    Dim $aAccelKeys[1][2] = [["{ENTER}", $gleich]]
    GUISetAccelerators($aAccelKeys)
    #EndRegion GUI

    [/autoit] [autoit][/autoit] [autoit]

    #Region Funcs
    Func _check(); Checken, ob aktuelle Anzeige überschrieben werden soll
    $nRead = GUICtrlRead($disp)
    If $nRead == $nErgebnis Then;falls Anzeige = Ergebnis soll eine neue Rechnung gestartet werden
    Global $bErsetzen = True;also werden wir nachher die Anzeige überschreiben
    Else;ansonsten wird die Zahl hinter die aktuelle Anzeige gesetzt...
    Global $bErsetzen = False
    EndIf
    EndFunc ;==>_check

    [/autoit] [autoit][/autoit] [autoit]

    Func _add($char)
    _check()
    If $bErsetzen = False Then
    GUICtrlSetData($disp, GUICtrlRead($disp) & $char)
    Else
    GUICtrlSetData($disp, $char)
    EndIf
    EndFunc ;==>_add

    [/autoit] [autoit][/autoit] [autoit]

    Func _vorzeichen()
    $nRead = GUICtrlRead($disp)
    $left = StringLeft($nRead, "1");erstes Zeichen von links
    If $left == "-" Then;falls das erste Zeichen von links ein Minus ('-') ist
    $changed = StringReplace($nRead, "-", "");wird es gelöscht
    GUICtrlSetData($disp, $changed)
    Else;ansonsten
    GUICtrlSetData($disp, "-" & GUICtrlRead($disp));wird ein Minus vor die erste Zahl gesetzt
    EndIf
    EndFunc ;==>_vorzeichen
    #Region Sonstiges
    #Region Memory
    Func _memory($sAction, $i="")
    Switch $sAction
    Case "save"
    If $anMem[$i] == "" Then ;noch nicht benützt
    _ArrayInsert($anMem, $i, $nErgebnis)
    MsgBox(64, "Memory", "Succesfully saved '" & $nErgebnis & " ' into Memoryslot " & $i)
    GUICtrlSetData($anValue[$i], $anMem[$i])
    Else ; wurde schon beschrieben
    $iAnswer = MsgBox(292, "Already in use", "Memory slot A already contains something. Would you like to owerwrite the information?")
    Switch $iAnswer
    Case 6 ;Yes Button gedrückt
    _calc()
    _ArrayInsert($anMem, $i, $nErgebnis)
    MsgBox(64, "Memory", "Succesfully saved '" & $nErgebnis & " ' into Memoryslot ")
    GUICtrlSetData($anValue[$i], $anMem[$i])
    Case 7 ;No Button gedrückt
    EndSwitch
    EndIf
    Case "insert"
    If $anMem[$i] == "" Then
    MsgBox(16, "Not in use", "Memory Slot " & $i & "is NOT in use!")
    Else
    GUICtrlSetData($disp, GUICtrlRead($disp) & $anMem[$i])
    EndIf
    Case "copy"
    If $anMem[$i] == "" Then
    MsgBox(16, "Not in use", "Memory Slot " & $i & "is NOT in use!")
    Else
    ClipPut($anMem[$i])
    EndIf
    Case "clear"
    $iAnswer = MsgBox(305, "Clear Memory?", "All information will be deleted.")
    If $iAnswer == 1 Then
    For $i = 1 To 5
    $anMem[$i] = ""
    Next
    EndIf
    EndSwitch
    EndFunc ;==>_memory
    #EndRegion Memory
    Func _inscopy()
    $nRead = GUICtrlRead($disp)
    ClipPut($nRead)
    EndFunc ;==>_inscopy

    [/autoit] [autoit][/autoit] [autoit]

    Func _insclip()
    $sClip = ClipGet()
    $nConverted = StringRegExpReplace($sClip, "[^0123456789*/+-^()]", "");aussortieren
    If @error Then MsgBox(16, "Error", "Error: Clipboard contains invalid data!")
    GUICtrlSetData($disp, $nConverted)
    EndFunc ;==>_insclip

    [/autoit] [autoit][/autoit] [autoit]

    Func _inspi()
    _check()
    If $bErsetzen = False Then
    GUICtrlSetData($disp, GUICtrlRead($disp) & $nPi)
    Else
    GUICtrlSetData($disp, $nPi)
    EndIf
    EndFunc ;==>_inspi

    [/autoit] [autoit][/autoit] [autoit]

    Func _calc($iMode = 1)
    $nRead = GUICtrlRead($disp);Anzeige
    If $iMode = "sqrt" Then
    Global $nErgebnis = Execute("sqrt(" & StringRegExpReplace(StringReplace($nRead, ",", "."), "[^0123456789*/+-/^()]", "") & ")"); Wurzel von Display
    Else
    Global $nErgebnis = Execute(StringRegExpReplace(StringReplace($nRead, ",", "."), "[^0123456789*/+-/^()]", ""));rechnen
    EndIf
    If @error == 1 Then ; Fehler
    MsgBox(16, "Error", "Couldn't calculate this expression!" _
    & @CRLF & "Please check for syntax or other mistakes!" _
    & @CRLF & "Expression was:" & $nRead, 15)
    EndIf
    GUICtrlSetData($disp, $nErgebnis); anzeigen
    EndFunc ;==>_calc

    [/autoit] [autoit][/autoit] [autoit]

    Func _dellast() ; letztes Zeichen löschen
    $nRead = GUICtrlRead($disp);Anzeige
    GUICtrlSetData($disp, StringTrimRight($nRead, 1));Rechts ein Zeichen löschen
    EndFunc ;==>_dellast

    [/autoit] [autoit][/autoit] [autoit]

    Func _about()
    MsgBox(64, "About...", "This calculator was coded by Mario Eckert." & @CRLF & _
    "Any changes or using without permission are strictly forbidden!" & @CRLF & _
    "(c) 2009 Mario Eckert")
    EndFunc ;==>_about
    #EndRegion Sonstiges
    #EndRegion Funcs
    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit
    Case $del
    _dellast()
    Case 36 To 45;0 bis 9
    _add($nMsg-36)
    Case $komma
    _add(".")
    Case $vorzeichen
    _vorzeichen()
    Case $plus
    _add("+")
    Case $minus
    _add("-")
    Case $mal
    _add("*")
    Case $geteilt
    _add("/")
    Case $clear
    GUICtrlSetData($disp, "");Anzeige wird gelöscht
    Case $hoch
    _add("^")
    Case $klammerauf
    _add("(")
    Case $klammerzu
    _add(")")
    Case $hoch2
    _add("^2")
    Case $gleich
    _calc()
    Case 11 To 15;Save to Slot 1-5
    _memory("save", $nMsg - 10)
    Case 17 To 20; Insert
    _memory("insert", $nMsg - 16)
    Case 23 To 27; Copy to Clip
    _memory("copy", $nMsg - 22)
    Case $memclear
    _memory("clear")
    Case $inscopy
    _inscopy()
    Case $inspi
    _inspi()
    Case $insclip
    _check()
    _insclip()
    Case $sqrt
    _calc("sqrt")
    Case $about
    _about()
    EndSwitch
    WEnd

    [/autoit]

    8 Mal editiert, zuletzt von Miraculi (6. Juni 2009 um 14:58)

  • Hallo Miraculi,

    tolle Leistung :thumbup: , vor allem das mit den Memoryfunktionen hat mir imponiert. Wenn du etwas mehr Erfahrung mit AutoIt hast wirst du zwar bemerken, dass du dir einige Zeilen Tipparbeit einsparen gekonnt hättest.
    Ich seh zwar in deinem Skript, dass du Komma zu Punkt wandelst, die Routine scheint aber nicht angesprungen zu werden.

    mfg (Auto)Bert

  • Hallo Miraculi,
    Ich seh zwar in deinem Skript, dass du Komma zu Punkt wandelst, die Routine scheint aber nicht angesprungen zu werden.

    mfg (Auto)Bert

    Hallo Bert,

    vielen Dank für das Lob.
    Die Umwandlung wird doch durch folgenden Code gelöst sein, oder?

    [autoit]


    $nRead = GUICtrlRead($disp);Anzeige
    $nToCalc=StringReplace($nRead,",",".")
    Global $nErgebnis = Execute($nToCalc);rechnen

    [/autoit]
  • Hey Ho.. ja fürs erste Script ist es doch nicht schlecht! :thumbup:
    Mit dem Komma in Punkt umwandeln geht bei mir.. Trotzdem ein paar kleine Anmerkungen:
    Und der +/- Button ist spitze :D

    - Für einen Taschenrechner den ich ja eig nur nebensächlich ist, ist er einen tick zu groß und platzverschwendend
    - Am Ende kommen 2 nervende MsgBoxen.. sowas würde ich in die Credits schreiben
    - Die Memory-Funcs sind zwar sehr schön, aber ich persöhnlich kann mir nicht 5 Blöcke auf einmal merken..
    Ich würde auch immer den aktuellen Wert hinter den Buchstaben schreiben.
    - Und wie AutoBert schon sagte, man könnte dein Script sehr viel kürzen (Ich schätze mal so um 300++ Zeilen)

  • Hallo Miraculi,

    ich habe beim überfliegen des Skriptes diese Func gesehen

    [autoit]

    Func _komma()
    GUICtrlSetData($disp, GUICtrlRead($disp) & ".");Execute erwartet '.', nicht ','
    EndFunc ;==>_komma

    [/autoit]

    und dachte du würdest hier Koma gegen Punkt tauschen, dass klappt aber nur bei Bedienung mit der Maus. Beim Eingeben über Tastatur bekomme ich für 3.5 * 4,5 als Ergebnis 14

    Zitat

    vielen Dank für das Lob.
    Die Umwandlung wird doch durch folgenden Code gelöst sein, oder?

    [autoit]

    $nRead = GUICtrlRead($disp);Anzeige
    $nToCalc=StringReplace($nRead,",",".")

    [/autoit]


    Wenn ich diese beiden Zeilen in die Func _calc einbaue rechnet er obiges Beispiel richtig Ergebnis: 15.75

    den Vorschlag von @ChaosKeks mit den MemorySlots find ich auch sehr gut. Das man auf sein erstes (veröffentlichtes) Programm stolz ist (und das mit Recht :thumbup: ) und es mit MsgBoxen anzeigt find ich verständlich,

    mfg (Auto)Bert

  • Hi,

    [autoit]


    $ergebnis = _StringAddThousandsSep(StringReplace(Execute(StringReplace($read, ",", ".")), ".", ","))

    ; ### Ablauf von Innen nach Aussen ###
    ; Erstest StringReplace > wandeln der eingegebenen Kommata von $read in Dezimalpunkte
    ; Execute > ausführen der Berechnung
    ; Zweites StringReplace > wandeln der Dezimalpunkte der Berechnung von $read ausgeben in Kommata
    ; _StringAddThousandsSep > Ausgabe mit Tausenderpunkt
    ; ### $ergebnis = _StringAddThousandsSep(StringReplace(Execute(StringReplace($read, ",", ".")), ".", ",")) ###

    [/autoit]


    Edit: Link eingefügt. ;)
    Taschenrechner
    Viel Erfolg ! :thumbup:

  • Zitat

    _StringAddThousandsSep > Ausgabe mit Tausenderpunkt

    Das hatte ich mir auch überlegt, mich aber bewusst dagegen entschieden. Das ist zwar übersichtlicher, aber wenn man dann C&P macht irgendwie ziemlich doof. Ich werde das einfach so lassen, trotzdem danke :D

    €: Wie kann man es machen, dass der Cursor automatisch in dem Input ist, so dass man sofort lostippen kann?

    Einmal editiert, zuletzt von Miraculi (4. Juni 2009 um 12:08)

  • [autoit]

    GuiCtrlSetState(-1,$GUI_FOCUS)

    [/autoit]


    Da du aber im MessageMode gearbeitet hast, bieten sich Accelerators ganz gut an ;)

  • Danke, hat geklappt. :D
    Verstehe aber nicht ganz, wieso die Accelerators sich anbieten sollten. Die weisen einem Control doch einfach nur einen HotKey zu, oder?

  • Update, siehe erster Post :rock:
    @ChaosKeks:
    Jetzt hab ich das verstanden und eingebaut, danke ;)

  • Hallo,

    das hatte ich schon verstanden :D
    ( Siehe Post 2+3 )

    Einmal editiert, zuletzt von Miraculi (5. Juni 2009 um 20:35)

  • Ich glaube Dateianhang (.au3) und Spoiler sind ungleich ?
    Ein Beispiel von mir: Array für die Zahlen

    Spoiler anzeigen
    [autoit]


    ; SB_Taschenrechner_by_Simon
    #include <WindowsConstants.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Dim $arZiffern[10]

    [/autoit] [autoit][/autoit] [autoit]

    GUICreate("SB Taschenrechner", 320, 140, Default, Default, $WS_POPUP + $WS_BORDER)
    GUISetBkColor(0xCDAD00)

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 0 To 9
    $arZiffern[$i] = GUICtrlCreateButton($i, 10 + $i * 30, 40, 30, 30)
    Next

    [/autoit] [autoit][/autoit] [autoit]

    GUISetState()

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    Switch GUIGetMsg()
    Case - 3
    Exit
    EndSwitch
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    ; Ende

    [/autoit]


    siehe auch hier:
    Taschenrechner

  • Hallo,

    jo, du hast recht, Source ist der gekürzte, .au3 die alte Version. Denke, dass man das ja auch eben schnell in SciTe kopieren kann :D
    Leider sind bei dir die Zahlen alle nebeneinander, was nicht der üblichen Form für Taschenrechner entspricht... ;)


    €: Hab dem Verständnis wegen jetzt mal die .au3 rausgenommen...

  • Leider sind bei dir die Zahlen alle nebeneinander, was nicht der üblichen Form für Taschenrechner entspricht... ;)

    Siehe mal hier, nun habe ich doch tatsächlich die Zahlen durcheinander gebracht ! ;)

    Spoiler anzeigen
    [autoit]


    ; calcnew_by_Mario_Eckert

    [/autoit] [autoit][/autoit] [autoit]

    Global $arZiffern[10]
    Global $ar2D[10][2] = [["31", "225"],["31", "75"],["84", "75"], _
    ["137", "75"],["31", "125"],["84", "125"],["137", "125"],["31", "175"], _
    ["84", "175"],["137", "175"]]

    [/autoit] [autoit][/autoit] [autoit]

    $main = GUICreate("Calculator", 300, 335)
    GUISetBkColor(0x003366) ;i blue

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 0 To 9
    $arZiffern[$i] = GUICtrlCreateButton($i, $ar2D[$i][0], $ar2D[$i][1], 35, 35)
    Next

    [/autoit] [autoit][/autoit] [autoit]

    GUISetState()

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    Switch GUIGetMsg()
    Case - 3
    Exit
    EndSwitch
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    ; Ende

    [/autoit] [autoit][/autoit] [autoit]

    ;$0 = GUICtrlCreateButton ("0", 31, 225, 35, 35)
    ;$1 = GUICtrlCreateButton ("1", 31, 75, 35, 35)
    ;$2 = GUICtrlCreateButton ("2", 84, 75, 35, 35)
    ;$3 = GUICtrlCreateButton ("3", 137, 75, 35, 35)
    ;$4 = GUICtrlCreateButton ("4", 31, 125, 35, 35)
    ;$5 = GUICtrlCreateButton ("5", 84, 125, 35, 35)
    ;$6 = GUICtrlCreateButton("6", 137, 125, 35, 35)
    ;$7 = GUICtrlCreateButton ("7", 31, 175, 35, 35)
    ;$8 = GUICtrlCreateButton ("8", 84, 175, 35, 35)
    ;$9 = GUICtrlCreateButton("9", 137, 175, 35, 35)

    [/autoit]


    Viel Erfolg ! :)

  • Und der +/- Button ist spitze :D

    Also, erstmal sehr gut gemacht den Rechner!!!! Aber der +/- Button ist ein bisschen falsch, da er nur das Vorzeichen der 1. Zahl ändern kann und nicht das der 2. oder 3. Zahl. Eigentlich langt da ja auch, wenn man das normale + oder - nimmt. So habe ich es bei meinem Rechner auch gelassen, den ich mal programmiert habe.

  • Der Taschenrechner ist echt super.
    Du könntest noch ein paar Functionen hinzufügen.
    z.B Tan() Sin() cos() aCos() aSin() usw.
    Dann ist er bald besser als der von Windows, schöner ist er ja schon.

    MFG Lotus
    :thumbup:

  • Also, erstmal sehr gut gemacht den Rechner!!!! Aber der +/- Button ist ein bisschen falsch, da er nur das Vorzeichen der 1. Zahl ändern kann und nicht das der 2. oder 3. Zahl. Eigentlich langt da ja auch, wenn man das normale + oder - nimmt. So habe ich es bei meinem Rechner auch gelassen, den ich mal programmiert habe.


    Also, erstmal danke für das Lob!!!
    Bei allen Taschenrechnern, die ich kenne macht der Button / Knopf /w/e auch nur genau das :P . Ich weiß gar nicht, wie das anders funktionieren soll :huh:

    @Lotus:

    Auch dir herzlichen Dank für dein Lob ;)
    Da kümmer ich mich später drum, ich bin von meinem jetztigen Projekt voll in Anspruch genommen :D