I am trying to write a recursive code that can convert a number to any base system. for example, the integer 10 into binary would convert to 1010
So far I have this but I'm having "None" in between my output. Can anyone help me with my code?
def convert(a,b):
add = a%b
if a<=1:
return a
else:
print(base开发者_运维百科(a//b,b), add)
my idea is that a%b is the number to add to the end of the number and a//b is the recursive part where it uses the answer of the previous binary number so 10 in base 2 is just convert(5,2) and add the 0 at the end since a//b=5 and a%b=0 which = 1010
You have no return statement in your else block, and you have no recursive call to convert
.
I think you want:
if a<=1:
return str(a)
else:
return str(convert(a//b,b)) + str(add)
as in
>>> def convert(a,b):
... add = a%b
... if a<=1:
... return str(a)
... else:
... return str(convert(a//b,b)) + str(add)
...
>>> convert(10,2)
'1010'
In general, try to avoid mixing types in recursive functions. It is most often the case that both your base case and your recursive case should return the same type.
I recommend you structure your code in a more precise way. You can split the vaguely-specified task you mention along different sub-tasks, e.g.:
- determine and normalize the signs of
the number and base (do you need to
support negative bases, or can you
just raise an exception?), also
ensuring an immediate exception gets
raised in error cases (e.g. a base of
0
or1
); - write a function that (give positive and
correct values for
a
andb
) returns a "sequence of digits" to representa
in baseb
, where a "digit" is an integer between0
included andb
excluded; - write a function that given a's sign and sequence-of-digits expansions builds and returns a string representation -- depends on how you want to represent very large "digits" when b is large, say > 36 if you want to use digits, then ASCII letters, for the first 36 digits in the obvious way; maybe you should accept an "alphabet" string to use for the purpose (and the first function above should raise an exception when b's too large for the given alphabet)
- write a function that uses all the above ones to print the string out
Of these tasks, only the second one can be seen as suitable to a "recursive" implementation if one insists (though an iterative implementation is in fact much more natural!) -- given that this is homework, I guess you'll have to do it recursively because that's part of the assigned task, ah well!-). But, for reference, one obvious way to iterate would be:
def digitsequence(a, b):
results = []
while True:
results.append(a % b)
if a < b: break
a //= b
return reversed(results)
assuming one wants the digit sequence in the "big endian" order we're used to from the way positional decimal notation entered Western culture (it was the more naturally-computed little-endian order in the Arabic original... but Arab being written right-to-left, the literal transcription of that order in European languages, written left-to-right, became big-endian!-).
Anyway, you can take simple, linear recursion as a way to "reverse" things implicitly (you could say such recursion "hides" a last-in, first-out stack, which is clearly a way to reverse a sequence;-), which I guess is where the recursion spec in the homework assignment may be coming from;-).
The convert
function returns None, and print
prints it. You should either remove the print
call, or accumulate the result as a string and return it.
(I'm assuming that the call to base
is actually meant to be a recursive call to convert
.)
I'm working on making a pip package for this.
I recommend you use my bases.py https://github.com/kamijoutouma/bases.py which was inspired by bases.js
from bases import Bases
bases = Bases()
bases.toBase16(200) // => 'c8'
bases.toBase(200, 16) // => 'c8'
bases.toBase62(99999) // => 'q0T'
bases.toBase(200, 62) // => 'q0T'
bases.toAlphabet(300, 'aAbBcC') // => 'Abba'
bases.fromBase16('c8') // => 200
bases.fromBase('c8', 16) // => 200
bases.fromBase62('q0T') // => 99999
bases.fromBase('q0T', 62) // => 99999
bases.fromAlphabet('Abba', 'aAbBcC') // => 300
refer to https://github.com/kamijoutouma/bases.py#known-basesalphabets for what bases are usable
For your particular question
If your looking to go binary and back you can do
>>> from bases import Bases
>>> bases = Bases()
>>> bases.toBase(200,2)
'11001000'
>>> bases.fromBase('11001000',2)
200
>>> bases.toBase2(200)
'11001000'
>>> bases.fromBase2('11001000')
200
Have Fun !!!
And again for a list of usable bases with this library refer to https://github.com/kamijoutouma/bases.py#known-basesalphabets
A simple recursive solution (with limitations) and code to test it:
from string import hexdigits
def convert(a, b):
return '0' if a == 0 else convert(a // b, b).lstrip('0') + hexdigits[a % b]
if __name__ == '__main__':
# Test code
from random import randint
for _ in range(10):
number = randint(0, 1000)
base = randint(2, 16)
conversion = convert(number, base)
print(number, "base", base, "->", conversion, "->", int(conversion, base), "base", base)
Limitations include lack of support for negative numbers; currently limited to bases in the range 2 - 16; doesn't test for invalid arguments.
TEST RUN
% python3 test.py
127 base 3 -> 11201 -> 127 base 3
666 base 3 -> 220200 -> 666 base 3
348 base 2 -> 101011100 -> 348 base 2
139 base 10 -> 139 -> 139 base 10
464 base 7 -> 1232 -> 464 base 7
330 base 11 -> 280 -> 330 base 11
633 base 10 -> 633 -> 633 base 10
789 base 4 -> 30111 -> 789 base 4
355 base 15 -> 18a -> 355 base 15
582 base 8 -> 1106 -> 582 base 8
%
精彩评论