{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "
\n", "
\n", "Math 301: Permuation Puzzles
\n", "Appendix A: SageMath Introduction

\n", " Dr. J. Mulholland
\n", " Department of Mathemtics, SFU\n", "
\n", "\n", "
\n", "
    \n", "
  1. Introduction
  2. \n", "\n", "
    \n", "
  3. Variables and Statements
  4. \n", "\n", "
    \n", "
  5. Lists
  6. \n", "\n", "
    \n", "
  7. Sets
  8. \n", "\n", "
    \n", "
  9. Commands and Functions
  10. \n", "\n", "
    \n", "
  11. if, while and for statements
  12. \n", "\n", "
    \n", "
  13. Exercises
  14. \n", "
\n", "\n", "\n", "
\n", "
\n", " 1) Introduction\n", "
\n", "
\n", "Ted Kosen, author of *Sage For Newbies*, describes Sage as follows:\n", "\n", "
Sage is an open source mathematics computing environment for performing symbolic, algebraic, and numerical computations. Mathematics computing environments are complex, and require a significant amount of time and effort to become proficient at using one. It will take a beginner a while to become an expert in using SAGE, but fortunately one does not need to be a SAGE expert in order to begin using it to solve problems.
\n", "\n", "This is precisely the viewpoint we will take in this course. We will not attempt to become Sage experts, we will however us it to solve problems. In particular, problems regarding permutation puzzles.\n", "\n", "A mathematics computing environment is a collection of computer algorithms, and data structures, that are built on top of a programming language. This means one has access to a full programming language, in SageMath's case it is Python, and further access to a mathematical objects library complete with algorithms for performing calculations.\n", "\n", "Rather than say anything more about what SageMath is, let's just see for ourselves what it can do.\n", "\n", "\n", "We can use it like a calculator to add/subtract/multiply/divide numbers.\n", "\n", "Put your cursor in the code block below and either press [shift-enter] or click \"run cell\" (play button) in the menu at the top of the page." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "7" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "2+5" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "When typing input, [enter] will jump you down to the next line, [shit-enter] will evaluate the code-block.\n", "\n", "A bit of terminology:
\n", "What is typed in a cell is called the **source code**.
\n", "When the cell is executed, what SageMath prints to the screen is called the output.\n", "\n", "So \"2+5\" in the cell above is the source code, and \"7\" is the output.\n", "\n", "
\n", " 1.1) Arithmetic Operations\n", "\n", "\n", "| operation | syntax |\n", "|--------------|---------|\n", "| addition | + |\n", "| subtraction | - |\n", "|multiplication| * |\n", "|division | / |\n", "|remainder | % |\n", "|exponents | ^ or ** |\n" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "31/5" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "3+2/5*2^3" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "8" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "2^3" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "8" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "2**3" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1953125" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "5^3^2" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "11%4" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As you can see, SageMath follows the usual order of operations: \n", "\n", "* first evaluate exponents from right to left,\n", "* then multiplication, division, and remainder from left to right \n", "* finally, addition and subtraction from left to right.\n", "\n", "You can change the order in which expressions are evaluated by using parenthesis: ( )." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### For you to try:\n", "\n", "Try some of your own calculations in the cell below." ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# type your commands here" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "
\n", " 1.2) Inserting a New Cell\n", "
\n", "
\n", "\n", "A new cell will automatically appear below the last cell of your sheet when the contents of the last cell have been evaluated (a cell is an input line).  Sometimes, however, we would like to add a new cell in the middle of our worksheet.  To insert a new execution shell in the worksheet, you can use the \"+\" tool in the tool bar at the top. This will insert a cell below the currently selected cell.\n", "\n", "If you just want to add a cell, or a bunch of cells, at the end of the worksheet, just select the last cell and hit shift-enter to add a new cell." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### For you to try: \n", "\n", "Add a new cell below this cell. Also, add a new cell above it.\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "
\n", "\n", " 1.3) Working in a Cell: Enter, Shift-Enter, The Semicolon, and Comments\n", "\n", "Multiple statements can be placed on lines following each other. After typing \"1+2\", press [enter] to bring the cursor down to the next line. Type \"3-1\" on this new line. Now evaluate the commands by either pressing [shift-enter] or click \"run cell\" (play button) in the menu at the top of the page." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# type your commands here" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Notice in the two lines of code you entered above only the output of the last calculation will be displayed. To display the output of another line use the \"print\" command.\n", "\n", "The `print` command is for sending outputs to the screen. We'll see more on this in section 2.2 below.\n" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3\n" ] }, { "data": { "text/plain": [ "8" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "print 1+2 \n", "3+5" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "Semicolons \";\" can be placed after statements as optional terminators, but most of the time one will only see them used to place multiple statements on the same line.\n" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3\n" ] }, { "data": { "text/plain": [ "8" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "print 1+2; 3+5" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It will come in handy to be able to add comments directly in the source code. Comments are basically notes to yourself about what you are doing, and are not intended for the computer to execute. Anything followed by the \"#\" symbol is treated as a comment." ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "-1" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#this is a comment\n", "2-3 # and this is another comment after some code" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "
\n", "
\n", " 2) Variables and Statements\n", "
\n", "
\n", "\n", "Part of the power of a computing environment lies in the ability to store, manipulate, and recall information. This is done using \"variables\" and \"statements\".\n", "\n", "
\n", "
\n", " 2.1) Variables\n", "
\n", "
\n", "\n", "

\n", "A variable is a name that is associated with the data stored in a memory address. One way to create variables in SageMath is through assignment which consists of placing the variable you would like to create to the left of an equal sign \"=\", and the expression on the right side.\n", "

\n", "

\n", "Here we create a variable \"a\", and assign to it the number 5.\n", "

" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "a=5" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "b=7 # create a new variable b and assign 7 to it.\n", "a=3 # reassign to the variable a, the number 3." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "10" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "c=a+b # assign to the variable c the sum of a and b\n", "c # output the value of c" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "
\n", " 2.2) Statements\n", "
\n", "
\n", "\n", "Statements are the part of a programming language that are used to encode algorithmic logic.\n", "\n", "Simple statements:\n", "* **assignment**:
\n", "   a= a + 1\n", "* **call**:
\n", "   var(x), print(a+1), factor(24)
\n", "* **assumption**:
\n", "   assume(x > 0)\n", "\n", "
\n", "\n", "Compound statements\n", "* **if-statement**:
\n", "   if A>3:
\n", "       print(A-3)
\n", "   else:
\n", "       print(\"not big enough\")\n", "* **while-statement**:
\n", "   while x<= 10:
\n", "       print x
\n", "       x = x+1\n", "* **for-statement**:
\n", "   for x in [1,2,3,4,5]:
\n", "        print x\n", "\n", "We will look at `if`, `while`, and `for` statements more thoroughly later. But the odd one may creep into some of our examples below.\n", "\n", "\n", "**print**
\n", "\n", "SageMath has a statement called `print` that allows the results of expressions to be displayed regardless of where they are located in the cell.\n" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3 2\n" ] } ], "source": [ "a=3\n", "b=2\n", "print a,b" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "5 is prime\n" ] } ], "source": [ "if is_prime(5): # is_prime() is a built-in function\n", " print(\"5 is prime\")\n", "else: \n", " print(\"5 is not prime\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "
\n", " 3) Lists \n", "
\n", "
\n", "\n", "Lists are one of the most fundamental objects in any programming language. \n", "\n", "
\n", "
\n", " 3.1) Defining a List\n", "
\n", "
\n", "\n", "A list is defined by putting the items of the list, separated by commas, inside square brackets \"[ ]\".\n" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1, 2, 'milk', 'cheese', 'new shoes']" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "L=[1,2,\"milk\",\"cheese\",\"new shoes\"]\n", "L" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can select items from the list as follows. (Note: the first item in a SageMath/Python list is indexed by 0, not 1 as you may have expected.)\n" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "L[0] #select the first item (indexed by 0) from the list" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'new shoes'" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "L[4] # select the last item" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "ename": "IndexError", "evalue": "list index out of range", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mIndexError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mL\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mInteger\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m5\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;31m# what if there is no item with the index you've input\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mIndexError\u001b[0m: list index out of range" ] } ], "source": [ "L[5] # what if there is no item with the index you've input" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Order matters in a list. If items are in different orders, then the list are not equal." ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[1,2,3]==[2,1,3]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can also create a list by stating conditions we want the elements to satisfy. This usually requires starting with a bigger list, and either constructing a sublist, or constructing a new list." ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[2, 4]" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[n for n in [1,2,3,4] if is_even(n)] # selects the even integers" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[3, 5, 7, 9]" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[2*n+1 for n in [1,2,3,4]] # creates a new list of odd integers from old list" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[2, 4, 6, 7, 8, 10, 12, 14, 16, 18, 20, 21, 22, 24, 26, 28, 30, 32, 34, 35, 36, 38, 40, 42, 44, 46, 48, 49, 50, 52, 54, 56, 58, 60, 62, 63, 64, 66, 68, 70, 72, 74, 76, 77, 78, 80, 82, 84, 86, 88, 90, 91, 92, 94, 96, 98, 100]\n" ] } ], "source": [ "print [n for n in [1..100] if n%7==0 or is_even(n)]" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]\n" ] } ], "source": [ "print filter(is_prime,[1..100])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "
\n", " 3.2) List Operations: remove and append\n", "
\n", "
" ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "collapsed": true }, "outputs": [], "source": [ "L=[1,2,3]" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1, 2]" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "L.remove(3) # removes item 3 from L\n", "L" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1, 2, 4]" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "L.append(4) #adds item 4 to the end of list L \n", "L" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "len(L)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here are some more list operations. We won't really use any of them, but just in case you are curious.

\n", "list.**append(x)**
\n", "     Add an item to the end of the list.

\n", "\n", "list.**extend(L)**
\n", "     Extend the list by appending all the items in the given list.

\n", "\n", "list.**insert(i, x)**
\n", "     Insert an item at a given position. The first argument is the index of the element before which to insert, so a.insert(0, x) inserts at the front of the list, and a.insert(len(a), x) is equivalent to a.append(x).

\n", "\n", "list.**remove(x)**
\n", "     Remove the first item from the list whose value is x. It is an error if there is no such item.

\n", "\n", "list.**pop([i])**
\n", "     Remove the item at the given position in the list, and return it. If no index is specified, a.pop() removes and returns the last item in the list. (The square brackets around the i in the method signature denote that the parameter is optional, not that you should type square brackets at that position. You will see this notation frequently in the Python Library Reference.)

\n", "\n", "list.**index(x)**
\n", "     Return the index in the list of the first item whose value is x. It is an error if there is no such item.

\n", "\n", "list.**count(x)**
\n", "     Return the number of times x appears in the list.

\n", "\n", "list.**sort()**
\n", "     Sort the items of the list, in place.

\n", "\n", "list.**reverse()**
\n", "     Reverse the elements of the list, in place.

\n", "\n", "\n", "\n", "
\n", "
\n", " 3.3) Built-in Lists\n", "
\n", "
\n", "\n", "\n", "SageMath (and Python) already have some built-in lists that we can use.\n", "\n", "The `range` function, `range(a,b)`, creates the list of integers beginning with a and ending at b-1. Here we assume a is less than b.\n" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "range(1,11) # creates a list of integers from 1 to 10" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[1..10] # another way to construct the list" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can select one or multiple items from a list as follows." ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2\n", "[1, 2, 3]\n" ] } ], "source": [ "L=range(1,26)\n", "print L[1] # selects item of index 1\n", "print L[0:3] # sublist of L consisting of items indexed 0 up to but not including index 3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The items in a list can be overwritten by new items, as the following shows." ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1, 2, 3, 4]" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "L=[1,2,3,4]\n", "L" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1, 5, 3, 4]" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "L[1]=5\n", "L" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "An example of using lists to factor all integers from 1 to 10." ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1, 2, 3, 2^2, 5, 2 * 3, 7, 2^3, 3^2, 2 * 5]" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[factor(n) for n in range(1,11)]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "
\n", " 4) Sets \n", "
\n", "
\n", "\n", "\n", "Sage has a built-in `Set` type. It offers a fast lookup of whether an element is in the set or not, and it come equipped with standard set-theoretic operations: union, intersection, etc.\n", "\n", "Unlike lists, where order matters, the order of the elements in a set does not matter. All the matters is the elements themselves. So in this sense, we can think of sets as unordered lists.\n", "\n", "\n", "
\n", "
\n", " 4.1) Defining a Set\n", "
\n", "
" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{1, 2, 3}" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Set([1,2,3]) # here we turn the list [1,2,3] into a set" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Set([1,2,3])==Set([2,1,3]) # order doesn't matter in a set" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100}" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Set(range(1,101)) # using the range list to construct a set" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Another way to construct the same set:" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100}" ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Set(1..100)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can construct sets by specifying conditions on the elements, much like we did with lists." ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{8, 2, 4, 10, 6}" ] }, "execution_count": 40, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Set(x for x in range(1,11) if is_even(x))" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48}" ] }, "execution_count": 43, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Set(x for x in range(1,51) if x%3==0) # integers divisible by 3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There is also a `filter` command for selecting elements satisfying some special condition. Here we select the prime numbers." ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[2, 3, 5, 7, 11, 13, 17, 19]" ] }, "execution_count": 44, "metadata": {}, "output_type": "execute_result" } ], "source": [ "S=Set(1..20)\n", "filter(is_prime,S)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "
\n", " 4.2) Set Operations\n", "
\n", "
\n", "\n", "We have all the usual set operations available." ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 50, "metadata": {}, "output_type": "execute_result" } ], "source": [ "S=Set([1,2,\"milk\"])\n", "\"milk\" in S # we can use \"in\" to check if an element is in a set" ] }, { "cell_type": "code", "execution_count": 51, "metadata": { "collapsed": true }, "outputs": [], "source": [ "A=Set([1,2,3,4]); B=Set([3,4,5,6]);" ] }, { "cell_type": "code", "execution_count": 52, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "4" ] }, "execution_count": 52, "metadata": {}, "output_type": "execute_result" } ], "source": [ "A.cardinality()" ] }, { "cell_type": "code", "execution_count": 53, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 53, "metadata": {}, "output_type": "execute_result" } ], "source": [ "3 in A" ] }, { "cell_type": "code", "execution_count": 54, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 54, "metadata": {}, "output_type": "execute_result" } ], "source": [ "6 in A" ] }, { "cell_type": "code", "execution_count": 55, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{1, 2, 3, 4, 5, 6}" ] }, "execution_count": 55, "metadata": {}, "output_type": "execute_result" } ], "source": [ "A.union(B)" ] }, { "cell_type": "code", "execution_count": 56, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{3, 4}" ] }, "execution_count": 56, "metadata": {}, "output_type": "execute_result" } ], "source": [ "A.intersection(B)" ] }, { "cell_type": "code", "execution_count": 57, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{1, 2}" ] }, "execution_count": 57, "metadata": {}, "output_type": "execute_result" } ], "source": [ "A.difference(B)" ] }, { "cell_type": "code", "execution_count": 61, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "The Cartesian product of ({1, 2, 3, 4}, {3, 4, 5, 6})" ] }, "execution_count": 61, "metadata": {}, "output_type": "execute_result" } ], "source": [ "cartesian_product([A,B])" ] }, { "cell_type": "code", "execution_count": 62, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(1, 3)\n", "(1, 4)\n", "(1, 5)\n", "(1, 6)\n", "(2, 3)\n", "(2, 4)\n", "(2, 5)\n", "(2, 6)\n", "(3, 3)\n", "(3, 4)\n", "(3, 5)\n", "(3, 6)\n", "(4, 3)\n", "(4, 4)\n", "(4, 5)\n", "(4, 6)\n" ] } ], "source": [ "for i in cartesian_product([A,B]):\n", " print i" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "
\n", " 4.3) Built-in Sets\n", "
\n", "
\n", "\n", "SageMath comes loaded with many common mathematical sets: integers ZZ, natural numbers NN, real numbers RR, etc. " ] }, { "cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Integer Ring" ] }, "execution_count": 45, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ZZ" ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 46, "metadata": {}, "output_type": "execute_result" } ], "source": [ "1 in ZZ" ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 47, "metadata": {}, "output_type": "execute_result" } ], "source": [ "1/2 in ZZ" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 48, "metadata": {}, "output_type": "execute_result" } ], "source": [ "0 in NN # NN denotes the natural numbers" ] }, { "cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 49, "metadata": {}, "output_type": "execute_result" } ], "source": [ "-1 in NN" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "
\n", " 5) Commands and Functions \n", "
\n", "
\n", "\n", "\n", "We now look at ways to define our own commands.\n", "\n", "\n", "
\n", "
\n", " 5.1) Defining Your Own Command\n", "
\n", "
\n", "\n", "The syntax for defining a command, which in this template we have called \\verb|function_name|, is:\n", "\n", " def function_name( ):\n", " :\n", " \n", " \n", " :\n", " return \n", "\n", "Here are some examples." ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "4" ] }, "execution_count": 50, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def f(x):\n", " return x*x\n", "\n", "f(2) # here we test the command f" ] }, { "cell_type": "code", "execution_count": 51, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "49" ] }, "execution_count": 51, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f(7)" ] }, { "cell_type": "code", "execution_count": 52, "metadata": {}, "outputs": [], "source": [ "def is_divisible_by_three(x):\n", " if x%3==0: # check to see if the remainder is 0 when divided by 3\n", " return True\n", " else:\n", " return False # this ends the definition of the command" ] }, { "cell_type": "code", "execution_count": 53, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 53, "metadata": {}, "output_type": "execute_result" } ], "source": [ "is_divisible_by_three(6) # here we test the command" ] }, { "cell_type": "code", "execution_count": 54, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 54, "metadata": {}, "output_type": "execute_result" } ], "source": [ "is_divisible_by_three(7)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Commands can take more than one parameter." ] }, { "cell_type": "code", "execution_count": 56, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'LimabeanLimabeanLimabean'" ] }, "execution_count": 56, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# this function capitalizes the word x then concatenates it with itself n times\n", "def repeat_word(x,n):\n", " return x.capitalize()*n \n", "\n", "repeat_word(\"limabean\",3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "
\n", " 5.2) Lambda Functions\n", "
\n", "
\n", "\n", "Python supports the creation of anonymous functions (i.e. functions that are not bound to a name) using a construct called `lambda`. This is a very powerful concept that's well integrated into Python and is often used in conjunction with typical functional concepts like `filter()` and `map()`.\n", "\n", "Using the lambda function we can create a function like `f` above." ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": true }, "outputs": [], "source": [ "f = lambda x: x*x " ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "4" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f(2)" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ " at 0x7fc9b4f10a28>" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A lambda function can take more than one argument." ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'superman'" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "concat = lambda x,y: x+y \n", "concat(\"super\",\"man\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Also note that you can put a lambda definition anywhere a function is expected, and you don't have to assign it to a variable at all. \n", "Here we use a lambda function along with `filter()` to pick out all elements of a list which are divisible by 3." ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48]\n" ] } ], "source": [ "print filter(lambda x: x%3==0,range(1,50))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "
\n", " 6) if, while, and for statements \n", "
\n", "
\n", "\n", "\n", "\n", "
\n", "
\n", " 6.1) if statement\n", "
\n", "
\n", "\n", "A **conditional statement** is what we use when we want our code to make decisions. For example, suppose we wanted to divide a number by 2 only if it is even. We can do this in Sage by using an `if` statement. The general syntax for Python's `if-else` statement is\n", "\n", " if :\n", " \n", " :\n", " else:\n", " \n", " : \n", " \n", "`` is an expression that can use *relational operators* `<`, `>`, `<=`, `>=`, `==` (is equal), and `!=` (is not equal), as well as *logical operators*: `and`, `or`, `not`. Its value is either `True` or `False`. If the condition is true, the statements indented under `if` are executed, otherwise the statements under `else` are executed. The `else` clause is optional: you can have `if` alone. In that case, if the condition is true the program executes the statements indented under `if`, otherwise the program skips them.\n" ] }, { "cell_type": "code", "execution_count": 57, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "n is divisible by 3\n" ] } ], "source": [ "n = 15\n", "if n%3==0:\n", " print('n is divisible by 3')\n", "else:\n", " print('n is not divisible by 3')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Often you'll need to string a chain of several `if-else` statements together. For example" ] }, { "cell_type": "code", "execution_count": 58, "metadata": {}, "outputs": [], "source": [ "def letterGrade(score):\n", " if score >= 90:\n", " return 'A'\n", " else:\n", " if score >= 80:\n", " return 'B'\n", " else:\n", " if score >= 70:\n", " return 'C'\n", " else:\n", " if score >= 60:\n", " return 'D'\n", " else:\n", " return 'F'\n" ] }, { "cell_type": "code", "execution_count": 59, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'B'" ] }, "execution_count": 59, "metadata": {}, "output_type": "execute_result" } ], "source": [ "letterGrade(84)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Python lets you simplify the indentation and compress the `if-else` on one line by using the keyword `elif`. The above code can be shortened to " ] }, { "cell_type": "code", "execution_count": 60, "metadata": {}, "outputs": [], "source": [ "def letterGrade(score):\n", " if score >= 90:\n", " return 'A'\n", " elif score >= 80:\n", " return 'B'\n", " elif score >= 70:\n", " return 'C'\n", " elif score >= 60:\n", " return 'D'\n", " else:\n", " return 'F'" ] }, { "cell_type": "code", "execution_count": 61, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'B'" ] }, "execution_count": 61, "metadata": {}, "output_type": "execute_result" } ], "source": [ "letterGrade(84)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "
\n", " 6.2) while loop\n", "
\n", "
\n", "\n", "`while` loops are one of the most useful techniques in programming. Essentially, a `while` loop allows us to repeat the same block of statements multiple times (but with different values of variables) while a certain condition holds true.\n", "The general syntax for Python's `while` loop is\n", "\n", " while :\n", " \n", " :\n", "\n", "As long as the condition remains true the program repeats the statements in the `while` block.\n", "\n", "The next example uses a `while` loop to add the integers from 1 to 10. " ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "55" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "i = 1\n", "sum1ton = 0\n", "while i <= 10:\n", " sum1ton += i # equivalent to sum1ton = sum1ton + i\n", " i += 1 # increments i by 1\n", "sum1ton" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "
\n", " 6.3) for loop\n", "
\n", "
\n", "\n", "`for` loops are traditionally used when you have a block of code which you want to repeat a fixed number of times. In Python, `for` loops iterate over a fixed list. As an alternative, the `while` loop could be used, however, `while` is used when a condition is to be met, or if you want a block of code to theoretically repeat forever, for example repeatedly asking for user input until the format the user provides is correct. The general syntax for Python's `for` loop is\n", "\n", " for x in :\n", " \n", " :\n", "\n", "Here is an example of using the `for` loop to step through the entries of a list and square each one." ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\n", "4\n", "9\n", "16\n", "25\n" ] } ], "source": [ "L = [1,2,3,4,5]\n", "for x in L:\n", " print x^2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In the next example we use a `for` loop together with an `if` statement to print the list of integers from 1 to 20 which are divisible by 3." ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3\n", "6\n", "9\n", "12\n", "15\n", "18\n" ] } ], "source": [ "for x in range(1,21):\n", " if x%3 == 0:\n", " print x" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This has been a quick introduction to get you up and running in this class. We will be developing our experience with SageMath over the term. So have fun!\n", "\n", "\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "
\n", " 7) Exercises\n", "
\n", "
\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Exercise 1**: Assign 27 to the variable a, 1027 to the variable b, and the product to the variable c. Have SageMath output the values of all three variables." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Exercise 2:** For a, b and c in Exercise 1, use the factor() command to factor c. Also, use the remainder command % to determine is 16 is a factor of ab+1." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Exercise 3:** Create and print a list of integers from 50 to 100 (inclusive)." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Exercise 4**: From the list in Exercise 3, create a sublist consisting of (a) even integers, (b) odd integers, (c) primes, and (d) numbers divisible by 13." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Exercise 5**: Create the two sets $A=\\{1,2,3,4,5,6\\}$, $B=\\{2,4,6,8,10\\}$ and find (a) their intersection, (b) their union, and (c) the cardinality of their cartesian product." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Exercise 6**: Define a function `sum1ToN` that returns $1+2+3+\\cdots + n$ using the formula $1+2+3+\\cdots+n=\\frac{n(n+1)}{2}$. " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Exercise 7**: The function below prints string `obj` n times:\n", "\n", " def printNtimes(n,obj):\n", " count=0\n", " result='' # empty string\n", " while count < n:\n", " result += str(obj) # += is equivalent to result = result + str(obj)\n", " count += 1\n", " print(result) \n", "\n", "Test it with various inputs for `obj` and n. \n", "\n", "Notice there is no `return` line in the function. Since we don't ask the function to return anything we could either write the last line as `return`, or just leave it out as we have done above. Type in \n", "\n", "`print printNtimes(3,'hello')` \n", "\n", "and describe what happens." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Exercise 8**: Write a function `pow4(x)` that returns $x^4$ and performs only two multiplications (and no exponentiations)." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Exercise 9**: Write a function `divBy(n,m)` which returns True if integer n is divisible by m, otherwise it returns False." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "SageMath 8.8.beta7", "language": "sage", "name": "sagemath" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.15" } }, "nbformat": 4, "nbformat_minor": 1 }