Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 days ago.
Improve this question
I have a small fastapi application that can get 4 optional arguments from the user, and based on the user's input run a matching function like so:
def do_function(origin, destination, departure, arrival):
if departure is None and arrival is None:
do_a(origin, destination)
elif departure is not None and arrival is None:
do_b(origin, destination, departure)
elif departure is None and arrival is not None:
do_c(origin, destination, arrival)
elif departure is not None and arrival is not None:
do_d(origin, departure, arrival)
elif departure is not None and arrival is None:
do_e(origin, departure)
# and so on...
What is the most pythonic way of executing this code without using long and tiering "if-elif"?
I've seen a similar question here: most efficient way to selection specific function based on input , but it doesn't apply to my case where there are only 4 optional inputs and more than 4 function options.
Use Structural Pattern Matching (3.10+)
This situation is a very good one to use Structural Pattern Matching.
def do_function(origin, destination, departure, arrival):
match (origin, destination, departure, arrival):
case (origin, destination, None, None):
print(origin, destination)
case (origin, destination, departure, None):
print(origin, destination, departure)
case (origin, destination, None, arrival):
print(origin, destination, arrival)
case (origin, destination, departure, arrival):
print(origin, departure, arrival)
Here is a tutorial on structural pattern matching, and here is the PEP 622.
Create a map dict[tuple[bool, bool], function]:
function_map = {
(True, True) : foo,
(True, False) : bar,
...
}
func_key = departure is None, arrival is None
function_map[func_key](origin, departure, arrival)
Related
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
I'm making a simple program in order to compare the currentdate to another date, and I need to separate the "/" and remove trailing zeros; I made a function for that:
def correctdate(compare, Dayslist, Monthslist):
for day in compare:
if day == "/" or day == "\\":
compare.remove(day)
break
else:
Dayslist.append(day)
for removenum in Dayslist:
#* Removing the numbers from the list
compare.remove(removenum)
for month in compare:
Monthslist.append(month)
#* Joining the numbers into a string
correctdate.DaysLeft = "".join(Dayslist)
correctdate.MonthsLeft = "".join(Monthslist)
#* Stripping leading zeros
correctdate.DaysLeft = correctdate.DaysLeft.lstrip("0")
correctdate.MonthsLeft = correctdate.MonthsLeft.lstrip("0")
return
The code works just fine but i want to save the DaysLeft, Monthsleft to print it/edit it ETC..
so i do this:
correctdate(compare,Dayslist,Monthslist)
print(correctdate.Daysleft)
and i get this:
AttributeError: 'function' object has no attribute 'Daysleft'
There was a typo in printing the object attribute
I wrote:
print(correctdate.Daysleft)
Its supposed to be:
print(correctdate.DaysLeft)
Sorry for the inconvenience
You ve to return it in your function, and outside it get it into variables:
def correctdate(compare, Dayslist, Monthslist):
for day in compare:
if day == "/" or day == "\\":
compare.remove(day)
break
else:
Dayslist.append(day)
for removenum in Dayslist:
#* Removing the numbers from the list
compare.remove(removenum)
for month in compare:
Monthslist.append(month)
#* Joining the numbers into a string
correctdate.DaysLeft = "".join(Dayslist)
correctdate.MonthsLeft = "".join(Monthslist)
#* Stripping leading zeros
correctdate.DaysLeft = correctdate.DaysLeft.lstrip("0")
correctdate.MonthsLeft = correctdate.MonthsLeft.lstrip("0")
return correctdate.DaysLeft,correctdate.MonthsLeft
This for return outside function, now you ve to call function correctly:
DaysLeft,Monthsleft = correctdate(compare,Dayslist,Monthslist)
print(DaysLeft,Monthsleft)
Anyway this code "correctdate.MonthsLeft" looks like you want use class and not only functions, so you should use like that https://www.w3schools.com/python/python_classes.asp
def correctdate(compare, Dayslist, Monthslist):
You declare a function with name correctdate that accepts 3 parameters.
correctdate.DaysLeft = "".join(Dayslist)
correctdate.MonthsLeft = "".join(Monthslist)
Then you try to assign a value to a function, which is not possible because correctdate is not a variable, not an object. You just declared it as a function.
What are you trying to achieve?
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I am trying to create a code that does not require parameters to determine if one is qualified for a loan, but the function takes years and annual wage into account to determine if qualified. How can I get the function to take inputs without parameters?
edit: I cannot give it parameters becausse that is what was asked of me. To create this function without parameters.
def loan():
"""
-------------------------------------------------------
To qualify for a loan, the annual salary must be 30000 or more and
employee must have worked for a minimum of 5 years
Use: qualified = loan()
-------------------------------------------------------
Returns:
qualified - True if employee qualifies for a loan,
False otherwise (boolean)
-------------------------------------------------------
"""
MIN_SALARY =30000
MIN_YEARS = 5
if years < 5:
qualified = False
elif years >= MIN_YEARS:
if salary >= MIN_SALARY:
qualified = True
else:
qualified = False
else:
qualified = False
return qualified
#--------------Main Program-----------------#
years = int(input('Years employed: '))
salary = float(input('Annual salary: '))
qualified = loan(years = years, salary = salary)
print()
print('Qualified for a loan: {}'.format(qualified))
You could use keyword args for this...
def loan(**kwargs):
...
...but the more sensible and practical thing would be to specify the parameters you expect to be passed into the function.
def loan(years, salary):
...
Methods aren't magical and they have their own scope. If you don't add variables to that scope, then the only way you'd get information is from global scope, which is expressly discouraged and also wholly unnecessary in this case.
I was able to figure it out. What I did was add the inputs into the code itself.
def loan():
"""
-------------------------------------------------------
To qualify for a loan, the annual salary must be 30000 or more and
employee must have worked for a minimum of 5 years
Use: qualified = loan()
-------------------------------------------------------
Returns:
qualified - True if employee qualifies for a loan,
False otherwise (boolean)
-------------------------------------------------------
"""
years =(int(input('Years employed: ')))
salary = (float(input('Annual salary: ')))
#rest of the function
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
I need to print following info using unnecessary argument (track):
def make_album(singer, album, track = ''):
album = {'singer_name' : singer, 'slbum' : album}
if track:
album['track'] = track
return album
output = make_album('Linkin Park', 'October')
print(output)
output = make_album('Lara Fabian', 'Ju\'tem', 13)
print(output)
output = make_album('Space Girls', 'Viva')
print(output)
But the output is kind of
None
{'singer_name': 'Lara Fabian', 'slbum': "Ju'tem", 'track': 13}
None
How to denote args to avoid none output
you have a return in your function only if your track argument is not an empty string otherwise your function returns None to fix you can use:
def make_album(singer, album, track = ''):
album = {'singer_name' : singer, 'slbum' : album}
if track:
album['track'] = track
return album
This question already has answers here:
How can I call a function within a class?
(2 answers)
Calling one method from another within same class in Python
(1 answer)
Closed 3 years ago.
I am having some trouble calling one function from inside another
Here is the code I have:
supported_timeframes = ['1m', '5m', '1h', '1d']
supported_indicators = ['SMA', ... ]
supported_sources = ['open', 'close']
indicator_values = {}
class Indicator:
def __init__(self):
self.indictor = '' # indicator
self.timeframe = '' # timeframe
self.period = 0 # look-back period
self.source = '' # open / close
def error(self, indicator, timeframe, period, source):
if timeframe not in supported_timeframes:
return 'timeframe not supported --', 'supported
timeframes:', supported_indicators
if indicator not in supported_indicators:
return 'indicator not found --', 'supported indicators:',
supported_indicators
if source not in supported_sources:
return 'source is not -- open -- or -- close'
else:
pass
def SMA(self, indicator, timeframe, period, source):
error()
# TODO get candle data from timeframe
# TODO calc requested indicator from candle data and append to
# indicator_values dict
# return indicator
for indicator in indicator_values:
return indicator
I have the function error first to check if wrong values have been entered into the parameters.
Then I want to call that function in def SMA(...) function because I am going to have many more functions that each calculate an indicator similar to the SMA one, so to keep things concise I am trying to call error() in each of them instead of copy and pasting the code within every time.
However when doing this, I get an error message within def SMA(...) that says error() is undefined.
Thank you so much in advance if you can help me out!
Unless I'm missing something, you just need to add self where you are calling error()
def SMA(self, indicator, timeframe, period, source):
self.error()
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I am working my way through some Python tutorials one of the things that keeps coming up is user input and i just wanted to check that i am validating it correctly and not going about it the long way around.
I have written the code below and only need to ask for the day month and year but if i needed to start asking for address phone number name etc etc this would grow and grow is that normal?
def get_input( i ):
while True:
# We are checking the day
if i == 'd':
try:
day = int( raw_input( "Please Enter the day: " ) )
# If the day is not in range reprint
if day > 0 and day < 32:
#Need to account for short months at some point
return day
else:
print 'it has to be between 1 and 31'
except ( ValueError ):
print "It has to be a number!"
elif i == 'm':
# We are checking the month
month = raw_input( 'Please enter ' +
'in words the month: '
).strip().lower()
if month in months: # use the dict we created
return month
else:
print 'Please check you spelling!'
elif i == 'y':
# Now the year
try:
year = int( raw_input( "Please Enter the year" +
"pad with 0's if needed: " ) )
#make we have enough digits and a positive
if year > 0 and len( year ) == 4:
return year
except ( ValueError, TypeError ):
print "It has to be a four digit number!"
Why don't you just have the user input the whole date in one go, and try it out to validate it?
from time import strptime
def get_date():
while True:
date = raw_input("Please enter a date in DD/MM/YYYY format: ")
try:
parsed = strptime(date, "%d/%m/%Y")
except ValueError as e:
print "Could not parse date: {0}".format(e)
else:
return parsed[:3]
year, month, day = get_date()
This will catch errors like 29/2/2011 but accept valid inputs like 29/2/2012.
If you'd like to accept several formats, just make a list of the format strings you want to accept and try them out one after another on the input, until you find one that works. But watch out for the problem of usage overloading.
For validating phone numbers I'd just go for a regexp. If you've never used regexps before there's a nice python regexp howto here. Addresses are very free form, so I don't think I'd bother validating them beyond restricting the length and doing basic security checking, especially if you're accepting international addresses.
But in general, if there's a python module for it you should just try to create an instance based on the input and catch the errors, like I do for the time module in the above example.
Don't even try to validate names. Why not? Look at this article. :)
Perhaps a framework like colander might be helpful here:
http://docs.pylonsproject.org/projects/colander/en/latest/?awesome