5
\$\begingroup\$

I've just been putting together an audio meter by stacking bootstrap progress bars, and thought there was probably a better way, mathematically / logically, of achieving this.

levels = (vumeter) ->
  green = if vumeter % 50 < vumeter then 50 else vumeter
  yellow = if vumeter % 85 < vumeter then 35 else vumeter - 50
  red = if vumeter % 100 < vumeter then 15 else vumeter - 85

  'green': green
  'yellow': yellow
  'red': red
\$\endgroup\$
2
  • \$\begingroup\$ Welcome to CodeReview.SE! You should tell us what you are trying to achieve \$\endgroup\$
    – SylvainD
    Commented Aug 13, 2014 at 16:37
  • \$\begingroup\$ Well the above code works and is done logically (when vumeter is greater than 50, then green is 50 and yellow is the remainder) etc but I suspect this can be done more efficiently.. \$\endgroup\$
    – gratz
    Commented Aug 13, 2014 at 16:41

2 Answers 2

3
\$\begingroup\$

Assuming that you want to replicate a classical audio meter (aka green bar grows until 50, then a yellow bar appears on top of green and grows until 85, then a red bar grows from there), then the easiest way to do this is with min and max functions.

Assuming that vumeter should not be mutated here is the pseudo-code I came up with:

green = min(vumeter, 50)
yellow = max(min(vumeter - green, 35), 0)
red = max(min(vumeter - green - yellow, 15), 0)
\$\endgroup\$
4
\$\begingroup\$

vumeter % 50 < vumeter doesn't make much sense to me. For non-negative numbers, this is equivalent to vumeter > 50, so you can just use that instead. For negative numbers, this will always return false, although it seems like this would be an illegal argument to your function.

@mleyfman provided a great solution. In practice, the code provided achieves something called clamping, where you restrict a value to a specified range. You can roll your own clamp function like so:

clamp = (value, min, max) -> Math.min(Math.max(min, value), max)

levels = (vumeter) ->
  'green'  : clamp(vumeter,  0,  50)
  'yellow' : clamp(vumeter, 50,  85) - 50
  'red'    : clamp(vumeter, 85, 100) - 85
  // or, if you find it more meaningful to provide maxima as parameters rather than ranges:
  'green': clamp(vumeter, 0, 50)
  'yellow': clamp(vumeter - 50, 0, 35)
  'red': clamp(vumeter - 85, 0, 15)
\$\endgroup\$
1
  • \$\begingroup\$ Accepted @mleyfman's answer as I think theirs was first (and have lower rep) but appreciate your response as well and have upvoted it. Both very useful, thanks! \$\endgroup\$
    – gratz
    Commented Aug 14, 2014 at 11:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.