Rostbraten's picture
Update navigium.py
84b92b1 verified
import requests
import re
import json
import pandas as pd
from openpyxl import load_workbook
from openpyxl.styles import PatternFill, Border, Side
from io import BytesIO
from export_to_Brainyoo import save_by2
import concurrent.futures
import locale
from termcolor import colored
from openpyxl.styles import Font
import time
locale.setlocale(locale.LC_ALL, 'C')
def dice(scriptio, verbum, iudicatum="good"):
if iudicatum == "good":
color = "green"
elif iudicatum == "bad":
color = "red"
print(colored(scriptio, color) + ": " + colored(verbum, 'yellow'))
def request2navigium(words=["currere"]):
output = []
format = {
"grundform": str,
"bedeutungen": list,
"flexion": list,
"wortart": str,
"deponens": bool,
"klassenlabel": str
}
for word in words:
url = f"https://www.navigium.de/suchfunktion/_search?q={word}"
try:
json_file = requests.get(url).content
data = json.loads(json_file)
time.sleep(2)
except:
dice("Error: Wort konnte auf Navigium nicht gefunden werden", word, "bad")
continue
try:
answer = data[0]["searchItems"][0]
except:
dice("Error: Wort konnte auf Navigium nicht gefunden werden bzw. grundlegende Informationen nicht vorhanden", word, "bad")
continue
formated_answer = format.copy()
try:
formated_answer["grundform"] = answer["lemma"]
formated_answer["bedeutungen"] = answer["bedeutungsgruppe"][0]["bedeutungJoined"]
formated_answer["flexion"] = answer["flexion"]
formated_answer["wortart"] = answer["wortart"]
formated_answer["deponens"] = answer["deponens"]
try:
formated_answer["klassenlabel"] = answer["klassenlabel"]
except:
formated_answer["klassenlabel"] = "Keine Angabe"
except:
dice("Error: Informationen konnten nicht extrahiert werden", word, "bad")
continue
output.append(formated_answer)
dice("Erfolgreich: Alle Informationen konnten erfolgreich extrahiert werden", word, "good")
return output
def threaded_function(words, function=request2navigium, anzahl_threads=20, wordtype=None):
# Erstellen von Blöcken für jeden Thread
blockgröße = len(words) // anzahl_threads
rest = len(words) % anzahl_threads
# Verteilen der Namen auf die Threads
threads_aufgaben = []
start_index = 0
for i in range(anzahl_threads):
zusätzliche_namen = 1 if i < rest else 0
end_index = start_index + blockgröße + zusätzliche_namen
threads_aufgaben.append(words[start_index:end_index])
start_index = end_index
# Liste für alle Ergebnisse
alle_ergebnisse = []
# Verwenden von Threads, um die Namen zu verarbeiten
with concurrent.futures.ThreadPoolExecutor(max_workers=anzahl_threads) as executor:
# Future-Objekte sammeln
if wordtype == None:
future_to_result = {executor.submit(function, word): word
for word in threads_aufgaben}
else:
future_to_result = {executor.submit(function, word, wordtype): word
for word in threads_aufgaben}
# Ergebnisse sammeln
for future in concurrent.futures.as_completed(future_to_result):
try:
ergebnis = future.result()
alle_ergebnisse.extend(ergebnis)
except Exception as e:
print(f"Ein Fehler ist aufgetreten: {e}")
# Hier hast du alle Ergebnisse in der Variable 'alle_ergebnisse'
return alle_ergebnisse
def sort_by_wordtype(input):
sorted = {
"Nomen": [],
"Verben": [],
"Adjektive": [],
"Adverbien": [],
"Pronomen": [],
"Konjunktionen": [],
"Präpositionen": [],
"Subjunktionen": [],
"Unbekannt": []
}
wortarten_kürzel = {
"SUBST": "Nomen",
"VERB": "Verben",
"ADJ": "Adjektive",
"ADV": "Adverbien",
"PRON": "Pronomen",
"KONJ": "Konjunktionen",
"PREP": "Präpositionen",
"SUBJ": "Subjunktionen"
}
for word in input:
if word["wortart"] in wortarten_kürzel.keys():
sorted[wortarten_kürzel[word["wortart"]]].append(word)
else:
sorted["Unbekannt"].append(word)
return sorted
def split_into_words(input, delete_special_characters=True):
einzelne_worte = []
for s in input:
if delete_special_characters == True:
s = re.sub(r'[^\w\s]', '', s)
if len(s.split()) > 1:
einzelne_worte.extend(s.split())
else:
einzelne_worte.append(s)
return einzelne_worte
def identify_adjectives(word, NomGen, arg, failures, plural):
for flexion in word["flexion"]:
if flexion["form"] == f"AdjektivForm(NOM,SG,m,{arg})":
NomGen["Nom"]["m"] = flexion["wort"][0].replace("‑","")
if not flexion["wort"][0].replace("‑","") == "":
failures -= 1
if flexion["form"] == f"AdjektivForm(NOM,SG,f,{arg})":
NomGen["Nom"]["f"] = flexion["wort"][0].replace("‑","")
if not flexion["wort"][0].replace("‑","") == "":
failures -= 1
if flexion["form"] == f"AdjektivForm(NOM,SG,n,{arg})":
NomGen["Nom"]["n"] = flexion["wort"][0].replace("‑","")
if not flexion["wort"][0].replace("‑","") == "":
failures -= 1
if flexion["form"] == f"AdjektivForm(GEN,SG,m,{arg})":
NomGen["Gen"]["m"] = flexion["wort"][0].replace("‑","")
if not flexion["wort"][0].replace("‑","") == "":
failures -= 1
if flexion["form"] == f"AdjektivForm(GEN,SG,f,{arg})":
NomGen["Gen"]["f"] = flexion["wort"][0].replace("‑","")
if not flexion["wort"][0].replace("‑","") == "":
failures -= 1
if flexion["form"] == f"AdjektivForm(GEN,SG,n,{arg})":
NomGen["Gen"]["n"] = flexion["wort"][0].replace("‑","")
if not flexion["wort"][0].replace("‑","") == "":
failures -= 1
if failures == 6:
failures = 6
plural = True
for flexion in word["flexion"]:
if flexion["form"] == f"AdjektivForm(NOM,PL,m,{arg})":
NomGen["Nom"]["m"] = flexion["wort"][0].replace("‑","")
if not flexion["wort"][0] == "":
failures -= 1
if flexion["form"] == f"AdjektivForm(NOM,PL,f,{arg})":
NomGen["Nom"]["f"] = flexion["wort"][0].replace("‑","")
if not flexion["wort"][0] == "":
failures -= 1
if flexion["form"] == f"AdjektivForm(NOM,PL,n,{arg})":
NomGen["Nom"]["n"] = flexion["wort"][0].replace("‑","")
if not flexion["wort"][0] == "":
failures -= 1
if flexion["form"] == f"AdjektivForm(GEN,PL,m,{arg})":
NomGen["Gen"]["m"] = flexion["wort"][0].replace("‑","")
if not flexion["wort"][0] == "":
failures -= 1
if flexion["form"] == f"AdjektivForm(GEN,PL,f,{arg})":
NomGen["Gen"]["f"] = flexion["wort"][0].replace("‑","")
if not flexion["wort"][0] == "":
failures -= 1
if flexion["form"] == f"AdjektivForm(GEN,PL,n,{arg})":
NomGen["Gen"]["n"] = flexion["wort"][0].replace("‑","")
if not flexion["wort"][0] == "":
failures -= 1
return NomGen, failures, plural
def cleanup_properties(properties):
for key, property in properties.items():
if property.replace(" ", "") == "":
properties[key] = "-"
return properties
def advanced_formating(input):
vocabulary = {
"Nomen": [],#
"Verben": [],#
"Adjektive": [],#
"Adverbien": [],#
"Pronomen": [],#
"Konjunktionen": [],#
"Präpositionen": [],#
"Subjunktionen": [],#
"Unbekannt": []#
}
for word in input["Nomen"]:
word_properties = {
"Nom. Sg.": "-",
"Gen. Sg.": "-",
"Genus": "-",
"Dekl.-Kl.": "-",
"Bedeutung": "-"
}
failures = 2
for flexion in word["flexion"]:
if flexion["form"] == "SubstantivForm(NOM,SG)":
word_properties["Nom. Sg."] = flexion["wort"][0].replace("‑","")
if not flexion["wort"][0].replace("‑","") == "":
failures -= 1
if flexion["form"] == "SubstantivForm(GEN,SG)":
word_properties["Gen. Sg."] = flexion["wort"][0].replace("‑","")
if not flexion["wort"][0].replace("‑","") == "":
failures -= 1
if failures == 2:
failures = 2
for flexion in word["flexion"]:
if flexion["form"] == "SubstantivForm(NOM,PL)":
word_properties["Nom. Sg."] = flexion["wort"][0].replace("‑","") + " (Pl.)"
if not flexion["wort"][0].replace("‑","") == "":
failures -= 1
if flexion["form"] == "SubstantivForm(GEN,PL)":
word_properties["Gen. Sg."] = flexion["wort"][0].replace("‑","") + " (Pl.)"
if not flexion["wort"][0].replace("‑","") == "":
failures -= 1
einzelne_worte = split_into_words([word["grundform"].replace("-", " - ")], delete_special_characters=False)
if failures >= 2:
dice("Fehler: Keine Nominativ- oder Genitivform gefunden", einzelne_worte[0], "bad")
word_properties["Genus"] = einzelne_worte[-1]+"."
try:
if "Dritte Deklination".lower() in word["klassenlabel"].lower():
word_properties["Dekl.-Kl."] = "kons.-Dekl."
for flexion in word["flexion"]:
if flexion["form"] == "SubstantivForm(GEN,PL)":
if flexion["wort"][0].endswith("ium"):
word_properties["Dekl.-Kl."] = "gem.-Dekl."
else:
word_properties["Dekl.-Kl."] = word["klassenlabel"].replace(",", "").replace("(", "").replace(")", "")[:-7] + "."
except:
word_properties["Dekl.-Kl."] = "unbekannt"
word_properties["Bedeutung"] = word["bedeutungen"]
word_properties = cleanup_properties(word_properties)
vocabulary["Nomen"].append(word_properties)
for word in input["Verben"]:
word_properties = {
"Infinitiv": "-",
"1. Ps. Sg. Präs. Ind. Akt.": "-",
"1. Ps. Sg. Perf. Ind. Akt.": "-",
"PPP": "-",
"Konj.": "-",
"Bedeutung": "-"
}
"InfinitivForm(PRAES,AKT)"
"VerbForm(P1,SG,PRAES,IND,AKT,m)"
"VerbForm(P1,SG,PERF,IND,AKT,m)"
"PartizipialForm(PPP,AdjektivForm(NOM,SG,n,POS))"
"VerbForm(P1,SG,PRAES,IND,DEP,m)"
if word["deponens"] == False:
for flexion in word["flexion"]:
if flexion["form"] == "InfinitivForm(PRAES,AKT)":
word_properties["Infinitiv"] = flexion["wort"][0].replace("‑","")
if flexion["form"] == "VerbForm(P1,SG,PRAES,IND,AKT,m)":
word_properties["1. Ps. Sg. Präs. Ind. Akt."] = flexion["wort"][0].replace("‑","")
if flexion["form"] == "VerbForm(P1,SG,PERF,IND,AKT,m)":
word_properties["1. Ps. Sg. Perf. Ind. Akt."] = flexion["wort"][0].replace("‑","")
if flexion["form"] == "PartizipialForm(PPP,AdjektivForm(NOM,SG,n,POS))":
word_properties["PPP"] = flexion["wort"][0].replace("‑","")
else:
for flexion in word["flexion"]:
if flexion["form"] == "InfinitivForm(PRAES,DEP)":
word_properties["Infinitiv"] = flexion["wort"][0].replace("‑","")
if flexion["form"] == "VerbForm(P1,SG,PRAES,IND,DEP,m)":
word_properties["1. Ps. Sg. Präs. Ind. Akt."] = flexion["wort"][0].replace("‑","")
if flexion["form"] == "VerbForm(P1,SG,PERF,IND,DEP,m)":
word_properties["1. Ps. Sg. Perf. Ind. Akt."] = flexion["wort"][0].replace("‑","")
if flexion["form"] == "PartizipialForm(PPP,AdjektivForm(NOM,SG,n,POS))":
word_properties["PPP"] = flexion["wort"][0].replace("‑","")
if "Verb".lower() in word["klassenlabel"].lower():
word_properties["Konj."] = "unbekannt"
elif word["deponens"] == True:
word_properties["Konj."] = "Deponens"
else:
word_properties["Konj."] = word["klassenlabel"].replace("ugation", ".")
word_properties["Bedeutung"] = word["bedeutungen"]
word_properties = cleanup_properties(word_properties)
vocabulary["Verben"].append(word_properties)
for word in input["Adjektive"]:
word_properties = {
"Nom. Sg.: m./f./n.": "",
"Gen. Sg.: m./f./n.": "",
"Dekl.-Kl.": "-",
"Bedeutung": "-"
}
failures = 6
NomGen = {"Nom": {"m": "-", "f": "-", "n": "-"}, "Gen": {"m": "-", "f": "-", "n": "-"}}
arg = "POS"
plural = False
NomGen, failures, plural = identify_adjectives(word, NomGen, arg, failures, plural)
try:
if "Adjektiv".lower() in word["klassenlabel"].lower():
word_properties["Dekl.-Kl."] = "unbekannt"
elif "Dritte Deklination".lower() in word["klassenlabel"].lower():
word_properties["Dekl.-Kl."] = "kons.-Dekl."
for flexion in word["flexion"]:
if flexion["form"] == "AdjektivForm(GEN,PL,m,POS)":
if flexion["wort"][0].endswith("ium"):
word_properties["Dekl.-Kl."] = "gem.-Dekl."
else:
word_properties["Dekl.-Kl."] = word["klassenlabel"].replace(",", "").replace("(", "").replace(")", "")[:-7] + "."
except:
word_properties["Dekl.-Kl."] = "unbekannt"
if failures == 6:
failures = 6
arg = "KOMP"
plural = False
NomGen, failures, plural = identify_adjectives(word, NomGen, arg, failures, plural)
word_properties["Dekl.-Kl."] = "Komp."
if failures == 6:
failures = 6
arg = "SUP"
plural = False
NomGen, failures, plural = identify_adjectives(word, NomGen, arg, failures, plural)
word_properties["Dekl.-Kl."] = "Sup."
if failures == 6:
failures = 6
plural = False
word_properties["Dekl.-Kl."] = "unbekannt"
dice("Es konnten keine der Flexionen extrahiert werden", einzelne_worte[0], "bad")
einzelne_worte = split_into_words([word["grundform"].replace("-", " - ")], delete_special_characters=False)
for key in NomGen:
NomGen[key] = ', '.join(NomGen[key].values())
if plural == True:
word_properties["Nom. Sg.: m./f./n."] = NomGen["Nom"] + " (Pl.)"
word_properties["Gen. Sg.: m./f./n."] = NomGen["Gen"] + " (Pl.)"
else:
word_properties["Nom. Sg.: m./f./n."] = NomGen["Nom"]
word_properties["Gen. Sg.: m./f./n."] = NomGen["Gen"]
word_properties["Bedeutung"] = word["bedeutungen"]
vocabulary["Adjektive"].append(word_properties)
word_properties = cleanup_properties(word_properties)
return vocabulary
def save2json(file, data):
with open(file,"w+",encoding='utf-8') as file:
json.dump(data, file, ensure_ascii=False, indent=4)
def save2excel(filepath, vocabulary, cleanup=True):
if cleanup == True:
tmp_excel = BytesIO()
with pd.ExcelWriter(tmp_excel) as writer:
# Für jede Wortart ein eigenes Sheet erstellen
for wortart, vokabeln in vocabulary.items():
# Ein DataFrame für jede Wortart erstellen
df = pd.DataFrame(vokabeln)
# In das entsprechende Sheet schreiben
df.to_excel(writer, sheet_name=wortart, index=False)
file = cleanup_excel(tmp_excel, filepath)
return file
elif cleanup == False:
with pd.ExcelWriter(filepath) as writer:
# Für jede Wortart ein eigenes Sheet erstellen
for wortart, vokabeln in vocabulary.items():
# Ein DataFrame für jede Wortart erstellen
df = pd.DataFrame(vokabeln)
# In das entsprechende Sheet schreiben
df.to_excel(writer, sheet_name=wortart, index=False)
def locale_sort_key(value):
return locale.strxfrm(value)
def cleanup_excel(input_file, output_file):
excel_file = pd.ExcelFile(input_file)
output_stream = BytesIO()
sheets_dict = {}
for sheet_name in excel_file.sheet_names:
df = pd.read_excel(input_file, sheet_name=sheet_name)
if df.empty:
continue
df_no_duplicates = df.drop_duplicates()
if df_no_duplicates.empty:
continue
#df_sorted = df_no_duplicates.sort_values(by=df_no_duplicates.columns[0], ascending=True)
df_sorted = df_no_duplicates.sort_values(by=df_no_duplicates.columns[0], key=lambda col: col.map(locale_sort_key), ascending=True)
sheets_dict[sheet_name] = df_sorted
with pd.ExcelWriter(output_stream, engine='openpyxl') as writer:
for sheet_name, df in sheets_dict.items():
df.to_excel(writer, sheet_name=sheet_name, index=False)
wb = load_workbook(output_stream)
# Definiere den grauen Farbton und die Rahmeneinstellungen
gray_fill = PatternFill(start_color='D3D3D3', end_color='D3D3D3', fill_type='solid')
thin_border = Border(left=Side(style='thin'), right=Side(style='thin'),
top=Side(style='thin'), bottom=Side(style='thin'))
# Anpassung der Spaltenbreite und Stile für Spaltennamen und Zellen
for sheet_name in wb.sheetnames:
sheet = wb[sheet_name]
# Grau für die Spaltennamen und Rahmenlinien für alle Zellen
for row in sheet.iter_rows():
for cell in row:
cell.border = thin_border # Rahmenlinien für jede Zelle
if cell.row == 1: # Überprüfen, ob es sich um die Kopfzeile handelt
cell.fill = gray_fill # Grau für die Kopfzeile
# Dynamische Anpassung der Spaltenbreite
for column_cells in sheet.columns:
max_length = 0
column = column_cells[0].column_letter # Holt den Spaltenbuchstaben
for cell in column_cells:
try:
if cell.value: # Nur nicht-leere Zellen prüfen
max_length = max(max_length, len(str(cell.value)))
except:
pass
adjusted_width = (max_length + 2)
sheet.column_dimensions[column].width = adjusted_width
ws = sheet
# Bestimmen der letzten Zeile und der Anzahl der Spalten
letzte_zeile = ws.max_row
letzte_spalte = ws.max_column
# Die Zellen am Ende des Dokuments zusammenführen
ws.merge_cells(start_row=letzte_zeile + 1, start_column=1, end_row=letzte_zeile + 1, end_column=letzte_spalte)
kursiv_font = Font(italic=True)
# Text in die gemergte Zelle einfügen
zelle = ws.cell(row=letzte_zeile + 1, column=1, value="Diese Liste basiert auf Daten von \"https://www.navigium.de/suchfunktion/_search?q={}\". © Rechteinhaber: Navigium.de")
zelle.font = kursiv_font
wb.save(output_file)
wb.save(input_file)
print(f"Bereinigte Datei wurde als '{output_file}' gespeichert, und die Spaltenbreiten wurden angepasst.")
return input_file
def save2by2(excel_file, by2_filepath):
Data = {}
# Lade die Excel-Datei und hole die Namen der Arbeitsblätter
excel_file = pd.ExcelFile(excel_file)
sheet_names = ["Nomen", "Verben", "Adjektive", "Adverbien", "Pronomen", "Konjunktionen", "Subjunktionen", "Präpositionen", "Unbekannt"]
# Iteriere über jedes Arbeitsblatt in der Excel-Datei
for sheet in sheet_names:
# Lese das Arbeitsblatt in ein DataFrame
try:
df = pd.read_excel(excel_file, sheet_name=sheet)
except:
continue
# Hole Fragen und Antworten aus den ersten beiden Spalten
fragen = df.iloc[:, 0].tolist()
if sheet == "Nomen" or sheet == "Verben" or sheet == "Adjektive" or sheet == "Pronomen" or sheet == "Präpositionen":
result_list = []
for index, row in df.iterrows():
# Greife auf die zweite und dritte Spalte der Zeile zu, unabhängig von den Namen
if row.iloc[0] == "Diese Liste basiert auf Daten von \"https://www.navigium.de/suchfunktion/_search?q={}\". © Rechteinhaber: Navigium.de":
continue
elif sheet == "Nomen":
combined_str = f"{row.iloc[0]}, {row.iloc[1]}; {row.iloc[2]}; {row.iloc[3]}:\n{row.iloc[-1]}"
elif sheet == "Verben":
combined_str = f"{row.iloc[0]}, {row.iloc[1]}, {row.iloc[2]}, {row.iloc[3]}; {row.iloc[4]}:\n{row.iloc[-1]}"
elif sheet == "Adjektive":
combined_str = f"{row.iloc[0]}; {row.iloc[1]}; {row.iloc[2]}:\n{row.iloc[-1]}"
elif sheet == "Präpositionen":
combined_str = f"{row.iloc[0]} ({row.iloc[1]}):\n{row.iloc[-1]}"
elif sheet == "Pronomen":
combined_str = f"{row.iloc[0]}, {row.iloc[1]}:\n{row.iloc[-1]}"
# Füge den kombinierten String der Liste hinzu
result_list.append(combined_str)
antworten = result_list
else:
antworten = df.iloc[:, 1].tolist()
# Speichere die Fragen und Antworten im Dictionary
Data[sheet] = (fragen, antworten)
save_by2(by2_filepath, Data)