5167浏览
查看: 5167|回复: 1

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

[复制链接]

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

先举个栗子,这是一个猜数字的小游戏:
  1. # template for "Guess the number" mini-project
  2. # input will come from buttons and an input field
  3. # all output for the game will be printed in the console
  4. import simplegui
  5. import random
  6. secret_number = 0
  7. end = 100
  8. remaining_guess = 7
  9. # helper function to start and restart the game
  10. def new_game():
  11.         # initialize global variables used in your code here
  12.         global secret_number
  13.         global end
  14.         secret_number = random.randrange(0, end)
  15.    
  16.         print "New game. Range is from 0 to", end
  17.         print "Number of remaining guesses is", remaining_guess
  18.         print ""
  19. # define event handlers for control panel
  20. def range100():
  21.         # button that changes the range to [0,100) and starts a new game
  22.         global remaining_guess
  23.         remaining_guess = 7
  24.    
  25.         global end
  26.         end = 100
  27.    
  28.         new_game()
  29.    
  30. def range1000():
  31.         # button that changes the range to [0,1000) and starts a new game     
  32.         global remaining_guess
  33.         remaining_guess = 10
  34.    
  35.         global end
  36.         end = 1000
  37.    
  38.         new_game()
  39.    
  40. def input_guess(guess):
  41.         # main game logic goes here
  42.         global secret_number
  43.         global remaining_guess
  44.    
  45.         guessi = int(guess)
  46.         print "Guess was", guessi
  47.         remaining_guess -= 1
  48.         print "Number of remaining guesses is", remaining_guess
  49.    
  50.         if guessi < secret_number:
  51.                 print "Higher"
  52.         elif guessi > secret_number:
  53.                 print "Lower"
  54.         else:
  55.                 print "Correct"
  56.                 print ""
  57.                 range100()
  58.             
  59.     print ""
  60.    
  61.      if remaining_guess == 0:
  62.                 print "You lose."
  63.          print ""
  64.                 range100()
  65.    
  66. # create frame
  67. frame = simplegui.create_frame("game", 200, 200)
  68. # register event handlers for control elements and start frame
  69. frame.add_button('Range is [0,100)', range100, 200)
  70. frame.add_button('Range is [0,1000)', range1000, 200)
  71. frame.add_input("Input your guess: ", input_guess, 50)
  72. # call new_game
  73. new_game()
  74. # always remember to check your completed program against the grading rubric
复制代码
http://www.codeskulptor.org/#user41_5azXiELlsx_1.py
这个网址要翻一下墙的哈 - -
而且由于simpleGUI这个API的特殊性,貌似只能在codeskulpter网站运行。
点开运行了之后是这样的:
【Python入门系列2】Event-driven Programming图4
运行结果是这样的:
  1. New game. Range is from 0 to 100
  2. Number of remaining guesses is 7
  3. Guess was 25
  4. Number of remaining guesses is 6
  5. Higher
  6. Guess was 50
  7. Number of remaining guesses is 5
  8. Lower
  9. Guess was 38
  10. Number of remaining guesses is 4
  11. Lower
  12. Guess was 31
  13. Number of remaining guesses is 3
  14. Higher
  15. Guess was 34
  16. Number of remaining guesses is 2
  17. Lower
  18. Guess was 33
  19. Number of remaining guesses is 1
  20. Lower
  21. Guess was 32
  22. Number of remaining guesses is 0
  23. Correct
  24. New game. Range is from 0 to 100
  25. Number of remaining guesses is 7
复制代码

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



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

event的种类常见的以下几种:
【Python入门系列2】Event-driven Programming图2

一般使用下面的program structure是比较合理而符合人的认知以及写代码结构的:
【Python入门系列2】Event-driven Programming图3
那么这就是刚才的小program里的代码编写顺序。


几点需要注意的tips:
1. 全局变量与局部变量
Python与其他编程语言比较相异的一点是,Python对于变量的定义区分基本上是没有的- -。
因此就会产生一点需要注意的问题。
  1. num1 = 1
  2. print "num1 =", num1
  3. def fun():
  4.             num2 = num1 + 1
  5.             print "num2 =", num2
  6. fun()
  7. print "num1 =", num1
  8. print "num2 =", num2
复制代码
运行这个Python文件,输出结果是这样的:
  1. num1 = 1
  2. num2 = 2
  3. num1 = 1
  4. num2 =
  5. Traceback (most recent call last):
  6.     Line 11, in <module>
  7.         print "num2 =", num2
  8. NameError: name 'num2' is not defined
复制代码
出现了一个NameError,这是为什么呢?
因为在函数体内部定义的变量是局部变量,当程序执行调用函数体的时候才会产生,当函数体调用结束后这个局部变量也就随之消失了。因此在全局中要求输出num2的时候它已经不在了。
而全局变量则不然,它是随着程序一直存在的。

把上面的例子改一改:
  1. num1 = 1
  2. print "num1 =", num1
  3. def fun():
  4.             num1 = 2
  5.             num2 = num1 + 1
  6.             print "num2 =", num2
  7. fun()
  8. print "num1 =", num1
复制代码
运行结果是:
  1. num1 = 1
  2. num2 = 3
  3. num1 = 1
复制代码
我们看到,最后输出的num1还是全局变量的num1,而非函数体中的那一个,函数体中的那一个早就随函数调用的结束消失了。

那么,如果我们要在函数中用到全局变量,我们应该怎么用呢?
在函数中变量前加global申明即可。
如下例所示:
  1. num = 4
  2. def fun1():
  3.             global num
  4.             num = 5
  5. def fun2():
  6.             global num
  7.             num = 6
  8. print num
  9. fun1()
  10. print num
  11. fun2()
  12. print num
复制代码
运行结果是:
  1. 4
  2. 5
  3. 6
复制代码

2.  输入值的转换
在课上使用的simpleGUI的API中,使用add_input这个接口输入的值都是string类型的,因此如果我们需要数字,必须进行强制类型转换。
在开头的例子中,用的是这行代码:
  1. 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, and  are 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.




Screen Shot 2016-03-28 at 12.38.31 AM.png

凌风清羽  中级技匠

发表于 2016-3-29 15:46:44

好长~
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail