Python面试题
Published in:2020-07-27 |

你将设计一个投票系统,选举出政党的候选人。

有一个候选人的名单,投票人将从中选出一个候选人作为领导。

选举规则如下:

每个投票人只能投票一次。投票人通过产生一个随机数,来决定选择哪个候 选人,该随机数处于1和候选人总数之间。

每个候选人都拥有一个记录(集合),记录着哪些投票人投了他的票。

选举结束后,票数最高的候选人当选。

投票系统

一、概述

You are tasked to implement a voting system for electing a leader of a political party. The process is as follows:

你将设计一个投票系统,选举出政党的候选人。

The party has a list of candidates(候选人) and the voter(投票人) attempt to elect one of the candidates as leader.

有一个候选人的名单,投票人将从中选出一个候选人作为领导。

The voting rules are as follows:

选举规则如下:

  1. Each voter can vote only once. The voter decides which candidate to choose by generating a random number between 1 and the total number of candidates.

    每个投票人只能投票一次。投票人通过产生一个随机数,来决定选择哪个候 选人,该随机数处于1和候选人总数之间。

  2. Each candidate maintains a record of the voters that voted for him

    每个候选人都拥有一个记录(集合),记录着哪些投票人投了他的票。

  3. After election, the candidate with the highest number of votes is elected

    选举结束后,票数最高的候选人当选。

二、Program Deign: 程序设计

Part 1: 第一部分

Design a Person class which includes the following 设计一个Person类

1.1 实例属性和类属性

__name: contains the name of the person 名字。

__age: the age of the person 年龄

__sex:性别

__salary: the persons salary (a real number) 薪水(实数)

__birthday: 生日 类型应该为datetime

 **__id**: the id of the person. A person id cannot be changed intentionally or unintentionally by any method (current or future). It is assigned by the program at creation time and it reflects the order in which the record was created. Namely, the first person’s id is 1; the second person’s id is 2 and so on. Person的id,id不能被任何函数修改,创建Person对象时被赋值,并且反映 创建的顺序。第1个Person的id是1,第2个Person的id是2,依此类推。 

__totalPersons: a static variable that maintains the total persons Person的总数,一个类属性

1.2 方法

​ a constructor __ init_ _(self,name:str,age:int,sex:bool,salary:float,year:int,month:int,day:int)//Q:构造函数的参数为何没有id?

​ 其它方法参考《人员信息管理系统》

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# _*_coding:UTF-8 _*_
from datetime import date


class Person(object):
__totalPersons = 0 # 总人数

# def __init__(self, name, age, salary, year, month, day):
# Person.totalPersons += 1
# self.__name = name
# self.__age = age
# self.__salary = salary
# self.__birthday = date(year, month, day)

def __init__(self, name: str, age: int, sex: bool, salary: float, year: int, month: int, day: int):
self.__sex = sex
self.__age = age
self.__name = name
self.__salary = salary
self.__birthday = date(year, month, day)
Person.__totalPersons += 1
self.__id = self.__totalPersons

def get_age(self):
return self.__age

def get_name(self):
return self.__name

def get_sex(self):
return self.get_sex()

def get_birthday(self):
return self.__birthday

def get_salary(self):
return self.__salary

def set_sex(self, sex):
self.__sex = sex

def set_name(self, name):
self.__name = name

def set_age(self, age):
self.__age = age

def set_salary(self, salary):
self.__salary = salary

def set_birthday(self, y, m, d):
self.__birthday + date(y, m, d)

# def __str__(self):
# return "姓名:%s,年龄:%d,薪资:%d" % (self.__name, self.__age, self.__salary)

def get_toal_persons(self):
return self.__totalPersons

def __str__(self):
return "姓名:%s,年龄:%s,性别%s,日期:%s" % (self.__name, self.__age, self.__sex, self.__birthday)

def output(self):
print(self)


if __name__ == '__main__':
p1 = Person("John", 20, 6000, 2020, 1, 1)
p2 = Person("John", 20, 6000, 2020, 1, 1)

print(p1)
print(type(p2))

Part 2: 第二部分

Design a Voter class that will inherit from the Person class and will have the following fields:

设计一个Voter(投票人)类,继承自Person类。

2.1 实例属性和类属性

__polingStation::the number of the poling station that the voter needs to go and register

​ 投票人要去的投票站的id

__totalNumVoters: a static variable that contains the total number of voters that each candidate has.

​ 选民总人数

2.2 方法

  • the method def SelectCadidate(self,candidates:PersonList ) : randomly select a candidate

    选择候选人,参数是候选人集合,随机选择一个候选人并返回。

  • the method Vote(self, aCandidate:Candidate ): vote a candidate

    投票函数,选出候选人之后,把当前的投票人对象,加入到该候选人的投票 人集合里。

1
2
def Vote(self,aCandidate:Candidate):
aCandidate.addVoter(self)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
from person import Person
from personlist import PersonList
from candidate import Candidate
import random


class Voter(Person):
__totalNumVoters = 0 # id 和 Voter总人数

# def __init__(self, name, age, salary, year, month, day):
# Person.__init__(self, name, age, salary, year, month, day)
# Voter.totalNumVoters += 1
# self.__polingStation = polingStation
# self.__id = Voter.totalNumVoters

def __init__(self, polingStation, *args, **kwargs):
self.__flag = False # 标识投票状态
self.__polingStation = polingStation
Voter.__totalNumVoters += 1
super().__init__(*args, **kwargs)


def select_cadidate(self, candidates: PersonList):
# p = random.randint(1, candidates.size()) # 选中的候选者的id
#
# for candidate in candidates:
# if p == candidate.get_id(): # 选中id == 候选者id
# return candidate
# index = random.randint(0,len(candidates))
# return candidates[index]
# random.choice随机选出候选者对象
return random.choice(candidates)

# def get_age(self):
# return self.__age
#
# def get_salary(self):
# return self.__salary

def vote(self, aCandiate: PersonList):
# aCandiate.get_voterList().add(self) # 使用候选者的voterlist存放投票者对象
# 限制每个人的投票次数
if self.__flag: # flag 为flase
print("已经投票,请不要重复投票")
else:
# 随机选出,将自己添加给候选者
aCandiate.add_voter(self)
self.__flag = True
print("投票成功")

def get_total_voters(self):
return self.totalNumVoters

def resert_vote(self): # 重置投票状态
self.__flag = False

Part 3: 第三部分

Design a Candidate class that will inherit from Person class and will have the following:

候选人类,继承自Person类

3.1 实例属性和类属性

__voterList: the voterList contains all the voters that voted for the candidate. The set should not be limited in size. Use the container class PersonSet that you implemented in assignment

​ 容器类,包含所有投票给该候选人的投票人,容器的尺寸没有限制,使用作 业1中完成的PersonList类。

__numCandidates: a static variable that contains the total number of candidates which are still in the race for the leadership

​ 候选人总数。

3.2 方法

  • a method that returns the number of votes that the candidate received: getVotesNum() return the number of voters

    返回候选人得到的选票数

  • getAverageVotersAge(): prints the average age of the voters that voted for the candidate

    打印投票给该候选人的投票人的平均年龄

  • GetAverageVotersSalary(): prints the average salary of the voters that voted for the candidate

    打印投票给该候选人的投票人的平均薪水。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
from person import Person
from personlist import PersonList


class Candidate(Person):
__numCandidates = 0 # 候选者id 和 候选者总人数

# def __init__(self, name, age, salary, year, month, day):
# Candidate.numCandidates += 1
# Person.__init__(self, name, age, salary, year, month, day)
# self.__name = name
# self.__id = Candidate.numCandidates
# self.__voterList = PersonList() # voterlist对象

def __init__(self, *args, **kwargs):
# 创建一个容器,用于记录谁给参选者投了票
self.__voterList = PersonList()
super().__init__(*args, **kwargs)
Candidate.__numCandidates += 1


# def output(self):
# print('候选人:', self, 'id:', self.__id)

def get_voterList(self): # 获取私有属性voterList 用于存放选择候选者的支持者
return self.__voterList

# def get_id(self): # 获取私有属性 候选者的id
# return self.__id
#
# def get_name(self):
# return self.__name

def add_voter(self, voter): # 添加投票人
self.__voterList.add(voter)

def show_voters(self): # 展示候选者的支持人信息
print(self.__voterList)

def get_voter_number(self): # 获取的票数量
return self.__voterList.size()
# return len(self.__voterLisrt)

def get_average_voter_age(self):
sum = 0
for i in self.get_voterList():
sum += i.get_age()
if self.get_voter_number():
return sum / self.get_voter_number()
return 0

def get_average_voter_slary(self):
sum = 0
for i in self.get_voterList():
sum += i.get_salary()
if self.get_voter_number():
return sum / self.get_voter_number()
return 0

def reset_voters(self):
for i in range(self.__voterList.size()): # 进行二次投票,清空支持候选者的列表
self.__voterList.pop()



Part 5: 第四部分

PersonList类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
from person import Person


class PersonList:
def __init__(self):
self.__list = []
self.__index = 0
self.__index1 = 0

def __len__(self): # 默认覆盖len方法
return len(self.__list)

def __getitem__(self, index):
return self.__list[index]

def add(self, person: Person): # 添加person
self.__list.append(person)

def size(self): # 容器中的元素个数
return len(self.__list)

def remove(self, person):
self.__list.remove(person)

def pop(self, index=None):
if not index:
return self.__list.pop()
return self.__list.pop(index)

# def output(self): # 输出打印容器中的所有的person对象
# for p in self.__list:
# p.output()

def reset(self):
self.__index1 = -1 # 重置index

def next_element(self): # 负责循环迭代
if self.__index1 >= self.size():
self.__index = -1
self.__index += 1
return self.__list[self.__index1]

def __iter__(self):
self.__index = 0 # 重置下标
return self

def __next__(self):
if self.__index < len(self.__list):
item = self.__list[self.__index]
self.__index += 1
return item
else:
raise StopIteration

def __str__(self):
string = ""
for p in self.__list:
string += p.__str__() + '\n'
return string


if __name__ == '__main__':
p1 = Person("John", 20, 6000, 2020, 1, 1)
p2 = Person("John", 20, 6000, 2020, 1, 1)

pl = PersonList()
pl.add(p1)
pl.add(p2)
print(pl)
# pl.output()
for i in pl:
print(i)

Part 5: 第五部分

测试代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# _*_coding:UTF-8 _*_
from personlist import PersonList
from candidate import Candidate
from voter import Voter

counter = 1 # 计数,第几次投票


def start_voting(voters, candidates):
global counter
print(f"...........................第{counter}次投票...........................")
counter += 1

for c in candidates: # 遍历候选人的容器
c.reset_voters() # 清理容器
for voter in voters:
voter.resert_vote()

# 让每个投票人随即投票并添加到候选者的列表
for voter in voters:
c = voter.select_cadidate(candidates)
voter.vote(c) #进行投票操作

# 显示每个候选者人对应的投票人
for can in candidates:
print("投票给[%s]的人you:"%can.get_name())
can.show_voters()

#判断
maxCan = candidates[0]
for i in range(1,len(candidates)):
if candidates[i].get_voter_number()>maxCan.get_voter_number():
maxCan = candidates[i]

# 定义新容器存放,新一轮的候选者
newCandidates =PersonList()
for can in candidates:
if maxCan.get_voter_number()==can.get_voter_number():
newCandidates.add(can)

if newCandidates.size()>=2:
start_voting(voters,newCandidates)
else:
print("最高票数的人是:%s,得票数为:%d"%(maxCan.get_name(),maxCan.get_voter_number()))
print((f"支持这的平均年龄{maxCan.get_average_voter_age()},平均薪水为:{maxCan.get_average_voter_slary()}"))

def main():

# 创建投票者队伍
voters = PersonList()
# 创建参选者队伍
candidates = PersonList() # 此处考察面向对象的创建和使用
# 添加3个参选人:
candidates.add(Candidate(sex=True, age=18, name='Tom', salary=4654, year=2001, month=5, day=3))
candidates.add(Candidate(sex=True, age=19, name='Jack', salary=4654, year=2001, month=5, day=3))
candidates.add(Candidate(sex=True, age=20, name='Linda', salary=4654, year=2001, month=5, day=3))
# 添加5个投票者
voters.add(Voter(polingStation="NewYork1", sex=True, age=20, name='zhao1', salary=4654, year=2001, month=5, day=3))
voters.add(Voter(polingStation="NewYork2", sex=False, age=20, name='zhao2', salary=4654, year=2001, month=5, day=3))
voters.add(Voter(polingStation="NewYork3", sex=False, age=20, name='zhao3', salary=4654, year=2001, month=5, day=3))
voters.add(Voter(polingStation="NewYork4", sex=True, age=20, name='zhao4', salary=4654, year=2001, month=5, day=3))
voters.add(Voter(polingStation="NewYork5", sex=False, age=20, name='zhao5', salary=4654, year=2001, month=5, day=3))


start_voting(voters,candidates)

if __name__ == '__main__':
main()
Prev:
JavaScript-实现简易购物车
Next:
Python--字符串练习题