Controlling python script with CSV - python

I want to control my python script output with values in a csv:
I select a Category and some parameters like that:
csv1
or like that csv2
In my python-script I got the Values of each parameter in a list that looks like that:
A_Names = ("Anton", "Berta", "Charlie")
Ages = ("32","18","23")
Nicknames = ("Agent A", "Agent B", None)
Birthdays = ("03.03.1986", "02.02.2000", "01.01.1995")
IDs = (100, 200, 300)
The idea now is to have a script that will combine these information so the output for csv1 would be:
Anton
A_Name: Anton
Age: 32
Nickname: Agent A
Birthday: 03.03.1986
Berta
A_Name: Berta
Age: 18
Nickname: Agent B
Birthday: 02.02.2000
Charlie
A_Name: Charlie
Age: 23
Nickname: No Nickname yet
Birthday: 01.01.1995
and the output for the csv2 would be:
Anton
Nickname: Agent A
A_Name: Anton
ID: 100
Berta
Nickname: Agent B
A_Name: Berta
ID: 200
Charlie
Nickname: No Nickname yet
A_Name: Charlie
ID: 300
and of course it should also work both together in a csv3 like that, and the same outputs just after another.
So the first idea was just to code my output like that:
#let's assume i got the columns from the csv in lists like that:
Categories = ("Agents", "Agents")
Parameter1 = ("A_Name", "Nickname")
Parameter2 = ("Age", "A_Name")
Parameter3 = ("Nickname", "ID")
Parameter4 = ("Birthday")
#then the most unflexible code would look like that:
def Show_Values():
for n in range (0,len(A_Names)):
print A_Names[n]
print " %s: %s" % (Parameter1[0], A_Names[n])
print " %s: %s" % (Parameter2[0], Ages[n])
print " %s: %s" % (Parameter3[0], Nicknames[n])
print " %s: %s" % (Parameter4[0], Birthdays[n])
for n in range (0,len(A_Names)):
print A_Names[n]
print " %s: %s" % (Parameter1[1], Nicknames[n])
print " %s: %s" % (Parameter2[1], A_Names[n])
print " %s: %s" % (Parameter3[1], IDs[n])
Show_Values()
So this is very stupid code and I repeat myself there over and over and always need to add the correct value for the 2nd %s.
My question now is how can I create a smarter, shorter Code, that knows that A_Name[0] is the first Element of A_Names.
And that he should add the "%s: %s" % (parameter, value), automatically for the amount of parameters I am looking for via the csv. I think I need
the length of the row for that so two more lists from the csv:
Row0 = (Agents, A_Name, Age, Nickname, Birthday)
Row1 = (Agents, Nickname, A_Name, ID)
len(Row0)-1
len(Row1)-1
edit:
Ok thank you so far, here's my new approach, reading rows only from a csv:
import csv
with open("TableAgentsComma.csv", "rb") as file:
reader = csv.reader(file, delimiter=",")
inputHeader = next(reader)
rows=[r for r in reader]
A_Names = ["Anton", "Berta", "Charlie"]
Ages = ["32","18","23"]
Nicknames = ["Agent A", "Agent B", None]
Birthdays = ["03.03.1986", "02.02.2000", "01.01.1995"]
IDs = [100, 200, 300]
def Show_Values():
for n in range (0, len(A_Names)):
print A_Names[n]
print " %s: %s" % (rows[0][1], A_Names[n])
print " %s: %s" % (rows[0][2], Ages[n])
print " %s: %s" % (rows[0][3], Nicknames[n])
print " %s: %s" % (rows[0][4], Birthdays[n])
for n in range (0, len(A_Names)):
print A_Names[n]
print " %s: %s" % (rows[1][1], Nicknames[n])
print " %s: %s" % (rows[1][2], A_Names[n])
print " %s: %s" % (rows[1][3], IDs[n])
Show_Values()
But of course it's still an inflexible script and I would like it to respond to the csv, and generate its output depending on the amount of rows and the parameters inside.
Also I need to find out how the script will know that the parameter "ID" is found in the list IDs etc.
The csv file:
Category,Parameter1,Parameter2,Parameter3,Parameter4,Parameter5,
Agents,A_Name,Age,Nickname,Birthday,,
Agents,Nickname,A_Name,ID,,,
Agents,A_Name,Age,,,,
Agents,ID,,,,,

If you store the data as a dictionary you can look up the key based on the name in the csv file:
data = {
"A_Names" : ["Anton", "Berta", "Charlie"],
"Ages" : ["32","18","23"],
"Nicknames": ["Agent A", "Agent B", None],
"Birthdays": ["03.03.1986", "02.02.2000", "01.01.1995"],
"IDs": [100, 200, 300]
}
def Show_Values():
for row in rows:
for n in range (0, len(data["A_Names"])):
print data["A_Names"][n]
for header in row:
if header == "Agents" or header == "": # This field doesn't match any thing in the data.
continue
header = header.strip()
header += "s"
print " %s: %s" % (header, data[header][n])
Since the data is now in a dict we can look up the value based on the parameter which we got from the file. I probably should have called it "parameter" rather than "header".
Show_Values()
Output:
Anton
A_Names: Anton
Ages: 32
Nicknames: Agent A
Birthdays: 03.03.1986
Berta
A_Names: Berta
Ages: 18
Nicknames: Agent B
Birthdays: 02.02.2000
Charlie
A_Names: Charlie
Ages: 23
Nicknames: None
Birthdays: 01.01.1995
And then from the second row in the .csv:
Anton
Nicknames: Agent A
A_Names: Anton
IDs: 100
Berta
Nicknames: Agent B
A_Names: Berta
IDs: 200
Charlie
Nicknames: None
A_Names: Charlie
IDs: 300

Related

How can I store values in a dictionary with a while loop and show them as a table in python 3.0?

So the code I'm doing right now as to create a catalogue, so first it asks the user how many items he wants to add to the catalogue and the to introduce 7 attributes to this item, being name, type, color, power, light type, price and units. In addition to this I'm also storing the id (first item would be 1, second is 2, etc) and the price + taxes.
lee_entero is a function that makes sures the number introduced is positive and an integer.
To do this i do the following:
prod={}
l=[]
n= lee_entero("how many items? ")
for i in range(1,n+1):
p_nombre = input("Name: ")
p_tipo = input("Type: ")
p_color = lee_color("Color: ")
p_potencia = lee_RealPositivo("Power(K): ")
p_tipoLuz = lee_luz("Light type (amarillo, azul o blanco): ")
p_precio = lee_RealPositivo("Price without taxes: ")
if (p_precio <= 50):
print("Low price ")
elif (p_precio <= 100):
print("Medium Price ")
else:
print("High price ")
p_total = p_precio + p_precio*IVA/100
p_unidades = lee_entero("Units: ")
ids=i
prod={"Product nº":ids, "name": p_nombre, "type": p_tipo, "color": p_color, "power": p_potencia, "light type": p_tipoLuz, "price": p_precio, "total": p_total, "units": p_unidades }
l.append(prod)
i=i+1
And then I want this to be displayed as a table for which i have tried:
print("{:<15} {:<15} {:<15} {:<15} {:<15} {:<15} {:<15} {:<15} {:<15}".format("id", "Nombre", "Tipo", "Color", "Potencia", "Tipo Luz", "Precio", "Precio IVA", "Unidades"))
print("*******************************************************************************************************************************************************")
for key, value in prod.items():
elid, nombre, tipo, color, potencia, tipoluz, precio, precioiva, unidades = value
print("{:<15} {:<15} {:<15} {:<15} {:<15} {:<15} {:<15} {:<15} {:<15}".format(elid, nombre, tipo, color, potencia, tipoluz, precio, precioiva, unidades))
but this doesn't work.
Overall im looking for a way to store the values of each product and then display them as a table without importing any libraries, but right now is giving me the TypeError: cannot unpack non-iterable int object and I haven't been able to make it work, so any help is appreciated.
You are iterating over a dict, so using
for key, value in prod.items():
will generate pair
key == "Product nº"
value == ids
in the first iteration. So you are trying to unpack value, which is int. To achieve what you want, to can do something like:
for value in prod.values():
print("{:<15}".format(value),end=" ")
print()
which will print all values from the dictionary without a new line, and then add a new line at the end

Search in List; Display names based on search input

I have sought different articles here about searching data from a list, but nothing seems to be working right or is appropriate in what I am supposed to implement.
I have this pre-created module with over 500 list (they are strings, yes, but is considered as list when called into function; see code below) of names, city, email, etc. The following are just a chunk of it.
empRecords="""Jovita,Oles,8 S Haven St,Daytona Beach,Volusia,FL,6/14/1965,32114,386-248-4118,386-208-6976,joles#gmail.com,http://www.paganophilipgesq.com,;
Alesia,Hixenbaugh,9 Front St,Washington,District of Columbia,DC,3/3/2000,20001,202-646-7516,202-276-6826,alesia_hixenbaugh#hixenbaugh.org,http://www.kwikprint.com,;
Lai,Harabedian,1933 Packer Ave #2,Novato,Marin,CA,1/5/2000,94945,415-423-3294,415-926-6089,lai#gmail.com,http://www.buergimaddenscale.com,;
Brittni,Gillaspie,67 Rv Cent,Boise,Ada,ID,11/28/1974,83709,208-709-1235,208-206-9848,bgillaspie#gillaspie.com,http://www.innerlabel.com,;
Raylene,Kampa,2 Sw Nyberg Rd,Elkhart,Elkhart,IN,12/19/2001,46514,574-499-1454,574-330-1884,rkampa#kampa.org,http://www.hermarinc.com,;
Flo,Bookamer,89992 E 15th St,Alliance,Box Butte,NE,12/19/1957,69301,308-726-2182,308-250-6987,flo.bookamer#cox.net,http://www.simontonhoweschneiderpc.com,;
Jani,Biddy,61556 W 20th Ave,Seattle,King,WA,8/7/1966,98104,206-711-6498,206-395-6284,jbiddy#yahoo.com,http://www.warehouseofficepaperprod.com,;
Chauncey,Motley,63 E Aurora Dr,Orlando,Orange,FL,3/1/2000,32804,407-413-4842,407-557-8857,chauncey_motley#aol.com,http://www.affiliatedwithtravelodge.com
"""
a = empRecords.strip().split(";")
And I have the following code for searching:
import empData as x
def seecity():
empCitylist = list()
for ct in x.a:
empCt = ct.strip().split(",")
empCitylist.append(empCt)
t = sorted(empCitylist, key=lambda x: x[3])
for c in t:
city = (c[3])
print(city)
live_city = input("Enter city: ")
for cy in city:
if live_city in cy:
print(c[1])
# print("Name: "+ c[1] + ",", c[0], "| Current City: " + c[3])
Forgive my idiotic approach as I am new to Python. However, what I am trying to do is user will input the city, then the results should display the employee's last name, first name who are living in that city (I dunno if I made sense lol)
By the way, the code I used above doesn't return any answers. It just loops to the input.
Thank you for helping. Lovelots. <3
PS: the format of the empData is: first name, last name, address, city, country, birthday, zip, phone, and email
You can use the csv module to read easily a file with comma separated values
import csv
with open('test.csv', newline='') as csvfile:
records = list(csv.reader(csvfile))
def search(data, elem, index):
out = list()
for row in data:
if row[index] == elem:
out.append(row)
return out
#test
print(search(records, 'Orlando', 3))
Based on your original code, you can do it like this:
# Make list of list records, sorted by city
t = sorted((ct.strip().split(",") for ct in x.a), key=lambda x: x[3])
# List cities
print("Cities in DB:")
for c in t:
city = (c[3])
print("-", city)
# Define search function
def seecity():
live_city = input("Enter city: ")
for c in t:
if live_city == c[3]:
print("Name: "+ c[1] + ",", c[0], "| Current City: " + c[3])
seecity()
Then, after you understand what's going on, do as #Hoxha Alban suggested, and use the csv module.
The beauty of python lies in list comprehension.
empRecords="""Jovita,Oles,8 S Haven St,Daytona Beach,Volusia,FL,6/14/1965,32114,386-248-4118,386-208-6976,joles#gmail.com,http://www.paganophilipgesq.com,;
Alesia,Hixenbaugh,9 Front St,Washington,District of Columbia,DC,3/3/2000,20001,202-646-7516,202-276-6826,alesia_hixenbaugh#hixenbaugh.org,http://www.kwikprint.com,;
Lai,Harabedian,1933 Packer Ave #2,Novato,Marin,CA,1/5/2000,94945,415-423-3294,415-926-6089,lai#gmail.com,http://www.buergimaddenscale.com,;
Brittni,Gillaspie,67 Rv Cent,Boise,Ada,ID,11/28/1974,83709,208-709-1235,208-206-9848,bgillaspie#gillaspie.com,http://www.innerlabel.com,;
Raylene,Kampa,2 Sw Nyberg Rd,Elkhart,Elkhart,IN,12/19/2001,46514,574-499-1454,574-330-1884,rkampa#kampa.org,http://www.hermarinc.com,;
Flo,Bookamer,89992 E 15th St,Alliance,Box Butte,NE,12/19/1957,69301,308-726-2182,308-250-6987,flo.bookamer#cox.net,http://www.simontonhoweschneiderpc.com,;
Jani,Biddy,61556 W 20th Ave,Seattle,King,WA,8/7/1966,98104,206-711-6498,206-395-6284,jbiddy#yahoo.com,http://www.warehouseofficepaperprod.com,;
Chauncey,Motley,63 E Aurora Dr,Orlando,Orange,FL,3/1/2000,32804,407-413-4842,407-557-8857,chauncey_motley#aol.com,http://www.affiliatedwithtravelodge.com
"""
rows = empRecords.strip().split(";")
data = [ r.strip().split(",") for r in rows ]
then you can use any condition to filter the list, like
print ( [ "Name: " + emp[1] + "," + emp[0] + "| Current City: " + emp[3] for emp in data if emp[3] == "Washington" ] )
['Name: Hixenbaugh,Alesia| Current City: Washington']

How to print list of lists without extra brackets and quotes?

I'm working on assignment for my Python 3 programming class. It's a database to look up movies and the year they came out. However, I'm having a hard time printing the output without extra brackets and quotes:
# Build a dictionary containing the specified movie collection
list_2005 = [["Munich", "Steven Spielberg"]]
list_2006 = [["The Departed", "Martin Scorsese"], ["The Prestige", "Christopher Nolan"]]
list_2007 = [["Into the Wild", "Sean Penn"]]
movies = {
'2005': list_2005,
'2006': list_2006,
'2007': list_2007
}
# Prompt the user for a year
# Displaying the title(s) and directors(s) from that year
user_year = str(input("Enter a year between 2005 and 2007:\n"))
if user_year in movies:
for name in movies[user_year]:
print("%s" % ', '.join(name))
print()
elif user_year not in movies:
print("N/A")
# Display menu
user_choice = ''
while user_choice != 'q':
print("MENU\nSort by:\ny - Year\nd - Director\nt - Movie title\nq - Quit")
print()
user_choice = str(input("Choose an option:\n"))
if user_choice == 'y':
for key, value in sorted(movies.items()):
print("%s:" % key)
print(" %s" % ''.join(str(movies[key])))
# Carry out the desired option: Display movies by year,
# display movies by director, display movies by movie title, or quit
I would like this output to be:
2005:
Munich, Steven Spielberg
2006:
The Prestige, Christopher Nolan
The Departed, Martin Scorsese
etc.
The output I am getting:
2005:
['Munich', 'Steven Spielberg']
2006:
[['The Prestige', 'Christopher Nolan'], ['The Departed', 'Martin Scorsese']]
etc.
Replace
print(" %s" % ''.join(str(movies[key])))
with
print("\t" + '\n\t'.join("{}, {}".format(m[0], m[1]) for m in movies[key]))

'print key_1 + value_1+value_2 + good ' by using two dictionaries ?? nothing else

dic = {
'key_1':['val_1','val_2'],
'key_2':['val_3','val_4'],
'key_3':['val_5','val_6']
}
info = {
'i_1':'good',
'i_2':'bad'
}
for k,v in dic.items()
print 'Jack scrd'+info[i_2]+"in both subjects"+dic[val1]+'&'+dic[val2]
I know the print code is not right but gave it here for understanding what I really wanted to do here. I want only the above similar line in printing command.
The following does this. The format command allows you to easily substitute {} with the variables of your choice in a string. When it comes to the dictionary dic[k] would render all the lists which ['val_1','val_2'] is one. So you would give dic[k][0] to get the first value, and dic[k][1] to get the second value.
for k,v in dic.items():
msg = 'Jack scrd {} in both subjects {} & {}'
print msg.format(info['i_2'], dic[k][0], dic[k][1])
# Jack scrd bad in both subjects val_1 & val_2
# Jack scrd bad in both subjects val_5 & val_6
# Jack scrd bad in both subjects val_3 & val_4
Perhaps you want to do this?
Remove the for loop
print 'Jack scrd'+info['i_2']+'in both subjects'+str(dic['key_1'][0])+"&"+str(dic['key_1'][1])
you can use .join to join all list items with a given separator. If you want to print all keys of dic you can use:
dic = {
'key_1':['val_1','val_2'],
'key_2':['val_3','val_4'],
'key_3':['val_5','val_6']
}
info = {
'i_1':'good',
'i_2':'bad'
}
for keys in dic:
# .join will join all list items for a particular key with & and store it in variable subjects
subjects = ' & '.join(dic[keys])
print "jack scored " + info['i_1'] + " in both subjects " + subjects
output:
jack scored good in both subjects val_1 & val_2
jack scored good in both subjects val_5 & val_6
jack scored good in both subjects val_3 & val_4
place_iraq = {
'shrine_1' : ['karbala','imam hussein as.'],
'shrine_2' : ['najaf', 'imam ali as.'],
'yard' : ['karbala', 'wadi-us-salam'],
'shrine_3' : ['karbala', 'abbas as.']
}
type = {
't1':'shrine',
't2': 'grave yard'
}
print 'The '+str(type['t1'])+' of '+str(place_iraq['shrine_1'][1])+' is situated in ' +\
str(place_iraq['shrine_1'][0])
print 'The '+str(type['t1'])+' of '+str(place_iraq['shrine_2'][1])+' is situated in ' +\
str(place_iraq['shrine_2'][0])
print 'The '+str(type['t1'])+' of '+str(place_iraq['shrine_3'][1])+' is situated in ' +\
str(place_iraq['shrine_3'][0])
print 'The '+str(type['t2'])+' of '+str(place_iraq['yard'][1])+' is situated in ' +\
str(place_iraq['yard'][0])

Iterating through a yaml file

I am trying to iterate through a yaml file. I want to extract the contents
ipv6: "2031:31:31:31:: 2032:32:32:32:: 2033:33:33:33:: 2034:34:34:34:: 2035:35:35:35::"
Below is my code. I get the below error :
for x in self.dhcp_dict['subnets'][sub]['ipv4'].split():
TypeError: string indices must be integers, not str
Can anyone tell em where i am going wrong? Thanks
Jessi
Code:
dict = yaml.load(fd)
self.server_dict = dict['server_configs']
self.interface_dict = self.server_dict['interface']
self.dhcp_dict = self.server_dict['dhcp_config']
def configureDhcpv6(self):
pdb.set_trace()
log.info ("Writing the dhcp.conf file")
infile = open('v6.txt', 'w+')
self.lease_time = self.dhcp_dict['lease_time']
infile.write("default-lease-time %s; \n" %(self.lease_time))
infile.write("preferred-lifetime 604800;\noption dhcp-renewal-time 604800;\noption dhcp-rebinding-time 7200;\noption dhcp6.domain-search cisco.com;\noption dhcp6.preference 255;\noption dhcp6.rapid-commit;\noption dhcp6.info-refresh-time 21600;\ndhcpv6-lease-file-name /var/lib/dhcpd/dhcpd6.leases;\nauthoritative;\nlog-facility local7;\n\n")
for sub in self.dhcp_dict['subnets']:
if (sub == 'relay'):
for x in self.dhcp_dict['subnets'][sub]['ipv6'].split():
range6 = sub + "11" + " " + sub + "254"
infile.write("Subnet 6 %s/64 {\n" % (sub))
infile.write(" range6 %s;\n}\n\n" % (range6))
infile.close()
Yaml file:
dhcp_config:
lease_time: "300"
relay_server: "5.5.5.0"
subnets:
relay:
ipv4: "30.30.30.0 31.31.31.0 32.32.32.0 33.33.33.0 34.34.34.0 35.35.35.0"
ipv6: "2031:31:31:31:: 2032:32:32:32:: 2033:33:33:33:: 2034:34:34:34:: 2035:35:35:35::"
smart_relay: "31.1.1.0 32.1.1.0 33.1.1.0 34.1.1.0 35.1.1.0"
snoop: "36.36.36.0 37.37.37.0 38.38.38.0 39.39.39.0 30.30.30.0"

Categories