Haciendo un progtwig de collatz automatizamos las cosas aburridas.

Estoy tratando de escribir un progtwig de Collatz usando las pautas de un proyecto que se encuentra al final del capítulo 3 de Automatizar las cosas aburridas con Python. Estoy usando python 3.4.0 . A continuación se presenta el esquema del proyecto:

Escriba una función llamada collatz() que tenga un parámetro llamado número. Si el número es par, entonces collatz() debería imprimir el number // 2 y devolver este valor. Si el número es impar, entonces collatz() debe imprimir y devolver 3 * number + 1 . Luego, escriba un progtwig que permita al usuario escribir un número entero y que siga llamando a collatz() en ese número hasta que la función devuelva el valor 1 .

La salida de este progtwig podría verse algo como esto:

 Enter number: 3 10 5 16 8 4 2 1 

Estoy tratando de hacer una función que use sentencias if y elif dentro de un bucle while. Quiero que se imprima el número, y luego volver al principio del bucle y reducirme a uno usando la secuencia de Collatz, con cada instancia de un número resultante que se imprime a medida que pasa por el bucle. Con mi código actual, solo puedo imprimir la primera instancia del número, y ese número no pasa por el bucle después de eso. Lo siguiente es mi código:

 #collatz print("enter a number:") try: number = (int(input())) except ValueError: print("Please enter a valid INTEGER.") def collatz(number): while number != 1: if number % 2==0: number = (number//2) #print(number) return (print(int(number))) elif nnumber % 2==1: number = (3*number+1) #print(number) return (print(int(number))) continue collatz(number) 

 def collatz(number): if number % 2 == 0: print(number // 2) return number // 2 elif number % 2 == 1: result = 3 * number + 1 print(result) return result n = input("Give me a number: ") while n != 1: n = collatz(int(n)) 

Salida:

 Give me a number: 3 10 5 16 8 4 2 1 Give me a number: 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1 

Esto es lo que se me ocurrió:

 import sys def collatz(number): if number % 2 == 0: # Even number result = number // 2 elif number % 2 == 1: # Odd number result = 3 * number + 1 while result == 1: # It would not print the number 1 without this loop print(result) sys.exit() # So 1 is not printed forever. while result != 1: # Goes through this loop until the condition in the previous one is True. print(result) number = result # This makes it so collatz() is called with the number it has previously evaluated down to. return collatz(number) print('Enter a number: ') # Program starts here! try: number = int(input()) # ERROR! if a text string or float is input. collatz(number) except ValueError: print('You must enter an integer type.') # Fully working! 

Su función collatz() debe imprimir y devolver solo el siguiente valor. (Termina cuando vuelve.)

El bucle while no debe estar dentro de la función collatz() .

También tiene nombres de variables inconsistentes ( n , number , number ) y se comenta algún código importante.

Mis 17 líneas de código para el mismo ejercicio que se me ha ocurrido.

  def collatz(number): """ check if the number is even or odd and performs calculations. """ if number % 2 == 0: # even print(number // 2) return number //2 elif number % 2 != 0: # odd result = 3*number+1 print(result) return result try: n = input('Enter number: ') # takes user input while n !=1: # performs while loop until 'n' becomes 1 n = collatz(int(n)) # passes 'n' to collatz() function until it arrives at '1' except ValueError: print('Value Error. Please enter integer.') 

Nuncjo consiguió la solución que funciona. Lo modifiqué un poco para agregar las declaraciones try y except para el manejo de errores.

 def collatz(number): if number % 2 == 0: print(number // 2) return number // 2 elif number % 2 == 1: result = 3 * number + 1 print(result) return result try: n = input("Enter number: ") while n != 1: n = collatz(int(n)) except ValueError: print('whoops, type an integer, bro.') 
 def collatz(number): while number != 1: if number % 2 == 0: number = number // 2 print(number) elif number % 2 == 1: number = number * 3 + 1 print(number) try: num = int(input()) collatz(num) except ValueError: print('Please use whole numbers only.') 

Esto es lo que se me ocurrió por mi cuenta y basado únicamente en lo que he aprendido del libro hasta ahora. Me tomó un poco, pero una de las herramientas que utilicé fue inestimable para mí al encontrar mi solución y también ha sido inestimable para aprender este contenido: la herramienta de visualización de python en: http://www.pythontutor.com/visualize.html # mode = editar

Pude ver lo que estaba haciendo mi código y dónde estaba colgado y pude hacer ajustes continuamente hasta que lo hice bien.

 def collatz(num): if num % 2: return 3 * num + 1 else: return num // 2 while True: try: number = int(input('Enter a positive integer.')) if number <= 0: continue break except ValueError: continue while number != 1: number = collatz(number) print(number) 

Mi código

 def collatz(number): while number != 1: if number % 2 == 0: print(number // 2) number = number // 2 elif number % 2 == 1: print(number * 3 + 1) number = number *3 + 1 try: print ('Enter the number to Collatz:') collatz(int(input())) except ValueError: print('Enter a valid integer') 
 def collatz(number): if number % 2 == 0: # Even number return number // 2 elif number % 2 == 1: # Odd number return number * 3 + 1 print('Please enter a number') # Ask for the number # Check if the number is an integer, if so, see if even or odd. If not, rebuke and exit try: number = int(input()) while number != 1: collatz(number) print(number) number = collatz(number) else: print('You Win. The number is now 1!') except ValueError: print('Please enter an integer') 

Esto es lo que se me ocurrió para este ejercicio de práctica. Solicita una entrada. Valida si es un entero. Si no lo reprende y sale. Si es así, recorre la secuencia de collatz hasta que el resultado es 1 y luego ganas.

 def collatz(number): if number % 2 == 0: print(number//2) return number // 2 elif number % 2 == 1: print(3*+number+1) return 3 * number + 1 r='' print('Enter the number') while r != int: try: r=input() while r != 1: r=collatz(int(r)) break except ValueError: print ('Please enter an integer') 

Agregué validación de entrada

A cada solución en este hilo le falta una cosa: si el usuario ingresa “1”, la función aún debe ejecutar los cálculos de la secuencia de Collatz. Mi solución:

 def collatz(number): while number == 1: print("3 * " + str(number) + " + 1 = " + str(3*number+1)) number = 3*number+1 ##this while loop only runs once if at all b/c at end of it the value of the variable is not equal to 1 else: while number != 1: if number % 2 == 0: print(str(number) + ' // 2 = ' + str(number//2)) number = number//2 else: print("3 * " + str(number) + " + 1 = " + str(3*number+1)) number = 3*number+1 print('Please input any integer to begin the Collatz sequence.') while True: try: number = int(input()) collatz(number) break except ValueError: print('please enter an integer') 
 def collatz (número):
     si (número% 2 == 0):
         n = número // 2
         imprimir (n)
         volver n
     más:
         ev = 3 * número + 1
         imprimir (ev)
         volver ev
 num1 = entrada ("Ingrese un número: \ n")

 tratar:
     num = int (num1)
     si (num == 1):
         imprimir ("Introduzca un número entero mayor que 1")
     elif (num> 1):
         a = collatz (num) 
         while (Verdadero):
             si (a == 1):
                 descanso
             más:
                 a = collatz (a)
     más:
         imprimir ("Por favor, ingrese un entero positivo para comenzar la secuencia de Collatz")

 excepto:
     imprimir ("por favor, introduzca un número entero")

Trate de encontrar una solución basada en hasta el Capítulo Función de automatizar las cosas aburridas. Si necesita ayuda relacionada con el problema de Collatz, visite aquí: http://mathworld.wolfram.com/CollatzProblem.html

Estoy leyendo el mismo curso e hice una solución muy larga (mejorándolo cuando aprendo algo nuevo). Le sugiero que mantenga actualizado su progtwig de Collatz a medida que avanza en los capítulos, es una buena capacitación. ¡El mío tiene la manipulación de cadenas y el guardado en un \ collatzrecords.txt ahora!

Resolví el problema central utilizando la recursión (un método se llama a sí mismo):

 def autocollatz(number): global spam spam.append(number) if number % 2 == 0: autocollatz (int(number/2)) elif number % 2 == 1 and number != 1: autocollatz(int(number*3+1)) 

el spam es mi lista para todos los valores que un número “ve” en su camino a 1. como puede ver, cuando el número es par, el método se llama nuevamente con número / 2. si el número es par, se llama con el número * 3 + 1.

modificó el número == 1 cheque un poco. Espero que ahorre tiempo de cálculo, ¡hasta 23 000 000 ya! (El registro actual es 15 733 191 con 704 pasos para llegar a 1)

 import sys def collatz(number): if number % 2 == 0: result = number // 2 print (result) elif number % 2 == 1: result = number * 3 + 1 print (result) while result == 1: sys.exit while result != 1: number = result collatz(number) print ('Enter a number') try: number = int(input()) collatz(number) except ValueError: print('Please enter a valid integer') 
 def collatz(number): while number != 1: if number %2==0: number = number//2 yield number elif number %2 ==1: number=number*3 +1 yield number while True: try: for n in collatz(int(input('Enter number:'))): print(n) break except ValueError: print('Please enter an integer') 

El extra mientras que True loop ayudará al progtwig a continuar funcionando después de que el usuario ingrese un número no entero.

 def collatz(number): if number % 2 == 0: return number // 2 elif number % 2 == 1: return 3 * number + 1 try: chosenInt = int(input('Enter an integer greater than 1: ')) while chosenInt < 2: print("Sorry, your number must be greater than 1.") chosenInt = int(input('Enter an integer greater than 1: ')) print(chosenInt) while chosenInt != 1: chosenInt = collatz(chosenInt) print(chosenInt) except ValueError: print('Sorry, you must enter an integer.') 
 def collatz(number): if number%2==0: return number//2 elif number%2==1: return number*3+1 step=1 #counter variable for amusement and seeing how many steps for completion. try: #in case of ValueError number=int(input('Enter a Number for Collatz Sequencing:')) while collatz(number)!=1: print(collatz(number)) number=int(collatz(number)) if collatz(number)!=1: print('Calculating step ' + str(step) + '.') step=step+1 else: print ('Calculating step ' +str(step) + '.') print('1 Has Been Reached.') except ValueError: print('Enter an Integer please:') 

Aquí están mis 19 líneas:

 def collatz(number): if number % 2 == 0: return number // 2 else: return number*3 + 1 number = 0 while number == 0: try: number = int(input('Please enter a number: ')) if number == 0: print('Number must be an integer not equal to zero.') else: while True: number = collatz(number) print(number) if abs(number) == 1 or number == -5 or number == -17: break #Collatz seq ends/enters recurring loop when number hits -17, -5, -1 or 1 except ValueError: print('Number must be an integer.') 

Creo que esta solución puede ser incluso más simple para los estudiantes que la aceptada:

 def collatzSequence(number): if (number % 2 == 0): # if it's even number = number // 2 else: # if it's odd number = number * 3 + 1 print (number) return (number) n = int(input('Enter a number: ')) while (n != 1): n = collatzSequence(n) 

El resultado será algo como esto:

 Enter a number: 5 16 8 4 2 1 

Algo que me ayudó mucho en esta etapa de mi aprendizaje es comprender que una función debe tener un propósito bien definido y agregar un bucle a la función lo diluye.

Aquí está mi solución (alguien me ayudó a trabajar en esto y abordó los mismos errores que veo en su código):

 def collatz(number): # defining the function here. The function takes 1 argument - number. if number % 2 == 0: # if statement where we say that if the remainder of number by 2 is 0, then its an even number. even = number // 2 # assign number divided by two to a variable named even. print(even) # displaying that even value. return even # return that value. else: # else if number is not even. odd = 3 * number + 1 # then it is an odd number, and if it is an odd number then we will multiple that number by 3 and add 1. print(odd) # printing the odd number return odd # return that value try: number = int(input('please enter a number:')) # number is an input from a user and here we ask the user for what input except ValueError: print('Error, you must enter an integer.') while number !=1: # while loop states that while the value of number does not equal 1... number = collatz(number) # ... assign the output of the collatz() function as a new value of the number, and run the collatz() function again.