বহু ভাষায় null বা none-এর মতো একটি উপায় থাকে, যা দিয়ে অনুপস্থিত মান বোঝানো হয়। যেহেতু Julia ডিজাইন করা হয়েছে প্রচুর পরিমাণে (প্রায়ই এলোমেলো) ডেটা সামলানোর জন্য, তাই এতে শূন্যতার একাধিক রূপ রয়েছে।
মূল লক্ষ্য হলো অনুপস্থিত বা সন্দেহজনক মান চোখে পড়া মাত্রই সেগুলো চিহ্নিত করা, তারপর কোনো এক্সসেপশন না ছুঁড়ে কাজ চালিয়ে যাওয়া।
nothingকোনো মান সত্যিই না থাকলে তা nothing দিয়ে প্রকাশ করা হয়। সম্ভবত C (NULL) বা Python (None) যা করে তার সঙ্গে এটাই সবচেয়ে কাছাকাছি।
julia> n = nothing
julia> isnothing(n)
true
julia> typeof(n)
Nothing
অর্থাৎ nothing হলো Nothing টাইপের একটি সিঙ্গলটন মান, আর আমরা এটি পরীক্ষা করতে পারি।
nothing-এর একটি কমন ব্যবহার হলো এমন ফাংশনের রিটার্ন (না-)ভ্যালু হিসেবে, যেগুলো কেবল তাদের সাইড ইফেক্টের জন্য ব্যবহৃত হয় (প্রিন্ট করা, নেটওয়ার্ক কনফিগারেশন, বা যা-ই হোক)।
missingযে পরিস্থিতিতে কোনো মান তত্ত্বগতভাবে আছে, কিন্তু তা কী তা আমরা জানি না, সেখানে missing ব্যবহৃত হয়।
উদাহরণস্বরূপ, রাস্তায় চলাচলকারী যানবাহন গণনা করার সময় মানুষের পর্যবেক্ষকের বিরতি লাগতে পারে, কিংবা স্বয়ংক্রিয় সেন্সর নষ্ট হয়ে যেতে পারে, কিন্তু যান চলাচল চলতেই থাকে।
তাই missing হলো একটি প্লেসহোল্ডার, যা মানুষকে সতর্ক করে যে ডেটার এই ফাঁকটি তারা কীভাবে সামলাবে, সে বিষয়ে তাদের সিদ্ধান্ত নিতে হবে।
julia> mv = [1, 2, missing]
3-element Vector{Union{Missing, Int64}}:
1
2
missing
julia> typeof(mv)
Vector{Union{Missing, Int64}} (alias for Array{Union{Missing, Int64}, 1})
julia> ismissing.(mv) # broadcast function, displays as 1 for true, 0 for false
3-element BitVector:
0
0
1
অন্যদিকে খুব কম ভাষায় এই বৈশিষ্ট্যটি আগে থেকেই থাকে, তবে কাছাকাছি উদাহরণ হলো R-এর NA বা SQL-এর NULL।
missing মান উপস্থিত থাকলে এক্সপ্রেশন সাধারণত ডিফল্টভাবে missing রিটার্ন করে।
আপনি যদি চান এই মানগুলো উপেক্ষা করা হোক, তবে সেটি স্পষ্ট করতে skipmissing() ফাংশনটি ব্যবহার করুন:
julia> mv = [1, 2, missing]
3-element Vector{Union{Missing, Int64}}:
1
2
missing
julia> sum(mv) # missing in, missing out
missing
julia> skipmissing(mv)
skipmissing(Union{Missing, Int64}[1, 2, missing])
julia> collect(skipmissing(mv))
2-element Vector{Int64}:
1
2
julia> sum(skipmissing(mv)) # functions like sum() can work with iterators
3
যেহেতু skipmissing একটি ইটারেটর তৈরি করে, তাই আপনার ভেক্টর দরকার হলে এটিকে collect() দিয়ে মুড়ে নিন।
কখনও কখনও missing মানগুলোকে কোনো ডিফল্ট দিয়ে বদলে ফেলা সুবিধাজনক।
এ কাজে @coalesce() ম্যাক্রোটি সুবিধাজনক, কারণ এটি প্রথম যে মানটি missing নয়, সেটি রিটার্ন করে (আর অন্য কিছু না থাকলে missing)।
julia> str = ["I", "exist", missing]
3-element Vector{Union{Missing, String}}:
"I"
"exist"
missing
julia> [@coalesce(s, "-") for s in str]
3-element Vector{String}:
"I"
"exist"
"-"
NaN"Not a Number"-এর সংক্ষিপ্ত রূপ NaN, এমন পরিস্থিতিতে একটি গণনার সমস্যা চিহ্নিত করে, যেখানে একটি সংখ্যা প্রত্যাশিত ছিল।
julia> v = [0, 1, -1]
3-element Vector{Int64}:
0
1
-1
julia> v / 0
3-element Vector{Float64}:
NaN
Inf
-Inf
julia> sum(v / 0)
NaN
NaN-সহ যেকোনো ধরনের গণনা একটি NaN ফলাফল দেবে।
বর্তমানে NaN মান সরানোর জন্য কোনো বিশেষ ফাংশন নেই, তবে স্ট্যান্ডার্ড filter() ফাংশনটি এটি বেশ সহজেই করতে পারে।
কেবল সেই মানগুলোই ফলাফল অ্যারেতে কপি করা হবে, যেগুলোর জন্য প্রদত্ত কোনো শর্ত true হয়:
julia> filter(!isnan, [1, 2, NaN])
2-element Vector{Float64}:
1.0
2.0
এই অনুশীলনীতে আপনি কারখানার কর্মীদের পরার জন্য নেম ব্যাজ তৈরির কোড লিখবেন। কর্মীদের একটি ID, একটি নাম এবং একটি বিভাগের নাম থাকে। কর্মী ব্যাজের লেবেলগুলো এভাবে ফরম্যাট করা হয়: "[id] - name - DEPARTMENT"।
print_name_badge ফাংশনটি ইমপ্লিমেন্ট করুন। এটি একটি ID, একটি নাম এবং একটি বিভাগ নেবে। এটি ব্যাজের লেবেল রিটার্ন করবে, যেখানে বিভাগের নামটি বড় হাতের অক্ষরে থাকবে।
julia> print_name_badge(67, "Katherine Williams", "Strategic Communication")
"[67] - Katherine Williams - STRATEGIC COMMUNICATION"
কম্পিউটার সিস্টেমের একটি খুঁতের কারণে, কারখানায় কাজ শুরু করার সময় নতুন কর্মীদের মাঝে মাঝে এখনও ID থাকে না। যেহেতু ব্যাজ বাধ্যতামূলক, তাই তারা ID প্রিফিক্স ছাড়া একটি অস্থায়ী ব্যাজ পাবেন।
print_name_badge ফাংশনটি বাড়িয়ে লিখুন। যখন ID অনুপস্থিত থাকে, তখন এটি ID ছাড়াই একটি ব্যাজ তৈরি করবে।
julia> print_name_badge(missing, "Robert Johnson", "Procurement")
"Robert Johnson - PROCUREMENT"
এমনকি কারখানার মালিককেও সব সময় একটি ব্যাজ পরতে হয়। তবে মালিকের কোনো বিভাগ থাকে না, কখনো থাকবেও না: তিনি সব বিভাগের ঊর্ধ্বে। এই ক্ষেত্রে লেবেলটি বিভাগের নামের বদলে "OWNER" রিটার্ন করবে।
print_name_badge ফাংশনটি বাড়িয়ে লিখুন। যখন বিভাগ nothing হয়, তখন ধরে নিন ব্যাজটি কোম্পানির মালিকের।
julia> print_name_badge(204, "Rachel Miller", nothing)
"[204] - Rachel Miller - OWNER"
মনে রাখবেন, মালিকও একজন নতুন কর্মী হতে পারেন।
julia> print_name_badge(missing, "Rachel Miller", nothing)
"Rachel Miller - OWNER"
ID কতটা ভালোভাবে ইস্যু হচ্ছে তার একটি মোটামুটি পরিমাপ হিসেবে, আপনি যাদের ID নেই এমন কর্মীদের সম্মিলিত বেতন দেখতে চান। একটি উচ্চ মান মানে অনেকেই অপেক্ষায় আছেন, অথবা সমস্যাটি ঊর্ধ্বতন কর্মীদেরও প্রভাবিত করছে: দুটোই খারাপ।
salaries_no_id ফাংশনটি ইমপ্লিমেন্ট করুন, যা ID-এর একটি ভেক্টর এবং বেতনের একটি সংশ্লিষ্ট ভেক্টর নেয়, এবং যাদের এখনও ID নেই তাদের বেতনের যোগফল রিটার্ন করে। দুটি ভেক্টরের দৈর্ঘ্যই সমান।
julia> ids = [204, missing, 210, 352, missing, 263]
julia> salaries = [23, 21, 47, 35, 17, 101] * 1000
julia> salaries_no_id(ids, salaries)
38,000
Exercism-এ সাইন আপ করুন, Julia ট্র্যাকের 35টি কনসেপ্ট128টি অনুশীলনী আর সত্যিকারের মানুষের মেন্টরিং দিয়ে শিখুন ও দক্ষ হয়ে উঠুন, সম্পূর্ণ বিনামূল্যে।