Text font size adapting to space In order to practice my programming skills, I am trying to implement a Button class, to use in pygame. I know there are libraries like PGU, I do this to improve in programming.

I spent a bit of time creating a function to find a good font size for the text inside the button, depending on the length of the text and the dimensions of the button.

I came to this result, it's close enough to what I want. However, I am looking for advice to improve this function that looks wobbly:

def balanced_text_size_button(length, width, height):
    # sqrt(length) / length -&gt; The higher the length is, the smaller this value become,
    # it decrease slower and slower as length increase (never reach 0).
    # pow(....., 1.6) -&gt; The resulting value is multiplied,
    # the impact is more important on high value
    # (I don't think it makes much sense I found this empirically).
    length_factor = math.pow((math.sqrt(length) / length), 1.6)

    # If there is a lot of horizontal space for the text, the font will be big,
    # but if there is a lot of char to write it will be smaller.
    font_size = width * length_factor

    # This way the font is not too high
    if font_size &gt; height:
        font_size = height * 0.9

    return int(font_size)


A preview of what it looks like:
Firstly I'd simplify your maths:

$$
\text{font_size} = \text{width} * (\frac{\sqrt{\text{length}}}{\text{length}}) ^ {1.6}\\
(\frac{\sqrt{x}}{x})^{1.6} = \frac{1}{x^{0.8}}\\
\text{font_size} = \frac{\text{width}}{\text{length}^{0.8}}
$$

After this we're left with your if, personally I think using min would be better here, min(font_size, height * 0.9).
That way we know the maximum is \$\text{height} * 0.9\$ rather than \$\text{height}\$, and makes the font_size not jump.
This is up to you, but a jump in the font size is ugly in my opinion.

If we look at the affect of not using min and using min:

&gt;&gt;&gt; balanced_text_size_button(1, 89, 100)
89
&gt;&gt;&gt; balanced_text_size_button(1, 91, 100)
91
&gt;&gt;&gt; balanced_text_size_button(1, 100, 100)
100
&gt;&gt;&gt; balanced_text_size_button(1, 101, 100)
90
&gt;&gt;&gt; balanced_text_size_button_min(1, 89, 100)
89
&gt;&gt;&gt; balanced_text_size_button_min(1, 91, 100)
90
&gt;&gt;&gt; balanced_text_size_button_min(1, 100, 100)
90
&gt;&gt;&gt; balanced_text_size_button_min(1, 101, 100)
90


The above makes much more sense.
And so I'd change your function to:

def balanced_text_size_button(length, width, height):
    return int(min(width / math.pow(length, 0.8), height * 0.9))


And if you want to keep your description I'd use comments.
I wouldn't use a doc-string as the implementation details aren't needed by the end user.
I'd either use a heavy comment like you did:

def balanced_text_size_button(length, width, height):
    # Decide the font size by getting a desired with and height font size.
    # For text to not go out of the box, the smallest of the two wanted sizes is taken.
    # The width size is found by dividing the width by an exponential of the text.
    # An exponent is used to have a reduced affect on larger values.
    # The exponent 0.8 seems to give the best results.
    # The height is decided by picking a font size of 90% of it.
    return int(min(width / math.pow(length, 0.8), height * 0.9))


Or as the code is easy to understand, you can just say why you're using a magic variable.

def balanced_text_size_button(length, width, height):
    # The exponent 0.8 seems to give the best results.
    return int(min(width / math.pow(length, 0.8), height * 0.9))