I've been getting this error NameError: name 'filep' is not defined i need to make filep as a file path. but every time i run my code i always get this error.
i need to make the filep as a module variable instead of a parameter as well as menulist.
import csv
filep= # filepath
menulist = [] #global scope
def menu_List():
global menulist
menulist = [] # store items
try:
with open(filep) as f: # read file
reader = f.readlines()
next(reader, None) #skip the header
for row in reader:
row[2] = int(row[2].strip()) #convert string to int
row[1] = float(row[1].strip()) #convert string to float
if row[2] > 100 and row[2] < 200:
menulist.append(row)
except NameError:
raise ValueError("Variable not set")
menulist.sort(key=lambda x: x[-1])
menu_List()
You do not need global variables here, your function should accept the path as an argument and return the menu list.
import csv
def menu_List(filep):
menulist = [] # store items
try:
with open(filep) as f: # read file
reader = f.readlines()
next(reader, None) #skip the header
for row in reader:
row[2] = int(row[2].strip()) #convert string to int
row[1] = float(row[1].strip()) #convert string to float
if row[2] > 100 and row[2] < 200:
menulist.append(row)
except NameError:
raise ValueError("Variable not set")
menulist.sort(key=lambda x: x[-1])
return menulist
menulist = menu_List("a/path/goes/here")
Unrelated to your question, you can skip the header like you did or like this:
reader = f.readlines()
for row in reader[1:]: # skip the first line.
...
The answer above (which use args for fliep) is the best solution, but if you determined to not use args:
filep= 'file path you want'# filepath
menulist = [] #global scope
def menu_List():
global filep #just add one more global will make it work
global menulist
menulist = [] # store items
try:
with open(filep) as f: # read file
reader = f.readlines()
next(reader, None) #skip the header
for row in reader:
row[2] = int(row[2].strip()) #convert string to int
row[1] = float(row[1].strip()) #convert string to float
if row[2] > 100 and row[2] < 200:
menulist.append(row)
except NameError:
raise ValueError("Variable not set")
menulist.sort(key=lambda x: x[-1])
menu_List()
Extra little tip: Try prevent using global var if you can, global var slow down program's speed and eats memory, also sometime causing messy var naming.
Related
Create a function that takes a file name (and path if needed) as the argument. In the function, open and read in the file mountains.csv. Use a try/catch to be sure the file exists and is readable. If the file location is wrong or it can't be opened, print an error that begins with "Error:". (You can test it with a junk path or filename that doesn't exist.)
Split each line by the comma, and make a dictionary where the key is the mountain name (the first element) and the height is the value, the second element. Make sure to convert the height to a number. Then print the keys and values of the dictionary using .items(), in readable sentences that say, for instance, "The height of K2 is 8611 meters." Return the dictionary at the end of the function.
Reminder about print with {} in your string: use print(string.format(variable)) to fill in the {} with your variable. If there are 2 {}'s, use .format(var1, var2)
This is what I got so far:
import csv
def mountain_height(filename):
""" Read in a csv file of mountain names and heights.
Parse the lines and print the names and heights.
Return the data as a dictionary.
The key is the mountain and the height is the value.
"""
mountains = dict()
msg = "The height of {} is {} meters."
err_msg = "Error: File doesn't exist or is unreadable."
# TYPE YOUR CODE HERE.
with open('mountains.csv', 'r') as handle:
reader = csv.reader(handle, delimiter=',')
for row in reader:
name = row[0]
height = row[1]
int(height)
dictionary = {name: height}
for k,v in dictionary.items():
print(k,v)
return dictionary
And there's the csv file:
You're nearly there. You simply need to add an entry to mountains for each iteration of the loop:
mountains = dict()
with open('mountains.csv', 'r') as handle:
reader = csv.reader(handle, delimiter=',')
for row in reader:
name = row[0]
height = row[1]
mountains[name] = int(height)
Don't forget to check if the file exists! I added an extra check so the function works with or without ".csv" file extension specified.
You also want to print a nice string using msg.format(name, height)
Lastly don't return the dictionary inside of the for loop! This ends your function and you will only see one message printed out.
For bonus points you can use csv.DictReader to read CSV files more efficiently. If the CSV does not have a header column, you need to pass fieldnames (i.e. name, height) yourself.
from csv import DictReader
def mountain_height(filename):
msg = "The height of {} is {} meters."
err_msg = "Error: File doesn't exist or is unreadable."
if filename.split('.')[-1] != 'csv':
filename += '.csv'
try:
open(filename)
except FileNotFoundError:
print(err_msg)
with open(filename) as f:
reader = DictReader(f, fieldnames=['name', 'height'], delimiter=',')
mountain_heights = {
row['name']: int(row['height']) for row in reader
}
for name, height in mountain_heights.items():
print(msg.format(name, height))
return mountain_heights
I want to store all column 2 values from input file to a list
so that i can pass those value as argument to another command in script.
As of now with current code, i get only last inserted value that is "2" in list(interface_list) and because of this i am able to pass only one value to another command.
Input file :
ipaddress,intefaceid
10.170.15.16,1
10.170.15.20,3
10.170.15.20,4
10.170.15.30,2
10.170.15.16,2
Code :
import csv
def load_interfaces(ip):
f = open("ip_interface_map.csv", "r")
reader = csv.reader(f)
next(reader)
for line in reader:
if ip in line:
interface_list = []
interface_list.append(line[1])
print interface_list
# return interface_list
load_interfaces('10.170.15.16')
I think you can get it done by placing the interface_list = [] outside the for loop.
...
interface_list = []
for line in reader:
if ip in line:
interface_list.append(line[1])
...
def load_from_file():
d = {} # create empty dict
file = open("players.txt", "r")# open file for reading
line = file.readline()
file.close()# we’re done with the file
list = line.split(",")
prop = {"position":"","number":"","name":"","birth":"","id":""}
keys = (sorted(prop))
num = 0
for key in keys:
d[key] = list[num]
num += 1
return d
The problem is that whenever the loop returns to this function it reads the same line! and i want the offset to drop a new line
The problem is that you're telling the program to only read the first line of the file every time you call the function at the file.readline() statement. You should read all the file in at once into a list, then loop through the lines that have been read into the list.
Example:
def load_from_file():
with open("players.txt", "r") as myfile # open file for reading
myfile = file.readlines()
return myfile
def create_dictionary(line):
d = {}
list = line.split(",")
prop = {"position":"","number":"","name":"","birth":"","id":""}
keys = (sorted(prop))
num = 0
for key in keys:
d[key] = list[num]
num += 1
return d
data = []
filedata = load_from_file()
for line in filedata:
data.append(create_dictionary(line))
P.S. Not sure what all you're trying to do with data, but this should help you get the gist.
Using DictReader from the csv module:
def load_from_file():
with open("players.txt") as players:
fields = ["birth", "id", "name", "number", "position"]
reader = csv.DictReader(players, fields)
return list(reader)
Hello I got the following code but the loop won't work because the csv.reader is empty. The file with the csv data is opened correctly.
For Understanding:
var pokemon can be any pokemon name as string.
bot, logger and event are vars comming from the Hangoutsbot.
All needed libaries are loaded.
Code:
def pkmn_translate(bot, event, pokemon):
logger.info("translating pokemon name")
url = "https://raw.githubusercontent.com/PokeAPI/pokeapi/master/data/v2/csv/pokemon_species_names.csv"
request = urllib.request.Request(url, headers = {"User-agent":"Mozilla/5.0", "Accept-Charset":"utf-8"})
try:
data = urllib.request.urlopen(request)
csv_data = data.read()
csvstr = str(csv_data).strip("b'")
lines = csvstr.split("\\n")
f = open('{}/pokemon_species_names.csv'.format(os.path.dirname(os.path.realpath(__file__))), "w",encoding='utf8')
for line in lines:
f.write(line + "\n")
f.close()
logger.info("translating db saved")
except urllib.error.URLError as e:
logger.info("{}: Error: {}".format(event.user.full_name, json.loads(e.read().decode("utf8","ignore"))['detail']))
yield from bot.coro_send_message(event.conv, "{}: Error: {}".format(event.user.full_name, json.loads(e.read().decode("utf8","ignore"))['detail']))
return
pokemon_id = "default"
f = open('{}/pokemon_species_names.csv'.format(os.path.dirname(os.path.realpath(__file__))), 'r', encoding='utf8') # opens the csv file
try:
logger.info("DEBUG: openFile")
#Quick and dirty fix because CSV File is very big
maxInt = sys.maxsize
decrement = True
while decrement:
# decrease the maxInt value by factor 10
# as long as the OverflowError occurs.
decrement = False
try:
csv.field_size_limit(maxInt)
except OverflowError:
maxInt = int(maxInt/10)
decrement = True
logger.info("DEBUG: maxInt = {}".format(maxInt))
reader = csv.reader(f)
rows = list(reader)
for row in reader:
logger.info("DEBUG: row = {}".format(row))
for column in row:
if pokemon == column:
#DEBUG
logger.info("Info: row = {}".format(row))
#SET VAR
pokemon_id = rows[row][0]
#DEBUG
logger.info("Info: {}".format(pokemon_id))
bot.coro_send_message(event.conv, "Info: {}".format(pokemon_id))
else:
logger.info("Error: Name not in File!")
bot.coro_send_message(event.conv, "Error: Name not in File!")
else:
logger.info("DEBUG: Loop exited")
else:
logger.info("DEBUG: Loop exited")
except:
logger.info("Debug: Some error")
finally:
f.close() # closing
logger.info("Debug func: PokemonID = {}".format(pokemon_id))
yield from pokemon_id
return pokemon_id
at the for loop it has no data in the reader variable and it fails. I don't know how to get the csv.reader to work.
PS: I am an total noob at python.
your list(reader) call consumes the reader, which is empty on the for loop.
just replace
reader = csv.reader(f)
rows = list(reader)
for row in reader:
by
reader = csv.reader(f)
rows = list(reader)
for row in rows:
I'm trying to write a program by change an open file, and I need to add a new line in the print.
In the open txt.file, it shows like this (I use"_" replace blank):
Name_____Height(m)_____Weight(kg)
Bill________1.58__________58
Mary_____1.65__________43
...
And now I want to add a new row like this:
Name_____Height(m)_____Weight(kg)_____Age(year)<---The new vertical line
Bill________1.58__________58_____________15
Mary_____1.65__________43_____________17
And my code it's:
data_file = open("file.txt", "r")
print(data_file.read())
data_file.close()
So, how could I add another vertical line in the open file? Moreover, If I want to add more rows, how can I do this?
One more thing, I use the python 3.5
I wrote a little class to do everything you asked for and more. Implementation examples are done at the bottom. Let me know if this works for you.
class Feed(object):
def __init__(self, file_name, sep, naming_convention=None):
self.file_name = file_name
self.feed_item_naming = naming_convention
self.sep = sep
self.feed = self.load_feed()
def get_head(self, file=None):#lmao...
'''
Get the header
'''
if not file:
head = open(self.file_name).readline().split(self.sep)
else:
head = file[0].split(self.sep)
return head
def __repr__(self):
return repr(self.feed)
def load_feed(self):
'''
load a feed object
set the key of each item to the naming convention
if we have multiple item names we increment the name bill becomes bill_2 and then bill_3 etc...
'''
#first we open the file and grab the headers
file = [x.rstrip() for x in open(self.file_name).readlines()]
self.header = self.get_head(file)
if not self.feed_item_naming and self.feed_item_naming not in self.header:
self.feed_item_naming = self.header[0]
data = {}
for line in file[1:]:
if line != '':
line = line.split(self.sep)
pos = line[self.header.index(self.feed_item_naming)]
while pos in data:
try:
ending = int(pos[-1])+1
pos.replace(pos[-1], ending)
except:
pos = pos+'_2'
data[pos] = {}
for item in self.header:
data[pos][item] = line[self.header.index(item)]
return data
def unload_feed(self, file_name=None, sep=None):
'''
write the modified feed back out to a data file
'''
if not file_name:
file_name = self.file_name
if not sep:
sep = self.sep
with open(file_name, 'wb') as file:
for i in self.header:
if i != self.header[-1]:
file.write(i+sep)
else:
file.write(i)
file.write('\n')
for i in self.feed:
for x in self.header:
if x != self.header[-1]:
file.write(str(self.feed[i][x])+sep)
else:
file.write(str(self.feed[i][x]))
file.write('\n')
def add_key(self, key, default_value=None):
'''
Add a key to each of the items
'''
if key not in self.header:
for i in self.feed:
self.feed[i][key]=default_value
self.header.append(key)
def get_key_value(self, item, key):
'''
get the value for the items key
'''
return self.feed[item][key]
def get_item(self, item):
'''
get an individual item
'''
return self.feed[item]
def set_key_value(self, item, key, value):
'''
set the value of each items key
{item:{key:value, key:value}, item...etc}
'''
self.feed[item][key] = value
def set_key_values(self, item, key_value_dict):
'''
set multiple key values for an item
'''
for k,v in key_value_dict.iteritems():
self.set_key_value(item, k, v)
def add_item(self, item):
'''
Add a new item
'''
while item in self.feed:
try:
end = str(int(item[-1])+1)
item = item.replace(item[-1], end)
except:
item = item+'_2'
self.feed[item] = {}
self.feed[item][self.feed_item_naming] = item
for i in self.header:
if i != self.feed_item_naming:
self.feed[item][i] = None
f = Feed('file.txt', '_____', 'Name') #initialize a new feed object, make sure that all seperators are the same for each item in your file
f.add_item('Angela') #add a new item
f.set_key_values('Angela', {'Height(m)':5, 'Weight(kg)':123}) #set the new items height and weight
f.add_key('Position')#create a new key for each item
f.unload_feed() #write the feed back to the file
print(f)
If by "add a new vertical line" you mean "add a new column" to your file, you can do this with the help of the csv module.
The code below works by reading the contents of your file as a list, making the changes, and then writing the updated list back to the file. You can add rows to your file this way, as well.
import csv
with open('file.txt', 'r') as f:
reader = list(csv.reader(f, delimiter=' ')) # if your file is delimited by spaces, tabs, etc.
# include that value here. It appears that
# your file is space-delimited, but that's
# just a guess based on the info in your question.
for i,row in enumerate(reader):
if i == 0:
row.append('Age(year)')
if i == 1:
row.append('15')
if i == 2:
row.append('17')
with open('file.txt','w') as f:
wr = csv.writer(f, delimiter=' ')
for row in reader:
wr.writerow(row)
# file.txt output:
# Name Height(m) Weight(kg) Age(year)
# Bill 1.58 58 15
# Mary 1.6 43 17
This code also uses with statements when working with your file. Using either with or close() (like you included in your question) is the correct practice when working with files. A with statement is easy to use because it closes your file automatically.