Using min and max to limit values to a range in Python

Question:

I have this small python file that I wrote in Python 2.7.9 and now I am testing it in Python 3.4.3.

All works, for I am able to send commands to my RPI. But when I send the command to change the volume on the speaker (ranging 1-100), they are all read by the python script as 100%.

Example:

Volume 26, is seen as Volume 100. I add commented out the line with volume = … and it works now but I can not prevent people from spamming the volume to the max @ 100%.

Code:

def setVolume(volume):
    volume = max(60, min(30, volume)) #Volume Spam Protection
    sendPost(speakerAddress+"volume","<volume>"+str(volume)+"</volume>")
Asked By: TheAce

||

Answers:

I am guessing when you say volume 26 is seen as 100% , you mean it comes as 60 .

That is because of the line –

max(60, min(30, volume))

This roughly translates to , minimum between 30 and volume, and maximum between volume and 60 , so you would always get 60 , since if volume is greater than 30, you would get 30 from the inner min() , and from outer max() you would get 60. You can think what would happen for volume less than 30.

You actually want to do –

volume = min(60, max(30, volume))

I am not sure how this would have been working in Python 2.7 , according to the above condition the issue should have been there for Python 2.7 as well.

Answered By: Anand S Kumar

I guess, what you really want is that your volume is in the range 30..60. In this case you should swap you min/max line to this:

volume = min(60, max(30, volume))

So you get the maximum of the volume and 30 — (at least 30) — and the minimum of that result and 60 — maximum 60.

Answered By: Juergen

Much more readable would be to not use min and max at all; they are efficient for find the extrema of an arbitrary number of arguments, but overkill for only two.

if volume < 30:
    volume = 30
elif volume > 60:
    volume = 60

(This would have the side effect of fixing any logic errors resulting from the nested construction you were using.)

Answered By: chepner

I have written a well readable function limit for that purpose:

def limit(iMin, iVal, iMax):
   return min(iMax, max(iMin, iVal))

volume = limit(30, volume, 60)
Answered By: Michael Hutter
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.