Intro to Python, Chapter 2 – Strings and Lists

This post was originally published here

Something was really bothering Baldric about 106479825301.0, the answer to the mysterious request he’d received. Sitting down at his desk after enduring his meeting with Kevin, he realized what it was. If you only looked at the answer’s whole number portion…

>>> int(106479825301.0)

…then every number from 0 to 10 appeared exactly once in the larger number’s digits.

“Huh, that’s weird. Well, whatever that means, it’s got nothing to do with me, that’s for sure. No sir, I’d rather be a hobgoblin dentist than poke my nose into Management’s affairs. Not curious at all. Nope.”

After a moment more of staring at the number in silence, Baldric shrugged and proceeded to surreptitiously study a page from a music theory book he’d swiped from the library years ago. This was the most dangerous book he could bring himself to sneak into work. He had worse hidden at home.

Around 10pm, when one was permitted, if not encouraged, to leave the office, Baldric was about to get up and walk home when something caught his ear. A couple of clerks were having a hushed conversation in the hall just outside his cubicle, and he could have sworn he’d heard the word “rebel”. He sat still, pretending to read.

“A rebel leader, huh?”

“Yeah, goes by the name of Cassandra. Apparently they caught her in some kind of ambush.”

The clerk that had just spoken paused for a moment, then lowered his voice. Baldric slowly stood up and crept closer to the conversation, straining to hear.

“You didn’t hear this from me, but supposedly she froze half a legion in their tracks, turned ’em to ice cubes with this magic of hers before they took her down.”

“Mother’s beard, sounds like my kind of gal,” Baldric thought to himself. “That’s of course if she wasn’t a rebel. No, zero interest in that kind of person. I’d better take note of her name though…just so I can make sure to stay away from her, in case we meet by accident or something.” To record the rebel’s name, Baldric began to weave new patterns he had read about in the Book of Magic.

>>> rebel_name = 'Cassandra'
>>> rebel_name

# you can also use double quotes, >>> rebel = "Cassandra"

He could tell this magic was something altogether different from integers and floats and quickly investigated.

>>> type(rebel_name)
<class 'str'>

# str is short for string, a sequence of characters surrounded by quotes
# strings can include letters, numbers, spaces, and other keyboard characters

# you can convert other things into strings using str()
>>> str(2)

>>> str(2.0)

# you can also convert certain strings to numbers
>>> int('2')

>>> float('2')

# but not just any string can be a number
>>> int("mother's beard")
Traceback (most recent call last):
  File "python", line 1, in 
ValueError: invalid literal for int() with base 10: "mother's beard"

Interesting. But the clerks weren’t finished speaking.

“From what I hear, they’ve got her on display at the Teleportation Circle.”

“They didn’t Fire her yet?”

“Well, technically they have to Hire her first, and you know how the paperwork is. But I heard she’s scheduled for Firing first thing in the morning.”

The subject changed, and Baldric decided to slip out. He wanted to see if he could find this pre-burnt-at-stake rebel and still get some sleep before the looming 5am daily start time. It had been easy avoiding unwanted conversations on the way out of the office recently, as many employees were out sick. A significant majority, in fact. Everyone apparently had the same nasty cold. Even Bill from Accounting was out sick, and previously he hadn’t left the office in 7 years! At least the place was quieter than usual.

Just outside the office, posted to the only lit lantern pole on the street, Baldric saw a poster. He could just make out what it said in the moonlight.

CAPTURED: Cassandra Winterheart
CRIMES: Inappropriate Use of Magic, Libel, Arson, Mass Murder, Rebellion, Overdue Books

Come one, come all, to the Firing of the notorious rebel leader Cassandra Winterheart tomorrow at dawn.
All Employees are permitted to attend.

“Cassandra Winterheart. She’s a keeper for sure…I mean, they ought to keep her locked up for sure. I’d better update the name I recorded earlier though, just to be circumspect. Hmm…to add to a string, I seem to recall the Book saying you could use ‘+’ just like with numbers.”

>>> 'Cassandra' + 'Winterheart'

# try >>> 'Cassandra' + ' Winterheart'
# or >>> 'Cassandra' + ' ' + 'Winterheart'

“It worked! Though I need to remember the space. Since I already have her first name saved in the variable rebel_name, I’ll see if I can just add to that same variable.”

# variables containing strings can be added to as follows (try with numbers too)
>>> rebel_name = rebel_name + ' Winterheart'
>>> rebel_name
'Cassandra Winterheart'

# also try >>> rebel_name += ' Winterheart'

Baldric left the poster and began walking down the dimly-lit streets of the city in the direction of the Teleportation Circle. “Well, I guess I’ll just go for a walk to clear my head before I go home. No direction in particular. Just getting a little exercise, that’s all.” He noticed that, aside from a few guard patrols, the streets were deserted. There were more than a few rats about, but not a single person. Normally there’d be at least a little activity this time of night. Maybe everyone was getting a good night’s rest for the Firing tomorrow.

Putting those thoughts out of his mind, Baldric experimented further with this new Magic of his.

“So Magic can be used with not only numbers, but words too! I wonder if there’s anything else I can do with strings. Well, if addition works with strings, and all the basic arithmetical operators ( + , – , * , / ) worked with numbers, maybe all the other operators work on strings too.”

>>> rebel_name - ' is someone I hope I NEVER meet'
Traceback (most recent call last):
  File "python", line 1, in <module>
TypeError: unsupported operand type(s) for -: 'str' and 'str'

>>> rebel_name * ' is someone I hope I NEVER meet'
Traceback (most recent call last):
  File "python", line 1, in <module>
TypeError: cant multiply sequence by non-int of type 'str'

>>> rebel_name / ' is someone I hope I NEVER meet'
Traceback (most recent call last):
  File "python", line 1, in <module>
TypeError: unsupported operand type(s) for /: 'str' and 'str'

Text that looks like the results above indicates that some kind of 
error (aka 'exception') has occurred. In these cases, they are all TypeErrors.
The text after 'TypeError:' gives a description of the error.
The text above 'TypeError:' says where in the code the error occurred.
For now, don't worry too much about interpreting these messages.
Just know that they mean something in the code didn't quite work.

# And this is a single line comment
# but the above paragraph is a multi-line comment (and string too), which is wrapped in triple quotes.
# To see that it can also be a string, try assigning the above multi-line comment to a variable.

Baldric’s weavings of Magic, instead of coalescing into a result, simply unraveled and faded away. “Well, that didn’t work. So I can at least combine strings to make longer strings. But what if I just want part of a string? Like, say, Cassandra’s initials? Maybe something like…”

>>> rebel_name[1]

“What happened there? Oh, I remember now, Magic starts most things counting from zero, not one. So to get the first character, I need to do…”

>>> rebel_name[0]

“And if I wanted the initials…”

>>> first_initial = rebel_name[0]
>>> last_initial = rebel_name[10]
>>> print(first_initial, last_initial)

# try assigning both variables at once
# >>> first_initial, last_initial = rebel_name[0], rebel_name[10]

“That’s nice, but I’ll wager there’s a way I can select more than just one character from a string at a time. Actually, I think I remember how.”

>>> rebel_name[0:8]

“I see, so the 0th character is included in the slice, but the 8th character is not. So if I want all characters from index 0 to index 8, I need to do…”

>>> rebel_name[0:9]

# also try >>> rebel_name[:9]

“Perfect! I’ll store both names separately.”

>>> first_name, last_name = rebel_name[:9], rebel_name[10:]

>>> print(first_name, last_name)
Cassandra Winterheart

At this point, Baldric could just make out the top of HR’s facility over the rooftops to the northwest, a set of three inverted pyramids held aloft over an open pit of lava by a wild array of spindly stone pillars. The lava cast the the fortress in a deep red glow. But more menacing still was the Emperor’s Palace to the north, an impossibly high black stone fortress that loomed over the city like a gravestone over an ant colony.

Baldic froze as he suddenly had a flashback to his dream last night. His recollection was foggy, but he remembered dark corridors, and a man, and a door, and…he was starting to recall more of the dream when something caught his eye high up in the sky. A faintly shimmering purple web spreading out over the city. He watched it in perplexion as it continued to expand, crisscrossing the sky as far as he could see.

“What in the name of my father’s axe is that? Oh boy, yep, definitely another one of those things that is not my business. What mystical sky web? I don’t see anything. Maybe it’s time to head home.” He turned around and started walking, then paused to stare up at the sky for a moment more. Finally Baldric turned back around and continued determinedly in the direction he had been going. “I can get home just as fast taking this route. It’s more scenic anyways.” Walking along, he was soon lost in thought once again.

“Hmm, so addition is the only operation that works with two strings. Something about that is bugging me…Aha! What if I use both strings and numbers together?”

>>> test_string = "Busyness is Progress!"

>>> test_string + 3
Traceback (most recent call last):
  File "python", line 1, in <module>
TypeError: Cant convert 'int' object to str implicitly

>>> test_string - 3
Traceback (most recent call last):
  File "python", line 1, in <module>
TypeError: unsupported operand type(s) for -: 'str' and 'int'

>>> test_string * 3
'Busyness is Progress!Busyness is Progress!Busyness is Progress!'
# Bingo!

>>> test_string / 3
Traceback (most recent call last):
  File "python", line 1, in <module>
TypeError: unsupported operand type(s) for /: 'str' and 'int'

“Fascinating! So you can actually multiply strings and numbers together to form a longer string. But what if…”

Muttering to himself as he strolled along, Baldric half-consciously navigated the city streets. At one point he thought he heard something and stopped to look around. He had wandered into an alley with deep shadows and several nooks and crannies. Not seeing anyone, he continued on, more cautiously than before, when a putrid stench struck his nostrils. He was about to vomit, but had to focus on maintaining his balance as something wet caught his ankle. He heard a moan from behind, and turned to see a man stumbling towards him in the moonlight. Half the man’s face was missing.

Baldric fell over backwards in shock and landed in more of the smelly wet ropes. As the man staggered towards him, Baldric wished the man would go away, and found himself weaving threads of Magic, something other than Logic. A gust of wind burst towards the man, barely slowing him down for a moment. Baldric then focused on the man freezing in his tracks. A chilling mist descended on his assailant, ice crystallizing over him, but the man kept stumbling on. Scrambling backwards through more rubbish, Baldric frantically imagined a wall. The earth rose up in front of Baldric to form a knee-high rise which the man tripped over, but still he crawled onward, moaning and grasping for Baldric’s foot. Imagining the man’s destruction, Baldric channeled yet a different kind of Magic, and jets of flame erupted from Baldric’s outstretched hand. The man was enveloped by the flames and after a moment finally lay still, smoke rising from his charred corpse.

Panting heavily, Baldric stood up, trying to make sense of what had just happened. He was glad it was too dark to see what he had been crawling through. “Wow…okay. That was…something. Yeah. Of all the places in the world, who would’ve guessed that this was where I’d see my ex-wife again? And I guess I can shoot fire now? What a day. Anyways, I’d better be moving along. No telling how many more of those things there are, or what the city guards would make of the situation.”

Still slightly in shock, Baldric continued on and soon found himself in a large, circular moonlit plaza. It looked like something was carved into the ground here, several rings of symbols apparently encircling the plaza, but they were hard to see in the darkness. He could, however, make out the three large statues spread evenly around the circle. Statues of sphinxes, as he recalled. “Uh oh, looks like I accidentally wandered over to the Teleportation Circle. Oh well, no harm done, I’ll just turn around and…” There was a wheeled cage in the center of the Circle containing a shadowy seated figure. It rose when it saw him and motioned him over.

“Pssst. Baldric, quickly, there isn’t much time!” it whispered.

Baldric gasped. He glanced around, pondered running home one last time, then hurried over to the cage. Inside was a young elven woman in a gray prisoner’s garb. Beautiful, like a porcelain doll made flesh. She commanded an air of authority, however, and even in the darkness Baldric could tell she was a woman that expected to be obeyed. “Not my type at all actually,” Baldric thought to himself. “Eighty pounds and a little stubble would do her good.”

“Uhh, how do you know my name?” he whispered back.

“We don’t have time for explanations, but suffice it to say our meeting was preordained by powers greater than you or I. I take it you know who I am? Good. Now, there’s something I need you to do. Tonight.”

“Me? Why, what could I possibly do? Why don’t you just break out and do it yourself?”

“Look at the ground Baldric, at the seal that blocks my Magic and holds me here more strongly than steel ever could.”

Looking at the ground, Baldric could indeed see a circle around the cage composed of intricate patterns of faint-green numbers and letters. Studying the patterns, he felt a vague sense of understanding. He began to weave his own Logic, and…

Cassandra’s eyes began to widen in surprise. “Stop that! What are you doing?”

“Oh, you can see it too? I don’t know, it just almost seems like a puzzle, like I could…”

“No, you must leave it alone! It’s…it’s set to explode if anyone tries to undo it.” Composing herself, Cassandra’s mouth curved into a small smile.

“I must say, it’s extremely rare for anyone to be such a natural with Logic. But you must focus, and be very careful who you use Magic around. Other Magic users will spot you plain as day. In any case, listen closely. We are going to bring down the Emperor.”

Baldric felt like the wind had been knocked out of him.

“Whoa whoa whoa, I’m just out for a walk lady. You can’t really mean…” Lowering his voice to the barest whisper, Baldric leaned towards Cassandra. “How would we do that?”

“First you must retrieve something for me. A lockbox, from the desk of the HR Manager.”

Baldric gaped and spluttered trying to respond. “The the the, the the the…HR Manager? Look, I’m sorry lady, I really am, but what chance does a lazy old dwarf like me have against THAT thing? I’ve heard the rumors. I’m not doing it.”

“Tonight the creature will be absent from its lair.”

“It’s lair? You mean HR’s facility, right?”

“No, the HR Manager has its own office underground, not too far from the facility. Like I said, it isn’t there right now, but for how long I cannot say, which is why you must go with all haste. Sneak into its office and retrieve from its desk a small black metal lockbox. Then return home and await my word.”

“Okay, let’s say I do all that. How exactly is that supposed to help us defeat the Emperor?”

Cassandra gave him a considering look. “I suppose you deserve to know what you’re getting into. The lockbox contains something we need for the fourth phase of my plans, which I’ll get to in a second. For phase two, after you acquire the lockbox, we shall sneak into the Emperor’s castle and destroy the source of his awesome powers. I know not what it is, only where it is located.”

Baldric wove Magic to record Cassandra’s plans.

# to store multiple objects, such as numbers or strings, try using a list
>>> objectives = ['steal lockbox', 'destroy power source']

>>> objectives
['steal lockbox', 'destroy power source']

>>> type(objectives)

This new type of object, the list, that Baldric had read about in the Book of Magic intrigued him, and he couldn’t help but think to himself, “If numbers could be converted to strings with str(), and certain strings could be converted to numbers with int() and float(), I wonder if lists can also be converted back and forth between different types too.”

>>> list(4)
Traceback (most recent call last):
  File "python", line 1, in <module>
TypeError: 'int' object is not iterable

>>> list(4.0)
Traceback (most recent call last):
  File "python", line 1, in <module>
TypeError: 'float' object is not iterable

>>> list('steal lockbox')
['s', 't', 'e', 'a', 'l', ' ', 'l', 'o', 'c', 'k', 'b', 'o', 'x']

# aha, strings can be converted to lists!
# and integers and floats cannot be converted to lists

>>> int(objectives)
Traceback (most recent call last):
  File "python", line 1, in <module>
TypeError: int() argument must be a string, a bytes-like object or a number, not 'list'

>>> float(objectives)
Traceback (most recent call last):
  File "python", line 1, in 
TypeError: float() argument must be a string or a number, not 'list'

>>> str(objectives)
"['steal lockbox', 'destroy power source']"

# alternately, lists can be converted to strings
# but lists cannot be converted to integers or floats

Baldric realized Cassandra was speaking to him and tuned back in.

“Third, once the Emperor is weakened, we must free the prisoners from HR, many of whom are Magic users.”

“Well,” Baldric thought to himself, “if ‘+’ can combine strings, I’ll bet it can combine lists too.”

>>> objectives = objectives + ['free prisoners']
>>> objectives
['steal lockbox', 'destroy power source', 'free prisoners']

“I see, similar to strings indeed. I wonder if using the ‘*’ operator with a list and a number has a similar effect.”

>>> objectives * 2
['steal lockbox', 'destroy power source', 'free prisoners', 'steal lockbox', 'destroy power source', 'free prisoners']

“I think I’m starting to get the hang of this.”

“I can see your Magic you know, do try and concentrate!” Cassandra scolded. “Fourth, with the help of those Magic users, we hijack the Teleportation Circle and summon my rebel army to the heart of the Empire. We’ll need both your powers of Logic and a key that the lockbox contains in order to activate the Circle. Fifth, we assault the Emperor’s castle, and with our combined might, overthrow the Empire and slay the Emperor himself.”

>>> objectives += ['hijack teleporter', 'assault castle'] # remember, x += y is the same as x = x + y
>>> objectives
['steal lockbox', 'destroy power source', 'free prisoners', 'hijack teleporter', 'assault castle']

Baldric, seeing how lists were similar to strings, thought to himself, “So if I wanted to get the first or last items in my list…”

>>> objectives[0]
'steal lockbox'

>>> objectives[4] # also try >>> objectives[-1]
'assault castle'

“Just as expected. And again, just like strings, I’ll bet if I want a slice of the list, I just need to do something like…”

# all items but the first
>>> objectives[1:]
['destroy power source', 'free prisoners', 'hijack teleporter', 'assault castle']

# third and fourth items
>>> objectives[2:4]
['free prisoners', 'hijack teleporter']

A question occurred to Baldric. Maybe Cassandra knew the answer. “Oh, I need to ask you, what’s with that purple web in the sky? It’s not your doing is it?”

“No Baldric, that is the creation of the HR Manager, a magical construct it weaves to capture and consume the dreams of the populace every night. If this is the first night you’ve seen it, it’s because your Magical powers have only recently emerged.”

“Come to think of it, I haven’t had any dreams in a long time…aside from one last night.”

“Yes, Magical ability typically affords some protection from the HR Manager’s designs. But that won’t save you if it catches you in person.”

Cassandra provided Baldric with details on how to infiltrate the HR Manager’s lair, then sent him on his way.

“Now that you understand what we’re up against, go with all haste, Baldric Hightower, and retrieve the lockbox from the desk of the HR Manager before it returns to its lair. There is a cart waiting for you just north of here which will take you to the underground entrance. Good luck, and may the Great Serpent watch over you.”

With grim determination, Baldric nodded to Cassandra and set off on his way. Walking up the street, he soon found a donkey cart with its driver leaning against it, appearing to have dozed off. The driver didn’t look up as Baldric approached, but silently climbed into the front, leaving a seat open next to him. Baldric climbed on, and the driver set off.

After a ride through the dark streets they pulled into an alley behind a warehouse. They were somewhere between the Emperor’s Palace and the HR facility now. The driver got off the cart and walked over to a nearby sewer access hatch.

“Here’s yer’ bloody manhole, sealed up tight with Magic. Wizards used to run this city you know, and they made sure not just anyone could go skulkin’ about the sewers. If you can get through there, you’ll climb down a ladder, turn right, follow the walk until you come to a dead end, then crawl through the grate and up the passage.”

Upon the sewer hatch was engraved:

Each line is a string
That should be extended
So multiply by 43
Oh that would be splendid

Put the strings in a list
Multiply it just the same
Then use the string and list indices
To solve this game

Indices: [107][733], [137][898:902], [152][682:685], [187][864], [238][1301:1303], [253][957], [296][847:849], [334][-1], [-4][-2]

“These pairs of indices given here are peculiar,” Baldric muttered to himself. “Ah, I think I see what’s going on here. Let’s say for example that I have a list containing a few strings, like the objectives list.”

>>> objectives = ['steal lockbox', 'destroy power source', 'free prisoners', 'hijack teleporter', 'assault castle']

“Then if I apply a pair of indices to that list, such as [2][5], I’ll be selecting the list element at index 2, then the character at index 5 of that list element.”

>>> objectives[2]
'free prisoners'

>>> objectives[2][5]

“And I bet I can get string slices like this too.”

>>> objectives[2][5:9]

“Just as I thought. Alright then, let’s get this manhole open.”

s1 = 'Each line is a string'
s2 = 'That should be extended'
s3 = 'So multiply by 43'
s4 = 'Oh that would be splendid'
s5 = 'Put the strings in a list'
s6 = 'Multiply it just the same'
s7 = 'Then use the string and list indices'
s8 = 'To solve this game'
n = 43

string_list = [s1*n, s2*n, s3*n, s4*n, s5*n, s6*n, s7*n, s8*n]

final_list = string_list * n

# use back slashes to continue one line onto multiple lines for readability
answer = final_list[107][733] + final_list[137][898:902] + final_list[152][682:685] + 
         final_list[187][864] + final_list[238][1301:1303] + final_list[253][957] + 
         final_list[296][847:849] + final_list[334][-1] + final_list[-4][-2]

what is busyness

“What is busyness? Hmm. Busyness is…no, not progress. It’s a disease, if you ask me. It’s death.”

With that, the text on the sewer hatch vanished, and the circular cover swung upward, revealing the top of a ladder leading down into darkness. Baldric climbed down, and the lid shut behind him. The driver climbed back on his cart.

“What a dwarf is doing crawling through manholes at this hour I don’t want to know. Manhole. Hehe, what a word.”

The driver and his donkey slowly made their way through the night, the Magical web still silently lurking over the city. High above it the moon rose in the sky, and was momentarily obscured by a large winged silhouette.

Congratulations, you earned 97 experience and 24 gold! You are now a Level 2 Dwarven Apprentice! (cue victory music)

Here are the Python topics you covered (and may want to DuckDuckGo for further inquiry):

  • strings
  • lists
  • string and list concatenation
  • extending strings and lists via multiplication
  • string and list indexing
  • string and list slicing
  • converting data types with int(), float(), str(), and list()
  • multi-line comments/strings (using triple quotes)

Chapter 3 – Conditional Statements >>>

Related Posts

Local Interpretable Model-agnostic Explanations – LIME in Python When working with classification and/or regression techniques, its always good to have the ability to ‘explain’ what your model is doing. ...
Python – TechEuler Python – TechEulerUnOrdered Linked list – Prepend, Append, Insert At, Reverse, Remove, SearchUse of __slots__ in Python ClassUsage of Unde...
Introduction to Python Ensembles Stacking models in Python efficiently Ensembles have rapidly become one of the hottest and most popular methods in applied machine learning. Virtually...
Postgres Internals: Building a Description Tool In previous blog posts, we have described the Postgres database and ways to interact with it using Python. Those posts provided the basics, but if you...