1.起步
Python是跨平台语言,可以在Linux、Windows和Mac上安装,我这里使用Mac,安装步骤我就略去了,很简单,网上也有很多资料。
知识点1:进入/退出python2和python3控制台
要检查系统是否安装了Python3,可尝试执行命令python3。注意,如果执行命令python,默认调用的是python2。输入该命令后,进入了python,可以使用 来退出python控制台。下边是我的操作(注意,我使用了2种方式来退出):
maning@maningdeMacBook-Pro ~ % python3
Python 3.8.2 (default, Aug 25 2020, 09:23:57)
[Clang 12.0.0 (clang-1200.0.32.2)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> exit()
maning@maningdeMacBook-Pro ~ % python
WARNING: Python 2.7 is not recommended.
This version is included in macOS for compatibility with legacy software.
Future versions of macOS will not include Python 2.7.
Instead, it is recommended that you transition to using 'python3' from within Terminal.
Python 2.7.16 (default, May 8 2021, 11:48:02)
[GCC Apple LLVM 12.0.5 (clang-1205.0.19.59.6) [+internal-os, ptrauth-isa=deploy on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> ^D
知识点2:文本编辑器(Sublime)配置正确的python版本
配置Sublime Text的编译系统, 具体方法如下:
保存文件Python3.sublime-build 到默认打开的文件夹下
{
"cmd": ["python3", "-u", "$file" ]
}
完成了上述配置后,就可以直接在Sublime中进行脚本的执行了(使用Python3),运行的快捷键是 ,请看我的执行结果:
2. 变量
变量名只能包含字母、数字和下划线。变量名能以字母或下划线打头,但不能以数字打头。python变量命名使用类似SQL的风格,不是驼峰风格,例如,比较标准的定义变量是name_length。
2.1 字符串
在Python中,用引号引起来的,都是字符串, 。因为这个灵活的特征,我们就可以在字符串中定义双引号/单引号了。明显的,想在字符串中定义双引号,我可以使用单引号来定义字符串。想在字符串中定义单引号,我可以使用双引号来定义字符串。
if __name__ == '__main__':
message = "Kafka's simple message"
print(message)
message = 'Xiao Ming says: "We will never divorce!" '
print(message)
要想在字符串中插入变量值,可以在字符串的前引号前加上字母f,再将要插入的变量放在花括号内。f是format的简写,很明显这个功能可以用来做字符串合并。这个也和经常使用的 "{}".format(vr1)一样,是其高版本方法。
2.2 数
python也是包含整型,浮点型。这里只说与java的区别吧,python中2个整型相除时,得到的结果是浮点数。例如16/2得到的是8.0 这是区别于java的。
2.3 python之禅
这里在python控制台输入了 import this 后,输了一些编写优雅python代码的规则,就是传说中的python之禅 :
>>> import this
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
3. 列表
列表是python中很重和基础的数据结构。 python的列表与java的数组十分相似,我感觉有2个区别:
1.python可以访问-1,-2元素,返回倒数第一、二个元素。
2.元素类型可以不一致。
3.1 列表访问和修改
1.访问和修改元素的方式和java数组一致,例如brands[0] ,需要注意,下标从0开始。
2.增加元素可以使用方法,例如brands.append('BMW') 。
3.使用可删除任意位置处的列表元素,条件是知道其索引。例如 del brands[0]会删除brands列表的第一个元素。
4.可以使用方法,删除并返回删除的数据,不给参数表示删除最后一个元素,也可以指定元素,例如 moto = brands.pop(4) 删除第5个元素并返回。
5.可以使用方法,删除列表中值等于参数名的元素,如果列表中有多个相同的元素,只会删除第一个。 例如brands.remove("Ford"),删除列表中值为Ford的元素。
针对列表的插入和删除,我写了一个程序,当做训练吧,可以参考 :
def invite_someone(list_d):
if len(list_d) == 0 :
print("邀请列表空了!")
for i in list_d:
print(f"我邀请{i}来参加晚宴!")
if __name__ == '__main__':
names = ["XiaoDeng", "XiaoHong", "XiaoLi", "XiaoMing"]
# 3-4
invite_someone(names)
# 3-5
not_attend_name = names.pop(1)
print(f"--------{not_attend_name}不能参加!--------")
names.append("XiaoMa")
invite_someone(names)
# 3-6
print("--------我找到了一个更大的餐桌!--------")
names.insert(0, "XiaoZhang")
names.insert(3, "XiaoFu")
names.append("XiaoZhao")
invite_someone(names)
# 3-7
print("--------餐桌大小原因,我只能邀请2个人来参加!--------")
while len(names) > 2:
del_name = names.pop()
print(f"非常抱歉{del_name},餐桌小了无法再邀请您!")
for i in names:
print(f"{i},您仍在邀请列表中")
names.remove("XiaoZhang")
del names[0]
invite_someone(names)
3.2 列表的排序
1.类似ArrayList,python的列表也可以排序,使用方法,需要注意的是,该方法会永久改变原列表。默认不加参数是升序排序,sort(reverse=True) 将会降序排序。
2.要保留列表元素原来的排列顺序,同时以特定的顺序呈现它们,可使用函数。例如:sorted(brands)。函数sorted()让你能够按特定顺序显示列表元素,同时不影响它们在列表中的原始排列顺序。
3.方法可以让当前的List逆序显示,不是按照列表元素大小排序,而是按照列表原来的顺序逆序。
4.如果要得到列表的长度,需要使用函数,例如len(brands)
针对列表的排序,写了下边的测试程序 :
if __name__ == '__main__':
cities = ["New York", "Beijing", "Paris", "London", "Tokyo", "Shanghai"]
print(f"原列表:{cities}")
# 注意sorted是函数,不是方法
print(f"sorted()列表:{sorted(cities)}")
print(f"原列表:{cities}")
print(f"反序sorted()列表:{sorted(cities, reverse=True)}")
print(f"原列表:{cities}")
# 注意使用reverse()方法会返回None,调用该方法,改变了原来的列表。
cities.reverse()
print(f"reverse()列表:{cities}")
print(f"原列表:{cities}")
cities.reverse()
print(f"再次reverse()列表:{cities}")
print(f"原列表:{cities}")
cities.sort()
print(f"sort()列表:{cities}")
print(f"原列表:{cities}")
cities.sort(reverse=True)
print(f"反向sort()列表:{cities}")
print(f"原列表:{cities}")
3.3 操作列表
使用list()和range()可以得到数字列表。range()有三个参数,其参数意思分别是 : ,需要注意的是,一、二两位置的数据,代表是左闭右开的。例如下边的例子:
>>> list(range(2,14,3))
[2, 5, 8, 11]
1.对于list来说,可以使用 来实现统计目标。例如min(brands)
2.列表解析是一种简便的编码方式,在python中比较常见,其实是合并了一个for循环语句和list的append()语句,看起来简单明了。
3.列表切片:切片是列表中常用的操作,为了获取列表的部分数据,访问方法是brands[起始位置:终了位置] , 跟上边的range一样,这个也是左闭右开的,同时,起始位置和终了位置都可以省略,起始位置省略表示从第一个元素开始,终了位置省略表示到最后一个元素。
4.复制列表: 这里表示增加一个副本,而不是一个变量指向原有列表。 可以使用切片实现。
请看下边的例子,综合使用了range,列表循环访问,列表解析的内容:
if __name__ == '__main__':
# 4-3
for i in range(1, 21):
print(i)
# 4-5
nums_list = list(range(1, 1000001))
print(f"minValue :{min(nums_list)}")
print(f"maxValue :{max(nums_list)}")
print(f"sunValue :{sum(nums_list)}")
# 4-6
for i in range(1, 21, 2):
print(i)
# 4-7
for i in range(3, 31, 3):
print(i)
# 4-8 / 4-9 列表解析
poly_num = [value**3 for value in range(1, 11)]
print(poly_num)
# 4-10 切片
print(poly_num[1:4])
# 4-11
replica_poly_num = poly_num[:] # 起始终了位置都省略,代表从头到尾
replica_poly_num.append(-1)
print(f"原有列表:{poly_num}")
print(f"副本列表:{replica_poly_num}")
3.4 元组
上边的内容介绍了列表,发现列表是可变的。python中 。元组很像列表,但是使用括号,而不是方括号定义。访问元组时与访问列表一样。
4.列表访问
4.1 生成数字列表
使用for语句可以方便地遍历一个列表中的所有元素。,当然有一个参数时,例如range(b) 其代表的范围是 [0,b)。如果要生成数值列表,需要进一步使用list(range(a,b))。range的第三个参数是步长,没有该参数默认给1 。
列表解析 :列表解析将for循环和创建新元素的代码合并成一行,并自动附加新元素。
4.2 数字列表的统计计算
可以针对数字列表使用Python的统计函数,例如 min() 、max() 、sum()等。
4.3 列表切片
切片的前后位置和range类似,例如 。 如果省略开始的序号,那么从开始位置算起,如果省略终了序号,那么到最后一个元素结束。 例如 ad[:4] 和 ad[1:]。
可以使用切片来复制列表: 例如
if __name__ == '__main__':
ad_basic = list(range(0, 9, 2))
print(f"ad_basic : {ad_basic}")
for i in range(0, 4):
print(i)
print(f"Statistics : minValue:{min(ad_basic)}, maxValue:{max(ad_basic)}, sumValue:{sum(ad_basic)}")
print(f"ad_basic[0:4] :{ad_basic[0:4]}")
ad_basic_new = ad_basic[:]
print(f"ad_basic_new :{ad_basic_new}")
5. if语句
5.1 条件判断
if语句大家都很熟悉,这里分门别类简单介绍python中的if语句。
(1)就是做字符串的等值和不等值判定,可以使用 == 和 != 来进行。 例如:"go_with" == "Go_with" 和 "go_with" != "Go_with" 。
(2) 做数值型的等值和不等值判定。 例如: 14 == 12 和 14 >= 12 等。
(3) 做逻辑与和逻辑或判定。 例如 :"go_with" == "Go_with" and 14 >= 12 或者 14 >= 12 or "go_with" != "Go_with"
(4) 特定值在(或不在)列表中。例如 : num_list是一个数值列表,14 in num_list 表示特定值在列表中, 14 not in num_list 表示特定值不在列表中。
5.2 语句结构
if语句包括 if结构, if-else结构 ,if-elif-else结构。需要注意以下几点 :
在if-elif-else结构中,如果有一个条件满足了,就会跳过所有剩余条件判断。下面举例一个if语句的代码段,作为参考 :
age = 36
if age < 2:
type_name = "婴儿"
elif 2 <= age < 4:
type_name = "幼儿"
elif 4 <= age < 13:
type_name = "儿童"
elif 13 <= age < 20:
type_name = "青少年"
elif 20 <= age < 65:
type_name = "成年人"
else:
type_name = "老年人"
print(f"这个{age}岁的人是{type_name}")
5.3 判断列表为空
在if语句中将列表名用作条件表达式时,Python将在列表至少包含一个元素时返回True,并在列表为空时返回False。if 条件后直接跟列表名。
if语句语法格式: 在诸如==、>=和<=等比较运算符两边各添加一个空格。
test_list = []
if test_list:
print(test_list)
else:
print("空列表")
6. 字典
在Python中,字典是一系列键值对,可将任何Python对象用作字典中的值。在字典中,想存储多少个键值对都可以。
6.1 字典添加、删除元素
1.增加元素:
要添加键值对,可依次指定字典名、用方括号括起的键和相关联的值。在Python3.7中,字典中元素的排列顺序与定义时相同。如果将字典打印出来或遍历其元素,将发现元素的排列顺序与添加顺序相同。
2.删除元素:
对于字典中不再需要的信息,可使用del语句将相应的键值对彻底删除。。
3.统一定义:
可以通过直接定义字典,一种不错的做法是,在最后一个键值对后面也加上逗号,为以后在下一行添加键值对做好准备。
4.防止查询的key不存在:
使用方括号取值时,如果指定的键不存在就会报错。 为了防止这种错误,可以使用get方法。。
# 最后一个元素后边加一个逗号,方便后边要增加元素
favorite_languages = {
'jen': 'python',
'sarah': 'c',
'edward': 'ruby',
'phil': 'python',
}
# 增加字典元素
favorite_languages["andy"] = "scala"
# 删除字典元素
del favorite_languages["jen"]
# 该行会报错
# print(favorite_languages["jen"])
# 使用get防止字典中缺少这个元素
print(favorite_languages.get("jen", "C++"))
print(favorite_languages.get("andy", "C++"))
6.2 字典遍历
字典遍历有三种不同方法,分别是:
6.2.1.遍历键值对:
如果需要遍历键值对,在for循环中可声明两个变量,用于存储键值对中的键和值。for语句的第二部分包含字典名和方法items()。例如下边例子:
print("开始遍历字典元素:\n 1.遍历键值对:")
for key, value in favorite_languages.items():
print(f"{key} likes language {value}")
6.2.2.遍历所有键:
要遍历字典的所有键,使用keys()方法,其实该方法返回了一个列表,该列表中包含所有键,由于列表的特性,我们可以对该列表使用 sorted()方法进行排序。
print("遍历字典中的键")
for name in favorite_languages.keys():
print(f"原序名字:{name}")
for name_sorted in sorted(favorite_languages.keys()):
print(f"顺序名字:{name_sorted}")
6.2.3.遍历所有值:
遍历字典的所有值,需要使用values()方法。返回的值可能会有重复(python只保证字典的键不重复),可以使用set()方法来把值转化为一个集合,这样就不会重复了。
python中定义集合时,也使用花括号,和字典类似,但是没有冒号。 例如定义一个集合 languages_set = {"java", "python", "C", "java", "JAVA"}
print("遍历字典中的值")
for language in favorite_languages.values():
print(f"编程语言{language}")
for language in set(favorite_languages.values()):
print(f"编程语言{language}")
6.3 嵌套
嵌套理解起来很容易,主要包含:在列表中嵌套字典、在字典中嵌套列表以及在字典中嵌套字典。这里就不赘述了。
7.用户输入和while循环
7.1 input()函数
函数input()让程序暂停运行,等待用户输入一些文本。获取用户输入后,Python将其赋给一个变量,以方便你使用。函数input()接受一个参数——要向用户显示的提示(prompt)或说明。
age = input("How old are you, Darling?")
age = int(age)
if 18 <= age <= 35:
print("恭喜,年轻的少年!")
else:
print("不是最好的年龄!")
7.2 while循环和break、continue
while、break和continue在大多数语言中都存在这里不赘述了,可以通过例子看下如何在python中使用这3个语句。
while True:
user_input = input("please input your name:")
if user_input == "quit":
break
print(f"Hello, {user_input}")
break语句: 直接退出循环。
continue语句: 退出本次循环,直接开始下一次循环。
8. 函数
8.1 参数初步
我们知道,python中定义函数需要使用def关键字。当有多个参数时,才给函数传递实参时,Python有2种传递方式,分别是位置实参和关键字实参。另外,还要注意给参数默认值的方法。
1.位置实参 :
对于位置实参,参数的顺序很重要,不能错。在下边的例子中,describe_pet("Tom", "cat") 就是传递位置实参,其不需要指定key(key=value)。 这种方式简便,但是如果参数很多,一定注意顺序。
2.关键字实参 :
相比于第一种,这里将key(也就是定义函数时的形参)指定了,顺序也就不重要了。describe_pet(animal_name="Jerry", animal_type="mouse") 这种传递方式虽然麻烦,但是的确更加准确规范。
3.给参数默认值。
在定义函数时,观察第二个参数在定义时已经给了值,这个就是默认值。def describe_pet(animal_name, animal_type="dog"): 那么在传递实参时,如果不给该参数传递值的话,就直接使用这个默认值。当然,如果给了值,就使用传递的实参。 例如: describe_pet("Harry")
def describe_pet(animal_name, animal_type="dog"):
print(f"I have a {animal_type}")
print(f"The {animal_type}'s name is {animal_name}")
if __name__ == '__main__':
# 位置实参
describe_pet("Tom", "cat")
# 关键字实参
describe_pet(animal_name="Jerry", animal_type="mouse")
# 使用默认参数
describe_pet("Harry")
8.2 传递任意数量的实参
Python允许函数从调用语句中收集任意数量的实参。
如果要让函数接受不同类型的实参,必须在函数定义中将接纳任意数量实参的形参放在最后。Python先匹配位置实参和关键字实参,再将余下的实参都收集到最后一个形参中。
同时,可将函数编写成能够接受任意数量的键值对——调用语句提供了多少就接受多少。这种情况在形参前加2个星号,对比于列表参数的一个星号。
下边这个例子,包含这2种类型的多参数 :
def pizza_making(size, *toppings):
print(f"Making {size} inch pizza, needs the following content:")
for topping in toppings:
print(f"-{topping}")
# toppings是一个元组
print(f"%%%%the first topping is {toppings[0]}")
print(toppings)
def list_user_info(school_name, **userinfo):
print(f"This func will list {school_name} school's user list.")
for key, value in userinfo.items():
print(f"Student {key} is {value}!")
if __name__ == '__main__':
# 通过元组来保存多个实参
pizza_making(16, "mushroom", "pepper", "water")
pizza_making(23, "mushroom", "pepper")
# 通过字典来保存多个实参(键值对)
list_user_info("Jiaotong University", leo="boy", lily="girl", tom="boy")
"""
代码执行结果
Making 16 inch pizza, needs the following content:
-mushroom
-pepper
-water
%%%%the first topping is mushroom
('mushroom', 'pepper', 'water')
Making 23 inch pizza, needs the following content:
-mushroom
-pepper
%%%%the first topping is mushroom
('mushroom', 'pepper')
This func will list Jiaotong University school's user list.
Student leo is boy!
Student lily is girl!
Student tom is boy!
"""
8.3 将函数存储在模块中
将函数存储在称为模块的独立文件中,再将模块导入到主程序中。import语句允许在当前运行的程序文件中使用模块中的代码。
在import时,需要指定模块文件的目录。
要让函数是可导入的,得先创建模块。模块是扩展名为.py的文件,包含要导入到程序中的代码。
1.import语句导入了名为module_name.py的整个模块。使用时,需要这样调用函数 : module_name.function_name()
2.导入特定函数 : from module_name import function_0,function_1,function_2
3.如果要导入函数的名称可能与程序中现有的名称冲突,或者函数的名称太长,可指定简短而独一无二的别名。例如这样给函数重命名:from pizza import make_pizza as mp ; 或者这样给模块重命名:import pizza as p 。
4.导入模块中的所有函数 : from pizza import * 由于导入所有函数,在调用时,不需要使用句点表示法。
9. 类
9.1 类的基本说明 :
Python也支持面向对象开发方法。 下边定义一个示例类Dog。
下面先说明下构造方法,Python中的构造方法是:init() 。 构造方法中的形参self必不可少,而且必须位于其他形参的前面。Python调用构造方法创建实例时,将自动传入实参self。每个与实例相关联的方法调用都自动传递实参self,它是一个指向实例本身的引用,让实例能够访问类中的属性和方法。
class Dog:
def __init__(self, name, age):
self.name = name
self.age = age
def sit(self):
print(f"{self.name} is sitting now")
def roll_up(self):
print(f"{self.name} is rolling up now")
可以通过3种方式修改属性的值 : 1.直接通过实例进行修改 。 2.通过方法来修改属性值。 3.通过方法对属性的值递增。
9.2 继承
一个类继承另一个类时,将自动获得另一个类的所有属性和方法。原有的类称为父类,而新类称为子类。
在既有类基础编写子类时,通常要调用父类的 init 方法。这将初始化在父类init()方法中定义的所有属性,从而让子类包含这些属性。
下面的例子中ElectricCar继承了Car类, 所以自带了Car类的description方法。
class Car:
def __init__(self, brand, model, price):
self.brand = brand
self.model = model
self.price = price
def description(self):
long_name = f"{self.brand} {self.model} price: {self.price}"
print(long_name)
class ElectricCar(Car):
def __init__(self, brand, model, price, capacity):
super().__init__(brand, model, price)
self.capacity = capacity
if __name__ == '__main__':
my_electric = ElectricCar("tesla", "model3", 400000, "900KWH")
my_electric.description()
9.3 导入类
类似于函数,也可以将类放到模块(就是.py程序文件)中来进行引入,这样主体程序结构可以保持简洁。这里规定,一个模块中可以定义多个类。
使用import语句引入类时,规则和引入函数是一样的。 那四种方式也同样适用,这里就不赘述了。
9.4 python标准库
Python标准库是一组模块,我们安装的Python都包含它。
需要同时导入标准库中的模块和你编写的模块时,先编写导入标准库模块的import语句,再添加一个空行,然后编写导入你自己编写的模块的import语句。
类名应采用驼峰命名法,即将类名中的每个单词的首字母都大写,而不使用下划线。实例名和模块名都采用小写格式,并在单词之间加上下划线。
10. 文件处理和异常
10.1 文件读取和写入
10.1.1 open()函数
如果要处理文件,先要打开文件,这时就要使用到函数open()了,open有2个常用参数,open('file_locaiton', 'module') 。
1.要打开的文件名称(还要包括路径) : 这里可以使用绝对路径,也可以使用相对路径。总之能够表述出文件名和其位置就行了,如果是相对路径,那么Python在当前执行的文件所在的目录中查找指定的文件。
2.打开模式 :这里包括四种模式,分别是读取模式('r')、写入模式('w')、附加模式('a')或读写模式('r+')。
函数open()返回一个表示文件的对象。
10.1.2 with关键字
既然使用open()函数将文件打开,在使用完了就得将其关闭。关键字with在不再需要访问文件后将其关闭。使用with有好处,我们就交给python让其在合适的时候为我们关闭文件对象。
open()打开的文件对象只在with语句块内有效。
10.1.3 读取和写入文件:
1.读取文件 :
文件对象包含2个方法,分别是read()和readlines()。 read()读取这个文件的全部内容,并将其作为一个长长的字符串返回。 readlines()从文件中读取每一行,并将其存储在一个列表中。
2.写入文件:
写入文件使用方法 write() 。函数write()不会在写入的文本末尾添加换行符,因此如果写入多行时没有指定换行符。
写入模式('w')会清空原有文件并写入新内容。 而附加模式('a')将写入文件的行添加到文件末尾。
10.2 异常处理 :
异常处理可以帮助我们在发生异常后,保证程序还能继续执行。 包含两种常见的结构:
1.try-except-else结构 :Python尝试执行try代码块中的代码,只有可能引发异常的代码才需要放在try语句中。有时候,有一些仅在try代码块成功执行时才需要运行的代码,这些代码应放在else代码块中。except代码块告诉Python,如果尝试运行try代码块中的代码时引发了指定的异常该怎么办。
2.try-except-finally结构 :区别于try-except-else结构的主要点是,finally结构块不管try块是否执行成功,都会执行finally代码块。
10.3 存储数据:
模块json让你能够将简单的Python数据结构转储到文件中,并在程序再次运行时加载该文件中的数据。你还可以使用json在Python程序之间分享数据。
写入文件:
函数json.dump()接受两个实参:要存储的数据,以及可用于存储数据的文件对象。
读取文件:
json.load()加载存储在文件中的信息,并将其赋给变量。
下面使用一个统一的程序来展示上边三个功能: 读写文件;异常处理;json文件存储读取。
import json
def check_user(input_name):
flag = False
try:
with open("userinfo.json", 'r') as userinfo_obj:
for line in userinfo_obj:
if input_name in line:
flag = True
print(f"{input_name} are in the list!")
break
except FileNotFoundError:
# 清空写文件
with open("userinfo.json", 'w') as userinfo_obj:
userinfo_obj.write("")
print("The file userinfo.json doesn't exist, we have created!")
else:
print(f"{input_name} are not in the list!")
return flag
def add_user(input_name):
flag = False
try:
# 读文件
with open("userinfo.json") as my_file:
for line in my_file:
if input_name in line:
flag = True
except FileNotFoundError:
print("The file userinfo.json doesn't exist")
else:
if not flag:
# 追加写文件
with open("userinfo.json", 'a') as my_write_file:
my_write_file.write(input_name + "\n")
print(f"{input_name} has been written!")
if __name__ == '__main__':
user_name = input("Please input you name!")
check_user(user_name)
add_user("Eric")
add_user("Bob")
add_user("Lucy")
user_list = []
with open("userinfo.json") as citi_file:
for line in citi_file:
user_list.append(line.rstrip())
with open("userinfo_ds.json", 'w') as userinfo_ds_write:
json.dump(user_list, userinfo_ds_write)
with open("userinfo_ds.json") as json_file:
new_user_list = json.load(json_file)
print(new_user_list)