Reading: Apply script language syntax and concepts

Apply script language syntax and concepts

Contents:

Data types

Numerical types

The string data type

Data structures

Functions

Objects and methods

Code libraries

Interfacing with the operating system

Summary

Data types

All practical programming languages need to deal with different ‘types’ of data. For example:

Integers like 1, 2, -10 are used to count things, or for simple integer arithmetic:

seconds_since_midnight = 32334

Numbers like 1.23 are used for engineering or commercial calculations:

purchase_price = 34.99

Often we need to store text:

address = ‘26 Mount Street’

Boolean values can represent whether some condition is True or False:

high_temperature_alarm = True

Sometimes we need to store multiple items

shopping = [‘eggs’, ‘newspaper’, ‘coffee’]

Sometimes we want to store a range of information about the same thing:

patient.name = ‘Fred Bloggs’
patient.age = ‘34’
patient.condition = ‘diabetes’

In the study of programming languages, the notion of a data type is very central. The types of a language determine what sorts of values can be used in a program, and the legal operations that can be performed.

For example, two of the basic data types in Python are:

  • Integer
  • String

This means that we can use values of these types, and assign them to variables. In the example below, the variable "city" is initialised with a string, and the variable "year" contains an integer:

city = 'Sydney'# city currently holds a string

year = 2006# year contains an integer

Note that the type defines what operations are legal. So we can use the addition operator on integers:

print year + 1# will print 2007

But if we try to add an integer to a string, a runtime error will result:

print 'abc' + 1# gives a type error

The error printed will be something like:

TypeError: cannot concatenate 'str' and 'int' objects

The various operator symbols like ‘+’ and ‘*’ may have different meanings for different types. For example, the ‘+’ operator can be used to combine two strings, but the meaning is concatenation (joining strings) rather than numerical addition:

print 'abc' + 'def'# will print abcdef

Similarly, in Python it is legal to ‘multiply’ a string by an integer, but the meaning is of course different from numerical multiplication. The code below will print the string ‘abcabcabc’, in other words, three copies of ‘abc’ joined together:

my_str = 'abc'

my_int = 3

print my_str * my_int

In addition to the built-in types, most languages also allow the programmer to create abstract data types of their own, and define operations upon them. This is one aspect of object-oriented programming.

Dynamic versus static typing

Some languages such as C++ and Java are statically typed, which means that the types of all variables must be stated when the variable is defined. For example:

int k; // create an integer called k

Note that this means that the variable itself is given a type, so that we cannot now go:

k = 'abc';// error - k can only hold integers

Python and most other scripting languages are dynamically typed, which means that variables do not have a fixed type. The type of a variable at any time is determined by the type of the value it contains. So in Python it is perfectly legal to assign different types to the same variable during the program:

k = 2# k contains an integer

k = 'abc'# k contains a string

k = True# k contains a Boolean

Dynamic typing has the advantage of convenience in that you don’t have to define every variable first, and it gives more flexibility and generality. On the other hand, static typing allows the compiler to detect type errors at compile time, and helps to prevent bugs caused by incorrect types.

Note that the trivial example above is not a good example of the advantages of dynamic typing. To use the one variable for different purposes during a program is bad practice. Here is an example that gives some idea of the real flavour of dynamic typing, and its advantages for rapid development. Don’t worry if you don’t understand it in detail:

myList = [1, 'abc', True, 1+3j, ('abbot', 'costello')]

for thing in myList:

print thing

The list called myList contains 5 different types of things. Each of these values is assigned to variable ‘thing’ in turn, and printed.

For more information about data types, start at the Wikipedia article ‘Type Systems’.

Numerical types

Consider the Python code below:

x = 2

y = 2.0

z = x + y

There is quite a lot going on behind the scenes in this example when the code is interpreted:

  • The Python interpreter ‘understands’ that 2 is a number, specifically an integer, and it has a way to represent integers in binary.
  • The interpreter allocates a place in memory to put the variable ‘x’.
  • The variable x has to hold an integer value, so its type is integer in this case.
  • The interpreter will represent the number 2.0 differently to 2, in a format called ‘floating point’, which allows non-integer decimal values to be stored.
  • Thus variable y must be of type floating point, so it can hold the value 2.0
  • The interpreter must know how to add the values in x and y. In this case, the integer value in x is first converted to a floating-point value, then the two values are added together to give the new floating-point value 4.0.
  • This new value is then stored in z, which must be a floating-point type.

Some languages like Pascal, ADA, and Java are known as ‘strongly typed’ languages. This entails a few things, including:

  • Variables must be declared to be of a particular type before they are used.
  • Only data of the specified type can be stored in a variable.
  • Conversions between types (for example integer and floating point) must be explicit. The compiler or interpreted will not make any guesses about what you want to do.

Scripting languages may allow data of different types to be stored in the same variable. To do this, the interpreter determines and redefines the type of a variable based upon the type of the data being stored.

Most scripting languages are ‘dynamically typed’. This means that they will make decisions at run-time about automatic type conversions and so on. So for example, Python will allow expressions such as:

x = 1 # x is an integer with value 1

x = x + 0.23 # x is now a floating point 1.23

x = str(x) + 'abc' # x is now the string '1.23abc'

A note about the division operator in Python

What do you think will be printed by the following python code?

print 4 / 2# result is 2

print 5 / 2# result is 2

The first answer is 2 (as you might expect), but the second answer is also 2 (you may not have expected this). What is happening here is called ‘integer division’, which means the quotient and remainder type division you would have learnt in school. This happens because both numbers are integers. If we want to get a floating point result, we must make one of the numbers a floating point number as shown below:

print 5 / 2.0# prints 2.5
print 5.0 / 2# prints 2.5

print float(5) / 2# explicit conversion - prints 2.5

Now the above behaviour is quite familiar to programmers, but it can cause lots of problems for beginners. Therefore the designers of Python have decided to change this behaviour in the near future. In the next version of Python, the operation 2/5 will produce a floating point number, and if you really want integer division, you will have to use a new operator ‘//’ like this:

print 5//2# new integer division operator (prints 2)

For more details on numeric types and expressions supported by Python, see:

  • The Python Tutorial  3 Informal Introduction  3.1.1 Numbers
  • Non-Programmer's Tutorial  Hello, World  Expressions
  • Python Library Reference  2.3 Built-in Types  2.3.4 Numeric Types

The string data type

Strings are text data made up of a sequence of characters. A string is declared by enclosing the characters in quotation marks.

For example, here we make a variable called country, and assign to it the string ‘Australia’:

country = 'Australia'

Python strings can use either single quotes (‘) or double quotes (‘).This allows us to have single quotes, (or apostrophes) inside a string by enclosing the string in double quotes, and vice-versa:

script = 'Jan said "Hello" and "Welcome" '

saying = "It's a mad world, that's for sure"

Here are some typical operations we perform with strings. We can print this string in the same way as a number:

print country

To find the length of a string, use the len() function.

myString = 'abcd'
length = len(myString)
print length # prints 4

We can concatenate strings by using the ‘+’ operator. To concatenate means to form a longer string by placing one string after another. Note that this operation is very different to adding two numbers. The interpreter knows the type of any variable or expression, so it knows which operation to perform.

str1 = 'Hello'
str2 = 'World'
str3 = str1 + ' ' + str2
print str3# will print 'Hello World'

Parts of strings can be accessed using indexing or slices. For example:

str = 'The rain in Spain'
print str[0] # will print 'T'
print str[4]# will print 'r'

print str[1:5]# will print 'he r'

To check whether a string contains an occurrence of some other string, we can use the find method. This method returns the index at which the other string begins:

str = 'The rain in Spain'
location = str.find('Spain')
print location # prints 12

There are many more methods that can be applied to strings. For more information about strings, see:

  • The Python Tutorial  3 Informal Introduction  3.1.2 Strings
  • Non-Programmer's Tutorial  Hello, World
  • Non-Programmer's Tutorial  Revenge of the Strings
  • Python Library Reference  2.3 Built-in Types  2.3.6 Sequence Types

Data structures

Data structures allow us to collect different data values together in a unified structure.

The most important Python data structures are lists and Dictionaries.

Lists

Python lists are somewhat like arrays in Java, but more flexible. We can store different types of values in a list, and the list can grow in size as we add more items.

Python lists allow us to store multiple data items in one place. Strings, numbers and other data objects can be elements of the same list. The following example defines a list with 4 elements; the first two are strings and the last two are numbers.

myList = ['spam', 'eggs', 100, 1234]

To access individual elements in a list, an index is used. The following prints the third item (the number 100) in the list. Note that the first item has index 0.

print a[2]# print 100

Lists can have items added to the end of them using the append function, or by using the ‘+’ operator with a second list.

groceries = ['apples', 'eggs']
groceries.append['spam']
# groceries now contains ['apples', 'eggs', 'spam']
groceries += ['bread', 'sugar']
# groceries now contains:

#['apples', 'eggs', 'spam', 'bread', 'sugar']

For more information about Python lists, see:

  • The Python Tutorial  3 Informal Introduction  3.1.4 Lists
  • The Python Tutorial  5 Data Structures  5.1 More on lists
  • Dive Into Python  3 Native Datatypes  3.1 Introducing Dictionaries
  • Non-Programmer's Tutorial  Dictionaries
  • Python Library Reference  2.3 Built-in Types  2.3.6 Sequence Types

Dictionaries

Dictionaries are sometimes called ‘associative arrays’ or ‘hashes’. The idea is that each value we place in the dictionary has an associated key. For example, let’s say we want to store the telephone numbers of friends, and be able to find a number using the name of the friend. This is simple with a dictionary—we simply use the names as the keys, and the phone numbers as the values to store.

# define an initial phone list

phoneList = { 'jack':23445, 'jill':12334, 'mack':56778 }

# add a new number

phoneList['Sara'] = 56678

# retrieve a number

print phoneList['jack']

# print phoneList.keys()
# print phoneList.values()

The above code will print:

23445

['Sara', 'jill', 'mack', 'jack']
[56678, 12334, 56778, 23445]

Note that the keys and values in the dictionary are not stored in any particular order. All that matters is that you can retrieve the value associated with any particular key.

For more information about Python dictionaries, see:

  • The Python Tutorial  5 Data Structures  5.4 Dictionaries
  • Dive Into Python  3 Native Datatypes  3.1 Introducing Dictionaries
  • Non-programmer's Tutorial  Dictionaries
  • Python Library Reference  2.3 Built-in types  2.3.7 Mapping Types

Functions

Computer algorithms are easier to understand and implement if they are broken down into manageable, meaningful parts. The idea is that we will write a block of code, and give it a name, so that we can execute this block of code just by mentioning the name somewhere else in the program. In Python we call this block of code a ‘function’, and when we execute the function by mentioning its name, we say that we are ‘calling’ the function.

Below is a simple example of a function that prints two lines. Note that the def keyword indicates the beginning of a function definition:

def lumberJackChorus():
print "I'm a lumberjack and I'm OK"
print 'I sleep all night and I work all day'

Whenever we want to print those lines, we simply call the function like this:

lumberJackChorus()

Note that we can call the function from anywhere in our program, and as many times as we like. A function like this has the advantage that we can simplify our code. Whenever we need to print the chorus, we simply call this function as shown.

We can pass values to functions

You probably noticed that the function definition above, and the call, used parentheses after the function name with nothing in between, like this: lumberJackChorus(). You always need these brackets when defining or calling a function.

Usually however, the brackets will not be empty but will contain a list of input values for the function to work with. Here is an example (note that the backslash ‘\’ at the end of the fourth line just allows us to continue the statement on the next line.):

# lumberjack chorus with parameters

def lumberJackChorus(dayTimeActivity, nightTimeActivity):

print "I'm a lumberjack and I'm OK"

print 'I ' + nightTimeActivity + ' all night' \

+ and I ' + dayTimeActivity + ' all day'

# different versions of the chorus

lumberJackChorus('work', 'sleep')

lumberJackChorus('sleep', 'party')

Now, we have a more useful chorus function, because we can modify the day time and night time activities of our lumberjack! So the first call to our function will print:

I'm a lumberjack and I'm OK

I sleep all night and I work all day

But the second will print:

I'm a lumberjack and I'm OK

I party all night and I sleep all day

Let's have a closer look at what is happening here. The first line of the function definition defines two 'formal parameters', dayTimeActivity and nightTimeActivity. These parameters are much like variables that will be initialised when the function is called.

def lumberJackChorus(dayTimeActivity, nightTimeActivity):

So when the function is called like this:

lumberJackChorus('work', 'sleep')

...the parameter dayTimeActivity will be a string with value 'work', and the parameter nightTimeActivity will be a string with value 'sleep'. These parameters are used within the function to print the appropriate value.

Functions can return a value

Not only can we pass values to a function as parameters, but a function can return values back to the ‘place’ where it was called. The classic examples of this are the math functions such as sin, or sqrt (square root), or abs (absolute value). So for example, we can calculate the square root of four by using:

# The sqrt function is found in the math module,
# so first we need to import it at the top of our program
from math import sqrt

# now print the square root of 4

print sqrt(4.0)

In this example, the sqrt function has accepted the value 4 and will return the value 2.0, which will in turn be printed by the print statement. Note the effect of the line:

print sqrt(4.0)

is just as if we had written:

print 2.0

Now let's write our own function that returns a value.

# add three to any number

def addThree(x):

return x + 3

The return statement returns (sends back to the caller) a result. In this case, the result returned is simply a number that is three more than the parameter x. So for example if we call the function like this:

print addThree(5)

...then the value printed will be 5 + 3 = 8.

Note that the effect of this call is the same as if we had written '8' instead of 'addThree(5)'. The expression 'addThree(5)' has the value 8. Thus we can use function calls just like any other variable in an expression. Here is another example using our addThree function:

a = 2

b = addThree(a)

print 'a =', a, ' b =', b

In this case, the value of variable 'a' (that is, 2) is passed to the function, and the value 2+3=5 is returned. This value is then assigned to variable 'b'. So at the end of this code, 'a' has the value 2, and 'b' has the value 5. Note carefully that the value of variable 'a' is not changed by the function. If we want to modify the variable 'a', we would need to go:

a = addThree(a)

Functions can contain arbitrary code

So far, we have just shown some very simple calculations within a function. By you can define variables, and put any statements you like inside the function. You can even define more functions inside a function if you need to!

Let’s look at a few more examples of functions. The example below defines a function that finds the maximum of two numbers. Here we have used an if-statement to check which of the two parameters is largest.

# find the maximum of two numbers

def maximum(a, b):

if a > b:

return a

else:

return b

print 'The maximum of 3 and 4 is:', maximum(3, 4)

For more information about functions, see:

  • The Python Tutorial  4 More control flow tools  4.6 Defining functions
  • Non-programmer's Tutorial  Defining functions

Objects and methods

The most significant development in programming practice in the last decade is the widespread adoption of object-oriented programming. This unit does not cover the details of object-oriented programming, however most modern scripting languages do support object-oriented programming.