简体   繁体   English

如何改善此混乱的功能或其重复性?

[英]How can I improve this messy function or its reiteration?

Very long and annoying question, ill try to do my best to explain it. 很长很烦人的问题,请尽我所能解释。

I have a file containing data such as 我有一个包含数据的文件,例如

Sarah;Brown;s.brown@gmail.com;0715123451;1;24;0;0
Joe;Blogg;j.bloggs@gmail.com;0749814574;1;60;0;0
Andrew;Smith;a.smith@gmail.com;0718451658;1;45;0;0
Ray;Charles;r.charles@gmail.com;0715451589;1;40;0;0
Kevin;White;k.white@gmail.com;0749858748;1;20;0;0
Samantha;Collins;s.collins@gmail.com;0715243568;1;10;0;0
Frank;Jones;f.jones@gmail.com;0719487516;2;10;0;0
Liam;Blair;l.blair@gmail.com;0729857614;2;4;0;0
Pat;Phillips;p.phillips@gmail.com;071574216;2;17;0;0
John;Brown;j.brown@gmail.com;0798452648;2;11;0;0
Peter;Bond;p.bond@gmail.com;0798415758;6;4;0;0
Edward;Costello;e.costello@gmail.com;0712474588;2;45;0;0
Iain;Wilkins;i.wilkins@gmail.com;0715497211;2;23;0;0
Time;Pratchett;t.pratchett@gmail.com;0784975135;3;48;0;0
Eleanor;House;e.house@gmail.com;0799871542;3;9;0;0
Gergory;Davies;g.davies@gmail.com;0719475847;3;22;0;0
Tina;Turner;t.turner@gmail.com;0749857123;3;17;0;0
Sally;Stevens;s.stevens@gmail.com;077154198;3;30;0;0
John;Lennon;j.lennon@gmail.com;0704910874;3;29;0;0

The first element is the name, second is surname, third is email address, 4rth is phone number, 5th is division number, 6th is points scored, the remaining two don't matter for this issue. 第一个元素是姓名,第二个是姓氏,第三个是电子邮件地址,第4个是电话号码,第5个是部门编号,第6个是得分,其余两个与这个问题无关。

What I have been asked to do is to check the top two scorers (6ths element) and the bottom two scorers in a division (5th element). 我被要求做的是检查一个部门中排名靠前的两个得分手(第6个元素)和一个部门中排名靠后的两个得分手(第5个元素)。 When they have been identified, the top two should be promoted (go up a division), the bottom 2 should be demoted (go down a division). 确定它们之后,应该提升前两个(降级),将下面的两个降级(降级)。 I have written this piece of crap: 我写了这段废话:

def rollDivision2():

    lst = [line.strip().split(';') for line in open('players.txt','r').readlines()] # creates nested list
    totalPoints = []

    for i in range(len(lst)):
        if lst[i][4] == "2": # checking divisions this is why i need 6 different function
            totalPoints.append(int(lst[i][5])) # creates lists from all scores for the division chosen

#----------------------------------------------- figuring out best two scores and writing
    maxPoints = max(totalPoints)    
    for person in lst:
        if person[4] == "2" and person[5] == str(maxPoints): #this is why i need 6 different function
            biggest = person # creating variable with name of person that has the biggest score
            biggestStr = biggest[0] + ";" + biggest[1] + ";" + biggest[2] + ";" + biggest[3] + ";" + biggest[4] + ";" + biggest[5] + ";"  + biggest[6] + ";" + biggest[7] + "\n" #puts that lists into a string
            break #personWithMostPoints is the whole line of player with most points

    secondMaxPoints = secondLargest(totalPoints) #this is why i need 6 different function
    for person in lst:
        if person[4] == "2" and person[5] == str(secondMaxPoints): #checking for most points in the division
            secondBiggest = person
            secondBiggestStr = secondBiggest[0] + ";" + secondBiggest[1] + ";" + secondBiggest[2] + ";" + secondBiggest[3] + ";" + secondBiggest[4] + ";" + secondBiggest[5] + ";"  + secondBiggest[6] + ";" + secondBiggest[7] + "\n"
            break 

    lineToWriteBiggest = biggest[0] + ";" + biggest[1] + ";" + biggest[2] + ";" + biggest[3] + ";" + "1" + ";" + biggest[5] + ";"  + biggest[6] + ";" + biggest[7] + "\n"
    lineToWriteSecondBiggest = secondBiggest[0] + ";" + secondBiggest[1] + ";" + secondBiggest[2] + ";" + secondBiggest[3] + ";" + "1" + ";" + secondBiggest[5] + ";"  + secondBiggest[6] + ";" + secondBiggest[7] + "\n"
#----------------------------------------------- figuring out best two scores

#----------------------------------------------- figuring out worst two scores
    minPoints = min(totalPoints)    
    for person in lst:
        if person[4] == "2" and person[5] == str(minPoints): #this is why i need 6 different function
            least = person
            leastStr = least[0] + ";" + least[1] + ";" + least[2] + ";" + least[3] + ";" + least[4] + ";" + least[5] + ";"  + least[6] + ";" + least[7] + "\n"
            break #personWithMostPoints is the whole line of player with most points


    secondLeastPoints = secondSmallest(totalPoints) #method defined in utility functions   
    for person in lst:
        if person[4] == "2" and person[5] == str(secondLeastPoints): #this is why i need 6 different function
            secondLeast = person 
            secondLeastStr = secondLeast[0] + ";" + secondLeast[1] + ";" + secondLeast[2] + ";" + secondLeast[3] + ";" + secondLeast[4] + ";" + secondLeast[5] + ";"  + secondLeast[6] + ";" + secondLeast[7] + "\n"
            break 

    lineToWriteLeast = least[0] + ";" + least[1] + ";" + least[2] + ";" + least[3] + ";" + "3" + ";" + least[5] + ";"  + least[6] + ";" + least[7] + "\n"
    lineToWriteSecondLeast = secondLeast[0] + ";" + secondLeast[1] + ";" + secondLeast[2] + ";" + secondLeast[3] + ";" + "3" + ";" + secondLeast[5] + ";"  + secondLeast[6] + ";" + secondLeast[7] + "\n"




    f = open("players.txt","a")
    f.write(lineToWriteBiggest)
    f.write(lineToWriteSecondBiggest)
    f.write(lineToWriteLeast)
    f.write(lineToWriteSecondLeast)
    f.close()

    f = open("players.txt",'r') # Input file
    t = open("temp.txt", 'w') #Temp output file

    for line in f:
        if line != biggestStr and line != secondBiggestStr and line != leastStr and line != secondLeastStr and line != "\n":
            t.write(line) #writes all lines apart from the original line (one that needs to be deleted)

    f.close()
    t.close()
    os.remove("players.txt") #deletes players
    os.rename('temp.txt', 'players.txt') #new file with modified info is renamed to players

It is very ugly and impractical, moreover, I have to have 6 of these functions (as there are 6 divisions) which makes the program ridiculously overweight. 这是非常丑陋且不切实际的,而且,我必须拥有这些功能中的6个(因为有6个分区),这使程序非常可笑。 If anyone could help me, whether it be how I could use this function just once to check all 6 division instead of having to write 6 individual ones. 如果有人可以帮助我,我是否可以仅使用一次此功能来检查所有6个分区,而不必编写6个单独的分区。

I'm sorry you had to see this, I just don't know what else to do at this point. 很抱歉,您必须看到这一点,但我不知道此时该怎么办。 Any help would be very appreciated. 任何帮助将不胜感激。 Many thanks 非常感谢

lines = list(open("some.txt"))
for division,items in itertools.groupby(lines,lambda line:int(line.split(";")[4])):
    sorted_people = sorted(items,key=lambda item:int(item.split(";")[-1])
    print "DIVISION:",division
    print "TOP TWO:",sorted_people[-2:]
    print "BOTTOM TWO:",sorted_people[:2]

Check this out - 看一下这个 -

def convert(arr):
    return [int(x) if x.isnumeric() else x for x in arr]


def find_top_two(division):
    cur_div = [x for x in arr if x[4] == division]
    cur_div.sort(key = lambda T : T[5], reverse = True)
    return cur_div[:2]


def find_bottom_two(division):
    cur_div = [x for x in arr if x[4] == division]
    cur_div.sort(key = lambda T : T[5])
    return cur_div[:2]

with open('players.txt', 'r') as f:
    arr = f.readlines()

arr = [convert(s.strip('\n').split(';')) for s in arr]

print('Top 2 of division 2 :\n', find_top_two(2))

print('Bottom 2 of division 2 :\n', find_bottom_two(2))

Output - 输出-

Top 2 of division 2 :
 [['Edward', 'Costello', 'e.costello@gmail.com', 712474588, 2, 45, 0, 0], ['Iain', 'Wilkins', 'i.wilkins@gmail.com', 715497211, 2, 23, 0, 0]]
Bottom 2 of division 2 :
 [['Liam', 'Blair', 'l.blair@gmail.com', 729857614, 2, 4, 0, 0], ['Frank', 'Jones', 'f.jones@gmail.com', 719487516, 2, 10, 0, 0]]

Not the best and most efficient code, but this should work. 不是最好和最有效的代码,但这应该可以工作。 I'll leave you to fill in the blanks. 我让你填补空白。

def getPlayersOfDivision(playerInfo, division):
    result = []
    for player in playerInfo:
        if int(player[4]) == division:
            result.append(player)

def findPlayer(playerInfo, firstName, lastName):
    for i,player in enuemrate(playerInfo):
        if player[0] == firstName and player[1] = lastName:
            return i

def get2BestPlayers(playerInfo):
    pass

def get2WorstPlayers(playerInfo):
    pass

def changePlayerDivision(playerInfo, pos, upOrDown):
    pass

with open('players.txt', 'r') as f:
    playerInfo = f.readlines()

playerInfo = [line.strip().split(';') for line in playerInfo]

numDivisions = ???
for i in range(numDivisions):
    divisionPlayers = getPlayersOfDivision(playerInfo, i)
    bestPlayers = get2BestPlayers(divisionPlayers)
    worstPlayers = get2WorstPlayers(divisionPlayers)
    newPlayerInfo = changePlayerDivision(playerInfo, findPlayer(playerInfo, divisionPlayer[bestPlayers[0]][0], divisionPlayer[bestPlayers[0]][1]), +1)
    newPlayerInfo = changePlayerDivision(playerInfo, findPlayer(playerInfo, divisionPlayer[bestPlayers[1]][0], divisionPlayer[bestPlayers[1]][1]), +1)
    newPlayerInfo = changePlayerDivision(playerInfo, findPlayer(playerInfo, divisionPlayer[worstPlayers[0]][0], divisionPlayer[worstPlayers[0]][1]), -1)
    newPlayerInfo = changePlayerDivision(playerInfo, findPlayer(playerInfo, divisionPlayer[worstPlayers[1]][0], divisionPlayer[worstPlayers[1]][1]), -1)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM