งูหลามเพชฌฆาตแก้

Oct 08 2020

ฉันเขียนโปรแกรมที่อ่านไฟล์ csv ที่มี 100 แถวที่ดูเหมือน:

1;S****L;SCHOOL
2;*A*G*A*;HANGMAN

จากนั้นลองเดาตัวอักษรเหมือนในเกมเพชฌฆาต ขอบเขตของฉันคือการนับตัวอักษรที่ถูกและผิดทุกตัวอักษรแล้วสรุปออกมา รหัสใช้งานได้ดีฉันพยายามเดาตัวอักษรถูก + ผิดประมาณ 1670 ตัว แนวทางของฉันคือสร้างพจนานุกรมที่ฉันเก็บตัวอักษรทั้งหมดจากตัวอักษรและอ่านทุกคำจากไฟล์จากนั้นรวมลักษณะของตัวอักษรทุกตัวและเก็บไว้ในพจนานุกรม บางอย่างเช่น

{
   "A" : 30,
   "B" : 40
}

จากนั้นฉันจัดเรียงคำสั่งตามทุกตัวอักษรและก่อนอื่นให้ลองเดาตัวอักษรด้วยความเข้าใจมากที่สุด

คำถามของฉัน. มีอะไรบ้างที่ฉันสามารถปรับปรุงเพื่อให้ได้จำนวนครั้งน้อยลง?

import csv

INPUT_FILE = "words.csv"


def oppenFile():        # function to read the file
    with open(INPUT_FILE, "r", encoding="utf-8") as words:
        reader = list(csv.reader(words, delimiter=";"))
        return reader


def letterCount():      # function that count every the letter in the file and return a dict: {A : 2}
    letters = dict.fromkeys("QWERTYUIOPĂÎASDFGHJKLȘȚÂZXCVBNM", 0)
    words = oppenFile()
    for w in range(len(words)):
        for l in list(words[w][2]):
            if l not in list(words[w][1]):
                letters[l] += 1
    return letters


def checkLetters(word, wholeWord, letters):     # function that solve a word return the number of right + wrong attempts
    attempts = 0
    for letter, key in letters.items():
        if letter in wholeWord and letter not in word:
            attempts += 1
            index = [i for i, lit in enumerate(wholeWord) if lit == letter]
            letters[letter] -= len(index)
            for j in range(len(index)):
                word = word[:index[j]] + letter + word[(index[j] + 1):]

        elif '*' not in word:
            break
        else:
            attempts += 1
    return attempts


def hangman():
    words = oppenFile()
    numberOfAttempts = 0
    letters = letterCount()

    for i in range(len(words)):
        letters = dict(sorted(letters.items(), key=lambda x: x[1], reverse=True)) # sort the dict

        numberOfAttempts += checkLetters(words[i][1], words[i][2], letters)

    print(f"{numberOfAttempts} right + wrong attempts")


if __name__ == "__main__":
    hangman()

คำตอบ

5 hjpotter92 Oct 08 2020 at 04:07

ยินดีต้อนรับสู่ Code Review!

PEP-8

ใน python เป็นเรื่องปกติ (และแนะนำ) ให้ปฏิบัติตามคำแนะนำสไตล์ PEP-8 สำหรับการเขียนโค้ดที่สะอาดบำรุงรักษาได้และสม่ำเสมอ

ฟังก์ชั่นและตัวแปรควรตั้งชื่อในlower_snake_caseชั้นเรียนเป็นและคงเป็นUpperCamelCaseUPPER_SNAKE_CASE

พิมพ์คำใบ้

ด้วยเวอร์ชัน python ที่ใหม่กว่าคุณสามารถใช้คำใบ้ประเภทเพื่อให้ภาพรวมคร่าวๆเกี่ยวกับประเภทของตัวแปรและพารามิเตอร์ฟังก์ชัน

การนับตัวอักษร

Python มี inbuilt collections.Counterเพื่อให้คุณใช้ประโยชน์จากไฟล์.

ความคิดเห็น

ความคิดเห็นไม่ได้ช่วยตรงนี้จริงๆ นอกจากนี้ชอบเขียน docstring มากกว่าความคิดเห็นสำหรับฟังก์ชัน

ชื่อตัวแปร

คุณเปิดไฟล์และตั้งชื่อตัวชี้เป็นwordsในขณะที่ฟังก์ชันกำลังส่งคืนรายการคำ เรียกว่าreaderซึ่งจะถูกเก็บไว้ในตัวแปรที่เรียกว่าwords?

การแปลงแปลก ๆ

คุณสร้างการจับคู่ตัวอักษรเป็นจำนวนตามลำดับเป็นพจนานุกรม (hash-map / table / lookup) จากนั้นแปลงเป็นรายการทูเปิลที่มีมูลค่า 2 ค่าเรียงลำดับและแปลงกลับเป็นพจนานุกรม ทำไม? dictมี\$ O(1) \$ การค้นหาและการจัดเรียงไม่มีเหตุผลในกรณีของคุณ

การทำซ้ำด้วยดัชนี

คุณใช้โครงสร้างลูปต่อไปนี้:

for i in range(len(words)):

โดยที่iตัวเองไม่ได้ให้บริการตามวัตถุประสงค์ การเกิดขึ้นของการใช้งานของทุกคนจะอยู่ในรูปi words[i]คุณสามารถทำซ้ำค่าของwordsรายการเอง:

for word in words: