Tag: python

  • Advent of Code

    Advent of Code is a yearly programming contest created by Eric Wastl and it is currently being held at adventofcode.com. That means that this site spawns two daily programming challenges — until Christmas — to see who can solve them the fastest. But it is not just about being fast, Advent of Code is also a great way to improve your programming skills with daily puzzles or learn a new language. Because everyone gets the same daily puzzles it is also a great way to share and discuss results, and above all, learn.

    Though I knew of Advent of Code, I hadn’t participated before, but it seems two days, and four puzzles later, I am sort of in. Or at least, after only two days I am already fascinated by what I have seen, so I thought I’d share!

    Fascinating findings

    • Python seems to be the most popular language, by far. At least judging by Github repo names, which is of course not an exact measure, but it is more or less an indicator, as a lot of people tend to share their solutions there. Python is the most popular language, and it isn’t even close:
    • Browsing through the code, it — once again — becomes apparent that even with the exact same tools (e.g. Python) we all bring different experiences and education to the table which results in a colorful variation of solutions for the exact same puzzles. I’ve seen 100+ lines of Python code generate the exact same result as 10 lines. Advent of Code emphasizes that we are all unique individuals, and there is not a specific right way, just as long as you get there.
    • If I had to guess, I would have picked JavaScript to be the most popular language. But as you can see it only comes in second. Ruby, Go and C# are also unsurprising entries on this list, but Haskell and Elixir are — to me at least. These two functional languages seem to have quite a bit of buzz around them and people passionately seem to pick these languages as their language of choice, which is interesting as I know very little about either. Fun side note: even the creator of Elixir participates in AoC! 
    • Very few people seem to pick PHP. Which I also find surprising, because gigantic parts of the web run PHP. But PHP seems to have little appeal when it comes to coding challenges?
    • Some people are fast, I mean really fast! Just look at the times on the leader board. Judging from these times, this means some people are able to read around 1000 words explaining a puzzle, and then coding up not one, but two solutions and submitting the correct answer in under four minutes!  I kid you not. This next person live-streamed it, and clocks in around 5 minutes (even without using the command-line shortcuts like CTRL-R), and — here’s the kicker — it didn’t even put him in the top 20 for that day!
    • Of course you can use any language you like or even pen and paper, it is a puzzle after all. And people use some really crazy stuff, I love it! Anything goes, even Excel, and I think that is one of the goals of AoC: try to learn new things! There is one person who deliberately tried a new language for each challenge.

    Notable entries

    So it’s not all about speed, it’s also about trying new things. Here are some other unexpected examples.

    • Minecraft: This one takes the cake for me. See if you can wrap your head around what is happening here:

    Personal learnings so far

    So apart from these fascinating findings, I also got involved myself. I think because I solved the very first challenge with a simple AWK one-liner. But solving the followup challenge seemed trickier in AWK, though people seem to have done so (of course).

    Being completely new to Python, and seeing how popular it is, I decided to give it a go, and I must say I think I understand a bit better now why and how Python is so popular. Yes, it is well known that it forces deliberately clean code but it also provides ways for incredibly succinct code. And so far I have learned about map(), collections.counter, zip(), and cycle() Very handy, built-in functions and datatypes that I was unaware of, but which are incredibly powerful.

    Some people tend to disagree (probably very few), as I found this comment on StackOverflow when researching the Counter dict.

    I don’t think that’s fair, because in a sense every higher level programming language is an abstraction of differently expressed machine code. So unless you’re typing in machine code directly you are also using general purpose tools, and how narrow or general something is, who’s to say? And as long as it helps people do things faster — programming languages are tools after all — I’m all for it. Just let the computer worry about the zeros and ones.

    I was very surprised and pleased with the mentioned Python functions. For example, I brute-forced a solution in Bash which took probably more than 10 minutes to run, but ran in 0.07 seconds in only a couple of lines of Python. So, of course, the knowledge of the right functions and data structures once again proved to be the difference between 100 lines or 10, which reminded me of this quote of Linus Torvalds:

    So that’s it and if you want to learn something new, go give it a try!

  • Django in 10 minutes

    Django in 10 minutes

    This post is for myself, two weeks ago. I needed something like this. Or, maybe it’s for you? You know a little bit of Python, kind of understand the MVC concept and have a clear understanding of RDBMS? Congratulations, you will have no trouble getting something up and running in Django in a couple of minutes.

    Whether you need to move a database to an editable, shareable environment for less tech savvy people (phpMyAdmin), or move some spreadsheets to a database and want a quick CRUD setup? Django, a Python based web framework, can help. Follow these steps (yes, Django docs are great, but elaborate).

    Step 0 Database design

    The most important step. Forget about the rest if you don’t have this in order. Design a good database. Think about your keys and relations. You can use MySQL Workbench or edit Python code  (more on that later) to create a database. If you get this step right: Django takes care of the rest!

    Here is a small database setup I used. Made with MySQL workbench.

    MySQL workbench design

    So I created this, exported it and and imported it into a MySQL database. But you can have a different approach. As long as you think about your database design.

    Step 1 Setup your environment

    Normally this would be the first step. But since database design is vital I made that the first step. So, I assume you have a Python environment, therefore you are gonna use virtualenv. You don’t need-need it, but it creates an environment where you can’t break too much. Python uses pip to install packages. Django itself is a such a Python package, but most of the time you don’t want random development packages cluttering your main system. You want to keep all of that in your virtual environment. Virtual is a big word: it is just a dedicated directory.

    mkdir venv (or any name)
    virtualenv venv -p /usr/bin/python3.4 (or whatever your Python location is)
    source venv/bin/activate (activate the virtual environment)
    

    Bam! You are now *in* your virtual environment: noted by the prompt (venv). If you now invoke pip it installs packages only in that virtual environment. Want to leave the virtual environment? Type: deactivate.

    Step 2 Create your Django project and app

    Next, you need Django. You can install it system-wide or only within your virtual environment. Either way, just use pip:

    pip3 install Django
    pip3 install mysqlclient

    Now you have Django (and you have installed the mysqlclient with it). Depending on your system you may also need to install libmysqlclient-dev (apt-get install libmysqlclient-dev on Debian) for the mysqlclient to install correctly.

    Next: create a Django project. A Django project is a collection (a folder!) of apps. And apps are also folders. They all sit in the same root folder, together with the manage.py file. This next command creates a folder and within that folder another folder with the same name and it creates the manage.py file. This is your project.

    django-admin startproject my_fancy_project

    Next: create an app. Projects don’t do much by themselves: apart from some settings. So in the project directory where the manage.py file is, you type:

    python3 manage.py startapp my_awesome_app

    A folder will be created next to your project folder. This is your app folder and where most of the work will be done. You can create as many apps as you like. Some projects are one app, some are multiple. Apps share the project settings.

    Step 3 Create your models

    Django comes with batteries included. Meaning, by default it has a db.sqlite3 file as a database. This database stores users and sessions and all that. However I want to use MySQL.

    On to the magic!

    So my database (step 0) is in MySQL.

    In your project settings.py file point your project to this database:

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'iptv',
            'USER': 'iptv',
            'PASSWORD': 'my_awesome_password',
            'HOST': '127.0.0.1',
            'PORT': '3306',
        }
    }

    Now we want to tell Django to look at our database and DO THE WORK. Use the inspectdb command to INSPECT your database and AUTOCREATE a models.py file.

    python3 manage.py inspectdb my_awesome_app/models.py

    The models.py file is your most important file. It holds the logic for your app. This is a file with essentially Python code that describes your database (every table as a class). You can also code it by hand, but inspectdb is very handy!
    Here is what my class/table/model called Package looks like in the models.py file. This is autogenerated by inspectdb. I added the __str__(self) function by hand (so you see the right name in Django). And notice how it links to your db_table ‘packages’.

    class Package(models.Model):
        idpackages = models.AutoField(primary_key=True)
        name = models.CharField(max_length=45, blank=True, default="", null=False)
    
        def __str__(self):
            return self.name
    
        class Meta:
            managed = False
            db_table = 'packages'

    Congratulations! You now have code that understands and can talk to your database!

    Step 4 Profit!

    You’re done. What do you mean? Well, this is where Django shines. It comes with a very capable Administrator interface, user management, logging and more. Django is designed to quickly get something up and running so people can start filling the database while you create a frontend (view). However for intended purposes, maybe you don’t need a frontend. Maybe the Administrator backend interface will do just fine.

    Okay, there are still a few steps. But you came this far, so the next steps are easy.

    Of course you need a user: create one. This will only work after you’ve done makemigrations and migrate (see below).

    python manage.py createsuperuser --username=jan --email=jan@j11-awesomeness.com

    This will create a Django user so you can log in to the admin backend. But wait, nothing is running yet. You can use whatever webserver you like, but batteries included, you can just start up a Python webserver:

    python manage.py runserver 0:8000
    
    (venv)[11:08:59]jan@server:~/projects/my_fancy_project$ python manage.py runserver 0:8000
    Performing system checks...
    
    System check identified no issues (0 silenced).
    November 22, 2017 - 10:09:02
    Django version 1.11.7, using settings 'project.settings'
    Starting development server at http://0:8000/
    Quit the server with CONTROL-C.

    This starts a webserver on port 8000 (choose whatever port you like). You can now browse to http://[youripaddress]:8000/admin and you will be presented with a login screen.

    Note that whenever you make changes to your database structure (don’t do this too often, start with a good design). Run the following:

    python manage.py makemigrations
    python manage.py migrate

    This will make a migration schedule for you, and migrate things. But you also need to use these commands to initially migrate from the built-in default database (db.sqlite3) to MySQL: after you defined the settings.py file (step 4).

    So, I have a user, I migrated my Django project to MySQL, I have my models.py file and I have a webserver running. So, I get a login screen like this on http://[youripaddress]:8000/admin

    Django administration login screen

    So I logged in. But where is my app? Where are my models/tables, so I can edit them? Well they are there, just not visible in the admin interface just yet. In the settings.py project file add your app to INSTALLED_APPS. And you’re done. You now have a complete CRUD environment where you can create and edit users and groups (Django default) and tables from your app (oh yeah!). It looks like this.

    Django administration interface

    When you click the tables (models!): you can see  automatic dropdown lists with database relations and checkboxes and all that. This is all generated from the models.py file.


    Django contacts exampleDjango channels example
    What’s next?

    As said, this is a quick way to get your data in de Django admin interface and start adding data, while you work on the frontend (views). I am not doing that, the admin is good enough for me. So, remember: apps are folders, the models.py file is important, most things are done with manage.py.

    Django is really popular and there are lots of tools/libraries you can use/hook into your own Django app. Just use pip. For example I use django-sql-explorer which is a full frontend to create, store and export SQL queries.

    Conclusion

    I like Django because from all the things I tried (things: easy web CRUD) this made the most sense. I also like the start-with-your-database-design approach (very reminiscent of MS Access, which I love). However, I still think it maybe is too much work. Sure, if you have done it before, know virtual environments, know manage.py, know a bit of Python,  this all really can be done in 5 minutes. Really. However, if you haven’t, maybe this could all be a bit overwhelming, so hopefully this blog helps! Or maybe there are even easier tools to get something up and running quickly?