যাদু নম্বরগুলি দূর করা: কখন "না" বলার সময় হয়?


36

আমরা সকলেই অবগত যে ম্যাজিক নম্বরগুলি (হার্ড-কোডেড মানগুলি) আপনার প্রোগ্রামে সর্বনাশ ডেকে আনতে পারে, বিশেষত যখন এমন কোনও কোডের সংশোধন করার সময় এসেছে যার কোনও মন্তব্য নেই তবে আপনি রেখাটি কোথায় আঁকেন?

উদাহরণস্বরূপ, আপনার যদি এমন কোনও ফাংশন থাকে যা দুই দিনের মধ্যে সেকেন্ডের সংখ্যা গণনা করে, আপনি কি প্রতিস্থাপন করবেন

seconds = num_days * 24 * 60 * 60

সঙ্গে

seconds = num_days * HOURS_PER_DAY * MINUTES_PER_HOUR * SECONDS_PER_MINUTE

আপনি কোন্ পর্যায়ে সিদ্ধান্ত নিয়েছেন যে হার্ড-কোডেড মানটির অর্থ কী তা সম্পূর্ণ স্পষ্ট এবং এটিকে একা রেখে দিন?


2
কেন সেই গণনাটিকে কোনও ফাংশন বা ম্যাক্রো দিয়ে প্রতিস্থাপন করবেন না তাই আপনার কোডটি দেখতে দেখতে শেষ হবেseconds = CALC_SECONDS(num_days);
হতাশাহীন

15
TimeSpan.FromDays(numDays).Seconds;
কেউ

18
@ ওস্টারওয়াল: সেই মনোভাবের সাথে ( HOURS_PER_DAY will never need to be altered), আপনি কখনই মঙ্গল গ্রহে নিযুক্ত সফ্টওয়্যারটির কোডিং করবেন না। : পি
হতাশাহীন

23
আমি স্থির সংখ্যা কেবলমাত্র SECONDS_PER_DAY = 86400 এ কমিয়ে দিতাম। কেন পরিবর্তন হবে না এমন কিছু গণনা করবেন?
জনএফএক্স

17
লিপ সেকেন্ডের কী হবে?
জন

উত্তর:


40

সংখ্যাযুক্ত আক্ষরিক পরিবর্তে প্রতীকী ধ্রুবক ব্যবহার করার দুটি কারণ রয়েছে:

  1. যাদু সংখ্যা পরিবর্তন হলে রক্ষণাবেক্ষণ সরল করতে। এটি আপনার উদাহরণের জন্য প্রযোজ্য নয়। এক ঘন্টার মধ্যে সেকেন্ডের সংখ্যা, বা একদিনে কয়েক ঘন্টার সংখ্যা পরিবর্তিত হবে তা অত্যন্ত সম্ভাবনা।

  2. পাঠযোগ্যতা উন্নত করতে। "24 * 60 * 60" অভিব্যক্তিটি প্রায় সকলের কাছেই স্পষ্ট। "SECONDS_PER_DAY" খুব, তবে আপনি যদি বাগের শিকার করে থাকেন তবে আপনাকে SECONDS_PER_DAY সঠিকভাবে সংজ্ঞায়িত করা হয়েছে কিনা তা পরীক্ষা করতে হবে। সংকোচনের মান আছে।

সেই ম্যাজিক সংখ্যার জন্য যা একবারে প্রদর্শিত হয় এবং বাকি প্রোগ্রামের চেয়ে স্বতন্ত্র থাকে that এই সংখ্যার জন্য একটি প্রতীক তৈরি করতে হবে কিনা তা স্বাদের বিষয়। যদি কোনও সন্দেহ থাকে তবে এগিয়ে যান এবং একটি প্রতীক তৈরি করুন।

এটা করো না:

public static final int THREE = 3;

3
+1 @ কেভিন ক্লাইন: আমি ব্রেভিটি সম্পর্কে একটি বাগ-শিকার সম্পর্কে আপনার বক্তব্যের সাথে একমত। নামযুক্ত ধ্রুবকটি ব্যবহার করার জন্য আমি যে অতিরিক্ত উপকারটি দেখতে পাচ্ছি, বিশেষত ডিবাগিংয়ের সময় এটি হ'ল এটি যদি সনাক্ত হয় যে কোনও ধ্রুবককে ভুলভাবে সংজ্ঞায়িত করা হয়েছিল তবে আপনাকে কেবলমাত্র ভুলভাবে প্রয়োগ করা সমস্ত ঘটনার জন্য একটি সম্পূর্ণ প্রকল্পের সন্ধানের চেয়ে কোডের একটি অংশ পরিবর্তন করতে হবে need মান।
অস্টারওয়াল

40
বা আরও খারাপ:publid final int FOUR = 3;
গ্যাবলিন

3
ওহে প্রিয়, আপনি অবশ্যই সেই লোকটির সাথে অবশ্যই কাজ করেছিলেন যা আমি একবার কাজ করেছিলাম।
দ্রুত_ এখন

2
@ গ্যাবলিন: ফর্সা হওয়ার জন্য, পাবগুলিতে idsাকনা থাকা বেশ কার্যকর।
অ্যালান পিয়ার্স

10
আমি এটি দেখেছি: public static int THREE = 3;... নোট - না final!
স্টিফেন সি

29

আমি কখনই ম্যাজিক নম্বর না রাখার নিয়মটি রাখব।

যদিও

seconds = num_days * 24 * 60 * 60

ক্র্যাঞ্চ মোডে তিন বা চার সপ্তাহের জন্য দিনে 10 ঘন্টা কোড করার পরে বেশিরভাগ সময় পুরোপুরি পাঠযোগ্য

seconds = num_days * HOURS_PER_DAY * MINUTES_PER_HOUR * SECONDS_PER_MINUTE

পড়া অনেক সহজ।

হতাশাহীন উইথফোর্ডস ডিজাইনারের পরামর্শ আরও ভাল:

seconds = num_days * DAYS_TO_SECOND_FACTOR

বা আরও ভাল

seconds = CONVERT_DAYS_TO_SECONDS(num_days)

আপনি খুব ক্লান্ত হয়ে গেলে বিষয়গুলি স্পষ্ট হওয়া বন্ধ করে দেয়। রক্ষণাত্মকভাবে কোড


13
আপনার বর্ণনা মতো ক্রাচ মোডে প্রবেশ করা একটি প্রতিরক্ষামূলক প্রতিরোধক যা এড়ানো উচিত। প্রোগ্রামাররা প্রায় 35-40 ঘন্টা / সপ্তাহে টেকসই উত্পাদনশীলতা পৌঁছে দেয়।
btilly

4
@ তবে আমি আন্তরিকভাবে আপনার সাথে একমত। তবে এটি প্রায়শই বাহ্যিক কারণের কারণে ঘটে।
ভিজিটর পাই

3
আমি দ্বিতীয়, মিনিট, দিন এবং ঘন্টাটির জন্য ধ্রুবককে সাধারণভাবে সংজ্ঞায়িত করি। '30 * MINUTE 'অন্য কিছু যদি না পড়ে সত্যিই সহজ হয় এবং আমি এটি সম্পর্কে চিন্তা না করেই এর একটি সময় জানি।
জাচারি কে

9
@ ব্যাটলি: পিকটি 35-40 ঘন্টা বা রক্তের আলচোহাল স্তর 0.129% থেকে 0.138% এর মধ্যে থাকে। আমি এটি এক্সকেসিডিতে পড়েছি , তাই এটি সত্য হয়ে উঠবে!
অস্টারওয়াল

1
যদি আমি HOURS_PER_DAY এর মতো ধ্রুবক দেখেছি তবে আমি এটি মুছে ফেলব এবং তারপরে প্রকাশ্যে আপনাকে আপনার সমবয়সীদের সামনে অপমান করব। ঠিক আছে, সম্ভবত আমি জনসাধারণের অবমাননা ভুলে যাব তবে আমি সম্ভবত এটি মুছে ফেলব।
এড এস

8

না বলার সময় প্রায় সবসময় is যে সময়গুলিতে আমি কেবল হার্ড-কোডেড নম্বরগুলি ব্যবহার করা আরও সহজ এটি ইউআই লেআউটের মতো জায়গায় - ফর্মের প্রতিটি নিয়ন্ত্রণের অবস্থানের জন্য একটি ধ্রুবক তৈরি করা খুব কিউমারসোন এবং ক্লান্তিকর হয়ে ওঠে এবং যদি সেই কোডটি সাধারণত কোনও ইউআই ডিজাইনার দ্বারা পরিচালিত হয় তবে বেশি কিছু যায় আসে না। ... যদি না ইউআই গতিশীলভাবে তৈরি করা হয়, বা কোনও অ্যাঙ্কারের সাথে সম্পর্কিত অবস্থান ব্যবহার করে বা হাতে লেখা হয় by সেক্ষেত্রে আমি বলব লেআউটটির জন্য কিছু অর্থবহ ধ্রুবক সংজ্ঞায়িত করা আরও ভাল। এবং আপনার কিছু বাছাই করার জন্য যদি এখানে বা সেখানে একটি ফজ ফ্যাক্টরের প্রয়োজন হয় "কিছু ঠিক", এটিও সংজ্ঞায়িত করা উচিত।

তবে আপনার উদাহরণে, আমি মনে করি যে প্রতিস্থাপন 24 * 60 * 60করা DAYS_TO_SECONDS_FACTORআরও ভাল।


আমি স্বীকার করি যে প্রসঙ্গ এবং ব্যবহার পুরোপুরি স্পষ্ট হলে হার্ড-কোডেড মানগুলিও ঠিক আছে। এটি অবশ্য রায় দেওয়ার আহ্বান ...

উদাহরণ:

যেমন @ আরএমএক্স নির্দেশ করেছে, 0 বা 1 ব্যবহার করে কোনও তালিকা খালি আছে কিনা তা পরীক্ষা করতে বা লুপের সীমানায় এমন একটি ক্ষেত্রে উদাহরণ যেখানে ধ্রুবকের উদ্দেশ্যটি খুব পরিষ্কার।


2
এটি সাধারণত ব্যবহার করা ঠিক আছে 0বা 1আমি গণনা করি। if(someList.Count != 0) ...চেয়ে ভাল if(someList.Count != MinListCount) ...। সবসময় না, তবে সাধারণত
কেউ নেই

2
@ ডিমা: ভিএস ফর্ম ডিজাইনার সমস্ত কিছু পরিচালনা করে। এটি যদি ধ্রুবক তৈরি করতে চায় তবে তা আমার পক্ষে ঠিক আছে। তবে আমি উত্পন্ন কোডে যাচ্ছি না এবং সবগুলি হার্ড-কোডেড মানকে ধ্রুবকগুলির সাথে প্রতিস্থাপন করছি।
হতাশিত

4
আসুন কোডটি বিভ্রান্ত না করে এমন একটি সরঞ্জাম দ্বারা উত্পাদিত এবং হ্যান্ডেল হ'ল যদিও মানুষের ব্যবহারের জন্য লিখিত কোড সহ।
বিজাইক্লপ

1
@ বিস্ট্রক্লপ হিসাবে ফ্রেস্ট্রেটড উইথফর্মস ডিজাইনার উল্লেখ করেছেন যে, উত্পন্ন কোড সম্পূর্ণ ভিন্ন প্রাণী। নামযুক্ত ধ্রুবকগুলি অবশ্যই কোডটিতে ব্যবহার করা উচিত যা লোকেদের দ্বারা পড়া এবং সংশোধিত হয়। উত্পাদিত কোড, কমপক্ষে আদর্শের ক্ষেত্রে, একেবারেই সংশোধন করা উচিত নয়।
দিমা

2
@ ফ্রাস্ট্রেটড উইথফর্মস ডিজাইনার: আপনার প্রোগ্রামের কয়েক ডজন ফাইলগুলিতে হঠাৎ বদলাতে হবে এমন একটি মূল্যবান মান হার্ড-কোডড হলে কী হবে? উদাহরণস্বরূপ, আপনি এম্বেড থাকা প্রসেসরের জন্য প্রতি মাইক্রোসেকেন্ডে ক্লক-টিকের সংখ্যার প্রতিনিধিত্ব করে এমন মানটিকে হার্ড-কোড করে তারপরে আপনার সফ্টওয়্যারটিকে এমন ডিজাইনে পোর্ট করতে বলা হয় যেখানে মাইক্রো সেকেন্ডে আলাদা আলাদা ক্লক-টিক থাকে। 8 এর মতো যদি আপনার মানটি কিছু সাধারণ হয়ে থাকে তবে কয়েক ডজন ফাইলে অনুসন্ধান / প্রতিস্থাপন সম্পাদন করা আরও সমস্যার কারণ হতে পারে।
ওস্টারওয়াল

8

যখন আপনি সংখ্যার কোনও অর্থ বা উদ্দেশ্যটি পিন করতে পারবেন না তখন থামুন।

seconds = num_days * HOURS_PER_DAY * MINUTES_PER_HOUR * SECONDS_PER_MINUTE

শুধু সংখ্যা ব্যবহার না করে পড়া অনেক সহজ। (যদিও এটি একটি একক SECONDS_PER_DAYধ্রুবক থাকার দ্বারা আরও পাঠযোগ্য হতে পারে তবে এটি সম্পূর্ণ আলাদা বিষয়।)

অনুমান করুন যে কোনও বিকাশকারী কোডটি দেখছে এটি দেখতে পারে। তবে ধরে নিবেন না যে তারা কেন জানেন। যদি আপনার ধ্রুবক কেন এটি বুঝতে সহায়তা করে তবে এটির জন্য যান। যদি না হয়, না।

যদি আপনি অনেকগুলি ধ্রুবক দিয়ে শেষ করতে চান, যেমন একটি উত্তর দ্বারা প্রস্তাবিত হয়, পরিবর্তে একটি বাহ্যিক কনফিগারেশন ফাইল ব্যবহার করার কথা বিবেচনা করুন, কারণ কোনও ফাইলে কয়েক ডজন ধ্রুবক থাকা পঠনযোগ্যতার উন্নতি করে না।


7

আমি সম্ভবত এই জাতীয় জিনিসগুলিতে "না" বলব:

#define HTML_END_TAG "</html>"

এবং অবশ্যই "না" বলবে:

#define QUADRATIC_DISCRIMINANT_COEF 4
#define QUADRATIC_DENOMINATOR_COEF  2

7

সুস্পষ্ট জিনিসের জন্য ধ্রুবকগুলির ব্যবহারের প্রচারের জন্য আমি যে সর্বোত্তম উদাহরণ পেয়েছি তা HOURS_PER_DAYহ'ল:

আমরা হিসাব করছিলাম কতক্ষণ জিনিসগুলি কোনও ব্যক্তির কাজের সারিতে বসে ছিল। প্রয়োজনীয়তাগুলি শিথিলভাবে সংজ্ঞায়িত করা হয়েছিল এবং প্রোগ্রামার 24বেশ কয়েকটি জায়গায় হার্ড কোডিং করেছিল। অবশেষে আমরা বুঝতে পেরেছিলাম যে 24 ঘন্টা কোনও সমস্যার জন্য বসে থাকার জন্য ব্যবহারকারীদের শাস্তি দেওয়া মোটেও ন্যায়সঙ্গত নয় যখন সত্যিকার অর্থে কেবলমাত্র 8 ঘন্টা কাজ করে। কাজটি যখন এটি ঠিক করতে এসেছিল এবং অন্যান্য প্রতিবেদনগুলির মধ্যে কী একই সমস্যা থাকতে পারে তা দেখুন 24 এর কোডটির মাধ্যমে গ্রেপ করা / অনুসন্ধান করা বেশ কঠিন ছিল তবে গ্রেপ / অনুসন্ধান করা খুব সহজ হত forHOURS_PER_DAY


ওহ, না, তাই আপনি প্রতিদিন কাজের সময় (আমি 7.5 বিটিডাব্লুতে কাজ করি) বা দিনে কয়েক ঘন্টা নির্ধারণ করি কিনা সে অনুযায়ী প্রতিদিনের ঘন্টাগুলি পরিবর্তিত হয়। ধ্রুবকের অর্থের মতো পরিবর্তন করতে আপনি এর নামটি অন্য কোনও জায়গায় প্রতিস্থাপন করতে চান। সহজ অনুসন্ধানের বিষয়ে আপনার বক্তব্যটি বৈধ।
gbjbaanb

2
দেখা যাচ্ছে যে এই ক্ষেত্রে HOURS_PER_DAY আসলেই কাঙ্ক্ষিত ধ্রুবক ছিল না। তবে নাম অনুসারে এটি অনুসন্ধান করতে সক্ষম হওয়া একটি বিশাল সুবিধা, যদিও (বা বিশেষত যদি) আপনার এটি অনেক জায়গায় অন্য কোনও কিছুতে পরিবর্তন করা প্রয়োজন।
ডেভিড কে

4

আমি মনে করি যে যতক্ষণ এই সংখ্যাটি পুরোপুরি ধ্রুবক এবং পরিবর্তনের কোনও সম্ভাবনা নেই, এটি পুরোপুরি গ্রহণযোগ্য। সুতরাং আপনার ক্ষেত্রে, seconds = num_days * 24 * 60 * 60ঠিক আছে (অবশ্যই ধরে নেওয়া যায় যে আপনি কোনও লুপের মধ্যে এই ধরণের গণনা করার মতো নির্বোধ কিছু করেন না) এবং তাত্ক্ষণিকভাবে পাঠযোগ্যতার পক্ষে আরও ভাল seconds = num_days * HOURS_PER_DAY * MINUTES_PER_HOUR * SECONDS_PER_MINUTE

আপনি যখন এমন কাজ করেন তখন এটি খারাপ হয়:

lineOffset += 24; // 24 lines to a page

এমনকি আপনি যদি পৃষ্ঠায় আর লাইন ফিট করতে না পারেন বা এমনকি যদি আপনার এটি পরিবর্তন করার কোনও উদ্দেশ্য না থাকে তবে পরিবর্তে একটি ধ্রুবক পরিবর্তনশীল ব্যবহার করুন, কারণ একদিন এটি আপনাকে ভ্রষ্ট করতে ফিরে আসবে। শেষ পর্যন্ত, বিষয়টি পঠনযোগ্যতা, সিপিইউতে 2 চক্র গণনার সঞ্চয় না করে। এটি আর 1978 নয় যখন মূল্যবান বাইটগুলি তাদের সমস্ত মূল্যের জন্য নিচু করা হয়েছিল।


2
নামী ধ্রুবক SECONDS_PER_DAY ব্যবহার না করে আপনি কি হার্ড-কোড থেকে অপরিবর্তনীয় মান 86400- এর পক্ষে গ্রহণযোগ্য মনে করবেন? আপনি কীভাবে যাচাই করবেন যে মানটির সমস্ত উপস্থিতি সঠিক ছিল এবং একটি 0 অনুপস্থিত বা 6 বিজ্ঞাপন 4 অদলবদল করা হয়নি?
ওস্টারওয়াল

তাহলে কেন নয়: সেকেন্ড = num_days * 86400? সেটিও বদলাবে না।
জেফো

2
নাম ব্যবহার করে এবং নম্বরটি ব্যবহার করে - আমি উভয়ভাবেই SECONDS_PER_DAY কাজটি করেছি। আপনি যখন 2 বছর পরে কোডে ফিরে আসেন, নাম্বার নাম্বারটি সবসময় আরও অর্থবোধ করে।
দ্রুত_নু

2
সেকেন্ড = num_days * 86400 আমার কাছে পরিষ্কার নয়। শেষ পর্যন্ত এটিই গণনা করে। যদি আমি "সেকেন্ড = সংখ্যা_দিন * ২৪ * *০ * ,০" দেখি, পরিবর্তনশীল নামগুলি এই উদাহরণে অর্থটিকে ভালভাবে ধার দেয় তবে আমি তাত্ক্ষণিকভাবে নিজেকে জিজ্ঞাসা করব কেন আমি সেগুলি পৃথক করেছি এবং অর্থটি স্পষ্ট হয়ে যায় কারণ আমি চলে এসেছি এগুলিকে সংখ্যা হিসাবে (তাই তারা অবিচ্ছিন্ন) নয়, ভেরিয়েবল নয় যার কাছে আরও তদন্তের জন্য আমাকে তাদের মানগুলি বুঝতে হবে এবং যদি তারা স্থির থাকে।
নীল

1
লোকেরা প্রায়শই বুঝতে পারে না: আপনি যদি সেই লাইন অফসেট মান 24 থেকে 25 থেকে পরিবর্তন করেন তবে 24 কোথায় ব্যবহার করা হয়েছে এবং যদি এটির পরিবর্তনের প্রয়োজন হয় তা দেখতে আপনার সমস্ত কোডটি দিয়ে যেতে হবে এবং তারপরে সমস্ত দিন কয়েক ঘন্টা গণনা করতে হবে 24 দ্বারা গুণ করা সত্যিই আপনার পথে into ুকুন ।
gnasher729

3
seconds = num_days * 24 * 60 * 60

পুরোপুরি ঠিক আছে। এগুলি আসলে যাদুর সংখ্যা নয় কারণ এগুলি কখনই পরিবর্তন হবে না।

যুক্তিযুক্তভাবে পরিবর্তন করতে পারে বা এর কোন সুস্পষ্ট অর্থ নেই এমন কোনও সংখ্যা ভেরিয়েবলের মধ্যে রাখা উচিত। যার অর্থ বেশ অনেকগুলি।


2
চান seconds = num_days * 86400এখনো গ্রহণযোগ্য হতে পারে? যদি এর মতো মানটি বিভিন্ন ফাইলে একাধিকবার ব্যবহৃত হয়, তবে আপনি কীভাবে যাচাই করবেন যে কেউ দুর্ঘটনাক্রমে seconds = num_days * 84600এক বা দুটি জায়গায় টাইপ করেনি ?
অস্টারওয়াল

1
86400 লেখা লেখার থেকে ভিন্ন 24 * 60 * 60
Carra

4
অবশ্যই এটি পরিবর্তন হবে। প্রতিদিন এর 86,400 সেকেন্ড থাকে না। উদাহরণস্বরূপ, দিবালোক সঞ্চয় সময় বিবেচনা করুন। একবার একটি বছর, কিছু কিছু জায়গায় মাত্র একদিন 23 ঘণ্টা আছে, এবং অন্য দিন তারা 25. থাকবে সমকামী আপনার নম্বর ভাঙা হয়।
ডেভ দেলং

1
@ ডেভ, দুর্দান্ত পয়েন্ট লিপ সেকেন্ড অস্তিত্ব - en.wikipedia.org/wiki/Leap_second

ন্যায্য বিন্দু. কোনও ফাংশন যুক্ত করা একটি সুরক্ষার কাজ হবে যদি আপনার কখনও সেই ব্যতিক্রমগুলি ধরতে হয়।
ক্যাররা

3

আমি একটি ইউনিট থেকে অন্য ইউনিটে রূপান্তর করতে ধ্রুবক (যাদু মান) তৈরি করা এড়াতে চাই। রূপান্তরকরণের ক্ষেত্রে আমি স্পিকিং পদ্ধতির নাম পছন্দ করি। এই উদাহরণে এটি উদাহরণস্বরূপ DayToSeconds(num_days)অভ্যন্তরীণ পদ্ধতিটির যাদু মানগুলির প্রয়োজন নেই কারণ, "24" এবং "60" এর অর্থ পরিষ্কার।

এই ক্ষেত্রে আমি কখনই সেকেন্ড / মিনিট / ঘন্টা ব্যবহার করতাম না। আমি কেবল টাইমস্প্যান / ডেটটাইম ব্যবহার করব।


1

সিদ্ধান্ত নিতে প্যারামিটার হিসাবে প্রসঙ্গ ব্যবহার করুন

উদাহরণস্বরূপ, আপনার কাছে "ক্যালকুলেটসেকেন্ডস বিটউইন: অ্যাডে এবং: আরেকটি ডে" নামে একটি ফাংশন রয়েছে, সেই সংখ্যাগুলি কী করবে সে সম্পর্কে আপনাকে খুব বেশি ব্যাখ্যা করার প্রয়োজন হবে না, কারণ ফাংশনটির নামটি বেশ প্রতিনিধিত্বমূলক।

এবং আরেকটি প্রশ্ন হ'ল, এটি আলাদাভাবে গণনা করার সম্ভাবনাগুলি কোনটি? কখনও কখনও একই জিনিসটি করার প্রচুর উপায় রয়েছে, তাই ভবিষ্যতের প্রোগ্রামারদের গাইড করতে এবং আপনি কোন পদ্ধতিটি ব্যবহার করেছেন তা দেখানোর জন্য, ধ্রুবকগুলির সংজ্ঞা দেওয়া এটি নির্ধারণ করতে সহায়তা করতে পারে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.