Appending item to list in Python overwring all existing elements - python

I am writing a script to read a .osu file and convert it to specific objects. This has to be done multiple times for each "hitobject"
The reading part works fine, however appending the object is the problem
When appending the object, it seems to overwrite all existing elements in the list. I can not for the life of me figure out why this is happening.
I have tried creating a "temp" list, which stores the objects in a local list instead of the "self.notes" list, still the same issue.
I believe the error is occurring in this part of the file:
if hitobjline != -1:
hitobjects = self.file_lines[hitobjline+1:]
for i in hitobjects:
ln = i[:i.find(':')].split(',')
new_note = [NoteType.Circle, NoteType.Hold][int(ln[3] == '128')]
add_note = File.Note
add_note.NoteTypeByte = ln[3]
add_note.Note_Number = int(ln[0])
add_note.Time = int(ln[2])
add_note.NoteType = new_note
add_note.Raw = ln
self.notes.append(add_note)
print(ln, ln[3], ln[3] == '128', new_note, add_note.NoteType)
For background, the .osu files have a syntax like: x,y,time,type,hit,end:stuff-i-dont-need-to-worry-about
I expected an out put of self.notes[0].NoteType to be osureader.NoteType.Hold as the first line of the file is 192,192,410,128,0,2974:0:0:0:0: (the 128 indicating the 'Hold'
However, I get, osureader.NoteType.Circle, the last line of the file.

Related

Im having difficulty utilizing an array in python

I'm trying to manipulate text from a word file however when I save it to an array of classes, all the indexes are being overwritten instead of the one particular index I intend to change.
for line in modified:
if line.startswith('Date'):
output.append(line)
list2=line.split(' ')
work.date=list2[1]
# print(work.date)
if line.startswith('PPV'): #list1[2]=l,[3]=t,[4]=v
output.append(line)
list1=line.split(' ')
work.lpv=list1[2]
# print("l is ",list1[2],work.lpv)
work.tpv=list1[3]
# print("t is ",list1[3],work.tpv)
work.vpv=list1[4]
# print("v is ",list1[4],work.vpv)
daylist[count]=work
#print("l2 is ",list1[2],work.lpv)
#print("daylist", count, "saved")
print(count,daylist[count].date) #this displays the correct value at the propper index but all other indexs have also been changed to this value
count+=1
Im trying to save a class which holds a string and a few floats to an array but cannot seem to get it to save to each index properly as it is read from the file. ive tried messing with the scope and list initialization but cant seem to figure it out. Any input would be appreciated, Thanks!
Every index in the daylist array references the same work object. When you change an attribute of work (e.g. work.date) it's reflected in all references to that single object. You want each index to reference a separate, independent object but that's not what the code is doing.
Try something like this where work is a dictionary:
for line in modified:
work = {} # <-- this makes the name "work" refer to a new, empty dict
if line.startswith('Date'):
output.append(line)
list2=line.split(' ')
work["date"] = list2[1]
elif line.startswith('PPV'):
output.append(line)
list1=line.split(' ')
work["lpv"] = list1[2]
# ...
print(count, daylist[count]["date"])
count += 1
Here's a helpful link on how names reference objects: How does Python referencing work?

Iterate over Python list with clear code - rewriting functions

I've followed a tutorial to write a Flask REST API and have a special request about a Python code.
The offered code is following:
# data list is where my objects are stored
def put_one(name):
list_by_id = [list for list in data_list if list['name'] == name]
list_by_id[0]['name'] = [new_name]
print({'list_by_id' : list_by_id[0]})
It works, which is nice, and even though I understand what line 2 is doing, I would like to rewrite it in a way that it's clear how the function iterates over the different lists. I already have an approach but it returns Key Error: 0
def put(name):
list_by_id = []
list = []
for list in data_list:
if(list['name'] == name):
list_by_id = list
list_by_id[0]['name'] = request.json['name']
return jsonify({'list_by_id' : list_by_id[0]})
My goal with this is also to be able to put other elements, that don't necessarily have the type 'name'. If I get to rewrite the function in an other way I'll be more likely to adapt it to my needs.
I've looked for tools to convert one way of coding into the other and answers in forums before coming here and couldn't find it.
It may not be beatiful code, but it gets the job done:
def put(value):
for i in range(len(data_list)):
key_list = list(data_list[i].keys())
if data_list[i][key_list[0]] == value:
print(f"old value: {key_list[0], data_list[i][key_list[0]]}")
data_list[i][key_list[0]] = request.json[test_key]
print(f"new value: {key_list[0], data_list[i][key_list[0]]}")
break
Now it doesn't matter what the key value is, with this iteration the method will only change the value when it finds in the data_list. Before the code breaked at every iteration cause the keys were different and they played a role.

UnboundLocalError: local variable 'document' referenced before assignment

I have a function, which takes a CSV and processes it. I am trying to count the rows in the CSV file before running through it to ensure I get to the end.
def parse_campaigns_cutsheet(country_code, input_file, DB, DB_hist, zip_id):
filecontent = urllib2.urlopen(input_file)
count = 0
csvFile = csv.DictReader(filecontent)
rowage = len(list(csvFile))
for row in csvFile:
count += 1
if 'MM' not in row['Tier']:
continue
if RB_COUNTRIES_new[country_code]['cut_sheet_country'] != row['Country']:
continue
document = DB.find_one({'rb_account_id': RB_COUNTRIES_new[country_code]['rb_account_id']})
if document is None:
continue
DB.save(document)
report_work(document, DB, DB_hist)
I keep getting the following error UnboundLocalError: local variable 'document' referenced before assignment. If i remove the rowage = len(list(csvFile)) line it works fine?
This happens because the DictReader is a generator.
When you call list on DictReader, it will yield all the values into the list, and won't be iterable any more.
That why when your for-loop tries to iterate over it, it never does, and the document will never be assigned.
If you want to accomplish what you're trying to do, you can keep a reference to the list and then iterate over the list:
...
csvFile = csv.DictReader(filecontent)
filecontent_list = list(csvFile)
rowage = len(filecontent_list)
for row in filecontent_list:
...
Keep in mind - this is mean that all your data will be saved in memory!
When iterating over the generator without forcing it to be a list, only one iterating are being saved in the memory each time.

In Pandas- how to check of dataframe is empty after every manipulation?

In doing a lot of manipulations on dataframe and in one of them it can return empty (which an except able result).
the thing is if turns empty it crashes on the other line, like in the following code:
NumOfActiveDays = local_input_list.groupby(['DeviceSidID'])['timestamp'].nunique().reset_index().rename(columns={'timestamp': 'NumOfDays'})
NumOfActiveDays = NumOfActiveDays[NumOfActiveDays.NumOfDays >= float(extdf.dict[entity]['days_thresh'])]
local_input_list = local_input_list[local_input_list.DeviceSidID.isin(NumOfActiveDays.loc[:, 'DeviceSidID'])].reset_index(drop=True)
if NumOfActiveDays will become empty it will crash the third line...
is there a better why to check if data manipulation ends up empty instead of after every line to do if df.empty()?
Thanks

.split from a file and putting it in an array

Im reading a file with some information and each part is separated with a # however on each line i want it to be a different array so i did this and im not sure why its not working.
main_file = open("main_file.txt","r")
main_file_info=main_file.readlines()
test=[]
n=0
for line in main_file_info:
test[n]=line.split("#")
test=test[n][1:len(test)-1] # to get rid of empty strings at the start and the end
print(test)# see what comes out
main_file.close()
The way you are inserting the output of line.split("#") in your list is wrong. Your list is not initialized, hence, you can't simply assign anything to any element of the list. So, what you need to do is this :
test.append(line.split("#"))
Or, you can initialize your list as below :
test = [[]]*(len(main_file_info))
test = [None for _ in range(total)]
# instead of test = []
or simply just append to test:
test.append( line.split("#") )

Categories

Resources