str() not returning string in my function - python

So I've defined a recursive function numToBaseB that converts a given number in base ten into any other base between 2 and 10. The desired output is a string, but for some reason I keep getting an int.
def numToBaseB(num, b):
if num == 0:
return ''
elif b > 10 or b < 2:
return "The base has to be between 2 and 10"
else:
return numToBaseB(num // b, b ) + str(num % b)
So for me:
numToBaseB(4, 2) would return
100
instead of the desired output:
'100'

Your program is working as designed:
>>> numToBaseB(1024,2)
'10000000000'
>>> numToBaseB(4,2)
'100'
Of course, if you do print(numToBaseB(4,2)), the quotes will not be displayed.

If you want to have quotes though, you can always do this:
print (" ' "+numToBase(4,2)+" ' ")
But in the program, if you use str() anyways, it will be treated as string ofcourse.
:)
Edit: typing on phone, so sorry for this madness :(

Related

how to I make the code to print the numbers given and and show what it equals

I tried to make just add print(a+b) and I only got what it equals I don't know what to do I can't find it or look for it online.
You are mixing up printing a string vs. printing an expression.
Printing a string like print('hello world') will print the literal message because you've indicated it's a string with quotes.
However, if you provide an expression like print(a+b), it will evaluate that expression (calculate the math) and then print the string representation of that evaluation.
Now, what you want is actually a mix of both, you want to print a string that has certain parts replaced with an expression. This can be done by "adding" strings and expressions together like so:
print(a + '+' + b + '=' + (a+b))
Notice the difference between + without quotes and '+' with quotes. The first is the addition operator, the second is the literal plus character. Let's break down how the print statement parses this. Let's say we have a = 5 and b = 3. First, we evaluate all the expressions:
print(5 + '+' + 3 + '=' + 8)
Now, we have to add a combination of numbers with strings. The + operator acts differently depending on context, but here it will simply convert everything into a string and then "add" them together like letters or words. Now it becomes something like:
print('5' + '+' + '3' + '=' + '8')
Notice how each number is now a string by the surrounding quotes. This parses to:
print('5+3=8')
which prints the literal 5+3=8
You mean like that:
a = int(input("Give me a number man: "))
b = int(input("Give me another number: "))
print(f'print({a} + {b}) = {a + b}')
print(f'print({a} - {b}) = {a - b}')
print(f'print({a} * {b}) = {a * b}')
print(f'print({a} // {b}) = {a // b}')
print("Look at all those maths!")
Output
Give me a number man: 3
Give me another number: 2
print(3 + 2) = 5
print(3 - 2) = 1
print(3 * 2) = 6
print(3 // 2) = 1
Look at all those maths!

Python: how to print non string array?

I'm pretty new to python, and I wonder how I can print objects of my class fracture. The str funcion is set properly, I guess
def __str__(self):
if self._denominator == 1:
return str(self._numerator)
else:
return str(self._numerator)+'/'+str(self._denominator)
because of
>>>print ('%s + %s = %s' % (f1,f2,f1+f2))
1/3 + -1/4 = 1/12
Now I'd like to print it properly as a sorted array, and I hoped to get something like
>>>print(', '.join(("Sam", "Peter", "James", "Julian", "Ann")))
Sam, Peter, James, Julian, Ann
But this didn't work for my fracture or even for numbers (like print(' < '.join((1,2,3))))
All I got was:
for i in range(len(fractures)):
if i+1 == len(fractures):
print (fractures[i])
else:
print (fractures[i], end=' < ')
Is this really the best solution? That's quite messing up the code, compared on how easy this works with strings...
If you want to print "1 < 2 < 3" all you need to do is change the type from an int to a string as such:
print(' < '.join(str(n) for n in (1,2,3)))
You have to convert the ints to strings first:
numbers = (1, 2, 3)
print(' < '.join(str(x) for x in numbers))
You can convert your array using map:
print(' < '.join(map(str,(1,2,3))))
You can convert integers to string.
print(' < '.join((str(1),str(2),str(3))))

saving the number into the variable in every run of cycle python

I wrote the function that converts the string in argument to number. If the string does not contain number the cycle breaks and the new variable with numbers is printed.
If the argument is "123" the function returns 6. I don't want to return the sum, just placing every number in a row. How do I accomplish the result 123? I don!t know what to use instead of string2 += float(c).
def try_parse(string):
string2=0
for c in string:
if c.isdigit() == True:
string2 += float(c)
else:
break
return string2
I modified your code:
def try_parse(string):
string2 = ""
for c in string:
if not c.isdigit() and c != '.':
break
string2 += c
return string2
You can see that now I use string2 as a string and not an int (When the + sign is used on an int you sum, and with a string + is used for concatenation).
Also, I used a more readable if condition.
Update:
Now the condition is ignoring the '.'.
Tests:
>>> try_parse('123')
'123'
>>> try_parse('12n3')
'12'
>>> try_parse('')
''
>>> try_parse('4.13n3')
'4.13'
Note
The return type is string you can use the float() function wherever you like :)
You need to use a string for string2, and str instead of float.
You want string2 = "", and string2 += c. (You don't need to call str on c because it is already a string.)
You could leave the conversion to a number to Python (using int(), rather than float(); you only filter on digits), and only worry about filtering:
def try_parse(string):
digits = []
for c in string:
if c.isdigit():
digits.append(c)
return int(''.join(digits))
but if you really want to build a number yourself, you need to take into account that digits are not just their face value. 1 in 123 does not have the value of one. It has a value of 100.
The easiest way then to build your number would be to multiply the number you have so far by 10 before adding the next digit. That way 1 stays 1, and 12 starts as 1 then becomes 10 as you add the 2, etc:
def try_parse(string):
result = 0
for c in string:
if c.isdigit():
result = result * 10 + int(c)
return result

ValueError: invalid literal for int() with base 10 for non-digits

I am trying to create a simple program that reads a string of 4 digits, makes sure it is indeed 4 digits, makes sure there are no non-digits, then separates the first two digits from the last two and adds them together. I can make it all work but I still got this error:
ValueError: invalid literal for int() with base 10:
This only happens when I try a string such as '456f'.
What can I change to fix this?
Code:
s = input('please type a 4-digit integer \n')
valid = True
for c in s:
if len(s)!= 4:
valid = False
if not c.isdigit():
print (c, 'is not a valid input')
number = int(s)
firstOne = number // 100
secondOne = number % 100
sum = firstOne + secondOne
x = '/'
if valid == True:
print('your integer is ' + str(number), x, 'first two digits are ' + str(firstOne), x, 'second two digits are ' + str(secondOne), x, 'sum of two new numbers is ' + str(sum))
else:
print(len(s), 'is an invalid amount of digits')
You are checking whether all the characters are digits, but this check has no consequences -- you just carry on even when you found invalid characters. This makes the code fail with the quoted error message.
I'd suggest to use a dedicated function to read the integer which repeats the query until it got a valid input:
def input_int_digits(prompt, digits=4):
while True:
s = input(prompt).strip()
if len(s) == digits and s.isdigit():
return int(s)
print("Invalid input -- {}-digit integer expected.".format(digits))
Note that I used str.strip() to remove leading or trailing whitepsace and that str.isdigit() checks whether all characters of the string are digits -- you don't need to loop over the string.
Let's focus on this code:
for c in s:
if len(s)!= 4:
valid = False
if not c.isdigit():
print (c, 'is not a valid input')
number = int(s)
The first thing to say is that the len() check should be moved outside the character loop.
if len(s)!= 4:
valid = False
for c in s:
...
The next comment to make is that whilst you are detecting non-digits, you continue executing code as if nothing is wrong. You presumably intend to set valid to False.
if not c.isdigit():
print (c, 'is not a valid input')
valid = False
Now, the main part of the problem. You need to skip the conversion to int when invalid input is detected.
if valid:
number = int(s)
...
If you want to continue with such an approach your code would look like this:
valid = True
s = input('please type a 4-digit integer \n')
if len(s)!= 4:
valid = False
print(len(s), 'is an invalid amount of digits')
if valid:
for c in s:
if not c.isdigit():
valid = False
print (c, 'is not a valid input')
if valid:
number = int(s)
firstOne = number // 100
secondOne = number % 100
sum = firstOne + secondOne
x = '/'
print('your integer is ' + str(number), x, 'first two digits are ' + str(firstOne), x, 'second two digits are ' + str(secondOne), x, 'sum of two new numbers is ' + str(sum))
Having said all of that, I'd probably reorganise the code quite a bit to deal with the errors as soon as they are detected. Code is much easier to understand if you can organise your error handling that way.
s = input('please type a 4-digit integer \n')
if len(s)!= 4:
sys.exit(str(len(s)) + ' is an invalid amount of digits')
for c in s:
if not c.isdigit():
sys.exit(c + ' is not a valid input')
number = int(s)
firstOne = number // 100
secondOne = number % 100
sum = firstOne + secondOne
x = '/'
print('your integer is ' + str(number), x, 'first two digits are ' + str(firstOne), x, 'second two digits are ' + str(secondOne), x, 'sum of two new numbers is ' + str(sum))
Now, that's a start in the right direction, but you can continue in this vein making the code better and better. Sven's answer gives you an excellent illustration of where such a process would ultimately lead.
What about
...
valid = len(s) == 4 and all(c.isdigit() for c in s)
if not valid:
print (c, 'is not a valid input')
...
or even better (thanks, Sven!)
...
valid = len(s) == 4 and s.isdigit()
...
In the for that checks for isdigit , you print an error message if the string contains non-digits but still call for int() on all s
you need to exit the program after "is not a valid input" message
you can change the print to
sys.exit("is not a valid input")

python string input problem with whitespace!

my input is something like this
23 + 45 = astart
for the exact input when i take it as raw_input() and then try to split it , it gives me an error like this
SyntaxError: invalid syntax
the code is this
k=raw_input()
a,b=(str(i) for i in k.split(' + '))
b,c=(str(i) for i in b.split(' = '))
its always number + number = astar
its just that when i give number+number=astar i am not getting syntax error ..!! but when i give whitespace i get sytax error
Testing with Python 2.5.2, your code ran OK as long as I only had the same spacing
on either side of the + and = in the code and input.
You appear to have two spaces on either side of them in the code, but only one on either
side in the input. Also - you do not have to use the str(i) in a generator. You can do
it like a,b=k.split(' + ')
My cut and pastes:
My test script:
print 'Enter input #1:'
k=raw_input()
a,b=(str(i) for i in k.split(' + '))
b,c=(str(i) for i in b.split(' = '))
print 'Here are the resulting values:'
print a
print b
print c
print 'Enter input #2:'
k=raw_input()
a,b=k.split(' + ')
b,c=b.split(' = ')
print 'Here are the resulting values:'
print a
print b
print c
From the interpreter:
>>>
Enter input #1:
23 + 45 = astart
Here are the resulting values:
23
45
astart
Enter input #2:
23 + 45 = astart
Here are the resulting values:
23
45
astart
>>>
Edit: as pointed out by Triptych, the generator object isn't the problem. The partition solution is still good and holds even for invalid inputs
calling (... for ...) only returns a generator object, not a tuple
try one of the following:
a,b=[str(i) for i in k.split(' + ')]
a,b=list(str(i) for i in k.split(' + '))
they return a list which can be unpacked (assuming one split)
or use str.partition assuming 2.5 or greater:
a, serperator, b = k.partition('+')
which will always return a 3 tuple even if the string isn't found
Edit: and if you don't want the spaces in your input use the strip function
a = a.strip()
b = b.strip()
Edit: fixed str.partition method, had wrong function name for some reason
I think I'd just use a simple regular expression:
# Set up a few regular expressions
parser = re.compile("(\d+)\+(\d+)=(.+)")
spaces = re.compile("\s+")
# Grab input
input = raw_input()
# Remove all whitespace
input = spaces.sub('',input)
# Parse away
num1, num2, result = m.match(input)
You could just use:
a, b, c = raw_input().replace('+',' ').replace('=', ' ').split()
Or [Edited to add] - here's another one that avoids creating the extra intermediate strings:
a, b, c = raw_input().split()[::2]
Hrm - just realized that second one requires spaces, though, so not as good.
Rather than trying to solve your problem, I thought I'd point out a basic step you could take to try to understand why you're getting a syntax error: print your intermediate products.
k=raw_input()
print k.split(' + ')
a,b=(str(i) for i in k.split(' + '))
print b.split(' = ')
b,c=(str(i) for i in b.split(' = '))
This will show you the actual list elements produced by the split, which might shed some light on the problem you're having.
I'm not normally a fan of debugging by print statement, but one of the advantages that Python has is that it's so easy to fire up the interpreter and just mess around interactively, one statement at a time, to see what's going on.

Categories