""" Joshua Stough Washington and Lee University 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 = 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 = eval(input("Please provide a height: ")) width = eval(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], end = ' ') #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, end = ' ') 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), end=' ') #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))