Python is not recognizing my variables, but instead replacing them with zero - python

Here is my code:
change = 0
count = 0
value = 0
answer = 0
def numberTest():
if change == 0:
skip()
else:
value = change
def skip():
count + 1
number = value
# Check if the input is valid
if value != number:
print('PLEASE ENTER A VALID NUMBER!!!')
else:
Even = number % 2
if Even == 0:
print('Substituting even number in: x / 2')
print('%s/2=' % number)
answer = number / 2
else:
print('Substituting odd number in: 3x + 1')
print('3' + number + ' + 1=')
answer = number * 3
answer = answer + 1
answer = str(answer)
print(''+ answer +'')
if answer == 1:
finalValue()
else:
check()
def check():
value = answer
skip()
def loop():
value = int(input('Input a number: '))
change = value
skip()
loop()
def finalValue():
print('The number (' + change + ') returned as 1.')
print('A total of (' + count + ') commands were executed.')
change = change + 1
count = 0
print('')
print('')
print('')
numberTest()
Whenever I start the code, I am asked to enter a number (as expected), but then this happens:
Input a number: 1
Substituting even number in: x / 2
0/2=
0.0
I really do not understand why the program is not working as I expected, but there is one part of the code that I am suspicious of:
value = int(input('Input a number: '))
I also wrote this myself, and I am new to Python, I have only previously worked with batch, so transitioning was quite easy, though I am not very familiar with some of the commands...
EDIT
What I was expecting the program to do was ask for a number, store that number, then run it through a series of tests, but when the number gets to the actual tests, it substitutes "x" for "0", even if I type in a number such as "54656". Maybe, when it asks for the number, when I input the number, it just doesn't store it right, or something is wrong with my code...

You are trying to change global variables without declaring them:
a = 'bad'
def bad_fn():
a = 'good'
bad_fn()
print('bad_fn() is'+a)
def good_fn():
global a
a = 'good'
good_fn()
print('good_fn() is'+a)
results in
bad_fn() is bad
good_fn() is good
In general, using global variables in bad practice. Passing parameters explicitly makes debugging and code reuse much less of a headache. Here is rewritten version of your code which should be easier to understand:
# Test the Collatz conjecture:
# http://en.wikipedia.org/wiki/Collatz_conjecture
import profile
# Python 2/3 compatibility shim
import sys
if sys.hexversion >= 0x3000000:
# Python 3.x
inp = input
rng = range
else:
# Python 2.x
inp = raw_input
rng = xrange
# cache of already-seen values
seen = set([1])
def test(n):
visited = set()
while True:
if n in seen: # Ran into an already-seen chain that goes to 1
seen.update(visited)
return len(visited)
elif n in visited: # Closed loop! this should never happen
print('Loop found at n = {}'.format(n))
return None
else:
visited.add(n)
if n % 2: # n is odd?
n = 3*n + 1
else:
n //= 2
def do_profile(upto=1000000):
prof = profile.Profile()
prof.run('for n in rng(2, {}): test(n)'.format(upto))
prof.print_stats()
def main():
while True:
try:
n = int(inp('Enter a number to test (or x to exit): '))
except ValueError:
break
res = test(n)
if res is None:
print("Well, that's odd...")
else:
print("Chain terminated after {} values were tested".format(res))
if __name__=="__main__":
main()
It took 17.7s on my machine to run do_profile(1000000). It looked at a total of 2,168,611 numbers, the highest of which was 56,991,483,520. No loops were found.
Edit: I have added an inp() shim function; the code should now run in both Python 2 or Python 3.
Edit2: moved the profiling code into the main code listing and added range/xrange to the Python 2/3 shims.

If you want to change a global variable, you need to declare it preceded by global in your function, ie:
value = 0
def changeValue():
global value
value += 1
If you do not need to change the variable, global is not required.

Related

Generating a palindrome number taken from input

I'm writing a program that takes a number from input and generates it's palindrome number. My program only prints the first half not the second. I tried reverse, didnt work.I have incluede those lines as comment.
My Code:
def show_palindrome(maximum):
maximum = int(input("Enter Number : "))
for number in range(1, maximum + 1):
temporary = number
reverse = 0
while (temporary > 0):
reminder = temporary % 10
reverse = (reverse * 10) + reminder
temporary = temporary //10
if(number == reverse):
#number2 = number[::-1]
#print(number,number2, end = '')
print(number, end = '')
show_palindrome(3)
My output:
123
The output I need:
12321
I believe you're looking for something like this:
def show_palindrome(maximum = None):
if not maximum:
maximum = input("Enter Number : ")
output = str(maximum)
for number in range(1, int(maximum)):
output = str(int(maximum) - number) + str(output) + str(int(maximum) - number)
return output
print(show_palindrome(3))
this returns 12321 for instance
A couple of things I would do differently in your function:
If you're going to require the input in the def (The way you make it optional is to set it equal to something when you declare it like I have it set to None (maximum=None), then you don't need the input() statement.
Since you already know how long you want it to be ( you require it declared when you initialize the function, it's just 2*maximum - 1) there's really no need to use a while loop.
Other than that good job! Keep it up!
You can try something simpler like this:
def show_palindrome():
num = input("Enter Number : ")
print(num + num[:-1][::-1])
show_palindrome()
Input:
123
12
1
Output:
12321
121
1
Apart from the string slice method (as used by #PApostol), you could also use the reversed method :
def show_palindrome():
value = input("Enter Number : ")
print(value[:-1] + "".join(reversed(value)))
Input:
123
Output:
12321
def palindrome(maximum):
number = ''.join([str(num) for num in range(1, maximum + 1)])
return int(number + number[-2::-1])
print(palindrome(3))
Output:
12321
Your code seems over complicated, and I don't even know what to fix in it. What I can tell is that passing a parameter maximum to overwrite it just after with maximum = int(input("Enter Number : ")) is useless, don't pass the parameter.
So let's back to easy things
Build palindrome using strings method : slicing backwards from index -2, and reverse it with -1 increment
def show_palindrome():
value = input("Enter Number : ")
print(value + value[-2::-1])
Build palindrome using math operations : save the remainder, except the first one
def show_palindrome():
value = input("Enter Number : ")
result = value
value = int(value) // 10 # remove last char which would be redundant
while value > 0:
result += str(value % 10)
value = value // 10
print(result)
show_palindrome()

hailstone program in python

i have to write a hailstone program in python
you pick a number, if it's even then half it, and if it's odd then multiply it by 3 and add 1 to it. it says to continue this pattern until the number becomes 1.
the program will need methods for the following:
accepting user input
when printing the sequence, the program should loop until the number 1.
print a count for the number of times the loop had to run to make the sequence.
here's a sample run:
prompt (input)
Enter a positive integer (1-1000). To quit, enter -1: 20
20 10 5 16 8 4 2 1
The loop executed 8 times.
Enter a positive integer (1-1000). To quit, enter -1: 30
30 15 46 23 70 35 106 53 160 80 40 20 10 5 16 8 4 2 1
The loop executed 19 times.
Enter a positive integer (1-1000). To quit, enter -1: -1
Thank you for playing Hailstone.
right now i have this:
count = 0
def hailstone(n):
if n > 0
print(n)
if n > 1:
if n % 2 == 0:
hailstone(n / 2)
else:
hailstone((n * 3) + 1)
count = count + 1
i don't know what to do after this
Try to think in a modular way, make two functions: check_number() and user_call(). Check_number will verify if the current number in the loop is odd or even and the user_call() just wraps it to count how many times the loop did iterate.
I found the exercise in a great book called Automate Boring Stuff with Python, you have to check it out, if you don't know it already.
Here's my code. Try to use what serves you the best.
from sys import exit
def check_number(number):
if number % 2 ==0:
print(number // 2)
return(number // 2)
else:
print(number*3+1)
return number*3+1
def user_call(number):
count = 0
while number != 1:
count += 1
number = check_number(number)
return count
if __name__ == "__main__":
try:
number = int(input('Give a number \n'))
count = user_call(number)
print('count ',count)
except Exception as e:
exit()
you can use global
visit https://www.programiz.com/python-programming/global-keyword to learn more
import sys
res = []
def hailstone(number):
global res
if number > 1:
if number % 2 == 0:
res.append( number // 2 )
hailstone(res[len(res)-1])
else:
res.append(number * 3 + 1)
hailstone(res[len(res)-1])
return res
number = int(input('Enter a positive integer. To quit, enter -1: '))
if number <= 0 or number == 0:
print('Thank you for playing Hailstone.')
sys.exit()
else:
answers = hailstone(number)
for answer in answers:
print(answer)
print('The loop executed {} times.'.format(len(answers) + 1))
I used recursion to solve the problem.
Heres my code:
Edit: All criteria met
count = 0
list_num = []
def input_check():
number = int(input("Enter a positive integer (1-1000). To quit, enter -1: "))
if number >= 1 and number <= 1000:
hailstone_game(number)
elif number == -1:
return
else:
print("Please type in a number between 1-1000")
input_check()
def hailstone_game(number):
global count
while number != 1:
count += 1
list_num.append(number)
if number % 2 == 0:
return hailstone_game(int(number/2))
else:
return hailstone_game(int(number*3+1))
list_num.append(1) # cheap uncreative way to add the one
print(*list_num, sep=" ")
print(f"The loop executed {count} times.")
return
input_check()
Additional stuff that could be done:
- Catching non-integer inputs using try / except
Keep in mind when programming it is a good habit to keep different functions of your code separate, by defining functions for each set of 'commands'. This leads to more readable and easier to maintain code. Of course in this situation it doesn't matter as the code is short.
Your recursive function is missing a base/terminating condition so it goes into an infinite loop.
resultArray = [] #list
def hailstone(n):
if n <= 0: # Base Condition
return
if n > 0:
resultArray.append(n)
if n > 1:
if n % 2 == 0:
hailstone(int(n/2))
else:
hailstone((n * 3) + 1)
# function call
hailstone(20)
print(len(resultArray), resultArray)
Output
8 [20, 10, 5, 16, 8, 4, 2, 1]
Here's a recursive approach for the problem.
count=0
def hailstone(n):
global count
count+=1
if n==1:
print(n)
else:
if n%2==0:
print(n)
hailstone(int(n/2))
else:
print(n)
hailstone(3*n+1)
hailstone(21)
print(f"Loop executed {count} times")

Collatz sequence - Have I done it right?

I am now learning how to program in python and the book I am learning from gave me the practice project to build this sequence and place it in a loop until the value is 1.
My code looks like this:
print('Enter a number')
number = input()
num = number
def collatz(number):
global num
if int(num) % 2 == 0:
num = int(num) // 2
print(str(num))
elif int(num) % 2 == 1:
num = 3 * int(num) + 1
print(str(num))
while num != 1:
number = num
collatz(number)
It works, but I am not sure if I've done it in the way I should've.
My issue was that I was using number both as a global variable and a parameter and when I first write the code every 'num' was called 'number', when first testing it it would enter an endless loop and repeat the first if or elif all over again. I figured that the problem is that it doesn't refer to the global variable but creates a local one, so I've tried to declare at the beginning to use the global one, as you can see, however it didn't let me as global variable and parameter can't be the same, so I've created the 'num' variable and assigned it to the if block, but now it looks like that the number parameter doesn't really interfere with my code.
The fact that it works makes me happy, however I would like to confirm this is right.
There are a few things I'd suggest you fix.
No need for a separate print for input. Also might as well cast it to int now.
number = int(input('Enter a number'))
Get rid of the global and use return. Also get rid of your casting in your function.
See:
def collatz(n): # parameter is an int
if n % 2 == 0:
n = n // 2
elif n % 2 == 1:
n = 3 * n + 1
print(n) # single print
return n
So combined:
def collatz(n):
if n % 2 == 0:
n = n // 2
elif n % 2 == 1:
n = 3 * n + 1
print(n)
return n
number = int(input('Enter a number'))
while number != 1:
number = collatz(number)

Function keeps doing the same thing

This program suppose to find 1000 prime numbers and pack them into a list
Here's the code:
num = raw_input('enter a starting point')
primes = [2]
num = int(num)
def prime_count(num):
if num % 2 == 0: #supposed to check if the number is divided by 2 evenly
num = num +1 #if it is, then add 1 to that number and check again
return num
elif num % num == 0:
primes.append(num) #supposed to add that prime to a list
num = num + 1 #add 1 and check again
return num
while len(primes) <= 999:
prime_count(num)
So what actually happens when I run it:
it asks me raw_input and then goes to various things depending on what I choose as input:
If I choose a prime, let's say 3, it runs and adds 999 of 3s to the list instead of adding it just one time and going on to try 4
If I choose a non-prime, let's say 4, it just breaks, after that I can't even print out a list
What am i doing wrong?
UPDATE:
I fixed it, but when i run it with this i'm getting an error (TypeError: unsupported operand type(s) for %: 'NoneType' and 'int')
number = raw_input('enter a starting point')
primes = [2]
number = int(number)
def prime_count(x):
if x % 2 == 0: #supposed to check if the number is divided by 2 evenly
number = x +1 #if it is, then add 1 to that number and check again
return number
else:
for i in range(3, x-1):
if x % i == 0:
primes.append(x) #supposed to add that prime to a list
number = x + 1 #add 1 and check again
return number
while len(primes) <= 999:
number = prime_count(number)
You're never using the return value from prime_count. Try this:
while len(primes) <= 999:
num = prime_count(num)
You've set your self up for confusion by using the name num as both a parameter (also a local variable) inside of prime_count, and also as a global variable. Even though they have the same name, they are different variables, due to Python's rules for the scope of variables.
Also, prime_count is (probably unintentionally) leveraging the fact that primes is a global variable. Since you're not assigning to it, but rather just calling a method (append), the code will work without using the global keyword.
However, your algorithm isn't even correct. if num % num == 0 says "if a number divided by itself has a remainder of zero" which will always be true. This program will find a lot of "primes" that aren't primes.
Real Python programs do very little in the global scope; your current code is just asking for confusion. I suggest you start with this template, and also do some reading of existing Python code.
def add_three(a_param):
a_local_var = 3 # This is *different* than the one in main!
# Changes to this variable will *not* affect
# identically-named variables in other functions
return a_local_var + a_param
def main():
a_local_var = 2
result = add_three(a_local_var)
print result # prints 5
if __name__ == '__main__':
main()

Count Even Numbers User has Inputted PYTHON 3

I must create two functions. One that can tell whether one number is odd or even by returning t/f, and the other will call the first function then return how many even numbers there are.
This is my code so far:
Even = [0,2,4,6,8]
IsEvenInput = int(input("Please enter a number: "))
def IsEvenDigit(a):
if a in Even:
return True
else:
return False
y = IsEvenDigit(IsEvenInput)
print(y)
def CountEven(b):
count = 0
for a in b:
if IsEvenDigit(a):
count+=1
return count
d = input("Please enter more than one number: ")
y = CountEven(d)
print(y)
This keeps outputting 0 and doesn't actually count. What am I doing wrong now?
d = input("Please enter more than one number: ")
This is going to return a string of numbers, perhaps separated by spaces. You'll need to split() the string into the sequence of text digits and then turn those into integers.
There's a general approach to determining whether a number is odd or even using the modulus / remainder operator, %: if the remainder after division by 2 is 0 then the number is even.
Here is another approach:
def is_even(number):
return number % 2 == 0
def even_count(numbers_list):
count = 0
for number in numbers_list:
if is_even(number): count += 1
return count
raw_numbers = input("Please enter more than one number: ")
numbers_list = [int(i) for i in raw_numbers.split()]
count = even_count(numbers_list)
print(count)
This will take care of all other numbers too.
So by calling CountEvent(d) outside the scope of the function CountEven, you aren't using recursion, you're simple calling the function after it's been defined.
Try reducing the amount of code outside of your functions.
#Start by declaring your functions:
def isEven(n):
return n % 2 == 0
def countEven():
count = 0
string_of_numbers = input("Please enter numbers separated by spaces: ")
list_of_number_characters = string_of_numbers.split(' ')
for number in list_of_number_characters:
number_as_int = int(number)
if isEven(number_as_int) == True:
count = count + 1
print("There were " + str(count) + " even numbers found.")
countEven() #Call the function that runs your program
You are counting whether the integers - [0, 2, 4, 6, 8] etc. - are characters in a string - "0", "2", "4", "6", "8" etc. Currently, IsEvenDigit(a) will never be true, because a character in a string will not be in the list of even integers, so the code beneath the if statement will never be executed. You need IsEvenDigit(int(a)) in the CountEven function.
On another topic, a commenter to your post suggested reading PEP 8. Your code is actually formatted pretty well, its just in Python, CamelCase is used just for classes, and words_seperated_by_underscores is used for variables and function names.
Or if you want brevity and unreadability, some code:
main = lambda: sum(map(lambda x: int(x) % 2 == 0, (i for i in input("Enter a number: "))))
main()
It does define 2 (anonymous) functions!
A possible solution:
def is_even(n):
return not n % 2
def count_even(numbers)
return sum(map(is_even, numbers))
nums = input("Enter numbers separated by spaces: ")
nums = map(int, nums.split())
print(count_even(nums))

Categories