John Stewart

Hi! I'm John. I'm a developer, coder, geek, tech head, maker of websites at MLB. JavaScript always. Creater of Pomy.io 🍅

Python Scheduler

Time to automate

This is more of a refelection post on a little thing I worked on recently. A friend of a friend during a game of Fortnite said I should check out Python and Selenium and try and automate something in my life. So that's exactly what I did.

I had wanted to try Python for awhile and the idea of automating some part of my life was interesting. How hard could it be?

First, what to automate? Well I go to the gym a good amount and my gym is special in that I have to book the class ahead of time. Often times I forget to schedule myself for a given class and end up not going. This is unfortunate, mainly because I pay a lot of money to go to this gym.

So I created a python script that runs and books all my classes for me. Life was good until I let this script just keep running but before I get into that I have some technical thoughts I want to share.

Python Likes

Dynamically Typed, but Strongly

# flask app
app = Flask(__name__)

# workout manager init
wm = WorkoutManager()
wm.schedule_job()

# thread setup
schedule_thread = Thread(target=wm.run_schedule)
schedule_thread.daemon = True
schedule_thread.start()

Initially declaring a variable that way felt very weird. Felt like I was creating a bunch of JavaScript global variables and truly living life on the edge. The no semi-colon thing I didn't like at first but after awhile all of this felt simple and expressive. Dare I say, pseudocode like.

Object Oriented, Really

Python is recognized by most of the big companies as a proper object oriented programming language. Coming from JavaScript land we get many of the benefits of an object oriented language but we are not boxed into just that paradigm which I like. That said, unfortunately a lot of people don't give JavaScript its due diligence and don't take it seriously as a language. That's a mistake but I'll save that for another post.

Below is some contrived OO code showcasing some inheritance in Python.

class Person:
    def __init__(self, name):
      self.name = name

class SoftwareEngineer(Person):
  def __init__(self, name):
    Person.__init__(self, name)
    self.job = "Software Engineer"

john = SoftwareEngineer("John")

print(john)

I like writing the above, seems simple enough. self instead of this was fine other than the fact that I didn't like how much self gets passed around. I'm sure I don't know enough as to why that's the case but I just accepted it and moved on.

python-1

Yeah, no prototype there. I'm used to looking up the __proto__ and seeing what else is available but can't do that here.

Sync

Python is synchronous. I'm starting to realize this is normal in other languages but coming from JavaScript where everything is asynchronous, this really took some getting used to. To me it seems crazy to make a request and pause program execution until that request comes back. But check this out.

r = requests.get('https://api.github.com/user', auth=('user', 'pass'))
r.status_code # 200
r.headers['content-type'] # 'application/json; charset=utf8'
r.encoding # 'utf-8'
r.text # u'{"type":"User"...'
r.json() # {u'disk_usage': 368627, u'private_gists': 484, ...}

Yeah, that behaves exactly how you are reading it. Big fan!

Best Practices

I try to be a good developer and follow some set of best practices when writing my code. I like the feeling that I'm doing it "right". What is "right"? Idk. But you know what I mean.

python-2

So I googled "Python best practices" and the first link gave me enough information to get the feeling that I was writing some good Python code.

File I/O

Writing file operations in Python really felt like I was writing pseudocode. The best part was when I ran it, it actually did the things. Very nice!

Python Dislikes

I'll be brief here because overall I had a great time working with everything but here are a few annoyances or pain points.

  • pip, it's fine but kind of crazy it took a decade(?) to agree on a package manager
  • virtualenv, again it seems it's not clear if this is recommended or not
  • proper production deployment of the app
  • pip requirements.txt yielded different results each time, probably user error but still seems like this could be improved a bit

Oh Yeah

That separate issue from before? Yeah, turns out when you don't show up to these classes they charge you $10 and I decided to go on vacation and forgot the script was running. So be careful, automation can cost you. 😂

Now.sh Shoutout

Real quick, as mentioned above a pain point was deploying the application. This was more of an annoyance with what was the "right" way to configre the Docker container along with my zero understanding of Python WSGI. That said, now.sh can deploy Docker containers. While it seems that Now is mainly for Node apps, I went ahead and shipped some Python on there in a Docker container. 🎉🔥👌🏽

Summary

I'm sure I got some terminology wrong above but the take away from Python for me was I should be writing more of it. It's like writing pseudo code that actually does the things. More Python!

If you liked this article and want to say hi, then you can find me on Twitter.