Sistema de enteros a base-x usando recursión en python

Estoy intentando escribir un código recursivo que puede convertir un número a cualquier sistema base. por ejemplo, el entero 10 en binario se convertiría a 1010

Hasta ahora tengo esto, pero tengo “Ninguno” entre mi salida. ¿Puede alguien ayudarme con mi código?

def convert(a,b): add = a%b if a<=1: return a else: print(base(a//b,b), add) 

mi idea es que a% b es el número que se agrega al final del número y a // b es la parte recursiva donde usa la respuesta del número binario anterior, por lo que 10 en la base 2 es simplemente conversión (5,2) y agregue el 0 al final ya que a // b = 5 y a% b = 0 que = 1010

No tiene ninguna statement de devolución en su bloque else, y no tiene una llamada recursiva para convert .

Creo que quieres:

 if a<=1: return str(a) else: return str(convert(a//b,b)) + str(add) 

como en

 >>> 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' 

En general, trate de evitar mezclar tipos en funciones recursivas. En la mayoría de los casos, tanto su caso base como su caso recursivo deberían devolver el mismo tipo.

Te recomiendo estructurar tu código de una manera más precisa. Puede dividir la tarea vagamente especificada que menciona en diferentes subtareas, por ejemplo:

  • determine y normalice los signos del número y la base (¿ necesita respaldar bases negativas o simplemente puede generar una excepción?), asegurándose también de que se genere una excepción inmediata en los casos de error (por ejemplo, una base de 0 o 1 );
  • escriba una función que (proporcione valores positivos y correctos para a y b ) devuelva una “secuencia de dígitos” para representar a en la base b , donde un “dígito” es un número entero entre 0 incluido y b excluido;
  • escriba una función que, dado el signo de a y las expansiones de secuencia de dígitos, construya y devuelva una representación de cadena – depende de cómo desee representar “dígitos” muy grandes cuando b es grande, digamos> 36 si desea usar dígitos, luego Letras ASCII, para los primeros 36 dígitos de la manera obvia; tal vez debería aceptar una cadena de “alfabeto” para usar con este propósito (y la primera función anterior debería generar una excepción cuando b es demasiado grande para el alfabeto dado)
  • escribe una función que use todos los anteriores para imprimir la cadena

De estas tareas, solo la segunda puede considerarse adecuada para una implementación “recursiva” si uno insiste (aunque una implementación iterativa es mucho más natural). Dado que esto es tarea, supongo que tendrá que hágalo recursivamente porque eso es parte de la tarea asignada, ah bueno! -). Pero, para referencia, una manera obvia de iterar sería:

  def digitsequence(a, b): results = [] while True: results.append(a % b) if a < b: break a //= b return reversed(results) 

asumiendo que uno quiere la secuencia de dígitos en el orden "big endian" al que estamos acostumbrados por la forma en que la notación decimal posicional ingresó en la cultura occidental (fue el orden little-endian más naturalmente calculado en el original árabe ... pero en árabe se está escribiendo De derecha a izquierda, la transcripción literal de ese orden en idiomas europeos, escrita de izquierda a derecha, se convirtió en big-endian! -).

De todos modos, puede tomar la recursión lineal simple como una forma de "revertir" las cosas implícitamente (se podría decir que dicha recursión "esconde" una stack de último en entrar, primero en salir, que es claramente una manera de revertir una secuencia 😉 que supongo es de donde puede provenir la especificación de recursión en la tarea ;-).

Estoy trabajando en hacer un paquete de pip para esto.

Te recomiendo que uses mi bases.py https://github.com/kamijoutouma/bases.py que se inspiró en 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 

Consulte https://github.com/kamijoutouma/bases.py#known-basesalphabets para saber qué bases se pueden usar

Para tu pregunta particular

Si buscas ir binario y volver puedes hacer.

 >>> from bases import Bases >>> bases = Bases() >>> bases.toBase(200,2) '11001000' >>> bases.fromBase('11001000',2) 200 >>> bases.toBase2(200) '11001000' >>> bases.fromBase2('11001000') 200 

Que te diviertas !!!

Y nuevamente para obtener una lista de bases utilizables con esta biblioteca, consulte https://github.com/kamijoutouma/bases.py#known-basesalphabets

La función de convert devuelve Ninguna, e print imprime. Debe eliminar la llamada de print o acumular el resultado como una cadena y devolverlo.

(Supongo que la llamada a la base realidad está destinada a ser una llamada recursiva a la convert ).

Una solución recursiva simple (con limitaciones) y código para probarlo:

 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) 

Las limitaciones incluyen la falta de apoyo para los números negativos; Actualmente limitado a bases en el rango 2 – 16; no prueba para argumentos inválidos

PRUEBA DE FUNCIONAMIENTO

 % 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 %