python練手項目


  為了練習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)
    
0000題

 

第 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
0001題

 

第 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()
    
0002題

 

第 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()
0003題

 

第 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) 
0004
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!
The zen of python

 

第 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)
0005題

 

第 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)
0006題

 

第 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
    
    
0007

 

第 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'))
0008-0009題

 

第 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')
0010題

 

第 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)
0011題

 

第 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)
0012題

 

第 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數據
0013題

 

第 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")
0014

 

第 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")
0015題

 

第 0016 題: 純文本文件 numbers.txt, 里面的內容(包括方括號)如下所示:

[
	[1, 82, 65535], 
	[20, 90, 13],
	[26, 809, 1024]
]

請將上述內容寫到 numbers.xls 文件中,如下圖所示:

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")
0016題

 

第 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))
0017題

 

第 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)
0018題

 

第 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))
0019題

 

第 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
0020題

 

第 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')
0021題

 

第 0022 題: iPhone 6、iPhone 6 Plus 早已上市開賣。請查看你寫得 第 0005 題的代碼是否可以復用。

 見第0005題

 

第 0023 題: 使用 Python 的 Web 框架,做一個 Web 版本 留言簿 應用。

閱讀資料:Python 有哪些 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)
]
urls.py
#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())
views.py

數據模型:(注意數據庫中文亂碼問題)

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; 
    }
}
settings.py數據庫配置
#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
model.py

前端模板和樣式

<!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>&nbsp;&nbsp;留言於<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>&nbsp;&nbsp;留言於<span>"+data.create_time+"</span></p>\n" +
                       "                <p>"+content+"</p>\n" +
                       "                <hr/>\n";
                   $("#detail").prepend(mes);
               }
            });
        };
    </script>
</body>
</html>
index.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;
}
layout.css

實現效果:

  

 

第 0024 題: 使用 Python 的 Web 框架,做一個 Web 版本 TodoList 應用。

SpringSide 版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),
]
urls.py
#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())
views.py
#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數據
forms.py
#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)
pagination.py

數據模型:

#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
models.py
"""
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'
settings.py

前端模板和樣式:

<!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>
                        &nbsp;&nbsp;
                        <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>
list.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>
login.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>
register.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>
addTask.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>
pop.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>
editTask.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()
0025-1

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)
0025-2

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瀏覽器    
0025-3

 

 
       


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM