The function menu5 returns a message to the user. I would like at the same time that the user called this function, that it called another similar function, that sent message to another person.
Here is the code:
def menu5(self, message=None, match=None, to=None):
# Retransfer the requester's phone
number = message.getFrom()
# Cut after the #
number = number.split('#')
# Separate only the number
number = number[0]
# Delete the 55
number = number[2:13]
# Person who will receive the message
toSend = '5527999999999#s.whatsapp.net'
# Function call to be triggered
self.operator(msg=number, op=toSend)
return textMessageProtocolEntity(txtMenu5, to=message.getFrom())
def operator(self, to=None, msg=None, op=None):
return TextMessageProtocolEntity(msg, to=op)
If you want the return value of some function, you need to explicitly store it:
def menu5(self, message=None, match=None, to=None):
# ...
# Function call to be triggered
txtmsg = self.operator(msg=number, op=toSend)
return TextMessageProtocolEntity(txtMenu5, to=message.getFrom()), txtmsg
The function menu5 now returns a two-element tuple with two TextMessageProtocolEntitys in it. Note that your original code was always calling self.operator, as expected - it just wasn't doing anything with the return value.
Related
The task is to write a class decorator, which reads a JSON file and makes its key/values to become properties of the class.
But one of conditions is that there has to be the ability to pass values manually (by creating a class object) as well.
I almost did it. There's just a tiny problem. The program reads data from JSON file and passes them successfully to the class. But when passing values manually during creation of an object of the class, values don't change and they are still being taken from JSON.
The problem only disappears when passing values as default values.
room = Room(1, 1) # Doesn't work
room = Room(tables=1, chairs=1) # Does work
Since arguments have to be passed only as numbers in tests, I have to manage it to work with just numbers, not default values.
Here's the code.
from json import load
def json_read_data(file):
def decorate(cls):
def decorated(*args, **kwargs):
if kwargs == {}:
with open(file) as f:
params = {}
for key, value in load(f).items():
params[key] = value
return cls(**params)
else:
return cls(*args, **kwargs)
return decorated
return decorate
#json_read_data('furniture.json')
class Room:
def __init__(self, tables=None, chairs=None):
self.tables = tables
self.chairs = chairs
def is_it_enough(self):
return self.chairs * 0.5 - self.tables > 0.4
kitchen = Room() # This is passing values from JSON file
print(kitchen.__dict__) # Prints {'tables': 2, 'chairs': 5}
room = Room(tables=1, chairs=1) # This is passing values manually
print(room.__dict__) # Prints {'tables': 1, 'chairs': 1}
'''
JSON file:
{
"tables": 2,
"chairs": 5
}
'''
But if we change to room = Room(1, 1), print(room.dict) prints {'tables': 2, 'chairs': 5} again. Please help me solve this problem!
You need to add your arguments to the decorator. Remember that your decorator is called first and then it calls the decorated function.
You could declare your decorator as: def json_read_data(file, *args): then the subsequent calls to cls() would have to be adapted to accept them. The second one already does, the first one needs modification.
It seems, this edit really worked:
def decorated(*args, **kwargs):
if not args and not kwargs:
I have a class named knob and one of my methods is get_click(click). Right now when I call the method get_click(click) I have to specify a Integer value first in order for the code to execute like so knob.get_click(5000). How would I design this portion so that if I don't specify an Integer value the get_click(click) would run would pass a default value and only change when I add an Integer parameter. I tried adding default values in the constructor, but the get_click(click) function kept asking for an argument.
class knob:
def __init__(self, click = "7000", rotateleft="50", rotateright="50"):
self.click = click
self.rotateleft = rotateleft
self.rotateright = rotateright
def get_click(click):
print("G4 "+ str(click) +"\r\n")
def get_rotateleft(self):
return self.rotateleft
def get_rotateright(self):
return self.rotateright
def get_click(self, click=5000): # Set Default value for click
print("G4 "+ str(click) +"\r\n")
I'm creating a class using tkinter that lets you input multiple product's information, and I've got everything else down except for changing the entry fields to set values for the other products.
I'm putting the product changeover process into a function called saveVars which saves the entered information to the specific product variable, and then clears the entry fields, and switches the saveVars to be performed on the second product variable.
i = 1
def saveVars(i):
if i == 1:
product1.productName = self.prodName.get()
product1.productID = self.prodID.get()
product1.productSize = self.prodSize.get()
product1.productPrice = self.prodPrice.get()
product1.productQuant = self.quantity.get()
elif i == 2:
product2.productName = self.prodName.get()
product2.productName = self.prodID.get()
product2.productSize = self.prodSize.get()
product2.productPrice = self.prodPrice.get()
product2.productQuant = self.quantity.get()
elif i == 3:
product3.productName = self.prodName.get()
product3.productName = self.prodID.get()
product3.productSize = self.prodSize.get()
product3.productPrice = self.prodPrice.get()
product3.productQuant = self.quantity.get()
newProduct()
i += 1
return i
I'm expecting to get it to switch the variable the entries are being saved to to the next respective product based on a +1 function, I'm having it return the i function as the new i, which should then save the entries to the next variable in the process, but it keeps telling me that I'm 'missing 1 required positional argument: 'i'
You are trying to call the function without parameter as the command attribute does not take parameters just the name of the function.
To pass parameters you could use partial form functools package
import statement :
from functools import partial
your call to function would look like :
addItemButton = Button(window, text = "Add to Cart", fg='black',bg='yellow',width = 10, height = 2, command = partial(saveVars,i)) addItemButton.place(x=800,y=375)
You can set the inital value to i in your class using a global variable instead of declaring it outside the class. You can save it anywhere you wish and pass it while calling the funtion.
It seems like you are calling saveVars without the parameter in some case. To prevent this you can set a default value of i, eg.
def saveVars(i=0)
I am creating a class to make some calculations. The class would have 3 arguments to get started. I have done like this in a simplified representation:
class TheCalcs:
def __init__(self, pk_from_db, cat_score_list, final_score):
self.pk_from_db = pk_from_db
self.cat_score_list = cat_score_list
self.final_score = final_score
def calculate_cat_score(self):
#Do some calcs with the data of the pk_from_db and return that!
a_list_of_scores = [] # create a list of scores
return a_list_of_scores
def final_score(self): # The argument for this function would be the return of the calculate_cat_score function!
# Again do some calcs and return the final score
the_final_score = int()
return the_final_score
def score_grade(self): # the argument this this function again the return but now from the final_score function
# Do some cals and return the grade
the_grade = ("a string", "an integer")
return the_grade
When I call the class I would have to present the arguments --> However as you can see I just do now the value of the first argument. The second and the third being calculated throughout the class. When I call the class just with one argument I will of course have an error of failing arguments. Anyone has an idea on that?
If those values are calculated, simply don't make them arguments. You could instead call those calculation methods to compute the values:
class TheCalcs:
def __init__(self, pk_from_db):
self.pk_from_db = pk_from_db
self.cat_score_list = self.calculate_cat_score()
self.final_score = self.calculate_final_score()
# ...
or postpone calculations until you need them.
I keep getting error: "unhashable type: list" for line (routing_table[key][0] = [[params], func]. I'm attempting to pass a url and function into a route function. This route function should pick out the parameters for other functions by use of regular expressions. The ultimate goal is to read in "/page/<page_id>, then pick out <page_id> and replace that with user input. That user input will then be passed into the function. I don't see why this isn't working.
import re
routing_table = {}
def route(url, func):
key = url
key = re.findall(r"(.+?)/<[a-zA-Z_][a-zA-Z0-9_]*>", url)
if key:
params = re.findall(r"<([a-zA-Z_][a-zA-Z0-9_]*)>", url)
routing_table[key][0] = [[params], func]
else:
routing_table[url] = func
def find_path(url):
if url in routing_table:
return routing_table[url]
else:
return None
def index():
return "This is the main page"
def hello():
return "hi, how are you?"
def page(page_id = 7):
return "this is page %d" % page_id
def hello():
return "hi, how are you?"
route("/page/<page_id>", page)
print(routing_table)
I'm not sure why you are using re.findall if you're only interested in the first value found.
Nevertheless, your problem is simply the way you index the result: key is a list, and as the error says, you can't use a list as a dict key. But you've put the [0] outside the first set of brackets, so Python interprets this as you wanting to set the first value of routing_table[key], rather than you wanting to use the first value of key as the thing to set.
What you actually mean is this:
routing_table[key[0]] = [[params], func]