কোডের প্রতিটি সংখ্যা একটি "যাদু নম্বর" হিসাবে বিবেচিত হয়?


21

সুতরাং যে কোডটিতে আমরা একটি পদ্ধতিতে আর্গুমেন্ট হিসাবে প্রেরণ করছি তাতে প্রতিটি সংখ্যা ম্যাজিক নম্বর হিসাবে বিবেচিত হয়? আমার কাছে, এটা করা উচিত নয়। আমি মনে করি যদি কিছু নম্বর ধরা যাক এটি ব্যবহারকারীর নামের নূন্যতম দৈর্ঘ্যের জন্য এবং আমরা কোডে "6" ব্যবহার শুরু করি ... তবে হ্যাঁ আমাদের রক্ষণাবেক্ষণের সমস্যা আছে এবং এখানে "6" একটি ম্যাজিক সংখ্যা .... তবে যদি আমরা এমন কোনও পদ্ধতিতে কল করছি যেগুলির একটি যুক্তি একটি সংস্থার আইথ সদস্য হিসাবে উদাহরণস্বরূপ একটি পূর্ণসংখ্যা গ্রহণ করে এবং তারপরে আমরা "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, বেশিরভাগ লোকেরা এর অর্থ কী তা বুঝতে পারে তা বোঝার সাথে একটি পূর্ণ ঘূর্ণন চিহ্নিত করা যেমন একটি সংখ্যা ব্যবহার করা উপযুক্ত হবে (যদিও এটি এটি এমন একটি ক্ষেত্রে যেখানে ধ্রুবক সরবরাহ করা ক্ষতিগ্রস্থ হবে না )
কেচালাক্স

11
কেচালাক্স: আমি যদি পারতাম তবে আমি আপনার মন্তব্যটি -1 করতাম। 360 একটি যাদু নম্বর। যদি 360 অন্য ধ্রুবকের জন্য মান হিসাবে দেখা দেয়, তবে আপনার কাছে 360 এর জন্য 2 টি সেট রয়েছে যা সম্পর্কহীন এবং অবিচ্ছেদ্য। জুনিয়র বরাবর আসে, "এটি একটি ম্যাজিক নম্বর", বিশ্বব্যাপী অনুসন্ধান করুন এবং 360 কে "ডিগ্রি_ইন_সার্কেল" দিয়ে প্রতিস্থাপন করুন, সমস্ত ইউনিট এবং রিগ্রেশন পরীক্ষা চালান, সমস্ত পাস - কোড ঠিক করে দেয়। এখন একটি কুকুরের প্রাতঃরাশের কোড দিন, এবং অল্প সময়ের পরে তার কী হয় তা আমরা সবাই জানি .......
ম্যাট্নজ

4
@ ম্যাটনজ: আশা করা যায় যে এই ধরণের বড় আকারের কোড পরিবর্তন খুব দ্রুত ধরা পড়বে (আশা করি কোড পর্যালোচনা চলাকালীন, যদি তারা সেই জুনিয়র হয়) এটি উত্পাদনে যাওয়ার অনেক আগেই। আমি মনে করি যে যে কেউ সেই প্রসঙ্গে এটি করবেন তা সম্ভবত 0আমার বিকল্প উদাহরণের প্রসঙ্গে প্রতিস্থাপন করবে । কোন ক্ষেত্রে, এটি তাদের হতে পারে এমন ক্ষুদ্রতম ক্ষয়ক্ষতি হতে পারে। জ্যামিতিক গণনাগুলি করার মতো কোনও কোডিং আমি করেছি দীর্ঘ সময় হয়েছে তবে সাধারণত 15, 30, 45, 60, 90, 180, 360 মানগুলি স্থির ছিল যা গ্রহণ করা হয়েছিল। আমি কাউকে কখনই সংজ্ঞায়িত করতে দেখিনি FIFTEEN_DEGREES, ...
হতাশাগ্রস্ত

5
@ কেচালাক্স ডিগ্রি থেকে রেডিয়ানদের দিকে বদল হলে উদাহরণটি প্রকৃতপক্ষে আলাদা হতে পারে। 360 দ্বারা, আপনি 1 সম্পূর্ণ ঘূর্ণন প্রকাশ করছেন। যেহেতু একই মানের জন্য একাধিক উপস্থাপনা রয়েছে, তাই এটি টেনে আনা উচিত। বিশেষত 360PI বিবেচনা করা 2PI (180 রোটেশনগুলি এখনও একই দিকে একই দিকে নির্দেশ করে) বা 360 আবর্তনকে 1 ঘূর্ণনের সমান দেখতে পারে তবে পার্শ্ব প্রতিক্রিয়া আলাদা হতে পারে।
ক্রিস

14
সেখানে কিছুটা খড়ের মানুষ, দুটি এবং MINUS_ONE একেবারেই খারাপ, কারণ একটি যাদু সংখ্যাকে এর পাঠ্যে রেন্ডারিংয়ের সাথে প্রতিস্থাপন করাই বোকামি। ধ্রুবকের নামটির অর্থ বোঝাতে হবে। আপনার উদাহরণগুলি বাদে সংখ্যার মৌলিক তথ্যগুলি সম্পর্কে, কেবলমাত্র সেই নির্দিষ্ট সংখ্যার সাথে ঘনিষ্ঠভাবে আবদ্ধ, সুতরাং এর বাইরে সত্যিকার অর্থে কোনও অর্থ নেই।
মাইকেল বর্গওয়ার্ট

17
bool hasApples = apples > 0;

এটি স্পষ্টত শূন্য মানে অনুপস্থিতি। "অনুপস্থিতি ভ্যালু" নামক একটি ভেরিয়েবলের চেয়ে আমি 0 টি বোঝা সহজ মনে করি।


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

এটি স্পষ্টত 0 শুরুর অবস্থান। আমি "ফার্স্টপজিশন" নামের একটি ভেরিয়েবল দ্বারা বিভ্রান্ত হব। এই ধরনের পরিবর্তনশীল আমাকে যদি ভাবতে শুরু করে যে শুরুর অবস্থানটি পরিবর্তন হতে পারে।


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 সহ একটি গুরুত্বপূর্ণ সতর্কবাণী হ'ল কিছু ক্ষেত্রে কোড এমনভাবে হার্ড-কোডড সংখ্যার উপর নির্ভর করতে পারে যা সহজেই নাম ধ্রুবক দ্বারা প্রতিনিধিত্ব করতে পারে না। উদাহরণস্বরূপ, একটি পদ্ধতি যা পৃথক পরামিতি হিসাবে দুটি ভেক্টরের ক্রস প্রোডাক্টটি গণনা করে তত্ক্ষণিক ভেক্টরগুলিতে কেবল তখনই অর্থবহ হবে। প্রয়োজনীয় সংখ্যার মাত্রা এমন কোনও মূল্য নয় যা পুরোপুরি রুটিনটি পুনরায় লিখে না দিয়ে অর্থবহভাবে পরিবর্তন করা যায়। এমনকি যদি কেউ তিন-মাত্রিক ভেক্টরগুলির ক্রস প্রোডাক্ট গণনা করার জন্য একটি সম্ভাব্য প্রয়োজন আগে থেকেই দেখে, "3" মানটির জন্য একটি নাম ধ্রুবক ব্যবহার করা সেই প্রয়োজনটি পূরণ করা সহজ করে তুলতে খুব কম কাজ করে।


4

এটি, সমস্ত নীতি হিসাবে, ডিগ্রি একটি বিষয়। সাধারণভাবে বলতে গেলে, সোর্স কোডের সংখ্যাটি আক্ষরিকের তুলনায় তারা বেশি সন্দেহ হয়। 10 এর মতো সর্বাধিক দৈর্ঘ্য বা 0x587FB0 এর মতো মেমরি ঠিকানার স্পষ্টতই খারাপ অভ্যাস - এটি প্রায় নিশ্চিত যে খুব শীঘ্রই বা পরে আপনাকে এই মানগুলি একাধিকবার পুনরাবৃত্তি করতে হবে, এমন জায়গাগুলিতে যেগুলি অসম্পূর্ণতা এবং সূক্ষ্ম ত্রুটিগুলির পরিচয় দেওয়া হয়েছিল তা চালু করা হয়নি that পরিবর্তন করেছেন।

0 স্কেলের অন্য প্রান্তে; এটি এখনও সন্দেহজনক তবে যথেষ্ট নয়। আপনি 0 কে সেন্ডিনেল মান হিসাবে ব্যবহার করছেন? তারপরে সম্ভবত আপনার পরিবর্তে একটি প্রতীকী ধ্রুবক ব্যবহার করা উচিত, কেবল কারণ ধ্রুবকটি এর অর্থ কী তা ব্যাখ্যা করতে পারে। এটি কি "0 এর অর্থ সফল সমাপ্তি" এর মতো চূড়ান্তভাবে আবদ্ধ সাংস্কৃতিক চুক্তি? এটা সম্ভবত ঠিক আছে। এর অর্থ কি "সংগ্রহের প্রথম আইটেম"? এটি নিরীহ হতে পারে, তবে যদি বিকল্প পদ্ধতি থাকে যেমন first()আমি সম্ভবত এটি পছন্দ করি।


1
"আপনি কি 0 টি সেন্ডিনেল মান হিসাবে ব্যবহার করছেন?" <- আপনি এখানে "সেন্ডিনেল" বলতে কী বোঝাতে চান তা ব্যাখ্যা করতে পারেন? মেলে বলে মনে হচ্ছে এমন কোনও সংজ্ঞা আমি পাই না।
rory.ap

3

প্রসঙ্গ থেকে তাত্ক্ষণিকভাবে প্রকাশ না হওয়া প্রতিটি নামবিহীন নম্বর হ'ল ম্যাজিক নম্বর। সংখ্যার সংজ্ঞা দেওয়া যেহেতু প্রসঙ্গ থেকে তাত্ক্ষণিকভাবে সুস্পষ্ট হয় তা সংজ্ঞায়িত করার জন্য এটি কিছুটা নির্বোধ।

জ্যাঙ্গোতে (পাইথন ওয়েব ফ্রেমওয়ার্ক), আমি কাঁচা সংখ্যার সাথে কিছু ডাটাবেস ক্ষেত্রের সংজ্ঞা দিতে পারি:

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)। প্রাথমিকভাবে অ্যাপ্লিকেশন মোতায়েন করার পরে যদি আমার ক্ষেত্রের দৈর্ঘ্য পরিবর্তন করতে হয় তবে আমার জ্যাঙ্গো কোডে ক্ষেত্রের প্রতি ঠিক এক জায়গায় এটি পরিবর্তন করতে হবে এবং তারপরে ডিবির স্কিমা পরিবর্তন করার জন্য মাইগ্রেশন লিখতে হবে। যদি কখনও আমাকে max_lengthকোনও ধরণের অবজেক্টের একটি সংজ্ঞায়িত ক্ষেত্রের রেফারেন্সের প্রয়োজন হয় তবে আমি তা সরাসরি করতে পারি - যদি ক্ষেত্রগুলি কোনও Personশ্রেণীর সংজ্ঞা দিচ্ছিল , আমি এটি পেতে ব্যবহার Person._meta.get_field('firstname').max_lengthকরতে পারিmax_lengthব্যবহৃত হচ্ছে (যা এক জায়গায় সংজ্ঞায়িত)। একই 40 টি একাধিক ক্ষেত্রের জন্য ব্যবহৃত হয়েছিল তা অপ্রাসঙ্গিক কারণ আমি এগুলি স্বাধীনভাবে পরিবর্তন করতে চাই। প্রথম নামটির দৈর্ঘ্য কখনই মিডলনাম বা লাস্টনামের দৈর্ঘ্যের উপর নির্ভর করে না; এগুলি পৃথক মান এবং স্বাধীনভাবে পরিবর্তন করতে পারে।

প্রায়শই অ্যারে সূচকগুলি নামবিহীন সংখ্যা ব্যবহার করতে পারে; যেমন আমার কাছে যদি সিএসভি ফাইলের ডেটা থাকে যা আমি পাইথন অভিধানে রাখতে চাই, অভিধানটিতে সারির প্রথম উপাদানটি দিয়ে 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একটি ক্লাসিক পরীক্ষা যা প্রতীক হিসাবে চিৎকার করে। এমন দিন আসবে যখন আপনি 45 টি চরিত্রের নাম সমর্থন করতে চান এবং এখন "40" এর প্রতিটি ব্যবহার সন্দেহজনক এবং অবশ্যই যত্ন সহকারে পরীক্ষা করা উচিত।
রস প্যাটারসন

1
@ রোসপ্যাটারসন - এটি সি নয় যেখানে আমরা ক্রমাগত বিশ্বব্যাপী MAX_ARRAY_SIZE এর সাথে তুলনা করি তবে একটি শালীন ওয়েব কাঠামো। আপনি যেখানে ডাটাবেস মডেল ঘোষণা করেন কেবল সেই জায়গাতেই ম্যাজিক নম্বরটি আসে; অন্যান্য সমস্ত কিছুর তুলনায় এই মানটির তুলনা করা হয় (উদাহরণস্বরূপ, কোডটিতে কোথাও 40 টি উপস্থিত নেই)। এছাড়াও নোট করুন, স্কিমা মাইগ্রেশনটি কোনও ডিবিতে আবদ্ধ হওয়ার কারণে আপনি সহজেই এই পরিবর্তনশীলটি পরিবর্তন করতে পারবেন না। আমি যদি 1 অক্ষরের মাঝের নামটি বলতে চাইলে এটি কোডে পরিবর্তন করার জন্য অবিলম্বে এক জায়গায় স্পষ্ট 40হয় 1। আপনাকে প্রসঙ্গে ভাবতে হবে।
ডাঃ জিম্বব

2
দুঃখিত, আপনি দুটি পয়েন্ট ভুল। প্রথমে, ওপি একটি "প্রোগ্রামিং অনুশীলন" প্রশ্ন জিজ্ঞাসা করেছিল যা কোনও ভাষা নির্দিষ্ট করে না। তারা "পদ্ধতি" বলেছিল, "ফাংশন" নয়, তাই আসুন কিছু বস্তু-ভিত্তিক ধারণা করা যাক, তবে এটি আমাদের যাদু-সংখ্যার ডেটাগুলির ক্ষেত্র থেকে বাইরে নিয়ে যায় না। দ্বিতীয়ত, যদি ম্যাজিক নম্বরটি ডাটাবেসে বেক করা হয় ( যেমন , স্কিমা), তবে কোডটিতে থাকা আরও খারাপ। করণীয় সঠিক জিনিসটি হ'ল যাদুটিকে তার উত্স থেকে প্রায় এক ধ্রুবক করে তোলা - হয় ডেটাবেস নিজেই বা একটি স্কিমা মডিউল যা এই সমস্ত ধ্রুবককে কেন্দ্র করে তোলে-যা হবে-কোড-এর জীবনকালকে পৃথক করে।
রস প্যাটারসন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.