iooops 发表于 2016-3-29 09:34:18

【Python入门系列2】Event-driven Programming


上课笔记。
这周讲到了Event-driven Programming。

先举个栗子,这是一个猜数字的小游戏:
# template for "Guess the number" mini-project
# input will come from buttons and an input field
# all output for the game will be printed in the console
import simplegui
import random

secret_number = 0
end = 100
remaining_guess = 7

# helper function to start and restart the game
def new_game():
      # initialize global variables used in your code here
      global secret_number
      global end
      secret_number = random.randrange(0, end)
   
      print "New game. Range is from 0 to", end
      print "Number of remaining guesses is", remaining_guess
      print ""


# define event handlers for control panel
def range100():
      # button that changes the range to [0,100) and starts a new game
      global remaining_guess
      remaining_guess = 7
   
      global end
      end = 100
   
      new_game()
   

def range1000():
      # button that changes the range to [0,1000) and starts a new game   
      global remaining_guess
      remaining_guess = 10
   
      global end
      end = 1000
   
      new_game()
   
def input_guess(guess):
      # main game logic goes here
      global secret_number
      global remaining_guess
   
      guessi = int(guess)
      print "Guess was", guessi
      remaining_guess -= 1
      print "Number of remaining guesses is", remaining_guess
   
      if guessi < secret_number:
                print "Higher"
      elif guessi > secret_number:
                print "Lower"
      else:
                print "Correct"
                print ""
                range100()
            
    print ""
   
   if remaining_guess == 0:
                print "You lose."
         print ""
                range100()

   
# create frame
frame = simplegui.create_frame("game", 200, 200)

# register event handlers for control elements and start frame
frame.add_button('Range is [0,100)', range100, 200)
frame.add_button('Range is [0,1000)', range1000, 200)

frame.add_input("Input your guess: ", input_guess, 50)



# call new_game
new_game()

# always remember to check your completed program against the grading rubric
http://www.codeskulptor.org/#user41_5azXiELlsx_1.py
这个网址要翻一下墙的哈 - -
而且由于simpleGUI这个API的特殊性,貌似只能在codeskulpter网站运行。
点开运行了之后是这样的:

运行结果是这样的:
New game. Range is from 0 to 100
Number of remaining guesses is 7

Guess was 25
Number of remaining guesses is 6
Higher

Guess was 50
Number of remaining guesses is 5
Lower

Guess was 38
Number of remaining guesses is 4
Lower

Guess was 31
Number of remaining guesses is 3
Higher

Guess was 34
Number of remaining guesses is 2
Lower

Guess was 33
Number of remaining guesses is 1
Lower

Guess was 32
Number of remaining guesses is 0
Correct

New game. Range is from 0 to 100
Number of remaining guesses is 7

这个module的重点是,event-driven programming的思想。



我们知道,一般玩个什么游戏、使个什么交互应用,每次有不同的操作,就会产生不同的结果。
如下图所示,初始化之后,根据用户的操作,会产生不同的触发事件,当有input event进来的时候,就会等待handler来进行处理,知道最后程序运行结束。


event的种类常见的以下几种:


一般使用下面的program structure是比较合理而符合人的认知以及写代码结构的:

那么这就是刚才的小program里的代码编写顺序。


几点需要注意的tips:
1. 全局变量与局部变量
Python与其他编程语言比较相异的一点是,Python对于变量的定义区分基本上是没有的- -。
因此就会产生一点需要注意的问题。
num1 = 1
print "num1 =", num1

def fun():
            num2 = num1 + 1
            print "num2 =", num2

fun()

print "num1 =", num1
print "num2 =", num2运行这个Python文件,输出结果是这样的:
num1 = 1
num2 = 2
num1 = 1
num2 =
Traceback (most recent call last):
    Line 11, in <module>
      print "num2 =", num2
NameError: name 'num2' is not defined出现了一个NameError,这是为什么呢?
因为在函数体内部定义的变量是局部变量,当程序执行调用函数体的时候才会产生,当函数体调用结束后这个局部变量也就随之消失了。因此在全局中要求输出num2的时候它已经不在了。
而全局变量则不然,它是随着程序一直存在的。

把上面的例子改一改:
num1 = 1
print "num1 =", num1

def fun():
            num1 = 2
            num2 = num1 + 1
            print "num2 =", num2

fun()

print "num1 =", num1运行结果是:
num1 = 1
num2 = 3
num1 = 1我们看到,最后输出的num1还是全局变量的num1,而非函数体中的那一个,函数体中的那一个早就随函数调用的结束消失了。

那么,如果我们要在函数中用到全局变量,我们应该怎么用呢?
在函数中变量前加global申明即可。
如下例所示:
num = 4

def fun1():
            global num
            num = 5

def fun2():
            global num
            num = 6

print num
fun1()
print num
fun2()
print num运行结果是:
4
5
6
2.输入值的转换
在课上使用的simpleGUI的API中,使用add_input这个接口输入的值都是string类型的,因此如果我们需要数字,必须进行强制类型转换。
在开头的例子中,用的是这行代码:
guessi = int(guess)
3. 代码规范(参见Python官方文档https://docs.python.org/release/2.6.8/tutorial/controlflow.html#intermezzo-coding-style)
提高易读性,减少易错性。

[*]    Use 4-space indentation, and no tabs.
         4 spaces are a good compromise between small indentation (allows greater nesting depth) and large indentation (easier to read). Tabs introduce confusion, andare best left out.
[*]    Wrap lines so that they don’t exceed 79 characters.
[*]    This helps users with small displays and makes it possible to have several code files side-by-side on larger displays.
[*]    Use blank lines to separate functions and classes, and larger blocks of code inside functions.
[*]    When possible, put comments on a line of their own.
[*]    Use docstrings.
[*]    Use spaces around operators and after commas, but not directly inside bracketing constructs: a = f(1, 2) + g(3, 4).
[*]    Name your classes and functions consistently; the convention is to use CamelCase for classes and lower_case_with_underscores for functions and methods. Always use self as the name for the first method argument (see A First Look at Classes for more on classes and methods).
[*]    Don’t use fancy encodings if your code is meant to be used in international environments. Plain ASCII works best in any case.




凌风清羽 发表于 2016-3-29 15:46:44

好长~{:5_169:}
页: [1]
查看完整版本: 【Python入门系列2】Event-driven Programming