Python实现的通讯录

Python实现的通讯录_第1张图片

"为何表情,要让这世界安排?"

诶,我们也对python的一些基础语法有了一定能的了解了。并且在这基础上,学习了python中的文件操作,那么有了这些东西以后啊,我们能做什么呢?或许对很多数据结构的初学者来说,通讯录是他们第一个可以展示他们所习得知识的舞台。那么python中的通讯录,是怎样实现的呢?

一、main函数与功能列表

python属于是一种半编译半解释的语言,没有严格的main函数。但是,我们写C/C++,Java等语言写一个程序时,第一步往往都是是实现好一个main函数,因为那是程序启动的"入口"。

def menu():
   print("1> Add a new students's information ")
   print("2> Delete a existed Students' information ")
   print("3> Show all of information ")
   print("4> Find a Stduent ")
   print("0> For exit the Use ")
   choice = input("Please Enter your choice for Execute> ")
   return choice


def main():
    print('----------------------------------')
    print('             欢迎来到学生管理系统               ')
    print('----------------------------------')
    #打印菜单信息
    while True:
        choice = menu()
        if choice == '1':
            #add
            pass
        elif choice =='2': 
            #delete
            pass
        elif choice =='3':
            #show
            pass
        elif choice =='4':
            #find
            pass
        elif choice =='0':
            #exit process
            print("Students'management System close done!")
        else:
            #输入错误
            print("Wrong Input,Please Try Again~")

我们设计3个通讯录的主功能,"增删查"。每个功能的pass是为了现在编译能过,没啥实际意义。

Python实现的通讯录_第2张图片

二、增加信息

我们需要为通讯录做一份协议,即学生信息的格式。

Python实现的通讯录_第3张图片
Students = []
def Insert():
    print("Now for Add Students' information")
    # 姓名 学号 性别 院系
    student_id = input("Please Enter information for ID")
    student_name = input("Please Enter information for st_name")
    student_sexy = input("Please Enter information for sexy")
    student_faculty = input("Please Enter information for faculty")

    #差错处理
    if student_sexy not in ('男','女'):
        print("Wrong Input in Student_Sexy")
        return

    #收集信息,整合成一个字典类型{}
    student = {
        'student_id':student_id,
        'student_name':student_name,
        'student_sexy':student_sexy,
        'student_faculty':student_faculty
    }

    #存入students
    #如果要使用全局变量 最好先声明 再使用
    global Students
    Students.append(student)
    print("Success in Saving information")

用C语言完成通讯录时,为了保证其的动态性~我们选择使用一块动态内存开辟的空间。

如:Data_Block,而里面的数据 或许是一个struct st_Info{ .... }Data_Block[st_Info]。在pyhton中,似乎不需要像C语言管理数据的数组一样,像heap申请内存空间。而是用列表[](类似数组一样),但是它是动态开辟的,可以存储任何数据类型。如我们使用的全局边Students = []。每个student是一个哈希结构的字典,key:value(当然为什么这里选择字典结构呢?后面会提及)。因此,在python中,这里实现的存储学生信息的容器从动态数组(Data_Block)变为了列表(Students),从struct结构体(st_Info)变为了字典结构(student)。

第十一行的差错处理是有必要的,str1 not in('c1','c2'),是python特有的表达方式,是让str1去由('c1','c2')构成的列表序列查找,如果存在返回True,否则返回False。

三、删除信息

def Delete():
    #这里删除我们 选择根据student_id删除
    StudentID = input("Please Enter st_ID you wanner to delete")
    for s in Students:
        if s['student_id'] == StudentID:
            Students.remove(s)
    print("Sucess in deleting Information")
Python实现的通讯录_第4张图片

这里的s会在Students这个序列里去取里面的每个对象。这里我们设计的字典结构的原因找到了,我们可以很轻松地甄别到哪个s才是 要被删除的。

列表.remove(obj):指的是在列表中删除obj元素。

四、打印与查找

打印格式,我们希望[姓名] \t [学号] \t [性别]\t [院系]\t

def Show():
    for info in Students:
        print(f"[{info['student_name']}]\t[{info['student_id']}]\t[{info['student_gender']}]\t{info['student_faculty']}")
    print(f"Show the number of Information:{len(Students)}")


def Find():
    #我们这里输入姓名查找因此 不免会有同名的现象。我们统一做的处理是打印出出来
    count = 0
    name = input("Please Enter Name you wanner to find> ")
    for info in Students:
        if name == info['student_name']:
            print(f"[{info['student_id']}]\t[{info['student_name']}]\t[{info['student_gender']}]\t,[{info['student_faculty']}]")
            count += 1
    print(f"Total of the Students: {count}")

测试:

那么我们的增删查实现的功能也完成了,我们来看看成果吧~

Python实现的通讯录_第5张图片
Python实现的通讯录_第6张图片

五、文件版本

Python实现的通讯录_第7张图片

此时我们的系统还存有两个人的信息,我们重新打开程序试试看。

Python实现的通讯录_第8张图片

我们发现没有任何数据??? 那么之前辛辛苦苦插入的数据去哪里了呢?我们都知道,程序一旦运行起来,OS通过调度将程序的代码读进内存,以供cpu快速取指令执行任务。一旦程序结束,那么本来该分配给程序的空间,也就被"销毁"。你运行时存储的数据,无非是在内存中存储的,是易失性的。

那么什么数据是永久存储的呢?答案当然是磁盘!

Python实现的通讯录_第9张图片

我们想要的存入记事本的格式是这样的,以便读取。

def Save():
    #将我们的数据存入磁盘
    with open('DataSave.txt','w',encoding = 'utf-8') as f :
        #写入文件
        for info in Students:
            f.wirte(f"{info['student_name']}\t{info['student_id']}\t{info['student_gender']}\t{info['student_faculty']}\n")

    print(f"Total for Save: {len(Students)}")

with open上下文管理器,等于说我们可以不需要手动管理想系统申请的文件描述符,它会帮我们进行资源的回收管理。

有了save,那么一定有从磁盘文件中读取数据的步骤:

def Load():
    #有没有可能 我是第一次打开更新这个管理系统?那么就不会存在DataSave.txt
    if not os.path.exists('DataSave.txt.'):
        print("Nothing to Load")
        return #也就不需要读取了

    count = 0
    global Students
    #读文件
    with open('DataSave.txt','r',encoding='utf-8') as f:
        # 因为我们是按照行存储的 那么读取数据也是按照行读取
        for line in f:
            #name   id  gender  faculty\n
            line = line.strip() #去掉传末尾\n
            tokens = line.split('\t')#以'\t'作为分隔符 切割字符串
            #解析出来的格式一定有四个(name,id,gender,faculty)
            if len(tokens) != 4:
                print("Wrong Parse format!")
                return
        #填充信息
        student = {
            'student_name':tokens[0],
            'student_id':tokens[1],
            'student_gender':tokens[2],
            'student_faculty':tokens[3]
        }
        #插入总的序列容器中
        Students.append(student)
        count += 1
    print(f"Total Load num: {count}")
Python实现的通讯录_第10张图片

六、测试

Python实现的通讯录_第11张图片

我们需要在程序加载处Load之前存储的数据。

Python实现的通讯录_第12张图片
Python实现的通讯录_第13张图片

我们首先清空记事本,开是我们的录用信息之旅吧~

Python实现的通讯录_第14张图片

如我们所见,我们存入的信息能在磁盘上保存了。

程序退出:

Python实现的通讯录_第15张图片

当然怎么退出我们的通讯录呢,我想点最上面的红色方括号有些挫。系统sys提供了结束进程的函数,调用即可。

Python实现的通讯录_第16张图片

总结

其实可以看见,如果你写过一套完整的纯C写的通讯录,你就会发现后发展起来的语言,对于前者的一些不好地方的舍弃,好的地方的取用。我们在python中用可以存储任何数据类型、自动扩容的列表,替代了需要动态开辟的数组。我们用python的字典,替代了需要在.h中定义的strcut st_Info{}。我们可以使用line = str.split('\t'),以'\t'分割切开,返回一个列表赋值给line,我们同样使用str.strip()去掉字符串末尾与数据读取无关紧要字符…… 只能说,"Life is short,you need Python"

本篇就到此结束了,感谢你的阅读。

祝你好运,向阳而生~

Python实现的通讯录_第17张图片

你可能感兴趣的:(python)