At this point we need to pause and look a little more carefully at how Sage works with Python. Python is a modern offtheshelf scripting language that is very friendly to Scientific Computing and to Object Oriented Programming (OOP). Python's support for OOP is absolutely essential for Sage's goal of integrating different Open Source Math packages.
This first example illustrates Pyhton's basic control flow. The example contains a while loop with an ifthenelse case statement. For at least 3 decades good programming practice has strongly suggested that you indent your code to reflect its logical block structure. With Python this is no longer a suggestion. There are no beginends or other bracketing notation. As a reward for proper indenting, you get shorter programs. Also note that = is the assignment operator, == is the relational operator for equality, % is the mod operator.

Python has a for clause that walks through a list. It also has a function for generating lists of integers, called range.
Python also indexes the world starting at zero.


Python defines functions with the def command.


Python has three builtin data structures: list, tuple, and dictionary.
A list in Python is entered and displayed with square brackets. When Python indexes into a list it starts at 0, and the index is specified with square brackets. When indexing into a 2dimensional list, Python uses two separate indices. The first index indicates which list in the list of lists, and the second index indicates which element in that list.

Python provides a number of "slicing" operations

Python does not deal directly with matrices, although Sage definitely does. In Python adding two lists is just concatenation.

In the last example A+B is a list consisting of 6 elements the first 4 elements are numbers and the last two elements are lists.
Lists in Python are very general collections. In Python we can walk through a list in 3 different ways.




We can change the items in a list.

Python has a very flexible initialization construction, called list comprehension. It mirrors the way we typically define a set in mathematics.

Even trickier constructions are possible by adding a conditional phrase.

Suppose that we want to construct the list of the Fibonacci numbers that are less than 100.
The following Python code will do the job.

The second builtin Python data structure is the tuple. It is just like a list except that it gets set up with parentheses instead of square brackets. Tuples are different from lists in that they are immutable  they can not be changed. Think of them as read only data structures.


Beware! Although the tuple can not be changed it is possible that some of the elements of the tuple can be changed.

While the list is enclosed with square brackets and the tuple is enclosed with parentheses, the dictionary is enclosed with curly braces. The dictionary also provides arbitrary keys in lieu of indexing, although the notation is similar. A dictionary is a list of pairs. The first member of each pair is the key, and a key can only occur once in a dictionary. The key is followed by a colon and the value, the second item of the pair. Keys must be unique and immutable, but otherwise they are completely arbitrary. The values are totally arbitrary.



Sage makes extensive use of Python classes. The type command tells us the name of the class of an object.
Integers are a particularly interesting case.






This example underscored the fact that the single "=" is assignment and the double "==" is equality.
It also showed that multiple statements can be on the same line when separated by ";"

In this example, the solution is returned in a list. Lists are the primary data structure workhorse. However, we can also have the solution(s) returned as a list of dictionaries which provides access by name.

Python's support of Object Oriented Programming provides Python with the possibility of accomplishing many more tasks than Matlab. As an example, we can look at Sage's use of matrices. We will start by generating some random matrices of integers.



Use tab completion to see what A knows how to do. In OOP the functions that belong to an object are called methods. Experiment with different methods. In Sage you can create matrices over any ring. Of course, some of the methods will vary depending on the ring.

To create your own objects, you define the class that those objects would belong to and the methods that it allows. Here are examples of three extremely important Data Structures  Stacks, Queues, and Priority Queues.
The following block defines a stack class with five methods  push, pop, peek, clear, and display. There is also an initialization method, __init__, which is invoked whenever a Stack object is created. This method insures that the stack owns an empty list, _s. Using an underscore as the first letter in the name of a variable is a Python technique for indicating that it is a private variable.




The following block defines a queue class with two methods  enqueue and dequeue. However, instead of following the Stack class approach and having this own a private deque object, this queue is a subclass of the deque class. So this queue object is a deque. One consequence is that this queue object will inherit the methods of the deque class. This can be confirmed with the tab completion in the block following the definition of the Queue class.

deque([]) deque([]) 
A priority queue is a container where each item is inserted with a certain priority. When items are removed, the item with the highest priority is the item that is removed. Priority queues can be implemented using a heap. A heap is a Complete Binary Tree with a partial ordering. A complete binary tree is a binary tree where the tree is filled out from top to bottom, left to right. To be a heap, the complete binary tree must satisfy the following partial ordering criteria.
The priority of the parent must always be equal to or higher than the priority of its children.
This is often referred to as the heap property. The heap property is an invariant which must be true before and after pushing or popping an item.
There is a natural embedding of a complete binary tree into an array using the functions
