ट्रैक
/
Elixir
Elixir
/
अभ्यास
/
रिमोट कंट्रोल कार
रिमोट कंट्रोल कार

रिमोट कंट्रोल कार

सीखने का अभ्यास

परिचय

स्ट्रक्ट

स्ट्रक्ट, मैप के ऊपर बना एक एक्सटेंशन है, जो कंपाइल-टाइम जाँच और डिफॉल्ट वैल्यू देता है। स्ट्रक्ट का नाम उस मॉड्यूल के नाम पर रखा जाता है जिसमें इसे बनाया जाता है। स्ट्रक्ट बनाने के लिए defstruct कंस्ट्रक्ट का उपयोग कीजिए। यह कंस्ट्रक्ट आमतौर पर मॉड्यूल की परिभाषा के ठीक बाद लिखा जाता है। defstruct या तो एटम का ऐरे लेता है (nil डिफॉल्ट वैल्यू के लिए), या कीवर्ड ऐरे (तय की गई डिफॉल्ट वैल्यू के लिए)। जिन फील्ड की कोई डिफॉल्ट वैल्यू नहीं है, वे डिफॉल्ट वैल्यू वाले फील्ड से पहले आने चाहिए।

defmodule Plane do
  defstruct [:engine, wings: 2]
end

plane = %Plane{}
# => %Plane{engine: nil, wings: 2}

फील्ड पढ़ना और बदलना

चूँकि स्ट्रक्ट मैप के ऊपर बने होते हैं, हम वैल्यू पाने और बदलने के लिए ज़्यादातर मैप फंक्शन इस्तेमाल कर सकते हैं। स्ट्रक्ट के लिए Access Behaviour लागू नहीं होता। इसकी जगह स्ट्रक्ट फील्ड पढ़ने के लिए स्टैटिक एक्सेस ऑपरेटर . इस्तेमाल करना बेहतर है।

  • फील्ड की वैल्यू पाना:

    plane = %Plane{}
    plane.engine
    # => nil
    Map.fetch(plane, :wings)
    # => {:ok, 2}
    
  • फील्ड की वैल्यू बदलना:

    plane = %Plane{}
    %{plane | wings: 4}
    # => %Plane{engine: nil, wings: 4}
    

पैटर्न मैचिंग

स्ट्रक्ट का पैटर्न मैचिंग में इस्तेमाल स्ट्रक्ट के नाम के साथ या उसके बिना किया जा सकता है।

plane = %Plane{}
%Plane{wings: wings} = plane
%{wings: wings} = plane

पैटर्न में स्ट्रक्ट का नाम शामिल करने से आप यह पक्का कर सकते हैं कि बाईं और दाईं, दोनों तरफ एक ही तरह के स्ट्रक्ट हैं।

defmodule Helicopter do
  defstruct [:engine, rotors: 1]
end

%Plane{} = %Helicopter{}
# => (MatchError) no match of right hand side value: %Helicopter{engine: nil, rotors: 1}

फील्ड की वैल्यू शुरू में देना ज़रूरी बनाना

स्ट्रक्ट बनाते समय वैल्यू ज़रूर शुरू हो जाएँ, यह पक्का करने के लिए हम फील्ड कीज़ के ऐरे के साथ @enforce_keys मॉड्यूल एट्रिब्यूट इस्तेमाल कर सकते हैं। अगर कोई की सूची में नहीं है, तो उसकी वैल्यू nil होगी, जैसा ऊपर के उदाहरण में दिख रहा है। अगर ज़रूरी बनाई गई कोई की शुरू में नहीं दी गई, तो एरर आती है।

defmodule User do
  @enforce_keys [:username]
  defstruct [:username]
end

%User{}
# => (ArgumentError) the following keys must also be given when building struct User: [:username]

निर्देश

इस अभ्यास में आप एक रिमोट कंट्रोल कार के साथ खेलेंगे, जिसे खरीदने के लिए आपने अंत में इतना पैसा बचा लिया है।

कार की बैटरी शुरू में पूरी (100%) रहती है। जब भी आप रिमोट कंट्रोल से कार चलाते हैं, वह 20 मीटर तय करती है और बैटरी का एक प्रतिशत खर्च हो जाता है। कार का उपनाम तब तक पता नहीं चलता जब तक कार बन न जाए।

रिमोट कंट्रोल कार पर एक शानदार LED डिस्प्ले लगा है, जो दो तरह की जानकारी दिखाता है:

  • अब तक तय की गई कुल दूरी, जो इस तरह दिखाई जाती है: "<METERS> meters".
  • बैटरी का बचा हुआ चार्ज, जो इस तरह दिखाया जाता है: "Battery at <PERCENTAGE>%".

अगर बैटरी 0% पर पहुँच जाए, तो आप कार और नहीं चला सकते, और बैटरी डिस्प्ले पर "Battery empty" दिखाई देगा।

1. बिल्कुल नई रिमोट कंट्रोल कार बनाइए

एक बिल्कुल नई रिमोट कंट्रोल कार स्ट्रक्चर लौटाने के लिए RemoteControlCar.new/0 फंक्शन लागू कीजिए:

RemoteControlCar.new()
# => %RemoteControlCar{
#      battery_percentage: 100,
#      distance_driven_in_meters: 0,
#      nickname: "none"
#    }

स्ट्रक्चर में उपनाम ज़रूरी है, इसलिए ध्यान रखिए कि वैल्यू new फंक्शन में शुरू में सेट की जाए, स्ट्रक्चर में नहीं।

2. उपनाम के साथ बिल्कुल नई रिमोट कंट्रोल कार बनाइए

दिए गए उपनाम के साथ बिल्कुल नई रिमोट कंट्रोल कार स्ट्रक्चर लौटाने के लिए RemoteControlCar.new/1 फंक्शन लागू कीजिए:

RemoteControlCar.new("Blue")
# => %RemoteControlCar{
#      battery_percentage: 100,
#      distance_driven_in_meters: 0,
#      nickname: "Blue"
#    }

3. दूरी प्रदर्शित कीजिए

LED डिस्प्ले पर दिखाई जाने वाली दूरी लौटाने के लिए RemoteControlCar.display_distance/1 फंक्शन लागू कीजिए:

car = RemoteControlCar.new()
RemoteControlCar.display_distance(car)
# => "0 meters"

ध्यान रखिए कि यह फंक्शन आर्गुमेंट के रूप में सिर्फ RemoteControlCar स्ट्रक्चर ही स्वीकार करे।

4. बैटरी प्रतिशत प्रदर्शित कीजिए

LED डिस्प्ले पर दिखाया जाने वाला बैटरी प्रतिशत लौटाने के लिए RemoteControlCar.display_battery/1 फंक्शन लागू कीजिए:

car = RemoteControlCar.new()
RemoteControlCar.display_battery(car)
# => "Battery at 100%"

ध्यान रखिए कि यह फंक्शन आर्गुमेंट के रूप में सिर्फ RemoteControlCar स्ट्रक्चर ही स्वीकार करे। अगर बैटरी 0% पर हो, तो बैटरी डिस्प्ले पर "Battery empty" दिखाई देगा।

5. चलाने से बैटरी और तय की गई दूरी बदलती है

ऐसा RemoteControlCar.drive/1 फंक्शन लागू कीजिए जो:

  • तय किए गए मीटरों की संख्या में 20 जोड़ता है
  • बैटरी का 1% खर्च करता है
RemoteControlCar.new("Red")
|> RemoteControlCar.drive()

# => %RemoteControlCar{
#      battery_percentage: 99,
#      distance_driven_in_meters: 20,
#      nickname: "Red"
#    }

ध्यान रखिए कि यह फंक्शन आर्गुमेंट के रूप में सिर्फ RemoteControlCar स्ट्रक्चर ही स्वीकार करे।

6. बैटरी खत्म हो जाने पर चलाने का ध्यान रखिए

RemoteControlCar.drive/1 फंक्शन को ऐसे बदलिए कि जब बैटरी खत्म हो (0% पर हो), तो न तय की गई दूरी बढ़े और न बैटरी प्रतिशत घटे:

%RemoteControlCar{
  battery_percentage: 0,
  distance_driven_in_meters: 1980,
  nickname: "Red"
}
|> RemoteControlCar.drive()

# => %RemoteControlCar{
#      battery_percentage: 0,
#      distance_driven_in_meters: 1980,
#      nickname: "Red"
#    }
GitHub के ज़रिए संपादित करें यह लिंक एक नई विंडो या टैब में खुलता है
Elixir Exercism

रिमोट कंट्रोल कार शुरू करने के लिए तैयार हैं?

Exercism पर साइन अप कीजिए और Elixir को 58 कॉन्सेप्ट168 अभ्यास तथा असली इंसानों से मिलने वाली मेंटरिंग के साथ सीखिए और उसमें महारत हासिल कीजिए, वह भी बिल्कुल मुफ्त।