From 0632b1a7e1563c16ff23acda860c84f1e7f5ae57 Mon Sep 17 00:00:00 2001 From: Patrick Date: Tue, 27 Feb 2024 19:16:32 +0100 Subject: [PATCH] step1 complete step2 started --- Data/Test/one.csv | 42 ++++++++++- Data/Test/two.csv | 174 +++++++++++++++++++++++++++------------------- main.py | 29 +++++--- src/step1.py | 27 ++++--- src/step2.py | 29 ++++++++ 5 files changed, 204 insertions(+), 97 deletions(-) create mode 100644 src/step2.py diff --git a/Data/Test/one.csv b/Data/Test/one.csv index 964c5f3..79f489d 100644 --- a/Data/Test/one.csv +++ b/Data/Test/one.csv @@ -1,4 +1,4 @@ -Nachname; Vorname; +name;vorname; Backhaus;Tina; Beck;Christopher; Beck;Marina; @@ -57,4 +57,42 @@ Niemann;Lara; Noguera Abreu;Kristina; Ochse;Olaf; Pabst;Stefan; -Peters;Nicole; \ No newline at end of file +Peters;Nicole; +Piehl;Jan-Philip; +Posselt;Janett; +Prüfert;Birte; +Radloff;Jannika; +Resch;Christina Carola; +Richter-Conrad;Barbara; +Riedel;Dietmar; +Ries;Claudia; +Ritter;Ewa Joanna; +Rohmer;Thomas; +Rudolf;Julia; +Schacht;Dörthe; +Scharfe;Sarah Marie; +Schrader;Lea Ann; +Schröder;Sandra; +Schwarz;Anneli-Dorothea; +Schwarz;Berit; +Seebauer;Astrid; +Seebauer;Benjamin; +Siedtmann;Katja; +Sommer;Alexander; +Steiger;Lisa; +Steinfatt;Jan Hendrik; +Stukenbrock;Taira; +Teichmann;Sascha; +Tereshchenko;Oksana; +Thiele;Jörg; +Thiele;Ulrike; +Topal;Sebnem; +Torkuhl;Clara; +Treichel;Hannah Lena; +Vehrs;Marian; +Villwock;Hanno; +Voigt;Finja; +Weiß;Lea Pauline Katharina Laetitia; +Welder;Jennifer; +Wolter;Michael; +Wulf;Alexander; \ No newline at end of file diff --git a/Data/Test/two.csv b/Data/Test/two.csv index 5b1c680..e88dffe 100644 --- a/Data/Test/two.csv +++ b/Data/Test/two.csv @@ -1,73 +1,101 @@ -Nachname; Vorname; -Backhaus;Tina; -Beck;Christopher; -Beck;Marina; -Berger;Charlyn; -Bernhardi;Antonia; -Bischoff;Meike; -Blöß;Anne-Kristin; -Böhm;Susanne; -Boles;Simone Hildegard; -Brabant;Nadja; -Bremer;Heinz-Dieter; -Bremer;Timo; -Buchbinder;Jürgen; -Bücker;Meike Charlotte; -Bünger;Birte; -Delfs;Dorothee; -Didt;Marlen; -Diercks;Berit-Deike; -Dohrendorf;Hella; -Ehler;Patricia; -Ehrenforth;Maike; -Elgert;Dorit; -Fischer;Rieke Flavia; -Freyer;Jennifer; -Gilbert;Amke; -Glinzner;Sylke; -Gosch;Christina; -Grimm;Antonia; -Hartmann;Marisa Sophie; -Healy-Kloppenburg;Insa; -Herrig;Swantje; -Holst;Patrick; -Iven;Meike; -Jacke;Friederike-Lisette; -Piehl;Jan-Philip; -Posselt;Janett; -Prüfert;Birte; -Radloff;Jannika; -Resch;Christina Carola; -Richter-Conrad;Barbara; -Riedel;Dietmar; -Ries;Claudia; -Ritter;Ewa Joanna; -Rohmer;Thomas; -Rudolf;Julia; -Schacht;Dörthe; -Scharfe;Sarah Marie; -Schrader;Lea Ann; -Schröder;Sandra; -Schwarz;Anneli-Dorothea; -Schwarz;Berit; -Seebauer;Astrid; -Seebauer;Benjamin; -Siedtmann;Katja; -Sommer;Alexander; -Steiger;Lisa; -Steinfatt;Jan Hendrik; -Stukenbrock;Taira; -Teichmann;Sascha; -Tereshchenko;Oksana; -Thiele;Jörg; -Thiele;Ulrike; -Topal;Sebnem; -Torkuhl;Clara; -Treichel;Hannah Lena; -Vehrs;Marian; -Villwock;Hanno; -Voigt;Finja; -Weiß;Lea Pauline Katharina Laetitia; -Welder;Jennifer; -Wolter;Michael; -Wulf;Alexander; \ No newline at end of file +username;name;vorname;klasse;schuelerid;mailUserQuota;oxUserQuota;oxContext +andersk2;Anders;Katarzyna;;a51e9a1d-8757-425c-a5b4-b42701e8285a;512;5120;16 +backhaust;Backhaus;Tina;;e3de9cf9-b0f4-49f5-8a94-840815d4d85a;512;5120;16 +beckc;Beck;Christopher;;f0f2ce5b-6452-4596-9821-56a1ebb82188;512;5120;16 +beckm;Beck;Marina;;8afe5ead-ed43-4253-8909-a7ae886715d3;512;5120;16 +bergerc2;Berger;Charlyn;;86880eb3-9210-42e2-be40-8d2a4265324a;512;5120;16 +bischoffm;Bischoff;Meike;;d6cf8df5-51a9-43c0-8ffd-ff5480b3a4da;512;5120;16 +bloessa;Blöß;Anne-Kristin;;ecf88a00-b838-438b-b1c5-d3119b1d2027;512;5120;16 +boehms;Böhm;Susanne;;e14c5538-4ecc-4a2c-975f-628c3dbba6ec;512;5120;16 +boless;Boles;Simone Hildegard;;4327c5b6-a434-4e58-b863-f5832ec38d03;512;5120;16 +brabantn;Brabant;Nadja;;909e8802-7a8f-4043-8c4d-4b5cc163c935;512;5120;16 +bremerh;Bremer;Heinz-Dieter;;5224606f-9de3-4b1e-bb6d-2cf31dd546fc;512;5120;16 +bremert;Bremer;Timo;;f82d00d2-7d05-4fe4-967a-03ae72f54c7d;512;5120;16 +buchbinderj;Buchbinder;Jürgen;;8138abcc-942f-42ba-9910-69536e26eed6;512;5120;16 +bucikovar;Buciková;Radana;;40cd1cf8-645f-4651-8d7d-e7a752cee3df;512;5120;16 +bueckerm;Bücker;Meike Charlotte;;bea33288-a0c6-4bea-868b-cedae41b43a8;512;5120;16 +buengerb;Bünger;Birte;;627f357e-169c-4efc-a544-ed2f14b5dff9;512;5120;16 +burmeystert;Burmeyster;Tatiana;;cdd8ad8d-2669-4467-bb63-563ef1e3b5a6;512;5120;16 +claassenn;Claaßen;Nele;;2005f747-526e-4cc4-b3d8-c9d7b88c1ba8;512;5120;16 +delfsd;Delfs;Dorothee;;c7ef3d84-b8a9-458a-976a-571813ddce0d;512;5120;16 +didtm;Didt;Marlen;;f055faf7-fa21-44ec-b6d1-cc957e1de0e1;512;5120;16 +diercksb;Diercks;Berit-Deike;;455baf87-49d7-4e00-af70-09d88b0c55a7;512;5120;16 +dr.f;Lehnau Dr.;Frank;;6c4e8feb-6702-433a-9531-98a2b9a8e73e;512;5120;16 +ehlerp;Ehler;Patricia;;1097df38-d0c4-45c1-baf0-0968d6330a2b;512;5120;16 +ehlerss;Ehlers;Sabine;;59076ac5-532d-4926-a4a8-7782d5025702;512;5120;16 +elgertd;Elgert;Dorit;;4eb689b2-b535-4cd6-9642-ba38871a4c48;512;5120;16 +faltinr;Faltin;Reinhard;;b0a19b46-c310-4bec-87f9-a50eb895045f;512;5120;16 +faueri;Fauer;Ina;;8f151862-5d72-4c70-9d74-da419aa38a71;512;5120;16 +fischern;Fischer;Nele;;2f3635e4-044a-409a-9e5c-cdfb6d7ebcd5;512;5120;16 +fischerr;Fischer;Rieke Flavia;;683cef23-bea2-4e7c-a09d-e401ffc3eca2;512;5120;16 +freyerj;Freyer;Jennifer;;7cc6650c-e5f5-4c36-9157-07d10d3aa17c;512;5120;16 +gilberta;Gilbert;Amke;;64cc443d-882b-4dc1-a49e-19b8e5522bad;512;5120;16 +glinzners;Glinzner;Sylke;;72bc43ff-064b-41f6-993f-317dfc749783;512;5120;16 +healykloppenburgi;Healy-Kloppenburg;Insa;;e7f93db5-bf1b-419f-8b93-8c824debd850;512;5120;16 +herfertj;Herfert;Jenny;;b34a2e77-f555-4654-a090-ff49fb2e999b;512;5120;16 +herrigs;Herrig;Swantje;;07004384-5856-43b6-9e32-467f27a63cea;512;5120;16 +hilbertvogts;Hilbert-Vogt;Susanne;;01b14b52-ee70-4295-a693-318ea211e463;512;5120;16 +holstp;Holst;Patrick;;15780d68-62c1-4651-bb6e-67c5056e7344;512;5120;16 +ivenm;Iven;Meike;;0802930d-5b72-4f68-ac1f-3a94be3e9070;512;5120;16 +jackef;Jacke;Friederike-Lisette;;5bf01e41-fc4d-41aa-be7d-1d34d33e599d;512;5120;16 +janshenf;Janshen;Friederike;;e7570384-8dee-4f0d-ad14-c2208e6d6f1a;512;5120;16 +kaisery;Kaiser;Yvonne;;91431b7f-3c25-4c8f-a996-de648e0f9f4c;512;5120;16 +kellerd;Keller;Dörthe;;7f9985ab-59fd-4da2-8a4f-ded73489dd3e;512;5120;16 +kibbelj;Kibbel;Janina;;24281fdc-d941-49a7-b895-189c84c1d7bb;512;5120;16 +klingelhoefers;Klingelhöfer;Stefanie;;854193b8-6fa8-476a-94d3-4d7a702ce222;512;5120;16 +kloppk;Klopp;Kristina;;c903ae9c-49bb-481f-b8d8-dd9c898e246b;512;5120;16 +kraftr;Kraft;Rahel Janina;;f0e2a8a6-5049-4762-9f2c-c384290ecbc8;512;5120;16 +krohni;Krohn;Iwanka;;5e01c5a3-7d21-43c7-b9aa-6b5aa26845af;512;5120;16 +langa;Lang;Alisa;;30ad1551-1724-47c7-a61d-42341ff143f3;512;5120;16 +laturnusu;Laturnus;Ulrike;;4c00e9ca-f722-40f0-9dfd-b752d0d7ce5f;512;5120;16 +lehnauf;Lehnau;Frank;;2e276e1d-2d99-43a1-97bf-7f9951772cda;512;5120;16 +lippitscha;Lippitsch;Annette;;f4ee88bc-8d0d-43cf-bc2b-aaa82ce4b5f5;512;5120;16 +llerenas;Llerena;Susanne;;4254a59a-e0a2-4d63-b221-abd72cd713d2;512;5120;16 +marohnk;Marohn;Kai;;0c5a1343-8b3a-4e93-b1a7-33f6bd2dcf65;512;5120;16 +martensa;Martens;Annika;;1931fc8e-d626-4a5d-a339-cd4194507efc;512;5120;16 +massmannj;Maßmann;Jillian;;8bc7e49e-892a-463a-a1fa-eb69c12bc66d;512;5120;16 +mertensm;Mertens;Melissa;;bd0bf292-45b5-4614-a226-6c055c2e5d85;512;5120;16 +meyburgc;Meyburg;Carina;;3db1f005-a8f8-4060-8c78-0fe52df90090;512;5120;16 +moellera;Möller;Alexandra;;f44935df-81b5-4196-b3a2-68c96ac5afeb;512;5120;16 +moellerherma;Möllerherm;Antje;;8cd5774d-03ad-4f38-b8c4-496997773322;512;5120;16 +muellert;Müller;Thomas;;739cbc79-096e-498a-8e38-be9bbbaf3e3e;512;5120;16 +neumannl;Neumann;Lisa Marie;;953d2ebd-de8e-4c61-a827-dde777a65212;512;5120;16 +nicoloffa;Nicoloff;Alexandra;;d5438535-9c7a-4d7a-adef-92d5ee58ecc1;512;5120;16 +niemannl;Niemann;Lara;;c0564030-539d-4218-a9f8-e1475ccdb357;512;5120;16 +ochseo;Ochse;Olaf;;c65a070f-e525-4b2f-aabe-c14c4d2edec5;512;5120;16 +pabsts;Pabst;Stefan;;39a78afb-3802-48c1-9626-0176b84d5573;512;5120;16 +petersn;Peters;Nicole;;1a94837f-9b1f-4fea-8899-4801275c328d;512;5120;16 +piehlj;Piehl;Jan-Philip;;569aaa43-9727-469f-a050-84a0caf9e019;512;5120;16 +pruefertb;Prüfert;Birte;;191a4a36-d1c0-4f59-90dd-f931027fab2e;512;5120;16 +reschc;Resch;Christina;;ca8c9ab3-53b2-42c1-ae74-34aa85290892;512;5120;16 +riedeld;Riedel;Dietmar;;c7020213-2d76-463b-8275-b3d312bc39f3;512;5120;16 +riesc;Ries;Claudia;;57d4677d-a213-4af2-948d-59c555bd76fb;512;5120;16 +rudolfj;Rudolf;Julia;;e3aa8d5c-5015-47bf-a086-3251a2c5b6a1;512;5120;16 +sadowskip;Sadowski;Paul Peter;;c10f45a6-4858-45fe-81fe-a897c40e6edc;512;5120;16 +scharfes;Scharfe;Sarah Marie;;d26b2121-8442-4a20-9b1c-2ddd079d4359;512;5120;16 +schraderl;Schrader;Lea Ann;;6b64819b-329c-41d9-ac92-3b777604b721;512;5120;16 +schroederm;Schröder;Matthias;;1478dc8f-ac5a-4e19-ac4f-9b7ecff2a0ed;512;5120;16 +schroeders;Schröder;Sandra;;811aa921-9326-4273-9848-8a1b03623c82;512;5120;16 +schultzs2;Schultz;Sarah Elysa;;18d584b1-9c23-4ea8-ae92-6a91e8121d73;512;5120;16 +schwarza;Schwarz;Anneli-Dorothea;;2a6dd23c-f310-4bd8-ba1b-28a39c929f5e;512;5120;16 +seebauera;Seebauer;Astrid;;921902ff-fc4d-428d-9120-d3b2c10d43bc;512;5120;16 +seebauerb;Seebauer;Benjamin;;c7bce821-fd69-43ea-8ab2-78fc8b6f0526;512;5120;16 +siedtmannk;Siedtmann;Katja;;d42c9b41-8d15-4b26-884c-4e6fde1b0659;512;5120;16 +simonl2;Simon;Lina;;09145e3f-eff1-47f4-bb97-fc14725f5923;512;5120;16 +sommera;Sommer;Alexander;;692357fb-6083-4ea1-90cb-98b93ed66ff8;512;5120;16 +steinfattj;Steinfatt;Jan Hendrik;;764148a7-a37b-4aaf-8db0-3a282cc22d0b;512;5120;16 +stukenbrockt;Stukenbrock;Taira;;4a9d4044-7bed-4952-8dc6-55de9d01f488;512;5120;16 +teichmanns;Teichmann;Sascha;;e3428db4-0005-4498-84c6-3c3b967427cd;512;5120;16 +tetzlaffs;Tetzlaff;Sonja;;88a70a21-90cf-4504-a02c-5fd0dcf84df5;512;5120;16 +thielej;Thiele;Jörg;;697e7b38-381c-4ced-a80f-efb9bb7fc8f4;512;5120;16 +thieleu;Thiele;Ulrike;;e030fc2d-97a8-4ce3-913c-4a940b20dbbb;512;5120;16 +villwockh;Villwock;Hanno;;e953e7e5-ea76-47b6-baf7-7bd76d317ca2;512;5120;16 +weimanni;Weimann;Imme;;ed48bcff-9e5b-4751-b581-68b4081d2451;512;5120;16 +weissl;Weiß;Lea Pauline Katharina Laetitia;;18882825-9771-46f2-8fe1-c220504d7453;512;5120;16 +wetzigc;Wetzig;Christine;;34cc5223-9242-4561-8dd3-eac6ee8fecd6;512;5120;16 +wiemannm;Wiemann;Milana;;ea9ad95a-8738-4c12-92ab-2ffdab595ffa;512;5120;16 +willhoeftn;Willhöft;Nina Franziska;;4e64df8f-eff2-4e2e-a05c-367d971c40e1;512;5120;16 +wittea;Witte;Anita;;b258fb06-020d-4899-b7a8-0cd2003b4bb2;512;5120;16 +wittstocka;Wittstock;Annika;;c9c9809b-ce1e-4e5b-a0b7-f8202f5db648;512;5120;16 +wolterm;Wolter;Michael;;53607793-36bc-4f7e-b80a-3723d0171ed6;512;5120;16 +wulfa;Wulf;Alexander;;c2bd5c52-3028-4bf4-a92c-ba425606aa5f;512;5120;16 diff --git a/main.py b/main.py index 9135d9b..a284ce5 100644 --- a/main.py +++ b/main.py @@ -7,7 +7,8 @@ ############################################################### # IMPORT - standard Python imports für benötigte Bibliotheken # -from src import step1, step3 +from src import step1, step2, step3 + import pandas as pd # pandas für Datenmanagement import chardet # chardet erkennt Formatierung - Umwandlung des erkannten Formats in UTF-8 import csv # zur Verarbeitung von .csv Dateien @@ -31,19 +32,20 @@ ox_quota_sus = 5120 # oxUserQuota LuL # MAIN FUNCTION START # if __name__ == "__main__": - print("Schul-IT UCS-Import Tool:") + print("Schul-IT UCS-Import Tool:\n") dev = True # ----------------------------------------------------------------- # # Step 1 - Dateien wählen, formatieren, einlesen | Variablen setzen # + print("Step1: Listen einlesen\n") # ToDo Daten mit UI einlesen # lehrer_liste_neu = "./Data/SaM/export_lehrer_SaM.csv" - lehrer_liste_neu = "./Data/Test/export_lehrer_202402121146.CSV" - lehrer_liste_system = "./Data/SaM/sys_lehrer_SaM.csv" + lehrer_liste_neu = "./Data/Test/one.csv" + lehrer_liste_system = "./Data/Test/two.csv" - schueler_liste_neu = "./Data/SaM/export_schueler_SaM.csv" - schueler_liste_system = "./Data/SaM/sys_schueler_SaM.csv" + # schueler_liste_neu = "./Data/SaM/export_schueler_SaM.csv" + # schueler_liste_system = "./Data/SaM/sys_schueler_SaM.csv" # Variablen füllen: if not dev: @@ -60,21 +62,26 @@ if __name__ == "__main__": print("Spalten der Import Liste - Lehrer:", lul_new.columns) lul_sys = step1.create_dataframe_system(lehrer_liste_system) - sus_new = step1.check_export_file(schueler_liste_neu) - print("Spalten der Import Liste - Schüler:", sus_new.columns) - sus_sys = step1.create_dataframe_system(schueler_liste_system) + # sus_new = step1.check_export_file(schueler_liste_neu) + # print("Spalten der Import Liste - Schüler:", sus_new.columns) + # sus_sys = step1.create_dataframe_system(schueler_liste_system) # Test- und Funktionsuser auslagern - keywords = 'Test' + keywords = ['Test', 'test', 'Raum', 'raum', 'User', 'user', 'Tafel', 'tafel', 'Admin', 'admin'] lul_testuser_df = step1.extract_testusers(lul_sys, keywords) + print("Anzahl Test- / Systemuser LuL:", len(lul_testuser_df)) # sus_testuser_df = step1.extract_testusers(sus_sys, keywords) + # print("Anzahl Test- / Systemuser SuS:", len(sus_testuser_df)) + # print(lul_testuser_df) # in Datasets aufteilen - Testuser, Abgleich, UUIDs # ---------------------------------------------------- # # Step 2 - auf name, vorname reduzieren und abgleichen # + print("\nStep2: Listen abgleichen") # 2.1 Data Frames für Abgleich erstellen + step2.print_status(lul_new, lul_sys, False) # 2.2 Datei mit gesamten Anzahlen generieren und füllen # 2.3 Nicht zuordnungsbare bzw. neue Einträge nach Abweichung zur Bestandsliste prüfen und ausgeben # UUIDs zwischenspeichern? @@ -84,4 +91,4 @@ if __name__ == "__main__": # Lul: Namen + UUIDs + Testuser lul_import = step3.add_school_data(lul_sys, school_id, ox_context, mail_quota_lul, ox_quota_lul) # SuS: Namen + UUIDs + Klassen + Testuser - sus_import = step3.add_school_data(sus_sys, school_id, ox_context, mail_quota_sus, ox_quota_sus) + # sus_import = step3.add_school_data(sus_sys, school_id, ox_context, mail_quota_sus, ox_quota_sus) diff --git a/src/step1.py b/src/step1.py index 7a8f487..bf71f0b 100644 --- a/src/step1.py +++ b/src/step1.py @@ -8,11 +8,11 @@ def check_export_file(path): result = chardet.detect(file.read()) detected_encoding = result['encoding'] - print(detected_encoding) + # print(detected_encoding) # Try: Datei in pandas einlesen try: - return pd.read_csv(path, encoding=detected_encoding) + return pd.read_csv(path, encoding=detected_encoding, sep=';') # Catch: zusätzliche Kommas entfernen except pd.errors.ParserError as e: # Wenn ein Parserfehler auftritt, gibt eine Fehlermeldung aus @@ -26,7 +26,7 @@ def check_export_file(path): print(f"Alle Kommas entfernt, einlesen wir erneut versucht ...") # Nach Komma Ersetzung erneut versuchen try: - return pd.read_csv(path, encoding=detected_encoding) + return pd.read_csv(path, encoding=detected_encoding, sep=';') except pd.errors.ParserError as e: print(f"Erneut Fehler in CSV-Datei: {e}") print(f"Datei muss manuell geändert werden.") @@ -35,16 +35,21 @@ def check_export_file(path): # zum Einlesen der bisherigen Systemdaten def create_dataframe_system(path): try: - return pd.read_csv(path, encoding='utf') + return pd.read_csv(path, encoding='utf', sep=';') except pd.errors.ParserError as e: print(f"Fehler beim Einlesen der CSV") # zum Extrahieren von Test- und Funktionsusern -def extract_testusers(dataframe, keywords): - testdata_df = pd.DataFrame(columns=dataframe.columns) - for index, row in dataframe.iterrows(): - if any(row.str.contains(keywords)): - #extract = dataframe.loc[row.str.contains(keywords).name] - print(row.str.contains(keywords)) - return testdata_df +def extract_testusers(df, keywords): + data = pd.DataFrame() + for keyword in keywords: + data = pd.concat([data, df[df.apply(contains_search_term, axis=1, key=keyword)]]) + return data + + +def contains_search_term(row, key): + for value in row: + if key in str(value): + return True + return False diff --git a/src/step2.py b/src/step2.py new file mode 100644 index 0000000..1cfbb87 --- /dev/null +++ b/src/step2.py @@ -0,0 +1,29 @@ +import pandas as pd +from Levenshtein import distance + + +def print_status(new, sys, bool_class): + print(f"\nEinträge in Import Liste: {len(new)}") + print(f"Einträge in System Liste: {len(sys)}") + + if bool_class: + merged_df = pd.merge(new, sys, on=['name', 'vorname'], how='outer', indicator=True) + matches = pd.merge(new, sys, on=['name', 'vorname']) + matches = matches[['name', 'vorname', 'klasse']] + else: + merged_df = pd.merge(new, sys, on=['name', 'vorname'], how='outer', indicator=True) + matches = pd.merge(new, sys, on=['name', 'vorname']) + matches = matches[['name', 'vorname']] + + # Subsets für Zeilen erstellen, die nur in einem der DataFrames vorhanden sind + only_new = merged_df[merged_df['_merge'] == 'left_only'].drop(columns=['_merge']) + only_sys = merged_df[merged_df['_merge'] == 'right_only'].drop(columns=['_merge']) + + print("\nAnzahl Übereinstimmungen:", len(matches)) + print("Anzahl neuer Nutzer:", len(only_new)) + print("Anzahl veralteter Nutzer:", len(only_sys)) + print(matches) + + +def search_typos(new, sys): + matches = pd.merge(new, sys, on=['name', 'vorname'])