Registrierung Kalender Mitgliederliste Teammitglieder Suche Häufig gestellte Fragen Zur Startseite

Informatiker Board » Themengebiete » Praktische Informatik » Programmierung mit for-Schleife » Hallo Gast [Anmelden|Registrieren]
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | An Freund senden | Thema zu Favoriten hinzufügen
Neues Thema erstellen Antwort erstellen
Zum Ende der Seite springen Programmierung mit for-Schleife
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
lea
Grünschnabel


Dabei seit: 02.11.2017
Beiträge: 8

Programmierung mit for-Schleife Auf diesen Beitrag antworten Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       Zum Anfang der Seite springen

Meine Frage:
Nehmen Sie an, jeder Person wird ein einziger Hobby-Wert zugeordnet. Verschiedene
Hobbies haben dabei verschiedene Wertigkeiten (in 2-er Potenzen) und der HobbyWert
einer Person setzt sich aus der Summe der Wertigkeiten seiner Hobbies zusammen.
Die folgenden Hobbies werden dabei berucksichtigt. ¨
Schwimmen (1)
Brettspiele (2)
Angeln (4)
Kochen (8)
Laufen (16)
Fußball spielen (32)
Klavier spielen (64)
N¨ahen (128)
Beispiel: Tom spielt in seiner Freizeit Fußball und angelt. Er hat einen Hobby-Wert
von 36
Schreiben Sie ein Python 3.6 Programm, welches Anhand eines gegebenen HobbyWertes
berechnet, welche Hobbies eine Person hat und dies ausgibt. H¨ohere 2-er
Potenzen sollen dabei ignoriert werden (z.B. bei einer Angabe von 257 sollte nur
?
Schwimmen? ausgegeben werden.)

Folgendes Problem: Ich weiß, dass ich hier eine for-Schleife verwenden soll, weiß aber nicht genau wie.


Meine Ideen:
hobbies = ['Schwimmen', 'Brettspiele',...] #hier die ganzen Hobbies in die Liste schreiben, weiter komme ich nicht


try:
input('-->', number)
for i in range
02.11.2017 21:43 lea ist offline E-Mail an lea senden Beiträge von lea suchen Nehmen Sie lea in Ihre Freundesliste auf
as_string as_string ist männlich
Haudegen


Dabei seit: 06.11.2013
Beiträge: 639
Herkunft: Heidelberg

Auf diesen Beitrag antworten Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       Zum Anfang der Seite springen

Hallo!

Eins vorne weg: Ich hab noch nie ein Python-Programm geschrieben!
Allerdings habe ich etwas gegooglet und das hier probiert:
code:
1:
2:
3:
4:
5:
6:
7:
hobbys = ["Schwimmen", "Brettspiele", "Angeln", "Kochen", "Laufen", "Fußball spielen", "Klavier spielen", "Nähen"]
number = int(input('-->'))
for idx, hobby in enumerate(hobbys):
        if((1 << idx) & number):
                print(hobby)


Die for-Schleife habe ich mit dem enumerate gemacht, um immer auch den Index im Array mit zu bekommen. So ist in idx zuerst eine 0 wenn in hobby "Schwimmen" ist, eine 1, wenn in hobby "Brettspiele" steht und eine 2 bei "Angeln" usw.
Die if-Bedingung ist dabei interessant: 1 << idx nutzt den bit-shift Operator "<<". Der nimmt die Zahl, die links steht (also die 1) und verschiebt alle Bit um die Anzahl der Stellen, die in idx aktuell steht.
Also Beispiel: Die 1 ist ja in Binärdarstellung:
00000001
wenn idx gerade 3 wäre, würde die 1 verschoben, so dass man das hier hat:
00001000
Das wieder zurück ins Dezimalsystem gewandelt ergibt einfach eine 8
Das bedeutet: Man bekommt auf diese Weise gerade die Zahlen, die den einzelnen Hobbys zugeordnet sind.
Als nächstes habe ich den Bitwise-Und-Operator verwendet, das ist einfach das Kaufmanns-und. Das macht für jedes einzelne Bit der Zahl links und rechts eine und-Verknüpfung und setzt nur dann das Bit im Ergebnis, wenn beide Bit der Eingabezahlen auch gesetzt sind.
Angenommen die Eingabezahl war die 11. Das würde für Schwimmen, Brettspiele und Kochen stehen.
Im ersten Schleifendurchlauf ist idx 0. Dann würde der Ausdruck 1 << idx die 1 gar nicht verschieben (halt um 0 Stellen...), also ist das Ergebnis immer noch eine 1.
Als nächstes käme diese Und-Verknüpfung. Da die eben ausgerechnete Zahl (also die 1) nur ein Bit gesetzt hat, nämlich das erste (oder letzte, je nachdem von wo aus Du zählst, auf jeden Fall das niederwertigste), werden automatisch alle anderen Bit 0. Egal was in der Zahl auf der rechten Seite drin steht, wenn links schon eine 0 ist, ergibt die Und-Verknüpfung auch eine 0. Nur an der Stelle, bei der links die Eins steht, könnte es vielleicht ein anderes Ergebnis geben, wenn zufällig rechts auch eine 1 an dieser Stelle wäre.
Man nennt so etwas auch eine "Maske". Nur die Bit, die in der Maske gesetzt sind, können auch im Ergebnis durch kommen. Man nimmt also die eingegebene Zahl und hält eine Maske drüber, die in unserem Fall nur ein Loch hat (nämlich bei der 1). Dort scheint das Bit von der Eingabezahl durch, alle andere Stellen werden 0.
Diese Maske verschieben wir durch die <<idx-Operation bei jedem Schleifendurchlauf eine Stelle weiter. Auf diese Art filtern wir jedes einzelne Bit von number nach und nach aus, bei jedem Schleifendurchlauf ein anderes.

Bei dem Python-if scheint es so zu sein, wie in vielen anderen C-artigen Programmiersprachen auch: Wenn eine Zahl in der Bedingung steht, dann wird nur die 0 als false interpretiert, alle anderen Zahlen werden true. Deshalb genügt es auch, die Bedingung so zu schreiben, wie ich das getan habe: Wenn die Maske gerade über einer 0 steht, wird das Ergebnis auch 0 --> false, wenn es über einer 1 stand, dann wird es irgendeine andere Zahl sein --> true.

Das mit Maske und Bit-Operationen ist in diesem Zusammenhang ein sehr wichtiges und häufig verwendetes Konzept (eher in Hardware-naher Programmierung, aber manchmal auch sonst wo). Es mag zuerst recht befremdlich erscheinen, aber für Computer ist das die natürlichste Art, etwas zu rechnen. Wenn man damit geschickt arbeitet, kann man manche Dinge unglaublich schnell mit dem Computer machen. Z. B. ist das im Netzwerkbereich mit den ganzen Subnetting ein Thema. Aber auch in sehr vielen anderen Gebieten. Auch die Verwendung wie hier von der Art Menge (oder englisch Set) ist eine gebräuchliche Anwendung.

Gruß
Marco
02.11.2017 22:45 as_string ist offline E-Mail an as_string senden Beiträge von as_string suchen Nehmen Sie as_string in Ihre Freundesliste auf
lea
Grünschnabel


Dabei seit: 02.11.2017
Beiträge: 8

Auf diesen Beitrag antworten Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       Zum Anfang der Seite springen

dankeschön für die schnelle Antwort, das hilft auf jeden Fallsmile
02.11.2017 22:53 lea ist offline E-Mail an lea senden Beiträge von lea suchen Nehmen Sie lea in Ihre Freundesliste auf
lea
Grünschnabel


Dabei seit: 02.11.2017
Beiträge: 8

Auf diesen Beitrag antworten Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       Zum Anfang der Seite springen

Noch eine weitere Frage dazu. Wenn ich 256 eingebe soll keine Hobbys rauskommen genauso bei null. Wenn ich das mit else mache, gibt er mir für jeden Part in der Liste Keine Hobbys aus. Wie schaffe ich es, dass nur einmal Keine Hobbys da steht
02.11.2017 23:08 lea ist offline E-Mail an lea senden Beiträge von lea suchen Nehmen Sie lea in Ihre Freundesliste auf
as_string as_string ist männlich
Haudegen


Dabei seit: 06.11.2013
Beiträge: 639
Herkunft: Heidelberg

Auf diesen Beitrag antworten Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       Zum Anfang der Seite springen

Dann müsste man noch eine Boolesche Variable einführen, vielleicht "found" oder so, die man mit false initialisiert und bei jedem Fund auf true setzt (das ändert ja nur beim ersten mal was). Dann kann man die am Ende nach der Schleife noch überprüfen.
Müsste aber selbst schauen, wie man das in Python am besten macht...

Gruß
Marco
02.11.2017 23:18 as_string ist offline E-Mail an as_string senden Beiträge von as_string suchen Nehmen Sie as_string in Ihre Freundesliste auf
as_string as_string ist männlich
Haudegen


Dabei seit: 06.11.2013
Beiträge: 639
Herkunft: Heidelberg

Auf diesen Beitrag antworten Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       Zum Anfang der Seite springen

Also ich mag es in solchen Fällen eigentlich, wenn man gleich mitzählt, wie viele Hobbys gefunden wurden. Das ist besser, als nur True/False und hat aber auch keine Nachteile, weil keine Hobbys gefunden wird ja dann 0 und 0 ist False, sobald eines gefunden wurde oder auch mehrere, dann ist die Variable True. Sie hat also mehr Information (nämlich auch die tatsächliche Anzahl) aber ohne Umstände auch die True/False Information.

Dann würde man vor der Schleife
code:
1:
found = 0
schreiben und ganz am Ende:
code:
1:
2:
if not found:
        print("Keine Hobbys gefunden")


Und zum print im inneren if-Block innerhalb der for-Schleife dann noch found jedes Mal um eins hochzählen, mit "found += 1" z. B.

Gruß
Marco
02.11.2017 23:35 as_string ist offline E-Mail an as_string senden Beiträge von as_string suchen Nehmen Sie as_string in Ihre Freundesliste auf
Baumstruktur | Brettstruktur
Gehe zu:
Neues Thema erstellen Antwort erstellen
Informatiker Board » Themengebiete » Praktische Informatik » Programmierung mit for-Schleife