Re: Code-Review zur Thematik "Konstanten"
Verfasst: Sonntag 31. Oktober 2021, 22:18
Ja, "Uncle Bob" hat seine Marktlücke gefunden – mit dem diskutiert man daher wohl besser nicht 

Seit 2002 Diskussionen rund um die Programmiersprache Python
https://www.python-forum.de/
Code: Alles auswählen
In [380]: "foo bar".title()
Out[380]: 'Foo Bar'
In [381]: "foo bar".capitalize()
Out[381]: 'Foo bar'
Code: Alles auswählen
def encode(text, key):
return _code(add, text, key)
def decode(text, key):
return _code(sub, text, key)
def _code(offset_function, text, key):
...
Code: Alles auswählen
encode = partial(_code, add)
decode = partial(_code, sub)
def _code(offset_function, text, key):
...
versteheBei mehr als einem Wort macht es aber einen Unterschied:
ja genau, das schlägt Hr. Martin vor.Man kann ja auch der Meinung sein, dass man erst das ”grosse, grobe Bild malt” und die kleineren detaillierteren Teile danach ausfüllt. Also von der Hauptfunktion startend, und dann die Einzelschritte, bis zu Detailaufgaben und Hilfsfunktionen runter, der Quelltext im Laufe der Datei immer spezieller wird.
Code: Alles auswählen
A
"Abends werden die Faulen fleissig." - Citatboken, Bokförlaget Natur och Kultur, Stockholm, 1967, ISBN 91-27-01681-1
"Abwarten und Tee trinken." - Wander-DSL, Bd. 5, Sp. 702, commons. (Dort zitiert als: "Abwarten und Theetrinken.")
"Adel verpflichtet." (Noblesse oblige) - nach Pierre-Marc-Gaston de Lévis, Maximes et réflections
"Alle Menschen in der Welt streben nur nach Gut und Geld; und wenn sie es dann erwerben legen sie sich hin und sterben." - Citatboken, Bokförlaget Natur och Kultur, Stockholm, 1967, ISBN 91-27-01681-1
"Alle Sünden in eine münden."
"Alle Wege führen nach Rom." - Wander-DSL, Bd. 4, Sp. 1842, commons
"Aller Anfang ist schwer." - Wander-DSL, Bd. 1, Sp. 80, commons
"Aller guten Dinge sind drei." - Wander-DSL, Bd. 1, Sp. 605, commons. (Dort zitiert als: "Aller guten Ding seynd drey.")
"Alles Gute kommt von oben."
"Alles hat seine Zeit, nur die alten Weiber nicht." - Wander-DSL, Bd. 1, Sp. 46, commons
"Alles neu macht der Mai." - nach dem Gedicht von Hermann Adam von Kamp "Alles neu, macht der Mai" (1818)
Code: Alles auswählen
from pathlib import Path
def investigate_sayings():
# TODO
# Verbesserung mittels wiki-api - Texte direkt aus Wikipedia "Sprichwörter" auslesen?
# Methode "tut" zu viel - Zerlegen in Beschaffung der Daten und Erstellen des Datenmodells
filename = Path("C:/Users/Buchfink/Documents/Projkete/WortspielGenerator/Sprueche.txt")
with open(filename, "r", encoding="UTF-8") as file:
investigated_sayings = {}
for line in file:
splitted = line.strip().split(".\"")
saying = splitted[0].strip().replace('\"', '')
if len(saying) == 1:
continue
words = saying.split(" ")
interesting_words = []
for word in words:
if word.istitle():
interesting_words.append(word)
investigated_sayings[saying] = interesting_words
return investigated_sayings
def get_rhyme(word):
# TODO
# Quelle ist noch unklar. Daher nur mal exemplarische simplifizierte Beispielzuordnung
# Ungelöste Probleme:
# - Quelle selbst, hardcodiert ist ja keine Lösung :)
# - Artikelproblem - gleicher Artikel funktioniert immer, unterschiedliche Artikel eher weniger (kontextabhängig)
# - es gibt ggf. mehrere Reimwörter pro Wort,
# - Plural vs. Singular
# - Beidseitigkeit - sprich Laus reimt sich auf Maus und umgekehrt. Man könnte vereinfachen, indem man
# jedes Pärchen nur einmal einfügt
rhymes = {
"Esel": "Sessel", "Sessel": "Esel",
"Geld": "Held", "Held": "Geld",
"Spiegel": "Igel", "Igel": "Spiegel",
"Kopf": "Topf", "Topf": "Kopf",
"Baum": "Raum", "Raum": "Baum",
"Berg": "Zwerg", "Zwerg": "Berg",
"Laus": "Maus", "Maus": "Laus",
"Adel": "Sargnagel", "Sargnagel": "Adel",
"Wunsch": "Punsch", "Punsch": "Wunsch",
"Flügel": "Kleiderbügel",
"Waffen": "Karaffen",
"Macht": "Verdacht"
}
rhyme = rhymes.get(word)
return rhyme
def substitute_with_rhymes(investigated_sayings):
substituted_sayings = []
for key, value in investigated_sayings.items():
for word in value:
substituted_word = get_rhyme(word)
if substituted_word is not None:
substituted_sayings.append(key.replace(word, substituted_word))
return substituted_sayings
def show_sayings(sayings):
for saying in sayings:
print(saying)
print(f"Anzahl {len(sayings)}")
def main():
investigated = investigate_sayings()
substituted = substitute_with_rhymes(investigated)
show_sayings(substituted)
if __name__ == '__main__':
main()
Code: Alles auswählen
investigated_sayings = [
{
"originalsentence": "...",
"keywords": [...]
},
...
]
Code: Alles auswählen
for word in keywords:
Code: Alles auswählen
if substituted_word is not None:
Code: Alles auswählen
if substituted_word:
Code: Alles auswählen
interesting_words = []
for word in words:
if word.istitle():
interesting_words.append(word)
ja - genau sowas hab ich gesucht. Ich wusste nicht (wie/dass) das geht. Danke für den Hinweis!Unter Punkt 2 würde ich aber nicht auf eine Klasse als Datenbehälter wechseln, solange ein Dictionary ausreicht
--> das hab ich direkt korrigiert."is not None" kann man ersetzen:
Das werde ich erst googeln müssen, bevor ich konkrete Fragen dazu stellen kann.List-Comprehension, Dict-Comprehension, oder Generator-Expression.
Es ist schwer zu sagen, wo das irgendwann hingeht. Ich finde Sprache als solches tatsächlich ziemlich interessant. (Mein Name ist eine Anspielung auf den Umstand, dass ich andauernd irgendein Buch lese).Wenn man das Erkennen von Endreimen automatisieren und das Problem "NLP-mäßig" angehen will, ist das nämlich nicht trivial und erfordert (denke ich) die Auseinandersetzung mit entsprechenden Algorithmen (z. B. zur Silbentrennung).
Code: Alles auswählen
In [1]: from collections import namedtuple, defaultdict
In [2]: Saying = namedtuple("Saying", "sentence, keywords")
In [4]: Saying("foo", ["bar"])
Out[4]: Saying(sentence='foo', keywords=['bar'])
# oder
In [5]: sayings = defaultdict(list)
In [6]: sayings["foo"].append("bar")
In [7]: sayings["foo"].append("baz")
In [9]: sayings["spam"].append("eggs")
In [10]: sayings
Out[10]: defaultdict(list, {'foo': ['bar', 'baz'], 'spam': ['eggs']})
Nicht sicher was du genau mit "leeren Werten" meinst, bei keinem dieser falsy Werte würde der if-Zweig ausgeführt.aber `if foo` statt `if foo is not None` schreibe ich nie, weil das auch bei „leeren“ (bzw. allgemein „falsy“) Werten ins `if` springt.
Code: Alles auswählen
falsy_values = [list(), dict(), tuple(), range(0), 0.0, 0, False, set(), None, ""]
for thing in falsy_values:
if thing:
print(f"{thing} is truthy")
else:
print(f"{thing} is falsy")
"""
[] is falsy
{} is falsy
() is falsy
range(0, 0) is falsy
0.0 is falsy
0 is falsy
False is falsy
set() is falsy
None is falsy
is falsy
"""
Code: Alles auswählen
from pathlib import Path
from collections import defaultdict
def investigate_sayings():
# TODO
# Verbesserung mittels wiki-api - Texte direkt aus Wikipedia "Sprichwörter" auslesen?
# Tutorial: https://wdqs-tutorial.toolforge.org/index.php/simple-queries/the-simplest-query/basic-sparql-query/
# Methode "tut" zu viel - Zerlegen in Beschaffung der Daten und Erstellen des Datenmodells
filename = Path("C:/Users/Carina/Documents/Projkete/WortspielGenerator/Sprueche.txt")
with open(filename, "r", encoding="UTF-8") as file:
investigated_sayings = defaultdict(list)
for line in file:
splitted = line.strip().split(".\"")
saying = splitted[0].strip().replace('\"', '')
if len(saying) == 1:
continue
words = saying.split(" ")
for word in words:
if word.istitle():
investigated_sayings[saying].append(word)
return investigated_sayings
Es kann durchaus sein, dass mein "ungutes Gefühl" daher rührt, dass Umlaute in Delphi ein Problem waren, bevor dort Unicode eingeführt wurde. Wenn das in Python kein Problem ist, dann passt das jaEin Dict mit beliebigen Strings als Keys ist IMHO nicht komisch.
Ich fürchte ich muss hier noch "falsy" googeln, denn den Begriff höre/lese ich heute zum ersten Mal.aber `if foo` statt `if foo is not None` schreibe ich nie, weil das auch bei „leeren“ (bzw. allgemein „falsy“) Werten ins `if` springt
hm... jetzt bin ich etwas verwirrt.@rogerb: Flüchtigkeitsfehler, muss natürlich „nicht ins `if` springt“ heißen. Der Punkt ist, dass mit `if foo` nicht zwischen `None` und allgemein falsy unterscheiden werden kann, deswegen besser `if foo is not None`.
Code: Alles auswählen
In [418]: "foo bar".split(" ")
Out[418]: ['foo', '', 'bar']
Code: Alles auswählen
def investigate_sayings():
# TODO
# Verbesserung mittels wiki-api - Texte direkt aus Wikipedia "Sprichwörter" auslesen?
# Tutorial: https://wdqs-tutorial.toolforge.org/index.php/simple-queries/the-simplest-query/basic-sparql-query/
# Methode "tut" zu viel - Zerlegen in Beschaffung der Daten und Erstellen des Datenmodells
filename = Path(
"C:/Users/Carina/Documents/Projkete/WortspielGenerator/Sprueche.txt"
)
with open(filename, "r", encoding="UTF-8") as file:
investigated_sayings = defaultdict(list)
for line_number, line in enumerate(file, 1):
if line.startswith('"'):
saying, seperator, _ = line[1:].partition('."')
if seperator:
for word in saying.split():
if word.istitle():
investigated_sayings[saying].append(word)
else:
print(
f"Fehler: Ende von Spruch in Zeile {line_number} nicht gefunden."
)
else:
line = line.rstrip()
if not (len(line) == 1 and line.isalpha()):
print(
f"Fehler: Unerwartete(s) Zeichen in Zeile {line_number}."
)
return investigated_sayings
Im Hinblick auf das Fehlermanagement habe ich leider noch nicht geschafft, die ganzen Randfälle zu testen (Und ja, selbstredend gehört sowas dazuAus dem ``split(" ")`` würde ich ein ``split()`` machen. Sonst kann es die leere Zeichenkette tatsächlich geben:
ja ich tendiere auch eher zu Exceptions, da es sich bei dieser Funktion um "Backend"*-Logik handelt.Wobei ich kein Fan von Fehlermeldungen und weitermachen bin, ich hätte das wahrscheinlich als Ausnahmen gemacht und abgebrochen wenn da was kommt was nicht ins erwartete Schema passt.
Code: Alles auswählen
Aktuell versuche ich noch den zweiten Vorschlag von rogerb einzubauen. Da "kämpfe" ich noch mit den Tutorials, aber ich glaube, dass ich jetzt weiß, was er meinte.