TDD अल्गोरिदमिक समस्याओं के दृष्टिकोण की तरह


10

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

तो यह मुझे लगता है कि अगर मैं TDD के समान दृष्टिकोण का उपयोग कर सकता हूं? यानी अगर मैं आमतौर पर इसी तरह से धीरे-धीरे एक समाधान विकसित कर सकता हूं?

अगर मैं एक छँटाई एल्गोरिथ्म लिख रहा था, तो मैं एक मानक बुलबुले से 2-तरह के बुलबुले में स्थानांतरित कर सकता था, लेकिन फिर क्विकॉर्ट की तरह कुछ और उन्नत एक "क्वांटम छलांग" होगा, लेकिन कम से कम मुझे टेस्टडेटा होगा जो मैं आसानी से समझ सकता हूं।

ऐसे परीक्षणों के लिए अन्य सुझाव? एक चीज जो मैं अगली बार करूंगा, वह आंतरिक छोरों की तुलना में अधिक विधियों / कार्यों का उपयोग करना है। उदाहरण के लिए, छंटाई में, आपको अक्सर स्वैप की आवश्यकता होती है। यदि यह एक तरीका था तो मुझे कॉलिंग कोड को संशोधित करना होगा। मैं व्युत्पन्न वर्गों के रूप में और भी अधिक उन्नत समाधान कर सकता था।

"एल्गोरिथम" बनाम "सामान्य" समस्याओं से मेरा मतलब उन समस्याओं से है जहां समय-जटिलता महत्वपूर्ण है। इसलिए टीडीडी में अधिक टेस्ट पास करने के बजाय, आप इसे "बेहतर व्यवहार" करेंगे।

"TDD के समान" से मेरा मतलब है:

  1. मैन्युअल परीक्षण pr वृद्धि पर समय बचाने के लिए अपेक्षाकृत स्वचालित परीक्षण लिखें।
  2. वृद्धिशील विकास।
  3. प्रतिगमन परीक्षण, यह पता लगाने की क्षमता कि क्या कोड टूट जाता है या कम से कम अगर कार्यक्षमता में वृद्धि होती है।

मुझे लगता है कि यह समझने में आसान होना चाहिए कि क्या आप तुलना करते हैं

  1. सीधे एक शेल-प्रकार लिखना
  2. बुदबुदाने से कूदकर क्विकॉर्ट (कुल फिर से लिखना)
  3. शेल-सॉ (यदि संभव हो) के लिए एक-तरफ़ा बुलबुला-प्रकार से बढ़ते हुए।

"TDD के समान" से आपका क्या अभिप्राय है? आप स्पष्ट रूप से एक छँटाई समारोह को विकसित करने के लिए टीडीडी का उपयोग करने की कोशिश कर सकते हैं, और फिर एक और अधिक कुशल एक द्वारा छँटाई एल्गोरिथ्म को बदलने पर फ़ंक्शन को मान्य करने के लिए इकाई परीक्षणों का उपयोग करते हैं, लेकिन ऐसा लगता है कि आपके मन में एक अलग सवाल है?
डॉक्टर ब्राउन

"धीरे-धीरे" :-) - अंतिम वाक्य देखें "तो इसके बजाय ..."
ओलाव

2
सुनिश्चित करें कि आप पहले एक काम (लेकिन बहुत कुशल नहीं) समाधान के साथ बहुत सारी समस्याओं को हल करने की कोशिश कर सकते हैं, फिर इसे सुधार सकते हैं। यह किसी भी तरह से एल्गोरिथम या प्रोग्रामिंग समस्याओं तक सीमित नहीं है, और यह टीडीडी के साथ बहुत आम नहीं है। क्या इससे आपके सवाल का जवाब मिलता है?
डॉक्टर ब्राउन

@DocBrown नहीं - बुलबुले / क्विकॉर्ट उदाहरण देखें। टीडीडी "अच्छी तरह से काम करता है" क्योंकि एक वृद्धिशील दृष्टिकोण कई प्रकार की समस्याओं के लिए अच्छी तरह से काम करता है। अलग-अलग समस्याएं हो सकती हैं।
ओलव

तो आप का मतलब है "एक वृद्धिशील तरीके से एल्गोरिथ्म डिजाइन प्रश्नों को हल करना संभव है" (जैसा कि टीडीडी एक वृद्धिशील दृष्टिकोण है), और "टीडीडी द्वारा नहीं", सही? कृपया स्पष्ट करें।
डॉक्टर ब्राउन

जवाबों:


9

टीडीडी के साथ सुडोकू सॉल्वर बनाने के रॉन जेफ़रीज़ का प्रयास भी देखें , जो दुर्भाग्य से काम नहीं आया।

एल्गोरिथम डिजाइन एल्गोरिथ्म की एक महत्वपूर्ण समझ की आवश्यकता है। इन सिद्धांतों के साथ, वृद्धिशील रूप से आगे बढ़ना संभव है, एक योजना के साथ, जैसे पीटर नॉरविग ने किया था

वास्तव में, गैर-तुच्छ डिजाइन प्रयास की आवश्यकता वाले एल्गोरिदम के लिए, यह लगभग हमेशा होता है कि प्रयास प्रकृति में वृद्धिशील है। लेकिन प्रत्येक "वेतन वृद्धि", जो एक एल्गोरिथ्म डिजाइनर की आंखों में छोटा है, एक ऐसे व्यक्ति को क्वांटम छलांग (अपना वाक्यांश उधार लेने के लिए) जैसा दिखता है, जिसके पास एल्गोरिदम के इस विशेष परिवार के साथ समान विशेषज्ञता या ज्ञान नहीं है।

यही कारण है कि बहुत सारे एल्गोरिथ्म प्रोग्रामिंग अभ्यास के साथ संयुक्त सीएस सिद्धांत में एक बुनियादी शिक्षा समान रूप से महत्वपूर्ण है। यह जानते हुए कि एक विशेष "तकनीक" (एल्गोरिदम के छोटे भवन ब्लॉकों) मौजूद है, इन वृद्धिशील क्वांटम छलांग बनाने की दिशा में एक लंबा रास्ता तय करना है।


एल्गोरिदम और टीडीडी में वृद्धिशील प्रगति के बीच कुछ महत्वपूर्ण अंतर हैं, हालांकि।

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

टीडीडी में, एक परीक्षण के रूप में एक नई आवश्यकता को जोड़ता है, और यह परीक्षण शुरू में (लाल) पास नहीं होगा। फिर आवश्यकता संतुष्ट (हरा) है। अंत में कोड रिफैक्ट हो जाता है।

एल्गोरिथ्म विकास में, आवश्यकता आमतौर पर नहीं बदलती है। परिणाम शुद्धता सत्यापन परीक्षण या तो पहले लिखा जाता है, या एल्गोरिथम के मसौदे (अत्यधिक आत्मविश्वास लेकिन धीमा) के कार्यान्वयन के तुरंत बाद पूरा हो जाता है। यह डेटा शुद्धता परीक्षण शायद ही कभी बदला गया है; टीडीडी संस्कार के भाग के रूप में कोई भी इसे विफल (लाल) करने के लिए नहीं बदलता है।

हालांकि, इस पहलू में, डेटा विश्लेषण एल्गोरिदम विकास से अलग है, क्योंकि डेटा विश्लेषण आवश्यकताओं (इनपुट सेट और अपेक्षित परिणाम दोनों) को केवल मानव समझ में शिथिल रूप से परिभाषित किया गया है। इस प्रकार आवश्यकताएं तकनीकी स्तर पर अक्सर बदलती रहती हैं। यह तेजी से परिवर्तन एल्गोरिदम विकास और सामान्य सॉफ़्टवेयर अनुप्रयोग विकास के बीच कहीं डेटा विश्लेषण डालता है - जबकि अभी भी एल्गोरिथम-भारी है, आवश्यकताओं को किसी भी प्रोग्रामर के स्वाद के लिए "बहुत तेज़" भी बदल रहा है।

यदि आवश्यकता बदलती है, तो यह आम तौर पर एक अलग एल्गोरिथ्म के लिए कहता है।

एल्गोरिथ्म विकास में, परिवर्तन (कसना) असफल (लाल) करने के लिए प्रदर्शन तुलना परीक्षण मूर्खतापूर्ण है - यह आपको अपने एल्गोरिथ्म में संभावित परिवर्तनों के बारे में कोई जानकारी नहीं देता है जो प्रदर्शन में सुधार करेगा।

इसलिए, एल्गोरिथम विकास में, शुद्धता परीक्षण और प्रदर्शन परीक्षण दोनों TDD परीक्षण नहीं हैं। इसके बजाय, दोनों प्रतिगमन परीक्षण हैं । विशेष रूप से, शुद्धता प्रतिगमन परीक्षण आपको एल्गोरिथ्म में परिवर्तन करने से रोकता है जो इसकी शुद्धता को तोड़ देगा; प्रदर्शन परीक्षण आपको एल्गोरिथ्म में परिवर्तन करने से रोकता है जो इसे धीमा चलाएगा।

आप अभी भी एक व्यक्तिगत कार्य शैली के रूप में टीडीडी को शामिल कर सकते हैं, सिवाय इसके कि "लाल - हरा - रिफ्लेक्टर" अनुष्ठान कड़ाई से आवश्यक नहीं है और न ही एल्गोरिदम विकास की विचार प्रक्रिया के लिए विशेष रूप से फायदेमंद है ।

मैं तर्क दूंगा कि एल्गोरिथ्म में सुधार वास्तव में (वर्तमान में सही नहीं) यादृच्छिक बनाने से होता है, जो कि वर्तमान एल्गोरिथ्म के डेटा प्रवाह आरेखों में क्रमपरिवर्तन है, या पहले से ज्ञात कार्यान्वयन के बीच उन्हें मिलाते और मिलाते हैं।


टीडीडी का उपयोग तब किया जाता है जब कई आवश्यकताएं होती हैं जिन्हें आपके परीक्षण सेट में वृद्धि के साथ जोड़ा जा सकता है

वैकल्पिक रूप से, यदि आपका एल्गोरिथ्म डेटा-चालित है, तो परीक्षण डेटा / टेस्ट केस के प्रत्येक टुकड़े को वृद्धिशील रूप से जोड़ा जा सकता है। टीडीडी भी उपयोगी होगा। इस कारण से नया परीक्षण डेटा जोड़ने के लिए "TDD- जैसा" दृष्टिकोण - इस डेटा को सही ढंग से संभालने के लिए कोड में सुधार करें - रिफ्लेक्टर "ओपन-एंडेड डेटा एनालिटिक्स के काम के लिए भी काम करेगा, जिसमें एल्गोरिदम के उद्देश्य मानव में वर्णित हैं -सेंट्रिक शब्द और इसकी माप-सफलता भी मानव परिभाषित शब्दों में न्याय करती है।

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

TDD कंप्यूटर विज्ञान का विकल्प नहीं है। यह एक मनोवैज्ञानिक बैसाखी है जो प्रोग्रामरों को एक साथ कई आवश्यकताओं को पूरा करने के सदमे को दूर करने में मदद करता है।

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


टीडीडी में, "सूक्ष्म आवश्यकताओं" (या छिपे हुए गुणों) पर भी ध्यान केंद्रित किया गया है। उदाहरण के लिए, पैरामीटर सत्यापन, अभिकथन, अपवाद को फेंकना और संभालना आदि , TDD निष्पादन पथ की शुद्धता को सुनिश्चित करने में मदद करता है जो अक्सर सॉफ्टवेयर निष्पादन के सामान्य पाठ्यक्रम में प्रयोग नहीं किए जाते हैं।

कुछ प्रकार के एल्गोरिथ्म कोड में ये चीजें शामिल हैं; ये TDD के लिए उत्तरदायी हैं। लेकिन क्योंकि एल्गोरिथ्म का सामान्य वर्कफ़्लो टीडीडी नहीं है, ऐसे परीक्षण (पैरामीटर सत्यापन, अभिकथन और अपवाद फेंकने और संभालने पर) लागू कोड लिखे जाने के बाद (कम से कम आंशिक रूप से) लिखे जाने के बाद लिखे जाते हैं।


आपकी पोस्ट ("अंकल बॉब") में पहले दो उद्धृत शब्दों का क्या अर्थ है?
रॉबर्ट हार्वे

@RobertHarvey चाचा बॉब के अनुसार, TDD का उपयोग एल्गोरिथ्म खोज के लिए किया जा सकता है। एक अन्य चमकदार के अनुसार, यह काम नहीं करता है। मैंने सोचा था कि दोनों का उल्लेख किया जाना चाहिए (अर्थात कभी भी किसी ने एक उदाहरण का उल्लेख किया है, एक दूसरे उदाहरण का उल्लेख करने के लिए भी बाध्य है) ताकि लोगों को सकारात्मक और नकारात्मक उदाहरणों के बारे में संतुलित जानकारी मिले।
रवांग

ठीक। लेकिन आप मेरी उलझन को समझते हैं? आपका पहला पैराग्राफ किसी को "अंकल बॉब" शब्द बोलते हुए प्रतीत होता है। कौन कह रहा है?
रॉबर्ट हार्वे

@ रोबर्टहवे आदेश का अनुपालन।
रवांग

2

आपकी समस्या के लिए, आपके पास दो परीक्षण होंगे:

  1. यह सुनिश्चित करने के लिए एक परीक्षण कि एल्गोरिथ्म अभी भी सटीक है। उदा। क्या यह सही ढंग से हल किया गया है?
  2. प्रदर्शन तुलना परीक्षण - प्रदर्शन में सुधार हुआ है। यह मुश्किल हो सकता है, इसलिए यह एक ही मशीन, एक ही डेटा पर परीक्षण चलाने और किसी अन्य संसाधनों के उपयोग को सीमित करने में मदद करता है। एक समर्पित मशीन मदद करती है।

परीक्षण या पूर्ण परीक्षण कवरेज क्या बहस का विषय है, लेकिन मुझे लगता है कि आपके आवेदन के जटिल भागों को ठीक-ठीक ट्यून किया जाना चाहिए (बहुत बदल जाना) स्वचालित परीक्षण के लिए सही उम्मीदवार हैं। एप्लिकेशन के इन हिस्सों को आमतौर पर बहुत पहले ही पहचान लिया जाता है। इस टुकड़े के साथ एक TDD दृष्टिकोण का उपयोग करना समझ में आता है।

विभिन्न समस्याओं को हल करने के लिए अनिच्छा से जटिल समस्याओं को हल करने में सक्षम नहीं होना चाहिए। एक स्वचालित परीक्षण होने से इस क्षेत्र में मदद मिलनी चाहिए। कम से कम आपको पता होगा कि आप इसे बदतर नहीं बना रहे हैं।


1

इसलिए टीडीडी में अधिक टेस्ट पास करने के बजाय, आप इसे "बेहतर व्यवहार" करेंगे।

की तरह।

आप रन समय और जटिलता के लिए परीक्षण कर सकते हैं। सिस्टम संसाधनों पर विवाद की अनुमति देने के लिए रनटाइम परीक्षणों को थोड़ा क्षमा करने की आवश्यकता होगी। लेकिन, कई भाषाओं में, आप विधियों को ओवरराइड या इंजेक्ट कर सकते हैं और वास्तविक फ़ंक्शन कॉलों की गणना कर सकते हैं। और, यदि आप आश्वस्त हैं कि आपका वर्तमान एल्गोरिथ्म सब-ऑप्टिमल है, तो आप एक परीक्षण पेश कर सकते हैं जो बस मांग करता है कि भोले कार्यान्वयन की तुलना में कम बार sort()आह्वान compare()किया जाए।

या, आप sort()दो सेटों पर तुलना कर सकते हैं और compare()अपने लक्ष्य जटिलता (या यदि आप कुछ असंगतता की अपेक्षा करते हैं) द्वारा कॉल में पैमाने सुनिश्चित कर सकते हैं।

और, यदि आप सैद्धांतिक रूप से यह साबित कर सकते हैं कि आकार के एक सेट की Nतुलना N*log(N)तुलना में कड़ाई से अधिक नहीं होनी चाहिए , तो आपके पहले से ही काम करने वाले इनवोकेशन को प्रतिबंधित करना उचित हो सकता है ...sort()N*log(N)compare()

तथापि ...

किसी प्रदर्शन या जटिलता की आवश्यकता को पूरा करना यह सुनिश्चित नहीं करता है कि अंतर्निहित कार्यान्वयन {AlgorithmX} है । और, मेरा तर्क है कि यह सामान्य रूप से ठीक है। इससे कोई फर्क नहीं पड़ता कि एल्गोरिथ्म का क्या उपयोग किया जाता है, बशर्ते आप अपने कार्यान्वयन से टकराते हुए अपनी आवश्यकताओं को पूरा करते हैं, जिसमें कोई महत्वपूर्ण जटिलता, प्रदर्शन या संसाधन की आवश्यकताएं शामिल हैं।

लेकिन, यदि आप यह सुनिश्चित करना चाहते हैं कि किसी विशेष एल्गोरिथ्म का उपयोग किया जाता है, तो आपको अधिक थकाऊ होने और गहराई में और अधिक प्राप्त करने की आवश्यकता होगी। इस तरह की चीजें..

  • यह सुनिश्चित करना कि वास्तव में compare()और swap()(या जो भी) कॉल की अपेक्षित संख्या है
  • सभी प्रमुख कार्यों / विधियों को लपेटना और पूर्वानुमानित डेटा सेट के साथ सुनिश्चित करना, कि कॉल बिल्कुल अपेक्षित क्रम में होते हैं
  • यह सुनिश्चित करने के लिए एन चरणों में से प्रत्येक के बाद कार्यशील स्थिति की जांच करना कि यह अपेक्षित रूप से बदल गया है

लेकिन फिर, यदि आप यह सुनिश्चित करने की कोशिश कर रहे हैं कि {AlgorithmX} का विशेष रूप से उपयोग किया जाता है, तो संभवतः {AlgorithmX} की विशेषताएं हैं, आप इस बात की परवाह करते हैं कि परीक्षण करने के लिए अधिक महत्वपूर्ण हैं कि क्या {AlgorithmX} वास्तव में अंत में उपयोग किया गया था ...


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


आपरेशनों की संख्या पर सीमा लगाने की संभावना के संबंध में उत्कृष्ट बिंदु। मैं तर्क दूंगा कि यह (मोक्स, स्टब्स और जासूस) की शक्ति है, कुछ ऐसा जो टीडीडी में इस्तेमाल किया जा सकता है, जिसे अन्य प्रकार के परीक्षणों में भी इस्तेमाल किया जा सकता है।
रवांग

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

यदि आप codility.com/programmers/task/stone_wall को देखते हैं, तो आपको पता चलेगा कि क्या आपके पास N जटिलता से अधिक है, विशेष मामलों को छोड़कर, जहां आपको उदाहरण के लिए बहुत लंबे अंतराल पर काम करना है।
ओलाव

@ "लेखन" परीक्षण में कुछ चतुर प्रिंटआउट की तुलना में एक लंबा समय लगेगा ... " एक बार करने के लिए ... उह .. शायद , लेकिन यह भी बहुत बहस योग्य है। हर बिल्ड पर बार-बार करने के लिए? ... निश्चित रूप से नहीं।
svidgen

@ ओवल "वास्तविक दुनिया में मुझे लगता है कि आप जानना चाहेंगे कि क्या कुछ मामलों में प्रदर्शन अचानक कम हो जाता है।" लाइव सेवाओं में, आप समग्र प्रदर्शन पर नज़र रखने के लिए नए रेलिक जैसे कुछ का उपयोग करेंगे - न कि केवल कुछ विधियों के। और आदर्श रूप से, आपके परीक्षण आपको बताएंगे कि प्रदर्शन-महत्वपूर्ण मॉड्यूल और विधियाँ आपके द्वारा नियोजित करने से पहले अपेक्षाओं को पूरा करने में विफल रहती हैं।
svidgen
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.