Meeting 2020-01-28

Python Variables and Math

We got to last week's project just as the bell rang, and I want to make sure everyone had a chance to try it before going on to Python math.

More on Python Variables

One possibly obvious but important thing about variables I didn't write up last week: Whenever you could have a constant value in a statement or expression, you can put a variable (of the correct type) instead, and Python uses the value of that variable in the expression.

And just a reminder that the equals sign doesn't mean what it means in a math equation. It is an assignment statement that computes a value and assigns it to the variable on the left of the equals. So something like:

playerX = playerX + 1

would never be true in math, but in Python it just increments (adds one to) the value stored in playerX. Python has different symbols that are used to test for equality/inequality: ==, !=, <, >, <=, >=

Project: Rewind Position

For our Minecraft project we will write a Python program that teleports you to some position in the Minecraft world, delays, and then moves you back to your spawn point. We will set the position and the time delay using variables in the program.

Enter the following program in an IDLE editor window. You can cut and paste it but you will learn more if you type it in and correct your mistakes!

from mcpi.minecraft import Minecraft

import time

mc = Minecraft.create()

playerX = -1234

playerY = 33

playerZ = 1234

delay_time = 10

moving_msg = 'Moving you somewhere'

spawn_msg = 'Back to spawn!'

mc.postToChat(moving_msg)

mc.player.setTilePos(playerX, playerY, playerZ)

time.sleep(delay_time)

mc.postToChat(spawn_msg)

mc.player.setTilePos(0,4,0)

Save the program to %appdata%/.minecraft/mcpipy/lowelltele.py (or pick your own name) and in Minecraft enter "/py lowelltele" to run it.

Try changing the values of the playerX, playerY, playerZ, and sleep_time variables and running it again. If your program gets stuck you can end it by entering "/py" (no program name). What happens if you set a variable to a floating point value like 1234.567? How about a string value?

The coordinates you provide are relative to the spawn point, not the absolute coordinates you see when you press F3. So x,y,z=(0,0,0) is your spawn point. The "Y" coordinate is the height above the ground. Depending on your terrain, teleporting you to Y=0 may put you underground. So, I increased it to Y=4.

Python Math

REPL stands for "Read-Evaluate-Print Loop", which describes how the Python Shell window operates on the code you type. In the shell you don't need to type full statements, you can just type an expression like (2*playerX)-4, and Python will Read it, Evaluate it, Print the result, and Loop back for more input. You can also type full Python statements and the shell will let you import libraries, create and update variables, and call functions. This can be useful for testing out code and seeing how things work in Python. However, everything disappears when the window is closed, so when you have code that you want to use again, open a Python text editor window (press Control-N), copy and paste it in, and save the file somewhere.

The REPL shell window can be used as a calculator as long as you follow Python math syntax. Python has the standard addition (+), subtraction (-), multiplication (*), and division (/) operators so you can enter calculations like:

>>> 1+2+3+4+5+6

21

>>> 1*2*3*4*5*6

720

Or calculate about how many blocks would be in a 20x20 pyramid that is 10 blocks high:

>>> 20*20*10 / 3

1333.3333333333333

Like regular math, Python math operators have precedence, so equations don't just get evaluated from left to right. Multiplication and division get evaluated before addition and subtraction so 2+4*5 = 22, not 30. Like regular math, you can use parentheses to group operations that you want to be evaluated first:

>>> 2+4*5

22

>>> (2+4)*5

30

Python has some other math operators that are worth knowing about. Exponentiation is written as ** (and not ^) so:

>>> 2*2*2*2*2*2

64

>>> 2 ** 6

64

Python has a modulo function % which computes the remainder after integer division:

>>> 21 % 5

1

>>> 24 % 5

4

>>> 25 % 5

0

Along with % it has a "floor division" operator // which returns the integer part of the division (note that it doesn't round up if the fractional value is greater than 0.5 - returning just the integer part is called a "floor" operator):

>>> 21 // 5

4

>>> 24 // 5

4

>>> 25 // 5

5

Note that // returns an integer type instead of floating point.

>>> type( 24 // 5)

<class 'int'>

>>> type( 24 / 5)

<class 'float'>

Python Assignment Operators

In programming it is very common to want to update the value of a variable instead of creating a new variable:

block_count = block_count + 10

damage = damage * 1.5

num_arrows = num_arrows - 1

Python gives us a shorthand way to do this that is called an assignment operator and combines the the math operator with the equals sign:

block_count += 10

damage *= 1.5

num_arrows -= 1

Using assignment operators is optional but can save you some typing.

Project: Jump Position

Let's use assignment operators to move a player around the map in jumps. Start from the Rewind Position program (or cut-and-paste this code):

from mcpi.minecraft import Minecraft

import time

mc = Minecraft.create()

playerX = -100

playerY = 66

playerZ = 100

delay_time = 2

jumpX = 30

mc.player.setTilePos(playerX, playerY, playerZ)

### Add jump code here

time.sleep(delay_time)

mc.player.setTilePos(0,64,0)

Make sure this program works and then add a block of code to make the player jump after a pause:

time.sleep(delay_time)

playerX += jumpX

mc.player.setTilePos(playerX, playerY, playerZ)

Insert as many copies of this code as you would like where it says "### Add jump code here". Each copy will do another jump before returning the player to the spawn point. But there must be a better way to do this than making a bunch of copies of the same code!

Try other values for the jump, and try other assignment operators like *= instead of +=.