Donnerstag, 27. Januar 2011
Python -> Java (POS1: 2A, 2C)
from sys import argv, stderr, stdin, stdout def count(inStream): anz = 0 imWort = False zeichen = inStream.read(1) eof = zeichen == "" while not eof: if imWort: if " \n\t".find(zeichen) >= 0: imWort = False else: if " \n\t".find(zeichen) == -1: imWort = True anz = anz + 1 zeichen = inStream.read(1) eof = zeichen == "" return anz if __name__ == "__main__": outStream = stdout if len(argv) == 1: inStream = stdin elif len(argv) >= 2: inStream = open(argv[1], "r") if len(argv) == 3: outStream = open(argv[2], "w") anz = count(inStream) ausgabe = "Anzahl = %d\n" % anz outStream.write(ausgabe)Was macht das Programm?
Was kann man über die Einhaltung Programmierrichtlinien bei diesem Programm sagen (abgesehen vom fehlenden Header)?
Labels: Aufgabe, Java, POS1-2, Python
Zählen von Zeichen aus einer Menge (POS1: 2A, 2C)
stdin
) die Zeichen aus einer Menge von Zeichen zählt. Die Menge der Zeichen wird als Kommandozeilenargument angegeben. Weitere Argumente sind die Dateien, die gelesen werden. Ist nur ein Parameter angegeben, so soll aus stdin gelesen werden. Kein Parameter ergibt eine Fehlermeldung. Groß-/Kleinschreibung ist nicht zu berücksichtigen.Aufrufbeispiele (die Startklasse ist in diesem Beispiel
Count
):~/workspace/count/bin > java Count aeiou file1.txt file2.txt a -> 23 e -> 30 i -> 14 o -> 12 u -> 17 ~/workspace/count/bin > java Count Fehler: mindestens die Menge der Zeichen angeben! ~/workspace/count/bin > java Count -h Bestimmen der Häufigkeiten einer Menge von Zeichen. Aufruf: java Count [-h] zeichenmenge [dateien...] ~/workspace/count/bin > java Count abc das ist der Text. Beispiel zweite Zeile. ^D a -> 1 b -> 1 c -> 0 ~/workspace/count/bin >Nennen Sie das Projekt
count
(dann natürlich klasse-familienname-java-count
), wobei name
Ihr Familienname und klasse
Ihre Klasse ist (z.B. 2ad-haberstroh-java-count
).Samstag, 22. Januar 2011
Ermittle die Top-10 der Worte in einem Text (POS1: 2A, 2C)
Aufgabe 1
Schreiben Sie eine Funktionhauf(string)
, welche die 10 häufigsten Worte im String string ermittelt und als Liste von Tupeln der Art (wort, anzahl)
zurück liefert (Länge der Liste ist <= 10). Die Liste muss so sortiert sein, dass das Häufigste Wort ganz am Anfang ist. Haben Worte die selben Häufigkeiten, so haben diese alphabetisch sortiert zu sein.
Aufgabe 2
Schreiben Sie eine Funktion histogramm(liste, weite = 60)
, welche aus der übergebenen Liste ein Histogramm erzeugt und als String zurück liefert. Eine „Zeile“ soll so aussehen:das 123 ************Wobei für das Wort 14 Zeichen, die Anzahl 3 Zeichen vorgesehen werden müssen. Dahinter ist eine Anzahl Sternchen, die der Anzahl bezogen auf das Maximum (höchste Anzahl in der Liste) und der Weite entspricht (
round(anzahl / max * weite)
).
Aufgabe 3
Schreiben Sie eine Funktion main()
, welche alle auf der Kommandozeile angegebenen Dateien öffnet und die Gesamthäufigkeiten ermittelt (also hauf()
mit dem gesamten gelesenen Text aufruft) und mit den ermittelten Daten das Histogramm ausgibt.Sind keine Dateien angegeben, so ist von stdin zu lesen (bis
EOF
).Beispielaufruf mit den Testdaten vom /vorgabe-Verzeichnis:
hp@l111~/workspace/python$ python3 haufdiagramm.py testdaten.txt der 89 ************************************************************ die 61 ***************************************** und 43 ***************************** Histogramm 40 *************************** in 28 ******************* für 17 *********** ist 17 *********** den 16 *********** das 15 ********** ein 14 *********
Mögliche Lösung
Ich werde die einzelnen Funktionen erklären:import sysDieser Import wird für die Kommandozeilenargumente benötigt.
Folgende Funktion ermittelt die Wort-Häufigkeiten, sortiert das Ergebnis nach Häufigkeit und liefert die ersten 10 Elemente.
def hauf(string): """ermittelt die 10 häufigsten Worte in 'string' und liefert Liste mit Tupel (wort, anzahl)""" dict = {} for wort in string.split():
split()
ohne Parameter zerlegt einen String in eine Liste von "Worten", wobei ein "Wort" eine Folge von Zeichen ohne Leerzeichen, Tabulator und Zeilenumbruch ist. Mit anderen Worten Leerzeichen, Tabulatoren und Zeilenumbrüche sind die Trenner.wort = wort.rstrip('.,;?!")') # Satzzeichen entfernen wort = wort.lstrip('"(') # Hochkomma und Klammer dürfen vorne stehen
lstrip()
und rstrip()
entfernen alle Zeichen in Klammer llinks bzw. rechts. In unserem Fall alle Satzzeichen, die unmittelbar vor einem Wort bzw. nach einem Wort stehen dürfen.Die beiden Zeilen könnte man natürlich auch zusammenfassen zu:
wort = wort.rstrip('.,;?!")').lstrip('"(')
.Die folgende erste Zeile prüft, ob der String auch tatsächlich ein Wort ist (nur Buchstaben).
if wort.isalpha(): if wort in dict: dict[wort] += 1 else: dict[wort] = 1Obige 4 letzte Zeilen prüfen zunächst, ob das Wort bereits im Dictionary enthalten ist. Wenn ja, dann wird die gespeicherte Anzahl erhöht, wenn nein, dann wird unter diesem Wort eine
1
gespeichert.l = list(dict.items())Erzeugt eine Liste mit Tupeln
(wort, anzahl)
aus dem Dictionary.l.sort(key=lambda x: (-x[1], x[0]))
sort()
sortiert eine Liste nach der natürlichen Reihenfolge. Mit dem Parameter key
kann eine Funktion übergeben werden, anhand deren Returnwert sortiert werden soll. Die Funktion wird jeweils mit einem Listenelement aufgerufen. Man könnte also eine Funktion schreiben, die jeweils das zweite Element des Tupels (die Liste besteht in diesem Fall ja aus Tupeln der Art (wort, anzahl)
) zurückliefert. Da absteigend sortiert werden soll, muss entweder der Wert mit -1
multipliziert werden (-[x1]
) oder man muss beim Sortieren sort(reverse=True)
aufrufen. Den Namen dieser Funktion übergibt man dann per key=sortfunktion
.Diese Funktion könnte so aussehen:
def sortierfunktion(x):return (-x[1], x[0])
lambda x:
definiert eine anonyme Funktion (Funktion ohne Namen) mit dem Parameter x
, die gleich an Ort und Stelle definiert und übergeben werden kann.l = l[0:10] return lDie letzten beiden Zeilen schneiden die ersten 10 Elemente der Liste aus und liefern sie zurück.
Das könnte man auch nur mit einer Anweisung machen:
return l[:10]
.def stars(num, max, width): """liefert String mit so vielen Sternen, wie num / max * width""" return "*" * round(num / max * width)Dazu braucht man nicht allzu viel sagen.
Die folgende Funktion erzeugt das in Aufgabe 2 geforderte Histogramm.
Um einen passenden Maßstab für die geforderte Weite
weite=60
zu finden, wird das Maximum der Werte ermittelt. Das muss natürlich das zweite Element des ersten Tupels der Liste sein, wenn überhaupt Tupel in der Liste sind.def histogramm(liste, weite=60): """erzeugt Histogramm und liefert es zurück""" if len(liste) > 0: max = liste[0][1] ret = "" for wort, anzahl in liste:Diese Schleife geht jedes Tupel der Liste durch, wobei die Tupel gleich in
wort
und anzahl
"ausgepackt" wird.ret += "%-14s%3d %s\n" % (wort, anzahl, stars(anzahl, max, weite))Hier wird jede Zeile an den String
ret
angehängt, wobei Stringformatierung angewendet wird.return ret
Die folgenden beiden Funktionen dient nur zum Testen mit fixen Strings und liefert einen String mit vorgegebenen Anzahlen von Worten.
def teststr(): """liefert Testeingabe""" s = "Häufigkeit " * 50 + "das " * 123 + "die, " * 100 + "Haus " * 40 s += "Maus " * 38 + "Koffer " * 34 + "Kilogramm " * 22 + "Punkt " * 18 s += "Genau " * 16 + "Zehn " * 10 s += "nichts " * 5 + "23 " * 50 + "ziemlich " * 3 return s def test(): """Testen...""" liste = hauf(teststr()) print(histogramm(liste, 12.3))
Diese Funktion prüft, ob überhaupt Kommandozeilenargumente vorhanden sind. Gibt es welche, so werden alle Argumente als Dateien zum Lesen geöffnet und mit
read()
komplett gelesen und an den String eingabe
angehängt.Gibt es keine Dateinamen auf der Kommandozeile, so wird mittels
eingabe = sys.stdin.read()
von der Standardeingabe gelesen.Die letzte Zeile ruft die beiden Hauptfunktionen auf und gibt das Ergebnis aus.
Es fehlt allerdings noch die Überprüfung, ob eine Datei überhaupt existiert bzw. geöffnet werden kann. Diesen Teil möge der Leser selber ergänzen.
def main(): """öffnet Datei oder liest von stdin""" if len(sys.argv) > 1: eingabe = "" for arg in sys.argv[1:]: f = open(arg) eingabe += " " + f.read() f.close() else: eingabe = sys.stdin.read() print(histogramm(hauf(eingabe)))
Die folgenden Zeilen dienen zum Aufrufen der Funktion
main()
(bzw. test()
zum Testen), sofern dieses Script als Programm aufgerufen wurde.if __name__ == '__main__': # test() main()
Vollständiges Programm (ohne Header)
import sys def hauf(string): """ermittelt die 10 häufigsten Worte in 'string' und liefert Liste mit Tupel (wort, anzahl)""" dict = {} for wort in string.split(): wort = wort.rstrip('.,;?!")') # Satzzeichen entfernen wort = wort.lstrip('"(') # Hochkomma und Klammer dürfen vorne stehen if wort.isalpha(): if wort in dict: dict[wort] += 1 else: dict[wort] = 1 l = list(dict.items()) l.sort(key=lambda x: (-x[1], x[0])) l = l[0:10] return l def stars(num, max, width): """liefert String mit so vielen Sternen, wie num / max * width""" return "*" * round(num / max * width) def histogramm(liste, weite=60): """erzeugt Histogramm und liefert es zurück""" if len(liste) > 0: max = liste[0][1] ret = "" for wort, anzahl in liste: ret += "%-14s%3d %s\n" % (wort, anzahl, stars(anzahl, max, weite)) return ret def teststr(): """liefert Testeingabe""" s = "Häufigkeit " * 50 + "das " * 123 + "die, " * 100 + "Haus " * 40 s += "Maus " * 38 + "Koffer " * 34 + "Kilogramm " * 22 + "Punkt " * 18 s += "Genau " * 16 + "Zehn " * 10 s += "nichts " * 5 + "23 " * 50 + "ziemlich " * 3 return s def test(): """Testen...""" liste = hauf(teststr()) print(histogramm(liste, 12.3)) def main(): """öffnet Datei oder liest von stdin""" if len(sys.argv) > 1: eingabe = "" for arg in sys.argv[1:]: f = open(arg) eingabe += " " + f.read() f.close() else: eingabe = sys.stdin.read() print(histogramm(hauf(eingabe))) if __name__ == '__main__': # test() main()
Labels: Aufgabe, Lösung, POS1-2, Python
Freitag, 14. Januar 2011
Ganze Zahlen zählen (Schleife, Sequenzen, Funktionen POS1: 1BHIF)
Beispiel:
Eingabe:
das ist eine Zahl 123 und noch eine 1 und noch zwei 3213x23123Ausgabe:
4 Zahlen gefunden.Das Programm soll richtige Sätze ausgeben, also "Keine Zahlen gefunden.", wenn in der Eingabe keine Zahlen sind oder "Eine Zahl gefunden.", wenn eine Zahl in der Eingabe war. Ab 4 soll dann die Zahl ausgegeben werden, z.B. "6 Zahlen gefunden."
Mögliche Lösung:
""" author: Haberstroh, Harald matnr: d09666 file: anzzahlen.py desc: Zähle ganze Zahlen Beispiel: das ist eine Zahl 123 und noch eine 1 und noch zwei 3213x23123 Ausgabe: 4 Zahlen gefunden date: 14.1.2011 class: Lehrer catnr: 33 """ #---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+---- def anz_zahlen(string): """ermittelt die Anzahl der ganzen Zahlen im String""" anzahl = 0 in_zahl = False for zeichen in string: if zeichen in "0123456789": if not in_zahl: anzahl += 1 in_zahl = True else: in_zahl = False return anzahl def ausgabe(anzahl): """gibt deutschen Satz aus mit Anzahl""" if anzahl == 0: print("Keine Zahl gefunden.") elif anzahl == 1: print("Eine Zahl gefunden.") elif anzahl == 2: print("Zwei Zahlen gefunden.") elif anzahl == 3: print("Drei Zahlen gefunden.") else: print(anzahl, "Zahlen gefunden.") def main(): """EVA Eingave Verarbeitung Ausgabe - das Hauptprogramm""" string = input("> ") anzahl = anz_zahlen(string) ausgabe(anzahl) def test(): """Testen von anz_zahlen() und ausgabe()""" string = "das ist eine Zahl 123 und noch eine 1 und noch eine 3213x23123" anzahl = anz_zahlen(string) ausgabe(anzahl) ausgabe(anz_zahlen("keine")) ausgabe(anz_zahlen("eine Zahl 123")) ausgabe(anz_zahlen("zwei 23 und 324")) ausgabe(anz_zahlen("drei 23 34 22")) ausgabe(anz_zahlen("vier 234 234 234 45")) ausgabe(anz_zahlen("5 234 234 234 45")) if __name__ == '__main__': main() # test()Beachten Sie, dass ich hier eine eigene Funktion
test()
gemacht habe, um viele Testfälle immer wieder leicht probieren zu können. Statt main()
muss dann nur test()
aufgerufen werden.Das Programm wäre auch ohne die Funktion
test()
fertig und korrekt. test()
half nur bei der Entwicklung bei der Fehlersuche.Labels: Aufgabe, Lösung, POS1-1, Python
Donnerstag, 13. Januar 2011
Beispiele zeichenweise Bearbeitung, Java (POS-1: 2A, 2C)
Anzahl der Strings in der Eingabe ermitteln
Schreiben Sie ein Programm, welches die Anzahl der Strings in der Eingabe ermittelt. Strings sind beliebige Zeichenketten zwischen Hochkomma (z.B.
). Verwenden Sie Schalter zum Erkennen von Strings (Zustand "InString", wenn man innerhalb eines Strings ist und "OutString", wenn gerade kein String gelesen wird).ein string
Anzahl der Zahlen ermitteln
Schreiben Sie ein Programm, welches die Anzahl der Zahlen in der Eingabe ermittelt (ganze Zahlen, müssen durch Leerzeichen, Tabulatoren oder Zeilenumbrüchen von anderen Eingaben getrennt sein).
Ziffern zählen
Schreiben Sie ein Java-Programm, welches die Anzahl der Ziffern in der Standardeingabe ermittelt und ausgibt.
Vokale zählen
Schreiben Sie ein Java-Programm, welches die Anzahl der Vokale in der Standardeingabe ermittelt und ausgibt.
Zeichen, Worte und Zeilen zählen
Schreiben Sie ein Java-Programm, welches die Anzahl der Zeichen, Worte und Zeilen in der Standardeingabe ermittelt und ausgibt.
Mittwoch, 12. Januar 2011
Java Einführung (POS1: 2A, 2C)
Verwenden Sie dazu einen Texteditor und übersetzen Sie das Programm auf der Kommandozeile.
Schreiben Sie ein einfaches Java-Programm, welches das kleine Einmaleins ausgibt. Welchen Namen könnte das Programm haben?
X 1 2 3 4 5 6 7 8 9 10 1 1 2 3 4 5 6 7 8 9 10 2 2 4 6 8 10 12 14 16 18 20 3 3 6 9 12 15 18 21 24 27 30 4 4 8 12 16 20 24 28 32 36 40 5 5 10 15 20 25 30 35 40 45 50 6 6 12 18 24 30 36 42 48 54 60 7 7 14 21 28 35 42 49 56 63 70 8 8 16 24 32 40 48 56 64 72 80 9 9 18 27 36 45 54 63 72 81 90 10 10 20 30 40 50 60 70 80 90 100Verwenden Sie wieder einen Texteditor und den Java-Compiler auf der Kommandozeile.
Montag, 10. Januar 2011
TIOBE-Index: Python ist Programmiersprache 2010
Detaillierte Informationen gibt es hier und hier.
Labels: C, C#, C++, Go, Objective C, Programmiersprachen, Python, ruby
Abonnieren Posts [Atom]