r/learnpython • u/zaphodikus • 1d ago
Confusing code min() max()
I'm debugging some code and I found this function
import math
def Clamp(n, smallest, largest):
return max(smallest, min(n, largest))
surely that code is just wrong? and needs to be max([smallest, min([n, largest])) by passing a list not unnamed args for default and key? I need a sanity check here.
4
u/Langdon_St_Ives 22h ago
I love how hours after the correct answer has already been given, people still respond with explanations what this clamp() function is meant to do, when it's clear OP knows full well what it does... 😂
1
u/zaphodikus 20h ago
I had not had much sleep at all, it was to help guear a line of code throwing a divide by zero. Now if only I had as many people looking at the other question I had about windows firewalls.... which is no longer urgent, that issue annoyingly stopped reproducing, so back to the drawing board, or, get more sleep.
Flipping between C#, C++ and Python is not good Karma I suspect. Sleep first Dave.
7
u/lfdfq 1d ago
Let's look at the documentation for min and max.
https://docs.python.org/3/builtins/functions.html#min https://docs.python.org/3/builtins/functions.html#max
min(iterable, /, *, key=None)¶ min(iterable, /, *, default, key=None) min(arg1, arg2, /, *args, key=None)
So it has multiple signatures, one that takes an iterable and a default, another takes multiple (at least 2) args. The / separates the positional-only (on left) from positional-or-keyword (on the right), the * means all parameters after that are keyword-only. So default must be passed by keyword.
The text in the doc makes this clearer:
If two or more positional arguments are provided, the largest of the positional arguments is returned.
3
u/zaphodikus 1d ago
Ah I did suspect it was relying on positional parameter magic and that default and key were named args , forgot all about what that
/does, panic for me is over. I still need to find why the Font in question is tripping me on divide by zero for a size, but that's on me.
2
u/ExpertSentence4171 20h ago
Capitalized function name. Eww
1
u/zaphodikus 20h ago
yeah, that's why it hurt my eyes, but it's not my code I ,,, well that's not true, he left, it's mine now.
14
u/TheBB 1d ago
In [1]: max? Docstring: max(iterable, *[, default=obj, key=func]) -> value max(arg1, arg2, *args, *[, key=func]) -> value With a single iterable argument, return its biggest item. The default keyword-only argument specifies an object to return if the provided iterable is empty. With two or more arguments, return the largest argument.
max(x, y) is perfectly fine. Same for min obviously.
key and default can only be given as keyword arguments.
5
u/tea-drinker 1d ago
The functions are implemented so they can accept either a list or multiple arguments.
https://github.com/python/cpython/blob/da20d7401de97b425897d3069f71f77b039eb16f/Python/bltinmodule.c#L1718 for the source code where it checks what you passed to it.
0
u/Wise-Emu-225 1d ago
Look at the docs and see if they need a list as an argument. Min an max can probably have an arbitrary nr of args. Sometimes both is possible. I guess the code is fine.
Edit: unless it doesn’t do what was meant. Which is difficult to judge with no context.
-1
u/JamzTyson 1d ago
Try plugging some values in, and figure out what happens.
Example:
largest = 10 smallest = 5
Now consider values of n from 1 to 12.
Try figuring out the results in your head, then run the code to check your answers.
-1
u/deanominecraft 1d ago
python allows functions to take an arbitrary amount of arguments as a list, using a * in the function signature (calling it args is just a convention), try experiment with this code:
def mean(*args):
total=0
for i in args:
total+=i
return total
print(mean(5,194, 28,8,69) #prints the meanyou can also do this with a dictionary by using ** (once again kwargs is just a convention, it can be called whatever you want) eg:
def hello(**kwargs):
try:
print(f"hi {kwargs["name"]}")
except:
print("hi, you didnt tell me your name")
print(myfunc(name="john")) # prints hi john
print(myfunc(john="name")) # prints hi, you didnt tell me your namemin and max have some extra logic to do with types so that you can also pass in a list, but for functions like mine that dont do that, you can unpack the arguments from a list or dictionary like this:
mean(*mylist) hello(**mydict)
-1
u/deadeye_82_1 23h ago
Yes, that's very confusing.
In this combination:
min is the largest value, or n
max is the smallest value, or the value of min
14
u/NewbornMuse 1d ago
You can sanity check this yourself!
If you open an interactive python session, does
max(3, 6, 10, -2)generate an error or does it return something? If so, what?What kind of error would you expect if you call something with wrong arguments? Are you seeing anything like that, or is it something completely different?
What does the python documentation say about max and min?