"यदि कोई कर्मचारी अपना काम अच्छी तरह से करना चाहता है, तो उसे पहले अपने औजारों को तेज करना होगा।" - कन्फ्यूशियस, "द एनालेक्ट्स ऑफ कन्फ्यूशियस। लू लिंगगोंग"
मुखपृष्ठ > प्रोग्रामिंग > रीफैक्टरिंग रीडमेजिनी

रीफैक्टरिंग रीडमेजिनी

2024-12-23 को प्रकाशित
ब्राउज़ करें:473

Refactoring ReadmeGenie

परिचय

इस सप्ताह मुझे रीडमेजिनी को दोबारा तैयार करने का काम सौंपा गया था। यदि आप अभी-अभी यहां आए हैं, तो ReadmeGenie मेरा ओपन-सोर्स प्रोजेक्ट है जो उपयोगकर्ता द्वारा इनपुट की गई फ़ाइलों के आधार पर रीडमी उत्पन्न करने के लिए AI का उपयोग करता है।

प्रारंभ में, मेरे विचार थे, "कार्यक्रम ठीक काम कर रहा है। मैं इसे पहले दिन से ही व्यवस्थित तरीके से विकसित कर रहा हूं... तो इसे क्यों बदला जाए?"

खैर, प्रोजेक्ट से एक सप्ताह का ब्रेक लेने के बाद, मैंने इसे फिर से खोला और तुरंत सोचा, "यह क्या है?"

रिफैक्टर क्यों?

आपको कुछ संदर्भ देने के लिए, यहां एक उदाहरण दिया गया है: मेरे मुख्य कार्यों में से एक, जिसे मैंने कभी सही माना था, आवश्यकता से कहीं अधिक जटिल निकला। रिफैक्टरिंग प्रक्रिया के दौरान, मैंने इसे पांच अलग-अलग कार्यों में तोड़ दिया - और अनुमान लगाएं क्या? अब कोड बहुत साफ-सुथरा है और इसे प्रबंधित करना आसान है।

इस फ़ंक्शन के मूल संस्करण पर एक नज़र डालें:

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. वैश्विक चर हटाएँ
वैश्विक चर अप्रत्याशित दुष्प्रभाव पैदा कर सकते हैं। राज्य को उसके दायरे में रखें और आवश्यकता पड़ने पर मूल्यों को स्पष्ट रूप से पारित करें।

2. गणना के लिए फ़ंक्शंस का उपयोग करें
जहां संभव हो, मध्यवर्ती मानों को वेरिएबल्स में संग्रहीत करने से बचें। इसके बजाय, आवश्यकता पड़ने पर गणना करने के लिए फ़ंक्शंस का उपयोग करें—इससे आपका कोड लचीला रहता है और डीबग करना आसान हो जाता है।

3. अलग जिम्मेदारियाँ
एक ही कार्य को एक काम करना चाहिए, और उसे अच्छे से करना चाहिए। कमांड-लाइन तर्क पार्सिंग, फ़ाइल रीडिंग, एआई मॉडल प्रबंधन और आउटपुट जेनरेशन जैसे कार्यों को अलग-अलग फ़ंक्शन या कक्षाओं में विभाजित करें। यह पृथक्करण भविष्य में आसान परीक्षण और संशोधन की अनुमति देता है।

4. नामकरण में सुधार करें
सार्थक चर और फ़ंक्शन नाम महत्वपूर्ण हैं। कुछ समय बाद अपने कोड पर दोबारा गौर करने पर, स्पष्ट नाम आपको सब कुछ दोबारा सीखने की आवश्यकता के बिना प्रवाह को समझने में मदद करते हैं।

5. दोहराव कम करें
यदि आप स्वयं को कोड कॉपी और पेस्ट करते हुए पाते हैं, तो यह एक संकेत है कि आप साझा कार्यों या कक्षाओं से लाभान्वित हो सकते हैं। डुप्लिकेशन से रखरखाव कठिन हो जाता है, और छोटे बदलावों के परिणामस्वरूप आसानी से बग हो सकते हैं।

GitHub के प्रति प्रतिबद्ध होना और आगे बढ़ना

1. एक शाखा बनाएं
मैंने इसका उपयोग करके एक शाखा बनाकर शुरुआत की:

git checkout -b 

यह कमांड एक नई शाखा बनाता है और उस पर स्विच करता है।

2. प्रतिबद्धताओं की एक श्रृंखला बनाना
एक बार नई शाखा में, मैंने वृद्धिशील प्रतिबद्धताएँ बनाईं। प्रत्येक कमिट कार्य के एक तार्किक हिस्से का प्रतिनिधित्व करता है, चाहे वह किसी फ़ंक्शन को दोबारा तैयार करना हो, बग को ठीक करना हो, या एक नई सुविधा जोड़ना हो। बार-बार, छोटी प्रतिबद्धताएँ बनाने से परिवर्तनों को अधिक प्रभावी ढंग से ट्रैक करने में मदद मिलती है और परियोजना के इतिहास की समीक्षा करना आसान हो जाता है।

git status
git add 
git commit -m "Refactored function"

3. स्वच्छ इतिहास बनाए रखने के लिए पुनर्निर्माण
कई प्रतिबद्धताएँ बनाने के बाद, मैंने इतिहास को साफ़ और रैखिक बनाए रखने के लिए अपनी शाखा का नवीनीकरण किया। रीबेसिंग से मुझे गिटहब पर धकेले जाने से पहले कमिट को पुन: व्यवस्थित करने, संयोजित करने या संशोधित करने की अनुमति मिलती है। यह विशेष रूप से उपयोगी है यदि कुछ कमिट बहुत छोटे हैं या यदि मैं बहुत अधिक वृद्धिशील परिवर्तनों के साथ कमिट इतिहास को अव्यवस्थित करने से बचना चाहता हूँ।

git rebase -i main

इस चरण में, मैंने मुख्य शाखा के शीर्ष पर एक इंटरैक्टिव रिबेस शुरू किया। -i ध्वज मुझे प्रतिबद्ध इतिहास को अंतःक्रियात्मक रूप से संशोधित करने की अनुमति देता है। मैं अपनी कुछ छोटी प्रतिबद्धताओं को एक बड़ी, एकजुट प्रतिबद्धता में बदल सकता हूँ। उदाहरण के लिए, यदि मेरे पास प्रतिबद्धताओं की एक श्रृंखला होती जैसे:

रिफैक्टर भाग 1
रिफैक्टर भाग 2
रिफैक्टर में बग ठीक करें

मैं उन्हें स्पष्ट संदेश के साथ एक ही प्रतिबद्धता में समेट सकता हूं

4. GitHub में परिवर्तन ला रहा है
एक बार जब मैं रिबेस के बाद प्रतिबद्ध इतिहास से संतुष्ट हो गया, तो मैंने GitHub में बदलावों को आगे बढ़ाया। यदि आपने अभी एक नई शाखा बनाई है, तो आपको इसे -u ध्वज के साथ रिमोट रिपॉजिटरी में पुश करना होगा, जो भविष्य में पुश के लिए अपस्ट्रीम शाखा सेट करता है।

git push -u origin 

5. विलय
अंतिम चरण में मैंने मुख्य शाखा में तेजी से आगे बढ़ने वाला विलय किया और फिर से धक्का दिया

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

टेकअवे

हर चीज में सुधार की गुंजाइश होती है। रिफैक्टरिंग एक परेशानी की तरह लग सकती है, लेकिन इसका परिणाम अक्सर साफ-सुथरा, अधिक रखरखाव योग्य और अधिक कुशल कोड होता है। तो, अगली बार जब आप रिफैक्टरिंग के बारे में झिझक महसूस करें, तो याद रखें: चीजों को करने का हमेशा एक बेहतर तरीका होता है।
भले ही मुझे लगता है कि यह अब बिल्कुल सही है, मुझे अपनी अगली प्रतिबद्धता में निश्चित रूप से कुछ सुधार करना होगा।

विज्ञप्ति वक्तव्य इस लेख को पुन: प्रस्तुत किया गया है: https://dev.to/htsagara/refactoring-redmegenie-4816?1 यदि कोई उल्लंघन है, तो कृपया इसे हटाने के लिए [email protected] से संपर्क करें।
नवीनतम ट्यूटोरियल अधिक>

चीनी भाषा का अध्ययन करें

अस्वीकरण: उपलब्ध कराए गए सभी संसाधन आंशिक रूप से इंटरनेट से हैं। यदि आपके कॉपीराइट या अन्य अधिकारों और हितों का कोई उल्लंघन होता है, तो कृपया विस्तृत कारण बताएं और कॉपीराइट या अधिकारों और हितों का प्रमाण प्रदान करें और फिर इसे ईमेल पर भेजें: [email protected] हम इसे आपके लिए यथाशीघ्र संभालेंगे।

Copyright© 2022 湘ICP备2022001581号-3