Python Neuling braucht Hilfe bei Hausaufgabe

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
Milhouse
User
Beiträge: 5
Registriert: Montag 7. November 2011, 16:25

Hallo liebe Community.

Bin noch ziemlich neu hier und auch neu in der Welt der Programmierung :)
Nun haben wir letztens eine Aufgabe von unserem Dozenten bekommen an der ich ein wenig verzweifle.
Die Aufgabe besteht darin, ein Programm mit Python zu schreiben welches für einen gegebenen string alle wörter findet und ausdruckt die GENAU einmal, zweimal und dreimal vorkommen, und dazu noch die proper-substrings von anderen wörtern in diesem string sind.
Ich verzweifel langsam an dieser Aufgabe und weiß gar nicht richtig wo ich anfangen soll.

Ich poste hier mal den string um den es geht:
s = """Wer oh wer reitet da so spaet durch nacht und wind
oh jeh oh jeh es ist ein Vater und er hat heute sowohl sein hund als
auch sein dartboard vergessen"""

Gewuenschter Output:
Kommt genau einmal vor:
Wer
als
es
er
Vater
nacht
spaet
wer
hat
dartboard
auch
heute
da
sowohl
reitet
ist
vergessen
so
durch
hund
wind
ein
Kommt genau zweimal vor:
jeh
und
sein
Kommt genau dreimal vor:
oh
proper substrings:
oh
da
und
so
er
es
ein

Hoffe irgendwer kann mir helfen oder mir den richtigen ansatz geben.
Danke im vorraus :)
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hallo und willkommen im Forum!

Du solltest dich als erstes von dem Gedanken trennen, dass hier jemand deine Hausaufgaben für dich erledigen wird ;-) Zeig doch mal, was du bisher versucht hast. Damit lässt sich dir am effektivsten helfen. Das Forum unterstützt übrigens auch Code-Tags für Python, damit solltest du deinen Code hervorheben.

Sebastian
Das Leben ist wie ein Tennisball.
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

So hier, absichtlich nicht in Code-Form damit du gezwungen bist es dir anzusehen ;)

Code: Alles auswählen

In [1]: s = """Wer oh wer reitet da so spaet durch nacht und wind
   ...: oh jeh oh jeh es ist ein Vater und er hat heute sowohl sein hund als
   ...: auch sein dartboard vergessen"""

In [2]: from collections import defaultdict

In [3]: count = defaultdict(int) # defaultdict ist wirklich praktisch -> anschauen!

In [4]: for word in s.split():
   ...:     count[word] += 1
   ...: 

In [5]: import pprint; pprint.pprint(dict(count)) # nur zum sehen, was sich jetzt in dem defaultdict verbirgt
{'Vater': 1,
 'Wer': 1,
 'als': 1,
 'auch': 1,
 'da': 1,
 'dartboard': 1,
 'durch': 1,
 'ein': 1,
 'er': 1,
 'es': 1,
 'hat': 1,
 'heute': 1,
 'hund': 1,
 'ist': 1,
 'jeh': 2,
 'nacht': 1,
 'oh': 3,
 'reitet': 1,
 'sein': 2,
 'so': 1,
 'sowohl': 1,
 'spaet': 1,
 'und': 2,
 'vergessen': 1,
 'wer': 1,
 'wind': 1}

In [15]: for k,v in count.items():
   ....:     res[v].append(k)
   ....: 

In [16]: res # wie oft kommt welches wort vor?
Out[16]: defaultdict(<class 'list'>, {1: ['Wer', 'als', 'es', 'er', 'Vater', 'auch', 'spaet', 'wer', 'hat', 'vergessen', 'dartboard', 'da', 'heute', 'nacht', 'sowohl', 'reitet', 'ist', 'so', 'durch', 'hund', 'wind', 'ein'], 2: ['und', 'jeh', 'sein'], 3: ['oh']})

In [23]: proper = list()

In [24]: for word in words:
   ....:     for ag in words:
   ....:         if word in ag and not word == ag:
   ....:             proper.append(word)
   ....:             break
   ....: 

In [25]: proper # "proper-substrings" mit duplikaten, welche man durch ein "set" entfernen kann, oder einfach einen weiteren check im "if": "if word in ag and not word == ag and not word in proper:"
Out[25]: ['oh', 'da', 'so', 'und', 'oh', 'oh', 'es', 'ein', 'und', 'er']

In [26]: set(proper)
Out[26]: set(['oh', 'da', 'und', 'so', 'er', 'es', 'ein'])
Ich hoffe du kopierst das nicht nur, sondern schaust es dir auch genau an!

//Edit: @EyDu :oops: hat wohl doch wer gemacht
the more they change the more they stay the same
Trulla
User
Beiträge: 4
Registriert: Dienstag 8. November 2011, 12:20

Hey,

ich habe die gleiche Aufgabe und habe ein paar Fragen:

Was genau machst du bzw passier im Schritt 15?
Was ist "res[]"? Und fügt append nicht am Ende der Liste normalerweise ein Element dazu?
Was macht defaultdict? Ich habe mir zwar ein paar Sachen dazu durchgelesen, aber richtig verstanden habe ich es immernoch nicht...

Weitere Fragen folgen sicherlich, sobald ich weiß, was in 15 passiert...^^
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Trulla hat geschrieben: Was ist "res[]"? Und fügt append nicht am Ende der Liste normalerweise ein Element dazu?
Was macht defaultdict? Ich habe mir zwar ein paar Sachen dazu durchgelesen, aber richtig verstanden habe ich es immernoch nicht...
Hast Du denn verstanden, was ein Dictionary ist und wie es funktioniert? Wenn ja, sollte das DefaultDict eigentlich keine größeren Schwierigkeiten machen ;-)

Schau Dir dazu doch mal das offizielle Tutorial an! Zudem kannst Du in einer Shell die einzelnen Schritte mal versuchen, nachzuvollziehen.

Kurzer Hint: In Schritt 15 dreht Dav1d eigentlich nur das DefaultDict `count` aus Schritt 3 um. `count` bildet ja Wörter auf die Anzahl ab (Wort -> Key, Anzahl -> Value), in Schritt 15 soll es umgedreht werden (Anzahl -> Key, Wörter -> Value). Das DefaultDict wird nur verwendet, um sich die Initialisierung der leeren Liste zu einem Wort zu sparen, welches neu als Schlüssel eingetragen wird. Man kann das auch recht einfach ohne dieses spezielle Objekt realisieren, da braucht es dann eben nur eine zusätzliche if-Bedingung beim Eintragen. Aber wozu kompliziert, wenn es ein fertiges Objekt gibt, welches genau die Funktionalität liefert ;-)

Edit: Schritt 4 könnte man durch die Verwendung von `collections.Counter` noch mal einfacher gestalten:

Code: Alles auswählen

In [28]: c = Counter(s.split())

In [29]: c
Out[29]: Counter({'oh': 3, 'und': 2, 'jeh': 2, 'sein': 2, 'Wer': 1, 'als': 1, 'es': 1, 'er': 1, 'Vater': 1, 'auch': 1, 'spaet': 1, 'wer': 1, 'hat': 1, 'vergessen': 1, 'dartboard': 1, 'da': 1, 'heute': 1, 'nacht': 1, 'sowohl': 1, 'reitet': 1, 'ist': 1, 'so': 1, 'durch': 1, 'hund': 1, 'wind': 1, 'ein': 1})
Zuletzt geändert von Hyperion am Dienstag 8. November 2011, 12:55, 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
Trulla
User
Beiträge: 4
Registriert: Dienstag 8. November 2011, 12:20

Ich weiß halt nicht, ob wir dictionaries benutzen dürfen, das hatten wir noch nicht. Momentan bastel ich an einer if-Schleife.
Ist gar nicht so leicht und ziemlich aufwendig. Meine Idee ist, den in eine Liste umgewandelten string zu nehmen und nun für jedes Listenelement i die Anzahl zu nehmen (mit count Befehl), anschließend abzufragen, ob es 1,2 oder 3 ist und dann entsprechend zu drucken. Das wird aber recht verschachtelt und komplex, oder? Geht das generell überhaupt?
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Trulla hat geschrieben:Momentan bastel ich an einer if-Schleife.
Das ist ja wie eine Seuche. Kaum denkt man, man habe den Begriff if-schleife langsam ausgerottet, da taucht er schon wieder irgendwo auf.

Was bringt dich auf die Idee, dass if ein Schleifenkonstrukt sei?
Trulla
User
Beiträge: 4
Registriert: Dienstag 8. November 2011, 12:20

*for-Schleife.... Sorry....
BlackJack

@Trulla: Ich verstehe dieses "das hatten wir noch nicht"-Argument irgendwie nicht. Das kommt komischerweise öfter. Ist es denn bei euch verboten selbstständig etwas zu lernen? Dürft ihr grundsätzlich nur soweit denken wie der Lehrer/Dozent das erlaubt. ;-)

Nur mit Listen und `list.count()` geht das zwar schon, aber das wird alles andere als schön, und effizient schon mal gar nicht. Listen (`list`) und Wörterbücher (`dict`) sind neben Tupeln (`tuple`) die beiden grundlegenden Container-Datentypen in Python. Deshalb sind sie auch „eingebaut“, dass heisst man muss sie nicht extra aus einem Modul importieren. Mengen (`set`) übrigens auch. Die wären bei einer Listen-Lösung mit `count()` interessant um sich zu merken und zu testen ob man ein Wort schon einmal hatte, beziehungsweise um die Liste der Worte in eine Menge zu überführen um Duplikate zu eliminieren. Aber den Datentyp hattet ihr wahrscheinlich auch noch nicht…
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

@Hyperion, ich wusste da gibt es schon was…ich hab es nur nicht auf die Schnelle gefunden ;).
the more they change the more they stay the same
Milhouse
User
Beiträge: 5
Registriert: Montag 7. November 2011, 16:25

@Dav1d, Ich verstehe zwar das prinzip an sich dass man eben einen counter einbaut und somit je öfter das wort vorkommt sich der counter +1 erhöht, allerdings verstehe ich so gut wie kaum einen der befehle die du da benutzt. was ist s.split()? wenn ich das bei mir probiere funktioniert da nichts.
Tut mir leid aber ich bin wirklich noch ein neuling in python und kenne mich noch nicht so recht aus.
Ich glaube allerdings auch, dass wir das nicht mit dictionaries machen sollen weil wir die noch gar nicht hatten. Ich weiß das ist kein argument es nicht so zu machen aber die aufgabe soll ja dazu sein das was wir schon hatten nochmal zu vertiefen.
BlackJack

@Milhouse: Die `split()`-Methode auf Zeichenketten gehört zu den absoluten Grundlagen. Es gibt eine Dokumentation (http://docs.python.org/), da kann man die Datentypen, Funktionen, und Methoden nachschlagen. Wird gerne mal übersehen: Der Index ist da manchmal hilfreich. Und auch wenn das alles noch nicht im Unterricht dran war: Das Tutorial sollte man mal durchgearbeitet haben.

Ansonsten hilft zum Lernen beziehungsweise beim Verständnis auch oft es einfach mal in einer Python-Shell aus zu probieren. Ruf dort mal die `split()`-Methode auf Deiner Zeichenkette auf und schau was passiert. Wenn ihr die noch nicht hattet, dann kann es nicht nur um Vertiefen von Dingen gehen die ihr schon hattet. Die Methode ist hier ziemlich essentiell.
Trulla
User
Beiträge: 4
Registriert: Dienstag 8. November 2011, 12:20

Nein, es ist keineswegs verboten, selbstständig zu lernen. Bringt ja auch mehr Spaß und macht auch wesentlich mehr Sinn. Das Problem daran ist, dass die Dozenten das etwas anders sehen und auf die Aufgabe nicht die volle Punktzahl geben, wenn überhaupt. Wie oft habe ich schon gehört, dass das nicht "im Sinne der Aufgabenstellung" war, da wir den "Stoff der Vorlesung" umsetzen sollen. Entschuldige also, wenn ich mir unsicher bin, ob ich das so machen "darf". Es ist für mich genauso frustrierend wie, anscheinend, für dich, denn ich kann mir ja offensichtlich die ganze Sache wesentlich einfacher machen, wenn ich die dict() benutze. ;-)

Und split() hatten wir angesprochen, das ist also gar kein Problem.

Habe das ganze nun, sehr hässlich und umständlich, mit einer for-Schleife und if-Abfragen mehr oder minder gelöst. Probleme habe ich noch bei den substrings. Jemand einen Tip, wie man das simpel (wir sind ganz neu dabei) lösen kann?
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Trulla hat geschrieben:Probleme habe ich noch bei den substrings. Jemand einen Tip, wie man das simpel (wir sind ganz neu dabei) lösen kann?

Code: Alles auswählen

>>> print "ab" in "Gabel"
True
>>> print "ba" in "Gabel"
False
>>> print "Gabel".find("ab")
1
Dokumentation zu find().
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Wenn du keine Dictionaries verwenden sollst, was hält dich davon ab selbst eins zum implementieren? Viel mehr als das brauchst du wohl nicht:

Code: Alles auswählen

>>> def dict_get(d, key, default_value):
...     for elem in d:
...         if elem[0] == key:
...             return elem
...     d.append([key, default_value])
...     return d[-1]
... 
>>> data = "das ist ein text das ist noch mehr text und noch viel mehr text"
>>> counter = []
>>> for word in data.split():
...     elem = dict_get(counter, word, 0)
...     elem[1] += 1
... 
>>> counter
[['das', 2], ['ist', 2], ['ein', 1], ['text', 3], ['noch', 2], ['mehr', 2], ['und', 1], ['viel', 1]]
Das Leben ist wie ein Tennisball.
Antworten