Day10:使用CSV文件创建用户数据库
本周的项目是使用CSV文件构建一个用户数据库副本。
项目要求:可以接收用户输入的信息,并允许用户登录/注销/注册。
为了跟上这节课的进度,让我们在"Week_06"笔记本下添加一个markdown单元格,在单元格内写上“周五项目:利用CSV文件创建一个用户数据库”。
1 程序设计
这周的项目充满逻辑性。
我们需要了解如何设置一个循序渐进的步骤来让用户登录或登出。
这个程序有三个主要部分:用户注册部分、用户登录部分和程序运行的主体循环部分。
程序的前两个部分主要是执行注册和登录任务,因此我们可以针对这两个任务分别创建函数,并在主循环中适时调用它们。
下面,我们不妨列出实现该项目要求的程序设计思路:
判断用户是否已经登录。
a. 如果已经登陆,询问用户是否想要注销或退出。
i. 退出程序或注销用户,然后重新启动。
b. 如果未登录,询问用户是否想要登录/注册/退出。
i. 如果想要登录,请用户输入邮箱和密码。
1. 如果正确,则登录用户,并重新启动。
2. 否则返回错误信息,并重新启动。
ii. 如果想要注册,请用户输入邮箱/密码/密码2。
1. 如果前后两个密码相同,则保存用户信息并重新启动。
2. 否则返回错误信息,并重新启动。
iii. 如要退出,则输出“thank you”,并退出程序。
上面是程序主体循环的流程图。
既然你已经知道程序的运行逻辑,我建议你尝试自己构建它。自己先写出程序,再跟我的代码对比,有助于你查漏补缺。在用户退出前,程序应该持续运行,并允许用户注册或登录。当登录后,便只能选择注销或退出。
这个项目很简单,但可以帮助你进一步理解如何处理菜单系统。
2 设置必要的导入
首先,让我们导入运行程序所需的文件和函数:
1| # 导入要用到的包
2| import csv
3| from IPython.display import clear_output
我们将在一个单元格中编写所有代码,所以现在不需要运行单元格。
导入CSV库,以便能够使用CSV文件;导入clear_output
函数,该函数允许我们清除单元格中的notebook语句。
3 处理用户注册
接下来,我们设计用于注册用户的函数。让我们来看看这个函数:
5| # 处理用户注册,并将用户信息写入CSV文件中
6| def registerUser( ):
7| with open("users.csv", mode="a", newline="") as f:
8| writer = csv.writer(f, delimiter=",")
10| print("To register, please enter your info:")
11| email = input("E-mail: ")
12| password = input("Password: ")
13| password2 = input("Re-type password: ")
15| clear_output( )
17| if password == password2:
18| writer.writerow( [email, password] )
19| print("You are now registered!")
20| else:
21| print("Something went wrong. Try again.")
我们首先定义了函数,随后打开一个名为user.csv
的CSV文件。这个文件将用于存储用户的数据。为了向文件中添加额外信息,我们为该文件创建了一个writer对象。在提示用户输入相关信息后,我们检查输入的两个密码是否相同。
如果相同,则利用创建的writer对象将用户信息添加到CSV文件中;反之,则让用户知道导致错误的原因。现在你可以随意调用这个函数并测试它。
在第一次测试之后,你应该注意到程序自动创建了CSV文件。
4 处理用户登录
我们要设计的第二个任务是允许用户登录,让我们学习下端代码:
23| # 询问用户信息,如果登录成功返回true,反之则返回false
24| def loginUser( ):
25| print("To login, please enter your info:")
26| email = input("E-mail: ")
27| password = input("Password: ")
29| clear_output( )
31| with open("users.csv", mode="r") as f:
32| reader = csv.reader(f, delimiter=",")
34| for row in reader:
35| if row == [email, password]:
36| print("You are now logged in!")
37| return True
39| print("Something went wrong, try again.")
40| return False
在用户登录函数中,我们提示用户输入他们的信息。
然后以只读模式打开存储用户信息的文件。随后使用CSV库创建一个reader对象,在第34行代码处逐行遍历CSV信息。我们读取的每一行数据都是包含两个元素的列表,第一元素是电子邮件,第二个元素是密码。
在第35行,我们比较了CSV文件中的每一行信息和用户输入的信息。如果数据匹配,则用户登录成功,并返回True;否则,展示错误信息,并返回False。
执行注册函数后,可以尝试调用此函数。
注意: CSV文件存储在与笔记本文件位于相同的目录中。
5 创建程序主体
到目前为止,我们为了实现项目要求,创建了的两个函数,分别用于注册和登录用户。程序的主体部分将处理菜单系统,以及根据用户的选择而输出特定的信息。
下面,让我们继续完成这个程序:
42| # 主体循环中的变量
43| active = True
44| logged_in = False
46| # 主体循环
47| while active:
48| if logged_in:
49| print("1. Logout\n2. Quit")
50| else:
51| print("1. Login\n2. Register\n3. Quit")
53| choice = input("What would you like to do? ").lower( )
55| clear_output( )
57| if choice == "register" and logged_in == False:
58| registerUser( )
59| elif choice == "login" and logged_in == False:
60| logged_in = loginUser( )
61| elif choice == "quit":
62| active = False
63| print("Thanks for using our software!")
64| elif choice == "logout" and logged_in == True:
65| logged_in = False
66| print("You are now logged out.")
67| else:
68| print("Sorry, please try again!")
运行上段代码。
在循环开始之前,我们为程序定义两个变量。
这些变量将跟踪正在登录的用户以及程序是否应该继续运行。然后,我们进入主循环并根据用户当前状态显示适当的菜单。程序初次运行时,用户从未进行过登录,因此将显示第二个菜单(即第51行)。
然后,我们使用input()
询问用户希望做什么。接下来便是逻辑判断部分,我们将根据用户的选择,执行一个特定的操作。我们这样做是为了让用户在还没有登录时才可以选择登录或注册(当然也可以退出)。
同样,用户只有在登录后注销。
如果用户选择登录或注册,我们则调用相应的函数来执行任务。执行完处理用户登录的函数后,将返回True或False,然后我们函数所返回的值赋给logged_in
变量。
如果用户决定退出,我们将active
变量更新为False并退出程序。在用户退出前,程序将根据用户的状态不断显示适当的菜单。
如果用户不选择程序中所列选项,我们将显示错误消息。
今日小结
今天,我们通过使用CSV文件学习了用户注册过程中程序的后台逻辑。
在本书的后面,我们将使用类似的概念来存储数据。