نشان اسم

نشان اسم

تمرین یادگیری

مقدمه

بسیاری از زبان‌ها روشی مانند 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

زبان‌های کمی این قابلیت را به‌صورت توکار دارند، اما معادل‌های نزدیک آن NA در R یا NULL در SQL هستند.

عبارت‌ها معمولاً اگر مقادیر 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

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] - name - DEPARTMENT".

1. ساخت برچسب برای یک کارمند

تابع print_name_badge را پیاده‌سازی کنید. این تابع باید یک شناسه، یک اسم و یک دپارتمان بگیرد. باید برچسب را برگرداند، با اسم دپارتمان به حروف بزرگ.

julia> print_name_badge(67, "Katherine Williams", "Strategic Communication")
"[67] - Katherine Williams - STRATEGIC COMMUNICATION"

2. ساخت برچسب برای یک کارمند جدید

به دلیل یک ایراد عجیب در سیستم رایانه‌ای، کارکنان جدید گاهی وقتی کار در کارخانه را شروع می‌کنند هنوز شناسه ندارند. چون برچسب الزامی است، یک برچسب موقت بدون پیشوند شناسه دریافت می‌کنند.

تابع print_name_badge را گسترش دهید. وقتی شناسه missing است، باید برچسبی بدون آن بسازد.

julia> print_name_badge(missing, "Robert Johnson", "Procurement")
"Robert Johnson - PROCUREMENT"

3. ساخت برچسب برای صاحب کارخانه

حتی صاحب کارخانه هم باید همیشه برچسب بپوشد. اما او دپارتمان ندارد و هرگز هم نخواهد داشت: او فراتر از همه‌ی دپارتمان‌هاست. در این حالت، برچسب باید به جای اسم دپارتمان "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"

4. محاسبه‌ی مجموع حقوق کارکنان بدون شناسه

به عنوان یک معیار تقریبی از اینکه شناسه‌ها چقدر خوب صادر می‌شوند، می‌خواهید مجموع حقوق کارکنان بدون شناسه را ببینید. مقدار بالا یعنی تعداد زیادی در انتظارند، یا مشکل گریبان افراد باسابقه را گرفته است: هر دو بد است.

تابع salaries_no_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
ویرایش از طریق GitHub این لینک در پنجره یا زبانه‌ی جدیدی باز می‌شود
Julia Exercism

آماده‌اید نشان اسم را شروع کنید؟

در Exercism ثبت‌نام کنید تا Julia را همراه با 35 مفهوم128 تمرین و مربی‌گری انسانی واقعی یاد بگیرید و در آن استاد شوید، همه‌ی این‌ها رایگان.