五十一、九十九瓶的变体
原文:http://inventwithpython.com/bigbookpython/project51.html
在歌曲“九十九瓶”的这个版本中,该程序通过删除一个字母、交换一个字母的大小写、调换两个字母或重叠一个字母,在每个小节中引入了一些小的不完美。
随着歌曲继续播放,这些突变累积起来,产生了一首非常傻的歌曲。在尝试这个项目之前,尝试项目 50“九十九瓶”是个好主意。
运行示例
当您运行999bottles2.py
时,输出将如下所示:
niNety-nniinE BoOttels, by Al Sweigart email@protected
`--snip--`
99 bottles of milk on the wall,
99 bottles of milk,
Take one down, pass it around,
98 bottles of milk on the wall!
98 bottles of milk on the wall,
98 bottles of milk,
Take one d wn, pass it around,
97 bottles of milk on the wall!
97 bottles of milk on the wall,
97 bottels of milk,
Take one d wn, pass it around,
96 bottles of milk on the wall!
`--snip--`
75b otlte of mIl on teh wall,
75 ottels f miLk,
Take one d wn, pass it ar und,
74 bbOttles of milk on t e wall!
`--snip--`
1 otlE t of iml oo nteh lall,
1 o Tle FF FmMLIIkk,
Taake on d wn, pAasSs itt au nn d,
No more bottles of milk on the wall!
工作原理
Python 中的字符串值是不可变的,意味着它们不能被改变。如果字符串'Hello'
存储在名为greeting
的变量中,代码greeting = greeting ' world!'
实际上不会改变'Hello'
字符串。相反,它创建了一个新的字符串'Hello world!'
,来替换greeting
中的'Hello'
字符串。这方面的技术原因超出了本书的范围,但是理解其中的区别是很重要的,因为这意味着像greeting[0] = 'h'
这样的代码是不允许的,因为字符串是不可变的。然而,由于列表是可变的,我们可以创建一个单字符字符串列表(如第 62 行),改变列表中的字符,然后从列表中创建一个字符串(第 85 行)。这就是我们的程序看起来如何改变,或者说突变,包含歌词的字符串。
"""niNety-nniinE BoOttels of Mlik On teh waLl
By Al Sweigart email@protected
Print the full lyrics to one of the longest songs ever! The song
gets sillier and sillier with each verse. Press Ctrl-C to stop.
This code is available at https://nostarch.com/big-book-small-python-programming
Tags: short, scrolling, word"""
import random, sys, time
# Set up the constants:
# (!) Try changing both of these to 0 to print all the lyrics at once.
SPEED = 0.01 # The pause in between printing letters.
LINE_PAUSE = 1.5 # The pause at the end of each line.
def slowPrint(text, pauseAmount=0.1):
"""Slowly print out the characters in text one at a time."""
for character in text:
# Set flush=True here so the text is immediately printed:
print(character, flush=True, end='') # end='' means no newline.
time.sleep(pauseAmount) # Pause in between each character.
print() # Print a newline.
print('niNety-nniinE BoOttels, by Al Sweigart email@protected')
print()
print('(Press Ctrl-C to quit.)')
time.sleep(2)
bottles = 99 # This is the starting number of bottles.
# This list holds the string used for the lyrics:
lines = [' bottles of milk on the wall,',
' bottles of milk,',
'Take one down, pass it around,',
' bottles of milk on the wall!']
try:
while bottles > 0: # Keep looping and display the lyrics.
slowPrint(str(bottles) lines[0], SPEED)
time.sleep(LINE_PAUSE)
slowPrint(str(bottles) lines[1], SPEED)
time.sleep(LINE_PAUSE)
slowPrint(lines[2], SPEED)
time.sleep(LINE_PAUSE)
bottles = bottles - 1 # Decrease the number of bottles by one.
if bottles > 0: # Print the last line of the current stanza.
slowPrint(str(bottles) lines[3], SPEED)
else: # Print the last line of the entire song.
slowPrint('No more bottles of milk on the wall!', SPEED)
time.sleep(LINE_PAUSE)
print() # Print a newline.
# Choose a random line to make "sillier":
lineNum = random.randint(0, 3)
# Make a list from the line string so we can edit it. (Strings
# in Python are immutable.)
line = list(lines[lineNum])
effect = random.randint(0, 3)
if effect == 0: # Replace a character with a space.
charIndex = random.randint(0, len(line) - 1)
line[charIndex] = ' '
elif effect == 1: # Change the casing of a character.
charIndex = random.randint(0, len(line) - 1)
if line[charIndex].isupper():
line[charIndex] = line[charIndex].lower()
elif line[charIndex].islower():
line[charIndex] = line[charIndex].upper()
elif effect == 2: # Transpose two characters.
charIndex = random.randint(0, len(line) - 2)
firstChar = line[charIndex]
secondChar = line[charIndex 1]
line[charIndex] = secondChar
line[charIndex 1] = firstChar
elif effect == 3: # Double a character.
charIndex = random.randint(0, len(line) - 2)
line.insert(charIndex, line[charIndex])
# Convert the line list back to a string and put it in lines:
lines[lineNum] = ''.join(line)
except KeyboardInterrupt:
sys.exit() # When Ctrl-C is pressed, end the program.
在输入源代码并运行几次之后,尝试对其进行实验性的修改。标有(!)
的注释对你可以做的小改变有建议。你也可以自己想办法做到以下几点:
- 交换两个相邻单词的顺序,其中“单词”是由空格分隔的文本。
- 在极少数情况下,让歌曲开始向上计数几个迭代。
- 改变整个单词的大小写。
探索程序
试着找出下列问题的答案。尝试对代码进行一些修改,然后重新运行程序,看看这些修改有什么影响。
- 如果把第 47 行的
bottles = bottles - 1
改成bottles = bottles - 2
会怎么样? - 如果您将第 64 行的
effect = random.randint(0, 3)
更改为effect = 0
会发生什么? - 如果删除或注释掉第 62 行的
line = list(lines[lineNum])
,会出现什么错误?
五十二、数字系统计数器
原文:http://inventwithpython.com/bigbookpython/project52.html 我们习惯用十进制来计数,十进制使用 10 个数字:0 到 9。这个系统的发展可能是因为人类用手指来计数,而大多数人有 10 个手指。但是也存在其他的数字系统。计算机使用二进制的数字系统,只有 0 和 1 两个数字。程序员有时也使用十六进制,这是一种以 16 为基数的数字系统,使用数字 0 到 9,但也扩展到字母
A
到F
。
我们可以用任何数字系统表示任何数字,这个程序可以用十进制、二进制和十六进制显示一系列数字。
运行示例
当您运行numeralsystems.py
时,输出将如下所示:
Numeral System Counters, by Al Sweigart email@protected
`--snip--`
Enter the starting number (e.g. 0) > 0
Enter how many numbers to display (e.g. 1000) > 20
DEC: 0 HEX: 0 BIN: 0
DEC: 1 HEX: 1 BIN: 1
DEC: 2 HEX: 2 BIN: 10
DEC: 3 HEX: 3 BIN: 11
DEC: 4 HEX: 4 BIN: 100
DEC: 5 HEX: 5 BIN: 101
DEC: 6 HEX: 6 BIN: 110
DEC: 7 HEX: 7 BIN: 111
DEC: 8 HEX: 8 BIN: 1000
DEC: 9 HEX: 9 BIN: 1001
DEC: 10 HEX: A BIN: 1010
DEC: 11 HEX: B BIN: 1011
DEC: 12 HEX: C BIN: 1100
DEC: 13 HEX: D BIN: 1101
DEC: 14 HEX: E BIN: 1110
DEC: 15 HEX: F BIN: 1111
DEC: 16 HEX: 10 BIN: 10000
DEC: 17 HEX: 11 BIN: 10001
DEC: 18 HEX: 12 BIN: 10010
DEC: 19 HEX: 13 BIN: 10011
工作原理
在 Python 中,通过分别调用bin()
和hex()
函数,可以获得数字的二进制和十六进制表示:
>>> bin(42)
'0b101010'
>>> hex(42)
'0x2a'
通过调用int()
并提供要转换的基数,将这些字符串转换回十进制整数,如下所示:
>>> int('0b101010', 2)
42
>>> int('0x2a', 16)
42
记住,bin()
和hex()
返回的二进制和十六进制“数”实际上是字符串值:bin(42)
返回字符串'0b101010'
,hex(42)
返回字符串'0x2a'
。在编程中,惯例是给二进制数加上前缀0b
,给十六进制数加上前缀0x
。这样,就不会有人把二进制数 10000(十进制数 16)和十进制数“一万”混淆了。数字系统程序在显示数字之前会删除这些前缀。
"""Numeral System Counters, by Al Sweigart email@protected
Shows equivalent numbers in decimal, hexadecimal, and binary.
This code is available at https://nostarch.com/big-book-small-python-programming
Tags: tiny, math"""
print('''Numeral System Counters, by Al Sweigart email@protected
This program shows you equivalent numbers in decimal (base 10),
hexadecimal (base 16), and binary (base 2) numeral systems.
(Ctrl-C to quit.)
''')
while True:
response = input('Enter the starting number (e.g. 0) > ')
if response == '':
response = '0' # Start at 0 by default.
break
if response.isdecimal():
break
print('Please enter a number greater than or equal to 0.')
start = int(response)
while True:
response = input('Enter how many numbers to display (e.g. 1000) > ')
if response == '':
response = '1000' # Display 1000 numbers by default.
break
if response.isdecimal():
break
print('Please enter a number.')
amount = int(response)
for number in range(start, start amount): # Main program loop.
# Convert to hexadecimal/binary and remove the prefix:
hexNumber = hex(number)[2:].upper()
binNumber = bin(number)[2:]
print('DEC:', number, ' HEX:', hexNumber, ' BIN:', binNumber)
在输入源代码并运行几次之后,尝试对其进行实验性的修改。你也可以自己想办法做到以下几点:
- 使用 Python 的
oct()
函数为基数为 8 的数字系统,八进制输入新的一行。 - 在网上搜索“数字系统转换”,了解如何实现自己的
bin()
、oct()
、hex()
函数。
探索程序
试着找出下列问题的答案。尝试对代码进行一些修改,然后重新运行程序,看看这些修改有什么影响。
- 如果把第 37 行的
hex(number)[2:].upper()
改成hex(number)[2:]
会怎么样? - 如果把第 33 行的
int(response)
改成response
会导致什么错误?
五十三、元素周期表
原文:http://inventwithpython.com/bigbookpython/project53.html 元素周期表把所有已知的化学元素组织成一张表。这个程序显示这个表,并让玩家访问每个元素的附加信息,比如它的原子序数、符号、熔点等等。我从维基百科上收集了这些信息,并将其存储在一个名为
periodictable.csv
的文件中,你可以从inventwithpython.com/periodictable.csv
下载这个文件。
运行示例
当您运行periodictable.py
时,输出将如下所示:
Periodic Table of Elements
By Al Sweigart email@protected
Periodic Table of Elements
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
1 H He
2 Li Be B C N O F Ne
3 Na Mg Al Si P S Cl Ar
4 K Ca Sc Ti V Cr Mn Fe Co Ni Cu Zn Ga Ge As Se Br Kr
5 Rb Sr Y Zr Nb Mo Tc Ru Rh Pd Ag Cd In Sn Sb Te I Xe
6 Cs Ba La Hf Ta W Re Os Ir Pt Au Hg Tl Pb Bi Po At Rn
7 Fr Ra Ac Rf Db Sg Bh Hs Mt Ds Rg Cn Nh Fl Mc Lv Ts Og
Ce Pr Nd Pm Sm Eu Gd Tb Dy Ho Er Tm Yb Lu
Th Pa U Np Pu Am Cm Bk Cf Es Fm Md No Lr
Enter a symbol or atomic number to examine, or QUIT to quit.
> 42
Atomic Number: 42
Symbol: Mo
Element: Molybdenum
Origin of name: Greek molýbdaina, 'piece of lead', from mólybdos, 'lead'
Group: 6
Period: 5
Atomic weight: 95.95(1) u
Density: 10.22 g/cm^3
Melting point: 2896 K
Boiling point: 4912 K
Specific heat capacity: 0.251 J/(g*K)
Electronegativity: 2.16
Abundance in earth's crust: 1.2 mg/kg
Press Enter to continue...
`--snip--`
工作原理
csv
或逗号分隔值文件,是一个表示原始电子表格的文本文件。csv
文件中的每一行是用逗号分隔的各列。例如,periodictable.csv
中的前三行如下所示:
1,H,Hydrogen,"Greek elements hydro- and -gen, meaning 'water-forming`--snip--`
2,He,Helium,"Greek hḗlios, 'sun'",18,1,4.002602(2)[III][V],0.0001785`--snip--`
3,Li,Lithium,"Greek líthos, 'stone'",1,2,6.94[III][IV][V][VIII][VI],`--snip--`
Python 的csv
模块使得从csv
文件导入数据变得容易。中的字符串列表,就像第 15 到 18 行一样。第 32 行到第 58 行把这个列表变成了一个字典,这样程序的其他部分就可以很容易地通过元素名或原子序数来调用信息。
"""Periodic Table of Elements, by Al Sweigart email@protected
Displays atomic information for all the elements.
This code is available at https://nostarch.com/big-book-small-python-programming
Tags: short, science"""
# Data from https://en.wikipedia.org/wiki/List_of_chemical_elements
# Highlight the table, copy it, then paste it into a spreadsheet program
# like Excel or Google Sheets like in https://invpy.com/elements
# Then save this file as periodictable.csv.
# Or download this csv file from https://invpy.com/periodictable.csv
import csv, sys, re
# Read in all the data from periodictable.csv.
elementsFile = open('periodictable.csv', encoding='utf-8')
elementsCsvReader = csv.reader(elementsFile)
elements = list(elementsCsvReader)
elementsFile.close()
ALL_COLUMNS = ['Atomic Number', 'Symbol', 'Element', 'Origin of name',
'Group', 'Period', 'Atomic weight', 'Density',
'Melting point', 'Boiling point',
'Specific heat capacity', 'Electronegativity',
'Abundance in earth's crust']
# To justify the text, we need to find the longest string in ALL_COLUMNS.
LONGEST_COLUMN = 0
for key in ALL_COLUMNS:
if len(key) > LONGEST_COLUMN:
LONGEST_COLUMN = len(key)
# Put all the elements data into a data structure:
ELEMENTS = {} # The data structure that stores all the element data.
for line in elements:
element = {'Atomic Number': line[0],
'Symbol': line[1],
'Element': line[2],
'Origin of name': line[3],
'Group': line[4],
'Period': line[5],
'Atomic weight': line[6] ' u', # atomic mass unit
'Density': line[7] ' g/cm^3', # grams/cubic cm
'Melting point': line[8] ' K', # kelvin
'Boiling point': line[9] ' K', # kelvin
'Specific heat capacity': line[10] ' J/(g*K)',
'Electronegativity': line[11],
'Abundance in earth's crust': line[12] ' mg/kg'}
# Some of the data has bracketed text from Wikipedia that we want to
# remove, such as the atomic weight of Boron:
# "10.81[III][IV][V][VI]" should be "10.81"
for key, value in element.items():
# Remove the [roman numeral] text:
element[key] = re.sub(r'[(I|V|X) ]', '', value)
ELEMENTS[line[0]] = element # Map the atomic number to the element.
ELEMENTS[line[1]] = element # Map the symbol to the element.
print('Periodic Table of Elements')
print('By Al Sweigart email@protected')
print()
while True: # Main program loop.
# Show table and let the user select an element:
print(''' Periodic Table of Elements
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
1 H He
2 Li Be B C N O F Ne
3 Na Mg Al Si P S Cl Ar
4 K Ca Sc Ti V Cr Mn Fe Co Ni Cu Zn Ga Ge As Se Br Kr
5 Rb Sr Y Zr Nb Mo Tc Ru Rh Pd Ag Cd In Sn Sb Te I Xe
6 Cs Ba La Hf Ta W Re Os Ir Pt Au Hg Tl Pb Bi Po At Rn
7 Fr Ra Ac Rf Db Sg Bh Hs Mt Ds Rg Cn Nh Fl Mc Lv Ts Og
Ce Pr Nd Pm Sm Eu Gd Tb Dy Ho Er Tm Yb Lu
Th Pa U Np Pu Am Cm Bk Cf Es Fm Md No Lr''')
print('Enter a symbol or atomic number to examine, or QUIT to quit.')
response = input('> ').title()
if response == 'Quit':
sys.exit()
# Display the selected element's data:
if response in ELEMENTS:
for key in ALL_COLUMNS:
keyJustified = key.rjust(LONGEST_COLUMN)
print(keyJustified ': ' ELEMENTS[response][key])
input('Press Enter to continue...')
探索程序
试着找出下列问题的答案。尝试对代码进行一些修改,然后重新运行程序,看看这些修改有什么影响。
- 如果把 81 行的
response == 'Quit'
改成response == 'quit'
会导致什么 bug? - 如果删除或注释掉第 53 行和第 55 行会发生什么?
五十四、PigLatin
原文:http://inventwithpython.com/bigbookpython/project54.html PigLatin 是一种文字游戏,它将英语单词转换成对拉丁语的模仿。在 PigLatin 中,如果一个单词以辅音开头,说话者会把这个字母去掉,放在末尾,后面跟着
ay
比如pig
变成了igpay
,latin
变成了atinlay
。否则,如果单词以元音开头,说话者只需在末尾加上yay
即可。例如,elephant
变成了elephantyay
,umbrella
变成了umbrellayay
运行示例
当您运行piglatin.py
时,输出将如下所示:
Igpay Atinlay (Pig Latin)
By Al Sweigart email@protected
Enter your message:
> This is a very serious message.
Isthay isyay ayay eryvay erioussay essagemay.
(Copied pig latin to clipboard.)
工作原理
englishToPigLatin()
函数获取一个英文文本字符串,并返回一个对应的 Pig Latin 字符串。只有当用户直接运行程序时,main()
函数才会被调用。您也可以编写自己的 Python 程序,用一条import piglatin
语句导入piglatin.py
,然后调用piglatin.englishToPigLatin()
来使用englishToPigLatin()
函数。这种重用技术可以节省您自己重新编写代码所需的时间和精力。
"""Pig Latin, by Al Sweigart email@protected
Translates English messages into Igpay Atinlay.
This code is available at https://nostarch.com/big-book-small-python-programming
Tags: short, word"""
try:
import pyperclip # pyperclip copies text to the clipboard.
except ImportError:
pass # If pyperclip is not installed, do nothing. It's no big deal.
VOWELS = ('a', 'e', 'i', 'o', 'u', 'y')
def main():
print('''Igpay Atinlay (Pig Latin)
By Al Sweigart email@protected
Enter your message:''')
pigLatin = englishToPigLatin(input('> '))
# Join all the words back together into a single string:
print(pigLatin)
try:
pyperclip.copy(pigLatin)
print('(Copied pig latin to clipboard.)')
except NameError:
pass # Do nothing if pyperclip wasn't installed.
def englishToPigLatin(message):
pigLatin = '' # A string of the pig latin translation.
for word in message.split():
# Separate the non-letters at the start of this word:
prefixNonLetters = ''
while len(word) > 0 and not word[0].isalpha():
prefixNonLetters = word[0]
word = word[1:]
if len(word) == 0:
pigLatin = pigLatin prefixNonLetters ' '
continue
# Separate the non-letters at the end of this word:
suffixNonLetters = ''
while not word[-1].isalpha():
suffixNonLetters = word[-1] suffixNonLetters
word = word[:-1]
# Remember if the word was in uppercase or titlecase.
wasUpper = word.isupper()
wasTitle = word.istitle()
word = word.lower() # Make the word lowercase for translation.
# Separate the consonants at the start of this word:
prefixConsonants = ''
while len(word) > 0 and not word[0] in VOWELS:
prefixConsonants = word[0]
word = word[1:]
# Add the pig latin ending to the word:
if prefixConsonants != '':
word = prefixConsonants 'ay'
else:
word = 'yay'
# Set the word back to uppercase or titlecase:
if wasUpper:
word = word.upper()
if wasTitle:
word = word.title()
# Add the non-letters back to the start or end of the word.
pigLatin = prefixNonLetters word suffixNonLetters ' '
return pigLatin
if __name__ == '__main__':
main()
探索程序
试着找出下列问题的答案。尝试对代码进行一些修改,然后重新运行程序,看看这些修改有什么影响。
- 如果把第 33 行的
message.split()
改成message
会怎么样? - 如果把第 11 行的
('a', 'e', 'i', 'o', 'u', 'y')
改成()
会怎么样? - 如果把第 11 行的
('a', 'e', 'i', 'o', 'u', 'y')
改成('A', 'E', 'I', 'O', 'U', 'Y')
会怎么样?
五十五、强力球彩票
原文:http://inventwithpython.com/bigbookpython/project55.html 强力球彩票是一种令人兴奋的小额输钱方式。如果你购买一张 2 美元的彩票,你可以选择六个号码:从 1 到 69 中抽取五个,从 1 到 26 中抽取第六个“强力球”号码。数字的顺序并不重要。如果彩票选择了你的六个号码,你将赢得 15.86 亿美元!除了你不会赢,因为你的赔率是 292201338 分之一。但是如果你花 200 美元买了 100 张票,你的胜算是。。。2922013 分之一。你也不会赢,但至少你会损失 100 倍的钱。越喜欢输钱,彩票越好玩!
为了帮助你想象你中不了彩票的几率,这个程序模拟了多达一百万个强力球抽奖,然后将它们与你挑选的数字进行比较。现在你可以不用花钱就能享受彩票中奖的所有刺激。
有趣的事实:每一组六个数字都和其他数字一样有可能赢。所以下次你想买彩票的时候,选 1、2、3、4、5 和 6。这些数字很可能会以更复杂的形式出现。
运行示例
当您运行powerballottery.py
时,输出将如下所示:
Powerball Lottery, by Al Sweigart email@protected
Each powerball lottery ticket costs $2. The jackpot for this game
is $1.586 billion! It doesn't matter what the jackpot is, though,
because the odds are 1 in 292,201,338, so you won't win.
This simulation gives you the thrill of playing without wasting money.
Enter 5 different numbers from 1 to 69, with spaces between
each number. (For example: 5 17 23 42 50 51)
> 1 2 3 4 5
Enter the powerball number from 1 to 26.
> 6
How many times do you want to play? (Max: 1000000)
> 1000000
It costs $2000000 to play 1000000 times, but don't
worry. I'm sure you'll win it all back.
Press Enter to start...
The winning numbers are: 12 29 48 11 4 and 13 You lost.
The winning numbers are: 54 39 3 42 16 and 12 You lost.
The winning numbers are: 56 4 63 23 38 and 24 You lost.
`--snip--`
The winning numbers are: 46 29 10 62 17 and 21 You lost.
The winning numbers are: 5 20 18 65 30 and 10 You lost.
The winning numbers are: 54 30 58 10 1 and 18 You lost.
You have wasted $2000000
Thanks for playing!
工作原理
这个程序的输出看起来相当一致,因为第 109 行的allWinningNums.ljust(21)
代码用足够的空间填充数字,占据 21 列,不管中奖数字有多少位。这使得“你输了。”文本总是出现在屏幕的同一个地方,所以即使程序快速输出几行,它仍然是可读的。
"""Powerball Lottery, by Al Sweigart email@protected
A simulation of the lottery so you can experience the thrill of
losing the lottery without wasting your money.
This code is available at https://nostarch.com/big-book-small-python-programming
Tags: short, humor, simulation"""
import random
print('''Powerball Lottery, by Al Sweigart email@protected
Each powerball lottery ticket costs $2. The jackpot for this game
is $1.586 billion! It doesn't matter what the jackpot is, though,
because the odds are 1 in 292,201,338, so you won't win.
This simulation gives you the thrill of playing without wasting money.
''')
# Let the player enter the first five numbers, 1 to 69:
while True:
print('Enter 5 different numbers from 1 to 69, with spaces between')
print('each number. (For example: 5 17 23 42 50)')
response = input('> ')
# Check that the player entered 5 things:
numbers = response.split()
if len(numbers) != 5:
print('Please enter 5 numbers, separated by spaces.')
continue
# Convert the strings into integers:
try:
for i in range(5):
numbers[i] = int(numbers[i])
except ValueError:
print('Please enter numbers, like 27, 35, or 62.')
continue
# Check that the numbers are between 1 and 69:
for i in range(5):
if not (1 <= numbers[i] <= 69):
print('The numbers must all be between 1 and 69.')
continue
# Check that the numbers are unique:
# (Create a set from number to remove duplicates.)
if len(set(numbers)) != 5:
print('You must enter 5 different numbers.')
continue
break
# Let the player select the powerball, 1 to 26:
while True:
print('Enter the powerball number from 1 to 26.')
response = input('> ')
# Convert the strings into integers:
try:
powerball = int(response)
except ValueError:
print('Please enter a number, like 3, 15, or 22.')
continue
# Check that the number is between 1 and 26:
if not (1 <= powerball <= 26):
print('The powerball number must be between 1 and 26.')
continue
break
# Enter the number of times you want to play:
while True:
print('How many times do you want to play? (Max: 1000000)')
response = input('> ')
# Convert the strings into integers:
try:
numPlays = int(response)
except ValueError:
print('Please enter a number, like 3, 15, or 22000.')
continue
# Check that the number is between 1 and 1000000:
if not (1 <= numPlays <= 1000000):
print('You can play between 1 and 1000000 times.')
continue
break
# Run the simulation:
price = '$' str(2 * numPlays)
print('It costs', price, 'to play', numPlays, 'times, but don't')
print('worry. I'm sure you'll win it all back.')
input('Press Enter to start...')
possibleNumbers = list(range(1, 70))
for i in range(numPlays):
# Come up with lottery numbers:
random.shuffle(possibleNumbers)
winningNumbers = possibleNumbers[0:5]
winningPowerball = random.randint(1, 26)
# Display winning numbers:
print('The winning numbers are: ', end='')
allWinningNums = ''
for i in range(5):
allWinningNums = str(winningNumbers[i]) ' '
allWinningNums = 'and ' str(winningPowerball)
print(allWinningNums.ljust(21), end='')
# NOTE: Sets are not ordered, so it doesn't matter what order the
# integers in set(numbers) and set(winningNumbers) are.
if (set(numbers) == set(winningNumbers)
and powerball == winningPowerball):
print()
print('You have won the Powerball Lottery! Congratulations,')
print('you would be a billionaire if this was real!')
break
else:
print(' You lost.') # The leading space is required here.
print('You have wasted', price)
print('Thanks for playing!')
探索程序
试着找出下列问题的答案。尝试对代码进行一些修改,然后重新运行程序,看看这些修改有什么影响。
- 如果把 100 行的
possibleNumbers[0:5]
改成numbers
,101 行的random.randint(1, 26)
改成powerball
,会发生什么? - 如果删除或注释掉第 96 行的
possibleNumbers = list(range(1, 70))
,会得到什么错误?