当前位置: 首页 > news >正文

Python 小型项目大全 21~25

二十一、DNA 可视化

原文:http://inventwithpython.com/bigbookpython/project21.html

脱氧核糖核酸是一种微小的分子,存在于我们身体的每个细胞中,包含着我们身体如何生长的蓝图。它看起来像一对核苷酸分子的双螺旋结构:鸟嘌呤、胞嘧啶、腺嘌呤和胸腺嘧啶。这些用字母 G、C、A 和 T 来表示。DNA 是一个长分子;它是微观的,但是如果把它拉长,它的 30 亿个碱基对会有 2 米长!这个程序是一个简单的 DNA 动画。

运行示例

当您运行dna.py时,输出将如下所示:

DNA Animation, by Al Sweigart email@protected
Press Ctrl-C to quit...#G-C##C---G##T-----A##T------A##A------T##G-----C##G---C##C-G####T-A##C---G##G-----C##G------C##T------A##A-----T##C---G##G-C####T-A##T---A##A-----T#
`--snip--`

工作原理

与项目 15“深坑”和项目 20“数字雨”类似,这个程序通过打印ROWS列表中的字符串来创建滚动动画。使用format()字符串方法将 AT 和 CG 对插入到每个字符串中。

"""DNA, by Al Sweigart email@protected
A simple animation of a DNA double-helix. Press Ctrl-C to stop.
Inspired by matoken https://asciinema.org/a/155441
This code is available at https://nostarch.com/big-book-small-python-programming
Tags: short, artistic, scrolling, science"""import random, sys, timePAUSE = 0.15  # (!) Try changing this to 0.5 or 0.0.# These are the individual rows of the DNA animation:
ROWS = [#123456789 <- Use this to measure the number of spaces:'         ##',  # Index 0 has no {}.'        #{}-{}#','       #{}---{}#','      #{}-----{}#','     #{}------{}#','    #{}------{}#','    #{}-----{}#','     #{}---{}#','     #{}-{}#','      ##',  # Index 9 has no {}.'     #{}-{}#','     #{}---{}#','    #{}-----{}#','    #{}------{}#','     #{}------{}#','      #{}-----{}#','       #{}---{}#','        #{}-{}#']#123456789 <- Use this to measure the number of spaces:try:print('DNA Animation, by Al Sweigart email@protected')print('Press Ctrl-C to quit...')time.sleep(2)rowIndex = 0while True:  # Main program loop.# Increment rowIndex to draw next row:rowIndex = rowIndex + 1if rowIndex == len(ROWS):rowIndex = 0# Row indexes 0 and 9 don't have nucleotides:if rowIndex == 0 or rowIndex == 9:print(ROWS[rowIndex])continue# Select random nucleotide pairs, guanine-cytosine and# adenine-thymine:randomSelection = random.randint(1, 4)if randomSelection == 1:leftNucleotide, rightNucleotide = 'A', 'T'elif randomSelection == 2:leftNucleotide, rightNucleotide = 'T', 'A'elif randomSelection == 3:leftNucleotide, rightNucleotide = 'C', 'G'elif randomSelection == 4:leftNucleotide, rightNucleotide = 'G', 'C'# Print the row.print(ROWS[rowIndex].format(leftNucleotide, rightNucleotide))time.sleep(PAUSE)  # Add a slight pause.
except KeyboardInterrupt:sys.exit()  # When Ctrl-C is pressed, end the program. 

探索程序

试着找出下列问题的答案。尝试对代码进行一些修改,然后重新运行程序,看看这些修改有什么影响。

  1. 如果把第 42 行的rowIndex = rowIndex + 1改成rowIndex = rowIndex + 2会怎么样?
  2. 如果把 53 行的random.randint(1, 4)改成random.randint(1, 2)会怎么样?
  3. 如果将第 9 行的PAUSE = 0.15设置为PAUSE = -0.15,会得到什么错误信息?

二十二、小鸭子

原文:http://inventwithpython.com/bigbookpython/project22.html

这个程序创建了一个滚动的小鸭场。每只小鸭子都略有不同:它们可以面向左边或右边,有两种不同的体型,四种眼睛,两种嘴巴,三种翅膀位置。这给了我们 96 种不同的可能变异,这些变异是小鸭程序不断产生的。

运行示例

当你运行ducklings.py的时候,输出将如下所示:

Duckling Screensaver, by Al Sweigart email@protected
Press Ctrl-C to quit...=" )
=")                                          (  v)=")
( ^)                                          ^ ^ ( v) >'')^^                                                ^^  (  ^)>")                       ^ ^( v)      =^^)("<  ("<                >")   ^^       (  >)
(^ ) (< )                ( ^)            ^ ^^^   ^^             ("<  ^^                       (``<>^^)(^^=               (^ )                          (<  )(  ^)
(v  ) ( "<           ^^                            ^ ^  ^ ^
`--snip--`

工作原理

这个程序用一个Duckling类表示小鸭子。在这个类的__init__()方法中选择了每只鸭子的随机特征,而每只鸭子的各个身体部分由getHeadStr()getBodyStr()getFeetStr()方法返回。

"""Duckling Screensaver, by Al Sweigart email@protected
A screensaver of many many ducklings.>" )   =^^)    (``=   ("=  >")    ("=
(  >)  (  ^)  (v  )  (^ )  ( >)  (v )
^ ^    ^ ^    ^ ^    ^^    ^^    ^^This code is available at https://nostarch.com/big-book-small-python-programming
Tags: large, artistic, object-oriented, scrolling"""import random, shutil, sys, time# Set up the constants:
PAUSE = 0.2  # (!) Try changing this to 1.0 or 0.0.
DENSITY = 0.10  # (!) Try changing this to anything from 0.0 to 1.0.DUCKLING_WIDTH = 5
LEFT = 'left'
RIGHT = 'right'
BEADY = 'beady'
WIDE = 'wide'
HAPPY = 'happy'
ALOOF = 'aloof'
CHUBBY = 'chubby'
VERY_CHUBBY = 'very chubby'
OPEN = 'open'
CLOSED = 'closed'
OUT = 'out'
DOWN = 'down'
UP = 'up'
HEAD = 'head'
BODY = 'body'
FEET = 'feet'# Get the size of the terminal window:
WIDTH = shutil.get_terminal_size()[0]
# We can't print to the last column on Windows without it adding a
# newline automatically, so reduce the width by one:
WIDTH -= 1def main():print('Duckling Screensaver, by Al Sweigart')print('Press Ctrl-C to quit...')time.sleep(2)ducklingLanes = [None] * (WIDTH // DUCKLING_WIDTH)while True:  # Main program loop.for laneNum, ducklingObj in enumerate(ducklingLanes):# See if we should create a duckling in this lane:if (ducklingObj == None and random.random() <= DENSITY):# Place a duckling in this lane:ducklingObj = Duckling()ducklingLanes[laneNum] = ducklingObjif ducklingObj != None:# Draw a duckling if there is one in this lane:print(ducklingObj.getNextBodyPart(), end='')# Delete the duckling if we've finished drawing it:if ducklingObj.partToDisplayNext == None:ducklingLanes[laneNum] = Noneelse:# Draw five spaces since there is no duckling here.print(' ' * DUCKLING_WIDTH, end='')print()  # Print a newline.sys.stdout.flush()  # Make sure text appears on the screen.time.sleep(PAUSE)class Duckling:def __init__(self):"""Create a new duckling with random body features."""self.direction = random.choice([LEFT, RIGHT])self.body = random.choice([CHUBBY, VERY_CHUBBY])self.mouth = random.choice([OPEN, CLOSED])self.wing = random.choice([OUT, UP, DOWN])if self.body == CHUBBY:# Chubby ducklings can only have beady eyes.self.eyes = BEADYelse:self.eyes = random.choice([BEADY, WIDE, HAPPY, ALOOF])self.partToDisplayNext = HEADdef getHeadStr(self):"""Returns the string of the duckling's head."""headStr = ''if self.direction == LEFT:# Get the mouth:if self.mouth == OPEN:headStr += '>'elif self.mouth == CLOSED:headStr += '='# Get the eyes:if self.eyes == BEADY and self.body == CHUBBY:headStr += '"'elif self.eyes == BEADY and self.body == VERY_CHUBBY:headStr += '" 'elif self.eyes == WIDE:headStr += "''"elif self.eyes == HAPPY:headStr += '^^'elif self.eyes == ALOOF:headStr += '``'headStr += ') '  # Get the back of the head.if self.direction == RIGHT:headStr += ' ('  # Get the back of the head.# Get the eyes:if self.eyes == BEADY and self.body == CHUBBY:headStr += '"'elif self.eyes == BEADY and self.body == VERY_CHUBBY:headStr += ' "'elif self.eyes == WIDE:headStr += "''"elif self.eyes == HAPPY:headStr += '^^'elif self.eyes == ALOOF:headStr += '``'# Get the mouth:if self.mouth == OPEN:headStr += '<'elif self.mouth == CLOSED:headStr += '='if self.body == CHUBBY:# Get an extra space so chubby ducklings are the same# width as very chubby ducklings.headStr += ' 'return headStrdef getBodyStr(self):"""Returns the string of the duckling's body."""bodyStr = '('  # Get the left side of the body.if self.direction == LEFT:# Get the interior body space:if self.body == CHUBBY:bodyStr += ' 'elif self.body == VERY_CHUBBY:bodyStr += '  '# Get the wing:if self.wing == OUT:bodyStr += '>'elif self.wing == UP:bodyStr += '^'elif self.wing == DOWN:bodyStr += 'v'if self.direction == RIGHT:# Get the wing:if self.wing == OUT:bodyStr += '<'elif self.wing == UP:bodyStr += '^'elif self.wing == DOWN:bodyStr += 'v'# Get the interior body space:if self.body == CHUBBY:bodyStr += ' 'elif self.body == VERY_CHUBBY:bodyStr += '  'bodyStr += ')'  # Get the right side of the body.if self.body == CHUBBY:# Get an extra space so chubby ducklings are the same# width as very chubby ducklings.bodyStr += ' 'return bodyStrdef getFeetStr(self):"""Returns the string of the duckling's feet."""if self.body == CHUBBY:return ' ^^  'elif self.body == VERY_CHUBBY:return ' ^ ^ 'def getNextBodyPart(self):"""Calls the appropriate display method for the next bodypart that needs to be displayed. Sets partToDisplayNext toNone when finished."""if self.partToDisplayNext == HEAD:self.partToDisplayNext = BODYreturn self.getHeadStr()elif self.partToDisplayNext == BODY:self.partToDisplayNext = FEETreturn self.getBodyStr()elif self.partToDisplayNext == FEET:self.partToDisplayNext = Nonereturn self.getFeetStr()# If this program was run (instead of imported), run the game:
if __name__ == '__main__':try:main()except KeyboardInterrupt:sys.exit()  # When Ctrl-C is pressed, end the program. 

在输入源代码并运行几次之后,尝试对其进行实验性的修改。标有(!)的注释对你可以做的小改变有建议。

探索程序

试着找出下列问题的答案。尝试对代码进行一些修改,然后重新运行程序,看看这些修改有什么影响。

  1. 如果将第 75 行的random.choice([LEFT, RIGHT])改为random.choice([LEFT])?会发生什么
  2. 如果把 194 行的self.partToDisplayNext = BODY改成self.partToDisplayNext = None会怎么样?
  3. 如果把 197 行的self.partToDisplayNext = FEET改成self.partToDisplayNext = BODY会怎么样?
  4. 如果把 195 行的return self.getHeadStr()改成return self.getFeetStr()会怎么样?

二十三、蚀刻绘图器

原文:http://inventwithpython.com/bigbookpython/project23.html

当您使用WASD键在屏幕上移动笔尖时,蚀刻绘图器通过描绘一条连续的线来形成一幅图片,就像蚀刻素描玩具一样。让你艺术的一面爆发出来,看看你能创造出什么形象!这个程序还可以让你把你的绘图保存到一个文本文件中,这样你以后就可以把它们打印出来。此外,你可以将其他图形的WASD运动复制粘贴到这个程序中,比如源代码第 6 到 14 行中的希尔伯特曲线分形的WASD命令。

运行示例

当你运行etchingdrawer.py时,输出将看起来像图 23-1 。

f23001

:在蚀刻绘图器程序中绘制的图

工作原理

与项目 17“骰子数学”一样,这个程序使用存储在名为canvas的变量中的字典来记录绘图的线条。关键字是(x, y)元组,值是表示要在屏幕上的 x,y 坐标处绘制的线形的字符串。附录 b 给出了可以在 Python 程序中使用的 Unicode 字符的完整列表。

第 126 行有一个对open()的函数调用,它传递了一个encoding='utf-8'参数。原因超出了本书的范围,但这是 Windows 将行字符写入文本文件所必需的。

"""Etching Drawer, by Al Sweigart email@protected
An art program that draws a continuous line around the screen using the
WASD keys. Inspired by Etch A Sketch toys.For example, you can draw Hilbert Curve fractal with:
SDWDDSASDSAAWASSDSASSDWDSDWWAWDDDSASSDWDSDWWAWDWWASAAWDWAWDDSDWOr an even larger Hilbert Curve fractal with:
DDSAASSDDWDDSDDWWAAWDDDDSDDWDDDDSAASDDSAAAAWAASSSDDWDDDDSAASDDSAAAAWA
ASAAAAWDDWWAASAAWAASSDDSAASSDDWDDDDSAASDDSAAAAWAASSDDSAASSDDWDDSDDWWA
AWDDDDDDSAASSDDWDDSDDWWAAWDDWWAASAAAAWDDWAAWDDDDSDDWDDSDDWDDDDSAASDDS
AAAAWAASSDDSAASSDDWDDSDDWWAAWDDDDDDSAASSDDWDDSDDWWAAWDDWWAASAAAAWDDWA
AWDDDDSDDWWAAWDDWWAASAAWAASSDDSAAAAWAASAAAAWDDWAAWDDDDSDDWWWAASAAAAWD
DWAAWDDDDSDDWDDDDSAASSDDWDDSDDWWAAWDDThis code is available at https://nostarch.com/big-book-small-python-programming
Tags: large, artistic"""import shutil, sys# Set up the constants for line characters:
UP_DOWN_CHAR         = chr(9474)  # Character 9474 is '│'
LEFT_RIGHT_CHAR      = chr(9472)  # Character 9472 is '─'
DOWN_RIGHT_CHAR      = chr(9484)  # Character 9484 is '┌'
DOWN_LEFT_CHAR       = chr(9488)  # Character 9488 is '┐'
UP_RIGHT_CHAR        = chr(9492)  # Character 9492 is '└'
UP_LEFT_CHAR         = chr(9496)  # Character 9496 is '┘'
UP_DOWN_RIGHT_CHAR   = chr(9500)  # Character 9500 is '├'
UP_DOWN_LEFT_CHAR    = chr(9508)  # Character 9508 is '┤'
DOWN_LEFT_RIGHT_CHAR = chr(9516)  # Character 9516 is '┬'
UP_LEFT_RIGHT_CHAR   = chr(9524)  # Character 9524 is '┴'
CROSS_CHAR           = chr(9532)  # Character 9532 is '┼'
# A list of chr() codes is at https://inventwithpython.com/chr# Get the size of the terminal window:
CANVAS_WIDTH, CANVAS_HEIGHT = shutil.get_terminal_size()
# We can't print to the last column on Windows without it adding a
# newline automatically, so reduce the width by one:
CANVAS_WIDTH -= 1
# Leave room at the bottom few rows for the command info lines.
CANVAS_HEIGHT -= 5"""The keys for canvas will be (x, y) integer tuples for the coordinate,
and the value is a set of letters W, A, S, D that tell what kind of line
should be drawn."""
canvas = {}
cursorX = 0
cursorY = 0def getCanvasString(canvasData, cx, cy):"""Returns a multiline string of the line drawn in canvasData."""canvasStr = ''"""canvasData is a dictionary with (x, y) tuple keys and values thatare sets of 'W', 'A', 'S', and/or 'D' strings to show whichdirections the lines are drawn at each xy point."""for rowNum in range(CANVAS_HEIGHT):for columnNum in range(CANVAS_WIDTH):if columnNum == cx and rowNum == cy:canvasStr += '#'continue# Add the line character for this point to canvasStr.cell = canvasData.get((columnNum, rowNum))if cell in (set(['W', 'S']), set(['W']), set(['S'])):canvasStr += UP_DOWN_CHARelif cell in (set(['A', 'D']), set(['A']), set(['D'])):canvasStr += LEFT_RIGHT_CHARelif cell == set(['S', 'D']):canvasStr += DOWN_RIGHT_CHARelif cell == set(['A', 'S']):canvasStr += DOWN_LEFT_CHARelif cell == set(['W', 'D']):canvasStr += UP_RIGHT_CHARelif cell == set(['W', 'A']):canvasStr += UP_LEFT_CHARelif cell == set(['W', 'S', 'D']):canvasStr += UP_DOWN_RIGHT_CHARelif cell == set(['W', 'S', 'A']):canvasStr += UP_DOWN_LEFT_CHARelif cell == set(['A', 'S', 'D']):canvasStr += DOWN_LEFT_RIGHT_CHARelif cell == set(['W', 'A', 'D']):canvasStr += UP_LEFT_RIGHT_CHARelif cell == set(['W', 'A', 'S', 'D']):canvasStr += CROSS_CHARelif cell == None:canvasStr += ' 'canvasStr += '\n'  # Add a newline at the end of each row.return canvasStrmoves = []
while True:  # Main program loop.# Draw the lines based on the data in canvas:print(getCanvasString(canvas, cursorX, cursorY))print('WASD keys to move, H for help, C to clear, '+ 'F to save, or QUIT.')response = input('> ').upper()if response == 'QUIT':print('Thanks for playing!')sys.exit()  # Quit the program.elif response == 'H':print('Enter W, A, S, and D characters to move the cursor and')print('draw a line behind it as it moves. For example, ddd')print('draws a line going right and sssdddwwwaaa draws a box.')print()print('You can save your drawing to a text file by entering F.')input('Press Enter to return to the program...')continueelif response == 'C':canvas = {}  # Erase the canvas data.moves.append('C')  # Record this move.elif response == 'F':# Save the canvas string to a text file:try:print('Enter filename to save to:')filename = input('> ')# Make sure the filename ends with .txt:if not filename.endswith('.txt'):filename += '.txt'with open(filename, 'w', encoding='utf-8') as file:file.write(''.join(moves) + '\n')file.write(getCanvasString(canvas, None, None))except:print('ERROR: Could not save file.')for command in response:if command not in ('W', 'A', 'S', 'D'):continue  # Ignore this letter and continue to the next one.moves.append(command)  # Record this move.# The first line we add needs to form a full line:if canvas == {}:if command in ('W', 'S'):# Make the first line a horizontal one:canvas[(cursorX, cursorY)] = set(['W', 'S'])elif command in ('A', 'D'):# Make the first line a vertical one:canvas[(cursorX, cursorY)] = set(['A', 'D'])# Update x and y:if command == 'W' and cursorY > 0:canvas[(cursorX, cursorY)].add(command)cursorY = cursorY - 1elif command == 'S' and cursorY < CANVAS_HEIGHT - 1:canvas[(cursorX, cursorY)].add(command)cursorY = cursorY + 1elif command == 'A' and cursorX > 0:canvas[(cursorX, cursorY)].add(command)cursorX = cursorX - 1elif command == 'D' and cursorX < CANVAS_WIDTH - 1:canvas[(cursorX, cursorY)].add(command)cursorX = cursorX + 1else:# If the cursor doesn't move because it would have moved off# the edge of the canvas, then don't change the set at# canvas[(cursorX, cursorY)].continue# If there's no set for (cursorX, cursorY), add an empty set:if (cursorX, cursorY) not in canvas:canvas[(cursorX, cursorY)] = set()# Add the direction string to this xy point's set:if command == 'W':canvas[(cursorX, cursorY)].add('S')elif command == 'S':canvas[(cursorX, cursorY)].add('W')elif command == 'A':canvas[(cursorX, cursorY)].add('D')elif command == 'D':canvas[(cursorX, cursorY)].add('A') 

探索程序

试着找出下列问题的答案。尝试对代码进行一些修改,然后重新运行程序,看看这些修改有什么影响。

  1. 如果把 101 行的response = input('> ').upper()改成response = input('> ')会怎么样?
  2. 如果把第 61 行的canvasStr += '#'改成canvasStr += '@'会怎么样?
  3. 如果把第 89 行的canvasStr += ' '改成canvasStr += '.'会怎么样?
  4. 如果把 94 行的moves = []改成moves = list('SDWDDSASDSAAWASSDSAS')会怎么样?

二十四、因子查找器

原文:http://inventwithpython.com/bigbookpython/project24.html

一个数的因数是任何两个其它数,当它们彼此相乘时,产生该数。比如2 × 13 = 26,所以 2 和 13 是 26 的因数。还有,1 × 26 = 26,所以 1 和 26 也是 26 的因数。所以我们说 26 有四个因子:1,2,13,26。

如果一个数只有两个因子(1 和它本身),我们称之为质数。否则,我们称之为合数。使用因数查找器发现一些新的质数!(提示:质数总是以不是 5 的奇数结尾。)你也可以让计算机用项目 56“质数”来计算它们

这个程序的数学并不太重,这使它成为初学者的理想项目。

运行示例

当您运行factorfinder.py时,输出将如下所示:

Factor Finder, by Al Sweigart email@protected
`--snip--`
Enter a number to factor (or "QUIT" to quit):
> 26
1, 2, 13, 26
Enter a number to factor (or "QUIT" to quit):
> 4352784
1, 2, 3, 4, 6, 8, 12, 16, 24, 29, 48, 53, 58, 59, 87, 106, 116, 118, 159, 174, 177, 212, 232, 236, 318, 348, 354, 424, 464, 472, 636, 696, 708, 848, 944, 1272, 1392, 1416, 1537, 1711, 2544, 2832, 3074, 3127, 3422, 4611, 5133, 6148, 6254, 6844, 9222, 9381, 10266, 12296, 12508, 13688, 18444, 18762, 20532, 24592, 25016, 27376, 36888, 37524, 41064, 50032, 73776, 75048, 82128, 90683, 150096, 181366, 272049, 362732, 544098, 725464, 1088196, 1450928, 2176392, 4352784
Enter a number to factor (or "QUIT" to quit):
> 9787
1, 9787
Enter a number to factor (or "QUIT" to quit):
> quit

工作原理

我们可以通过检查第二个数是否能整除第一个数来判断一个数是否是另一个数的因数。例如,7 是 21 的因数,因为 21 ÷ 7 是 3。这也给了我们 21 的另一个因素:3。但是,8 不是 21 的因数,因为 21 ÷ 8 = 2.625。分数余数部分告诉我们这个等式没有被均匀地划分。

%模数操作符将执行除法并告诉我们是否有余数:21 % 7计算为0,意味着没有余数,7 是 21 的因数,而21 % 8计算为1,一个非零值,意味着它不是一个因数。因子查找程序在第 35 行使用这种技术来确定哪些数字是因子。

math.sqrt()函数返回传递给它的数字的平方根。例如,math.sqrt(25)返回5.0,因为 5 的倍数本身就是 25,所以它是 25 的平方根。

"""Factor Finder, by Al Sweigart email@protected
Finds all the factors of a number.
This code is available at https://nostarch.com/big-book-small-python-programming
Tags: tiny, beginner, math"""import math, sysprint('''Factor Finder, by Al Sweigart email@protectedA number's factors are two numbers that, when multiplied with each
other, produce the number. For example, 2 x 13 = 26, so 2 and 13 are
factors of 26\. 1 x 26 = 26, so 1 and 26 are also factors of 26\. We
say that 26 has four factors: 1, 2, 13, and 26.If a number only has two factors (1 and itself), we call that a prime
number. Otherwise, we call it a composite number.Can you discover some prime numbers?
''')while True:  # Main program loop.print('Enter a positive whole number to factor (or QUIT):')response = input('> ')if response.upper() == 'QUIT':sys.exit()if not (response.isdecimal() and int(response) > 0):continuenumber = int(response)factors = []# Find the factors of number:for i in range(1, int(math.sqrt(number)) + 1):if number % i == 0:  # If there's no remainder, it is a factor.factors.append(i)factors.append(number // i)# Convert to a set to get rid of duplicate factors:factors = list(set(factors))factors.sort()# Display the results:for i, factor in enumerate(factors):factors[i] = str(factor)print(', '.join(factors)) 

探索程序

试着找出下列问题的答案。尝试对代码进行一些修改,然后重新运行程序,看看这些修改有什么影响。

  1. 如果删除或注释掉第 36 行的factors.append(i)会发生什么?
  2. 如果删除或注释掉第 40 行的factors = list(set(factors))会发生什么?(提示:输入一个平方数,如 25 或 36 或 49。)
  3. 如果删除或注释掉第 41 行的factors.sort()会发生什么?
  4. 如果将第 31 行的factors = []改为factors = '',会得到什么错误信息?
  5. 如果把第 31 行的factors = []改成factors = [-42]会怎么样?
  6. 如果将第 31 行的factors = []改为factors = ['hello'],会得到什么错误信息?

二十五、快速反应

原文:http://inventwithpython.com/bigbookpython/project25.html

这个程序测试你的反应速度:一看到DRAW这个词就按回车。但是要小心。在DRAW出现之前按下它,你就输了。你是西方最快的键盘吗?

运行示例

当您运行fastdraw.py时,输出将如下所示:

Fast Draw, by Al Sweigart email@protectedTime to test your reflexes and see if you are the fastest
draw in the west!
When you see "DRAW", you have 0.3 seconds to press Enter.
But you lose if you press Enter before "DRAW" appears.Press Enter to begin...It is high noon...
DRAW!You took 0.3485 seconds to draw. Too slow!
Enter QUIT to stop, or press Enter to play again.
> quit
Thanks for playing!

工作原理

input()函数在等待用户输入字符串时暂停程序。这个简单的行为意味着我们不能只用input()来创建实时游戏。然而,你的程序将缓冲键盘输入,这意味着如果你在input()被调用之前按下CAT键,这些字符将被保存,一旦input()执行,它们将立即出现。

通过记录第 22 行的input()调用之前的时间和第 24 行的input()调用之后的时间,我们可以确定玩家按下回车花了多长时间。然而,如果他们在调用input()之前按下回车,回车按下的缓冲会导致input()立即返回(通常在大约 3 毫秒内)。这就是为什么第 26 行检查时间是否小于 0.01 秒或 10 毫秒,以确定玩家按下回车太快。

"""Fast Draw, by Al Sweigart email@protected
Test your reflexes to see if you're the fastest draw in the west.
This code is available at https://nostarch.com/big-book-small-python-programming
Tags: tiny, beginner, game"""import random, sys, timeprint('Fast Draw, by Al Sweigart email@protected')
print()
print('Time to test your reflexes and see if you are the fastest')
print('draw in the west!')
print('When you see "DRAW", you have 0.3 seconds to press Enter.')
print('But you lose if you press Enter before "DRAW" appears.')
print()
input('Press Enter to begin...')while True:print()print('It is high noon...')time.sleep(random.randint(20, 50) / 10.0)print('DRAW!')drawTime = time.time()input()  # This function call doesn't return until Enter is pressed.timeElapsed = time.time() - drawTimeif timeElapsed < 0.01:# If the player pressed Enter before DRAW! appeared, the input()# call returns almost instantly.print('You drew before "DRAW" appeared! You lose.')elif timeElapsed > 0.3:timeElapsed = round(timeElapsed, 4)print('You took', timeElapsed, 'seconds to draw. Too slow!')else:timeElapsed = round(timeElapsed, 4)print('You took', timeElapsed, 'seconds to draw.')print('You are the fastest draw in the west! You win!')print('Enter QUIT to stop, or press Enter to play again.')response = input('> ').upper()if response == 'QUIT':print('Thanks for playing!')sys.exit() 

探索程序

试着找出下列问题的答案。尝试对代码进行一些修改,然后重新运行程序,看看这些修改有什么影响。

  1. 如果把第 22 行的drawTime = time.time()改成drawTime = 0会怎么样?
  2. 如果把第 30 行的timeElapsed > 0.3改成timeElapsed < 0.3会怎么样?
  3. 如果把第 24 行的time.time() - drawTime改成time.time() + drawTime会怎么样?
  4. 如果删除或注释掉第 15 行的input('Press Enter to begin...')会发生什么?

相关文章:

Python 小型项目大全 21~25

二十一、DNA 可视化 原文&#xff1a;http://inventwithpython.com/bigbookpython/project21.html 脱氧核糖核酸是一种微小的分子&#xff0c;存在于我们身体的每个细胞中&#xff0c;包含着我们身体如何生长的蓝图。它看起来像一对核苷酸分子的双螺旋结构&#xff1a;鸟嘌呤、…...

MinIO从信息泄漏到RCE

文章目录信息泄露漏洞利用漏洞分析漏洞修复RCE漏洞分析参考文章信息泄露 漏洞利用 如果MinIO以集群方式部署&#xff0c;存在信息泄露漏洞&#xff0c;攻击者可以通过HTTP请求获取目标进程的所有环境变量&#xff0c;包括MINIO_SECRET_KEY和MINIO_ROOT_PASSWORD. vulhub有环…...

202.Spark(九):SparkStreaming案例实操

目录 一、启动zookeeper,kafka基础环境 二、项目导好jar包,并且创建源数据,并在kafka中测试能否消费到数据...

GlusterFS(GFS)分布式文件系统

目录 一.文件系统简介 1.文件系统的组成 2.文件系统的作用 3.文件系统的挂载使用 二.GlusterFS概述 1.GlusterFS是什么&#xff1f; 2.GlusterFS的特点 3.GlusterFS术语介绍 3.1 Brick&#xff08;存储块&#xff09; 3.2 Volume&#xff08;逻辑卷&#xff09; 3.3…...

ChatGPT文本框再次升级,打造出新型操作系统

在ChatGPT到来之前&#xff0c;没有谁能够预见。但是&#xff0c;它最终还是来了&#xff0c;并引起了不小的轰动&#xff0c;甚至有可能颠覆整个行业。 从某种程度上说&#xff0c;ChatGPT可能是历史上增长最快的应用程序&#xff0c;仅在两个多月就拥有了1亿多活跃用户&…...

DPU02国产USB转UART控制芯片替代CP2102

目录DPU02简介DPU02芯片特性应用DPU02简介 DPU02是高度集成的USB转UART的桥接控制芯片&#xff0c;该芯片为RS-232设计更新为USB设计&#xff0c;并简化PCB组件空间提供了一个简单的解决方案。       DPU02包括了一个USB 2.0全速功能控制器、USB收发器、振荡器、EEPROM和带…...

Softing新版HART多路复用器软件支持西门子控制器

用于访问配置和诊断数据的HART多路复用器软件——Softing smartLink SW-HT&#xff0c;现在支持西门子的ET200远程IO和FDT/DTM接口。 smartLink SW-HT是一个基于Docker容器的软件应用。通过该软件&#xff0c;用户可以快速地访问以太网远程IO的HART设备&#xff0c;并且无需额外…...

〖Python网络爬虫实战⑫〗- XPATH语法介绍

订阅&#xff1a;新手可以订阅我的其他专栏。免费阶段订阅量1000python项目实战 Python编程基础教程系列&#xff08;零基础小白搬砖逆袭) 说明&#xff1a;本专栏持续更新中&#xff0c;目前专栏免费订阅&#xff0c;在转为付费专栏前订阅本专栏的&#xff0c;可以免费订阅付费…...

实例方法、类方法、静态方法、实例属性、类属性

背景&#xff1a;今天在复习类相关知识的时候&#xff0c;突然想到这几种类型的方法的区别和用法&#xff0c;感觉有点模棱两可&#xff0c;于是总结一下&#xff0c;加深记忆。 定义&#xff1a;想要区别和理解几种方法&#xff0c;首先要定义一个类&#xff0c;要在类中加深…...

数据结构---二叉树

专栏&#xff1a;数据结构 个人主页&#xff1a;HaiFan. 专栏简介&#xff1a;这里是HaiFan.的数据结构专栏&#xff0c;今天的内容是二叉树。 二叉树树的概念及结构二叉树概念及结构二叉树的概念二叉树的存储结构二叉树的顺序结构及实现大根堆和小根堆堆的实现及其各个接口堆的…...

CMake——从入门到百公里加速6.7s

目录 一、前言 二、HelloWorld 三、CMAKE 界面 3.1 gui正则表达式 3.2 GUI构建 四 关键字 4.1 add_library 4.2 add_subdirectory 4.3 add_executable 4.4 aux_source_directory 4.5 SET设置变量 4.6 INSTALL安装 4.7 ADD_LIBRARY 4.8 SET_TARGET_PROPERTIES 4.9…...

无公网IP,在外公网远程访问RabbitMQ服务「内网穿透」

文章目录前言1.安装erlang 语言2.安装rabbitMQ3. 内网穿透3.1 安装cpolar内网穿透(支持一键自动安装脚本)3.2 创建HTTP隧道4. 公网远程连接5.固定公网TCP地址5.1 保留一个固定的公网TCP端口地址5.2 配置固定公网TCP端口地址前言 RabbitMQ是一个在 AMQP(高级消息队列协议)基础上…...

Node【二】NPM

文章目录&#x1f31f;前言&#x1f31f;NPM使用&#x1f31f;NPM使用场景&#x1f31f;NPM的常用命令&#x1f31f;NPM命令使用介绍&#x1f31f; 使用NPM安装模块&#x1f31f; 下载三方包&#x1f31f; 全局安装VS本地安装&#x1f31f; 本地安装&#x1f31f; 全局安装&…...

【2023最新】超详细图文保姆级教程:App开发新手入门(2)

上章节我们已经成功的创建了一个 App 项目&#xff0c;接下来我们讲述一下&#xff0c;如何导入项目、编辑代码和提交项目代码。 Let’s Go! 4. 项目导入 当用户创建一个新的应用时&#xff0c;YonStudio 开发工具会自动导入模板项目的默认代码&#xff0c;不需要手动进行代…...

sftp使用

Client端使用Server端的账户username&#xff0c;sftp登录Server&#xff0c;除了IP地址&#xff0c;也可以使用/etc/hosts定义的域名&#xff0c;注意&#xff0c;Client的默认路径&#xff1a;Shell中的当前路径&#xff0c;Server的默认路径&#xff1a;server账户家目录 ​…...

FastGithub---------不再为访问github苦恼

声明&#xff1a;只解决github加速神器&#xff0c;解决github打不开、用户头像无法加载、releases无法上传下载、git-clone、git-pull、git-push失败等问题。 github为什么打不开&#xff1f; 其实不用加速的情况下&#xff0c;使用5G是可以打开的&#xff0c;只是资源加载…...

Spring Boot AOP @Pointcut拦截注解的表达式与运算符

项目场景&#xff1a; 这里主要说下Spring Boot AOP中Pointcut拦截类上面的注解与方法上面的注解&#xff0c;怎么写表达式怎么&#xff0c;还有Pointcut中使用运算符。 PointCut 表达式 拦截注解的表达式有3种&#xff1a;annotation、within、target 1、annotation 匹配有…...

2023年第十四届蓝桥杯javaB组省赛真题

&#x1f468;‍&#x1f4bb;作者简介&#xff1a;练习时长两年半的java博主 &#x1f4d6;个人主页&#xff1a;君临๑ &#x1f39e;️文章介绍&#xff1a;2023年第十四届蓝桥杯javaB组省赛真题 &#x1f389;所属专栏&#xff1a;算法专栏 &#x1f381; ps&#xff1a;点…...

CefSharp.WinForms 112.2.70最新版体验

一、准备 下载最新包及依赖包(对应.NET4.5.2,后续版本可能4.6.2+)到packages中,本地升级更快 NuGet Gallery | CefSharp.WinForms 112.2.70 NuGet Gallery | CefSharp.Common 112.2.70 NuGet Gallery | cef.redist.x64 112.2.7 NuGet Gallery | cef.redist.x86 112.2.…...

leetcode每日一题:数组篇(1/2)

&#x1f61a;一个不甘平凡的普通人&#xff0c;日更算法学习和打卡&#xff0c;期待您的关注和认可&#xff0c;陪您一起学习打卡&#xff01;&#xff01;&#xff01;&#x1f618;&#x1f618;&#x1f618; &#x1f917;专栏&#xff1a;每日算法学习 &#x1f4ac;个人…...

C++初阶-list的底层

目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

工业安全零事故的智能守护者:一体化AI智能安防平台

前言&#xff1a; 通过AI视觉技术&#xff0c;为船厂提供全面的安全监控解决方案&#xff0c;涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面&#xff0c;能够实现对应负责人反馈机制&#xff0c;并最终实现数据的统计报表。提升船厂…...

【网络安全产品大调研系列】2. 体验漏洞扫描

前言 2023 年漏洞扫描服务市场规模预计为 3.06&#xff08;十亿美元&#xff09;。漏洞扫描服务市场行业预计将从 2024 年的 3.48&#xff08;十亿美元&#xff09;增长到 2032 年的 9.54&#xff08;十亿美元&#xff09;。预测期内漏洞扫描服务市场 CAGR&#xff08;增长率&…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》

在注意力分散、内容高度同质化的时代&#xff0c;情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现&#xff0c;消费者对内容的“有感”程度&#xff0c;正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中&#xff0…...

剑指offer20_链表中环的入口节点

链表中环的入口节点 给定一个链表&#xff0c;若其中包含环&#xff0c;则输出环的入口节点。 若其中不包含环&#xff0c;则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...

【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制

使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下&#xff0c;限制某个 IP 的访问频率是非常重要的&#xff0c;可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案&#xff0c;使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...

Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换

目录 关键点 技术实现1 技术实现2 摘要&#xff1a; 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式&#xff08;自动驾驶、人工驾驶、远程驾驶、主动安全&#xff09;&#xff0c;并通过实时消息推送更新车…...

【LeetCode】3309. 连接二进制表示可形成的最大数值(递归|回溯|位运算)

LeetCode 3309. 连接二进制表示可形成的最大数值&#xff08;中等&#xff09; 题目描述解题思路Java代码 题目描述 题目链接&#xff1a;LeetCode 3309. 连接二进制表示可形成的最大数值&#xff08;中等&#xff09; 给你一个长度为 3 的整数数组 nums。 现以某种顺序 连接…...

9-Oracle 23 ai Vector Search 特性 知识准备

很多小伙伴是不是参加了 免费认证课程&#xff08;限时至2025/5/15&#xff09; Oracle AI Vector Search 1Z0-184-25考试&#xff0c;都顺利拿到certified了没。 各行各业的AI 大模型的到来&#xff0c;传统的数据库中的SQL还能不能打&#xff0c;结构化和非结构的话数据如何和…...

ui框架-文件列表展示

ui框架-文件列表展示 介绍 UI框架的文件列表展示组件&#xff0c;可以展示文件夹&#xff0c;支持列表展示和图标展示模式。组件提供了丰富的功能和可配置选项&#xff0c;适用于文件管理、文件上传等场景。 功能特性 支持列表模式和网格模式的切换展示支持文件和文件夹的层…...