Python3 Casting - python

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

Related

Can I make this recursion work with negative numbers?

I wrote this code and it's alright with positive numbers, but when I tried negative numbers it crashes. Can you give any hints on how to make it work with negative numbers as well? It needs to be recursive, not iterative, and to calculate the sum of the digits of an integer.
def sum_digits(n):
if n != 0:
return (n % 10 + sum_digits(n // 10))
else:
return 0
if __name__=='__main__':
print(sum_digits(123))
Input: 123
Output: 6
On the assumption that the 'sum' of the three digits of a negative number is the same as that of the absolute value of that number, this will work:
def sum_digits(n):
if n < 0:
return sum_digits(-n)
elif n != 0:
return (n % 10 + sum_digits(n // 10))
else:
return 0
That said, your actual problem here is that Python's handling of modulo for a negative number is different than you expect:
>>> -123 % 10
7
Why is that? It's because of the use of trunc() in the division. This page has a good explanation, but the short answer is that when you divide -123 by 10, in order to figure out the remainder, Python truncates in a different direction than you'd expect. (For good, if obscure, reasons.) Thus, in the above, instead of getting the expected 3 you get 7 (which is 10, your modulus, minus 3, the leftover).
Similarly, it's handling of integer division is different:
>>> -123 // 10
-13
>>> 123 // 10
12
This is un-intuitively correct because it is rounding 'down' rather than 'towards zero'. So a -12.3 rounds 'down' to -13.
These reasons are why the easiest solution to your particular problem is to simply take the absolute value prior to doing your actual calculation.
Separate your function into two functions: one, a recursive function that must always be called with a non-negative number, and two, a function that checks its argument can calls the recursive function with an appropriate argument.
def sum_digits(n):
return _recursive_sum_digits(abs(n))
def _recursive_sum_digits(n):
if n != 0:
return (n % 10 + sum_digits(n // 10))
else:
return 0
Since _recursive_sum_digits can assume its argument is non-negative, you can dispense with checking its sign on every recursive call, and guarantee that n // 10 will eventually produce 0.
If you want to just sum the digits that come after the negative sign, remove the sign by taking the absolute value of the number. If you're considering the first digit of the negative number to be a negative digit, then manually add that number in after performing this function on the rest of the digits.
Here is your hint. This is happening because the modulo operator always yields a result with the same sign as its second operand (or zero). Look at these examples:
>>> 13 % 10
3
>>> -13 % 10
7
In your specific case, a solution is to first get the absolute value of the number, and then you can go on with you approach:
def sum_digits(n):
n = abs(n)
if n != 0:
return (n % 10 + sum_digits(n // 10))
else:
return 0

Display the middle elements of a string

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.

Always int divide int = float in Python

My problem is when I divide a number like: 10 / 2 → integer / integer.
The result is 5.0 and it is float, but it shouldn't be float. The problem is Python adds 0.0 to every number accept to divide with the second number.
So I want 10/2 be integer.
I tried
x = 10
y = x/2
type(y) == int
It prints false. I want type(y) print the true result although x was a prime or odd number.
/ gives a floating point result. If you want an integer result, use //.
The reason it works like this is that if you have something like
function1() / function2()
it is possible to tell the type of the result even if you don't know the types returned by the individual functions.
Edit 1
Note that it has not always been this way. This is a "new" Python 3 behaviour, also available (but not active by default) for Python 2.2 onwards - see PEP 238. Thanks to #Steve314 for pointing this out.
Edit 2
However, it seems that what you are really trying to do is tell if one number goes exactly into another. For this you should use % (remainder)
print(15 % 5 == 0)
print(16 % 3 == 0)
This prints
True
False
Edit 3
If you want the type of the result to depend on whether the division goes exactly, you would need to do
a // b if a % b == 0 else a / b

Checking odd/even numbers and changing outputs on number size

I have a couple of problems to solve for an assignment, and am a bit stuck.
The question is to write a program that gets the user to input an odd number (check it's odd), then print an upside down pyramid of stars based on the size of the input.
For example, if you enter 5, it comes up with
*****
***
*
My problem is therefore two-fold.
1) How do I check if it's even or odd? I tried if number/2 == int in the hope that it might do something, and the internet tells me to do if number%2==0, but that doesn't work.
2) How do I change the asterisks in the middle of each line?
Any help with either problem is greatly appreciated.
Giving you the complete answer would have no point at all since this is homework, so here are a few pointers :
Even or Odd:
number % 2 == 0
definitely is a very good way to find whether your number is even.
In case you do not know %, this does modulo which is here the remainder of the division of number by 2. http://en.wikipedia.org/wiki/Modulo_operation
Printing the pyramid:
First advice: In order to print *****, you can do print "*" * 5.
Second advice: In order to center the asterisks, you need to find out how many spaces to write before the asterisks. Then you can print a bunch of spaces and asterisks with print " "*1 + "*"*3
The modulo 2 solutions with %2 is good, but that requires a division and a subtraction. Because computers use binary arithmetic, a much more efficient solution is:
# This first solution does not produce a Boolean value.
is_odd_if_zero = value & 1
# or
is_odd = (value & 1) == 1
# or
is_even = (value & 1) == 0
A few of the solutions here reference the time taken for various "is even" operations, specifically n % 2 vs n & 1, without systematically checking how this varies with the size of n, which turns out to be predictive of speed.
The short answer is that if you're using reasonably sized numbers, normally < 1e9, it doesn't make much difference. If you're using larger numbers then you probably want to be using the bitwise operator.
Here's a plot to demonstrate what's going on (with Python 3.7.3, under Linux 5.1.2):
Basically as you hit "arbitrary precision" longs things get progressively slower for modulus, while remaining constant for the bitwise op. Also, note the 10**-7 multiplier on this, i.e. I can do ~30 million (small integer) checks per second.
Here's the same plot for Python 2.7.16:
which shows the optimisation that's gone into newer versions of Python.
I've only got these versions of Python on my machine, but could rerun for other versions of there's interest. There are 51 ns between 1 and 1e100 (evenly spaced on a log scale), for each point I do the equivalent of:
timeit('n % 2', f'n={n}', number=niter)
where niter is calculated to make timeit take ~0.1 seconds, and this is repeated 5 times. The slightly awkward handling of n is to make sure we're not also benchmarking global variable lookup, which is slower than local variables. The mean of these values are used to draw the line, and the individual values are drawn as points.
Simple but yet fast:
>>> def is_odd(a):
... return bool(a - ((a>>1)<<1))
...
>>> print(is_odd(13))
True
>>> print(is_odd(12))
False
>>>
Or even simpler:
>>> def is_odd(a):
... return bool(a & 1)
1) How do I check if it's even or odd? I tried "if number/2 == int" in the hope that it might do something, and the internet tells me to do "if number%2==0", but that doesn't work.
def isEven(number):
return number % 2 == 0
if number%2==0
will tell you that it's even. So odd numbers would be the else statement there. The "%" is the mod sign which returns the remainder after dividing. So essentially we're saying if the number is divisible by two we can safely assume it's even. Otherwise it's odd (it's a perfect correlation!)
As for the asterisk placing you want to prepend the asterisks with the number of spaces correlated to the line it's on. In your example
***** line 0
*** line 1
* line 2
We'll want to space accordingly
0*****
01***
012*
la = lambda x : "even" if not x % 2 else "odd"
I guess the easiest and most basic way is this
import math
number = int (input ('Enter number: '))
if number % 2 == 0 and number != 0:
print ('Even number')
elif number == 0:
print ('Zero is neither even, nor odd.')
else:
print ('Odd number')
Just basic conditions and math. It also minds zero, which is neither even, nor odd and you give any number you want by input so it's very variable.
Regarding the printout, here's how I would do it using the Format Specification Mini Language (section: Aligning the text and specifying a width):
Once you have your length, say length = 11:
rowstring = '{{: ^{length:d}}}'.format(length = length) # center aligned, space-padded format string of length <length>
for i in xrange(length, 0, -2): # iterate from top to bottom with step size 2
print rowstring.format( '*' * i )
there are a lot of ways to check if an int value is odd or even.
I'll show you the two main ways:
number = 5
def best_way(number):
if number%2==0:
print "even"
else:
print "odd"
def binary_way(number):
if str(bin(number))[len(bin(number))-1]=='0':
print "even"
else:
print "odd"
best_way(number)
binary_way(number)
hope it helps
This is simple code. You can try it and grab the knowledge easily.
n = int(input('Enter integer : '))
if n % 2 == 3`8huhubuiiujji`:
print('digit entered is ODD')
elif n % 2 == 0 and 2 < n < 5:
print('EVEN AND in between [2,5]')
elif n % 2 == 0 and 6 < n < 20:
print('EVEN and in between [6,20]')
elif n % 2 == 0 and n > 20:
print('Even and greater than 20')
and so on...
Here's my solution:
def is_even(n):
r=n/2.0
return True if r==int(r) else False
Sample Instruction
Given an integer, n, performing the following conditional actions:
If n is odd, print Weird
If n is even and in the inclusive range of 2 to 5, print Not Weird
If n is even and in the inclusive range of 6 to 20, print Weird
If n is even and greater than 20, print Not Weird
import math
n = int(input())
if n % 2 ==1:
print("Weird")
elif n % 2==0 and n in range(2,6):
print("Not Weird")
elif n % 2 == 0 and n in range(6,21):
print("Weird")
elif n % 2==0 and n>20:
print("Not Weird")
def main():
n = float(input('odd:'))
while n % 2 == 0:
#if n % 2 == 1: No need for these lines as if it were true the while loop would not have been entered.
#break not required as the while condition will break loop
n = float(input('odd:'))
for i in range(int((n+1)/2)):
print(' '*i+'*'*int((n-2*i))+' '*i)
main()
#1st part ensures that it is an odd number that was entered.2nd part does the printing of triangular
Modulus method is the usual method. We can also do this to check if odd or even:
def f(a):
if (a//2)*2 == a:
return 'even'
else:
return 'odd'
Integer division by 2 followed by multiplication by two.
My solution basically we have two string and with the & we get the right index:
res = ["Even", "Odd"]
print(res[x & 1])
Please note that it seems slower than other alternatives:
#!/usr/bin/env python3
import math
import random
from timeit import timeit
res = ["Even", "Odd"]
def foo(x):
return res[x & 1]
def bar(x):
if x & 1:
return "Odd"
return "Even"
la = lambda x : "Even" if not x % 2 else "Odd"
iter = 10000000
time = timeit('bar(random.randint(1, 1000))', "from __main__ import bar, random", number=iter)
print(time)
time = timeit('la(random.randint(1, 1000))', "from __main__ import la, random", number=iter)
print(time)
time = timeit('foo(random.randint(1, 1000))', "from __main__ import foo, random", number=iter)
print(time)
output:
8.05739480999182
8.170479692984372
8.892275177990086
1. another odd testing function
Ok, the assignment was handed in 8+ years ago, but here is another solution based on bit shifting operations:
def isodd(i):
return(bool(i>>0&1))
testing gives:
>>> isodd(2)
False
>>> isodd(3)
True
>>> isodd(4)
False
2. Nearest Odd number alternative approach
However, instead of a code that says "give me this precise input (an integer odd number) or otherwise I won't do anything" I also like robust codes that say, "give me a number, any number, and I'll give you the nearest pyramid to that number".
In that case this function is helpful, and gives you the nearest odd (e.g. any number f such that 6<=f<8 is set to 7 and so on.)
def nearodd(f):
return int(f/2)*2+1
Example output:
nearodd(4.9)
5
nearodd(7.2)
7
nearodd(8)
9
This the function
def oddOrEven(num):
if num%2 == 0:
print("even")
else:
for i in range(num):
for j in range(i+1):
print(" ", end="")
for m in range(num-i, 0, -1):
print("* ", end="")
print()
but there is a catch because it is almost impossible to return a pattern so we have to print instead of return it then use it directly oddOrEven(5) will print:
* * * * *
* * * *
* * *
* *
*
Determining even/odd:
is_odd = num & 1
is_even = (num & 1) == 0 # slowly: bitwise and number comparison
is_even = (num & 1) is 0 # faster: bitwise and pointer comparsion
is_even = ~num & 1 # fastest: two bitwise operations
Using is is faster than the comparisons with double equals, but negation with ~ is even faster.

Checking to see if a number ends in 5?

I'm trying to define a function that takes 2 parameters, adds them up, and if the sum of the two parameters ends in 5, it reports a 2. If it doesn't end in 5, it returns 8.
Any ideas?
I was thinking of doing an if statement, but I'm confused as to how I would check if a number ends in 5( or is 5).
Thanks for your help, trying to teach myself how to program is so difficult yet so rewarding :)
Solution
My answer assumes you are checking integers (which seems pretty reasonable judging from your question):
def sum_ends_with_5(a, b):
"""
Checks if sum ends with "5" digit.
"""
result = a + b
return 2 if result % 10 == 5 else 8
or more flexible (with any number of arguments):
def sum_ends_with_5(*args):
"""
Checks if sum ends with "5" digit.
"""
result = sum(args)
return 2 if result % 10 == 5 else 8
How it works (aka tests)
The function behaves like that:
>>> sum_ends_with_5(5)
2
>>> sum_ends_with_5(3)
8
>>> sum_ends_with_5(2, 8)
8
>>> sum_ends_with_5(7, 8)
2
>>> sum_ends_with_5(10, 20, 3, 2)
2
Shorter version
So, if you want to write it in shorter and more flexible way, you can do this:
def sum_ends_with_5(*args):
return 2 if sum(args) % 10 == 5 else 8
Take the modulus by 10 and check if it's 5.
print num % 10 == 5
Numbers end in 5 if and only if they are are divisible by 5 but are not divisible by 10. You can easily check for these conditions with modulo arithmetic. More generally, you can check if a number ends with a digit by comparing the mod 10 value of that number to the digit.
num = 1234
isDivisibleByFive = num % 10 == 5
One easy approach is to take the number and convert it to a string and check the last digit using indexing to see if it is 5:
E.g.,
n = 153
str(n)[-1] == '5':
False
and
n = 155
str(155)[-1] == '5'
True
So as part of an if-statement:
if str(n)[-1] == `5`:
print "number ends in 5"
else:
print "number did not end in 5"
If you just wanted to check for divisibility by 5 (which is different than ending with 5) you could use the mod operation.
But you also could mod by 10 and check for a remainder of 5 to determine if the number (int) ends with 5. My solution checks for the last digit of any number (including floats)
I like the solution from Tadeck best but there is another way, not as good in my opinion for this specific use case, but still may be useful if your return values ever need to follow more complex rules than is available from a simple modulo operation.
def xlatVal (*nums):
# 0 1 2 3 4 5 6 7 8 9
lookupTbl = [8,8,8,8,8,2,8,8,8,8]
return lookupTbl[sum(nums) % 10]
While the values are still reduced to a range using modulo, this allows arbitrary translations across that range.
Convert it to a string and check the last character:
str(num)[-1] == "5"

Categories