Diese Woche wurde ich beauftragt, das ReadmeGenie zu überarbeiten. Wenn Sie gerade erst hier angekommen sind: ReadmeGenie ist mein Open-Source-Projekt, das mithilfe von KI Readme-Dateien basierend auf den vom Benutzer eingegebenen Dateien generiert.
Zuerst dachte ich: „Das Programm funktioniert gut. Ich habe es seit dem ersten Tag organisiert entwickelt … warum sollte ich es also ändern?“
Nun, nachdem ich eine Woche Pause vom Projekt gemacht hatte, öffnete ich es wieder und dachte sofort: „Was ist das?“
Um Ihnen etwas Kontext zu geben, hier ein Beispiel: Eine meiner Kernfunktionen, die ich einst für perfekt hielt, erwies sich als viel komplexer als nötig. Während des Refactoring-Prozesses habe ich es in fünf separate Funktionen zerlegt – und wissen Sie was? Der Code ist jetzt viel sauberer und einfacher zu verwalten.
Sehen Sie sich die Originalversion dieser Funktion an:
def generate_readme(file_paths, api_key, base_url, output_filename, token_usage): try: load_dotenv() # Check if the api_key was provided either as an environment variable or as an argument if not api_key and not get_env(): logger.error(f"{Fore.RED}API key is required but not provided. Exiting.{Style.RESET_ALL}") sys.exit(1) # Concatenate content from multiple files file_content = "" try: for file_path in file_paths: with open(file_path, 'r') as file: file_content = file.read() "\\n\\n" except FileNotFoundError as fnf_error: logger.error(f"{Fore.RED}File not found: {file_path}{Style.RESET_ALL}") sys.exit(1) # Get the base_url from arguments, environment, or use the default chosenModel = selectModel(base_url) try: if chosenModel == 'cohere': base_url = os.getenv("COHERE_BASE_URL", "https://api.cohere.ai/v1") response = cohereAPI(api_key, file_content) readme_content = response.generations[0].text.strip() FOOTER_STRING else: base_url = os.getenv("GROQ_BASE_URL", "https://api.groq.com") response = groqAPI(api_key, base_url, file_content) readme_content = response.choices[0].message.content.strip() FOOTER_STRING except AuthenticationError as auth_error: logger.error(f"{Fore.RED}Authentication failed: Invalid API key. Please check your API key and try again.{Style.RESET_ALL}") sys.exit(1) except Exception as api_error: logger.error(f"{Fore.RED}API request failed: {api_error}{Style.RESET_ALL}") sys.exit(1) # Process and save the generated README content if readme_content[0] != '*': readme_content = "\n".join(readme_content.split('\n')[1:]) try: with open(output_filename, 'w') as output_file: output_file.write(readme_content) logger.info(f"README.md file generated and saved as {output_filename}") logger.warning(f"This is your file's content:\n{readme_content}") except IOError as io_error: logger.error(f"{Fore.RED}Failed to write to output file: {output_filename}. Error: {io_error}{Style.RESET_ALL}") sys.exit(1) # Save API key if needed if not get_env() and api_key is not None: logger.warning("Would you like to save your API key and base URL in a .env file for future use? [y/n]") answer = input() if answer.lower() == 'y': create_env(api_key, base_url, chosenModel) elif get_env(): if chosenModel == 'cohere' and api_key != os.getenv("COHERE_API_KEY"): if api_key is not None: logger.warning("Would you like to save this API Key? [y/n]") answer = input() if answer.lower() == 'y': create_env(api_key, base_url, chosenModel) elif chosenModel == 'groq' and api_key != os.getenv("GROQ_API_KEY"): if api_key is not None: logger.warning("Would you like to save this API Key? [y/n]") answer = input() if answer.lower() == 'y': create_env(api_key, base_url, chosenModel) # Report token usage if the flag is set if token_usage: try: usage = response.usage logger.info(f"Token Usage Information: Prompt tokens: {usage.prompt_tokens}, Completion tokens: {usage.completion_tokens}, Total tokens: {usage.total_tokens}") except AttributeError: logger.warning(f"{Fore.YELLOW}Token usage information is not available for this response.{Style.RESET_ALL}") logger.info(f"{Fore.GREEN}File created successfully") sys.exit(0)
1. Globale Variablen eliminieren
Globale Variablen können zu unerwarteten Nebenwirkungen führen. Behalten Sie den Status innerhalb des Bereichs bei, zu dem er gehört, und übergeben Sie Werte bei Bedarf explizit.
2. Funktionen für Berechnungen verwenden
Vermeiden Sie nach Möglichkeit die Speicherung von Zwischenwerten in Variablen. Verwenden Sie stattdessen Funktionen, um bei Bedarf Berechnungen durchzuführen – so bleibt Ihr Code flexibel und einfacher zu debuggen.
3. Getrennte Verantwortlichkeiten
Eine einzelne Funktion sollte eine Sache tun, und zwar gut. Teilen Sie Aufgaben wie das Parsen von Befehlszeilenargumenten, das Lesen von Dateien, die KI-Modellverwaltung und die Ausgabegenerierung in separate Funktionen oder Klassen auf. Diese Trennung ermöglicht ein einfacheres Testen und Ändern in der Zukunft.
4. Benennung verbessern
Wichtig sind aussagekräftige Variablen- und Funktionsnamen. Wenn Sie Ihren Code nach einiger Zeit erneut aufrufen, helfen Ihnen klare Namen, den Ablauf zu verstehen, ohne alles neu lernen zu müssen.
5. Duplikate reduzieren
Wenn Sie Code kopieren und einfügen, ist das ein Zeichen dafür, dass Sie von gemeinsam genutzten Funktionen oder Klassen profitieren könnten. Duplikate erschweren die Wartung und kleine Änderungen können leicht zu Fehlern führen.
1. Erstellen Sie einen Zweig
Ich habe damit begonnen, einen Zweig zu erstellen mit:
git checkout -b
Dieser Befehl erstellt einen neuen Zweig und wechselt zu diesem.
2. Eine Reihe von Commits durchführen
Sobald ich mich im neuen Zweig befand, führte ich inkrementelle Commits durch. Jeder Commit stellt einen logischen Teil der Arbeit dar, sei es die Umgestaltung einer Funktion, die Behebung eines Fehlers oder das Hinzufügen einer neuen Funktion. Durch häufige, kleine Commits können Sie Änderungen effektiver verfolgen und den Verlauf des Projekts leichter überprüfen.
git status git addgit commit -m "Refactored function"
3. Neubasierung, um einen sauberen Verlauf zu behalten
Nachdem ich mehrere Commits durchgeführt hatte, habe ich meinen Zweig neu gegründet, um den Verlauf sauber und linear zu halten. Durch Rebasing kann ich Commits neu anordnen, kombinieren oder ändern, bevor sie an GitHub übertragen werden. Dies ist besonders nützlich, wenn einige der Commits sehr klein sind oder ich vermeiden möchte, den Commit-Verlauf mit zu vielen inkrementellen Änderungen zu überladen.
git rebase -i main
In diesem Schritt habe ich eine interaktive Rebase über dem Hauptzweig initiiert. Mit dem Flag -i kann ich den Commit-Verlauf interaktiv ändern. Ich könnte einige meiner kleineren Commits zu einem größeren, zusammenhängenden Commit zusammenfassen. Wenn ich zum Beispiel eine Reihe von Commits hätte wie:
Refactor Teil 1
Refactoring Teil 2
Fehler im Refactor
Ich könnte sie in einem einzigen Commit mit einer klareren Botschaft zusammenfassen
4. Änderungen an GitHub übertragen
Nachdem ich mit dem Commit-Verlauf nach dem Rebase zufrieden war, habe ich die Änderungen auf GitHub übertragen. Wenn Sie gerade einen neuen Zweig erstellt haben, müssen Sie ihn mit dem Flag -u in das Remote-Repository übertragen, wodurch der Upstream-Zweig für zukünftige Push-Vorgänge festgelegt wird.
git push -u origin
5. Zusammenführen
Im letzten Schritt habe ich eine schnelle Zusammenführung zum Hauptzweig durchgeführt und erneut gepusht
git checkout main # change to the main branch git merge --ff-only# make a fast-forward merge git push origin main # push to the main
Alles hat Raum für Verbesserungen. Refactoring mag mühsam erscheinen, führt jedoch häufig zu saubererem, besser wartbarem und effizienterem Code. Wenn Sie also das nächste Mal beim Refactoring zögern, denken Sie daran: Es gibt immer einen besseren Weg, Dinge zu erledigen.
Auch wenn ich denke, dass es jetzt perfekt ist, werde ich bei meinem nächsten Commit auf jeden Fall etwas verbessern können.
Haftungsausschluss: Alle bereitgestellten Ressourcen stammen teilweise aus dem Internet. Wenn eine Verletzung Ihres Urheberrechts oder anderer Rechte und Interessen vorliegt, erläutern Sie bitte die detaillierten Gründe und legen Sie einen Nachweis des Urheberrechts oder Ihrer Rechte und Interessen vor und senden Sie ihn dann an die E-Mail-Adresse: [email protected] Wir werden die Angelegenheit so schnell wie möglich für Sie erledigen.
Copyright© 2022 湘ICP备2022001581号-3