- Determine whether integer is between two other integers
- 16 Answers 16
- Python – if in Range, if not in Range
- Example 1 – If Number in range()
- Example 2 – If Number not in range()
- Conclusion
- Check if numbers are in a certain range in python (with a loop)? [duplicate]
- 3 Answers 3
- Assert an integer is within range
- 4 Answers 4
- Creating your own custom assert
- Or use assertLessEqual and assertGreaterEqual
Determine whether integer is between two other integers
How do I determine whether a given integer is between two other integers (e.g. greater than/equal to 10000 and less than/equal to 30000 )?
Check your boolean operators, of course a number will be greater than 10000 if it’s greater than 30000. Look at the little details and you will catch far more mistakes.
The last edit made on this question is just putting «the solution» into the problem code. (makes the question somewhat invalid, defeats the purpose of this post I think.)
The question clearly refers to the syntax of such comparison and has nothing to do with the number >= 30000 blunder. The edit was fine.
16 Answers 16
@MikeC With the interval comparison number is first compared against 10000 . If it’s less than 10000 the expression is immediately short-circuited and the second comparison is not checked. The complexity is O(1) . in range(0, n) instead generates the entire sequence of numbers and then iterates through it. The complexity is O(n) . The complexity of in set(range(0, n)) is still O(n) because building a set has a time complexity of O(n) ics.uci.edu/~pattis/ICS-33/lectures/complexitypython.txt
@MikeC Try to run in your shell: > python -m timeit ‘10000 <= 10 <= 30000' >python -m timeit ’10 in range(10000, 30001)’ > python -m timeit ’10 in set(range(10000, 30001))’=>
looks like in python3.5.2, range is ~10x slower than the if statement, with speed constant in regard to range check value. thus most likely difference due to function overhead.
@IanElvister That’s incorrect. range no longer creates a list in Python 3. See Why is 10**15 in range(10**15+1) so fast in Python 3?
>>> r = range(1, 4) >>> 1 in r True >>> 2 in r True >>> 3 in r True >>> 4 in r False >>> 5 in r False >>> 0 in r False
Wow I always thought range (or xrange in python2) returns a generator thus you cannot repeatedly test on it.
Its important to so keep in mind that 4 in range(1,4) is False. So better use the 1 >= r
(1.) bad performance (as others have pointed out this syntax looks good but can take a long time to execute because it is O(n) operations vs the if a
To check that the number is in the range 10000 — 30000, use the Python interval comparison:
This Python feature is further described in the Python documentation.
You can also use it for the initial comparison, although it’s as useless: if 10000
There are two ways to compare three integers and check whether b is between a and c:
The first one looks like more readable, but the second one runs faster.
Let’s compare using dis.dis:
>>> dis.dis('a < b and b < c') 1 0 LOAD_NAME 0 (a) 2 LOAD_NAME 1 (b) 4 COMPARE_OP 0 (<) 6 JUMP_IF_FALSE_OR_POP 14 8 LOAD_NAME 1 (b) 10 LOAD_NAME 2 (c) 12 COMPARE_OP 0 (<) >> 14 RETURN_VALUE >>> dis.dis('a < b < c') 1 0 LOAD_NAME 0 (a) 2 LOAD_NAME 1 (b) 4 DUP_TOP 6 ROT_THREE 8 COMPARE_OP 0 (<) 10 JUMP_IF_FALSE_OR_POP 18 12 LOAD_NAME 2 (c) 14 COMPARE_OP 0 (<) 16 RETURN_VALUE >> 18 ROT_TWO 20 POP_TOP 22 RETURN_VALUE >>>
and using timeit:
also, you may use range, as suggested before, however it is much more slower.
if number >= 10000 and number
Define the range between the numbers:
if num in r: print("All right!")
range doesn't count the last value 10 in your case . range(1,11) is correct, if you need to compare between 1 and 10
Python lets you just write what you mean in words:
if number in xrange(10000, 30001): # ok you have to remember 30000 + 1 here :)
In Python3, use range instead of xrange .
edit: People seem to be more concerned with microbench marks and how cool chaining operations. My answer is about defensive (less attack surface for bugs) programming.
As a result of a claim in the comments, I've added the micro benchmark here for Python3.5.2
$ python3.5 -m timeit "5 in range(10000, 30000)" 1000000 loops, best of 3: 0.266 usec per loop $ python3.5 -m timeit "10000
If you are worried about performance, you could compute the range once
$ python3.5 -m timeit -s "R=range(10000, 30000)" "5 in R" 10000000 loops, best of 3: 0.0551 usec per loop
Python – if in Range, if not in Range
You can check if a number is present or not present in a Python range() object.
To check if given number is in a range, use Python if statement with in keyword as shown below.
if number in range(start, stop[, step]): statement(s)
number in range() expression returns a boolean value: True if number is present in the range(), False if number is not present in the range.
You can also check the other way around using not to the existing syntax.
if number not in range(start, stop[, step]): statement(s)
Now the expression: number not in range() returns True if the number is not present in the range, and False if number is present in the range.
Example 1 – If Number in range()
In this example, we will create a range object that represents some sequence of numbers, and check if a given number is present in the range or not.
Python Program
range_1 = range(2, 20, 3) number = int(input('Enter a number : ')) if number in range_1 : print(number, 'is present in the range.') else : print(number, 'is not present in the range.')
D:\workspace\python> python example.py Enter a number : 4 4 is not present in the range. D:\workspace\python> python example.py Enter a number : 5 5 is present in the range. D:\workspace\python> python example.py Enter a number : 11 11 is present in the range. D:\workspace\python> python example.py Enter a number : 12 12 is not present in the range.
Example 2 – If Number not in range()
You can also check if the number is not in range.
In this example, we will create a range object that represents some sequence of numbers, and check if a given number is not present in the range.
Python Program
range_1 = range(2, 20, 3) number = int(input('Enter a number : ')) if number not in range_1 : print(number, 'is not present in the range.') else : print(number, 'is present in the range.')
D:\workspace\python> python example.py Enter a number : 4 4 is not present in the range. D:\workspace\python> python example.py Enter a number : 5 5 is present in the range. D:\workspace\python> python example.py Enter a number : 11 11 is present in the range. D:\workspace\python> python example.py Enter a number : 12 12 is not present in the range.
Conclusion
Concluding this Python Tutorial, we learned how to check if a given number is present in the range() or not using if in range and if not in range expressions.
Check if numbers are in a certain range in python (with a loop)? [duplicate]
Basically I'm writing a program to calculate test scores but first the user has to enter the scores which are between 0 - 100. If the user enters a test score out of that range, I want the program to tell the user to rewrite that number. I don't want the program to just end with a error. How can I do that?
Create a helper function that loops forever, calling input() on every loop. When a correct value is input, return it, otherwise print an error and let the loop ask again.
3 Answers 3
while True: n = int(input("enter a number between 0 and 100: ")) if 0
Just like the code in your question, this will work both in Python 2.x and 3.x.
He doesn't have to say which he's using; the fact that he's doing int(input pretty much proves it's Py3.
@abarnert: It hints at it, but doesn't prove anything. I only write Python 2.x, yet routinely use parentheses with print() . I'd also write int(input(. )) here, just to make the code future-proof.
With all due respect, someone who's clearly a beginner is not being taught to write Python 2 code that usually also works in Python 3; he's being taught to write Python 3 code.
@abarnert: I think we are debating a trivial, irrelevant issue. I therefore propose that we leave it at that.
First, you have to know how to check whether a value is in a range. That's easy:
Almost a direct translation from English. (This is only a good solution for Python 3.0 or later, but you're clearly using Python 3.)
Next, if you want to make them keep trying until they enter something valid, just do it in a loop:
for i in range(total): while True: n = int(input("Enter a test score >> ")) if n in range(0, 101): break myList.append(n)
Again, almost a direct translation from English.
But it might be much clearer if you break this out into a separate function:
def getTestScore(): while True: n = int(input("Enter a test score >> ")) if n in range(0, 101): return n for i in range(total): n = getTestScore() myList.append(n)
As f p points out, the program will still "just end with a error" if they type something that isn't an integer, such as "A+". Handling that is a bit trickier. The int function will raise a ValueError if you give it a string that isn't a valid representation of an integer. So:
def getTestScore(): while True: try: n = int(input("Enter a test score >> ")) except ValueError: pass else: if n in range(0, 101): return n
Assert an integer is within range
I am writing some unittests in python that are testing if I receive an integer. However sometimes this integer can be off by 1 or 2 and I don't really care. Essentially I want to be able to assert that the received integer is within a certain range, something like:
self.assertBetween(998, 1000, my_integer)
Whether you use 1 or 2 asserts depends on what you really want to know and communicate. If you only care that my_integer is between the limits, one assert is a cleaner more concise means to test and communicate that to the next guy looking at the code (which maybe you in 3 months). If instead there is a good reason to know if my_integer is below 1000 separately to also knowing if my_integer is above 998, then it makes more sense to use 2 asserts.
4 Answers 4
@Yep_It's_Me: you asked if there's any benefit to this over your two separate conditionals. Yes. It's more concise, clearer, and more efficient (one function call instead of two).
@JohnZwinck while I agree this is shorter, I do not think this is something I would recommend because it has the same drawback as two assertTrue s. You lose verbosity of FAIL-message. With assertTrue , you'll get AssertionError: False is not true , which is not very helpful. I prefer to see what's wrong, so I would rather use assertGreaterEqual(my_integer, 998); assertLessEqual(my_integer, 1000) - that way you'll know what's wrong immediately (e.g.: AssertionError: 100 not greater or equal to 998 ).
the error message with this assertion wouldn't tell what was the value of my_integer or the limits (usually you don't have hard-coded limits like these). so I'd prefer the assertBetween method in @JanSpurny's answer.
Python has a built in function you may use for this: assertAlmostEqual .
self.assertAlmostEqual(myinteger, 999, delta=1) # is equivalent to self.assertTrue(998
The optional parameter delta specifies the allowed distance from the value you're testing.
I don't think it's a good idea to use assertTrue with comparison inside - that way you lose any information in FAIL message:
AssertionError: False is not true
Which is not helpful at all and you're basicaly back to "raw" assert and you are losing a lot of unittest 's methods benefits.
Creating your own custom assert
in which you can print more meaningful message. For example:
import unittest class BetweenAssertMixin(object): def assertBetween(self, x, lo, hi): if not (lo
then you'll have following output (shortened):
====================================================================== FAIL: test_too_high (__main__.Test1) ---------------------------------------------------------------------- Traceback (most recent call last): File "example.py", line 19, in test_too_high self.assertBetween(1001, 998, 1000) File "example.py", line 8, in assertBetween raise AssertionError('%r is not between %r and %r' % (x, lo, hi)) AssertionError: 1001 is not between 998 and 1000 ====================================================================== FAIL: test_too_low (__main__.Test1) ---------------------------------------------------------------------- Traceback (most recent call last): File "example.py", line 16, in test_too_low self.assertBetween(997, 998, 1000) File "example.py", line 8, in assertBetween raise AssertionError('%r is not between %r and %r' % (x, lo, hi)) AssertionError: 997 is not between 998 and 1000 ----------------------------------------------------------------------
Or use assertLessEqual and assertGreaterEqual
if you don't want custom assert (which does add another traceback record and several lines of code):
. def test_no_custom_assert(self): my_integer = 100 self.assertGreaterEqual(my_integer, 998) self.assertLessEqual(my_integer, 1000) .
which is a bit longer (it may be shorter in total than adding custom assert if it's used only once) than assertTrue(998
====================================================================== FAIL: test_no_custom_assert (__main__.Test1) ---------------------------------------------------------------------- Traceback (most recent call last): File "example.py", line 23, in test_no_custom_assert self.assertGreaterEqual(my_integer, 998) AssertionError: 100 not greater than or equal to 998