比较函数中CSV文件中的字符串

时间:2019-05-08 09:08:38

标签: python python-3.x csv

我遇到一个问题,我有一个函数,该函数接受一个I​​D,然后检查ID中的格式是否无效。

规则是:

1)ID的长度必须为5

2)ID必须以字母开头,具体取决于部落名称

3)ID必须以有效字母结尾,具体取决于平均功率

4)在两个字母之间包含三个整数

ID格式: TNNNL 其中: T-部落名称 N-个数字 L-对应化身平均功率的字母

average power description

csv file:

name,tribe,id,Air,Water,Earth,Fire,Rule to test
Pema,Xero,X14C,24,54,34,43,Length of Avatar ID is not 5
Otaku,Taru,T111F,54,78,65,78,Invalid last letter
Aang,Nomad,NA21B,89,67,54,78,Invalid ID format
Zuko,Giant,A111C,48,54,98,75,Invalid first letter

我的代码:

import csv

def isValidAvatarIDFormat(ava_id):
    filePath = "data1.csv"
    with open(filePath) as csvfile:
        reader = csv.DictReader(csvfile)
        for row in reader:
            tribe = row['tribe']
            air_power = row['Air']
            water_power = row['Water']
            earth_power = row['Earth']
            fire_power = row ['Fire']
            #check id length
            if(len(ava_id) != 5):
                return("Length of ID is not 5")
            #check first letter
            elif(ava_id[0] != tribe[0]):
                return("Invalid first letter")
            #check last letter
            elif(ava_id[4] != findAveragePower(air_power, water_power, earth_power, fire_power)):
                return("Invalid last letter")
            #check 3 digits in the middle
            elif bool(ava_id[1].isdigit() and ava_id[2].isdigit() and ava_id[3].isdigit()) == False:
                 return("Invalid ID format")

def findAveragePower(air_power, water_power, earth_power, fire_power):
        air_power = row['Air']
        water_power = row['Water']
        earth_power = row['Earth']
        fire_power = row ['Fire']
        average = int(int(air_power) + int(water_power) + int(earth_power) + int(fire_power)) / 4
        if(average >= 80):
            return "A"
        if(average >= 70 and average < 80):
            return "B"
        if(average >= 60 and average < 70):
            return "C"
        if(average >= 50 and average < 60):
            return "D"
        if(average >= 40 and average < 50):
            return "E"
        if(average <40):
            return "F"

#Main Program:
filePath = "data1.csv"
with open(filePath) as csvfile:
    reader = csv.DictReader(csvfile)
    print("{0:<5} | {1:^5} | {2:^5}".format("Avatar Name", "Avatar ID", "Comments"))
    for row in reader:
        string = isValidAvatarIDFormat(row['id'])
        print("{0:<11} | {1:<9} | {2:<15}".format(row['name'],row['id'], string))

预期输出: 我曾期望输出与CSV文件中“测试规则”列下的输出相同。但是输出结果比我预期的要大得多。

实际输出:

actual output

2 个答案:

答案 0 :(得分:1)

每次调用isValidAvatarIDFormat时,您都要重新开始将ID与csv文件中的第一行进行比较。

说,Main中的第二次迭代,其中ID = T111F,在执行string = isValidAvatarIDFormat(row['id'])时,您开始将T111F的第一个字母与Xero进行比较,这肯定会给您一个错误。

为了使其正常工作,我建议使用整行(而不只是ID和重新打开文件)作为isValidAvatarIDFormat的输入,因为这是您需要的所有信息。

def isValidAvatarIDFormat(row):
    ava_id = row['id']
    tribe = row['tribe']
    air_power = row['Air']
    water_power = row['Water']
    earth_power = row['Earth']
    fire_power = row ['Fire']
    #check id length
    if(len(ava_id) != 5):
        return("Length of ID is not 5")
    #check first letter
    elif(ava_id[0] != tribe[0]):
        return("Invalid first letter")
    #check last letter
    elif(ava_id[4] != findAveragePower(air_power, water_power, earth_power, fire_power)):
        return("Invalid last letter")
    #check 3 digits in the middle
    elif not bool(ava_id[1].isdigit() and ava_id[2].isdigit() and ava_id[3].isdigit()):
         return("Invalid ID format")

更新

如果无法更改输入,这是另一种方法:

# part of isValidAvatarIDFormat
for row in reader:
    if row['id'] != ava_id:
        continue
    else:
        all_your_other_operations
        break

答案 1 :(得分:0)

我删除了:

tribe = row['tribe']
在isValidAvatarIDFormat()中使用

,是因为我意识到每次我输入函数时,它都会再次调用第一个部落,因此,它将始终以“无效的第一个字母”形式返回输出。由于存储在“部落”中的每个值都将始终为“ Xero”,并将始终与文件中的每个ID进行比较。