I have this code :
doc = parse('sites.xml')
sites = []
for item in doc.documentElement.getElementsByTagName("site"):
try:
site = Site()
site.name = item.getElementsByTagName("name")[0].childNodes[0].nodeValue
site.start = item.getElementsByTagName("start")[0].childNodes[0].nodeValue
site.end = item.getElementsByTagName("end")[0].childNodes[0].nodeValue
site.Id = item.getElementsByTagName("id")[0].childNodes[0].nodeValue
sites.append(site)
except:
pass
for l in range(len(sites)):
print(site.name + ' ' + site.start + ' ' + site.end + ' ' + site.Id)
I got the last line repeated on output. I don't know why the value of site has changed. Normally at every iteration I create a new reference.
You are iterating len(sites) times, but never assign anything to site; it is still bound to the last value bound in the previous loop.
Just loop over sites directly:
for site in sites:
print(site.name + ' ' + site.start + ' ' + site.end + ' ' + site.Id)
Using a range(len(sites)) loop is still possible, albeit un-pythonic and needlessly verbose; you'd have to use the generated index to bind site each loop iteration with:
for l in range(len(sites)):
site = sites[l]
print(site.name + ' ' + site.start + ' ' + site.end + ' ' + site.Id)
In your second for loop (for l in range...) you're not getting the site instance. You're getting an index and storing it in l (which gives you an int), but you're never using that index to retrieve the site instance from the sites list so the variable site is still pointing to the last site created on your first for loop.
Try:
for l in range(len(sites)):
site=sites[l]
print(site.name + ' ' + site.start + ' ' + site.end + ' ' + site.Id)
or even better
for site in sites:
print(site.name + ' ' + site.start + ' ' + site.end + ' ' + site.Id)
Related
I'm trying to send an email to someone with information I've scraped from the web but I can't get the contents to send. I keep receiving empty emails. Any help would be great. I've tried all sorts of different numbers of ' and +s and i can't figure it out.
def singaporeweather():
singaporehigh=singapore_soup.find(class_='tab-temp-high').text
singaporelow=singapore_soup.find(class_='tab-temp-low').text
print('There will be highs of ' + singaporehigh + ' and lows of ' +
singaporelow + '.')
def singaporesuns():
singaporesunsets=singapore_soup.find(class_='row col-sm-5')
suns_singapore=singaporesunsets.find_all('time')
sunset_singapore=suns_singapore[1].text
sunrise_singapore=suns_singapore[0].text
print('Sunrise: ' + sunrise_singapore)
print('Sunset: ' + sunset_singapore)
def ukweather():
ukhigh= uk_soup.find('span', class_='tab-temp-high').text
uklow= uk_soup.find(class_='tab-temp-low').text
print('There will be highs of ' + ukhigh + ' and lows of ' + uklow +
'.')
def uksuns():
uk_humid = uk_soup.find('div', class_='row col-sm-5')
humidity=uk_humid.find_all('time')
sunrise_uk=humidity[0].text
sunset_uk= humidity[1].text
print('Sunrise: '+str(sunrise_uk))
print('Sunset: '+str(sunset_uk))
def ukdesc():
uk_desc=uk_soup.find('div',class_='summary-text hide-xs-only')
uk_desc_2=uk_desc.find('span')
print(uk_desc_2.text)`enter code here`
def quotes():
quote_text=quote_soup.find(class_='b-qt qt_914910 oncl_q').text
author=quote_soup.find(class_='bq-aut qa_914910 oncl_a').text
print('Daily quote:\n' + '\"'+quote_text +'\"'+ ' - ' + author +'\n')
def message():
print('Subject:Testing\n\n')
print(('Morning ' +
nameslist[random.randint(1(len(nameslist)-1))]).center(30,'*'),
end='\n'*2)
quotes()
print('UK'.center(30,'_') + '\n')
ukweather()
ukdesc()
uksuns()
print('\n' + 'Singapore'.center(30,'_') + '\n')
singaporeweather()
singaporedesc()
singaporesuns()
smtpthing.sendmail('XXX#outlook.com', 'XXX#bath.ac.uk', str(message()))
In your functions, instead of printing the results to the console, you should use return statements so that you can use the function's result in your main program. Otherwise, message() is returning null, which is why your email is empty (the main program cannot see message()'s result unless it is returned).
Try something like:
def singaporeweather():
singaporehigh=singapore_soup.find(class_='tab-temp-high').text
singaporelow=singapore_soup.find(class_='tab-temp-low').text
return 'There will be highs of ' + singaporehigh + ' and lows of ' +
singaporelow + '.'
By using a return statement like this one, you will be able to use singaporeweather()'s result in your main program, e.g.:
var result = singaporeweather()
Using returns in the rest of your methods as well, you will be able to do the following in your function message():
def message():
body = "" #your message
body += 'Subject:Testing\n\n'
body += ('Morning ' + nameslist[random.randint(1(len(nameslist)-1))]).center(30,'*')
body += quotes()
body += 'UK'.center(30,'_') + '\n'
+ ukweather()
+ ukdesc()
+ uksuns()
+ '\n' + 'Singapore'.center(30,'_') + '\n'
+ singaporeweather()
+ singaporedesc()
+ singaporesuns()
#finally, don't forget to return!
return body
Now you are returning body, now you can use message()'s result in your main program to send your email correctly:
smtpthing.sendmail('XXX#outlook.com', 'XXX#bath.ac.uk', str(message()))
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.
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))
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
I have a question. I have been really trying to learn Python. For a project, I want to make an ncurses GUI for my backup server. My backup server runs rdiff-backup, and I want to have the ncurses take in variable names and plug them into my script. I have been trying to do a lot of reading so I don't ask dumb questions.
Here is my function for running the script:
def runScript():
# Cannot concatenate 'str' and 'list' objects
#script = rdiff + rdiffArgs
script = rdiff + ' ' + rdiffVerbosity + ' ' + rdiffStatistics \
+ ' ' + clientName + '#' + clientHost + '::' + clientDir \
+ ' ' + serverDir
os.system(script)
What I originally thought would be neat was to add all the variables into a list, so I could just run say
script = rdiff + rdiffArgs
Is there a better way to do this without all the space concatenation?
Thanks for your assistance
EDIT: Let me post the whole script so far. I wasn't very clear and I really appreciate your help and patience
#!/usr/bin/env python
import os
import smtplib
# Global variables
rdiff = '/usr/bin/rdiff-backup'
rdiffVerbosity = '-v5'
rdiffStatistics = '--print-statistics'
emailSmtp = 'smtp.gmail.com'
smtpPort = '465'
emailUsername = 'reports'
emailPassword = '3kc9dl'
emailTo = 'user#domain.com'
emailFrom = 'internal#domain.com'
serverName = 'root'
serverHost = 'SV-Datasafe'
serverDir = '/srv/backup/SV-Samba01'
clientName = 'root'
clientHost = 'SV-Samba01'
clientDir = '/srv'
rdiffArgs = rdiffArgs = [rdiffVerbosity, rdiffStatistics, \
clientName + '#' + clientHost + '::' \
+clientDir + ' ' + serverDir]
time = ''
dateStamp = datetime.now()
def sendEmail():
subject = dateStamp + clientName
body = clientDir + ' on ' + clientHost + ' backed up to ' + serverName + \
' in the directory ' + serverDir + ' on ' + dateStamp
message = """\
From: %s
To: %s
Subject: %s
%s
""" % (emailFrom, emailTo, subject, body)
deliverEmail = smtplib.SMTP(emailSmtp, port=smtpPort)
deliverEmail.login(emailUsername, emailPassword)
def runScript():
# Cannot concatenate 'str' and 'list' objects
#script = rdiff + rdiffArgs
script = rdiff + ' ' + rdiffVerbosity + ' ' + rdiffStatistics \
+ ' ' + clientName + '#' + clientHost + '::' + clientDir \
+ ' ' + serverDir
os.system(script)
# TODO:: Logging
you can use format specifiers
def runScript():
script = "%s %s %s#%s %s::%s %s" %(rdiff,rdiffVerbosity,rdiffStatistics,clientName,clientHost,clientDir,serverDir)
os.system(script)
or say your rdiffArgs is already in a list
rdiffArgs = [rdiffVerbosity,rdiffStatistics,clientName,clientHost,clientDir,serverDir]
you can join them with a space
rdiffArgs = ' '.join(rdiffArgs)
lastly, just so you might want to know, you can import rdiff in your script , since rdiff-backup is written in Python
from rdiff_backup.Main import Main as backup
task=['/etc', '/tmp/backup']
backup(task)
the above backs up /etc/ to /tmp/backup. That way, you don't have to make system call to rdiff-backup. Of course, this is up to you. making system call is sometimes easier
try to use subprocess module and pass arguments as list e.g.
client = clientName + '#' + clientHost + '::' + clientDir
cmd = [rdiff, rdiffVerbosity, rdiffStatistics, client , serverDir]
p = Popen(cmd ", shell=True)
print os.waitpid(p.pid, 0)[1]
or if have args already as list use something like this
cmd = [rdiff] + args
You join paths using os.path.join
You concatenate strings like so: "".join(['a', 'b']) or ", ".join(['c', 'd'])
Which part is difficult? I am not sure I understand the question 100%
Is this it?
script = rdiff + " ".join(rdiffArgs)