Seite 2 von 3
Re: Kann mir jemand hierbei helfen?
Verfasst: Samstag 19. Oktober 2019, 12:56
von nezzcarth
@Sirius3:
Stimmt. Das habe ich nicht bedacht. Allerdings sind bei mir die Zahlen für die Modulo-Variante noch immer besser (wenn auch nicht mehr so drastisch):
Code: Alles auswählen
#!/usr/bin/env python3
from time import time
from random import randint, shuffle
from statistics import mean, stdev
N = 10_000
REPETITIONS = 100
LOWER = 1
UPPER = 1_000_000_000
def string_based(s):
return s[-1] in ('0', '5') and len(s) > 2
def modulo_based(n):
return n % 5 == 0 and n > 99
def decimal_based(n):
if n % 10 not in (0, 5):
return False
i = 0
k = n
while k > 0:
i += 1
k //= 10
if i > 2:
return False
return True
ALGORITHMS = [
('string comparison', string_based),
('modulo calculation', modulo_based),
('decimal position', decimal_based)
]
def random_numbers(n, lower, upper):
divisible = set()
indivisible = set()
while len(divisible) < n or len(indivisible) < n:
x = randint(lower, upper)
if len(divisible) < n and x % 5 in (0, 5):
divisible.add(x)
elif len(indivisible) < n:
indivisible.add(x)
return tuple(divisible), tuple(indivisible)
def main():
print('N:', N)
print('Range:', LOWER, UPPER)
print('Repetitions:', REPETITIONS)
results = dict()
algorithms = ALGORITHMS
for _ in range(REPETITIONS):
divisible, indivisible = random_numbers(N, LOWER, UPPER)
for label, function in ALGORITHMS:
if label == 'string comparison':
divisible_temp = [str(i) for i in divisible]
indivisible_temp = [str(i) for i in indivisible]
else:
divisible_temp = divisible
indivisible_temp = indivisible
t1 = time()
for group in (divisible_temp, indivisible_temp):
for number in group:
result = function(number)
t2 = time()
results.setdefault(label, [])
results[label].append(t2 - t1)
# shuffle last, so order is mainted in modern python
shuffle(algorithms)
print()
for label, durations in results.items():
print(label, '(mean):', mean(durations))
print(label, '(sd):', stdev(durations))
print(label, '(sum):', sum(durations))
print()
if __name__ == '__main__':
main()
Code: Alles auswählen
$ ./fives.py :(
N: 10000
Range: 1 1000000000
Repetitions: 100
string comparison (mean): 0.0033177709579467773
string comparison (sd): 0.00032582172245825377
string comparison (sum): 0.33177709579467773
modulo calculation (mean): 0.002630734443664551
modulo calculation (sd): 0.0005114850119894751
modulo calculation (sum): 0.2630734443664551
decimal position (mean): 0.0063778114318847655
decimal position (sd): 0.0006249521611702232
decimal position (sum): 0.6377811431884766
Habe ich da noch etwas übersehen?
Re: Kann mir jemand hierbei helfen?
Verfasst: Samstag 19. Oktober 2019, 13:03
von nezzcarth
nezzcarth hat geschrieben: Samstag 19. Oktober 2019, 12:56
Habe ich da noch etwas übersehen?
..., dass man die Zahlen in Strings umwandeln muss, weil die Eingabe der Ausgangsfrage per 'input()' kommt und so vorliegt.

Das Result meiner letzten Messung ist ja nun, dass es besser ist, Zahlen als Zahlen vorliegen zu haben. Also kann man festhalten, Modulo ist für Zahlen absolut gesehen schneller als die String-Variante für Strings. Allerdings ist das eigentliche Bottleneck die Konvertierung und der Fragsteller sollte die String-Variante nehmen.
Re: Kann mir jemand hierbei helfen?
Verfasst: Samstag 19. Oktober 2019, 13:11
von Neiqi
Ich check gerade gar nichts

Re: Kann mir jemand hierbei helfen?
Verfasst: Samstag 19. Oktober 2019, 13:26
von nezzcarth
Neiqi hat geschrieben: Samstag 19. Oktober 2019, 13:11
Ich check gerade gar nichts
Na ja, das Ergebnis meiner Abschweifungen ist, dass ich mich teilweise korrigieren muss: Da du die Zahl per 'input()' einließt, liegt sie als String vor und dann ist es tatsächlich schneller, mit Zeichenkettenoperationen zu arbeiten.
Zudem habe ich da mal eine letzte Frage, in richtig großen Projekten ist es nicht sogar besser wenn man den Computer sowenig wie möglich rechnen lässt wenn es auch anders geht wie in meinem Code zum Beispiel. In meinem Code schaut sich das Programm doch nur 1 Zahlengruppe an undzwar die welche als letztes in dem String aufgeführt wurde müsste doch schneller sein als die Zahl zu berechnen oder sehe ich da was Falsch?
Diese Aussagen sind meiner Meinung so aber nicht haltbar. Denn absolut gesehen ist die Modulo-Berechnung in Python (zumindest laut meiner Messung) schneller. In deinem Fall würde sie dadurch verlangsamt, dass die Eingabe als String vorliegt und die Konvertierung in eine Zahl Zeit kostet. Kann man es sich aussuchen, ob man Strings oder Zahlen hat, wären in dem Beispiel Zahlen aber zu bevorzugen.
Re: Kann mir jemand hierbei helfen?
Verfasst: Samstag 19. Oktober 2019, 13:39
von __blackjack__
@Neiqi: Am wichtigsten ist in aller Regel immer erst einmal ob der Quelltext leicht verständlich und *fehlerfrei* ist. Das leicht verständlich hilft dabei ihn fehlerfrei zu schreiben oder zumindest zu machen wenn man einen Fehler gefunden hat. Schnelle aber falsche Ergebnisse braucht keiner.
Was zu fehlerfrei auch dazu gehört ist die Validierung von Eingaben und das berücksichtigen von Sonderfällen. Wenn man die Eingabe in eine Zahl umwandelt, dann fällt sofort auf wenn der Benutzer keine Zahl eingeben hat, sondern beispielsweise "Hallo". Und glaub mir Benutzer tun so etwas. Auch wenn die Aufforderung war eine Zahl einzugeben.
Selbst wenn der Benutzer ein Zahl eingibt, kann das ja auch -4711 oder 23.5 sein. Oder 0000000042. Auch gegen so etwas muss man sein Programm absichern, so das es entweder schon die Eingabe zurückweist, oder auch für diese Fälle ein korrektes Ergebnis ausgibt.
Edit: Da es ja mittlerweile einige Zeitmessungen gab: IMHO sollten Anfänger `pytest` vor `timeit` als Werkzeug in die Finger bekommen. Erst korrekt, dann schnell.
Re: Kann mir jemand hierbei helfen?
Verfasst: Samstag 19. Oktober 2019, 13:42
von Neiqi
Ahh verstehe okay,
Zu dem Problem mit der 000 und der 100 habe ich eine Lösung gefunden.
bei 101 hatte ich jetzt kein Fehler entdeckt hier der neue Code. Ich muss echt sagen, dass das richtig spaß macht
Code: Alles auswählen
import sys
Zahl = str(input("Bitte gebe hier deine Zahl ein die größer 0 ist"))
Zahl1 = int(Zahl)
if Zahl1 == 0:
print("Gebe eine korrekte Zahl ein")
sys.exit(0)
elif Zahl[-1] in ('0', '5'):
print("deine Zahl ist durch 5 Teilbar ohne Rest")
else:
print("Deine Zahl ist nicht durch 5 Teilbar ohne Rest")
if Zahl1 == 100:
print("Deine Zahl ist gleich 100")
elif len(Zahl) > 3:
print("Deine Zahl ist größer als 100")
else:
print("Deine Zahl ist kleiner als 100")
Re: Kann mir jemand hierbei helfen?
Verfasst: Samstag 19. Oktober 2019, 13:45
von __blackjack__
@Neiqi: `input()` liefert bereits eine Zeichenkette — es ist überflüssig da noch mal `str()` drauf anzuwenden. Und vielleicht solltest Du das dann auch nicht `zahl` und `zahl1` nennen, sondern `text` oder `ziffern` und `zahl`. Und klein geschrieben. Und bitte nicht irgendwelche Nummern an Namen hängen. Gewöhn Dir so etwas gar nicht erst an!
Re: Kann mir jemand hierbei helfen?
Verfasst: Samstag 19. Oktober 2019, 13:52
von __blackjack__
@Neiqi: Vergiss am besten `sys.exit()` als Mittel der Steuerung des Programmflusses gleich wieder. Mach das ordentlich, ohne solche Abkürzungen, so das der Programmfluss ganz normal am Ende des Codes ankommen kann.
Code: Alles auswählen
#!/usr/bin/env python3
def main():
ziffern = input("Bitte gebe hier deine Zahl ein die größer 0 ist")
zahl = int(ziffern)
if zahl == 0:
print("Gebe eine korrekte Zahl ein")
else:
if ziffern[-1] in ('0', '5'):
print("deine Zahl ist durch 5 Teilbar ohne Rest")
else:
print("Deine Zahl ist nicht durch 5 Teilbar ohne Rest")
if zahl == 100:
print("Deine Zahl ist gleich 100")
elif len(ziffern) > 3:
print("Deine Zahl ist größer als 100")
else:
print("Deine Zahl ist kleiner als 100")
if __name__ == "__main__":
main()
Und nun gib mal -1000 ein. Das ist laut diesem Programm grösser als 100.
Edit: Warum schliesst Du eigentlich die 0 überhaupt aus?
Re: Kann mir jemand hierbei helfen?
Verfasst: Samstag 19. Oktober 2019, 13:55
von Neiqi
Das mit dem Zahl und Zahl1 kam von unserem Professor er meinte, dass es besser ist...
Ja stimmt aber -1000 ist ja nicht größer 0^^
Aber du hast recht, hatte gerade das mit der - auch im sinn^^
Naja weil die 0 nur probleme macht und man eine 0 ja eh nicht teilen kann...^^
und das Problem ist wenn ich das Programm nicht nach der Fehlerhaften eingabe schließe läuft es weiter und spuckt müll aus
Re: Kann mir jemand hierbei helfen?
Verfasst: Samstag 19. Oktober 2019, 14:20
von Sirius3
@Neiqi: Zahl und Zahl1 sind besser als was?
0043 ist immer noch nicht größer als 100.
Re: Kann mir jemand hierbei helfen?
Verfasst: Samstag 19. Oktober 2019, 14:22
von nezzcarth
__blackjack__ hat geschrieben: Samstag 19. Oktober 2019, 13:39
Edit: Da es ja mittlerweile einige Zeitmessungen gab: IMHO sollten Anfänger `pytest` vor `timeit` als Werkzeug in die Finger bekommen. Erst korrekt, dann schnell.
Na ja, aus meiner Sicht wäre die 'korrektere' Lösung, die Eingabe in einen Integer zu verwandeln und das Ergebnis zu berechnen. Zahlen wie Strings zu behandeln ist meiner Meinung nach grenzwertig. Und hier zum Beispiel auch an das Dezimalsystem gebunden. Und du hattest ja sogar noch weitere Gründe geliefert. Die Messungen sollten einerseits der Überzeugung dienen (das ging nach hinten los

), andererseits hat er ja im zitierten Post nach Performanceaspekten gefragt. Persönlich finde ich immer noch, dass man das Ergebnis von 'input()' einfach in einen Integer umwandeln und damit rechnen sollte; auch wenn es 'langsamer' ist (es geht ja trotzdem noch schnell genug).
Re: Kann mir jemand hierbei helfen?
Verfasst: Samstag 19. Oktober 2019, 14:26
von Neiqi
habe import sys rausgenommen und die Variablen namen auch verändert und das problem mit der -1000 auch gelöst
Code: Alles auswählen
ziffer = str(input("Bitte gebe hier deine Zahl ein die größer 0 ist"))
zahl = int(ziffer)
if zahl == 0:
print("Gebe eine korrekte Zahl ein")
else:
if ziffer[-1] in ('0', '5'):
print("deine Zahl ist durch 5 Teilbar ohne Rest")
else:
print("Deine Zahl ist nicht durch 5 Teilbar ohne Rest")
if zahl == 100:
print("Deine Zahl ist gleich 100")
elif zahl < 0:
print("Deine Zahl ist kleiner als 100")
elif len(ziffer) > 3:
print("Deine Zahl ist größer als 100")
else:
print("Deine Zahl ist kleiner als 100")
Re: Kann mir jemand hierbei helfen?
Verfasst: Samstag 19. Oktober 2019, 14:32
von Neiqi
Ja es macht auch mehr Sinn das rechnerisch zu lösen, durch meinen Denkansatz werde ich immer mit neuen Problemen wie jetzt z.B. 0034 konfrontiert wo ich immer mehr dazulerne indem ich versuche die Probleme zu lösen. Es macht auch zudem extrem viel Spaß. ^^
Re: Kann mir jemand hierbei helfen?
Verfasst: Samstag 19. Oktober 2019, 14:40
von Neiqi
Noch eine Frage dazu, wie kann ich denn in einem String ein gewisses Zeichen ignorieren die aber von einem Input stammen und und nur bis zu einem gewissen Zeichen gehen.
Also z.B : 0003 die ersten drei Zeichen werden ignoriert, oder 0120 das erste Zeichen wird ignoriert.
1000 kein zeichen wird ignoriert. ^^
Re: Kann mir jemand hierbei helfen?
Verfasst: Samstag 19. Oktober 2019, 14:55
von Sirius3
Es ist sehr inkonsequent, für Vergleiche == 100 und < 0 die Zahl zu nehmen, für > 100 aber die Ziffern.
`ziffer` ist der falsche Name für mehreren Ziffern.
Code: Alles auswählen
ziffern = input("Bitte gebe hier deine Zahl ein die größer 0 ist")
ziffern = ziffern.strip().lstrip('0') # führende 0en entfernen
if not ziffern or not ziffern.isdigit():
print("Gebe eine korrekte Zahl ein")
else:
if ziffern[-1] in ['0', '5']:
print("deine Zahl ist durch 5 Teilbar ohne Rest")
else:
print("Deine Zahl ist nicht durch 5 Teilbar ohne Rest")
if ziffern == '100':
print("Deine Zahl ist gleich 100")
elif len(ziffern) > 3:
print("Deine Zahl ist größer als 100")
else:
print("Deine Zahl ist kleiner als 100")
Re: Kann mir jemand hierbei helfen?
Verfasst: Samstag 19. Oktober 2019, 14:57
von snafu
Einfach die int()-Funktion benutzen. Damit werden führende Nullen automatisch abgeschnitten. Mich wundert, dass du das nicht einfach ausprobiert hast...
Re: Kann mir jemand hierbei helfen?
Verfasst: Samstag 19. Oktober 2019, 15:02
von snafu
Neiqi hat geschrieben: Samstag 19. Oktober 2019, 14:32
Ja es macht auch mehr Sinn das rechnerisch zu lösen, durch meinen Denkansatz werde ich immer mit neuen Problemen wie jetzt z.B. 0034 konfrontiert wo ich immer mehr dazulerne indem ich versuche die Probleme zu lösen. Es macht auch zudem extrem viel Spaß. ^^
Volle Zustimmung. Als Lerneffekt ist es ganz nett, das mal selber zu machen mit Stringoperationen. Aber int() kann das schon alles und sollte daher bevorzugt werden. Nachfolgende Prüfungen dann auch besser auf der "echten" Zahl und nicht auf dem String. "ziffern" für den String finde ich übrigens nicht so gut, da es ja auch in dem Moment schon als Zahl gemeint ist. Warum nicht "eingabe" für den String und "zahl" nach der Umwandlung in einen Integer?
Re: Kann mir jemand hierbei helfen?
Verfasst: Samstag 19. Oktober 2019, 15:59
von Neiqi
Also ich habe das jetzt auch mal einfach rechnerisch gemacht, und wäre ich da am Anfang drauf gekommen wäre es wirklich super leicht. Dadurch, dass ich mich jetzt aber die ganze Zeit damit beschäftigt habe das mit dem String zu lösen und die Probleme dort zu beheben, hat es einfach mein Verständnis schon einmal enorm nach vorne gebracht weshalb die Lösung gerade einmal eine Minute gedauert hat rechnerisch jetzt.
Danke aufjedenfall an alle, die mich hier so toll unterstützt haben!
Code: Alles auswählen
zahl = float(input("Bitte gebe hier deine Zahl ein"))
if zahl == 0:
print("Gebe eine korrekte Zahl ein")
else:
if zahl % 5 == 0:
print("deine Zahl ist durch 5 Teilbar ohne Rest")
else:
print("deine Zahl ist nicht durch 5 Teilbar ohne Rest")
if zahl > 100:
print("Deine Zahl ist größer als 100")
elif zahl == 100:
print("Deine Zahl ist gleich 100")
else:
print("deine Zahl ist kleiner als 100")
Eine sache wäre da noch, ich war mir jetzt nicht ganz einig welche IDE ich benutze, ich habe mich jetzt für PyCharm entschieden, da bekomme ich sogar die Pro Version kostenlos komme damit ganz gut klar wollte nur Fragen was die Community von der IDE hält. LG
Re: Kann mir jemand hierbei helfen?
Verfasst: Samstag 19. Oktober 2019, 16:23
von __blackjack__
@snafu: Ich finde `ziffern` eigentlich passender, weil dann der Code so ziemlich genau dem entspricht wie man den Algorithmus der Teilbarkeit durch 5 in Worten beschreibt: Die letzte Ziffer ist "0" oder "5" → ``ziffern[-1] in ["0", "5"]``. Das Problem ist vielleicht das man den Rückgabewert von `input()` tatsächlich erst einmal `eingabe` nennen sollte; `ziffern` erst nach dem man die Eingabe validiert und bereinigt hat.
@Neiqi: Führende "0"en könntest Du mit der `lstrip()`-Methode beseitigen. Dann darf da aber natürlich kein "-" davor stehen, das müsste man noch einmal extra behandeln oder verbieten:
Re: Kann mir jemand hierbei helfen?
Verfasst: Mittwoch 23. Oktober 2019, 12:35
von DeaD_EyE
Meine Aufgabe ist es, ein Programm zu schreiben, welches sagt, ob die eingegebene Zahl durch 5 Teilbar ist ohne Rest und ob sie größer ist als 100.
- Prüfen ob eine Zahl durch 5 teilbar ist:
https://de.wikipedia.org/wiki/Division_ ... che_Zahlen
Der Operator % liefert den Rest. Wenn 0 übrig bleibt, ist die Zahl teilbar.
- Prüfen ob sie größer ist als 100:
Hier einfach zahl ist größer als
Die beiden Ausdrücke mit and verknüpfen:
Code: Alles auswählen
(zahl % 5 == 0) and (zahl > 100)
# die Klammern sind nur für die Optik. Normal lässt man die weg.
Die Variable zahl muss dann natürlich auch ein integer oder float sein.
Die Funktion input liefert strings zurück. Stings muss man erst nach integer umwandeln.
Mach daraus eine Funktion:
Code: Alles auswählen
def my_condition(number):
return number % 5 == 0 and number > 100
Die Abfrage der Zahl machst du in einer anderen Funktion.
Wenn my_condition True zurückliefert, dann ist die Bedingung erfüllt,
bei False ist die Bedingung nicht erfüllt.
Code: Alles auswählen
my_number = 105
if my_condition(my_number):
print("Bedingung erfüllt")