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, animal = -2, "tiger"
print(animal[-1])
print(animal[idx])
print("animal"[2])
print(animal[idx + 2])
print(animal[idx + 100])
r
e
i
t
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]
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
What happens if I try to access an index that doesn't exist? →
word = "pugs"
print(word[50])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: string index out of ranges
What if we want to do something to each character in a string?
We can iterate over every character that's in a string.
# for loops!
for c in "hello":
print(c)
my_crazy_string = "oh my!"
for c in my_crazy_string:
print(c)
o
h
m
y
!
The following code:
word = "jetpack"
suffix = "am"
for c in word:
print(c + suffix)
assert <some expression that results in a bool>, <a string>
assert expected == actual, "describe test"
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
A docstring is a triple-quoted string immediately following the header of a function definition.
def foo()
"""gives back a greeting"""
return "hi"
Try implementing this function!
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"
Here's another way of doing it 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"
There are actually a couple of much easier ways to do this rather than writing our own function. What are two ways of determining whether or not a string is a substring of another string? →
# use the in operator:
'a' in 'aardvark'
# use the find method:
'aardvark'.find('a')
Write a function that counts how many times a letter occurs in a word. →
>>> print(count_letters('a', 'aardvark'))
3
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"
Just like finding a substring, there's a much easier way to find the number of times a substring occurs inside another string. What is the method that let's us do this? →
# it's just count!
"banana".count('an')
Let's write a function that takes a string and puts a space after every character. →
>>> print(insert_spaces('aaaah!'))
a a a a h !
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"))
You can also retrieve a substring from another string.
This is done using slicing. Slicing syntax works as follows:
>>> "placate"[3:6]
'cat'
Looking at the slicing code again:
>>> "placate"[3:6]
'cat'
The general case is:
some_long_string[m:n]
Write the slice to pick out the following substring from the original string:
s = "gone!"
# 01234
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
Create a function that returns the first word in a sentence.
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"))
Create a function that determines whether or not a string only has numbers (0-9) in it.
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"))
And of course, there's already a couple of methods that do this. What are they? →
"123".isdigit()
"123".isnumeric()
"abc".isdigit()
"abc".isnumeric()