Ra

Random মধ্যে Python

{one: "১টি অনুশীলনী", other: "%{count}টি অনুশীলনী"}

Random সম্পর্কে

বাস্তব জগতের ঘটনা সিমুলেট করার জন্য অনেক প্রোগ্রামেরই (আপাতদৃষ্টিতে) র‍্যান্ডম মান দরকার হয়।

কমন ও পরিচিত কিছু উদাহরণ:

  • একটি কয়েন টস: ('Heads', 'Tails') থেকে একটি র‍্যান্ডম মান।
  • একটি পাশা গড়ানো: ১ থেকে ৬-এর মধ্যে একটি র‍্যান্ডম ইন্টিজার।
  • তাসের একটি ডেক শাফল করা: কার্ডের একটি অ্যারের র‍্যান্ডম ক্রম।

কম্পিউটার দিয়ে সত্যিকারের র‍্যান্ডম মান তৈরি করা একটি অবাক করার মতো কঠিন কারিগরি চ্যালেঞ্জ, তাই এই ফলাফলগুলোকে "সিউডোর‍্যান্ডম" বলা হতে পারে।

বাস্তবে, Python-এর স্ট্যান্ডার্ড লাইব্রেরির random মডিউলের মতো ভালোভাবে ডিজাইন করা একটি লাইব্রেরি দ্রুত, নমনীয়, এবং মডেলিং, সিমুলেশন ও গেমে বেশিরভাগ প্রয়োগের জন্যই যথেষ্ট ভালো ফলাফল দেয়।

এই পেজের বাকি অংশে random-এর সবচেয়ে কমন কয়েকটি ফাংশনের তালিকা দেওয়া হবে। আমরা আপনাকে random-এর সম্পূর্ণ ডকুমেন্টেশন ঘেঁটে দেখার জন্য উৎসাহ দিচ্ছি, কারণ এখানে আমরা যেগুলো নিয়ে আলোচনা করছি তার চেয়ে অনেক বেশি অপশন রয়েছে।

Caution

নিরাপত্তা বা ক্রিপ্টোগ্রাফিক কাজে random মডিউল কখনোই ব্যবহার করা উচিত নয়।

এর বদলে Python secrets মডিউলটি দেয়। এটি বিশেষভাবে ক্রিপ্টোগ্রাফিক নিরাপত্তার জন্য অপ্টিমাইজ করা হয়েছে। secrets মডিউল তৈরি করার পেছনের কিছু পূর্ববর্তী সমস্যা ও কারণ PEP 506-এ পাওয়া যাবে।

ইমপোর্ট করা

random মডিউলের টুলগুলো ব্যবহার করার আগে, আপনাকে প্রথমে এটি ইমপোর্ট করতে হবে:

>>> import random

# Choose random integer from a range
>>> random.randrange(1000)
360

>>> random.randrange(-1, 500)
228

>>> random.randrange(-10, 11, 2)
-8

# Choose random integer between two values (inclusive)
>>> random.randint(5, 25)
22

মডিউলের নাম বারবার টাইপ করা এড়াতে, আপনি নাম ধরে নির্দিষ্ট ফাংশন ইমপোর্ট করতে পারেন:

>>> from random import choice, choices

# Using choice() to pick Heads or Tails 10 times
>>> tosses = []
... for side in range(10):
...    tosses.append(choice(['H', 'T']))    

>>> print(tosses)
['H', 'H', 'H', 'H', 'H', 'H', 'H', 'T', 'T', 'H']


# Using choices() to pick Heads or Tails 8 times
>>> picks = []
... picks.extend(choices(['H', 'T'], k=8))
... print(picks)
['T', 'H', 'H', 'T', 'H', 'H', 'T', 'T']

র‍্যান্ডম ইন্টিজার তৈরি করা

randrange() ফাংশনের তিনটি রূপ আছে, range(start, stop, step) থেকে একটি র‍্যান্ডম মান বাছাই করার জন্য:

  1. randrange(stop) এমন একটি ইন্টিজার n দেয় যেখানে 0 <= n < stop
  2. randrange(start, stop) এমন একটি ইন্টিজার n দেয় যেখানে start <= n < stop
  3. randrange(start, stop, step) এমন একটি ইন্টিজার n দেয় যেখানে start <= n < stop এবং n হলো start, start + step, start + 2*step... সিকোয়েন্সের একটি সদস্য

step == 1 এমন কমন ক্ষেত্রে, randint(a, b) ফাংশনটি আরও সুবিধাজনক ও পাঠযোগ্য হতে পারে। randint()-এর সম্ভাব্য ফলাফলে উপরের সীমাটিও অন্তর্ভুক্ত, তাই randint(a, b) ব্যবহার করা randrange(a, b+1) ব্যবহারের সমান:

>>> import random

# Select one number at random from the range 0, 499
>>> random.randrange(500)
219

# Select 10 numbers at random between 0 and 9 two steps apart.
>>> numbers = []
... for integer in range(10):
...    numbers.append(random.randrange(0, 10, 2))

>>> print(numbers)
[2, 8, 4, 0, 4, 2, 6, 6, 8, 8]

# roll a die
>>> random.randint(1, 6)  
4

সিকোয়েন্স নিয়ে কাজ করা

এই অংশের ফাংশনগুলো ধরে নেয় যে আপনি কোনো সিকোয়েন্স বা অন্য কোনো কন্টেইনার থেকে শুরু করছেন।

এটি সাধারণত একটি list হয়, বা কিছু সীমাবদ্ধতা নিয়ে একটি tuple কিংবা set (একটি tuple ইমিউটেবল, আর set আনঅর্ডারড)।

choice() এবং choices()

choice() ফাংশন একটি নির্দিষ্ট সিকোয়েন্স থেকে র‍্যান্ডমভাবে বাছাই করা একটি এলিমেন্ট রিটার্ন করে। একেবারে সহজ উদাহরণে এটি হতে পারে একটি কয়েন টস:

# This will pick one of the two values in the list at random 5 separate times 
>>> [random.choice(['H', 'T']) for _ in range(5)]
['T', 'H', 'H', 'T', 'H']

choices() ফাংশন ব্যবহার করে আমরা মূলত একই কাজ করতে পারি, যেখানে অ্যারের দৈর্ঘ্যসহ একটি কিওয়ার্ড আর্গুমেন্ট দিতে হয়:

>>> random.choices(['H', 'T'], k=5)
['T', 'H', 'T', 'H', 'H']

উপরের উদাহরণগুলোতে আমরা ধরে নিয়েছিলাম একটি ন্যায্য কয়েন, যেখানে হেডস বা টেইলসের সম্ভাবনা সমান, কিন্তু ওয়েটও নির্দিষ্ট করা যায়। উদাহরণস্বরূপ, যদি একটি ব্যাগে ১০টি লাল বল আর ১৫টি সবুজ বল থাকে, এবং আমরা র‍্যান্ডমভাবে একটি বের করতে চাই:

>>> random.choices(['red', 'green'], [10, 15])
['red']

sample()

উপরের choices() উদাহরণটি ধরে নেয় যা পরিসংখ্যানবিদেরা "রিপ্লেসমেন্টসহ স্যাম্পলিং" বলেন। প্রতিটি বাছাই বা পছন্দ ভবিষ্যতের পছন্দের সম্ভাবনার উপর কোনো প্রভাব ফেলে না, এবং সম্ভাব্য পছন্দগুলোর ডিস্ট্রিবিউশন বাছাই থেকে বাছাইয়ে একই থাকে।

লাল ও সবুজ বলের উদাহরণে: প্রতিটি বাছাইয়ের পর আমরা বলটি ব্যাগে ফিরিয়ে দিই এবং পরের বাছাইয়ের আগে ভালোভাবে ঝাঁকিয়ে নিই। এটি এমন পরিস্থিতির বিপরীত যেখানে আমরা একটি লাল বল বের করে আনি এবং সেটি আর ফেরত দেওয়া হয় না। বলটি ফেরত না দেওয়ার অর্থ হলো ব্যাগে এখন কম লাল বল আছে, এবং পরের বাছাইটি লাল হওয়ার সম্ভাবনা এখন কম।

এই "রিপ্লেসমেন্ট ছাড়া স্যাম্পলিং" সিমুলেট করতে, random মডিউল sample() ফাংশনটি দেয়। sample()-এর সিনট্যাক্স choices()-এর মতোই, শুধু এটি একটি counts কিওয়ার্ড প্যারামিটার যোগ করে:

>>> random.sample(['red', 'green'], counts=[10, 15], k=10)
['green', 'green', 'green', 'green', 'green', 'red', 'red', 'red', 'red', 'green']

স্যাম্পলগুলো যেই ক্রমে বাছাই করা হয়েছে সেই ক্রমেই রিটার্ন করা হয়।

shuffle()

k > 1 হলে choices() ও sample() দুটোই নতুন অ্যারে রিটার্ন করে। এর বিপরীতে, shuffle() একটি অ্যারের ক্রম ইন-প্লেস এলোমেলো করে দেয়, আর আগের ক্রম হারিয়ে যায়:

>>> my_list = [1, 2, 3, 4, 5]
>>> random.shuffle(my_list)
>>> my_list
[4, 1, 5, 2, 3]

ডিস্ট্রিবিউশন নিয়ে কাজ করা

এখন পর্যন্ত আমরা এমন সব ক্ষেত্রে মন দিয়েছি যেখানে সব ফলাফলের সম্ভাবনা সমান। উদাহরণস্বরূপ, random.randrange(100) ০ থেকে ৯৯-এর যেকোনো ইন্টিজার সমান সম্ভাবনায় দিতে পারে।

বাস্তব জগতের অনেক পরিস্থিতিই এর চেয়ে অনেক বেশি জটিল। ফলে, পরিসংখ্যানবিদেরা "বাস্তব জগতের" ফলাফল গাণিতিকভাবে বর্ণনা করার জন্য নানা রকম distributions তৈরি করেছেন।

ইউনিফর্ম ডিস্ট্রিবিউশন

ইন্টিজারের ক্ষেত্রে, সব সম্ভাবনা সমান হলে randrange() ও randint() ব্যবহার করা হয়। একে uniform ডিস্ট্রিবিউশন বলা হয়।

randrange() ও randint()-এর ফ্লোটিং-পয়েন্ট সমতুল্যও আছে।

random() এমন একটি float মান x দেয় যেখানে 0.0 <= x < 1.0।

uniform(a, b) এমন x দেয় যেখানে a <= x <= b।

>>> [round(random.random(), 3) for _ in range(5)]
[0.876, 0.084, 0.483, 0.22, 0.863]

>>> [round(random.uniform(2, 5), 3) for _ in range(5)]
[2.798, 2.539, 3.779, 3.363, 4.33]

গাউসিয়ান ডিস্ট্রিবিউশন

একে "নরমাল" ডিস্ট্রিবিউশন বা "বেল-শেপড" কার্ভও বলা হয়, এটি মাপা মানের অসূক্ষ্মতা বর্ণনা করার একটি খুবই কমন উপায়।

উদাহরণস্বরূপ, ধরে নিন আপনার কাজের কারখানায় এইমাত্র ১০,০০০ বোল্ট কেনা হয়েছে, যেগুলো একই রকম হওয়ার কথা। সেগুলো ধরার জন্য আপনি কারখানার রোবট সেট আপ করতে চান, তাই ১০০টির একটি স্যাম্পল ওজন করে দেখলেন তাদের গড় (বা mean) ওজন ৪.৭৩১g। এর মানে এই হওয়ার সম্ভাবনা অত্যন্ত কম যে তাদের সবার ওজন ঠিক ৪.৭৩১g। হয়তো দেখলেন মানগুলো ৪.৬২৭ থেকে ৪.৭৯৪g পর্যন্ত ছড়িয়ে আছে, কিন্তু ৪.৭৩১g-এর আশপাশে জড়ো হয়েছে।

এটিই Gaussian distribution, যেখানে সম্ভাবনা গড়ের কাছে সর্বোচ্চ হয় এবং দুই দিকে সমানভাবে কমতে থাকে (তাই "বেল-শেপড")। সফটওয়্যারে এটি সিমুলেট করতে, আমাদের কার্ভটির প্রস্থ নির্দিষ্ট করার কিছু উপায় দরকার (সাধারণত দামি বোল্টগুলো সস্তা বোল্টের চেয়ে গড়ের চারপাশে বেশি করে জড়ো হয়!)。

প্রথা অনুযায়ী এটি করা হয় standard deviation দিয়ে: ছোট মান মানে তীক্ষ্ণ, সংকীর্ণ কার্ভ; বড় মান মানে নিচু, প্রশস্ত কার্ভ। গণিতবিদেরা গ্রিক অক্ষর ভালোবাসেন, তাই আমরা গড় বোঝাতে μ ('mu') এবং স্ট্যান্ডার্ড ডেভিয়েশন বোঝাতে σ ('sigma') ব্যবহার করি। তাই, যদি পড়েন যে "৯৫% মান μ-এর ২σ-এর মধ্যে থাকে" বা "৫-সিগমা কনফিডেন্সে হিগস বোসন শনাক্ত করা গেছে", তাহলে এমন মন্তব্য স্ট্যান্ডার্ড ডেভিয়েশনের সাথে সম্পর্কিত।

>>> mu = 4.731
>>> sigma = 0.316
>>> [round(random.gauss(mu, sigma), 3) for _ in range(5)]
[4.72, 4.957, 4.64, 4.556, 4.968]
GitHub-এর মাধ্যমে সম্পাদনা করুন লিংকটি নতুন একটি উইন্ডো বা ট্যাবে খুলবে