-
Notifications
You must be signed in to change notification settings - Fork 9
PythonBasics
This doc is designed for two types of people. Please click on the link below that best describes you:
(Please note that this doc is a work-in-progress.)
When you write code in CardStock, you're writing Python code. CardStock defines many CardStock-specific things, including CardStock object types like Button, TextField, Oval, etc., and functions to help your stack do things, like goto_card() and alert(). All of these CardStock-specific things are explained in the CardStock Reference. But in order to understand how everything fits together, you'll want to learn some basics of Python first.
Most programs largely consist of manipulating the values of things. For example:
- Setting the title of a button
- Getting the text that a user typed into a TextField
- adding 100 to the score variable in your game
- setting the position of an oval object
Every value (piece of data) in Python has a type. It could be:
- an int (integer / whole number) like 1, 124, or -7.
- a float ("floating point" number with a decimal part) like 0.2, 2.0, 1.5, 3.1415, etc.
- a string (arbitrary text, contained in either single or double quotes) like "CardStock", 'This is some text', "I'm a double quoted string with a single quote (apostrophe) inside because a stray single quote inside of a single-quoted string confuses Python!"
- a list (a list of other pieces of python data) like [1, 2, 3], ["Anne", "Bob", "Clint", "Doug"], [28, "word", 1.5, [1, 2, 3]]
- a bool or boolean value, is just a simple True or False. If you test a value, like checking whether
x == 3
orx < 7
, you will get back a bool. - other types that you can learn more about later, like a dictionary, function, bytes, other objects
- or in CardStock, values can be CardStock objects, like a Card, Button, Oval, or TextLabel, etc.
When programming, you often need to store a value for later. To do this, you
create a variable. A variable is basically a named container that holds a value.
You can make a variable and set its value just by using the assignment operator (=
):
# Note that text after a # sign is called a comment.
# It's just for people to read, and is ignored by Python
x = 5 # This sets the new variable x to the number 5
y = "Hello" # This sets the new variable y to the string "Hello"
z = [1, 2, 3] # This sets the new variable z to a list of ints
Then, later in your code, when you want to use, check, or modify this value, you can just use the variable name instead of the value itself. Some examples:
x = 5
x = x + 1 # This sets x to be one more than the current value of x, so x is now 6
name = "Ben" # The new variable name now holds the string "Ben"
name = name + "is great." # name now holds "Benis great." Oops! We should have included a space before is
name = "Jane"
name = name + " is great." # note the leading space. The variable name now holds "Jane is great."
You can also get individual items from a list, or individual characters from a string, using square brackets with the position (called the index) of the piece you want inside. One thing that often confuses beginners is that the first item in a list, or the first character in a string is at index 0. The second one is at index 1.
names = ["Anne", "Bob", "Clint", "Doug"]
n = names[0] # "Anne"
n = names[3] # "Doug"
n = names[-1] # "Doug"
# WHAT? Using a negative index in python actually counts back from the end,
# so using an index of -1 gives you the last item.
n = names[1] # variable n is now "Bob"
first_initial = n[0] # so the letter at the 0th/first index of n is "B"
A note on variable names: Variable names are usually just letters or words, but can also contain underscores _
and
numbers, as long as the name doesn't start with a number. Dash is not allowed either, since
Python will think you are subtracting. And you should avoid naming variables using any
built-in python keywords like if, str, int, list, etc.
Some good variable names include: i, x, names, bird_color, oval_1
Some bad/broken/not-allowed names include str, list, while, 12monkeys, bird-color
You got a sneak peek at expressions in the previous section, with examples like x = x + 1
Expressions are combinations of values, variables, and operators that produce a result.
They are the first step in building up meaningful code, and are used to perform calculations and make
decisions.
Operators are symbols or special keywords that perform operations on values or variables. Here are a few examples:
- Arithmetic operators:
-
+
(addition),-
(subtraction),*
(multiplication),/
(division),%
(modulus a.k.a. remainder)
-
- Comparison operators:
-
==
(equal to), != (not equal to),<
(less than),>
(greater than), <= (less than or equal to), >= (greater than or equal to)
-
- Logical operators:
-
and
,or
,not
-
- Assignment operators:
-
=
(assign),+=
(increment),-=
(decrement),*=
,/=
-
Note that like many programming languages, Python uses a single =
to mean assignment (setting a variable),
and uses a double ==
to compare two values and check if they are equal.
Some examples:
x + 9 # result is 9 more than the current value held in the variable x
(7+x)/2 # half of the sum of 7 plus whatever is in x
"Hi " + name # "Hi Ben" if name is "Ben", or "Hi Jane" if name is "Jane", etc.
# The % (modulus) operator means divide and give me the remainder
182 % 10 # So this means do 182/10 but give me back just the remainder, which is 2
x % 2 # This one is interesting. If x is even, the result is 0, and is 1 if x is odd.
x % 2 == 0 # And this results in True if x is even, and False if x is odd.
x == 9 # True if x is 9, otherwise False
x < 7 # True if x is less than 7, False if x is 7 or more
x == 7 and name == "Ben" # True only if x is 7 and also name is "Ben", otherwise False
total = x + y + z # Adds the values in x, y, and z, and stores them into total
isHi = (x == "Hi") # sets the variable isHi to True if x holds the string "Hi", otherwise to False
# These operators are shorthand for modifying a variable
a += 5 # Adds 5 to a. Same as a = a + 5
a -= 10 # Subtracts 10 from a. Same as a = a - 10
a *= 10 # Multiply a by 10
a /= 2 # Divide a in half
Using functions, and eventually writing your own functions, are important parts of programming. They allow you to group some code together and give it a name, which can make your code more organized, modular, and reusable. Functions can take input called arguments, and return a result called a return value. For example, you might have a function called double_it(n), that takes a number n and returns double that number. Then you could write:
x = double_it(4) # x is now 8
x = double_it(x) # x is now 16
z = double_it( double_it(1) ) # 1 got doubled to 2, which got doubled to 4, and stored in z
Python has many built-in functions to do various useful things. Some examples are:
-
len(x)
: it takes a container like a list, or a string, and returns the length of that thing. For examplelen("Hello")
returns 5, andlen([1,2,3])
returns 3. -
int(x)
: takes whatever you give it, and tries to turn it into an int. If you give it a float value likeint(4.1)
it gets rounded and you'll get back 4. If you give it a string like int("72") you'll get back the int 72. If you give it something else like int("hello"), you will get an error. -
str(x)
: takes whatever you give it, and try to turn it into a string. str(12) will give you the string "12". -
max(a, b, ...)
: If you give max() a list of numbers, you get back the biggest one. -
min(a, b, ...)
: If you give min() a list of numbers, you get back the smallest one. -
range(n)
: Generates and returns a list(ish) of numbers from 0 through n-1. Sorange(4)
returns the 4 items [0, 1, 2, 3]. This sounds weird at first, but is very useful when we get to for loops.
You can also define your own functions using the def
keyword. And inside your
function, you can use the return
statement to end the function, and optionally
return a value that will be used as the result of calling this function in the
code that called it.
# begin a function definition, showing that it takes one argument we're calling n
def double_it(n):
new_value = n * 2 # create a new variable that is double n
return new_value # and return it.
x = double_it(50) # Sets x to the return value of double_it(50), which is 100
A function can return any type of value, or nothing at all. A function can just make stuff happen, and not return anything. Here's an example from an imagined CardStock stack:
def change_colors(color): # this function takes one argument we're calling color
card.fill_color = color # it sets each of these objects' fill_color to color
oval_1.fill_color = color
rect_1.fill_color = color
line_2.fill_color = color
# and it doesn't bother returning anything
change_colors("red") # Changes all of those objects' fill_color properties to "red"
change_colors("white")# And now to white
Many types of objects, like strings, lists, and CardStock objects, have internal parts that
are accessible as properties and methods. A property is like a variable that is part of the
object, and a method is like a function that's built into the object, that usually gets
something from, or does something to that object. You access any of these
parts of an object using dot notation, by adding a .
after the object name, followed by the
property or method name. Basically you can think of the dot as letting you dig into a part of
the object.
This is the most basic way that your code will interact with CardStock objects, as you can see in some of the following examples.
num_list = [12, 6, 110, 1, 4]
num_list.sort() # Calls the sort() list method on num_list, which now holds [1, 4, 6, 12, 110]
name = "Ben"
name = name.lower() # Calls the lower() string method on name, which now contains "ben"
test_button.title = "Click Me" # Sets the test_button CardStock button object's title to "Click Me"
card.fill_color = "red" # Sets the CardStock card's background to bright red
field_1.text = field_1.text + "Here's some more text."
# Added more text to the end of the contents of field_1
oval_1.hide() # Makes the oval_1 object disappear
image_1.flip_vertical() # flips the image object image_1 vertically, so the image appears upside down.
For more info on all the properties and methods of all the CardStock object types, check out the Reference guide.
Programs very often need to make decisions about whether or not to do things,
or which thing to do. To do this, we use Python's if
, elif
, and else
statements.
We can use the if
statement to run some lines of code only if an expression
results in a True value, and the else
statement to run other code otherwise.
The elif
statement is a combination of else and if, and lets you chain a bunch of if
statements together. As in: if x is 1, do this, or else if x is 2, do this, or else if x is 3,
do this, or else if none of those were true, do this instead.
if x == 1: # Note the : colon and the indentation below
# The indented code only runs if the expression x == 1 results in True, which means it only runs when x is 1
print("x is 1!")
if x == 1:
print("Do this")
elif x == 2:
print("Do this other thing")
elif x == 3:
print("Do this third thing")
else:
print("x was not 1, 2, or 3, so do this instead")
if a == 3 and b == 1 and c == 4 and d == 1:
# In an imaginary code guessing game, if the variables a, b, c, and d
# are all equal to their secret code values, then print:
print("You got the secret code right!")
if name == "Ben":
# This runs if name is "Ben"
response = "Hi Ben, welcome back!"
else:
# This runs whenever name is anything other than exactly "Ben"
response = "Hi " + name + ". I don't believe we've met."
# Sets response to, for example, "Hi Jane. I don't believe we've met."
if key_name == "Right":
# If the user just pressed the Right arrow key
position += 10 # Increases position by 10.
elif key_name == "Left":
# If the user just pressed the Left arrow key
position -= 10
elif key_name == "Space":
# If the user just pressed the Space bar
position = 0
else:
# If the user just pressed anything else
response = "Why'd you press " + key_name + "?"
Another common thing that programs need to do, is run the same code a bunch of times. Either
once for each item in a list, a set number of times, or until we reach a target. Python gives
us two main ways to do this: The for
loop and the while
loop.
A for
loop runs the code inside it once for each item in a list. It takes a list, and also a
variable name to use to hold each item in the list, one at a time, changing the variable's value
each time it loops back through the code.
odds = [1, 3, 5, 7, 9]
# loop through these odds, running the indented code below once for each item in odds,
# and setting the variable num to each item in the list, one by one,
# each time through the loop.
for num in odds:
alert(num) # This line runs 5 times, with num set to 1 the first time, then 3, etc.
# The above code shows an alert that says 1, then an alert that says 3,
# then one more each for 5, 7, and 9.
total = 0 # set up a value to hold the total
for num in odds:
# this code runs once for each number in odds
total += num # Shorthand for total = total + num
# At the end of the loop, total holds 25 (the sum of all the elements in odds)
total_label.text = total # Set a CardStock label's text value to the total
ovals = [oval_1, oval_2, oval_3, oval_4] # A list of CardStock oval objects
for oval in ovals:
# Sets each oval's fill_color to "red"
oval.fill_color = "red"
# You can also use the range() function to create a list of a specific
# size for us to loop through
for i in range(10):
# Runs this code 10 times, with i set to each of: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
field_1.text += str(i) # Adds the string version of the number to the end of field_1's text
# At the end of the loop, we've added "0123456789" to the end of field_1.text
The while
loop on the other hand, is like a loop with a built-in if
statement. You tell
it to keep looping while something remains True. As soon as the thing stops being True, the
loop will stop repeating. For example:
i = 0 # start variable i at 0
while i < 4: # keep looping while i < 4
print(i)
i += 1 # Increment i by 1
print("Done")
# When Python first arrives at this while loop, i is 0, so i is definitely less than 4
# So we enter the loop. We print 0, and then set i to 1. This round of the loop is done, so
# we go back to the top of the while loop again and check if i is still less than 4. It is!
# So we enter the loop again. We print 1, and then add 1 more to i, so it is now 2.
# We then check again, and yes, i < 4, so we print 2, and set i to 3.
# We then check again, and yes, i < 4, so we print 3, and set i to 4.
# Now when we get back to the top of the while loop and check if i < 4, that check is False!
# 4 is not less than 4. So Python ends the loop, and moves on to whatever code comes next,
# in this case, printing Done.
Python has the very basics built in, but when you want to do something a bit fancier, you
might need to pull in other parts of Python. These other parts are called modules, and you
can load them so that they are accessible to your code using the import
statement. Here
are a few examples:
Here are two ways to import the same function to generate random numbers:
# This imports the whole random module.
# We'll use dot notation later to get at the individual parts of the module.
import random
# This opens an alert with a random int from 1-100, different each time!
alert( random.randint(1,100) ) # calls the randint function from the random module we imported
# But if you prefer, you can just import the one function you need from a module
from random import randint
# This opens an alert with a random int from 1-100, different each time!
alert( randint(1,100) ) # calls the randint function we imported
Here are some useful math functions:
import math
math.sqrt(25) # returns 5, the square root of 25
math.pi # returns 3.141592653589793
math.ceil(1.2) # the ceil() function just rounds up, so this returns 2
math.floor(1.8) # the floor() function just rounds down, so this returns 1
CardStock uses an event-driven model. This just means that your CardStock code runs in response to things happening. These things that happen are called events, and you will write your CardStock code as chunks of code that run when these events trigger (when they happen). Each type of CardStock object can respond to a specific set of events.
For example, buttons respond to an on_click() event. So if you want an alert
to pop up and say "Hello" when a user clicks your button, you can just put
alert("Hello")
into the on_click() event for that button.
All CardStock objects respond to an on_setup() event, that triggers when that object is first created, each time the stack runs. This can be a good place to put setup code, like setting the initial value of a variable, importing a module, or defining functions you'll use later.
Card objects respond to the on_key_press(), on_key_hold(), and on_key_release() events, so you can add your own code to do stuff when a keyboard key is pressed, or held down, or released.
Each event runs as a functions that includes relevant arguments. All events
include the self
argument, which holds the cardstock object that
the event was triggered for. So for on_setup(self), self refers to the object
that is being set up. But many events include more information, like
on_mouse_move(self, mouse_pos) which includes the new mouse position on the card.
And on_key_press(self, key_name) includes an argument variable holding a string
telling you what key was just pressed.
For more info on all the types of events that can be triggered for each of the CardStock object types, check out the Reference guide.
And to see an example of putting a complete, simple stack together, look through the Dice Tutorial.
Python is an extremely rich language, with tons more to learn about, including other useful built-in types (dictionary, bytes), tons of modules, both built-in and installable (random, os, sys, file, json, requests), error handling (try except), and cool tricks to build lists in interesting ways (list comprehension). But this should already be enough to get you started!