Validate IP address from list - python

I would like to validate IP addresses from a list that may contain incorrectly formated addresses or other garbage. If the field does not contain a properly formated field, simply continue ignoring that field.
Per How to validate IP address in Python? it seems that there are two methods two accomplish this, REGEX or socket.inet_aton().
Below is an attempt to use socket.inet_aton() to parse a CSV and check the field if it is an IPv4 address. Currently it prints the garbage or not properly formatted IP addresses. Any tips on printing the inverse, or IP that are proper IP addresses?
Update
Numeric fields are not printing in discrete octet notation, i.e. 12345 prints. How could non-octet notation be filtered out?
for data in import_text('data.csv', ','):
try:
socket.inet_aton(data)
except socket.error:
continue
print (data)

The else clause of a try/except block is executed if no exception occurred.
try:
socket.inet_aton(data)
except socket.error:
pass
else:
print(data)
But since you require it expressed as a discrete octet, your best approach is not regex, not socket.inet_aton, but a simple validation function:
def valid_ip(addr):
try:
addr = addr.strip().split(".")
except AttributeError:
return False
try:
return len(addr) == 4 and all(octet.isdigit() and int(octet) < 256
for octet in addr)
except ValueError:
return False
Then it's just:
if valid_ip(data):
print data

The print statement is in the "except" block, so it is only invoked when there is an error parsing the passed string as IP address.
Change the contents of the for loop to this:
try:
socket.inet_aton(data)
except socket.error:
continue
print (data)

According to the manual, inet_aton accepts strings with less than 3 dots:
inet_aton() also accepts strings with less than three dots; see the Unix manual page inet(3) for details.
That might be part of what's happening to you here.

you should print right after the inet_aton() call:
for data in import_text('data.csv', ','):
try:
socket.inet_aton(data)
# data is ok, otherwise a socket.error would have been raised
print(data)
except socket.error:
continue # if you don't care about "garbage"
whenever inet_aton is fed anything that is not a valid IP socket.error is raised, and control goes to the except block.

Related

how to jump a list member in python?

so I'm trying to send i message to a group of people . I want to know how can I jump to 'test2' (next list member ) if 'test1' (current list member ) got an error .
profile_id = ['test1','test2']
for ids in profile_id:
api.send_direct_message(ids,text)
for iterates trough iprofile_id. So, the variable ids will first be the element 'test 1', do whatever is inside the for loop (i.e., send message to the person that is called 'test 1'. Then ids becomes 'test2', and a message is sent to 'test2'. But you try sending a message to the list of people, not the person picked (ids). I assume that the function send_direct_message does not allow lists, so therefore you need to have your third line be api.send_direct_message(ids, text).
Why not use TRY and then EXCEPT for the relevant class?
You can then use PASS to do nothing and continue to the next.
as Menashe already said, you can use TRY, EXCEPT and PASS.
like this:
profile_id = ['test1','test2']
for ids in profile_id:
try:
api.send_direct_message(ids,text)
except:
pass
You can try to use try/except for that, but only in a case if you raise an exception in send_direct_message
profile_ids = ['test1','test2']
for index, profile_id in enumerate(profile_ids):
try:
api.send_direct_message(profile_id,text)
# assume that using just Exception is not a good tone, try to use specific exception you raise in the method here instead of just Exception
except Exception as exc:
if (index+1) >= len(profile_ids):
break
api.send_direct_message(profile_ids[index+1], text)
# but in such a case think of list index out of range error, that will be thrown when list will go to an end

Search in text file by date

I have code like this:
from datetime import datetime
from tabulate import tabulate
def search_projection_date():
projections = open('projections.txt','r').readlines()
date = input("Input projection date: ")
try:
date = date.strptime(date, "%d.%m.%Y.")
except:
print("Date input error!")
#search_projection_date()
for i in projections:
projections = i.strip("\n").split("|")
if date == projections[2]:
table = [['Code:',projections[0]],['Hall:',projections[1]],['Date:',projections[2]],['Start time:',projections[3]],['End time:', projections[4]],['Day(s):', projections[5]], ['Movie:', projections[6]], ['Price:', projections[7]]]
print (tabulate(table))
#break
else:
print("No projection on that date")
And text file like this:
0001|AAA|17.12.2017.|20:30|21:00|sunday|For a few dolars more|150
0002|BBB|17.12.2017.|19:30|21:15|saturday|March on the Drina|300
0003|GGG|19.12.2017.|18:00|19:00|tuesday|A fistful of Dolars|500
0004|GGG|16.12.2017.|21:15|00:00|sunday|The Good, the Bad and the Ugly|350
I try to search movie projections by date...
If there is a projection on the entered date it will find it and print the list, but before printing that list it will always print "Date input error" and after that list "No projection on that date". (if I put break in if statement it will print only the first found projection on entered day, withouth else statement, obvious)
Questions: How to print ONLY list of projections without "date input error" if date is correctly input.
How to print only "No projection on that date" if date is correct but there is no projection and how to ask user for input that until puts it correctly? In this way with recursion it will always throw exception and recursion search_projection_date() function.
There are a whole bunch of major problems with your code. As it happens, they showcase why some general advice we hear so often is actually good advice.
The line date = input("Input projection date: ") creates a string named date. input always returns a string. Strings in Python do not have a method called strptime. Which brings us to issue #2:
You should not catch generic exceptions. You were probably looking to trap a TypeError or ValueError in the except clause. However, you are getting an error that says AttributeError: 'str' object has no attribute 'strptime'. This is because you can't call methods that you want to exist but don't. Your except line should probably read something like except ValueError:.
Your except clause does nothing useful (beyond the problems listed above). If the string is not formatted correctly, you print a message but continue anyway. You probably want to use raise in the except clause to propagate the exception further. Luckily for you, you actually want the date to be a string, which brings us to issue #4:
Why are you attempting to convert the string to a date to begin with? You can not compare a date object and a string that you get from the file and ever expect them to be equal. You want to compare a string to a string. If you had some kind of validation in mind, that's fine, but use datetime.strptime and don't replace the original string; just raise an error if it doesn't convert properly.
The else clause in a for loop will execute whenever the loop terminates normally (i.e., without a break). Since you always iterate through all the lines, you will always trigger the else clause. You need to have another way to determine if you found matching items, like a boolean flag or a counter. I will show an example with a counter, since it is more general.
You never close your input file. Not a huge problem in this tiny example, but can cause major issues with bigger programs. Use a with block instead of raw open.
Your method of iterating through the file is not wrong per-se, but is inefficient. You load the entire file into memory, and then iterate over the lines. In Python, text files are already iterable over the lines, which is much more efficient since it only loads one line at a time into memory, and also doesn't make you process the file twice.
Combining all that, you can make your code look like this:
def search_projection_date():
counter = 0
with open('projections.txt','r') as projections:
date = input("Input projection date: ")
for line in projections:
projection = line.strip("\n").split("|")
if date == projection[2]:
table = [['Code:',projection[0]],
['Hall:',projection[1]],
['Date:',projection[2]],
['Start time:',projection[3]],
['End time:', projection[4]],
['Day(s):', projection[5]],
['Movie:', projection[6]],
['Price:', projection[7]]]
print(tabulate(table))
counter += 1
if not counter:
print("No projection on that date")
else:
print("Found {0} projections on {1}".format(counter, date))
I trusted your use of tabulate since I am not familiar with the module and have no intention of installing it. Keep in mind that the date verification is optional. If the user enters an invalid string, that's the end of it: you don't need to check for dates like 'aaaa' because they will just print No projection on that date. If you insist on keeping the verification, do it more like this:
from datetime import datetime
datetime.strftime(date, '%d.%m.%Y.')
That's it. It will raise a ValueError if the date does not match. You don't need to do anything with the result. If you want to change the error message, or return instead of raising an error, you can catch the exception:
try:
datetime.strftime(date, '%d.%m.%Y.')
except ValueError:
print('Bad date entered')
return
Notice that I am catching a very specific type of exception here, not using a generic except clause.

Determine if Host is Domain Name or IP in Python

Is there a function in Python that determines if a hostname is a domain name or an IP(v4) address?
Note, the domain name may look like: alex.foo.bar.com or even (I think this is valid): 1.2.3.com.
One of the visual differences between IP and domain address is when you delete dots in the IP address the result would be a number. So based on this difference we can check if the input string is an IP or a domain address. We remove dots in the input string and after that check if we can convert the result to an integer or we get an exception.
def is_ip(address):
return address.replace('.', '').isnumeric()
Although in some IP-Representations like dotted hexadecimal (e.g. 0xC0.0x00.0x02.0xEB) there can be both letters and numbers in the IP-Address. However the top-level-domain (.org, .com, ...) never includes numbers. Using the function below will work in even more cases than the function above.
def is_ip(address):
return not address.split('.')[-1].isalpha()
I'd use IPy to test if the string is an IP address, and if it isn't - assume it's a domain name. E.g.:
from IPy import IP
def isIP(str):
try:
IP(str)
except ValueError:
return False
return True

Try / except syntax in Python with two of the same exceptions

I am checking emails against two lists -- a list of domains and a list of individual emails.
How would I construct the following try statement --
Try: 'email in email_list'
Except DoesNotExist: 'domain in domain list' # if email not found
Except DoesNotExist: 'print error message' # if both email and domain not found
What syntax do I need to use to construct this statement?
It sounds like you're looking for something like:
if email in email_list:
# do something with email
elif domain in domain_list:
# do something with domain
else:
print "neither email nor domain found"
There is probably no need for exceptions in this case.
Why don't define two exceptions: DomainDoesNotExists, EmailDomainDoesNotExists ?
try:
'email in email_list'
except DomainDoesNotExists:
...
except EmailDomainDoesNotExists:
...
There is no way to do what you want with only one Exception type (e.g. DoesNotExists).
But you better listen to #Greg Hewgill, in this case you don't need exceptions
It is hard to know what you are trying to do. Your capitalizations are a problem. When you catch exceptions, proceed from the most specific to the general. The first handler block handles the exception and puts you out of the try-except progression.
try:
yourEmailRoutine
except DomainDoesNotExist:
##code to be carried out if domain does not exist...
print "The domain %s does not exist." % yourDomainName
Since emails are often malformed, you might want to use Greg's suggestion to deal with this in an if-elif-else progression.

Identical string return FALSE with '==' in Python, why?

The data string is receive through a socket connexion. When receiving the first example where action variable would = 'IDENTIFY', it works. But when receiving the second example where action variable would = 'MSG' it does not compare.
And the most bizarre thing, when I use Telnet instead of my socket client both are being compare successfully. But the string are the same... Is there a possibility that the string are not encode in the same way? How can I know?
data example:
data = 'IDENTIFY 54143'
or
data = 'MSG allo'
action = data.partition(' ')[0]
if action == "MSG":
self.sendMessage(data)
elif action == "IDENTIFY":
self.sendIdentify(data)
else:
print "false"
Can't reproduce your problem. To debug it, print or log the repr() of data and action: this will likely show you the cause (probably some non-visible binary byte has snuck into data, based on how you obtained it [[which you don't show us]] and hence into action).

Categories

Resources