Using a dict is first of all more efficient (look-up time of O(1) as opposed to the list.index's O(n)), and also reduces the need for try/except with the help of the get() method. The "problem" is that dicts' keys need to be hashable - which lists are not. So you will need to convert them to tuples (which are hashable):
buttons = {
(PIN_5,): 1,
(PIN_5, PIN_6): 2,
(PIN_6,): 3,
(PIN_6, PIN_19): 4
}
And now using the get method you check for a key, and if it is not found, it will return the second default argument:
button_pressed = buttons.get(tuple(pins_high), 0)
Note that this is "order-sensitive" - meaning that [PIN_6, PIN_5] will return 0 and not 2!
Using a dict is first of all more efficient (look-up time of O(1) as opposed to the list.index's O(n)), and also reduces the need for try/except with the help of the get() method. The "problem" is that dicts' keys need to be hashable - which lists are not. So you will need to convert them to tuples (which are hashable):
buttons = {
(PIN_5,): 1,
(PIN_5, PIN_6): 2,
(PIN_6,): 3,
(PIN_6, PIN_19): 4
}
And now using the get method you check for a key, and if it is not found, it will return the second default argument:
button_pressed = buttons.get(tuple(pins_high), 0)
Note that this is "order-sensitive" - meaning that [PIN_6, PIN_5] will return 0 and not 2!
no. First thigns first: whenever you have to retrieve a value given a key, just use a dictionary:
buttons = {
(): 0,
(PIN_5,): 1,
(PIN_5, PIN_6): 2,
...
}
See that (1) the values can be arbitrary, and no need to do hacks so that the rder of insertion of your combination needs to match the numeric value you need, and (2), search order is arbitrary, O[1], no linear search for each button press, and (3) dictionaries have the .get method that allow you to check for containment without needing to handle exceptions.
Moreover, and a bit more "advanced" - you can use "frozenset" objects for the keys, so you don't depend on button order:
F = frozenset
buttons = {
F(): 0,
F((PIN_5,)): 1,
F((PIN_5, PIN_6)): 2,
...
}
...
button_pressed = buttons.get(F(pins_high), 0)
Videos
try:
doSomething()
except Exception:
pass
or
try:
doSomething()
except:
pass
The difference is that the second one will also catch KeyboardInterrupt, SystemExit and stuff like that, which are derived directly from BaseException, not Exception.
See documentation for details:
trystatement- exceptions
However, it is generally bad practice to catch every error - see Why is "except: pass" a bad programming practice?
It's generally considered best-practice to only catch the errors you are interested in. In the case of shutil.rmtree it's probably OSError:
>>> shutil.rmtree("/fake/dir")
Traceback (most recent call last):
[...]
OSError: [Errno 2] No such file or directory: '/fake/dir'
If you want to silently ignore that error, you would do:
try:
shutil.rmtree(path)
except OSError:
pass
Why? Say you (somehow) accidently pass the function an integer instead of a string, like:
shutil.rmtree(2)
It will give the error "TypeError: coercing to Unicode: need string or buffer, int found" - you probably don't want to ignore that, which can be difficult to debug.
If you definitely want to ignore all errors, catch Exception rather than a bare except: statement. Again, why?
Not specifying an exception catches every exception, including the SystemExit exception which for example sys.exit() uses:
>>> try:
... sys.exit(1)
... except:
... pass
...
>>>
Compare this to the following, which correctly exits:
>>> try:
... sys.exit(1)
... except Exception:
... pass
...
shell:~$
If you want to write ever better behaving code, the OSError exception can represent various errors, but in the example above we only want to ignore Errno 2, so we could be even more specific:
import errno
try:
shutil.rmtree(path)
except OSError as e:
if e.errno != errno.ENOENT:
# ignore "No such file or directory", but re-raise other errors
raise