一. 判断第几天
闰年(四年一闰,百年不闰,四百年再闰)
元组(tuple)
用于表达固定数据项、函数多返回值等
特点: 1.元素可以是不同类型(元组通常不同数据组成,列表通常由相同类型数据组成)
2.元组中各元素存在先后关系,可通过索引访问元组中元素(元组表示的是结构,列表表示的是顺序)
集合(set):
- python中的集合(set)类型同数学中集合概念一致,即包含0或多个数据项的无序组合
- 集合中的元素不可重复
- 集合时无序组合,没有索引和位置的概念
- set()函数用于集合的生成,返回结果是一个无重复且排序任意的集合
- 集合通常用于表示成员间的关系、元素去重
集合的操作:
- s-t 或 s.difference(t) :返回在集合s中但不在t中的元素
- s&t 或 s.intersection(t) :返回同时在集合s和t中的元素
- s|t 或 s.union(t) : 返回在集合s和t中的所有元素
- s^t 或 s.symmetric_difference(t):返回集合s和t中的元素,但不包含同时在其中的元素
from datetime import datetime def is_leap_year(year): is_leap = False if (year % 400 == 0) or (year % 4 == 0) and (year % 100 != 0): is_leap = True return is_leap #默认fail,如果满足条件就变为True def main(): input_day_str = input('请输入时间(yyyy/mm/dd): ') input_date = datetime.strptime(input_day_str,'%Y/%m/%d') year = input_date.year month = input_date.month day = input_date.day _30_day_in_month_list = {4,6,9,11} _31_day_in_month_list = {1,3,5,7,8,10,12} days =day #初始化days for i in range(1,month): if i in _30_day_in_month_list: days += 30 elif i in _31_day_in_month_list: days += 31 else: days+=28 if month > 2 and is_leap_year(year): #函数判断是否执行 days += 1
#days_in_month_list = [31,28,31,30,31,30,31,31,30,31,30,31]
#if is_leap_year(year):
#days_in_month_list[1] = 29
#days = sum(days_in_month_list[:month - 1]) + day
print('这是第{}年的第{}天。'.format(year,days)) if __name__ == '__main__': main()
字典(dict):
- 字典类型(dict)是“键--值”(通常键是唯一的)数据项的组合,每个元素都是一个键值对
- 例:身份证号(键) --个人信息 (值)
- 字典类型数据通过映射查找数据项
- 映射:通过任意键查找集合中的值得过程
- 字典类型以键为索引,一个键对应一个值
- 字典类型的数据是无序的
字典操作:
- 增加某一项 :d[key] = value
- 访问: d[key]
- 删除某项: del d[key]
- key是否在字典中: key in d
字典遍历:
- 遍历所有的key:
for key in d.keys(): print(key)
- b遍历所有的value:
for value in d.values(): print(value)
- 遍历所有的数据项:
for item in d.items(): print(items)
--snip--
def main(): input_day_str = input('请输入时间(yyyy/mm/dd): ') input_date = datetime.strptime(input_day_str,'%Y/%m/%d') year = input_date.year month = input_date.month day = input_date.day month_dict = {31:{1,3,5,7,8,10,12},30:{4,6,9,11}} days =day #初始化days for i in range(1,month): if i in month_dict[31]: days += 31 elif i in month_dict[30]: days += 30 else: days+=28 if month > 2 and is_leap_year(year): #函数判断是否执行 days += 1 print('这是第{}年的第{}天。'.format(year,days)) if __name__ == '__main__': main()
二.判断密码强弱
设置一个8位包含数字,大小写字母的密码(设置一个变量strength_level用于记录密码强度,初始为0。满足一个条件+1)
python判断字符串
- str.isnumeric() :检测字符串是否只由数字组成
- str.isalpha() :检测字符串是否只由字母组成
- str.islower() :检测字符串中所有字母是否都为小写
- str.isupper() :检测字符串中所有字母都为大写
- 更多isxxx()方法参考:https://doc.python.org/3/library/stdtypes.html#string-methods
1 def str_number(pass_word): 2 for i in pass_word: 3 if i.isnumeric(): #字符串的使用 4 return True #return跳出函数循环, 5 return False 6 def str_letter(pass_word): 7 for i in pass_word: 8 if i.isalpha(): 9 return True 10 return False 11 12 def main(): 13 pass_word = input("please key in your pass word:") 14 strength_level = 0 15 if len(pass_word) >= 8: 16 strength_level += 1 17 else: 18 print("密码长度至少为8位") 19 if str_letter(pass_word): 20 strength_level+= 1 21 else: 22 print("请输入包含字母的密码") 23 if str_number(pass_word): 24 strength_level +=1 25 else: 26 print("请输入包含数字的密码") 27 28 if strength_level ==3: 29 print("恭喜,密码设置成功!") 30 else: 31 print("密码设置失败") 32 33 if __name__ =="__main__": 34 main()
密码尝试超过5次
循环的终止
- break 语句: 终止整个循环
- continue语句:终止本次循环,而不终止整个循环的执行
- 重点:减少一个函数中return使用次数
-
def str_number(pass_word_str): has_number = False for i in pass_word_str: if i.isnumeric(): #字符串的使用 has_number = True #return跳出函数循环, break return has_number
def str_number(pass_word): for i in pass_word: if i.isnumeric(): #字符串的使用 return True #return跳出函数循环, return False def str_letter(pass_word): for i in pass_word: if i.isalpha(): return True return False def main(): pass_word = input("please key in your pass word:") strength_level = 0 i = 0 while i <= 4: i +=1 if len(pass_word) >= 8: strength_level += 1 else: print("密码长度至少为8位") if str_letter(pass_word): strength_level+= 1 else: print("请输入包含字母的密码") if str_number(pass_word): strength_level +=1 else: print("请输入包含数字的密码") if strength_level ==3: print("恭喜,密码设置成功!") break elif i<= 4: pass_word =input("密码设置失败,请再试一次:") else: print("您输入的密码尝试超过5次。。。") if __name__ =="__main__": main()
1 def str_number(pass_word_str): 2 has_number = False 3 for i in pass_word_str: 4 if i.isnumeric(): #字符串的使用 5 has_number = True #return跳出函数循环, 6 break 7 return has_number 8 9 def str_letter(pass_word_str): 10 has_number1 = 0 11 for x in pass_word_str: 12 if x.isalpha(): 13 has_number1 = True 14 break 15 return has_number1 16 17 def main(): 18 pass_word = input("please key in your pass word:") 19 20 times = 5 21 while times > 0: 22 strength_level = 0 #该位置对其进行重新初始化 23 if len(pass_word) >= 8: 24 strength_level += 1 25 else: 26 print("密码长度至少为8位") 27 if str_letter(pass_word): 28 strength_level+= 1 29 else: 30 print("请输入包含字母的密码") 31 if str_number(pass_word): 32 strength_level +=1 33 else: 34 print("请输入包含数字的密码") 35 36 if strength_level == 3: 37 print("恭喜,密码设置成功!") 38 break 39 else: 40 pass_word =input("密码设置失败,请再试一次:") 41 times -= 1 42 43 if times <= 0: 44 print("您输入的密码尝试超过5次。。。") 45 46 if __name__ =="__main__": 47 main()
第一个代码行中的 strength_level = 0 位置错误,在循环外对其初始化无效
文件的操作
- 1. 打开文件:建立文件与程序的关联
- open(filename,mode) ( filename:文件名(包括路径) ; mode: 打开模式)
- r: 只读,文件不存在则报错
- w:只写,文件不存在则自动创建(只写w,每次重新覆盖上次的存入)
- a :在文件末尾附件
- r+:读写
- open(filename,mode) ( filename:文件名(包括路径) ; mode: 打开模式)
- 2. 操作文件:写入,读取等
- write():将文本数据写入文件中
- writelines():将字符串列表写入文件中
- 3. 关闭文件:终止程序与文件的关联
- close()
1 def str_number(pass_word_str): 2 has_number = False 3 for i in pass_word_str: 4 if i.isnumeric(): #字符串的使用 5 has_number = True #return跳出函数循环, 6 break 7 return has_number 8 9 def str_letter(pass_word_str): 10 has_number1 = 0 11 for x in pass_word_str: 12 if x.isalpha(): 13 has_number1 = True 14 break 15 return has_number1 16 17 def main(): 18 pass_word = input("please key in your pass word:") 19 20 times = 5 21 while times > 0: 22 strength_level = 0 #该位置对其进行重新初始化 23 if len(pass_word) >= 8: 24 strength_level += 1 25 else: 26 print("密码长度至少为8位") 27 if str_letter(pass_word): 28 strength_level+= 1 29 else: 30 print("请输入包含字母的密码") 31 if str_number(pass_word): 32 strength_level +=1 33 else: 34 print("请输入包含数字的密码") 35 if strength_level ==1: 36 level = '弱' 37 elif strength_level ==2: 38 level = '较弱' 39 else: 40 level = '强' 41 f = open('pass_word.txt', 'a') # 注意引号'',如果不写入路径,默认存储在当前文件路径下 42 f.write('密码:{},强度:{} '.format(pass_word,level)) 43 f.close() 44 45 if strength_level == 3: 46 print("恭喜,密码设置成功!") 47 break 48 else: 49 pass_word =input("密码设置失败,请再试一次:") 50 times -= 1 51 52 if times <= 0: 53 print("您输入的密码尝试超过5次。。。") 54 55 if __name__ =="__main__": 56 main()
--snip-- def main(): --snip-- if strength_level ==1: level = '弱' elif strength_level ==2: level = '较弱' else: level = '强' f = open('pass_word.txt', 'a') # 注意引号'',如果不写入路径,默认存储在当前文件路径下 f.write('密码:{},强度:{} '.format(pass_word,level)) f.close() if strength_level == 3: print("恭喜,密码设置成功!") break else: pass_word =input("密码设置失败,请再试一次:") times -= 1 if times <= 0: print("您输入的密码尝试超过5次。。。") if __name__ =="__main__": main()
- 读取文件操作
- read():返回值为包含整个文件内容的一个字符串
- readline():返回值为文件下一行内容的字符串
- readlines():返回值为整个文件内容的列表,每项是以换行符为结尾的一行字符串
- 文件遍历:
- f = open('tmp.txt', 'r')
- for line in f #或者for line in f.readlines
- 处理一行数据
- f.close()
- f = open('tmp.txt', 'r')
def main(): f = open('pass_word.txt','r') """方法1:read()方法,输出整个文件内容""" # content = f.read() # print(content) """方法2:readline(),每次只能读取一行""" # line = f.readline() # print(line) """方法3:readlines(),输出的方式为列表[]""" lines = f.readlines() for line in lines: #或者for line in f: #处理一行数据 print('read:{}'.format(line)) f.close() if __name__ =="__main__": main()
面向过程VS面向对象
- 面向过程(POP):以程序执行过程为设计流程的编程思想
- 面向对象(OOP):以事物为中心的编程思想
- 面向对象 即现实世界中的对象:属性,行为
- 类(class):某种类型集合的描述
- 属性:类本身的一些特征
- 方法:类所能实现的行为
类的定义
- class ClassName
- __init__(self) 构造函数:初始化对象的各属性
- self代表类的实例
1 class PasswordTool: 2 def __init__(self, password): #self代表类本身, 3 #类的属性 4 self.password =password #代表外部程序调用内部程序时,需要传进来一个值给类当成附属属性 5 self.strength_level = 0 6 def process_password(self): 7 #if len(pass_word) >= 8: #其中password的为类中的password应修改如下 8 if len(self.password)>= 8: 9 #strength_level += 1 #strength_level也是其中的类的属性自身+1,应修改以下 10 self.strength_level +=1 11 else: 12 print("密码长度至少为8位") 13 #if str_letter(self.password): #此处也应调用自身的类 14 #if self.str_letter(self.password): #此处不需要传参数 15 if self.str_letter(): 16 self.strength_level += 1 17 else: 18 print("请输入包含字母的密码") 19 if self.str_number(): 20 self.strength_level +=1 21 else: 22 print("请输入包含数字的密码") 23 #类的方法,是动态的 24 #def str_number(self, pass_word_str): #在定义类的属性时,都需要加一个self,当成默认的第一个参数,在类中都可以自己调用。 25 def str_number(self): 26 has_number = False 27 #for i in pass_word_str: 此处位置也应该修改为以下 28 for i in self.password: 29 if i.isnumeric(): #字符串的使用 30 has_number = True #return跳出函数循环, 31 break 32 return has_number 33 def str_letter(self): 34 has_number1 = 0 35 for x in self.password: 36 if x.isalpha(): 37 has_number1 = True 38 break 39 return has_number1 40 41 def main(): 42 43 times = 5 44 while times > 0: 45 pass_word = input("please key in your pass word:") 46 #实例化密码工具对象 47 password_tool = PasswordTool(pass_word) #此处需要传入参数,初始化 48 password_tool.process_password() 49 50 f = open('pass_word', 'a') 51 f.write('密码:{},强度:{} '.format(pass_word, password_tool.strength_level)) 52 f.close() 53 54 if password_tool.strength_level == 3: 55 print("恭喜,密码设置成功!") 56 break 57 else: 58 pass_word = print("密码设置失败,请再试一次") 59 times -= 1 60 61 if times <= 0: 62 print("您输入的密码尝试超过5次。。。") 63 64 if __name__ == "__main__": 65 main()
面向对象的特点
- 封装
- 将数据及相关操作打包在一起
- 支持代码复用
- 继承
- 子类(subclass)借用父类(supperclass)的行为
- 避免重复操作,机身代码复用率
- 定义 class ClassName(SupperClassName)
- 多态
- 在不同情况下用一个函数名启用不同方法
- 灵活性
1 class PasswordTool: 2 def __init__(self, password): #self代表类本身, 3 #类的属性 4 self.password =password #代表外部程序调用内部程序时,需要传进来一个值给类当成附属属性 5 self.strength_level = 0 6 def process_password(self): 7 #if len(pass_word) >= 8: #其中password的为类中的password应修改如下 8 if len(self.password)>= 8: 9 #strength_level += 1 #strength_level也是其中的类的属性自身+1,应修改以下 10 self.strength_level +=1 11 else: 12 print("密码长度至少为8位") 13 #if str_letter(self.password): #此处也应调用自身的类 14 #if self.str_letter(self.password): #此处不需要传参数 15 if self.str_letter(): 16 self.strength_level += 1 17 else: 18 print("请输入包含字母的密码") 19 if self.str_number(): 20 self.strength_level +=1 21 else: 22 print("请输入包含数字的密码") 23 #类的方法,是动态的 24 #def str_number(self, pass_word_str): #在定义类的属性时,都需要加一个self,当成默认的第一个参数,在类中都可以自己调用。 25 def str_number(self): 26 has_number = False 27 #for i in pass_word_str: 此处位置也应该修改为以下 28 for i in self.password: 29 if i.isnumeric(): #字符串的使用 30 has_number = True #return跳出函数循环, 31 break 32 return has_number 33 def str_letter(self): 34 has_number1 = False 35 for x in self.password: 36 if x.isalpha(): 37 has_number1 = True 38 break 39 return has_number1 40 41 class FileTool: 42 def __init__(self, filepath): #定义属性 43 self.filepath = filepath 44 def write_to_file(self,line): #此处需要传入形参line 45 f= open(self.filepath, 'a') 46 f.write(line) 47 f.close() 48 def readfile(self): 49 f = open(self.filepath, 'r') 50 #f.readlines(lines) # 需要一个形参传回,写write则不需要 51 lines = f.readlines() 52 f.close() 53 return lines 54 55 def main(): 56 57 times = 5 58 filepath = 'passworld_flie' 59 file_tool = FileTool(filepath) 60 while times > 0: 61 pass_word = input("please key in your pass word:") 62 #实例化密码工具对象 63 password_tool = PasswordTool(pass_word) #此处需要传入参数,初始化 64 password_tool.process_password() 65 66 line= '密码:{},强度:{} '.format(pass_word, password_tool.strength_level) 67 #写操作 68 file_tool.write_to_file(line) #此处需要调用参数 69 70 if password_tool.strength_level == 3: 71 print("恭喜,密码设置成功!") 72 break 73 else: 74 pass_word = print("密码设置失败,请再试一次") 75 times -= 1 76 if times <= 0: 77 print("您输入的密码尝试超过5次。。。") 78 79 # 读操作 80 lines = file_tool.readfile() # 此处需要调用函数,不需要参数;又因为return lines,故用lines接收 81 print(lines) 82 83 if __name__ == "__main__": 84 main()
class PasswordTool: --snip-- class FileTool: def __init__(self, filepath): #定义属性 self.filepath = filepath def write_to_file(self,line): #此处需要传入形参line f= open(self.filepath, 'a') f.write(line) f.close() def readfile(self): #不需要传入实参 f = open(self.filepath, 'r') #f.readlines(lines) # 需要一个形参传回,写write则不需要 lines = f.readlines() f.close() return lines def main(): times = 5 filepath = 'passworld_flie' file_tool = FileTool(filepath) while times > 0: pass_word = input("please key in your pass word:") #实例化密码工具对象 password_tool = PasswordTool(pass_word) #此处需要传入参数,初始化 password_tool.process_password() line= '密码:{},强度:{} '.format(pass_word, password_tool.strength_level) file_tool.write_to_file(line) #此处需要调用参数 if password_tool.strength_level == 3: print("恭喜,密码设置成功!") break else: pass_word = print("密码设置失败,请再试一次") times -= 1 if times <= 0: print("您输入的密码尝试超过5次。。。") lines = file_tool.readfile() # 此处需要调用函数,不需要参数;又因为return lines,故用lines接收 print(lines) if __name__ == "__main__": main()
三.模拟掷骰子
通过计算机程序模拟掷骰子,并显示个点数的出现次数及频率(例:投掷2个骰子50次,出现点数和为7的次数是8,频率是0.16)
Random模块——用于生成随机数
- random() :生成一个[0,1.0)之间的随机浮点数
- uniform(a,b):生成一个a到b之间的随机浮点数
- randint(a,b):生成一个a到b之间的随机整数
- choice(<list>):从列表中随机返回一个元素
- shuffle(<list>):将列表中元素随机打乱
- sample(<list>,k):从指定列表中随机获取k个元素
- 更多模块参考:https://docs.python.org/3/library/random.html
enumerate()函数
- enumerate()函数用于可遍历的组合转换为一个索引序列,获取元素索引号及元素值
- 一般用于for循环中,同时列出元素和元素的索引号
模拟抛一个筛子
1 """模拟抛一个筛子""" 2 import random 3 4 def roll_dice(): 5 roll= random.randint(1,6) 6 return roll 7 8 def main(): 9 total_times = 1000000 10 #初始化列表[0,0,0,0,0,0] 11 reslut_list = [0]*6 #等同于初始化[0,0,0,0,0,0] 12 for i in range(total_times): 13 roll = roll_dice() 14 for j in range(1,7): #筛子的点数 15 if roll == j: 16 reslut_list[j-1] +=1 #在j-1 的位置上+1 17 print(reslut_list) 18 for i,result in enumerate(reslut_list): #enumerate()返回2个值, i为索引号,result为结果 19 print('点数{}的次数:{},频率:{}'.format(i+1,result,result/total_times)) 20 if __name__ =='__main__': 21 main()
zip()函数
- zip()函数用于将对应的元素打包成一个个元组(注意:元组中元素不可修改, 单项输出在python3中需要加list)
- dict(zip(|1, |2))为修改或转换成字典(遍历字典方式:items)
1 """抛2个筛子,对应点数和次数关联起来""" 2 import random 3 4 def roll_dice(): 5 roll= random.randint(1,6) 6 return roll 7 8 def main(): 9 total_times = 10 10 #初始化列表有11个值 11 reslut_list = [0]*11 #等同于初始化[0,0,0,0,0,0] 12 #初始化点数列表 13 roll_list = list(range(2,13)) 14 roll_dict = dict(zip(roll_list, reslut_list)) #zip函数中为键—值对,zip(key,value) 15 for i in range(total_times): 16 roll1 = roll_dice() 17 roll2 = roll_dice() 18 for j in range(2,13): #筛子的点数 19 if (roll1+ roll2) == j: 20 roll_dict[j] +=1 #在j 的位置上+1 21 print(reslut_list) 22 for i,result in roll_dict.items(): #遍历字典.items 23 print('点数{}的次数:{},频率:{}'.format(i,result,result/total_times)) 24 if __name__ =='__main__': 25 main()
matplotlib模块
- matplotlib的子模块pyplot提供2D图表制作的基本函数。 参照:https://matplotlib.org/gallery.html 因matplotlib默认英文输出,如果中文和负号输出显示问题可设置
-
- plt.rcParams['font.sans-serif'] = ['SimHei']
- plt.rcParams['axes.unicode_minus'] = False
- 散点图绘制
- import matplotlib.pyplot as plt
- # x,y分别是x坐标和y坐标的列表
- plt.scatter(x,y)
- plt.show()
- 直方图绘制
- plt.hist(data, bins)
- data : 数据列表
- bins(柱状) :分组边界
- plt.xticks()设置x坐标的坐标点位置及标签
- plt.title()设置绘图标题
- plt.xlabel(),plt.ylabel()设置坐标轴的标签
- normed/density:为指定其频率(归一化);
- edgecolor:指定边界线颜色;linewidth指定边界线宽度
- rwidth:指定柱(桶)宽度
- plt.hist(data, bins)
1 """可视化抛2个筛子""" 2 import random 3 import matplotlib.pyplot as plt 4 5 def roll_dice(): 6 roll= random.randint(1,6) 7 return roll 8 9 def main(): 10 total_times = 1000 11 #初始化列表有11个值 12 reslut_list = [0]*11 #等同于初始化[0,0,0,0,0,0] 13 #初始化点数列表 14 roll_list = list(range(2,13)) 15 roll_dict = dict(zip(roll_list, reslut_list)) #zip函数中为键—值对,zip(key,value) 16 roll1_list = [] 17 roll2_list = [] 18 for i in range(total_times): 19 roll1 = roll_dice() 20 roll2 = roll_dice() 21 22 roll1_list.append(roll1+roll2) 23 #roll2_list.append(roll2) 24 #roll_list_total = roll1_list +roll2_list #列表不可相加 25 for j in range(2,13): #筛子的点数 26 if (roll1+ roll2) == j: 27 roll_dict[j] +=1 #在j 的位置上+1 28 print(reslut_list) 29 for i,result in roll_dict.items(): #遍历字典.items 30 print('点数{}的次数:{},频率:{}'.format(i,result,result/total_times)) 31 #数据可视化 32 y = range(1, total_times+1) 33 plt.scatter(roll1_list, y, c = 'green', alpha= 0.7) 34 plt.show() 35 36 if __name__ =='__main__': 37 main()
NumPy
- NumPy(Numeric python):用python实现科学计算库
- 包括
- 强大的N维数组对象array
- 成熟的科学函数库
- 实用的线性代数、随机数生成函数等
- NumPy的操作对象是多维数组ndarray
- ndarray.shape数组的维度 (import NumPy as NP)
- 创建数组:np.array(<list>),np.arange().....
- 改变数组形reshape()
- NumPy创建随机数组
- np.random.randint(a,b,size) ---(创建[a,b)间形状为size的数组)
import numpy as np arr = np.random.randint(1,10,(3,4)) print(arr)
- NumPy基本运算
- 以数组为对象进行基本运算,即向量化操作
- np.histogram()输出直方图的统计结果
import matplotlib.pyplot as plt import numpy as np #解决中文显示问题,matplotlib默认英文设置 plt.rcParams['font.sans-serif'] = ['SimHei'] plt.rcParams['axes.unicode_minus'] = False def main(): total_times = 1000 roll1 = np.random.randint(1,7,size= total_times) roll2 = np.random.randint(1,7,size = total_times) total_num = roll2+ roll1 #列表不可相加,矩阵相加 #设置x轴坐标中文点显示 tick_labels = ['2点', '3点','4点', '5点','6点', '7点','8点', '9点','10点', '11点', '12点'] tick_pos = np.arange(2,13) +0.5 #设置偏移中间位置 plt.xticks(tick_pos, tick_labels) #位置position对应label值 #hist直方图hist(data, bins);normed/density:为指定其频率(归一化);edgecolor:指定边界线颜色;linewidth指定边界线宽度, plt.hist(total_num, bins=range(2,14), density =1, edgecolor= 'black',linewidth= 1, rwidth= 0.8) plt.title('掷骰子数统计') plt.xlabel('点数') plt.ylabel('频率') plt.show() if __name__ =='__main__': main()