How can i convert binary string to its numerical equivalent? - python-3.x

I'm trying to get toBase10(101) to spit out 5. I also need it to work for numbers besides 101, I know that there is a binary converter built into python but I can't figure it out.
Right now I have
def toBase10(x):
int( 'x' , 2 ) == x
return x
I get the error can't convert non-string with explicit base. Why can't I use x in here?

def toBase10(x):
return int(x, 2)

I converted the integer into a string and then into binary with which I could easily convert into an integer:
def binaryconvert(x):
x = str(x)
binarynumber = int(x, base=2)
convertnumber = int(binarynumber)
return convertnumber
print(binaryconvert(101))
#the answer would be 5
There's also another way if your input is already binary:
def binaryconvert(x):
convertnumber = int(x)
return convertnumber
x = int(input("Input: "),2)
print(binaryconvert(x))

try
def toBase10(item):
return int(str(item),2)
then you can pass either string or int
print toBase10(101)
print toBase10('101')
i think the int cast error is because you are passing in a number not a string, although this looks odd --> "int( x , 2 ) == x" too

Related

Convert Float with decimal to string without decimal Python 3.7

Struggling to convert a float 12345678.0 to a string 12345678 Gone through a few different solutions I've found in SO, but can't seem to get to the finish line, the decimal point will not drop.
Here is what I've tried
df["variable"]= df["variable"].astype(str)
df["variable"]= df["variable"].astype(int).astype(str)
# old lambda solution
cols = ['variable']
for col in cols:
df[col] = df[col].apply(lambda x: int(x) if x == x else "")
# convert int to string
df["variable"] = df["variable"].astype(str)
You can do it simply like this:
df['variable'] = df['variable'].astype(int, errors = 'ignore').astype(str)
Here's your lambda function
lambda x: str(int(x))

Python3 Determine if logarithm is "perfect," i.e., no remainder on float

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.

How to convert all 'object' values in dataset to float or int in a single command?

I have a train dataset which has 43 attributes. Each of the attributes have some tuple values as objects (as in strings with certain characters).
Now, I'm trying to scale the values using a scaler, but it gives the following error:
could not convert string to float: '?'
Now, I don't know how to convert objects to int or float in a single command and converting it for each of the 43 attributes one by one is a bit tedious.
So I want to know how to do it for the complete dataset with a single command.
I use the convert function which tries to parse the string as a float.
If it cannot, it tries to parse it as a int, and if it still cannot, assigns the value 0 (you can change the default value is the string is not a int or a float to something else)
l = []
def convert(str):
x = 0
try:
x = int(str)
except:
try:
x = float(str)
except:
pass
l.append(x)
for i in ['1','2','3','?','4.5']:
convert(i)
print(l)
#[1, 2, 3, 0, 4.5]

Creating a function that returns index of minimum value in a list?

def minimum_index(xs):
minimum_index=xs[0]
for i in range(len(xs)):
if xs[i]<xs[i+1]:
min_i=i
elif xs[i]>xs[i+1]:
min_i=i+1
continue
return minimum_index
This looks correct to me, but for some reason, I keep trying to change things around and I either get an incorrect return value or no return value.
Simplify the function
def minimum_index(xs):
ans = 0
for i in range(1, len(xs)):
if xs[i] < xs[ans]:
ans = i
return ans
or in a more pythonic way
minimum_index = lambda xs: xs.index(min(xs))
Your code has at least two issues: You seem to have two variables that stand for the minimal index, and you mix them up. Also, it is not enough to compare subsequent elements, you will have to compare to the minimal value. Try this:
def minimum_index(xs):
minx = xs[0]
mini = 0
for i in range(1,len(xs)):
if xs[i]<minx:
mini = i
minx = xs[i]
return mini
If you are using numpy, then you can simply use their numpy.argmin(xs).

When to use ast.literal_eval

I came across this code and it works, but I am not entirely sure about when to use ast and whether there are performance issues when this is used instead of getting the string value from input() and converting it to int.
import ast
cyper_key = ast.literal_eval(input("Enter the key (a value between 0 and 25) : "))
# this get the user input as an int to the variable cyper_key
I read the docs I understand what it does.
This can be used for safely evaluating strings containing Python
values from untrusted sources without the need to parse the values
oneself. It is not capable of evaluating arbitrarily complex
expressions, for example involving operators or indexing.
I am looking for an explanation on above bold points.
When to use it.
ast.literal_eval(input()) would be useful if you expected a list (or something similar) by the user. For example '[1,2]' would be converted to [1,2].
If the user is supposed to provide a number ast.literal_eval(input()) can be replaced with float(input()), or int(input()) if an integer is expected.
Performance
Note that premature [micro-]optimization is the root of all evil. But since you asked:
To test the speed of ast.literal_eval(input()) and float(input() you can use timeit.
Timing will vary based on the input given by the user.
Ints and floats are valid input, while anything else would be invalid. Giving 50% ints, 40% floats and 10% random as input, float(input()) is x12 faster.
With 10%, 10%, 80% and float(input()) is x6 faster.
import timeit as tt
lst_size = 10**5
# Set the percentages of input tried by user.
percentages = {'ints': .10,
'floats': .10,
'strings': .80}
assert 1 - sum(percentages.values()) < 0.00000001
ints_floats_strings = {k: int(v*lst_size) for k, v in percentages.items()}
setup = """
import ast
def f(x):
try:
float(x)
except:
pass
def g(x):
try:
ast.literal_eval(x)
except:
pass
l = [str(i) for i in range({ints})]
l += [str(float(i)) for i in range({floats})]
l += [']9' for _ in range({strings}//2)] + ['a' for _ in range({strings}//2)]
""".format(**ints_floats_strings)
stmt1 = """
for i in l:
f(i)
"""
stmt2 = """
for i in l:
g(i)
"""
reps = 10**1
t1 = tt.timeit(stmt1, setup, number=reps)
t2 = tt.timeit(stmt2, setup, number=reps)
print(t1)
print(t2)
print(t2/t1)
ast -> Abstract Syntax Trees
ast.literal_eval raises an exception if the input isn't a valid Python datatype, so the code won't be executed if it's not.
This link AST is useful for you to understand ast.
If it's going to be used as an int, then just use:
cypher_key = int(input("Enter the key (a value between 0 and 25) : "))
Only use that if you expect the user to be entering 10e7 or something. If you want to handle different bases, you can use int(input(...), 0) to automatically divine the base. If it really is an integer value between 0 and 25, there's no reason to use ast.
Running this in a python-3.x shell, I get no differences when I give correct input:
>>> cyper_key = ast.literal_eval(input("Enter the key (a value between 0 and 25) : "))
Enter the key (a value between 0 and 25) : 5
>>> cyper_key
5
However, when you give a string or something that cannot be converted, the error can be confusing and/or misleading:
>>> cyper_key = ast.literal_eval(input("Enter the key (a value between 0 and 25) : "))
Enter the key (a value between 0 and 25) : foo
Traceback (most recent call last):
File "python", line 3, in <module>
ValueError: malformed node or string: <_ast.Name object at 0x136c968>
However, this can be useful if you don't want to cast either float or int to your input, which may lead to ValueErrors for your int or floating points for your float.
Thus, I see no necessary use in using ast to parse your input, but it can work as an alternate.

Resources