টাকা, তা যে মুদ্রায়ই থাকুক না কেন, মনে হয় একটি ফ্লোটিং-পয়েন্ট নম্বর। কিন্তু মুদ্রার জন্য ফ্লোট ব্যবহার করা একটি ভুল।
ফ্লোট নম্বর (অতএব, ফ্লোট অবজেক্ট) হল, সংজ্ঞা অনুসারে, অযৌক্তিক বাস্তব সংখ্যা যা স্থানীয় স্থাপত্যের বৈশিষ্ট্যযুক্ত দ্বিগুণ-নির্ভুলতা ভাসমান-বিন্দু উপস্থাপনা ব্যবহার করে। সঠিক সংখ্যা হিসাবরক্ষকদের অসন্তুষ্ট করে।
এই নিবন্ধে, আপনাকে কিছু দ্রুত উদাহরণের মাধ্যমে নির্দেশিত করা হবে যা আপনাকে রুবি এবং রেলে অর্থের ডেটা নিয়ে কাজ করার জন্য উপলব্ধ বিকল্পগুলি সমাধান করতে সাহায্য করবে৷
ফ্লোট কি?
আমরা যেমন বলেছি, float
বস্তুর বিভিন্ন পাটিগণিত আছে। এটি মূল কারণ যে তারা সঠিক সংখ্যা, বিশেষ করে রুবি (অধিকাংশ ভাষার মতো) ফ্লোটগুলিকে প্রতিনিধিত্ব করতে একটি নির্দিষ্ট সংখ্যক বাইনারি সংখ্যা ব্যবহার করে। অন্য কথায়, রুবি ভাসমান সংখ্যাকে দশমিক থেকে বাইনারিতে রূপান্তর করে এবং এর বিপরীতে।
আপনি যখন বাস্তব সংখ্যার (ওরফে দশমিক সংখ্যা) বাইনারি প্রতিনিধিত্বের গভীরে ডুব দেন, তখন তাদের মধ্যে কিছুকে সঠিকভাবে উপস্থাপন করা যায় না, তাই সিস্টেমের জন্য একমাত্র অবশিষ্ট বিকল্প হল তাদের বৃত্তাকার করা।
আপনি যদি সামনের দিকে চিন্তা করেন এবং সাধারণ গণিত কাঠামোগুলি বিবেচনা করেন, যেমন পর্যায়ক্রমিক দশমাংশ, আপনি বুঝতে পারেন যে pi থেকে এগুলি একটি নির্দিষ্ট সংখ্যার মধ্যে সম্পূর্ণরূপে উপস্থাপন করা যাবে না। সংখ্যা, উদাহরণস্বরূপ, অসীম। ফ্লোটগুলি সাধারণত 32 বা 64 বিট পর্যন্ত নির্ভুলতা ধরে রাখতে পারে, যার অর্থ সীমাতে পৌঁছালে সংখ্যাটি কেটে যাবে৷
আসুন একটি ক্লাসিক উদাহরণ বিশ্লেষণ করি:
1200 * (14.0/100)
এটি একটি সংখ্যার শতাংশ গণনা করার একটি সহজ উপায়। 1200 এর চৌদ্দ শতাংশ হতে হবে 168; যাইহোক, রুবির মধ্যে এই মৃত্যুদন্ডের ফলাফল হবে
1200 * (14.0/100)
=> 168.00000000000003
যাইহোক, যদি আপনি সূত্রে মাত্র 0.1% যোগ করেন, আপনি ভিন্ন কিছু পাবেন:
1200 * (14.1/100)
=> 169.2
বিকল্পভাবে, আপনি round
করতে পারেন সম্ভাব্য নিকটতম একটি মান, কত দশমিক স্থান কাঙ্ক্ষিত তা নির্ধারণ করে:
(my_calculation).round(2)
প্রকৃতপক্ষে, আরও জটিল গণনার ক্ষেত্রে এটি নিশ্চিত করা যায় না, বিশেষ করে যদি আপনি এই মানগুলির তুলনা করেন৷
আপনি যদি এর পেছনের প্রকৃত বিজ্ঞান বুঝতে আগ্রহী হন, তাহলে আমি ওরাকলের পরিশিষ্টটি পড়ার সুপারিশ করছি:ফ্লোটিং-পয়েন্ট পাটিগণিত সম্পর্কে প্রত্যেক কম্পিউটার বিজ্ঞানীর কী জানা উচিত। এটি ব্যাখ্যা করে, বিস্তারিতভাবে, ফ্লোট সংখ্যার ভুল প্রকৃতির পিছনের কারণগুলি৷
বিশ্বস্ত বিগডেসিমাল
নিম্নলিখিত কোড স্নিপেট বিবেচনা করুন:
require "bigdecimal"
BigDecimal("45.99")
এই কোডটি সহজেই একটি ইকমার্স কার্টের পরিমাণকে আলিঙ্গন করে একটি বাস্তব যুক্তি উপস্থাপন করতে পারে। শেষ পর্যন্ত, বাস্তব মান সর্বদা 45.9989 বা 45.99000009 এর পরিবর্তে 45.99 হবে, উদাহরণস্বরূপ।
এটি BigDecimal
এর সুনির্দিষ্ট প্রকৃতি . সাধারণ পাটিগণিত গণনার জন্য, float
একই ভাবে কাজ করবে; যাইহোক, এটি অপ্রত্যাশিত, যা এটি ব্যবহার করার বিপদ।
যখন এটি BigDecimal
দিয়ে চালানো হয় , একই শতাংশ গণনা আমরা পূর্ববর্তী বিভাগে ফলাফল
require "bigdecimal"
(BigDecimal(1200) * (BigDecimal(14)/BigDecimal(100))).to_s("F")
=> 168.0
এটি একটি irb-এ দ্রুত কার্যকর করার অনুমতি দেওয়ার জন্য একটি সংক্ষিপ্ত সংস্করণ কনসোল।
মূলত, যখন আপনি সরাসরি BigDecimal
প্রিন্ট করেন বস্তু, আপনি এর বৈজ্ঞানিক স্বরলিপি পাবেন, যা আমরা এখানে চাই না। to_s
মেথড ফরম্যাটিং সেটিংসের কারণে প্রদত্ত আর্গুমেন্ট গ্রহণ করে এবং BigDecimal এর সমতুল্য ভাসমান মান প্রদর্শন করে। এই বিষয়ে আরও বিশদ বিবরণের জন্য, রুবি ডক্স দেখুন৷
আপনি যদি দশমিক স্থানের জন্য একটি সীমা নির্ধারণ করতে চান, এতে truncate
আছে পদ্ধতি, যা আপনার জন্য কাজ করবে:
(BigDecimal(1200) * (BigDecimal("14.12")/BigDecimal(100))).truncate(2).to_s("F")
=> 169.44
রুবিমানি প্রকল্প
এসব সমস্যার কথা চিন্তা করেই তৈরি করা হয়েছে রুবিমানি। এটি রুবি ডেভেলপারদের একটি ওপেন-সোর্স সম্প্রদায় যার লক্ষ্য রুবি ইকোসিস্টেমে অর্থের ডেটা ম্যানিপুলেট করার জন্য দুর্দান্ত লাইব্রেরি প্রদান করে বিকাশকারীদের জীবনকে সহজতর করা।
প্রকল্পটি সাতটি লাইব্রেরি নিয়ে গঠিত, যার মধ্যে তিনটি গুরুত্বপূর্ণ:
- টাকা:টাকা এবং মুদ্রা রূপান্তর নিয়ে কাজ করার জন্য একটি রুবি লাইব্রেরি। এটি ওয়েবের জন্য হোক না কেন, মজবুত এবং আধুনিক অ্যাপ্লিকেশনগুলিতে অর্থ পরিচালনা করার জন্য বেশ কয়েকটি বস্তু-ভিত্তিক বিকল্প সরবরাহ করে৷
- মানি-রেল:সমস্ত
money
মিশ্রিত করে রুবি অন রেলের জন্য RubyMoney-এর একটি ইন্টিগ্রেশন রেলের নমনীয়তার সাথে এর লাইব্রেরি শক্তি। - মনিটাইজ:বিভিন্ন বস্তুকে
money
-এ রূপান্তর করার জন্য একটি লাইব্রেরি বস্তু এটি এমন অ্যাপ্লিকেশনগুলির জন্য একটি সহায়ক লাইব্রেরির মতো কাজ করে যা অনেকগুলি স্ট্রিং পার্সিং নিয়ে কাজ করে, উদাহরণস্বরূপ৷
প্রকল্পটিতে আরও চারটি আকর্ষণীয় লাইব্রেরি রয়েছে:
- EU_central_bank:একটি লাইব্রেরি যা ইউরোপীয় কেন্দ্রীয় ব্যাংক থেকে প্রকাশিত হার ব্যবহার করে বিনিময় হার গণনা করতে সাহায্য করে।
- Google_currency:একটি রেফারেন্স হিসাবে Google মুদ্রার হার ব্যবহার করে মুদ্রা রূপান্তরের জন্য একটি আকর্ষণীয় লাইব্রেরি।
- অর্থ-সংগ্রহ:
money
যোগফল/মিনিট/সর্বোচ্চ নির্ভুলভাবে গণনা করার জন্য একটি সহায়ক গ্রন্থাগার বস্তু। - মানি-হিউরিস্টিকস:মানি জেমের জন্য স্ট্রিং ইনপুটের হিউরিস্টিক বিশ্লেষণের জন্য একটি মডিউল।
"মানি" রত্ন
সবচেয়ে বিখ্যাত দিয়ে শুরু করা যাক:অর্থ রত্ন। এর প্রধান বৈশিষ্ট্যগুলির মধ্যে নিম্নলিখিতগুলি হল:
- একটি
money
যে শ্রেণীতে প্রাসঙ্গিক আর্থিক তথ্য থাকে, যেমন মান, মুদ্রা এবং দশমিক চিহ্ন। - আরেকটি ক্লাস যাকে বলা হয়
Money::Currency
যা বিকাশকারীর দ্বারা ব্যবহৃত আর্থিক ইউনিট সম্পর্কিত তথ্য মোড়ানো হয়। - ডিফল্টরূপে, এটি পূর্বোক্ত ত্রুটিগুলি এড়াতে ভাসমান-বিন্দু সংখ্যার পরিবর্তে পূর্ণসংখ্যার সাথে কাজ করে৷
- এক মুদ্রা থেকে অন্য মুদ্রায় অর্থ বিনিময় করার ক্ষমতা, যা অত্যন্ত দুর্দান্ত।
তা ছাড়া, আমরা আপনার প্রকল্পের মধ্যে অন্য যেকোন মডেলের মতোই অর্থের ডেটা ম্যানিপুলেট করার জন্য সামঞ্জস্যপূর্ণ এবং অবজেক্ট-ওরিয়েন্টেড কাঠামোর দ্বারা অফার করা উচ্চ নমনীয়তাও পাই৷
এর ব্যবহার বেশ সহজ, শুধু সঠিক রত্নটি ইনস্টল করুন:
gem install money
একটি নির্দিষ্ট পরিমাণ অর্থ জড়িত একটি দ্রুত উদাহরণ হবে
my_money = Money.new(1200, "USD")
my_money.cents #=> 1200
my_money.currency #=> Currency.new("USD")
আপনি দেখতে পাচ্ছেন, অর্থ সেন্টের উপর ভিত্তি করে উপস্থাপন করা হয়। বারো শত সেন্ট 12 ডলারের সমতুল্য।
ঠিক যেমন আপনি BigDecimal এর সাথে করেছেন, আপনিও এই বস্তুগুলির সাথে কিছু মৌলিক গণিত করতে পারেন। উদাহরণস্বরূপ,
cart_amount = Money.new(10000, "USD") #=> 100 USD
discount = Money.new(1000, "USD") #=> 10 USD
cart_amount - discount == Money.new(9000, "USD") #=> 90 USD
আকর্ষণীয়, তাই না? এটি আমরা উল্লেখ করা বস্তুর প্রকৃতি। কোডিং করার সময়, সত্যিই মনে হয় আপনি অব্যক্ত এবং সাধারণ সংখ্যার পরিবর্তে আর্থিক মানগুলিকে কাজে লাগাচ্ছেন৷
মুদ্রা রূপান্তর
যদি আপনার নিজের এক্সচেঞ্জ রেট সিস্টেম থাকে তবে আপনি একটি এক্সচেঞ্জ ব্যাঙ্ক অবজেক্টের মাধ্যমে মুদ্রা রূপান্তর করতে পারেন। নিম্নলিখিত বিবেচনা করুন:
Money.add_rate("USD", "BRL", 5.23995)
Money.add_rate("BRL", "USD", 0.19111)
যখনই আপনি তাদের মধ্যে মান বিনিময় করতে চান, আপনি নিম্নলিখিত কোডটি চালাতে পারেন:
Money.us_dollar(100).exchange_to("BRL") #=> Money.new(523, "BRL")
আপনি যে কোন পাটিগণিত এবং তুলনামূলক মূল্যায়ন করতে চান তার ক্ষেত্রেও এটি প্রযোজ্য।
iso_code
এর মতো আরও প্রদত্ত মুদ্রার গুণাবলীর জন্য ডক্স উল্লেখ করতে ভুলবেন না (যা সেই মুদ্রার আন্তর্জাতিক তিন-সংখ্যার কোড প্রদান করে) এবং decimal_mark
(মান এবং অর্থ ডেটার ভগ্নাংশের মধ্যে অক্ষর), অন্যদের মধ্যে।
ওহ, আমি প্রায় ভুলে গিয়েছিলাম; একবার আপনি অর্থ রত্ন ইনস্টল করার পরে, আপনি একটি BigDecimal
অ্যাক্সেস করতে পারেন to_money
নামক পদ্ধতি যা স্বয়ংক্রিয়ভাবে আপনার জন্য রূপান্তর সম্পাদন করে।
"মনিটাইজ" রত্ন
RubyMoney প্রকল্পের মধ্যে প্রতিটি লাইব্রেরি কী ভূমিকা পালন করে তা বোঝা গুরুত্বপূর্ণ। যখনই আপনাকে একটি ভিন্ন রুবি বস্তু রূপান্তর করতে হবে (একটি String
, উদাহরণস্বরূপ) Money
এ , তারপর monetize
আপনি যা খুঁজছেন তা।
প্রথমে, রত্ন নির্ভরতা ইনস্টল করা বা আপনার Gemfile-এ যোগ করা নিশ্চিত করুন :
gem install monetize
স্পষ্টতই, money
এছাড়াও ইনস্টল করা প্রয়োজন৷
parse
আপনি যখন একটি ভিন্ন বিন্যাসে অর্থের ডেটা পান তখন পদ্ধতিটিও খুব দরকারী; উদাহরণস্বরূপ,
Money.parse("£100") == Money.new(100, "GBP") #=> true
যদিও আপনি যে পরিস্থিতিতে এই পার্সিং পদ্ধতিটি ব্যবহার করবেন সেগুলি সীমাবদ্ধ, এটি খুব কার্যকর হতে পারে যখন আপনি একটি HTTP অনুরোধ থেকে এর মুদ্রা কোডের সাথে ফর্ম্যাট করা একটি মান পান। ওয়েবে, সবকিছুই পাঠ্য, তাই স্ট্রিং থেকে money
-এ রূপান্তর করা হচ্ছে খুব দরকারী হতে পারে।
যাইহোক, আপনার সিস্টেম কীভাবে মানগুলিকে ম্যানিপুলেট করে এবং সেগুলিকে কোনওভাবে হ্যাক করা যায় কিনা সে বিষয়ে সতর্ক থাকুন। আপনি যে মানটি পাচ্ছেন তা সেই লেনদেনের আসল মূল্য তা নিশ্চিত করতে আর্থিক সিস্টেমগুলি সর্বদা একাধিক সুরক্ষা স্তর দ্বারা আবৃত থাকে৷
"মনিটাইজ-রেল" রত্ন
এটি এমন একটি লাইব্রেরি যা একই অর্থ ম্যানিপুলেশন অপারেশনগুলি নিয়ে কাজ করে, তবে একটি রেল অ্যাপের মধ্যে৷
রেলের পাশাপাশি এটি কাজ করার জন্য আমাদের কেন একটি দ্বিতীয় লাইব্রেরি দরকার? ঠিক আছে, আপনি অবশ্যই money
ব্যবহার করতে পারেন সাধারণ গণিত ক্রিয়াকলাপের জন্য রেল প্রকল্পের মধ্যে একা মণি। যাইহোক, যখন আপনার রেল স্ট্রাকচারগুলিকে money
এর সাথে যোগাযোগ করতে হবে তখন এটি সঠিকভাবে কাজ করবে না এর বৈশিষ্ট্য।
নিম্নলিখিত উদাহরণ বিবেচনা করুন:
class Cart < ActiveRecord::Base
monetize :amount_cents
end
এটি একটি বাস্তব, কার্যকরী রেল মডেল অবজেক্ট। আপনি এটি ডাটাবেসের সাথে ব্যবহার করতে পারেন (এমনকি উপনাম সহ যখন আপনি একটি ভিন্ন মডেল অ্যাট্রিবিউট নাম চান), মঙ্গয়েড, REST ওয়েব পরিষেবাদি ইত্যাদি।
আমরা এখন পর্যন্ত যে সমস্ত বৈশিষ্ট্যের সাথে যোগাযোগ করেছি তা এই রত্নটির ক্ষেত্রেও প্রযোজ্য। সাধারণত, এটি চালানোর জন্য শুধুমাত্র অতিরিক্ত সেটিংস প্রয়োজন, যা config/initializers/money.rb-এ স্থাপন করা উচিত ফাইল:
MoneyRails.configure do |config|
# set the default currency
config.default_currency = :usd
end
এটি আপনার প্রদান করা একটি ডিফল্ট মুদ্রা সেট করবে। যাইহোক, বিকাশের সময়, সম্ভাবনা রয়েছে যে আপনাকে এক্সচেঞ্জ রূপান্তর সম্পাদন করতে হবে বা মডেল জুড়ে একাধিক মুদ্রা পরিচালনা করতে হবে।
যদি তাই হয়, money-rails
আমাদের একটি মডেল-স্তরের মুদ্রার সংজ্ঞা কনফিগার করার অনুমতি দেয়:
class Cart < ActiveRecord::Base
# Use GPB as model level currency
register_currency :eur
monetize :amount_cents, as "amount"
monetize :discount_cents, with_currency: :eur
monetize :converted_value, with_currency: :usd
end
মনে রাখবেন যে একবার সবকিছু সেট আপ হয়ে গেলে, আপনার প্রকল্পগুলির পাশাপাশি অর্থের প্রকারগুলি ব্যবহার করা সত্যিই সহজ৷
র্যাপিং আপ
এই ব্লগ পোস্টে, আমরা রুবি এবং রেল ইকোসিস্টেমের মধ্যে অর্থের মানগুলি মোকাবেলা করার জন্য কিছু উপলব্ধ বিকল্পগুলি অন্বেষণ করেছি৷ কিছু গুরুত্বপূর্ণ পয়েন্ট নিচে সংক্ষিপ্ত করা হল:
- যদি আপনি ফ্লোট সংখ্যার গণনার সাথে কাজ করছেন, বিশেষ করে যদি তারা অর্থের ডেটা উপস্থাপন করে, তাহলে
BigDecimal
এ যান অথবাmoney
দৃষ্টান্ত। - আপনার বিকাশের পাশাপাশি আরও অসঙ্গতি এড়াতে শুধুমাত্র একটি সিস্টেমে লেগে থাকার চেষ্টা করুন।
-
money
লাইব্রেরি হল পুরো RubyMoney সিস্টেমের মূল, এবং এটি খুব শক্তিশালী এবং সহজবোধ্য।money-rails
এটি Rails অ্যাপ্লিকেশনের জন্য সমতুল্য সংস্করণ, এবংmonetize
যখনই আপনাকেMoney
এ যেকোনো মান থেকে পার্স করতে হবে তখনই এটি প্রয়োজনীয় বস্তু। -
Float
ব্যবহার করা এড়িয়ে চলুন . এমনকি যদি আপনার অ্যাপের এখন কিছু গণনা করার প্রয়োজন না হয়, তবে সম্ভাবনা রয়েছে যে একজন অপ্রস্তুত ডেভ ভবিষ্যতে এটি করবে। আপনি এটি বন্ধ করার জন্য সেখানে নাও থাকতে পারেন৷
মনে রাখবেন, অফিসিয়াল ডক্স সবসময় একটি আবশ্যক হতে হবে. BigDecimal এর ব্যবহারের অনেক বড় ব্যাখ্যা এবং উদাহরণ দিয়ে ভরা, এবং RubyMoney জেম প্রজেক্টের ক্ষেত্রেও এটি সত্য।