Python编程:从入门到实践 第9章 课后习题
9-1 餐馆:创建一个名为Restaurant 的类,其方法__init__() 设置两个属性:restaurant_name 和cuisine_type 。创建一个名为describe_restaurant() 的方法和一个名为open_restaurant() 的方法,其中前者打印前述两项信息,而后者打印一条消息,指出餐馆正在营业。
class Restaurant():
def __init__(self, restaurant_name, cuisine_type):
self.r_name = restaurant_name
self.c_type = cuisine_type
def describe_restaurant(self):
print("\nRestaurant's name is:", self.r_name.title(),
"and it has", self.c_type.title()+".")
def open_restaurant(self):
print('\n' + self.r_name.upper(), 'is opening!')
dinner = Restaurant('kfc','chips')
Restaurant.describe_restaurant(dinner)
Restaurant.open_restaurant(dinner)
复制代码
输出结果:
Restaurant's name is: Kfc and it has Chips.
KFC is opening!
复制代码
根据这个类创建一个名为restaurant的实例,分别打印其两个属性,再调用前述两个方法。
见上。
9-2 三家餐馆:根据你为完成练习9-1而编写的类创建三个实例,并对每个实例调用方法describe_restaurant()。
略。
9-3 用户:创建一个名为User的类,其中包含属性first_name和last_name,还有用户简介通常会存储的其他几个属性。在类User中定义一个名为describe_user() 的方法,它打印用户信息摘要;再定义一个名为greet_user() 的方法,它向用户发出个性化的问候。
创建多个表示不同用户的实例,并对每个实例都调用上述两个方法。
class User():
def __init__(self, first_name, last_name, gender='male'):
self.f_name = first_name
self.l_name = last_name
self.g_gender = gender
def describe_user(self):
print(self.f_name.title(), self.l_name.title(),
'has the following details:',self.g_gender +'.')
def greet_user(self):
print('Hello,', self.f_name, self.l_name + '.\n')
a = User('san', 'zhang')
User.describe_user(a)
User.greet_user(a)
b = User('si', 'li', 'female')
User.describe_user(b)
User.greet_user(b)
复制代码
输出结果:
San Zhang has the following details: male.
Hello, san zhang.
Si Li has the following details: female.
Hello, si li.
复制代码
9-4 就餐人数:在为完成练习9-1而编写的程序中,添加一个名为number_served的属性,并将其默认值设置为0。根据这个类创建一个名为restaurant 的实例;打印有多少人在这家餐馆就餐过,然后修改这个值并再次打印它。
添加一个名为set_number_served()的方法,它让你能够设置就餐人数。调用这个方法并向它传递一个值,然后再次打印这个值。
添加一个名为increment_number_served() 的方法,它让你能够将就餐人数递增。调用这个方法并向它传递一个这样的值:你认为这家餐馆每天可能接待的就餐人数。
class Restaurant():
def __init__(self, restaurant_name, cuisine_type, number_served=0):
self.r_name = restaurant_name
self.c_type = cuisine_type
self.no_served = number_served
def describe_restaurant(self):
print("Restaurant's name is:", self.r_name.title(),
"and it has", self.c_type.title(), "and served", self.no_served,
'people.\n')
def open_restaurant(self):
print(self.r_name.upper(), 'is opening!\n')
def set_number_served(self, number_served):
self.no_served = number_served
def increment_number_served(self, incre_number):
self.no_served += incre_number
print('-----Original:------')
dinner = Restaurant('kfc','chips')
Restaurant.describe_restaurant(dinner)
print('-----Fixed served number-----')
dinner = Restaurant('burger king','coke',23)
Restaurant.describe_restaurant(dinner)
print('-----Revised served-----')
dinner = Restaurant('mcdonald','burgers',23)
dinner.set_number_served(54)
Restaurant.describe_restaurant(dinner)
print('-----Incremental served-----')
dinner = Restaurant('pizza hut','pizza',23)
dinner.set_number_served(100)
dinner.increment_number_served(20)
Restaurant.describe_restaurant(dinner)
复制代码
结果:
-----Original:------
Restaurant's name is: Kfc and it has Chips and served 0 people.
-----Fixed served number-----
Restaurant's name is: Burger King and it has Coke and served 23 people.
-----Revised served-----
Restaurant's name is: Mcdonald and it has Burgers and served 54 people.
-----Incremental served-----
Restaurant's name is: Pizza Hut and it has Pizza and served 120 people.
复制代码
9-5 尝试登录次数:在为完成练习9-3而编写的User类中,添加一个名为login_attempts的属性。编写一个名为increment_login_attempts() 的方法,它将属性login_attempts 的值加1。再编写一个名为reset_login_attempts() 的方法,它将属性login_attempts 的值重置为0。
根据User类创建一个实例,再调用方法increment_login_attempts() 多次。打印属性login_attempts 的值,确认它被正确地递增;然后,调用方法reset_login_attempts() ,并再次打印属性login_attempts 的值,确认它被重置为0。
class User():
def __init__(self, first_name, last_name, gender='male'):
self.f_name = first_name
self.l_name = last_name
self.g_gender = gender
self.loggin_attempt = 0
def describe_user(self):
print(self.f_name.title(), self.l_name.title(),
'has the following details:',self.g_gender +'.')
def greet_user(self):
print('Hello,', self.f_name, self.l_name + '.\n')
def increment_login_attempts(self):
self.loggin_attempt += 1
print('He attempted', self.loggin_attempt, 'logins.')
def reset_login_attempts(self):
self.loggin_attempt = 0
print(self.loggin_attempt)
a = User('san', 'zhang')
a.describe_user()
a.greet_user()
n = 0
while n<5:
n += 1
a.increment_login_attempts()
a.reset_login_attempts()
复制代码
结果:
San Zhang has the following details: male.
Hello, san zhang.
He attempted 1 logins.
He attempted 2 logins.
He attempted 3 logins.
He attempted 4 logins.
He attempted 5 logins.
0
复制代码
9-6 冰淇淋小店:冰淇淋小店是一种特殊的餐馆。编写一个名为IceCreamStand 的类,让它继承你为完成练习9-1或练习9-4而编写的Restaurant 类。这两个版本的Restaurant 类都可以,挑选你更喜欢的那个即可。添加一个名为flavors 的属性,用于存储一个由各种口味的冰淇淋组成的列表。编写一个显示这些冰淇淋的方法。创建一个IceCreamStand 实例,并调用这个方法。
class Restaurant():
def __init__(self, restaurant_name, cuisine_type, number_served=0):
self.r_name = restaurant_name
self.c_type = cuisine_type
self.no_served = number_served
def describe_restaurant(self):
print("Restaurant's name is:", self.r_name.title(),
"and it has", self.c_type.title(), "and served", self.no_served,
'people.\n')
def open_restaurant(self):
print(self.r_name.upper(), 'is opening!\n')
def set_number_served(self, number_served):
self.no_served = number_served
def increment_number_served(self, incre_number):
self.no_served += incre_number
class IceCreamstand(Restaurant):
def __init__(self, restaurant_name, cuisine_type):
super().__init__(restaurant_name,cuisine_type)
self.flavor_list = []
def flavors(self):
for flavor in self.flavor_list:
print('Ice cream tastes are:', flavor + '.')
print('-----Original:------')
dinner = Restaurant('kfc','chips')
dinner.describe_restaurant()
print('-----Fixed served number-----')
dinner = Restaurant('burger king','coke',23)
dinner.describe_restaurant()
print('-----Revised served-----')
dinner = Restaurant('mcdonald','burgers',23)
dinner.set_number_served(54)
dinner.describe_restaurant()
print('-----Incremental served-----')
dinner = Restaurant('pizza hut','pizza',23)
dinner.set_number_served(100)
dinner.increment_number_served(20)
dinner.describe_restaurant()
print('-----Ice cream flavor-----')
taste = IceCreamstand('DQ', 'Ice Shake')
flavor_list = []
while True:
flavor_input = input("name a flavor, press q to quit:\n\t")
if flavor_input != 'q':
flavor_list.append(flavor_input)
else:
break
taste.flavor_list = flavor_list
taste.flavors()
复制代码
正好练习一下while。结果:
-----Original:------
Restaurant's name is: Kfc and it has Chips and served 0 people.
-----Fixed served number-----
Restaurant's name is: Burger King and it has Coke and served 23 people.
-----Revised served-----
Restaurant's name is: Mcdonald and it has Burgers and served 54 people.
-----Incremental served-----
Restaurant's name is: Pizza Hut and it has Pizza and served 120 people.
-----Ice cream flavor-----
name a flavor, press q to quit:
berry
name a flavor, press q to quit:
vanilla
name a flavor, press q to quit:
chocolate
name a flavor, press q to quit:
moccha
name a flavor, press q to quit:
q
Ice cream tastes are: berry.
Ice cream tastes are: vanilla.
Ice cream tastes are: chocolate.
Ice cream tastes are: moccha.
复制代码
9-7 管理员:管理员是一种特殊的用户。编写一个名为Admin的类,让它继承你为完成练习9-3或练习9-5而编写的User类。添加一个名为privileges 的属性,用于存储一个由字符串(如”can add post” 、”can delete post” 、”can ban user” 等)组成的列表。编写一个名为show_privileges() 的方法,它 显示管理员的权限。创建一个Admin 实例,并调用这个方法。
class User():
def __init__(self, first_name, last_name, other_info=''):
self.f_name = first_name
self.l_name = last_name
self.o_info = other_info
self.login_attempts = 0
def describe_user(self):
if self.o_info:
print('User', self.l_name.title(), self.f_name.title(),
'has following info:', self.o_info)
else:
print('User', self.l_name.title(), self.f_name.title() + '.')
def greet_user(self):
print('Hello,', self.l_name.title(), self.f_name.title()+'.')
def increment_login_attempts(self):
for x in range(0,4,1):
self.login_attempts += 1
print('Logging attempts:', self.login_attempts)
def reset_login_attempts(self):
self.login_attempts = 0
print('Reset loging:', self.login_attempts)
class Admin(User):
def __init__(self, first_name, last_name):
super().__init__(first_name, last_name)
self.privileges = ["can add post" ,"can delete post" ,"can ban user"]
def show_privileges(self):
for x in self.privileges:
print("Admin's privileges include",x +'.')
p1 = User('san', 'zhang', 23)
p1.describe_user()
p1.greet_user()
p1.increment_login_attempts()
p1.reset_login_attempts()
p2= Admin('si', 'li')
p2.show_privileges()
复制代码
结果:
User Zhang San has following info: 23
Hello, Zhang San.
Logging attempts: 1
Logging attempts: 2
Logging attempts: 3
Logging attempts: 4
Reset loging: 0
Admin's privileges include can add post.
Admin's privileges include can delete post.
Admin's privileges include can ban user.
复制代码
9-8 权限:编写一个名为Privileges 的类,它只有一个属性——privileges ,其中存储了练习9-7 所说的字符串列表。将方法show_privileges() 移到这个类中。在Admin 类中,将一个Privileges 实例用作其属性。创建一个Admin 实例,并使用方法show_privileges() 来显示其权限。
class User():
def __init__(self, first_name, last_name, other_info=''):
self.f_name = first_name
self.l_name = last_name
self.o_info = other_info
self.login_attempts = 0
def describe_user(self):
if self.o_info:
print('User', self.l_name.title(), self.f_name.title(),
'has following info:', self.o_info)
else:
print('User', self.l_name.title(), self.f_name.title() + '.')
def greet_user(self):
print('Hello,', self.l_name.title(), self.f_name.title()+'.')
def increment_login_attempts(self):
for x in range(0,4,1):
self.login_attempts += 1
print('Logging attempts:', self.login_attempts)
def reset_login_attempts(self):
self.login_attempts = 0
print('Reset loging:', self.login_attempts)
class Admin(User):
def __init__(self, first_name, last_name):
super().__init__(first_name, last_name)
self.priv = Privileges()
class Privileges():
def __init__(self, privileges=[]):
self.priv = privileges
def show_privileges(self):
if self.priv:
for x in self.priv:
print("Admin's privileges in Class Previleges include",x +'.')
else:
print('There is no privilege.')
person = Admin('wu', 'wang')
person.priv.show_privileges() #这次显示无privilege
my_privileges = ['can reset passwords','can moderate discussions',
'can suspend accounts']
person.priv.priv = my_privileges
#为啥要两次?一次传递到Admin(user)中,然后第二次传到Privileges中?
person.priv.show_privileges() #这次显示有privilege
复制代码
结果:
There is no privilege.
Admin's privileges in Class Previleges include can reset passwords.
Admin's privileges in Class Previleges include can moderate discussions.
Admin's privileges in Class Previleges include can suspend accounts.
复制代码
person.priv.priv = my_privileges
卡住了半天,开始怎么都无法把list传递进去,后来阴差阳错发现要两次,这个地方不是很懂,只能按照刚才自己注释的理解。
9-9 电瓶升级:在本节最后一个electric_car.py版本中,给Battery 类添加一个名为upgrade_battery() 的方法。这个方法检查电瓶容量,如果它不是85,就将它设置为85。创建一辆电瓶容量为默认值的电动汽车,调用方法get_range(),然后对电瓶进行升级,并再次调用get_range()。你会看到这辆汽车的续航里程增加了。
class Car():
"""A simple attempt to represent a car."""
def __init__(self, manufacturer, model, year):
"""Initialize attributes to describe a car."""
self.manufacturer = manufacturer
self.model = model
self.year = year
self.odometer_reading = 0
def get_descriptive_name(self):
"""Return a neatly formatted descriptive name."""
long_name = str(self.year) + ' ' + self.manufacturer + ' ' + self.model
return long_name.title()
def read_odometer(self):
"""Print a statement showing the car's mileage."""
print("This car has " + str(self.odometer_reading) + " miles on it.")
def update_odometer(self, mileage):
"""
Set the odometer reading to the given value.
Reject the change if it attempts to roll the odometer back.
"""
if mileage >= self.odometer_reading:
self.odometer_reading = mileage
else:
print("You can't roll back an odometer!")
def increment_odometer(self, miles):
"""Add the given amount to the odometer reading."""
self.odometer_reading += miles
class Battery():
"""A simple attempt to model a battery for an electric car."""
def __init__(self, battery_size=60):
"""Initialize the batteery's attributes."""
self.battery_size = battery_size
def describe_battery(self):
"""Print a statement describing the battery size."""
print("This car has a " + str(self.battery_size) + "-kWh battery.")
def get_range(self):
"""Print a statement about the range this battery provides."""
if self.battery_size == 60:
range = 140
elif self.battery_size == 85:
range = 185
message = "This car can go approximately " + str(range)
message += " miles on a full charge."
print(message)
def upgrade_battery(self):
if self.battery_size != 85:
self.battery_size = 85
print('Battery upgraded to 85.')
else:
print("You don't need upgrade.")
class ElectricCar(Car):
"""Models aspects of a car, specific to electric vehicles."""
def __init__(self, manufacturer, model, year):
"""
Initialize attributes of the parent class.
Then initialize attributes specific to an electric car.
"""
super().__init__(manufacturer, model, year)
self.battery = Battery()
my_car = ElectricCar('Honda','Accord','2019')
print('Prior to upgrading:')
my_car.battery.get_range()
print('\nUpgrade battery:')
my_car.battery.upgrade_battery()
print('\nRange check after upgrading:')
my_car.battery.get_range()
复制代码
本段教材上面的代码抄的。。。实在懒得输入了。。。结果:
Prior to upgrading:
This car can go approximately 140 miles on a full charge.
Upgrade battery:
Battery upgraded to 85.
Range check after upgrading:
This car can go approximately 185 miles on a full charge.
复制代码
9-10 导入Restaurant 类:将最新的Restaurant类存储在一个模块中。在另一个文件中,导入Restaurant类,创建一个Restaurant实例,并调用Restaurant的一个方法,以确认import语句正确无误。
from rest import Restaurant
复制代码
9-11 导入Admin类:以为完成练习9-8而做的工作为基础,将User、Privileges和Admin类存储在一个模块中,再创建一个文件,在其中创建一个Admin实例并对其调用方法show_privileges(),以确认一切都能正确地运行。
from priv import User, Privileges, Admin
复制代码
9-12 多个模块:将User类存储在一个模块中,并将Privileges 和Admin类存储在另一个模块中。再创建一个文件,在其中创建一个Admin实例,并对其调用方法show_privileges(),以确认一切都依然能够正确地运行。
from a import User
from b import Privileges, Admin
复制代码
9-13 使用OrderedDict:在练习6-4中,你使用了一个标准字典来表示词汇表。请使用OrderedDict 类来重写这个程序,并确认输出的顺序与你在字典中添加键 —值对的顺序一致。
from collections import OrderedDict
names = OrderedDict()
names = {'string':'字符串',
'list':'列表',
'tuple':'元组',
}
for key, value in names.items():
print('\t'+key,'is:',value)
names['print'] = '打印'
names['import'] = '导入'
for key, value in names.items():
print('\t'+key,'is:',value)
复制代码
9-14 骰子:模块random 包含以各种方式生成随机数的函数,其中的randint() 返回一个位于指定范围内的整数,例如,下面的代码返回一个1~6内的整数:
from random import randint
x = randint(1, 6)
复制代码
请创建一个Die类,它包含一个名为sides的属性,该属性的默认值为6。编写一个名为roll_die() 的方法,它打印位于1和骰子面数之间的随机数。创建一个6面的骰子,再掷10次。 创建一个10面的骰子和一个20面的骰子,并将它们都掷10次。
from random import randint
class Die():
def __init__(self, dice_side):
self.sides = dice_side
def roll_die(self):
return randint(1, self.sides)
roll_results = []
num = input('How many rolls?')
d = Die(int(num))
for x in range(int(num)):
result = d.roll_die()
roll_results.append(result)
print('Results are:',roll_results)
复制代码
修改了一下,可以roll任意数字。结果:
How many rolls?15
Results are: [2, 13, 1, 11, 12, 9, 2, 3, 14, 9, 3, 5, 2, 8, 9]
复制代码
9-15 PythonModule of the Week :要了解Python标准库,一个很不错的资源是网站PythonModule ofthe Week。请访问pymotw.com/ 并查看其中的目录,在其中找一个你感兴趣的模块进行探索,或阅读模块collections 和random 的文档。
前天去陪家人看电影去了,昨天工作实在太累。所以只复习了一下。但是,复习收获还是很多啊。