Running two separate (non-nested) for loops within one CSV file - python

I am currently trying to create a config template using CSV rows and columns as variable output into a text file for one of my network configurations. Here is the code:
import sys
import os
import csv
with open('VRRP Mapping.csv', 'rb') as f:
reader = csv.reader(f)
myfile = open('VRRP fix.txt', 'w')
next(reader, None)
myfile.write('*' * 50 + '\n' + 'VLAN interfaces for Core A\n' + '*' * 50 + '\n\n')
for row in reader:
#First, for the A side
myfile.write('interface vlan ' + str(row[0]) + '\n')
myfile.write('no ip vrrp ' + str(row[7]) + '\n')
myfile.write('ip vrrp ' + str(row[8]) + ' ' + row[9] + '\n')
myfile.write('ip vrrp ' + str(row[8]) + ' adver-int 10\n')
myfile.write('ip vrrp ' + str(row[8]) + ' backup-master enable\n')
myfile.write('ip vrrp ' + str(row[8]) + ' holddown-timer 60\n')
myfile.write('ip vrrp ' + str(row[8]) + ' priority ' + str(row[3]) + '\n')
myfile.write('ip vrrp ' + str(row[8]) + ' enable\n')
myfile.write('exit\n\n')
myfile.write('*' * 50 + '\n' + 'VLAN interfaces for Core B\n' + '*' * 50 + '\n\n')
for row in reader:
#And then the B side
myfile.write('interface vlan ' + str(row[0]) + '\n')
myfile.write('no ip vrrp ' + str(row[7]) + '\n')
myfile.write('ip vrrp ' + str(row[8]) + ' ' + row[9] + '\n')
myfile.write('ip vrrp ' + str(row[8]) + ' adver-int 10\n')
myfile.write('ip vrrp ' + str(row[8]) + ' backup-master enable\n')
myfile.write('ip vrrp ' + str(row[8]) + ' holddown-timer 60\n')
myfile.write('ip vrrp ' + str(row[8]) + ' priority ' + str(row[5]) + '\n')
myfile.write('ip vrrp ' + str(row[8]) + ' enable\n')
myfile.write('exit\n\n')
myfile.close()
The problem I am having is after the first for loop. The 'VLAN interfaces for core b' shows up, but everything in the second for loop does not output to the text file at all.
Suggestions?

If you need to read the reader twice, you need to read the file twice. Once you finish a book, you don't just keep reading and expect to find anything else. You need to go back to the beginning. To do that, use
f.seek(0)
next(reader, None)
between the for loops. Note that f is a terrible name for a file object, as also is myfile. They are not at all descriptive of what file it is or what the file is for.

You have consumed all lines in your reader object and need to start from the beginning again. Before the second for loop add:
f.seek(0)
This will bring the pointer back to the beginning of the file so you can loop over it again. http://www.tutorialspoint.com/python/file_seek.htm

Related

How to print out and make program do nothing after that python-3.x [duplicate]

This question already has answers here:
How do I terminate a script?
(14 answers)
Closed 4 months ago.
I want to print out an error code "DAT_GRESKA" or "GRESKA" in other input and then make the code do nothing but in my case it is taking me back and asking me to redo the input because its false. How do I make it to stop but without using exit() or quit().
import csv
def unos_csv():
ucsv = input("Unesi CSV datoteku: ")
if ucsv == 'raspored1.csv' or ucsv == 'raspored2.csv':
ucsv = str(ucsv)
return ucsv
else:
print('DAT_GRESKA')
return main()
def ime_predmeta():
subname = input("Unesi kod predmeta: ")
if subname.isupper():
return subname
else:
print("GRESKA")
return main()
def obrada():
file = open(unos_csv(), "r")
reader = csv.reader(file, delimiter=',')
predmet = ime_predmeta()
with open(predmet + '.txt', 'a')as a:
for row in reader:
danu_nedelji = int(row[0])
dejan = row[3].split('[')[1].split(']')[0]
if predmet in row[3]:
t1 = row[1]
t2 = row[2]
h1, m1 = t1.split(':')
h2, m2 = t2.split(':')
t11 = int(h1) * 60 + int(m1)
t22 = int(h2) * 60 + int(m2)
tkon = t22 - t11
tkon = str(tkon)
if danu_nedelji == 0:
a.write("Monday" + ' ' + row[1] + ' ' + row[2] + ' ' + tkon + ' ' + dejan + '\n')
elif danu_nedelji == 1:
a.write("Tuesday" + ' ' + row[1] + ' ' + row[2] + ' ' + tkon + ' ' + dejan + '\n')
elif danu_nedelji == 2:
a.write("Wednesday" + ' ' + row[1] + ' ' + row[2] + ' ' + tkon + ' ' + dejan + '\n')
elif danu_nedelji == 3:
a.write("Thursday" + ' ' + row[1] + ' ' + row[2] + ' ' + tkon + ' ' + dejan + '\n')
elif danu_nedelji == 4:
a.write("Friday" + ' ' + row[1] + ' ' + row[2] + ' ' + tkon + ' ' + dejan + '\n')
a.close()
def main():
obrada()
if __name__ == '__main__':
main()
I think you misunderstand how the return statement works.
The reason that your program "continues" ... it doesn't continue -- you specifically invoke your main program another time. If you simply want to go back to the calling location and continue, use
return
You used
return main()
which is a command to invoke main again, wait until it's done, and send that value back to whatever called the function.

Is there a way to solve this TypeError [duplicate]

This question already has answers here:
Why do I get an IndexError (or TypeError, or just wrong results) from "ar[i]" inside "for i in ar"?
(4 answers)
Closed 6 months ago.
I am having trouble figuring out what is wrong with my code. I need help.
next(fhr) # skip header row
customer_list = [] # initialize empty customer list
for line in fhr:
ls = line.split(',')
customer_list.append([ls[0], ls[1], ls[2], ls[3], ls[4], ls[5], ls[6], int(ls[7]), ls[8], ls[9], ls[10].strip('\n')])
from operator import itemgetter
customer_list.sort(key=itemgetter(7), reverse=True)
print(customer_list)
writepath = './loan-data-output-v1.csv'
fwh = open(writepath, 'w', encoding='utf-8')
fwh.write('Name' +','+ 'State' +','+'Age' +','+'Annual Income'+','+ 'Loan Type' +','+' Loan Amount' +','+ 'Length of Loan in Years' +','+ 'Days Delinquent' +','+ 'Interest Rate' +','+ 'Number of Loans Prior' +','+'Years as Customer' + '\n')
for i in customer_list:
if customer_list[i][7] >= 90:
fwh.write(customer_list[i][0] + ',' + customer_list[i][1] + ',' + customer_list[i][2] + ',' + customer_list[i][3] + ',' + customer_list[i][4] + ',' + customer_list[i][5] + ',' + customer_list[i][6] + ',' + customer_list[i][7] + ',' + customer_list[i][8] + ',' + customer_list[i][9] + ','+ customer_list[i][10] + '\n')
fhr.close()
fwh.close()
I am getting this error for the last for loop and I'm not sure what to do about it. Can someone help.
TypeError: list indices must be integers or slices, not list
You are using lists of lists so when you use for i in list_of_list, i itself becomes a list..
for i in customer_list:
if i[7] >= '90':
fwh.write(i[0] + ',' + i[1] + ',' + i[2] + ',' + i[3] + ',' + i[4] + ',' + i[5] + ',' + i[6] + ',' + str(i[7]) + ',' + i[8] + ',' + i[9] + ','+ i[10] + '\n')
fhr.close()
fwh.close()
Alternatively you can use,
for i in range(0,len(customer_list)):
if customer_list[i][7] >= '90':
fwh.write(customer_list[i][0] + ',' + customer_list[i][1] + ',' + customer_list[i][2] + ',' + customer_list[i][3] + ',' + customer_list[i][4] + ',' + customer_list[i][5] + ',' + customer_list[i][6] + ',' + str(customer_list[i][7]) + ',' + customer_list[i][8] + ',' + customer_list[i][9] + ','+ customer_list[i][10] + '\n')
fhr.close()
fwh.close()
EDIT: Second method assumes that your length of customer_list is constant or in other words you are not adding anything to customer_list during the loop. Thanks to DanielRoseman for pointing out potential bug in second code..
EDIT 2:
Thanks to quamrana for suggesting this way,
for i in customer_list:
if i[7] >= '90':
i[7] = str(i[7])
fwh.write(','.join(i[0:11]) + '\n')
fhr.close()
fwh.close()

Python : Calculate values and send in email

UPDATE : I have corrected my code and below is working fine as expected
Basically i need an output like below in mail.
I achieved this. but need to know if any efficient code then below one.
name 5001 5010 9000 4 %
name 5002 5010 9000 4 %
name 5003 5010 9000 4 %
name 5004 5010 9000 4 %
Storing the values in list.
Below are dummy values
container = []
for server in range(1,5):
container.append('name')
container.append(server + 5000)
container.append(5000+10)
container.append(4000+5000)
container.append(2500 % 12)
print('\n' + str(container))
Assign list of values to msgBody in order to send it via email
I'm just putting piece of code here. Below also working fine
msgBody1 = ''
for count in range(4):
if count == 0:
tempValue = '\n' + '\n' + str(container[count]) + '\t' + str(container[count+1]) + '\t' + str(container[count+2]) + '\t'
+ str(container[count+3]) + '\t' + str(container[count+4])
msgBody1 = msgBody1 + str(tempValue) + ' %'
elif count == 1:
tempValue = '\n' + '\n' + str(container[count+4]) + '\t' + str(container[count+5]) + '\t' + str(container[count+6]) + '\t'
+ str(container[count+7]) + '\t' + str(container[count+8])
msgBody1 = msgBody1 + str(tempValue) + ' %'
elif count == 2:
tempValue = '\n' + '\n' + str(container[count+8]) + '\t' + str(container[count+9]) + '\t' + str(container[count+10]) + '\t'
+ str(container[count+11]) + '\t' + str(container[count+12])
msgBody1 = msgBody1 + str(tempValue) + ' %'
elif count == 3:
tempValue = '\n' + '\n' + str(container[count+12]) + '\t' + str(container[count+13]) + '\t' + str(container[count+14]) + '\t'
+ str(container[count+15]) + '\t' + str(container[count+16])
msgBody1 = msgBody1 + str(tempValue) + ' %'
Any other better and short code to replace msgBody1
Thanks in advance
Your question is not clear; the code example does not make any sense. But from the structure of it, it seems like you are trying to use dict, but you are defining or sourcing lists.
Not sure why for server in servers, I hope your servers list is collection of numerical value, which does not make any sense.
Please go through list Vs dict, and list.append() and how to add new key, value pairs to dictionary.

why does my python script write only last line from SELECT sql query

I have a python code, which do a SELECT from mysql database, then write result to files.
In result, files /tmp/ifcfg-* is ok, but in file /tmp/route i see only last line from database query, it look like:
10.130.48.0/23 via 10.130.48.7
but i expect
10.130.48.0/23 via 10.130.48.7
192.168.156.0/22 via 192.168.156.91
10.16.234.0/29 via 10.16.234.2
10.16.234.8/29 via 10.16.234.10
what is the reason ?
get_settings = "SELECT id_srv, \
vlan, \
phys_dev_srv, \
onboot, \
inet_ntoa(subnet_ipv4), \
prefix, \
inet_ntoa(int_ipv4), \
inet_ntoa(dns_srv_01), \
inet_ntoa(dns_srv_02), \
dns_domain \
FROM interfaces_ipv4 WHERE id_srv = '%i'" % (curr_srv_id);
cursor = conn.cursor()
cursor.execute(get_settings)
rows = cursor.fetchall()
for row in rows:
with open('/tmp/ifcfg-' + row[2] + '.' + str(row[1]), 'w+') as result, \
open('/tmp/route', 'w+') as route:
result.write('# vlan ' + str(row[1]) + '\n')
result.write('VLAN=yes' + '\n')
result.write('BOOTPROTO=static' + '\n')
result.write('NAME=' + row[2] + '.' + str(row[1]) + '\n')
result.write('DEVICE=' + row[2] + '.' + str(row[1]) + '\n')
result.write('PHYSDEV=' + row[2] + '\n')
result.write('ONBOOT=' + row[3] + '\n')
result.write('IPADDR=' + row[6] + '\n')
result.write('PREFIX=' + str(row[5]) + '\n')
result.write('DNS1=' + row[7] + '\n')
result.write('DNS2=' + row[8] + '\n')
result.write('DOMAIN=' + row[9] + '\n')
route.write(row[4] + '/' + str(row[5]) + ' via ' + row[6] +'\n')
Place the with statement outside the for-loop
Ex:
cursor = conn.cursor()
cursor.execute(get_settings)
rows = cursor.fetchall()
with open('/tmp/ifcfg-' + row[2] + '.' + str(row[1]), 'w+') as result, open('/tmp/route', 'w+') as route:
for row in rows:
result.write('# vlan ' + str(row[1]) + '\n')
result.write('VLAN=yes' + '\n')
result.write('BOOTPROTO=static' + '\n')
result.write('NAME=' + row[2] + '.' + str(row[1]) + '\n')
result.write('DEVICE=' + row[2] + '.' + str(row[1]) + '\n')
result.write('PHYSDEV=' + row[2] + '\n')
result.write('ONBOOT=' + row[3] + '\n')
result.write('IPADDR=' + row[6] + '\n')
result.write('PREFIX=' + str(row[5]) + '\n')
result.write('DNS1=' + row[7] + '\n')
result.write('DNS2=' + row[8] + '\n')
result.write('DOMAIN=' + row[9] + '\n')
route.write(row[4] + '/' + str(row[5]) + ' via ' + row[6] +'\n')
Your approach is overriding the content of the file because you are opening the file each time in the forloop and writing content again.

Python: write line to file, that combine with different types

I have json, it contains next keys
[u'domain', u'_timestamp', u'meta_tags', u'author', u'title', u'url', u'tags', u'flow', u'link_tags', u'content', u'post_id', u'flags', u'polling', u'published', u'hubs', u'_id']
I need to writelines from it to .vw file.
But some of them are numeric, and some string. And I need to save this types.
Also I have file with values of target
url target
vk.com 0.934250
I use
targets = train_target.target.values.tolist()
with open('train.json') as inp_json, \
open('habr_train.vw', 'w') as out_vw:
for i, line in enumerate(tqdm_notebook(inp_json)):
data_json = json.loads(line)
if data_json['flow'] is None and data_json['author']['nickname'] is None:
res_line = str(targets[i]) + ' |title ' + data_json['title'] + ' |tags ' + ' '.join(data_json['tags']) \
+ ' |domain ' + data_json['domain'] + ' |flow None' + ' |author None' + ' |hubs ' + data_json['hubs'][0]['title'] + ' |num content_len:' + str(round(len(data_json['content']) / 1000000, 1)) + ' month:' + str(datetime.fromtimestamp(data_json['_timestamp']).month) + ' hour:' + str(datetime.fromtimestamp(data_json['_timestamp']).hour) + '\n'
elif data_json['flow'] is None:
res_line = str(targets[i]) + ' |title ' + data_json['title'] + ' |tags ' + ' '.join(data_json['tags']) \
+ ' |domain ' + data_json['domain'] + ' |flow None' + ' |author ' + data_json['author']['nickname'] + ' |hubs ' + data_json['hubs'][0]['title'] + ' |num content_len:' + str(round(len(data_json['content']) / 1000000, 1)) + ' month:' + str(datetime.fromtimestamp(data_json['_timestamp']).month) + ' hour:' + str(datetime.fromtimestamp(data_json['_timestamp']).hour) + '\n'
elif data_json['author']['nickname'] is None:
res_line = str(targets[i]) + ' |title ' + data_json['title'] + ' |tags ' + ' '.join(data_json['tags']) \
+ ' |domain ' + data_json['domain'] + ' |flow ' + data_json['flow'] + ' |author None' + ' |hubs ' + data_json['hubs'][0]['title'] + ' |num content_len:' + str(round(len(data_json['content']) / 1000000, 1)) + ' month:' + str(datetime.fromtimestamp(data_json['_timestamp']).month) + ' hour:' + str(datetime.fromtimestamp(data_json['_timestamp']).hour) + '\n'
else:
res_line = str(targets[i]) + ' |title ' + data_json['title'] + ' |tags ' + ' '.join(data_json['tags']) \
+ ' |domain ' + data_json['domain'] + ' |flow ' + data_json['flow'] + ' |author ' + data_json['author']['nickname'] + ' |hubs ' + data_json['hubs'][0]['title'] + ' |num content_len:' + str(round(len(data_json['content']) / 1000000, 1)) + ' month:' + str(datetime.fromtimestamp(data_json['_timestamp']).month) + ' hour:' + str(datetime.fromtimestamp(data_json['_timestamp']).hour) + '\n'
out_vw.write(res_line.encode('utf-8'))
It works, but next I need to use library and it returns me error, that str(targets[i]) should be float.
Is any way to save types of values?
How can I fix that?
instead of use the concatenate operator you can use format to avoid those kind of errors
example:
res_line = '{0} |title {1} |tags {2} |domain {3} |flow None |author None |hubs {4} |num content_len: {5} month: {6} hour: {7}\n'.format(str(targets[i]),data_json['title'], ' '.join(data_json['tags']), data_json['domain'], data_json['hubs'][0]['title'], str(datetime.fromtimestamp(data_json['_timestamp']).month), str(datetime.fromtimestamp(data_json['_timestamp']).hour))

Categories

Resources