Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Functions
#6
(Sep-11-2019, 07:06 AM)harold Wrote: Perfringo, thanks for the assist! Your code is slightly way too high for me to understand. However, appreciate it anyway.

Maybe if I walk you through this code it will become 'low hanging fruit' Wink

Our task in english: I would like to convert temperature. If temperature is in Fahrenheit then I want Celsius and if temperature in Celsius I want Fahrenheit.

Observation about our task: we have two options (no Kelvin), so we need to know only base (in which scale the initial temperature) and convert it to another scale. If we have had 'Kelvin' as well then we would have needed to know both base and target scales.

So there should be two parameters for function: (1) temperature, (2) base scale (either Celsius or Fahrenheit):

def convert_temperature(temperature, base='Celsius'):
There is keyword argument used. It assumes, that one needs more conversion from Celsius to Fahrenheit than other way around. If it's the case then one should use base='Fahrenheit'.

In order to convert temperature i.e. apply correct formula we must be certain that base is 'known'. As stated, we convert only 'Celsius' and 'Fahrenheit'. So we use some defensive code to ensure that if we start to convert temperature we have allowed base. For that we define allowed bases list, we check whether entered base in allowed list (with .title() method we correct some possible typos of capitalisations) and if not we raise ValueError and notifying user what bases are allowed:

bases = ['Celsius', 'Fahrenheit']
if base.title() not in bases:
    raise ValueError(f'Conversion base must one of values: {", ".join(bases)}')
Now we have ensured that base is either 'Celsius' or 'Fahrenheit'.

To convert temperature we use dictionary of functions instead of if statement. .

How it works: we have dictionary which keys are bases and values are anonymous functions (lambdas). We have ensured that we pass only keys which are in dictionary (either 'Celsius' or 'Fahrenheit') therefore we can do dictionary lookup and provide function with argument - temperature.

NB! in original code there is one important bug. Base is checked against .title method but not converted. So 'celsius' will pass our defensive code but when we look for this key we will get KeyError because we don't have it in our conversion dictionary . So we either convert the base to title or we make dictionary lookup into title.

conversions = {'Celsius': lambda t: (t - 32) / 1.8,
               'Fahrenheit': lambda t: (t * 1.8) + 32}
return conversions[base.title()](temperature)
To use this function then if base is 'Celsius' then keyword argument is optional:

>>> convert_temperature(20)
-6.666666666666666
>>> convert_temperature(20, base='Celsius')
-6.666666666666666
>>> convert_temperature(300, base='Fahrenheit')
572.0
If we want to enforce usage of keyword argument then we can do it with *,
I'm not 'in'-sane. Indeed, I am so far 'out' of sane that you appear a tiny blip on the distant coast of sanity. Bucky Katt, Get Fuzzy

Da Bishop: There's a dead bishop on the landing. I don't know who keeps bringing them in here. ....but society is to blame.
Reply


Messages In This Thread
Functions - by harold - Sep-11-2019, 03:55 AM
RE: Functions - by perfringo - Sep-11-2019, 06:16 AM
RE: Functions - by buran - Sep-11-2019, 06:40 AM
RE: Functions - by perfringo - Sep-11-2019, 06:57 AM
RE: Functions - by harold - Sep-11-2019, 07:06 AM
RE: Functions - by perfringo - Sep-11-2019, 07:43 AM

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020