Python3 Determine if logarithm is "perfect," i.e., no remainder on float - python-3.x

Problem statement:
I am trying to determine if a logarithm is "perfect," i.e., there is no remainder. The issue I am having is that math.log() always returns a float.
I read this: https://docs.python.org/3/tutorial/floatingpoint.html
Here is my current solution:
import sys
import math
def is_even_log(argument, base):
x = math.log(argument, base) # yields float
numerator, denominator = x.as_integer_ratio()
print(
f"numeratorerator: {numerator}, "
f"denominatorominator: {denominator}")
if numerator % denominator == 0:
print(f"Log base {base} of {argument} is even")
return True
else:
print(f"Log base {base} of {argument} is not even")
return False
is_even_log(int(sys.argv[1]), int(sys.argv[2]))
Question
Just curious if anyone has better way to do this? I would imagine that I could access some property of the PyObject which indicates if there is a remainder or not.

You can round the logarithm to the nearest integer, and check if it's correct by exponentiating back up again:
def is_even_log(argument, base):
return argument == base**round(math.log(argument, base))

Log b in base i equals x is equivalent to b equals i to the power x. So the code would be:
def is_even_log(arg, base):
x = math.log(arg, base)
return arg == base ** int(x+1/2)
As the int function returns the truncation of a float, int(x+1/2) returns the rounded number.
This solution works for integers (both arg and base) because in this case the if statement is a comparaison between integers
Testing the equality of floats is not recommended anyways because of the approximations.

Related

Return value of a python function

I am new to python. Does all python function return some value? What will be the return value of the following function?
import math
def getQuadratic(a,b):
square = a**2 + b**2
squareRoot = math.sqrt(square)
return squareRoot
print("The square root of the sum of the squares of 3 and 4 is:", getQuadratic(3,4))
To evaluate the type returned by a Python function, you need to look at EVERY return statement, because each may return something different. And if a function doesn't have an explicit return, there's an implied return None at the end.
In your case there's only one return, and it's easy to figure out what type it's returning.
All python methods return something. Even if you have no return statement they will still return None.
def my_function():
pass
print(my_function())
>>> None
This function is definitely returning something. It's returning the value of the variable squareRoot. So when you're executing the print statement, the value that was returned is getting printed along with the string ahead of it.
Python being a dynamically typed language, does not require you to define any type for variables or functions.
Everything in python is a first class object.
On your example:
import math
def getQuadratic(a,b):
square = a2 + b2 # is this square? a**2?
squareRoot = math.sqrt(square)
return squareRoot
print("The square root of the sum of the squares of 3 and 4 is:", getQuadratic(3,4))
The variables a, b can take on any value.
Python does this by making everything a python object.
So, its easier to think of this way. int is your equivalent in C, however, in python it is treated as class <int>
However, static typing is now possible. It still depends on framework for static typing to be utilized. But your equivalent python program is interpreted as:
import math
def getQuadratic(a:int,b:int) -> float:
square = a2 + b2 # is this square? a**2?
squareRoot = math.sqrt(square)
return squareRoot
print("The square root of the sum of the squares of 3 and 4 is:", getQuadratic(3,4))
TL;DR
In direct answer to your question,
python does not require any types
a = 1 is valid.
a = 'SoF' is still valid
where a is a Python Object, and can be allocated to any other python object such as value, string, functions, or entire modules.
It really doesn't make much difference in types. Its the way Python is designed.

how to display multiplication table by defining function

I know how to display the multiplication table using loops but how do I make a function that can do the same thing? Pls tell me the whole program
#In this method the value of the highest multiple is passed in mult
#base is base value which will be multiplied
#this function runs from mult to 1
def multiply_rev(base,mult):
if(mult == 0):
return
else:
print("{} * {} = {}".format(base,mult,base*mult))
multiply_rev(base,mult-1)
#In this method the value of the lowest multiple is passed in mult
#base is base value which will be multiplied
##this function runs from mult to 10
def multiply_for(base,mult):
if(mult == 11):
return
else:
print("{} * {} = {}".format(base,mult,base*mult))
multiply_for(base,mult+1)
multiply_rev(2,10)
print("+++++++++++++++++++++++++++++++++++++++++++++++++++++++")
multiply_for(2,1)
This is a typical example for recursion. Google recursion for more informaion.

Python seems to make every variable a float

I tried to write a simple fizzbuzz program in python,
I tried to use isinstance to determine if a number is a float or a int instead of creating a list, but whenever I try it for some reason it considers every number to be a float is this a thing in python or a flaw in my logic?
i = 3
if isinstance(i/3,float) == False:
print("Fizz")
else:
print("???")
The / operator returns a float. Even if the value could be expressed by an integer, you'll still get a float. E.g., 3/3 will return the float value of 1.0. Instead, you could check the remainder directly using the % operator:
if i % 3 == 0:
print("Fizz")
else:
print("???")

Types conditions on python after an input

I'm a beginner at programming and what I want is to place a condition in which I write a real number and want the program to tell me whether it's a fractional or an integer.
I'm starting with:
x = float(input("Writte a real number: "))
and then I thought of using a double condition in which I would do something like:
if type(x)==int:
print("integer number")
and another one with float instead of int (or use an else, since I say before to write a real number). But I guess this isn't right since I predefine x as a float. Another problem would be the numbers like 2.0 or 3.0 since they are integer but I would get them as fractionals.
You can achieve this by using an important property of integers: the floor and ceiling value of an integer would be the same; whereas, for a floating-point number, these values would differ by 1.
So, you could do something like:
import math
x = float(input("Writte a real number: "))
if math.ceil(x) == math.floor(x):
print("integer number")
The floor of a number x is the largest integer less than or equal to x.
The ceiling of a number x is the smallest integer greater than or equal to x.
You can see some examples of floor and ceiling here.
Inspired by #Carcigeniacte's comment. You can leave it as a string initially, check the conversions against each other; then if they are the same, it's an int, otherwise it's a float. After that, convert it to whichever numerical type is appropriate for the calculations later. Just don't forget to check for a bad input:
while True:
x = input('write a real number: ')
try:
float(x) # Checking the input can be converted to a number
break
except ValueError:
print('\nPlease input a number') # runs if it can't be converted
continue
if float(x) == int(x): # looking for integers
print('\nInteger Number')
x = int(x)
else:
print('\nFractional Number')
x = float(x)

Generating sequence of numbers with recursion python

The goal is to generate catalan numbers ! my code works up to n = 30 (i tried the same algorithm in JAVA and it's totally correct,but, then something strange happens with python , it gives wrong numbers back after n=30. I'm totally sure that there is an issue about rounding or maybe formats, but can't figure it out by myself!
def catalan(n):
if n < 0:
return -1
else:
if n == 0:
return 1
else:
c_n = (4*n-2)/(n+1)*catalan(n-1)
return int(c_n)
By using /(n+1) you produce a floating point number, which by its nature has a limited precision. This precision is not accurate enough for the larger numbers that appear with n > 30.
So instead, use a formula that sticks with integer numbers: first multiply and only then perform the division, an integer division:
c_n = (4*n-2)*catalan(n-1)//(n+1)
The cast to int is then also unnecessary, and you can just do:
return c_n
Side note: you don't need else when you return in the if part of the statement. So you can write:
def catalan(n):
if n < 0:
return -1
if n == 0:
return 1
return (4*n-2)*catalan(n-1)//(n+1)

Resources