DAY 7 Continuing with our problem solving: NEXT CODE (not a function - why? no particular reason) reverse a string. how would a human do that? s = 'abcde' get the e, add the d, add the c, add the b, add the a another thing you can do, which will enable us to use a simple for loop starting from the beginning of the string: let's build up the string in variable reverse. it will start as '' the for loop: for char in s: so, as above, we'll go through it char by char from the beginning see the examp le: each char reverse [fill in this column first] 'a' 'a' NOW: let's put the next character on the front of our new list! 'b' 'ba' 'c' 'cba' SO: take reverse so far -- the 'cba' and put 'd' on the front of it 'd' 'dcba' 'e' 'edcba' take reverse so far and put char on the front of it. how do we do that? reverse = char + reverse! reverse = "" # An accumulator for char in s: reverse = char + reverse print reverse *** Look at string_funs.py - show them how I tested it. ***** *** it will save you time to do this. some extra typing to do the *** test cases, but you will know right away if it is right. Save *** these tests. Then, if you ever change the code, you can just run *** these print statements, and see if it still works! *** == Objects and Methods -- all data values are 'objects' -- many types of objects define functions that are specific to that type of object called 'methods' not 'functions' [general idea; object-oriented programming] You call functions like this: function_name(arguments) Methods are functions that "belong" to an object, and you call them differently. Strings have many methods defined for them. A bunch of common ones are listed in figure 4.3 in the text. These are functions that python strings "own" "lower" - converts any letters in the string to lower case >>> mystring = 'Hi, There, Bear!' >>> mystring.lower() >>> # mystring is not changed; but you knew that # strings are immutable!! If you do help on all the string # methods, you will see that they return an object; obviously # they don't change the original string. >>> mystring >>> help(str.lower) >>> help(mystring.lower) >>> help('abc'.lower) >>> help(str.replace) >>> help(str.count) >>>help(str.find) >>>help(str.startswith) >>>help(str.len) ** not a method of str ** a primitive function built into python Designers of Python could have defined it either way - method or function Also, programmers design their own kinds of objects (we'll see a bit of this; CS401 covers this) Guidelines: method or function? - if operation is only relevant to one type of objective, make it a method of that type lower, replace, and so on - if it applies to different types of objects, make it is function, so it can be applied to those different types of objects len('hello') len([1,2,3,4,5]) etc. -YOU WON'T need to make this decision in this class. But the issue was probably bugging you. - Your job: be able to recognize when we are calling something as a function and when we are calling something as a method. ==More about strings # strings are immutable # strings are sequences of characters # each character has an index - its location in the string # the first index is 0 # comparing strings: alphabetical # for non-alphabetic characters, an ordering is defined # What you need to know: "a" < "b" < ... < "z" "A" < "B" < ... < "Z" "0" < "1" < ... < "9" # you won't need to know, e.g., ',' < '!' for this class (unless we tell you such a fact for an assignment). But, for text processing applications, you would need this. OK that was alot of information!!! Let's do examples to excercise it all == Examples with Strings == # ------- String methods ------- s = "What an WONDERFUL day was September 20th, 2009!" s2 = s.lower() # calling it as a method. var . method name () s s2 >>>"This is CS????".replace("????", "0008") >>> "This is CS0008".count("i") >>> "This is CS0008".count("j") s = "yabababa daba do!" s.count("aba") # algorithm? after it finds a match, it starts #looking in the string AFTER the end of the match. s.count("abab") s.count("bad") #can't ignore spaces - they are chars too! >>> "This is CS0008".find("is") # first occurrence looking from left >>> "This is CS0008".rfind("is") # first occurrence looking from right >>> "This is CS0008".find("is", 3) # first occurrence looking from index 3 on from left >>> "This is CS0008".find("is", 2) >>> "This is CS0008".find("the") # not found # ------- String comparisions ------- 'a' > 'b' 'ant' <= 'apple' 'a' < 'A' ',' < '!' '!' < 'a' # ------- String length function ------- len(s) == Writing another string function == def are_same_string(str1, str2): '''Return True if string str1 and string str2 have the same contents (ignoring case), and False otherwise.''' **** I'll give the constraint from lab -- do this with one line!! **** what type of statement does it need to be? **** everyone! if you have one statement, and the docstring is this... !! A return! ADD return str1.lower() == str2.lower() print are_same_string("AbCdEF", 'abcdef'), 'sb True' # ------ Slicing and dicing strings ------ s = "sliceofspam" s[0] # Grab a single character. First index is zero. s[3] s[-2] # Negative indexes are for counting from the RHS # here's how to think of the numbering: "0 s 1 l 2 i...ceofspam" ...7 s -3 p -2 a -1 m 0 but 0 is the one on the left s[2:5] # Slice a string. From position 2 to 5 (not inclusive) s[3:] # If omit the second index, goes to the far RHS s[:8] # If omit the first index, goes from the far LHS s[:] # If omit both, goes from both extremes. Ie, you get the whole string s[3:-2] # You can use negative indices when slicing too s[-5:] s[5:2] # ?? NOTE: At the end of class, I went over the while loop example at the beginning of speaking 8. I am going over that again at the beginning of speaking 8, so I'm putting it on that file.