如何使用 Stone 的測試資料

處理 Stone 提供的測試資料

今天要來介紹 Stone 的輸入輸出功能. 你應該知道, 每當寫完一個程式, 經常會需要做各種測試, 驗證自己寫的程式是不是可以產生正確的結果, 所以我們經常會定義像是 test() 這樣的函數, 來測試我們寫的各種函數或類別.

例如, 以下程式 中的 test() 函數可以測試 double() 這個函數是不是可以正確運作:

def double(x):
  return x * 2

def test():
  if double(2) == 4:
    println("Correct")
  else:
    println("Wrong")

事實上, 有些 Stone 題目提供了測試資料, 讓使用者可以測試自己寫的程式是否正確.

例如, Stone 提供了一組輸入資料讓你測試 double() 函數, 像是這樣:

0
2
3.5

另外 Stone 也提供一組它所期待的輸出結果:

0
4
7

如果你寫了一個程式, 讀取輸入資料中的 0, 2, 3.5, 並且將這些數字透過 double() 函數算出 0, 4, 7, 然後印出和輸出結果一致的答案, 那就算通過了題目的測試資料.

因此想要通過測試, 我們必須完成兩個任務:

  1. 讀取輸入資料: 讀取題目提供的測試資料, 需要了解測試資料的格式, 依序讀取做為程式的輸入值.
  2. 符合輸出結果: 程式計算出答案之後, 還必須依照指定的格式將結果印出, 大小寫, 換行, 空白和標點符號都需要注意, 有任何和輸出結果不一致的地方就無法通過測試.

 

我們一起來看看幾個例子.

1. 逐行讀取字串

Jimmy
Henry

如果想逐行讀取字串, 可以像下面這樣做:

while hasln():
  var str = nextln()
  println("Hello " + str)

這樣程式會印出:

Hello Jimmy
Hello Henry

接著, Stone 會將這個輸出和結果比較, 如果題目設定的輸出結果是:

Hello Jimmy
Hello Henry

那比對結果會一致, 恭禧你通過測試.

但是, 如果輸出結果是:

hello Jimmy
hello Henry

這樣的輸出無法通過測試資料, 因為大小寫不同, 你必須修改自己的程式使得結果可以一致.

 

2. 逐行讀取數字

100
200
300

如果想逐行讀取數字, 可以這樣寫:

while hasln():
  var str = nextln()
  var num = math.number(str)
  println(num + 1)

這樣程式會印出:

101
201
301

注意程式中的 math.number() 可以將字串轉換為數字, 當然需要是有效的數字字串才行.

 

3. 讀取一行, 然後逐字讀取

sandwich hamburger burrito
coke juice water

如果想讀取一行, 然後逐字讀取, 可以這樣做:

while hasln():
  var line = nextln()
  var tokens = util.split(line, " ")
  for i from 1 to tokens.length-1:
    print(i + ":" + tokens[i] + " ")
  println()

這樣程式會印出:

1:sandwich 2:hamburger 3:burrito 
1:coke 2:juice 3:water 

注意印出的結果的每一行最後都有一個空白, 有時題目設定的輸出結果是每一行最後沒有空白, 這個時候就要想辦法不在每一行的最後印出空白, 否則就無法通過測試.

 

4. 讀取一行, 然後一個一個讀取數字

10 20 30
100 200 300

如果想讀取一行, 然後逐個數字讀取, 可以這樣做:

while hasln():
  var line = nextln()
  var tokens = util.split(line, " ")
  for i from 1 to tokens.length-1:
    var num = math.number(tokens[i])
    print(num + 1 + " ")
  println()

這樣的程式會印出:

11 21 31
101 201 301

了解以上幾個範例之後, 應該對於題目的測試有基本的了解了.

 

處理 grid 的老鼠和鍵盤事件

在這裡, 我們也一起複習一下 grid 如何處理老鼠和鍵盤的事件, 請看以下範例:

import grid

def clk(r, c):
  println(r + " " + c + " clicked")

def kk(keyCode, ch):
  println(keyCode + " " + ch + " typed")

def start():
  grid.onClick(clk)
  grid.onKey(kk)

老鼠事件, 需要使用 grid 中的 onClick() 函數, 點擊 grid 的某一格, 會呼叫 clk() 函數, 並帶入點擊的位置 r 和 c, 也就是在哪一列的哪一行.

在以上程式, 我們先在 start() 函數中使用 grid.onClick(clk) 告訴 grid 是 clk() 函數要處理老鼠事件, 現在我們點擊 grid 上的 (4, 5) 這一格, clk() 函數就會被執行, 且帶入輸入值 r=4, c=5.

鍵盤事件, 需要使用 grid 中的 onKey() 函數, 在 grid 上任何地方點擊一下, 然後任意打鍵盤上的任一按鍵, 會呼叫 kk() 函數, 並帶入按鍵的號碼和字母.

在以上程式, 我們先在 start() 函數中使用 grid.onKey(kk) 告訴 grid 是 kk() 函數要處理老鼠事件, 現在我們點擊 grid 上的任何地方 (讓瀏覽器知道現在要使用 grid), 然後再鍵盤上敲擊任何一個按鍵, kk() 函數就會被執行, 並帶入按鍵代碼 keyCode 和按鍵字母 ch, 例如向上鍵的 keyCode 會是 38, ch 會是 "up". 想了解更多按鍵可以搜尋 "javascript key table".