Und noch einmal: der Taschenrechner

  • VB.NET

Es gibt 15 Antworten in diesem Thema. Der letzte Beitrag () ist von Dizzy.

    Und noch einmal: der Taschenrechner

    Guten Tag Liebe vb-paradise Community,

    zurzeit mache ich meine Ausbildung als Fachinformatiker für Anwendungsentwicklung.
    Meine Firma hat mich direkt ins kalte Wasser geschmissen, ich soll einen Konsolen-Taschenrechner in VBnet programmieren.
    Ich habe vorher noch nie etwas mit VBnet gemacht.
    Also habe ich mich drangesetzt und erstmal einen einfachen Taschenrechner entworfen, der die Grundrechenarten rechnen kann, aber lediglich mit zwei Zahlen rechnen kann.
    Hier der Quelltext:

    VB.NET-Quellcode

    1. Imports System.Threading
    2. Module Module1
    3. Sub Main()
    4. Console.WriteLine("---------------------------")
    5. Console.WriteLine("Taschenrechner V1.0")
    6. Console.WriteLine("---------------------------")
    7. Console.WriteLine("Die Operatoren sind: +, -, *, / und ^")
    8. Console.WriteLine("---------------------------")
    9. Dim xkey As New ConsoleKeyInfo()
    10. Do
    11. Dim z1 As Double
    12. Dim z2 As Integer
    13. Dim e1 As String
    14. Dim e2 As String
    15. Dim oper As String
    16. System.Console.WriteLine("Zahl 1: ")
    17. e1 = System.Console.ReadLine()
    18. If FormatNumber(e1) = True Then
    19. z1 = e1
    20. Else
    21. System.Console.WriteLine("Die Eingabe ist keine Ganzzahl!")
    22. End If
    23. System.Console.WriteLine("Eingabe1:" & z1)
    24. System.Console.WriteLine("Operator ")
    25. oper = Console.ReadLine()
    26. System.Console.WriteLine("Zahl 2: ")
    27. e2 = System.Console.ReadLine()
    28. If FormatNumber(e2) = True Then
    29. z2 = e2
    30. Else
    31. System.Console.WriteLine("Die Eingabe ist keine Ganzzahl!")
    32. End If
    33. Dim rechnung As Double
    34. Select Case oper
    35. Case "+"
    36. rechnung = z1 + z2
    37. Console.WriteLine(" = " & rechnung)
    38. Case "-"
    39. rechnung = z1 - z2
    40. Console.WriteLine(" = " & rechnung)
    41. Case "*"
    42. rechnung = z1 * z2
    43. Console.WriteLine(" = " & rechnung)
    44. Case "/"
    45. rechnung = z1 / z2
    46. Console.WriteLine(" = " & rechnung)
    47. Case Else
    48. Console.WriteLine("Falsche Eingabe!")
    49. End Select
    50. Console.WriteLine("Wollen Sie das Programm erneut rechen lassen? J/N")
    51. Do
    52. Wiederholung:
    53. Select Case Console.ReadLine
    54. Case "n"
    55. Exit Sub
    56. Case "N"
    57. Exit Sub
    58. Case "j"
    59. Exit Do
    60. Case "J"
    61. Exit Do
    62. Case Else
    63. Console.WriteLine("Ungültige Eingabe!")
    64. GoTo Wiederholung
    65. End Select
    66. Loop
    67. Loop
    68. End Sub
    69. End Module


    Mein Problem dabei ist aber, dass die Eingabe nur in einer Zeile erfolgen soll.
    Also habe ich meinen Taschenrechner umgeschrieben. Ein Arbeitskollege meinte ich könnte den String dann in Listen zerlegen lassen.
    Also habe ich zuerst eine Liste mit Operatoren erstellt, die ich zum splitten der Eingabe nutze, um nur die Zahlen aus der Eingabe zu bekommen.
    Soweit so gut, das klappt und alle Zahlen sind nun in der Liste. Nun habe ich die Eingabe noch ein zweites mal gesplittet, aber nun mit den Zahlen aus der eben erstellten Liste.
    Nun komme ich nicht weiter. Wie kann ich denn jetzt mit diesen beiden String-Listen rechnen?(Ich weiß mit Strings rechnet man nicht :saint: )
    Code:

    VB.NET-Quellcode

    1. Module module1
    2. Sub Main()
    3. Console.WriteLine("---------------------------")
    4. Console.WriteLine("Taschenrechner V1.0")
    5. Console.WriteLine("---------------------------")
    6. Console.WriteLine("Die Operatoren sind: +, -, *, / und ^")
    7. Do
    8. Dim eingabe As String
    9. Dim operant As New List(Of String)
    10. operant.Add("+")
    11. operant.Add("-")
    12. operant.Add("/")
    13. operant.Add("*")
    14. operant.Add("^")
    15. operant.Add("(")
    16. operant.Add(")")
    17. Console.WriteLine(" ----------------------- ")
    18. 'Eingabe
    19. Console.WriteLine("Ihre Rechnung ")
    20. eingabe = Console.ReadLine
    21. Dim zahlen As List(Of Double) = New List(Of Double)(eingabe.Split(operant.ToArray(), StringSplitOptions.None))
    22. Dim operant2 As List(Of String) = New List(Of String)(eingabe.Split(zahlen.ToArray(), StringSplitOptions.RemoveEmptyEntries))
    23. Console.WriteLine("--")
    24. Dim zaehler As Integer = 0
    25. Dim value As List(Of Double) = New List(Of Double)
    26. 'While (laenge > zaehler)
    27. ' value.Add(Double.Parse(zahlen(zaehler)))
    28. ' zaehler += 1
    29. ' Console.WriteLine(zahlen)
    30. 'End While
    31. 'Hier wird die Berechnungen gemacht.
    32. Dim zwischenergebnis As Double
    33. 'Select Case operant2
    34. ' Case "+"
    35. ' zwischenergebnis = zahlen(0) + zahlen(1)
    36. ' Case "-"
    37. ' zwischenergebnis = zahlen(0) + zahlen(1)
    38. ' Case "/"
    39. ' zwischenergebnis = zahlen(0) + zahlen(1)
    40. ' Case "*"
    41. ' zwischenergebnis = zahlen(0) + zahlen(1)
    42. 'End Select
    43. Console.WriteLine("--------------")
    44. Console.WriteLine("Ergebnis: " & zwischenergebnis)
    45. Console.WriteLine("--------------")
    46. 'Wiederholung oder Abbruch des TR
    47. Console.WriteLine("Soll Wierderholt werden? J/N")
    48. Do
    49. Wiederholung:
    50. Select Case Console.ReadLine
    51. Case "n"
    52. Exit Sub
    53. Case "N"
    54. Exit Sub
    55. Case "j"
    56. Exit Do
    57. Case "J"
    58. Exit Do
    59. Case Else
    60. Console.WriteLine("Ungültige Eingabe!")
    61. GoTo Wiederholung
    62. End Select
    63. Loop
    64. Loop
    65. End Sub
    66. End Module


    Ich hoffe das ist nicht völliger Blödsinn ist, den ich da produziert habe. :huh:
    Habe mich durch viele Foren gearbeitet und versucht zu verstehen, wie man das ändern könnte, aber ich habe einfach nichts brauchbares für die Konsole gefunden.
    Mir wurde auch die Compute() Methode gesagt, aber diese braucht ja eine Datatable. Verstehe da nocht nicht ganz wie das funktioniert.

    Ich hoffe ihr seit jetzt nicht alzu genervt, da es bestimmt schon der 500. Taschenrechner ist, den ihr gesehen habt. :/
    Hoffentlich könnt ihr mir behilflich sein.

    mastermc
    Die Aufgabe ist so bescheuert, dass sie eiglich ein Grund ist, die Firma zu wechseln.
    1. Es ist ganz ausgeschlossen, dass ein Newbie einen Parser schreibt, der mathematische Ausdrücke korrekt auswertet.
      Beispiele: 2 + 3 * 4 und (2 + 3) * 4 - da wirst du dich dumm und dämlich dran programmieren
    2. Die Vorgabe "Konsole" ist abartig, du wirst wahrscheinlich nie Leben eine Konsolen-Anwendung schreiben müssen, weil Konsolen-Anwendungen mutet man keinem User zu.
      Warum nicht richtig anfangen, mit WinForms und Textboxen und Buttons aufs Form klatschen, und dann mit Logik hinterlegen?
      Das ist sowohl leichter zu lösen als auch praxisnäher.
    Zu deim Problem:
    Scheinbar parst du ja bereits Token, nämlich Zahlen und Operatoren (und sogar Klammern seh ich - vmtl. denkst du, das seien auch Operatoren - sind es nicht)
    Aber mit 2 Listen geht das nicht, du musst iwie Datensätze schaffen, wo ein Operator mit 2 Zahlen verknüpft wird.
    Tatsächlich wird ein Operator nicht mit 2 Zahlen verknüpft, sondern mit 2 Ausdrücken, und jeder Ausdruck kann selbst wieder Zahlen und/oder Operatoren enthalten (Klammern jetzt mal beiseite gelassen).

    Also wenn das Thema dich interessiert, such mal nach "Formelparser" in den Tipps&Tricks.
    Aber wie gesagt: Für einen Anfänger ist das nicht zu bewältigen, und wer solche Aufgaben stellt, ist offenbar nicht kompetent genug, das abzuschätzen.
    Hi und willkommen in diesem Forum!

    Was mir gleich aufgefallen ist: GoTo
    Sollte nicht mehr verwendet werden(Spaghettigcode).

    Zweitens(hängt damit zusammen: VB.NET ist NICHT casesensitiv, d.h es ist egal ob "j" oder "J" bzw "n" oder "N".
    Also mach

    VB.NET-Quellcode

    1. Do
    2. If Console.ReadLine() = "J"
    3. Exit Do
    4. Else
    5. Exitm Sub
    6. End If
    7. End Do


    Lg Radinator
    In general (across programming languages), a pointer is a number that represents a physical location in memory. A nullpointer is (almost always) one that points to 0, and is widely recognized as "not pointing to anything". Since systems have different amounts of supported memory, it doesn't always take the same number of bytes to hold that number, so we call a "native size integer" one that can hold a pointer on any particular system. - Sam Harwell
    Mich würde mal die exakte Aufgabenstellung interessieren... hieß es schlichtweg "mach nen Taschenrechner inner Konsole" oder haste da was genaueres dazu? Und wurde dir die Aufgabe von irgendeinem Programmierer gegeben, oder gibts da nen expliziten Ausbildungsbeauftragten, der sich "nur" um die Azubis kümmert?
    @ErfinderDesRades
    ich finde die Aufgabe genauso bescheuert, aber sie soll eldiglich als Übungsaufgabe für die 2. Aufgabe dienen.(dann in Windows Form)^^

    Ja ich habe gedacht, dass man Klammern auch als Operatoren ansieht. :whistling:
    Ich werde mich dem wohl dann nicht witmen, habe so viele Beiträge schon gelesen, wo genau das gleich drin steht, was du auch eben geschrieben hast.
    Danke für deine Antwort! :)

    @Radinator
    Okay danke, das wusste ich nicht!
    Habe es mit reingeschrieben!

    @EaranMaleasi
    Erstmal: Cooler Avatar :) (Habe SAO erst diesen Monat entdeckt und bin direkt süchtig!)
    die genaue Aufgabenstellung lautet:

    Erstelle den Taschenrechner als ausführbare Konsolenanwendung
    Der Taschenrechner soll über folgende Merkmale verfügen:
    - Beherrschung der 4 Grundrechenarten
    - Eingabe über die Tastatur
    - Ausgabe des Ergebnisses
    - Beendigung des Programms mit der Taste "X" jederzeit möglich
    - Abbruch der aktuellen Rechnung mit der Taste "E" jederzeit möglich
    - Die ganze Rechenoperation in einer Zeile, die mit <Enter> abegschlossen wird
    - Das Ergebnis wird in einer neuen Zeile ausgegeben

    Die Aufgabe wurde mir vom Abteilungsleiter 'Entwicklung' gestellt.
    Willkommen im Forum. :thumbup:

    mastermc schrieb:

    Konsolen-Taschenrechner

    ErfinderDesRades schrieb:

    Die Aufgabe ist so bescheuert, dass sie eiglich ein Grund ist, die Firma zu wechseln.
    Sagt alles.
    Wahrscheinlich will Dein Chef Dir in einem Crash-Kurs VB beibringen.
    Console ist absoluter Mist für diese Aufgabenstellung, Du solltest nachbessern und zumindest eine WinForms-Anwendung machen dürfen.
    Oder frag ihn, ob Du in Z80-Assembler programmieren darfst. :thumbsup:
    Und: Mach Dir für jede kleinere in sich geschlossene Teilaufgabe ein Unterprogramm, z.B.
    • einen numerischen Wert auslesen
    • einen Operator auslesen
    • ein Ergebnis anzeigen
    usw.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @mastermc

    Ich würde die Klammern weg lassen.

    Die einfachste lösung wäre ein eingabewechsel
    "Bitte geben Sie eine Zahl ein"
    "Bitte geben Sie einen Operator ein"
    "Bitte geben Sie eine Zahl ein"
    ....
    Bei Jeder eingabe auf "X","E" Prüfen zum Beenden/Löschen und auf "ENTER" zum Berechnen.

    Damit wäre die Aufgabe erfüllt und du könntest mit etwas "wichtigerem" weiter machen :)
    There is no CLOUD - just other people's computers

    Q: Why do JAVA developers wear glasses?
    A: Because they can't C#

    Daily prayer:
    "Dear Lord, grand me the strength not to kill any stupid people today and please grant me the ability to punch them in the face over standard TCP/IP."

    Artentus schrieb:

    Dass der VB-Compiler Bezeichner caseinsensitive auswertet hat rein gar nichts mit Stringvergleichen zu tun. Diese verhalten sich in alle .Net-Sprachen gleich, nämlich casesensitive, außer du gibts explizit etwas anderes an.


    Ging ja auch nur darum, dass ich zeigen wollte dass man kein GoTo+Select Case braucht :D
    In general (across programming languages), a pointer is a number that represents a physical location in memory. A nullpointer is (almost always) one that points to 0, and is widely recognized as "not pointing to anything". Since systems have different amounts of supported memory, it doesn't always take the same number of bytes to hold that number, so we call a "native size integer" one that can hold a pointer on any particular system. - Sam Harwell

    mastermc schrieb:

    Der Taschenrechner soll über folgende Merkmale verfügen:
    1. - Beherrschung der 4 Grundrechenarten
    2. - Eingabe über die Tastatur
    3. - Ausgabe des Ergebnisses
    4. - Beendigung des Programms mit der Taste "X" jederzeit möglich
    5. - Abbruch der aktuellen Rechnung mit der Taste "E" jederzeit möglich
    6. - Die ganze Rechenoperation in einer Zeile, die mit <Enter> abegschlossen wird
    7. - Das Ergebnis wird in einer neuen Zeile ausgegeben
    Ok, dann mach was, was nur 2 Zahlen und 1 Operator akzeptiert, und alles andere ablehnt - das ist leistbar.
    In der Aufgabe steht ja nix von von Klammer-Logik und Berücksichtigung von Operator-Vorrängen.
    Wenner das zuwenig findet, frag ihn, ob er ehrlich meint, du sollest jetzt den Shunting-Yard-Algorithmus implementieren für die Konversion von Infix -> Postfix, und dann noch die stack-orientierte Evaluation der nach postfix-Logik angeordneten Token.
    Man darf gespannt sein, ob der ShuntingYard ihm ühaupt bekannt ist.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „ErfinderDesRades“ ()

    ErfinderDesRades schrieb:

    ühaupt bekannt ist.
    Oder umgekehrte polnische Notation. :D
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Die Aufgabe ist so abartig, dass ich gleich mal ein par Zeilen zusammen geschustert habe!
    Ohne GoTo und Exit Do!

    VB.NET-Quellcode

    1. Option Strict On
    2. Module Module1
    3. Sub Main()
    4. Dim Eingabe As String = "N"
    5. Dim x As Double
    6. Dim y As Double
    7. While Eingabe <> "X"
    8. Console.WriteLine("Zahl 1")
    9. x = CDbl(Console.ReadLine())
    10. Console.WriteLine("Zahl 2")
    11. y = CDbl(Console.ReadLine())
    12. Console.WriteLine("Operator oder mit X beenden!")
    13. Eingabe = Console.ReadLine()
    14. Console.WriteLine("-----------")
    15. Console.WriteLine("Ergebnis")
    16. Console.WriteLine(Ergebnis(x, y, Eingabe))
    17. Console.WriteLine("-----------")
    18. End While
    19. End Sub
    20. Function Ergebnis(Zahl1 As Double, Zahl2 As Double, OP As String) As Double
    21. Ergebnis = 0
    22. Select Case OP
    23. Case "*"
    24. Ergebnis = Zahl1 * Zahl2
    25. Case "/"
    26. Ergebnis = Zahl1 / Zahl2
    27. Case "-"
    28. Ergebnis = Zahl1 - Zahl2
    29. Case "+"
    30. Ergebnis = Zahl1 + Zahl2
    31. End Select
    32. End Function
    33. End Module
    Guten Morgen liebe VB-Paradise Community,

    hatte gestern keine Zeit mehr mich zu melden.
    Danke für eure ganzen Antworten! Haben mir echt weitergeholfen. Werde den Code von @Dizzy nutzen um meinen Code zu verbessern.

    Riesen Dank an alle die sich Gedanken um mein Problem gemacht haben! :)

    MfG
    mastermc
    ich bin davon ausgegangen, dass es dir selbst auffällt: Dizzies Code verstößt gegen punkt#6 der Anforderungen

    Andererseits ist vlt. gut, das einzureichen, denn dadurch kommst du mittm Chef ins Gespräch über das Projekt.
    Und das ist ganz fortschrittliche Software-Entwicklung, nämlich in Zyklen, wo man immer wieder Zwischenstände rückmeldet und Anforderungen präzisiert oder geändert bekommt, oder auch einfach bestätigt, auf dem richtigen Weg zu sein.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „ErfinderDesRades“ ()

    mastermc schrieb:

    um meinen Code zu verbessern.
    Bedenke noch folgendes:
    Wenn ein "X" eingegeben wird, sollte die While-Schleife unmittelbar verlassen werden, dazu gibt es ein Exit While.
    Wenn Du eine Division durchführst, solltest Du vorher abtesten, ob der Nenner = 0 ist und eine entsprechende Meldung ausgeben.
    Ich als "Auftraggeber" würde dies fast als erstes testen. ;)
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Wie schon gesagt ich habe das mal so auf die schnelle geschrieben, was mir so spontan eingefallen ist.
    Mir ist klar das der Code den anforderungen nicht entspricht, sollte aber einfach nur eine Möglichkeit aufzeigen wie man es machen könnte. Mal abgesehen davon, dass das Ganze eigentlich eh eine etwas eigenartige Aufgabenstellung ist.
    Ich denke mal mastermc bekommt das schon hin, dass alle Punkte erfüllt werden.

    Ach ja das mit der Whle Schleife ohne Exit While. Ich bin kein Freund davon eine Schleife vorzeitig mit Exit zu verlassen wenn es sich vermeiden lässt.