वस्तुतः सारणी प्रारूप में "इफ इफ इफ इफ" क्यों कथन हैं?


73
if   i>0 : return sqrt(i)  
elif i==0: return 0  
else     : return 1j * sqrt(-i)

वी.एस.

if i>0:  
   return sqrt(i)  
elif i==0:  
   return 0  
else:  
   return 1j * sqrt(-i)  

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

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


91
क्योंकि लोगों को दूसरा विकल्प अधिक पठनीय लगता है?
ग्रैंडमास्टरबी

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

47
@horta "एकमात्र मामला जहां यह समस्याग्रस्त हो सकता है वह है फाई कोड परिवर्तन और लंबा हो जाता है।" - आपको कभी भी यह नहीं समझना चाहिए कि कोड का एक टुकड़ा नहीं बदला जाएगा। कोड रीफैक्टरिंग एक सॉफ्टवेयर के जीवनचक्र का एक बड़ा हिस्सा लेता है।
चार्ल्स अदीस

7
@horta: मेरे साथ कुछ नहीं करना है। यह कोड है। मैं जिस कोडबेस को पढ़ रहा हूं, उसके संदर्भ में, मैं यह देखना चाहता हूं कि क्या स्टेटमेंट (और अन्य भाषा निर्माण) लगातार फॉर्मेट किए गए हैं, बिना किसी एज केस के। ऐसा नहीं है कि मैंने किसी विशेष तरीके से कोड पढ़ना सीखा है, मैं या तो ठीक पढ़ सकता हूं , लेकिन अगर सब कुछ समान है तो यह अधिक पठनीय है। दोबारा, मेरे लिए समान नहीं, बाकी कोड के लिए भी यही।
GManNickG

44
इसके अलावा, अधिकांश डिबगर लाइन आधारित हैं। एक बयान पर एक ब्रेकपॉइंट नहीं डाल सकते हैं जो अंदर है ifअगर यह एक ही लाइन पर है।
इसनाए

जवाबों:


93

एक कारण यह हो सकता है कि आप उन भाषाओं का उपयोग नहीं कर रहे हैं जहाँ यह लोकप्रिय है।

कुछ प्रति-उदाहरण:

गार्ड और पैटर्न के साथ हास्केल:

sign x |  x >  0        =   1
       |  x == 0        =   0
       |  x <  0        =  -1

take  0     _           =  []
take  _     []          =  []
take  n     (x:xs)      =  x : take (n-1) xs

पैटर्न के साथ Erlang:

insert(X,Set) ->
    case lists:member(X,Set) of
        true  -> Set;
        false -> [X|Set]
    end.

Emacs लिस्प:

(pcase (get-return-code x)
  (`success       (message "Done!"))
  (`would-block   (message "Sorry, can't do it now"))
  (`read-only     (message "The shmliblick is read-only"))
  (`access-denied (message "You do not have the needed rights"))
  (code           (message "Unknown return code %S" code)))

आम तौर पर मैं देखता हूं कि तालिका प्रारूप कार्यात्मक भाषाओं (और सामान्य अभिव्यक्ति पर आधारित) के साथ बहुत लोकप्रिय है, जबकि लाइनों को तोड़ना दूसरों में सबसे लोकप्रिय है (ज्यादातर कथन आधारित)।


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

3
@JaredSmith अभिव्यक्ति / कथन आधारित विभाजन के लिए धन्यवाद - मुझे लगता है कि यह कार्यात्मक / अनिवार्यता से भी अधिक उपयुक्त हो सकता है। फिर से माणिक लगभग अभिव्यक्ति आधारित है और अक्सर उस सम्मेलन का उपयोग नहीं करता है। (सब कुछ के अपवाद) अंक 1 और 2 के संबंध में, मुझे असली Haskell कोड का 50% + "तुच्छ रिटर्न" लगता है जो कि कुछ बड़े हिस्से के हिस्से हैं - यह सिर्फ इतना है कि यह कोड कैसे लिखा गया है - न केवल यहां उदाहरणों में। उदाहरण के लिए, यहाँ आधे कार्यों के करीब एक / दो लाइनर हैं। (कुछ पंक्तियाँ टेबल लेआउट का उपयोग करती हैं)
विराटपुर २16

हाँ। मैं हास्केलर नहीं हूं, लेकिन कुछ ओसमेल करता हूं और पाता हूं कि पैटर्न मिलान समान रूप से समकक्ष स्विच की तुलना में बहुत अधिक संक्षिप्त हो जाता है, और पॉलीमॉर्फिक फ़ंक्शन उस जमीन को बहुत अधिक कवर करते हैं। मुझे लगता है कि हास्केल के प्रकार की कक्षाएं उस कवरेज का और भी विस्तार करेंगी।
जेरेड स्मिथ

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

@viraptor तकनीकी रूप से अन्य 50% - haskell कोड "गैर-तुच्छ रिटर्न" है क्योंकि सभी haskell फ़ंक्शन कार्यात्मक रूप से शुद्ध हैं और इनके दुष्प्रभाव नहीं हो सकते हैं। यहां तक ​​कि कमांड लाइन पर पढ़ने और प्रिंट करने वाले फ़ंक्शंस केवल लंबे समय तक रिटर्न स्टेटमेंट हैं।
फराप जूल

134

यह अधिक पठनीय है। कुछ कारण क्यों:

  • लगभग हर भाषा इस वाक्यविन्यास का उपयोग करती है (सभी नहीं, सबसे - आपका उदाहरण पायथन प्रतीत होता है, हालांकि)
  • isanae ने एक टिप्पणी में कहा कि अधिकांश डिबगर लाइन आधारित हैं (कथन आधारित नहीं)
  • यदि आप इनलाइन अर्धविराम या ब्रेसिज़ लेना चाहते हैं तो यह और भी बदसूरत लगने लगता है
  • यह ऊपर से नीचे तक अधिक आसानी से पढ़ता है
  • यदि आपके पास तुच्छ रिटर्न स्टेटमेंट के अलावा कुछ भी नहीं है तो यह बहुत ही भयानक है
    • किसी भी इंडेंट सार्थक वाक्य रचना खो दिया है जब आप सशर्त कोड के रूप में कोड अब नेत्रहीन (से अलग है स्किम दान नीली )
    • यह विशेष रूप से बुरा होगा यदि आप बयानों को 1-पंक्ति में आइटम पैच / जोड़ना जारी रखते हैं
  • यह केवल पठनीय है अगर आपकी सभी जांचें समान लंबाई के बारे में हैं
  • इसका मतलब है कि आप जटिल फ़ॉर्मेट नहीं कर सकते हैं अगर बहु बयान में बयान, वे जाएगा है oneliners होने के लिए
  • जब मैं एक साथ कई लाइनों को पार्स करने की कोशिश नहीं कर रहा हूं, तो लाइन द्वारा लंबवत लाइन पढ़ते समय मुझे बग / लॉजिकफ्लो नोटिस करने की अधिक संभावना है
  • हमारा दिमाग संकरा, लंबा पाठ MUCH को लंबे, क्षैतिज पाठ की तुलना में तेजी से पढ़ता है

जिस मिनट आप यह करने की कोशिश करते हैं, आप इसे बहुस्तरीय कथनों में फिर से लिखेंगे। जिसका मतलब है कि आपने सिर्फ समय बर्बाद किया है!

इसके अलावा लोग अनिवार्य रूप से कुछ जोड़ते हैं:

if i>0:  
   print('foobar')
   return sqrt(i)  
elif i==0:  
   return 0  
else:  
   return 1j * sqrt(-i)  

आपके द्वारा यह प्रारूप तय करने से पहले बहुत बार ऐसा करने में समय नहीं लगता है। आह, लेकिन आप यह सब एक पंक्ति में इनलाइन कर सकते हैं! एंडरलैंड अंदर पर मर जाता है

या यह:

if   i>0 : return sqrt(i)  
elif i==0 and bar==0: return 0  
else     : return 1j * sqrt(-i)

जो वास्तव में, वास्तव में कष्टप्रद है। इस तरह की चीजों को फॉर्मेट करना किसी को पसंद नहीं है।

और आखिरी, आप "टैब के लिए कितने स्थान" समस्या के पवित्र युद्ध को शुरू करेंगे। तालिका प्रारूप के रूप में आपकी स्क्रीन पर पूरी तरह से प्रस्तुत करना सेटिंग्स के आधार पर मेरा प्रस्तुतिकरण नहीं हो सकता है।

पठनीयता वैसे भी आईडीई सेटिंग्स पर निर्भर नहीं होनी चाहिए।


14
@ हॉर्ता क्योंकि आपको इसे बदलना होगा यदि आप इसे अपने पहले तरीके से प्रारूपित करते हैं, तो शुरू में? मैं भविष्य के एंडरलैंड के लिए काम को कम करने के बारे में हूं। सुंदर स्वरूपित टेबल और गिनती के स्थान और टैब बनाना दृश्य स्वरूपण को अद्यतन करने के लिए जब मैं कुछ तर्क जोड़ सकता हूं यदि चेक बिल्कुल भी मजेदार नहीं है (पठनीयता के प्रभावों की अनदेखी)।
एंडरलैंड

14
@ हॉर्ता वह जरूरी नहीं कह रहा है कि वह इसे ठीक नहीं करेगा, वह कह रहा है कि उसे इसे ठीक करना होगा, और यह बहुत समय थकाऊ प्रारूपण पर खर्च किया गया है, बजाय प्रोग्रामिंग पर।
सेवादार

11
@horta: IMHO आपका रास्ता अक्सर कम पठनीय होता है, और निश्चित रूप से प्रारूपण के लिए बहुत अधिक कष्टप्रद होता है। इसके अलावा, इसका उपयोग केवल तभी किया जा सकता है जब "ifs" छोटे एक लाइनर होते हैं, जो कि शायद ही कभी मामला होता है। अंत में, यह किसी भी तरह से अच्छा नहीं है, IMHO, इस तरह से "इफ" के दो प्रकारों को ले जाने के लिए।
२०:०४

9
@horta आपको उन प्रणालियों पर काम करने के लिए धन्य लगता है, जहां आवश्यकताओं, सिस्टम, एपीआई और उपयोगकर्ता की जरूरतों को कभी नहीं बदलना चाहिए। आप भाग्यशाली आत्मा हैं।
एंडरलैंड

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

55

मैं एक दृढ़ विश्वास हूं, 'कोड कई बार पढ़ा जाता है, कुछ लिखा जाता है - इसलिए पठनीयता बहुत महत्वपूर्ण है।'

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


3
प्रासंगिक: thecodelesscode.com/case/94
केविन

11
यह बताता है कि लोग रूढ़िवादी क्यों हैं। यह स्पष्ट नहीं करता है कि लोगों ने अपने कोड को शुरू करने के लिए एक निश्चित तरीका क्यों चुना।
जोर्गेन फोग जूल

8
सवाल था 'मैं इसे अक्सर क्यों देखता हूं', न कि यह शैली कहां से आई है। दोनों प्रश्न दिलचस्प हैं; मैंने जो सोचा था, उसका जवाब देने की कोशिश की।
बजे आर्ट स्व्री जूल

16

पहले से ही उल्लेखित अन्य कमियों के साथ, सारणीबद्ध लेआउट मैन्युअल हस्तक्षेप की आवश्यकता वाले संस्करण नियंत्रण मर्ज संघर्षों की बाधाओं को बढ़ाता है।

जब सारणीबद्ध रूप से परिष्कृत कोड के एक ब्लॉक को पुन: असाइन करने की आवश्यकता होती है, तो संस्करण नियंत्रण प्रणाली उन सभी पंक्तियों को संशोधित करने के रूप में व्यवहार करेगी:

diff --git a/foo.rb b/foo.rb
index 40f7833..694d8fe 100644
--- a/foo.rb
+++ b/foo.rb
@@ -1,8 +1,8 @@
 class Foo

   def initialize(options)
-    @cached_metadata = options[:metadata]
-    @logger          = options[:logger]
+    @metadata = options[:metadata]
+    @logger   = options[:logger]
   end

 end

अब मान लें कि इस समय में, एक अन्य शाखा में, एक प्रोग्रामर ने संरेखित कोड के ब्लॉक में एक नई लाइन जोड़ी है:

diff --git a/foo.rb b/foo.rb
index 40f7833..86648cb 100644
--- a/foo.rb
+++ b/foo.rb
@@ -3,6 +3,7 @@ class Foo
   def initialize(options)
     @cached_metadata = options[:metadata]
     @logger          = options[:logger]
+    @kittens         = options[:kittens]
   end

 end

उस शाखा को विलय करना विफल हो जाएगा:

wayne@mercury:/tmp/foo$ git merge add_kittens
Auto-merging foo.rb
CONFLICT (content): Merge conflict in foo.rb
Automatic merge failed; fix conflicts and then commit the result.

यदि संशोधित किए जा रहे कोड में सारणीबद्ध संरेखण का उपयोग नहीं किया गया होता, तो मर्ज अपने आप सफल हो जाता।

(यह जवाब कोड में सारणीबद्ध संरेखण को हतोत्साहित करने वाले मेरे अपने लेख से "साहित्यिक चोरी" था )।


1
दिलचस्प है, लेकिन क्या यह मर्ज टूल की विफलता नहीं है? विशेष रूप से इस मामले में गिट? यह कन्वेंशन के लिए जाने का आसान तरीका है। मेरे लिए, यह कुछ ऐसा है जिस पर (टूल साइड से) सुधार किया जा सकता है।
हॉर्टा जूल

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

पकड़ लिया। जैसा कि टिप्पणियों में कहीं और उल्लेख किया गया है, जब तक कि हमारे पास आईडीई या प्रोग्रामिंग इनपुट प्रारूप नहीं हैं जो सीधे प्रारूप में तालिकाओं को शामिल करते हैं, टूलींग की समस्याएं हमेशा होंगी हममें से केवल उन लोगों के लिए जीवन मुश्किल बना रहा है जो तालिकाओं को पसंद करते हैं।
२१:३२

1
@ तोरता सही। कोड में सारणीबद्ध संरेखण के लिए मेरी अधिकांश आपत्तियां पर्याप्त रूप से उन्नत उपकरणों के साथ दूर जा सकती हैं।
वेन कॉनराड

8

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

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


सच। मैंने देखा है कि मैं जिस पाठ संपादक का उपयोग करता हूं (vim) को सारणीबद्ध स्वरूपण या यहां तक ​​कि विस्तृत पाठ के लिए भयानक समर्थन है। मैंने अन्य पाठ-संपादकों को बहुत बेहतर करते नहीं देखा है।
हॉर्टा

6

'स्विच' कथन है जो विशेष मामलों के लिए इस तरह की चीज़ प्रदान करता है, लेकिन मुझे लगता है कि आप इसके बारे में क्या पूछ रहे हैं।

मैंने देखा है कि यदि तालिका प्रारूप में कथन हैं, लेकिन इसे सार्थक बनाने के लिए बड़ी संख्या में शर्तें हैं। 3 अगर पारंपरिक प्रारूप में बयानों को सबसे अच्छा दिखाया गया है, लेकिन अगर आपके पास 20 थे, तो उन्हें एक बड़े ब्लॉक में प्रदर्शित करना बहुत आसान है जो इसे स्पष्ट करने के लिए स्वरूपित है।

और वहाँ बिंदु है: स्पष्टता। यदि यह देखना आसान हो जाता है (और आपका पहला उदाहरण यह देखना आसान नहीं है कि: सीमांकक कहां है) तो स्थिति के अनुकूल होने के लिए इसे प्रारूपित करें। अन्यथा, लोगों की अपेक्षा से चिपके रहें, क्योंकि पहचानना हमेशा आसान होता है।


1
ओपी पायथन का उपयोग करता हुआ दिखाई देता है, इसलिए नहीं switch
जेरेड स्मिथ

2
"3 अगर पारंपरिक प्रारूप में कथन सबसे अच्छे से दिखाए जाते हैं, लेकिन अगर आपके पास 20 थे" ... तो आपके पास सोचने के लिए बड़े मुद्दे हैं! :)
ग्रिम Opiner

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

@JaredSmith: जाहिरा तौर पर switchबुराई है, लेकिन एक शब्दकोश instantiating तो आदेश तुच्छ शाखाओं में करने के लिए उस पर एक लुकअप बुराई नहीं है ...
मार्क के कोवान

1
@MarkKCowan ओह मैंने व्यंग्य पकड़ा लेकिन सोचा कि आप इसका इस्तेमाल मुझसे मज़ाक करने के लिए कर रहे हैं। इंटरनेट और whatnot पर संदर्भ की कमी।
जारेड स्मिथ

1

यदि आपकी अभिव्यक्ति वास्तव में है कि सबसे आसान प्रोग्रामिंग भाषाएं प्रदान करती हैं:?

return  ( i > 0  ) ? sqrt( i)
      : ( i == 0 ) ? 0
        /* else */ : 1j * sqrt( -i )

यह एक छोटा पठनीय सारणीबद्ध प्रारूप है। लेकिन महत्वपूर्ण हिस्सा यह है: मैं एक नज़र में देखता हूं कि "प्रमुख" कार्रवाई क्या है। यह एक रिटर्न स्टेटमेंट है! और मूल्य कुछ शर्तों द्वारा तय किया जाता है।

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

if ( i > 0 )
{
    throw new InvalidInputException(...);
}
else if ( i == 0 )
{
    return 0;
}
else
{
    log( "Calculating sqrt" );
    return sqrt( -i );
}

7
दरअसल, मुझे आपका "कम पठनीय सारणीबद्ध प्रारूप" पढ़ने में काफी बुरा लगता है, जबकि ओपी द्वारा प्रस्तावित प्रारूप पूरी तरह से ठीक है।
मैट्टो इटालिया

@MatteoItalia कैसे इस संपादित संस्करण के बारे में?
फाल्को

5
क्षमा करें, अभी भी बदतर; मुझे लगता है कि यह इस तथ्य से आता है कि ?और :से पहचानना कठिन हैं if/ elseकीवर्ड और / या जोड़ा प्रतीकों में से 'शोर' की वजह से।
मट्टियो इतालिया

@MatteoItalia: मेरे पास सौ से अधिक विभिन्न मूल्यों के मामले हैं। तालिका मान त्रुटियों के लिए जाँच करना संभव बनाता है। मल्टी-लाइन के साथ, यह असंभव है।
gnasher729

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

1

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

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

एक लोकप्रिय त्रुटि जो कोडिंग मानकों को अक्सर संबोधित करती है, वह है छोटी गच्चा: -

if (x == 10)
    do_something();
    do_something_else();

यह वह नहीं करता है जो आप सोचते हैं कि यह करता है। जहां तक ​​C का संबंध है, यदि x 10 है तो आप कॉल करते हैं do_something(), लेकिन फिर x के मान की परवाह किए बिना कॉल किया do_something_else()जाता है । केवल "अगर" बयान के बाद कार्रवाई सशर्त है। यह वही हो सकता है जो कोडर का इरादा करता है, जिस स्थिति में रखरखाव के लिए एक संभावित जाल है; या यह नहीं हो सकता है कि कोडर का इरादा क्या है, जिस स्थिति में बग है। यह एक लोकप्रिय साक्षात्कार प्रश्न है।

कोडिंग मानकों में समाधान सभी सशर्त क्रियाओं के आसपास ब्रेसिज़ को अनिवार्य करना है, भले ही वे सिंगल-लाइन हों। अब हम मिल गए

if (x == 10)
{
    do_something();
    do_something_else();
}

या

if (x == 10)
{
    do_something();
}
do_something_else();

और अब यह सही ढंग से काम करता है और अनुरक्षकों के लिए स्पष्ट है।

आप देखेंगे कि यह आपके टेबल-स्टाइल प्रारूप के साथ पूरी तरह से असंगत है।

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

if x == 10:
    do_something()
    do_something_else()

एक्स == 10 पर दोनों do_something()और do_something_else()सशर्त कॉल करता है , जबकि

if x == 10:
    do_something()
do_something_else()

इसका मतलब है कि केवल do_something()एक्स पर सशर्त है, और do_something_else()हमेशा कहा जाता है।

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


1
मुझे लगता है आपने पॉइंट छोड़ दिया। आप जिस मुद्दे की बात करते हैं वह एक अजीब सी विशिष्ट गैर-मानक दुःस्वप्न है जो आपके द्वारा बोलने वाले मुद्दे का कारण बनता है। यदि C में कोडिंग है, तो मैं कभी भी वैकल्पिक सरल का उपयोग करने की सलाह नहीं दूंगा यदि मेरे द्वारा सुझाए गए सारणीबद्ध प्रारूप के साथ विधि। इसके बजाय, जब से आप C का उपयोग कर रहे हैं, आप सभी को एक पंक्ति में ब्रेसिज़ का उपयोग करेंगे। ब्रेसिज़ वास्तव में टेबल प्रारूप को और भी स्पष्ट कर देंगे क्योंकि वे सीमांकक के रूप में कार्य कर रहे हैं।
होर्ता

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

2
मेरा कहना था कि यह एक तालिका प्रारूप को और भी अधिक स्पष्ट करता है। संयोग से, यह सी-विशिष्ट नहीं है - यह सी से प्राप्त सभी भाषाओं द्वारा साझा किया गया है, इसलिए सी ++, सी #, जावा और जावास्क्रिप्ट सभी एक ही गेटा की अनुमति देते हैं।
ग्राहम

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

1

टेबुलर लेआउट कुछ सीमित मामलों में उपयोगी हो सकता है, लेकिन कुछ ही समय में यह उपयोगी होता है।

साधारण मामलों में?: एक बेहतर विकल्प हो सकता है। मध्यम मामलों में एक स्विच अक्सर बेहतर होता है (यदि आपकी भाषा में एक है)। जटिल मामलों में आप पा सकते हैं कि एक कॉल टेबल एक बेहतर फिट है।

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

के बारे में कुछ सवाल थे ?:। हाँ, यह टर्नरी ऑपरेटर है (या जैसा कि मुझे लगता है कि यह मान चाहे तो)। पहले ब्लश के लिए यह उदाहरण थोड़ा जटिल है:? उपाय।

if i==0: return 0
return i>0?sqrt(i):(1j*sqrt(-i))

1
आपको यह स्पष्ट करना पड़ सकता है कि "??" "असिंचित के लिए है (उदाहरण के लिए, उदाहरण के लिए, संभवतः प्रश्न से संबंधित)।
पीटर मॉर्टेंसन

मैं मान रहा हूं कि यह टर्नरी ऑपरेटर है। मुझे लगता है कि यह अच्छा कारण है कि टर्नरी ऑपरेटर मानक को पुनर्व्यवस्थित करने के लिए जाता है अगर सामान, करो, वरना, अन्य सामान प्रारूप करें जो लोग दिन और दिन बाहर देखते हैं और इसलिए आसानी से पढ़ सकते हैं।
हॉर्टा

@PeterMortensen: अगर बिन बुलाए पता नहीं इसका क्या मतलब है, तो उन्हें स्पष्ट सवाल पूछने और सीखे जाने तक कोड से दूर रहना चाहिए।
gnasher729

@ तोर्ता टेरनेरी है if ? do stuff : do other stuff। यदि / नहीं तो समान आदेश।
नवीन

1
@ नवीन अह, शायद यह उस भाषा की असफलता है जिसका मैं सबसे अधिक उपयोग करता हूं (अजगर)। stackoverflow.com/questions/394809/…
horta

-3

मुझे टेबल प्रारूप में कुछ भी गलत नहीं दिख रहा है। व्यक्तिगत पसंद, लेकिन मैं इस तरह एक टर्नरी का उपयोग करेगा:

return i>0  ? sqrt(i)       :
       i==0 ? 0             :
              1j * sqrt(-i)

returnहर बार दोहराने की जरूरत नहीं है :)


1
जैसा कि कुछ टिप्पणियों में उल्लेख किया गया है, रिटर्न स्टेटमेंट आदर्श या पोस्ट का बिंदु नहीं है, बस कोड का एक हिस्सा मैंने ऑनलाइन पाया और कुछ तरीके तैयार किए।
हॉर्टा जूल

पायथन टर्निरी हैं do_something() if condition() else do_something_else(), नहीं condition() ? do_something() : do_something_else()
इशाया मीडोज

@IsiahMeadows ओपी ने कभी पायथन का उल्लेख नहीं किया।
नवीन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.