লগ লাইন

লগ লাইন

লার্নিং অনুশীলনী

ভূমিকা

যখন এমন ডেটা মডেল করেন যা কেবল কিছু নির্দিষ্ট সম্ভাব্য অবস্থা গ্রহণ করতে পারে, যেমন সপ্তাহের বার, কম্পাসের দিক, বা কন্ট্রোলারের বোতাম, তখন Int বা String-এর মতো বেসিক টাইপের বড় অসুবিধা আছে। ইন্টিজার বা স্ট্রিং দিয়ে, আপনার কোডকে ক্রমাগত অবৈধ মান পরীক্ষা করতে হয় (যেমন 999 স্ট্যাটাস কোড বা "leftt"-এর মতো টাইপো), এবং মানুষ পাঠক সহজে বলতে পারে না সংখ্যাগুলো কী বোঝায়।

Swift এনামারেশন (যাকে প্রায়ই এনাম বলা হয়) দিয়ে এই সমস্যার সমাধান করে। একটি এনাম সম্পর্কিত, নামযুক্ত মানের একটি গ্রুপের জন্য একটি কমন টাইপ ডিফাইন করে। কারণ কম্পাইলার আগেই সমস্ত সম্ভাব্য কেস জানে, এটি কম্পাইল টাইমে আপনার কোডের সঠিকতা এবং সম্পূর্ণতা পরীক্ষা করতে পারে। এনামগুলো এছাড়াও মেথড, ইনিশিয়ালাইজার, এবং কম্পিউটেড প্রপার্টি থাকতে পারে।

এনাম ডিফাইন করা

একটি এনাম ডিফাইন করুন enum কিওয়ার্ড ব্যবহার করে, তারপর টাইপের নাম, এবং এর কেসগুলো দ্বিতীয় বন্ধনীর ভিতরে তালিকাবদ্ধ করুন। Swift কনভেনশন অনুসারে, টাইপের নাম UpperCamelCase ব্যবহার করে, আর প্রতিটি কেস lowerCamelCase ব্যবহার করে:

enum NESButton {
    case up
    case down
    case left
    case right
    case a
    case b
    case select
    case start
}

আপনি একটি লাইনে কমা দিয়ে আলাদা করে একাধিক কেসও ডিফাইন করতে পারেন:

enum NESButton {
    case up, down, left, right, a, b, select, start
}

কোনো এনাম কেস উল্লেখ করতে, এনাম টাইপের নাম, একটি ডট (.), এবং কেসের নাম লিখুন। একবার টাইপ জানা গেলে বা কম্পাইলার অনুমান করতে পারলে, আপনি টাইপের নাম বাদ দিয়ে সংক্ষিপ্ত ডট সিনট্যাক্স ব্যবহার করতে পারেন:

var lastPressed = NESButton.up

// Swift infers the type, so you can omit the type name:
lastPressed = .down

let konamiCode: [NESButton] = [.up, .up, .down, .down, .left, .right, .left, .right, .b, .a]

মেথড এবং ইনিশিয়ালাইজার

এনামগুলো ক্লাস এবং স্ট্রাক্টের মতোই মেথড এবং কাস্টম ইনিশিয়ালাইজার ডিফাইন করতে পারে। একটি এনাম মেথডের ভিতরে, self বর্তমান কেস মানকে বোঝায়:

enum Coin {
    case heads
    case tails

    init(_ value: Int) {
        if value.isMultiple(of: 2) {
            self = .heads
        } else {
            self = .tails
        }
    }

    func flip() -> Coin {
        switch self {
        case .heads: return .tails
        case .tails: return .heads
        }
    }
}

let tails = Coin(13)     // .tails
let heads = Coin(0)      // .heads
let flipped = heads.flip() // .tails

র' ভ্যালু

এনাম কেসগুলো ডিফল্ট মান দিয়ে পূর্ব-পূরণ করা যায় যাকে র' ভ্যালু বলা হয়। একটি এনামের সমস্ত র' ভ্যালু একই টাইপ শেয়ার করতে হবে (যেমন Int, String, বা Character):

enum NESButton: Character {
    case up = "⬆️"
    case down = "⬇️"
    case left = "⬅️"
    case right = "➡️"
    case a = "🅰️"
    case b = "🅱️"
    case select = "✅"
    case start = "🚦"
}

print(NESButton.left.rawValue) // Prints "⬅️"

আপনি init(rawValue:) ব্যবহার করে একটি র' ভ্যালু থেকে এনাম ইনিশিয়ালাইজ করতে পারেন। কারণ একটি অবৈধ র' ভ্যালু দেওয়া হতে পারে, এই ইনিশিয়ালাইজার একটি অপশনাল রিটার্ন করে:

let upButton = NESButton(rawValue: "⬆️") // Optional(NESButton.up)
let invalid = NESButton(rawValue: "🙄")  // nil

Swift স্বয়ংক্রিয়ভাবে String এবং Int এনামের জন্য র' ভ্যালু অ্যাসাইন করতে পারে:

  • String এনামের জন্য, প্রতিটি কেসের র' ভ্যালু ডিফল্টভাবে তার কেসের নাম হয়।
  • Int এনামের জন্য, র' ভ্যালুগুলো 0 থেকে শুরু হয় এবং অন্যথায় নির্দিষ্ট না করা হলে ১ করে বাড়ে।
enum Planet: Int {
    case mercury = 1, venus, earth, mars
}

print(Planet.earth.rawValue) // Prints 3

নির্দেশনা

এই অনুশীলনীতে আপনি লগ লাইন প্রসেস করবেন।

প্রতিটি লগ লাইন একটি স্ট্রিং, যার ফরম্যাট নিম্নরূপ: "[<LVL>]: <MESSAGE>"।

লগ লেভেলগুলো নিম্নরূপ:

  • TRC (trace)
  • DBG (debug)
  • INF (info)
  • WRN (warning)
  • ERR (error)
  • FTL (fatal)

আপনার তিনটি কাজ আছে, প্রয়োজনীয় কার্যকারিতা সরবরাহ করতে এগুলোর প্রত্যেকটি সম্পন্ন করতে হবে।

1. LogLevel enum তৈরি করুন

এমন একটি LogLevel enum ডিফাইন করুন, যার উপরের লগ লেভেলগুলোর সাথে মিলে যাওয়া ছয়টি কেস থাকবে, এবং যেসব লেভেল অনুপস্থিত বা নন-স্ট্যান্ডার্ড, তাদের জন্য একটি unknown কেসও থাকবে।

  • trace
  • debug
  • info
  • warning
  • error
  • fatal
  • unknown

2. লগ লেভেল পার্স করুন

এরপর, একটি লগ লাইনের লগ লেভেল পার্স করার জন্য LogLevel-এর ইনিশিয়ালাইজার ইমপ্লিমেন্ট করুন:

LogLevel("[INF]: File deleted")
// Returns LogLevel.info
LogLevel("Something went wrong!")
// Returns LogLevel.unknown

3. লগ লাইনকে শর্ট ফরম্যাটে রূপান্তর করুন

একটি লগ লাইনের লগ লেভেল বেশ লম্বা হয়। লগ লাইনগুলো সংরক্ষণ করতে প্রয়োজনীয় ডিস্ক স্পেস কমাতে একটি শর্ট ফরম্যাট তৈরি করা হয়েছে: "<ENCODED_LEVEL>:<MESSAGE>"।

এনকোড করা লগ লেভেল হলো একটি লগ লেভেলের সাথে একটি সংখ্যার সহজ ম্যাপিং:

  • trace - 0
  • debug - 1
  • info - 4
  • warning - 5
  • error - 6
  • fatal - 7
  • unknown - 42

shortFormat(message: String) -> String মেথডটি ইমপ্লিমেন্ট করুন, যা সংক্ষিপ্ত লগ লাইন ফরম্যাটকে একটি String হিসেবে আউটপুট দিতে পারবে:

let overflow = LogLevel.error
overflow.shortFormat(message: "Stack overflow")
// Returns "6:Stack overflow"
GitHub-এর মাধ্যমে সম্পাদনা করুন লিংকটি একটি নতুন উইন্ডো বা ট্যাবে খোলে
Swift Exercism

লগ লাইন শুরু করতে প্রস্তুত?

Exercism-এ সাইন আপ করুন, Swift ট্র্যাকের 35টি কনসেপ্ট116টি অনুশীলনী আর সত্যিকারের মানুষের মেন্টরিং দিয়ে শিখুন ও দক্ষ হয়ে উঠুন, সম্পূর্ণ বিনামূল্যে।