المسارات
/
Julia
Julia
/
التمارين
/
شارات الأسماء
شارات الأسماء

شارات الأسماء

تمرين تعلّمي

مقدمة

توفّر لغات كثيرة وسيلة مثل 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

اختصارًا لعبارة "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] - name - DEPARTMENT".

1. أنشئ شارة لموظف

نفّذ الدالة print_name_badge. يجب أن تأخذ معرّفًا واسمًا وقسمًا. ويجب أن تُرجع ملصق الشارة، مع اسم القسم بأحرف كبيرة.

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

2. أنشئ شارة لموظف جديد

بسبب خلل في نظام الحاسوب، لا يكون لدى الموظفين الجدد معرّف في بعض الأحيان عند بدء عملهم في المصنع. ولأن الشارات مطلوبة، فسيحصلون على شارة مؤقتة بدون بادئة المعرّف.

وسّع الدالة print_name_badge. عندما يكون المعرّف مفقودًا، يجب أن تُنشئ شارة بدونه.

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 تمرينًا، وإرشاد بشري حقيقي، وكل ذلك مجانًا.