Python Class replacement not working - python-3.x

class A:
def __init__(self, a: int, b: [str]):
self._foo = a
self._bar = b
def get_foo(self):
return self._foo
def get_bar(self):
return self._bar
def do_that(given):
x = given.get_foo()
x += 10
y = given.get_bar()
y[0] += ' there'
y = ['cool']
given = A(-10, ['test'])
x = A(1, ['hello'])
print(x.get_bar())
How come print(x.get_bar()) prints hello there, instead of 'test' when given is replaced with A(-10, ['test'])? In a similar function like this,
def test(x):
x = 4
return x
x = 1
test(x)
x is replaced with 4 and 4 is actually returned.

In your second bit of code def test(x):, you're overwriting the input to 4, regardless of what you put in by setting x = 4.
In your first bit of code, you're not actually calling the do_that(given): function when you call x.get_bar(), so the ['hello'] will not be overwritten with ['test']. Also, where given is defined as a variable within def get_bar(given):, it is not ever being used.

Related

Is there a way to convet a user's input string into a class method name in python?

hi I've recently started working with classes in python and there is a code which I must use class for converting temperature scales . for example you choose two scales and give the temp in the first scale and the temp in the second scale will be shown in the output.one way is to use if condition , for example I can get an input from the user and after checking the conditions call the desired method:
class temp_convertor:
def c_f(c):
f = 1.8*(c)+32
return f
def f_c(f):
c = (f-32)*(5/9)
return c
def c_k(c):
k = c +273.15
return k
def k_c(k):
c = k-273.15
return c
def c_r(c):
r = temp_convertor.c_f(c)+ 459.67
return r
def r_c(r):
c = temp_convertor.f_c(r-459.67 )
return c
def k_r(k):
r = temp_convertor.c_r(temp_convertor.k_c(k))
return r
def r_k(r):
k = temp_convertor.c_k(temp_convertor.r_c(r))
return k
a = input("scale1,scale2: ")
if a == "f,c":
temp_convertor.f_c(float(input("temp? ")))
elif a == "c,f":
temp_convertor.c_f(float(input("temp? ")))
# and for every convertor I should continue checking conditions :(
but I've used global()[name] for calling functions before for example:
def apple(a):
print(2*a)
globals()[input("type apple if you want to double your number: ")](int(input("number: ")))
and the output is something like this:
type apple if you want to double your number: apple
number: 5
10
but I can't use that here:
class temp_convertor:
def c_f(c):
f = 1.8*(c)+32
return f
def f_c(f):
c = (f-32)*(5/9)
return c
def c_k(c):
k = c +273.15
return k
def k_c(k):
c = k-273.15
return c
def c_r(c):
r = temp_convertor.c_f(c)+ 459.67
return r
def r_c(r):
c = temp_convertor.f_c(r-459.67 )
return c
def k_r(k):
r = temp_convertor.c_r(temp_convertor.k_c(k))
return r
def r_k(r):
k = temp_convertor.c_k(temp_convertor.r_c(r))
return k
print(temp_convertor.globals()[input("scale1_scale2")](float(input("temp? "))))
and the error is : AttributeError: type object 'temp_convertor' has no attribute 'globals'
I want to know if the second solution is somehow possible and if not is there any shorter solution ?
Thanks for reading this!
use
getattr(temp_convertor, input('scale1_scale2: '))(float(input('temp? ')))

Why does my number reverser function produce an infinite loop

Whenever i try print the number reverser function i always get an infinite loop,instead of my expected output 54321. Can someone help find the problem? Thanks.
def order(num):
x=str(num)
if x==False:
return None
else:
return order(x[1:])+(x[0])
print (order(12345))
Welcome to your community.
There are some problems with your code:
First:
A string never will be equal to False.
for instance:
'0' is not equal to False.
'' is not equal to False.
Second:
You cannot add a String to None.
This Error will be thrown: TypeError: can only concatenate str (not "NoneType") to str
Modify your code like this:
def order(num):
x=str(num)
if x=='':
return ''
else:
return order(x[1:])+(x[0])
print (order(12345))
Tip 1: A string can be equal to '' (empty string).
In your function, you compare the string x with the boolean False. This is not a correct way to test whether string x is an empty string or not.
In addition, if string x is empty, then you shouldn't return None, but an empty string: reversing an empty string should logically return an empty string.
Here I present two ways to fix your function, which I implemented under the names reverse0 and reverse1. I also present a few other alternatives to achieve the same result using python features, under the names reverse2 to reverse6. Finally I present three other ways to reverse nonnegative integers, under the names reverse7 to reverse9.
def reverse0(num):
x = str(num)
if len(x) == 0:
return ''
else:
return reverse0(x[1:]) + x[0]
def reverse1(num):
x = str(num)
if not x:
return ''
else:
return reverse1(x[1:]) + x[0]
def reverse2(num):
return str(num)[::-1]
def reverse3(num):
return ''.join(reversed(str(num)))
def reverse4(num):
x = str(num)
return ''.join(x[len(x)-1-i] for i in range(len(x)))
def reverse5(num):
x = str(num)
return ''.join(x[-i] for i in range(1, len(x)+1))
def reverse6(num):
y = ''
for c in str(num):
y = c + y
return y
# reverse7 only works for nonnegative integers
def reverse7(num):
if num < 10:
return str(num)
else:
return str(num % 10) + reverse7(num // 10)
# reverse8 only works for nonnegative integers
def reverse8(num):
l = []
while num > 9:
l.append(num % 10)
num = num // 10
l.append(num)
return ''.join(str(d) for d in l)
# reverse9 only works for nonnegative integers
# reverse9 returns an int, not an str
def reverse9(num):
y = 0
while num > 0:
y = 10 * y + (num % 10)
num = num // 10
return y
Relevant documentation:
builtin reversed;
str.join;
An informal introduction to string slices such as x[::-1].

how to pass dictionary value to arithmetic functions in different classes of python

I am trying to pass a dictionary value to a simple arithmetic
functions. I am using 3 classes.ClassA have add() sub() mul() div() functions defined.Class B contain only values used for operations. Class c having some checks.ClassA look like these.
class ClassA(object):
def addition(self, x, y):
return x + y
def substraction(self, x, y):
return x - y
def division(self, x,y):
return x / y
def multiplication(self, x, y):
return x * y
ClassB looks like this.
class ClassB(object):
def __init__(self):
self.var1 = 2
self.var2 = 8
and here is ClassC
from File1 import ClassA
from File2 import ClassB
class ClassC(ClassB):
def __init__(self,ClassB):
self.var3= ClassB.var1
self.var4= ClassB.var2
print(self.var3)#testing
print(self.var4)#testing
def checkWholeNumber(self):
if self.var3%2 ==0 or (self.var3+1)%2 & self.var4%2 == 0 or (self.var4+1)%2:
print(self.var3) #if value is whole then it will print some value or will throw exception
return True
return False
def addDictAndAss(self):
myDict={}
myDict["x"]=self.var3
myDict["y"]=self.var4
print(myDict) #to check whether values are added or not
object1 = ClassB()
object2 = ClassC(object1)
object2.checkWholeNumber()
object2.addDictAndAss()
object3= ClassA()
object3.addition(*myDict)
Now I want to assign my created dictionary to functions of the classA. Thanks in advance.
Edit1:File1.py contain ClassA ,File2.py contain ClassB, File3.py contain ClassC
#Step1:
class ClassA(object):
def addition(x, y):
X=x
Y=y
return X + Y
def substraction(x, y):
X = x
Y = y
return X - Y
def division(x, y):
X = x
Y = y
return X / Y
def multiplication(x, y):
X = x
Y = y
return X * Y
#step2:
class ClassB(object):
def __init__(self):
self.var1 = 10
self.var2 = 8
#Step3:
from File1 import ClassA
from File2 import ClassB
class ClassC(ClassB):
def __init__(self,ClassB):
self.var3= ClassB.var1
self.var4= ClassB.var2
#print(self.var3)#testing
#print(self.var4)#testing
def checkWholeNumber(self):
if self.var3%2 ==0 or (self.var3+1)%2 & self.var4%2 == 0 or (self.var4+1)%2:
# print(self.var3) #if value is whole then it will print some value or will throw exception
return True
return False
def addDictAndAss(self):
myDict={}
myDict["x"]=self.var3
myDict["y"]=self.var4
#print(myDict) #to check whether values are added or not
print("Please select one arithmatic operator i.e. '+','-','/','*'")
operator=input()
if operator == '+':
add=ClassA.addition(**myDict)
print(add)
elif operator == '-':
sub=ClassA.substraction(**myDict)
print(sub)
elif operator == '/':
div=ClassA.division(**myDict)
print(div)
elif operator == '*':
mul=ClassA.multiplication(**myDict)
print(mul)
# Creating object and calling(assiging)
object1 = ClassB()
object2 = ClassC(object1)
object2.checkWholeNumber()
object2.addDictAndAss()
object3= ClassA()
Please suggest a better way to do this.

Python: How can I change a function's argument value from an inner frame?

In the example below, force should change the value of the parameter x of the double function. ValidateAndCast checks the given parameter and casts it. So in this case, after force returns, x should be 2, and thus the return value of double should be 4. Assume that all the altering is done in the force function.
How do I achieve this? I've looked into inspect so far and will continue studying.
def is_number(x):
try:
float(x)
return True
except:
return False
def to_int(x):
return int(float(x))
def double(x):
force(x=ValidateAndCast(is_number, to_int))
return x * 2
x = '2.54'
y = double(x)
print(y)
This solution works for me.
import ctypes
import inspect
def change():
def apply(frame):
frame.f_locals['x'] = 4
ctypes.pythonapi.PyFrame_LocalsToFast(ctypes.py_object(frame), ctypes.c_int(1))
calling_frame = inspect.stack()[1][0]
apply(calling_frame)
def f(x):
change()
return x * 2
y = f(2)
print(y) # prints 8

how to multiply all numbers in a stack

Trying to multiply all the numbers in a stack, I originally thought of popping all elements into a list and then multiplying but wasn't sure how to/ if that was right.
this is my current code but I'm getting:
TypeError: 'method' object cannot be interpreted as an integer.
def multi_stack(s):
stack = Stack()
mult = 1
size = my_stack.size
for number in range(size):
tmp = my_stack.pop(size)
mult = mult * tmp
L.append(tmp)
for number in range(size):
my_stack.push(L.pop())
print(must)
I made a test case aswell
my_stack = Stack()
my_stack.push(12)
my_stack.push(2)
my_stack.push(4)
my_stack.push(40)
print(multi_stack(my_stack))
print(my_stack.size())`
this should print out :
3840
0
The Stack class I'm using
class Stack():
def __init__(self):
self.items = []
def is_empty(self):
return self.items == []
def push(self,items):
return self.items.append(items)
def pop(self):
if self.is_empty() == True:
raise IndexError("The stack is empty!")
else:
return self.items.pop()
def peek(self):
if self.is_empty() == True:
raise IndexError("The stack is empty!")
else:
return self.items[len(self.items) - 1]
def size(self):
return len(self.items)
Python lists support append() and pop() methods that allow you to replicate LIFO stack behavior. Use append() to add to the end and pop() to remove the last element.
However, the underlying data structure is still a list. You can use many things to multiply a list together. for example, assuming a non-empty list:
import functools
mylist = [i for i in range(1, 10)]
product = functools.reduce(lambda x, y: x * y, mylist)
or
mylist = [i for i in range(1, 10)]
product = mylist[0]
for j in mylist[1:]:
product *= j
EDIT: Here is an example using your Stack class:
import functools
stack = Stack()
stack.push(1)
stack.push(3)
stack.push(9)
def multi_stack(s):
"""
s: a Stack() object
"""
return functools.reduce(lambda x, y: x * y, s.items)
def multi_stack_readable(s):
"""
s: a Stack() object
"""
if s.size() > 1:
product = s.items[0]
for i in s.items[1:]:
product *= i
return product
elif s.size() == 1:
return s.items
else:
raise IndexError("the stack is empty!")
print(multi_stack(stack))
print(multi_stack_readable(stack))
Using lambda functions is sometimes considered less readable, so I included a more readable version using a for loop. Both produce the same result.
Your code doesnt work because size = my_stack.size returns a method object and not the integer you expected; you forgot to add the parentheses at the end to actually call the method. So when you tried for number in range(size):, you get an exception because you are passing a method object instead of an integer to range(). There are also a bunch of other mistakes: you didnt use the parameter passed to the function at all, instead affecting global variable my_stack (unless that was your intent); you're performing operations on some unknown variable L; you created stack at the top of your function and did nothing with it, and so on. In general, too convoluted for such a simple goal. There are more efficient ways to do this but correcting your code:
def multi_stack(s):
mult = 1
size = s.size()
for i in range(size):
tmp = s.pop()
mult = mult * tmp
return mult
This should return your expected product, though it wont empty the stack. If you want to do that, then get rid of the function parameter, and substitute s for my_stack as before.

Resources