class 2-2 小專案練習
阿新 • • 發佈:2018-11-08
一. 判斷第幾天
閏年(四年一閏,百年不閏,四百年再閏)
元組(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()View Code
密碼嘗試超過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()View Code
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()View Code
第一個程式碼行中的 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('密碼:{},強度:{}\n'.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()View Code
--snip-- def main(): --snip-- if strength_level ==1: level = '弱' elif strength_level ==2: level = '較弱' else: level = '強' f = open('pass_word.txt', 'a') # 注意引號'',如果不寫入路徑,預設儲存在當前檔案路徑下 f.write('密碼:{},強度:{}\n'.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('密碼:{},強度:{}\n'.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()View Code
面向物件的特點
- 封裝
- 將資料及相關操作打包在一起
- 支援程式碼複用
- 繼承
- 子類(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= '密碼:{},強度:{}\n'.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()View Code
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= '密碼:{},強度:{}\n'.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()View Code
zip()函式
- zip()函式用於將對應的元素打包成一個個元組(注意:元組中元素不可修改)
- 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()View Code