<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Overview
Hour 1
Curiousities from Assignment 2
Sets
Software Decomposition
Functions
Modules
Classes
Hour 2
Files
Emily
Hour 3
Graded lab
A curiousity from Assignment 2
The result of test cases changed when the order was changed
This shouldn't happen because
Step1:  Sets
A set is a collection data structures that holds unique values. It works like a mathematical set.
Properties of Mathematical Sets
* All elements in a set must be unique. No two elements have the same value.
* Sets are unordered.
* Elements in sets can be of different data types
Step2:  Problem
set() removes duplicates
Not useful for situations where we are testing if duplicates have been removed
We'll need a different is_equal function
Software Decomposition
We break up code into smaller chunks to make it more manageable and easier to understand.
Benefits
Hides information
Chunks lines into concepts
Organize similar concepts together
Creates smaller scopes
Reuse
Language Features
Functions
Modules
Classes
Modules
A module is a file that contain Python code. Large programs are easier to debug and maintain when they are divided into modules.
We have already been using this feature. Each exercise is a module. Test modules import program modules
Naming Modules
Must end in .py
Must not be a Python keyword
Import
Access the contents of another module using import. It's like reading it into memory.
Put these statements at the top of the file, one per line
Example
Suppose you have been asked to write a program that calculates the following.
* Area of a circle
* Circumference of a circle
* Area of a rectangle
* Perimeter of a rectangle
What modules would you create? What functions would you create?
Functions
A function is a way to group together lines of code.
Useful for doing the same task in different places.
Makes the code easier to read.
Avoids repeating code.
def function_name()
Step3:  Designing a Program to Use Functions
When we design a program, we have to plan ahead to use functions effectively. Taking a problem or program and breaking it into sub-parts is calle top-down design.
Steps in Top-Down Design
The overall task is broken into sub-tasks.
Each sub-task is examined to determine whether it can be broken down further. Repeat until no more sub-tasks can be identified.
Once all the sub-tasks are identified, they are written in code.
IPO Chart
IPO stands for input, processing, and output.
Hierarchy Chart
Useful for displaying calls to function
Step4:  Example
Lab 3 where we used a function to get and check input from keyboard
Input function only checked for integer, not for permitted values
Separation of concerns
When to Add a Function
Section of code becomes too long
Functionality is reused
Naming Functions
Verb phrase
Objects
Objects are created from abstract data types that encapsulate data and functionality together.
Idea
Step5:  File Input and Output
Files store data for later use.
Writing to a disk saves data from memory in a file.
Reading from a disk gets data from a file and puts it into memory.
Encodings
A bit is a binary digit. It can have a value of 0 or 1. There are 8 bits in 1 byte.
Text encodings, such as ASCII or unicode, can be read by humans. Non-text encodings are used for images, audio, executables, etc.
ASCII is an 7-bit encoding for representing Latinate characters and control codes (like \n). Since it is 7 bits, it can represent 2^7 or 128 characters.
It has since been succeeded, but not replaced, by Unicode (a character set) encoded in 8, 16, or 32 bits. This format can be used to represent over 113 000 glyphs from a variety of alphabets.
Opening a file
To start using a file, given its filename, you have to open it. But first, the name— a string. How we get that string depends on our needs. Here are a few options.
Have the user to enter the name using the input() function.
Have user to select it from a list presented by the interface. 
Store the name in a configuration file
Hard code the string in the program
Once we have the filename, we need to turn it into something that the Python program can work with. This involves creating a file handle or file object, by opening the file.
Step6:  with is a Python keyword that automatically calls certain functions before and after the statement
open is a Python function
jabberwocky.txt is the name of the file to be opened
file reader is a variable that is assigned the file object (or “stream” or “reader”/“writer”) returned by open
"r" is a string indicating what we wish to do with the file.
Options for this string are "r", "w", "a", meaning read, write or append. The default is "r".
If you write to a file that already exists, the old contents are erased. If you append, the new content is added to the end of the file.
What 'with' does for us
When opening a file, there are some things that can go wrong. The file might not exist. The program might not have permission to access the file. There might be a hardware error that occurs during access. For these reasons, file reading usually occurs after some checking or within a try-except block.
Once we are done accessing the file, we have to close it. The contents aren’t actually saved to disk until we close it. Closing the file also reduces the resources used by our program and makes the file available for others to access.
If we didn't have "with", here's what the code would look like.
Step7:  Reading from a file
Now that we have a file handle or reader, we can get the contents. There are five ways to
read from a basic file handle.
Step8:  Why is the output double spaced?
How can we single space the output?
Step9:  When would you use this instead of a for loop?
Step10:  Advantages and Disadvantages
Dealing with "end of file"
Unless you choose to stop reading, you will eventually reach the end of an input file, called “EOF”. The the first three approaches automatically recognizes EOF. With the remaining two, you have to detect the situation of being at EOF yourself.
If you are at EOF, when you call read() or readline() you get an empty string.
Note
Step11:  Writing to a file
First, we open a file to write, using the same "with" construction
Then we write the contents.
Step12:  Until you close, Python may save up the text for later output.
Examine missive.txt before you close it; it’s probably empty.
<ASSISTANT_TASK:>
Python Code:
list1 = [["a", "b", "c"], [1, 2, 3]]
# print tuple(["a", "b", "c"])
# print tuple([1, 2, 3])
map(tuple, list1)
for item in list1:
    tuple(item)
table1 = [["a", "b", "c"], [1, 2, 3]]
table2 = [["a", "b", "c"], [1, 2, 3]]
table3 = [["a", "b", "c"], [1, 2, 4]]
table4 = [[1, 2, 3], ["a", "b", "c"]]
# list.sort()
# sorted(list)
def is_equal(t1, t2):    
    t1.sort()
    t2.sort()
    return t1 == t2
Explanation: Overview
Hour 1
Curiousities from Assignment 2
Sets
Software Decomposition
Functions
Modules
Classes
Hour 2
Files
Emily
Hour 3
Graded lab
A curiousity from Assignment 2
The result of test cases changed when the order was changed
This shouldn't happen because:
Order shouldn't matter
The test cases are independent functions
Another curiousity
is_equal function in test file uses "set"
```
def is_equal(t1, t2):
    return set(map(tuple, t1)) == set(map(tuple, t2))
def is_equal(t1, t2):
    return sorted(t1) == sorted(t2)  
```
End of explanation
# Create a set
one_set = set()
# Constructor takes a single argument that is an iterable
another_set = set('aaabcc')
print(another_set)
Explanation: Sets
A set is a collection data structures that holds unique values. It works like a mathematical set.
Properties of Mathematical Sets
* All elements in a set must be unique. No two elements have the same value.
* Sets are unordered.
* Elements in sets can be of different data types
End of explanation
# Turn this code into a function
def what_to_wear(temperature):
    output = ""
    
    if (temperature < 15):
        output = "Wear a coat."
    
    return output
what_to_wear(8)
Explanation: Problem
set() removes duplicates
Not useful for situations where we are testing if duplicates have been removed
We'll need a different is_equal function
Software Decomposition
We break up code into smaller chunks to make it more manageable and easier to understand.
Benefits
Hides information
Chunks lines into concepts
Organize similar concepts together
Creates smaller scopes
Reuse
Language Features
Functions
Modules
Classes
Modules
A module is a file that contain Python code. Large programs are easier to debug and maintain when they are divided into modules.
We have already been using this feature. Each exercise is a module. Test modules import program modules
Naming Modules
Must end in .py
Must not be a Python keyword
Import
Access the contents of another module using import. It's like reading it into memory.
Put these statements at the top of the file, one per line
Example
Suppose you have been asked to write a program that calculates the following.
* Area of a circle
* Circumference of a circle
* Area of a rectangle
* Perimeter of a rectangle
What modules would you create? What functions would you create?
Functions
A function is a way to group together lines of code.
Useful for doing the same task in different places.
Makes the code easier to read.
Avoids repeating code.
def function_name():
    statement
    statement
    statement
A function has the following parts.
A name
Parameters (inputs)
Optionally, return values (outputs)
Functions are either a void function or a value-returning function.
End of explanation
def get_hourly_rate():
    print ("get_hourly_rate")
def get_hours_worked():
    print ("get_hours_worked")
def get_input():
    print ("get_input")
    get_hours_worked()
    get_hourly_rate()
def main():
    print("main")
    get_input()
    
main()
Explanation: Designing a Program to Use Functions
When we design a program, we have to plan ahead to use functions effectively. Taking a problem or program and breaking it into sub-parts is calle top-down design.
Steps in Top-Down Design
The overall task is broken into sub-tasks.
Each sub-task is examined to determine whether it can be broken down further. Repeat until no more sub-tasks can be identified.
Once all the sub-tasks are identified, they are written in code.
IPO Chart
IPO stands for input, processing, and output.
Hierarchy Chart
Useful for displaying calls to function
End of explanation
import random
# The Coin class simulates a coin that can be flipped
class Coin:
    # The __init__ methods is the constructor
    
    def __init__(self):
        self.sideup = 'Heads'
    
    def toss(self):
        flip = random.randint(0, 1)
        if flip == 0:
            self.sideup = "Heads"
        else:
            self.sideup = "Tails"
    
    def get_sideup(self):
        return self.sideup
def main():
    my_coin = Coin()
    
    print("This side is up: " + my_coin.get_sideup())
    
    print("I am tossing the coin...")
    my_coin.toss()
    
    print("This side is up: " + my_coin.get_sideup())
main()
for _ in range(5):
   print random.randint(0, 1)
Explanation: Example
Lab 3 where we used a function to get and check input from keyboard
Input function only checked for integer, not for permitted values
Separation of concerns
When to Add a Function
Section of code becomes too long
Functionality is reused
Naming Functions
Verb phrase
Objects
Objects are created from abstract data types that encapsulate data and functionality together.
Idea: Objects, or data representations, are more stable than functionality.
Also called encapsulation
Information hiding
Object reusability
Functions attached to an object are called methods.
Example
Your alarm clock as a software object. It would have the following data attributes.
current_second (a value in the range 0-59)
current_minute (a value in the range 0-59)
current_hour (a value in the range 0-12)
alarm_time (a valid hour and minute)
alarm_is_set (True or False)
These attributes define the state of the alarm clock.
These attributes are private, meaning you can't change them. 
But you can use public methods (buttons) to change them.
set_time
set_alarm_time
set_alarm_on
set_alarm_off
There are private methods that are part of the clock's internal workings.
* increment_current_second
* increment_current_minute
* increment_current_hour
* sound_alarm
We have already been using objects, specifically the MismatchedAttributesException in Exercise 3 of Assignment 2.
Class
A class is the code that specifies the data attributes and methods for a particular type of object.
They are like blueprints or cookie cutters
Naming
Nouns
Capitalize first letter
End of explanation
with open("jabberwocky.txt", "r") as file_reader:
    # insert file operation here
    file_contents = file_reader.read()
print file_contents
Explanation: File Input and Output
Files store data for later use.
Writing to a disk saves data from memory in a file.
Reading from a disk gets data from a file and puts it into memory.
Encodings
A bit is a binary digit. It can have a value of 0 or 1. There are 8 bits in 1 byte.
Text encodings, such as ASCII or unicode, can be read by humans. Non-text encodings are used for images, audio, executables, etc.
ASCII is an 7-bit encoding for representing Latinate characters and control codes (like \n). Since it is 7 bits, it can represent 2^7 or 128 characters.
It has since been succeeded, but not replaced, by Unicode (a character set) encoded in 8, 16, or 32 bits. This format can be used to represent over 113 000 glyphs from a variety of alphabets.
Opening a file
To start using a file, given its filename, you have to open it. But first, the name— a string. How we get that string depends on our needs. Here are a few options.
Have the user to enter the name using the input() function.
Have user to select it from a list presented by the interface. 
Store the name in a configuration file
Hard code the string in the program
Once we have the filename, we need to turn it into something that the Python program can work with. This involves creating a file handle or file object, by opening the file.
End of explanation
file_name = "jabberwocky.txt"
try:
    file_reader = open(file_name)
    # file read operation goes here
except(OSError, IOError):
    print("Error reading file: " + file_name)
else:
    s = file_reader.read()
    file_reader.close()
Explanation: with is a Python keyword that automatically calls certain functions before and after the statement
open is a Python function
jabberwocky.txt is the name of the file to be opened
file reader is a variable that is assigned the file object (or “stream” or “reader”/“writer”) returned by open
"r" is a string indicating what we wish to do with the file.
Options for this string are "r", "w", "a", meaning read, write or append. The default is "r".
If you write to a file that already exists, the old contents are erased. If you append, the new content is added to the end of the file.
What 'with' does for us
When opening a file, there are some things that can go wrong. The file might not exist. The program might not have permission to access the file. There might be a hardware error that occurs during access. For these reasons, file reading usually occurs after some checking or within a try-except block.
Once we are done accessing the file, we have to close it. The contents aren’t actually saved to disk until we close it. Closing the file also reduces the resources used by our program and makes the file available for others to access.
If we didn't have "with", here's what the code would look like.
End of explanation
file_name = "jabberwocky.txt"
# All at once into a string
with open(file_name) as file_reader:
    file_contents = file_reader.read()
# All at once into a list
with open(file_name) as file_reader:
    file_contents = file_reader.readlines()
# All lines, one at a time
with open(file_name) as file_reader:
    for line in file_reader:
        print (line),
Explanation: Reading from a file
Now that we have a file handle or reader, we can get the contents. There are five ways to
read from a basic file handle.
End of explanation
# One line at a time
with open(file_name) as file_reader:
    line = file_reader.readline()
    print(line)
    line= file_reader.readline()
    print(line)
    line = file_reader.readline()
    print(line)
Explanation: Why is the output double spaced?
How can we single space the output?
End of explanation
# By groups of characters
with open(file_name) as file_reader:
    input_group = file_reader.read(10)   # Read 10 characters
    print(input_group)
    input_group = file_reader.read(10)   # Read the next 10 characters
    print(input_group)
Explanation: When would you use this instead of a for loop?
End of explanation
# Open a file called filename and read line by line until EOF is reached
Explanation: Advantages and Disadvantages
Dealing with "end of file"
Unless you choose to stop reading, you will eventually reach the end of an input file, called “EOF”. The the first three approaches automatically recognizes EOF. With the remaining two, you have to detect the situation of being at EOF yourself.
If you are at EOF, when you call read() or readline() you get an empty string.
Note: An empty string is not the same as a blank line.
End of explanation
file_name = "missive.txt"
with open(file_name, 'w') as output_file:
    output_file.write("Dear Uncle Marty,\n")
    output_file.write("Thanks for the nifty present.\n")
    output_file.write("Love,\nYour Niece\n")
Explanation: Writing to a file
First, we open a file to write, using the same "with" construction
Then we write the contents.
End of explanation
output_file = open(file_name, 'w')
output_file.write("Dear Uncle Marty,\n")
output_file.write("Thanks for the nifty present.\n")
output_file.write("Love,\nYour Niece\n")
kb_hit = raw_input("waiting...")
output_file.close()
Explanation: Until you close, Python may save up the text for later output.
Examine missive.txt before you close it; it’s probably empty.
End of explanation
<END_TASK>