क्या कोड के हर नंबर को "मैजिक नंबर" माना जाता है?


21

कोड में हर संख्या जिसे हम एक विधि के रूप में भेज रहे हैं एक तर्क के रूप में माना जाता है? मेरे लिए, यह नहीं होना चाहिए। मुझे लगता है कि अगर कोई संख्या बताती है कि यह उपयोगकर्ता नाम की न्यूनतम लंबाई के लिए है और हम कोड में "6" का उपयोग करना शुरू करते हैं ... तो हाँ हमारे पास रखरखाव की समस्या है और यहां "6" एक जादुई संख्या है .... लेकिन अगर हम एक ऐसी विधि कह रहे हैं, जिसका एक तर्क किसी संग्रह के ith सदस्य के रूप में उदाहरण के लिए एक पूर्णांक को स्वीकार करता है और फिर हम "0" को उस विधि कॉल में पास करते हैं, तो इस स्थिति में मैं "0" को एक जादू के रूप में नहीं देखता हूं नंबर। तुम क्या सोचते हो?


4
आपके उदाहरण में, 0 क्या दर्शाता है?
एरोन कुर्त्ज़ाल्स

2
इस मामले में, आप स्पष्ट करते हैं कि "0" में कोई जादुई गुण नहीं है।
ट्यूलेंस कोर्डोवा

4
0,1 और 42 को छोड़कर सब कुछ जादू है
Mawg

जवाबों:


43

यदि संदर्भ में संख्या का अर्थ बहुत स्पष्ट है, तो मुझे नहीं लगता कि यह "जादुई संख्या" समस्या है।

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

s := substring(big_string, 0, findFirstOccurence(SOME_TOKEN, big_string));

इस संदर्भ में, संख्या 0 का अर्थ पर्याप्त रूप से स्पष्ट है। मुझे लगता है कि आप START_OF_SUBSTRINGइसे परिभाषित कर सकते हैं और इसे 0 पर सेट कर सकते हैं , लेकिन इस मामले में मुझे लगता है कि यह ओवरकिल होगा (हालांकि यह सही दृष्टिकोण होगा यदि आप जानते थे कि आपके प्रतिस्थापन की शुरुआत 0 नहीं हो सकती है, लेकिन यह निर्दिष्ट करता है आपकी स्थिति)।

एक अन्य उदाहरण यह हो सकता है कि आप यह निर्धारित करने की कोशिश कर रहे हैं कि क्या संख्या समान या विषम है। लिख रहे हैं:

isEven := x % 2;

के रूप में अजीब नहीं है:

TWO := 2;
isEven := x % TWO;

के रूप में नकारात्मक संख्या का परीक्षण

MINUS_ONE := -1;
isNegativeInt := i <= MINUS_ONE;

मुझे भी अजीब लगता है, मैं बहुत कुछ देखता हूँ

isNegativeInt := i <= -1;

6
एक अन्य उदाहरण को वहां पर फेंकने के लिए, कोड में जहां आप स्पष्ट रूप से एक सर्कल पर डिग्री के साथ काम कर रहे हैं, एक नंबर का उपयोग करना उचित होगा जैसे 360कि इस समझ के साथ पूर्ण रोटेशन को चिह्नित करना कि ज्यादातर लोगों को पता होगा कि इसका क्या मतलब है (हालांकि यह ऐसा मामला है जहां यह एक निरंतर प्रदान करने के लिए चोट नहीं पहुंचाएगा )
KChaloux

11
KChaloux: अगर मैं कर सकता था, तो मैं आपकी टिप्पणी -1 करूंगा। 360 एक मैजिक नंबर है। यदि 360 किसी अन्य स्थिरांक के लिए मान होता है, तो आपके पास 360 के लिए 2 सेट हैं जो असंबंधित और अप्रभेद्य हैं। जूनियर के साथ आता है, "यह एक जादू की संख्या है", वैश्विक खोज और "Degrees_in_Circle" के साथ 360 को बदलें, सभी इकाई और प्रतिगमन परीक्षण चलाएं, सभी पास - कोड फिक्स को डिलीवर करते हैं। कोड अब एक कुत्ते का नाश्ता, और हम सभी जानते हैं कि थोड़े समय के बाद क्या होता है .......
मैट्टनज

4
@mnnz: उम्मीद है कि बड़े पैमाने पर कोड परिवर्तन जल्दी से पकड़ा जाएगा (उम्मीद है कि कोड समीक्षा के दौरान, अगर वे उस जूनियर हैं) लंबे समय से पहले यह उत्पादन में मिला है। मुझे लगता है कि कोई ऐसा व्यक्ति जो उस संदर्भ में ऐसा करेगा 0, वह मेरे प्रतिस्थापन उदाहरण के संदर्भ में भी प्रतिस्थापित करेगा । जिस स्थिति में, यह कम से कम नुकसान हो सकता है जो वे पैदा कर सकते हैं। मुझे ज्यामितीय गणना किए हुए कोई भी कोडिंग करते हुए एक लंबा समय हो गया है, लेकिन आम तौर पर, 15, 30, 45, 60, 90, 180, 360 के मूल्य निरंतर थे। मैंने कभी किसी को परिभाषित करते नहीं देखा FIFTEEN_DEGREES, ...
FrustratedWithFormsDesigner

5
@KChaloux उदाहरण वास्तव में अलग हो सकता है अगर डिग्री से रेडियंस में बदलाव हो। 360 तक, आप 1 पूर्ण रोटेशन व्यक्त कर रहे हैं। चूंकि समान मूल्य के लिए कई प्रतिनिधित्व हैं, इसलिए इसे बाहर निकाला जाना चाहिए। विशेष रूप से 360PI पर विचार करना 2PI (180 घुमाव पर समान है लेकिन फिर भी अंत में समान दिशा को इंगित करता है), या 360 घूर्णन 1 रोटेशन के समान हो सकता है, लेकिन दुष्प्रभाव अलग हो सकते हैं।
क्रिस

14
वहाँ एक पुआल आदमी का कुछ, TWO और MINUS_ONE पूरी तरह से खराब हैं क्योंकि पाठ में इसके प्रतिपादन के साथ एक जादू नंबर की जगह OF OF COURSE idiotic है। स्थिरांक का नाम इसके अर्थ को व्यक्त करना है। आपके उदाहरणों को छोड़कर, संख्याओं के बारे में मौलिक तथ्यों के बारे में हैं, केवल उन विशिष्ट संख्याओं से निकटता से जुड़ा हुआ है, इसलिए वास्तव में इससे परे कोई अर्थ नहीं है।
माइकल बोर्गवर्ड

17
bool hasApples = apples > 0;

यह स्पष्ट शून्य का मतलब अनुपस्थिति है। मुझे "अनुपस्थिति" नामक एक चर की तुलना में समझने में 0 आसान लगता है।


for(int i=0; i < arr.length; i++)

यह स्पष्ट है 0 प्रारंभिक स्थिति है। मैं "firstPosition" नामक एक चर से भ्रमित हो जाएगा। इस तरह के एक चर मुझे आश्चर्य होगा अगर शुरुआती स्थिति बदल सकती है।


14

मैं यह तय करने में तीन प्रमुख कारकों का सुझाव दूंगा कि क्या कुछ निरंतर घोषणा होना चाहिए:

  1. क्या संख्या ऐसी है जो ठीक और संक्षिप्त रूप से प्रतिनिधित्व योग्य है
  2. क्या कोई प्रशंसनीय परिदृश्य हैं जिसके तहत मूल्य को बदलना होगा, लेकिन कोड को फिर से लिखना नहीं होगा
  3. क्या कोई व्यक्ति जो नंबर देखता है, वह नामांकित व्यक्ति को देखने वाले की तुलना में अधिक तेज़ी से या कम तेज़ी से पहचान सकता है

एक पाई शाब्दिक के रूप में पीआई की तरह शायद एक नामांकित स्थिरांक के रूप में लिखा जाना चाहिए, क्योंकि एक संख्यात्मक शाब्दिक रूप से उपयुक्त क्रिया है, अनावश्यक रूप से अव्यवस्थित, या दोनों। कैश में स्लॉट्स की संख्या की तरह कुछ का नाम एक स्थिर (हालांकि नीचे नोट देखें) होना चाहिए ताकि कैश का विस्तार करने की संभावना के बिना सभी कोड को संशोधित कर सके जो इसका उपयोग करता है। कथन में "4", "28", और "29" जैसी चीजें if ((year % 4)==0) FebruaryDays = 29; else FebruaryDays = 28;संभवतः स्थिरांक का नाम नहीं होनी चाहिए, क्योंकि अभिव्यक्ति लगभग निश्चित रूप से अधिक पठनीय है if ((year % YearsBetweenLeapYears)==0) FebruaryDays = FebruaryDaysInLeapYear; else FebruaryDays = FebruaryDaysInNonLeapYear;। ध्यान दें कि मानकों के अनुरक्षकों ने संकेत दिया है कि उस वर्ष फरवरी 2100 की लंबाई उपरोक्त सूत्र से मेल नहीं खाएगी, इस तरह की तारीखों को सही ढंग से संभालने के लिए बाधा (यानी कोड पूर्णांक अतिप्रवाह या ऐसी अन्य समस्याओं से फंस नहीं जाएगा)।

नियम # 2 के साथ एक महत्वपूर्ण चेतावनी यह है कि कुछ मामलों में कोड एक तरह से हार्ड-कोडित संख्याओं पर भरोसा कर सकता है, जिसे आसानी से एक नामित निरंतर द्वारा प्रतिनिधित्व नहीं किया जा सकता है। उदाहरण के लिए, एक विधि, जो असतत मापदंडों के रूप में पारित दो वैक्टरों के क्रॉस उत्पाद की गणना करती है, केवल तीन आयामी डॉक्टर्स पर उपयोग किए जाने पर सार्थक होगी। आयामों की आवश्यक संख्या एक ऐसा मूल्य नहीं है जिसे नियमित रूप से पूरी तरह से लिखे बिना ही सार्थक रूप से बदला जा सकता है। यहां तक ​​कि अगर किसी को तीन 4-आयामी वैक्टर के क्रॉस उत्पाद की गणना के लिए एक संभावित आवश्यकता होती है, तो मूल्य "3" के लिए नामित स्थिरांक का उपयोग करके उस आवश्यकता को पूरा करना आसान हो जाएगा।


4

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

0 पैमाने के दूसरे छोर पर है; यह अभी भी संदिग्ध है लेकिन काफी नहीं है। क्या आप एक प्रहरी मूल्य के रूप में 0 का उपयोग कर रहे हैं? तब आपको शायद इसके बजाय एक प्रतीकात्मक निरंतर का उपयोग करना चाहिए, क्योंकि निरंतर यह समझा सकता है कि इसका क्या अर्थ है। क्या यह "0 का मतलब है कि सफल समापन" जैसा एक अत्यंत सांस्कृतिक समझौता है? शायद ठीक है। क्या इसका मतलब है "एक संग्रह में पहला आइटम"? यह हानिरहित हो सकता है, लेकिन अगर कोई वैकल्पिक तरीका है जैसे कि first()मैं शायद यही पसंद करूंगा।


1
"क्या आप एक प्रहरी मूल्य के रूप में 0 का उपयोग कर रहे हैं?" <- क्या आप यहाँ "प्रहरी" द्वारा समझा जा सकता है? मुझे ऐसी परिभाषा नहीं मिल रही है जो मेल खाती प्रतीत हो।
rory.ap

3

प्रत्येक अनाम संख्या जो संदर्भ से तुरंत स्पष्ट नहीं है वह एक जादुई संख्या है। इसकी थोड़ी मूर्खतापूर्ण संख्या को परिभाषित करने के लिए जिसका अर्थ है कि संदर्भ से तुरंत स्पष्ट है।

Django (अजगर वेब फ्रेमवर्क) में, मैं कुछ डेटाबेस फ़ील्ड को कच्ची संख्या के साथ परिभाषित कर सकता हूं जैसे:

firstname = models.CharField(max_length=40)
middlename = models.CharField(max_length=40)
lastname =  models.CharField(max_length=40) 

जो स्पष्ट (और अनुशंसित अभ्यास ) है

MAX_LENGTH_NAME = 40
...
firstname = models.CharField(max_length=MAX_LENGTH_NAME)
middlename = models.CharField(max_length=MAX_LENGTH_NAME)
lastname =  models.CharField(max_length=MAX_LENGTH_NAME) 

जैसा कि मुझे कभी भी लंबाई बदलने की आवश्यकता नहीं है (और हमेशा max_lengthक्षेत्र की तुलना कर सकते हैं )। यदि मुझे शुरू में आवेदन की तैनाती के बाद क्षेत्र की लंबाई बदलने की आवश्यकता है, तो मुझे इसे अपने django कोड में प्रति फ़ील्ड बिल्कुल एक स्थान पर बदलने की आवश्यकता है, और फिर इसके अलावा DB के स्कीमा को बदलने के लिए माइग्रेशन लिखें। यदि मुझे कभी max_lengthकिसी प्रकार के ऑब्जेक्ट के परिभाषित क्षेत्र का संदर्भ देने की आवश्यकता है , तो मैं इसे सीधे कर सकता हूं - यदि वे फ़ील्ड एक Personवर्ग को परिभाषित कर रहे हैं, तो मैं इसे Person._meta.get_field('firstname').max_lengthप्राप्त करने के लिए उपयोग कर सकता हूंmax_lengthउपयोग किया जा रहा है (जो एक स्थान पर परिभाषित है)। तथ्य यह है कि एक ही 40 का उपयोग कई क्षेत्रों के लिए किया गया था, अप्रासंगिक है क्योंकि मैं उन्हें स्वतंत्र रूप से बदलना चाहता हूं। Firstname की लंबाई कभी भी middlename या lastname की लंबाई पर निर्भर नहीं होनी चाहिए; वे अलग-अलग मूल्य हैं और स्वतंत्र रूप से बदल सकते हैं।

अक्सर सरणी सूचकांक अनाम संख्याओं का उपयोग कर सकते हैं; जैसे अगर मेरे पास एक डेटा की CSV फाइल है, जिसे मैं एक अजगर शब्दकोश में रखना चाहता हूं, तो पंक्ति में पहला तत्व, जिस शब्दकोश में keyमैं लिखूंगा:

mydict = {}
for row in csv.reader(f):
    mydict[row[0]] = row[1:]

यकीन है कि मैं नाम index_column = 0और कुछ कर सकता है जैसे:

index_col = 0
mydict = {}
for row in csv.reader(f):
    mydict[row[index_col]] = row[:index_col] + row[index_col+1:]

या इससे after_index_col = index_col + 1छुटकारा पाने के लिए बदतर परिभाषित करते हैं index_col+1, लेकिन यह मेरे विचार में कोड को स्पष्ट नहीं करता है। इसके अलावा, अगर मैं index_colएक नाम देता हूं, तो मैं बेहतर काम करता हूं कोड भले ही कॉलम 0 (इसलिए row[:index_col] +भाग) नहीं है।


7
वास्तव में, max_lngth=40बनाम max_length=MAX_LENGTH_NAMEएक है क्लासिक एक जादुई संख्या के examlple कि चिल्लाती एक प्रतीक माना जाता है। वह दिन आएगा जब आप 45 चरित्र नामों का समर्थन करना चाहते हैं, और अब "40" का हर उपयोग संदिग्ध है और इसकी सावधानीपूर्वक जांच की जानी चाहिए।
रॉस पैटरसन

1
@RossPatterson - यह वह C नहीं है जहाँ हम लगातार एक वैश्विक var MAX_ARRAY_SIZE से तुलना करते हैं, लेकिन एक सभ्य वेब फ्रेमवर्क। मैजिक नंबर एक ही जगह आता है, जहां आप डेटाबेस मॉडल घोषित करते हैं; इस मूल्य के मुकाबले बाकी सब की तुलना की जाती है (उदाहरण के लिए, कोड में कहीं और 40 दिखाई देता है)। यह भी ध्यान दें, स्कीमा माइग्रेशन किए बिना आप इस वेरिएबल को आसानी से नहीं बदल सकते, क्योंकि यह एक डीबी से बंधा हुआ है। अगर मैं 1 वर्ण मध्य नामों को बदलना चाहता हूं तो इसका तुरंत कोड में बदलने के लिए एक स्थान स्पष्ट 40है 1। आपको संदर्भ के बारे में सोचना होगा।
डॉम जिंबाब

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