Intro to Python, Chapter 6 – Built-in Functions and Methods


Magic-wielding escapees were desperately deflecting the Imperial attacks on the fortress’ supports as best they could. Ranks of longbowmen rained down arrows, but conjured gusts of wind sent many of them flying back the other way. The rebels were holding the Imperials off for the moment, but Baldric could see it was only a matter of time before they all took a dive, like so many employees before them, into the lake of fire.

Of course, HR prisoners usually died by some other means first, such as repeated staff meetings. Ten a day, Baldric had heard. Then they were bundled up and stacked like firewood as he’d seen below before being tossed in the lava. Bundled up…the shrouds…

“Cassandra, the death shrouds HR uses. We’ve got some powerful Wind users here. What if we all grab a shroud and let the Wind guys float us out of here!?”

One of the Wind users, a graying gnome, looked up at them. He seemed to think for a moment, then shrugged and said, “It won’t be easy, but we might be able to manage it.”

After a moment of thought, Cassandra nodded. “The Great Serpent help us if that’s the best we’ve got. Sigh, get to it immediately.”

Baldric flew down the stairs and back to the storerooms of Block A. Weaving arms of Wind that gathered up all the shrouds into one big bundle, he carried them up to the roof, sweating with the concentration it took to maintain the flows of Wind. He emerged from the trapdoor back among the prisoners and pulled a huge bundle of shrouds up after him.

Cassandra had apparently briefed everyone on the plan because on cue several individuals at a time ran over to the shrouds and quickly began unfolding and reconfiguring them and the accompanying ropes so that they became a sort of makeshift parasail wing with a rope through the middle of each of the two shorter sides that was then tied around one’s torso. But the rebel Magic users were visibly tiring from the efforts of the defense, and the additional lapse from rebels seeing to their escape shrouds gave the Imperials an opening. With a sickening crunch Baldric felt a main support give way.

“Everyone ready?” Cassandra shouted.

One of the prisoners shouted back, “Wait, we’re short a shroud!” A 4-foot diameter fireball from the Imperials streaked through the air, leaving no trace of the prisoner it passed through behind.

“Alright we’re good to go,” Cassandra responded. “Wind channelers, get us off this Light-forsaken thing!”

Just as the fortress gave way under everyone’s feet, Baldric felt a strong updraft that instantly filled his death shroud parachute and carried him skyward. Like dandelion seeds, the ragtag rebels were blown through the air to the east towards the Teleportation Circle. The Imperials, caught by surprise, tried to pick them off with arrows and Magical projectiles, but the rebels were soon outside their range and on their way back to the city proper.

Cassandra floated over to Baldric. “We’ll be at the Teleportation Circle in several minutes, and you’ll need to unlock it ASAP. You’ll find three stone sphinxes, and each will have a puzzle to solve. Once those are are taken care of, that key I gave you will activate the Circle. I must warn you though, the puzzles involve heavy use of built-in functions, string methods, and list methods. But I have no doubt you can do it.”

“Well, that makes one of us,” Baldric muttered to himself. He began to ponder his chances of unlocking the Circle. Was he at that level yet? He knew at the very least he had a whole lot more to learn about built-in functions and methods, and he decided to see what he could figure out on his own.

Sphinx 1

“I know that a built-in function is a function just like all the ones I’ve written, except I don’t actually have to write it. It’s just always there in the background, waiting for me to use it. And actually, now that I think about it, I’ve already used a lot of built-in functions without even realizing it.”


print()
Displays, or “prints out”, what’s passed into it. Useful in script mode where values aren’t printed to the console unless this function is called.

# in interactive mode, print() often acts the same as just entering an expression without print()
>>> 2 + 2
4

>>> print(2 + 2)
4
# in script mode, the result of 2+2 is not displayed
2 + 2

# but with print(), now the script does print out the resulting value
print(2 + 2)
4


type()
Identifies the type of a given object.

>>> type(4)
<class 'int'>

>>> type("aren't there ever any bathroom breaks in adventures?")
<class 'str'>

int()
Converts the passed object to an integer.

>>> int(4.2)
4

>>> int(4.9)
4

>>> int("4")
4

float()
Converts the passed object to a float.

>>> float(4)
4.0

>>> float("4")
4.0

str()
Converts the passed object to a string.

>>> str(4)
'4'

list()
Converts the passed object to a list.

>>> list('rebellion')
['r', 'e', 'b', 'e', 'l', 'l', 'i', 'o', 'n']

range()
Returns an iterable sequence of integers. Often used with for loops.

>>> for i in range(1,5):
        print(i)
1
2
3
4

>>> for i in range(3):
        print(i)
0
1
2

len()
Returns the length of a given object.

>>> len("sphinx")
6

>>> len(["sphinx 1", "sphinx 2", "sphinx 3"])
3

“That’s quite a lot right there. But I wonder if there are other, perhaps even more powerful, built-in functions,” Baldric thought to himself.

“Ah, excuse me Cassandra, I’ve got to go ask Boomdoom about something.” Baldric spotted the massive half-orc and floated over to him.

“Uhh, hey Boomdoom.”

“Doomboom.”

“Uh yeah, that’s what I meant (great start). Hey, about those built-in functions you were telling me about earlier, are there any more I should know about?” Baldric showed him the ones he’d just reviewed.

“Yes, there is one you must learn immediately and never forget: help(). If you are ever not sure what something is or what it will do, call help(). Say you are not sure what len() does.”


help()
Gives you some hopefully helpful information on whatever object you pass it.

# pass in the function len() to help
# we want to input the actual function into help, and not call len()
# and so we leave off the parentheses, just passing in the function's name

>>> help(len)
Help on built-in function len in module builtins:

len(obj, /)
    Return the number of items in a container.

“Simple, no? Now you know len() returns the number of items in a container, or in other words it tells you the length of something. Sometimes help() returns much information that can be difficult to understand. But with functions it will often give at least a helpful summary of what the function does and what arguments it takes. As another example, say you want to know more about print().”

>>> help(print)
Help on built-in function print in module builtins:

print(...)
    print(value, ..., sep=' ', end='n', file=sys.stdout, flush=False)
    
    Prints the values to a stream, or to sys.stdout by default.
    Optional keyword arguments:
    file:  a file-like object (stream); defaults to the current sys.stdout.
    sep:   string inserted between values, default a space.
    end:   string appended after the last value, default a newline.
    flush: whether to forcibly flush the stream.

“We already understand the basic use of print(). But now we see print() has a sep parameter, which is a single space by default. And this parameter determines what separates multiple printed values. What happens if we change sep to a smiley face?”

>>> print("rip", "emperor", "in", "half")
rip emperor in half

>>> print("rip", "emperor", "in", "half", sep=' :) ')
rip :) emperor :) in :) half

“Wow, you sure know a lot Zoomzoom.”

“Doomboom. Grandmother was wise, taught me much. But there are still other built-in functions you must know. I will show you now.”

Doomboom began to weave patterns of Logic entirely new to Baldric.


sum()
Returns the sum of a list (or some other iterable) of numbers.

>>> sum([1, 2, 3, 4])
10

>>> sum(range(5))
10

min(), max()
Returns the minimum or maximum of a list (or some other iterable) of numbers.

>>> nums = [23, 4, 66, 7]

>>> max(nums)
66

>>> min(nums)
4

round()
Round a number to a given precision.

>>> round(3.2468, 2)
3.25

>>> round(3.6)
4

sorted()
Returns a list of sorted values.

number_list = [23, 4, 66, 7]
letter_list = ['b', 'a', 'd', 'c']
letter_string = 'cats'

>>> sorted(number_list)
[4, 7, 23, 66]

>>> sorted(letter_list)
['a', 'b', 'c', 'd']

>>> sorted(letter_string)
['a', 'c', 's', 't']

At this point they were now descending swiftly towards the large Teleportation Circle in the heart of the city. Looking back, he could see the Imperial forces snaking through the streets in the direction of the Circle, but otherwise the city was quiet. Baldric thought he could just catch glimpses of movement here and there, but couldn’t ever quite make out what it was.

Cassandra spoke up. “Once we land, we’re going to need to defend the Circle long enough for Baldric to unlock it. Then I’ll teleport away, and with any luck I’ll return with our army in short order. If you don’t want any part in this, no one will force you. You may leave as soon as we…” Cassandra was interrupted by screams as a swarm of whistling arrows flew through the group, puncturing parasails and body parts alike.

Baldric could make out shapes now in the shadows of the windows and doorways below them. As another volley headed towards them, Baldric felt the winds abruptly shift and blow the arrows away. But the rebels were getting dispersed now, drawn every which way by the air currents, and many were sinking faster than others from the holes in their parasails. Cassandra barked one last command, “Everyone rendezvous at the Circle!” before she started launching icy volleys of her own back at the Imperials.

It was chaos now, arrows flying in all directions and elemental death being fired in return. Buildings went up in flame from roaring firebolts. Dust devils arose among the Imperials, obscuring their view of the sky. Lightning rained down on clumps of soldiers, sending them flying. Baldric just kept his sights on the Circle, steering himself towards it as stealthily as he could. He landed and, amid the swirling dust and cries of battle, made his way over to one of the stone sphinxes. At the base of the statue was an inscription of a list of numbers and some text.

751.553187794811, 
798.553187794811, 
4133.8085586674515, 
786.553187794811, 
792.553187794811, 
807.553187794811, 
783.553187794811, 
810.553187794811, 
795.553187794811, 
813.553187794811, 
819.553187794811, 
804.553187794811, 
789.553187794811, 
816.553187794811

"""
minimum by maximum by sum by count, rounded
"""

“Hmm, I’m gonna go ahead and guess I need to take the product of the minimum, maximum, sum, and length of the list. Well let’s see…if I wanted a function that can find the largest number in a list of numbers, I bet I could do something like this:”

def maximum(nums):
    max_so_far = 0
    for num in nums:
        if num > max_so_far:
            max_so_far = num
    return max_so_far

“But wait a second, something’s tickling the back of my mind…of course, I can just use the built-in max() function! In fact, all these procedures the sphinx wants have a corresponding built-in function.”

>>> numbers = [
    751.553187794811, 
    798.553187794811, 
    4133.8085586674515, 
    786.553187794811, 
    792.553187794811, 
    807.553187794811, 
    783.553187794811, 
    810.553187794811, 
    795.553187794811, 
    813.553187794811, 
    819.553187794811, 
    804.553187794811, 
    789.553187794811, 
    816.553187794811
    ]

>>> max(numbers)
4133.8085586674515

>>> min(numbers)
751.553187794811

>>> sum(numbers)
14503.99999999999

>>> len(numbers)
14

“Everything looks like it’s working, so let’s see if taking the product works.”

>>> answer = max(numbers) * min(numbers) * sum(numbers) * len(numbers)

>>> print(answer)
630849710511.9988

“Hmm, nothing happened. Guess I’ll round it to the nearest whole number.”

>>> print(round(answer))
630849710512

The sphinx’s eyes glowed a bright green. Baldric looked around for the next sphinx. He noticed for the first time, through all the dust and smoke, that hundreds of rebels were all around him now, with Cassandra running around and barking orders. Four major streets all fed into the roundabout surrounding the sizable Circle, so four different groups were defending their respective streets. Wagons and carts and crates were all being magically whisked through the air to be placed in growing barricades that rebels just finding the Circle were scurrying over.

Cries broke out to the north, followed by a shower of arrows the rebels took cover from. Dust devils laced with ice shards were sent down the street in response. To the west, the rebels cursed as their barricade ignited in flame. But after blowing apart the second story of the building where the flames had shot from with a series of lightning bolts and dowsing the barricade’s flames with Water, the west road was quiet once again.

Sphinx 2

Baldric hurried over to a second sphinx and inspected the inscription.

'the boots',
'of destruction',
'of ten',
'the wizard',
'of boredom',
'of doom',
'of power',
'the staff meetings',
'of rot',
'of servitude',
'the pencil sharpeners',
'the crystal',
'of blinding speed',
'the mind games',
'the gossip',
'the god',
'of dreams',
'of light',
'the groups',
'of logic',
'the hammer',
'of darkness',
'the axe',
'the performance reviews'

"""
take only those of length 6 or 10,
then pop index 5 and insert at the start,
taking the first two as your answer
"""

“Based on these instructions, I’m gonna guess I’ll probably want to use a few list methods. Let’s see…methods…yeah, not ringing a bell.”

A familiar voice rumbled behind Baldric. “Looks like you need list methods. I will show you now.”

Baldric turned around to find Doomboom standing behind him. “First, remind me again, what are methods exactly?”

“Methods are functions, just like built-in functions or functions you write yourself. The difference is that methods are contained inside other objects, like lists or strings, and can only be accessed through these objects. The terminology can overlap since the string and list methods are also technically built-in functions, but don’t be too concerned about these distinctions. Here are some examples of using list methods.”


list.append()
Appends an object to the end of the list.

>>> letters = ['a', 'b', 'c']

>>> letters.append('d')

>>> print(letters)
['a', 'b', 'c', 'd']

list.extend()
Appends all objects in an iterable to the end of a list.

>>> letters = ['a', 'b']

>>> letters.extend(['c', 'd'])

>>> print(letters)
['a', 'b', 'c', 'd']

list.insert()
Inserts an object at the given list index.

>>> letters = ['a', 'b', 'c']

>>> letters.insert(1, 'd')

>>> print(letters)
['a', 'd', 'b', 'c']

list.pop()
Removes and returns object at index (default is last).

>>> letters = ['a', 'b', 'c', 'd']

>>> letters.pop()
'd'

>>> print(letters)
['a', 'b', 'c']

>>> letters.pop(0)
'a'

>>> print(letters)
['b', 'c']

list.remove()
Removes first occurrence of object in list.

>>> letters = ['a', 'b', 'c', 'b']

>>> letters.remove('b')

>>> print(letters)
['a', 'c', 'b']

list.clear()
Remove all items from the list.

>>> letters = ['a', 'b', 'c']

>>> letters.clear()

>>> print(letters)
[]

list.index()
Returns the index of the first occurrence in list of passed object.

>>> letters = ['a', 'b', 'c', 'b']

>>> letters.index('b')
1

list.count()
Returns the number of times the passed object occurs in the list.

>>> letters = ['a', 'b', 'c', 'b']

>>> letters.count('b')
2

“Notice how some of these list methods modified their list, and did so without requiring any sort of variable assignment. In other words, the lists were modified “in place”. It’s a common error to do something like…”

>>> hobbies = ['smash', 'bash', 'flatten']

>>> hobbies = hobbies.append(['crush'])

>>> print(hobbies)
None

# append() doesn't return anything, or to be precise it returns None
# because it modifies the list in place, no variable assignment required

“…when you should have instead done…”

>>> hobbies = ['smash', 'bash', 'flatten']

>>> hobbies.append(['crush']) # modify the list in place

>>> print(hobbies)
['smash', 'bash', 'flatten', 'crush']

“And if you ever forget what a method does, use help() like so.”

# you have to reference count() via a list
# so you can use any list, including an empty list as shown here
>>> help([].count)
Help on built-in function count:

count(...) method of builtins.list instance
    L.count(value) -> integer -- return number of occurrences of value

“If you want help on all list methods, just pass in any list to help(). For now, just ignore anything that starts with underscores. Look past those to see the methods I just showed you.”

>>> help([])
# pass in an empty list to help() yourself to see the lengthy output

“Sometimes though, you just want a quick list of method names to jog your memory. For this, use the dir() function.”

>>> dir([])
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', 
'__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', 
'__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', 
'__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', 
'__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', 
'__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', 
'__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 
'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']

“Again, ignore the names that start with underscores. That will come later in your training. And keep in mind you may also use dir() without any arguments just to see what the available names are currently, such as what the names are of the variables or functions you’ve already defined.”

“Thanks Choomfloom…”

“Doomboom.”

“…I think I get it now.”

There was some commotion from the east road, and Doomboom left to see to it. Baldric turned his attention back to the sphinx’s inscription.

“First things first, I’ll filter out all the strings from the list that aren’t of length 6 or 10.”

"""
take only those of length 6 or 10,
then pop index 5 and insert at the start,
taking the first two as your answer
"""

phrases = ['the boots',
 'of destruction',
 'of ten',
 'the wizard',
 'of boredom',
 'of doom',
 'of power',
 'the staff meetings',
 'of rot',
 'of servitude',
 'the pencil sharpeners',
 'the crystal',
 'of blinding speed',
 'the mind games',
 'the gossip',
 'the god',
 'of dreams',
 'of light',
 'the groups',
 'of logic',
 'the hammer',
 'of darkness',
 'the axe',
 'the performance reviews']

filtered_phrases = []

for e in phrases:
  if (len(e) == 10) or (len(e) == 6):
    filtered_phrases.append(e)

print(filtered_phrases)
['of ten', 'the wizard', 'of boredom', 'of rot', 'the gossip', 'the groups', 'the hammer']

“Next I’ll use the list.pop() method on the fifth list element, then insert it at the starting position.”

popped_element = filtered_phrases.pop(5)
filtered_phrases.insert(0, popped_element)
print(filtered_phrases)
['the groups', 'of ten', 'the wizard', 'of boredom', 'of rot', 'the gossip', 'the hammer']

“And finally I just need to grab the first two list elements and I should have my answer.”

answer = filtered_phrases[0] + ' ' + filtered_phrases[1]
print(answer)
the groups of ten

The second sphinx’s eyes lit up green. Baldric began to run over to the next sphinx when the relative calm broke all at once. Several boulders crashed into the Circle, while all four streets filled with legions of mounted Imperial guardsmen and gliders overhead dropped dropped some sort of handheld explosives. Dodging several explosions and crossbow bolts, Baldric found himself in the path of charging mounted Imperials. Baldric wove Wind, and several quick concentrated bursts of air blew the soldiers off their mounts. Baldric fell to the ground dodging the horses, and saw following in their path a massive, rumbling boulder.

A guttural roar sounded behind him, followed by Doomboom sprinting past him to shoulder the boulder straight on, stopping its momentum dead. Baldric saw once again Doomboom’s Magic being woven straight into himself in a sort of circular fashion. The half orc’s hands dug into the boulder and somehow found a grip. He tugged it off the ground and with several spins released it, sending it crashing into a nearby building.

The boulder uncurled among the ruin and revealed itself to be a scaly, four-legged monstrosity. It jumped to its feet and ran at Doomboom, hacking up a projectile stream of liquid as it advanced. Doomboom rolled out of the way, pulled a heavy iron lantern pole out of the ground like a weed and brought it down on the charging creature’s head with a sickening crunch. It lay still. Baldric noticed the ground where it’s spit landed had dissolved into a large pit.

“Baldric,” Doomboom shouted over the din, “That last sphinx requires string methods. Unlock it with haste.” And with that he was off, diving right into the middle of a nearby skirmish.

Sphinx 3

Taking cover behind a small stone well, Baldric hastily studied string methods with the use of dir() and help().


str.upper()
Returns an uppercase copy of the string.

>>> "Baldric Hightower".upper()
'BALDRIC HIGHTOWER'

str.lower()
Returns a lowercase copy of the string.

>>> 'Baldric Hightower'.lower()
'baldric hightower'

str.title()
Returns a copy of the string with the first letter of every word capitalized.

>>> 'only three demons and one dwarf so far'.title()
'Only Three Demons And One Dwarf So Far'

str.index()
Returns the index of the first match of the passed substring.

>>> 'one sphinx to go'.index('sphinx')
4

str.count()
Returns the number of substring occurrences in the string.

>>> 'if I had a copper for every copper in this string...'.count('copper')
2

str.isalnum()
Returns True if string contains only letters and numbers, otherwise False.

>>> 'five'
True

>>> '500'
True

>>> '$500'
False

>>> 'five hundred'
False

str.replace()
Replaces every instance of first substring with second substring.

>>> 'soon the assault begins'.replace('s', '$')
'$oon the a$$ault begin$'

str.split()
Returns a list of strings split apart on passed substring.

>>> 'may-the-light-protect-us'.split('-')
['may', 'the', 'light', 'protect', 'us']

str.join()
Uses the string to concatenate all elements of the passed iterable.

>>> '-'.join(['may', 'the', 'light', 'protect', 'us'])
'may-the-light-protect-us'

“Hmm, string methods seem pretty similar to list methods. Well, here goes nothing.”

Baldric ran to the final sphinx and hurriedly inspected the inscription.

"""!!$@$$Rze?j&&@mexz!?mb!e@?$$$r ja!l@$?$$zw&&aj?@!$$$y@zs:
!&&B@!u$$?$s?yzn!@e?s$$$s z?@$?$$isx $$$P?@&&r!jog@z?rjes@!s!,
$?$$O!bex@?z!di&@&?ezn?$?$@$c@e! izs F$@$$r?@eze?x$$$d@joxm,!
&&P!@ro?$$$@zf!@it qis@$?$$ $$@$!P&&@urp??@zo@se,!$?$$
&&A!@u?z$$@$tjh@$$$!@jo?ritz@&&y @ixs zD@$$$i@vz?i!@ne!@&?&,
$@$$?axz@n!d &@&W!o!$$@$!@zr&&k ji@zs z&&@Li?!$@$?$@fxe.!!?
"""

"""
get counts for characters z!$&@qxj?j&z
then remove characters
and use counts as indices
"""

“Basically it looks like there’s this one long string I need to clean up, and then use the count of certain characters prior to the cleaning process to pick out characters by their index after cleaning. And it looks like string methods are needed, just like Badabing Badaboom said.”

“So to get counts of characters, I think I can just use the string.count() method.”

>>> s = """!!$@$$Rze?j&&@mexz!?mb!e@?$$$r ja!l@$?$$zw&&aj?@!$$$y@zs:
!&&B@!u$$?$s?yzn!@e?s$$$s z?@$?$$isx $$$P?@&&r!jog@z?rjes@!s!,
$?$$O!bex@?z!di&@&?ezn?$?$@$c@e! izs F$@$$r?@eze?x$$$d@joxm,!
&&P!@ro?$$$@zf!@it qis@$?$$ $$@$!P&&@urp??@zo@se,!$?$$
&&A!@u?z$$@$tjh@$$$!@jo?ritz@&&y @ixs zD@$$$i@vz?i!@ne!@&?&,
$@$$?axz@n!d &@&W!o!$$@$!@zr&&k ji@zs z&&@Li?!$@$?$@fxe.!!?
"""

>>> s.count('z')
21

“21 z’s. That seems to work. Then if I want to get the counts for all the characters…”

>>> s = """!!$@$$Rze?j&&@mexz!?mb!e@?$$$r ja!l@$?$$zw&&aj?@!$$$y@zs:
!&&B@!u$$?$s?yzn!@e?s$$$s z?@$?$$isx $$$P?@&&r!jog@z?rjes@!s!,
$?$$O!bex@?z!di&@&?ezn?$?$@$c@e! izs F$@$$r?@eze?x$$$d@joxm,!
&&P!@ro?$$$@zf!@it qis@$?$$ $$@$!P&&@urp??@zo@se,!$?$$
&&A!@u?z$$@$tjh@$$$!@jo?ritz@&&y @ixs zD@$$$i@vz?i!@ne!@&?&,
$@$$?axz@n!d &@&W!o!$$@$!@zr&&k ji@zs z&&@Li?!$@$?$@fxe.!!?
"""

>>> chars = "z!$&@qxj?j&z"
>>> counts = []

>>> for char in chars:
      counts.append(s.count(char))

>>> print(counts)
[21, 31, 66, 26, 46, 1, 8, 9, 32, 9, 26, 21]

“Perfect, so there’s 21 z’s, 31 exclamation marks, and so on. Now I need to remove all these characters from the string. I think there’s a string method that can do that too. Using string.replace(), I can replace all the unwanted characters with empty strings.”

>>> for char in chars:
        s = s.replace(char, "")

>>> print(s)
Remember always:
Busyness is Progress,
Obedience is Freedom,
Profit is Purpose,
Authority is Divine,
and Work is Life.

“Ah, what a lovely message. Anyways, now I have to use the character counts as indices to pick out a message from this string.”

>>> answer = ""

>>> for i in indices:
        answer += s[i]

>>> print(answer)
'notice again'

The third and final sphinx’s eyes glowed green. An eye-shaped hole opened up in the sphinx’s forehead. Baldric pulled out the Teleportation Circle key and slid it in. It clicked into place and lit up, resembling a third green glowing eye. Baldric wanted to cry out in celebration, but found himself drawn into the sphinx’s three-eyed gaze. Green filled his vision, and into the green he went. Green faded to black, and through an endless night he traveled.


Congratulations, you earned 2,139 experience and 1,742 gold. You are now a Level 8 Dwarven Warlock!
(cue victory music)

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



Chapter 7 – Imports and Nesting >>>