What is the index of the following characters in these strings? →
1. 0
2. 6
3. 2
What's the output of the following code? →
idx = -2
animal = "tiger"
print(animal[-1])
print(animal[idx])
print("animal"[2])
print(animal[idx + 2])
print(animal[idx + 3])
print(animal[idx + 100])
r
e
i
t
i
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: string index out of range
The indexing syntax is as follows:
# index into string that's bound to a variable name
a = "foo"
a[0]
# index into a string literal
"foo"[0]
# index into the return result of a function
def give_back_foo():
return "foo"
give_back_foo()[0]
We know the first two.
String formatting uses placeholders (we only use %s for now) in a template string, the percent sign and strings within parentheses to create a new string.
name, pet = 'Bill', 'giraffe'
s = 'Hi %s. How is your %s?' % (name, pet)
print(s)
What happens if I try to change the string "pugs" into "hugs" using inexing and the assignment operator? →
"hugs"[0] = 'p'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment
Here's a program that prints out every letter in "jalopy" with 'eer' appended to it.
word = "jalopy"
for c in word:
print(c + 'eer')
Using loops, we can implement a function that determines whether a letter is in a word (there's actually already a construct in Python that does this… ).
def letter_in_word(letter, word):
""" determines whether or not a letter is in a word"""
for c in word:
if c == letter:
return True
return False
assert True == letter_in_word('x', "ox"), "letter is in word"
assert False == letter_in_word('y', "ox"), "letter is not in word"
The break statement immediately stops the execution of a loop. What does the following code print out? →
for letter in "challenge":
if letter == 'a':
break
print(letter + "at")
cat
hat
Here's another way of implementing letter_in_word using break.
def letter_in_word(letter, word):
result = False
for c in word:
if c == letter:
result = True
break
return result
assert True == letter_in_word('c', "chihuahua"), "letter is in word"
assert False == letter_in_word('x', "chihuahua"), "letter is not in word"
Python allows you to carve out a smaller string (a substring) from another string by using slicing.
some_long_string[m:n]
Write the slice to pick out the following substring from the original string:
s = "gone!"
s[0:2]
s[1:3]
s[1:4]
s[1:5]
"eggs and ham"[:4] #eggs
"eggs and ham"[9:] #ham
"eggs and ham"[9:100] #ham
Use the in operator!
>>> word = "ice cream"
>>> letter = "a"
>>> letter in word
True
>>> "cat" in "vacation"
True
>>> "cat" in "work"
False
>>>
Some other things to note:
A string is always a substring of itself.
>>> "vacation" in "vacation"
True
Empty string is always a substring of any other string.
>>> "" in "vacation"
True
not in is the logical opposite of the in operator
>>> "cat" not in "vacation"
False
Strings are objects. They have methods. Lots of 'em!
to be continued in next slide! →
In the interactive shell, you could use the dir with a string in parentheses to show all of the methods of an object:
dir("some string")
upper(), lower(), capitilize(), and title() return the string that the method was called on as all uppercase, all lowercase, first letter uppercase, and title-cased (first letter of every word uppercase). What would the following print out? →
print("this should be uppercase".upper())
print("THIS SHOULD BE LOWERCASE".lower())
print("this should be uppercase".capitalize())
print("this should be uppercase".title())
THIS SHOULD BE UPPERCASE
this should be lowercase
This should be uppercase
This Should Be Uppercase
isdigit(), isnumeric() and isalpha() test whether a string is only composed of all numbers or all letters (all three return False if empty string). What would the following print out? →
* isnumeric() also returns true for numeric characters other than 0-9, such as '⅕'.
print("123".isdigit()) # True
print("1.23".isdigit()) # False (. is not 0 - 9)
print("one two three".isdigit()) # False (not 0 - 9)
print("onetwothree".isalpha()) # True
print("one two three".isalpha()) # False (has spaces)
print("one!".isalpha()) # False (has !)
print("1".isalpha()) # False (it's a digit)
print("⅕".isdigit()) # False (not 0 - 9)
print("⅕".isnumeric()) # True (isnumeric allows other numeric chars)
isspace() gives back true if all of the characters in the string it's called on is white space - any kind of white space. What is the output of the following? →
print(" ".isspace())
print("\n".isspace())
print("some space".isspace())
True
True
False
find() returns the first index where the argument (a character or substring) is found. It returns -1 if the substring is not in the original string.
print("hello".find("h"))
print("hello".find("x"))
print("hello".find("lo"))
0
-1
3
strip() removes leading and trailing whitespace (it can also remove other leading and trailing characters). What do you think this results
print(" spaces all around ".strip())
spaces all around
Format is like the string formatting operator, but possibly easier?!
"{0} elephants".format("twenty")
"{0} elephants".format(20)
"{0} elephants".format(20, 100)
"{1} elephants".format(20, 100)
"{0} elephants and {1} peanuts".format(20, 100)
twenty elephants
20 elephants
20 elephants
100 elephants
20 elephants and 100 peanuts
isupper() and islower() return True if the string that is called on is the case specified. What does the following output? →
print("this should be uppercase".isupper())
print("THIS SHOULD BE LOWERCASE".isupper())
False
True
count(s) …counts the number of times substring, s, occurs in the original string.
'aardvark'.count('a') # --> 3
replace(s, new_s) …replaces all occurrences of substring, s, with new_s. (note that this gives back a new string, and it does not change the original)
'aardvark'.replace('a', '42') # --> 4242rdv42rk
words = "fooXXbarXXbazXXqux"
words_list = words.split('XX')
words_again = '~~~'.join(words_list) # notice this is called on a string!
print(words_list)
print(words_again)
['foo', 'bar', 'baz', 'qux']
foo~~~bar~~~baz~~~qux
len is a built-in function that Returns the length of a sequence
print(len("cat"))
# gives 3
Let's write a function that counts how many letters are in a word. →
def count_letters(letter, word):
"""returns the number of times a letter occurs in a word"""
count = 0
for c in word:
if c == letter:
count += 1
return count
assert 3 == count_letters("a", "aardvark"), "should count letters in word"
assert 0 == count_letters("x", "aardvark"), "zero if no letters in word"
Let's write a function that takes a string and puts a space after every character. →
def insert_spaces(word):
"""inserts spaces after every letter in word"""
new_word = ""
for c in word:
new_word += c + " "
return new_word
assert "f i s h " == insert_spaces("fish"), "inserts spaces after every letter"
assert "" == insert_spaces(""), "empty string if word is empty"
print(insert_spaces("fish"))
Create a function that returns the first word in a sentence.
# version 1:
def get_first_word(sentence):
"""returns the first word in a sentence"""
index = 0
for c in sentence:
if c == " ":
break
index += 1
return sentence[0:index]
assert "hi" == get_first_word("hi there!"), "returns first word"
assert "hi" == get_first_word("hi"), "returns word if only one word"
assert "" == get_first_word(" "), "returns empty if only white space"
assert "" == get_first_word(""), "returns empty if sentence is empty"
# print(get_first_word("hi there!"))
# print(get_first_word("hi"))
(Again, split is not required for the exam, but feel free to use this if you feel like it's applicable).
# version 2 with split:
def get_first_word(s):
if len(s) == 0:
return ""
else:
return s.split()[0]
Write four test cases for get_first_word using: →
assert "foo" == get_first_word("foo bar baz"), "returns first word in space separated string"
assert "" == get_first_word(""), "returns first word in space separated string"
# etc...
Create a function called is_digit that determines whether or not a string only has numbers (0-9) in it.
(General strategy is iterating over a sequence of characters, and changing a value outside of the loop based on characters)
def is_digit(s):
"""determines if a string is numeric (only contains 0 through 9)"""
if s == "":
return False
for c in s:
if c not in "0123456789":
return False
return True
assert True == is_digit("58723"), "true of all characters are numeric "
assert False == is_digit("twelve"), "false if not all characters are numeric"
assert False == is_digit("12 ducks"), "false if not all characters are numeric"
assert False == is_digit(""), "false if empty string"
# print(is_digit("43"))