hidden
hidden

Reputation: 48

How can I reduce the number of "if" statements in my code?

I am trying to make a minecraft resource calculator in Python, but as it will have a decent number of items I feel like using a bunch of if statements to determine user input isn't the best way I could do it.

def hoppercalc():
    print(noofitems * 5, "iron")

def pistoncalc():
    print(noofitems * 3, "planks,",
    noofitems * 4, "cobblestone,",
    noofitems, "redstone and iron")

noofitems = int(input("How many items do you want to make? "))
itemname = input("What item do you want to make? ")

if itemname == "hopper":
  hoppercalc()
if itemname == "piston":
  pistoncalc()

Upvotes: 1

Views: 393

Answers (6)

eroot163pi
eroot163pi

Reputation: 1825

I suggest below methods, where you don't have to make your own dictionary or list, and use your programs scope to get all things you defined

You can look into sequence of elements from locals and get itemname, if it exists then it will execute

locals().get(itemname + 'calc') and locals().get(itemname + 'calc')()

In this case outermost main function, so you can also use globals

globals().get(itemname + 'calc') and globals().get(itemname + 'calc')()

I use .get on dictionary because if function does not exist it will return None. None evaluates to False so it will not execute next boolean statement

locals will get all instances existing in the present scope, while global gets all globals. Other than these you also have

You can evaluate expression if you trust the input. Eval comes with its own draw back and if user is not trusted it can even delete files for example

eval(itemname + 'calc()')

Upvotes: 0

parvat raj
parvat raj

Reputation: 66

This will help. but this is not the best way to do. you should use dictionary datatype.

    def f1():
    print("func one")

    def f2():
    print("func two")

    def f3():
    print("func three")

    def f4():
    print("func four")

    func_list = [f1, f2, f3, f4]
    word_list = ["one", "two", "three", "four"] 

    val = input("Enter :")
    for x in range(len(word_list)):
        if word_list[x] == val:
             func_list[x]()# call the function in list corresponds to list
        else:
             print("wrong entry")

Upvotes: 0

tzaman
tzaman

Reputation: 47860

I'd think about this a little differently. Instead of making a function for each item recipe, just make a table that represents the ingredient quantities, then you can do lookups in it with a single calculation function:

recipes = {
    "hopper": {"iron": 5},
    "piston": {"planks": 3, "cobblestone": 4, "redstone": 1, "iron": 1},
}

def show_recipe(item, quantity=1):
    ingredients = recipes[item]
    for name, amount in ingredients.items():
        print(amount * quantity, name)

show_recipe("piston", 2)

This prints:

6 planks
8 cobblestone
2 redstone
2 iron

Now adding a new recipe just involves adding a line in the table, instead of writing a whole new function. If you want to get more sophisticated you can move to having Enum classes to represent your items and ingredients, and then put the recipe method on the item class, and so on.

Also note that I made the item quantity a parameter to the function; this is in general a good idea instead of using a global.

Upvotes: 2

Kevin
Kevin

Reputation: 33

A dirty but quick fix is to take one function calc that gets an attribute itemname. Inside that function, if itemname is hopper, do thee code of hoppercalc, else do the code of pistoncalc.

I'd still recommend a dictionary though. https://docs.python.org/3/tutorial/datastructures.html#dictionaries

Some examples here: https://www.programiz.com/python-programming/dictionary

Upvotes: 0

Agathon813
Agathon813

Reputation: 29

How about getting rid of two functions and using one?

def calc():
    if itemname == "hopper":
        print(noofitems * 5, "iron")  
    elif itemname == "piston":
        print(noofitems * 3, "planks,", noofitems * 4, "cobblestone,",
            noofitems, "redstone and iron")
    return

Upvotes: 0

Open AI - Opting Out
Open AI - Opting Out

Reputation: 24164

You could map the item name to the calculation function:

calculations = {'hopper': hoppercalc,
                'piston': pistoncalc}

calculations[itemname]()

Upvotes: 0

Related Questions