December 16, 2017
Getting started with parametric design in DrawBot, Part 2
The following are notes taken from Just van Rossum’s Python class in the KABK Type and Media program, on Sep 20, 2017. If you haven’t yet learned anything about Drawbot, start with part 1 of this series.
In these classes, Just does a great job of breaking down concepts and going in a logical order, but he also goes quite fast. So, these notes are what I could take at that speed, while I was also following along doing the examples in Drawbot. If you find anything that is unclear, feel free to reach out to me via Twitter and ask me about it.
Drawbot editor
Drawbot isn’t the world’s greatest text editor, but it does do some neat things.
Numbers
Highlight a number, then hold command
while hitting up/down arrows. Hold Shift
to move by 10, option
to move by 0.1, and option + shift
to move by 0.01.
When you have a number highlighted, you can old command
, then click + drag
to move the value up and down. You can even highlight two numbers to move them together.
Text highlighting with the keyboard only === yo
Like most text environments, you can highlight text by holding shift
, then using left/right/up/down arrows.
Tabbing
You can tab in/out a whole block of text by highlighting it, then using Command + ]
or Command + [
Booleans & if
statements
if 3:
print("yes")
# non-zero numbers or strings are true
if 0:
print("zero")
# false
if "":
print("empty string")
# false
if True:
print("True")
# True (and False) have capitals
if 2 < 5:
print("yup")
# 2 < 5 can be run anywhere, and the True/False value can be referenced
a = 123
if a is not None:
print("yes")
You can compare the values of two variables:
nameA = "Stephen"
nameB = "Steven"
if nameA == nameB:
print("the names are equal")
else:
print("the names are different")
# prints "the names are different"
numA = 12
numB = 12
if numA == numB:
print("the numbers are equal")
# prints "the numbers are equal"
Identity equivalents
- strong equivalents are
is
andis not
Conditionals
if a != b:
print("yes")
Indexing
list = [12, 34, 123, 232, "string"]
print(list[1]) # 34
Python is “zero indexed” – counting on lists starts from zero (the same is true in for loops, etc).
Length
print(len(list)) # prints 5, the "length" of the list
You can print the last item of the list, or count from the last item
print(list[-1]) # prints last item
print(list[-2]) # prints second-to-last item
print(list[len(list) - 1]) # longer form of list[-1]
A string also has a length:
print(len("abc")) # prints 3
Managing lists
You can manage data in lists, like
list.append("a new item")
print(list) # [12, 34, 123, 232, 'hey look a string', 'a new item']
“For” loops
family = ["Homer", "Marge", "Lisa", "Bart"]
for member in family: # here, you set up "member" as a variable to describe each element of the list
print(member) # prints Homer, Marge, Lisa, and Bart, each on a new line
You can also loop through the letters of a string
for item in "abcde":
print(item) # prints a b c d e
Q: What is a “counter” A: each time you go through a “for loop,” the variable you assign to the list you are going through increases by 1. Using this value each time you go through the loop allows you to do things differently each time you run through the loop.
Loops
x= 50
rect(x,100,100,100)
x= 200
rect(x,100,100,100)
x= 350
rect(x,100,100,100)
x= 500
rect(x,100,100,100)
x= 650
rect(x,100,100,100)
x= 800
rect(x,100,100,100)
👆 That was a lot of typing. Instead, let’s use a loop:
for i in range(6):
x = 50 + i * 150
print(x)
rect(x, 300, 100, 100)
In addition to being faster to write, this is more flexible, too! We can now easily change the quantity of squares.
Let’s make a grid and make y flexible
gridDistance = 150
squareSize = 120
for i in range(6):
x = 70 + i * gridDistance
for j in range(6):
y = 70 + j * gridDistance
if x < 500 and y < 500:
rect(x, y, squareSize, squareSize)
else:
oval(x, y, squareSize, squareSize)
(By the way, i
is common in code loop examples, because it’s short for “interger.” As an extension, j
is popular as the next loop variable, and so on.)
Modulo
Want to alternate between things in an odd/even, or “every nth object” fasion? You can reach for modulo.
The Modulo math operation divides by something, and outputs the remainder. It is represented by %
.
SO, If you modulo-divide a number by 2 like x % 2
, it will result in 1
if it’s an odd number (truthy), and 0
if its even (falsy). You can add this to a grid example to alternate between shapes or colors:
if j % 2:
fill(1,0,0) # makes odd shapes red
You can make a checkerboard like
if (i + j) % 2:
fill(1,0,0) # makes odd shapes on first row red, then even shapes on next row red
In my next post about Drawbot, I will diverge from class notes and take an “explain it like I’m 5” deep-dive into making a perfect, expandable grid in Drawbot. Scroll to the bottom of this post if you’d like to get there now.
Questions from class
Q: What version of python should we be focused on?
~In DrawBot, we are using Python 2.7. There is also an experimental version of DrawBot that uses Python 3.6.~
~Robofont scripting uses Python 2.7, so as beginners and students learning about type design, using Drawbot in Python 2.7 works in our favor.~
Update, Jan 2018: DrawBot now uses Python 3.6, and RoboFont 2, current in Beta and being released this spring, will use Python 3.6 for scripting.
Thanks for reading!
If you’d like to keep charging ahead, I’ve written a deep-dive tutorial into making a “perfect” grid in Drawbot: check out the next post in this DrawBot series.
I’m typing these posts into the void, so hopefully someone out there has enjoyed this. Did you actually read this post? Have you tried any of these examples in DrawBot yet? Would you like me to clean up my other notes to in follow-up posts? Let me know on Twitter!