স্ট্যান্ডার্ড লাইব্রেরিতে কেন কোনও ফ্লোটিং পয়েন্ট রেঞ্জ বাস্তবায়ন নেই?
যেমনটি এখানে সমস্ত পোস্ট দ্বারা পরিষ্কার করা হয়েছে, এর কোনও ভাসমান পয়েন্ট সংস্করণ নেই range()
। তাই বলা হয়, ভ্রান্তি যদি আমরা বিবেচনা যে অর্থে তোলে range()
ফাংশন প্রায়ই (এবং অবশ্যই, তার মানে একটি একটি সূচক হিসেবে ব্যবহার করা হয় অ্যাকসেসর ) জেনারেটর। সুতরাং, আমরা যখন কল করি তখন আমরা range(0,40)
কার্যকরভাবে বলব যে আমরা 40 টির মান 0 থেকে শুরু করে 40 পর্যন্ত, তবে 40 এর মধ্যে অন্তর্ভুক্ত নয়।
যখন আমরা বিবেচনা করি যে সূচক প্রজন্ম সূচকের সংখ্যাটি যতটা তার মান হিসাবে তত পরিমাণে range()
হয় তবে স্ট্যান্ডার্ড লাইব্রেরিতে ভাসমান প্রয়োগের ব্যবহারটি কম বোঝায়। উদাহরণস্বরূপ, আমরা যদি ফাংশনটি কল frange(0, 10, 0.25)
করি তবে আমরা 0 এবং 10 উভয়ই অন্তর্ভুক্ত করার প্রত্যাশা করব, তবে এটি 41 মান সহ একটি ভেক্টর অর্জন করবে।
সুতরাং, কোনও frange()
ফাংশন তার ব্যবহারের উপর নির্ভর করে সর্বদা স্বাক্ষরিত আচরণের পাল্টা প্রদর্শন করবে; সূচকের দৃষ্টিকোণ থেকে এটির অনেকগুলি মান রয়েছে যা গণিতের দৃষ্টিকোণ থেকে যুক্তিসঙ্গতভাবে ফিরে আসা উচিত a
গাণিতিক ব্যবহারের কেস
যা বলা হয়েছে, আলোচিত হিসাবে, numpy.linspace()
প্রজন্মকে গাণিতিক দৃষ্টিকোণ দিয়ে দুর্দান্তভাবে সম্পাদন করে:
numpy.linspace(0, 10, 41)
array([ 0. , 0.25, 0.5 , 0.75, 1. , 1.25, 1.5 , 1.75,
2. , 2.25, 2.5 , 2.75, 3. , 3.25, 3.5 , 3.75,
4. , 4.25, 4.5 , 4.75, 5. , 5.25, 5.5 , 5.75,
6. , 6.25, 6.5 , 6.75, 7. , 7.25, 7.5 , 7.75,
8. , 8.25, 8.5 , 8.75, 9. , 9.25, 9.5 , 9.75, 10.
])
সূচক ব্যবহারের কেস
এবং ইনডেক্সিং দৃষ্টিকোণের জন্য, আমি কিছু কৌশলযুক্ত স্ট্রিং ম্যাজিকের সাথে কিছুটা ভিন্ন পদ্ধতি লিখেছি যা আমাদের দশমিক জায়গাগুলির সংখ্যা নির্দিষ্ট করতে দেয়।
# Float range function - string formatting method
def frange_S (start, stop, skip = 1.0, decimals = 2):
for i in range(int(start / skip), int(stop / skip)):
yield float(("%0." + str(decimals) + "f") % (i * skip))
একইভাবে, আমরা অন্তর্নির্মিত round
ফাংশনটিও ব্যবহার করতে পারি এবং দশমিকের সংখ্যা নির্দিষ্ট করতে পারি:
# Float range function - rounding method
def frange_R (start, stop, skip = 1.0, decimals = 2):
for i in range(int(start / skip), int(stop / skip)):
yield round(i * skip, ndigits = decimals)
একটি দ্রুত তুলনা এবং পারফরম্যান্স
অবশ্যই, উপরের আলোচনাটি প্রদত্ত, এই ক্রিয়াকলাপগুলিতে মোটামুটি সীমিত ব্যবহারের কেস রয়েছে। তবুও, এখানে একটি দ্রুত তুলনা করা হয়েছে:
def compare_methods (start, stop, skip):
string_test = frange_S(start, stop, skip)
round_test = frange_R(start, stop, skip)
for s, r in zip(string_test, round_test):
print(s, r)
compare_methods(-2, 10, 1/3)
ফলাফল প্রতিটি জন্য অভিন্ন:
-2.0 -2.0
-1.67 -1.67
-1.33 -1.33
-1.0 -1.0
-0.67 -0.67
-0.33 -0.33
0.0 0.0
...
8.0 8.0
8.33 8.33
8.67 8.67
9.0 9.0
9.33 9.33
9.67 9.67
এবং কিছু সময়:
>>> import timeit
>>> setup = """
... def frange_s (start, stop, skip = 1.0, decimals = 2):
... for i in range(int(start / skip), int(stop / skip)):
... yield float(("%0." + str(decimals) + "f") % (i * skip))
... def frange_r (start, stop, skip = 1.0, decimals = 2):
... for i in range(int(start / skip), int(stop / skip)):
... yield round(i * skip, ndigits = decimals)
... start, stop, skip = -1, 8, 1/3
... """
>>> min(timeit.Timer('string_test = frange_s(start, stop, skip); [x for x in string_test]', setup=setup).repeat(30, 1000))
0.024284090992296115
>>> min(timeit.Timer('round_test = frange_r(start, stop, skip); [x for x in round_test]', setup=setup).repeat(30, 1000))
0.025324633985292166
মনে হচ্ছে স্ট্রিং ফর্ম্যাটিং পদ্ধতিটি আমার সিস্টেমে চুল দ্বারা জিতল।
সীমাবদ্ধতা
এবং শেষ অবধি, উপরের আলোচনা থেকে একটি পয়েন্ট প্রদর্শন এবং একটি শেষ সীমাবদ্ধতা:
# "Missing" the last value (10.0)
for x in frange_R(0, 10, 0.25):
print(x)
0.25
0.5
0.75
1.0
...
9.0
9.25
9.5
9.75
তদ্ব্যতীত, skip
প্যারামিটারটি যখন stop
মান দ্বারা বিভাজ্য না হয়, তবে পরবর্তী ইস্যুটি প্রদত্ত একটি ওয়াঙ্কিং ফাঁক থাকতে পারে:
# Clearly we know that 10 - 9.43 is equal to 0.57
for x in frange_R(0, 10, 3/7):
print(x)
0.0
0.43
0.86
1.29
...
8.14
8.57
9.0
9.43
এই সমস্যাটি সমাধান করার জন্য কয়েকটি উপায় রয়েছে তবে দিনের শেষে, সেরা নমুনাটি সম্ভবত নম্পিকে ব্যবহার করা হবে।