ট্র্যাক
/
Java
Java
/
অনুশীলনী
/
ক্যালকুলেটরের ধাঁধা
ক্যালকুলেটরের ধাঁধা

ক্যালকুলেটরের ধাঁধা

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

ভূমিকা

এক্সেপশন

Java প্রোগ্রামিং ভাষা এরর এবং অন্যান্য অস্বাভাবিক ঘটনা সামলাতে এক্সেপশন ব্যবহার করে।

এক্সেপশন কী

এক্সেপশন হলো প্রোগ্রাম চালানোর সময় ঘটে যাওয়া এমন একটি ঘটনা, যা নির্দেশনার স্বাভাবিক প্রবাহকে ব্যাহত করে। Java-তে এক্সেপশন স্পষ্টভাবে রেইজ করা হয়, আর একটি এক্সেপশন রেইজ করার কাজটিকে বলা হয় এক্সেপশন থ্রো করা। একটি এক্সেপশন সামলানোর কাজটিকে বলা হয় এক্সেপশন ক্যাচ করা।

Java-তে সব এক্সেপশনই Exception ক্লাসের সাবক্লাস, আর Exception নিজেই Throwable-এর সাবক্লাস।

Java দুই ধরনের এক্সেপশন আলাদা করে:

  1. চেকড এক্সেপশন
  2. আনচেকড এক্সেপশন
চেকড এক্সেপশন

চেকড এক্সেপশন হলো এমন অস্বাভাবিক অবস্থা, যা একটি অ্যাপ্লিকেশন আগে থেকেই আঁচ করতে পারে এবং তা থেকে সামলে উঠতে পারে। একটি চেকড এক্সেপশনের উদাহরণ হলো FileNotFoundException, যা ঘটে যখন কোনো মেথড এমন একটি ফাইল পড়তে চায় যেটি নেই।

এই ধরনের এক্সেপশন কম্পাইল-টাইমে চেক করা হয়: যে মেথডগুলো চেকড এক্সেপশন থ্রো করে, তাদের মেথড সিগনেচারে তা উল্লেখ করা উচিত, আর যে কোড এমন কোনো মেথড কল করে যেটি চেকড এক্সেপশন থ্রো করতে পারে, সেটি সামলানো তার জন্য বাধ্যতামূলক, নাহলে কোডটি কম্পাইল হবে না।

সব চেকড এক্সেপশনই Exception-এর সাবক্লাস, যেগুলো RuntimeException-কে এক্সটেন্ড করে না।

আনচেকড এক্সেপশন

আনচেকড এক্সেপশন হলো এমন অস্বাভাবিক অবস্থা, যা একটি অ্যাপ্লিকেশন সাধারণত আগে থেকে আঁচ করতে বা তা থেকে সামলে উঠতে পারে না। একটি আনচেকড এক্সেপশনের উদাহরণ হলো NullPointerException, যা ঘটে যখন কোনো মেথড একটি নন-নাল মান আশা করে কিন্তু null পায়।

এই ধরনের এক্সেপশন কম্পাইল-টাইমে চেক করা হয় না: যে মেথডগুলো আনচেকড এক্সেপশন থ্রো করে, তাদের মেথড সিগনেচারে তা উল্লেখ করা বাধ্যতামূলক নয়, আর যে কোড এমন কোনো মেথড কল করে যেটি আনচেকড এক্সেপশন থ্রো করতে পারে, সেটি সামলানোও বাধ্যতামূলক নয়।

সব আনচেকড এক্সেপশনই RuntimeException থেকে ইনহেরিট করে, যা নিজে Exception-এর একটি এক্সটেনশন।

এক্সেপশন থ্রো করা

Java-তে একটি মেথড throw স্টেটমেন্ট ব্যবহার করে একটি এক্সেপশন থ্রো করতে পারে।

একটি চেকড এক্সেপশন থ্রো করা

কোনো মেথড থেকে চেকড এক্সেপশন থ্রো করার সময় throws কিওয়ার্ড ব্যবহার করে মেথড সিগনেচারে তা উল্লেখ করা বাধ্যতামূলক, যেমনটা নিচের উদাহরণে দেখানো হয়েছে। এতে কল করা কোড বাধ্য হয় আগে থেকেই ধরে নিতে যে একটি এক্সেপশন থ্রো হতে পারে, এবং সেই অনুযায়ী তা সামলে নিতে হয়।

public class InsufficientBalanceException extends Exception {

}

public class BankAccount {
  public void withdraw(double amount) throws InsufficientBalanceException {
    if (balance < amount) {
      throw new InsufficientBalanceException();
    }

    // rest of the method implementation
  }
}
একটি আনচেকড এক্সেপশন থ্রো করা

কোনো মেথড থেকে আনচেকড এক্সেপশন থ্রো করার সময় মেথড সিগনেচারে তা উল্লেখ করা বাধ্যতামূলক নয়, যদিও এটি সমর্থিত।

public class BankAccount {
  public void withdraw(double amount) {
    if (amount < 0) {
      throw new IllegalArgumentException("Cannot withdraw a negative amount");
    }

    // rest of the method implementation
  }
}

এক্সেপশন সামলানো

Java-তে এক্সেপশন সামলানো হয় try, catch ও finally কিওয়ার্ড দিয়ে।

  • যে কোড স্টেটমেন্টগুলো একটি এক্সেপশন থ্রো করতে পারে, সেগুলো একটি try ব্লকে মুড়ে দেওয়া উচিত।
  • try ব্লকের পরে থাকে এক বা একাধিক catch ব্লক, যেগুলো try ব্লকে থ্রো হওয়া এক্সেপশনগুলো ক্যাচ করে।
  • catch ব্লকগুলোর পরে ঐচ্ছিকভাবে থাকে একটি finally ব্লক, যা try ব্লকের পরে সবসময়ই চলে, এক্সেপশন থ্রো হোক বা না হোক।

নিচের উদাহরণে দেখা যায় এই কিওয়ার্ডগুলো কীভাবে কাজ করে:

public class ATM {
  public void withdraw(BankAccount bankAccount, double amount) {
    try {
      System.out.println("Withdrawing " + amount);
      bankAccount.withdraw(amount);
      System.out.println("Withdrawal succeeded");
    } catch (InsufficientBalanceException) {
      System.out.println("Withdrawal failed: insufficient balance");
    } catch (RuntimeException e) {
      System.out.println("Withdrawal failed: " + e.getMessage());
    } finally {
      System.out.println("Current balance: " + bankAccount.getBalance());
    }
  }
}

এই উদাহরণে, কোনো এক্সেপশন থ্রো না হলে নিচের লেখাটি প্রিন্ট হয়:

Withdrawing 10.0
Withdrawal succeeded
Current balance: 5.0

কিন্তু যদি bankAccount.withdraw(amount) স্টেটমেন্টটি একটি InsufficientBalanceException থ্রো করে, তাহলে নিচের লেখাটি প্রিন্ট হয়:

Withdrawing 10.0
Withdrawal failed: insufficient balance
Current balance: 5.0

অথবা, যদি bankAccount.withdraw(amount) কোনো আনচেকড এক্সেপশন থ্রো করে, তাহলে নিচের লেখাটি প্রিন্ট হয়:

Withdrawing -10.0
Withdrawal failed: Cannot withdraw a negative amount
Current balance: 5.0

এরর

Java-তে এরর নামে আরেকটি আলাদা শ্রেণিও আছে, যেগুলো অ্যাপ্লিকেশনের বাইরের গুরুতর সমস্যা। একটি এররের উদাহরণ হলো OutOfMemoryError, যা ঘটে যখন কোনো অ্যাপ্লিকেশন সিস্টেমে থাকা মেমোরির চেয়ে বেশি মেমোরি ব্যবহার করতে চায়।

আনচেকড এক্সেপশনের মতোই, এররও কম্পাইল-টাইমে চেক করা হয় না। পার্থক্য হলো, এগুলো সিস্টেম-স্তরের সমস্যা বোঝায় এবং সাধারণত অ্যাপ্লিকেশনের বদলে Java Virtual Machine বা এনভায়রনমেন্ট থ্রো করে। অ্যাপ্লিকেশনগুলোর সাধারণত এগুলো ক্যাচ করার বা সামলানোর চেষ্টা করা উচিত নয়।

Java-তে সব এররই Error ক্লাস থেকে ইনহেরিট করে।

নির্দেশনা

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

লক্ষ্য হলো এমন একটি কার্যকর ক্যালকুলেটর তৈরি করা, যা 16, 51 এবং + আর্গুমেন্ট পেলে নিচের প্যাটার্ন অনুসারে একটি স্ট্রিং রিটার্ন করবে: 16 + 51 = 67।

CalculatorConundrum calculator = new CalculatorConundrum();

calculator.calculate(16, 51, "+");
// => returns "16 + 51 = 67"

calculator.calculate(32, 6, "*");
// => returns "32 * 6 = 192"

calculator.calculate(512, 4, "/");
// => returns "512 / 4 = 128"

1. কয়েকটি মৌলিক অপারেশন সমর্থন করার জন্য calculate মেথডটি ইমপ্লিমেন্ট করুন

এই কাজে ইমপ্লিমেন্ট করার মূল মেথডটি হবে CalculatorConundrum.calculate() মেথড। এটি তিনটি আর্গুমেন্ট নেয়। প্রথম দুটি আর্গুমেন্ট operand1 ও operand2 হলো দুটি ইন্টিজার সংখ্যা, যেগুলোর উপর একটি অপারেশন চালানো হবে। তৃতীয় আর্গুমেন্ট operation হলো স্ট্রিং টাইপের, এবং এই অনুশীলনীতে নিচের অপারেশনগুলো ইমপ্লিমেন্ট করা প্রয়োজন:

  • + স্ট্রিং ব্যবহার করে যোগ
  • * স্ট্রিং ব্যবহার করে গুণ
  • / স্ট্রিং ব্যবহার করে ভাগ

2. অবৈধ অপারেশন হ্যান্ডেল করুন

অবৈধ অপারেশন হ্যান্ডেল করার জন্য CalculatorConundrum.calculate() মেথডটি আপডেট করুন:

  • operation আর্গুমেন্টটি null হলে, Operation cannot be null মেসেজসহ একটি IllegalArgumentException থ্রো করা উচিত।
  • operation আর্গুমেন্টটি "" হলে, Operation cannot be empty মেসেজসহ একটি IllegalArgumentException থ্রো করা উচিত।
  • operation আর্গুমেন্টটি +, * বা / ছাড়া অন্য কোনো অপারেশন হলে, Operation '{operation}' does not exist মেসেজসহ একটি IllegalOperationException থ্রো করা উচিত।
calculator.calculate(10, 1, null);
// => throws IllegalArgumentException with message "Operation cannot be null"

calculator.calculate(10, 1, "");
// => throws IllegalArgumentException with message "Operation cannot be empty"

calculator.calculate(10, 1, "-");
// => throws IllegalOperationException with message "Operation '-' does not exist"

3. শূন্য দিয়ে ভাগ করলে যে এক্সেপশন থ্রো হয় তা হ্যান্ডেল করুন

Java-তে শূন্য দিয়ে ভাগ করার চেষ্টা করলে একটি ArithmeticException থ্রো হয়। এই এক্সেপশনটি ক্যাচ করে Division by zero is not allowed মেসেজ ও ক্যাচ করা ArithmeticException-টিকে কারণ হিসেবে নিয়ে একটি IllegalOperationException থ্রো করার জন্য CalculatorConundrum.calculate() মেথডটি আপডেট করুন।

calculator.calculate(512, 0, "/");
// => throws IllegalOperationException with message "Division by zero is not allowed"
GitHub-এর মাধ্যমে সম্পাদনা করুন লিংকটি একটি নতুন উইন্ডো বা ট্যাবে খোলে
Java Exercism

ক্যালকুলেটরের ধাঁধা শুরু করতে প্রস্তুত?

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