Bestimmte Zahlen ausgeben

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
Antworten
jontho11
User
Beiträge: 3
Registriert: Freitag 20. November 2020, 17:12

Hallo zusammen,

ich soll folgende Aufgabe lösen, nur leider stellt meine Dozentin weder Hilfen noch Tipps bereit.
Ich bin für jede Hilfe dankbar! :mrgreen:

Schreiben Sie ein Programm, das alle Zahlen zwischen 1 und 1000000 addiert, die durch 2 oder
3, aber weder durch 5 noch durch 7 ganzzahlig teilbar sind. Geben Sie die Summe auf den
Bildschirm aus. :roll:

Vom aktuellen Vorlesungsstand her müsste es irgendwie mit while-Schleifen zu lösen sein..
Danke! :!:
Benutzeravatar
sparrow
User
Beiträge: 4506
Registriert: Freitag 17. April 2009, 10:28

Ja, das geht theoretisch mit einer while-Schleife.
Hübscher und richtig ist es mit einer for-Schleife.

Frag dich, wie du die Aufgabe ohne Programmiersprache lösen würdest - also "real". Und dann überträgst du die Schritte in den Code.
Benutzeravatar
__blackjack__
User
Beiträge: 13927
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@jontho11: Wo ist denn das konkrete Problem bei der Umsetzung? Was hast Du schon gemacht? Das Ergebnis ist ganz schön gross. ∞ um genau zu sein. Aber wahrscheinlich sind gar nicht alle Zahlen zwischen 1 und einer Million gemeint, sondern nur die ganzen Zahlen. Dann ist das Ergebnis nur noch 228.571.571.418. 🤓

Du könntest mit einem Programm anfangen das erst einmal *alle* ganzen Zahlen aus dem gegebenen Bereich addiert. (Ergebnis: 500.000.500.000)

Und dann die Bedigungs(en) einbauen, so dass nur noch die Zahlen mit den geforderten Eigenschaften addiert werden.
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
Sam123
User
Beiträge: 35
Registriert: Freitag 20. November 2020, 12:25

Wenn ich alle Zahlen 1-1000000 aufaddiere, kommt bei mir auch 500.000.500.000 heraus.
Aber wenn ich die Bedingungen einbaue, dann kriege ich 57.142.142.856 heraus (und nicht 228.571.571.418.).

mit for-Schleife oder while-Schleife

Code: Alles auswählen

summe = 0
for i in range(1,1000001):
    if (i % 2 == 0) and (i % 3 == 0):
        if (i % 5 != 0) and (i % 7 != 0):
            summe += i
    print("i: {}".format(i))
    print("Summe: {}".format(summe))
    print("------------------------")

Code: Alles auswählen

summe = 0
i = 1
while i <= 1000000:
    if (i % 2 == 0) and (i % 3 == 0):
        if (i % 5 != 0) and (i % 7 != 0):
            summe += i
    print("i: {}".format(i))
    print("Summe: {}".format(summe))
    print("------------------------")
    i += 1
Benutzeravatar
__blackjack__
User
Beiträge: 13927
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Sam123: Aufgabentext „durch 2 oder 3 […] ganzzahlig teilbar“, Dein Code dazu ``(i % 2 == 0) and (i % 3 == 0)``. Finde den Fehler. 🙂

Die Klammern um die Teilbedingungen sind übrigens überflüssig.

Edit: Lösung ohne ``for``/``while``-Schleife:

Code: Alles auswählen

#!/usr/bin/env python3


def is_divisible_by_any(number, divisors):
    return any(number % divisor == 0 for divisor in divisors)


def main():
    print(
        sum(
            number
            for number in range(1, 1_000_001)
            if is_divisible_by_any(number, [2, 3])
            and not is_divisible_by_any(number, [5, 7])
        )
    )


if __name__ == "__main__":
    main()
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
Sam123
User
Beiträge: 35
Registriert: Freitag 20. November 2020, 12:25

@blackjack: Danke, jetzt passts mit dem Ergebnis! Wer lesen kann, ist klar im Vorteil :)
jontho11
User
Beiträge: 3
Registriert: Freitag 20. November 2020, 17:12

Hallo zusammen,

vielen Dank für die ganzen Antoworten! :shock: :mrgreen:
Hier einmal das, was ich jetzt nach Youtube, udemy und Buch geschafft habe.

Option a:

Code: Alles auswählen

result = 0
for x in range(1,1000001):
   if (x % 2 == 0) and not (x % 5 == 0) and not (x % 7 == 0):
       result += x
       if (x % 3 == 0) and not (x % 5 == 0) and not (x % 7 == 0):
           result += x
print(result)
228570571422

Option b:

Code: Alles auswählen

result = 0
for x in range(1,1000001):
   if (x % 2 == 0) and not (x % 5 == 0) and not (x % 7 == 0):
       
       if (x % 3 == 0) and not (x % 5 == 0) and not (x % 7 == 0):
           result += x
print(result)
57142142856

Der Unterschied ist, dass ich einmal das result weggelassen habe(Option b), dadurch wird das Ergebnis erheblich kleiner --> wird dadurch das erste if wirkungslos? --> Option b ist also definitiv nicht richtig.
Und dennoch komme ich nicht auf das Ergebnis von dir @__blackjack__ : 228571571418

Woher kommt die Differenz ?


Es sieht der Methode von @Sam123 sehr ähnlich, nur :
verwende ich "if not" anstelle von !=. Sollte aber passen.?



Am Freitag war hier noch ein Kommentar mit dem ungefähren Inhalt, wie man so ein Programm vorher aufbaut. Das hat mir sehr geholfen, da kann ich allerdings nur Danke an Unbekannt sagen.
Benutzeravatar
__blackjack__
User
Beiträge: 13927
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@jontho11: Die Klammern bei den Bedingungen sind alle überflüssig, weil sowohl die Rechenoperationen als auch die Vergleiche stärker binden als ``and`` und ``or``. Bei ``and`` und ``or`` bindet ``and`` stärker als ``or``. Da solltest Du also mal schauen in welcher Reihenfolge das ausgewertet wird und ob das so denn richtig ist.

Warum gibt es bei Dir zwei ``if``? Und bei Option a sogar zwei Stellen an denen `x` auf `result` addiert wird.
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
jontho11
User
Beiträge: 3
Registriert: Freitag 20. November 2020, 17:12

@__blackjack__

Danke dir! :)
Warum ich was wie mache.. zu wenig Übung, hab gerade erst angefangen und jetzt wieder ne menge gelernt.

Code: Alles auswählen


result = 0

for x in range(1,1000001):
   if x % 2 == 0 and not x % 5 == 0 and not x % 7 == 0 \
           or x % 3 == 0 and not x % 5 == 0 and not x % 7 == 0:
       result += x

print(result)

Sirius3
User
Beiträge: 18220
Registriert: Sonntag 21. Oktober 2012, 17:20

Statt not a == b würde man a != b schreiben. Und die Dopplung der gemeinsamen and-Bedingungen würde man durch geschickte Klammerung vermeiden.
Sam123
User
Beiträge: 35
Registriert: Freitag 20. November 2020, 12:25

Warum funktioniert eigentlich dieser Code?

Code: Alles auswählen

summe = 0
for i in range(1,1000001):
    if ((i % 2 == 0) or (i % 3 == 0)) and ((i % 5 != 0) and (i % 7 != 0)):
            summe += i
print(summe)
(Ergebnis: 228.571.571.418)


und dieser nicht?

Code: Alles auswählen

summe = 0
for i in range(1,1000001):
    if (i % 2 == 0) or (i % 3 == 0) and (i % 5 != 0) and (i % 7 != 0):
            summe += i
print(summe)
(Ergebnis: 307.143.642.852)
Benutzeravatar
__blackjack__
User
Beiträge: 13927
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Sam123: Weil ``and`` stärker bindet als ``or``. ``a or b and c and d`` ist das äquivalent zu ``a or (b and c and d)``. Du willst aber das erst das ``or`` ausgewertet wird, also musst Du da explizit Klammern setzen: ``(a or b) and c and d``. Die Klammern um ``c and d`` kann man setzen, die verändern aber nichts am Ergebnis.

Das ist wie bei Punkt- und Strichrechnung. ``a + b * c * d`` ist etwas anderes als ``(a + b) * c * d``, weil ``*`` stärker bindet als ``+``.
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
Antworten