2014-12-19 68 views
1

我試圖寫一個代碼,要求輸入電子郵件和密碼(不是爲了任何特定用途),並檢查他們對包含多行的csv文件。每行包含一個電子郵件和密碼以及一些制定的客戶詳細信息。我正在嘗試編寫一個接受電子郵件地址和密碼(5至12個字符長)的代碼,然後在文件中搜索包含電子郵件和密碼的行,並打印整行(包括客戶詳細信息)。這是到目前爲止我的代碼(有些凹陷的看起來有點古怪這裏,但實際上只是縮進的代碼塊的結果):在python中檢索和檢查密碼與csv文件

import csv 
import re 
import sys 

f = open('A453_datafile_4_Mat 4 Data File.csv', 'r').read() 

print("Welcome to our website! To access your customer details, we first require you to sign in. ") 
print("") 
email = input ("Email address: ") 
if re.match("\A(?P<name>[\w\-_]+)@(?P<domain>[\w\-_]+).(?P<toplevel>[\w]+)\Z",email,re.IGNORECASE): 
print('') 
else: 
    email = input("Sorry, this isn't a valid email address! Try again: ") 
    if re.match("\A(?P<name>[\w\-_]+)@(?P<domain>[\w\-_]+).(?P<toplevel>[\w]+)\Z",email,re.IGNORECASE): 
     print('') 
    else: 
     print("You have entered your email incorrectly two times. The program will now terminate.") 
    sys.exit() #ends program 

password = input ("Password: ") 
if re.match("\A(?P<name>[\w\-_]+)\Z",password,re.IGNORECASE): 
    print('') 
else: 
    password = input("Sorry, this isn't a valid password! Try again: ") 
    if re.match("\A(?P<name>[\w\-_]+)\Z",password,re.IGNORECASE): 
     print('') 
    else: 
     print("You have entered your password incorrectly two times. The program will now terminate.") 
     sys.exit() #ends program 


details = [line for line in f.split('\n') if email in line] and [line for line in f.split('\n') if password in line] 

if details == []: 
    print("Sorry, your email or password is invalid.") 
else: 
    print("Thank you! Here are your customer details: ") 
    print("") 
    details = str(details).strip('[]') 
    print(details) 

我在這條線的問題,因爲「和」似乎並沒有工作,我會如何想:

details = [line for line in f.split('\n') if email in line] and [line for line in f.split('\n') 

如果我進入一個故意錯誤的密碼(如字母「X」),和它發生在另一條線路上存在的,它會打印該行,儘管它不包含電子郵件地址。

下面是這樣一個例子:

歡迎光臨我們的網站!要訪問您的客戶的詳細信息,我們首先需要您登錄

郵箱地址:[email protected]

密碼:X

謝謝!這裏是你的客戶的詳細信息:

'miguel5 @ bluebell.net,happy3,米格爾,桑托斯,45葡萄大道,牛津,O- X 7 3RF'

雖然它與正確的密碼:

歡迎來到我們的網站!要訪問您的客戶的詳細信息,我們首先需要您登錄

郵箱地址:[email protected]

密碼:ocrabc

謝謝!這裏是你的客戶的詳細信息:

'ojones @ coldmail.net,ocrabc,奧利弗·瓊斯,53家淡水河谷,朴茨茅斯,P03 2TD'

而這也正則表達式,因爲我不能工作如何密碼長度限制在5 - 12個字符(我是新的正則表達式並沒有被教導如何使用它):

if re.match("\A(?P<name>[\w\-_]+)\Z",password,re.IGNORECASE) 

我懷疑解決這個可能主要是解決前一個問題(除非有人知道該文件的內容),儘管有些幫助,如果可能的話,將不勝感激。

可能還有其他問題,我沒有拿起,但據我所知這就是它。

我知道這個問題很長,所以感謝您花時間閱讀它,任何答案都將不勝感激!

+3

呃 - 不要以純文本存儲密碼... –

+0

不介意我問,爲什麼沒有數據庫? – StefanNch

+0

@Jesse W at Z - 他們不是真正的密碼,所有的信息都是爲​​了這個程序的目的而編寫的。 – Kaedra

回答

0

你的代碼當前正在做什麼循環遍歷文件兩次:每個[line for line in f.split()]是一個單獨的循環。第一個循環獲取郵件匹配的行的列表,第二個獲取密碼匹配的行的列表。

然後你使用'和'運算符來組合這兩個列表。 Python允許你這樣做,如果兩個列表都不爲空,那麼結果將爲True,否則爲False。由於您試圖將操作結果與[]進行比較,所以比較總是失敗。

的你試圖做正確的版本是有一個單迴路,並檢查一次兩個條件,它是由Python列表理解允許你這樣做:

[line for line in f.split() if email in line and password in line] 

然而,由於這是一個子字符串檢查,當用戶正確輸入密碼的一部分時,這將匹配,這通常不是你在檢查密碼時想要的。相反,你應該檢查整個字符串:

line.startswith(email + "," + password + ",") 
+0

謝謝,這真的很有幫助。我不知道如何檢查整個字符串。 – Kaedra

1

很長的問題與簡單的答案。不要使用布爾操作'和'進行列表連接。使用+,它會產生正確的列表。什麼是'和' - 它將每個操作數轉換爲布爾值True/False,如果兩個列表都是非空的 - 返回最後一個。否則它返回[](從來不會發生在你的情況)。

+0

謝謝!我沒有用過,之前和我認爲在這種情況下可能比+更合適,顯然我應該在下次嘗試! – Kaedra

0

下面是一個簡單的FPGA實現搜索CSV文件包含特定字符串(S):

f = open('A453_datafile_4_Mat 4 Data File.csv', 'r').read() 
rows = re.split('\n', f.decode()) 

for index, row in enumerate(rows): 
    cells = row.split(',') 
    if ('USER_EMAIL_HERE' in cells) and ('USER_PASSWORD_HERE' in cells): 
     #Do stuff here 

我沒有測試過這一點,僅供參考。

0

這裏是一個清理的版本:

import csv 
from collections import namedtuple 
from itertools import repeat 
import re 
import sys 

EMAIL_REG = re.compile("^([\w\-_][email protected][\w\-_]+\.[\w]+)$", re.IGNORECASE) 
PASSWORD_REG = re.compile("^([\w\-_]{5,12})$", re.IGNORECASE) 
PASSWORD_CSV = 'A453_datafile_4_Mat 4 Data File.csv' 

# define a User type 
# (the field names should match the columns from the .csv file) 
User = namedtuple("User", ["email", "password", "firstname", "lastname", "address", "city", "postalcode"]) 
# prettier output 
User.__str__ = lambda self: "{} {}: {} ({} {}, {})".format(self.firstname, self.lastname, self.email, self.address, self.city, self.postalcode) 

def all_users_from_csv(fname, **kwargs): 
    """ 
    Return an iterable of Users from the specified csv file 
    """ 
    with open(fname) as in_file: 
     for row in csv.reader(in_file, **kwargs): 
      yield User(row) 

def match_user(users, email, password): 
    """ 
    Return the first user in users who matches the specified email and password; 
     on failure, return None 
    """ 
    for user in users: 
     if user.email == email and user.password == password: 
      return user 
    return None 

def input_match(prompt, reg, max_tries=None): 
    """ 
    Prompt for input that matches reg; 
     on success, return first match group 
     on failure, try again (up to max_tries times, if specified) 
     on max_tries failures, return None 
    """ 
    if max_tries is None: 
     # not specified - repeat forever 
     tries = repeat(None) 
    else: 
     # repeat specified number of times 
     tries = range(max_tries) 

    for i in tries: 
     s = input(prompt) 
     m = reg.match(s) 
     if m: 
      return m.groups(0) 

    # if max_tries exceeded 
    return None 

def do_signin(): 
    email = input_match("Email address: ", EMAIL_REG, 2) 
    if email is None: 
     print("You did not enter a valid email address. Good-bye!") 
     return None 

    password = input_match("Password: ", PASSWORD_REG, 2) 
    if email is None: 
     print("You did not enter a valid password. Good-bye!") 
     return None 

    users = all_users_from_csv(PASSWORD_CSV) 
    return match_user(users, email, password) 

def main(): 
    print("Welcome to our website! To access your customer details, we first require you to sign in.\n") 

    user = do_signin() 
    if user is None: 
     print("Sorry, your email or password is invalid.") 
    else: 
     print("Thank you! Here are your customer details:\n") 
     print(user) 

if __name__=="__main__": 
    main() 

及其相關評論:

  1. 需要注意的是,每次你想給用戶相匹配,它有比較(最多)每行.csv文件中;這是緩慢而浪費的。幾乎任何數據庫都可以讓您在電子郵件和密碼字段中編制索引,從而提高效率。

  2. 我將代碼分成單獨的函數;每個功能都很簡單,只有一個特定的目的。命名常量,良好的函數名稱,文檔字符串和註釋 - 它們都會讓您的程序更容易理解,測試和稍後修改。