logical mistake while checking integer - python

i was just writing a code to check whether a number is a perfect square and encountered an issue - the code is workin only for '4' , for example if entered number is 36, when i reaches the value 6, i**i is found to be 6*36- i mean i possesses different values there
n=int(input('Enter an integer '))
x=0
for i in range(1,n+1):
if (i**i)==n:
print('you entered a perfect square ',i,'^',i,'=',n)
else:
x=x+1
if x==n:
print('you didnt enter a perfect square ')
i dont want any edits to my logic - somebody pls improve the same code

In Python, i**i means i^i, but to check if the given number is a perfect square or not, you need to check if i**2 == n. With your logic, we don't need to check for numbers which are more than sqrt(n). If you use a function, code will be much easier to debug. So an improved version will be:
from math import sqrt
def is_perf_sq(n):
for i in range(1, int(sqrt(n))+1):
if i**2 == n:
return 'You entered a perfect square '+ str(i) + '^ 2 =' + str(n)
return str(n) + ' is not a perfect square'
n = int(input('Enter an integer:').strip())
print(is_perf_sq(n))
Run time improvement:
You don't need to check for all number and square and check them, you just need the square root of that number. Then add 0.5 to it and square the integer part, if we get back the number then it's a perfect square otherwise not. So the code will be then:
from math import sqrt
n = int(input('Enter an integer:'))
if int(sqrt(n)+0.5)**2 == n:
print(n, 'is a perfect square')
else:
print(n, 'is not a perfect square')

change the line
if (i**i)==n:
to
if (i*i) == n:

Related

WAP in python script to input a multidigit number and find each of the number's factorial

The output shows a different result. Yes, the factorials of those numbers are right but the numbers outputted aren't right.
Here's the code:
input:
n = int(input("Enter a number: "))
s = 0
fact = 1
a = 1
for i in range(len(str(n))):
r = n % 10
s += r
n //= 10
while a <= s:
fact *= a
a += 1
print('The factorial of', s, 'is', fact)
Output:
Enter a number: 123
The factorial of 3 is 6
The factorial of 5 is 120
The factorial of 6 is 720
You're confusing yourself by doing it all in one logic block. The logic for finding a factorial is easy, as is the logic for parsing through strings character by character. However, it is easy to get lost in trying to keep the program "simple," as you have.
Programming is taking your problem, designing a solution, breaking that solution down into as many simple, repeatable individual logic steps as possible, and then telling the computer how to do every simple step you need, and what order they need to be done in to accomplish your goal.
Your program has 3 functions.
The first is taking in input data.
input("Give number. Now.")
The second is finding individual numbers in that input.
for character in input("Give number. Now."):
try:
int(character)
except:
pass
The third is calculating factorials for the number from step 2. I won't give an example of this.
Here is a working program, that is, in my opinion, much more readable and easier to look at than yours and others here. Edit: it also prevents a non numerical character from halting execution, as well as using only basic Python logic.
def factorialize(int_in):
int_out = int_in
int_multiplier = int_in - 1
while int_multiplier >= 1:
int_out = int_out * int_multiplier
int_multiplier -= 1
return int_out
def factorialize_multinumber_string(str_in):
for value in str_in:
print(value)
try:
print("The factorial of {} is {}".format(value, factorialize(int(value))))
except:
pass
factorialize_multinumber_string(input("Please enter a series of single digits."))
You can use map function to get every single digit from number:
n = int(input("Enter a number: "))
digits = map(int, str(n))
for i in digits:
fact = 1
a = 1
while a <= i:
fact *= a
a += 1
print('The factorial of', i, 'is', fact)
Ok, apart from the fact that you print the wrong variable, there's a bigger error. You are assuming that your digits are ever increasing, like in 123. Try your code with 321... (this is true of Karol's answer as well). And you need to handle digit zero, too
What you need is to restart the calculation of the factorial from scratch for every digit. For example:
n = '2063'
for ch in reversed(n):
x = int(ch)
if x == 0:
print(f'fact of {x} is 1')
else:
fact = 1
for k in range(2,x+1):
fact *= k
print(f'fact of {x} is {fact}')

Is there a way to remove elements of a range without creating an array/list of included/excluded values in a for loop? (Python)

I am using Python 3.9 and I have created a very simple program to identify whether or not a number is prime when given in integer input.
My code itself works, but it can be very slow even given large numbers
(50 million+). I am using a for loop to check if any numbers between 1
and the input(x) are evenly divisible by the input(x). I want to exclude all
even numbers and multiples of 5 from the range since no primes are even or end in 5.
Is there a way to explicitly remove all evens and multiples of 5 without creating an array of excluded/included values like I did?
Here is a snippet code and time of the program for reference:
#program with filtering out evens and multiples of 5
print("Is your number prime?? Well... let's check!")
#'x' can actually be any input but I am using 60000049 as a constant value for the sake of timing.
x=60000049
factorlist=[]
#Included_values is an array in which all elements are divided into 'x' after it excluded all evens and multiples of 5.
included_values=[]
for i in range (1,x+1):
if i%2!=0 or i%5!=0:
included_values.append(i)
for i in range(1,len(included_values)):
if x%included_values[i]==0:
factorlist.append(i)
if len(factorlist)>2:
print("Oh no! It appears like the number you have entered is not prime. Try again!")
print('The factors to your number are:',factorlist)
if len(factorlist)<=2:
print('Yay! You have chosen a prime number!!')
Yay! You have chosen a prime number!!
~17.96522307395935
The first version of my program is much slower than the one that does not exclude any values:
#My program without filtering out evens or multiples of 5.
#'x' can actually be any number but I am using 60000049 for the sake of timing.
print("Is your number prime?? Well... let's check!")
x=60000049
factorlist=[]
for i in range (1,x+1):
if x%i==0:
factorlist.append(i)
if len(factorlist)>2:
print("Oh no! It appears like the number you have entered is not prime. Try again!")
print('The factors to your number are:',factorlist)
if len(factorlist)==2:
print('Yay! You have chosen a prime number!!')
Yay! You have chosen a prime number!!
~6.147368431091309
As you can see, my second program is much faster because it does not cycle through the range to get an array of excluded values first.
If there is a way to exclude even values and multiples of 5 first without cycling through the entire range (1,x+1), it would make my program much faster. If this is possible, let me know!
To answer your question, you could of course have an if inside the for to skip values. Well you already do, but using a list. I mean you could just have condition there.
Otherwise, a list comprehension is a more efficient way to create a new list than calling append in a loop like you do:
included_values = [i for i in range(1, x+1)
if i%2 !=0 or i%5 != 0]
I did that change in https://replit.com/#ToniAlatalo/DapperSeagreenMacro#main.py
Also the other for I think you could convert from:
for i in range(1,len(included_values)):
to:
for value in included_values:
Which might be a tiny bit faster but probably not much different.
If you want to exclude multiples of 2 or 5 only, you can try using list comprehension included_values = [k for k in range(1,x+1) if k%2!=0 and k%5!=0]
If you want your program to be "more efficient", I suggest checking to the square root of x only. included_values = [k for k in range(1, math.ceil(math.sqrt(x)))]
But, your code is not that efficient.
x = int(input("Is your number prime?? Well... let's check! Type your number here:" ))
from math import sqrt, ceil
if x ==2:
print('Your number is a prime')
elif x < 2:
print("Your number isn't prime")
else:
print('Your number is not prime' if any([k for k in range(2,ceil(sqrt(x))) if x%k==0]) else 'Your number is a prime')
Breakdown of code:
x = int(input("Is your number prime?? Well... let's check! Type your number here:" )) This will get your "x", but if x is predetermined, you can skip this.
from math import sqrt,ceil This will import sqrt and ceil from the math library
if x ==2:
print('Your number is a prime')
elif x < 2:
print("Your number isn't prime")
Check if number is smaller than 3, if it's 2, print the number is prime, else print that it's not prime
print('Your number is not prime' if any([k for k in range(1,ceil(sqrt(x))) if x%k==0]) else 'Your number is a prime') Check if any([k for k in range(2,ceil(sqrt(x))) if x%k==0]) is true, if it's true, number isn't a prime, but if it's false, number is a prime(Since x isn't divisible by any number in range of 2 to square root of x).
Granted, this is not perfect but will be fast enough for normal uses.
The i%2!=0 or i%5!=0 condition will only exclude multiples of 10 from your included_values list. Also, your next loop adds an index (instead of a factor) to the factorlist so it doesn't print the right factors even for the ones it does find (try it with x=15) it will also find that 10 is prime.
All this being said, if you want to list all the factors of the number (when it is not prime), you can't really skip any divisors.
To make it go faster, what you could do is check for factors up to the square root of x and add each divisor along with the resulting quotient for every match you find.
x = 60000049
factors = []
for f in range(1,int(x**0.5)+1):
if x%f == 0:
factors.extend({x//f,f})
print(factors) # [60000049, 1]
By skipping multiples of 2 and 5, appart from skipping factors and producing a wrong result, you'd only reduce the number of tests by 60% but stopping at the square root will eliminate 99.98% of them (for x=60000049).

Have some doubts in this python program (PRIME or NOT)

So, I wrote a code to find if a number is PRIME or NOT...
I wrote it in 2 different ways, they are almost same but I just had a doubt. So here it is:
1st code:
num = int(input("Enter the number: "))
lim = num//2 + 1
for i in range(2,lim):
if num % i == 0:
print("Prime!")
break
else:
print("Not Prime!")
2nd Code:
num = int(input("Enter the number: "))
for i in range(2,num):
if num % i == 0:
print("Prime!")
break
else:
print("Not Prime!")
The 1st code takes the input(num) and according to the input sets a limit(which is the half number + 1)
and then checks if the num is divisible by all the numbers in range (2 to lim)
The second one is same but instead of setting a limit it just checks all numbers lower than the input, which means it has to do a little more work...
Now both of these are almost same, the only difference is I saved a line in 2nd one and output efficiency is also better!
Which code would you want me to prefer/
also if this code has any problems, pointing them out would be helpful!
Thanks :)
Explanation
The most important piece of iteration, namely determining whether a number is prime or not, is to keep track of it. Without this process and in the OP's program, a variable is not used to handle this, meaning that he checks whether a number is or isn't prime every single time and concludes at that point. He also uses an else statement which is syntactically incorrect.
To prevent this, we can use a variable to keep track of this. Let's call it isprime. We need to assume that a number will always be a prime unless otherwise said. This can be achieved by setting isprime to default be True, and setting it to be False when we conclude that it is not a prime, because is has a divisor. Finally, we can check this variable at the end and determine whether that number is a prime or not, because it would be set to False if not, or left as True if it is.
Another observation made is that the limit for determining primes can be reduced down to sqrt(n). This is because we do not need to find every factor if it exists, just its lowest corresponding factor. Let's look at an example:
Factors of 24: 2, 3, 4, 6, 8, 12
We can stop checking for the factors right here:
2, 3, 4 | 6, 8, 12, 24
This is because if a number has a factor (such as greater than the square root), it will have a corresponding factor less than the square root. As a result, we can set our limit to be sqrt(n), just for peace of mind + a time complexity of O(sqrt(n)) v. O(n).
As an extra note, sqrt is not inbuilt into Python. You will have to import it from the math library using:
from math import sqrt
Final Code
# Setup
num = int(input("Enter the number: "))
lim = sqrt(num)
isprime = True
# Loop & check
for i in range(2,lim):
if num % i == 0:
isprime = False
break
# Results
if isprime:
print("Prime!")
else:
print("Not prime!")
The logic of the solution is wrong. You gave to switch the "Prime" and "Not Prime" tags. Like follows;
num = int(input("Enter the number: "))
lim = num//2 + 1
for i in range(2,lim):
if num % i == 0:
print("Not Prime!")
break
else:
print("Prime!")
The solution 1 is more efficient because you do not need to do extra
computation to check num//2 + 1. So it is preferable.

Convert decimal number to binary

This is all the further i've gotten.
import math
num_to_convert = int(input("Please enter any intger from 1 and 100:"))
while num_to_convert < 1 or num_to_convert > 100:
num_to_convert = int(input("Sorry that's not an integer from 1 to 100, try again:"))
else:
print("I'm lost!")
I found this but I don't understand whats going on. Maybe some explanation of what's going on would help.
def decimalToBinary(n):
if(n > 1):
# divide with integral result
# (discard remainder)
decimalToBinary(n//2)
print(n%2, end=' ')
It seems like you want to convert an integer which is not a decimal to binary from your code i would write
while True:
try:
value1=input("Integer you want to convert to binary: ")
binaryvalue=(bin(int(value1)))
print (binaryvalue[2:])
except:
print("I did not understand that")
pass
Valuetoconvert=int(input("Number to convert: "))
u = format(Valuetoconvert, "08b")
print(u)
Try this then
See Below:
def toBin(n):
if n < 2:
return str(n)
else:
if n % 2 == 0:
return toBin(n//2) + "0"
else:
return toBin(n//2) + "1"
Explanation:
This is my sollution which works similar to yours. I hope you know what recursion is otherwise this is going to be difficult to understand.
Anyway the algorithm is to devide the number repeatedly by 2 until the number is smaller than 2 cause then you have the sollution right away(base case).
When the current number is greater than 2 you check wether it is
divisible by 2. If it is even you append a 0 to your string else append a 1. You can try this out on paper to better understand it.

How to find out if a number is a perfect square without using sqrt function or ** in Python? [duplicate]

This question already has answers here:
Check if a number is a perfect square
(25 answers)
Closed 4 days ago.
I have to write a program that finds out whether or not a number is a perfect square. The terms are I don't use a sqrt function or an exponent (**)
I previously showed my teacher my solution using exponent (**) and she told me not to include that there.
num=int(input("Enter a positive integer: "))
base=1
while num/base!=base:
base=base+1
if (num/base)%1==0:
print(num,"is a square")
else:
print(num,"is not a square")
It works fine with perfect squares but when they're not, it won't work because I can't find a way to get it out of the while loop even though it's not a perfect square.
You have to change
while num/base!=base:
to
while num/base>base:
and it will work.
You can iterate till finding a value bigger than you number:
You are sure the while will finish since you have a strictly increasing sequence.
def is_perfect_square(x):
i = 1
while i*i < x:
i += 1
return i*i == x
print(is_perfect_square(15))
# False
print(is_perfect_square(16))
# True
The sum of the first odd integers, beginning with one, is a perfect square.
See proof
1 = 1
1 + 3 = 4
1 + 3 + 5 = 9
1 + 3 + 5 + 7 = 16
and so on .....
So here, we can make use of this important fact to find a solution without using pow() or sqrt() in-built functions.
num = int(input("Enter a positive integer: "))
odd = 1
while num > 0:
num -= odd
odd += 2
if num == 0:
print('It is a pefect square')
else:
print('It is not a pefect square')
I guess it is not a place to answer such questions, but here is a super straightforward solution without using any tricks.
num=int(input("Enter a positive integer: "))
for i in range(num + 1): # in case you enter 1, we need to make sure 1 is also checked
pow = i * i
if pow == num:
print('%d is a pefect square' % num)
break
elif pow > num:
print('%d is not a pefect square' % num)
break
Instead of dividing and taking the remainder, multiply the base and see if it matches the number you are testing. For instance.
for i in range(1, num + 1):
sq = i * i
if sq == num:
print(f"{i} squared is exactly {num}")
break
if sq > num:
print(f"{num} is not a perfect square")
break
You might get a better mark if you do something more clever than increment from 1. A binary search would speed things up a lot for large numbers.
Hey Buddy Try This Code,
num=int(input("Enter a positive integer: "
base=1
while num/base>base:
base=base+1
if (num/base)%1==0:
print(num,"is a square")
else:
print(num,"is not a square")
It should work I tried it
Jai hind jai bharat
Here is something that I came up with:
from math import *
num = eval(input('Enter a number: '))
sq = sqrt(num)
sq1 = sq%1 #here we find the decimal value and then..
if sq1 == 0.0: #if the value = 0 it is a perfect square else it is not, only perfect
squares will be whole numbers.
print(f'{num} is a perfect square')
else:
print(f'{num} is not a perfect square')

Categories

Resources