2 Basic Mathematical Operations 8kyu


Posted by mijouhsieh on 2024-01-05

8kyu Basic Mathematical Operations


1 題目說明:

函式做基本的數學四則運算,依運算子 return 數值結果
函式接受 3 個參數:

  • operation(string/char)
  • value1(number)
  • value2(number)

Examples(Operator, value1, value2) --> output

('+', 4, 7) --> 11
('-', 15, 18) --> -3
('*', 5, 5) --> 25
('/', 49, 7) --> 7

2 code:

export function basicOp(operation: string, value1: number, value2: number): number {
  // Good luck!
  if(operation === '+') {
    return value1 + value2
  } else if (operation === '-') {
    return value1 - value2
  } else if (operation === '*') {
    return value1 * value2
  } else {                   // 可再優化: 除法之外的運算子
    return value1 / value2   // 可再優化: 除法 分母不可為0
  }
}

3 修改code

題目 定義函式回傳值類型為數字,比如返回0或者NaN (Not a Number),以表明當出現無效操作時的特殊情況。確保函式在所有可能的程式路徑上都返回一個數字。

wiki 除以零是一個沒有定義的值。

export function basicOp(operation: string, value1: number, value2: number): number {
  // Good luck!
  if(operation === '+') {
    return value1 + value2;
  } else if (operation === '-') {
    return value1 - value2;
  } else if (operation === '*') {
    return value1 * value2;
  } else if (operation === '/') {
     if (value2 === 0) {  //除法 分母不能為0
        return "NaN"; // 或者 return 0;
      }
    return value1 / value2;
  } else {
    return NaN; // 或者 return 0;
  }
}

MDN NaN

console.log(typeof NaN) //number

4 ChatGTP提醒:

一些邊界條件需要考慮進去。
若 operation 不是 "+""-""*""/" 時,函式就沒有返回值。這樣在 TypeScript 中會被解釋為函式可能返回 undefined。
加上一個 else 區塊來返回一個預設值或者拋出一個錯誤。
除法,若 value2 是 0 的話,這樣會導致除以零的錯誤

5 進行優化:

  • Switch Statement: 使用 switch 語句來取代多個 if-else。可使程式碼更易讀且更簡潔。
  • 錯誤處理: 增加錯誤處理,當操作符號不是你預期的四種之一時,可返回一個錯誤訊息。

優化 函式回傳值 type annotation: 聯合型別 Union Types : number | string 才能 return 字串

export function basicOp(operation: string, value1: number, value2: number): number | string {
  switch(operation) {
    case '+':
      return value1 + value2;
    case '-':
      return value1 - value2;
    case `*`:
      return value1 * value2;
    case '/':
      if (value2 === 0) {  //除法 分母不能為0
        return "Cannot divide by zero";
      }
      return value1 / value2;
    default:
      return "Invalid operation"; //加減乘除之外的運算子
  }
}

優化 函式回傳值 type annotation: 聯合型別 Union Types : number | string

6 語法

throw

throw 是一個 JavaScript / TypeScript 中的關鍵字,用於拋出一個異常(或錯誤)。

當程式執行到 throw 時,它會立即停止並跳轉到最近的能夠處理這個錯誤的程式碼塊。若沒有處理這個錯誤的程式碼,這個異常將會被傳遞到呼叫這個函式的地方,或者如果這個函式是頂層函式的話,它將會成為一個未處理的全局異常。

在上面的代碼中,throw new Error("Invalid operation"); 就是當 operation 不是 '+', '-', '*' 或 '/' 任何一個時拋出的錯誤。這樣做的好處是可以清楚地指示這是一個錯誤情況,並且如果程式碼中有合適的地方來處理這個錯誤,可以讓程式流程更加清晰。

else {
  throw new Error("Invalid operation");
}

7 submit code

export function basicOp(operation: string, value1: number, value2: number): number {
  // Good luck!
  if(operation === '+') {
    return value1 + value2;
  } else if (operation === '-') {
    return value1 - value2;
  } else if (operation === '*') {
    return value1 * value2;
  } else if (operation === '/') {
     if (value2 === 0) {  //除法 分母不能為0
        return NaN; // 或 return 0;
      }
    return value1 / value2;
  } else {
    return NaN; // 或 return 0;
  }
}

8 RECAP

  • if/ else => switch
  • else {...} 要考慮4個加減乘除外,可能的因素
  • 除法 分母不能為0。 除以零是一個沒有定義的值。

有錯誤回傳 字串型別

  1. 函式回傳值的type annotation為 聯合型別 Union Types : number | string
  2. return "Invalid operation" 返回一個錯誤訊息。
  3. throw new Error("Invalid operation") 拋出一個錯誤,而不是讓函式可能返回 undefined。

有錯誤回傳 number型別

  1. return NaN
  2. return 0

switch 用法 (補)

throw 用法 (補)


9 觀摩

const ops = {
  "+": (l, r) => l + r,
  "-": (l, r) => l - r,
  "*": (l, r) => l * r,
  "/": (l, r) => l / r,
}
export const basicOp = (operation: keyof typeof ops, value1: number, value2: number): number => (
  ops[operation](value1, value2)
)
  • operation 的類型被限制為 ops 物件的鍵(keyof typeof ops),也就是 +, -, *, / 這些字串中的一個。

basicOp 函式的主要功能是通過 ops 物件 根據指定的操作符號調用對應的函式來執行運算。它會從 ops 中找到與 operation 相符的函式,然後將 value1 和 value2 傳遞給該函式進行運算,最終返回運算結果。

這樣的寫法非常簡潔和有效率,因為它使用了物件來組織和映射不同的操作符號和對應的函式,使得代碼易於閱讀和維護。


測試

import {basicOp} from "./solution";
import {assert} from "chai";

describe('basicOp', () => {
  it('basic tests', () => {
    assert.strictEqual(basicOp('+', 4, 7), 11);
    assert.strictEqual(basicOp('-', 15, 18), -3);
    assert.strictEqual(basicOp('*', 5, 5), 25);
    assert.strictEqual(basicOp('/', 49, 7), 7);
  })
})

#TypeScript #if/else #switch #NaN #throw







Related Posts

React(19) - ErrorBoundary

React(19) - ErrorBoundary

Estimation – ML & MAP 介紹

Estimation – ML & MAP 介紹

AI輔導室|立體環形文字

AI輔導室|立體環形文字


Comments