What we’re doing: more Python working with strings.
Why we’re doing it: to practice algorithmic thinking. And troubleshooting, of course.
Preparation
Log on to a MathLAN computer and click on the Applications button in bottom left corner. Go to Development and then the program called IDLE 3. This will open a window that looks like a terminal window but running Python instead of a file directory. This is called the Shell screen. In it, you interact directly with Python. If you want to create a script you can save, go to File and open an existing script or start a new one. To run it in the shell, first save it and then go to Run > Run module.
Note: take note of where you are doing your coding. When we’re trying out basic commands, it’s convenient to write them directly in the shell. When it comes to writing functions or scripts, it’s a good idea to write code in a file rather than the shell. This way, you can debug and run it multiple times without re-typing it.
Also note: at the end of the last lab, I claimed that we were going to spend the next two lab days creating computational literature. I thought about it, and I decided that doing a few processes in Python would help us understand what we were doing better, and provide further practice in algorithmic thinking.
One more note: in this lab, we’re going to practice doing something that is very common in both CS learning and working: pair programming. See the board for your partner.
More things with strings
As we’ve learned, strings are a set of characters in a particular order. We’ve practiced string concatenation ( using the + operator) and we’ve practiced the conditional if...in with strings. Now we’re going to do some other things with strings.
len()
We’ve talked about the len() or length function with respect to lists, but they can also be used on strings. Try it out in the shell:
>>>>len(“banana”)
and you can also do it on a string variable:
>>>word = “banana”
>>>len(word)
Now try adding a space after banana–what do you think will happen to the result?
Index position
So now we know how many characters are in banana. We can use this information to pull out characters in specific locations. You can refer to characters in a string using their index positions (similar to calling an item in a list).
The syntax for this is
stringVariableName[IndexNumber]
example: word[1]
What letter do you think the following commands will return?
>>>word = “banana”
>>>word[6]
>>>word[0]
Try to explain these results.
Given these results, how might we tell Python to locate the last character of a word if we didn’t know in advance how long the word was?
First, we would need to know how many characters were in the string:
>>>word = “banana”
>>>wordLength = len(word)
But remember, if we use the len() result, we’ll be referring to an index position that doesn’t exist. We need to subtract one to account for the fact that Python starts counting at zero. That is then the index position we need for the string.
>>>lastLetter = word[wordLength-1]
>>>print(lastLetter)
Answer the following questions before you go on:
Why does the lastLetter variable use brackets instead of parentheses?
Based on the fact that [wordLength-1] works, what can you tell about the data type that the len() function returns?
Slicing
Using index positions, we can also select groups of characters from a string by referring to a range of index positions. This is called slicing. What do you think the following command will return (using the same stored word variable we have just established):
>>>word[0:2]
Did it give you what you expected? What can you deduce about the syntax based on this?
Try to apply what you’ve hypothesized to predict the output of the following commands:
>>>word[:2]
>>>word[2:]
Write a function that takes a word as input and returns that word without the first letter.
String methods
So far, we’ve looked at built in functions. len() is a built in function. There is another type of commands you can give in Python called methods. They are very similar in effect (take an argument as input and give an output) but have a different syntax. They are built into Python for certain types of data (also known as objects), and they are available any time you are using that type of data (rather than needing to import them as a module).
The basic syntax is:
argument.method()
What does this method do?
>>>word = banana
>>>print(word.upper())
Experiment with the following additional methods:
word.capitalize()
word.lower()
What if you are working with a sentence rather than a word? Python will see it as a long string, but you might want to think of it as a list of words. You can use the string method string.split() to break a sentence into a list of words.
>>>sentence = “I want a banana.”
>>>print(sentence.split())
Iteration on a string
You can also iterate on characters in a string the same way we iterated over items in a list.
Try this:
>>>word = “banana”
>>>for letter in word:
print(letter)
(remember to hit enter twice to run what you’ve entered in the shell)
Okay, but what if you don’t want every letter to print on a new line, you just want to assemble a new word?
What you need is a new place to put the results of each iteration. To do this, you can start the function with an empty string to be filled up later.
Write this script and run it:
def printWord():
word = input("Enter a word: ")
newWord = ""
for letter in word:
newWord = newWord + letter
print(newWord)
This is a pretty boring function. But let’s put the technique to use…
Pyg Latin
When you were a kid, did anyone ever tell you that there was a language called pig latin? Here’s how you “speak” pig latin:
For each word:
if the first letter of the word is a consonant, move the consonant to the end and add -ay
if the first letter of the word is a vowel, add -ay to the end
Write a function that takes a sentence as input and produces the pig latin version. Before the function runs, make sure the sentence actually exists, eg is longer than zero characters.
Hints:
- To get started, make a list of the steps involved. For each item on the list, what commands have you seen that could address it?
- There are multiple ways to do this, but it will involve being able to work with individual words, being able to check if the first letter is a vowel or not, and looping through the words.
- Remember the
if … incommand? You can check for multiple things at once if you put them in a list. - Test several sentences to see if it works as you anticipate.
- Getting rid of punctuation is an interesting problem. There are libraries to do this. You could also just ask the user not to include punctuation. How could you check the input to make sure they had done this?
If time
Grocery list
Write a function that compares two lists: one with the foods that you have in your kitchen, and one with the things that you need in your kitchen. What do you need that you don’t have? Output these things in a third list.
Get a list of things from a website
What if you’re tired of making up words? Maybe someone out there has put together a big long list you can grab.
To do that, we first need to go to a website and open it. And to do that, we need to call on some modules with a set of tools to help:
>>>import urllib.request, json, io
Now we can open a page and store its contents in an object:
>>>list = urllib.request.urlopen("https://raw.githubusercontent.com/dariusk/corpora/master/data/foods/fruits.json")
>>>listread = list.read()
And now, to put you a step ahead, I’ll tell you that the data on the url is in json format, and guess what, there’s a module to help us read it.
Now we can use helper functions in this library to pull out the list of the things we actually want from the json on that page:
>>>fruitsList = json.loads(listread.decode("utf-8"))["fruits"]
Now, can you tell me how many fruits are in that list?
A couple of syntax things: I put in the .decode method after getting error messages in our Python shell, even though it worked on the Python on my own laptop. Turns out they are slightly different version (3.5 vs. 3.7). Our classroom version, 3.5, needs to be told what the character encoding is for this method, otherwise it doesn’t realize it’s getting strings.
And how did I know that [“fruits”] was the chunk of the json object that I wanted? I inspected the source data.
Acknowledgements
This lab is based on the Strings lesson from the open online course Python 3 for Everyone: https://www.py4e.com/
