Pythonator makes Python coders out of gamers. It runs on a Minetest game server and comes with a companion PyCharm Edu course which teaches gamers how to overcome the obstacles in the game by writing Python programs.

A Pythonator workshop will be held at QSITE conference 2018. Attendees should bring a Windows, Mac or Linux laptop. Android and iPads are not suitable. If you don’t already have the following software installed, please install it prior to attending.

Python 3

PyCharm Edu 2018.1.2

Download and install PyCharm Edu v2018.1.2.
Download the Pythonator companion courses for PyCharm Edu. Do not unzip or extract the companion courses. Safari users need to ensure Safari doesn’t ‘open “safe” files after downloading’ which automatically unzips these files. This is the bottom setting in the General tab of Safari Preferences…

Minetest 0.4.17.1

If you are running macOS 10.13 you can download a prebuilt version of minetest 0.4.17.1. To install, open the downloaded dmg file and drag the minetest icon on to the Applications icon. To run the first time right-click the minetest icon in Applications folder and click “Open”. There might be a security warning but you will then be able to click “Open” button.

Detailed installation – Mac (using the command line)

This section is for those comfortable with the Mac command line using Terminal application. I prefer installing using Homebrew because it matches the build of minetest to my version of macOS and it is easy to install updates.

Python 3 and Minetest

Type the following in Terminal to install XCode, Homebrew, Python 3 and Minetest if you have not installed them already.

The last line opens the installed minetest folder in Finder. Double-click the minetest icon. While minetest is running, right-click on the icon in the dock and select “Options > Keep in Dock” to make it easier to run next time.

PyCharm Edu 2018.1.2

Download and install PyCharm Edu v2018.1.2.
Download the Pythonator companion courses for PyCharm Edu. Do not unzip or extract the companion courses.

Licence

If you want to run the PyCharm Edu Minetest course developed by Triptera you will need a licence. Licences are free if you are running the course in 2018. Please contact Triptera for a licence. Please provide details where you would like to use the software. The licence covers the “builder_police” mod for Minetest and the “Ninja 2 minetest course” for PyCharm Edu, both of which are available with open source. All other components are covered by free and open source licences. Support is available to assist you setting up the PyCharm Edu Minetest course.

Minetest

Minetest is a Minecraft clone allowing players to build block structures in a virtual world. To set up your PyCharm Edu Minetest course server follow instructions at Python programming course using Minetest

Minetest is open source free software which runs on Linux, Mac, Windows plus it even runs on Android, iOS and Haiku. At CoderDojo we used to run this course in Minecraft but have now switched to Minetest because of its many advantages.

Minetest is free so ninjas don’t have to buy a Minecraft licence.

Minetest passwords can be set by server op. This is much better than Minecraft which would not ask for the password when ninjas were at home, but as soon as they joined our LAN at CoderDojo Minecraft asked for their password which they couldn’t remember.

Minetest can run on a LAN with no Internet access. Minecraft users would have to log in to the unreliable library wifi to enter their Minecraft password and then switch networks to our LAN to join the virtual world.

Minetest has an excellent modding interface that encourages mods unlike Minecraft which obfuscates its java code to make modding harder. The Lua modding language has surprisingly good performance. I hadn’t used Lua before but I picked it up quite quickly and it is apparently common in other games which need scripting. I did have trouble getting network sockets working in Lua on Windows but eventually solved that problem.

Minetest does not do mobs (monsters and other non player characters) as well as Minecraft. Mobs in Minetest are not native so have to be implemented in mods using the Lua scripting language. This has not been an issue for this course which we run without mobs for better performance.

Op Commands

Running the PyCharm Edu Minetest course is mostly automatic. However there are a few custom commands you can enter through in-game chat to manage the world

/set_jail_free_task 1
sets the task a player needs to complete to get out of jail

There are also some useful built-in commands

/help
provides help on chat commands

/help all
lists all the chat commands

/help command
help on a specific chat command. e.g. /help time

/time 6:00
set clock to morning time so players are not in darkness. If this becomes onerous, consider setting the “Time speed” to zero in Settings > Advanced settings > Server / Singleplayer > Game > Time speed

/grant player_name irc_builder
gives a player privileges to use building commands over IRC (should be automatic for new players) will show player’s list of existing privileges.
example /grant tim irc_builder

/revoke player_name irc_builder
opposite of grant

/teleport player_name x y z
move player to new coordinates. e.g. /teleport tim 95 12 20 see help for variations

/setpassword player_name new_password
sets player’s password in Minetest. Password can not be blank or contain spaces if it is to work with ircbuilder.
example /set_password tim sesame

/privs
see what privileges you have

You can even send any of these commands to the server over IRC. Send private messages to the server botnick (eg mtserver). The first message is to login. The second and subsequent messages are the same as the chat commands but replace the / with cmd. Below is an example IRC session. Replace mtuser and mtuserpass with the minetest user and password you want to connect as. The minetest username can be different to the IRC nick name.

login mtuser mtuserpass
cmd privs
cmd time 6:00

You can even use python console to send commands if you don’t have an IRC client. mtuser needs to be the serverop player name

PyCharm Edu is an Integrated Development Environment (IDE) for python which has the additional ability to run courses for learning python programming. It also enables teachers to create those courses. PyCharm Edu is cross platform, running on Linux, Mac and Windows.

At CoderDojo I am mentoring ninjas in coding python so I thought I would try PyCharm Edu. To create a course, I created a series of tasks. Each task is a python program with sections left out to be completed by ninjas (answer placeholders). A task has a task description to explain to the ninjas what to do, and a series of tests to determine when they had completed the task. Each answer placeholder has hints to help solve it, some text which needs to be replaced by the ninja and even the correct answer. The tasks have to provide enough information for the ninja to understand what needed to be done, but not enough that the answer was trivial.

Writing the tests was challenging. The tests needed to check for all possible correct answers. For example, if the correct answer was “x+y” then I should also accept “y+x” or “y + x”. I solved this problem by using the python eval() or exec() to test the value of functions or the effect of statements rather than compare the exact characters typed to the answer.

For example, here is how I used eval() to test for where the correct formula should be (x+y).

When the ninja (student) is running the course they have access to a full python IDE, including command completion and debugging. As a teaching aid one of the most useful features is the console where ninjas can test individual python statements. The console has a sub-window showing variables created in the console and their values, great for teaching how variables work.

The ninja can see the code for the current task and a task description describing what they have to do. In the diagram below notice the sections of code with thin rectangles around them. These are the answer placeholders that the ninja needs to replace to solve the task. They shouldn’t need to type outside these rectangles, although they can if they want to embellish the program.

While attempting a task they can do the following actions:

Get hints on an answer

Reset the task to undo all their changes

View the answers (after which they must reset the task)

Run the program with output going to a local window (ctrl-shift-F10)

Check the task which assesses how well they have done by running tests

Advance to next or previous task

Advantages of using PyCharm Edu over web python tutorials or text editors:

Do you want to learn at home how to program in python while enjoying the fun of building structures in Minetest? These instructions will help you create your own setup similar to the one used at Coderdojo. First of all, make sure you have finished the instructions for the Minetest client install and the Minetest server install.

The steps to configure your course platform:

Install builder_police mod for Minetest.

Install courses in PyCharm Edu

To configure your course platform you will need Internet access to download builder_police from github, ircbuilder python module from pypi.org, and the courses from this website.

To run the course you will need Internet access to a public IRC server (e.g., irc.rizon.net) which handles the communications between your python program and Minetest.

Minetest mods

The following commands are to be typed into Git-Bash (Windows) or Terminal (Mac, Linux). Change directory to the minetest mods directory. If the directory doesn’t exist you may have to create it.

Underneath the list of courses, click on the small rectangle with an arrow pointing into it and select “Import a local course”.

Select the downloaded file “Ninja_2_minetest_course_v5.zip”.

Once it has imported you can click on the “Join” button in the bottom right hand corner. Joining a course takes a while because PyCharm will set up a virtual environment for your python programming which doesn’t affect other python programs on your computer.

The virtual environment will detect that you need the python module ircbuilder version 0.0.5 or later and give you an option to install or ignore this requirement. Choose “Install requirement”.

To do the course there are some details you need to set so that your python programs can connect to IRC and Minetest. These details are all stored in a file called “coderdojo.py”. In PyCharm, go to the File menu and select “Open…”. Navigate to your home folder, the folder “PyCharmProjects”, then the folder “Ninja 2 minetest course v5”, select “coderdojo.py” and click “OK”.

If you want to practice at home building Minetest structures with python programs, you will need to install Minetest server with its mods. Before we start, make sure you have completed the Minetest client install.

Git

Windows users will need to download the latest from https://git-scm.com/ and install. This will also install Git-Bash which is a command line shell similar to those on Mac and Linux.

Linux and Mac users should already have git installed. To test, type the following in the Terminal:

git --version

If it is not installed it will give an error message saying “command not found”. Mac users can download the software from the above site or install it using brew as they did with minetest.

brew install git # Mac

Linux users can install using one of the following if it is not already installed.

apt install git # Ubuntu, Debian

yum install git # Fedora, Centos, Red Hat

Luasocket

The irc mod for minetest requires luasocket. This is difficult to install on windows so I have built a 64 bit version of minetest with irc mod and luasocket already built in. It can be downloaded from minetest-0.5.0-6cfd699b-irc-win64.zip.

On Mac, install luasocket using brew and luarocks.

brew install lua51

luarocks-5.1 install luasocket

On Ubuntu install luasocket using apt and luarocks.

apt install luarocks

luarocks install luasocket

Minetest mods

The following commands are to be typed into Git-Bash (Windows) or Terminal (Mac, Linux). Change directory to the minetest mods directory. If the directory doesn’t exist you may have to create it.

Configure mods and IRC

Every Minetest world in which you want to use these mods needs to have them enabled.

Run Minetest.

Select [Settings] tab, then [Advanced Settings] button in bottom left

Expand: + Server / Singleplayer + Security

[Edit] secure.trusted+mods. type in irc

Expand: + Mods + irc + Basic

[Edit] Bot nickname. For example: mtserver

[Edit] IRC server. I like Rizon which has server: irc.rizon.net

[Edit] Channel to join. Choose a unique channel . eg ##minetest3214

Port number can be 6667 and Auto-connect enabled. Channels starting with ## are generally temporary channels. Remember these settings to use in your python program. Make sure your IRC server allows several connections from the same IP address.

From the [Local Game] tab, select your world and click on [Configure]

Select mod on the right and click the “enabled” check box above for each of the four

Click [Save] button to return to [Local Game] tab

Type in a password in green password field and click [Host Game]

Users who wish to build structures from python will need privilege irc_builder. After they have logged in grant them this privilege by typing /grant username irc_builder

Program in Python 3

Now you can start to write programs in Python which will build structures in Minetest. Remember to install ircbuilder python module in your python virtual environment so that your program can communicate with IRC and hence with Minetest. You can do this in PyCharm Edu from Settings (Windows) or Preferences (Mac) > Project > Project Interpreter > + (and type in ircbuilder).

THIS PAGE HAS BEEN SUPERCEDED BY Pythonator at QSITE WHICH HAS UPDATED VERSIONS OF EVERY PIECE OF SOFTWARE DESCRIBED HERE!

At CoderDojo this term we will be learning to program in Python 3 to build structures in a Minetest world. Minetest is a free, open-source, high performance Minecraft clone that is easily modded. There already exist mods which allow chat commands to be executed over IRC (Internet Relay Chat). I have created a Minetest mod (irc_builder) to add chat commands allowing us to build structures using those commands. I have also created a python module (ircbuilder) which sends commands through IRC to the Minetest world.

PyCharm Edu

PyCharm Edu is a free open source integrated development environment (IDE) for Python, better than IDLE which comes with Python. It also can guide students through a course of lessons and tasks, providing hints and checking on tprogress automatically.

Windows, Mac, Linux: Download PyCharm Edu v2017.3 or later from the Jetbrains website. Install using defaults. The courses will be provided as zip files with the names

Minetest

You can install minetest client without any mods as server mods only need to be installed on the server and then every client can use them.

Windows 64 bit

Download Minetest v0.4.16 (portable 64 bit) from the Minetest website. Extract the zip file to your Documents folder. The program can be run by double clicking on Documents\minetest-0.4.16-win64\bin\minetest.exe

Windows 32 bit

Download Minetest v0.4.16 (portable 32 bit MSVC) from the Minetest website. Extract the zip filet to your Documents folder. The program can be run by double clicking on Documents\minetest-0.4.16-win32-msvc\bin\minetest.exe

Mac

The Mac version of Minetest needs to be installed using Terminal (Applications/Utilities). If you haven’t installed brew, install it first with (one line):

Importing modules

In the previous python in minecraft blog we created a program to construct an east-west tunnel. This is a useful program which we might want to use often. We can put the program into a function and save the function in a module so it can be used by other programs. We will call the function “buildEastTunnel()”. The module name will be just the name of the file, which in this case we will call “tunnel.py”. Then whenever we want to build a tunnel running east west, we can import the module just like we have been importing mcpi.minecraft and mcpi.block.

There are several ways to import functions. The simplest method imports the module but not the function name. We still need to tell python to look in that module when calling the function

import tunnel
tunnel.buildEastTunnel()

If you want to give the module a better name you can use “as” to assign a new name. This is what we do when importing mcpi.minecraft as minecraft.

import tunnel as mole
mole.buildEastTunnel()

If you want to use the function without qualifying it with the module name each time, you can import the function explicitly from the module.

from tunnel import buildEastTunnel
buildEastTunnel()

Function parameters

Now calling buildEastTunnel() as it is currently written will always construct a tunnel in the same place, x = -400 to -200, y = 72 at each end, z = 244. However, if we design the function to take parameters then when we call the function we can specify where the tunnel is built.

This example passes the mc object to the function so it knows which minecraft server to build the tunnel in. Then it gets the x, y and z coordinates at each end of the tunnel. Because the tunnel is running east-west there is only one z value required. Our code is designed to go from xmin to xmax but someone calling our function might put the higher value of x first and the lower value second or vice versa. We can take advantage of python’s ability to assign several variables at once to ensure xmin is less than xmax.

When designing a function to take parameters, it is possible to specify some parameters as “required” and other parameters as “optional”. Optional parameters need to be given a default value. In our example it would be useful for the y values to use ground level if it is not supplied. “Required” parameters have to come before “optional” parameters so the parameters list should now be (mc, x1, x2, z, y1, y2).

Finding ground height

We are calling a function getGroundHeight(mc,x,z) which we haven’t written yet. In mcpi.minecraft is a function mc.getHeight(x,z) which finds the highest block which is not air at x and z coordinates. Unfortunately that block will often be a tree or sapling. Here is a function which corrects mc.getHeight(x,z) for trees. It makes use of the mc.getBlock(x,y,z) function which returns the id of the block at those coordinates.

In the previous example, the user was the pilot. See if you can design an autopilot which will land the lunar landing module on the moon. You need to design a function which calculates a new burn value based on available data, altitude, speed, gravity. Here is my simple example.

Floating point numbers, called floats in python, are numbers which have a decimal point and sometimes digits after the decimal point. They are different to integers which represent whole numbers and do not have a decimal point. You can display the type of values or variables using the type() function. The following example displays the type of several values. In python 3, the division operation / always returns a float.

Printing floats can be messy because python prints as many decimal places as it thinks it needs up to about 16 significant figures. However python provides several methods of formatting floats to improve output. We will look at the .format() method which can be applied to any string and can be used to format all data types. It produces a new string which can be printed or saved to a file or stored in a variable for later use or passed to another function. .format() uses {} placeholders in a string to insert values of variables in the new string. Inside these curly braces you can specify details such as which value from the arguments (before the :), how wide the string is (integer just after the :), how many decimal places to show after the decimal point (for example .3f includes 3 decimal places after the decimal point of a float. Hence, to include the value of altitude to 3 decimal places in a new string we use

'Altitude = {:.3f}'.format(altitude)

which returns a string 'Altitude=970.000'

A width can be provided immediately following the :. To format and print several values in the same string, provided in the correct order in format, we have the following example:

This exercise also demonstrates the benefits of comments in python code. Comments are not interpreted by python and do not affect the program at all. However, they make it much easier for other people, or even yourself a few weeks later, understand what the program is supposed to do. All comments start with a #. Here is a game to pilot the lunar landing module onto the moon. Read the comments to work out what you need to do and then give it a go. See if you can work out how it works.

# moonlander.py
# this game simulates a lunar landing module (LLM) landing on the moon
# you are the pilot and need to control how much fuel you burn in the
# retro rockets so that your descent speed slows to zero just as your
# altitude above the moon's surface reaches zero. If you impact the moon
# more than 5 m below the surface, or your speed on impact is
# greater than 5 m/s then you have considered to have crashed.
# Otherwise it is considered to be a 'good' landing.
# If you run out of fuel, LLM will accelerate towards moon by gravity.
# set up the initial parameters
speed = 30 # speed approaching the moon
fuel = 1500 # how much fuel is left
altitude = 1000 # altitude above moon
gravity = 1.622 # acceleration due to gravity
burn = 0 # initial rate of burning fuel in retrorockets
# while LLM is above the moon's surface,
# calculate flight data and take input from pilot
while altitude > 0:
# calculate how long until LLM will impact moon at current speed (impact)
if speed <= 0:
impact = 1000
else:
impact = altitude / speed
# display flight data
print("Altitude={:8.3f} Speed={:6.3f} Fuel={:8.3f} Impact={:6.3f} Previous burn={:6.3f}".format(altitude,speed,fuel,impact,burn))
# take input from pilot
burn = float(input("Enter fuel to burn (0-50)?"))
# ensure rate of fuel burning is within rocket's capability and doesn't exceed remaining fuel
if burn < 0:
burn = 0
if burn > 50:
burn = 50
if burn > fuel:
burn = fuel
#calculate new flight data
altitude -= speed
speed += gravity - burn/10
fuel -= burn
# loop has ended so we must have hit moon's surface
# display final flight data and assess whether it was a crash or a good landing
print("Altitude={:8.3f} Speed={:6.3f} Fuel={:8.3f} Last burn={:6.3f}".format(altitude,speed,fuel,burn))
if altitude <- 5 or speed > 5:
print("You have crashed")
else:
print("You have landed")

This exercise is to find all the factors of a given number. Remember that a factor divides evenly into a number without leaving a remainder. We can use the modulo operator (%) to check for any remainder. The program will check all integers from 2 up to but not including the original number. To loop through those numbers we will use the for loop combined with the range() function.

number = int(input("Enter the number?"))
for i in range(2,number):
remainder = number % i
quotient = number // i
print(number,"=",i,"x",quotient,"+ remainder",remainder)
if remainder == 0:
print("remainder is zero so",i,"is a factor")
else:
print("remainder is not zero so",i,"is not a factor")

Using print() in this way shows clearly the flow of the program. However, two lines of code for each potential factor is a lot to read through. To reduce the number of lines of code, print() lets us specify a different ending than a new line. If we specify end=’ ‘ then print() will end the line with a space rather than a new line significantly reducing the number of lines of output.

The following program ignores output when the number is not a factor, and displays all the factors on the same line, with a final message whether the original number is prime or composite. Instead of asking for the number to be entered, the program finds all factors for all numbers between 2 and 99 inclusive.

for number in range(2,100):
print(number,'factors:', end=' ')
prime=True
for i in range(2,number):
if number%i == 0:
print(i, end=' ')
prime=False
if prime:
print('prime')
else:
print('composite')