Perfect Square function that doesn't return - python

I'm a beginner working with Python and I was given this task: write a function which returns the highest perfect square which is less or equal to its parameter (a positive integer).
def perfsq(n):
x = 0
xy = x * x
if n >= 0:
while xy < n:
x += 1
if xy != n:
print (("%s is not a perfect square.") % (n))
x -= 1
print (("%s is the next highest perfect square.") % (xy))
else:
return(print(("%s is a perfect square of %s.") % (n, x)))
When I run the code to execute the function it doesn't output anything. I'll admit, I'm struggling and if you could give me some advice on how to fix this, I would be grateful.

your loop condition which is
while xy < n:
this will be true always as xy is always 0 and n is always greater then zero if you will call the function with n = 0, it will print 0 is a perfect square of 0. and will return None.
for n > 0
why it is always true in the case of xy < n because you have assigned xy 0 and never modified it to anyother value when a loop runs it check the condition and it will always get True

Like Patrick Haugh says, try examining when the while loop exits. It can be helpful to put print() statements throughout your method to figure out how your method executes. In order to figure out when your loop exits, look at the exit condition of your while loop: xy < n.
Remember, a variable isn't updated until you update it.
def perfsq(n):
x = 0
xy = x * x
print("xy: {}".format(xy))
if n >= 0:
while xy < n:
x += 1
print("xy in loop: {}".format(xy))
if xy != n:
print (("%s is not a perfect square.") % (n))
x -= 1
print (("%s is the next highest perfect square.") % (xy))
else:
return(print(("%s is a perfect square of %s.") % (n, x)))

I see your mistake, and it's an easy one for someone to make. When you define
xy = x*x
the computer calculates x*x and assigns that number to be the value of xy. So when you then add one to x it does not change the value of xy. You have to tell the computer to recalculate xy every time:
while xy < n:
x += 1
xy = x*x

def perfsq(n):
x = 0
xy = x * x
if n >= 0:
while xy < n:
x += 1
xy = x*x <-- Here
if xy != n:
print (("%s is not a perfect square.") % (n))
x -= 1
xy = x*x <--Here
print (("%s is the next highest perfect square.") % (xy))
else:
print(("%s is a perfect square of %s.") % (n, x)) <--And here
Think about that.

Related

How many times x is divisible by y using function

So, basically I have to built an algorithm that tells me how many times X is divisible by Y. If its not divisible, it should return print -1.
Here's what i've got so far:
def divisible(x, y):
n = int(x/y)
if (n != 0 and x%y == 0):
print(x, "its divisible by",y,n,"times")
else:
print(-1)
divisible(5, 2)
The exercise its asking to use a counter to do this. How can I make It?
Thanks
Integer division and the modulo function should get you there -
divisible = lambda x, y: x // y if x % y == 0 else -1
divisible(13, 3)
# -1
divisible(12, 3)
# 4
def divisible (x, y):
# Initialize times to keep track of how many times x is
# divisible by y:
times = 0
# Enter an infinite loop:
while True:
# If the remainder of x divided by y is 0
# (= if x is divisible by y):
if ( x % y == 0 ):
# Increment times by 1 and actually divide x by y:
times += 1
x = x / y
# If x is *not* divisible by y, break out of the infinite loop:
else:
break
# If the original x was not divisible by y at all, return -1
# (otherwise, keep times unchanged):
if times == 0:
times = -1
return times
print(divisible(2, 2))
# 1
print(divisible(3, 2))
# -1
print(divisible(8, 2))
# 3
print(divisible(10000, 2))
# 4

Efficient way for checking number 3^x * 5^y

I want to check if number, based on lower and upper bound, has prime divisors only 3 and 5 and number should be multiplication of power of 3 and power of 5. My current solution is this. I want to optimize it, since checking powers with for loops isn't good way in my opinion. Thanks in advance.
def checkNum(x):
for i in range(1,50):
for j in range(1,50):
return x == (3**i) * (5**j)
def printResult(l, r):
for i in range(l,r):
if checkNum(i):
print(i)
Based on comments I think this is the best way:
def checkNum(x):
while x%3==0:
x = x //3
while x%5==0:
x = x//5
return x==1
I want to optimize it, since checking powers with for loops isn't good
way in my opinion.
Over a range of random numbers, we improve its speed by doing:
def checkNum0(x):
if x % 2 == 0: # eliminate half the numbers in one test!
return False
while x % 15 == 0: # speed up the process
x = x // 15
while x % 5 == 0:
x = x // 5
while x % 3 == 0:
x = x // 3
return x == 1
Or we can use a nested loop and combine both divisions into one:
def checkNum(x):
if x % 2 == 0: # eliminate half the numbers in one test!
return False
for divisor in (15, 5, 3):
while (quotient_remainder := divmod(x, divisor))[1] == 0:
x = quotient_remainder[0]
return x == 1

Python nested loops - no output

I've just started learning python. I am trying to check if the integer x is palindrome then divide it by a number between range (starting from largest y i.e. 999 ) y=999,998,...,100. If x/y=z and z is also a 3 digit integer then finish. Otherwise subtract 1 from x and do the same procedure.
def EuQ4():
x=998001
p=999
while 10000 < x:
x=x-1
if str(x)== str(x)[::-1]:
while p>100:
if x%p==0:
Pal=x/p
if Pal < 999:
print (Pal,p)
break
else:
x=x-1
else:
p=p-1
else:
x=x-1
EuQ4()
This is question 4 from Project Euler i.e. Find the largest palindrome made from the product of two 3-digit numbers.
You have a few logic errors in here. Some cause loops that just never end. For example, what happens when x % p == 0 but Pal is larger 999? You would get an infinite loop.
I made a few modifications, but it could still use some work.
def EuQ4():
x = 998001
while 10000 < x:
if str(x) == str(x)[::-1]:
print("{} is a pali!".format(x))
# Move it here so each time it stats at the right
# number or else it will just skip it after it does it once.
p = 999
while p > 100:
if x % p == 0:
pali = int(x / p)
if pali < 999:
print(pali, p)
return
p -= 1
x -= 1
EuQ4()
Edit:
I found these mistakes by using the debugger in my IDE. You could have easily done the same thing by going through the code line by line a few times.
I am sorry but it was hurting my head to read your question. If you are trying to learn Python while attempting these questions then I would propose this alternate answer - it does not answer your question but it does lead to the solution and I think it is more Pythonic. The question asks to find the largest palindrone made from the product of two 3 digit numbers. So the inputs should be 3 digit numbers. This code will allow you to specify the number of digits, max and min (as integers).
I am not proposing that this be the best solution the the Euler Problem posed rather it is a solution that gives you exposure to a range of features in Python.
def min_value(integer):
min_val = '1'
for n in range(0,integer-1):
min_val+='0'
return int(min_val)
def max_value(integer):
max_val = '9'
for n in range(0,integer-1):
max_val += '9'
return int(max_val) +1
def find_max_palindrones(x,y):
minimum_value = min_value(x)
maximum_value = max_value(y)
palindrones = []
working_range = [number for number in range(minimum_value,maximum_value,1)]
for x_value in working_range:
for y_value in working_range:
product = x_value * y_value
orig_order = [item for item in str(product)]
rev_order = [item for item in str(product)[::-1]]
if orig_order == rev_order:
palindrones.append(product)
max_p = max(palindrones)
return max_p
>>>find_max_palindrones(3,3)
906609
Put p=999 befor while p > 100 or use for p in range(999, 100, -1).
p = 999
while p > 100
And I think you call x=x-1 too many times.

Euler Project No. 2 with Python

Can somebody tell me why this should be wrong?
#Each new term in the Fibonacci sequence is generated
#by adding the previous two terms. By starting with 1 and 2,
#the first 10 terms will be:
#1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
#Find the sum of all the even-valued terms in the sequence
#which do not exceed four million.
sum=2
list = [1,2]
for x in range(2,100):
a = list[x-2]+list[x-1]
print(a)
list.append(a)
if a % 2 == 0:
sum += a
print('sum', sum)
if sum >= 4000000:
break
Here's a completely different way to solve the problem using a generator and itertools:
def fib():
a = b = 1
while 1:
yield a
a, b = b, a + b
import itertools
print sum(n for n in itertools.takewhile(
lambda x: x <= 4000000, fib()) if n % 2 == 0)
Output:
4613732
So your code, even though it is wrong (see other answers), happens to give the correct answer.
replace
sum += a
print('sum', sum)
if sum >= 4000000:
break
with
if a > 4000000:
break
sum += a
print('sum', sum)
You should compare "a" with 4000000, not "sum", like Daniel Roseman said.
The question asked for the sum of even terms which do not exceed four million. You're checking if the sum doesn't exceed 4m.
I'm trying to solve the same problem - although I understand the logic to do it, I don't understand why this works (outputs the right sum)
limit = 4000000
s = 0
l = [1,2]
while l[-1]<limit:
n = l[-1]+l[-2]
l.append(n)
print n
And then then moment I put in the modulo function, it doesn't output anything at all anymore.
limit = 4000000
s = 0
l = [1,2]
while l[-1]<limit:
n = l[-1]+l[-2]
if n % 2 == 0 :
l.append(n)
print n
I'm sure this is fairly simple...thanks!
This is the code I used. It is very helpful and teaches you about generators.
def fib():
x,y = 0,1
while True:
yield x
x,y = y, x+y
def even(seq):
for number in seq:
if not number % 2:
yield number
def under_a_million(seq):
for number in seq:
if number > 4000000:
break
yield number
print sum(even(under_a_million(fib())))
-M1K3
Keep it simple and it should take you less than 0.1 seconds.
from datetime import datetime
x, y = 1, 1
total = 0
for i in xrange (1, 100):
x = x + y
if x % 2 == 0 and x <= 4000000:
total += x
y = y + x
if y % 2 == 0 and x <= 4000000:
total += y
print total
starttime = datetime.now()
print datetime.now() - starttime

While loop example

x = y // 2 # For some y > 1
while x > 1:
if y % x == 0: # Remainder
print(y, 'has factor', x)
break # Skip else
x -= 1
else: # Normal exit
print(y, 'is prime')
This is an example for understanding while loop in a book I'm reading, I don't quite understand why a floor division and then y % x? Can someone please explain this piece of code, whats it doing?
Thanks!
This is a lame primality test.
% is the mod operator. It performs division and returns the remainder rather than the result of the division. For example, 5 // 2 == 2, and 5 % 2 == 1.
Commented:
x = y // 2 # For some y > 1 ##Reduce search space to half of y
while x > 1:
if y % x == 0: # Remainder ##If x divides y cleanly (4 / 2 == 2)
print(y, 'has factor', x) ##y is not prime
break # Skip else ##Exit the loop
x -= 1 # Normal exit ##Try the next value
else:
print(y, 'is prime')
The program prints at least one factor of an integer y, or if it has no factors (other than itself and 1), prints that y is prime.
It uses the variable x to try all possible factors greater than one. It starts at the floor of y divided by 2, because no number larger than half of y could be a factor. Using normal division rather than floor division could give you a fractional value if y is odd. (An even better solution is to start with the square root of y - if y is not prime, one of its factors will be less than or equal to its square root.)
Inside the loop, it tests y % x, which is the remainder after dividing y by x. If the remainder is zero, that means that x is a factor of y, and it prints it.
The else clause is executed at the end of the loop, unless a factor is found, in which case the "break" skips out of the loop and the else clause. So either a factor is found, or it's prime.
Here's the improved code with the indentation fixed:
import math
def check_primality(y):
x = int(math.sqrt(y))
while x > 1:
if y % x == 0:
print y, 'has factor', x
break
x -= 1
else:
print y, 'is prime'
The code simply checks if the square root of x has been reached. Note that you can check the primality of a number by checking if the integers from 2 up to the square root of x divides x perfectly (without a remainder).
the logic is:
if y modulo x is 0, it means that x is a dividor of y, so y has a factor. print that, and break out of the loop.
if not, decrease x by 1, and try again.
but some things are broken in this code:
the else statement position
the fact the 'print y is prime' is after the loop - it will always print it.
For any number (x) which is not prime, there would be a factor greater than 1 and less than (x/2).
9 = 3*3
The logic is to iterate through all the numbers <= x/2 and check if the number divides.
I think the program tries to find the biggest prime factors of y.
If y is a prime factor it prints this as well.
x = y // 2 is for testing the numbers in the range x: 2..y/2.
A better approach would be to test only the numbers x: 2..sqrt(y)
the % denotes a modulus which gives you the remainder of division...
and this code checks for prime Y and also checks if Y is a multiplier of x...
x = y // 2 #x=the division or modulus of y , 2
while x > 1: #you want to check if this is a division result or a modulus
if y % x == 0: # if y is a multiplier of x
print(y, 'has factor', x)
break # break the while loop
x -= 1 # decreament x
else: # this line executes if the wihle reached x > 1 and didnt break
print(y, 'is prime')
so if y is a multiplier of x it will decreament x and the loop continue
otherwise it will print y is prime

Categories