What I’ve been up to in Programming: Python


Selenium for Automated Pool Signup

Spent the last week debugging that script. Turns out the key to getting it to run in cron is to add export DISPLAY=:0 && before your command. That’s because Chrome will not launch without a display to send Chrome to.

Python Morsels

The most recent Python Morsels exercise was to figure out if a number was a perfect square. Trey began his problem statement this way: “This week I want you to write a function that might seem simple at first, but there’s a number of ways to solve it.” It definitely took some out of the box thinking for me to figure out how I was going to solve the base case. The math.sqrt() function returns a float so that it can give answers for non-perfect squares. So I kept thinking and I realized that any perfect, non-complex square root must be an integer. So I came up with the conditional to return. (And after all this Pythonic learning, I’ve learned not to evaluate for truth and then return a variable. Just return the evaluation)

import math


def is_perfect_square(number):
    return math.sqrt(number) == int(math.sqrt(number))


if __name__ == "__main__":
    print(is_perfect_square(9))

For the first bonus, Trey just wanted us to return False if the number was negative. The solution was trivial. Anyone who’s done any amount of functional programming could figure it out.

import math


def is_perfect_square(number):
    if number < 0:
        return False
    else:
        return math.sqrt(number) == int(math.sqrt(number))


if __name__ == "__main__":
    print(is_perfect_square(9))
    print(is_perfect_square(-9))

The second bonus was to handle extremely large numbers. Trey mentioned in his intro that the second two bonuses would be hard. I think I can probably reason my way to a solution for bonus 3 (complex numbers). I’m quite a bit rusty on complex numbers, but I think I can get my mind to remember. (Despite having an electrical engineering degree, I’ve rarely had to use it. Ended up becoming a programmer and then a boss in a programming shop) For this one, however, I had no idea why Python couldn’t deal with large numbers. After all isn’t Python the current darling of the scientific community now? So I clicked on the first link related to this hint. The Decimal answer didn’t work. I wasn’t ready to do gmpy2 yet. So I clicked on the second link. Looked like Decimal was probably most likely the way he wanted me to go. That, of course, created some issues with 0.0 not being equal to 0, so I had to change things. I spent about 15-20 minutes trying to figure out if there was a Decimal way to get the integer part separated from the part after the decimal. Tragically, no. I did discover math.modf which will do that for you. However, it was not operating under the same context as the Decimal, so it was rounding too small that to work. (What I was trying to do there is that any perfect square should have nothing to the right of the decimal point.) Eventually, I had the thought that almost the same as the base and bonus 1, just “phrased” slightly differently. If I was previously seeing if they were both the same number, then I could move it over to this side of the equation and ask if sqrt(a)-int(sqrt(a))=0. I finally had a working solution once I raised the context high enough to get enough decimal places for that to work.

import decimal
import math


def is_perfect_square(number):
    if number < 0:
        return False
    else:
        with decimal.localcontext() as c:
            c.prec = 100
            return decimal.Decimal(number).sqrt()-int(decimal.Decimal(number).sqrt()) == 0


if __name__ == "__main__":
    print(is_perfect_square(9))
    print(is_perfect_square(-9))

Bonus 3 (handling complex numbers) was incredibly easy, especially after bonus 2. All I had to do was a quick read of the cmath library and see that a number N that is complex has N.real and N.imag to access the numbers in each part of the complex number. Then I just do what I did above to see if they are integers by making sure nothing’s right of the decimal place. Piece of cake! Also, I already knew about kwargs from other Trey problems plus reading up on it and it FINALLY made sense after all these years of not making sense to me.

import decimal
import cmath


def is_perfect_square(number, **kwargs):
    if kwargs.get("complex"):
        return (cmath.sqrt(number).real - int(cmath.sqrt(number).real) == 0) and (cmath.sqrt(number).imag - int(cmath.sqrt(number).imag) == 0)
    else:
        if number < 0:
            return False
        else:
            with decimal.localcontext() as c:
                c.prec = 100
                return decimal.Decimal(number).sqrt()-int(decimal.Decimal(number).sqrt()) == 0


if __name__ == "__main__":
    print(is_perfect_square(9))
    print(is_perfect_square(-9))