Python has some different ways to use strings, numbers, and lists.
Strings
A string is a sequence of characters.
In Python, a string is enclosed in quotation marks, double or single. Additionally, Python includes a "multiline" string feature, so that a string can span multiple lines. Thus all of the following are Python strings:
"Hello World!"
'Hello World!'
"""Hello, World!
How are you today?"""
'''Hello, World!
How are you today?'''
In Scratch, strings are represented with text inputs. Text inputs are white and rounded:
say [Hello World!] think (join [Hello, ] [World!])
Often, one needs to combine two strings together (known as concatenation). In Python, string concatenation is done with the +
operator:
>>> "apple" + "banana"
'applebanana'
In Scratch, it is accomplished with the (join [string1] [string2])
block - (join [apple] [banana])
reports "applebanana".
Another common operation done on strings is to get its length, or the number of characters in the string. In Python, the built-in len(obj)
function gets the length of anything that has a length:
>>> len("Hello World!")
12
In Scratch, the self-explanatory (length of [string])
block is used - (length of [Hello World!])
reports "12".
Yet another need from a string is to get a character at a specific position. For example, the 3rd character of "Hello World!" is "l". Or, in more formal terms, the character at index 2 is "l". Note the difference here. Python, as a language, is 0-indexed. This means that the first thing in a sequence is indexed at 0. Therefore, "H" is at index 0 in "Hello World", "e" is at index 1, and so on. Scratch, as a language, is 1-indexed. This means that the first thing in a sequence is indexed at 1.
To access a character at a certain index of a string, Python uses a syntax called subscription. The syntax is to add square brackets enclosing the index after the object. To get the 3rd letter of the string "Hello World":
>>> "Hello World!"[2]
'l'
To access a character at a certain index of a string, Scratch simply uses the (letter () of [])
block. (letter (3) of [Hello World!])
reports "l".
Python-Only Features
Python strings have multiple features that Scratch does not.
- Getting a certain range of characters (also called slicing):
>>> "Hello World!"[3:6]
'lo '
- Capitalization methods:
>>> "Hello World!".upper()
'HELLO WORLD!'
>>> "Hello World!".lower()
'hello world!'
>>> "Hello World!".capitalize()
'Hello world!'
>>> "hello world!".title()
'Hello World!'
- Replacing substrings with other strings:
>>> "Hello World!".replace("Hello", "World")
'World World!'
- Finding the index of a substring in a string:
>>> "Hello World!".find("W")
6
Numbers
In Python, there are three types of numbers: integers (int
), floating-point numbers (float
), and complex numbers (complex
). An integer is represented as a sequence of base-10 digits, e.g. 1024
; a floating-point number is represented as a sequence of base-10 digits, with the decimal point as a dot, e.g. 3.14
; a complex number is represented as an integer or float (the "real" part), the plus sign, another integer or float (the "imaginary" part), then the letter J, all in parentheses, e.g. (1+5j)
In Scratch, integers and floating-point numbers are represented the same way:
repeat (5) wait (1.5) seconds
Scratch does not support complex numbers.
Both languages support the basic arithmetic operations:
((1) + (1)) // 2 ((1) - (1)) // 0 ((2) * (2)) // 4 ((2) / (2)) // 1
>>> 1 + 1 #sum of 1 and 1
2
>>> 1 - 1 #difference between 1 and 1
0
>>> 2 * 2 #product of 2 and 2
4
>>> 2 / 2 #quotient of 2 and 2
1.0
(respectively)
Both languages also have slightly more complex mathematical operations:
([floor v] of ((5) / (2))) // 2 ((5) mod (2)) // 1 (() - (5)) // -5 (() + (5)) // 5 ([abs v] of (-5)) // 5 (round (5.5)) // 6
>>> 5 // 2 #floored quotient of 5 and 2
2
>>> 5 % 2 #remainder of 5 / 2
1
>>> -5 #negative 5
-5
>>> +5 #unchanged 5
5
>>> abs(-5) #absolute value of -5
5
>>> round(5.5) #5.5 rounded off
6
(respectively)
Both languages also have much more complex mathematical operations:
([floor v] of (5.5)) // 5 ([ceiling v] of (5.4)) // 6 ([sqrt v] of (4)) // 2 ([sin v] of (30)) // 0.5 ([cos v] of (60)) // 0.5 ([tan v] of (45)) // 1 ([asin v] of (0.5)) // 30 ([acos v] of (0.5)) // 60 ([atan v] of (1)) // 45 ([ln v] of (5)) // 1.6094379124341003 ([log v] of (10)) // 1 ([e ^ v] of (2)) // 7.3890560989306495 ([10 ^ v] of (2)) // 100
>>> import math
>>> math.floor(5.5) #floor of 5.5
5
>>> math.ceil(5.4) #ceiling of 5.4
6
>>> math.sqrt(4) #square root of 4
2.0
>>> math.sin(math.radians(30)) #sine of 30 degrees. The Python math module's trigonometric functions use radians, so degrees must be converted to radians first.
0.49999999999999994 #close enough to 0.5, this inaccuracy is due to decimal imprecision
>>> math.cos(math.radians(60)) #cosine of 60 degrees
0.5000000000000001 #close enough to 0.5
>>> math.tan(math.radians(45)) #tangent of 45 degrees
0.9999999999999999 #close enough to 1
>>> math.degrees(math.asin(0.5)) #arcsine of 0.5. The Python math module's arc-trigonometric functions return radians, so it must be converted to degrees.
30.000000000000004 #close enough to 30
>>> math.degrees(math.acos(0.5)) #arccosine of 0.5
60.00000000000001 #close enough to 60
>>> math.degrees(math.atan(1)) #arctangent of 1
45.0
>>> math.log(5) #natural logarithm of 5 (i.e. logarithm of 5 in base e)
1.6094379124341003
>>> math.log10(10) #logarithm of 10 in base 10
1.0
>>> math.e ** 2 #e raised to a power
7.3890560989306495
>>> 10 ** 2 #10 raised to a power
100
(respectively)
Python-Only Features
Python has some additional operations:
>>> int(5.5) #convert 5.5 to a whole number
5
>>> float(5) #convert 5 to a floating-point number
5.0
>>> complex(1, 5) #create a complex number with real part 1 and imaginary part 5
(1+5j)
>>> (1+5j).conjugate() #conjugate of the complex number (1+5j)
(1-5j)
>>> divmod(5, 2) #the quotient and remainder of 5 / 2
(2, 1)
>>> 2 ** 4 #2 to the 4th power
16
>>> pow(256, 65536, 6) #256 to the 65,536th power, but then the remainder of that divided by 6
4
>>> 6 | 3 #bitwise OR of 6 and 3 (bitwise operations explained later)
7
>>> 6 ^ 3 #bitwise XOR of 6 and 3
5
>>> 6 & 3 #bitwise AND of 6 and 3
2
>>> 6 << 3 #6 bit-shifted to the left by 3 bits
48
>>> 6 >> 3 #6 bit-shifted to the right by 3 bits
0
>>> ~6 #6 bit-flipped
-7
Bitwise operations are a special feature of computers using binary to represent everything. The number 6 in binary is 110
. 3 in binary is 11
. Keeping this in mind, the bitwise operations are explained as follows:
- OR
Combine the two numbers' respective bits. If either of the two respective bits is 1, the resultant bit will be 1; otherwise, it is 0. Following this:
110 (6) 011 (3) --- 111 (7)
- XOR
Combine the two numbers' respective bits. If exactly one of the two respective bits is 1, the resultant bit will be 1; otherwise, it is 0. Following this:
110 (6) 011 (3) --- 101 (5)
- AND
Combine the two numbers' respective bits. If both of the two respective bits are 1, the resultant bit will be 1; otherwise, it is 0. Following this:
110 (6) 011 (3) --- 010 (2)
- Bit-shifting
Bit shifting means to simply move all of the bits of a number in a certain direction. 6 in binary is 110|
(anything to the left of the |
is part of the number; anything to the right is not).
6 bit-shifted once to the left: 1100|
(12). 6 bit-shifted 3 times to the left: 110000|
(48).
6 bit-shifted once to the right: 11|0
(11
is 3). 6 bit-shifted 3 times to the right: |110
(no more digits on the left of the |
, so it's 0).
- Bit-flipping
Bit flipping means to convert a 1 bit to a 0 bit, and vice versa. Because of the way negative numbers are stored, in this use case the number 6 is represented as 0000 0110
in 8-bit binary. Flipping all of the bits:
0000 0110 (6) --------- 1111 1001 (-7)
Here, the first bit tells the program whether the number is positive or negative - 0 meaning positive, 1 meaning negative. What this ends up meaning is that ~x
(bit-flipped x) is equal to -x - 1
(negative x minus 1)
Lists
Both Python and Scratch include lists. However, their implementations of lists differ in the extreme.
In Python, a list is simply another kind of value that can be assigned to a variable. A list is created using square brackets, separating each list item with a comma:
["a", "b", "c"]
In contrast, Scratch requires that all lists be created beforehand, and it additionally treats lists as a different concept from variables entirely. There is also no "list" input; instead, there are various blocks dealing with the manipulation of lists. However, both languages support the same basic set of list operations:
- Adding an item to the end of a list
In Python, lists have an "append" method used to add an item to the end.
>>> mylist = ["a", "b", "c"]
>>> mylist.append("d")
>>> mylist
['a', 'b', 'c', 'd']
In Scratch, the add [item] to [list v]
block accomplishes this - after adding an item, the list now has that item at the end.
- Accessing an item at a position of a list
A Python string is very much like a list of characters, so they both use the same syntax for accessing items.
>>> mylist = ["a", "b", "c"]
>>> mylist[1]
'b'
(Keep in mind that Python is 0-indexed - the first item is index 0.) In Scratch, the (item (1) of [list v])
block is used for this specific purpose. (Do note that Scratch is 1-indexed!)
- Getting the length of a list
The Python method is simple - the same len(obj)
method can be used on lists as well as on strings.
>>> len(["a", "b", "c"])
3
Scratch, in turn, provides the (length of [list v])
block for this purpose.
- Checking if a list contains an item
Python has a concise way of checking membership: the "in" operator.
>>> "b" in ["a", "b", "c"]
True
Scratch provides the <[list v] contains [thing]?>
block for this purpose.
- Replacing an item at a certain position
In Python, list items can be modified using the same target used to get them:
>>> mylist = ["a", "b", "c"]
>>> mylist[1] = "d"
>>> mylist
['a', 'd', 'c']
Scratch provides the replace item () of [list v] with [thing]
block for this purpose.
- Inserting an item at a certain position
Python provides an "insert" list method to insert items:
>>> mylist = ["a", "b", "c"]
>>> mylist.insert(1, "d")
>>> mylist
['a', 'd', 'b', 'c']
Scratch provides the insert [thing] at () of [list v]
block for this purpose.
- Deleting an item at a certain position
Python has a keyword, "del", that deletes names in general. It can be applied to the same syntax used to get list items:
>>> mylist = ["a", "b", "c"]
>>> del mylist[1]
>>> mylist
['a', 'c']
Scratch provides the delete () of [list v]
block for this purpose.
- Going through each list item in turn
In Python, a list is merely one kind of iterable. The following syntax can be applied to all iterables:
for name in iterable:
# name is now an item of the iterable
For example:
>>> for i in ["a", "b", "c"]:
print(i)
a
b
c
(It is a custom to use i
, j
, or k
for iteration names.)
In Scratch, it is much less simple. For starters, an extra variable needs to be made to keep track of what position in the list that the script is at. The full method is below:
set [i v] to [0] repeat (length of [list v]) change [i v] by (1) say (item (i) of [list v]) // "item i of list" is now the equivalent of "i" in the Python example. end