Python: TypeError while adding - python

I'm getting an error when trying to do these functions. I know you cannot add a string and integer, but I'm having trouble finding a way around this error for the following two functions.
TypeError: can only concatenate str (not "int") to str
def basetobase(B1,B2,s_in_B1):
#docstring here
pass
decimal = int(s_in_B1, B1)
if decimal == 0:
return '0'
result = ''
while decimal > 0:
remainder = decimal % B2
decimal = decimal // B2
result = str(remainder) + decimal
return result
def numtobase( N, B ):
#docstring here
pass
final = ""
if N == 0:
return result
while N > 0:
remainder = N % B
result = str(remainder) + (N // B)
return result
while len(result) % 8 != 0:
result = '0' + result
return result
I've tried switching both to strings, but it does not work and gives me another error.

Related

Value Replacement Recursion in Python

Hi I have a question with regards to python programming for my assignment
The task is to replace the occurrence of a number in a given value in a recursive manner, and the final output must be in integer
i.e. digit_swap(521, 1, 3) --> 523 where 1 is swapped out for 3
Below is my code and it works well for s = 0 - 9 if the final answer is outputted as string
def digit_swap(n, d, s):
result = ""
if len(str(n)) == 1:
if str(n) == str(d):
return str(s)
else:
return str(n)
elif str(n)[0] == str(d):
result = result + str(s) + str(digit_swap(str(n)[1:], d, s))
return result
else:
result = result + str(n)[0] + str(digit_swap(str(n)[1:], d, s))
return result
However, I have trouble making the final output as Integer
The code breaks down when s = 0
i.e. digit_swap(65132, 1, 0) --> 6532 instead of 65032
Is there any fix to my code?
def digit_swap(n, d, s):
result = ""
if len(str(n)) == 1:
if str(n) == str(d):
return str(s)
else:
return str(n)
elif str(n)[0] == str(d):
result = result + str(s) + str(digit_swap(str(n)[1:], d, s))
return int(result) # Changes
else:
result = result + str(n)[0] + str(digit_swap(str(n)[1:], d, s))
return int(result) # Changes
Conversion to string is unnecessary, this can be implemented much easier
def digit_swap(n, d, s):
if n == 0:
return 0
lower_n = (s if (n % 10) == d else (n % 10))
higher_n = digit_swap(n // 10, d, s) * 10
return higher_n + lower_n
assert digit_swap(521, 1, 3) == 523
assert digit_swap(65132, 1, 0) == 65032
do not return int from method, instead convert it to int from where you are calling method. Problem lies where your code trying to convert string to int return int(result).
So if result is 03 then function will return int('03') i.e 3.
call your method like this
print int(digit_swap(65132, 1, 0)) so you will get integer at the end.
For example int(00) is casted to 0. Therefore a zero is discarded. I suggest not to cast, instead leave it as a string. If you have to give back an int, you should not cast until you return the number. However, you still discard 0s at the beginning. So all in all, I would suggest just return strings instead of ints:
return str(result) # instead of return int(result)
And call it:
int(digit_swap(n,d,s))

Figure out where decimal point goes when dividing floats as integers

I'm wanting to make a script that can perform maths on large numbers while keeping the precision as high as required. I attempted ones ages ago and division was the worst part by far, so I thought I'd try start with it this time.
Basically, I'm using str inputs, as they obviously remain perfectly accurate, and I'd like to perform calculations on them as integers so that nothing is lost to floating point numbers. I'm doing that currently by removing the decimal point before the calculation, then trying to re-add it, but I can't figure out how.
With multiplication, you can figure out the decimal by adding how many numbers are left of the decimal point in both numbers. Unfortunately that method doesn't seem to work with division. I previously tried coding long division, but again it's an awkward one if there's floats involved.
Here's the current code I've got, with some of the non working parts removed:
from __future__ import division
def _divide(a, b, precision):
count = 0
while a and count < precision:
for num in str(int(a // b)):
yield int(num)
count += 1
a = a % b * 10
def divide(a, b, precision=100, round_int=True):
result = []
a = str(a)
b = str(b)
#Check for negative numbers
a_neg = a[0] == '-'
b_neg = b[0] == '-'
if a_neg and not b_neg or b_neg and not a_neg:
result.append('-')
#Process number strings
a_split = a.split('.')
b_split = b.split('.')
try:
a = abs(int(a_split[0] + a_split[1]))
except IndexError:
a = abs(int(a_split[0]))
try:
b = abs(int(b_split[0] + b_split[1]))
except IndexError:
b = abs(int(b_split[0]))
#Calculate number
result += list(_divide(a, b, precision=precision+round_int))
if not round_int:
return ''.join(map(str, result))
#Round last integer
last_int = int(result.pop(-1))
index = -1
if last_int >= 5:
try:
result[index] += 1
except TypeError:
index -= 1
result[index] += 1
#Lower any integers above 10
while True:
if result[index] == '.':
index -= 1
if result[index] > 9:
result[index] -= 10
if result[index-1] == '.':
index -= 1
result[index-1] += 1
else:
return ''.join(map(str, result)).rstrip('.')
index -= 1
a = '365.72'
b = '2247.7'
print divide(a, b, 9, False)
print float(a) / float(b)
I just drew up a quick hacky way which uses the inbuilt float division to figure out where the decimal is, but obviously it's not ideal as it'll fail after 1e300:
cheat_div = str(abs(float(a) / float(b)))
if 'e' in cheat_div:
num_decimals = int(cheat_div.split('e')[1])
if num_decimals > 1:
num_decimals += 1
else:
if cheat_div.startswith('0.'):
num_decimals = 2 + len(cheat_div[2:].lstrip('0')) - len(cheat_div)
else:
try:
num_decimals = cheat_div.index('.')
except ValueError:
num_decimals = 0
while not result[is_negative]:
del result[is_negative]
if num_decimals:
if num_decimals > 0:
result = result[:is_negative+num_decimals] + ['.'] + result[is_negative+num_decimals:]
else:
result = result[:is_negative] + ['0', '.'] + ['0'] * -num_decimals + result[is_negative:]

Binary Addition using a carry

Im trying to add two binary numbers without converting the two numbers, S and T, into a base 10,using recursion and I'm having difficulty incorporating the carry into the code. Also, I'm not exactly sure what to do if one binary number is longer than the other.
def addB(S,T):
'''adds binary number without converting to base 10'''
def addBhelper(S,T,carry):
if S=='' and T=='':
return ''
if S[-1] + T[-1]+carry==0:
return addBhelper(S[:-1],T[:-1],0) + str((carry+int(S[-1]) + int(T[-1]))% 2)
if S[-1] + T[-1]+carry==1:
return addBhelper(S[:-1],T[:-1],1) + str((carry+int(S[-1]) + int(T[-1])) % 2)
if S[-1] + T[-1]+carry==2:
return addBhelper(S[:-1],T[:-1],2) + str((carry+int(S[-1]) + int(T[-1])) % 2)
if S[-1] + T[-1]+carry==3:
return addBhelper(S[:-1],T[:-1],2) + str((carry+int(S[-1]) + int(T[-1])) % 2)
return addBhelper(S,T,0)
---- updated to fix code formatting
Here's a cleaner version that uses some Python syntactic sugar:
def add(a,b,c=0):
if a == '' and b == '':
return str(c)
a = a or '0'
b = b or '0'
n = int(a[-1]) + int(b[-1]) + c
return add(a[:-1],b[:-1],n//2) + str(n%2)
Use default value of carry c=0 to get rid of the inner function
a = a or '0' sets a to '0' if it's ''
You forgot to convert string to integer before adding them
n//2 get the carry
Let’s start with the first part, which is making sure the two strings are the same length. Since they're numbers, all you have to do is '0' pad the shorter number
max_len = max(len(S), len(T))
# the more simple to understand way
while len(S) < max_len: S = '0' + S
while len(T) < max_len: T = '0' + T
# or you can use this python trickery
S = ('0' * (max_len - len(S))) + S
T = ('0' * (max_len - len(T))) + T
For the carries, your carries should be as follows:
For sum = 0, carry = 0
For sum = 1, carry = 0
For sum = 2, carry = 1
For sum = 3, carry = 1
Hope that helps,

Convert decimal to ternary(base3) in python

I am trying to make a decimal number ternary in a python function. My idea was to keep dividing until the quotient and remainder were equal, but I can't seem to get that to work. Here's my code:
l = 1
#problem code
def ternary(n):
e = n/3
q = n%3
e= n/3
q= e%3
print q
r = input("What number should I convert?: ")
k = bin(r)
v = hex(r)
i = oct(r)
print k+"(Binary)"
print v+"(Hex)"
print i+"(Octals)"
ternary(r)
l+=1
# Variables:
#l,r,k,v,i
#n,q,e
My idea was to keep dividing until the quotient and remainder were equal, but I can't seem to get that to work.
Yeah, something like that. Essentially, you want to keep dividing by 3, and collect the remainders. The remainders then make up the final number. In Python, you can use divmod to divide and collect the remainder.
def ternary (n):
if n == 0:
return '0'
nums = []
while n:
n, r = divmod(n, 3)
nums.append(str(r))
return ''.join(reversed(nums))
Examples:
>>> ternary(0)
'0'
>>> ternary(1)
'1'
>>> ternary(2)
'2'
>>> ternary(3)
'10'
>>> ternary(12)
'110'
>>> ternary(22)
'211'
You can also use the implementation of NumPy:
https://numpy.org/doc/stable/reference/generated/numpy.base_repr.html?highlight=base_repr#numpy.base_repr
Though, I agree that a function for ternary exclusively is faster.
import numpy as np
number=100 # decimal
ternary=np.base_repr(number,base=3)
print(ternary)
#10201
This can also be done with recursion.
def ternary(n):
e = n//3
q = n%3
if n == 0:
return '0'
elif e == 0:
return str(q)
else:
return ternary(e) + str(q)
More generally, you can convert to any base b (where 2<=b<=10) with the following recursive function.
def baseb(n, b):
e = n//b
q = n%b
if n == 0:
return '0'
elif e == 0:
return str(q)
else:
return baseb(e, b) + str(q)

TypeError: 'int' object is unsubscriptable - python,coldn't find out why?

this is my code, the purpose of the code is assume two integer and produce a list.start with a number, multiply its nonzero digits and add that product to the number. This is the new number in the sequence. Repeat.for example:Start with 12: multiply the digits (1*2) and add -> 14. Multiply its digits (1*4) and add -> 18, and so on.it will stop when it hit the limit(except the origin digit).two integers 12,5(limit) and produce a list ['12','14','18','26','38','62'] i checked many times and i don't know why i get TypeError: 'int' object is unsubscriptable. can someone trace for me? :)
def check_n(n,p,p1,old_t,new_t,fn1,t,limit):
if len(new_t) - 1 != limit:
if n != "":
if int(n[0]) != 0:
p = p*int(n[0])
t = p + fn1
return check_n(n[1:],p,p1,old_t,new_t,fn1,t,limit)
else:
return check_n(n[1:],p,p1,old_t,new_t,fn1,t,limit)
else:
pl = p1 + "," + str(t)
old_t = str(fn1) + p1
new_t = old_t.split(',')
return check_n(t,p,p1,old_t,new_t,fn1,t,limit)
else:
return new_t
def in_both_sequences(n,limit):
fn1 = n
n = str(n)
p = 1
p1 = ""
old_t = []
new_t = []
t = 0
return check_n(n,p,p1,old_t,new_t,fn1,t,limit)
In the check_n function, n must be a string. But when check_n calls itself towards the bottom
return check_n(t,p,p1,old_t,new_t,fn1,t,limit)
you pass in t, which is an integer.
I couldn't replicate the same error. But I tweaked the approach and this is gets the list you want
def check_n(base, limit):
result_list = [str(base)]
# Build the list to the limit
for x in range(0, limit):
# Pull the latest number
str_base = result_list[len(result_list) - 1]
# Multiply non-zero digits of the str_base
prod = int(str_base[0])
for y in range(1, len(str_base)):
if int(str_base[y]) != 0:
prod = prod * int(str_base[y])
prod += int(str_base)
result_list.append(str(prod))
return result_list

Categories

Resources