For-Schleife ungerade Zahlen aufsummieren

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
mkaye
User
Beiträge: 4
Registriert: Sonntag 22. Januar 2023, 16:47

Liebe alle,

Für meinen Hochschullehrgang habe ich folgenden Auftrag bekommen:

Der User soll zwei Zahlen a und b eingeben, wobei a kleiner sein soll als b. Dein Programm soll dann alle geraden Zahlen zwischen a und b aufsummieren und das Ergebnis ausgeben.

Wie kann ich es schaffen, dass mir nur das Endergebnis angezeigt wird. Wenn ich die Zahlen 2 und 10 eingebe, kommt folgende Ausgabe:

4
10
18
28

28 wäre das aufsummierte Ergebnis, kann ich dieses Ergebnis separat ausgeben bzw. mit einen string ersichtlich machen , dass es sich um das Endergebnis handelt?

Hier meib Code:

Code: Alles auswählen

eingabe = "j"
summe = 0

while eingabe == "j":

    eingabe_zahla = int(input("Geben Sie Zahl a ein "))
    eingabe_zahlb = int(input("Geben Sie Zahl b ein, wobei Zahl b größer als Zahl a sein muss "))
    if (eingabe_zahla >= eingabe_zahlb):
         eingabe = input("Falsche Zahl eingegeben Möchtest du das Programm wiederholen? (j/n) ")
       
    for i in range(eingabe_zahla+1,eingabe_zahlb):
         if i % 2 == 0:
            summe = summe + i
            print(summe)
Liebe Grüße und danke für etwaige Hilfe
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Wozu dienen die Einrueckungen in Python? Wenn die Frage beantwortet ist, kann man darueber nachdenken: warum gibt Python in jedem Schritt der Berechnung etwas aus, und wo muesste die Anweisung stehen, damit dem nicht so ist.
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Das Problem mit der Einrückung ist entweder noch größer, oder die Abfrage nach dem Wiederholen des Programms macht so keinen Sinn.

Das "zwischen" läßt auch wieder die Interpretation zu, ob es inklusive oder exklusive der eingegebenen Zahlen gemeint ist.

Variablen werden erst dann initialisiert, wenn man sie auch braucht, was auch eine weitere Fehlerquelle eliminieren würde.
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@mkaye: Der Programmfluss ist übrigens nicht so besonders gut strukturiert. Eigentlich würde man das ja so beschreiben/formulieren, dass der Benutzer erst solange Zahlen eingeben muss bis die den Anforderungen genügen und erst wenn das der Fall ist, wird mit den Zahlen etwas berechnet. Hier ist *alles* in einer Schleife, auch die Berechnung mit falschen Eingaben die nur mehr oder weniger zufällig nicht wirklich etwas berechnet wenn die Eingaben die Anforderungen nicht erfüllen. Zudem ändert sich das sobald Du das Problem mit der Ausgabe behebst.

Zur Wiederholung der Eingabe: ``while``-Schleifen bei denen man einen Wert für die Prüfung vorbelegen muss, der eigentlich erst *in* der Schleife tatsächlich ermittelt wird, sind unüblich. Denn die erste `eingabe` ist ja gar nicht das Ergebnis einer Eingabe. An der Stelle schreibt man üblicherweise einfach eine ”Endlosschleife” (``while True:``) die an entsprechender Stelle mit ``break`` (oder in Funktionen manchmal auch ``return``) verlassen wird.

Auch diese Nachfrage ob das *Programm* wiederholt werden soll, wird sich anders/schwieriger gestalten wenn die Berechnung nicht mehr in der Schleife für die Eingabe der Zahlen enthalten ist. Das wird man anders organisieren müssen und/oder man braucht noch mal zusätzlich eine Schleife für das gesamte Programm das Eingabeschleife und Berechnung beinhaltet.

Namen sollte man nicht am Anfang ”auf Vorrat” definieren, sondern erst dann wenn man sie benötigt. `summe` wird erst für die Berechnung benötigt, sollte also nicht schon vor der Eingabe definiert werden.

Da sind unnötige Klammern um die ``if``-Bedingung.

Eigentlich gehört das alles in eine Funktion, und die Eingabe einer einzelnen Zahl würde man auch in eine Funktion heraus ziehen und um eine Fehlerbehandlung erweitern für den Fall, dass der Benutzer etwas eingibt was keine Zahl ist.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
imonbln
User
Beiträge: 149
Registriert: Freitag 3. Dezember 2021, 17:07

Sieh dir mal die Seite mit den Built-in Functions in Python an. Dann wird dir auffallen das, es schon ein Built-in sum gib und das range einen dritten Parameter step kennt, wenn du beides richtig einsetzt, musst du nur noch dafür Sorgen, dass a gerade und kleiner als B ist.

Das a gerade ist, könnte man übrigens wie folgt sicherstellen, ist ein wenig Bit Manipulation, geht dafür aber ohne eine IF-Abfrage

Code: Alles auswählen

    
    # Bump up number to next even value
    lower_number = (lower_number + 1) & ~0x01
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@imonbln: da der Modulo-Operator bekannt ist, könnte man auch auf die nächste gerade Zahl so aufrunden:

Code: Alles auswählen

lower_number += lower_number  % 2
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Hm, ihr habt das auch mit negativen Zahlen ausprobiert‽ Die werden weder vom Text noch vom Code ausgeschlossen! 😜

Ich hab's mal spasseshalber in Hy gelöst:

Code: Alles auswählen

#!/usr/bin/env hy
(import hyrule *)
(require hyrule *)

(defn even? [n] (= (% n 2) 0))


(defn ask-number [prompt]
  (loop []
    (try (int (input prompt))
      (except [ValueError]
        (print "Fehler! Bitte eine ganze Zahl eingeben!")
        (recur)))))


(defn ask-range []
  (loop []
    (setv a (ask-number "Geben Sie Zahl a ein: ")
          b (ask-number "Geben Sie Zahl b ein, mit b>a: "))
    (cond
      (< a b)
        (range (inc a) b)
      (!= (.lower (input "Falsche Eingabe. Zahlen noch einmal eingeben (j/n)? "))
          "j")
        None
      True
        (recur))))


(defmain []
  (when (not? (setx numbers (ask-range)) None)
    (print (sum (filter even? numbers)))))
Wobei man auch an den kleinen Gauss denken könnte und es einfach ausrechnen könnte, statt eine Schleife zu schreiben.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
AndyZ59
User
Beiträge: 1
Registriert: Montag 23. Januar 2023, 08:38

Hallo mkaye,

zuerst Mal fällt mir ein Widerspruch in der Aufgabenstellung und Musterlösung auf:
Wenn Du als "richtiges" Ergebnis 28 präsentierst, dann ist die 10 mit Dabei, die 2 allerdings nicht. In der Aufgabenstellung schreibst Du aber "zwischen" deb eingegebenen Zahlen. Was ist nun richtig?

Zur Programmstruktur schlage ich ebenfalls eine Funktion vor, in die die Zahlen a und b übergeben werden und die gewünschte Summe zurückkommt. Dann ist die Ausgabe mit dem einen gewünschten Wert auch schon erledigt.

Die Schleife mit while(true) ist ne gute Idee, raus mit break :wink:

Die Struktur wäre dann:

Code: Alles auswählen

# berechnet die Summe in einem Bereich zwischen 2 Zahlen
#
# Bereichsgrenzen incl?
# nur integer oder double?

# a, b, Wert : muss nicht angemeldet werden 

# ===== Unterprogramm(e) =====
def rechne_gerade (a, b):
  # je nachdem, ob die Grenzen a und b mitgerechnet werden sollen
  # -> Korrektur der Grenzen
  sum = 0
  if (a % 2 == 0):    # Korrektur untere gerade Grenze, wenn sie nicht mitgezählt werden soll
    a += 1
  if (b % 2 == 0):    # Korrektur obere gerade Grenze, wenn sie nicht mitgezählt werden soll
    b -= 1
  for i in range (a, b):
    if (i % 2 == 0):    # gerade Zahl gefunden
      sum += i
  return sum
  
# ===== Hauptprogramm =====
# input (a, b)
a = 7
b = 1
if (a > b):   # tauschen
  a, b = b, a 
  print ("ich musste die Zahlen tauschen")
Wert = rechne_gerade (a, b)
print (a, b, Wert) # in einem Schlußsatz

# das wars vermutlich schon

imonbln
User
Beiträge: 149
Registriert: Freitag 3. Dezember 2021, 17:07

Sirius3 hat geschrieben: Montag 23. Januar 2023, 08:33 @imonbln: da der Modulo-Operator bekannt ist, könnte man auch auf die nächste gerade Zahl so aufrunden:
Auch eine schöne Lösung.
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@AndyZ59: Die Klammern um die ganzen ``if``-Bedingungen sind überflüssig und eingerückt wird per Konvention 4 Leerzeichen und nicht nur 2.

Über die Anpassung der oberen Grenze solltest Du auch noch mal nachdenken. Die ist ja mindestens mal überflüssig, und man müsste dann noch begründen warum sie nicht schädlich ist.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
mkaye
User
Beiträge: 4
Registriert: Sonntag 22. Januar 2023, 16:47

Vielen lieben Dank für eure Unterstützung und Vorschläge , mittlerweile konnte ich das Ausgabeproblem lösen und den Code etwas verbessern!
Antworten