底下簡單說明一下test.py的內容:
程式開頭先導入需要使用的模組,另外因為要處理中文,所以程式開頭要加上 #coding=utf-8#coding=utf-8 #編碼要改成utf8 拿資料有中文才不會錯 import cgi import webapp2 import time from google.appengine.api import users from random import *接下來的部分是我們希望GAE顯示的網頁形式,底下是連線至網址時顯示的網頁內容,注意MAIN_PAGE_HTML 和程式中 class MainPage 裡 get(self)函數呼叫指令的對應 self.response.write(MAIN_PAGE_HTML)。 另外注意 name="myname"以及 name="PName",這在之後我們會使用 self.request.get 得到對應的值 請參考HTML Forms and Google App Engine
MAIN_PAGE_HTML = """ <html> <body> <p> 這是一個簡單的GAE程式,首先輸入你的姓名,接著輸入兩個數字,程式會計算並顯示和。 </p> <form action="/" method="post"> <p> Your Name</p> <div> <input type="text" name="myname" /> <input type="submit" name="PName" value="Submit"> </div> </form> <a href = "http://math.ncku.edu.tw/~mhchen/computer/mytest.zip"> Source Code</a> </body> </html> """第二個網頁除了顯示結果外,還有輸入的部分,較為複雜,所以把網頁分成三部分,header、程式輸出部分、以及 footer。header的部分主要是一些網頁的設定,還有輸入表單的設定:
LOG_PAGE_HEADER_TEMPLATE = """ <html> <head> <meta http-equiv="Content-Language" content="zh-tw" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title> Name Fight</title> <style type="text/css"> .style1 { text-align: center; } .style2 { font-size: x-large; } </style> </head> <body> <h3> Result</h3> <hr> <h3> Options</h3> <!form name="input" action="/play" method="post"!> <form name="input" action="/" method="post"> <a href="/"> <button type="button"> Replay</button> </a> <h4> A + B =?</h4> <div> A: <input type="text" name="num1" /> B: <input type="text" name="num2" /> <input type="submit" name="step" value="Sum"> </div> </form> <hr> <pre> """網頁底部的部分,主要是結尾,沒有特別的地方
LOG_PAGE_FOOTER_TEMPLATE = """\ </pre> <hr> </body> </html> """FINAL_PAGE_HEADER_TEMPLATE 和 FINAL_PAGE_FOOTER_TEMPLATE 是LOG_PAGE的簡化版,所以略過。 接著說明主程式MainPage部分: 一開始的 self.response.write(MAIN_PAGE_HTML) 會把前面給的MAIN_PAGE_HTML (字串)顯示出來
class MainPage(webapp2.RequestHandler): def get(self): self.response.write(MAIN_PAGE_HTML)接著的 post 函數是主要執行的部分,注意先前的輸入表單部分都有 method="post"。 由於有些變數在大部分的函數中出現,所以我們使用global 宣告,另外你自己定義的函數也建議先定義在開頭的地方
#class Playbook(webapp2.RequestHandler): def post(self): global player1 global hp1 global i global showlist global board,boardsize,xinx global ship_row, ship_col ########################### # Define your functions here # 在此定義你會使用到的函數 ############################ html_txt= u'' # hp_msg = "{0}擲出點數{1},目前點數{2}\n" # hp_msg_u = u"{0}擲出點數{1},目前點數{2}\n" # hp_old_msg_u = u"{0}目前點數{1}\n" sum_msg = "A = {0}, B= {1}; A+B = {2}\n" hello_msg = "Hello {0}\n"上面的sum_msg 以及 hello_msg是字串,但是我們使用了格式化的功能,讓我們可以自行填入{0}、{1}、{2}的值 接著我們使用 self.request.get 取得 PName 還有 myname 的值,另外 ".encode('utf-8')"主要是由於網頁設定為utf-8 另外注意 hello_msg.format(myname) 的使用
s_input = self.request.get('PName') if s_input != '': myname = self.request.get('myname').encode('utf-8') html_txt= hello_msg.format(myname) i = i+1 showlist.append(html_txt)接著我們使用 self.request.get 取得 step、num1、num2的值,由於這些值是字串,所以如果要做為數值使用需使用int(整數) 或是float(浮點數)轉換
step = self.request.get('step') flag_end = "N" if step != '': i = i + 1 # dice = randint(1,6) num1 = self.request.get('num1').encode('utf-8') num2 = self.request.get('num2').encode('utf-8') num_A = int(num1) num_B = int(num2) html_txt= html_txt + sum_msg.format(num_A,num_B,num_A+num_B)在取得輸入資料後,我們可以開始處理我們的問題,以battleship遊戲為例,我們可以先判斷是否有擊中敵艦
# if-elif-else (Determine if you hit the ship # # end of if showlist.append(html_txt)底下的 my_def() 函數的功能是把先前的記錄顯示出來
def my_def(): #print previous messages self.response.write('<hr> <h3> Log</h3> ') for j in range(0,i): self.response.write('<h4> Round %s </h3> ' % cgi.escape(str(i-j-1))) self.response.write('<blockquote> %s</blockquote> ' % cgi.escape(showlist[i-j-1]))在判斷是否擊中後,可以改變 flag_end 的值來變換顯示網頁,由於顯示網格有點複雜,所以我先把 呼叫 print_board(board) 的部分給註解,先不執行
if flag_end == "N": self.response.write(LOG_PAGE_HEADER_TEMPLATE) # print_board(board) self.response.write('<h3> Round %s </h3> ' % cgi.escape(str(i))) self.response.write(html_txt) my_def() self.response.write(LOG_PAGE_FOOTER_TEMPLATE) else: self.response.write(FINAL_PAGE_HEADER_TEMPLATE) # print_board(board) self.response.write('<h3> Round %s </h3> ' % cgi.escape(str(i))) self.response.write(html_txt) my_def() self.response.write(FINAL_PAGE_FOOTER_TEMPLATE) i = 0 showlist = [] board = [] xinx = []最底下底下的部分告訴Server網頁由哪個Handler處理:"/"由class MainPage處理。 另外 app 對應到 app.yaml 裡的script: test.app 的副檔名 app
app = webapp2.WSGIApplication([ ('/', MainPage), # ('/play', Playbook), ], debug=True)Last Modified 6/6/2014