Reputation: 65
So I have 3 different variables.
model which is a string and defines the iPhone model.
storage which is a integer that defines the phones storage.
And finally price, which is an integer that defines the price of the phone.
Example:
model = iPhone 7
storage = 64 (GB)
price = 700 ($)
Another example:
model = iPhone 5s
storage = 16
price = 150
Now I want my program to notify me if I can make a good deal by buying and reselling, and my question is how do I do that in the most efficent way?
I know that I can use if statements, but is there any method to save me from writing alot diffrent if or elif statements?
Example:
if model == "iPhone 7" and storage == 64 and price <= 700:
print("do_something")
That's alot of code for just 1 model and storage option. If I would be using this method i'd have to write 29 more.
Upvotes: 5
Views: 8696
Reputation: 2857
In this situation, I prefer dictionaries.
Create different handlers(function) that do specific task based on item and data passed. See following code :
# Different handlers, each takes keyword args and can work specific task
def fun1(**kwargs):
print (kwargs)
print("fun1")
def fun2(**kwargs):
print("fun2")
def fun3(**kwargs):
print("fun3")
def fun4(**kwargs):
print("fun4")
# Example data. key is phoneModel_storage
a = {
'iPhone1_64': {
"storage": 64,
"action": fun1,
"price":1235
},
'iPhone1_32': {
"storage": 64,
"action": fun3,
"price":1235
},
'iPhone2_16': {
"storage": 16,
"action": fun1,
"price":1235
},
'iPhone3_32': {
"storage": 32,
"action": fun3,
"price":1235
},
'iPhone4_128': {
"storage": 128,
"action": fun4,
"price":1235
},
}
model = "iPhone1"
storage = 64
data = a.get(model + "_" + str(storage), None)
if data:
data['action'](**data)
Upvotes: 0
Reputation:
There are soooo many answers here, but still none accepted, so I will put together another one:
# Prepare a list of what you know will be good deals:
dctGoodDeals = {}
dctGoodDeals[('iPhone 7', 64)] = 700
dctGoodDeals[('iPhone 5s', 16)] = 150
# You have got at that point in your code from somewhere:
model = 'iPhone 7'; storage=64; price=500
# model = 'iPhone S'; storage=64; price=500
# so you can put at that point into your code following:
try: if (price <= dctGoodDeals[(model, storage)]): print("do something") except: print("not yet in dctGoodDeals:", model, "with", storage, "GB")
This way you get all the printouts of what to do and save some typing effort of writing all the if
s.
Upvotes: 0
Reputation: 3775
if model, storage, price == "iPhone 7", 64, 700:
print("do_something")
Usually I do some mini domain specific language and define prices in a string, or csc file
table =
"""Iphone 7, 64, 700
Iphone 6, 34, 500"""
lines = table.split('\n) # for wider tables use standard csv package, but or for 3 columns
dico = dict( (r[0], r[1]), r[2]) for r in line.split(', ') for line in lines))
def good_deal(model, memory, price):
return dico.get( (model, memory), 10000000 ) > price
Upvotes: 0
Reputation: 2812
Defining methods to print something
def method1():
print "Yippee I have best iPhone 7 :)"
def method2():
print "Oh! still it is an iPhone 7"
def method3():
print "Yeah! I have best iPhone 5 :)"
def method4():
print "Oh! base iPhone 5"
Dictionary for if-else
stuff = {'iPhone 7' : {'64GB' : { '$700' : method1}, '32GB' : { '$500' : method2}}, 'iPhone 5' : {'32GB' : { '$250' : method3}, '16GB' : { '$150' : method4}}}
Access the statements like and add exception handling as needed
stuff['iPhone 7']['64GB']['$700']()
Reference How to avoid a lot of if else conditions
Upvotes: 0
Reputation: 54243
Your use case is perfect for a hashmap (dict) with something like tuples or preferably namedtuples.
from collections import namedtuple
Phone = namedtuple("Phone", "model storage price")
funcmap = {Phone("iPhone 7", 64, 700): \
lambda p: print("Do something to ", p),
Phone(...): # etc
...,
... }
phone = Phone("iPhone 7", 64, 700)
f = funcmap[phone] # maybe funcmap.get(phone, lambda _: None) in case it's new?
f(phone)
That said a decision-making algorithm seems better.
def is_good_deal(phone: Phone) -> (bool, None):
value_dict = {Phone("iPhone 7", 64, 700): 600,
...}
try:
return phone.value < value_dict[phone]
except KeyError:
# phone isn't in value_dict
return None
Upvotes: 0
Reputation: 4285
If you only care about checking if particular model matches exactly data that you have, then comparing dictionaries is a way to go:
>>> reference = {"model": "iPhone 5s", "storage": 16, "price": 550}
>>> tested = {"model": "iPhone 5s", "storage": 16, "price": 550}
>>> reference == tested
True
However, this will fail if you want broader criteria, like price falling within certain range.
Then, instead of writing 29 if
s, you can store reference dictionaries in list and check if your tested model is in that list with simplest
tested in reference_list:
# do something
Upvotes: 0
Reputation: 6685
You could make use of classes to minimize the code duplication:
class Phone():
BEST_MODELS = ["IPHONE7", "IPHONE 5S", "Galaxy S3"]
MIN_STORAGE = 100
MAX_STORAGE = 200
MIN_PRICE = 1000
MAX_PRICE = 3000
def __init__(self, model, storage, price):
self.model = model
self.storage = storage
self.price = price
def is_good_deal(self):
return (self.model in Phone.BEST_MODELS
and Phone.MIN_STORAGE <= self.storage <= Phone.MAX_STORAGE
and Phone.MIN_PRICE <= self.price <= Phone.MAX_PRICE)
p1 = Phone("IPHONE7", 150, 1700)
p2 = Phone("LG G1", 150, 700)
print(p1.is_good_deal()) # True
print(p2.is_good_deal()) # False
And if, for example, you have a collection of Phones, you can do the following:
lots_of_phones = [p1, p2]
good_deal_phones = (phone for phone in lots_of_phones if phone.is_good_deal())
Upvotes: 0
Reputation: 531
It's normal that you have to create a "decision rule" and somehow make it accessable by your program.
1-2 tips:
You might only specify the conditions when you have to act, and you do not specify the ones where you don't do anything.
You can use dicts instead "and"s like this which leads to less code:
deal2action = {
('iphone 7', '64', '700'):'ACT'
}
Usage:
my_deal = ('iphone 7', '64', '700')
my_action = deal2action[my_deal]
Upvotes: 1