Related
Recently i tried learning to program and after finishing my first tutorial I am trying tackling some problems from codewars.com.
"You are going to be given a word. Your job is to return the middle character of the word. If the word's length is odd, return the middle character. If the word's length is even, return the middle 2 characters."
Here is my solution:
def get_middle(n):
if len(n) % 2 == 0:
return n[(len(n)/2) - 1] and n[(len(n)/2)]
else:
return n[(len(n)/2) + 0.5]
Unfortunately when executing the function with for example "abc" I always get:
Traceback (most recent call last) <ipython-input-24-46429b2608e5> in <module>
----> 1 print(get_middle("abc"))
<ipython-input-23-56ccbf5e17f7> in get_middle(n)
3 return n[(len(n)/2) - 1] and n[(len(n)/2)]
4 else:
----> 5 return n[(len(n)/2) + 1]
TypeError: string indices must be integers
I don't understand why I always get the this kind of error. Aren't all my string indices integers?
I know there are are a lot of different solutions out there, but I really would like to know why mine isn't working the way I intended it to.
Thanks in advance!
In Python, there are two kinds of division: integer division and float division.
print(4 / 2)
---> 2.0
print(4 // 2)
---> 2
in Python 2, dividing one integer to an another integer,it comes an integer.
Since Python doesn't declare data types in advance, The interpreter automatically detects the type so you never know when you want to use integers and when you want to use a float.
Since floats lose precision, it's not advised to use them in integral calculations
To solve this problem, future Python modules included a new type of division called integer division given by the operator //
Now, / performs - float division, and
// performs - integer division.
def get_middle(n):
if len(n) % 2 == 0:
return n[(len(n)//2) - 1] and n[(int(len(n)/2))]
else:
return n[int(len(n)/2+ 0.5)]
The issue with our code is that division casts integer to float type automatically and Python starts complaining about it. Simple solution would be to add second / symbol to division or in else case cast it to integer:
def get_middle(n):
if len(n) % 2 == 0:
return n[(len(n)//2) - 1] and n[(len(n)//2)]
else:
return n[int((len(n)/2) + 0.5)]
Try math.floor:
import math
def get_middle(value):
length = len(value)
if length % 2 == 0:
# even length, pick the middle 2 characters
start = length // 2 - 1
end = length // 2 + 1
else:
# odd length, pick the middle character
start = math.floor(length // 2)
end = start + 1
return value[start:end]
A suggestion if you are learning programming, try to break down your steps rather than doing it all in one line, it helps a lot when trying to understand the error messages.
If you divide an odd integer by 2 with the /operator, you get a float. This float should be explicitly converted to an integer when it is used as an indice.
I am just starting out with programming in python and programming in general.
I've made this code:
for a in range(1,1001):
for b in range(1,1001):
c2=(a**2)+(b**2)
c=c2**0.5
if type(c) == int and a+b+c == 1000:
print(a*b*c)
To find a pitagorean set with a+b+c=1000, but had no return. Code runs but doesn't print out anything and ends.
This is a euler9 problem, and I know I can find solutions on the internet but i really want to understand why this particular one that I came up with doesn't work. In my understanding it should check every pair of a and b in range of 1000 and check if for any "a^2+b^2=c^2", square root of c is an integer and a+b+c=1000.
Thanks for help
A couple of things to note:
1) The type of c will always be a float. So, type(c) == int will always evaluate to False, and your print statement will never be hit. The reason for this is because your power is a float. In general, square roots are only sanely represented as floats.
2) You almost never want to check the type of a variable in Python, and your case is no exception. What you want to do is check whether or not c has a value that is an integer, not if the type of c is an integer. To do that, use the built-in is_integer. Here's an example:
>>> x = 1 ** .5
>>> x
1.0
>>> x.is_integer()
True
>>> y = 2 ** .5
>>> y
1.4142135623730951
>>> y.is_integer()
False
>>> (4**.5).is_integer()
True
>>> (19**.5).is_integer()
False
>>> (25**.5).is_integer()
True
HTH, good luck solving the problem.
P.S. It's Pythagorean, not Pitagorean.
Try to set c as a result of 1000-a-b this should be an integer.Than compare power of c with a^2 + b^2. As you are trying to make a square root in general it doesn't give an integer so the type of this is always float. If you remove comparing c type with int your code should work.
If you want to check if the value is an integer you should try build in function is_integer().
c.is_integer()
In this code, casting from float to int is not working. It always prints a float; all integers are printed with .0 afterwards.
What is wrong?
s = str(input())
if (len(s)/2)%2 == 0:
print(len(s)/2)
else:
print(int(round(len(s)/2/2)))
the only thing you need to change in your code is :-
if (len(s)/2)%2 == 0:
print(int(len(s)/2))
this should do the trick
you only converted the result in else block to integer but not in if block
Let's do a little debugging: put in some simple test cases, and print out plenty of results.
test = ["odd len", "even len"]
for s in test:
print("test case", s, len(s), len(s)/2)
if (len(s)/2)%2 == 0:
print("EVEN", len(s)/2)
else:
print("ODD ", int(round(len(s)/2/2)))
Output:
test case odd len 7 3.5
ODD 2
test case even len 8 4.0
EVEN 4.0
Do you expect the division in your "true" branch to provide an integer? That's float division in Python 3. I think you want the lines
if (len(s)/2)%2 == 0:
print("EVEN", len(s)//2)
which will give you output
test case odd len 7 3.5
ODD 2
test case even len 8 4.0
EVEN 4
You can save some extra operations by doing the length division only once at the top:
half_len = len(s) // 2
I am trying to find the largest cube root that is a whole number, that is less than 12,000.
processing = True
n = 12000
while processing:
n -= 1
if n ** (1/3) == #checks to see if this has decimals or not
I am not sure how to check if it is a whole number or not though! I could convert it to a string then use indexing to check the end values and see whether they are zero or not, that seems rather cumbersome though. Is there a simpler way?
To check if a float value is a whole number, use the float.is_integer() method:
>>> (1.0).is_integer()
True
>>> (1.555).is_integer()
False
The method was added to the float type in Python 2.6.
Take into account that in Python 2, 1/3 is 0 (floor division for integer operands!), and that floating point arithmetic can be imprecise (a float is an approximation using binary fractions, not a precise real number). But adjusting your loop a little this gives:
>>> for n in range(12000, -1, -1):
... if (n ** (1.0/3)).is_integer():
... print n
...
27
8
1
0
which means that anything over 3 cubed, (including 10648) was missed out due to the aforementioned imprecision:
>>> (4**3) ** (1.0/3)
3.9999999999999996
>>> 10648 ** (1.0/3)
21.999999999999996
You'd have to check for numbers close to the whole number instead, or not use float() to find your number. Like rounding down the cube root of 12000:
>>> int(12000 ** (1.0/3))
22
>>> 22 ** 3
10648
If you are using Python 3.5 or newer, you can use the math.isclose() function to see if a floating point value is within a configurable margin:
>>> from math import isclose
>>> isclose((4**3) ** (1.0/3), 4)
True
>>> isclose(10648 ** (1.0/3), 22)
True
For older versions, the naive implementation of that function (skipping error checking and ignoring infinity and NaN) as mentioned in PEP485:
def isclose(a, b, rel_tol=1e-9, abs_tol=0.0):
return abs(a - b) <= max(rel_tol * max(abs(a), abs(b)), abs_tol)
We can use the modulo (%) operator. This tells us how many remainders we have when we divide x by y - expresses as x % y. Every whole number must divide by 1, so if there is a remainder, it must not be a whole number.
This function will return a boolean, True or False, depending on whether n is a whole number.
def is_whole(n):
return n % 1 == 0
You could use this:
if k == int(k):
print(str(k) + " is a whole number!")
You don't need to loop or to check anything. Just take a cube root of 12,000 and round it down:
r = int(12000**(1/3.0))
print r*r*r # 10648
You can use a modulo operation for that.
if (n ** (1.0/3)) % 1 != 0:
print("We have a decimal number here!")
How about
if x%1==0:
print "is integer"
Wouldn't it be easier to test the cube roots? Start with 20 (20**3 = 8000) and go up to 30 (30**3 = 27000). Then you have to test fewer than 10 integers.
for i in range(20, 30):
print("Trying {0}".format(i))
if i ** 3 > 12000:
print("Maximum integral cube root less than 12000: {0}".format(i - 1))
break
The above answers work for many cases but they miss some. Consider the following:
fl = sum([0.1]*10) # this is 0.9999999999999999, but we want to say it IS an int
Using this as a benchmark, some of the other suggestions don't get the behavior we might want:
fl.is_integer() # False
fl % 1 == 0 # False
Instead try:
def isclose(a, b, rel_tol=1e-09, abs_tol=0.0):
return abs(a-b) <= max(rel_tol * max(abs(a), abs(b)), abs_tol)
def is_integer(fl):
return isclose(fl, round(fl))
now we get:
is_integer(fl) # True
isclose comes with Python 3.5+, and for other Python's you can use this mostly equivalent definition (as mentioned in the corresponding PEP)
Just a side info, is_integer is doing internally:
import math
isInteger = (math.floor(x) == x)
Not exactly in python, but the cpython implementation is implemented as mentioned above.
All the answers are good but a sure fire method would be
def whole (n):
return (n*10)%10==0
The function returns True if it's a whole number else False....I know I'm a bit late but here's one of the interesting methods which I made...
Edit: as stated by the comment below, a cheaper equivalent test would be:
def whole(n):
return n%1==0
You can use something like:
num = 1.9899
bool(int(num)-num)
#returns True
if it is True, It means it holds some value, hence not a whole number. Else
num = 1.0
bool(int(num)-num)
# returns False
>>> def is_near_integer(n, precision=8, get_integer=False):
... if get_integer:
... return int(round(n, precision))
... else:
... return round(n) == round(n, precision)
...
>>> print(is_near_integer(10648 ** (1.0/3)))
True
>>> print(is_near_integer(10648 ** (1.0/3), get_integer=True))
22
>>> for i in [4.9, 5.1, 4.99, 5.01, 4.999, 5.001, 4.9999, 5.0001, 4.99999, 5.000
01, 4.999999, 5.000001]:
... print(i, is_near_integer(i, 4))
...
4.9 False
5.1 False
4.99 False
5.01 False
4.999 False
5.001 False
4.9999 False
5.0001 False
4.99999 True
5.00001 True
4.999999 True
5.000001 True
>>>
This problem has been solved, but I would like to propose an additional mathematical-based solution for funcies.
The benefit of this approach is that it calculates the whole number part of your number, which may be beneficial depending on your general task.
Algorithm:
Decompose whole number part of your number its a sum of its decimals (e.g., 327=3*100+2*10+7*1)
take difference between calculated whole number and number itself
decide whether difference is close enough to be considered an integer.
from math import ceil, log, isclose
def is_whole(x: float) -> bool:
n_digits = ceil(log(x,10)) # number of digits of decimals at or above ones
digits = [(n//(10**i))%10 for i in range(n_digits)] # parse digits of `x` at or above ones decimal
whole = 0 # will equal the whole number part of `x`
for i in range(n_digits):
decimal = 10**i
digit = digits[i]
whole += digit*decimal
diff = whole - x
return isclose(diff, 0.0)
NOTE: the idea of parsing digits of a number was realized from here
Try using:
int(val) == val
It will give lot more precision than any other methods.
You can use the round function to compute the value.
Yes in python as many have pointed when we compute the value of a cube root, it will give you an output with a little bit of error. To check if the value is a whole number you can use the following function:
def cube_integer(n):
if round(n**(1.0/3.0))**3 == n:
return True
return False
But remember that int(n) is equivalent to math.floor and because of this if you find the int(41063625**(1.0/3.0)) you will get 344 instead of 345.
So please be careful when using int withe cube roots.
Exactly how does the % operator work in Python, particularly when negative numbers are involved?
For example, why does -5 % 4 evaluate to 3, rather than, say, -1?
Unlike C or C++, Python's modulo operator (%) always return a number having the same sign as the denominator (divisor). Your expression yields 3 because
(-5) / 4 = -1.25 --> floor(-1.25) = -2
(-5) % 4 = (-2 × 4 + 3) % 4 = 3.
It is chosen over the C behavior because a nonnegative result is often more useful. An example is to compute week days. If today is Tuesday (day #2), what is the week day N days before? In Python we can compute with
return (2 - N) % 7
but in C, if N ≥ 3, we get a negative number which is an invalid number, and we need to manually fix it up by adding 7:
int result = (2 - N) % 7;
return result < 0 ? result + 7 : result;
(See http://en.wikipedia.org/wiki/Modulo_operator for how the sign of result is determined for different languages.)
Here's an explanation from Guido van Rossum:
http://python-history.blogspot.com/2010/08/why-pythons-integer-division-floors.html
Essentially, it's so that a/b = q with remainder r preserves the relationships b*q + r = a and 0 <= r < b.
In python, modulo operator works like this.
>>> mod = n - math.floor(n/base) * base
so the result is (for your case):
mod = -5 - floor(-1.25) * 4
mod = -5 - (-2*4)
mod = 3
whereas other languages such as C, JAVA, JavaScript use truncation instead of floor.
>>> mod = n - int(n/base) * base
which results in:
mod = -5 - int(-1.25) * 4
mod = -5 - (-1*4)
mod = -1
If you need more information about rounding in python, read this.
Other answers, especially the selected one have clearly answered this question quite well. But I would like to present a graphical approach that might be easier to understand as well, along with python code to perform normal mathematical modulo in python.
Python Modulo for Dummies
Modulo function is a directional function that describes how much we have to move further or behind after the mathematical jumps that we take during division over our X-axis of infinite numbers.
So let's say you were doing 7%3
So in forward direction, your answer would be +1, but in backward direction-
your answer would be -2. Both of which are correct mathematically.
Similarly, you would have 2 moduli for negative numbers as well. For eg: -7%3, can result both in -1 or +2 as shown -
Forward direction
Backward direction
In mathematics, we choose inward jumps, i.e. forward direction for a positive number and backward direction for negative numbers.
But in Python, we have a forward direction for all positive modulo operations. Hence, your confusion -
>>> -5 % 4
3
>>> 5 % 4
1
Here is the python code for inward jump type modulo in python:
def newMod(a,b):
res = a%b
return res if not res else res-b if a<0 else res
which would give -
>>> newMod(-5,4)
-1
>>> newMod(5,4)
1
Many people would oppose the inward jump method, but my personal opinion is, that this one is better!!
As pointed out, Python modulo makes a well-reasoned exception to the conventions of other languages.
This gives negative numbers a seamless behavior, especially when used in combination with the // integer-divide operator, as % modulo often is (as in math.divmod):
for n in range(-8,8):
print n, n//4, n%4
Produces:
-8 -2 0
-7 -2 1
-6 -2 2
-5 -2 3
-4 -1 0
-3 -1 1
-2 -1 2
-1 -1 3
0 0 0
1 0 1
2 0 2
3 0 3
4 1 0
5 1 1
6 1 2
7 1 3
Python % always outputs zero or positive*
Python // always rounds toward negative infinity
* ... as long as the right operand is positive. On the other hand 11 % -10 == -9
There is no one best way to handle integer division and mods with negative numbers. It would be nice if a/b was the same magnitude and opposite sign of (-a)/b. It would be nice if a % b was indeed a modulo b. Since we really want a == (a/b)*b + a%b, the first two are incompatible.
Which one to keep is a difficult question, and there are arguments for both sides. C and C++ round integer division towards zero (so a/b == -((-a)/b)), and apparently Python doesn't.
You can use:
result = numpy.fmod(x,y)
it will keep the sign , see numpy fmod() documentation.
It's also worth to mention that also the division in python is different from C:
Consider
>>> x = -10
>>> y = 37
in C you expect the result
0
what is x/y in python?
>>> print x/y
-1
and % is modulo - not the remainder! While x%y in C yields
-10
python yields.
>>> print x%y
27
You can get both as in C
The division:
>>> from math import trunc
>>> d = trunc(float(x)/y)
>>> print d
0
And the remainder (using the division from above):
>>> r = x - d*y
>>> print r
-10
This calculation is maybe not the fastest but it's working for any sign combinations of x and y to achieve the same results as in C plus it avoids conditional statements.
It's what modulo is used for. If you do a modulo through a series of numbers, it will give a cycle of values, say:
ans = num % 3
num
ans
3
0
2
2
1
1
0
0
-1
2
-2
1
-3
0
I also thought it was a strange behavior of Python. It turns out that I was not solving the division well (on paper); I was giving a value of 0 to the quotient and a value of -5 to the remainder. Terrible... I forgot the geometric representation of integers numbers. By recalling the geometry of integers given by the number line, one can get the correct values for the quotient and the remainder, and check that Python's behavior is fine. (Although I assume that you have already resolved your concern a long time ago).
#Deekshant has explained it well using visualisation. Another way to understand %(modulo) is ask a simple question.
What is nearest smaller number to dividend that can be divisible by divisor on X-axis ?
Let's have a look at few examples.
5 % 3
5 is Dividend, 3 is divisor. If you ask above question 3 is nearest smallest number that is divisible by divisor. ans would be 5 - 3 = 2. For positive Dividend, nearest smallest number would be always right side of dividend.
-5 % 3
Nearest smallest number that is divisible by 3 is -6 so ans would be -5 - (-6) = 1
-5 %4
Nearest smallest number that is divisible by 4 is -8 so ans would be -5 - (-8) = 3
Python answers every modulo expression with this method. Hope you can understand next how expression would be going to execute.
I attempted to write a general answer covering all input cases, because many people ask about various special cases (not just the one in OP, but also especially about negative values on the right-hand side) and it's really all the same question.
What does a % b actually give us in Python, explained in words?
Assuming that a and b are either float and/or int values, finite (not math.inf, math.nan etc.) and that b is not zero....
The result c is the unique number with the sign of b, such that a - c is divisible by b and abs(c) < abs(b). It will be an int when a and b are both int, and a float (even if it is exactly equal to an integer) when either a or b is an int.
For example:
>>> -9 % -5
-4
>>> 9 % 5
4
>>> -9 % 5
1
>>> 9 % -5
-1
The sign preservation also works for floating-point numbers; even when a is divisible by b, it is possible to get distinct 0.0 and -0.0 results (recalling that zero is signed in floating-point), and the sign will match b.
Proof of concept:
import math
def sign(x):
return math.copysign(1, x)
def test(a: [int, float], b: [int, float]):
c = a % b
if isinstance(a, int) and isinstance(b, int):
assert isinstance(c, int)
assert c * b >= 0 # same sign or c == 0
else:
assert isinstance(c, float)
assert sign(c) == sign(b)
assert abs(c) < abs(b)
assert math.isclose((a - c) / b, round((a - c) / b))
It's a little hard to phrase this in a way that covers all possible sign and type combinations and accounts for floating-point imprecision, but I'm pretty confident in the above. One specific gotcha for floats is that, because of that floating-point imprecision, the result for a % b might sometimes appear to give b rather than 0. In fact, it simply gives a value very close to b, because the result of the division wasn't quite exact:
>>> # On my version of Python
>>> 3.5 % 0.1
0.09999999999999981
>>> # On some other versions, it might appear as 0.1,
>>> # because of the internal rules for formatting floats for display
What if abs(a) < abs(b)?
A lot of people seem to think this is a special case, or for some reason have difficulty understanding what happens. But there is nothing special here.
For example: consider -1 % 3. How much, as a positive quantity (because 3 is positive), do we have to subtract from -1, in order to get a result divisible by 3? -1 is not divisible by 3; -1 - 1 is -2, which is also not divisible; but -1 - 2 is -3, which is divisible by 3 (dividing in exactly -1 times). By subtracting 2, we get back to divisibility; thus 2 is our predicted answer - and it checks out:
>>> -1 % 3
2
What about with b equal to zero?
It will raise ZeroDivisionError, regardless of whether b is integer zero, floating-point positive zero, or floating-point negative zero. In particular, it will not result in a NaN value.
What about special float values?
As one might expect, nan and signed infinity values for a produce a nan result, as long as b is not zero (which overrides everything else). nan values for b result in nan as well. NaN cannot be signed, so the sign of b is irrelevant in these cases.
Also as one might expect, inf % inf gives nan, regardless of the signs. If we are sharing out an infinite amount of as to an infinite amount of bs, there's no way to say "which infinity is bigger" or by how much.
The only slightly confusing cases are when b is a signed infinity value:
>>> 0 % inf
0.0
>>> 0 % -inf
-0.0
>>> 1 % inf
1.0
>>> 1 % -inf
-inf
As always, the result takes the sign of b. 0 is divisible by anything (except NaN), including infinity. But nothing else divides evenly into infinity. If a has the same sign as b, the result is simply a (as a floating-point value); if the signs differ, it will be b. Why? Well, consider -1 % inf. There isn't a finite value we can subtract from -1, in order to get to 0 (the unique value that we can divide into infinity). So we have to keep going, to infinity. The same logic applies to 1 % -inf, with all the signs reversed.
What about other types?
It's up to the type. For example, the Decimal type overloads the operator so that the result takes the sign of the numerator, even though it functionally represents the same kind of value that a float does. And, of course, strings use it for something completely different.
Why not always give a positive result, or take the sign of a?
The behaviour is motivated by integer division. While % happens to work with floating-point numbers, it's specifically designed to handle integer inputs, and the results for floats fall in line to be consistent with that.
After making the choice for a // b to give a floored division result, the % behaviour preserves a useful invariant:
>>> def check_consistency(a, b):
... assert (a // b) * b + (a % b) == a
...
>>> for a in range(-10, 11):
... for b in range(-10, 11):
... if b != 0:
... check_consistency(a, b) # no assertion is raised
...
In other words: adding the modulus value back, corrects the error created by doing an integer division.
(This, of course, lets us go back to the first section, and say that a % b simply computes a - ((a // b) * b). But that just kicks the can down the road; we still need to explain what // is doing for signed values, especially for floats.)
One practical application for this is when converting pixel coordinates to tile coordinates. // tells us which tile contains the pixel coordinate, and then % tells us the offset within that tile. Say we have 16x16 tiles: then the tile with x-coordinate 0 contains pixels with x-coordinates 0..15 inclusive, tile 1 corresponds to pixel coordinate values 16..31, and so on. If the pixel coordinate is, say, 100, we can easily calculate that it is in tile 100 // 16 == 6, and offset 100 % 16 == 4 pixels from the left edge of that tile.
We don't have to change anything in order to handle tiles on the other side of the origin. The tile at coordinate -1 needs to account for the next 16 pixel coordinates to the left of 0 - i.e., -16..-1 inclusive. And indeed, we find that e.g. -13 // 16 == -1 (so the coordinate is in that tile), and -13 % 16 == 3 (that's how far it is from the left edge of the tile).
By setting the tile width to be positive, we defined that the within-tile coordinates progress left-to-right. Therefore, knowing that a point is within a specific tile, we always want a positive result for that offset calculation. Python's % operator gives us that, on both sides of the y-axis.
What if I want it to work another way?
math.fmod will take the sign of the numerator. It will also return a floating-point result, even for two integer inputs, and raises an exception for signed-infinity a values with non-nan b values:
>>> math.fmod(-13, 16)
-13.0
>>> math.fmod(13, -16)
13.0
>>> math.fmod(1, -inf) # not -inf
1.0
>>> math.fmod(inf, 1.0) # not nan
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: math domain error
It otherwise handles special cases the same way - a zero value for b raises an exception; otherwise any nan present causes a nan result.
If this also doesn't suit your needs, then carefully define the exact desired behaviour for every possible corner case, figure out where they differ from the built-in options, and make a wrapper function.