Python for Mathematics Students Version 2.1 March 4, 2013 K Vishnu Namboothiri Department of Mathematics BJM Govt. College, Chavara (Department of Collegiate Education, Government of Kerala) Kollam, Kerala, INDIA kvnamboothiri@gmail.com + http://vishnu.e-lokam.com Preface Welcome to the mathematical world of Python! This small tutorial is a result of my attempt to learn Python from scratch. My previous programming experiences were with the good old C, and then with some basic stuff in PHP. When I was entrusted to teach Python to students in my college as a part of their undergraduate program, I was really clueless about where to begin. The flexibility of Python in handling various objects was infact unbelievable and difficult to digest for anybody coming from a C programming background. I have written this text viewing math students/or their teachers who might have lost their sleep for several nights after they came to know that they are supposed to learn/teach Python as a part of their 6th semester BSc programme in the University of Kerala. The style used in this text is something which a moderate computer literate person can follow. Since I do not at present have any plan to make this text perfect or complete, it indeed lacks the rigidity or structure of a programming book. I have not tried to elaborate upon any of the programming ideas/concepts in python for the sake of completeness. Some features might have found a detailed treatment, only because they seem to be very much important through out the learning process in this book. I would anyway like to add a word of caution about this book. This is not supposed to be a replacement for the official Python tutorial or any other standard Python textbook. You may find it useful, in particular, if you are teaching Python to undergraduate math students as I mainly use math examples to analyse programming ideas. I have also drawn many of my examples from [1], but tried to modify it to suite the taste of an undergraduate math student/ his teacher. You are requested to exercise sufficient amount of caution while using this tutorial. I may try to polish this material once in a while, or whenever I get some time. If you come across some mistakes in this material (which I expect in abundance!) - typos, factual, and logical - you are requested to kindly send me an email so that I can correct it and repost it to my website. I am very much indebted to the websites stackoverflow.com and stackexchange.com for providing excellent articles in Python through their forums. I would have referred these sites more often compared to the official Python tutorial itself written by Guido van Rossum (father of Python!) and Fred L. Drake, Jr. Several other sites helped me to clear my questions which would seem to be trivial for an advanced programmer. The way in which I wrote this tutorial is very much influenced by Prof. Kumaresan of the University of Hyderabad. The style in which this book proceeds is closely related to his approach towards teaching. In MTTS(www.mtts.org.in) he usually insists that tell something only if it is not only necessary, but unavoidable. Dr. E Krishnan, a pioneering and shining personality in the open software/ math teaching world in Kerala, has also played a role in influencing me to include more math examples in this text. Thanks to all these great people, and then to many of my collegues who asked and encouraged me to post these notes to the www. Hope that the readers also will start enjoying Python as I did while writing this tutorial. Thanks also goes to the TEX/LATEX community as I have prepared this text in a colorful manner using the tricks/tips I learned from them. I am dedicating this book to all those math students for whom love at first sight couldn’t happen with the official Python tutorial or any other standard Python textbook! Vishnu Namboothiri K Alappuzha 17/2/2013 Contents Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 Quickstart 1.1 Getting Python and starting it . . . . . . . . . . 1.1.1 Starting the Python shell in Linux . . . . 1.1.2 Starting the Python shell in MS Windows 1.2 Learn from mistakes . . . . . . . . . . . . . . . . 1.3 Save your names for future use . . . . . . . . . . . . . . . . . . . . 2 Hands on python 2.1 Basic tools . . . . . . . . . . . . . . . . . . . . . . . . 2.2 Your first Python program file . . . . . . . . . . . . . 2.3 Handling complex numbers . . . . . . . . . . . . . . . 2.4 Functions and loops : wisdom is in learning from past 2.4.1 Defining a function . . . . . . . . . . . . . . . 2.4.2 More about while . . . . . . . . . . . . . . . . 2.4.3 While loop: one more example . . . . . . . . . 2.5 Standard math functions . . . . . . . . . . . . . . . . 2.6 No more secrets: let the user input values . . . . . . 2.7 In life, everything is conditional . . . . . . . . . . . . 2.8 Choosing function names . . . . . . . . . . . . . . . . 2.9 Defining names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . experiences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 Lists in python 3.1 Defining and accessing lists . . . . . . . . . . . . . . . . . . . . . . . . . 3.1.1 A better method for looping through list . . . . . . . . . . . . . 3.2 More on the range function . . . . . . . . . . . . . . . . . . . . . . . . 3.2.1 More examples using for . . . . . . . . . . . . . . . . . . . . . . 3.2.2 Another example using lists and for : simple sorting of numbers 3.3 Built-in Sort functions . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.4 Looping in Python: Extras . . . . . . . . . . . . . . . . . . . . . . . . . 3.4.1 else clause in loops . . . . . . . . . . . . . . . . . . . . . . . . . 3.4.2 More examples using lists: have some fun; play with the system 3.4.3 C arrays and Python lists . . . . . . . . . . . . . . . . . . . . . iii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ii . . . . . 1 1 1 2 2 4 . . . . . . . . . . . . 5 5 6 8 9 13 14 14 15 16 18 19 21 . . . . . . . . . . 23 23 26 26 27 30 31 32 34 35 36 Contents 3.5 3.4.4 Slicing lists . . . . . Advanced features of lists . 3.5.1 Lists as stacks . . . . 3.5.2 Using lists as queues 3.5.3 New lists from old . . . . . . 4 Data types: a detailed visit 4.1 Numeric Types . . . . . . . . 4.2 Tuples . . . . . . . . . . . . . 4.2.1 Accepting tuple inputs 4.3 Sorting iterables: Extras . . . 4.3.1 The lambda functions 4.4 Sets . . . . . . . . . . . . . . 4.5 Dictionary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 39 39 40 42 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 45 47 48 48 49 50 52 . . . . . . . . . . . . . . . . . . . . . . . . precision . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 55 58 60 61 61 62 63 6 Random Extras 6.1 The dir() function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.2 Clearing the python shell . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.3 Handling error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 67 68 68 7 100 7.1 7.2 7.3 7.4 7.5 7.6 71 71 71 75 75 76 76 5 Input and output 5.1 Output formatting . . . 5.2 Format Specifiers . . . . 5.2.1 Format specifiers: 5.2.2 Format specifiers: 5.2.3 Format specifiers: 5.2.4 Format specifiers: 5.3 File operations . . . . . problems in math! Basic Mathematics . Algebra . . . . . . . Linear Algebra . . . Real Analysis . . . . Statistics . . . . . . . Numerical Analysis . . . . . . . . . . . . . . . . . . . . . . . . . . . . align . sign . width, type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A Symbols, notations, and technical words 81 B Some results/ algorithms B.1 Euclidean Algorithm for finding GCD . . B.2 Fibonacci sequence or Fibonacci numbers B.3 Absolute value . . . . . . . . . . . . . . B.4 Harmonic Series . . . . . . . . . . . . . . B.5 Sieve of Eratosthenes . . . . . . . . . . . 83 83 84 84 84 84 K Vishnu Namboothiri -iv- . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . http://vishnu.e-lokam.com Contents C Basic Linux (Unix) shell commands 87 D Answers/hints for some selected exercises 91 K Vishnu Namboothiri -v- http://vishnu.e-lokam.com Chapter 1 QUICKSTART §1.1 Getting Python and starting it Installing Python in your System is very easy. If you are in a Windows Machine, you may download the Python Windows MSI installer from the page http://www.python.org/ getit/ and install the Python Intrepretor + IDLE (Integrated Development Environment). If you are in Ubuntu Linux/its variants/Debian Linux versions, the Ubuntu Software center/Synaptic package manager will help you to install the Python intrepretor + IDLE from their online sortware repositories. The page http://www.python.org/getit/ gives details about how to install Python in different operating systems. In this tutorial, I am assuming that you are using a Linux System in which Python 3.x + a text editor is installed. It is not necessary that you should definitely use IDLE itself for typing your Python programs. I will be refering to the text editor geany most of the times. It is up to you to choose your convenient editor. But don’t use an office editor like MS-Word/Open Office Writer/LibreOffice Writer for typing Python code as it may not save your code in ASCII format, and may cause unexpected errors later. Keep your system on, get ready to start typing the commands/program codes which appear frequently in this tutorial. Let us start. 1.1.1 Starting the Python shell in Linux Login to your Linux box. Start the terminal (Terminal Emulator/Xterm/bash/rterm/ any terminal which has a $ sign followed by a blinking cursor!) and in it, type python3.1 and press Enter to start the python 3.x shell. If you type simply python Enter in the shell, you may end up with Python 2.x, which seems to be the default Python version these days bundled with any modern Linux distribution (as on February 2013). You will see a welcome message displaying the Python version which you are using now (In my system, I have version 3.2.3) together with some optional keywords help, license etc. There will be also the >>> symbol which shows that the Python shell is ready to execute 1 Chapter 1. Quickstart your commands. You may type help Enter or any other keyword displayed on the screen to experiment. Now try to add two integers (say 5+2 Enter ), multiply (5*2), divide (5/2), exponentiate (5**2), find remainder (70%3) and observe (don’t merely see) the result. To say goodbye to python shell, simply type exit() Enter (or press Ctrl + D) you will be back again in the terminal. Whenever I ask you to type a command, you are supposed to type command Enter . Terminal/Python shell will start execution of your command only if you press Enter . 1.1.2 Starting the Python shell in MS Windows Login to your machine. On your Desktop or Start Menu you will find the IDLE(Python GUI) icon/menu item. Click/ double click on it to start the Python Shell. You will be displayed the welcome message and the >>> symbol which means that you are in the standard python shell. If you are not sure about how to install Python 3.x in your Linux/MS Windows machine, please check the official Python site http://www.python.org/getit. Exercises Ex. 1.1 — What is the difference between results of 5/2 and 5//2 in the python 2.x shell and 3.x shell?1 Ex. 1.2 — Try the above operations with mixed sign numbers (that is, negative numbers and positive numbers mixed). Ex. 1.3 — Have you tried division by 0 in the shell? Ex. 1.4 — If you simply type exit instead of exit() in the shell, what will happen? Ex. 1.5 — Have you tried the help command in the shell? This is a terribly useful command, so try it several times, read the messages appearing on the shell, and retry it. Ex. 1.6 — Make at least 5 mistakes in the shell: For example, 5/0, 0/0, 5/a, 5/abc etc. Record the mistakes you have made and the note down your observations. §1.2 Learn from mistakes In one of the previous exercises, you might have observed an error 1 See Appendix A to know about different Python versions K Vishnu Namboothiri -2- http://vishnu.e-lokam.com 1.2. Learn from mistakes Code 1.1: In the terminal/shell NameError: name ’ ....... ’ is not defined >>> Once again, visit Python’s shell and define the name, say a by assigning some value to it. Keep typing and entering the lines exactly as given below. At the end of each line press Enter . Code 1.2: In the terminal/shell a 5 a a a 5 =2 /a =3 +5 ∗∗ 5 ∗∗ a Observe the results. Now there is no such NameError as the name a has now been defined. Alphabets together with numbers and underscore are used to make names in Python. But a name should not start with a number. Though a name can start with an underscore, it is not enoucuraged in Python (and in many of the existing programming languages). Let us extend this game by defining a few more variables (names) in the shell. Code 1.3: In the terminal/shell pi = 3.14 radius = 5 area = pi ∗ radius ∗∗ 2 area You can see that the first three lines define something. The first two define two names where as the third one defines a name (area) as well as assigns an expression (,,,) to it. The evaluation of the expression in turn takes place as per the usual mathematical rules (brackets open first, exponentiation next . . . ) and puts the computed value in the name area. The final line instructs the shell to display the value in area. Now you try the below two lines in the shell. Code 1.4: In the terminal/shell radius = 10 area Don’t forget to press Enter at the end of each line. (This is the last time I am reminding you about pressing Enter !) Have you expected the result of the last line to be 31.4 as area = pi * radius ** 2? Remember that area does not hold any expression in it, but just the value of pi * radius ** 2. In the previous execution itself, area was assigned the value 3.14 * 5 ** 2 and we have not reassigned area any new value! The reassignment took place only in the case of radius. K Vishnu Namboothiri -3- http://vishnu.e-lokam.com Chapter 1. Quickstart Exercises Ex. 1.7 — Try the above procedure with at least three formulae, like finding area of a square, of a triangle, speed of a car. (using the formulae ab, 12 bh, d/t) Ex. 1.8 — If you press K inside the shell (in Linux) what is the result? What about pressing L? Ex. 1.9 — exit() from the shell, then come back, then execute the above key presses, what is the result? Ex. 1.10 — After doing the above exercise, type area Enter in the shell, what is the result? Ex. 1.11 — Have to tried credits or license in the shell? What are the results? §1.3 Save your names for future use From one of the exercises in the last section, we can see that variables we define in the shell lasts only for that session2 . For practical purposes, we may have to store the names and the values in it for future use. There is no way other than using files to store our program lines (or code) for future use. I will give you one surprise: we have in fact written a complete python program in one of the above steps! It may be difficult for you to believe especially if you are coming from a C Programming language background where every program should start with main(), put an opening brace after that, etc. Lot of technicalities. Python is really simple, at the same time unbelievably powerful. Time for a break! Not from the system, but from Python. Let us get acquainted with some useful Linux shell commands. Please read Appendix C and come back to catch the python. 2 Please see Appendix A K Vishnu Namboothiri -4- http://vishnu.e-lokam.com Chapter 2 HANDS ON PYTHON §2.1 Basic tools To start pythoning, we require two basic tools. First one is a text editor, and second one our good old terminal. If you are in MS Windows, and you have installed Python in it using the standard Microsoft Installer file (MSI), these two tools are combined together in an IDLE (Integraged Development and Learning Environment). I will be assuming the Linux Box and its features for explaining things. But all these the program lines we write here are very well valid in the Windows IDLE too. For making your life easier inside the Linux terminal, you are requested to go through the linux shell commands listed in Appendix C and get acquinted yourself. We have already seen the terminal, and have executed some stuff in the python shell. Depending on your OS, you have a variety of choices for text editors. By default, most of the systems have vi, nano editors. To test nano, from the terminal just type nano Enter . This is much more friendlier than vi for a beginner. None of these vi, nano editors are graphical editors. So you have to use key combinations to effectively handle them. If you want a better, friendlier interface, you should try using text editors like leafpad, gedit, geany etc. Please experiment yourself browsing your graphical interface menu for finding your text editor, or consult your system administrator. I am assuming the editor to be geany (which is available by default in my Crunchbang OS). It is a simple, but elegant editor for most of the programming purposes. It is a good practice to keep a separate directory for all your python programs. Open the terminal, type mkdir python to create a folder named python. If you are using a system which will be shared by many other students/users under one single username, suffix your name also to the directory. Use the command python_vishnu instead to create your personalised python program’s directory. 5 Chapter 2. Hands on python §2.2 Your first Python program file I am assuming that the python programs we create will be stored in the directory python_vishnu. You are requested to replace this directory name with the name of the directory which you have created. Now open a terminal, and type the following commands: Code 2.1: In the terminal/shell cd cd python vishnu geany findarea.py The above commands are self explanatory. The first one will take you to the home directory (for example /home/vishnu/ in my case). The third one will create a new file findarea.py in the directory python_vishnu . It is customary to end a python file name with the extension .py. The editor geany will open it for you to start typing. Depending on your OS, you may have to modify the word geany to something else (like gedit in Ubuntu Linux, leafpad in Lubuntu, Xubuntu, kate in Kubuntu OS etc.). An alternate way to create a python file is open the File Manager of your OS, move to the directory python_vishnu, right click on some empty space, click on create new text file (or create empty file), and give it the name findarea.py. Double click on the file findarea.py to open it in your default text editor. I am assuming that you have opened the findarea.py file using your favourite/default text editor. In the text editor, enter the following lines one by one: Code 2.2: findarea.py pi = 3.14 radius = 5 area = pi ∗ radius ∗∗ 2 area Save the file using the File menu on top. In most of the text editors, the key combination + S not only saves the file, but saves your energy too! Close it (Shortcut key: Alt + F4). You are back in the terminal (If you have closed the terminal, open it again, and cd to python_vishnu). Now enter the command python3.1 findarea.py Enter . Wait for the result. Ctrl , No result! , No result! , No result! , No result! The reason roughly is, when you are typing area in the python shell, the output is directed to the screen because you are talking directly to the python interpreter. Python shell catches the value of the variable area and throws back to the screen. But when you execute the same set of commands from terminal, it will not interpret your instruction area as a command to print the area. The value inside this variable need to be channeled to the terminal back via a print() function statement as given below. K Vishnu Namboothiri -6- http://vishnu.e-lokam.com 2.2. Your first Python program file Code 2.3: findarea2.py pi = 3.14 radius = 5 area = pi ∗ radius ∗∗ 2 print (area) Now the result of the command python3.1 findarea.py Enter appearing on my terminal is 50.24 which is what we expected. There is a huge difference between the way in which the print command is used in python 2.x and python 3.x. In python 2.x the parenthesis need not be used to wrap the print arguments where as using it is compulsory in python 3.x. print area will create a SyntaxError in python 3.x where as print (area) and print(area) both will work in python 2.x. To know more about the differences in Python 2.x and 3.x, please check the official documentation website page http://docs.python.org/3.0/whatsnew/3.0.html. The result is alright now, but it should be more informative. The number appearing on the screen does not give any idea to us about what it is (especially when we are running the code after a long time, or when we are showing the program output to somebody else. Let us modiify the print command slightly. print ("Radius = ", radius, " and so area is = ",area) and the result of python3.1 findarea.py is Radius = 4 and so area is = 50.23 As in the case of C language print have a number of formatting options. For example, print ("Radius = %0.2f" % radius, " and so area is = %0.1f" % area) will give the output as Radius = 4.00 and so area is = 50.2 Try to guess the effect of %0.2f. Now we have natural answer to the question “Why learn python after learning C ?” Try to write the above program in C. In the terminal, type Code 2.4: In the terminal/shell cd cd python vishnu geany findarea.c and then enter the following code in the file findarea.c. K Vishnu Namboothiri -7- http://vishnu.e-lokam.com Chapter 2. Hands on python Code 2.5: findarea.c #include <stdio.h> int main(){ float pi = 3.14, radius = 4, area; area = pi ∗ radius ∗ radius; printf (”Radius = %0.2f and so area is = %0.1f ”, radius, area); } Save it, and compile it using the command gcc -o findarea findarea.c The output is an executable file saved automatically by gcc (GNU Compiler Collection) under the name findarea. Execute it in the terminal using the command ./findarea (note the dot slash combination) and the result is Radius = 4.00 and so area is = 50.2. Which one do you like? C or Python? (Please don’t say neither!) §2.3 Handling complex numbers Python supports several datatypes, including simple integer type, and floating type. It also supports complex number arithmetic. Imaginary part of a complex number is written with a suffix of j or J. Let us write a small program showcasing some simple complex arithmetic. Code 2.6: complex.py # This is a Python comment: Program handling basic complex arithmetic #Program complex.py a , b = 10, 15 c , d = 20, 25 n1 = a + b ∗ 1j # or equivalently n1 = a + b * 1J. # You cannot simply write a + bj; but why? # bj will be a variable name then! n2 = c − d ∗ 2J print (n1, n2) print (n1 + (−n1)) print(n2 / n1) print (n2 ∗∗ n1) print (n1.real) print (n1.imag) print (n1 − n1.imag) # note the result print (n1 − n1.imag ∗1J) print (n1 − n1.real) K Vishnu Namboothiri -8- http://vishnu.e-lokam.com 2.4. Functions and loops : wisdom is in learning from past experiences print (n1.real == a) and the result is Code 2.7: In the terminal/shell >>> (10+15j) (20−50j) 0j (−1.6923076923076927−2.4615384615384617j) (−8.384717618452898e+24−8.076974165447137e+24j) 10.0 15.0 (−5+15j) (10+0j) 15j True In the last step, python simply checked whether the statement n1.real == a is true and the answer is naturally True. Also, when a number has both its real and imaginary parts nonzero, the number is enclosed in parenthesis. As in C, multiple assignments are possible in python. The expression c = d = 20 assigns the number 20 to both the variables. §2.4 Functions and loops : wisdom is in learning from past experiences The most important aspect of writing programs is that we can reuse a program code without typing it again and again. We can use parts of certain programs in other programs too. Let us proceed towards explaining this part of programming with a small example. It will try to find the GCD of two numbers using Euclidean Algorithm1 . Let us just see how to write this program in Python. Create a file findgcd1.py in your python programs’ directory (in my case, it is python_vishnu) and enter the below given lines. Code 2.8: findgcd1.py # Program to find gcd of two numbers # Program findgcd1.py # Two numbers chosen randomly a = 35 b = 14 while a: b , a = a, b % a 1 See a note on this algorithm in § B.1 K Vishnu Namboothiri -9- http://vishnu.e-lokam.com Chapter 2. Hands on python # See the indentation, and semicolon. Also, note the % operator print (”GCD is ”, b) and the result of python3.1 findgcd1.py on my terminal is GCD is 7. Some details are in order. The while keyword makes the lines below it after the semicolon (intended to it) repeat the statement b, a = a, b % a as long as a is true. In python, all non zero values represent truth or are True. Therefore, initially a is True (it being assigned a non zero value in the beginning). Infact, while a: has the same meaning as while a != 0:. Let us see the changes happening to the variables a, b while the program is running by adding an extra print statement. In your terminal copy the file findgcd1.py to a new file findgcd2.py and open the new file findgcd2.py using the commands Code 2.9: In the terminal/shell cd cd python vishnu cp findgcd1.py findgcd2.py geany findgcd2.py Modify the program slightly by adding an extra print statement and save it. Code 2.10: findgcd2.py # Program to find gcd of two numbers: findgcd2.py a = 35 b = 14 print (a, b) while a : b , a = a, b % a # Note the indentation, and semicolon. Also note the % operator print (a,” ”, b) # Note that the same indentation is given as in the above line print (”GCD is ”,b) # No indentation now, and so out of the while loop For the sake of a neater output, modify slightly the second print statement to print ("a = %2d b = %2d" % (a, b)) and run the new program using the command python3.1 findgcd2.py. The new output is Code 2.11: In the terminal/shell 35 14 a = 14 b = 35 a = 7 b = 14 a= 0 b= 7 GCD is 7 K Vishnu Namboothiri -10- http://vishnu.e-lokam.com 2.4. Functions and loops : wisdom is in learning from past experiences The value of a and b got reversed in the very first execution! Recall the way Euclidean Algorithm works. You will easily understand what is happening here once you try to execute the program yourself in your mind assuming your mind to be an interpreter. The same program can be modified to find the GCD of three numbers, say a,b,c. Save the below code as findgcd3.py. Code 2.12: findgcd3.py # Program to find gcd of three numbers: findgcd3.py a = 48 b = 70 c = 59 print (a,b) while a > 0 : b , a = a, b % a print (”a = %2d b = %2d ” % (a, b)) print (”GCD(a,b) is ”,b,”\n”) d = b # GCD is now d print (d,c) while d > 0: c , d = d, c % d print (”d = %2d c = %2d” % (d, c)) print (”GCD(d,c) is ”, c) and the output is Code 2.13: In the terminal/shell 48 70 a = 22 b = 48 a = 4 b = 22 a= 2 b= 4 a= 0 b= 2 GCD(a,b) is 2 2 59 d= 1 c = 2 d= 0 c = 1 GCD(d,c) is 1 We can extend this process for any set of finite numbers. But writing the same code again and again for each pair seems to be cumbersome. And infact, programming language is just meant to avoid these kind of situations. Python, just like any other programming language, offers a method to reduce our burden (and to reuse our code). Let us define a mygcd function K Vishnu Namboothiri -11- http://vishnu.e-lokam.com Chapter 2. Hands on python and use it. Type code the below and save it as mygcdfunctiontest.py Code 2.14: mygcdfunctiontest.py # Program to find gcd, using function: mygcdfunctiontest.py def mygcd(a,b) : while a : b, a = a, b % a # Note the indentation return b #Now also, note the indentation # Function definition over. How to call (use) it? a = 35 b = 144 print (mygcd(a,b)) # Simple! Done! Now run it from the terminal: python3.1 mygcdfunctiontest.py and the result is 1. But wait. The game is not over. We can in fact use this definition in or other python programs. Delete the last three lines, slightly modify it and save it as mygcdfunction.py. The code is given below. Code 2.15: mygcdfunction.py def mygcd(a,b): """This is vishnu’s GCD function""" while a: b, a = a, b%a return b # Function definition over! Create a new python file mygcdfunctiontest2.py and enter the below given text: Code 2.16: mygcdfunctiontest2.py a = 35 b = 144 print (mygcd(a,b)) If we run it, we will get the following error message: Code 2.17: In the terminal/shell print (mygcd(a,b)) NameError: name ‘mygcd’ is not defined K Vishnu Namboothiri -12- http://vishnu.e-lokam.com 2.4. Functions and loops : wisdom is in learning from past experiences This situation is more or less like this: Suppose you are in the final year of undergraduate math course in your college, and somebody asks you about another student called Raju. If that student is not in your class, your immediate response will be that I don’t know Raju. Suppose that now that the person gives you a hint that he probably belongs to the Physics class, then you will be able to answer. But the situation becomes slightly complicated if he is asking about Radha and Radha is there in Physics class as well as in your class. You will suddenly answer about your classmate Radha. If the person further clarifies that he wants to know about Radha in the Physics class (that is, physics.radha), then you will check the list of students in the Physics class, locate her name, and from the college authorities, you will fetch the details about physics.radha to him. Just like that, Python is a person who is asking you about mygcd. Even though we have defined the function mygcd it is in a different file, (not in our class and so) we should tell python about where exactly the mygcd definition can be found. Let us tell it to python. Modify the file as below and save it. Code 2.18: mygcdfunctiontest3.py a = 35 b = 144 import mygcdfunction # No need to type the last three characters in the filename ".py" print (mygcdfunction.mygcd(a,b)) Try to understand the steps we have executed. We imported the file where the function mygcd is defined, then used it. Now, instead of using the long name mygcdfunction.mygcd we can slightly modify our program code for the ease of reading and typing to just use mygcd. (This is equivalent to asking Radha to sit in our class for attending a common course! There is a small (?) problem now. Two students in the same class with the same name. Python favours the student who came last and forgets about the former Radha. Save the file as (or copy the file to) gcdfunctiontest4.py and modify the code to look like: Code 2.19: mygcdfunctiontest4.py a = 35 b = 144 import mygcdfunction from mygcdfunction import mygcd print (mygcd(a,b)) The code has the same effect as that in mygcdfunctiontest3.py. But the difference is, instead of a long function name, we used a shorter and convenient one. 2.4.1 Defining a function In one of the above programe codes, we used the keyword def. We are a defining a function there. The simplest form of defining a function is K Vishnu Namboothiri -13- http://vishnu.e-lokam.com Chapter 2. Hands on python def functionname(arguments): do something here using the arguments return the value or simply stop it continue with the rest of the program, see the indentation now 2.4.2 More about while The structure of the while block is the following: while testcondition : do something here −−− finish the code rest of the program, outside the while block If testcondition is true, the lines below it, intended to it will be executed. It will be executed again and again until the testcondition becomes false. Even if the testcondition remains true, break statement can be issued inside the while loop to come out of the loop to execute the rest of the program. In the above, testcondition can be a logical expression (like a <= b or just a variable (as in the previous example) whose value can be evaluated into either True or False. The possible logical operators are <, >, <=, >=, ==, and !=. 2.4.3 While loop: one more example You know the Fibonacci sequence of numbers very well: start with 1 and 1 as the first two numbers, then keep on adding two consecutive numbers2 in the sequence to get 1, 1, 2, 3, 5, 8, etc. Save the following code to a file fibonacci.py and explain yourself the working of it. Code 2.20: fibonacci.py # Fibonacci.py # Tries to find all Fibonacci numbers up to a given upper limit a=1 b=1 # Defined the first two Fibonacci terms n = 100 #Now trying to find all Fibonacci numbers which comes before n while b < n: b, a = a + b, b 2 See § B.2 for a precise definition of Fibonacci numbers. K Vishnu Namboothiri -14- http://vishnu.e-lokam.com 2.5. Standard math functions print (b) Execute it and see the result. Try to explain the execution of the lines yourself. §2.5 Standard math functions There is a huge collection of math functions available in python modules (files). To see the list of functions available in the math module, go to the shell and type the following lines. Code 2.21: In the terminal/shell import math help(math) A list of available math functions appear which includes acos (cos−1 ), cos, sqrt, fabs, . . . . In the Python shell in Linux, you may use K, L keys to see the full list. In Windows, the mouse scrolling in the python shell will do the job. Let us use some of these functions as in the next program, name it as mathfunctiontest.py. Code 2.22: mathfunctiontest.py import math print (”Value of Pi is ”, math.pi) # Show the value of the constant Pi print (”Value of e is ”, math.e) print (”Value of sin ( pi/2) is ”,math.sin(math.pi/2)) and the result is Code 2.23: In the terminal/shell >>> Value of Pi is 3.141592653589793 Value of e is 2.718281828459045 Value of sin(pi/2) is 1.0 Exercises Ex. 2.1 — Write a program to find the area of a rectangle. Ex. 2.2 — Write the above area program by defining a function called myrectarea. Ex. 2.3 — Write a program which uses at least 10 math functions. Ex. 2.4 — Verify that sin2 x + cos2 x = 1 in a Python program giving various values to x. K Vishnu Namboothiri -15- http://vishnu.e-lokam.com Chapter 2. Hands on python Ex. 2.5 — Remember that trigonometric functions expect arguments in radians, not in degrees. There is a function math.radians in python for performing this conversion. Use help(math.radians) for viewing the details. Prepare a program which accepts x in degrees, then convert it to radians, and then find the function value. Ex. 2.6 — Is log(e) = 1 in Python? Verify it in the python shell (not inside any program). Ex. 2.7 — Do these math functions accept complex input? Ex. 2.8 — Verify three more Trigonometric identities writing a single Python program. It should accept input values to the argument x. Ex. 2.9 — An absolute value function abs is available in python. Use it on complex numbers. Observe the results. Ex. 2.10 — Find distance between two complex numbers separating its real, imaginary parts. §2.6 No more secrets: let the user input values For a program to be practically useful, its users should be allowed to input values to it and the program should answer accordingly. In C this goal is achieved via the scanf() function. In python, there is an equivalent (infact, more robust) input function to accept user inputs. Let us save the following code under the filename inputtest.py Code 2.24: inputtest.py a = int(input(”Enter the first number: ”)) b = int(input(”Enter the second number: ”)) import mygcdfunction from mygcdfunction import mygcd print (mygcd(a,b)) and check the result: python3.1 inputtest.py. If you have typed it correctly, you will breath the air of success! The first input function statement shows a prompt to user to input a number. The user can input anything (depending on his choice!). The int keyword tries to convert it into an integer. If succeeded, the gcd will be calculated later. If not, an error message will be raised. Try yourself inputting a number, float, a letter, a few letters, etc. Can you guess the result of the following code? Save it under inputtest2.py and try to run. Apply your experience so far to make guesses. Code 2.25: inputtest2.py K Vishnu Namboothiri -16- http://vishnu.e-lokam.com 2.6. No more secrets: let the user input values a = float(input(”Enter the first number: ”)) b = int(input(”Enter the second number: ”)) import mygcdfunction from mygcdfunction import mygcd print (mygcd(int(a),b)) In python 2.x, the input() function was actually called raw_input(). The former was used to evaluate math expressions to integers. For example, in Python 2.x you can simply put 2-5 when you are prompted for a by the input() function. But now it is no longer allowed. To get the old input() behaviour, use eval(input()). But the eval+input combination is very dangerous, as it may allow an inadverent user to damage even your operating system files. See the official documentation for details. Save the following code under the name inputeval.py and execute it giving the inputs as 5+4 and 4**3. Code 2.26: inputeval.py a = eval(input(”Enter the first number: ”)) b = eval(input(”Enter the second number: ”)) # Now import the function import mygcdfunction from mygcdfunction import mygcd print (mygcd(int(a),b)) Have you got 1 as the result of this code? Exercises Ex. 2.11 — Write a program to accept three user inputs (as numbers) and find their gcd. Ex. 2.12 — Remember that lcm(a, b) ∗ gcd(a, b) = ab. Use this to write a program to find lcm of two numbers. It should accept user inputs. Ex. 2.13 — Use eval() to evaluate a math expression given as input, then find the lcm of the same two numbers. Ex. 2.14 — Write a program mylcmfunction.py containing the definition of mylcm() function. It may (and probably it should) import and use the previously defined mygcd() function. Use it in a program called lcmfunctiontest.py. It should accept user inputs. Ex. 2.15 — Can you input() two complex numbers and find their gcd? Try it. Observe the results. K Vishnu Namboothiri -17- http://vishnu.e-lokam.com Chapter 2. Hands on python §2.7 In life, everything is conditional In particular, it is so in math. You write most of the theorems using an if-then clause. Then it should naturally be like that in python too! Let us see an example. How to write a program to find absolute value of a real number? We basically need to identify whether the given number is 0 or positive or negative (Trichotomy property of real numbers, just recall it). The if keyword is precisely for that purpose. Save the following code under the name myfunctions.py. Code 2.27: myfunctions.py """ This file contains vishnu’s absolute value function for real numbers This is different from python’s built in abs() function""" def myabs(a): """Finding absolute value of a""" #recall the definition of the function for real numbers if a < 0 : return −a else : return a # Function myabs() definition over Let us create our own signum function sgn(x) also in the same file. Call it mysgn(x). Modify the above file myfunctions.py appending the below lines to it. Code 2.28: myfunctions.py # Defining the mysgn function def mysgn(x): """mysgn function tells whether the given number is positive, negative or zero""" if x < 0 : return −1 elif x == 0 : return 0 else : return 1 # Function mysgn() definition over What are the lines starting and ending with """ doing in the code? Ok. Go to the terminal and execute the following commands one by one: K Vishnu Namboothiri -18- http://vishnu.e-lokam.com 2.8. Choosing function names Code 2.29: In the terminal/shell cd cd python vishnu python3.1 >>>import myfunctions >>>help (myfunctions) >>>help(myfunctions.myabs) >>>help(myfunctions.mysgn) The last three commands show respectively the strings at the beginning of myfunctions.py, string just inside the myabs() definition, and string inside the mysgn() definition. The strings enclosed between two consecutive """ is called a DocString or a documentation string. It is displayed to the user when he requests for a help on the module/function. (For the time being, assume that a module is just a python file). It will be ignored while executing the program code, but will be used while using the help() function. Let us use our functions. Create a file myfunctonstest.py with the following content, and run it. Code 2.30: myfunctionstest.py a = eval(input(”Enter a number: ”)) import myfunctions from myfunctions import myabs, mysgn print (”Absolute value of the number %f is %f and the Signum value is %f ” % (a, myabs(a), mysgn(a ))) Give an input, and check whether the result matches with your expectations. The definition of the both the functions must be clear to you now. The if tests a condition, evaluates all expressions intended to it if the condition is true, elif (equivalent to else if in C ) comes into the picture when the condition after if is false, and then tests the condition in its line. If that also fails, the statement intended to else will be executed. Note that, else will not test any conditions. Any number of elif one can include in the if block, but one and only one if. Including else as the last option is optional, but recommended. So the conclusion is, if we have more than one condition to test, we use if-elif-else combination. If we have only one condition to test, a single if and else is enough. §2.8 Choosing function names You have to be really careful while choosing names for your functions or even variables. In general, while choosing names for your identifiers you should be intelligent enough to choose words different from existing names. But if we accidently create an identifier which coincides with an existing Python defined identifier, then? Your definition will be given preference compared to python’s own names. Python is very generous, and obedient. Let us see an example. K Vishnu Namboothiri -19- http://vishnu.e-lokam.com Chapter 2. Hands on python We have defined an absolute value function for real numbers with the name myabs(). There is a built-in absolute value function in python with name abs(). Create a file called duplicateabsfunction.py and enter the contents as follows: Code 2.31: duplicateabsfunction.py """ This file contains Vishnu’s absolute value function for real numbers This is different from python’s built in abs() function and it duplicates its name, and behaviour on real numbers.""" #recall the math definition of abs function def abs(a): """Finding absolute value of a""" if a < 0 : return −a else : return a Now in the python shell, execute the following commands one by one: Code 2.32: In the terminal/shell z = 10 + 15J abs(z) import duplicateabsfunction help(duplicateabsfunction) duplicateabsfunction.abs(z) from duplicateabsfunction import ∗ abs(z) The first line puts a complex number in the variable z. The second line finds its absolute value using the python built-in function abs(). The third line imports our duplicate definition file. The fourth one shows the DocString in the file, via a help command. The fifth one checks whether it is working. It will not(,), as we defined our abs() function for only real numbers. The sixth line brings each and every name in the duplicate file to our current name space. So now abs() is our duplicate function!. Trying to execute it gives the same error as in fifth line. We have completely lost our python friend abs()! To avoid this, one precaution is to define names in such a way that it won’t clash with the existing ones. Secondly, don’t import names from files to your name space unless it is really necessary. You could have equally used duplicateabsfunction.abs() in the just concluded shell session without any problem. To get back python’s own abs(), you may have to exit() from the shell and come back to start a new shell session. K Vishnu Namboothiri -20- http://vishnu.e-lokam.com 2.9. Defining names If we would like to import a function and would like to use it under some other name, we may used import as. For example, Code 2.33: In the terminal/shell >>> import math >>> from math import pi as PI >>> PI 3.141592653589793 >>> So, instead of math.pi, we can simply use PI. For C Programmers who are used to defining constants in uppercase letters, this example may seem to be very convenient. §2.9 Defining names A name in python is more or less like an identifier in C. It is a word (not a string: string is something which we enlcose in quote pairs) which we may use as variable, function name, etc. A name should start with an alphabet (A-Z, a-z)/ underscore ( ), and can contain alphanumerals/underscore. It is better if you start ordinary variable/function names with an alphabet. Exercises Ex. 2.16 — Write a complex absolute function and save it in a file complexabs.py. Ex. 2.17 — Use the above defined function to find the absolute value of a complex number in shell. Ex. 2.18 — Write a Fibonacci function fib() such that fib(n) will return the first Fibonacci number just after n. Ex. 2.19 — Write a program to find and display the Fibonacci numbers between two numbers m and n using the above defined function. K Vishnu Namboothiri -21- http://vishnu.e-lokam.com Chapter 3 LISTS IN PYTHON Let us continue with the GCD finding program example from previous chapters. There we learnt how to write a program which will find the GCD of three numbers at a time. But if we have to find the the GCD of a several numbers at a time, then what should we do? Of course we can keep on defining variables like a,b,c,d. . . , but this is practically not viable. Also, we may not exactly know at the time of writing our program that how many variables we may need for handling the numbers (when we do not like to restrict the number of numbers allowed by the program). §3.1 Defining and accessing lists For handling several numbers simultaneously (all of which we are going to use for a single purpose, say sorting, finding gcd etc) we need to use the list feature in python. Let us see an example using list. Enter the following code as listexample.py. Code 3.1: listexample.py # A simple program demonstrating a python list # Defining a ’non-empty’ list a = [’Vishnu’ , ’ is ’ , ’my’, ’name’, ’and my’, ’ year ’ , ’ of birth is ’ , 1981] # Using it print (a [0]) print (a [0][0]) print (a [1]) print (a [3]) print (a [3][2]) print (a [7] + 10) print (a [7][0]) and the result is Code 3.2: In the terminal/shell >>> 23 Chapter 3. Lists in python Vishnu V is name m 1991 Traceback (most recent call last ) : File ”/home/vishnu/Documents/Teaching/python teaching/listexample.py”, line 13, in < module> print (a [7][0]) TypeError: ’int ’ object is not subscriptable In the list named a we are storing different types of data. In the first item in the list a[0] (you are right ,; as in C, numbering of list elements start from 0, not from 1) keeps the value Vishnu. It is a string object and so it can be subscripted again to get the first character in this string like a[0][0]. But a[7] is of type int and so it cannot be subscripted again. Therefore, if we try to print (a[7][0] it will (and infact, it has) produce an error. Let us see the type of each element in the string. Save the below code as listexample2.py. Code 3.3: listexample2.py # A simple program demonstrating a python list, and showing the type of data it holds # Defining a ’non-empty’ list a = [’Vishnu’ , ’ is ’ , ’my’, ’name’, ’and my’, ’ year ’ , ’ of birth is ’ , 1981] # Using it print (a, type(a)) print (a [0], type(a[0])) print (a [0][0], type(a [0][0]) ) print (a [1], type(a[1])) print (a [3], type(a[3])) print (a [3][2], type(a [3][2]) ) print (a [7] + 10, type(a[7])) print (”Length of the list a is ” , len(a)) and the output in my system is is Code 3.4: In the terminal/shell [ ’Vishnu’, ’ is ’ , ’my’, ’name’, ’and my’, ’year’ , ’ of birth is ’ , 1981] <class ’ list ’> Vishnu <class ’str’> V <class ’str’> is <class ’str ’> name <class ’str’> m <class ’str’> 1991 <class ’int’> Length of the list a is 8 There are basically two datatypes in the above list: str and int. Note that there is no datatype like char which is used in C for handling single characters. In Python, a single character is a string of length 1. That’s it. The len() function gives the length of the list. K Vishnu Namboothiri -24- http://vishnu.e-lokam.com 3.1. Defining and accessing lists In C, the way to determine the length of an array is bit complicated. You should know the type of the array first (whether it is of type int, char, float etc.). Then use the code sizeof(a)/sizeof(int). The sizeof operator will not give the length of the array, but the number of bytes reserved for the array. Then you should divide the total number of bytes allocated for an array with the size of each item in the array. Note that, array elements cannot be of different type in C and so the division technique works perfectly. Now how do we print everything in the list. Of course we can print each element one by one. But instead, the for loop becomes very useful here. Save the below lines into listexample3.py Code 3.5: listexample3.py # listexample3.py # Program illustrating the use of for via a list example # Define the list a = [’Vishnu’ , ’ is ’ , ’my’, ’name’, ’and my’, ’ year ’ , ’ of birth is ’ , 1981] # Start printing, but before that, find the length of the list print (”Printing all the members in the list : ”) length = len(a) for i in range(0, length): print (a[ i ]) print (”Printing over”) and the output is Code 3.6: In the terminal/shell Printing all the members in the list: Vishnu is my name and my year of birth is 1981 Printing over Have you noticed that each of the print command directs its output to a new line? If we want all of them to be printed on one line, what should we do? Modify the print statement inside the for loop slightly to print (a[i], end = " ") and check the result. You can observe that now every item in the list appears in the same line, and that each of them are seperated by a space. Initially, they were seperated by a new line character \n (which forces each new item to start on a new line). We replaced the default end character, which is \n in the print output by a space. We can equally put end = "*" or what ever we like to appear as a separator for the printed list items. If we do not include the end argument, it will be taken by default as end = "\n". Note further that, the end argument indeed has to be K Vishnu Namboothiri -25- http://vishnu.e-lokam.com Chapter 3. Lists in python the end argument(!). It should be only as the last argument inside print(). Otherwise, an error like SyntaxError: non-keyword arg after keyword arg will be raised by Python. In python 2.x, the statement equivalent to print(a[i], end=" ") is print(a[i]), Note the comma at the end of the print statement. We have seen three more keywords in python in the last program: for, in, range. Unlike in C, for does not depend on testing an algebraic expression (like for(i=0;i<10;i++) in C ). The line for i in range(0, length): instructs the interpreter to execute the line below it, intended to it length times (that is for the variation of i in the range 0 to length, not including length. The maximum value i can reach is length-1.) 3.1.1 A better method for looping through list The below given code has the same effect as far as looping through a list is concerned. But it does not require finding the length of the list. Code 3.7: listexample4.py # listexample4.py # Program illustrating the use of for via a list example # Define the list a = [’Vishnu’ , ’ is ’ , ’my’, ’name’, ’and my’, ’ year ’ , ’ of birth is ’ , 1981] # Start printing, but before that, find the length of the list print (”Printing all the members in the list : ”) for x in a : print (x) print (”Printing over”) §3.2 More on the range function The official Python 3.1 documentation says: “range([start], stop[, step]) This is a versatile function to create iterables yielding arithmetic progressions. It is most often used in for loops. The arguments must be integers. If the step argument is omitted, it defaults to 1. If the start argument is omitted, it defaults to 0. The full form returns an iterable of integers [start, start + step, start + 2 * step, ...]. If step is positive, the last element is the largest start + i * step less than stop; if step is negative, the last element is the smallest start + i * step greater than stop. step must not be zero (or else ValueError is raised)” K Vishnu Namboothiri -26- http://vishnu.e-lokam.com 3.2. More on the range function One may create lists in python using the list() function together with the range() function as follows: Type the below given code into a file rangelist.py. Code 3.8: rangelist.py # rangelist.py # Create a list named b b=list(range(10)) # Apply the print function on it in different ways print (b) print (range(10)) print ( list (range(1, 11))) print ( list (range(0, 30, 5))) print ( list (range(0, 10, 3))) print ( list (range(0, −10, −1))) print ( list (range(0))) print ( list (range(1, 0))) print ( list ()) This will produce the output Code 3.9: In the terminal/shell >>> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] range(0, 10) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] [0, 5, 10, 15, 20, 25] [0, 3, 6, 9] [0, −1, −2, −3, −4, −5, −6, −7, −8, −9] [ ] [ ] [ ] The last three print() commands resulted in producing an empty list. Try to explain yourself the behaviour of the list(range()) combination in the other lines. One important thing you have to bear in mind is that, range cannot accept non integer step. Note that range(1, 10) does not help you to create a list containing 10 numbers. It will give numbers only from 1 to 9. You may verify this by entering list(range(1, 10)) in the python shell. 3.2.1 More examples using for Let us write a program which will accept an integer from the user, prepare a multiplication table for that number (that is, a list of products: the number × 1,2,. . . , 10) using the for, range combination. Save the following code in to multtable.py. Code 3.10: multtable.py # multtable.py # Program to find the multiplication table for a user given number K Vishnu Namboothiri -27- http://vishnu.e-lokam.com Chapter 3. Lists in python #Accept input from user n = int(input(”Ready to prepare multiplication table . Please enter a positive integer : ”)) print (” Multiplication table for n = ”,n) for i in range(1, 11): print ( i , ” ∗ ”, n, ” = ”, i ∗n) # Done! and the output should be Code 3.11: In the terminal/shell >>> Ready to prepare multiplication table . Please enter a positive integer : 7 Multiplication table for n = 7 1 ∗ 7 = 7 2 ∗ 7 = 14 3 ∗ 7 = 21 4 ∗ 7 = 28 5 ∗ 7 = 35 6 ∗ 7 = 42 7 ∗ 7 = 49 8 ∗ 7 = 56 9 ∗ 7 = 63 10 ∗ 7 = 70 The number columns are not properly aligned; let us do it using some extra formatters in print(). Modify the print statement in the above to print ("%2d * %2d = %3d" % (i, n, i*n)) You may save the file under a different name, say multtable2.py. Now check the output: Code 3.12: In the terminal/shell >>> Ready to prepare multiplication table . Please enter a positive integer : 7 Multiplication table for n = 7 1∗ 7= 7 2 ∗ 7 = 14 3 ∗ 7 = 21 4 ∗ 7 = 28 5 ∗ 7 = 35 6 ∗ 7 = 42 7 ∗ 7 = 49 8 ∗ 7 = 56 9 ∗ 7 = 63 10 ∗ 7 = 70 The numbers in the first two columns are given two spaces for proper alignment, and the third column is given three spaces. Had you used %02d and %03d replacing the corresponding formatting strings, the result would have been K Vishnu Namboothiri -28- http://vishnu.e-lokam.com 3.2. More on the range function Code 3.13: In the terminal/shell >>> Ready to prepare multiplication table . Please enter a positive integer : 7 Multiplication table for n = 7 01 ∗ 07 = 007 02 ∗ 07 = 014 03 ∗ 07 = 021 04 ∗ 07 = 028 05 ∗ 07 = 035 06 ∗ 07 = 042 07 ∗ 07 = 049 08 ∗ 07 = 056 09 ∗ 07 = 063 10 ∗ 07 = 070 The proper spacing of numbers is achieved via the use of the formatters %2d, %02d etc. in the print statement. Remember that, we started this chapter discussing about a GCD finding problem. We wanted to write a program to find GCD of an arbitrary number of numbers entered by the user. We can combine features of list and for for writing such a program. Let us analyse the following code (saved as file gcdmanynumberslist.py). Code 3.14: gcdmanynumberslist.py # Program gcdmanynumberlist.py # Find GCD of as many numbers as the user decides # Make an empty list, we will fill it later using user inputs! numberlist = list() # Equally we can use numberlist=[] n = int(input(”How many numbers you have to find GCD: ”)) # Start accepting input for i in range (0, n) : tray = int(input(”Enter number: ” )) numberlist.append(tray) # Appended the numbers in tray to the empty list to fill it # The list numberlist is no more empty! # You may check it (if you would like to,) via a print command: print (numberlist) import mygcdfunction # How many times we should invoke the mygcd()? # We have n numbers. So n-1 times # Find initially the gcd of first and second numbers, and then? gcdof2numbers = numberlist[0] for i in range(0,n−1) : gcdof2numbers = mygcdfunction.mygcd(gcdof2numbers,numberlist[i+1]) print (gcdof2numbers) # Show GCD in each step; in the first step, it is gcd of first and second numbers # This printing is not necessary, but throws some light into the internal computations K Vishnu Namboothiri -29- http://vishnu.e-lokam.com Chapter 3. Lists in python print (”You gave numbers ”, numberlist, ” and the final GCD is ”,gcdof2numbers) # Done! I can hear sounds from many mouths: ”Explain! Explain!” Ok! I will definitely do that. (1) numberlist = list() defines an empty list. That is, a list with no contents in it. It can be done in two ways, as mentioned in the comment after the program line. (2) n = int(input("How many numbers you have to find GCD: ")) asks user and gets the number of integers of which GCD has to be computed (3) tray = int(input("Enter number" )) defines a variable tray. As the name suggests, it is used to take (hold temporarily) the input from the user. We can code the program even without using such a variable, but for better readability, it seems to be a good tactic. (4) numberlist.append(tray): At each state when the user inputs a number, it is kept in tray and then the value in tray is appended to the list numberlist. The size of len(numberlist) keeps on increasing with every user input. (5) Now to the calculation part. If we have only two numbers to find the GCD, we need to use the mygcd() only once. If three numbers, then twice etc. Therefore, since we have n numbers, we need to calculate GCD n-1 times, taking two numbers each at a time. But wait. . . . Not all these three come from the numberlist. (6) Suppose that we have three numbers 9,15, and 33. Then initially gcdof2numbers will be assigned the value 9. Then inside the for loop, it will be reassigned the value mygcdfunction.mygcd(9,15) which is 3. Again, it will be reassigned the value mygcdfunction.mygcd(3,33) which is 3. Now i has the value 1 which is equal to n-2 and so the for loop breaks and gcdof2numbers carries the final GCD. 3.2.2 Another example using lists and for : simple sorting of numbers Given a list of numbers, we can sort them quickly using for loop. Let us see the code for it (and save it in sort.py) Code 3.15: sort.py # Program sort.py # Sort a list of numbers # Define the list of numbers which are to be sorted numberlist = [21, 17, 15, 8] lengthoflist = len(numberlist) for j in range(0, lengthoflist − 1) : K Vishnu Namboothiri -30- http://vishnu.e-lokam.com 3.3. Built-in Sort functions for i in range(j+1, lengthoflist) : if numberlist[j] > numberlist[i] : numberlist[j], numberlist[i] = numberlist[i], numberlist[j] # Swapping, in Python style, not C style! print (numberlist) # Used just for showing the manipulations taking place at each step print (numberlist) # The final, sorted list The print(numberlist) is kept inside the if block to see the changes happening in each step. It is not actually necessary for the functioning of the program. The output should be Code 3.16: In the terminal/shell >>> [17, 21, 15, 8] [15, 21, 17, 8] [8, 21, 17, 15] [8, 17, 21, 15] [8, 15, 21, 17] [8, 15, 17, 21] [8, 15, 17, 21] The numbers are sorted in the ascending order. Can you modify it to accept input from the user and sort it in the descending order? §3.3 Built-in Sort functions Python offers a built-in method as well as a function for sorting lists. If we have a list called samplelist, and we use samplelist.sort(), the list will get sorted. But if we use the sorted() function, then the list itself will not get sorted, but will return a copy of a sorted list. We may have to save the new list to another variable (or the same variable at the cost of loosing the previous un sorted list). Code 3.17: In the terminal/shell >>> numberlist = [1, 2, 3.5, 8, 7] >>> print (numberlist) [1, 2, 3.5, 8, 7] >>> print (sorted(numberlist)) [1, 2, 3.5, 7, 8] >>> print (numberlist) [1, 2, 3.5, 8, 7] >>> numberlist.sort() >>> print(numberlist) [1, 2, 3.5, 7, 8] The sort() method seems to be slightly faster than the sorted() function. See http:// stackoverflow.com/questions/1436962/python-sort-method-on-list-vs-builtin-sortedfunction. K Vishnu Namboothiri -31- http://vishnu.e-lokam.com Chapter 3. Lists in python Starting with Python 2.4, both list.sort() and sorted() added a key parameter to specify a function to be called on each list element prior to making comparisons. For example, here’s a case-insensitive string comparison1 : Code 3.18: In the terminal/shell >>> samplelist = ”I am learning Python programming”. split() >>> samplelist [ ’ I ’ , ’am’, ’ learning ’ , ’Python’, ’programming’] >>> sorted(samplelist) [ ’ I ’ , ’Python’, ’am’, ’ learning ’ , ’programming’] >>> sorted(samplelist, key = str.lower) [ ’am’, ’ I ’ , ’ learning ’ , ’programming’, ’Python’] >>> sorted(samplelist, key = str.lower, reverse = True) [ ’Python’, ’programming’, ’learning’, ’ I ’ , ’am’] >>> Have you noticed the difference? In the first sorted() application, the list was sorted giving uppercase letters a priority (which is the default behaviour of Python). In the second sorted() where a key was used, that key was applied to the list items before sorting them. Here the key applied was a function which will convert alphabets in a string to lower case (str.lower()). In the last example, the argument reverse = True reverses the default sorting behaviour from ascending order to descending order. This argument works well with the sort() method also. §3.4 Looping in Python: Extras For looping, mainly we use for and while keywords. We have already seen how to use these in examples. To enhance the capability of decision making while in loops, just like C, Python also offers two extra keywords which are to be used only in loops. They are break and continue. break causes the termination of execution of statements in the loop where as continue takes the place of execution straight away to the beginning of the loop. Note that, continue does not simply instruct the loop to be continued, it makes the program move to the beginning of the loop in which it is used. Let us first write a primality checking program using break. Code 3.19: checkPrimality.py # Program checkPrimality.py. Python 3.x # This program checks whether an integer given by a user is a prime or not. This will not check 0, or 1 for primality. n =int(input (”Please enter an integer other than 0, 1, −1 to check for primality : ”)) m = abs(n) # Take the absolute value of n 1 Example inspired by http://wiki.python.org/moin/HowTo/Sorting/ K Vishnu Namboothiri -32- http://vishnu.e-lokam.com 3.4. Looping in Python: Extras foundDivisor = False # Variables like this one are usually called as flags, as they indicate something, some situation; nothing else. import math from math import sqrt for q in range (2, int (sqrt(m)+1)) : if m % q == 0 : # If one q divides it, that is , remainder equal to 0, then it is not a prime. print (”The number %d is not a prime; %d divides it ” % (n, q)) foundDivisor = True break; if foundDivisor == False : print (”The number %d is a prime” % n) #If no number up to sqrt(m) divides m, then it is a prime Now let us see a modified version to check the primality of as many numbers as the user wants. If the user wants to stop, he has to enter 0. If he enters ±1 the program will continuously turn back to him asking for another input. This is achieved via the continue keyword. See it in action. Code 3.20: check_primality_many.py # Program check_primality_many.py # This program checks whether an integer given by a user is a prime or not. This will not check 0, or 1 for primality. checkPrimality = True while checkPrimality : n =int(input (”Please enter an integer other than 0, 1, −1 to check for primality , 0 to stop : ”)) if n == 0 : print (”Quitting. Bye . . . ”) break # The user wants to stop if n == 1 or n == −1 : print (” Invalid number. Try again”) continue # The user is not allowed to enter 1 or -1. If he wants to quit, he should enter 0. m = abs(n) # Take the absolute value of n foundDivisor = False # Variables like this one are usually called as flags, as they indicate something, some situation; nothing else. import math from math import sqrt K Vishnu Namboothiri -33- http://vishnu.e-lokam.com Chapter 3. Lists in python for q in range (2, int (sqrt(m)+1)) : if m % q == 0 : # If one q divides it, that is , remainder equal to 0, then it is not a prime. print (”The number %d is not a prime; %d divides it ” % (n, q)) foundDivisor = True break; # for loop ends if foundDivisor == False : print (”The number %d is a prime” % n) #If no number up to sqrt(m) divides m, then it is a prime # while loop ends 3.4.1 else clause in loops The official documentation says ( [1], page 21) “Loop statements may have an else clause; it is executed when the loop terminates through exhaustion of the list (with for) or when the condition becomes false (with while), but not when the loop is terminated by a break statement.” In the above example checking primality of a number, instead of using the flag founDivisor, we could have just used the else clause after the for loop to get the same effect. (In fact, one of my students pointed out this better method to me!) Exercises Ex. 3.1 — Try the end keyword with arguments\r,\b,\f and observe the results. Ex. 3.2 — What is the result of the following code? mylist = list(’abcd’) print (mylist) Ex. 3.3 — Try list(range()) starting with a negative integer. Ex. 3.4 — Print the first 10 even natural numbers using for and range. Ex. 3.5 — Print the first 100 natural numbers, and against them, print which of them are multiples of 3 using for and range. Ex. 3.6 — Define a factorial function. Use this to find nCr and nPr (combination/permutation of n objects taken r at a time). Ex. 3.7 — Write a programme to print squares and cubes of all natural numbers up to a user given number n. K Vishnu Namboothiri -34- http://vishnu.e-lokam.com 3.4. Looping in Python: Extras Ex. 3.8 — Define a mymax() function in the file myfunctions.py to find the largest number from a given list. Write a program to find the largest number from a user given list using this function. Ex. 3.9 — Modify the above program sort.py to 1) accept numberlist from user, 2) sort the list in ascending order. Save the files as sortinput.py and sortinput_descending.py. Ex. 3.10 — Verify prime factorization theorem for a given number Ex. 3.11 — Find all solutions of 3x ≡ 1(mod 5) in the range 1 to 30 Ex. 3.12 — You know Zn , the set of all congruence classes modulo n. We usually denote the classes using numbers 0, . . . , n−1. Using the mygcd() function, can you find which of these numbers have multiplicative inverse in Zn (that is, how many of them are relatively prime to n)? Ex. 3.13 — Find 3.4.2 Pk 1 n=1 n , and show that it can be made as large as we please. More examples using lists: have some fun; play with the system How to calculate one’s age from his date of birth? Simple: find the current year, subtract the year of birth from current year. Put the below given code in findage.py to try this method. Code 3.25: findage.py # Program findage.py # Define a list, consisting of a few details like name, etc. Year of birth compulsory in the list, as the last item a = [’Vishnu’ , ’ is ’ , ’my’, ’name’, ’and my’, ’ year ’ , ’ of birth is ’ , 1981] import datetime # A built-in Python module for handling date and time related manipulations # Try help(datetime) for details, after importing it now = datetime.datetime.now() print (”The system time now is ”, now) # The system time now current year = now.year current month = now.month current hour = now.hour print (”Current year is %d, month is %s, and hour is %d” %(current year, current month, current hour )) age = current year − a[len(a) − 1] print(”Name of the person is %s, year of birth %d and so age is %d” % (a[0], a[len(a) − 1], age)) The output is Code 3.26: In the terminal/shell The system time now is 2013−01−14 12:59:33.620262 K Vishnu Namboothiri -35- http://vishnu.e-lokam.com Chapter 3. Lists in python Current year is 2013, month is 1, and hour is 12 Name of the person is Vishnu, year of birth 1981 and so age is 32 Check the documentation for details on all other possibilities in the module datetime. You may also try help(datetime) in the Python shell. One more list example: To understand the behaviour of the range function combined with list, let us try the following code in the Python shell. Code 3.27: In the terminal/shell >>> print (list(range(1,10))) [1, 2, 3, 4, 5, 6, 7, 8, 9] >>> print (range(1,10)) range(1, 10) >>> print (list(range(1,10))) [1, 2, 3, 4, 5, 6, 7, 8, 9] >>> print (len(list(range(1,10)))) 9 >>> print (list(range(1,10))[0]) 1 >>> print (list(range(1,10))[9]) Traceback (most recent call last ) : File ”<stdin>”, line 1, in <module> IndexError: list index out of range >>> print (list(range(1,10))[8]) 9 The range function just provides a range of values to list. You will understand this better if you have already tried the exercise list(’abcd’). It does not in itself create a list of values. For that purpose, the list function is invoked. You may also see that Python follows the C convention of counting array elements from 0 onwards). In Python 2.x, range used to produce a list, where as in python 3.x it is not so. So print (range(1,10)) will simply throw you back the result as range(1, 10). But in Python 2.x, print range(1, 10) would have given a list of 9 numbers, as desired. 3.4.3 C arrays and Python lists Unlike arrays in C, python lists are quiet flexible. Recall that we have defined a = [’Vishnu’, ’is’, ’my’, ’name’, ’and my year of birth is’, 1981] Here the list a is actually a list of lists! For example, the item a[0] will give an array of characters in the C sense (Vishnu) where as a[0][0] will just give the single character V. In C, we call such a combination of characters (or chars) to be a two dimensional array. That’s not all! We have more freedom in lists as far as datatypes are concerned. Mixed datatypes are allowed in a list. a consists of not just alphabets or strings, it consists of integers too. 3.4.4 Slicing lists In the shell, execute the following: K Vishnu Namboothiri -36- http://vishnu.e-lokam.com 3.4. Looping in Python: Extras Code 3.28: In the terminal/shell >>> a = [’Vishnu’, ’is’, ’my’, ’name’, ’and my year of birth is ’ , 1981] >>> a [ ’Vishnu’, ’ is ’ , ’my’, ’name’, ’and my year of birth is ’ , 1981] >>> a[:3] [ ’Vishnu’, ’ is ’ , ’my’] >>> a[1:4] # Print all from 1 to 4 [ ’ is ’ , ’my’, ’name’] >>> a[0 : len(a)] [ ’Vishnu’, ’ is ’ , ’my’, ’name’, ’and my year of birth is ’ , 1981] >>> a[0 : len(a)] + [’ Are you happy now?’] # Concatenated output [ ’Vishnu’, ’ is ’ , ’my’, ’name’, ’and my year of birth is ’ , 1981, ’ Are you happy now?’] >>> a # But nothing actually happened to a! [ ’Vishnu’, ’ is ’ , ’my’, ’name’, ’and my year of birth is ’ , 1981] >>> a[0][0] ’V’ >>> a[0][0] = ’J’ # Try to change the first character in the first list item Traceback (most recent call last ) : File ”<stdin>”, line 1, in <module> TypeError: ’str ’ object does not support item assignment >>> a[0] = ’K V Namboothiri’ >>> a [ ’K V Namboothiri’, ’is’ , ’my’, ’name’, ’and my year of birth is ’ , 1981] >>> a[1] = [] >>> a [ ’K V Namboothiri’, [], ’my’, ’name’, ’and my year of birth is ’ , 1981] >>> a[1:3]=[] >>> a [ ’K V Namboothiri’, ’name’, ’and my year of birth is’ , 1981] >>> a[0]=a >>> a [[...], ’name’, ’and my year of birth is ’ , 1981] >>> a[0]=’Vishnu’ >>> a [ ’Vishnu’, ’name’, ’and my year of birth is ’ , 1981] Most of the above statements must be clear to you now. The operation we applied on the indices of the list a is called slicing. The statement a[start:stop]=[] removes all the list items between the given indices (from start to stop - 1). We can change the value of a list item completely, but not partially as depicted by the lines a[0][0]=’J’ and a[0]=’K V Namboothiri’. The line a[:] is exactly the same as a[firstindex:lastindex]. To append an item to the end of a list, use the append function. So a.append(’name’) will put the last item of a as the string ’name’. To remove a single list item, we may use the del keyword. So del a[index] removes the item a[index] from the list. For removing an item from a list and saving it to another variable at the same time, pop function can be used. Thus tray = a.pop(index) removes the item a[index] from the list, but at the same time puts its value inside tray. The function remove searches and removes the first occurrence of a specified item. See the following execution: K Vishnu Namboothiri -37- http://vishnu.e-lokam.com Chapter 3. Lists in python Code 3.29: In the terminal/shell >>> a [ ’Vishnu’, ’name’, ’and my year of birth is ’ , 1981] >>> a[1:3]=[] >>> a [ ’Vishnu’, 1981] >>> a.append(’name’) >>> a [ ’Vishnu’, 1981, ’name’] >>> del a[2] >>> a [ ’Vishnu’, 1981] >>> tray = a.pop(0) >>> a [1981] >>> tray ’Vishnu’ >>> a = [’Vishnu’, ’is’, ’my’, ’name’, ’and my year of birth is ’ , 1981] >>> a [ ’Vishnu’, ’ is ’ , ’my’, ’name’, ’and my year of birth is ’ , 1981] >>> a.append(1982) >>> a.append(1981) >>> a [ ’Vishnu’, ’ is ’ , ’my’, ’name’, ’and my year of birth is ’ , 1981, 1982, 1981] >>> a.remove(1981) >>> a [ ’Vishnu’, ’ is ’ , ’my’, ’name’, ’and my year of birth is ’ , 1982, 1981] If we suspect that there is an item present in a list and would like to remove it completely, we have to use remove() as many times as the item is present in the list. But how do we know the number of times an item is present in a list? There is a better alternative. Code 3.30: In the terminal/shell >>> a = [’Vishnu’, ’is’, ’my’, ’name’, ’and my year of birth is ’ , 1981, 1982, 1981] >>> a [ ’Vishnu’, ’ is ’ , ’my’, ’name’, ’and my year of birth is ’ , 1981, 1982, 1981] >>> while 1981 in a: a.remove(1981) >>> a [ ’Vishnu’, ’ is ’ , ’my’, ’name’, ’and my year of birth is ’ , 1982] The while loop with the condition item in list (here 1981 in a) applies the remove() method on the list as long as 1981 is present in the list. Note that, if we try to remove an item from a list without checking for its existence, an error will be raised by Python. If we have more than one item to append to a list, we may use the extend() method. Therefore, the line a.extend([list items seperated by comma]) will append all the items given in the list inside extend() to a. The below code is the continuation of the above shell session. K Vishnu Namboothiri -38- http://vishnu.e-lokam.com 3.5. Advanced features of lists Code 3.31: In the terminal/shell >>> a.extend([”and”, ”my”, ”country”, ”is”, ”India”]) >>> a [ ’Vishnu’, ’ is ’ , ’my’, ’name’, ’and my year of birth is ’ , 1982, ’and’, ’my’, ’country’, ’ is ’ , ’India’ ] The reverse statement reverses the order of a list of items. So if we have a number of items to insert to the beginning, we can reverse the list, append the items, and reverse it again to bring the appended items to the front! An insert statement is also available to insert an item from a specified index. So a.insert(index, ’Namboothiri K’) makes the item at position index to be ’Namboothiri K’ and pushes the items remaining to the right of the new item. See the following code. Code 3.32: In the terminal/shell >>> a [ ’Vishnu’, ’ is ’ , ’my’, ’name’, ’and my >>> a.reverse() >>> a [1981, 1982, ’and my year of birth is ’ , >>> a.reverse() >>> a [ ’Vishnu’, ’ is ’ , ’my’, ’name’, ’and my >>> a.remove(1982) >>> a [ ’Vishnu’, ’ is ’ , ’my’, ’name’, ’and my >>> a.insert(1, ’Namboothiri K’) >>> a [ ’Vishnu’, ’Namboothiri K’, ’is ’ , ’my’, §3.5 year of birth is ’ , 1982, 1981] ’name’, ’my’, ’ is ’ , ’Vishnu’] year of birth is ’ , 1982, 1981] year of birth is ’ , 1981] ’name’, ’and my year of birth is ’ , 1981] Advanced features of lists We have already seen most of the key features of Python. But to use it more effectively, let us see some special properties of lists which make them different from the C style array or structure. 3.5.1 Lists as stacks You know the basic meaning of a stack: a pile of objects, typically one that is neatly arranged: For example, a stack of boxes, stack of books etc. In computer science, it has a more or less similar meaning. Wikipedia says “In computer science, a stack is a particular kind of abstract data type or collection in which the principal (or only) operations on the collection are the addition of an entity to the collection, known as push, and removal of an entity, known as pop. The relation between the push and pop operations is such that the stack is a Last-In-First-Out (LIFO) data structure. In a LIFO data structure, the last element added to the structure must be the first one to be removed. This is equivalent to the requirement that, considered as a linear data structure, or more abstractly a sequential collection, the push and pop operations occur only at one end of the structure, referred to as the top of the stack. Often a peek or top operation is also implemented, returning the value of the top element without removing it.” K Vishnu Namboothiri -39- http://vishnu.e-lokam.com Chapter 3. Lists in python r Figure 3.1: The way in which a Stack behaves r Figure 3.2: How does a queue work? Therefore, the basic property of a stack is that, the last element added is the first element retrieved (last-in, first-out). To add an item to the top of the stack, use append(). To retrieve an item from the top of the stack (and remove it at the same time from the top), use pop() without an explicit index. We have already seen these in Code 3.29. 3.5.2 Using lists as queues What is a queue? If we have a set of objects which are in queue the first object entered into the queue should exit it first. That is, it follows a first in, first out mechanism to process its elements.0 In a queue, items are added to the end of the queue, and they are taken out (removed) from the beginning. Similarly, if we have a list, we can append() items to the lists (to the end), and remove the very first item in the list via pop(0) command. Let us see the following example which defines a list, and uses it as a queue. In this example, assume that three people Raju, Radha, and Maya in the same order comes to a bank counter for making payments. They have to be given service in the order in which they reached the bank. Whoever came first should go first after finishing transactions. Code 3.33: queue_example.py # Program using list as queue: queue_example.py #When the bank opens, nobody in the bank, so our list is empty! a = [] K Vishnu Namboothiri -40- http://vishnu.e-lokam.com 3.5. Advanced features of lists print(a) # See the queue # One person comes: Raju a . append(”Raju”) #The bank clerk is yet to start transacting: So Raju is the first person now in the queue print(a) # See the queue # One more person: Radha a . append(”Radha”) print(a) # See the queue # Clerk has started transaction. But who has to be serviced first? Obviously, Raju # After the service, his name has to be removed from the queue a . pop(0) print(a) # See the queue # Two more persons comes: Maya, Kuttu a . append(”Maya”) a . append(”kuttu”) print(a) # See the queue # Service rendered to Radha first, then Maya, then kuttu a . pop(0) print(a) # See the queue a . pop(0) print(a) # See the queue a . pop(0) print(a) # See the queue And the output is Code 3.34: In the terminal/shell [] [ ’Raju’] [ ’Raju’, ’Radha’] [ ’Radha’] [ ’Radha’, ’Maya’, ’kuttu’] [ ’Maya’, ’kuttu’] [ ’kuttu’] [] K Vishnu Namboothiri -41- http://vishnu.e-lokam.com Chapter 3. Lists in python Please see [1], section 5.1.2. for technical details on lists as queues. 3.5.3 New lists from old Python offers some fancier operations too on lists to generate new ones. In addition, these newly generated lists can have some logical connections with the old lists. For example, suppose that we have a set of numbers in a list. Let us see how to create a list of squares from the list in our hand. Then we will try to create ordered pairs consisting of items in our first list and cubes of those items. Also, we will apply some filtering to the ordered pairs later. Code 3.35: newlists_from_old.py # Program newlists_from_old.py #Gerating a list of numbers; the easy way! a = list(range(2,100)) print (”The list a is \n”, a) # A new list from a; squaring all the numbers in a square a = [x∗∗2 for x in a] print (”The list of squares in a is \n”,square a) # Make it a bit more complex, list of ordered pairs consisting of numbers from a as first co-ordinate, its cube as the second one a acube pairs = [[x, x∗∗3] for x in a] print (”The list of ordered pairs is \n”,a acube pairs) # Let us now check which of the items in a are cubes, and print them cubes in a = [x for x in a if (round(pow(x, 1/3)))∗∗3== x] # The above line uses two built-in functions: round, and pow print(”Cubes in a\n”,cubes in a) Try out the above exercise, execute it. Lists are quite flexible. It allows operations using for, if . . . inside it making the life easier. Lists can be nested and can be used in many practical situations. Please see section 5.1.2 of [1]. Exercises Ex. 3.14 — Make a list of three-tuples using the above techniques: the first co-ordinate a should consist of all odd numbers from 3 to 99, second co-ordinate its squares, third co-ordinate its cubes. K Vishnu Namboothiri -42- http://vishnu.e-lokam.com 3.5. Advanced features of lists The round() function is a built-in Python function which does not require any module import. Its structure is round(number[, ndigits]) where number is the number to be rounded off, ndigitis is the number of digits after the decimal point. ndigits can be even negative. Can you guess the effect of round(123.456,-2)? The pow() function is simlarly another built-in Python function. Its structure is pow(x, y[, z]). It returns x to the power y; if z is present, returns x to the power y, modulo z (computed more efficiently than pow(x, y) % z). The two-argument form pow(x, y) is equivalent to using the power operator: x**y. We had a great session on lists. Let expand our experience: Exercise! Exercises Ex. 3.15 — Find Fibonacci numbers up to 100. Ex. 3.16 — Write a program to reverse the letters in a string. For example, if the input is Vishnu’ the output should be ’unhsiV’. Ex. 3.17 — Prepare an addition table of a given number (It should produce 10 rows.) Ex. 3.18 — Remember that a number is a prime number if it is divisible by atmost two numbers: 1 and the number itself. Write a program to find whether a given number is a prime. Ex. 3.19 — Use the above program to prepare a function which will return 1 if the given number is a prime, 0 else. Use it to print all primes up to 100. Ex. 3.20 — Have you ever heard of the Sieve of Eratosthanese 2 ? Implement it in a python program to list all primes and non primes up to 100. A Sample output could be Code 3.37: In the terminal/shell Composite numbers up to 100 [4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 9, 15, 21, 27, 33, 39, 45, 51, 57, 63, 69, 75, 81, 87, 93, 99, 25, 35, 55, 65, 85, 95, 49, 77, 91] Composite numbers up to 100 (sorted) [4, 6, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21, 22, 24, 25, 26, 27, 28, 30, 32, 33, 34, 35, 36, 38, 39, 40, 42, 44, 45, 46, 48, 49, 50, 51, 52, 54, 55, 56, 57, 58, 60, 62, 63, 64, 65, 66, 68, 69, 70, 72, 74, 75, 76, 77, 78, 80, 81, 82, 84, 85, 86, 87, 88, 90, 91, 92, 93, 94, 95, 96, 98, 99, 100] Prime numbers up to 100 [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] 2 See B.5 for an explanation K Vishnu Namboothiri -43- http://vishnu.e-lokam.com Chapter 4 DATA TYPES: A DETAILED VISIT Python offers several datatypes. Its basket is very rich like most of the other modern programming languages. §4.1 Numeric Types We have already seen and used all these types of data: int (integer), float (floating point or decimal numbers), complex (complex numbers with a possible non zero imaginary part). Let us see an example showing different types of list, and their official names in Python. Code 4.1: display_type.py # Program display_type.py: Displays datatypes/data classes of items from a list. mixed list = [20, 20.5, 20 + 30j, ”Twenty”, [1, 2]] # Now loop through the list, and print it for x in mixed list: print (x,” : ”, type(x)) and the output is Code 4.2: In the terminal/shell >>> 20 : <class ’int ’> 20.5 : <class ’ float ’> (20+30j) : <class ’complex’> Twenty : <class ’str ’> [1, 2] : <class ’ list ’> As we have already seen, the complex class consists of a real and imaginary part. So if a = 2 + 3j then a.real is 2 and a.imag is its imaginary part. Infact, by definition, a complex number a is equal to a.real + a.imag*1j. The complex imaginary part specifier j should appear only on the right of a float. Therefore, 2 + j is wrong, and the correct usage is 2 + 1j. 45 Chapter 4. Data types: a detailed visit Note that, you can reassign a value to a, but you cannot change its real or imaginary part separately. See the following example. Code 4.3: complex_reassign.py # Program complex_reassign.py a = 2 + 3j print (a.real , a . imag) a . real = 4 # Wrong. This is not allowed a . imag = 5 # Wrong. This is not allowed a= 4 + 5j # Correct. and the output is Code 4.4: In the terminal/shell >> 2.0 3.0 Traceback (most recent call last ) : File ”/home/vishnu/Documents/Teaching/python teaching/complex reassign.py”, line 7, in <module> a. real = 4 # Wrong. This is not allowed AttributeError: readonly attribute The first line prints the real and imaginary parts as floats without any complaint! But the real, imaginary part independent reassignment fails.The same thing happened previously when we tried to change the part of string. (Do you remember when it was?) Two built-in functions are there to convert (or rather, try to convert) strings into numbers. They are again called as int and float. For example, int(2.5) will return the value as 2, where as float (3-2j) will result in an error. These two conversions are compulsory with user inputs. Therefore, for example, if we have to accept an integer from user via keyboard, and want to save it into variable number, then we should do it like number = int (input("Enter number")). There is no default technique in Python to accept complex number inputs. Instead, we may accept an a+bj as a string and then eval()uate them into a complex number. See the following example: Code 4.5: complex_input.py # Program complex_input.py # Accept two complex numbers and find their sum z1 = input(”Enter a complex number in the format a+bj: ”) z2 = input(”Enter a complex number in the format a+bj: ”) print (”Sum of numbers entered is ”, z1 ∗ z2) # This is not wrong syntactically. But the result will not be the sum of numbes! Just try and see # Let us evaluate the "strings/expressions" entered into complex numbers K Vishnu Namboothiri -46- http://vishnu.e-lokam.com 4.2. Tuples z1 = eval(z1) z2 = eval (z2) # Now see the sum print (”Sum of numbers entered is ”, z1 + z2) and the result of running it is Code 4.6: In the terminal/shell >>> Enter a complex number in the format a+bj: 2+1j Enter a complex number in the format a+bj: 1+2j Sum of numbers entered is 2+1j1+2j Sum of numbers entered is (3+3j) The first print before eval()uating z1 and z2 interpreted + as the concatenation operator on strings. But second time, the + was read as the mathematical addition operator. §4.2 Tuples A tuple consists of a number of values separated by commas. In python, a tuple looks more or less the same as a list. But it can be defined in a more free manner. Let us see the following shell session: Code 4.7: In the terminal/shell >>> mytuple = ’abc’, ’pqr’ # Equivalently, mytuple = (’abc’, ’pqr’) >>> mytuple ( ’abc’, ’pqr’) >>> mytuple[0] ’abc’ >>> mytuple[1] = ’xyz’ Traceback (most recent call last ) : File ”<pyshell#17>”, line 1, in <module> mytuple[1] = ’xyz’ TypeError: ’tuple’ object does not support item assignment >>> mytuple = ’abc’, ’xyz’ >>> mytuple ( ’abc’, ’xyz’) In the above shell session, a tuple item was attempted to modify. It resulted in an error. But in a list, this is very much allowed. This is probably the most striking difference between a list and a tuple. A tuple is a constant (immutable) list. But it can be changed as a whole, as seen in the last assignment above. This behaviour is acceptable, for example, if you want to create co-ordinates of a point. You are not going to change the parts of an ordered pair or tuple. Tuple also can have mixed data types in it. It can have even tuples inside it as items. Note: To create an empty tuple you have to use mytuple = (). Remember that mylist = [] or mylist = list() will create an empty list. To create a singleton tuple? Sorry, mytuple = ’abc’ is K Vishnu Namboothiri -47- http://vishnu.e-lokam.com Chapter 4. Data types: a detailed visit not enough, mytuple = ’abc’, should be used instead. (Note the comma at the end). In the shell, try mytuple = ’abc’ and then print(type(mytuple)) and see the result to convince yourself! 4.2.1 Accepting tuple inputs There is no built-in technique to accept a tuple as a user input. But the input() function can accept it as a string and convert later it into a tuple via the eval() function as shown in the next program: Code 4.8: acceptTupleInput.py # Program to accept tupple input: acceptTuppleInput.py mytuple = input(”Enter an ordered pair in the form (a,b): ”) # Accepted it as a string print (type(mytuple), mytuple) # Using eval() to convert it into a tupple print (type(eval(mytuple)), eval(mytuple)) Exercises Ex. 4.1 — Acccept a tuple from user and inform two which dimensional plane it belongs to. Ex. 4.2 — Accept two points in the plain/space (say (2, 3), (5, 7)) as ordered pairs/tuples, and find the distance between them using the usual distance function on the 2-dimensional/3-dimensional plane. §4.3 Sorting iterables: Extras We have already seen how to apply the sort() method and sorted() function on list items in section 3.3. The same two methods apply well in the case of tuples. (Sorting dictionaries seems to be bit complex!). But when you have a list of tuples, or list of lists, sorting them can become a nighmare. Default sorting techniques sort only by the very first argument in a list/tuple. See the below given example. Code 4.10: In the terminal/shell >>> students = [(’vishnu’, 31), ( ’kesav’ , 58)] >>> sorted(students) [( ’kesav’ , 58), ( ’vishnu’ , 31)] >>> studentstuple = tuple(students) >>> studentstuple (( ’vishnu’ , 31), ( ’kesav’ , 58)) >>> sorted(studentstuple) [( ’kesav’ , 58), ( ’vishnu’ , 31)] >>> K Vishnu Namboothiri -48- http://vishnu.e-lokam.com 4.3. Sorting iterables: Extras 4.3.1 The lambda functions The magical lambda keyword comes here as a saviour. Let us have a detailed look into its features1 . The keyword lambda is used to create anonymous functions in Python. See the following example to have a hands on experience. Code 4.11: In the terminal/shell >>> def f(x): return x∗∗2 >>> print (f(8)) 64 >>> g = lambda x: x∗∗2 >>> print (g(8)) 64 As you can see, f() and g() do exactly the same and can be used in the same ways. Note that the lambda definition does not include a return statement; it always contains an expression which is returned. 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. It may be treated as an inline function (and seems to be close to the macro function definitions in C). You may pass a lambda function definition as an argument to another function! Code 4.12: In the terminal/shell >>> mult3 = filter(lambda x: x % 3 == 0, [1, 2, 3, 4, 5, 6, 7, 8, 9]) >>> list(mult3) [3, 6, 9] Have you seen the effect of the lambda function? In the above shell session, when ever an x is encountered, it is matched against the condition x % 3 == 0 and x is returned if the condition turns out to be true. The filter() function together with the lambda definition plays the trick here. filter() accepts two arguments: the first one is a function (real or lambda), and the second one is the parameter for the first argument. If the function returns True for a parameter, that parameter will be added to a list the name of which appears to the left of filter(). So in the above case, each x in the list is passed to the lambda function, and if it turns out to be true, it is put into the variable mult3 to generate a filter object. It is then converted in to a list in the next statement. To sort a list of lists or list of tuples, the sorted + lambda combination works very well. Let us revisit our previous example. Code 4.13: In the terminal/shell >>> sorted(students) [( ’kesav’ , 58), ( ’vishnu’ , 31)] 1 Taken from http://stackoverflow.com/questions/8966538/syntax-behind-sortedkey-lambda and http://www.secnetix.de/olli/Python/lambda_functions.hawk K Vishnu Namboothiri -49- http://vishnu.e-lokam.com Chapter 4. Data types: a detailed visit >>> sorted(students, key = lambda mylist: mylist[1]) [( ’vishnu’ , 31), ( ’kesav’ , 58)] Here the sorted() function sorts the lists (or tuples) based on the key instead of the first item among the lists (tuples). The lambda function returns from each item in students the first item. So, when it takes (’kesav’, 58), the sorting takes place based on 58, and when it takes (’vishnu’, 31), the sorting takes place based on 31. Note that, we can define more complex lambda function to achieve sorting of objects in a much complex manner. §4.4 Sets A set is an unordered collection with no duplicate elements. Set objects also support mathematical operations like union, intersection, difference, and symmetric difference. Curly braces or the set() function can be use to create sets. Note: To create an empty set you have to use myset = set(), not myset = { }. The statement myset = { } creates an empty dictionary, a data structure that we discuss in the next section. The most important aspect of a set is that, if you have a list consisting of (possibly) duplicate data in it, then converting it into a set and then back to a list will filter all duplications out. The method is described in the next example. Code 4.14: set_example.py # Removing duplicates from a list using set # Algebra students algebra students = [’Raju’, ’Radha’, ’Luttu’ , ’Daki’ , ’ Hrishi ’ ] real analysis students = [’Maya’, ’Kuttu’, ’ Hrishi ’ , ’Raju’ , ’Radha’] all students set = set(algebra students) | set(real analysis students) all students list =list(all students set) print( all students list ) # Now an alphabetically sorted list all students list . sort () print( all students list ) and the output is Code 4.15: In the terminal/shell >>> [ ’Maya’, ’Radha’, ’Daki’, ’ Hrishi ’ , ’Luttu’, ’Kuttu’, ’Raju’] [ ’Daki’, ’ Hrishi ’ , ’Kuttu’, ’Luttu’, ’Maya’, ’Radha’, ’Raju’] The way in which mathematical set operations are carried out can be seen in the next example. Its output follows the code. Code 4.16: set_example2.py K Vishnu Namboothiri -50- http://vishnu.e-lokam.com 4.4. Sets # Defining three lists of students attending three different courses # then converting them into sets using set(), and applying operations on them algebra students = [’Raju’, ’Radha’, ’Luttu’ , ’Daki’ , ’ Hrishi ’ ] real analysis students = [’Maya’, ’Kuttu’, ’ Hrishi ’ , ’Raju’ , ’Radha’] computer students = [’Vishnu’, ’Maya’, ’Hrishi’ , ’ Priya ’ , ’Luttu’ ] # Let us find students taking all the three courses: mathematically, intersecting the sets common students = set(algebra students) & set(real analysis students) & set( computer students) print(”Common Students: ”, common students) # Let us now show the list of all the students, without repetition: mathematically, taking union all students = set(algebra students) | set(real analysis students) | set(computer students) print (”List of all students : ”, all students) # Students attending exactly one course only one course students = (set(algebra students)− (set(real analysis students) | set( computer students))) | set(real analysis students)− (set(algebra students) | set( computer students))) | (set(computer students)− (set(algebra students) | set( real analysis students))) print(”Students attending exactly one course : ”, only one course students) # Students attending exactly one of computer course or real only computer real course students = set(computer students)ˆ set(real analysis students) print (”Students attending exactly one of computer or real : ”, only computer real course students) Code 4.17: In the terminal/shell >>> Common Students: {’Hrishi’} List of all students: {’Maya’, ’Radha’, ’Daki’, ’Vishnu’, ’ Hrishi ’ , ’Luttu’, ’Kuttu’, ’Priya ’ , ’Raju’} Students attending exactly one course: {’Priya’ , ’Daki’, ’Kuttu’, ’Vishnu’} Students attending exactly one of computer or real: {’Radha’, ’Vishnu’, ’Luttu’, ’Kuttu’, ’ Priya’ , ’Raju’} Sets, unlike lists, does not allow indexing or slicing. The only way to access elements individually is to iterate through the set. The following example prints the individual elements in a set. Code 4.18: set_printing_elements.py # How to access set elements individually # The following method simply prints the elements in a set, the order in which they are appearing in the set. algebra students = [’Raju’, ’Radha’, ’Luttu’ , ’Daki’ , ’ Hrishi ’ ] for x in algebra students : print (x) K Vishnu Namboothiri -51- http://vishnu.e-lokam.com Chapter 4. Data types: a detailed visit It allows a pop() to remove arbitrarily an element from the set, and an add() method to add elements to a set. Code 4.19: modify_set.py algebra students = {’Raju’, ’Radha’, ’Luttu’ , ’Daki’ , ’ Hrishi ’} print (algebra students) algebra students.pop() # Remove one element; but which one? print (algebra students) algebra students.pop() # Remove again print (algebra students) algebra students.add(”Manu”) # Add one element print (algebra students) Code 4.20: In the terminal/shell >>> {’Hrishi ’ , ’Luttu’, ’Raju’, ’Radha’, ’Daki’} {’Luttu’, ’Raju’, ’Radha’, ’Daki’} {’Raju’, ’Radha’, ’Daki’} {’Radha’, ’Daki’, ’Raju’, ’Manu’} Exercises Ex. 4.3 — Receive a word from user, and show distinct characters in it as word in alphabetical order. §4.5 Dictionary One more datatype which closely imitates a list is dictionary. Unlike lists/tuples, which are indexed by a range of numbers, dictionaries are indexed by keys, which can be any immutable type; strings and numbers can always be keys. Tuples can be used as keys if they contain only strings, numbers, or tuples; if a tuple contains any mutable object either directly or indirectly, it cannot be used as a key. You cant use lists as keys, since lists can be modified in place using index assignments, slice assignments, or methods like append() and extend(). A dictionary is an unordered set of key:value pairs. For example, sample_dict={’india’: "New Delhi", ’srilanka’: "Colombo"} creates a dictionary with distinct keys india and srilanka. The values can be accessed via the variables sample_dict[’india’] etc. Remember that keys have to be distinct within a dictionary. A dictionary is created by enclosing key:value pairs inside curly braces. An empty dictionary K Vishnu Namboothiri -52- http://vishnu.e-lokam.com 4.5. Dictionary can be created using a pair of curly braces (with empty content in it).2 Let us see an example using a telephone directory type dictionary, which contain details of some employees like their phone number, and address. We will try to change some of the data in it, and will display the modified data to the user. Code 4.23: dictionary_example.py # Program demonstrating use of dictionary: dictionary_example.py telephone directory = {’Vishnu’:[234980,”Dept. of Collegiate Education”], ”Kumaresan” : [402313, ” University of Hyderabad”]} employee id = input(”Enter the employee’s name whose phone number has to be changed: ”) if employee id in telephone directory : print(”Employee Id: ”, employee id) print (”Phone: ”, telephone directory[employee id][0]) print (”Address: ”, telephone directory[employee id][1]) else : print(”Sorry, the employee id ”, employee id, ” could not be found”) print(”Enter the new telephone number for ”, employee id) telephone directory[employee id][0] = input(”Enter new phone number for the employee: ”) print(”Telephone number of ”,employee id, ” changed: New details are: ”) print(”Employee Id: ”, employee id) print (”Phone: ”, telephone directory[employee id][0]) print (”Address: ”, telephone directory[employee id][1]) Code 4.24: In the terminal/shell >>> Enter the employee’s name whose phone number has to be changed: Vishnu Employee Id: Vishnu Phone: 234980 Address: Dept. of Collegiate Education Enter the new telephone number for Vishnu Enter new phone number for the employee: 9400234 Telephone number of Vishnu changed: New details are: Employee Id: Vishnu Phone: 9400234 Address: Dept. of Collegiate Education Instead of showing a dictionary all at once like print(sample_dict) we can loop through the data and apply required formating on individual items. Code 4.25: loopthrough_dictionary.py # Program to loop through dictionary: loopthrough_dictionary.py 2 Remember what we said in one of the previous sections! K Vishnu Namboothiri -53- http://vishnu.e-lokam.com Chapter 4. Data types: a detailed visit telephone directory = {’Vishnu’:[234980,”Dept. of Collegiate Education”], ”Kumaresan” : [402313, ” University of Hyderabad”]} for key, value in telephone directory.items() : print(key, ”\nPhone: ”, value [0], ”\nAddress: ”, value [1]) Code 4.26: In the terminal/shell >>> Kumaresan Phone: 402313 Address: University of Hyderabad Vishnu Phone: 234980 Address: Dept. of Collegiate Education K Vishnu Namboothiri -54- http://vishnu.e-lokam.com Chapter 5 INPUT AND OUTPUT User input is handled in Python via the input() function the use of which we have already seen. In the first section of this chapter, we will see the ways in which we can format the python output; mainly using the format() method. §5.1 Output formatting In a python shell, entering (typing + Enter ) the variable names prints out its contents to the shell. But this method does not allow applying any nice formatting to the output. A very basic (and very fledible, expansible) output function in python is its C sibling print(). We have already seen several examples where this function was used. (If I remember correctly, only a very few examples didn’t use print() in this lecture notes.) If you want to print mixed type of data, say for example, a string and a number, then one natural way is to feed the variable names to python as two different arguments seperated by comma. Code 5.1: In the terminal/shell >>> >>> >>> Hello mystring = ’Hello’ mynumber = 123 print (mystring, mynumber) 123 Have you noticed a space between the two values in the output? The print() function seperates the values inside variables by a single space while outputting them. If this is not desired, the best way is to convert the numeric representation of the number into a string representation via the repr() function. Continuing inside the above shell session Code 5.2: In the terminal/shell >>> print(mystring + repr(mynumber)) Hello123 Let us just compare str(), repr(), eval() in the next shell session. Code 5.3: In the terminal/shell 55 Chapter 5. Input and output >>> x = 5 >>> print(x, str(x), type(str(x))) 5 5 <class ’str ’> >>> print(x, repr(x), type(repr(x))) 5 5 <class ’str ’> >>> print(x, str(str(x)), type(str(str(x)))) 5 5 <class ’str ’> >>> print(x, repr(repr(x)), type(repr(repr(x)))) 5 ’5’ <class ’str ’> >>> print (x, eval(str(x)), type(eval(str(x)))) 5 5 <class ’int ’> >>> print (x, eval(repr(repr((x)))), type(eval(repr(repr((x)))))) 5 5 <class ’str ’> >>> repr(x) ’5’ >>> repr(repr(x)) ’’’ 5 ’’’ The str() function converts (or tries to do so) its argument into a string. In the above example, our first attempt was to convert an integer value (5) to a string constant. The result of this operation is rightly reflected in the type statement. Once a value is converted into a string, nothing else can be and has to be done by the str() on it and so the function call str(str()) has no serious effect. The repr() function, initially behaves just like the str() function in the above example. But infact, it does something else. It tells us, how the variable is represented internally by python. The following example1 clarifies it further. Code 5.4: In the terminal/shell >>> import datetime >>> today = datetime.datetime.now() >>> today datetime.datetime(2013, 2, 7, 11, 57, 45, 799270) >>> str(today) ’2013−02−07 11:57:45.799270’ >>> repr(today) ’datetime.datetime(2013, 2, 7, 11, 57, 45, 799270)’ >>> print(today) 2013−02−07 11:57:45.799270 So repr() gives the internal representation of an object in Python where as str() converts into human readable form (if possible). In fact, the print() function applies str() to an object before displaying it. The repr() function is explained as follows in the Python documentation: “repr(object) Return a string containing a printable representation of an object. For many types, this function makes an attempt to return a string that would yield an object with the same value when passed to eval(), otherwise the representation is a string enclosed in angle brackets that contains the 1 Thanks to the website http://satyajit.ranjeev.in for this example. K Vishnu Namboothiri -56- http://vishnu.e-lokam.com 5.1. Output formatting name of the type of the object together with additional information often including the name and address of the object.” The magical function eval() evaluates the object and tries to simplify it as much as possible. Remember, that we have used it previously for entering a complex number. Also, eval() helps us to enter arithmetical expressions and to evaluate them into numerical data for processing inside the program. One more example given below. Code 5.5: In the terminal/shell >>> x = input(’’Enter an expression: ’’) Enter an expression: 5 + 3 >>> y = input(’’Enter another expression: ’’) Enter another expression: 3 ∗∗ 2 >>> x + y ’5 + 33 ∗∗ 2’ >>> eval(x) + eval(y) 17 A few extra formatting methods are applicable to the string datatype. They are rjust(), ljust(), and center(). mystring.rjust(10) tries to return mystring prepending it with blank spaces, to fill 10 positions, and justifies mystring to the right. If the length of mystring itself if more than the rjust argument, the rjust method is completely ignored returning simply mystring back. See the following example. Code 5.6: In the terminal/shell >>> mystring = ’’Hello’’ >>> mystring.rjust(10) ’ Hello’ >>> mystring ’Hello’ >>> mystring.rjust(20) ’ Hello’ >>> mystring2 = ’’Hello world, how are you?’’ >>> mystring2.rjust(10) ’Hello world, how are you?’ Combination of rjust(), ljust(), center() are very useful while displaying data in table format. Code 5.7: string_formatting.py # Program demonstrating the use of rjust, ljust, center # Program name: string_formatting.py print (”Name”.ljust(15), ”Age in years”. center(5), ”Amount paid”.center(15)) print (”Vishnu”.ljust(15), str (32). center(5), ”100.00”.rjust(15)) print (”Manu”.ljust(15), str(5). center(5), ”10.50”. rjust(15)) Code 5.8: In the terminal/shell >>> Name Vishnu Manu K Vishnu Namboothiri Age in years 32 5 Amount paid 100.00 10.50 -57- http://vishnu.e-lokam.com Chapter 5. Input and output §5.2 Format Specifiers In the print() function, there are certain other format specifying techniques which will improve the layout of the output. The format() method/function is very useful for performing these kind of formatting. A basic format() specifier should have the form ’’.... {0: format_spec} ....’’.format(value) where format_spec is a string with the general layout [[fill]align][sign][pad][width][,][.precision][type]. Explanations on each of these terms are given below. format spec [[fill]align][sign][#][0][width][,][.precision][type] fill a character other than { or } align < or > or = or ∧ sign + or − or empty space width An integer precision An integer "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" "G" | "n" | "o" | "s" | "x" | "X" | "%" Let us see a very basic example. Here no format specifier string is used (In other words, the format string is empty.) type Code 5.9: In the terminal/shell >>> print (’’{}{}’’.format(1, ’’Hello’’)) 1Hello The first empty brace pair corresponds to the number 1, and the second one takes as input the string Hello’’. Let us now have a detailed look at the various option the format() function offers. 2 Code 5.10: formatexample.py # Example showing various ways of using format() # Program format_example.py # Let us play with some math constants: pi and e import math 2 Thanks a lot to http://stackoverflow.com/questions/1598579/rounding-decimals-with-new-python-formatfunction for some insight. The rest of the ideas came from the official tutorial [1] section 6.1 K Vishnu Namboothiri -58- http://vishnu.e-lokam.com 5.2. Format Specifiers PI = math.pi E = math.e print (PI, E) print print print print print print print print print print print print (”%f %f” %(PI,E)) (”{} {}”.format(PI, E)) (”{0} {1}”.format(PI, E)) (”{1} {0}”.format(PI, E)) (”{0} {1} {0}”.format(PI, E)) (”%10.1f %5.2f” %(PI,E)) (”{0:10.1f} {1:5.2 f}”.format(PI, E)) (”%010.1f %5.2f” %(PI,E)) (”{0:010.1f} {1:5.2 f}”.format(PI, E)) (”{0:∗<10.1f} {1:5.2f}”.format(PI, E)) (”{0:∗>10.1f} {1:5.2f}”.format(PI, E)) (”{0:∗ˆ10.1f} {1:5.2 f}”.format(PI, E)) afterDecimalPointPI = 1 totalLengthPI = 10 print (”{0:∗ˆ{1}.{2}f} {3:5.2 f}”.format(PI, totalLengthPI, afterDecimalPointPI, E)) print (”{number1ToPrint}”.format(number1ToPrint = PI)) print (”{number1ToPrint:∗ˆ{length1}.{precision1}f}”.format(number1ToPrint = PI, length1 = totalLengthPI, precision1 = afterDecimalPointPI)) print (”{number1ToPrint:∗ˆ{length1}.{precision1}f} {number2Toprint:{length2}.{ precision2 }f}”.format (number1ToPrint = PI, length1 = totalLengthPI, precision1 = afterDecimalPointPI, number2Toprint = E, length2 = 5, precision2 = 2)) pifounder = ”Archimedes” print (”Value of PI was found by {0:∗ˆ15s} and it is {1:+0.5f}”.format(pifounder, PI)) print (”Value of PI was found by {0:∗ˆ15s} and it is {1:−0.5f}”.format(pifounder, PI)) The output of the above code is Code 5.11: In the terminal/shell >>> 3.141592653589793 3.141593 2.718282 3.141592653589793 3.141592653589793 2.718281828459045 3.141592653589793 3.1 2.72 3.1 2.72 00000003.1 2.72 00000003.1 2.72 3.1∗∗∗∗∗∗∗ 2.72 ∗∗∗∗∗∗∗3.1 2.72 ∗∗∗3.1∗∗∗∗ 2.72 ∗∗∗3.1∗∗∗∗ 2.72 3.141592653589793 ∗∗∗3.1∗∗∗∗ K Vishnu Namboothiri 2.718281828459045 2.718281828459045 2.718281828459045 3.141592653589793 2.718281828459045 3.141592653589793 -59- http://vishnu.e-lokam.com Chapter 5. Input and output ∗∗∗3.1∗∗∗∗ 2.72 Value of PI was found by ∗∗Archimedes∗∗∗ and it is +3.14159 Value of PI was found by ∗∗Archimedes∗∗∗ and it is 3.14159 The format specifiers and their meanings are probably clear now. Let us have a detailed explanation on the prints used in the program code 5.10. Line number 10 produces an unformatted output. The next line prints two numbers with 6 digits after the decimal place (which is the default behaviour of a float or f specifier). Line 13 and line 14 produces the same output. The empty braces correspond in turn to item 0 and item 1 inside the format() function. Using the item numbers in the modified order (1 and 0 inside braces, instead of 0 and 1) produces the output also in the revised order. Line 17 and 19 have the same effect (the same C style effect infact!). The style used in line 17 and 19 are going to become obsolete in the future editions of Python, and so the lines 18 and 20 are preferred. The formatter *<10.1f instructs to print a number as a float, using a total of 10 places, only one digit after the decimal point, fill the empty space by the symbol verb+*+, and align the number in between the *s to the left. Had we used *> instead, the number would have got aligned to the right, and ^ would have aligned it to the center. Instead of * we can use any other character as a filler, except the characters } and {. Lines 28 - 31 complicates the matter further making the life really difficult. In line 28, in the format string, there are numbers 0, {1}, and 3 as item numbers. 0 corresponds to the first item in the format() function, 1 to the second number inside format(), and 3 corresponds to the 3rd number inside format(). Try yourself and understand the meaning of the remaining lines! Details on various options used in the above format specifier table are described below. 5.2.1 Format specifiers: align Option Meaning < Forces the field to be left-aligned within the available space (This is the default.) > Forces the field to be right-aligned within the available space. Forces the padding to be placed after the sign (if any) but before the digits. This is used for printing fields in the form 000000120+. This alignment option is only valid for numeric types. = ^ Forces the field to be centered within the available space. K Vishnu Namboothiri -60- http://vishnu.e-lokam.com 5.2. Format Specifiers 5.2.2 Format specifiers: sign Option Meaning + space 5.2.3 indicates that a sign should be used for both positive as well as negative numbers. indicates that a sign should be used only for negative numbers (this is the default behavior). indicates that a leading space should be used on positive numbers, and a minus sign on negative numbers. Format specifiers: width, precision The # option is only valid for integers, and only for binary, octal, or hexadecimal output. If present, it specifies that the output will be prefixed by 0b, 0o, or 0x, respectively. The ’,’ option signals the use of a comma for a thousands separator. For a locale aware separator, use the ’n’ integer presentation type instead. width is a decimal integer defining the minimum field width. If not specified, then the field width will be determined by the content. If the width field is preceded by a zero (’0’) character, this enables zero-padding. This is equivalent to an alignment type of = and a fill character of ’0’. The precision is a decimal number indicating how many digits should be displayed after the decimal point for a floating point value formatted with ’f’ and ’F’, or before and after the decimal point for a floating point value formatted with ’g’ or ’G’. For non-number types the field indicates the maximum field size - in other words, how many characters will be used from the field content. The precision is not allowed for integer values. K Vishnu Namboothiri -61- http://vishnu.e-lokam.com Chapter 5. Input and output 5.2.4 Format specifiers: type The available integer presentation types are: Type Meaning b B inary format. Outputs the number in base 2. c Character. Converts the integer to the corresponding unicode character before printing. d Decimal Integer. Outputs the number in base 10. o Octal format. Outputs the number in base 8. x Hex format. Outputs the number in base 16, using lower- case letters for the digits above 9. X Hex format. Outputs the number in base 16, using upper- case letters for the digits above 9. n Number. This is the same as ’d’, except that it uses the current locale setting to insert the appropriate number separator characters. None The same as ’d’. The available presentation types for floating point and decimal values are: K Vishnu Namboothiri -62- http://vishnu.e-lokam.com 5.3. File operations Type Meaning e Exponent notation. Prints the number in scientific notation using the letter e to indicate the exponent. E Exponent notation. Same as ’e’ except it uses an upper case E as the separator character. f Fixed point. Displays the number as a fixed-point number. F Fixed point. Same as ’f’, but converts nan to NAN and inf to INF. g General format. This prints the number as a fixed-point number, unless the number is too large, in which case it switches to ’e’ exponent notation. Infinity and NaN values are formatted as inf, -inf and nan, respectively. G General format. Same as ’g’ except switches to ’E’ if the number gets to large. The representations of infinity and NaN are uppercased, too. n Number. This is the same as ’g’, except that it uses the current locale setting to insert the appropriate number separator characters. % None Percentage. Multiplies the number by 100 and displays in fixed (’f’) format, followed by a percent sign. Similar to ’g’, except with at least one digit past the decimal point and a default precision of 12. This is intended to match str(), except you can add the other format modifiers. Exercises Ex. 5.1 — Suppose z = 2.3456789 + 3.456789j is a complex number. Print it so that its real part uses a total of 10 spaces, and only 2 digits appear after decimal point. The remaining positions should be filled with #. §5.3 File operations For practical purposes, it is important that we would be able to load data from a file and to save the output (final as well as intermediate) to a file. Functions handling files become very useful here. A file needs to be opened before performing read or write in it. The opened file should be assigned to a file handle using which we perform later operations in the file like reading/writK Vishnu Namboothiri -63- http://vishnu.e-lokam.com Chapter 5. Input and output ing/closing it. As usual, let us go through an example to understand the concepts clearly. It involves three operations: opening the file, writing to it, closing it, then re-opening it, reading it, again closing it. The most important point you have to remember is that, our write operations will become completed only on closing the file handle and releasing the system resources. The temrination of the program itself will not guarantee the success/completion of the file writing operations. Code 5.12: fileoperations.py # Program fileoperations.py # Let us create a file filename = ”myfile.txt” f = open(”myfile.txt”, ’w’) # Open myfile.txt in write mode. # myfile.txt will be created if it does not exist f . write(”28, 32, 5”) # write a few numbers into into the file buffer; separated by comma f . write(”\n”) f . write(”Priya, Vishnu, Hrishi ”) f . close () # Close the file; and flush the buffer contents into the file. # Now open the same file; only for reading f = open(filename, ”r”) contents = f.read() # Put the contents in to a string variable print ((contents)) # Print the contents f . close () f = open(filename, ”r”) lines = f . readlines() print(lines) f . seek(0) # go to the first byte in the file print (f . readline()) f . seek(0) my ages = f.readline() agelist = [x.strip () for x in my ages.split(’, ’ ) ] print (agelist ) my names=f.readline() namelist = [x.strip() for x in my names.split(’,’)] print(namelist) # Now make tuples In the above code, the open() function has two arguments. The first argument is the name of the file we want to open, and the second argument, the mode in which it has to be opened. The modes supported across all the operating systems (including MS Windows!) are the following: K Vishnu Namboothiri -64- http://vishnu.e-lokam.com 5.3. File operations r open the file for only reading, no writing w either open a new file for writing, or open an existing file for writing, at the same time erase its previous contents a same as w, but it does not erase the contents in the file. It will append the data to the end of the file r+ open the file for both reading and writing; but the file MUST exist. No files will be created by the open() function if we use the r+ mode Anyway, the output of the above program, as expected, is Code 5.13: In the terminal/shell >>> 28, 32, 5 Priya, Vishnu, Hrishi Let us have one more example which shows how useful the file operations are. We will keep a file containing ages and names of students, and from it, we will generate a file in which we will put the names sorted according to their ages/ names according to the user input. A sample file would be of the form Vishnu, 31 Priya, 28 Manu, 5 Luttu, 30 Maya, 17 and a not so simple method to achieve the sorting is Code 5.14: sortfilecontents.py # Program to sort students based on age/name, after accepting data from a file # sortfilecontents.py filetosort = input(”Please enter the filename which contains the students ’ data: ”) f = open(filetosort, ”r”) data = f.readlines() f . close () # Read the contents, and so the file could be closed #Create an empty list studentNameAgePair = [] # List of tuples for student in data: studentraw = student.split(”,”) studentraw[0] = studentraw[0].strip() studentraw[1] = int(studentraw[1]) studentNameAgePair.append((studentraw[0], studentraw[1])) studentNameAgePair.sort(key=lambda x: x[1]) K Vishnu Namboothiri -65- http://vishnu.e-lokam.com Chapter 5. Input and output # sorted on age. x[0] would have sorted on name, which is the default resultfile = input(”Where should I store the sorted result ? ”) f = open(resultfile, ”w”) for student in studentNameAgePair: f . write(student[0] + ”, ” + str(student[1]) + ”\n”) f . close () Steps involved in the process are the following: 1. Requested the user to input the name of the file from which student details are to be read 2. Tried to open it 3. Copied all the contents as list of lines 4. Created an empty list for holding (name, age) tuples 5. Each line (student) in data is splitted at the separator comma (,), 6. In the list studentraw [name(string), age(string)] is stripped off white space via strip() and converted in to [name (string), age(int)] 7. Appended the modified studentraw list components (name, age) to studentNameAgePair. 8. Requested the user for providing output file name, tried to open and wrote to it, closed it. Done! K Vishnu Namboothiri -66- http://vishnu.e-lokam.com Chapter 6 RANDOM EXTRAS This chapter will try to fill some vacuum which the earlier chapters created. This will explain certain points which might not have come anywhere in previous chapters or might have come, but not with their due importance. Complete randomeness may be expected in the forthcoming sections; beware! §6.1 The dir() function This is based on Section 6.2 of [1]. The built-in function dir() is used to find out which names a module defines. It returns a sorted list of strings. In my Python shell (Python 3.2.3), the dir() gives the following output. Code 6.1: In the terminal/shell >>> dir() [ ’ builtins ’ , ’ doc ’ , ’ name ’, ’ package ’ ] >>> dir(math) [ ’ doc ’ , ’ name ’, ’ package ’ , ’acos’ , ’acosh’ , ’ asin ’ , ’asinh’ , ’atan’ , ’atan2’, ’ atanh’, ’ ceil ’ , ’copysign’ , ’cos’ , ’cosh’ , ’degrees’ , ’e’ , ’ erf ’ , ’ erfc ’ , ’exp’, ’expm1’ , ’fabs ’ , ’ factorial ’ , ’ floor ’ , ’fmod’, ’frexp’ , ’fsum’, ’gamma’, ’hypot’, ’ isfinite ’ , ’ isinf ’ , ’isnan’ , ’ldexp’ , ’lgamma’, ’log’ , ’log10’ , ’log1p’ , ’modf’, ’ pi ’ , ’pow’, ’ radians’ , ’ sin ’ , ’sinh’ , ’ sqrt ’ , ’tan’ , ’tanh’, ’trunc’ ] When we use dir() without any arguments, it lists all the names currently imported to the namespace. If we define some names and use the dir(), then it will display the newly defined names also. Code 6.2: In the terminal/shell >>> myname = ’’Vishnu’’ >>> dir() [ ’ builtins ’ , ’ doc ’ , ’ name ’, ’ package ’ , ’math’, ’myname’] The built-in functions/names in Python can be accessed via using dir() after importing the module builtins. 67 Chapter 6. Random Extras Code 6.3: In the terminal/shell >>> import builtins >>> dir(builtins) [ ’ArithmeticError’, ’AssertionError’, ’AttributeError’, ’BaseException’, ’BufferError’ , ’ BytesWarning’, ’DeprecationWarning’, ’EOFError’, ’Ellipsis’, ’EnvironmentError’, ’ Exception’, ’False ’ , ’FloatingPointError’, ’FutureWarning’, ’GeneratorExit’, ’IOError’, ’ ImportError’, ’ImportWarning’, ’IndentationError’, ’IndexError’, ’KeyError’, ’ KeyboardInterrupt’, ’LookupError’, ’MemoryError’, ’NameError’, ’None’, ’NotImplemented ’, ’NotImplementedError’, ’OSError’, ’OverflowError’, ’PendingDeprecationWarning’, ’ ReferenceError’, ’ResourceWarning’, ’RuntimeError’, ’RuntimeWarning’, ’StopIteration’, ’ SyntaxError’, ’SyntaxWarning’, ’SystemError’, ’SystemExit’, ’TabError’, ’True’, ’ TypeError’, ’UnboundLocalError’, ’UnicodeDecodeError’, ’UnicodeEncodeError’, ’ UnicodeError’, ’UnicodeTranslateError’, ’UnicodeWarning’, ’UserWarning’, ’ValueError’, ’ Warning’, ’ZeroDivisionError’, ’ ’, ’ build class ’ , ’ debug ’ , ’ doc ’ , ’ import ’ , ’ name ’, ’ package ’ , ’abs’ , ’ all ’ , ’any’, ’ ascii ’ , ’bin’ , ’bool’ , ’bytearray’ , ’ bytes’ , ’ callable ’ , ’chr’ , ’classmethod’, ’compile’, ’complex’, ’copyright’ , ’ credits ’ , ’ delattr ’ , ’ dict ’ , ’ dir ’ , ’divmod’, ’enumerate’, ’ eval ’ , ’exec’ , ’ exit ’ , ’ filter ’ , ’ float ’ , ’format’, ’ frozenset ’ , ’ getattr ’ , ’ globals ’ , ’ hasattr ’ , ’hash’, ’help’ , ’hex’, ’ id ’ , ’ input’ , ’ int ’ , ’ isinstance ’ , ’ issubclass ’ , ’ iter ’ , ’ len ’ , ’ license ’ , ’ list ’ , ’ locals ’ , ’ map’, ’max’, ’memoryview’, ’min’, ’next’, ’object’ , ’oct’ , ’open’, ’ord’ , ’pow’, ’ print ’ , ’property’, ’ quit ’ , ’range’ , ’repr’ , ’ reversed ’ , ’round’, ’ set ’ , ’ setattr ’ , ’ slice ’ , ’ sorted’ , ’staticmethod’, ’ str ’ , ’sum’, ’super’ , ’ tuple ’ , ’type’ , ’ vars ’ , ’ zip ’ ] §6.2 Clearing the python shell If you are in Linux, and python shell (not the Python IDLE; you should have started the shell from the terminal issuing the command python3.1), the following set of set of commands will do the job: Code 6.4: In the terminal/shell import os os.system(’’ clear ’ ’ ) In MS Windows, the method is Code 6.5: In the terminal/shell import os os.system(’’CLS’’) In IDLE, there does not seem to be anyway, other than closing and restarting it, to clean up the shell window. §6.3 Handling error There may be situations when user inputs lead to errors which may stop the the program from running or even crashing. To avoid it, and to control the program flow more efficiently, the programmer should be able to catch the runtime errors inside the program itself, and should try to inform the user about the mistakes. The try +except combination works well K Vishnu Namboothiri -68- http://vishnu.e-lokam.com 6.3. Handling error in this situation. Consider a problem involving division of integers. If the user is supposed to input the integers, and division by zero occurs, then Python raises an error like ZeroDivisionError: division by zero He may even try to enter some non integer by mistake. Let us see how to tackle these situations. Code 6.6: handleError.py # Program handleError.py to divide two integers valuesReceived = False while valuesReceived == False: # Loop until proper values are received try: a = int(input(”Enter first number: ”)) b = int(input(”Enter second number: ”)) d = a/b except (ValueError, ZeroDivisionError) as errormessage: print(”Really sorry . The following error occured : ” + str(errormessage) +” : Please re enter the numbers.\n”) else: valuesReceived = True print (”Numbers entered are {} and {} and their ratio is equal to {}”. format(a, b, a/b)) and it produces the following sample output: Code 6.7: In the terminal/shell >>> Enter first number: x Really sorry . The following error occured : invalid literal for int() with base 10: ’x’ : Please re enter the numbers. Enter first number: 1 Enter second number: 0 Really sorry . The following error occured : division by zero : Please re enter the numbers. Enter first number: 1 Enter second number: 2 Numbers entered are 1 and 2 and their ratio is equal to 0.5 The program requests the user to input two numbers. If one of the numbers is a non integer, then a ValueError will be raised by Python, and the error messge will be kept inside the variable errormessage. This is then shown back to the user after converting it into a string. If the user enters b as 0, a ZeroDivisionError will be raised by python. The user will not be allowed to go outside the loop until he enters two proper integers. If no exceptions are raised, then the else block will become active. It will turn the valuesReceived variable to True causing the loop to break. K Vishnu Namboothiri -69- http://vishnu.e-lokam.com Chapter 6. Random Extras An exception is an event, which occurs during the execution of a program, that disrupts the normal flow of the program’s instructions. In general, when a Python script encounters a situation that it can’t cope with, it raises an exception. An exception is a Python object that represents an error. When a Python script raises an exception, it must either handle the exception immediately otherwise it would terminate and come out. Handling exceptions are very much necessary especially when handling files. There may be situations when we may not be able to predict the kind of error (like ValueError, NameError etc). In that case, the systems error messages should be tracked and displayed to the user. Uncategorized (or errors which we do not know how to categorize while writing the code) can be tracked via except Exception as errormessage: block. Code 6.8: handleError2.py # Program handleError2.py to divide two integers valuesReceived = False while valuesReceived == False: # Loop until proper values are received try: a = int(input(”Enter first number: ”)) b = int(input(”Enter second number: ”)) d = a/b except Exception as errormessage: print(”Really sorry . The following error occured : ” + str(errormessage) +” : Please re enter the numbers.\n”) else: valuesReceived = True print (”Numbers entered are {} and {} and their ratio is equal to {}”. format(a, b, a/b)) K Vishnu Namboothiri -70- http://vishnu.e-lokam.com Chapter 7 100 PROBLEMS IN MATH! This chapter is incomplete. I am still posting it as some of the students in the University of Kerala may find it useful even in this incomplete form. You may think that what happened suddenly in this tutorial! I am here hoping to write (atleast) 100 programs in python each handling different different problems in Mathematics from the Undergraduate level. Hopefully I will be able to touch almost all the areas at present taught in a BSc level class in Kerala. If you feel that some specific problem should be included in this chapter which I have not done so far, please send me an email. §7.1 Basic Mathematics 1. Findparea of a triangle given the length of its three sides a, b, c using the formula . s = s(s − a)(s − b)(s − c) where s = a+b+c 2 Code 7.1: findareaTriangle.py # Find area of triangle using formula involving perimeter, length of its sides a = float(input(”Enter side a: ”)) b = float(input(”Enter side b: ”)) c = float(input(”Enter side c: ”)) s = (a + b + c)/2 from math import sqrt area = sqrt(s ∗ (s − a) ∗ (s − b) ∗ (s − c)) print(”Area of the triangle is ”, area) §7.2 Algebra 1. Finding GCD of two numbers See program code (2.8). 71 Chapter 7. 100 problems in math! 2. Find all divisors of a number The algorithm is very simple. Let the given number be n. We will check whether a d < n divides n or not, and show the result. Code 7.2: finddivisors.py # Program to find divisors of a given nonzero number. Python 2.7.x n = input(”Please enter a nonzero number: ”) if n == 0: print ”Sorry. You are supposed to input a nonzero number. Quitting the program ... ” exit () for d in range(2, n/2+1): if n%d == 0: print ”{0} is a factor of {1}”. format(d, n) 3. Check primality of a number Once again, a simple Python√ program can easily do this. Take a number, say n. Check whether the numbers 2, . . . , n divides it or not. If one of the numbers in this range divide n, it is not a prime. (Use a for loop for the checking.) If the loop terminates without finding any divisor, then it is a prime. See the code (3.19) in action. 4. Find all primes up to a given n using the Sieve of Eratosthanese See appendix B.5 for explanation on this technique, and then the code 3.38 5. Find all primes up to a given n usind direct division method Code 7.3: primelistUpton.py # Generate list of primes and list of composites up to a given n: Python 3.x. In Python 2.x, this program will be a big flop. But why? # Defining an isprime function def isprime(n): for d in range(2, int(n∗∗(1/2))+1): if n%d == 0: return False else: return True # Function definition over n = int(input(”Enter n: ”)) primelist = [] # Define empty list complist = [] import time start time = time.time() for i in range(2, n+1): if isprime(i): primelist.append(i) else: complist.append(i) print (”List of primes up to {}: {}”. format(n, primelist)) K Vishnu Namboothiri -72- http://vishnu.e-lokam.com 7.2. Algebra print (”List of composites up to {}: {}”. format(n, complist)) print (time.time() − start time, ”seconds”) Would you like to check the speed of both the methods for finding primes? In each of the above programs, insert the lines import time start time = time.time() before the beginning of loop, and after the loop, insert the line print (time.time() − start time, ’seconds’) This will show the time taken by the loops in each of the programs in seconds! 6. Find all units in Zn for a given n. This is equivalent to the problem of finding the multiplicative group Z× n . Remember that, an element m ∈ Zn is a unit in it provided that gcd(m, n) is 1. So we have to take all the elements in Zn in a for loop, and check whether its gcd with n is 1 or not. Code 7.4: unitsInZn.py # Program to find the units in Z_n (That is elements in Z_n with multiplicative inverse, or equivalently, elements m with gcd(m,n) == 1 n = int(input(”Enter number n: ”)) Z n units = [] # A list for holding the units if n <= 0: print (”Sorry. Invalid number n. Qutting . . .”) exit () from mygcdfunction import mygcd for m in range(1, n): if mygcd(m, n) == 1: Z n units.append(m) print (”Units in Z {0} are {1}”. format(n, Z n units)) 7. Find All generators of Z× n for a given n × An m in Z× will generate the whole group provided that its order is |Z× n n |. That is, if Zn s−1 contains s elements, then an element r ∈ Z× ≡ 1(mod n) n is a generator provided r t and r 6≡ 1(mod n) for any 1 ≤ t < s. Code 7.5: generatorsZnMultGp.py # Program to find the units in Z_n (That is elements in Z_n with multiplicative inverse, or equivalently, elements m with gcd(m,n) == 1 # Then it will find generators in Z_n*, if any exists n = int(input(”Enter number n: ”)) z n units = [] # A list for holding the units if n <= 0: K Vishnu Namboothiri -73- http://vishnu.e-lokam.com Chapter 7. 100 problems in math! print (”Sorry. Invalid number n. Qutting . . .”) exit () from mygcdfunction import mygcd for m in range(1, n): if mygcd(m, n) == 1: z n units.append(m) print (”Units in Z {0} are {1}”. format(n, z n units)) # Now find the generators from z_n_units generators z n mult = [] cardinality z n = len(z n units) for m in z n units: power = 1 for t in range(1, cardinality z n + 1): if ( m ∗∗ t) % n == 1: power = t break if power == cardinality z n: generators z n mult.append(m) if len(generators z n mult)>0: print (”Generators of Z {}∗ are {}”.format(n, generators z n mult)) else: print(”Z {}∗ has no generators”. format(n)) 8. Convert a number in base 10 to a given base n. The number will be divided by the given base, and the remainder will be taken to a list. After noting down the remainder, subtract the remainder from the number, and divide it again using base, and continue until the number becomes less than the base. Code 7.6: baseconversion.py # Convert the decimal representation of a number into another base representation number = int(input(”Enter number in base 10: ”)) b1 = int(input(”Enter base: ”)) converted number = [] # Number coefficients in new base will be stored in this. n1 = number # Copy the value to another variable so that number will not change while n1 >= b1: converted number.append(n1 % b1) n1 = n1 − (n1 % b1) n1 = int(n1/b1) converted number.append(n1%b1) numberlength = len(converted number) print(”Representation of {0} in base {1} is ”. format(number, b1)) for i in range(numberlength): print(”{0}∗({1}∗∗{2})”. format(converted number[i], b1, i), end = ””) if i < numberlength − 1: print(” + ”, end = ””) K Vishnu Namboothiri -74- http://vishnu.e-lokam.com 7.3. Linear Algebra §7.3 Linear Algebra 1. Find dot product (scalar product) of two vectors Code 7.7: dotproduct.py # Program to find dot product of two row vectors def dotproduct(v1, v2): # v1 and v2 must of of the same type, compatible for taking dot product sum = 0 for i in range(len(v1)): sum += v1[i] ∗ v2[i] return sum v1 = [1, 2, 4] v2 = [5, 6, 7] # Defined two lists of same type print(”Dot product of {0} and {1} is {2}”. format(v1, v2, dotproduct(v1, v2))) 2. Find sum of two matrices of the same order Code 7.8: matrixsum.py # Program to find sum of two matrices of the same order A = [[1,2,3], [4,5,6]] B = [[1,1,0], [2,2,1]] C = [] # The sum will be stored in this. Now, an empty list (matrix) rowcount = len(A) colcount = len(A[0]) for i in range(rowcount): row = [] # Prepare a row for appending to C for j in range(colcount): row.append(A[i][j] + B[i][j ]) C.append(row) #Append the newly obtained row of element sums to C print(”The sum is”) for r in C: print(r) §7.4 Real Analysis Pk 1 1. Find n=1 n for a given k. (The sum of first n terms of a harmonic series). See appendix B.4 for the definition of this series, and code 3.23 for the program. P 2. Find a k so that, for a given > 0, kn=1 n1 > . See the code 3.24. K Vishnu Namboothiri -75- http://vishnu.e-lokam.com Chapter 7. 100 problems in math! 3. Find the first n terms in the Fibonacci sequence. See the code 2.20. §7.5 Statistics 1. Find arithmetic mean of given numbers. Accept the numbers as a list, find its length, and divide the sum by its length. Code 7.9: arithmeticMean.py # Find arithmetic mean of given numbers. Python 3.x numberliststring = input(”Enter numbers seperated by comma\n”) numberlist = [float(x) for x in numberliststring.split(”,”)] n = len(numberlist) am = 0 for x in numberlist: am += x am /= n print (”Arithmetic Mean of {} is {}”.format (numberlist, am)) §7.6 Numerical Analysis 1. Bisection Method Suppose that a function f (x) is given with coefficients algebraic or transcendental. If we can identify an interval [a, b] in which a root of this function lies, and f (a)×f (b) < 0, then bisection method could be used to converge towards a shorter (in length) interval inside [a, b] which again contains the same root. At each step, we find the midpoint . Then we check which of f (a) × f (c) and of the interval, and notate it as c = a+b 2 f (c) × f (b) is < 0. Choose one of a, c and c, b such that the product of the f values of the end points of the interval would be less than 0. Say it is [a, c]. Put the value of c inside b, and rename the interval to be again [a, b]. Continue this process until |f ( a+b )| < some given error value(or tolerance, in the numerical analysis language). 2 We will take the value a+b to be the final approximation. Let us now see the code: 2 Code 7.10: bisectionMethod.py # Find root of a function using bisection method: Program bisectionMethod.py # Defining the function def f ( x): return x ∗∗ 3 + 4 ∗ x∗∗2 − 10 # Function definition over # Set the inverval end points a=0 K Vishnu Namboothiri -76- http://vishnu.e-lokam.com 7.6. Numerical Analysis b=0 tolerance = 0.0000001 # Final value of f(c), where c is the approx. root numberOfSteps = 1000 # If root could not be found, how many steps should be tried? stepsExecuted = 0 # Keep track of steps already executed while f(a)∗f(b) >= 0: if stepsExecuted > numberOfSteps: break; else: stepsExecuted += 1 values = raw input(”Please enter a and b (separated by comma) so that f(a)∗ f (b) < 0: ”) numberlist = values.split(”,”) a = float(numberlist[0]) b = float(numberlist[1]) if f ( a) == 0 or f(b) == 0: break # Exact root found, so break the loop if f ( a) ∗ f ( b) >=0: print (”Sorry; the end points cannot be accepted as f (a)∗f(b) = {} >=0\n”. format(f( a)∗f(b))) # After accepting the interval end points, quit the loop c = (a+b)/2 # Just for examination, see the values of a, b, c, f(c) print (”{:10s} {:10s} {:10s} {:20s}”. format(”a”, ”b”, ”c”, ”f(c)”)) while abs(f(c))> tolerance: # Bisect the interval untill |b-a| < tolerance c = (a+b)/2 if ( f ( a)∗f ( c)<= 0): b=c else: a=c print (”{:<+10f} {:<+10f} {:<+10f} {:<+20f}”. format(a, b, (a+b)/2, f((a+b)/2))) # Just for examination, see the values of a, b, c, f(c) # Loop ends if the condition is met if f ( a) == 0: print (”Found root: {}”. format(a)) elif f ( b) == 0: print (”Found root: {}”. format(b)) elif abs(f(c)) > tolerance : print(”Executed the loop {} times , but could not find root up to the accuracy specified . Last found approx. root is \ f({}) = {}. ”. format(stepsExecuted, abs(b−a)/2, f(abs(b−a)/2))) else: print (” Approx root is {0} and f({0}) is {1:0.10 f}”. format((a+b)/2, f((a+b)/2))) 2. Lagrange’s Interpolation Formula In this, for a given table of data ofPthe form (x0 , y0 ), (x1 , y1 ), . . . , (xn , yn ) a polynomial is constructed which of the form ni=0 li (x)yi where li (x) = K Vishnu Namboothiri (x − x0 )(x − x1 ) . . . (x − xi−1 )(x − xi+1 ) . . . (x − xn ) (xi − x0 )(xi − x1 ) . . . (xi − xi−1 )(xi − xi+1 ) . . . (xi − xn ) -77- http://vishnu.e-lokam.com Chapter 7. 100 problems in math! . We attempt to perform two tasks in our program. One, to find out the sum without actually calculating the polynomial. Two, calculate the polynomial and evaluate it at the polynomial. For calculating the polynomial, which involves symbolic variables, we use the Python module sympy. In the example, we handle the function log(x) for displaying the techniques. Needless to say that the technique will work irrespective of the function we choose. Code 7.11: LagrangeInterpolation.py # Program Lagrange Interpolation: Python 2.7.x # Definition: page 110 Burden, Numerical Analysis # The following example as verified from # S S Sastry, Introductor methods in Numerical Analysis, 4th Edn, P94 from math import log x = [2.0, 2.5, 3.0] y = [log(c) for c in x] a = 2.7 y of a = 0 # We have to find y(a). Initialize the variable with value 0 from sympy import ∗ # For performing symbolic manipulations; like multiplication of polynomials involving mere symbols, non numeric data t = Symbol(’t’) # t is now just a symbol, not holding any values in it poly t = 0 # Lagrange Polynomial. Initialize with 0 # Finding the value of y(a), and find y(t) simultaneously for i in range(0, len(x)): numerator = 1 denominator = 1 numerator t = 1 numerator t = 1 # Numerator of Lagrange factors; initialize with 1 for j in range(0, len(x)): if i == j: continue numerator ∗= (a − x[j]) denominator ∗= (x[i] − x[j]) numerator t ∗= (t − x[j]) poly fact = (numerator t/denominator)∗y[i] # Each Lagrange poly like L_0, L_1 etc. poly t += poly fact y of a += (numerator/denominator) ∗ y[i] print ”polynomial is ”, expand(poly t) # Print the polynomial after expanding into powers of t t = a # Ready to evaluate the polynomial at a using the Lagrange Polynomial print ”Value evaluated at t = a is”, eval(str(poly t)) print ”Solution is ”, y of a # This value was evaluated without finding the polynomial directly print ”Actual value is ”, log(a) #The actual function value # Check the differences between the above three values! K Vishnu Namboothiri -78- http://vishnu.e-lokam.com Bibliography [1] Python Tutorial - Release 3.1.1; Guido van Rossum, Fred L. Drake, Jr., editor; Python Software Foundation (2009) 79 Appendix A SYMBOLS, NOTATIONS, AND TECHNICAL WORDS i) Whenever you see a text appearing in typewriter like font you are supposed to type it to the terminal and execute it. ii) MS Windows: Any version of Microsoft Windows Operating system (XP/Windows 7 etc) iii) Python 2.x, Python 3.x: The most popular versions/editions of Python available these days. 2.x means it can be 2.6.1 or 2.7.1 etc. Similarly 3.x stands for 3.1.1 or 3.3.1 etc C iv) The symbol or Enter after a typewritten word/words simply mean that you are supposed to type it to the terminal/file and then press the Enter key on your keyboard. v) The symbol K stands for the up arrow on the keyboard. Guess for what does L stand! vi) Terminal always means the Linux Terminal emulator (which executes all your commands as efficiently as a real terminal does, but has an extra capability: limited mouse support) vii) Shell: Even though it can be (and is used) for denoting the Linux terminal, let us reserve it for the Python shell. viii) A session is the period a user stays in the Python shell after the commands python3 in the terminal before the command exit() in the shell. ix) geany: A very good text editor available in Linux. This is the default editor in Crunchbang. In Ubuntu, to install it, use the command sudo apt-get install geany in the terminal. x) gedit: Another good text editor available in Linux. This is the default editor in the common Ubuntu systems (based on GNOME desktop environment). If not available, to install it, use the command sudo apt-get install gedit in the terminal. xi) Ctrl + s, Alt + F4 etc: Hold the Control key down and press s, or hold the Alt key down and press function key F4 etc. xii) OS: Operating System, which may be Linux, MS Windows, Unix, or Apple Mac 81 Appendix B SOME RESULTS/ ALGORITHMS This section gives details of some of the mathematical theorems/algorithms used in this tutorial. §B.1 Euclidean Algorithm for finding GCD Recall that, gcd(a, b) is defined as the largest positive integer d such that d|a and d|b, and if some c|a and c|b, then d|c. But for finding gcd of given two numbers a and b, this definition itself is not very useful. We use Euclidean algorithm for finding the gcd effectively in a bounded number of steps (where the bound is the minimum of the size of the given two numbers). The algorithm initially writes a as sum of a product of b(6= 0) and a remainder r1 where 0 ≤ r1 < |b|. Then it expresses b as a sum of a product of r and some remainder r2 where 0 ≤ r2 < r. This process continues till we get the remainder in one of the steps to be 0. We take the remainder just before our concluded step as the gcd. The equations we use are the following: a = bq1 + r1 b = r1 q2 + r2 r1 = r2 q3 + r3 .. . If we analyse the above equations, one thing is clear. In the second equation, b came into the place of a, and r1 into the place of b. In the third equation, r1 is appearing in the place where b was present, and r2 where r1 was present. But r1 is nothing but the remainder obtained on dividing a with b. That is, a%b in Python’s language. So the chain of changes can be seen to be a → b, b → a%b which, in Python becomes a, b = b, a%b. Thats all! Keep on doing this swapping until b (which holds the remainder in each step) becomes zero. a which holds the previous value of the remainder (or previous value of b) becomes the last non zero remainder, which is the gcd. 83 Appendix B. Some results/ algorithms §B.2 Fibonacci sequence or Fibonacci numbers It is one of the most popular sequence of real numbers existing in the math (as well as non math) literature. The terms are usually named as F0 , F1 , . . . where F0 = 1, F1 = 1, and then Fn = Fn−1 + Fn−2 for all n ≥ 2. The terms become rapidly large when it moves on, but the ratio of consecutive terms approach a special, irrational number called Golden ratio. It is approximately equal to 1.618. . . . For more details on Fibonacci numbers, please visit the Wikipedia page http://en.wikipedia.org/wiki/Fibonacci_number. §B.3 Absolute value Absolute value of a real number x is defined as ( x if x ≥ 0 |x| = −x if x < 0 By Trichotomy property of real numbers, any real number x has to be either positive, or 0, or negative. Absolute value of a complex number (a number with a possible non zero imaginary part) is a generalization √ of the above definition. If a + bj is a complex number, where a, b ∈ R, then |a + bj| = | a2 + b2 |. Remember that since a2 and b2 are positive, the square root is a real number, and that absolute value of a real number we have already defined. §B.4 Harmonic Series P 1 The infinite series ∞ n=1 n is called the harmonic series. The divergence of this series (that is, the sum does not go towards a finite value; instead it becomes larger and larger) is a classic exercise for the undergraduate students in basic real analysis. The beauty is that, the sum becomes very large, but very slowly. We need to add 84 terms (that is we need to 1 ) for the sum to become just above 5. But if we want to make this sum find 1 + 12 + . . . + 84 just above 10, we need 12368 terms. If it has to cross 15, we need 1835422 terms! See how fast the number of terms required grows compared to the growth in the sum of terms itself. §B.5 Sieve of Eratosthenes From Wikipedia : The sieve of Eratosthenes is one of a number of prime number sieves, is a simple, ancient algorithm for finding all prime numbers up to any given limit. It does so by iteratively marking as composite (i.e. not prime) the multiples of each prime, starting with the multiples of 2. The multiples of a given prime are generated starting from that prime, as a sequence of numbers with the same difference, equal to that prime, between consecutive numbers. This K Vishnu Namboothiri -84- http://vishnu.e-lokam.com B.5. Sieve of Eratosthenes is the sieve’s key distinction from using trial division to sequentially test each candidate number for divisibility by each prime. The sieve of Eratosthenes is one of the most efficient ways to find all of the smaller primes (below 10 million or so). It is named after Eratosthenes of Cyrene, a Greek mathematician; although none of his works has survived, the sieve was described and attributed to Eratosthenes in the Introduction to Arithmetic by Nicomachus. K Vishnu Namboothiri -85- http://vishnu.e-lokam.com Appendix C BASIC LINUX (UNIX) SHELL COMMANDS In the terminal, type the following commands one by one. When you are finished press Enter to see the result. i) who : List the users connected to your system. If the system is in a network of computers, you may see a few names. Otherwise, only your (user)name! ii) who --help : All possible variations of the who command will be displayed. Just try it iii) whoami : The very first thing you should know is who you are! Displays your username. iv) pwd : Present working directory - in which directory you are now. . Directory is like a shelf in a library. It stores several books (files). If you change your directory, the files accessible to you also will change. v) mkdir : Make Directory - make your own shelf; sorry, directory. The command mkdir BookshelfofVis will create a directory named BookshelfofVishnu in the present working directory. vi) ls : List all files/directories in the present working directory. Two important options are ls -a and ls -al. vii) cd : Change the directory - example cd BookshelfofVishnu. If you try to execute the same line twice, what will happen? cd .. will bring your pwd to one level down. Suppose that you are creating a directory first and inside it second. Use the following commands: pwd mkdir first cd first pwd mkdir second cd second pwd will show the results as 87 Appendix C. Basic Linux (Unix) shell commands /home/username /home/username/first /home/username/first/second Now you are in the directory second. If you want to come back to first simply type cd .. Enter . Check the result using pwd Enter . Simply entering cd will bring you back to your (users) home directory /home/username/. viii) rm : Remove file(s) - example rm testfile. If you try to execute the same line twice, what will happen?. Wildcards (like *) are supported, but use with caution. ix) rmdir : Remove a directory - example rmdir second if your pwd is first. If the directory second has files in it, the command will not be executed. To remove the directory and contents in it recursively, use rm -r second. If you try to execute the same line twice, what will happen? x) date : Shows the system time and date. xi) ps : Shows the processes (programs) running in the current shell with their Process IDs (PID). If you want to know all the processes in the system running for user vishnu enter ps -u vishnu. xii) kill : Stop a process immediatley; kill it using its PID. Find out first a programs PID using ps -u vishnu. Suppose the PID is 7147, then enter kill 7147 to immediately stop the program with PID 7147. Use with caution as it may result in data lose. xiii) clear : Typed too many things on the terminal. Just clear it. xiv) cp: copy a file or directory from one location to other. Suppose you have test file in the directory first and you want to copy it to second and want to give the name testfile2. Assuming that your pwd is first, use the command cp testfile second/testfile2 xv) mv : Rename/movea file/directory. Usage mv oldname newname or mv oldname newdirectory/. Example cd /home/vishnu/first mkdir third mv second third/ This will result the directory second to be moved inside directory third mv third fourth This will cause the renaming of third to fourth. xvi) du : Show disk usage. If you are in directory first and type du you will see the size of first in bits. du -h will give the size in human readable form like GB, MB etc. K Vishnu Namboothiri -88- http://vishnu.e-lokam.com xvii) cat: Show the contents of a file - example cat myfile.txt will show the contents of myfile.txt in the terminal. cat can also be used to concatenate files xviii) tail: Show the last part of a file - example tail myfile.txt will show the last few lines of myfile.txt. Useful if you want to see the end of a big text file. xix) cat /etc/issue: will show you the Operating system’s name in which you are working (like Ubuntu, Crunchbang etc) xx) lsb_release -a: more or less the same as above. xxi) uname -a: to find the Linux kernel version. xxii) uptime: how long the system has been up (or on), how many users are logged in etc. xxiii) man command: Example man lsb_release will show the manual page in your Linux system about the command lsb_release. Exercises Ex. C.1 — Experiment all the above commands with the option --help and observe the result. Ex. C.2 — Create, change, delete directories and files several times; get acquainted with the commands. Ex. C.3 — Note down your results. K Vishnu Namboothiri -89- http://vishnu.e-lokam.com Appendix D ANSWERS/HINTS FOR SOME SELECTED EXERCISES Answer (Ex. 1.1) — Both the operations results in integer division in Python 2.x. But in Python 3.x, 5/2 results in float division and gives the answer as 2.5. Answer (Ex. 2.6) — Hint: math.log(math.e) Answer (Ex. 2.10) — Hint: Distance between two points (x1 , y1 ) and (x2 , y2 ) is ——. √ Answer (Ex. 2.16) — Hint: If a + bj is a complex number, then its absolute value is | a2 + b2 |. You may have to split the real, imaginary parts of a complex number, import math, then use math.sqrt(). Answer (Ex. 3.6) — Here is the full code! Code 3.21: PermComb.py # Program PermComb.py to find combination and permutation of integers # Defining the factorial function def fact(n): if n == 0 : return 1 else: return fact(n−1) ∗ n # Definition over n = int(input(”Enter n>=0: ”)) if n < 0 : print (” Invalid input n”) exit () 91 Appendix D. Answers/hints for some selected exercises r = int(input(”Enter r where 0<=r<=n: ”)) if r > n or r < 0 : print (” Invalid input n”) exit () nPr = fact(n)/fact(r) nCr = nPr/fact(n−r) print(”nCr = {0:.0f}, nPr = {1:.0f}”.format(nCr, nPr)) # A better output print(”{0}C{1} = {2:.0f}, {0}P{1} = {3:.0f}”. format(n, r, nCr, nPr)) See section 5.2 for details on format specifiers. Answer (Ex. 3.6) — Hint: Use the % operator Answer (Ex. 3.10)√— We need to factorize the given number in to primes. As a first step, store all the primes up to number to a list, say sieveprimes. Then check how many times a number in this sieveprimes divide the given number. Add a tupple (sieveprime, itspower) to a list. Finally print this list properly. Answer (Ex. 3.11) — Note that we have to find which numbers in range{1,31} satisfy the equation 3 * x -1 % 5 == 0. So? Answer (Ex. 3.12) — Take a number from {0, . . . , n−1}.We need to just check whether gcd(n, m) == 1 or not. Code 3.22: findInvertibleinZn.py # Program findInvertibleinZn.py. For a given n, find the numbers that are invertible in Z_n. # We need to check whether a k is relatively prime to n or not. def mygcd(a,b): while a > 0: b, a = a, b%a return b n = int(input(”Enter n: ”)) for i in range(1, n): if mygcd(i, n) == 1: print (”{} is invertible in Z{}”.format(i, n)) Answer (Ex. 3.13) — Program to find Harmonic sum first: K Vishnu Namboothiri -92- http://vishnu.e-lokam.com Code 3.23: harmonicSum.py # Program harmonicSum.py to find sum of inverses of first k natural numbers k = int(input(”Enter k: ”)) sum = 0 for i in range(1, k+1): sum += 1/i print (sum) Now make the sum as large as you please: Code 3.24: harmonicSumMakeLarge.py # Program harmonicSumMakeLarge.py. Make the harmonic sum as large as we please! bound = int(input(”How large the harmonic sum you want to be? Give upper bound: ”)) if bound <= 1: print(”Invalid input”) exit () sum = 0 n=1 import time start time = time.time() while sum < bound : sum += 1/n n += 1 #print ("n = {}, sum = {}". format(n, sum)) print (”n = {}, sum = {}”. format(n, sum)) print (”Taken”, time.time() − start time, ”seconds”) Answer (Ex. 3.14) — Hint: range(3,99,2). and then a_3tuple = [[x, x**2, x**3] for x in a] Answer (Ex. 3.16) — Hint: Make a list out of the given string; remember one of the previous exercises! Then reverse the list, print it neatly back. Stll difficult? Then here it is: Code 3.36: revstring.py # Program to reverse a string: revstring.py mystring = input(”Enter a word: ”) mystringlist = list(mystring) mystringlist.reverse() newstring = ”” # An empty string for i in range(0, len(mystringlist)): newstring += mystringlist[i] # Concatenate all the characters in the list to make a single string K Vishnu Namboothiri -93- http://vishnu.e-lokam.com Appendix D. Answers/hints for some selected exercises print(”The reversed word is”, newstring) Answer (Ex. 3.18) — See 3.19 Answer (Ex. 3.20) — Sieve of Eratosthanese up to 100 Code 3.38: sieverato.py # Use Sieve of Eratosthanese to find all primes up to n. Mark others as composite. def mysort(numberlist): """ Sort a list of numbers in the ascending order""" lengthoflist =len(numberlist) for j in range(0, lengthoflist−1): for i in range(j+1, lengthoflist): if numberlist[j] > numberlist[i]: numberlist[j], numberlist[i] = numberlist[i], numberlist[j] return numberlist n=100 primenumberlist=[] compnumberlist=[] import time start time = time.time() for j in range(2,n+1): if j in compnumberlist: continue else: primetaken=j primenumberlist.append(primetaken) for i in range(j+1, n+1): # The loop should try all numbers up to n if i in compnumberlist: continue elif i %primetaken==0: compnumberlist.append(i) print (”Composite numbers up to %d\n” %n, compnumberlist) print (time.time() − start time, ”seconds”) # Let us sort the compnumber list. Prime list is already sorted. compnumberlist= mysort(compnumberlist) print (”Composite numbers up to %d (Sorted)\n” %n, compnumberlist) print (”Prime numbers up to %d\n” %n, primenumberlist) Answer (Ex. 4.1) — Use eval() to convert the string into a tuple, check its length via len. K Vishnu Namboothiri -94- http://vishnu.e-lokam.com Answer (Ex. 4.2) — Note that the tuples entered by the user must of be same size. Code 4.9: findDistanceTuple.py # Program to accept tupple input, and find the distance between them # findDistanceTupple.py point1 = eval(input(”Enter an ordered pair in the form (a,b): ”)) point2 = eval(input(”Enter the next ordered pair in the form (a,b): ”)) # Accepted it as a string, and converted into tupple if len(point1) != len(point2): print(”The sizes of the tupples entered are not matching”) exit () distance = 0 for i in range(0, len(point1)): distance = point1[i] ∗∗2 + point2[i]∗∗2 # Finding sum of squares of matching coordinates distance = distance ∗∗ (1/2) # Take the square root of the sum of squares print (”Distance between {} and {} is {}”. format(point1, point2, distance)) Answer (Ex. 4.3) — The trick is, accept a string, convert it into a set so that the duplicate characters will be removed, then convert the set into a list, then sort it. Code 4.21: findDistinctChar.py # Program to find distinct characters in a word: findDistinctChar.py myword = input(”Enter a word to filter duplicate characters : ”) mywordset = set(myword) mywordlist = list (mywordset) mywordlist.sort() # Sort the list in alphabetical ascending order newword = ”” for x in mywordlist: newword += x # Concatenate every character in the list to a single word print (”Number of distinct characers : {} and the characters are {}”. format(len(newword), newword)) Code 4.22: In the terminal/shell >>> Enter a word to filter duplicate characters : Vishnu Namboothiri K Number of distinct characers: 15 and the characters are KNVabhimnorstu K Vishnu Namboothiri -95- http://vishnu.e-lokam.com Appendix D. Answers/hints for some selected exercises Answer (Ex. 5.1) — In format string, {0.real} corresponds to real part of the 0th item in the format specifier K Vishnu Namboothiri -96- http://vishnu.e-lokam.com