''' ========================================================================== Python for Parallelism in Introductory Computer Science Education SC '13 HPC Educators Program Steven Bogaerts, Wittenberg University Joshua Stough, Washington and Lee http://www.joshuastough.com/SC13 MIT License: see README_LICENSE.txt file: pythonIntro.py author: stough Summary: This is just an introduction to some python. When you execfile this file in the interactive python shell or type 'python introPython.py' at the command line or Run->Run Module in IDLE, every line in this file is executed in order. These lines are not because they are part of a multiline comment. ========================================================================== ''' #Here's a single line comment that is also not executed. from functools import reduce #map, filter, and reduce are special functions we will see. a = 4 + 3 b = 6 print(a) print(b) print(a + b) print(3**2) name = raw_input("Please tell me your name: ") print("You told me your name is " + name + ".\n") #We can also define functions in this script. def sayHello(): print("Hello") def computeArea(h,w): """Computes and returns the area of a rectangle with height h and width w""" val = h*w return val #Once we've defined these functions, we can use them. height = input("Please provide a height: ") width = input("Please provide a width: ") #the eval is a little dangerous, should probably use int or double, to #*cast* the input. print('The area of a rectangle with height %f and width %f is %f' % \ (height, width, computeArea(height, width))) """ The above print statement uses a *format string* to specify the printout without actually specifying the *literal* numbers to be printed, since those are stored in the *variables* height and width and some nameless *return value* from the function computeArea. After the format string comes a percent sign, then a *tuple* specfying the *expressions* to *evaluate* and use to replace the %f's in the format string. """ #Now let's look at lists and tuples, which are standard python data types to #store collections of things. alist = [1,2,3,4] atuple = (1,2,3,4) #Look at the attributes of the two variables by typing 'alist.' then pressing tab. #Try for atuple also. """The difference between a list and tuple is that while a list can be added to, inserted into, and elements removed from it, a tuple cannot be changed. It is *immutable*.""" #Elements and subcollections of lists, tuples, and strings can all be accessed #using indexing and slicing. lyst[2] for the third (zero-based) element, #lyst[:j] for all elements up to but not including j... #Different means of iterating through a list, or any iterable. #First indexing for i in range(len(alist)): print alist[i], #An extra argument to print, noting how to end the print (with a space). #old: print alist[i], print() #Iterate by element for x in alist: print x, print() #If you want index and element for i, e in enumerate(alist): print(i, e) """Now let's look at a recursive function. A recursive function must: --contain a base case: an argument for which no further computation is nec. --make the problem smaller: the function must make a smaller problem out of the argument. --call itself: a recursive function calls itself on the smaller problem.""" def fib(n): if n < 3: #base case, no further computation necessary. return 1 else: return fib(n-1) + fib(n-2) #here, fib calls itself on two smaller problems, then performs one simple #addition to solve the problem. print("the 5th fib number is " + str(fib(5)) + ".\n") #Note above I had to *cast* fib(5), which is an integer, to a string before I #could 'add' it to the string 'the 5th fib number is '. for i in range(1,11): print fib(i), #two versions of reversing a list, one iterative, one recursive. Of course, you #could simply say alist.reverse() or reversed(alist), but how does that work. def reverseListIter(l): r = [] #empty list for i in range(len(l)-1,-1,-1): r.append(l[i]) return r def reverseListRec(l): if len(l) > 0: return [l[-1]] + reverseListRec(l[0:len(l)-1]) else: return [] print("\nusing iterative reverse list returns : " + str(reverseListIter(alist))) print("using recursive reverse list returns : " + str(reverseListRec(alist))) """ Finally among the introductory material, we will look at the built-in functions for use on any *iterable* structure. """ """reduce: provide a function that takes two parameters and returns one result, and a list or tuple some iterable. here, sum is such a function, and a is such a list. reduce reduces the iterable to a single value.""" a = [1,2,3,4,5] #a is a list. print("a is " + str(a)) def f(x,y): return x+y #it's the same as sum on a list of length 2. sumOfa = reduce(f,a) print("the sum of a is " + str(sumOfa)) """map: apply the function to each element of the iterable in turn.""" #Here I also use a lambda, or anonymous, function that squares its argument. #old (pre list comprehensions): #theSquares = map(lambda x: x**2, a) theSquares = [x**2 for x in a] print("the squares of the elements of a are " + str(theSquares)) """filter: apply the function to each element of the iterable. The trick here is that the function returns true or false (in other words, it's a boolean function). the result is a list of the elements that satisfied the function. """ #give me only the odd elements. #old: #theOdds = filter(lambda x: x%2 == 1, a) theOdds = [x for x in a if x%2 == 1] print("the odd elements of a are " + str(theOdds))