简体   繁体   中英

How to replace a lot of if/elif statements in python?

i am writing function in python for control outputs on QUIDO board throught post html requests. I have a lot of if and elif statements in my program. Is there some way how to make code more transparent? Quido board has 16 outputs so i have 16 if statements with some if/elif inside.

    def setOutput(output,action):
#Output 1
if output == 1:
    if action == 1:
        r = requests.get(' http://192.168.1.254/set.xml?type=s&id=1')
        print(r.url)
    elif action == 0:
        r = requests.get(' http://192.168.1.254/set.xml?type=r&id=1')
        print(r.url)
#Output 2        
if output == 2:
    if action == 1:
        r = requests.get(' http://192.168.1.254/set.xml?type=s&id=2')
        print(r.url)
    elif action == 0:
        r = requests.get(' http://192.168.1.254/set.xml?type=r&id=2')
        print(r.url)
if output == 3:
    if action == 1:
        r = requests.get(' http://192.168.1.254/set.xml?type=s&id=3')
        print(r.url)
    elif action == 0:
        r = requests.get(' http://192.168.1.254/set.xml?type=r&id=3')
        print(r.url)
if output == 4:
    if action == 1:
        r = requests.get(' http://192.168.1.254/set.xml?type=s&id=4')
        print(r.url)
    elif action == 0:
        r = requests.get(' http://192.168.1.254/set.xml?type=r&id=4')
        print(r.url)
while 1:
setOutput(1, 1)
myTimer(1)
setOutput(1, 0)
myTimer(1)

Something like this should work.

def setOutput(output, action):
    assert isinstance(output, int)
    param_type = 's' if action == 1 else 'r'

    r = requests.get(f'http://192.168.1.254/set.xml?type={param_type}&id={output}')
    print(r.url)

Most replies will involve some kind of string variables:

if action in [0, 1]:
    t = 's' if action else 'r'
    print(requests.get(f' http://192.168.1.254/set.xml?type={t}&id={output}').url)

Dictionaries may work if action values are well defined:

action_map = {
    0: 's'
    1: 'r'
}
print(
    requests.get(
        f' http://192.168.1.254/set.xml?type{action_map[action]}&id={output}'
    ).url
)

It looks like your goal is to send the appropriate arguments to the server based on the action and the output , where the action is mapped to type as follows

0 --> "r"
1 --> "s"

And the output is directly passed in as the id param.

In this scenario, you can get rid of the output check and just pass it in directly.

r = requests.get('http://192.168.1.254/set.xml?type=s&id={output}')

Now, you only need to figure out how to get the correct type , which you can do a simple if/else or build a dictionary to support new actions.

dictionary helps alot in these cases:

def setOutput(output,action):
    type_dict = {
        1: 's',
        0: 'r'
    }
    url = f'http://192.168.1.254/set.xml?type={type_dict[action]}&id={str(output)}'
    r = requests.get(url)
    print(r.url)

setOutput(1, 1)
setOutput(1, 0)
setOutput(2, 1)
setOutput(2, 0)

output:

http://192.168.1.254/set.xml?type=r&id=1
http://192.168.1.254/set.xml?type=s&id=1
http://192.168.1.254/set.xml?type=r&id=2
http://192.168.1.254/set.xml?type=s&id=2

upvote if you find this solution handy...

you can simplify it:

def setOutput(output,action):
    type = 's' if (action == 1) else 'r'
    print("http://192.168.1.254/set.xml??type={0}&id={1}".format(type,output))

Personal preference but a params dictionary is easier and obviates the need for string formatting which can get clumsy if it needs to be modified/extended. Also, ALWAYS check the HTTP status

import requests

action_map = {1: 's', 2: 'r'}
url = 'http://192.168.1.254/set.xml'

def setOutput(output, action):
    params = {'type': action_map.get(action), 'id': output}
    (r := requests.get(url, params=params)).raise_for_status()
    print(r.url)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM