在学习java的基础上学习python

变量:

变量的语法:

a=10

其中 a 为变量名. 当我们创建很多个变量的时候, 就可以用名字来进行区分.

= 为赋值运算符, 表示把 = 右侧的数据放到 = 左侧的空间中.

变量的名字要遵守一定规则:

硬性规则(务必遵守) 变量名由数字字母下划线构成(跟java不同,不包含美元符号)

数字不能开头

变量名不能和 "关键字" 重复.

变量名大小写敏感

建议遵守的规则:

使用 "驼峰命名法". 形如 totalCount , personInfo 这种, 除了首个单词外, 剩余单词首字母大写

变量的类型:

注意: 和 C++ / Java 等语言不同, Python 变量的类型不需要显式指定, 而是在赋值的时候确定的

整数:int 

注意: 和 C++ / Java 等语言不同, Python 的 int 类型变量, 表示的数据范围是没有上限的. 只要内存足够 大, 理论上就可以表示无限大小的数据

小数:float

注意: 和 C++ / Java 等语言不同, Python 的小数只有 float 一种类型, 没有 double 类型, 但是实际上 Python 的 float 就相当于 C++ / Java 的 double, 表示双精度浮点数

字符串:str

使用 ' ' 或者 " " 引起来的,称为字符串. 可以用来表示文本

注意: 在 Python 中, 单引号构成的字符串和双引号构成的字符串, 没有区别. 'hello' 和 "hello" 是 完全等价的.与java不同,java中' '是字符  " "是字符串 

注意:str 类型的变量, 只能跟字符串进行+ 操作 其他类型不行 (java中可以,把int类型转为字符串类型进行拼接)

s='hello'
a=10
print(s+10)#出现异常

布尔:bool

布尔类型是一个特殊的类型, 取值只有两种, True (真) 和 False (假)

其他:自定义类型

除了上述类型之外, Python 中还有 list, tuple, dict

type() 打印数据类型:

a=10
print(type(a))

 动态类型特性:

在 Python 中, 一个变量是什么类型, 是可以在 "程序运行" 过程中发生变化的. 这个特性称为 "动态类型" (不像java 要进行类型转换)

a=10
print(type(a))
a='hello'
print(type(a))

输出:

 

注解:

# 进行单行注解

"""  进行多行注解

"""

输入输出:

通过控制台输出 :Python 使用 print 函数输出到控制台

count=1
print(f'输入{count}次')

注意: 使用 f 作为前缀的字符串, 称为 f-string 里面可以使用 { } 来内嵌一个其他的变量/表达式

通过控制台输入:python 使用 input 函数, 从控制台读取用户的输入

a=input('请输入一个数:')
print(f'你输入的数为{a}')

注意: input 的参数相当于一个 "提示信息", 也可以没有,input 的返回值就是用户输入的内容. 是字符串类型,如果要进行想要+=  * /  等算数运算是不行的,可以通过以下进行转类型

a=input('请输入一个数:')
a=int(a)
b=10
print(a+b)

其他的类型转换也可以通过以上方法进行转换  float() bool() str()

算数运算符

像 + - * / % ** // 这种进行算术运算的运算符, 称为算术运算符

注意1: / 中不能用 0 作为除数. 否则会 抛出异常

注意2: 熟悉C/Java 的同学可能认为, 2/3 结果为 0 (小数部分被截断). 但是在 Python 中得到的结果则是 一个小数. 更符合日常使用的直觉

注意3: % 不是 "百分数", 而是求余数

注意4: ** 是求乘方. 不光能算整数次方, 还能算小数次方

print(4**2)
print(4**0.5)

输出:

 

注意5: // 是取整除法(也叫地板除). 整数除以整数, 结果还是整数(舍弃小数部分, 并向下取整. 不是四舍五 入) 

关系运算符

像 < >= == != 这一系列的运算符称为 关系运算符, 它们是在比较操作数之间的关系

如果关系符合, 则表达式返回 True. 如果关系不符合, 则表达式返回 False

关系运算符不光针对整数/浮点数进行比较, 还能针对字符串进行比较

注意: 直接使用 == 或者 != 即可对字符串内容判定相等. (这一点和 C / Java 不同 java是堆地址的比较). 字符串比较大小, 规则是 "字典序"(一个单词在词典上越靠前, 就越小. 越靠后, 就越大.)

注意:对于浮点数来说, 不要使用 == 判定相等

a=0.1
b=0.2
c=0.3
print(a+b==c)
print(a+b)
print(c)

输出:

 

正确的比较方式: 不再严格比较相等了, 而是判定差值小于允许的误差范围.

a=0.1+0.2
b=0.3
print(-0.000001<(a-b)<0.000001) #输出为true  #java不能连续<

逻辑运算符:

像 and or not 这一系列的运算符称为 逻辑运算符(相当于java中的&&  ||   !)

赋值运算符: 

= 表示赋值. 这个我们已经用过很多次了. 注意和 == 区分.

链式赋值

a=b=10

多元赋值

a,b=10,20

 交换两个变量的值

a=10
b=20
a,b=b,a

 复合赋值运算符

Python 还有一些 复合赋值运算符. 例如 += -= *= /= %=

注意: 像 C++ / Java 中, 存在 ++ -- 这样的自增/自减运算符. Python 中则不支持这种运算. 如果需要使用, 则直接使用 += 1 或者 -= 1

其他:除了上述之外, Python 中还有一些运算符, 比如 身份运算符 (is, is not), 成员运算符 (in, not in), 位运算符 ( & | ~ ^ >) 等

条件语句

Python 中使用 if else 关键字表示条件语句

 if

if expression:
 do_something1
 do_something2
next_something

if else

if expression:
 do_something1
else:
 do_something2

 if - elif - else

f expression1:
 do_something1
elif expression2:
 do_something2
else:
 do_something3

注意: Python中的条件语句写法, 和很多编程语言不太一样.

if 后面的条件表达式, 没有 ( ), 使用 : 作为结尾.

if / else 命中条件后要执行的 "语句块", 使用缩进(通常是 4 个空格或者 1 个 tab)来表示, 而不是 { } 对于多条件分支, 不是写作 else if, 而是 elif (合体了).

有两个小练习

#判断一个数是否为偶数
a=int(input('请输入一个数:'))  #这个方法在python中可以,因为-19除以2余数为1 而java 或者c++是-1
if a%2==1:
    print('奇数')
else:
    print('偶数')
#判断是否是闰年
year =int(input('请输入一个年份:'))
if (year%100!=0 and year%4==0) or year%400==0:
    print('闰年')
else:
    print('平年')

空语句 pass

其中 pass 表示 空语句, 并不会对程序的执行有任何影响, 只是占个位置, 保持 Python 语法格式符合要求 (跟java不一样,python 条件/循环语句不能为空)

循环语句

while 循环 

while 条件:
   循环体

练习

#计算 1!+2!+3!+4!+5!
sum=0
num=1
while num<=5:
    i=1
    while i<=num
        i*=i
        i++
    sum+=i
    num+=1
print(sum)

for 循环

for 循环变量 in 可迭代对象:
    循环体

 使用 range 函数, 能够生成一个可迭代对象. 生成的范围是 [1, 11), 也就是 [1, 10]

打印1-10
for i in range(1,11)
    print(i)

 通过 range 的第三个参数, 可以指定迭代时候的 "步长". 也就是一次让循环变量加几.

#打印 2 4 6 8 10
for i in range(2,12,2)
    print(i)

range 的 步长 也可以设定成负数

#打印10-1
for i in range(1,10,-1)
    print(i)

continue 表示结束这次循环, 进入下次循环.

break 表示结束整个循环

函数

def 函数名(形参列表):
    函数体
    return 返回值

注意:和 C++ / Java 不同, Python 是动态类型的编程语言, 函数的形参不必指定参数类型. 换句话说, 一个 函数可以支持多种不同类型的参数. 

一个函数是可以一次返回多个返回值的. 使用 , 来分割多个返回值

def getPoint():
    x = 10
    y = 20
    return x, y
a, b = getPoint()

如果只想关注其中的部分返回值, 可以使用 _ 来忽略不想要的返回值.

def getPoint():
    x = 10
    y = 20
    return x, y
_, b = getPoint()

 变量只能在所在的函数内部生效. 在函数 getPoint() 内部定义的 x, y 只是在函数内部生效. 一旦出了函数的范围, 这两个变量就不再生效了.

在不同的作用域中, 允许存在同名的变量 虽然名字相同, 实际上是不同的变量. 

x = 20
def test():
    x = 10
    print(f'函数内部 x = {x}')
test()
print(f'函数外部 x = {x}') #10 20

在函数内部的变量, 也称为 "局部变量" 不在任何函数内部的变量, 也称为 "全局变量"

如果函数内部尝试访问的变量在局部不存在, 就会尝试去全局作用域中查找

x = 20
def test():
    print(f'x = {x}')
test() #20

如果是想在函数内部, 修改全局变量的值, 需要使用 global 关键字声明

x = 20
def test():
    global x
    x = 10
    print(f'函数内部 x = {x}')
test()
print(f'函数外部 x = {x}')# 10 10

if / while / for 等语句块不会影响到变量作用域 换而言之, 在 if / while / for 中定义的变量, 在语句外面也可以正常使用.

if True:
    x=10
print(x) #10 java for if while 是局部变量

函数之间的调用关系, 在 Python 中会使用一个特定的数据结构来表示, 称为 函数调用栈 . 每次函数调用, 都会在调用栈里新增一个元素, 称为 栈帧.

每个函数的局部变量, 都包含在自己的栈帧中

函数递归

递归是 嵌套调用 中的一种特殊情况, 即一个函数嵌套调用自己.

#计算5!
def factor(n):
    if n == 1:
        return 1
    return n * factor(n - 1)
result = factor(5)
print(result)

注意:

递归代码务必要保证 存在递归结束条件. 比如 if n == 1 就是结束条件. 当 n 为 1 的时候, 递归就结束了.

每次递归的时候, 要保证函数的实参是逐渐逼近结束条件的. 如果上述条件不能满足, 就会无限递归下去

参数的默认值

def add(x, y, debug=False):
    if debug:
        print(f'调试信息: x={x}, y={y}')
    return x + y
print(add(10, 20))
print(add(10, 20, True))

带有默认值的参数需要放到没有默认值的参数的后面

关键字参数

在调用函数的时候, 需要给函数指定实参. 一般默认情况下是按照形参的顺序, 来依次传递实参的. 但是我们也可以通过 关键字参数, 来调整这里的传参顺序, 显式指定当前实参传递给哪个形参.

def test(x, y):
    print(f'x = {x}')
    print(f'y = {y}')
test(x=10, y=20)
test(y=100, x=200)

 列表

列表就相对于java的数组

创建列表

创建列表主要有两种方式. [ ] 表示一个空的列表

如果需要往里面设置初始值, 可以直接写在 [ ] 当中

alist = [ ]
alist = list()
print(type(alist))
alist = [1, 2, 3, 4]
print(alist)

列表中存放的元素允许是不同的类型. (这一点和 C++ Java 差别较大).

alist = [1, 'hello', True]
print(alist)

访问下标 

可以通过下标访问操作符 [ ] 来获取到列表中的任意元素.

我们把 [ ] 中填写的数字, 称为下标或者索引 

a=[1,2,3,4]
print(a[0]) #1

通过下标不光能读取元素内容, 还能修改元素的值.

a=[1,2,3,4]
a[0]=2
print(a) #2234

使用 len 函数可以获取到列表/str的元素个数

a=[1,2,3,4]
print(len(a)) #4

下标可以取负数. 表示 "倒数第几个元素"

a=[1,2,3,4]
print(a[-1]) #4 相当于 print(len(a)-1)

 切片操作:

通过下标操作是一次取出里面第一个元素.

通过切片, 则是一次取出一组连续的元素, 相当于得到一个 子列表 使用 [ : ] 的方式进行切片操作.

a=[1,2,3,4]
prtint(a[0:4]) #1234  #不包含最后一个

可以省略前后边界

a=[1,2,3,4]
print(a[1:]) #234  #省略后边界,从下标为1到结束
print(a[:-1]) #123  #省略前边界,从0下标开始
print(a[:])  #1234 #前后边界都省略,全部列表

 切片操作还可以指定 "步长" , 也就是 "每访问一个元素后, 下标自增几步"

alist = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print(alist[::1]) #1234567890
print(alist[::2]) #13579
print(alist[::3]) #14710
print(alist[::5]) #16

 切片操作指定的步长还可以是负数, 此时是从后往前进行取元素. 表示 "每访问一个元素之后, 下标自 减几步"

alist = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print(alist[::-1])#10,9,8,7,6,5,4,3,2,1
print(alist[::-2])#10,8,6,4,2
print(alist[::-3])#10,7,4,1
print(alist[::-5])#10,5

如果切片中填写的数字越界了, 不会有负面效果. 只会尽可能的把满足条件的元素过去到.

alist = [1, 2, 3, 4]
print(alist[100:200]) #[]

 遍历列表元素

for

a=[1,2,3,4,5]
for i in a:
    print(i)

for 下标

a=[1,2,3,4]
for i in range(0,len(a)):
    print(a[i])

while

a=[1,2,3,4]
i=0 
while i<len(a):
    print(a[i])
    i+=1

新添元素 

使用 append 方法, 向列表末尾插入一个元素(尾插).

a=[1,2,3,4]
a.append(5)
print(a) #12345

使用 insert 方法, 向任意位置插入一个元素

a=[1,2,3,4]
a.insert(1,1)
print(a) #11234

查找元素 

使用 in 操作符, 判定元素是否在列表中存在. 返回值是布尔类型.

a=[1,2,3,4]
print(1 in a) #True
print(1 not in a)#False
print('hello' in a)#False

使用 index 方法, 查找元素在列表中的下标. 返回值是一个整数. 如果元素不存在, 则会抛出异常

a=[1,2,3,4]
print(a.insert(1))#0
print(a.insert(10)) #异常

 删除元素

使用 pop 方法删除最末尾元素

a=[1,2,3,4]
a.pop()
print(a)#123

 pop 也能按照下标来删除元素

a=[1,2,3,4]
a.pop(0)
print(a) #234

使用 remove 方法, 按照值删除元素

a=[1,2,3,4]
a.remove(1)
print(a) #234

连接列表 

使用 + 能够把两个列表拼接在一起.

注意:此处的 + 结果会生成一个新的列表. 而不会影响到旧列表的内容.

a=[1,2,3,4]
b=[5,6,7,8]
print(a+b) #12345678
print(a) #1234

使用 extend 方法, 相当于把一个列表拼接到另一个列表的后面.

注意:a.extend(b) , 是把 b 中的内容拼接到 a 的末尾. 不会修改 b, 但是会修改 a.

a=[1,2,3,4]
b=[5,6,7,8]
a.extend(b)
print(a)#12345678
print(b)#5678

元组 

元组和列表相比, 是非常相似的, 只是列表中放哪些元素可以修改调整, 元组中放的元素是创建元组的时候就设定好的, 不能修改调整.

元组的功能和列表相比, 基本是一致的. 元组使用 ( ) 来表示.

atuple=()
atuple = tuple()

因此, 像读操作,比如访问下标, 切片, 遍历, in, index, + 等, 元组也是一样支持的. 但是, 像写操作, 比如修改元素, 新增元素, 删除元素, extend 等, 元组则不能支持.

另外, 元组在 Python 中很多时候是默认的集合类型. 例如, 当一个函数返回多个值的时候.

def getPoint():
    return 10, 20
result = getPoint()
print(type(result)) #<class 'tuple'>

字典 

创建一个空的字典. 使用 { } 表示字典.

a = { }
b = dict()
print(type(a))
print(type(b))

 初始化

student = { 'id': 1, 'name': 'zhangsan' }
print(student)

最后一个键值对, 后面可以写 , 也可以不写.

student = {
    'id': 1,
    'name': 'zhangsan',
}

查看key

使用 in 可以判定 key 是否在 字典 中存在. 返回布尔值.

student = {
    'id': 1,
    'name': 'zhangsan',
}
print('id' in student) #True
print('score' in student) #False

使用 [ ] 通过类似于取下标的方式, 获取到元素的值. 只不过此处的 "下标" 是 key. (可能是整数, 也 可能是字符串等其他类型). 如果 key 在字典中不存在, 则会抛出异常.

student = {
    'id': 1,
    'name': 'zhangsan',
}
print(student['id']) #1
print(student['name']) #zhangsan
print(student['score']) #异常

新增/修改元素 

使用 [ ] 可以根据 key 来新增/修改 value

如果 key 不存在, 对取下标操作赋值, 即为新增键值对 如果 key 已经存在, 对取下标操作赋值, 即为修改键值对的值.

student = {
    'id': 1,
    'name': 'zhangsan',
}
student['score'] = 90
print(student) #id:1 name:zhangsan score:90

如果 key 已经存在, 对取下标操作赋值, 即为修改键值对的值.

student = {
    'id': 1,
    'name': 'zhangsan',
    'score': 80
}
student['score'] = 90
print(student) #id=1 name=zhangsan score:90

 删除元素

使用 pop 方法根据 key 删除对应的键值对.

student = {
    'id': 1,
    'name': 'zhangsan',
    'score': 80
}
student.pop('score')
print(student) #id=1 name:zhangsan

 遍历字典元素

直接使用 for 循环能够获取到字典中的所有的 key, 进一步的就可以取出每个值了.

student = {
    'id': 1,
    'name': 'zhangsan',
    'score': 80
}
for key in student:
    print(key, student[key]) 

取出所有 key 和 value

使用 keys 方法可以获取到字典中的所有的 key

student = {
    'id': 1,
    'name': 'zhangsan',
    'score': 80
}
print(student.keys()) [id,name,score]

使用 values 方法可以获取到字典中的所有 value

student = {
    'id': 1,
    'name': 'zhangsan',
    'score': 80
}
print(student.values()) #[1,zhangsan,80]

使用 items 方法可以获取到字典中所有的键值对.

student = {
    'id': 1,
    'name': 'zhangsan',
    'score': 80
}
print(student.items()) #[(id:1),(name:zhangsan),(score:80)]

合法的 key 类型

不是所有的类型都可以作为字典的 key.

字典本质上是一个 哈希表, 哈希表的 key 要求是 "可哈希的", 也就是可以计算出一个哈希值.

可以使用 hash 函数计算某个对象的哈希值.

但凡能够计算出哈希值的类型, 都可以作为字典的 key.

print(hash(0))
print(hash(3.14))
print(hash('hello'))
print(hash(True))
print(hash(())) 

注意:列表无法计算哈希值. 字典也无法计算哈希值

文件

打开文件

使用内建函数 open 打开一个文件.

f = open('d:/test.txt', 'r')

第一个参数是一个字符串, 表示要打开的文件路径

第二个参数是一个字符串, 表示打开方式. 其中 r 表示按照读方式打开. w 表示按照写方式打开. a 表示追加写方式打开.

如果打开文件成功, 返回一个文件对象. 后续的读写文件操作都是围绕这个文件对象展开.

如果打开文件失败(比如路径指定的文件不存在), 就会抛出异常. f = open('d:/test.txt', 'r') 比

关闭文件

使用 close 方法关闭已经打开的文件 

f.close()

使用完毕的文件要记得及时关闭,一个程序能同时打开的文件个数, 是存在上限的. 

写文件

文件打开之后, 就可以写文件了.

写文件, 要使用写方式打开, open 第二个参数设为 'w' 使用 write 方法写入文件.

f = open('d:/test.txt', 'w')
f.write('hello')
f.close()

注意:如果是使用 'r' 方式打开文件, 则写入时会抛出异常.

注意:使用 'w' 一旦打开文件成功, 就会清空文件原有的数据. 使用 'a' 实现 "追加写", 此时原有内容不变, 写入的内容会存在于之前文件内容的末尾.

针对已经关闭的文件对象进行写操作, 也会抛出异常.

读文件

读文件内容需要使用 'r' 的方式打开文件 使用 read 方法完成读操作. 参数表示 "读取几个字符"

f = open('d:/test.txt', 'r')
result = f.read(2)
print(result)
f.close()

如果文件是多行文本, 可以使用 for 循环一次读取一行.

f = open('d:/test.txt', 'r')
for line in f:
    print(f'line = {line}')
f.close()

注意: 由于文件里每一行末尾都自带换行符, print 打印一行的时候又会默认加上一个换行符, 因此 打印结果看起来之间存在空行. 使用 print(f'line = {line}', end='') 手动把 print 自带的换行符去掉.

f=open('D:\pyhton文件操作项目/text.txt','r',encoding='utf-8')
for line in f:
    print(f'line={line}',end='')
f.close()

使用 readlines 直接把文件整个内容读取出来, 返回一个列表. 每个元素即为一行. 

f = open('d:/test.txt', 'r')
lines = f.readlines()
print(lines)
f.close()

关于中文的处理 

此时修改打开文件的代码, 给 open 方法加上 encoding 参数, 显式的指定为和文本相同的字符集, 问题 即可解决.

f = open('d:/test.txt', 'r', encoding='utf8')

 使用上下文管理器

打开文件之后, 是容易忘记关闭的. Python 提供了 上下文管理器 , 来帮助程序猿自动关闭文件. 使用 with 语句打开文件. 当 with 内部的代码块执行完毕后, 就会自动调用关闭方法.

with open('d:/test.txt', 'r', encoding='utf8') as f:
    lines = f.readlines()
    print(lines)
比特就业

使用库

标准库: Python 自带的库. 只要安装了 Python 就可以直接使用.

第三方库: 其他人实现的库. 要想使用, 需要额外安装.

标准库

 实例一

#计算日期差
import datetime
date1 = datetime.datetime(2012, 2, 14)
date2 = datetime.datetime(2022, 7, 12)
print(date2 - date1)

算法题 字符串 反转字符串

def reverseWords(s):
    tokens = s.split(' ')
    tokens.reverse()
    return ' '.join(tokens)
print(reverseWords('I am a student.'))

旋转字符串

def rotateString(s, goal):
    return len(s) == len(goal) and goal in s + s

统计是给定字符串前缀的字符串数目

def countPrefixes(words, s):
    res = 0   # 符合要求字符串个数
    for word in words:
        if s.startswith(word):
            res += 1
    return res

 文件查找工具

import os
inputPath = input('请输入待搜索路径: ')
pattern = input('请输入待搜索关键词: ')
for dirpath, dirnames, filenames in os.walk(inputPath):
    for f in filenames:
        if pattern in f:
            print(f'{dirpath}/{f}')

第三方库

当我们确定了该使用哪个第三方库之后, 就可以使用 pip 来安装第三方库了.

实例一  生成二维码

pip install qrcode[pil] 下载第三方库

import qrcode
img = qrcode.make('zxy找到好工作')
img.save('qrcode.png')

实例二  操作 excel

pip install xlrd==1.2.0 下载第三方库

import xlrd
# 1. 打开 xlsx 文件
xlsx = xlrd.open_workbook('d:/test.xlsx')
# 2. 获取 0 号标签页. (当前只有一个标签页)
table = xlsx.sheet_by_index(0)
# 3. 获取总行数
nrows = table.nrows
# 4. 遍历数据
count = 0
total = 0
for i in range(1, nrows):
    # 使用 cell_value(row, col) 获取到指定坐标单元格的值.
    classId = table.cell_value(i, 1)
    if classId == 101:
        total += table.cell_value(i, 2)
        count += 1
print(f'平均分: {total / count}')

实例三  程序猿鼓励师

pynput 用于监听键盘按键. 注意版本不要用最新.

playsound 用于播放音频.

pip install pynput==1.6.8

pip install playsound==1.2.2

from pynput import keyboard
from playsound import playsound
count = 0
def on_release(key):
    print(key)
    global count
    count += 1
    if count % 10 == 0:
        playsound('ding.mp3')
listener = keyboard.Listener(
        on_release=on_release)
listener.start()#使用 listener.start 启动监听器. 
listener.join()#为了防止程序直接退出, 使用 listener.join 让程序等待用户按键.

加入线程,以及 队列

import random

from pynput import keyboard
from playsound import playsound
from threading import Thread


soundList = ['sound/1.mp3', 'sound/2.mp3', 'sound/3.mp3']


# 记录当前用户按了多少次键盘
count = 0


def onRelease(key):
    """
    这个函数, 就是在用户释放键盘按键的时候, 就会被调用到.
    这个函数不是咱们自己主动调用的, 而是把这个函数交给了 Listener , 
    由 Listener 在用户释放按键的时候自动调用.
    像这样的不是咱们自己主动调用, 而是交给别人, 在合适的时机进行调用, 这样的函数, 叫做 "回调函数" (callback function)
    :param key: 用户按下了哪个键
    """
    print(key)
    global count
    count += 1
    if count % 20 == 0:
        # 播放音频!
        # 生成随机数
        i = random.randint(0, len(soundList) - 1)
        # 此处的播放音频, 消耗时间比较多, 可能会引起输入的卡顿(不流畅)
        # 可以创建一个线程, 在线程里播放音频!!
        # playsound(soundList[i])
        t = Thread(target=playsound, args=(soundList[i], ))
        t.start()


# 当我们创建好 Listener 之后, 用户的键盘按键动作就会被捕获到.
# 还希望在捕获到之后能够执行一段代码.
listener = keyboard.Listener(on_release=onRelease)
listener.start()
listener.join()

 实例三   综合项目学生管理系统

#实现学生管理系统
import os.path
import sys

#使用这个全局变量来管理这个学生信息
#这个列表的元素是一个字典
students=[]
def save():
    """
    用来存档
    """
    #此处路径不是以d: 开头的绝对路径而是相对路径’
    #此时这个写法的含义就是让 record.txt和当前的code42.py在同一个目录下
    count=0
    with open('record.txt','w',encoding='utf-8') as f:
        for s in students:
            f.write(f"{s['studentId']}\t{s['name']}\t{s['gender']}\t{s['className']}\n")
        print(f'存档成功,共存档了{len(students)}行信息')

def load():
    """
    用于读档
    :return:
    """
    #如果存档文件不存在,则直接跳过这个读档流程
    #为了避免读方式打开文件时,文件不存在引发异常
    if not os.path.exists('record.txt'):
        return
    #读档的时候要保证先把旧的数据清理干净
    global students
    students=[]
    with open('record.txt','r',encoding='utf-8') as f:
       for line in f:
           #针对这一行,按照\t进行切割
           #切割之前,要去除末尾的换行
           line=line.strip()
           tokens=line.split('\t')
           if len(tokens)!=4:
               print(f'当前行格式有问题 line={line}')
               continue
           studet={
               'studentId':tokens[0],
               'name':tokens[1],
               'gender':tokens[2],
               'className':tokens[3],
           }
           students.append(studet)
    print(f'读档成功,共读了{len(students)}条信息')





def menu():
    print('1.新增学生')
    print('2.显示学生')
    print('3.查看学生')
    print('4.删除学生')
    print('0.退出程序')
    choice=input('请输入你的选择:')
    return choice


def insert():
    print('[新增学生]开始!')
    studentId=input('请输入学生的学号:')
    name=input('请输入学生的姓名:')
    gender=input('请输入学生性别:')
    if gender not in ('男','女'):
        print('性别输入的内容不符合要求,新添失败!')
        return
    className=input('请输入学生的班级:')
    student={
        'studentId':studentId,
        'name':name,
        'gender':gender,
        'className':className,
    }
    global students
    students.append(student)
    save()
    print('[新添学生]完毕!')


def show():
    print('显示学生开始')
    for s in students:
        print(f"[{s['studentId']}]\t{s['name']}\t{s['gender']}\t{s['className']}")
    print(f'显示学生结束,共显示了{len(students)}位学生')
def find():
    #根据学生姓名来进行查找
    print('查找学生开始')
    count=0
    name=input('请输入学生姓名:')
    for s in students:
        if name ==s['name']:
            count+=1
            print(f"[{s['studentId']}]\t{s['name']}\t{s['gender']}\t{s['className']}")
    print(f'查找学生结束,查找了{count}位学生')
def delete():
    print('删除学生开始')
    studentId=input('请输入学生id:')
    for s in students:
        if studentId==s['studentId']:
            print(f"删除{s['name']}学生信息")
            students.remove(s)
    save()
    print('删除学生结束')
def main():
    """
    入口函数
    :return:
    """
    #通过控制台和用户进行交互
    print('------------------------------------------')
    print('         欢迎来到学生管理系统                 ')
    print('------------------------------------------')
    #程序启动时加载load
    load()
    while True:
        #通过 menu函数来打印菜单
        choice=menu()
        if choice=='1':
            insert()
        elif choice=='2':
            show()
        elif choice=='3':
            find()
        elif choice=='4':
            delete()
        elif choice=='0':
            print('goodbye')
            sys.exit(0)
        else:
            print('你的输入有误,请重新输入')
            continue
main()


 

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值