
zahl die auf 5 endet überspringe
Der problembär möchte offenbar nicht wahrhaben, dass es meist bessere/anerkanntere Antworten gibt als die seinigen, da diese ein Problem oft weniger umständlich lösen, aber zum Teil auch mal ein bißchen mathematischen Sachverstand erfordern. Aus diesem Umstand heraus konstruiert er sich leider mehr oder weniger eine Art Verschwörung des Forums gegen ihn - so scheint es zumindest. Hierbei wird problembär auch nicht müde, bei jeder sich bietenden Gelegenheit insbesondere Anfänger vor den besagten Forumskätzern zu warnen, die alle immer irgendwas gegen seinen Programmierstil haben und ihn alle nur ärgern wollen. 

Ganz besonders gelungen ist auch immer seine Argumentationslinie gegen "pythonisches" programmieren: wenn es der Interpreter schluckt, dann ist es auch richtig! Punkt!
Ich habe mir darum mal erlaubt, ihm seine ganz persoenliche sortier-Funktion zu widmen, die ein bisschen beschraenkt ist (um ein anderes Wort das mit besch... anfaengt zu vermeiden)
Man sehe & staune - es funktioniert! Ob er das jetzt wohl auch immer verwenden wird?!
Ich habe mir darum mal erlaubt, ihm seine ganz persoenliche sortier-Funktion zu widmen, die ein bisschen beschraenkt ist (um ein anderes Wort das mit besch... anfaengt zu vermeiden)
Code: Alles auswählen
import tempfile, os, random, shutil
def problembaer_sort(l):
d = tempfile.mkdtemp()
for entry in l:
with open(os.path.join(d, str(entry)), "w") as outf:
pass
res = [int(h) for h in os.listdir(d)]
shutil.rmtree(d)
return res
l = range(10)
random.shuffle(l)
print l
print problembaer_sort(l)
Da würde ich doch noch Raymond Hettingers wunderbares sleep_sort vorschlagen das allerdings auf Integer-Werte beschränkt ist.deets hat geschrieben:Man sehe & staune - es funktioniert!
Code: Alles auswählen
from threading import Thread
import time
def worker(n, emit):
time.sleep(n)
emit(n)
print(n)
def sleep_sort(s):
result = []
emit = result.append
threads = [Thread(target=worker, args=(x, emit)) for x in s]
for t in threads:
t.start()
for t in threads:
t.join()
return result
if __name__ == '__main__':
import random
s = list(range(10))
random.shuffle(s)
print('Shuffled:', s)
print('Sorted:', sleep_sort(s))
Ich möchte hier nicht zu sehr auf dem problembär herumhacken, den ich gerade zum ersten Mal bemerke. Tatsächlich kann ich seine ursprüngliche Motivation auch nachvollziehen und gutheißen: Manchmal sind Antworten und Code-Vorschläge so weit von dem des Threadstarters entfernt, dass man befürchten kann, dass der womöglich nichts damit anfangen könnte, und irgendwo alleine verzweifelt. Aber gut: Das ist in jedem Fall unterschiedlich, und die meisten melden sich so oder so nicht zurück, egal ob man ihnen geholfen oder sie überfordert hat. Mein Vorschlag: Einfach antworten, dass man nix verstanden hat, dann wird doch auch gern detailierter erklärt. So, genug Trolle gefüttert für heute, hoffentlich war es nahrhaft und hilft durch den kommenden, langen Winter.
MorgenGrauen: 1 Welt, 8 Rassen, 13 Gilden, >250 Abenteuer, >5000 Waffen & Rüstungen,
>7000 NPC, >16000 Räume, >200 freiwillige Programmierer, nur Text, viel Spaß, seit 1992.
>7000 NPC, >16000 Räume, >200 freiwillige Programmierer, nur Text, viel Spaß, seit 1992.
Kann mir mal jemand die obige Code-Zeile erklären:derdon hat geschrieben:/me: Man kann auch einfach die Bedingung umkehren und sich so das continue-Statement sparen:
Code: Alles auswählen
>>> for i in xrange(1, 21, 2): ... if i % 5 and i % 10: ... print i ... 1 3 7 9 11 13 17 19
Code: Alles auswählen
if i % 5 and i % 10
-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
"Bedingung gilt wenn Zahl weder durch 5 noch durch 10 teilbar". Was gemacht wird ist die Modulo-Operation, die den Ganzzahligen Restwert einer Division zurückgibt. 6 % 5 wäre 1, 5 % 5 wäre 0. Also wenn bei Modulo etwas anderes als Null rauskommt, dann heißt es dass die Zahl teilbar ist. Und es wird eben sowohl Teilbarkeit durch 5 als auch durch 10 geprüft. Wenn beide Zahlen != 0 sind (, ist das Ergebnis != 0, und damit "falsch".pixewakb hat geschrieben:Kann mir mal jemand die obige Code-Zeile erklären:
Code: Alles auswählen
if i % 5 and i % 10
Nein, ``xrange`` stimmt so. ``range`` gibt eine Liste zurück, aber um über die Zahlen zu iterieren brauchst du die gesamte Liste nicht, es reicht ein iterierbares Objekt, und ein solches gibt ``xrange`` zurück.pixewakb hat geschrieben:Die Konstruktion raffe ich nicht. Statt xrange muss es range heißen?
Vergleiche im der Python-Interpreter was rauskommt wenn du ``range(10)`` und ``xrange(10)`` eingibst.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Leonidas hat sie erklärt, aber man sollte noch darauf hinweisen, dass die Bedingung natürlich nicht auf die Anforderung zutrifft und falsch ist. Das ist keine Umkehrung der von mir ursprünglich vorgeschlagenen Logik mit dem continue-Statement.pixewakb hat geschrieben:Kann mir mal jemand die obige Code-Zeile erklären:Code: Alles auswählen
if i % 5 and i % 10
Im Prinzip funktioniert das nur, weil durch das xrange(1, 21, 2) ohnehin nur ungerade Zahlen genommen werden. Lass im xrange die 2 wegfallen, so dass der Defaultwert von 1 für den Step angenommen wird und du siehst den Algorithmus kläglich an der 10 scheitern.
Leonidas hat geschrieben:Vergleiche im der Python-Interpreter was rauskommt wenn du ``range(10)`` und ``xrange(10)`` eingibst.
Code: Alles auswählen
>>> range(10)
range(0, 10)
>>> xrange(10)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'xrange' is not defined



Im Ernst: Den Umstand, dass Py3k genutzt werden könnte, sollte man inzwischen gerade bei Anfängern immer bedenken. Damit meine ich natürlich nicht, dass die Anfänger so doof sind und alle Python 3.x nutzen, sondern dass sie die Situationen der beiden parallel existierenden Versionszweige evtl nicht kennen.
Schreib ich, schreib ich's nicht...? Ach, verdammt: Das funktioniert natürlich nicht. Ich sage nur bin(25).Leonidas hat geschrieben:Also ich habe ja erwartet, dass man die Zahl in einen String in Binär umwandelt und dann auf "101$" matcht....
Stefan
Dann muss man doch einen einfacheren Ansatz wählen, nämlich eine Primfaktorzerlegung. Die Primfaktoren sammelt man in einer Liste, sortiert sie aufsteigend und wenn das dritte Element 5 ist, dann ist man schon fast fertig.sma hat geschrieben:Schreib ich, schreib ich's nicht...? Ach, verdammt: Das funktioniert natürlich nicht. Ich sage nur bin(25).Leonidas hat geschrieben:Also ich habe ja erwartet, dass man die Zahl in einen String in Binär umwandelt und dann auf "101$" matcht....
Wenn das dritte Element 5 ist, endet die Zahl auf 0. Und wenn gleich das erste Element 5 ist? Immer vorausgesetzt, Du sammelst die _verschiedenen_ Primfaktoren in einer Liste, sonst wird's entweder unübersichtlich oder langweilig./me hat geschrieben: Dann muss man doch einen einfacheren Ansatz wählen, nämlich eine Primfaktorzerlegung. Die Primfaktoren sammelt man in einer Liste, sortiert sie aufsteigend und wenn das dritte Element 5 ist, dann ist man schon fast fertig.
15 zerlegt sich in 3 * 5 und einen IndexError...?/me hat geschrieben:Dann muss man doch einen einfacheren Ansatz wählen, nämlich eine Primfaktorzerlegung. Die Primfaktoren sammelt man in einer Liste, sortiert sie aufsteigend und wenn das dritte Element 5 ist, dann ist man schon fast fertig.sma hat geschrieben:Schreib ich, schreib ich's nicht...? Ach, verdammt: Das funktioniert natürlich nicht. Ich sage nur bin(25).Leonidas hat geschrieben:Also ich habe ja erwartet, dass man die Zahl in einen String in Binär umwandelt und dann auf "101$" matcht....
Oder 135, was 3 * 3 * 3 * 5 ist und wo da an dritter Stelle eine 3 steht. Du willst ja in einer *Liste* sammeln, keinem Set.

Stefan
Also mein C64 schafft das. In Forth:
Code: Alles auswählen
\ Skip numbers ending in 5 bj
: divisible? ( n m -- t/f )
mod 0= ;
: main ( -- )
20 1 do
i 5 divisible? not
i 10 divisible?
or if i . then
loop ;
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Jetzt wollte ich mal schnell in COMMODORE BASIC V2 punkten und nun klappt das nicht:
@BlackJack: Kannst Du mir erklären, wieso das nach den Zahlen 1-4 abbricht? Klappen String-Vergleiche in BASIC nicht?
Code: Alles auswählen
10 for i=1 to 20:if right$(str$(i),1)<>"5" then print i:next
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
@Hyperion: Der Zeichenkettenvergleich ist nicht das Problem, sondern dass sich das ``THEN`` auf den Rest der Zeile bezieht. Das ``NEXT`` wird also bei 5 nicht mehr ausgeführt und es geht in der nächsten Zeile weiter. Die gibt es nicht → Programmende.
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Ah... danke. Früher hätte ich das gewusst.BlackJack hat geschrieben:@Hyperion: Der Zeichenkettenvergleich ist nicht das Problem, sondern dass sich das ``THEN`` auf den Rest der Zeile bezieht. Das ``NEXT`` wird also bei 5 nicht mehr ausgeführt und es geht in der nächsten Zeile weiter. Die gibt es nicht → Programmende.
Also hier kurz die funktionierende Version:
Code: Alles auswählen
10 for i=1 to 20:if right$(str$(i),1)<>"5" then print i
20 next
Zuletzt geändert von Hyperion am Sonntag 8. Januar 2012, 14:49, insgesamt 1-mal geändert.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert