Python星座問題

Python星座問題

問題描述
二千多年前希臘的天文學家希巴克斯命名十二星座,它們是水瓶座、雙魚座、白羊座、金牛座、雙子座、巨蟹座、獅子座、處女座、天秤座、天蠍座、射手座、摩羯座。給出一個CSV文件
PY301-SunSign.csv),內容示例如下: ‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬

序號,星座,開始月日,結束月日,Unicode
1,水瓶座,120,218,9810
2,雙魚座,219,320,9811
3,白羊座,321,419,9800
4,金牛座,420,520,9801
5,雙子座,521,621,9802 …(略)
以第1行爲例,120表示1月20日,218表示2月18日,9810是Unicode碼。

問題1: 在P301-1.py文件中修改代碼,讀入CSV文件中數據,獲得用戶輸入。根據用戶輸入的星座名稱,輸出此星座的出生日期範圍。‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬

參考輸入和輸出示例格式如下:‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬

請輸入星座中文名稱(例如, 雙子座): 雙子座‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬

雙子座的生日位於521-621之間‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬

第一問比較簡單,只是把數據取出,定位到特定數據,並格式化輸出即可。
f = open('PY301-SunSign.csv')
ls = []
for line in f:
    ls.append(line.strip('\n').split(','))
star = input('請輸入星座中文名稱(例如, 雙子座):')
while star:
    for l in ls:
        if star == l[1]:
            print('{}的生日位於{}-{}之間'.format(star,l[2],l[3]))
            break
    star = input('請輸入星座中文名稱(例如, 雙子座):')            
f.close()

問題2: 在P301-2.py文件中修改代碼,讀入CSV文件中數據,獲得用戶輸入。用戶鍵盤輸入一組範圍是1-12的整數作爲序號,序號間採用空格分隔,以回車結束。屏幕輸出這些序號對應的星座的名稱、字符編碼以及出生日期範圍,每個星座的信息一行。本次屏幕顯示完成後,重新回到輸入序號的狀態。‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬

參考輸入和輸出示例格式如下:‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬

請輸入星座序號(例如,5 10): 5 10‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬

雙子座(9802)的生日是5月21日至6月21日之間‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬

天蠍座(9807)的生日是10月24日至11月22日之間‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬

請輸入星座序號(例如,5):‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬

問題2相對要難一些,需要用到2層循環,另外對於月份,日期的切片是主要難點。月份長度是變長的,日期長度是定長2,需要仔細思考,體會。
f = open('PY301-SunSign.csv')
ls = []
for line in f:
    ls.append(line.strip('\n').split(','))
idxs = input('請輸入星座序號(例如,5 10):')
while idxs:
    idx = idxs.split()
    for i in idx:
        for l in ls:
            if i == l[0]:
                start_m = l[2][:-2]
                start_d = l[2][-2:]
                end_m = l[3][:-2]
                end_d = l[3][-2:]
                print('{}({})的生日是{}月{}日至{}月{}日之間'.\
                      format(l[1],l[4],start_m,start_d,end_m,end_d))
    idxs = input('請輸入星座序號(例如,5 10):')            
f.close()


問題3: 在問題2的基礎上,在P301-3.py文件中修改代碼,對鍵盤輸入的每個序號做合法性處理。如果輸入的數字不不合法,請輸出"輸入星座編號有誤!",繼續輸出後續信息,然後重新回到輸入序號的狀態。‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬

參考輸入和輸出示例格式如下:‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬

請輸入星座序號(例如,5 10): 5 14 11‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬

雙子座(9802)的生日是5月21日至6月21日之間‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬

輸入星座序號有誤!‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬

射手座(9808)的生日是11月23日至12月21日之間‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬

請輸入星座序號(例如,5 10):

問題3,難度更大一些,本例用到了for…else,沒有用flag,比答案更自然一些,具體實現細節和思路看下面的註釋。
#for ... else
#這裏涉及2層循環,遍歷星座表和遍歷星座序號,誰做外層循環?
#本題處理的業務流程是:從用戶讀入星座序號,依次檢索星座信息
#如果匹配則取出相關信息,轉換格式並打印
#如果不匹配,則輸出錯誤,並繼續檢索下一條索引
#所以,遍歷星座序號需要做外層循環,而遍歷星座表當做一次動作的子過程
#本例沒有直接檢查輸入的序號是否在1-12之間,而是遍歷完畢如果沒找到則進入for...else
#所以在for中,打印完匹配性,會break退出循環
#一則提高效率,如果某個索引已找到,則沒必要繼續找後面的,二者滿足進入else需要



f = open('PY301-SunSign.csv')
ls = []
for line in f:
    ls.append(line.strip('\n').split(','))
idxs = input('請輸入星座序號(例如,5 10):')
while idxs:
    idx = idxs.split()
    for i in idx:
        for l in ls:
            if i  == l[0]:
                start_m = l[2][:-2]
                start_d = l[2][-2:]
                end_m = l[3][:-2]
                end_d = l[3][-2:]
                print('{}({})的生日是{}月{}日至{}月{}日之間'.\
                      format(l[1],l[4],start_m,start_d,end_m,end_d))
                break
        else:
            print('輸入星座序號有誤!')
    idxs = input('請輸入星座序號(例如,5 10):')            
f.close()


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章