<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
Step2:  Glossary
Taken from https
Step4:  clone
To create a new object that has the same value as an existing object. Copying a reference to an object creates an alias but doesn’t clone the object.
Step6:  <h4 style="color
Step10:  delimiter
A character or string used to indicate where a string should be split.
Step12:  element
One of the values in a list (or other sequence). The bracket operator selects elements of a list.
Step14:  index
An integer variable or value that indicates an element of a list.
Step17:  list
A collection of objects, where each object is identified by an index. Like other types str, int, float, etc. there is also a list type-converter function that tries to turn its argument into a list.
Step19:  List comprehensions
List comphrensions take the form
Step21:  In the above example the general pattern
Step24:  Notice especially the "punctuation" separating the various parts of the comprehension
Step27:  You can translate many for loops into list comprehensions
Step30:  modifier
A function which changes its arguments inside the function body. Only mutable types can be changed by modifiers.
Step33:  mutable data type
A data type in which the elements can be modified. All mutable types are compound types. Lists are mutable data types; strings are not.
Step35:  nested list
A list that is an element of another list.
Step37:  object
A thing to which a variable can refer.
In an assignment such as
Step39:  Boiled down to its essential characteristics, direct iteration takes the form
Step41:  Indexed iteration often takes the form
Step43:  List accumulation is a convenient for creating a new list from an old list by applying a transformation to each element in the old list and appending the result to the new list.  It takes the form
Step46:  sequence
Any of the data types that consist of an ordered collection of elements, with each element identified by an index.
Step48:  side effect
A change in the state of a program made by calling a function that is not a result of reading the return value from the function. Side effects can only be produced by modifiers.
Step54:  tuple
A sequential collection of items, similar to a list. Any python object can be an element of a tuple. However, unlike a list, tuples are immutable.
<ASSISTANT_TASK:>
Python Code:
Assignment between variables creates aliases.
animal = "giraffe"
creature = animal
print("Is creature an alias of animal?", creature is animal)
Assignment of the same value to different variables does not necessarily create aliases.
weather_next_5_days       = ["Sunny", "Partly sunny", "Cloudy", "Sunny", "Sunny"]
weather_subsequent_5_days = ["Sunny", "Partly sunny", "Cloudy", "Sunny", "Sunny"]
if weather_subsequent_5_days is weather_next_5_days:
    is_weather_subsequent_alias_of_weather_next = "Yes."
else:
    is_weather_subsequent_alias_of_weather_next = "No."
if weather_subsequent_5_days == weather_next_5_days:
    same_forecast = "Yes."
else:
    same_forecast = "No."
print("Is weather_subsequent_5_days an alias of weather_next_5_days?",
    is_weather_subsequent_alias_of_weather_next, "\n")
print("Is the forecast for the next 5 days the same as the forecast for the subsequent 5 days?",
      same_forecast, "\n")
print("id(weather_next_5_days):      ", id(weather_next_5_days))
print("id(weather_subsequent_5_days):", id(weather_subsequent_5_days))
Explanation: Glossary
Taken from https://runestone.launchcode.org/runestone/static/thinkcspy/ListsContinued/Glossary.html
aliases
Multiple variables that contain references to the same object.
End of explanation
Clone a list to get a new object with the same values.
lst = [1, 2, 3]
alias = lst     # create an alias to lst
clone = lst[:]  # clone lst
print("Is alias an alias of lst?", alias is lst)
print("Is clone an alias of lst?", clone is lst)
print("Do lst, alias, and clone all have the same values?", lst == alias == clone)
Explanation: clone
To create a new object that has the same value as an existing object. Copying a reference to an object creates an alias but doesn’t clone the object.
End of explanation
List slicing DOES NOT deeply copy nested objects.
import time
delay = 2
hundreds = [100, 200, 300]
numbers = [1, hundreds]   # hundreds is nested
shallow_clone = numbers[:]
print("hundreds:", hundreds)
print("numbers:", numbers)
print("shallow_clone:", shallow_clone, "\n")
time.sleep(delay)
# verify that shallow_clone[0] == numbers[0]
print("shallow_clone[0] == numbers[0]:", shallow_clone[0] == numbers[0], "\n")
time.sleep(delay)
# modify the first element in numbers from 1 -> 10
numbers[0] = 10
print("numbers[0] = 10\n")
time.sleep(delay)
# test whether shallow_clone[0] also was modified
print("Was shallow_clone[0] also modified?",
      shallow_clone[0] == numbers[0], "\n")
time.sleep(delay)
# change the first element in the list of hundreds from 100 -> 500
numbers[1][0] = 500
print("numbers[1][0] = 500\n")
time.sleep(delay)
# test whether the list of hundreds in shallow_clone also has been modified
print("Was shallow_clone[1][0] also modified?",
      numbers[1][0] == shallow_clone[1][0], "\n")
time.sleep(delay)
# look at all of the variables
print("hundreds:", hundreds)
print("numbers:", numbers)
print("shallow_clone:", shallow_clone)
Explanation: <h4 style="color: #ff0000">Warning: list slicing will create a shallow copy ("clone") of nested lists.</h4>
End of explanation
By default, strings are split on whitespace.
quote = "Beware of bugs in the above         code; I have only proved it correct, not tried it. -Donald Knuth"
words = quote.split()
print(words)
Specify the delimiter to change how strings are split.
quote = "Beware of bugs in the above code; I have only proved it correct, not tried it. -Donald Knuth"
delimiter = ';'
phrases = quote.split(delimiter)
print(phrases)
A delimiter can also be specified to join.
quote = "Beware of bugs in the above code; I have only proved it correct, not tried it. -Donald Knuth"
delimiter = '-'
parts = quote.split(delimiter)
print(parts, "\n")
improved_quote = '\nby '.join(parts)
print(improved_quote)
Explanation: delimiter
A character or string used to indicate where a string should be split.
End of explanation
Access an element of a list by using square brackets with an index.
lst = [1, 2, 3]
print("The third element of lst:", lst[2])
Explanation: element
One of the values in a list (or other sequence). The bracket operator selects elements of a list.
End of explanation
By varying the index, you can access different elements of a list.
lst = [1, 2, 3]
i = 0    # i holds the index value
print("The element of lst at index 0 is", lst[i])
i = 1
print("The element of lst at index 1 is", lst[i])
Explanation: index
An integer variable or value that indicates an element of a list.
End of explanation
Create a list from a list literal.
lst = [1, 2, 3]
print(lst)
Create a list using list().
lst = list(range(1, 4))
print(lst, type(lst))
Explanation: list
A collection of objects, where each object is identified by an index. Like other types str, int, float, etc. there is also a list type-converter function that tries to turn its argument into a list.
End of explanation
Create a list from a list comprehension.
lst = [i for i in range(1, 11) if i <= 3]
print(lst)
Explanation: List comprehensions
List comphrensions take the form:
[expression for variable in sequence if condition]
End of explanation
Create a list from a list comprehension without an if clause.
lst = [i for i in range(1, 11)]
print(lst)
Explanation: In the above example the general pattern:
[expression for variable in sequence if condition]
Becomes:
[i for i in range(1, 100) if i &lt;= 3]
You can omit the condition when you want to take all of the values from the sequence.
A list comprehension without the optional if clause takes the form:
[expression for variable in sequence]
End of explanation
Create a list by accumulating values.
lst = []
for i in range(1, 10):
    if i <= 3:
        lst.append(i)
print(lst)
Create a list by accumulating values without if condition.
lst = []
for i in range(1, 11):
    lst.append(i)
print(lst)
Explanation: Notice especially the "punctuation" separating the various parts of the comprehension:
[... for ... in ... if ...]
Without the if clause:
[... for ... in ...]
These patterns are functionally equivalent to the more familiar list accumulation pattern.
End of explanation
List traversal using a for loop.
lst = [1, 2, 3]
for i in lst:
    print(i)
List traversal using a for loop and an index.
lst = [1, 2, 3]
for i in range(len(lst)):
    print(lst[i])
Explanation: You can translate many for loops into list comprehensions:
<pre>
lst = []                           
for i in range(1, 10):          becomes          lst = [i for i in range(1, 10) if i <= 3]       
    if i <= 3:
        lst.append(i)
</pre>
<pre>
lst = []                           
for i in range(1, 10):          becomes          lst = [i for i in range(1, 10)]       
    lst.append(i)
</pre>
<pre>
doubled = []                           
for i in range(1, 10):          becomes          doubled = [i * 2 for i in range(1, 10)]       
    doubled.append(i * 2)
</pre>
Generally:
<pre>
lst = []
for variable in sequence:       becomes          lst = [expression for variable in sequence if condition]
    if condition:
        lst.append(expression)
</pre>
list traversal
The sequential accessing of each element in a list.
End of explanation
import time
delay = 3
def title_modifier(lst):
    This function will change the list passed to it.
    for i in range(len(lst)):
        lst[i] = ' '.join([word[0].upper() + word[1:].lower() for word in lst[i].split()])
places = ["new york", "kansas city", "los angeles", "seattle"]
print("Places before being modified:", places, "\n")
time.sleep(delay)
print("Calling title_modifier(places)...", "\n")
return_value = title_modifier(places)
time.sleep(delay)
print("The return value of title_modifier(places) is", return_value, "\n")
time.sleep(delay)
print("Places after being modified:", places, "\n")
import time
delay = 3
def title_modifier(lst):
    This function will change the list passed to it.
    for i in range(len(lst)):
        place = lst[i]
        words = place.split()
        title_cased_words = []
        for word in words:
            first_letter = word[0]
            rest_of_word = word[1:]
            title_cased_words.append(first_letter.upper() + rest_of_word.lower())
        lst[i] = ' '.join(title_cased_words)
places = ["new york", "kansas city", "los angeles", "seattle"]
print("Places before being modified:", places, "\n")
time.sleep(delay)
print("Calling title_modifier(places)...", "\n")
return_value = title_modifier(places)
time.sleep(delay)
print("The return value of title_modifier(places) is", return_value, "\n")
time.sleep(delay)
print("Places after being modified:", places, "\n")
Explanation: modifier
A function which changes its arguments inside the function body. Only mutable types can be changed by modifiers.
End of explanation
Lists are mutable.
cities = ["Albuquerque", "Chicago", "Paris"]
print("Cities before changing cities[1]:", cities)
cities[1] = "Tokyo"
print("Cities after changing cities[1]:", cities)
Strings are not mutable
cities = "Albuquerque Chicago Paris"
print("Cities as a string:", cities)
cities[1] = "Tokyo"
print("This will never print because it is an error to try to change part of a string")
Explanation: mutable data type
A data type in which the elements can be modified. All mutable types are compound types. Lists are mutable data types; strings are not.
End of explanation
Lists of lists (nested lists).
The format of hourly_forecasts is a list of days:
hourly_forecasts = [day1, day2, ..., dayN]
Each day has a name and a list of conditions associated with that day for the hours of 1-3 pm:
day = [name, [conditions_at_1pm, conditions_at_2pm, conditions_at_3pm]]
Therefore, hourly_forecasts is, in part, a list of lists of lists.
hourly_forecasts = [["Monday", ["Sunny", "Sunny", "Partly Cloudy"]],
                   ["Tuesday", ["Cloudy", "Cloudy", "Cloudy"]],
                   ["Wednesday", ["Partly Cloudy", "Sunny", "Sunny"]]]
for day in hourly_forecasts:
    name = day[0]
    hourly_conditions = day[1]
    i = 1
    for conditions in hourly_conditions:
        print("The conditions at " + str(i) + "pm on " + name + " are forecast to be " + conditions)
        i += 1
Explanation: nested list
A list that is an element of another list.
End of explanation
Direct iteration.
months = ["January", "February", "March",
          "April", "May", "June", "July",
          "August", "September", "October",
          "November", "December"]
for month in months:
    print(month)
Explanation: object
A thing to which a variable can refer.
In an assignment such as:
python
lst = [1, 2, 3]
lst is the variable and [1, 2, 3] is the object to which lst refers.
pattern
A sequence of statements, or a style of coding something that has general applicability in a number of different situations. Part of becoming a mature Computer Scientist is to learn and establish the patterns and algorithms that form your toolkit. Patterns often correspond to your “mental chunking”.
End of explanation
Indexed iteration.
months = ["January", "February", "March",
          "April", "May", "June", "July",
          "August", "September", "October",
          "November", "December"]
for i in range(len(month)):
    print(months[i])
Explanation: Boiled down to its essential characteristics, direct iteration takes the form:
for element in sequence:
    expression(element)
Where expression typically uses the value in element, for example, to do arithmetic, print, etc.
End of explanation
List accumulation.
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
squares = []
for i in numbers:
    squares.append(i ** 2)
print(squares)
Explanation: Indexed iteration often takes the form:
for index in range(len(sequence)):
    expression(sequence[index])
The example uses range(len(sequence)) to get each index, and sequence[index] to get each element.
End of explanation
import time
delay = 3
def title_pure_function(lst):
    This function will create a new list and return it
    instead of changing the list passed into it.
    
    places_titled = []
    for i in range(len(lst)):
        place = lst[i]
        words = place.split()
        title_cased_words = []
        for word in words:
            first_letter = word[0]
            rest_of_word = word[1:]
            title_cased_words.append(first_letter.upper() + rest_of_word.lower())
        titled = ' '.join(title_cased_words)
        places_titled.append(titled)
    return places_titled
        
places = ["new york", "kansas city", "los angeles", "seattle"]
print("Places:", places, "\n")
time.sleep(delay)
print("Calling title_pure_function(places)...", "\n")
return_value = title_pure_function(places)
time.sleep(delay)
print("The return value of title_pure_function(places) is", return_value, "\n")
time.sleep(delay)
print("Places:", places, "\n")
Explanation: List accumulation is a convenient for creating a new list from an old list by applying a transformation to each element in the old list and appending the result to the new list.  It takes the form:
result = []
for element in sequence:
    result.append(expression(element))
Using list accumulation in a function and returning the accumulated value can help make a function pure.
pure function
A function which has no side effects. Pure functions only make changes to the calling program through their return values.
End of explanation
Lists are sequences.
lst = [1, 2, 3]
print("lst:    ", lst)
print("lst[0]: ", lst[0])
Tuples are sequences.
t = (1, 2, 3)
print("t:    ", t)
print("t[0]: ", t[0])
Explanation: sequence
Any of the data types that consist of an ordered collection of elements, with each element identified by an index.
End of explanation
def change_forecast(forecast):
    This modifier function changes the value of the
    forecast without returning anything.
    
    for i in range(len(forecast)):
        forecast[i] = "Cloudy"
forecast = ["Sunny", "Sunny", "Sunny"]
print("The forecast is", forecast)
return_value = change_forecast(forecast)
print("The return_value from calling change_forecast(forecast) is", return_value)
print("The forecast is", forecast)
Explanation: side effect
A change in the state of a program made by calling a function that is not a result of reading the return value from the function. Side effects can only be produced by modifiers.
End of explanation
Create a tuple from a comma-separated list of values.
vehicle = (2000, "Ford", "Ranger")
print(vehicle)
Parentheses are not required.
vehicle = 2000, "Ford", "Ranger"
print(vehicle)
You can create a tuple from a list.
vehicle = tuple([2000, "Ford", "Ranger"])
print(vehicle)
Tuples are immutable.
vehicle = (2000, "Ford", "Ranger")
vehicle[2] = "F-150"
Values in tuples can be "unpacked" into multiple variables.
vehicle = (2000, "Ford", "Ranger")
year, make, model = vehicle  # tuple unpacking
print("Year:", year)
print("Make:", make)
print("Model:", model)
print(vehicle)
Explanation: tuple
A sequential collection of items, similar to a list. Any python object can be an element of a tuple. However, unlike a list, tuples are immutable.
End of explanation
<END_TASK>