0

Problem: My code works when value[3] and [4] have 0 in it. However, when i try and add my actual values in, the code messes up (see below).

Text file explained here.

Joe,Bloggs,[email protected],01269512355, 1,15, 0, 0, 0 
FName, LName, Email, Number, Division, Points, ..., ...,

Code objective: The code should take the bottom and top two scoring players in each division and -1 or +1 to the division. +1 if low score and -1 if high score. So, if there was 6 people in a division, 2 would go up, 2 would go down and 2 would stay the same division.

Code:

f = open('test copy.txt', 'r')
lines = []
for line in f.readlines():
    line = [x.strip() for x in line.split(',')]
    line[4] = int(line[4])
    line[5] = int(line[5])
    lines.append(line)
f.close()

ordered = sorted(zip(range(len(lines)), lines), key=lambda x: x[1][3])
lines[ordered[-1][0]][4] += 1
lines[ordered[-2][0]][4] += 1
lines[ordered[0][0]][4] -= 1
lines[ordered[1][0]][4] -= 1

with open('test copy.txt', 'w') as f:
    for line in lines:
        line = [str(x) for x in line]
        f.write(', '.join(line) + '\n')

Text file that works:

Joe,Bloggs,0,0, 1,15, 0, 0, 0,
Sarah,Brown,0,0, 1,12, 0, 0, 0,
Andrew,Smith,0,0, 1,4, 0, 0, 0,
Ray,Charles,0,0, 1,3, 0, 0, 0,
Kevin,White,0,0, 1,8, 0, 0, 0,
Samantha,Collins,0,0, 1,2, 0, 0, 0,

Test file that needs to work but doesn't:

Joe,Bloggs,[email protected],01269512355, 1,15, 0, 0, 0
Sarah,Brown,[email protected],01866522555, 1,12, 0, 0, 0
Andrew,Smith,[email protected],01899512785, 1,4, 0, 0, 0
Ray,Charles,[email protected],01268712321, 1,3, 0, 0, 0
Kevin,White,[email protected],01579122345, 1,8, 0, 0, 0
Samantha,Collins,[email protected],04269916257, 1,2, 0, 0, 0

desired outcome:

Joe,Bloggs,[email protected],01269512355, 0,15, 0, 0, 0
Sarah,Brown,[email protected],01866522555, 0,12, 0, 0, 0
Andrew,Smith,[email protected],01899512785, 1,4, 0, 0, 0
Ray,Charles,[email protected],01268712321, 2,3, 0, 0, 0
Kevin,White,[email protected],01579122345, 1,8, 0, 0, 0
Samantha,Collins,[email protected],04269916257, 2,2, 0, 0, 0

Because the value[3] is an integer, that seems to be messing with the code in sorting out which number in value[5] is bigger and then changing value[4] to the proper number.

This is what happens to the text file that needs to work:

Joe, Bloggs, [email protected], 01269512355, 0, 15, 0, 0, 0
Sarah, Brown, [email protected], 01866522555, 1, 12, 0, 0, 0
Andrew, Smith, [email protected], 01899512785, 2, 4, 0, 0, 0
Ray, Charles, [email protected], 01268712321, 0, 3, 0, 0, 0
Kevin, White, [email protected], 01579122345, 1, 8, 0, 0, 0
Samantha, Collins, [email protected], 04269916257, 2, 2, 0, 0, 0

As you can see, it is different because of the phone number in value[3].

4
  • Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it in the question itself. Questions without a clear problem statement are not useful to other readers. See: How to create a Minimal, Complete, and Verifiable Example. Commented May 17, 2016 at 23:11
  • Added the desired outcome that i want Commented May 17, 2016 at 23:16
  • I'd recommend you to use the csv library and numpy. Both are easy to apply for such a task. Also, describing more exactly what messes up means might help getting an answer. Commented May 17, 2016 at 23:29
  • ive tried to explain the best i can. Hope this is clear. Commented May 17, 2016 at 23:33

2 Answers 2

1

Edit: the issue was that the score was in the 6th column, so key=lambda x: x[1][3] should have been key=lambda x: x[1][5].

Original response below:

It looks to me like your code is correct and doing what you expect of it. Your desired output, however, doesn't match your algorithm - the two highest, Samantha and Andrew, should go from 1 and 1 to 2 and 2, and Ray should stay the same at 1.

Sign up to request clarification or add additional context in comments.

5 Comments

yes, this is the question im asking. Whats going wrong? Is so annoying :(
What column are you trying to sort by? Right now you're sorting by "phone number"
im trying to increade value[4] from the highest and lowest 2 from value[5]. The phone number should have anything to do with this.
You just need to change key=lambda x: x[1][3] to key=lambda x: x[1][5] then. 3 is the index of the phone number.
god damn it, when i did this last it said out of range. Which must have been due to some invisible lines at the bottom of the text file. The change you suggested has worked. Thank you kind sir.
0

I use pandas and NumPy to solve this question. In the following source code I explain each step:

import numpy as np
import pandas as pd

# Load data:
d = np.genfromtxt('copy.txt', dtype=np.str, delimiter=',')
# Optional: Remove last three columns:
d = d[:,:-3]
# Convert to a dataframe:
d = pd.DataFrame(data = d[:,:], columns=['fname', 'lname', 'email', 'number', 'division', 'points'])
# Set relevant datatypes (for sorting):
d[['division', 'points']] = d[['division', 'points']].astype(int)
# Sorting:
d = d.sort_values(by=['division', 'points'], ascending=[True, False])
# Reindexing:
d.index = range(1, len(d) + 1)

# Print the data structure:
print d[['fname', 'division', 'points']]
#       fname  division  points
# 1       Joe         1      15
# 2    Andrew         1       4
# 3       Ray         1       3
# 4  Samantha         1       2
# 5     Sarah         2      12
# 6     Kevin         2       8

# Duplicate the column:
d['new_division'] = d['division']

def increase_first_elements (group, count):
    group['new_division'][:count] -= 1
    return group

def increase_last_elements (group, count):
    group['new_division'][-count:] += 1
    return group

# Reordering:
# In this example: Select first and last element (1).
# Important: Higher numbers (e.g. 2) work with larger tables (without select-intersections).
d = d.groupby('division').apply(increase_first_elements, 1)
d = d.groupby('division').apply(increase_last_elements, 1)

print d[['fname', 'division', 'new_division', 'points']]
#       fname  division  new_division  points
# 1       Joe         1             0      15
# 2    Andrew         1             1       4
# 3       Ray         1             1       3
# 4  Samantha         1             2       2
# 5     Sarah         2             1      12
# 6     Kevin         2             3       8

# Sorting:
d = d.sort_values(by=['new_division', 'points'], ascending=[True, False])
# Reindexing:
d.index = range(1, len(d) + 1)
# Cleanup:
d[['division']] = d[['new_division']].astype(int)
d = d.drop('new_division', 1)

print d[['fname', 'division', 'points']]
#       fname  division  points
# 1       Joe         0      15
# 2     Sarah         1      12
# 3    Andrew         1       4
# 4       Ray         1       3
# 5  Samantha         2       2
# 6     Kevin         3       8

# Extra: If you want to reset the points:
d[['points']] = 0
print d[['fname', 'division', 'points']]
#       fname  division  points
# 1       Joe         0       0
# 2     Sarah         1       0
# 3    Andrew         1       0
# 4       Ray         1       0
# 5  Samantha         2       0
# 6     Kevin         3       0

2 Comments

I get an error saying import pandas as pd ImportError: No module named pandas. Im running python 2.7.11 if that matters.
If you use pip, you can install these modules by executing pip install numpy pandas.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.