2014-03-24 113 views
0

我是Python新手,已經做了一個調查問卷程序。有什麼方法讓程序一次顯示一個問題及其選擇(除非前一個問題得到解答,否則下一個選擇題不會顯示)?讀一個文本文件,每次有一行n個行

我用切片來完成這個,但我想知道我在做什麼不是很好的做法或有更好的替代方法?

#opens the file with questions, and is told to read only via 'r' 
with open("PythonQ.txt", "r") as f: 
#reads the file line by line with 'readlines' 
    variable = f.readlines() 
#issue was with no slicing, it was reading letter by letter. so 
#without the slicing and the split, the questions would not print per question 
#the goal by slicing is to get readlines to read per question, not the entire file or first 5 words  
    for line in variable[0:6]: 
#this strips the brackets and splits it by commas only, otherwise it will print both  
     question = line.split(',') 
#joins elements of the list which are separated by a comma 
     print(", ".join(question)) 

choice1 = eval(input("\nYour choice?: ")) 

#sliced for second question. Begins at five to provide room in program between first and second question. 
for line in variable[6:12]: 
     question = line.split(',') 
     print(", ".join(question)) 

choice2 = eval(input("\nYour choice?: ")) 


for line in variable[12:18]: 
     question = line.split(',') 
     print(", ".join(question)) 

choice3 = eval(input("\nYour choice?: ")) 


for line in variable[18:24]: 
     question = line.split(',') 
     print(", ".join(question)) 

choice4 = eval(input("\nYour choice?: ")) 


for line in variable[24:30]: 
     question = line.split(',') 
     print(", ".join(question)) 

choice5 = eval(input("\nYour choice?: ")) 


for line in variable[30:36]: 
     question = line.split(',') 
     print(", ".join(question)) 

choice6 = eval(input("\nYour choice?: ")) 


for line in variable[36:42]: 
     question = line.split(',') 
     print(", ".join(question)) 

choice7 = eval(input("\nYour choice?: ")) 


for line in variable[42:48]: 
     question = line.split(',') 
     print(", ".join(question)) 

choice8 = eval(input("\nYour choice?: ")) 


for line in variable[48:54]: 
     question = line.split(',') 
     print(", ".join(question)) 

choice9 = eval(input("\nYour choice?: ")) 


for line in variable[54:60]: 
     question = line.split(',') 
     print(", ".join(question)) 

choice10 = eval(input("\nYour choice?: ")) 

#add up all the numbers the user typed and assigned it variable x 
x = choice1 + choice2 + choice3 + choice4 + choice5 + choice6 + choice7 + choice8 + choice9 + choice10 

#there are only so high a person's score can go, depending upon if user chose mostly 1's, 2's, 3's or 4's in quiz. 
if x <= 13: 
    print("\n\n\nYour personality and work environment type is...\n \n\n\nRealistic: The 'Doer'\n") 
#another file was created for the results. Import file. Then call the function, CategoryA. 
    import Results 
    Results.CategoryA() 
elif x <= 22: 
    print("\n\n\nYour personality and work environment type is...\n \n\n\nSocial: The Helper\n") 
    import Results 
    Results.CategoryB() 
elif x <= 31: 
    print("\n\n\nYour personality and work environment type is...\n \n\n\nEnterprising: The Persuader\n") 
    import Results 
    Results.CategoryC() 
elif x <= 40: 
    print("\n\n\nYour personality and work environment type is...\n \n\n\nConventional: The Organizer\n") 
    import Results 
    Results.CategorD() 
+2

你能舉一個你正在閱讀的文件(PythonQ.txt)的例子嗎? –

+0

看起來像OP讀取整個文件,其中包括一個六行的多項選擇題的測驗索引1).. 4):'variable = f.readlines()' – smci

+0

做什麼是'question = line .split(',')'後面跟着'print(「,」.join(問題))'?似乎沒有必要。 – smci

回答

0

下面是使用生成器在一個更加Python化的語言中完全重寫你的代碼。

你的問題是你讀了一個完整的文件,其中包含六行選擇題+答案索引1)4):variable = f.readlines()variable是一個比quiz_contents更糟糕的選擇,但是無論如何。

而你想單獨訪問每個6行的多項選擇題和答案。 由於您使用的是readlines(),要訪問每個塊,您必須在''上進行奇怪的分割,然後加上','(似乎不必要?),然後顯示它。所以不要使用variable = f.readlines()!在你的整個文件中,你可以將它整合成一個沒有任何分裂的巨型多行字符串 - 而不是一系列單獨的行(在換行符上分割),這就是連續6次調用readline()所得到的結果。你可以在換行上輸入split('\n'),但最好是避免使用readlines()。改爲使用readline(),每個問題6次。

因此,這裏是在下面的代碼重寫使用Python的方法:

  • 剛讀每6行塊,你需要它。無需使用文件內容
  • 請注意使用print (line, end='') # don't add extra newline
  • 我們需要某種get_chunk()來返回每個6行塊。在這種情況下,發電機比功能更優雅。它還允許我們檢測EOF並返回無。
  • 這使得調用代碼waaay更優雅,因爲我們現在只是說for chunk in get_chunk(quiz_contents)。當它從發生器中得到None時,該for循環將終止
  • 小注:get_chunk()實際上必須爲每個塊讀取6 + 4行 - 每個塊中有4個額外的空行。你可以平凡地刪除這些並添加打印(...)。
  • 在生成器中,我們使用列表理解chunk = [buf.readline() for _ in range(n)]而不是for循環。但是你可以使用for循環。 _是暴殄天物可變習慣Python的名稱(例如,在這種情況下,我們只需要數到6,我們從來沒有檢查for循環計數器否則)

__

quiz_file = './PythonQ.txt' 
num_questions = 10 

def get_chunk(buf, n): 
    """Read n-line chunks from filehandle. Returns sequence of n lines, or None at EOF.""" 

    while buf: 
     chunk = [buf.readline() for _ in range(n)] 

     if not any(chunk): # detect termination at end-of-file (list of ['', '',...]) 
      chunk = None 

     yield chunk 

    # Notes: 
    # This is a generator not a function: we must use 'yield' instead of 'return' to be able to return a sequence of lines, not just one single line 
    # _ is customary Python name for throwaway variable 


with open(quiz_file) as quiz_contents: # Note: quiz_contents is now just a filehandle, not a huge buffer. Much nicer. 

    choices = [None] * num_questions 

    i = 0 

    for chunk in get_chunk(quiz_contents, 6+4): # need to read 6 lines + 4 blank lines 

     if not chunk: 
      break  
     # Don't even need to explicitly test for end-condition 'if i >= num_questions: break' as we just make our generator yield None when we run out of questions 

     print() 
     for line in chunk: 
      print (line, end='') # don't add extra newline 

     choices[i] = int(input("\nYour choice (1-4)?: ")) # expecting number 1..4. Strictly you should check, and loop on bad input 
     i += 1 

     # Don't even need to test for end-condition as we'll just run out of questions 

    score = sum(choices) 
    print('Your score was', score) 

    # do case-specific stuff with score... could write a function process_score(score) 
0

對不起,我不能對你的問題沒有幫助,但我想。 我仍然想問:你有9個相同的代碼,所以我可以提供我的?

您的代碼重複:

for line in variable[6:12]: 
     question = line.split(',') 
     print(", ".join(question)) 

choice2 = eval(input("\nYour choice?: ")) 

9倍意味着循環: 如果我們重命名 「選擇1」 到 「X」

for i in range(1,10) 
    for line in variable[6*i:6*(i+1)]: 
     question = line.split(',') 
     print(", ".join(question)) 

x+=eval(input("\nYour choice?: ")) 

我接受所有的批評。

相關問題