python学习第五节:用面向对象实现friendbook

课程视频链接

跟着麦叔学Python:https://b23.tv/Xx9NV0

1. 主程序 friend.py

from cmd import *
def print_usage():
	print("欢迎使用FriendBook,您可以输入以下命令:")
	print("list: 显示名单")
	print("张三:查询张三的情况,李四同理")
	print("886: 退出")

print_usage()

while(True):
	cmd = input('请输入命令:')
	if(cmd == '886'):
		print("再见啦...")
		break
	elif(cmd == 'list'):
		show_list()
	elif(cmd.isdigit()):
		find_by_id(cmd)
	else:
		find(cmd)

2. 创建模拟数据并写入文本 gen_data.py

import random

xings_str = "李,王,张,刘,陈,杨,黄,赵,周,吴,徐,孙,朱,马,胡,郭,林,何,高,梁,郑,罗,宋,谢,唐,韩,曹,许,邓,萧,冯,曾,程,蔡,彭,潘,袁,于,董,余,苏,叶,吕,魏,蒋,田,杜,丁,沈,姜,范,江,傅,钟,卢,汪,戴,崔,任,陆,廖,姚,方,金,邱,夏,谭,韦,贾,邹,石,熊,孟,秦,阎,薛,侯,雷,白,龙,段,郝,孔,邵,史,毛,常,万,顾,赖,武,康,贺,严,尹,钱,施,牛,洪,龚"
mings_str = "大,二,三,四,五,六,七,八,九"
add_score_things = "点赞,赞美,投币,充电,打电话,帮助,送礼物"
reduce_score_things = "骂,打,欺骗,白嫖,要挟"

names = [] # ['45,戴八','']
records = []  # 张三 骂了 李四 减1分;王五 请吃饭 马六 加1分
#records = ['9,毛七,欺骗,60,尹四,-1','']  


def mock_names():
    xings = xings_str.split(",")
    mings = mings_str.split(",")
    for i in range(100):
        xing = random.choice(xings)
        ming = random.choice(mings)
        names.append('{},{}'.format(i+1, xing+ming)) # '45,戴八'
 

def mock_records():
    good_things = add_score_things.split(",")
    bad_things = reduce_score_things.split(",")
    things = good_things + bad_things
    for i in range(10000):
        n1 = random.choice(names)
        n2 = random.choice(names)
        thing = random.choice(things)
        if(things.index(thing) >= len(good_things)):
            score = -1
        else:
            score = 1
        records.append('{},{},{},{}'.format(n1, thing, n2, score)) # '9,毛七,欺骗,60,尹四,-1' 

def save_to_file():
    with open('names.txt', 'w') as names_file:  # with 在打开文件后会自动关闭,默认方式是'r',读文件;a,加;w,重新写
        for n in names:
            names_file.write('{}\n'.format(n))
    with open('records.txt', 'w') as records_file:
        for n in records:
            records_file.write('{}\n'.format(n))

# 直接运行才会生成,引入不会生成
if __name__ == '__main__':
    print("generating mock data")
    mock_names()
    mock_records()
    save_to_file()
    print("finished mock")

3. 创建类 person.py

class Person():
    def __init__(self, id, name):
        self.id = id
        self.name = name
        self.records = []
        self.scores = {}
    
    def add_record(self, record):
        self.records.append(record)
        self.scores.setdefault(record.person.id, 0) #如果键不存在于字典中,将会添加键并将值设为默认值,相当于判断并赋值
        self.scores[record.person.id] += record.score


    def remove_record(self, record):
        self.records.remove(record)   

class Record():
    def __init__(self, person, action, score):
        self.person = person
        self.action = action
        self.score = score


# 自动化测试
if __name__ == "__main__":
    p1 = Person(1, '张三')
    p2 = Person(2, '李四')
    r = Record(p2, '白嫖', -1)
    p1.add_record(r)
    assert len(p1.records) == 1, '应该有1条record'
    p1.remove_record(r)
    assert len(p1.records) == 0, '应该有0条record'

4. 将文本数据加载到类中 friend_data.py

from person import *

persons = [] 

def load_data():
    load_names()
    load_records()


def load_names():
    with open('names.txt') as name_file: # 默认是r
        lines = name_file.readlines() # 把每一行读出来
        for line in lines:
            id, name = line.split(',')
            persons.append(Person(int(id), name.strip())) #strip() 去掉开头和末尾的空格和换行符


def load_records():
    with open('records.txt') as records_file: # 默认是r
        lines = records_file.readlines() # 把每一行读出来
        for line in lines:
            # 20,洪六,投币,97,袁三,1
            points = line.split(',')  # points是一个列表
            p1 = find_person(points[0].strip()) # 去掉分割出来文字的空格
            p2 = find_person(points[3].strip())
            if (p1 == None or p2 == None):
                continue
            action = points[2].strip()
            score = int(points[5].strip())
            r = Record(p2, action, score)
            p1.add_record(r)


def find_person(id):
    ps = [p for p in persons if p.id == int(id)]
    if len(ps) > 0:
        #print('found {}'.format(ps[0].name))
        return ps[0]  #返回一个person实例


load_data()
if __name__ == "__main__":
    for p in persons:
        print('{} has {} records'.format(p.name, len(p.records)))

5. 实现主程序的命令 cmd.py

from friend_data import *

def show_list():
    for p in persons:
        print("{}. {}".format(p.id, p.name))


def find_by_id(id):
    id = int(id)
    p = find_person(id)
    if(p == None):
        print("无效的ID{}".format(id))
    else:
        show_one(p)


def show_one(p):
    print("{}. {}".format(p.id, p.name))
    #show_records(p)
    show_summary(p)


def show_records(p):
    for r in p.records:
        # 张三(12) 给我 充电 1
        p2 = r.person
        print("{}({}) 给我 {} {}".format(p2.name, p2.id, r.action, r.score))


def show_summary(p):
    print("===== 总分数 =====")
    for id2, score in p.scores.items(): 
        p2 = find_person(id2)
        print("{} ({}): {}".format(p2.name, p2.id, score))


def find(name):
    find_names = [p for p in persons if p.name == name] # 是list[]
    count = len(find_names)
    if(count == 0):
        print("不存在:{}".format(name))
    elif(count > 1):
        for p in find_names:
            print("{}. {}".format(p.id, p.name))
        print("有多个{},请输入id选择具体的人".format(name))
    else:
        show_one(find_names[0])

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值