Open .csv file edit one field, write back to .csv file - python

So I have a .csv file with names, lat, lon, and phone number; separated by comma. I need to open the file, edit the phone number into a more legible format and then write that back to the file.
There is a nice solution to editing the phone numbers Here
Not really sure of the best way to approach this problem. Any help is greatly appreciated. Thanks.
import csv
def phone_format(n):
return format(int(n[:-1]), ",").replace(",", "-") +n[-1]
with open('sample.csv', 'rU') as csvfile:
spotreader = csv.reader(csvfile)
spotwriter = csv.writer(csvfile)
for row in spotreader:
spotwriter.writerow([0] + phone_format(spotreader[1]))
This does not work. Not really sure how to get what I am looking for.
Sample of my csv file below
Jason Schow,,5016098648
Dena VanGorder,,6074621816
Lindsey McNabb,3066533971,3066505001
Jeff Wozniak,3066531566,3069420647
Victoria Norton,3067692840,3067697062
Benjie Butikofer,3067692107,3067697108
Jessica Duede,,3062813158
Pete Vogeh,3063776261,3069890349
Melissa Kwasney,,3069412583
Type of output to .csv file that I am looking for below:
Jason Schow,,501-609-8648
Dena VanGorder,,607-462-1816
Lindsey McNabb,306-653-3971,306-650-5001
Jeff Wozniak,306-653-1566,306-942-0647
Victoria Norton,306-769-2840,306-769-7062
Benjie Butikofer,306-769-2107,306-769-7108
Jessica Duede,,306-281-3158
Pete Vogeh,306-377-6261,306-989-0349
Melissa Kwasney,,306-941-2583

Shouldn't you be formatting on row, instead of spotreader? This works fine for me reading it from a .csv file. I added a check for ignoring empty strings. Also the spotwriter won't work since you aren't opening the file in write mode. 'rU' is read mode only. What you want to do is make a brand new .csv file and write the output there like this:
import csv
def phone_format(n):
return format(int(n[:-1]), ",").replace(",", "-") +n[-1]
with open('sample.csv', 'rU') as csvfile:
with open('sampleOutput.csv', 'w') as csvfile2:
spotreader = csv.reader(csvfile)
spotwriter = csv.writer(csvfile2)
for row in spotreader:
if row[1] != '':
spotwriter.writerow([row[0], phone_format(row[1]), row[2]])
else:
spotwriter.writerow([row[0], row[1], row[2]])
The input is your .csv file.
Output:
Jason Schow,,5016098648
Dena VanGorder,,6074621816
Lindsey McNabb,306-653-3971,3066505001
Jeff Wozniak,306-653-1566,3069420647
Victoria Norton,306-769-2840,3067697062
Benjie Butikofer,306-769-2107,3067697108
Jessica Duede,,3062813158
Pete Vogeh,306-377-6261,3069890349
Melissa Kwasney,,3069412583
This is assuming you only want to edit the first phone number, if you want to edit the second phone number too, you will have to do some additional programming.

Got it figured out. I stumbled across this in another stackoverflow article. Article Here
The corrected code is as follows. Thanks again for all the help and suggestions.
import csv
def phone_format(n):
return format(int(n[:-1]), ",").replace(",", "-") +n[-1]
with open('sample.csv', 'rU') as csvfile:
with open('sampleOutput.csv', 'w', newline='') as csvfile2:
spotreader = csv.reader(csvfile)
spotwriter = csv.writer(csvfile2)
for row in spotreader:
if row[1] != '' and row[2] != '':
spotwriter.writerow([row[0], phone_format(row[1]), phone_format(row[2])])
elif row[1] != '' and row[2] == '':
spotwriter.writerow([row[0], phone_format(row[1]), (row[2])])
elif row[1] == '' and row[2] != '' :
spotwriter.writerow([row[0], (row[1]), phone_format(row[2])])

Related

How to print only a the content of a cell in a specific row from a csv file in Python

I'm new to Python so excuse me if my question is kind of dumb.
I send some data into a csv file (I'm making a password manager). So I send this to this file (in this order), the name of the site, the e-mail corresponding and finally the password.
But I would like to print all the names already written in the csv file but here is my problem, for the first row it does print the whole row but for the following rows it works just well.
Here is my code, I hope u can help me with this.
csv_file = csv.reader(open('mycsvfile.csv', 'r'), delimiter=';')
try :
print("Here are all the sites you saved :")
for row in csv_file :
print(row[0])
except :
print("Nothing already saved")
Maybe it can help, but here is how I wrote my data into the csv file:
#I encrypt the email and the password thanks to fernet and an already written key
#I also make sure that the email is valid
file = open('key.key', 'rb')
key = file.read()
file.close()
f = Fernet(key)
website = input("web site name : \n")
restart = True
while restart :
mail = input("Mail:\n")
a = isvalidEmail(mail)
if a == True :
print("e-mail validated")
restart = False
else :
print("Wrong e-mail")
pws = input("password :\n")
psw_bytes = psw.encode()
mail_bytes = mail.encode()
psw_encrypted_in_bytes = f.encrypt(psw_bytes)
mail_encrypted_in_bytes = f.encrypt(mail_bytes)
mail_encrypted_str = mail_encrypted_in_bytes.decode()
psw_encrypted_str = psw_encrypted_in_bytes.decode()
f = open('a.csv', 'a', newline='')
tup1 = (website, mail_encrypted_str, psw_encrypted_str)
writer = csv.writer(f, delimiter = ';')
writer.writerow(tup1)
print("Saved ;)")
f.close()
return
And here is my output (I have already saved data)
Output (First, you see the name of the ws with the email and the psw encrypted then just the name which is what I want
I finally succeed, instead of using a csv.Reader, i used a csv.DictReader and as all the names i'm looking for are on the same column, i juste have to use the title of the columns.
So here is the code :
with open('mycsv.csv', newline='') as csvfile:
data = csv.DictReader(csvfile)
print("Websites")
print("---------------------------------")
for row in data:
print(row['The_title_of_my_column'])
make list from csv.reader()
rows = [row for row in csv_file]
and now you can get element by identifier using rows as list of lists
rows[id1][id2]

Writing a CSV File with Pandas Python

I did a python script to access a site, and on that site do a certain search for me to do a scan of the search result.
I write the return of the result as txt
clear = self.browser.find_elements_by_class_name('Whitebackground')
for scrape in clear:
with open('result.txt', 'a') as writer:
writer.write(scrape.text)
writer.write('\n')
writer.close()
I want to return the result in CSV to open in Excel
clear = self.browser.find_elements_by_class_name('Whitebackground')
for scrape in clear:
with open('result.csv', 'a') as writer:
writer.write(scrape.text)
writer.write('\n')
writer.close()
My problem is that I have to fill 4 columns
I get my current result that way
656473930362736
The car needs to change the oil
Model: sedan
type of fuel: Gasoline
I want to receive my result in CSV in this way
'Number'; 'description'; 'Model'; 'Type of fuel'
6564...; The car needs..; sedan ; Gasoline
'Number', 'description', 'Model', 'Type of fuel' would be the titles by columns
'6564...', 'The car needs...', 'sedan', 'Gasoline' Would be the rows of the columns
does anyone have any idea how I can do this??
if you can convert your data into dictionaries, its super easy:
data = []
datapoint = {}
datapoint['Number'] = 656473930362736
datapoint['Description'] = "The car needs to change the oil."
datapoint['Model'] = "Sedan"
datapoint['Type of Fuel'] = "Gasoline"
data.append(datapoint)
fieldnames = ['Number','Description','Model','Type of Fuel']
def filewriter(filename, data, fieldnames):
with open (filename, "w", newline='', encoding='utf-8-sig') as csvfile:
csvfile = csv.DictWriter(csvfile, fieldnames=fieldnames, delimiter=',', dialect='excel')
csvfile.writeheader()
for row in data:
csvfile.writerow(row)
filewriter("out.csv", data, fieldnames)
converting your data into dictionaries is a separate problem, but should be no big deal if your data is structured well.
Simply parse your text by splitting into elements:
txt = "656473930362736\n" \
"The car needs to change the oil\n" \
"Model: sedan\n" \
"type of fuel: Gasoline"
list_of_elements = txt.split('\n')
required_text = list_of_elements[0] + ';' + list_of_elements[1] + ';' list_of_elements[2].split(':')[1] + ';' + list_of_elements[3].split(':') + ';'
file.write(required_text + '\n')

How to export text to a new file, userinput?

So i wrote a little program in python which allows me to take a .csv file, filter out the lines i need and then export these into a new .txt file.
This worked quite well, so i decided to make it more user friendly by allowing the user to select the file that should be converted by himself through the console (command line).
My problem: The file is imported as a .csv file but not exported as a .txt file which leads to my program overwriting the original file which will be emptied because of a step in my program which allows me to delete the first two lines of the output text.
Does anyone know a solution for this?
Thanks :)
import csv
import sys
userinput = raw_input('List:')
saveFile = open(userinput, 'w')
with open(userinput, 'r') as file:
reader = csv.reader(file)
count = 0
for row in reader:
print(row[2])
saveFile.write(row[2] + ' ""\n')
saveFile.close()
saveFile = open(userinput, 'r')
data_list = saveFile.readlines()
saveFile.close()
del data_list[1:2]
saveFile = open(userinput, 'w')
saveFile.writelines(data_list)
saveFile.close()
Try This:
userinput = raw_input('List:')
f_extns = userinput.split(".")
saveFile = open(f_extns[0]+'.txt', 'w')
I think you probably just want to save the file with a new name, this Extracting extension from filename in Python talks about splitting out the extension so then you can just add your own extension
you would end up with something like
name, ext = os.path.splitext(userinput)
saveFile = open(name + '.txt', 'w')
You probably just need to change the extension of the output file. Here is a solution that sets the output file extension to .txt; if the input file is also .txt then there will be a problem, but for all other extensions of the input file this should work.
import csv
import os
file_name = input('Name of file:')
# https://docs.python.org/3/library/os.path.html#os.path.splitext
# https://stackoverflow.com/questions/541390/extracting-extension-from-filename-in-python
file_name, file_ext_r = os.path.splitext(file_name)
file_ext_w = '.txt'
file_name_r = ''.format(file_name, file_ext_r)
file_name_w = ''.format(file_name, file_ext_w)
print('File to read:', file_name_r)
print('File to write:', file_name_w)
with open(file_name_r, 'r') as fr, open(file_name_w, 'w') as fw:
reader = csv.reader(fr)
for i, row in enumerate(reader):
print(row[2])
if i >= 2:
fw.write(row[2] + ' ""\n')
I also simplified your logic to avoid writting the first 2 lines to the output file; no need to read and write the output file again.
Does this work for you?

While loop causing issues with CSV read

Everything was going fine until I tried to combine a while loop with a CSV read and I am just unsure where to go with this.
The code that I am struggling with:
airport = input('Please input the airport ICAO code: ')
with open('airport-codes.csv', encoding='Latin-1') as f:
reader = csv.reader(f, delimiter=',')
for row in reader:
if airport.lower() == row[0].lower():
airportCode = row[2] + "/" + row[0]
print(airportCode)
else:
print('Sorry, I don\'t recognise that airport.')
print('Please try again.')
Executing this code causes the 'else' to print continuously until the code is stopped, regardless of whether or not the input matches that in the CSV file. The moment I remove this statement the code runs fine (albeit doesn't print anything if the input doesn't match).
What I am aiming to try and do is have the question loop until true. So my attempt was as follows:
with open('airport-codes.csv', encoding='Latin-1') as f:
reader = csv.reader(f, delimiter=',')
for row in reader:
while True:
airport = input('Please input the airport ICAO code: ')
if airport.lower() == row[0].lower():
airportCode = row[2] + "/" + row[0]
print(airportCode)
break
else:
print('Sorry, I don\'t recognise that airport.')
print('Please try again.')
False
I'm pretty sure my limited experience is causing me to oversee an obvious issue but I couldn't find anything similar with my search queries so my next stop was here.
As requested, a few lines of the CSV file:
EDQO small_airport Ottengrüner Heide Airport 50.22583389, 11.73166656
EDQP small_airport Rosenthal-Field Plössen Airport 49.86333466,
EDQR small_airport Ebern-Sendelbach Airport 50.03944397, 10.82277775
EDQS small_airport Suhl-Goldlauter Airport 50.63194275, 10.72749996
EDQT small_airport Haßfurt-Schweinfurt Airport 50.01805496,
EDQW small_airport Weiden in der Oberpfalz Airport 49.67890167,
If you want to do it precisely your way, you just need to make sure your csv reader's pointer returns back to the beginning of the file when a user enters bad code, something like:
with open('airport-codes.csv', encoding='Latin-1') as f:
reader = csv.reader(f, delimiter=',')
airportCode = None # store for our code
while not airportCode: # loop until valid code found
airport = input('Please input the airport ICAO code: ') # ask for the code
for row in reader: # loop through our CSV
if airport.lower() == row[0].lower(): # if code found in the first column...
airportCode = row[2] + "/" + row[0]
break # no need to search further
if not airportCode: # we didn't find the code, print a helpful message
print('Sorry, I don\'t recognise that airport.')
print('Please try again.')
f.seek(0) # reset the CSV pointer to the beginning for the next loop
print("Airport found: {}".format(airportCode))
But I'd suggest you to just load your codes in memory and do quick lookups on the spot:
airportCode = None # store for our code
airport_codes = {} # our in-memory fast lookup
with open('airport-codes.csv', encoding='Latin-1') as f:
reader = csv.reader(f, delimiter=',')
for row in reader: # loop through our CSV
airport_codes[row[0].lower()] = row[2] + "/" + row[0] # store the lookup map
while not airportCode:
airport = input('Please input the airport ICAO code: ') # ask for the code
airportCode = airport_codes.get(airport.lower(), None)
if not airportCode:
print('Sorry, I don\'t recognise that airport.')
print('Please try again.')
print("Airport found: {}".format(airportCode))
An easy solution would be something like this:
airport = input('Please input the airport ICAO code: ')
airportCode = None
with open('airport-codes.csv', encoding='Latin-1') as f:
reader = csv.reader(f, delimiter=',')
for row in reader:
if airport.lower() == row[0].lower():
airportCode = row[2] + "/" + row[0]
print(airportCode)
break
if airportCode is not None:
print('Sorry, I don\'t recognise that airport.')
print('Please try again.')
I had a different suggestion using functions:
import csv
def findAirportCode(airport):
with open('airport-codes.csv', encoding='Latin-1') as f:
reader = csv.reader(f, delimiter=',')
for row in reader:
if airport.lower() == row[0].lower():
airportCode = row[2] + "/" + row[0]
return airportCode
return None
airport = input('Please input the airport ICAO code: ')
code = findAirportCode(airport)
if(code != None ):
print (code)
else:
print('Sorry, I don\'t recognise that airport.')
print('Please try again.')
I think your logical flow is just a little off. If you want to continue looping through the csv file until you find the airport code, and then print an error message if the code is not there, then we need to do things in a different order. Currently, the code loops through every line of the file. And for every line, if the input code does not match any airport codes in the csv file, it prints out the message that it isn't there. Instead, we want to print the error message if it's not in ANY of the lines. We also only want one prompt per entire loop through the csv file. Instead of this:
with open('airport-codes.csv', encoding='Latin-1') as f:
reader = csv.reader(f, delimiter=',')
for row in reader: # Loop over every row in the csv
while True: # This effectively keeps you in the loop until you 'break'
airport = input('Please input the airport ICAO code: ')
if airport.lower() == row[0].lower():
airportCode = row[2] + "/" + row[0]
print(airportCode)
break # break if this row matches the airport code
else:
print('Sorry, I don\'t recognise that airport.')
print('Please try again.') # Prints if this row doesn't match
False # This doesn't set anything to 'False'
Try this:
with open('airport-codes.csv', encoding='Latin-1') as f:
reader = csv.reader(f, delimiter=',')
while True:
matches = False
airport = input('Please input the airport ICAO code:')
for row in reader:
if airport.lower() == row[0].lower():
airportCode = row[2] + "/" + row[0]
print(airportCode)
matches = True
break
if not matches:
print('Sorry, I don\'t recognise that airport.')
print('Please try again.')
False
With this code, the flow is different. First, ask for an airport code. Then check it against the file until either you reach the end of the file or you find a matching code. If the code is found in the file, print it out. If it wasn't found, print a message and ask the user for a new airport code again.
Rather than trying to match each line in your CSV with the entered input, it is best to first read your whole CSV data into a Python dictionary. This then lets you easily "look up" any airport code you like without having to keep re-reading the whole file in:
import csv
airport_codes = {}
with open('airport-codes.csv', encoding='Latin-1', newline='') as f_input:
csv_input = csv.reader(f_input, delimiter='\t')
for row in csv_input:
if len(row) >= 2: # Make sure the CSV line has at least 2 columns
airport_codes[row[0].lower()] = row[2]
while True:
icao_code = input('Please input the airport ICAO code: ').lower().strip()
try:
print("{}/{}".format(row[0], airport_codes[icao_code]))
except KeyError:
print("Sorry, I don't recognise airport.")
print("Please try again.\n")
Doing it this way would allow your script to prompt for multiple questions.
Note: The data you have posted in your question appears to be tab delimited, if that is the case, \t is needed to read the entries correctly. It is also recommended to add newline='' to your open() statement if it is going to be used with a CSV reader as can be seen in the documentation.
The try and except is what is called exception handling, in this case if the entry you are looking for in the dictionary is not present, the code jumps to the except part. This is the preferred approach in Python.

Using the Title() in the CSV file

I have a CSV file which contains an Address field. The CSV file has Addresses outlined as the following in everything caps but I need your assistance in using the title() snippet on the append(row[1]). I have tried doing:
append.title(row[1]) but it does not work.
In the CSV File --------------Needs to be:
1234 PRESTON ROAD -------- 1234 Preston Road
1245 JACKSON STREET ------- 1245 Jackson Street
8547 RAINING COURT ------- 8547 Raining Court
with open('C:\\Users\\Jake\\Desktop\\My Files\\Python Files\\PermitData.csv', 'rb') as f:
reader = csv.reader(f)
next (reader)
data = list(reader)
PermitData = []
for row in data:
PermitData.append(row[0]),PermitData.append(row[1]),PermitData.append(row[2]),
PermitData.append(row[3]),PermitData.append(row[4]),PermitData.append(row[5]),
PermitData.append(row[6])
results = PermitData
for result in results:
print result
f.close()
The reason I am iterating over every row in the CSV file is the need to save the edited CSV file as a temp file before replacing the original with the edited one. I am not that articulate with Python as I am learning by doing actual projects so please forgive any stupidity in the question and coding. Please provide your kind advice and assistance.
The following code will create a new file named output.csv with the output that you asked for:
import csv
with open('C:\\Users\\Jake\\Desktop\\My Files\\Python Files\\output.csv', 'w') as out:
with open('C:\\Users\\Jake\\Desktop\\My Files\\Python Files\\PermitData.csv', 'rb') as f:
reader = csv.reader(f)
out.write(next(reader)[0].replace('\t', ' ') + '\n')
data = list(reader)
for item in data:
item = item[0].split(' ')
out.write(' '.join(
[item[0],
item[1].title(),
item[2].title()]) + '\n')
If what you want is just to print the result, try as follows:
import csv
results = []
with open('permitData.csv', 'rb') as f:
reader = csv.reader(f)
next(reader)
data = list(reader)
for item in data:
item = item[0].split(' ')
results.append(' '.join(
[item[0],
item[1].title(),
item[2].title()]))
Output:
>>> for result in results:
... print result
...
1234 Preston Road
1245 Jackson Street
8547 Raining Court
You'll need to call title() on the string you want to convert to Title Case. This should work:
append(row[1].title())
Try this:
PermitData = []
with open('C:\\Users\\Jake\\Desktop\\My Files\\Python Files\\PermitData.csv', 'rb') as f:
reader = csv.reader(f)
headers = next (reader)
for row in reader:
row = row[:1]+ [row[1].title()] + row[2:] # Assuming row[1] is your address field you need in a title case.
PermitData.append(row)
for result in PermitData:
print result
You should also note that you don't need to call f.close() when you are using the with syntax for opening a file.
The file gets closed automatically once you exit with

Categories