Find / Slicing Method issue - python

I was trying to use the find and string slicing method to extract the number at the end of the line. but I get this mismatch error because I came back with position 18 but from what I have read and research this position is suppose to be 18 am I missing something here?
str = ('X-DSPAM-Confidence:0.8475')
atpos = str.find(':')
print atpos
sppos = str.find(' ',atpos)
print sppos
host = float(str[atpos + 1:sppos])
print host

str = ('X-DSPAM-Confidence:0.8475')
atpos = str.find(':')
sppos = str.find(' ',atpos)
host = float(str[atpos + 1:])
print (host)

You should rather use the string.split method than looking for the specific position of the : delimiter,
_str = 'X-DSPAM-Confidence:0.8475'
host = float(_str.split(':')[1])
print(host)

str = ('X-DSPAM-Confidence:0.8475')
atpos = str.find(':')
sppos = str.find(' ',atpos)
host = float(str[atpos + 1:])
print host

text = "X-DSPAM-Confidence: 0.8475";
spacePos = text.find(" ")
number = text[spacePos::1]
#not really necessary but since we are just learning and playing
strippedNumber = number.lstrip();
result = float(strippedNumber)
def reprint(printed):
print printed
reprint(result)

Related

get next subnet in CIDR format

I have the following:-
start_range = "10.40.0.0/16"
end_range = "10.100.0.0/16"
I have to write a logic to iterate over all possible ranges(with same subnet mask /16) from start to end. For each subnet I will be doing some processing and then continuing to the next one.
I could achieve this in trivial way where I know, I have to increment last network octate(i.e increment 40 to 41 -> 42 -> 43 and so on).
start_subnet = "10.40.0.0/16"
end_subnet = "10.100.0.0/16"
start_val = int(start_subnet.split(".")[1])
end_val = int(end_subnet.split('.')[1])
subnet_split = start_subnet.split(".")
subnet_split[1] = "{}"
subnet_proto = ".".join(subnet_split) # "10.{}.0.0/16"
for i in range(start_val, end_val+1): # iterate from 40 to 100
cur_subnet = subnet_proto.format(i) # "10.40.0.0/16", "10.41.0.0/16" etc
# do processing on cur_subnet
Is there a better(Pythonic) way to get the next subnet(in CIDR format). May be netaddr module has something I am not aware of?
Following usage of netaddr helped me to get the expected result.
from netaddr import IPNetwork
start_range = IPNetwork("10.40.0.0/16")
end_range = IPNetwork("10.45.0.0/16")
allowed_range = []
while start_range<=end_range:
allowed_range.append(start_range)
start_range = start_range.next()
print allowed_range
This would print the following:-
[IPNetwork('10.40.0.0/16'), IPNetwork('10.41.0.0/16'),
IPNetwork('10.42.0.0/16'), IPNetwork('10.43.0.0/16'),
IPNetwork('10.44.0.0/16'), IPNetwork('10.45.0.0/16')]
This might be what you have in mind (not really well thought-through or tested, you've been warned!).
The ipaddress module is from python3 but it has a backport, just run
pip install ipaddress
to get it.
import ipaddress
def subnet_range(start_subnet, end_subnet):
start = ipaddress.ip_network(unicode(start_subnet))
end = ipaddress.ip_network(unicode(end_subnet))
assert start.prefixlen == end.prefixlen
ranges = [
n
for ipaddr in ipaddress.summarize_address_range(
list(start)[0],
list(end)[0])
for n in ipaddr.subnets(new_prefix=start.prefixlen)][:-1]
ranges.append(end)
return ranges
if __name__ == "__main__":
start_subnet = "9.250.0.0/16"
end_subnet = "10.100.0.0/16"
for r in subnet_range(start_subnet, end_subnet):
print r

return and print in python

how can I return the output of the function print () in python? I have the following function
def read_image(raw_image_path):
raw_image_path = get_one_track()
with open (raw_image_path) as raw_image_file:
content = raw_image_file.readlines()
for content in itertools.islice(content,1,len(content)):
image_id = content.split()[0]
driver_id = content.split()[2]
camera_spec = content.split()[1] + content.split()[2]
image_spec = [image_id,driver_id,camera_spec]
image_folder_file = read_img_folders_file()[0]
cam_spec=read_img_folders_file()[1]
nb = read_img_folders_file()[2]
image_path=''
for i in range(nb-1):
if cam_spec[i]== image_spec[2]:
image_path=image_folder_file[i]+'/'
raw_image= image_path+str(image_id).zfill(10)+'.png'
#print (raw_image)
return (raw image)
The problem is that when I use print (raw_image) I become all the images I need like
/home/stereo_front_left/0000001756.png
/home/stereo_front_left/0000001757.png
/home/stereo_front_left/0000001758.png
but when I try the get them outside the function I become just the first one. What can I do?
If you want to have all the raw_image outside the loop, you would need to store them in a list or somewhere and then write "return all_raw_images".
all_raw_images = []
for content in itertools.islice(content,1,len(content)):
image_id = content.split()[0]
driver_id = content.split()[2]
camera_spec = content.split()[1] + content.split()[2]
image_spec = [image_id,driver_id,camera_spec]
image_folder_file = read_img_folders_file()[0]
cam_spec=read_img_folders_file()[1]
nb = read_img_folders_file()[2]
image_path=''
for i in range(nb-1):
if cam_spec[i]== image_spec[2]:
image_path=image_folder_file[i]+'/'
raw_image= image_path+str(image_id).zfill(10)+'.png'
all_raw_images.append(raw_image)
return (all_raw_images)
You don't need to make print() return.
It is a function, not a method, so it automatically returns.
Sorry if I misunderstood your question. :)

How do i search in a telnet session output with re a string where x is a number between 1 and 99999?

import getpass
import sys
import telnetlib
import re
import smtplib
print "Pasul 1"
HOST = "route-views.routeviews.org"
user = "rviews"
password = ""
tn = telnetlib.Telnet(HOST)
tn.read_until("login: ", 5)
tn.write(user + "\r\n")
tn.read_until("Password: ", 5)
tn.write(password + "\r\n")
print tn.read_until(">", 10)
tn.write("show ip route 192.0.2.1"+"\r\n")
y = tn.read_until("free", 10)
print y
tn.write("exit"+ "\r\n")
tn.close()
print "Pasul 2"
for x in range(1,99999):
m = re.search(' Known via "bgp xxxxx"', y)
if m:
print (m.group(0))
break
else:
print False
break
x has to be a number between 1 and 99999
If i write ' Known via "bgp 6447"' it will find and print it, but if i write ' Known via "bgp xxxxx"', it returns false. Anybody knows why?
The output is this:
route-views>
show ip route 192.0.2.1
Routing entry for 192.0.2.1/32
Known via "bgp 6447", distance 20, metric 0
Tag 19214, type external
Last update from 208.74.64.40 4w0d ago
Routing Descriptor Blocks:
208.74.64.40, from 208.74.64.40, 4w0d ago
Route metric is 0, traffic share count is 1
AS Hops 1
Route tag 19214
MPLS label: none
route-views>
You're using regexp in a totally wrong way, try changing the whole this section:
for x in range(1,99999):
m = re.search(' Known via "bgp xxxxx"', y)
if m:
print (m.group(0))
break
else:
print False
break
with following:
m = re.search(r'Known via "bgp \d{0,5}"', y)
if m:
print m.group(0)
else:
print False
And notice r before expression, it's important here.
Probably you should read this docs for python re module: https://docs.python.org/2/library/re.html
Upd. By the way, your version does not works because x inside string is interpreted as literal "x", not the value of variable x. If you want to put a variable inside a string you should use formatting like in this example:
x = 12345
print ' Known via "bgp {}"'.format(x)
It gives me 'True' if I test
>>> y = ' Known via "bgp xxxxx"'
>>> re.search('Known via "bgp xxxxx"', y)
>>> if x:
... print "yes"
...
yes

unpack requires a string argument of length 24

I am not sure what I am doing wrong here but I am trying to open a file, trace1.flow, read the header information then throw the source IP and destination IP into dictionaries. This is done in Python running on a Fedora VM. I am getting the following error:
(secs, nsecs, booted, exporter, mySourceIP, myDestinationIP) = struct.unpack('IIIIII',myBuf)
struct.error: unpack requires a string argument of length 24
Here is my code:
import struct
import socket
#Dictionaries
uniqSource = {}
uniqDestination = {}
def int2quad(i):
z = struct.pack('!I', i)
return socket.inet_ntoa(z)
myFile = open('trace1.flow')
myBuf = myFile.read(8)
(magic, endian, version, headerLen) = struct.unpack('HBBI', myBuf)
print "Magic: ", hex(magic), "Endian: ", endian, "Version: ", version, "Header Length: ", headerLen
myFile.read(headerLen - 8)
try:
while(True):
myBuf = myFile.read(24)
(secs, nsecs, booted, exporter, mySourceIP, myDestinationIP) = struct.unpack('IIIIII',myBuf)
mySourceIP = int2quad(mySourceIP)
myDestinationIP = int2quad(myDestinationIP)
if mySourceIP not in uniqSource:
uniqSource[mySourceIP] = 1
else:
uniqSource[mySourceIP] += 1
if myDestinationIP not in uniqDestination:
uniqDestination[myDestinationIP] = 1
else:
uniqDestination[myDestinationIP] += 1
myFile.read(40)
except EOFError:
print "END OF FILE"
You seem to assume that file.read will raise EOFError on end of file, but this error is only raised by input() and raw_input(). file.read will simply return a string that's shorter than requested (possibly empty).
So you need to check the length after reading:
myBuf = myFile.read(24)
if len(myBuf) < 24:
break
Perhaps your have reached end-of-file. Check the length of myBuf:
len(myBuf)
It's probably less than 24 chars long. Also you don't need those extra parenthesis, and try to specify duplicated types using 'nI' like this:
secs, nsecs, booted, exporter, mySourceIP, myDestinationIP = struct.unpack('6I',myBuf)

Userfriendly way of handling config files in python?

I want to write a program that sends an e-mail to one or more specified recipients when a certain event occurs. For this I need the user to write the parameters for the mail server into a config. Possible values are for example: serveradress, ports, ssl(true/false) and a list of desired recipients.
Whats the user-friendliest/best-practice way to do this?
I could of course use a python file with the correct parameters and the user has to fill it out, but I wouldn't consider this user friendly. I also read about the 'config' module in python, but it seems to me that it's made for creating config files on its own, and not to have users fill the files out themselves.
Are you saying that the fact that the config file would need to be valid Python makes it unfriendly? It seems like having lines in a file like:
server = 'mail.domain.com'
port = 25
...etc would be intuitive enough while still being valid Python. If you don't want the user to have to know that they have to quote strings, though, you might go the YAML route. I use YAML pretty much exclusively for config files and find it very intuitive, and it would also be intuitive for an end user I think (though it requires a third-party module - PyYAML):
server: mail.domain.com
port: 25
Having pyyaml load it is simple:
>>> import yaml
>>> yaml.load("""a: 1
... b: foo
... """)
{'a': 1, 'b': 'foo'}
With a file it's easy too.
>>> with open('myconfig.yaml', 'r') as cfile:
... config = yaml.load(cfile)
...
config now contains all of the parameters.
I doesn't matter technically proficient your users are; you can count on them to screw up editing a text file. (They'll save it in the wrong place. They'll use MS Word to edit a text file. They'll make typos.) I suggest making a gui that validates the input and creates the configuration file in the correct format and location. A simple gui created in Tkinter would probably fit your needs.
I've been using ConfigParser. It's designed to read .ini style files that have:
[section]
option = value
It's quite easy to use and the documentation is pretty easy to read. Basically you just load the whole file into a ConfigParser object:
import ConfigParser
config = ConfigParser.ConfigParser()
config.read('configfile.txt')
Then you can make sure the users haven't messed anything up by checking the options. I do so with a list:
OPTIONS =
['section,option,defaultvalue',
.
.
.
]
for opt in OPTIONS:
section,option,defaultval = opt.split(',')
if not config.has_option(section,option):
print "Missing option %s in section %s" % (option,section)
Getting the values out is easy too.
val = config.get('section','option')
And I also wrote a function that creates a sample config file using that OPTIONS list.
new_config = ConfigParser.ConfigParser()
for opt in OPTIONS:
section,option,defaultval = opt.split(',')
if not new_config.has_section(section):
new_config.add_section(section)
new_config.set(section, option, defaultval)
with open("sample_configfile.txt", 'wb') as newconfigfile:
new_config.write(newconfigfile)
print "Generated file: sample_configfile.txt"
What are the drawbacks of such a solution:
ch = 'serveradress = %s\nport = %s\nssl = %s'
a = raw_input("Enter the server's address : ")
b = 'a'
bla = "\nEnter the port : "
while not all(x.isdigit() for x in b):
b = raw_input(bla)
bla = "Take care: you must enter digits exclusively\n"\
+" Re-enter the port (digits only) : "
c = ''
bla = "\nChoose the ssl option (t or f) : "
while c not in ('t','f'):
c = raw_input(bla)
bla = "Take care: you must type f or t exclusively\n"\
+" Re-choose the ssl option : "
with open('configfile.txt','w') as f:
f.write(ch % (a,b,c))
.
PS
I've read in the jonesy's post that the value in a config file may have to be quoted. If so, and you want the user not to have to write him/her-self the quotes, you simply add
a = a.join('""')
b = b.join('""')
c = c.join('""')
.
EDIT
ch = 'serveradress = %s\nport = %s\nssl = %s'
d = {0:('',
"Enter the server's address : "),
1:("Take care: you must enter digits exclusively",
"Enter the port : "),
2:("Take care: you must type f or t exclusively",
"Choose the ssl option (t or f) : ") }
def func(i,x):
if x is None:
return False
if i==0:
return True
elif i==1:
try:
ess = int(x)
return True
except:
return False
elif i==2:
if x in ('t','f'):
return True
else:
return False
li = len(d)*[None]
L = range(len(d))
while True:
for n in sorted(L):
bla = d[n][1]
val = None
while not func(n,val):
val = raw_input(bla)
bla = '\n '.join(d[n])
li[n] = val.join('""')
decision = ''
disp = "\n====== If you choose to process, =============="\
+"\n the content of the file will be :\n\n" \
+ ch % tuple(li) \
+ "\n==============================================="\
+ "\n\nDo you want to process (type y) or to correct (type c) : "
while decision not in ('y','c'):
decision = raw_input(disp)
disp = "Do you want to process (type y) or to correct (type c) ? : "
if decision=='y':
break
else:
diag = False
while not diag:
vi = '\nWhat lines do you want to correct ?\n'\
+'\n'.join(str(j)+' - '+line for j,line in enumerate((ch % tuple(li)).splitlines()))\
+'\nType numbers of lines belonging to range(0,'+str(len(d))+') separated by spaces) :\n'
to_modify = raw_input(vi)
try:
diag = all(int(entry) in xrange(len(d)) for entry in to_modify.split())
L = [int(entry) for entry in to_modify.split()]
except:
diag = False
with open('configfile.txt','w') as f:
f.write(ch % tuple(li))
print '-*- Recording of the config file : done -*-'

Categories

Resources