Testing to see if IPv4 address is valid - python

I want to return a boolean depending if the address given is a correct IPv4 address or not. I am having an issue with the all() built in in python. I have looked up the documentation on it and it seems straight forward. That being said I can't get it to work for my expression. If you could explain how it works layman's terms and how I could correct my code, that would be great.
def IPv4_address(address):
lst_split_address = address.split(".")
slice_split_address = [int(num) for num in lst_split_address[1:]]
if address.count(".") != 3:
return False
elif address == "":
return False
else:
if all(slice_split_address) >= slice_split_address[0]:
return True
else:
return False
print IPv4_address("10.20.30.40")

As said in the documentation of all, it checks if every element in a list evaluates to True (basically bool(e) is True) or it is empty.
Now you have a list of integers in slice_split_address and so it'll check if every element of that list evaluates to True if you just call it like you do and any number other than 0 will evaluate to True, but an IP like 127.0.0.1 is actually valid.
So what you need is actually a list which contains True if the corresponding number is between 0 and 255 (inclusive):
is_valid = [0 <= e <= 255 for e in slice_split_address]
If you call then all(is_valid) it returns if every item in slice_split_address is between 0 and 255. Usually it'll be combined into something like all(0 <= e <= 255 for e in slice_split_address).
Now there is still one issue in your implementation because slice_split_address doesn't actually contain the first number of the IP address, so you might include it. Or do you actually want the first number to be lower or equal to the other three numbers?
Also your check all(…) >= … doesn't make sense as all() only returns True or False so comparing it with an integer doesn't really make sense.
Note that all(is_valid) will also return True to IP addresses like 0.0.0.0 so might need to adjust the range I used.

If you are using Python3, there is a built-in ipaddress module that you can use.
As for what is wrong with your code, I don't believe that the all() function does what you think it does. all() expects an iterable of Booleans, and returns True if every one of those Booleans is True.
To get that to work how you expected, you probably want something like
all(addr_piece >= slice_split_address[0] for addr_piece in slice_split_address)

Don't reinvent the wheel (unless you're happy to maintain the wheel). You can use a regex to validate ipv4 addresses. The following pattern is taken from Django:
r'(?:25[0-5]|2[0-4]\d|[0-1]?\d?\d)(?:\.(?:25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}'
If you are working already in the context of a Django project, you may prefer to just import their validator and use it directly:
from django.core.validators import validate_ipv4_address

As others have said, there are better ways to do this. And your algorithm doesn't actually validate IPv4 addresses. But here's a repaired version of your code.
def IPv4_address(address):
if address.count(".") != 3:
return False
elif address == "":
return False
else:
lst_split_address = address.split(".")
slice_split_address = [int(num) for num in lst_split_address[1:]]
head = slice_split_address[0]
return all(u >= head for u in slice_split_address)
print IPv4_address("10.20.30.40")
output
True
I've moved the lst_split_address stuff into the else block because there's no need to do it if the if / elif parts return False.
all(u >= head for u in slice_split_address)
uses a simple generator expression to check that all items in slice_split_address are >= the head item.

Related

Is it better to use 'elif' or consecutive 'if' statements alongside return statements?

This question is specifically regarding coding convention. I know that using if or elif in this case will produce the same results. Just wondering which is the "proper" way to construct this function:
With consecutive if:
def can_take(self, selectedCourse):
if selectedCourse.hasPassed():
return False
if selectedCourse.getPrereqs() != 'none':
for prereq in selectedCourse.getPrereqs():
if not self.courses[prereq].hasPassed():
return False
return True
With elif:
def can_take(self, selectedCourse):
if selectedCourse.hasPassed():
return False
elif selectedCourse.getPrereqs() != 'none':
for prereq in selectedCourse.getPrereqs():
if not self.courses[prereq].hasPassed():
return False
return True
If I had to choose between the two, I would probably use two if statements, but that's just a matter of personal preference.
If I had a third choice, I wouldn't have any return statements with Boolean literals. I would write a single return statement that uses and and or.
return (not selected.hasPassed()
and (selected.getPrereqs() == 'none'
or all(x.hasPassed()
for x in selected.getPrereqs()))
This is close to how you would describe this in English: you can take the class if you have not passed it, and if the class either has no prerequisites or if you have passed all the prerequisites.
As John Kugelman points out, if getPrereqs returned an empty list instead of 'none', you could further reduce this to
return (not selected.hasPassed()
or all(x.hasPassed()
for x in selected.getPrereqs())
I love the early return pattern:
Get invalid cases out of the way first, either simply exiting or raising exceptions as appropriate, put a blank line in there, then add the "real" body of the method. I find it easier to read.
Returning early keeps the nesting level down, which is great way to reduce cognitive load. I would take it one step further and flip the second if statement around so it too returns early:
def can_take(self, selectedCourse):
if selectedCourse.hasPassed():
return False
if selectedCourse.getPrereqs() == 'none':
return True
for prereq in selectedCourse.getPrereqs():
if not self.courses[prereq].hasPassed():
return False
return True
That said, some other improvements I would make:
Avoid stringly typed variables. Switch that 'none' to None.
But then, when a method returns a list don't return None when there are no results. Return an empty list. Then the caller can blindly iterate over the list without checking if it's None or empty.
def can_take(self, selectedCourse):
if selectedCourse.hasPassed():
return False
for prereq in selectedCourse.getPrereqs():
if not self.courses[prereq].hasPassed():
return False
return True
If you're comfortable with generator expressions you could even convert the loop into an all(...) call, removing the need for the final return True.
def can_take(self, selectedCourse):
if selectedCourse.hasPassed():
return False
return all(self.courses[prereq].hasPassed()
for prereq in selectedCourse.getPrereqs())
I like this because it's a more direct encoding of the question: "Has the student passed all of the prereqs?"
I think I prefer the first version. Why? When you have an if...elif...elif... thing with returns in each branch, there are two "competing" control structures: the if statement and the returns. Obviously, the returns will "win", so we might as well remove the elif stuff. Either that, or have just one return statement, which returns a value computed by a preceding if...elif...elif...else structure.
We use elif but please understand it depends on your problem statement.
Note: Please do not create a big ladder out of it as then it becomes difficult to maintain and debug the code.

how to return "true" or false using recursive function?

Here is my code:
def mirror(s,s2):
new=""
if s=="":
return s
new = mirror(s[1:],s2) +s[0]
if len(new)==len(s2):
if new==s2:
return True
else:
return False
def main():
print(mirror("dcba","abcd"))
main()
Programmers new to recursion tend to make the problem harder than necessary and don't trust recursion to do the work for them. For this problem to make sense recursion-wise, you need to check one character from each string, then decide to declare them different, or recurse down the strings doing the same until you run out of characters (base case.) Something like:
def mirror(s1, s2):
if not s1 or not s2: # base case
return not s1 and not s2 # if both empty, success!
if s1[0] != s2[-1]: # compare opposite ends
return False
return mirror(s1[1:], s2[:-1]) # recurse on remaining strings
If you structure your recursive function like the following you should find some success.
recurs() {
if (finalCondition) return true
if (isReflection) {
return recurs()
}
else {
return false
}
}
The idea being that you recurse through the string, checking for the end condition first. Likely this will be an empty string or something like that. Then you check to see if the reflection condition still holds. If it does, you keep recursing, if not you return false. When you return false, it will propagate all the way back up to the initial call. Likewise, if you reach the end condition, and it returns true, that means you looked over the entirety of the strings and they satisfied the reflection requirement and true will propagate.

How to fix inconsistent return statement in python?

I am new to python and i have this project I am working on a small project with two functions where the first returns the index of the first time a difference is spotted in a string. The next function does that but in a list of strings. Now, due to my being an amateur, i have used an excessive amount of if and else statements which resulted in too many return statements especially in the second function, and i get the error [R1710: inconsistent-return-statements]. How do i fix it and can anybody give me clear examples to better pieces of code? Sorry for the question being so long.
IDENTICAL = -1
def singleline_diff(line1, line2):
"""
Inputs:
line1 - first single line string
line2 - second single line string
Output:
Returns the index where the first difference between
line1 and line2 occurs.
Returns IDENTICAL if the two lines are the same.
"""
len1 = len(line1)
len2 = len(line2)
minimum_length = min(len1, len2)
if len1 != len2:
if minimum_length == 0:
return 0
for idx in range(minimum_length):
if line1[idx] == line2[idx]:
pass
else:
return idx
return idx + 1
for idx in range(len1):
if line1[idx] == line2[idx]:
pass
else:
return idx
return IDENTICAL
def multiline_diff(lines1, lines2):
"""
Inputs:
lines1 - list of single line strings
lines2 - list of single line strings
Output:
Returns a tuple containing the line number (starting from 0) and
the index in that line where the first difference between lines1
and lines2 occurs.
Returns (IDENTICAL, IDENTICAL) if the two lists are the same.
"""
line_no = singleline_diff(lines1, lines2)
len_lines1, len_lines2 = len(lines1), len(lines2)
if len_lines1 == len_lines2:
if (len_lines1 or len_lines2) == 0:
if len_lines1 == len_lines2:
return (IDENTICAL, IDENTICAL)
else:
idx = singleline_diff(lines1[line_no], lines2[line_no])
return (line_no, idx)
else:
idx = singleline_diff(lines1[line_no], lines2[line_no])
if line_no == IDENTICAL:
return (IDENTICAL, IDENTICAL)
elif line_no != IDENTICAL:
return (line_no, idx)
else:
return (line_no, 0)
Where was a semantic mistake in OP's code is in Abhishek Arya's answer
TL;DR - early return:
def your_function():
if not should_do():
return # NO RETURN VALUE!
# rest of the function
...yes, this will no longer emit the inconsistent-return-statements ;)
This Q/A pops also when you search for inconsistent-return-statements, I want to give a brief "common problems" guide for those.
Case A: return value is irrelevant, you just want to exit function early
There are cases, where there are functions (or "procedures" if you want to get technical about it) that just do something, but are not expected to have any return values AT ALL,
at the same time, there may be e.g. some sort of check at the start of the function whether this function run even makes sense, what may first come to your mind, is wrapping the whole function code in an if statement:
def your_function(article):
if display_content():
content = get_content(article)
# do some extensive logic to generate final content
# ...
print(content)
...this is oversimplified, but let's hope you can imagine how such coding can pretty quickly fall into a "spaghetti code" if there are more checks and more code in general + it also steals that one "tab" of a space that you so desperately need to fit into your project's max line length.
Luckily, same as in many other programming languages, there IS a way of an early ending of a function by returning at ANY place within the function run, meaning in any "Control Flow" - including if/elif/else, for/while loops, ...
Now you'd probably jump quick to just return None, False, etc. although it would work, you'd still get the pylint inconsistent-return-statements warning - to understand why let's see the warning's message:
Either all return statements in a function should return an
expression, or none of them should. pylint(inconsistent-return-statements)
From pylint's point of view, if you put anything after the return it will be considered as an expression. So what to do? Actually, in Python, you CAN return "nothing" (again this is not unique to Python)
def your_function(article):
if not display_content():
return
content = get_content(article)
# do some extensive logic to generate final content
# ...
print(content)
Although in Python returning "nothing" should be (and technically, to my knowledge, it is) an equivalent of return None, by physically writing "None" you are expressing the intention no matter the implicity of it.
Don't confuse this though with pylint(assignment-from-none) (Assigning result of a function call, where the function returns None) - where both "return" AND "return None" are considered as returning None!
Case B: Your function has a case when it doesn't return
Quite common mistake especially in a larger code is to create a code part which results in simply not returning anything. This is not exactly OP's case, since they used just a negation of the same condition, but pylint doesn't know that, so here's its thought process:
if SOME_CONDITION: # ok, here's just another condition
return someReturnExpression # and ok, it returns SOMETHING, let's note that
elif OPPOSITE_OF_SOME_CONDITION: # ok, here's just another condition
return someReturnExpression # and ok, it returns SOMETHING, let's note that
# WAIT ! What?! THERE WAS NO "else:"! Hmmm...
# ...what happens if both conditions fail? NOTHING WOULD BE RETURNED!
# We need to make a warning about that!
# (fact that sometimes they return SOMETHING and sometimes NOTHING)
So this inconsistent-return-statements could be resolved with
if SOME_CONDITION: # ok, here's some condition
return someReturnExpression # and ok, it returns SOMETHING, let's note that
else: # ok, here's else
return someReturnExpression # and ok, it returns SOMETHING, let's note that
# Ok, so if returns SOMETHING, else returns SOMETHING,
# so SOMETHING is returned every time! that's good!
...this in itself works, but it will generate yet another pylint issue
Unnecessary "else" after "return" pylint(no-else-return)
See python actually encourages early returns since it often leads to a cleaner code.
return during function run ENDS(/exits) the function and pylint sees that - it sees that if the condition was true, the function code would simply end there - so what it, Abhishek Arya, me and many others suggest is simply continuing with the code after the if part:
if SOME_CONDITION:
return someReturnExpression
# ... some more code ...
# ... some more code ...
return someReturnExpression
Case C: Combination
Simply don't combine "just" return with return SOMETHING,
if you really need to return None, simply explicitly return None in that case
def get_article(id):
article = find_article(id)
if article.id == 0:
return None
return article
This is just an example, this is not how you'd really check for some articles ;)
Look at the code here:
if len_lines1 == len_lines2:
return (IDENTICAL, IDENTICAL)
else:
idx = singleline_diff(lines1[line_no], lines2[line_no])
return (line_no, idx)
You could have written the above thing like:
if len_lines1 == len_lines2:
return (IDENTICAL, IDENTICAL)
idx = singleline_diff(lines1[line_no], lines2[line_no])
return (line_no, idx)
You just don't need an else block to return this expression as this part of code will automatically be called if the control doesn't go into if block. Hope it helps.

GurobiError: Unable to convert argument to an expression

can someone help me with this error?
Where shoudl I look when I get the error: GurobiError: Unable to convert argument to an expression.
I should add that i'm using Gurobi library in python
from gurobipy import*
m=Model('mymodel')
def label(c):
return "x" + str(c).translate(None, " '")
shifts = [1,2]
hours = [1,2]
games = ['bj', 'cr']
pits = [1,2]
order1 = [1,2]
order2 = [1,2,3]
combo, oi = multidict( {
(1,1,'bj',1,1,1): 100,
(1,1,'bj',1,1,2):200,
(1,1,'bj',1,1,3):200,
(1,1,'bj',1,2,1):50,
(1,1,'bj',1,2,2):70,
(1,1,'bj',1,2,3):70,
(1,1,'cr',1,1,1):400,
(1,1,'cr',1,1,2):450
})
combo= tuplelist(combo)
for s in shifts:
for t in hours:
for i in games:
for n in order1:
m.addConstr(quicksum(x[s,t,i,p,n,k] for s,t,i,p,n,k in combo.select(s,t,i,'*',n,'*'))- int(1)== 0, name=label((s,t,i,p,n,k))
Gurobi will complain if you try to add a constraint with no model variables. It looks like for some combination of variables the list enumeration will construct the empty list, ie:
m.addConstr(quicksum([]) - 1 == 0)
aka
m.addConstr(-1 == 0)
which is not possible. In fact gurobi will still throw an error in the following example as even though it is feasible the expression contains no variables.
m.addConstr(-1 <= 0)
To solve this just check the list is non-empty before adding the constraint.
This issue is fixed in Gurobi 6.0.0. There quicksum([]) returns a linear expression with value 0 (instead of a float 0.0) and this solves the original problem.
The problem in version 5.6.3 and before is the use of the so called TempConstr.
When you call addConstr, you can use the explicit "lefthandside", "operator", "righthandside" approach:
m.addConstr(quicksum([]), GRB.EQUAL, 0)
This will work without problems.
If you use TempConstr and use quicksum on an empty list, what really goes on is the following:
m.addConstr(quicksum([]) == 0)
quicksum returns 0, if the list is empty, so your statement is:
m.addConstr(0 == 0)
and 0 == 0 is converted to True, so you actually call:
m.addConstr(True)
and this is obviously something Gurobi cannot handle (but it could give a better error description).
To sum things up: If you use quicksum and there is a chance, that a list is empty, you can either check if the list is empty as suggested by blueenvelope, use the explicit approach or use a small wrapper method, if this happens quite often:
def add_constr(model, expression, name=""):
if expression is True:
return model.addConstr(0, GRB.EQUAL, 0, name)
elif expression is False:
raise Exception('`False` as constraint for {}'.format(name))
else:
return model.addConstr(expression, name)
This wrapper works for TempConstr as expression only.

Are booleans mutable in python?

I have the following code in python:
def update(request, id):
success = 0
try:
product = Mattress.objects.get(id=id)
success = 1
except Mattress.DoesNotExist:
pass
if success == 1:
return render_to_response("success.html")
else:
return render_to_response('failure.html')
Is this code a valid way to check the "success" boolean. If the code passes through the try statement, will "success" be changed to 1 or is it remaining at 0?
Answering your question:
Are booleans mutable in python?
Yes and no. Variables that are assigned a boolean value are (probably always, and definitely in this case) mutable, yes. They're also not restricted to being assigned boolean values, as variables are not staticly typed.
But the booleans True and False themselves are not mutable. They are singletons that cannot be modified.
Looking at your actual code:
if success = 1:
Is not valid syntax, you want a == there. Also, idiomatically speaking you should not use 0 and 1 for success and failure values you should use True and False. So you should refactor to something like this:
def update(request):
success = False
try:
product = Mattress.objects.get(id=id)
success = True
except Mattress.DoesNotExist:
pass
if success:
return render_to_response("success.html")
else:
return render_to_response('failure.html')
Yes. success will be changed to 1 on success.
There are a few things wrong with this snippet.
Firstly, you're not using a boolean type. Python's booleans are True and False.
Second, you're not comparing in your if statement. That line isn't valid in Python 3. What you're looking for is: if success == 1: or if success == True:
You would still be able to assign a boolean value to a variable regardless of boolean immutability. I believe they are stored as a primitive type, so they're as immutable as any other primitive type.
You should consider using an actual boolean and not an integer. You can set success to true or false and Python will interpret them as keywords to the values of 1 and 0. Using numbers can be a bit tricky as some languages interpret things different. In some languages 0 is false but any value besides 0 is considered true. However the answer to your question is yes, it will work just fine.
Probably the question you are asking is not even related with the problem you are trying to solve. I think there is a a Pythonic way to achieve what you want by:
def update(request):
try:
product = Mattress.objects.get(id=id)
except Mattress.DoesNotExist:
template_name = 'failure.html'
else:
template_name = 'success.html'
return render_to_response(template_name)
Basically if the exception is thrown, i.e., the template you will render will be 'failure.html'. On the other hand, if the query is performed successfully, 'success.html' will be rendered.

Categories