Display the middle elements of a string - python

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.

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

Binary search program

def bsearch(s, e, first, last):
print(first, last)
if (last - first) < 2:
return s[first] == e or s[last] == e
mid = first + (last - first) / 2
if s[mid] == e: return True
if s[mid] > e: return bsearch(s, e, first, mid - 1)
return bsearch(s, e, mid + 1, last)
def search1(s,e):
print(bsearch(s, e, 0, len(s)-1))
print('Search complete')
def testSearch():
s = range(0, 1000000)
input('binary,-1')
print(search1(s, -1))
It's binary search algorithm. I have two questions.
Question 1:
Why is first necessary in the following line?
mid = first + (last - first) / 2
Question 2:
I can't run the result, when I ran the program.
The error message is:
range indices must be integers or slices, not float.
How I can solve it?
Starting with Question 2:
The error message "range indices must be integers or slices, not float" tells you that you are trying to slice (get a part of a list-like collection, e.g. with some_list[5:]) using float, not int. To be more precise, your mid is 5.0, not 5.
In Python 3 the default division is floating division (unlike Python 2). To get the integer division you need to use double slash operator:
mid = first + (last - first) // 2
Regarding Question 1: mid is the middle element. It is elementary equation to get the middle element, but maybe you are confused because you expected the other, equivalent equation; it can be calculated as
mid = first + (last - first) // 2
or:
mid = (first + last) // 2
The equation could be different if you were using an implementation which creates copies of list s at each recursive call. The implementation you provided works "in-place" so it needs the absolute coordinates.
EDIT: as pointed by #philipxy in comments, you could easily find what was causing the slice-related error, searching for your error message + "division".
I just tested this and the first Google result points to TypeError: list indices must be integers, not float; as this is exactly the same problem as yours (binary search), this question could be flagged as duplicate and closed if not your second question contained herein. In fact some more experienced users still may decide do flag it as a duplicate.

Converting decimal number to binary in Python

I am writing a program that converts a decimal number into a binary. I made it that far and I stuck with a problem. In the code with print(aa).
I tried to get a binary form of given number but it prints 1. I think I have "return" function problem here how can I solve it. Also, when I print binaryform it prints like the way below. Shouldn't it print reversely I mean first 1 and then 11 and then 111 .......10111.
# Python program to convert decimal number into binary number using recursive function
def binary(n, binaryform,i):
if n >= 1:
digit= n % 2
binaryform += digit*i
#print(binaryform)
i*=10
binary(n/2, binaryform, i)
print("xxx", binaryform)
return binaryform
dec = int(input("Enter an integer: "))# Take decimal number from user
aa = binary(dec, 0, 1)
print(aa)
OUTPUT:
Enter an integer: 23
('xxx', 10111)
('xxx', 111)
('xxx', 111)
('xxx', 11)
('xxx', 1)
1
Convert an integer number to a binary string. The result is a valid Python expression. If x is not a Python int object, it has to define an index() method that returns an integer. Python Documentation
You're writing a recursive function - that's fun and good.
Now consider what you do: you check the LOW part of the number. If the LOW part of the number is 1 or 0 you do something, but then you shrink the number and recurse, checking a new LOW part, but the new low part came from a HIGHER part originally.
So whatever you determine should actually be at the end of the string, not the beginning, when you come back from recursion.
That's your question about printing reversely, I think. And yes, except you should just assemble it reversely, and then print it normally.
Also, you're actually trying to construct a decimal integer that will print out as if it were a binary number. It would be a lot simpler if you just constructed a string: "10101".
If you just want to convert integer to binary, try this code here . It looks like this :
def binary(n):
b = ''
while n > 0:
b = str(n % 2) + b
n >>= 1
print(b)
binary(10)

Generate and Enter Value for OEIS Sequence in Python?

This is a rather difficult challenge for me as I am new to Python. How would I write a program in python based off this sequence function:
http://oeis.org/A063655
and does the following:
It asks for the value of the sequence and returns the corresponding number. For example, the number corresponding to the 10th value of the sequence is 7. I'd like to be able to do this for values over 300,000,000.
So, the final product would look like this:
Enter a value: 4
[7]
Any ideas where to start? I have a framework to generate sequences where (x) would be to put a mathematical equation or numbers, but I'm not exactly sure how to go from here or how to implement the "Enter a value" portion:
import math
def my_deltas():
while True:
yield (x)
yield (x)
def numbers(start, deltas, max):
i=start
while i<=max:
yield i
i+=next(deltas)
print(','.join(str(i) for i in numbers((x), my_deltas(),(x))))
If you're looking to have your computer keep track of over 300,000,000 elements of a sequence, if each is a 4 byte integer, you'll need at least 300,000,000 * 4bytes, or over 1.1GB of space to store all the values. I assume generating the sequence would also take a really long time, so generating the whole sequence again each time the user wants a value is not quite optimal either. I am a little confused about how you are trying to approach this exactly.
To get a value from the user is simple: you can use val = input("What is your value? ") where val is the variable you store it in.
EDIT:
It seems like a quick and simple approach would be this way, with a reasonable number of steps for each value (unless the value is prime...but lets keep the concept simple for now): You'd need the integer less than or equal to the square root of n (start_int = n ** .5), and from there you test each integer below to see if it divides n, first converting start_int to an integer with start_int = int(start_int) (which gives you the floor of start_int), like so: while (n % start_int) != 0: start_int = start_int - 1, decrement by one, and then set b = start_int. Something similar to find d, but you'll have to figure that part out. Note that % is the modulus operator (if you don't know what that is, you can read up on it, google: 'modulus python'), and ** is exponentiation. You can then return a value with the return statement. Your function would look something like this (lines starting with # are comments and python skips over them):
def find_number(value):
#using value instead of n
start_int = value ** .5
start_int = int(start_int)
while (n % start_int) != 0:
#same thing as start_int = start_int - 1
start_int -= 1
b = start_int
#...more code here
semiperimeter = b + d
return semiperimeter
#Let's use this function now!
#store
my_val = input("Enter a value: ")
my_number = find_number(my_val)
print my_number
There are many introductory guides to Python, and I would suggest you go through one first before tackling implementing a problem like this. If you already know how to program in another language you can just skim a guide to Python's syntax.
Don't forget to choose this answer if it helped!
from math import sqrt, floor
def A063655(n):
for i in range(floor(sqrt(n)), 0, -1):
j = floor(n / i)
if i * j == n:
return i + j
if __name__ == '__main__':
my_value = int(input("Enter a value: "))
my_number = A063655(my_value)
print(my_number)
USAGE
> python3 test.py
Enter a value: 10
7
> python3 test.py
Enter a value: 350000
1185
>

Python: Recursion and return statements

I have this simple code using recursion that calculates the exponent. I understand how the recursion works here except for the: if exp <= 0: return 1. Say I call the function to give me five to the second power. If I have it return 1, it will give me the correct value of 25, but if 2 it returns 50, and 3, 75.
I am having a little trouble seeing how exactly this works within the environment:
def recurPower(base,exp):
if exp <= 0:
return 1
return base*recurPower(base,exp-1)
print str(recurPower(5,2))
I'm not sure if I understand the question. The 1 in the base case is there it is base^0 (for any non-zero base) and also because it is the multiplicative identity, so you can freely multiply by it.
It might help you try "unrolling" the recursion, to see where the numbers go:
recurPower(5, 2) =
5 * recurPower(5, 1) =
5 * 5 * recurPower(5, 0) =
5 * 5 * 1 =
25
Putting 2 or 3 in place of the 1 gets you two or three times the exponent you are trying to calculate.
whats happening here, is you'll end up with a cascade of returning values that will start with the value which is returned by that return 1 statement, for example:
recurPower(5,2) ==
recurPower(5,2) -> recurPower(5,1) -> recurPower(5,0)
the return statements will then make this:
1 -> (1)*5 -> (5)*5
(in reverse of the previous chain since we're cascading up the chain).
if you change the return value to 2 you will get:
2 -> (2)*5 -> (10)*5
(in reverse of the previous chain since we're cascading up the chain).
Numbers in brackets are returned from lower down the recursion chain.

Categories