I have a CSV file that has several columns. Two of the columns are called Namn (Name) (Product) and Alla bilder (All images).
Some of the products have several images. These images are inserted on their own row under the "All images":
Example:
Name All images
Name1 Image1
Name2 Image2
Image2-1
Image2-2
Name3 Image3
I am trying to get all images belonging to one product to be inserted in the first image-row and seperated by a |. Here's the code I've managed with help from a friend to make, but I just don't get it to work. (I downloaded Python, and ran the .py script) - Nothing happens. Please note I have never touched Python before.
import codecs, csv
def main():
file_input = codecs.open('test.csv', 'r', 'utf-8-sig')
dictreader = csv.DictReader(file_input, delimiter=',')
main_rows = []
fields = []
temp_row = {}
for row_item in dictreader:
if len(fields) == 0:
# fix the fields header...
for field in row_item:
fields.append(field)
if row_item['Name'] == '':
# this row probably only contains picture information...
if 'Alla bilder' in row_item and row_item['Alla bilder'] != '':
if 'Alla bilder' not in temp_row:
temp_row['Alla bilder'] = row_item['Alla bilder']
elif temp_row['Alla bilder'] == '':
temp_row['Alla bilder'] = row_item['Alla bilder']
else:
temp_row['Alla bilder'] = temp_row['Alla bilder'] + '|' + row_item['Alla bilder']
else:
# this seems to be a new product row...
if len(temp_row) != 0:
# there seems to be something to store....
print('\nSTORING: ' + str(temp_row))
main_rows.append(temp_row)
temp_row = {}
# print('\nNEW ROW: ' + str(row_item))
temp_row = row_item
if len(temp_row) != 0:
# there seems to be something to store....
print('\nSTORING: ' + str(temp_row))
main_rows.append(temp_row)
file_output = codecs.open('test2.csv', 'w', 'utf-8-sig')
dictwriter = csv.DictWriter(file_output, delimiter=',', fieldnames=fields)
dictwriter.writerows(main_rows)
if _name_ == "_main_":
main()
else:
print('This file was called from another class...')
What error or message gives you when you start the script from the console?
Try changing
if _name_ == "_main_":
main()
else:
print('This file was called from another class...')
For
if __name__ == "__main__":
main()
else:
print('This file was called from another class...')
It's the only error I see (if I'm not wrong, it's __name__, not _name_). Changing that works for me. Using this input:
Name,Alla bilder
Name1,Image1
Name2,Image2
,Image2-1
,Image2-2
Name3,Image3
I get the next result:
Name1,Image1
Name2,Image2|Image2-1|Image2-2
Name3,Image3
Is that your problem?
Related
I have a script I'm writing to make pulling data from my fantasy football league easy and exported in a format that can be played with in Excel easily.
The script I have attached only contains the relevant parts to this questions as the larger script I have written has a lot of moving parts that doesn't apply here.
I'm essentially pulling this players.get_all_players() data from the Sleeper platform using the Sleeper-API-Wrapper (Github link here).
My script will take player data and put it into a .csv like this, with the player ID in the top row and all the info in a single cell below the ID. Screenshot of this below.
Excel .csv screenshot
How can I export this so that the data is nicely formatted into separate rows? I have a different spreadsheet where I'd like to be able to pull this data to automatically.
Alternatively, if I'm doing this in a really roundabout way, please let me know! This is the JSON response from the platform: JSON Response
# 9 All players - players.get_all_players()
warning = 1
while warning == 1:
print("%s%s\n\n\nWARNING:%s" % (fg(15), bg(9), attr(0)))
print("%s%sthe 'all players' option is intensive and may freeze your PC for several minutes.%s" % (fg(15), bg(0), attr(1)))
warning = input("continue anyway? (y/n)\n")
if warning == "n":
pe_loop = 0
action = 0
elif warning == "y":
name = "all players"; file = name
output = players.get_all_players()
break
else:
print("Not a valid option, try again.")
warning = 1
overwrite = 0
name_change = 0
while action == 0:
try:
action = int(input("%s%s\n1 - print\n2 - export to Excel\n3 - back to tasks\n4 - end\n--------------------\n%s" % (fg(14), bg(0), attr(1))))
except ValueError:
print("Not a valid option, try again.")
## Print
if action == 1 and week != 18:
print(output)
break
elif action == 1 and week == 18:
week = 0
while week < 18:
week += 1
if task == 3:
output = league.get_matchups(week)
elif task == 4:
output = league.get_transactions(week)
print(output)
## Export
elif action == 2:
path = os.path.join(parent_dir, file)
name_change = input("\nDo you want to name the file? (y/n)\n")
if name_change == "y":
name = input("\nEnter file name now:\n")
if name_change == "n":
file_path = path + "\\" + name + '_' + str(year) + ".xlsx"
if os.path.isfile(file_path) == True:
overwrite = input("\nFile name... '" + name + "' already exists! Would you like to overwrite this file? (y/n)\n")
if overwrite == "n":
count = 0
while os.path.isfile(file_path) == True:
count += 1
new_name = name + "_" + str(count)
file_path = path + "\\" + new_name + ".xlsx"
else:
name = new_name
print("\nThe new file was automatically named: " + new_name + "_wk" + str(week) + "\nand placed in: " + path)
if os.path.isdir(path) == False and overwrite == 0:
os.mkdir(path)
print("\nCreating new file path... " + file + "\n")
elif os.path.isdir(path) == True and overwrite == 0:
print("\nFile path... '" + file + "' exists!\n")
toCSV = output
# 9 All Players CSV file
with open(parent_dir + file + "\\" + name + ".csv", 'w', encoding='utf8', newline='') as output_file:
fc = csv.DictWriter(output_file, output.keys())
fc.writeheader()
fc.writerow(toCSV)
It turns out that sleeper_wrapper exposes a method players.get_players_df that gives you a pandas DataFrame containing all players.
Write that to a csv file using to_csv as suggested in the comments.
Strip down your code to receive better answers faster :)
This is the code that your question needs:
from sleeper_wrapper import Players
import csv
players = Players()
toCSV = players.get_all_players()
with open(parent_dir + file + "\\" + name + ".csv", 'w', encoding='utf8', newline='') as output_file:
fc = csv.DictWriter(output_file, output.keys())
fc.writeheader()
fc.writerow(toCSV)
This is how you write the csv using pandas:
import pandas as pd
from sleeper_wrapper import Players
players = Players()
all_players = players.get_all_players()
# stolen from https://github.com/NotTheCrocHunter/sleeper-api-wrapper/blob/91d8cf1b64cf55884b4c4746d53ccd1259d11c1f/sleeper_wrapper/players.py#L41
# because that method is unavailable in the version of sleeper_wrapper in PyPI
all_players_df = pd.DataFrame.from_dict(all_players, orient="index")
# all_players_df contains some information on teams as well, maybe you want to filter that out...
all_players_df.to_csv("your_output_file.csv")
I am trying to convert my old CSV files to another format and a new name (_new.csv). All files are in the folder with the date stamp. e.g Filename_05_08_2021.csv. Almost I have 63 files from today date to back. The problem is I have to provide each file name one by one while call function. Is there any way I can convert all of them? I am not sure what I am doing wrong here.
def new_csv(file_path):
c = csv.reader(open(file_path))
c_list = []
c_list.extend(c)
out_csv = open(file_path.replace('.csv','_new.csv'), "w")
for line in c_list:
if len(line) == 10:
out_csv.write(str(line[0]+','+line[1]+','+(line[2]).upper()+','+''+','+
(line[3][1:]).upper()+','+line[4]+','+line[5]+','+
line[6]+','+line[7]+','+line[9])+'\n')
if len(line) > 10:
out_csv.write(str(line[0]+','+line[1]+','+(line[2]).upper()+','+
(line[3][1:]).upper()+','+line[4][1:]+','+line[5]+','+
line[6]+','+line[7]+','+line[8]+','+line[10])+'\n')
out_csv.close()
print ("new .csv written")
if __name__ == '__main__':
new_csv('C:\\Myfolder\\Filename_05_08_2021.csv')
Just iterate within the directory. You can use glob:
import glob
def new_csv(file_path):
c = csv.reader(open(file_path))
c_list = []
c_list.extend(c)
out_csv = open(file_path.replace('.csv','_new.csv'), "w")
for line in c_list:
if len(line) == 10:
out_csv.write(str(line[0]+','+line[1]+','+(line[2]).upper()+','+''+','+
(line[3][1:]).upper()+','+line[4]+','+line[5]+','+
line[6]+','+line[7]+','+line[9])+'\n')
if len(line) > 10:
out_csv.write(str(line[0]+','+line[1]+','+(line[2]).upper()+','+
(line[3][1:]).upper()+','+line[4][1:]+','+line[5]+','+
line[6]+','+line[7]+','+line[8]+','+line[10])+'\n')
out_csv.close()
print ("new .csv written")
if __name__ == '__main__':
for filepath in glob.iglob('C:\\Myfolder\\*.csv'):
new_csv(filepath)
Your statements composing the string by adding commas is a bit clumsy. Consider modifying the list so each field has what you want, then using join to put it all together:
def new_csv(file_path):
out_csv = open(file_path.replace('.csv','_new.csv'), "w")
for line in csv.reader(open(file_path)):
line[2] = line[2].upper()
line[3] = line[3][1:].upper()
if len(line) == 10:
line.pop(8)
else:
line[4] = line[4][1:]
line.pop(9)
print( ','.join(line), file=out_csv )
out_csv.close()
print ("new .csv written")
For class I need to put names into a file then have the user type in the name they want to delete, and it deletes them. I almost have it it just deletes 2 people at once and I'm not sure why.
import os
def main():
found=False
search=input("Who would you like to delete? ")
student_grades = open("student_grades.txt", 'r')
temp_file= open('temp.txt', 'w')
descr = student_grades.readline()
while descr != '':
qty = (student_grades.readline())
descr = descr.rstrip('\n')
if descr != search:
temp_file.write(descr + '\n')
temp_file.write(str(qty) + '\n')
else:
found = True
descr = student_grades.readline()
student_grades.close()
temp_file.close()
os.rename('temp.txt', 'grades.txt')
if found:
print('The file has been updated.')
else:
print('That student was not found in the file.')
main()
There is also 2 files. student_grades.txt that has the names in it, and temp.txt with nothing. When typing in the name of the person, it can find them but it deletes 2 people instead of the one that was searched.
If you are using Python3.6+
from pathlib import Path
fname = "student_grades.txt"
def bak_file(old_name, new_name=None):
if new_name is None:
new_name = old_name + '.bak'
Path(new_name).write_bytes(Path(old_name).read_bytes())
print('-->', f'cp {old_name} {new_name}')
def main():
bak_file(fname)
lines = Path(fname).read_text().splitlines()
search = input("Who would you like to delete? ").strip()
if search in lines:
updated_lines = [i for i in lines if i != search]
Path(fname).write_text('\n'.join(updated_lines))
print(f'The file {fname} has been updated.')
else:
print('That student was not found in the file.')
if __name__ == '__main__':
main()
Are you sure it deletes two people? This qty = (student_grades.readline()) ... temp_file.write(str(qty) + '\n') makes me think that you might be adding unwanted new lines (no strip when getting the qty, but adding a new line when rewriting it), which might look like you removed two instead of one?
Eraw got it. It works now. I was following a program from my book and they had a slightly different scenario. I deleted qty = (student_grades.readline()) and temp_file.write(str(qty) + '\n') and this deletes only what needs to be deleted. Thanks!
I'm trying to read the next field in each line, but I'm not sure how.
I can get current field, but I want the contents of field+1 on each line.
Right now i get "ipAddressCheck1" into ipAddressCheck1, but i want its contents to be "192.168.77.254" (the next field), for example.
This is my code:
#!/usr/bin/python3.4
import csv
###PARAMS.txt file contents...
###Remove first two ## each line, put into PARAMS.txt file
##"ipAddressCheck1","192.168.77.254"
##"ipAddressCheck2","microsoft.com"
##"ipAddressVerify1","8.8.8.8"
##"ipAddressVerify2","8.8.8.7"
##"nbrCycles","10"
#!/usr/bin/python3.4
#fjv101
import csv
###PARAMS.txt file contents...
###Remove first two ## each line, put into PARAMS.txt file
##"ipAddressCheck1","192.168.77.254"
##"ipAddressCheck2","microsoft.com"
##"ipAddressVerify1","8.8.8.8"
##"ipAddressVerify2","8.8.8.7"
##"nbrCycles","10"
def pgminit():
filename = "PARAMS.txt"
accessMode = "r"
nbrCycles=0
fjaddr1="blank"
ipAddressCheck1="blank"
ipAddressCheck2="blank"
ipAddressVerify1="blank"
ipAddressVerify2="blank"
nbrCycles="0"
with open(filename, accessMode) as myCSVFile:
#Read file contents
allRowsList = csv.reader(myCSVFile)
print(allRowsList)
for currentRow in allRowsList:
for currentWord in currentRow:
if currentWord == "ipAddressCheck1" :
ipAddressCheck1 = currentWord
elif currentWord == "ipAddressCheck2" :
ipAddressCheck2 = "ipAddressCheck2"
elif currentWord == "ipAddressVerify1" :
ipAddressVerify1 = "ipAddressVerify1"
elif currentWord == "ipAddressVerify2" :
ipAddressVerify2 = "ipAddressVerify2"
elif currentWord == "nbrCycles" :
nbrCycles = 555
print("ipAdddressCheck1=",ipAddressCheck1)
print("ipAdddressCheck2=",ipAddressCheck2)
print("ipAdddressVerify1=",ipAddressVerify1)
print("ipAdddressVerify2=",ipAddressVerify2)
print("nbrCycles=",nbrCycles)
print("Press ENTER to continue...")
fjChoiceNUL=input()
pgminit()
I used csv.DictReader instead, and set the first line with words
PARAM1 and PARAM2. This becomes the field names, thus can locate
onto the desired field easily. So far, works great.
The resultant output is in comment below.
#!/usr/bin/python3.4
#fjv102
import csv
##"PARAM1","PARAM2"
###PARAMS.txt file contents...
###Remove first two ## each line, put into PARAMS.txt file
##"ipAddressCheck1","192.168.77.254"
##"ipAddressCheck2","microsoft.com"
##"ipAddressVerify1","8.8.8.8"
##"ipAddressVerify2","8.8.8.7"
##"nbrCycles","10"
def pgminit():
filename = "PARAMS.txt"
with open(filename) as myCSVFile:
#Read file contents
allRowsList = csv.DictReader(myCSVFile)
for currentRow in allRowsList:
if currentRow['PARAM1'] == "ipAddressCheck1" :
ipAddressCheck1 = currentRow['PARAM2']
elif currentRow['PARAM1'] == "ipAddressCheck2" :
ipAddressCheck2 = currentRow['PARAM2']
elif currentRow['PARAM1'] == "ipAddressVerify1" :
ipAddressVerify1 = currentRow['PARAM2']
elif currentRow['PARAM1'] == "ipAddressVerify2" :
ipAddressVerify2 = currentRow['PARAM2']
elif currentRow['PARAM1'] == "nbrCycles" :
nbrCycles = currentRow['PARAM2']
print("ipAdddressCheck1=",ipAddressCheck1)
print("ipAdddressCheck2=",ipAddressCheck2)
print("ipAdddressVerify1=",ipAddressVerify1)
print("ipAdddressVerify2=",ipAddressVerify2)
print("nbrCycles=",nbrCycles)
print("Press ENTER to continue...")
fjChoiceNUL=input()
pgminit()
I have a code to create a CSV with information from another CSV file. In my new CSV file, I would like to save only 20 rows sorted from highest to lowest of row ['impressions']
I read something about pandas but I don't find anything about how to do it!
To be more clear, I shared some images:
before:
enter image description here
after:
enter image description here
Code:
import csv
input_file = 'report_2017_12_11_12_31_19UTC.csv'
output_file= "All_Data_Tags.csv"
with open(input_file) as csvfile, open(output_file, "w") as output:
reader = csv.DictReader(csvfile)
cols = ("domain","ddomain","opportunities", "impressions", "fillRate", "DATA")
writer = csv.DictWriter(output, fieldnames=cols, extrasaction='ignore')
writer.writeheader()
for row in reader:
row['fillRate'] = '{:.2f}'.format(float(row['fillRate']) * 100)
if row['ddomain'] == "":
if row['domain'] == "":
row['ddomain'] = "App"
row['domain'] = " "
if row['domain'] == row['ddomain']:
row['domain'] = "Real Site"
if row['domain'] == "":
row['domain'] = "Detected Only"
if row['ddomain'] == "":
row['ddomain'] = "Vast Media"
if row['ddomain'] != row['domain']:
if row['ddomain'] != "Vast Media":
if row['domain'] != "Real Site":
if row['domain'] != "Detected Only":
if row['ddomain'] != "App":
row['DATA'] = "FAKE"
else:
row['DATA'] = "OK"
else:
row['DATA'] = "OK"
else:
row['DATA'] = "OK"
else:
row['DATA'] = "OK"
writer.writerow(row)
Here is the Answer:
code:
import pandas as pd
movies = pd.read_csv('Top20_Media_Yesterday.csv')
movies = movies.sort_values(['impressions'], ascending=False)
movies = movies.to_csv("Top20_Media_Yesterday.csv")
movies = pd.read_csv('Top20_Media_Yesterday.csv', nrows=21)
movies = movies.to_csv("Top20_Media_Yesterday.csv")
Use the DataFrame.sort_values function of the pandas framework, passing the column name(s),you wish to sort, to the by argument and setting axis to 1.
You can find similar examples here.