ट्रैक
/
Swift
Swift
/
अभ्यास
/
लज़ान्या मास्टर
लज़ान्या मास्टर

लज़ान्या मास्टर

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

परिचय

पैरामीटर की डिफॉल्ट वैल्यू

डिफॉल्ट पैरामीटर वैल्यू फंक्शन के किसी भी पैरामीटर के लिए दी जा सकती है। इसके लिए पैरामीटर लिस्ट में उस पैरामीटर के टाइप एनोटेशन के बाद एक वैल्यू असाइन की जाती है। जब डिफॉल्ट वैल्यू दी गई हो, तो फंक्शन को कॉल करते समय कॉल करने वाला उस पैरामीटर को छोड़ सकता है, और उसकी जगह डिफॉल्ट वैल्यू इस्तेमाल की जाती है।

func greeting(name: String = "guest", duration: Int = 2) -> String {
  "Welcome, \(name). Enjoy your \(duration) night stay."
}

greeting(name: "Bobo", duration: 7)
// Returns "Welcome, Bobo. Enjoy your 7 night stay."
greeting(duration: 3)
// Returns "Welcome, guest. Enjoy your 3 night stay."
greeting(name: "Wynona")
// Returns "Welcome, Wynona. Enjoy your 2 night stay."
greeting()
// Returns "Welcome, guest. Enjoy your 2 night stay."

वेरिएडिक पैरामीटर

वेरिएडिक पैरामीटर की मदद से कोई फंक्शन एक ही पैरामीटर के लिए किसी तय टाइप की शून्य या अधिक वैल्यू ले सकता है। वेरिएडिक पैरामीटर बनाने के लिए पैरामीटर के टाइप एनोटेशन के आगे तीन बिंदु (...) लगाइए।

फंक्शन के अंदर Swift इन वैल्यू को बताए गए टाइप के ऐरे के रूप में उपलब्ध कराता है:

import Foundation

func geometricMean(_ numbers: Double...) -> Double {
    var total = 1.0
    for number in numbers {
        total *= number
    }
    return pow(total, 1.0 / Double(numbers.count))
}

let result = geometricMean(1, 2, 3, 4, 5)
// result is 2.605171084697352
Note

अगर किसी फंक्शन में वेरिएडिक पैरामीटर के बाद और पैरामीटर भी हों, तो वेरिएडिक पैरामीटर के बाद आने वाले पहले पैरामीटर का आर्गुमेंट लेबल साफ़ तौर पर लिखा होना ज़रूरी है, ताकि Swift को पता चले कि वेरिएडिक आर्गुमेंट की सूची कहाँ खत्म होती है।

इन-आउट पैरामीटर

किसी फंक्शन के अंदर पैरामीटर को वेरिएबल नहीं, कॉन्स्टेंट माना जाता है। पैरामीटर की वैल्यू बदलने की कोशिश करने पर कंपाइल के समय एरर मिलती है। अगर किसी फंक्शन को पैरामीटर की वैल्यू बदलनी है, तो उसे इन-आउट पैरामीटर इस्तेमाल करना होगा, ताकि यह साफ़ हो जाए कि वैल्यू बदली जा सकती है।

इन-आउट पैरामीटर इस्तेमाल करने के लिए प्रोग्रामर को तीन बातों का ध्यान रखना होता है:

  1. फंक्शन बनाते समय पैरामीटर के टाइप एनोटेशन में : और टाइप के नाम के बीच inout कीवर्ड लिखकर इन-आउट पैरामीटर को साफ़ तौर पर चिह्नित करना होता है।
  2. इन-आउट पैरामीटर को पास की जाने वाली वैल्यू वेरिएबल के रूप में घोषित होनी चाहिए, कॉन्स्टेंट के रूप में नहीं। इसी तरह वह कोई लिटरल भी नहीं हो सकती।
  3. फंक्शन को कॉल करते समय वेरिएबल के नाम से पहले एक & लगाना होता है, जिससे साफ़ हो जाए कि इसे बदला जा सकता है।

ऐसा करने पर फंक्शन इन-आउट पैरामीटर की अंदर ही एक कॉपी बनाता है, फंक्शन के अंदर बताए अनुसार उसे बदलता है, और फिर फंक्शन लौटते समय बदली हुई वैल्यू को उसी वेरिएबल में वापस कॉपी कर देता है जो पास की गई थी।

func updateVersion(_ record: inout (version: Int, title: String)) {
  record.version += 1
}

var dbRecord = (version: 2, title: "Exercism")
updateVersion(&dbRecord)

// dbRecord is now (3, "Exercism")
इन-आउट पैरामीटर के बारे में दो-एक अतिरिक्त नियम भी ध्यान में रखने चाहिए।

1  इन-आउट पैरामीटर वाले फंक्शन के अंदर उस वेरिएबल को संदर्भित नहीं किया जा सकता जो इन-आउट पैरामीटर के रूप में पास किया गया था।
2. एक ही फंक्शन में एक ही वेरिएबल को कई इन-आउट पैरामीटर के रूप में पास नहीं किया जा सकता।
   जैसे, `inoutFunc(&mutVar, &mutVar)` लिखने पर कंपाइलर एरर देता है।

नेस्टेड फंक्शन

Swift में आप दूसरे फंक्शन के अंदर फंक्शन बना सकते हैं। इन्हें नेस्टेड फंक्शन कहते हैं।

नेस्टेड फंक्शन आम तौर पर ऐसे प्राइवेट हेल्पर होते हैं, जो अपने बाहरी फंक्शन के लिए कुछ खास काम करते हैं और बाहरी स्कोप को अव्यवस्थित नहीं करते:

func makeNumber(_ number: Int) -> Int {
    func double(_ x: Int) -> Int {
        x * 2
    }

    func increment(_ x: Int) -> Int {
        x + 1
    }

    return number.isMultiple(of: 2) ? increment(double(number)) : double(number)
}

print(makeNumber(3)) // Prints 6
print(makeNumber(4)) // Prints 9

नेस्टेड फंक्शन आम फंक्शन की तरह ही व्यवहार करते हैं, लेकिन इन्हें सिर्फ बाहरी फंक्शन के अंदर ही देखा जा सकता है।

निर्देश

इस अभ्यास में आप अपनी पसंदीदा कुकबुक से बनी शानदार लसान्या पकाने के लिए कुछ और कोड लिखेंगे।

आपके सामने पाँच काम हैं, और सबका संबंध लसान्या पकाने में लगने वाले समय से है।

1. अपेक्षित ओवन समय बदलने दीजिए

आप remainingMinutesInOven फंक्शन को बेहतर बनाना चाहते हैं। यह फंक्शन पैरामीटर के रूप में वे बीते हुए मिनट लेता है जितनी देर लसान्या ओवन में रही है, और पिछले काम में तय किए गए अपेक्षित ओवन समय के हिसाब से बताता है कि लसान्या को ओवन में अभी कितने मिनट और रहना है। पहले आप expectedMinutesInOven नाम की एक स्थिर वैल्यू पर निर्भर थे, जो remainingMinutesInOven फंक्शन के बाहर से आती थी। इसमें दो दिक्कतें थीं: यह आपकी पसंद के हिसाब से थोड़ा बहुत उलझा हुआ था, और लचीला भी कम था, क्योंकि इससे ओवन का अपेक्षित समय बदलना संभव नहीं था।

इसे साफ-सुथरा बनाने के लिए remainingMinutesInOven फंक्शन बनाइए। यह फंक्शन पैरामीटर के रूप में वे बीते हुए मिनट लेता है जितनी देर लसान्या ओवन में रही है, और साथ ही एक expectedMinutesInOven पैरामीटर भी लेता है, जिसकी वैल्यू पहले से 40 तय है। आपके फंक्शन को पिछले काम में तय अपेक्षित ओवन समय के हिसाब से बताना चाहिए कि लसान्या को ओवन में अभी कितने मिनट और रहना है।

remainingMinutesInOven(elapsedMinutes: 30)
// Returns 10
remainingMinutesInOven(elapsedMinutes: 30, expectedMinutesInOven: 75)
// Returns 45

2. परतों की अलग-अलग संख्या की सुविधा दीजिए

पिछले अभ्यास में आपने preparationTimeInMinutes फंक्शन लिखा था, जो पैरामीटर के रूप में लसान्या में डाली गई परतों की संख्या लेता है और बताता है कि लसान्या तैयार करने में आपने कितने मिनट लगाए, यह मानकर कि हर परत तैयार करने में 2 मिनट लगते हैं। लेकिन यह फंक्शन आपको खास पसंद नहीं है, क्योंकि इस फंक्शन को कॉल करने से पहले आपको अपनी लसान्या की परतें खुद गिननी पड़ती हैं। और इतना सब करने का समय किसके पास है?

अपना काम आसान बनाने के लिए preparationTimeInMinutes नाम का एक फंक्शन लिखिए, जो एक वेरिएडिक String पैरामीटर, layers, लेता है, जिसमें आप अपनी लसान्या की अलग-अलग परतें लिखते हैं। फिर यह फंक्शन आपकी लसान्या की परतें गिनकर बताएगा कि तैयारी में कितना समय लगेगा।

preparationTimeInMinutes(layers: "sauce", "noodles")
// Returns 4
preparationTimeInMinutes(layers: "sauce", "noodles", "sauce", "meat", "mozzarella", "noodles", "sauce", "eggplant", "béchamel", "noodles", "sauce", "mozzarella")
// Returns 24

3. नूडल्स और सॉस की मात्रा निकालिए

अपनी लसान्या की परतें लगाना शुरू करने से पहले आप यह पक्का करना चाहते हैं कि आपके सपनों की लसान्या बनाने के लिए आपके पास पर्याप्त सॉस और नूडल्स हों। लसान्या की हर नूडल परत के लिए आपको 3 नूडल्स चाहिए। लसान्या की हर सॉस परत के लिए 0.2 लीटर सॉस चाहिए।

quantities फंक्शन बनाइए, जो एक वेरिएडिक String पैरामीटर, layers, लेता है, जिसमें आप अपनी लसान्या की अलग-अलग परतें लिखते हैं। फिर यह फंक्शन तय करेगा कि आपका खाना बनाने के लिए कितने नूडल्स और कितना सॉस चाहिए। नतीजा (noodles: Int, sauce: Double) टाइप के टपल में लौटाना चाहिए।

quantities(layers: "sauce", "noodles", "sauce", "meat", "mozzarella", "noodles", "sauce", "eggplant", "béchamel", "noodles", "sauce", "mozzarella")
// Returns (noodles: 9, sauce: 0.8)
quantities(layers: "sauce", "noodles", "sauce", "noodles", "meat", "noodles", "mozzarella")
// Returns (noodles: 9, sauce: 0.4)

4. लीटर को वहीं फ्लुइड औंस में बदलिए

दुर्भाग्य से, आपके पास जो सॉस है उसका आयतन लीटर की जगह फ्लुइड औंस में लिखा है। यह जानने के लिए कि आपके पास पर्याप्त सॉस है या नहीं, toOz नाम का एक फंक्शन लिखिए, जो एक इन-आउट टपल पैरामीटर, (noodles: Int, sauce: Double), लेता है और सॉस की मात्रा को फ्लुइड औंस में बदल देता है। ध्यान रखिए कि एक लीटर में 33.814 फ्लुइड औंस होते हैं।

var amount = (noodles: 9, sauce: 0.8)
toOz(&amount)

amount
// Returns (noodles: 9, sauce: 27.0512)

5. परोसने के लिए सबसे अच्छी वाइन तय कीजिए

अंत में, आप जानना चाहते हैं कि अपनी लसान्या के साथ किस तरह की वाइन परोसी जाए। आपने सुना है कि अगर लसान्या में मोज़रेला, रिकोटा और बेशमेल की परतें मीट और सॉस की परतों से अधिक हों, तो सफेद वाइन परोसनी चाहिए, वरना रेड वाइन। redWine फंक्शन लिखिए, जो एक वेरिएडिक String पैरामीटर, layers, लेता है, जिसमें आप अपनी लसान्या की अलग-अलग परतें लिखते हैं। यह फंक्शन पाँच नेस्टेड फंक्शन इस्तेमाल करके लसान्या में मोज़रेला, रिकोटा, बेशमेल, सॉस और मीट की परतों की संख्या निकालेगा, और परतों की संख्याओं की तुलना करके तय करेगा कि रेड वाइन परोसनी चाहिए या नहीं। अगर हाँ, तो यह true लौटाएगा, और अगर नहीं, तो false।

redWine(layers: "sauce", "noodles", "sauce", "meat", "mozzarella", "noodles", "sauce", "eggplant", "béchamel", "noodles", "sauce", "mozzarella")
// Returns true
redWine(layers: "sauce", "noodles", "béchamel", "meat", "mozzarella", "noodles", "ricotta", "eggplant", "béchamel", "noodles", "sauce", "mozzarella")
// Returns false
GitHub के ज़रिए संपादित करें यह लिंक एक नई विंडो या टैब में खुलता है
Swift Exercism

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

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