1. 程式人生 > >Python核心程式設計 第七章 練習7–5

Python核心程式設計 第七章 練習7–5

7–5. userpw2.py. 下面的問題和例題7.1 中管理名字-密碼的鍵值對資料的程式有關。
(a)修改那個指令碼,使它能記錄使用者上次的登入日期和時間(用time 模組),並與使用者密碼一起 儲存起來。程式的介面有要求使用者輸入使用者名稱和密碼的提示。無論戶名是否成功登入,都應有提示, 在戶名成功登入後,應更新相應使用者的上次登入時間戳。如果本次登入與上次登入在時間上相差不 超過4 個小時,則通知該使用者: “You already logged in at: .”
(b) 新增一個“管理”選單,其中有以下兩項:(1)刪除一個使用者 (2)顯示系統中所有使用者的名 字和他們的密碼的清單。
(c) 口令目前沒有加密。請新增一段對口令加密的程式碼(請參考crypt, rotor, 或其它加密模組)
(d) 為程式新增圖形介面,例如,用Tkinter 寫。
(e) 要求使用者名稱不區分大小寫。
(f) 加強對使用者名稱的限制,不允許符號和空白符。
(g)合併“新使用者”和“老使用者”兩個選項。如果一個新使用者試圖用一個不存在的使用者名稱登入,
詢問該使用者是否是新使用者,如果回答是肯定的,就建立該帳戶。否則,按照老使用者的方式登入。
原原本本的程式碼:

#!/usr/bin/env python

db = {}

def newuser():
    prompt = 'login desired: '
    while True:
        name = raw_input(prompt)
        if db.has_key(name):
            prompt = 'name taken, try another: '
            continue
        else:
            break
    pwd = raw_input('passwd: ')
    db[name] = pwd

def
olduser():
name = raw_input('login: ') pwd = raw_input('passwd: ') passwd = db.get(name) if passwd == pwd: print 'welcome back', name else: print 'login incorrect' def showmenu(): prompt = """ (N)ew User Login (E)xisting User Login (Q)uit Enter choice: """
done = False while not done: chosen = False while not chosen: try: choice = raw_input(prompt).strip()[0].lower() except (EOFError, KeyboardInterrupt): choice = 'q' print '\nYou picked: [%s]' % choice if choice not in 'neq': print 'invalid menu option, try again' else: chosen = True if choice == 'q': done = 1 if choice == 'n': newuser() if choice == 'e': olduser() if __name__ == '__main__': showmenu()

(a)修改那個指令碼,使它能記錄使用者上次的登入日期和時間(用time 模組),並與使用者密碼一起 儲存起來。程式的介面有要求使用者輸入使用者名稱和密碼的提示。無論戶名是否成功登入,都應有提示, 在戶名成功登入後,應更新相應使用者的上次登入時間戳。如果本次登入與上次登入在時間上相差不 超過4 個小時,則通知該使用者: “You already logged in at: .”

#!/usr/bin/env python

from time import time,ctime #匯入模組
db = {}

def newuser():
    prompt = 'login desired: '
    while True:
        name = raw_input(prompt)
        if db.has_key(name):
            prompt = 'name taken, try another: '
            continue
        else:
            break
    pwd = raw_input('passwd: ')#使用者名稱合格後,要求輸入密碼
    logt=time()#獲取時間戳
    db[name]=[pwd,logt]#把密碼和時間組成列表存到字典,共享一個鍵

def olduser(): 
    name=raw_input('login: ') 
    pwd=raw_input('passwd: ')
    if name in db:#檢測是否是老使用者
        if pwd == db.get(name)[0]: #獲取老使用者密碼與輸入密碼比較
            print 'welcome back',name #顯示歡迎資訊
            print 'You lasttime logged in at:',ctime(db[name][1])
            #顯示上次登入的時間戳
            current=time()#獲取當前時間
            delta=current-db[name][1]#求上次登入與現在時間的時間差
            if delta<=14400: #判斷是否在4小時內
                print 'You already logged in 4 hours period!'

            else:#若時間差不在四小時之內
                logt=time()#獲取當前時間 
                db[name][1]=logt #把密碼和時間組成列表存到字典,共享一個鍵,更新時間戳
        else: #密碼錯誤
            print 'login incorrect'  

    else: #不是老使用者
        print 'login incorrect'  

def showmenu():
    prompt = """
(N)ew User Login
(E)xisting User Login
(Q)uit

Enter choice: """

    done = False
    while not done:
        chosen = False
        while not chosen:
            try:
                choice = raw_input(prompt).strip()[0].lower()
            except (EOFError, KeyboardInterrupt):
                choice = 'q'
            print '\nYou picked: [%s]' % choice

            if choice not in 'neq':
                print 'invalid menu option, try again'
            else:
                chosen = True

        if choice == 'q': done = 1
        if choice == 'n': newuser()
        if choice == 'e': olduser()

if __name__ == '__main__':
    showmenu()

(b) 新增一個“管理”選單,其中有以下兩項:(1)刪除一個使用者 (2)顯示系統中所有使用者的名字和他們的密碼的清單。

#!/usr/bin/env python

from time import time,ctime #匯入模組
db = {}

def newuser():
    prompt = 'login desired: '
    while True:
        name = raw_input(prompt)
        if db.has_key(name):
            prompt = 'name taken, try another: '
            continue
        else:
            break
    pwd = raw_input('passwd: ')
    logt=time()
    db[name]=[pwd,logt]

def olduser(): 
    name=raw_input('login: ') 
    pwd=raw_input('passwd: ')
    if name in db:
        if pwd == db.get(name)[0]: 
            print 'welcome back',name 
            print 'You lasttime logged in at:',ctime(db[name][1])
            current=time()
            delta=current-db[name][1]
            if delta<=14400: #判斷是否在4小時內
                print 'You already logged in 4 hours period!'

            else:
                logt=time()#獲取當前時間 
                db[name][1]=logt #把密碼和時間組成列表存到字典,共享一個鍵
        else: 
            print 'login incorrect'  

    else: 
        print 'login incorrect'

def deluser():
    Getuserpwd()
    c=raw_input('del a user,its name:')
    if c in db.keys():
        del db[c]
        print 'After del:'
        Getuserpwd()
    else:
        print 'Wrong choose!'

def Getuserpwd():
    if db:    
        for name in db:
            print 'name:',name,'pwd:',db[name][0]
    else:
        print 'No usr!'

def management():    
    prompt = """
(D)el a user
(G)et all user and pwd
(Q)uit

Enter choice: """

    done = False
    while not done:
        chosen = False
        while not chosen:
            try:
                choice = raw_input(prompt).strip()[0].lower()
            except (EOFError, KeyboardInterrupt):
                choice = 'q'
            print '\nYou picked: [%s]' % choice

            if choice not in 'gdq':
                print 'invalid menu option, try again'
            else:
                chosen = True

        if choice == 'q': done = 1
        if choice == 'd': deluser()
        if choice == 'g': Getuserpwd()


def showmenu():
    prompt = """
(N)ew User Login
(E)xisting User Login
(M)anagement
(Q)uit

Enter choice: """

    done = False
    while not done:
        chosen = False
        while not chosen:
            try:
                choice = raw_input(prompt).strip()[0].lower()
            except (EOFError, KeyboardInterrupt):
                choice = 'q'
            print '\nYou picked: [%s]' % choice

            if choice not in 'neqm':
                print 'invalid menu option, try again'
            else:
                chosen = True

        if choice == 'q': done = 1
        if choice == 'n': newuser()
        if choice == 'e': olduser()
        if choice == 'm': management()

if __name__ == '__main__':
    showmenu()

c)口令目前沒有加密. 請新增一段對口令加密的程式碼(請參考crypt,rotor,或其它加密模組)

#!/usr/bin/env python

from time import time,ctime #匯入模組
import base64#匯入加密模組
db = {}

def newuser():
    prompt = 'login desired: '
    while True:
        name = raw_input(prompt)
        if db.has_key(name):
            prompt = 'name taken, try another: '
            continue
        else:
            break
    p1 = raw_input('passwd: ')#明文密碼
    logt=time()
    p2 = base64.encodestring(p1)#密文密碼
    db[name]=[p2,logt]#儲存密文密碼

def olduser(): 
    name=raw_input('login: ') 
    p1=raw_input('passwd: ')
    if name in db:
        p2=base64.decodestring(db[name][0])#解密所存密文
        if p1 == p2 : #與使用者輸入密碼比對
            print 'welcome back',name 
            print 'You lasttime logged in at:',ctime(db[name][1])
            current=time()
            delta=current-db[name][1]
            if delta<=14400: #判斷是否在4小時內
                print 'You already logged in 4 hours period!'

            else:
                logt=time()#獲取當前時間 
                db[name][1]=logt #把密碼和時間組成列表存到字典,共享一個鍵
        else: 
            print 'login incorrect'  

    else: 
        print 'login incorrect'


def deluser():
    Getuserpwd()
    c=raw_input('del a user,its name:')
    if c in db.keys():
        del db[c]
        print 'After del:'
        Getuserpwd()
    else:
        print 'Wrong choose!'

def Getuserpwd():
    if db:    
        for name in db:
            print 'name:',name,'pwd:',db[name][0]
    else:
        print 'No user!'

def management():    
    prompt = """
(D)el a user
(G)et all user and pwd
(Q)uit

Enter choice: """

    done = False
    while not done:
        chosen = False
        while not chosen:
            try:
                choice = raw_input(prompt).strip()[0].lower()
            except (EOFError, KeyboardInterrupt):
                choice = 'q'
            print '\nYou picked: [%s]' % choice

            if choice not in 'gdq':
                print 'invalid menu option, try again'
            else:
                chosen = True

        if choice == 'q': done = 1
        if choice == 'd': deluser()
        if choice == 'g': Getuserpwd()


def showmenu():
    prompt = """
(N)ew User Login
(E)xisting User Login
(M)anagement
(Q)uit

Enter choice: """

    done = False
    while not done:
        chosen = False
        while not chosen:
            try:
                choice = raw_input(prompt).strip()[0].lower()
            except (EOFError, KeyboardInterrupt):
                choice = 'q'
            print '\nYou picked: [%s]' % choice

            if choice not in 'neqm':
                print 'invalid menu option, try again'
            else:
                chosen = True

        if choice == 'q': done = 1
        if choice == 'n': newuser()
        if choice == 'e': olduser()
        if choice == 'm': management()

if __name__ == '__main__':
    showmenu()

先貼一下前幾問的輸入輸出:

>>> 
#主選單
(N)ew User Login
(E)xisting User Login
(M)anagement
(Q)uit
#建立三個使用者
Enter choice: n

You picked: [n]
login desired: 1
passwd: 123

(N)ew User Login
(E)xisting User Login
(M)anagement
(Q)uit

Enter choice: n

You picked: [n]
login desired: a
passwd: xyz

(N)ew User Login
(E)xisting User Login
(M)anagement
(Q)uit

Enter choice: n

You picked: [n]
login desired: name999
passwd: 999name

(N)ew User Login
(E)xisting User Login
(M)anagement
(Q)uit
#老使用者輸出錯誤密碼的情況
Enter choice: e

You picked: [e]
login: 1
passwd: abc
login incorrect

(N)ew User Login
(E)xisting User Login
(M)anagement
(Q)uit
#錯誤選單選項的情況
Enter choice: 1

You picked: [1]
invalid menu option, try again

(N)ew User Login
(E)xisting User Login
(M)anagement
(Q)uit
#老使用者登入成功,顯示上次登入時間,若在四小時內,列印提示資訊
Enter choice: e

You picked: [e]
login: 1
passwd: 123
welcome back 1
You lasttime logged in at: Sat Apr 04 17:14:15 2015
You already logged in 4 hours period!

(N)ew User Login
(E)xisting User Login
(M)anagement
(Q)uit
#管理選單中的兩個子選單
Enter choice: m

You picked: [m]

(D)el a user
(G)et all user and pwd
(Q)uit

Enter choice: g
#獲得所有使用者和對應密碼,密碼是密文顯示
You picked: [g]
name: 1 pwd: MTIz

name: a pwd: eHl6

name: name999 pwd: OTk5bmFtZQ==


(D)el a user
(G)et all user and pwd
(Q)uit

Enter choice: d
#刪除一個使用者
You picked: [d]
name: 1 pwd: MTIz

name: a pwd: eHl6

name: name999 pwd: OTk5bmFtZQ==

del a user,its name:a
After del:
name: 1 pwd: MTIz

name: name999 pwd: OTk5bmFtZQ==


(D)el a user
(G)et all user and pwd
(Q)uit
#退出管理選單
Enter choice: q

You picked: [q]

(N)ew User Login
(E)xisting User Login
(M)anagement
(Q)uit
#退出總選單
Enter choice: q

You picked: [q]
>>> 

(d) 為程式新增圖形介面,例如,用Tkinter 寫。
正在收集資料,學習tkinter,以完成作業
(e) 要求使用者名稱不區分大小寫。
思路:選單選項的寫法給我啟發,設定將使用者名稱輸入轉換為小寫就好。

#!/usr/bin/env python

from time import time,ctime #匯入模組
import base64
db = {}

def newuser():
    prompt = 'login desired: '
    while True:
        name = raw_input(prompt).strip()[0].lower()#設定小寫
        if db.has_key(name):
            prompt = 'name taken, try another: '
            continue
        else:
            break
    p1 = raw_input('passwd: ')
    logt=time()
    p2 = base64.encodestring(p1)
    db[name]=[p2,logt]

def olduser(): 
    name=raw_input('login: ').strip()[0].lower()#設定小寫
    p1=raw_input('passwd: ')
    if name in db:
        p2=base64.decodestring(db[name][0])
        if p1 == p2 : 
            print 'welcome back',name 
            print 'You lasttime logged in at:',ctime(db[name][1])
            current=time()
            delta=current-db[name][1]
            if delta<=14400: #判斷是否在4小時內
                print 'You already logged in 4 hours period!'

            else:
                logt=time()#獲取當前時間 
                db[name][1]=logt #把密碼和時間組成列表存到字典,共享一個鍵
        else: 
            print 'login incorrect'  

    else: 
        print 'login incorrect'


def deluser():
    Getuserpwd()
    c=raw_input('del a user,its name:').strip()[0].lower()#設定小寫
    if c in db.keys():
        del db[c]
        print 'After del:'
        Getuserpwd()
    else:
        print 'Wrong choose!'

def Getuserpwd():
    if db:    
        for name in db:
            print 'name:',name,'pwd:',db[name][0]
    else:
        print 'No user!'

def management():    
    prompt = """
(D)el a user
(G)et all user and pwd
(Q)uit

Enter choice: """

    done = False
    while not done:
        chosen = False
        while not chosen:
            try:
                choice = raw_input(prompt).strip()[0].lower()
            except (EOFError, KeyboardInterrupt):
                choice = 'q'
            print '\nYou picked: [%s]' % choice

            if choice not in 'gdq':
                print 'invalid menu option, try again'
            else:
                chosen = True

        if choice == 'q': done = 1
        if choice == 'd': deluser()
        if choice == 'g': Getuserpwd()


def showmenu():
    prompt = """
(N)ew User Login
(E)xisting User Login
(M)anagement
(Q)uit

Enter choice: """

    done = False
    while not done:
        chosen = False
        while not chosen:
            try:
                choice = raw_input(prompt).strip()[0].lower()
            except (EOFError, KeyboardInterrupt):
                choice = 'q'
            print '\nYou picked: [%s]' % choice

            if choice not in 'neqm':
                print 'invalid menu option, try again'
            else:
                chosen = True

        if choice == 'q': done = 1
        if choice == 'n': newuser()
        if choice == 'e': olduser()
        if choice == 'm': management()

if __name__ == '__main__':
    showmenu()

(N)ew User Login
(E)xisting User Login
(M)anagement
(Q)uit

Enter choice: n

You picked: [n]
login desired: a
passwd: 1

(N)ew User Login
(E)xisting User Login
(M)anagement
(Q)uit

Enter choice: e

You picked: [e]
login: A
passwd: 1
welcome back a
You lasttime logged in at: Sat Apr 04 19:12:15 2015
You already logged in 4 hours period!

(f) 加強對使用者名稱的限制,不允許符號和空白符。
思路:除了符號和空白符。那就理解為使用者名稱應該由 數字和大小寫字母組成。

#!/usr/bin/env python

from time import time,ctime #匯入模組
import base64
import string #匯入string模組
db = {}
y=string.letters+string.digits#限定只能是數字和大小寫字母

def newuser():
    prompt = 'login desired,only accept digits and letters: '
    while True:
        name = raw_input(prompt).strip()[0].lower()
        if name in y:#驗證
            if db.has_key(name):
                prompt = 'name taken, try another: '
                continue
            else:
                break
        else:
            print 'Invalid name!'
    p1 = raw_input('passwd: ')
    logt=time()
    p2 = base64.encodestring(p1)
    db[name]=[p2,logt]

def olduser(): 
    name=raw_input('login: ').strip()[0].lower()
    p1=raw_input('passwd: ')
    if name in db:
        p2=base64.decodestring(db[name][0])
        if p1 == p2 : 
            print 'welcome back',name 
            print 'You lasttime logged in at:',ctime(db[name][1])
            current=time()
            delta=current-db[name][1]
            if delta<=14400: #判斷是否在4小時內
                print 'You already logged in 4 hours period!'

            else:
                logt=time()#獲取當前時間 
                db[name][1]=logt #把密碼和時間組成列表存到字典,共享一個鍵
        else: 
            print 'login incorrect'  

    else: 
        print 'login incorrect'


def deluser():
    Getuserpwd()
    c=raw_input('del a user,its name:').strip()[0].lower()
    if c in db.keys():
        del db[c]
        print 'After del:'
        Getuserpwd()
    else:
        print 'Wrong choose!'

def Getuserpwd():
    if db:    
        for name in db:
            print 'name:',name,',pwd:',db[name][0]
    else:
        print 'No user!'

def management():    
    prompt = """
(D)el a user
(G)et all user and pwd
(Q)uit

Enter choice: """

    done = False
    while not done:
        chosen = False
        while not chosen:
            try:
                choice = raw_input(prompt).strip()[0].lower()
            except (EOFError, KeyboardInterrupt):
                choice = 'q'
            print '\nYou picked: [%s]' % choice

            if choice not in 'gdq':
                print 'invalid menu option, try again'
            else:
                chosen = True

        if choice == 'q': done = 1
        if choice == 'd': deluser()
        if choice == 'g': Getuserpwd()


def showmenu():
    prompt = """
(N)ew User Login
(E)xisting User Login
(M)anagement
(Q)uit

Enter choice: """

    done = False
    while not done:
        chosen = False
        while not chosen:
            try:
                choice = raw_input(prompt).strip()[0].lower()
            except (EOFError, KeyboardInterrupt):
                choice = 'q'
            print '\nYou picked: [%s]' % choice

            if choice not in 'neqm':
                print 'invalid menu option, try again'
            else:
                chosen = True

        if choice == 'q': done = 1
        if choice == 'n': newuser()
        if choice == 'e': olduser()
        if choice == 'm': management()

if __name__ == '__main__':
    showmenu()

(N)ew User Login
(E)xisting User Login
(M)anagement
(Q)uit

Enter choice: n

You picked: [n]
login desired,only accept digits and letters: @1
Invalid name!
login desired,only accept digits and letters: a
passwd: 1

(g)合併“新使用者”和“老使用者”兩個選項。如果一個新使用者試圖用一個不存在的使用者名稱登入,詢問該使用者是否是新使用者,如果回答是肯定的,就建立該帳戶。否則,按照老使用者的方式登入。
思路:釋放了原來的兩個函式的直接呼叫
建立一個Userlog函式來一次呼叫就行了。新增一些判斷。

#!/usr/bin/env python

from time import time,ctime #匯入模組
import base64
import string 
db = {}
y=string.letters+string.digits

def newuser():
    prompt = 'login desired,name only accept digits and letters: '
    while True:
        name = raw_input(prompt).strip()[0].lower()
        if name in y:
            if db.has_key(name):
                prompt = 'name taken, try another: '
                continue
            else:
                break
        else:
            print 'Invalid name!'
    p1 = raw_input('passwd: ')
    logt=time()
    p2 = base64.encodestring(p1)
    db[name]=[p2,logt]

def olduser(): 
    name=raw_input('login: ').strip()[0].lower()
    p1=raw_input('passwd: ')
    if name in db:
        p2=base64.decodestring(db[name][0])
        if p1 == p2 : 
            print 'welcome back',name 
            print 'You lasttime logged in at:',ctime(db[name][1])
            current=time()
            delta=current-db[name][1]
            if delta<=14400: #判斷是否在4小時內
                print 'You already logged in 4 hours period!'                
            else:
                logt=time()#獲取當前時間 
                db[name][1]=logt #把密碼和時間組成列表存到字典,共享一個鍵
        else: 
            print 'login incorrect'  

    else:#當輸入的使用者名稱和密碼不是註冊過的,列印提升資訊:是否註冊?
        w=raw_input('register it(Y/N)?').strip()[0].lower()
        if 'y' == w:
            newuser()#若選擇註冊,呼叫新使用者註冊函式
        else:
            print 'login incorrect'

def userlog():#userlog函式首先預設呼叫老使用者登入函式
    olduser()


def deluser():
    Getuserpwd()
    c=raw_input('del a user,its name:').strip()[0].lower()
    if c in db.keys():
        del db[c]
        print 'After del:'
        Getuserpwd()
    else:
        print 'Wrong choose!'

def Getuserpwd():
    if db:    
        for name in db:
            print 'name:',name,',pwd:',db[name][0]
    else:
        print 'No user!'

def management():    
    prompt = """
(D)el a user
(G)et all user and pwd
(Q)uit

Enter choice: """

    done = False
    while not done:
        chosen = False
        while not chosen:
            try:
                choice = raw_input(prompt).strip()[0].lower()
            except (EOFError, KeyboardInterrupt):
                choice = 'q'
            print '\nYou picked: [%s]' % choice

            if choice not in 'gdq':
                print 'invalid menu option, try again'
            else:
                chosen = True

        if choice == 'q': done = 1
        if choice == 'd': deluser()
        if choice == 'g': Getuserpwd()


def showmenu():
    prompt = """
(U)ser Login
(M)anagement
(Q)uit

Enter choice: """

    done = False
    while not done:
        chosen = False
        while not chosen:
            try:
                choice = raw_input(prompt).strip()[0].lower()
            except (EOFError, KeyboardInterrupt):
                choice = 'q'
            print '\nYou picked: [%s]' % choice

            if choice not in 'uqm':
                print 'invalid menu option, try again'
            else:
                chosen = True

        if choice == 'q': done = 1
        if choice == 'u': userlog()
        if choice == 'm': management()

if __name__ == '__main__':
    showmenu()

(U)ser Login
(M)anagement
(Q)uit

Enter choice: u

You picked: [u]
login: 1
passwd: 1
register it(Y/N)?y
login desired,name only accept digits and letters: pythON
passwd: c++

(U)ser Login
(M)anagement
(Q)uit

Enter choice: u

You picked: [u]
login: PYthon
passwd: c++
welcome back p
You lasttime logged in at: Sat Apr 04 19:55:51 2015
You already logged in 4 hours period!