為了練習python,將python練習冊學習了一遍,記錄下自己的答案,習題地址:https://github.com/Yixiaohan/show-me-the-code
第 0000 題: 將你的 QQ 頭像(或者微博頭像)右上角加上紅色的數字,類似於微信未讀信息數量那種提示效果。
(使用到PIL(pip install pillow)圖像處理模塊)

#coding:utf-8 #PIL模塊圖像處理文檔 https://pillow.readthedocs.io/en/stable/reference/index.html from PIL import Image, ImageDraw, ImageFont import base64 #下載微信頭像 # t='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' # s = base64.b64decode(t); # with open('avatar.jpg','wb') as f: # f.write(s); #測試字體格式 # font2 = ImageFont.truetype('C:\\Windows\\Fonts\\simhei.ttf',20) # draw.text((0,0), u'ps軟件啊', font=font2, fill=(235,177,58)) # im.save('avatar2.jpg','JPEG') def addNumber(image,number): im = Image.open(image) draw = ImageDraw.Draw(im) font = ImageFont.truetype('C:\\Windows\\Fonts\\simhei.ttf',45) #設置字體格式及大小 (C:\\Windows\\Fonts下存放windows相關的字體文件,這里采用黑體常規) draw.text((im.size[0]-35,0),str(number),font=font,fill=(255,0,0)) #在圖上繪制數字5, (x,y)為繪制點坐標,font為字體,fill為顏色 im.save('avatar1.jpg','JPEG') #保存文件,第二個參數為文件格式 if __name__=='__main__': addNumber('avatar.jpg',5)
第 0001 題: 做為 Apple Store App 獨立開發者,你要搞限時促銷,為你的應用生成激活碼(或者優惠券),使用 Python 如何生成 200 個激活碼(或者優惠券)?

#coding:utf-8 #Python 生成 200 個激活碼(或者優惠券) import random import string chars = string.ascii_letters + string.digits #26個字母的大小寫和數字組合 def generateCode(count,length): for x in range(count): code='' for y in range(length): code = code+random.choice(chars) yield code if __name__=="__main__": codes = generateCode(200,20) #print codes for code in codes: print code
第 0002 題: 將 0001 題生成的 200 個激活碼(或者優惠券)保存到 MySQL 關系型數據庫中。

#coding:utf-8 # 將200 個激活碼(或者優惠券)保存到 MySQL 關系型數據庫中 import random import string import MySQLdb chars = string.ascii_letters + string.digits #26個字母的大小寫和數字組合 def generateCode(count,length): for x in range(count): code='' for y in range(length): code = code+random.choice(chars) yield code if __name__=="__main__": conn = MySQLdb.connect(host='127.0.0.1',user='root',passwd='', db='mydb',charset='utf8',port=3306) cursor = conn.cursor() cursor.execute(""" CREATE TABLE IF NOT EXISTS code_table( id INT PRIMARY KEY AUTO_INCREMENT NOT NULL, code VARCHAR(64) NOT NULL); """) codes = generateCode(200,20) #print codes for code in codes: cursor.execute("""INSERT INTO code_table(code) VALUES('%s');"""%code) conn.commit() conn.close()
第 0003 題: 將 0001 題生成的 200 個激活碼(或者優惠券)保存到 Redis 非關系型數據庫中。

#coding:utf-8 #將200 個激活碼(或者優惠券)保存到 Redis 非關系型數據庫中 import random import string import redis chars = string.ascii_letters + string.digits #26個字母的大小寫和數字組合 def generateCode(count,length): for x in range(count): code='' for y in range(length): code = code+random.choice(chars) yield code if __name__=="__main__": pool = redis.ConnectionPool(host='127.0.0.1',port=6379) r = redis.Redis(connection_pool=pool) pipe = r.pipeline(transaction=False) codes = generateCode(200,20) for code in codes: pipe.lpush('code_list',code) pipe.execute()
第 0004 題: 任一個英文的純文本文件,統計其中的單詞出現的個數。

#coding:utf-8 # 任一個英文的純文本文件,統計其中的單詞出現的個數 from collections import Counter import string punctuations = string.punctuation + string.whitespace #標點符號和空格(換行,制表符等) def countWords(file): with open(file,'r') as f: lines = f.readlines() words_list=[] for line in lines: words = line.split() words = [word.strip(punctuations).lower() for word in words] #去除掉單詞開頭或結尾的標點符號及空格,換行等 words_list.extend(words) counter_dict = Counter(words_list) #返回一個字典,鍵為單詞,值為出現次數 return counter_dict if __name__ =='__main__': counter_dict = countWords('The zen of python.txt') for key,value in counter_dict.items(): print "%s : %s"%(key,value)

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!
第 0005 題: 你有一個目錄,裝了很多照片,把它們的尺寸變成都不大於 iPhone5 分辨率的大小。

#coding:utf-8 #你有一個目錄,裝了很多照片,把它們的尺寸變成都不大於 iPhone5 分辨率的大小。 import os from PIL import Image def thumbnailImage(path): files = os.listdir(path) images = [os.path.join(path,file) for file in files if file.endswith('.jpg') ] # 找到jpg文件,並構造其路徑 print images for image in images: name,ext = os.path.splitext(image) #得到文件名 image = Image.open(image) image.thumbnail((1136,640)) # iphone分辨率為1136*640,按給定的像素值進行縮放, image.save(name+'.thumbnail.jpg','JPEG') if __name__=="__main__": path = "D:\\Python\\myprogram\\0005\\images" #用反斜線轉義路徑 thumbnailImage(path)
第 0006 題: 你有一個目錄,放了你一個月的日記,都是 txt,為了避免分詞的問題,假設內容都是英文,請統計出你認為每篇日記最重要的詞。

#coding:utf-8 #你有一個目錄,放了你一個月的日記,都是 txt,為了避免分詞的問題,假設內容都是英文,請統計出你認為每篇日記最重要的詞。 from collections import Counter import os import string punctuations = string.punctuation + string.whitespace #標點符號和空格(換行,制表符等) ignored_words=['the','what','how','where','why','him','she','her','they','them','and'] #這里根據單詞出現頻率來判斷重要性 def judgeWord(counter_dict): sort_list = sorted(counter_dict.items(),key=lambda x:x[1],reverse=True) #按單詞出現次數從大到小進行排序 for i in range(10): #從出現次數最多的10個單詞中選擇,不然返回第十一個 word= sort_list[i][0] if len(word)>2 and word not in ignored_words: #只包含兩個或一個字符的單詞忽略 return sort_list[i] return sort_list[10] def countWords(file): with open(file,'r') as f: words =f.read().split() words_list = [word.strip(punctuations).lower() for word in words] #去除掉單詞開頭或結尾的標點符號及空格,換行等 counter_dict = Counter(words_list) word = judgeWord(counter_dict) return word if __name__=="__main__": path="D:\\Python\\myprogram\\0006\\diaries" files = os.listdir(path) txt_files = [os.path.join(path,file) for file in files if file.endswith('.txt')] #print txt_files for txt_file in txt_files: word = countWords(txt_file) print "%s %s"%(os.path.basename(txt_file),word)
第 0007 題: 有個目錄,里面是你自己寫過的程序,統計一下你寫過多少行代碼。包括空行和注釋,但是要分別列出來。

#coding:utf-8 #有個目錄,里面是你自己寫過的程序,統計一下你寫過多少行代碼。包括空行和注釋,但是要分別列出來。 import os def countCodes(file): code=0 comment=0 blank_line=0 with open(file,'r') as f: lines = f.readlines() i=0 print len(lines) while i< len(lines): line = lines[i].strip() if len(line)==0: #判斷是否為空行 blank_line += 1 elif line.startswith('#'): #判斷是否為#開頭的單行注釋 comment += 1 elif line.startswith('"""'): #判斷是否為"""開頭的多行注釋 flag=True if line.count('"""')==2: #判斷是否出現這種注釋: """注釋內容""" flag=False else: i = i+1 comment +=1 while flag and i<len(lines): comment += 1 newline = lines[i].strip() if newline.endswith('"""'): flag=False else: i = i+1 elif line.startswith("'''"): #判斷是否為'''開頭的多行注釋 flag=True if line.count("'''")==2: flag=False else: i = i+1 comment +=1 while flag and i<len(lines): comment += 1 newline = lines[i].strip() if newline.endswith("'''"): flag=False else: i = i+1 else: code += 1 i = i+1 return [code,comment,blank_line] if __name__=="__main__": path="D:\\PyCharm\\tianmaoCrawl" files = os.listdir(path) py_files = [os.path.join(path,file) for file in files if file.endswith('.py')] counts = {'code':0,'comment':0,'blank_line':0} for file in py_files: results = countCodes(file) print results counts['code'] = counts['code']+results[0] counts['comment'] = counts['comment']+results[1] counts['blank_line'] = counts['blank_line']+results[2] print counts
第 0008 題: 一個HTML文件,找出里面的正文。
第 0009 題: 一個HTML文件,找出里面的鏈接。
分別用lxml模塊和BeautifulSoup模塊提取了鏈接屬性和文本內容,代碼如下:

#coding:utf-8 import requests from lxml import html from bs4 import BeautifulSoup #下載一個html文件 # response = requests.get("https://www.cnblogs.com/silence-cho/p/9786069.html") # print type(response.text) # with open('python.html','w') as f: # f.write(response.text.encode('utf-8')) #使用lxml模塊 with open('python.html','r') as f: html_file = f.read().decode('utf-8') tree = html.fromstring(html_file) a_tags = tree.xpath('//a[@href]') #找到a標簽,打印href屬性 for a_tag in a_tags: if a_tag.attrib.has_key('href'): print a_tag.attrib['href'] text = tree.text_content().encode('gbk',errors='ignore') #提取文本內容,寫入文本文件 with open('text2.txt','w') as f: f.write(text) #也可以使用Beautiful模塊 # soup = BeautifulSoup(html_file,'lxml') # a_tags = soup.find_all('a') # for a_tag in a_tags: # if a_tag.has_attr('href'): # print a_tag.attrs['href'] # text = soup.get_text().encode('gbk',errors='ignore') #使用get_text()方法 # with open('text1.txt','w') as f: # f.write(text) # strings = soup.strings #使用strings屬性 # with open('string.txt','w') as f: # for string in strings: #strings 為generator類型,包含拿到的所有文本 # f.write(string.encode('gbk',errors='ignore'))
第 0010 題: 使用 Python 生成類似於下圖中的字母驗證碼圖片

#coding:utf-8 #第 0010 題: 使用 Python 生成類似於下圖中的字母驗證碼圖片 from PIL import Image, ImageDraw, ImageFont,ImageFilter import string import random letters = string.letters def getRanColor(): return (random.randint(64,255),random.randint(64,255),random.randint(64,255)) #數值越大,顏色越淺 def getRanColor2(): return (random.randint(32,127),random.randint(32,127),random.randint(0,127)) def getRanChar(): return random.choice(letters) size= (240,60) #圖片大小為240*60 im = Image.new('RGBA',size,(255,255,255)) #背景為白色 draw = ImageDraw.Draw(im) font = ImageFont.truetype('C:\\Windows\\Fonts\\CENTURY.TTF',48) #背景填充點 for x in range(size[0]): for y in range(size[1]): draw.point((x,y),fill=getRanColor()) # x = random.randint(0, 236) # y = random.randint(0, 56) # draw.arc((x, y, x+4, y+4), 0, 90, fill=getRanColor()) #繪制弧線 for i in range(4): letter = getRanChar() #print letter x1 = 10+i*size[0]/4 draw.text((x1,2),letter,fill=getRanColor2(),font=font) # text = ' '.join(random.sample(letters,4)) #用空格拼接起來 # text_width,text_height = font.getsize(text) # x1 = (size[0]-text_width)/2 # y1 = (size[1]-text_height)/10 #除以2時字母總是靠下面? # draw.text((x1,y1),text,fill=getRanColor2(),font=font) im.filter(ImageFilter.BLUR) #模糊處理 im.save('captcha.png','PNG')
第 0011 題: 敏感詞文本文件 filtered_words.txt,里面的內容為以下內容,當用戶輸入敏感詞語時,則打印出 Freedom,否則打印出 Human Rights。

#coding:utf-8 def filterWords(word): with open('filtered_words.txt','r') as f: lines = f.readlines() words = [line.strip().decode('utf-8').encode('gbk') for line in lines] #filtered_words文件編碼格式為utf-8,用戶輸入的為gbk格式 print words if word in words: print "Freedom" else: print "Human Rights" if __name__=="__main__": word = raw_input(u"請輸入:".encode('gbk')) #windows命令行為gbk編碼 filterWords(word)
第 0012 題: 敏感詞文本文件 filtered_words.txt,里面的內容 和 0011題一樣,當用戶輸入敏感詞語,則用 星號 * 替換,例如當用戶輸入「北京是個好城市」,則變成「**是個好城市」。

#coding:utf-8 #第 0012 題: 敏感詞文本文件 filtered_words.txt,里面的內容 和 0011題一樣,當用戶輸入敏感詞語,則用 星號 * 替換,例如當用戶輸入「北京是個好城市」,則變成「**是個好城市」。 def filterWords(sentence): with open('filtered_words.txt','r') as f: lines = f.readlines() words = [line.strip().decode('utf-8').encode('gbk') for line in lines] #filtered_words文件編碼格式為utf-8,用戶輸入的為gbk格式 #print words for item in words: if item in sentence: print item,len(item) sentence = sentence.replace(item,"*"*len(item)) print sentence if __name__=="__main__": sentence = raw_input(u"請輸入:".encode('gbk')) #windows命令行為gbk編碼 filterWords(sentence)
第 0013 題: 用 Python 寫一個爬圖片的程序,爬 這個鏈接里的日本妹子圖片 :-)

#coding:utf-8 #用Python 寫一個爬圖片的程序,爬取圖片url="http://tieba.baidu.com/p/2166231880" import requests from lxml import html import hashlib def getName(url): m = hashlib.md5() m.update(url) name = m.hexdigest()+'.jpg' return name response = requests.get(url="http://tieba.baidu.com/p/2166231880",headers={"User-Agent":"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0"}) tree = html.fromstring(response.text) div_tags = tree.xpath("//div[@id='j_p_postlist']/div") #print tags image_urls = [] for tag in div_tags: url = tag.xpath(".//img[@class='BDE_Image']/@src") #匹配img標簽的src屬性 if url: image_urls.extend(url) for url in image_urls: im_name = getName(url) #對url進行hash摘要計算,拿到不同的圖片名字 print im_name im = requests.get(url=url,headers={"User-Agent":"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0"}) with open(im_name,'wb') as f: f.write(im.content) #response.content為返回的bytes數據
第 0014 題: 純文本文件 student.txt為學生信息, 里面的內容(包括花括號)如下所示:
{ "1":["張三",150,120,100], "2":["李四",90,99,95], "3":["王五",60,66,68] }
請將上述內容寫到 student.xls 文件中,如下圖所示:
閱讀資料 騰訊游戲開發 XML 和 Excel 內容相互轉換

#coding:utf-8 #第 0014 題: 純文本文件 student.txt為學生信息, 里面的內容(包括花括號)如下所示: # { # "1":["張三",150,120,100], # "2":["李四",90,99,95], # "3":["王五",60,66,68] # } #請將上述內容寫到 student.xls 文件中 #python 操控excel模塊(xlrd,xlwt,xlutils),其中讀取xlrd, 寫入xlwt import json import xlwt from collections import OrderedDict with open("students.txt",'r') as f: data = f.read() data_dict = json.loads(data,object_pairs_hook=OrderedDict) #設置object_pairs_hook=OrderedDict 反序列化時,記住解析的順序,返回的為有序字典 #print type(data_dict) workbook = xlwt.Workbook() #寫入數據應該為unicode,否則需設置編碼格式,如book = Workbook(encoding='utf-8') sheet1 = workbook.add_sheet('Sheet 1',cell_overwrite_ok=True) #添加一張sheet表,設置cell_overwrite_ok=True,不然對單元格重復操作會報錯 for i,(key,value) in enumerate(data_dict.items()): sheet1.write(i,0,key) #在單元格寫入,(0,0)表示第一行第一列的單元格 for index,val in enumerate(value,1): sheet1.write(i,index,val) workbook.save("students.xls")
第 0015 題: 純文本文件 city.txt為城市信息, 里面的內容(包括花括號)如下所示:
{ "1" : "上海", "2" : "北京", "3" : "成都" }
請將上述內容寫到 city.xls 文件中,如下圖所示:

#coding:utf-8 import json import xlwt from collections import OrderedDict with open("city.txt",'r') as f: data = f.read() ordata = json.loads(data,object_pairs_hook=OrderedDict) workbook = xlwt.Workbook() sheet1 = workbook.add_sheet("city",cell_overwrite_ok=True) for i,(key,value) in enumerate(ordata.items()): sheet1.write(i,0,key) sheet1.write(i,1,value) workbook.save("city.xls")
第 0016 題: 純文本文件 numbers.txt, 里面的內容(包括方括號)如下所示:
[
[1, 82, 65535],
[20, 90, 13],
[26, 809, 1024]
]
請將上述內容寫到 numbers.xls 文件中,如下圖所示:

#coding:utf-8 import json import xlwt with open("numbers.txt",'r') as f: data = f.read() data_list = json.loads(data) #print data_list workbook = xlwt.Workbook() sheet1 = workbook.add_sheet("numbers",cell_overwrite_ok=True) for row,item in enumerate(data_list): for col, number in enumerate(item): sheet1.write(row,col,number) workbook.save("numbers.xls")
第 0017 題: 將 第 0014 題中的 student.xls 文件中的內容寫到 student.xml 文件中,如
下所示:
<?xml version="1.0" encoding="UTF-8"?> <root> <students> <!-- 學生信息表 "id" : [名字, 數學, 語文, 英文] --> { "1" : ["張三", 150, 120, 100], "2" : ["李四", 90, 99, 95], "3" : ["王五", 60, 66, 68] } </students> </root>

#coding:utf-8 from xml.etree import ElementTree as ET from collections import OrderedDict import json import xlrd wb = xlrd.open_workbook("students.xls") students = wb.sheet_by_index(0) data=OrderedDict() for row in range(students.nrows): data[students.cell_value(row,0)]=[] for col in range(1,students.ncols): data[students.cell_value(row,0)].append(students.cell_value(row,col)) title=u""" <!-- 學生信息表 "id" : [名字, 數學, 語文, 英文] --> """ text_list = ['<?xml version="1.0" encoding="UTF-8"?>\n'] #第一行無法通過屬性設置 root = ET.Element("root") students = ET.SubElement(root,"students") students.tail='\n' students.text=title+json.dumps(data,ensure_ascii=False).replace("],","],\n")+u"\n" xml_str = ET.tostring(root,encoding="utf-8") #輸出字符竄編碼格式 text_list.append(xml_str) with open("students.xml","w") as xf: xf.write("".join(text_list)) # tree = ET.ElementTree(root) # tree.write("students.xml") #轉換txt文件到xml # with open("students.txt",'r') as f: # data = f.read() # text =["""<?xml version="1.0" encoding="UTF-8"?> # <root> # <students> # <!-- # 學生信息表 # "id" : [名字, 數學, 語文, 英文] # --> # """] # text.append(data) # text.append("""</students> # </root>""") # with open("students.xml","w") as xf: # xf.write("".join(text))
第 0018 題: 將 第 0015 題中的 city.xls 文件中的內容寫到 city.xml 文件中,如下所示:
<?xmlversion="1.0" encoding="UTF-8"?> <root> <cities> <!-- 城市信息 --> { "1" : "上海", "2" : "北京", "3" : "成都" } </cities> </root>

#coding:utf-8 import xlrd from xml.etree import ElementTree as ET from collections import OrderedDict import json data = OrderedDict() wb = xlrd.open_workbook("city.xls") sheet = wb.sheet_by_index(0) for row in range(sheet.nrows): data[sheet.cell_value(row,0)]=sheet.cell_value(row,1) text_list = ['<?xmlversion="1.0" encoding="UTF-8"?>\n'] root = ET.Element("root") city = ET.SubElement(root,"cities") city.tail = "\n" title =u""" <!-- 城市信息 --> """ city.text =title+json.dumps(data,ensure_ascii=False, indent=2)+u"\n" #indent=2,使輸出的數據換行顯示,有兩個空格縮進 text_list.append(ET.tostring(root,encoding="utf-8")) text = "".join(text_list) print text with open("city.xml","w") as xf: xf.write(text)
第 0019 題: 將 第 0016 題中的 numbers.xls 文件中的內容寫到 numbers.xml 文件中,如下所示:
<?xml version="1.0" encoding="UTF-8"?> <root> <numbers> <!-- 數字信息 --> [ [1, 82, 65535], [20, 90, 13], [26, 809, 1024] ] </numbers> </root>

#coding:utf-8 from xml.etree import ElementTree as ET import json import xlrd wb = xlrd.open_workbook("numbers.xls") sheet = wb.sheet_by_index(0) data=[] for row in range(sheet.nrows): rd=[] for col in range(sheet.ncols): rd.append(sheet.cell_value(row,col)) data.append(rd) text_list=['<?xml version="1.0" encoding="UTF-8"?>\n'] root = ET.Element("root") numbers = ET.SubElement(root,"numbers") numbers.tail = "\n" title=u""" <!-- 數字信息 --> """ numbers.text = title+json.dumps(data).replace("],","],\n")+u"\n" text_list.append(ET.tostring(root,encoding="utf-8")) with open("numbers.xml","w") as xf: xf.write("".join(text_list))
第 0020 題: 登陸中國聯通網上營業廳 后選擇「自助服務」 --> 「詳單查詢」,然后選擇你要查詢的時間段,點擊「查詢」按鈕,查詢結果頁面的最下方,點擊「導出」,就會生成類似於 2014年10月01日~2014年10月31日通話詳單.xls 文件。寫代碼,對每月通話時間做個統計。

#coding:utf-8 import xlrd import re import time def calPhoneTime(data): hour,minute,second=0,0,0 match = re.findall(u"(\d+)",data) if len(match)==3: hour =int(match[0]) minute = int(match[1]) second = int(match[2]) elif len(match)==2: minute = int(match[0]) second = int(match[1]) else: second = int(match[0]) return hour,minute,second #下面匹配方式也可以 # for row in range(1,sheet.nrows): # data = sheet.cell_value(row,3) # match = re.findall(u"(\d+時){0,1}(\d+分){0,1}(\d+秒)",data)[0] # if match[0] and match[0].endswith(u"時"): # h = int(match[0].strip(u"時")) # hour = hour+h # if match[1] and match[1].endswith(u"分"): # m = int(match[1].strip(u"分")) # minute = minute+m # if match[2] and match[2].endswith(u"秒"): # s = int(match[2].strip(u"秒")) # second = second+s # print hour,minute,second def formatTime(hour,minute,second): if second>=60: m,second=divmod(second,60) minute = minute+m if minute>=60: h,minute=divmod(minute,60) hour = hour+h return "%s hour %s minute %s second"%(hour,minute,second) if __name__=="__main__": hour,minute,second=0,0,0 wb = xlrd.open_workbook(u"2018年12月語音通信.xls") #必須進行unicode,不然會報錯,相當於:unicode("2018年12月語音通信.xls","utf-8") sheet = wb.sheet_by_index(0) start_time = time.mktime(time.strptime("2018-12-01","%Y-%m-%d")) #mktime返回浮點數,便於比較大小 end_time = time.mktime(time.strptime("2019-01-01","%Y-%m-%d")) for row in range(1,sheet.nrows): this_time = time.mktime(time.strptime(sheet.cell_value(row,2),"%Y-%m-%d %H:%M:%S")) if start_time<this_time and this_time<end_time: h,m,s = calPhoneTime(sheet.cell_value(row,3)) hour = hour+h minute = minute+m second = second+s phone_time = formatTime(hour,minute,second) print phone_time
第 0021 題: 通常,登陸某個網站或者 APP,需要使用用戶名和密碼。密碼是如何加密后存儲起來的呢?請使用 Python 對密碼加密。

#coding:utf-8 import hmac import os import hashlib m_dict={"md5":hashlib.md5,"sha1":hashlib.sha1,"sha256":hashlib.sha256} def encrypt_passwd(password, salt=None): algo = "sha256" if salt==None: salt = os.urandom(8) #8個字節的隨機數 if isinstance(password, unicode): password = password.encode('UTF-8') m = m_dict[algo] hash = hmac.new(salt,password,m).digest() return "%s$%s$%s"%(algo,salt,hash) def check_passwd(user_passwd,encrypt_passwd): algo,salt,hash = encrypt_passwd.split("$") m = m_dict[algo] return hash==hmac.new(salt,user_passwd,m).digest() if __name__=="__main__": old_passwd = raw_input("input password: ") encrypt_passwd = encrypt_passwd(old_passwd) new_passwd = raw_input("input password again: ") result = check_passwd(new_passwd,encrypt_passwd) print result #參考代碼 # import os # from hashlib import sha256 # from hmac import HMAC # def encrypt_password(password, salt=None): # """Hash password on the fly.""" # if salt is None: # salt = os.urandom(8) # 64 bits. # assert 8 == len(salt) # assert isinstance(salt, str) # if isinstance(password, unicode): # password = password.encode('UTF-8') # assert isinstance(password, str) # result = password # for i in xrange(10): # result = HMAC(result, salt, sha256).digest() # return salt + result # hashed = encrypt_password('secret password') # def validate_password(hashed, input_password): # return hashed == encrypt_password(input_password, salt=hashed[:8]) # assert validate_password(hashed, 'secret password')
第 0022 題: iPhone 6、iPhone 6 Plus 早已上市開賣。請查看你寫得 第 0005 題的代碼是否可以復用。
見第0005題
第 0023 題: 使用 Python 的 Web 框架,做一個 Web 版本 留言簿 應用。
使用django+mysql實現,代碼和效果如下:
url路由和視圖函數

"""MessageBoard URL Configuration The `urlpatterns` list routes URLs to views. For more information please see: https://docs.djangoproject.com/en/1.10/topics/http/urls/ Examples: Function views 1. Add an import: from my_app import views 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') Class-based views 1. Add an import: from other_app.views import Home 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') Including another URLconf 1. Import the include() function: from django.conf.urls import url, include 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) """ from django.conf.urls import url from django.contrib import admin from MessageBox import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r"^index/", views.index) ]

#coding:utf-8 from django.shortcuts import render,HttpResponse,redirect from models import Message,UserInfo import json # Create your views here. def index(request): if request.method=="POST": username = request.POST.get("username") content = request.POST.get("content") users = UserInfo.objects.filter(username=username) if (not content) or (not username): return redirect("/index/") if not users: user = UserInfo.objects.create(username=username) else: user = users[0] message_obj = Message.objects.create(user=user,content=content) message={"create_time":message_obj.create_time.strftime("%Y-%m-%d %H:%M:%S")} #auto_now_add時間必須格式化后才能用json處理 #print message return HttpResponse(json.dumps(message)) messages = Message.objects.all().order_by("-nid")[0:10] #逆序排列,使最新的留言的排在最前面 return render(request,"index.html",locals())
數據模型:(注意數據庫中文亂碼問題)

DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'blog', 'USER': 'root', 'PASSWORD': '', 'HOST': '', 'PORT': '', 'CHARSET':'utf8', 'COLLATION':'utf8_general_ci', #注意有中文時設置該utf8格式,同時建立數據庫時:CREATE DATABASE mydb DEFAULT CHARACTER SET utf8 COLLATION utf8_general_ci; } }

#coding:utf-8 from __future__ import unicode_literals from django.db import models from django.contrib.auth.models import AbstractUser # Create your models here. class UserInfo(AbstractUser): def __str__(self): return self.username class Meta: verbose_name="用戶" verbose_name_plural=verbose_name class Message(models.Model): nid = models.AutoField(primary_key=True) content=models.CharField(max_length=512) user = models.ForeignKey(to='UserInfo') create_time = models.DateTimeField(auto_now_add=True) def __str__(self): return self.nid class Meta: verbose_name="留言內容" verbose_name_plural=verbose_name
前端模板和樣式

<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>留言板</title> <link rel="stylesheet" type="text/css" href="/statics/css/layout.css"> </head> <body> <div id="header">留言簿</div> <div id="mbox"> <form> {% csrf_token %} <label><strong>請盡情留言吧:</strong></label><br/><br/> <textarea name="content" id="content"></textarea><br/> <label for="username">姓名</label> <input type="text" name="username" id="username"/> </form> <div id="bt"><button onclick="leaveMessage();">留言</button></div> </div> <div id="mcontent"> {% if messages %} <label><strong>留言歷史信息:</strong></label><br/><br/> <div id="detail"> {% for message in messages %} <p><a href='#'>{{ message.user.username }}</a> 留言於<span>{{ message.create_time|date:"Y-m-d H:i:s" }}</span></p> <p>{{ message.content }}</p> <hr/> {% endfor %} </div> {% endif %} </div> <div id="footer"> <p>人生若只如初見,何事秋風悲畫扇。</p> </div> <script type="text/javascript" src="/statics/js/jquery-3.3.1.js"></script> <script> function leaveMessage(){ var username = $("#username").val(); var content = $("#content").val(); $.ajax({ url:'/index/', method:"post", data:{username:username, content:content, csrfmiddlewaretoken: '{{ csrf_token }}'}, dataType:'json', success:function (data) { //console.log(data); $("#username").val(''); $("#content").val(''); var mes = "<p><a href='#'>"+username+"</a> 留言於<span>"+data.create_time+"</span></p>\n" + " <p>"+content+"</p>\n" + " <hr/>\n"; $("#detail").prepend(mes); } }); }; </script> </body> </html>

body{ margin:10px; font-size: 13px; ine-height: 1.2em; font-family: Helvetica Neue,Helvetica,PingFang SC,Hiragino Sans GB,Microsoft YaHei,Noto Sans CJK SC,WenQuanYi Micro Hei,Arial,sans-serif; } #header{ height:40px; padding:5px; padding-left: 60px; background-color:linen; font-size: 2.5em; } #mbox{ margin-top: 5px; background-color:silver; font-size:1.2em; padding:10px 300px; } #mbox textarea{ width: 700px; height:50px; } #mbox #bt{ padding-left: 660px; } #mcontent{ width:100%; font-size:1.2em; padding:20px; } #detail{ height:260px; overflow: auto; padding-left: 25px; margin-right: 25px; } #footer{ text-align: center; font-size: 1.2em; color: green; background-color: darkgrey; height:50px; padding-top: 2px; }
實現效果:
第 0024 題: 使用 Python 的 Web 框架,做一個 Web 版本 TodoList 應用。
使用django+mysql+bootstrap實現,代碼和效果如下:
url路由和視圖函數:

from django.conf.urls import url from django.contrib import admin from PlanList import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^todoList/', views.todoList), url(r'^addTask/', views.addTask), url(r'^login/', views.login), url(r'^logout/', views.logout), url(r'^register/', views.register), url(r'^deleteTask/(\d+)', views.deleteTask), url(r'^editTask/(\d+)', views.editTask), ]

#coding:utf-8 from django.contrib import auth from django.shortcuts import render,redirect import forms from .models import Task,User from pagination import Pagination # Create your views here. def login(request): result={'status': 0, 'msg': ''} if request.method=="POST": username = request.POST.get('username') passwd = request.POST.get('password') user = auth.authenticate(username=username,password=passwd) if user: auth.login(request,user) return redirect('/todoList/') else: result['msg'] = '用戶名或密碼錯誤!' result['status'] = 1 return render(request, 'login.html', {'result': result}) return render(request,'login.html',{'result': result}) def logout(request): auth.logout(request) return redirect('/login/') def register(request): result = {'status': 0, 'msg': ''} if request.method=="POST": form_obj = forms.UserForm(request.POST) if form_obj.is_valid(): form_obj.cleaned_data.pop('confirmPassword') User.objects.create_user(**form_obj.cleaned_data) return redirect('/login/') else: result['status'] = 1 result['msg'] = form_obj.errors return render(request, 'register.html', locals()) form_obj = forms.UserForm() return render(request,'register.html',locals()) def todoList(request): if not request.user.id: return redirect('/login/') title = request.GET.get('search', '') sort = request.GET.get('sort','') if sort=='': sort='deadline' tasks = Task.objects.filter(user_id=request.user.id).filter(title__contains=title).order_by(sort) current_page = int(request.GET.get('page', 1)) # 當前頁碼數 params = request.GET # get提交的參數 base_url = request.path # url路徑 all_count = tasks.count() # 總數 pagination = Pagination(current_page, all_count, base_url, params, per_page_num=3, pager_count=3) tasks_list = tasks[pagination.start:pagination.end] return render(request,'list.html',locals()) def addTask(request): if request.method=='POST': taskForm = forms.TaskForm(request.POST) if taskForm.is_valid(): #print taskForm.cleaned_data Task.objects.create(user=request.user,**taskForm.cleaned_data) return render(request, 'pop.html') # 返回一個空頁面(在其中關閉當前頁面,並調用父頁面的函數) taskForm = forms.TaskForm() return render(request,'addTask.html',locals()) def deleteTask(request,id): Task.objects.get(id=id).delete() return redirect('/todoList/') def editTask(request,id): if request.method=="POST": title = request.POST.get('title') content = request.POST.get('content') deadline = request.POST.get('deadline') Task.objects.filter(id=id).update(title=title,content=content,deadline=deadline) return redirect('/todoList/') task = Task.objects.get(id=id) return render(request, 'editTask.html', locals())

#coding:utf-8 from django import forms from django.core.exceptions import ValidationError import models class TaskForm(forms.Form): title = forms.CharField( label='任務標題', max_length=64, widget=forms.widgets.TextInput(attrs={'class':'form-control'}) ) content = forms.CharField( label='詳細內容', widget=forms.widgets.Textarea(attrs={'class': 'form-control'}) ) deadline = forms.DateTimeField() #不作為前端模板使用(改用datetimepicker插件),后端數據處理時使用 class UserForm(forms.Form): username = forms.CharField( max_length=16, label='用戶名', error_messages={ 'max_length':'用戶名最長16位', 'required':'用戶名不能為空', }, widget=forms.widgets.TextInput( attrs={'class':'form-control'} ), ) password = forms.CharField( min_length=6, label='密碼', error_messages={ 'min_length':'密碼至少6位', 'required':'密碼不能為空', }, widget=forms.widgets.PasswordInput( attrs={'class':'form-control'}, ), ) confirmPassword = forms.CharField( min_length=6, label='確認密碼', error_messages={ 'min_length':'確認密碼至少6位', 'required':'確認密碼不能為空', }, widget=forms.widgets.PasswordInput( attrs={'class':'form-control'}, ), ) phone = forms.CharField( label='手機號', max_length=11, widget=forms.widgets.TextInput( attrs={'class':'form-control'}, ), error_messages={ 'invalid':'手機號格式不正確', 'max_length': '手機號最長11位', 'required':'手機號不能為空', }, ) #重寫用戶名鈎子函數,驗證用戶名是否已經存在 def clean_username(self): username = self.cleaned_data.get('username') is_exist = models.User.objects.filter(username=username) if is_exist: self.add_error('username',ValidationError('用戶名已注冊')) else: return username #重寫郵箱鈎子函數,驗證郵箱是否已經存在 def clean_phone(self): phone = self.cleaned_data.get('phone') is_exist = models.User.objects.filter(phone=phone) if is_exist: self.add_error('phone',ValidationError('手機號已被注冊')) else: return phone #重寫form全局鈎子函數,判斷兩次密碼一致 def clean(self): password = self.cleaned_data.get('password') confirmPassword = self.cleaned_data.get('confirmPassword') if confirmPassword and password != confirmPassword: self.add_error('confirmPassword', ValidationError('兩次密碼不一致')) else: return self.cleaned_data #重寫后必須返回cleaned_data數據

#coding:utf-8 class Pagination(object): def __init__(self, current_page, all_count, base_url,params, per_page_num=8, pager_count=11, ): """ 封裝分頁相關數據 :param current_page: 當前頁 :param all_count: 數據庫中的數據總條數 :param per_page_num: 每頁顯示的數據條數 :param base_url: 分頁中顯示的URL前綴 :param params: url中提交過來的數據 :param pager_count: 最多顯示的頁碼個數 """ try: current_page = int(current_page) except Exception as e: current_page = 1 if current_page < 1: current_page = 1 self.current_page = current_page self.all_count = all_count self.per_page_num = per_page_num self.base_url = base_url # 總頁碼 all_pager, tmp = divmod(all_count, per_page_num) if tmp: all_pager += 1 self.all_pager = all_pager self.pager_count = pager_count # 最多顯示頁碼數 self.pager_count_half = int((pager_count - 1) / 2) import copy params = copy.deepcopy(params) params._mutable = True self.params = params # self.params : {"page":77,"title":"python","nid":1} @property def start(self): return (self.current_page - 1) * self.per_page_num @property def end(self): return self.current_page * self.per_page_num def page_html(self): # 如果總頁碼 < 11個: if self.all_pager <= self.pager_count: pager_start = 1 pager_end = self.all_pager + 1 # 總頁碼 > 11 else: # 當前頁如果<=頁面上最多顯示(11-1)/2個頁碼 if self.current_page <= self.pager_count_half: pager_start = 1 pager_end = self.pager_count + 1 # 當前頁大於5 else: # 頁碼翻到最后 if (self.current_page + self.pager_count_half) > self.all_pager: pager_start = self.all_pager - self.pager_count + 1 pager_end = self.all_pager + 1 else: pager_start = self.current_page - self.pager_count_half pager_end = self.current_page + self.pager_count_half + 1 page_html_list = [] self.params["page"] = 1 first_page =u'<li><a href="%s?%s">首頁</a></li>' % (self.base_url, self.params.urlencode(),) #有漢字,不用u'',會報錯? page_html_list.append(first_page) if self.current_page <= 1: prev_page = u'<li class="disabled"><a href="#">上一頁</a></li>' else: self.params["page"] = self.current_page - 1 prev_page = u'<li><a href="%s?%s">上一頁</a></li>' % (self.base_url, self.params.urlencode(),) page_html_list.append(prev_page) for i in range(pager_start, pager_end): # self.params : {"page":77,"title":"python","nid":1} self.params["page"] = i # {"page":72,"title":"python","nid":1} if i == self.current_page: temp = '<li class="active"><a href="%s?%s">%s</a></li>' % (self.base_url, self.params.urlencode(), i,) else: temp = '<li><a href="%s?%s">%s</a></li>' % (self.base_url, self.params.urlencode(), i,) page_html_list.append(temp) if self.current_page >= self.all_pager: next_page = u'<li class="disabled"><a href="#">下一頁</a></li>' else: self.params["page"] = self.current_page + 1 next_page =u'<li><a href="%s?%s">下一頁</a></li>' % (self.base_url, self.params.urlencode(),) page_html_list.append(next_page) self.params["page"] = self.all_pager last_page =u'<li><a href="%s?%s">尾頁</a></li>' % (self.base_url, self.params.urlencode(),) page_html_list.append(last_page) return ''.join(page_html_list)
數據模型:

#coding:utf-8 from __future__ import unicode_literals from django.db import models from django.contrib.auth.models import AbstractUser # Create your models here. class User(AbstractUser): phone = models.CharField(max_length=11) def __str__(self): return self.username class Meta: verbose_name = '用戶' verbose_name_plural=verbose_name class Task(models.Model): title = models.CharField(max_length=64) user = models.ForeignKey(to='User') create_date = models.DateTimeField(auto_now_add=True) content = models.TextField() deadline = models.DateTimeField() def __str__(self): return self.title class Meta: verbose_name = '任務' verbose_name_plural=verbose_name

""" Django settings for ToDoList project. Generated by 'django-admin startproject' using Django 1.10.8. For more information on this file, see https://docs.djangoproject.com/en/1.10/topics/settings/ For the full list of settings and their values, see https://docs.djangoproject.com/en/1.10/ref/settings/ """ import os # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/1.10/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = '5%v3hfy*+thu-in&f__ypd43y1lw&poky&+-=8=es4!mrnp=pa' # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True ALLOWED_HOSTS = [] # Application definition INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'PlanList.apps.PlanlistConfig', ] MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] ROOT_URLCONF = 'ToDoList.urls' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')] , 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ] WSGI_APPLICATION = 'ToDoList.wsgi.application' # Database # https://docs.djangoproject.com/en/1.10/ref/settings/#databases # DATABASES = { # 'default': { # 'ENGINE': 'django.db.backends.sqlite3', # 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), # } # } DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME':'planList', 'USER':'root', 'PASSWORD':'', 'HOST':'', 'PORT':'', 'CHARSET':'utf8', 'COLLATION':'utf8_general_ci', } } # Password validation # https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators AUTH_PASSWORD_VALIDATORS = [ { 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', }, { 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', }, { 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', }, { 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', }, ] # Internationalization # https://docs.djangoproject.com/en/1.10/topics/i18n/ LANGUAGE_CODE = 'en-us' TIME_ZONE = 'UTC' USE_I18N = True USE_L10N = True USE_TZ = True # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/1.10/howto/static-files/ STATIC_URL = '/static/' STATICFILES_DIRS = [os.path.join(BASE_DIR,'static')] AUTH_USER_MODEL = 'PlanList.User'
前端模板和樣式:

<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>ToDoList</title> <link rel="stylesheet" type="text/css" href="/static/bootstrap/css/bootstrap.min.css"> <style> body{ margin:10px; font-size: 13px; ine-height: 1.2em; font-family: Helvetica Neue,Helvetica,PingFang SC,Hiragino Sans GB,Microsoft YaHei,Noto Sans CJK SC,WenQuanYi Micro Hei,Arial,sans-serif; } .page-header h1{ color:forestgreen; } #task{ padding: 10px 25px; font-size:1.5em; background-color:lightgreen; color:forestgreen; } form{ padding-left: 580px; margin: 20px; } #sort{ margin-left: 100px; } #taskTable{ margin:10px 95px 10px 95px; } </style> </head> <body> <div class="dropdown pull-right"> <button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true"> <span class="glyphicon glyphicon-user"></span> {{ request.user.username }} <span class="caret"></span> </button> <ul class="dropdown-menu" aria-labelledby="dropdownMenu1"> <li><a href="/logout/">退出</a></li> </ul> </div> <div class="page-header"> <h1>QuickStart示例 <small>--TodoList應用演示</small></h1> </div> <div id="task">我的待辦事項</div> <form class="form-inline"> <div class="form-group"> <label for="taskName">名稱:</label> <input type="text" class="form-control" id="taskName" name="search" placeholder="搜索任務名稱"> </div> <button type="submit" class="btn btn-default">搜索</button> <label id="sort">排序方式:</label> <div class="form-group"> <select class="form-control" style="width:150px;" name="sort"> <option value="create_date">創建時間</option> <option value="deadline" selected="selected">截止時間</option> </select> </div> <button type="submit" class="btn btn-default">選擇</button> </form> <div id="taskTable"> <div> <table class="table table-bordered table-striped"> <tr> <th>任務</th> <th>創建時間</th> <th>截止時間</th> <th>管理</th> </tr> {% for task in tasks_list %} <tr> <td>{{ task.title }}</td> <td>{{ task.create_date|date:"Y-m-d H:i:s" }}</td> <td>{{ task.deadline|date:"Y-m-d H:i:s" }}</td> <td><a href="/deleteTask/{{ task.id }}"><button type="button" class='btn btn-success'>刪除</button></a> <a href="/editTask/{{ task.id }}"><button type="button" class='btn btn-success'>編輯</button></a> </td> </tr> {% endfor %} </table> </div> <div> <!--分頁標簽--> <nav aria-label="Page navigation"> <ul class="pagination">{{ pagination.page_html|safe }}</ul> </nav> </div> <button class="btn btn-success" onclick="createTask();">創建任務</button> </div> <hr/> <script type="text/javascript" src="/static/jquery-3.3.1.js"></script> <script type="text/javascript" src="/static/bootstrap/js/bootstrap.min.js"></script> <script> window.opener=null; function createTask(){ window.open("/addTask/","","width=800,height=600,top=100,left=100"); } function refresh(){ window.location.href='/todoList/'; } </script> </body> </html>

<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>登陸</title> <link rel="stylesheet" type="text/css" href="/static/bootstrap/css/bootstrap.min.css"> </head> <body> <h3 style="margin-top: 150px; text-align: center">歡迎登陸我的任務列表</h3> <br/><br/> <form class="form-horizontal" action="/login/" method="post"> {% csrf_token %} <div class="form-group"> <label for="inputUsername" class="col-sm-4 control-label">用戶名</label> <div class="col-sm-4"> <input type="text" class="form-control" id="inputUsername" placeholder="Username" name="username"> </div> </div> <div class="form-group"> <label for="inputPassword" class="col-sm-4 control-label">密碼</label> <div class="col-sm-4"> <input type="password" class="form-control" id="inputPassword" placeholder="Password" name="password"> </div> </div> <div class="form-group has-error"> <div class="col-sm-offset-4 col-sm-8"> {% if result.status %} <span class="help-block">{{ result.msg }}</span> {% endif %} </div> </div> <div class="form-group"> <div class="col-sm-offset-5"> <button type="submit" style="margin-left: 30px;" class="btn btn-info">登陸</button> <a class="btn btn-info" style="margin-left: 20px;" href="/register/">注冊</a> </div> </div> </form> </body> </html>

<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>注冊</title> <link rel="stylesheet" type="text/css" href="/static/bootstrap/css/bootstrap.min.css"> </head> <body> <div class="container"> <h3 style="margin-top: 100px; text-align: center">注冊我的任務列表</h3> <br/><br/> <div class="row"> <div class="col-md-6 col-md-offset-3 "> <form class="form-horizontal" action="/register/" method="post" enctype="multipart/form-data"> {% csrf_token %} <div class="form-group"> <label for="{{ form_obj.username.id_for_label }}" class="col-sm-2 control-label">{{ form_obj.username.label }}</label> <div class="col-sm-8"> {{ form_obj.username }} <div class="has-error"> <span class="help-block">{{ form_obj.username.errors.0 }}</span> </div> </div> </div> <div class="form-group"> <label for="{{ form_obj.password.id_for_label }}" class="col-sm-2 control-label">{{ form_obj.password.label }}</label> <div class="col-sm-8"> {{ form_obj.password }} <div class="has-error"> <span class="help-block">{{ form_obj.password.errors.0 }}</span> </div> </div> </div> <div class="form-group"> <label for="{{ form_obj.confirmPassword.id_for_label }}" class="col-sm-2 control-label">{{ form_obj.confirmPassword.label }}</label> <div class="col-sm-8"> {{ form_obj.confirmPassword }} <div class="has-error"> <span class="help-block">{{ form_obj.confirmPassword.errors.0 }}</span> </div> </div> </div> <div class="form-group"> <label for="{{ form_obj.phone.id_for_label }}" class="col-sm-2 control-label">{{ form_obj.phone.label }}</label> <div class="col-sm-8"> {{ form_obj.phone }} <div class="has-error"> <span class="help-block">{{ form_obj.phone.errors.0 }}</span> </div> </div> </div> <div class="form-group has-error"> <div class="col-sm-offset-4 col-sm-8"> {% if result.status %} <span class="help-block">{{ result.msg }}</span> {% endif %} </div> </div> <div class="form-group"> <div class="col-sm-offset-4 col-sm-4"> <button type="submit" class="btn btn-info">注冊</button> <a class="btn btn-info" style="margin-left: 20px;" href="/login/">登陸</a> </div> </div> </form> </div> </div> </div> </body> </html>

<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>添加任務</title> <link rel="stylesheet" type="text/css" href="/static/bootstrap/css/bootstrap.min.css"> <link rel="stylesheet" type="text/css" href="/static/datetimepicker/bootstrap-datetimepicker.min.css"> </head> <body> <h4 style="margin-top: 60px; text-align: center">添加任務</h4> <br/> <div class="container"> <div class="row" > <div class="col-md-6 col-md-offset-3 "> <form class="form-horizontal" method="post"> {% csrf_token %} <div class="form-group"> <label for="{{ taskForm.title.id_for_label }}" class="col-sm-2 control-label">{{ taskForm.title.label }}</label> <div class="col-sm-8"> {{ taskForm.title }} </div> </div> <div class="form-group"> <label for="{{ taskForm.content.id_for_label }}" class="col-sm-2 control-label">{{ taskForm.content.label }}</label> <div class="col-sm-8"> {{ taskForm.content }} </div> </div> <div class="form-group"> <label for="datetimepicker" class="col-sm-2 control-label">截止日期</label> <div class="col-sm-8"> <div class='input-group'> <input type='text' class="form-control" id='datetimepicker' name="deadline" placeholder="截止日期"/> <span class="input-group-addon"> <span class="glyphicon glyphicon-calendar"></span> </span> </div> </div> </div> <div class="form-group"> <div class="col-sm-offset-8 col-sm-4"> <button type="submit" class="btn btn-info" id="submit">提交</button> </div> </div> </form> </div> </div> </div> <script type="text/javascript" src="/static/jquery-3.3.1.js"></script> <script type="text/javascript" src="/static/bootstrap/js/bootstrap.min.js"></script> <script src="/static/datetimepicker/bootstrap-datetimepicker.min.js"></script> <script src="/static/datetimepicker/bootstrap-datetimepicker.zh-CN.js"></script> <script> //日歷插件, 官網地址:https://eonasdan.github.io/bootstrap-datetimepicker/ $('#datetimepicker').datetimepicker({ minView: "hour", //設置小時視圖 language: "zh-CN", sideBySide: true, // 同時選擇日期和時間,月視圖可以里不用設 format: 'yyyy-mm-dd hh:ii:ss', //設置日期顯示格式 startDate: new Date(), //設置開始時間,早於此刻的日期不能選擇 bootcssVer: 3, //顯示向左,向右的箭頭 autoclose: true, //選擇日期后自動關閉 todayHighlight: true, todayBtn: true, }).on('changeDate', change_date); function change_date(e) { window.choose_date = e.date.format("yyyy-MM-dd hh:mm:ss"); //location.href = "/order_list/?order_date=" + window.choose_date; }; Date.prototype.format = function(fmt){ var o = { "M+" : this.getMonth()+1, //月份 "d+" : this.getDate(), //日 "h+" : this.getHours(), //小時 "m+" : this.getMinutes(), //分 "s+" : this.getSeconds(), //秒 "q+" : Math.floor((this.getMonth()+3)/3), //季度 "S" : this.getMilliseconds() //毫秒 }; if(/(y+)/.test(fmt)) fmt=fmt.replace(RegExp.$1, (this.getFullYear()+"").substr(4 - RegExp.$1.length)); for(var k in o) if(new RegExp("("+ k +")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length))); return fmt; } </script> </body> </html>

<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Title</title> </head> <body> <script> window.opener.refresh(); window.close(); </script> </body> </html>

<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>編輯任務</title> <link rel="stylesheet" type="text/css" href="/static/bootstrap/css/bootstrap.min.css"> <link rel="stylesheet" type="text/css" href="/static/datetimepicker/bootstrap-datetimepicker.min.css"> </head> <body> <h3 style="margin-top: 160px; text-align: center">編輯任務</h3> <br/><br/> <div class="container"> <div class="row" > <div class="col-md-8 col-md-offset-2 "> <form class="form-horizontal" action="/editTask/{{ task.id }}/" method="post"> {% csrf_token %} <div class="form-group"> <label for="title" class="col-sm-2 control-label">任務標題</label> <div class="col-sm-8"> <input class="form-control" name="title" id="title" value="{{ task.title }}"/> </div> </div> <div class="form-group"> <label for="content" class="col-sm-2 control-label">詳細內容</label> <div class="col-sm-8"> <textarea class="form-control" name='content' id="content">{{ task.content }}</textarea> </div> </div> <div class="form-group"> <label for="datetimepicker" class="col-sm-2 control-label">截止日期</label> <div class="col-sm-8"> <div class='input-group'> <input type='text' class="form-control" id='datetimepicker' name="deadline" value="{{ task.deadline|date:'Y-m-d H:i:s'}}" /> <span class="input-group-addon"> <span class="glyphicon glyphicon-calendar"></span> </span> </div> </div> </div> <div class="form-group"> <div class="col-sm-offset-9 col-sm-3"> <button type="submit" class="btn btn-info" id="submit">提交</button> </div> </div> </form> </div> </div> </div> <script type="text/javascript" src="/static/jquery-3.3.1.js"></script> <script type="text/javascript" src="/static/bootstrap/js/bootstrap.min.js"></script> <script src="/static/datetimepicker/bootstrap-datetimepicker.min.js"></script> <script src="/static/datetimepicker/bootstrap-datetimepicker.zh-CN.js"></script> <script> //日歷插件, 官網地址:https://eonasdan.github.io/bootstrap-datetimepicker/ $('#datetimepicker').datetimepicker({ minView: "hour", //設置小時視圖 language: "zh-CN", sideBySide: true, // 同時選擇日期和時間,月視圖可以里不用設 format: 'yyyy-mm-dd hh:ii:ss', //設置日期顯示格式 startDate: new Date(), //設置開始時間,早於此刻的日期不能選擇 bootcssVer: 3, //顯示向左,向右的箭頭 autoclose: true, //選擇日期后自動關閉 todayHighlight: true, todayBtn: true, }).on('changeDate', change_date); function change_date(e) { window.choose_date = e.date.format("yyyy-MM-dd hh:mm:ss"); //location.href = "/order_list/?order_date=" + window.choose_date; }; Date.prototype.format = function(fmt){ var o = { "M+" : this.getMonth()+1, //月份 "d+" : this.getDate(), //日 "h+" : this.getHours(), //小時 "m+" : this.getMinutes(), //分 "s+" : this.getSeconds(), //秒 "q+" : Math.floor((this.getMonth()+3)/3), //季度 "S" : this.getMilliseconds() //毫秒 }; if(/(y+)/.test(fmt)) fmt=fmt.replace(RegExp.$1, (this.getFullYear()+"").substr(4 - RegExp.$1.length)); for(var k in o) if(new RegExp("("+ k +")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length))); return fmt; } </script> </body> </html>
實現效果:
第 0025 題: 使用 Python 實現:對着電腦吼一聲,自動打開瀏覽器中的默認網站。
例如,對着筆記本電腦吼一聲“百度”,瀏覽器自動打開百度首頁。
關鍵字:Speech to Text
參考思路:
1:獲取電腦錄音-->WAV文件 python record wav
2:錄音文件-->文本
STT: Speech to Text
STT API Google API
3:文本-->電腦命令
簡單折騰了下,谷歌語音識別API調用時失敗了。。。
1,獲取電腦錄音並保存為wav文件

#coding:utf-8 #pyaudio模塊文檔 http://people.csail.mit.edu/hubert/pyaudio/ #https://stackoverflow.com/questions/892199/detect-record-audio-in-python #https://www.cnblogs.com/hyb1/articles/3048756.html #錄音,保存為wav格式文件 import pyaudio import wave from array import array from sys import byteorder from struct import pack CHUNK = 1024 FORMAT = pyaudio.paInt16 CHANNELS = 2 RATE = 44100 RECORD_SECONDS = 5 WAVE_OUTPUT_FILENAME = "output.wav" THRESHOLD=500 def is_silent(snd_data): "Returns 'True' if below the 'silent' threshold" return max(snd_data) < THRESHOLD def normalize(snd_data): "Average the volume out" MAXIMUM = 16384 times = float(MAXIMUM)/max(abs(i) for i in snd_data) r = array('h') for i in snd_data: r.append(int(i*times)) return r def trim(snd_data): "Trim the blank spots at the start and end" def _trim(snd_data): snd_started = False r = array('h') for i in snd_data: if not snd_started and abs(i)>THRESHOLD: snd_started = True r.append(i) elif snd_started: r.append(i) return r # Trim to the left snd_data = _trim(snd_data) # Trim to the right snd_data.reverse() snd_data = _trim(snd_data) snd_data.reverse() return snd_data def add_silence(snd_data, seconds): "Add silence to the start and end of 'snd_data' of length 'seconds' (float)" r = array('h', [0 for i in xrange(int(seconds*RATE))]) r.extend(snd_data) r.extend([0 for i in xrange(int(seconds*RATE))]) return r def record(): p = pyaudio.PyAudio() stream = p.open(format=FORMAT, channels=CHANNELS, rate=RATE, input=True, frames_per_buffer=CHUNK) print("* recording") r = array("h") num_silent = 0 snd_started = False while True: snd_data = array("h",stream.read(CHUNK)) if byteorder=="big": snd_data.byteswap() r.extend(snd_data) silent = is_silent(snd_data) print silent if silent and snd_started: num_silent += 1 print num_silent elif not silent and not snd_started: snd_started = True if snd_started and num_silent > 30: break print("* done recording") sample_width = p.get_sample_size(FORMAT) stream.stop_stream() stream.close() p.terminate() r = normalize(r) r = trim(r) r = add_silence(r, 0.5) return sample_width, r # for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)): # data = stream.read(CHUNK) # print type(data) # frames.append(data) if __name__=="__main__": print("please speak a word into the microphone") sample_width,data = record() data = pack('<' + ('h'*len(data)), *data) wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb') wf.setnchannels(CHANNELS) wf.setsampwidth(sample_width) wf.setframerate(RATE) wf.writeframes(data) wf.close()
2,調用谷歌語音識別API,返回403.。。。。,還有待研究

#coding:utf-8 #谷歌語音識別API,參考http://blog.laobubu.net/archivers/google-speech-api-pt2 #谷歌語音識別API官網教程:https://cloud.google.com/speech-to-text/docs/quickstart-protocol (得翻牆) import requests response = requests.post(url="https://www.google.com/speech-api/v2/recognize?lang=en-us&key=AIzaSyAQgb", headers={"User-Agent":"Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1", "Content-Type":"audio/x-flac; rate=16000"}, files={"file":open("hello.flac","rb",encoding="utf-8")} #key=AIzaSyAQgb,需要去google cloud注冊申請,這個key已不能用 ) print(response)
3,文本轉電腦命令

#coding:utf-8 #將文字轉化為電腦命令 import os command ={"百度":"https://www.baidu.com","新浪":"https://www.sina.com","網易":"https://www.163.com/"} if __name__=="__main__": text = raw_input("please input: ") text_en = text.decode("gbk").encode("utf-8") if text_en in command: url = command[text_en] #windows命令行輸入為gbk格式 else: url="https://www.baidu.com" os.system('"D:\\firefox\\firefox.exe" %s'%url) #火狐瀏覽器打開url #os.system('"C:\\Program Files\\Internet Explorer\\iexplore.exe" %s'%url) #ie瀏覽器