Difference between revisions of "OPS435 Python Lab 3"

From CDOT Wiki
Jump to: navigation, search
(PART 1 - Using Functions)
 
(297 intermediate revisions by 5 users not shown)
Line 1: Line 1:
 +
<font color='red'>
 +
'''** DO NOT USE - TO BE UPDATED FOR CENTOS 8.0 **'''
 +
</font>
 
= LAB OBJECTIVES =
 
= LAB OBJECTIVES =
  
:In previous labs, you learned some programming tools in order to make your Python scripts '''more functional''' and allowed your Python script to run differently based on different data or situations. These tools included '''variables''', '''logic''' and '''loops'''. The utilization of these basic tools not only apply to Python scripts, but basically all programming languages including interpreted (including '''Perl scripts''', '''Bash Shell scripts''', '''JavaScript''', etc ) and compiled languages (including '''C''', '''C++''', '''Java''', etc).  
+
:In previous labs, you learned some programming tools in order to make your Python scripts '''more functional''' and allowed your Python script to run differently based on different data or situations. These tools included '''objects/variables''', '''condition statements''' and '''loops'''. The utilization of these basic tools not only apply to Python scripts, but basically all programming languages including interpreted (including '''Perl scripts''', '''Bash Shell scripts''', '''JavaScript''', etc ) and compiled languages (including '''C''', '''C++''', '''Java''', etc).  
  
:In this lab, you will learn the following tools including '''functions''', '''lists''', and '''loops''', with the primary focus on creating reusable code.
+
:In this lab, you will learn '''functions''', '''lists''', and '''loops''', with the primary focus on creating reusable code.
  
 
:'''<u>Objectives</u>'''
 
:'''<u>Objectives</u>'''
Line 9: Line 12:
 
:Write Python code in order to:
 
:Write Python code in order to:
  
:*'''Create reusable functions''' that can be imported by ipython3 or other python scripts
+
:*'''Create reusable functions''' that can be imported by other python scripts
  
 
:*'''Using and manipulating lists''' to allow for processing a large amount of data quickly
 
:*'''Using and manipulating lists''' to allow for processing a large amount of data quickly
  
:*'''Looping through lists''' using '''Functions'''. Looping (iteration) is the ability for your program to repeatedly run the same code over and over. In this way, you can run a loop that contains a list to better send data to functions for better, more efficient execution of your Python script'''.
+
:*'''Looping through lists'''. Looping (iteration) is the ability for your program to repeatedly run the same code over and over. In this way, you can run a loop that contains a list to better send data to functions for better, more efficient execution of your Python script.
 
<br><br>
 
<br><br>
  
= INVESTIGATION 1: USING FUNCTIONS =
+
= INVESTIGATION 1: CREATING THE SIMPLEST FUNCTIONS =
:A very simple definition of using '''functions''' is like having '''smaller programs contained inside a larger program''' that can be run by '''function name''' to perform '''repeated or commonly routine tasks'''. In programming languages such as C, C++, and Java, functions (programs) that are very useful are collected in various '''Libraries''' and thus relates to dependency issues that were discussed when compiling C programming code in your OPS25 course. We do not go into detail involving Libraries for this course since Python is an interpreted (i.e. not compiled) language.
 
  
 +
:A very simple definition of using '''functions''' is to create and reuse '''smaller programs within a larger program'''. In programming languages such as '''C''', '''C++''' and '''Java''', commonly used functions are pre-packaged in '''libraries'''. This relates to dependency issues that were discussed when compiling C programming code in your OPS235 course: if a supporting library is missing, the program would not be able to run the called function.
  
:Usually, a '''function''' will '''contain programming code''' in some part of the main program (most likely near the '''top''' of the program '''BEFORE''' the main program). We refer to that as '''"function declaration"'''.
+
:Usually, a '''function''' will '''contain programming code''' in some part of the python file (most likely near the top of the file, before the main program). We refer to that as a '''"function declaration"'''.
: When a program is run, the '''function's code is read into internal memory''', ready to be run when the function is '''run''' (referred to as '''calling the function''').  Until a Function is specifically told to execute, it's code will sit (in internal memory) unused.
+
: When a program is run, the '''function's code is read into internal memory''', ready to be run when the function is executed (referred to as '''calling the function''').  Until a Function is specifically told to execute, its code will sit (in internal memory) unused.
  
 +
:When creating programs that define and use functions, '''a large programming task can be broken-down into smaller elements''' (or '''modules'''). This is why creating programs that use functions is referred to as '''"modular programming"'''.
  
:When creating programs that define and use functions, '''a large programming task can be broken-down into smaller elements''' (or '''modules'''). This is why creating programs that use functions is referred to as '''"modular programming"'''.
+
== PART 1 - How User-Defined Functions are Declared and Run ==
  
:Functions may be designed '''not to accept arguments or return a value''', designed to '''not accept arguments but not return a value''', '''accept arguments and not return a value''', or '''both accept arguments and return a value'''.
+
:Functions may be designed:
 +
* '''not to accept arguments or return a value''',  
 +
* to '''not accept arguments but return a value''',  
 +
* to '''accept arguments and not return a value''',  
 +
* or to '''both accept arguments and return a value'''.
 +
In this investigation, we will focus on creating functions that either do NOT return a value, or return a value.
  
== PART 1 - Using Functions ==
 
 
'''Functions and Strings'''
 
'''Functions and Strings'''
  
: You will now learn how to define and run functions that will eventually use (and return) '''string data''' when a function is called.
+
: You will now learn how to define and run functions that will return '''string data''' when a function is called.
  
 
:'''Perform the Following Steps:'''
 
:'''Perform the Following Steps:'''
:#To start, open ipython and try experimenting with functions.<source>
+
 
ipython3
+
:#Create a new python file for testing code in this section.
</source>
+
:#Whenever you want to create a function, you must start with the keyword "'''def'''". The '''def''' keyword is used to start the definition of the function, it does not run the code you write. Functions, just like '''if''' statements, must have all code under them indented.<source lang="python">
:#Whenever you want to create a function, you must start with the keyword "'''def'''". The '''def''' keyword is used to start the definition of the function, it does not run the code you write. Functions, just like if statements, must have all code under them indented.<source>
 
 
def hello():
 
def hello():
 
     print('Hello World')
 
     print('Hello World')
 
     print('Inside a Function')
 
     print('Inside a Function')
 
</source>
 
</source>
:#Now that our function was created, we can use it over and over. To execute the code inside the function, run the function name with "'''()'''" '''brackets''' at the end of the function name.<br>Try running the '''hello()''' function by name three times by issuing the following:<source>
+
:#Executing your file you should have noticed that nothing happened. Well actually, something did happen... the function called '''hello(''') has been defined and stored in internal memory in order for it to run when called by its function name. Now that our function was created, we can use it over and over.
 +
:#To execute the code inside the function, run the function name with "'''()'''" '''brackets''' at the end of the function name.<br>Try running the '''hello()''' function by name three times like this:<source lang="python">
 
hello()
 
hello()
 
hello()
 
hello()
 
hello()
 
hello()
</source>You should notice that the function just does the same thing over-and-over no matter how many times your call the function by name. By the way, that is OK. On the other hand, you may want to create and use a function to do something, like perform error checking or some other task that returns a value to the '''main''' program for further processing. For example, a true or false value if the error checking function that was called was detected no errors or detected an error.<br><br>
+
</source>You should notice that the function just does the same thing over-and-over no matter how many times your call the function by name. By the way, that is OK. On the other hand, you may want to create and use a function to do something, like perform error checking or some other task that returns a value to the '''main''' program for further processing. For example, a '''true''' or '''false''' value if the error checking function that was called was detected no errors or detected an error. But let's stick to some simple examples first, before tackling more complex use of functions.<br><br>
:#Let's create a function that returns some data after the function is called. This function does not print out any text, it creates new variables and at the end returns the value.<source>
+
:#Let's create a function that '''returns''' some data after the function is called. This function does not print out any text: instead; it creates new variables and at the end returns the value of one of the variables.<source lang="python">
 
def return_text_value():
 
def return_text_value():
 
     name = 'Terry'
 
     name = 'Terry'
Line 53: Line 61:
 
     return greeting
 
     return greeting
 
</source>
 
</source>
:#The different between returning a value and printing a value, returned values can be caught and stored for later use. Once the returned value has been stored, it can be printed, manipulated, compared in if statements, and more. Below will cover how to store a returned value.<source>
+
:# Call the function like this:<source lang="python">
 +
return_text_value()
 +
</source>One major difference between a function '''returning a value''' and simply '''printing a value''' is that '''returned''' values can be caught and stored in variables used in the program (that called the function) for later use. Once the returned value has been stored, it can be printed, manipulated, compared in IF statements, etc. Below will cover how to store a returned value.<br><br>
 +
:#Notice that this syntax looks just the call to the input() function which you've used in the last lab:<source lang="python">
 
text = return_text_value()
 
text = return_text_value()
 
</source>
 
</source>
:#Now the returned text from the function has been stored in the variable "'''text'''". It can be used like any string value now.<source>
+
:#Now the returned text from the function has been stored in the variable "'''text'''". It can be used like any string value now.<source lang="python">
 
print(text)
 
print(text)
 
</source>
 
</source>
  
'''Functions and Integers'''
+
'''Functions and Numbers (Integers)'''
  
: You will now learn how to define and run functions that will send '''integer data''' when a function is called with arguments.
+
: You will now learn how to define and run functions that will return '''integer data''' when a function is called. In this section, you will define a function that will be returning integer values instead of text. There is not a big difference, but when returning number values, care needs to be taken if you try combining it with a string!
  
 
:'''Perform the Following steps:'''
 
:'''Perform the Following steps:'''
  
:#In this next example the functions will be returning integer values instead of text. There is not a big difference, but when returning number values, care needs to be taken if you try combining it with a string.<source>
+
:#Define the return_number_value() function:<source lang="python">
 
def return_number_value():
 
def return_number_value():
 
     num1 = 10
 
     num1 = 10
Line 74: Line 85:
  
 
</source>
 
</source>
:#Now try storing the return value of the above function.<source>
+
:#And call it:<source lang="python">
 
number = return_number_value()
 
number = return_number_value()
 
print(number)
 
print(number)
 
print(number + 5)
 
print(number + 5)
 
print(return_number_value() + 10)
 
print(return_number_value() + 10)
</source>
+
</source> What do you notice?<br><br>  
:#The warning again, because this is a number value, using it with strings can cause errors. <source>
+
:#Now, display both strings and numbers:<source lang="python">
 
number = return_number_value()
 
number = return_number_value()
 
print('my number is ' + number)
 
print('my number is ' + number)
---------------------------------------------------------------------------
+
</source> What do you notice? You should notice a warning message. This occurs because the returning value is a '''number''' and NOT a '''string'''! Combining numbers and strings in a statement (such as '''print()''') can cause errors. The error message should appear similar to the one displayed below: <source>
TypeError                                Traceback (most recent call last)
+
Traceback (most recent call last):
<ipython-input-24-d80d5924146a> in <module>()
+
  File "test.py", line 2, in <module>
----> 1 print('my numbr is ' + number)
+
    print('my number is ' + number)
 
+
TypeError: cannot concatenate 'str' and 'int' objects
TypeError: Can't convert 'int' object to str implicitly
 
 
</source>
 
</source>
:#If a number needs to be combined with a string use the one of the following syntax below.<source>
+
:#If a number needs to be combined with a string, use the '''str()''' predefined function that was discussed in a previous lab in order to convert the returned number into a string:<source lang="python">
 
number = return_number_value()
 
number = return_number_value()
 
print('my number is ', number)
 
print('my number is ', number)
Line 97: Line 107:
 
</source>
 
</source>
  
===Practice Using Functions===
+
== PART 2 - Creating a Python Script with Functions and Importing Functions ==
:'''Perform the Following Instructions:'''
+
 
:#Create a new script '''~/ops435/lab3/lab3a.py''' and store the following content inside:<source>
+
'''Creating a Python Script'''
#!/usr/bin/env python3
+
 
 +
:Now it's time to create a Python script that uses two functions. One function returns a string value to greet the user, where the other function returns the result of adding two values (stored in variables within the function).
 +
 
 +
:'''Perform the following Instructions:'''
  
# Function returning string value
+
:#Create a new script '''~/ops435/lab3/lab3a.py'''
def return_text_value():
 
    name = 'Terry'
 
    return 'Good Morning ' + name
 
  
# Function returning integer value
+
:::'''Input / Output Requirements'''
def return_number_value():
 
    num1 = 5
 
    num2 = 10
 
    num3 = num1 + num2
 
    return num3
 
  
# This IF Statement may seem cryptic and unclear. Any code written under this if statement will be run when you run your script.  
+
:::*The script should have a '''Shebang line'''
 +
:::*Below the '''Shebang line''', add an '''empty line''' followed by a comment stating: '''# return_text_value() function'''
 +
:::*Add an '''empty line''' followed by the '''return_text_value()''' function '''definition''' that you previously entered in the shell.
 +
:::*Add another '''empty line''' followed by a comment stating: '''# return_number_value() function'''
 +
:::*Add another '''empty line''' following by the '''return_number_value()''' function '''definition''' that you previously entered in the shell.
 +
:::*Add a '''couple of empty lines''', following by a comment stating: '''# Main Program'''
 +
:::*Add another '''couple of empty lines''', followed by the statements displayed below:<source lang="python">
 
if __name__ == '__main__':
 
if __name__ == '__main__':
 +
    print('python code')
 
     text = return_text_value()
 
     text = return_text_value()
 
     print(text)
 
     print(text)
Line 121: Line 133:
 
     print(str(number))
 
     print(str(number))
 
</source>
 
</source>
:#Exit the ipython3 shell, download the checking script and check your work. Enter the following commands from the bash shell.<source>
+
:Running your program you should have seen three lines being displayed: the text "python code", a greeting, and a result of a math calculation. The '''if''' statement in the code above is a special '''if''' statement needed to make sure that your "main" code only runs when you want it to. More on that later.
 +
 
 +
'''Importing Functions From other Python Scripts'''
 +
 
 +
In order to use functions from other scripts, you use the '''import''' statement.<br><br>
 +
 
 +
:# Let's see what happens if we forget to import functions from your lab3a.py script prior to calling a function. Create a new python file and try to call the return_text_value() function:<source lang="python">
 +
text = lab3a.return_text_value()
 +
</source>You should notice an error indicating '''"name 'lab3a' is not defined"'''. This error occurs since you failed to instruct python to '''import''' or "load existing defined functions from your lab3a.py script" to '''internal memory'''.<br><br>
 +
:# Modify your program like this:<source lang="python">
 +
import lab3a
 +
text = lab3a.return_text_value()
 +
print(text)
 +
lab3a.return_number_value()
 +
</source> You should notice that all of the function calls should now work.
 +
:# Download the checking script and check your work. Enter the following commands from the bash shell.<source lang="bash">
 
cd ~/ops435/lab3/
 
cd ~/ops435/lab3/
 
pwd #confirm that you are in the right directory
 
pwd #confirm that you are in the right directory
ls CheckLab3.py || wget matrix.senecac.on.ca/~acoatley-willis/CheckLab3.py
+
ls CheckLab3.py || wget https://raw.githubusercontent.com/Seneca-CDOT/ops435/master/LabCheckScripts/CheckLab3.py
 
python3 ./CheckLab3.py -f -v lab3a
 
python3 ./CheckLab3.py -f -v lab3a
 
</source>
 
</source>
:#Before proceeding, make certain that you identify any and all errors in lab3a.py. When the check script tells you everything is ok before proceeding to the next step.
+
:# Before proceeding, make certain that you identify any and all errors in lab3a.py. When the checking script tells you everything is OK before proceeding to the next step.
:#Start up ipython3 shell again.<source>
+
<br><br>
ipython3
+
 
</source>
+
= INVESTIGATION 2: CREATING FUNCTIONS WITH ARGUMENTS AND RETURN VALUES =
:#The if statement line found in lab3a.py is special if statement. It allows scripts to be imported into other python environment while only defining the functions, this powerful feature allows for python scripts to run differently depending on if you run it or import it. Take a look at the code, there is NO reason to run this in ipython3.<source>
+
 
if __name__ == '__main__':
+
== PART 1 - Providing Functions With Arguments ==
    print('python code')
+
 
</source>
+
:Functions can receive '''arguments''' - data to be used for processing. In this section, you will learn how to define functions that accept arguments and learn how to call functions with arguments (such as mathematical operations or testing conditions, which is useful for error-checking).
:#To show examples of how the above if statement works, run the lab3a.py script. The output will show that all the code found under the if statement was run. <source>
 
run lab3a.py
 
</source>
 
:#This next example will show when the code under the if statement does NOT run.<source>
 
import lab3a
 
</source>
 
:#When you import a python script it will run all code found that is not indented, including defining all of the functions. But, when importing, python will not run any code under the special if statement. Now that the script has been imported, we can run functions previously written.<source>
 
text = lab3a.return_text_value()
 
text
 
lab3a.return_number_value()
 
</source>
 
  
== PART 2 - Providing Functions With Arguments ==
+
'''Passing up Single and Multiple Arguments to a Function'''
Functions can take arguments that work similarly to Python scripts. In this section, the functions created will be given arguments, these functions will use the given arguments to provide different output.
 
  
 
:'''Perform the Following Steps:'''
 
:'''Perform the Following Steps:'''
:#Start the ipython3 shell<source>
+
:#Create a new Python file for testing.
ipython3
+
:#When passing arguments to functions, you put data such as '''strings''', '''numbers''', or '''variable names''' within brackets immediately following the function name.<br><br>'''NOTE:''' If a function accepts arguments, then those arguments must be declared (using variable names) when the function is declared. Those declared variable names are then used within the function for processing. Also, when you call a function with arguments, the number of arguments passed up to the function must match the number of arguments that were specified in the function declaration.<br><br>
</source>
+
:#Define a function called '''square()''':<source lang="python">
:#To create a new function that accepts arguments, provide variable names in the functions brackets. But if a function is given arguments in the definition, it must always get the same number of arguments when you call the function.<source>
 
 
def square(number):
 
def square(number):
 
     return number ** 2
 
     return number ** 2
</source>
+
</source>'''FYI:'''You may have learned that you multiple a number by itself in order to "square" the number. In python, the '''**''' operator will raise the operand on the left to the power of the operand on the right.<br><br>When calling functions with multiple arguments, the arguments are separated by '''commas'''. See what happens if you provide strings, strings without using quotes, or numbers with decimals in the following examples.
:#To square a number in math your multiply using '''number * number''' or use exponents '''number ** 2''' to the power of two. This function takes one argument '''number''', the function will use exponents to multiply the number given by itself.<source>
+
:#Test your '''square()''' function:<source lang="python">
 
square(5)
 
square(5)
 
square(10)
 
square(10)
 
square(12)
 
square(12)
 
square(square(2))
 
square(square(2))
</source>
+
square('2')
:#Providing more than one argument in a function requires the use of commas. Be careful NOT to provide strings or decimals, as you may cause errors.<source>
+
</source>Notice that nothing is printed, you need to print the values the functions return to see what they are.
 +
:#The last function call should produce an '''error message'''. This is caused by sending a '''string''' instead of a number that is processed by the function. We could use the int() function to convert any value passed in as a string by mistake to an integer number.<br><br>
 +
:#Declare the function '''sum_numbers()''':<source lang="python">
 
def sum_numbers(number1, number2):
 
def sum_numbers(number1, number2):
 
     return int(number1) + int(number2)
 
     return int(number1) + int(number2)
 
</source>
 
</source>
:#Running functions with multiple arguments is the same. When you put a function as a argument of another function, the inner-most function will run first, and the return value will be used as the argument on the outer function. For example, in this case below, '''sum_numbers(5, 5)''' will return '''10''', and provide square with that value '''square( 10 )'''.<source>
+
:#Call that function to see what happens:<source lang="python">
 
sum_numbers(5, 10)
 
sum_numbers(5, 10)
 
sum_numbers(50, 100)
 
sum_numbers(50, 100)
 +
</source>
 +
:#You can also do what looks like calling a function within another function, but it's actually just calling sum_numbers() first, then calling square() with the return from sum_numbers as an argument:<source lang="python">
 
square(sum_numbers(5, 5))
 
square(sum_numbers(5, 5))
</source>
+
</source>'''NOTE:''' Running functions with multiple arguments is the same. When call a function as an argument of another function, the '''inner-most function will run first''', and the return the value from that will be used as the argument for the '''outer function'''. In the example below, '''sum_numbers(5, 5)''' will return '''10''', thus providing that result to be  square with that value '''square(10)'''.<br><br>
 +
 
 +
'''Practice Creating a Function that Accepts Arguments and Returns a Value'''
 +
 
 +
:It is time to practice creating a shell script that uses a function that accepts arguments, and returns a value.
  
'''Practice Creating Functions With Return Values'''
 
 
:'''Perform the Following Instructions:'''
 
:'''Perform the Following Instructions:'''
:#The next script is NOT COMPLETE, your job is to make the script do what it askes. It contains 3 functions, one of adding, one for subtracting, and one for multiplying. Make sure each function performs the correct operation and returns a integer value. Create a new script '''~/ops435/lab3/lab3b.py''' with the following contents:<source>
+
#!/usr/bin/env python3
+
:#Create a new script '''~/ops435/lab3/lab3b.py'''. Refer to the '''Python Script template''' and the '''Additional Requirements''' sections when creating your Python script. Refer to Sample Run and Sample Imports displayed below for exact prompt and output
 +
 
 +
:::'''Python Script Template'''
 +
 
 +
:::<source lang="python">#!/usr/bin/env python3
  
 
def sum_numbers(number1, number2):
 
def sum_numbers(number1, number2):
 
     # Make this function add number1 and number2 and return the value
 
     # Make this function add number1 and number2 and return the value
  
def subtract_numbers():
+
def subtract_numbers(number1, number2):
 
     # Make this function subtract number1 and number2 and return the value
 
     # Make this function subtract number1 and number2 and return the value
 
     # Remember to make sure the function accepts 2 arguments
 
     # Remember to make sure the function accepts 2 arguments
  
def multiply_numbers():
+
def multiply_numbers(number1, number2):
 
     # Make this function multiply number1 and number2 and return the value
 
     # Make this function multiply number1 and number2 and return the value
 
     # Remember to make sure the function accepts 2 arguments
 
     # Remember to make sure the function accepts 2 arguments
   
+
 
# Place any code you want to test inside the if statement for practice
 
 
if __name__ == '__main__':
 
if __name__ == '__main__':
 
     print(sum_numbers(10, 5))
 
     print(sum_numbers(10, 5))
 
     print(subtract_numbers(10, 5))
 
     print(subtract_numbers(10, 5))
 
     print(multiply_numbers(10, 5))
 
     print(multiply_numbers(10, 5))
 +
 
</source>
 
</source>
:::*The script should have a '''Shebang line'''
+
 
:::*The script should have a function sum_numbers(number1, number2)
+
::'''Additional Requirements'''
:::*The script should have a function subtract_numbers(number1, number2)
+
 
:::*The script should have a function multiply_numbers(number1, number2)
+
::*All functions should accept two arguments
:::*All functions should accept two arguments
+
::*All functions should return an integer
:::*All functions should return a integer
+
::*The script should contain no errors
:::*The script should contain no errors
+
 
:::2. Sample Run 1:<source>
+
::'''Sample Run:'''<source lang="python">
run lab3b.py
+
./lab3b.py
 
15
 
15
 
5
 
5
 
50
 
50
 
</source>
 
</source>
:::3. Sample Import 1:<source>
+
::'''Other examples:'''<source lang="python">
ipython3
 
 
 
 
import lab3b
 
import lab3b
  
sum_numbers(10, 5)
+
lab3b.sum_numbers(10, 5)
15
+
# Will return 15
 
+
lab3b.sum_numbers(25, 25)
sum_numbers(25, 25)
+
# Will return 50
50
+
lab3b.subtract_numbers(10, 5)
 
+
# Will return 5
subtract_numbers(10, 5)
+
lab3b.subtract_numbers(5, 10)
5
+
# Will return -5
 
+
lab3b.multiply_numbers(10, 5)
subtract_numbers(5, 10)
+
# Will return 50
-5
+
lab3b.multiply_numbers(10, 2)
 
+
# Will return 20
multiply_numbers(10, 5)
+
</source>
50
 
  
multiply_numbers(10, 2)
+
::2. Download the checking script and check your work. Enter the following commands from the bash shell.<source lang="bash">
20
 
</source>
 
:::4. Exit the ipython3 shell, download the checking script and check your work. Enter the following commands from the bash shell.<source>
 
 
cd ~/ops435/lab3/
 
cd ~/ops435/lab3/
 
pwd #confirm that you are in the right directory
 
pwd #confirm that you are in the right directory
ls CheckLab3.py || wget matrix.senecac.on.ca/~acoatley-willis/CheckLab3.py
+
ls CheckLab3.py || wget https://raw.githubusercontent.com/Seneca-CDOT/ops435/master/LabCheckScripts/CheckLab3.py
 
python3 ./CheckLab3.py -f -v lab3b
 
python3 ./CheckLab3.py -f -v lab3b
 
</source>
 
</source>
:::5. Before proceeding, make certain that you identify any and all errors in lab3b.py. When the check script tells you everything is ok before proceeding to the next step.
 
  
'''Multiple Arguments and IF Statements'''
+
::3. Before proceeding, make certain that you identify any and all errors in lab3b.py. When the checking script tells you everything is OK - proceed to the next step.
  
The next function we make in this section if going to be more advanced and contain logic inside it. First try the following to practice logic in functions.
+
'''Passing up Multiple Arguments and Using Conditional Statements'''
 +
 
 +
:You will now create a more complex function that will not only pass arguments, but also include logic to control the flow of the function, and affect how your Python script will be run. You will create a function that uses an '''if/elif/else''' statement.
  
 
:'''Perform the Following Steps:'''
 
:'''Perform the Following Steps:'''
:#Start the ipython3 shell<source>
+
:#Use a temporary Python file to define the following function:<source lang="python">
ipython3
+
def describe_temperature(temp):
</source>
 
:#Now try making some functions that uses if statements, '''BUT BEWARE''', making an if statement inside a function means that you are indented two times to get to the if statement.<source>
 
def check_temperature(temp):
 
 
     if temp > 30:
 
     if temp > 30:
 
         return 'hot'
 
         return 'hot'
Line 256: Line 273:
 
     elif temp == 20:
 
     elif temp == 20:
 
         return 'perfect'
 
         return 'perfect'
     return 'ok'
+
     return 'ok'    
       
+
</source>The final '''return "ok"''' will only take place if a previous return has not taken place before it. Once return has been used in a function, the function immediately exits and returns the value.
 +
:#Call describe_temperature like this to confirm the results:<source>
 +
print(describe_temperature(50))
 +
# Will return 'hot'
 +
print(describe_temperature(20))
 +
# Will return 'perfect'
 +
print(describe_temperature(-50))
 +
# Will return 'cold'
 +
print(describe_temperature(25))
 +
# Will return 'ok'
 +
print(describe_temperature(10))
 +
# Will return 'ok'
 
</source>
 
</source>
:#Remember to note the extra indentation on the code under the if statements. The final '''return "ok"''' will only take place if a previous return has not taken place before it. Once return has been used in a function, the function immediately exits and returns the value. <source>
 
check_temperature(50)
 
'hot'
 
  
check_temperature(20)
+
'''Create a Python Script Receiving Multiple Arguments'''
'perfect'
 
  
check_temperature(-50)
 
'cold'
 
 
check_temperature(25)
 
'ok'
 
 
check_temperature(10)
 
'ok'
 
</source>
 
 
'''Practice Multiple Levels of Indentation'''
 
 
:'''Perform the Following Instructions:'''
 
:'''Perform the Following Instructions:'''
:#Create the '''~/ops435/lab3/lab3c.py''' script. The purpose of the script is to make a single function that can perform addition, subtraction, or multiplication on a pair of numbers. But the function will allow us to choose exatly what operation we are performing on it when we call the function. If the operate function does NOT understand the operator given, it should return a error message.
+
:#Create the '''~/ops435/lab3/lab3c.py''' script. The purpose of the script is to have a single function that can perform addition, subtraction, or multiplication on a pair of numbers. But the function will allow us to choose exatly what operation we are performing on it when we call it. If the operate function does NOT understand the operator given, it should return an error message (e.g. calling the function to 'divide' two numbers).
:#Use this template to get started:<source>
+
:#Use this template to get started:<source lang="python">
 
#!/usr/bin/env python3
 
#!/usr/bin/env python3
  
Line 291: Line 304:
 
     print(operate(10, 5, 'divide'))
 
     print(operate(10, 5, 'divide'))
 
</source>
 
</source>
:::*The script should have a '''Shebang line'''
+
:::*The operate() function should use '''conditional''' statements<br> &nbsp; '''FYI:''' Remember that you MUST consistently '''indent ALL code''' for within each section (or test).
:::*The script should have a function operate(num1, num2, operator)
+
:::*The operate() function should accept '''three arguments'''.
:::*The script should use if statements inside the operate function
+
:::*The operate() function should '''return''' the result.
:::*The operate function should accept three arguments
+
:::*The operate() function should '''return''' an error message if the operation is unknown<br> &nbsp; '''FYI:''' Use single quotes or double-quotes to pass a string value.
:::*The operate function should return the answer
+
:::*The script should contain show the exact output as the sample.
:::*The operate function should return a error message if the operation is unknown
+
:::*The script should contain no errors.
:::*The script should contain show the exact output as the sample imports
+
:::*As an extra exercise, try to write your function with only one return statement.
:::*The script should contain no errors
+
 
:::3. Sample Run 1:<source>
+
:::'''Sample Run 1:'''<source>
run lab3c.py
+
./lab3c.py
 
15
 
15
 
5
 
5
Line 306: Line 319:
 
Error: function operator can be "add", "subtract", or "multiply"
 
Error: function operator can be "add", "subtract", or "multiply"
 
</source>
 
</source>
:::4. Sample Import 1:<source>
+
 
 +
:::'''Sample Run 2 (using import from another Python file):'''<source>
 
import lab3c
 
import lab3c
 
+
lab3c.operate(10, 20, 'add')
operate(10, 20, 'add')
+
# Will return 30
30
+
lab3c.operate(2, 3, 'add')
 
+
# Will return 5
operate(2, 3, 'add')
+
lab3c.operate(100, 5, 'subtract')
5
+
# Will return 95
 
+
lab3c.operate(10, 20, 'subtract')
operate(100, 5, 'subtract')
+
# Will return -10
95
+
lab3c.operate(5, 5, 'multiply')
 
+
# Will return 25
operate(10, 20, 'subtract')
+
lab3c.operate(10, 100, 'multiply')
-10
+
# Will return 1000
 
+
lab3c.operate(100, 5, 'divide')
operate(5, 5, 'multiply')
+
# Will return Error: function operator can be "add", "subtract", or "multiply"
25
+
lab3c.operate(100, 5, 'power')
 
+
# Will return Error: function operator can be "add", "subtract", or "multiply"
operate(10, 100, 'multiply')
 
1000
 
 
 
operate(100, 5, 'divide')
 
Error: function operator can be "add", "subtract", or "multiply"
 
 
 
operate(100, 5, 'power')
 
Error: function operator can be "add", "subtract", or "multiply"
 
 
</source>
 
</source>
:::5. Exit the ipython3 shell, download the checking script and check your work. Enter the following commands from the bash shell.<source>
+
:::3. Download the checking script and check your work. Enter the following commands from the bash shell.<source lang="bash">
 
cd ~/ops435/lab3/
 
cd ~/ops435/lab3/
 
pwd #confirm that you are in the right directory
 
pwd #confirm that you are in the right directory
ls CheckLab3.py || wget matrix.senecac.on.ca/~acoatley-willis/CheckLab3.py
+
ls CheckLab3.py || wget https://raw.githubusercontent.com/Seneca-CDOT/ops435/master/LabCheckScripts/CheckLab3.py
 
python3 ./CheckLab3.py -f -v lab3c
 
python3 ./CheckLab3.py -f -v lab3c
 
</source>
 
</source>
:::6. Before proceeding, make certain that you identify any and all errors in lab3c.py. When the check script tells you everything is ok before proceeding to the next step.
+
:::4. Before proceeding, make certain that you identify any and all errors in lab3c.py. When the checking script tells you everything is OK - proceed to the next step.
 +
<br><br>
  
== PART 3 - Running System Commands with Subprocess ==
+
== PART 2 - Running System Commands with Subprocess ==
This last part of the investigation will give you access to system commands within your python scripts. While we are able to run some bash commands inside the ipython3 environment, these do not transfer over into the python code we write. It is not usually a good idea to run system commands in Python, this makes your Python code less portable and makes it require a speicifc operating system or a system that has those commands available. There is also the case of security, allowing python to execute commands on the system can be a security problem if care isn't taken. For these reason you should only use subprocess and the system commands as a last resort and stick to Python code only.
+
:The remainder of this investigation will allow you to run operating system commands via your Python script. Although there are different ways in which to issue operating system commands, you will learn two of them.
  
 
'''Perform the Following Steps:'''
 
'''Perform the Following Steps:'''
  
:#Start the ipython3 shell:<source>
+
:#Create a new python file for testing.
import subprocess
+
:#Import the '''''os''''' module in your python file.
dir(subprocess)
+
:#You can issue operating system commands by using the '''system()''' function. Try it:<source lang="python">
</source>
+
os.system('ls')
:#There are many available modules and attributes available as part of subprocess, we are interested in "'''Popen'''". This method subprocess.Popen() can be used to run system commands as a child process to the Python script. This below output will create a new child process, in Python we can control this through the new Python object we just created, "'''p'''". "'''p'''" now has a collection of methods(functions that are apart of a object) available, view them with '''dir()'''.<source>
+
os.system('whoami')
 +
os.system('ifconfig')
 +
</source>Notice that the output from the programs is printed in your script. Consider that may not always be what you want.<br><br>
 +
:#Try this also:<source lang="python">
 +
os.system('ipconfig')
 +
</source>You should notice an error message: ''''ipconfig: command not found''''. That error occurs since that command was an MS Windows command, and our current platform is Linux.<br><br>It is not always a good idea to run system commands in Python, this makes your Python code less portable and makes it require a specific operating system or a system that has those commands available. You should think about that when you decide whether you should or should not use a system command to accomplish some task or stick to pure Python code only.<br><br>As you may recall from lab2, you issued '''import sys''' to import special variables from the system. You can import a subprocess in order to run common non OS specific commands securely.<br><br>
 +
:#Import the subprocess module in your python file.
 +
:#There are many features available as part of the subprocess module, we are interested in "'''Popen'''". This method subprocess.Popen() can be used to run system commands as a child process to the Python script. The code below output will create a new child process, in Python we can control this through the new Python object we just created, "'''p'''". "'''p'''" now has a collection of methods(functions that are apart of a object) available.<br><br>
 +
:#To demonstrate, issue the following:<source lang="python">
 
p = subprocess.Popen(['date'], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
 
p = subprocess.Popen(['date'], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
dir(p)
+
</source>This function call and the following step is full of details we haven't yet talked about which is why it may look a little scary. By the time we're finished with the course - you will be able to look at code like this and not be intimidated. If you're curious and want to look ahead - you can find the definition for the [https://docs.python.org/3/library/subprocess.html#subprocess.Popen Popen function in the Python reference manual].
</source>
+
:#This next step is going to communicate with the process and get the retrieve it's output (stdout).<source>
:#This next step is going to communicate with the process and get the stdout and stderr from the command we previously.<source>
+
output = p.communicate()
stdout, stderr = p.communicate()
+
print(output)
stdout
+
print(output[0])
 
# The above stdout is stored in bytes
 
# The above stdout is stored in bytes
 
# Convert stdout to a string and strip off the newline characters
 
# Convert stdout to a string and strip off the newline characters
stdout = stdout.decode('utf-8').strip()
+
stdout = output[0].decode('utf-8').strip()
stdout
+
print(stdout)
 
</source>
 
</source>
:#While many of these system commands could be instead written in simply Python, the exercise of running system commands is important.
+
:# Sometimes you will be able to use purely python code to get your job done, but often you will need to call existing system commands. It's important to learn how to call them and how to interact with those external processes.
  
 
'''Practice Running System Commands From Python'''
 
'''Practice Running System Commands From Python'''
 
:'''Perform the Following Instructions:'''
 
:'''Perform the Following Instructions:'''
:#Create the "'''~/ops435/lab3/lab3d.py'''" script. The purpose of this script is to create a Python function that can return the linux system's root directory free space.
+
<ol>
:::*The script should have a '''Shebang line'''
+
<li>Create the "'''~/ops435/lab3/lab3d.py'''" script. The purpose of this script is to create a Python function that can return the linux system's root directory free space.
:::*The script should import subprocess
+
:*The script should '''import the correct module'''
:::*The script should use the linux command "df -h | grep '/$' | awk '{print $4}'"
+
:*The script should use the linux command: '''<nowiki>df -h | grep '/$' | awk '{print $4}'</nowiki>'''
:::*The script should contain the function free_space()
+
:*The script should contain the function called: '''free_space()'''
:::*The function free_space() should return a string which is in utf-8 and has newline characters stript
+
:*The function '''free_space()''' should return a string which is in '''utf-8''' and has '''newline characters strip'''
:::*Note: your output may be completely different, the free/available disk space on every computers root directory may be different.
+
:*'''Note:''' your output may be completely different, the free/available disk space on every computers root directory may be different.
:::2. Sample Run 1: <source>
+
:'''Sample Run 1:''' <source>
run lab3d.py
+
./lab3d.py
 
9.6G
 
9.6G
 
</source>
 
</source>
:::3. Sample Import 1:<source>
+
:'''Sample Run 2 (using import from another Python file):'''<source>
 
import lab3d
 
import lab3d
 
 
lab3d.free_space()
 
lab3d.free_space()
'9.6G'
+
# Will return 9.6G
</source>
+
</source></li>
:::4. Exit the ipython3 shell, download the checking script and check your work. Enter the following commands from the bash shell.<source>
+
<li>Download the checking script and check your work. Enter the following commands from the bash shell.<source lang="bash">
 
cd ~/ops435/lab3/
 
cd ~/ops435/lab3/
 
pwd #confirm that you are in the right directory
 
pwd #confirm that you are in the right directory
ls CheckLab3.py || wget matrix.senecac.on.ca/~acoatley-willis/CheckLab3.py
+
ls CheckLab3.py || wget https://raw.githubusercontent.com/Seneca-CDOT/ops435/master/LabCheckScripts/CheckLab3.py
 
python3 ./CheckLab3.py -f -v lab3d
 
python3 ./CheckLab3.py -f -v lab3d
</source>
+
</source></li>
:::5. Before proceeding, make certain that you identify any and all errors in lab3d.py. When the check script tells you everything is ok before proceeding to the next step.
+
<li>Before proceeding, make certain that you identify any and all errors in lab3d.py. When the checking script tells you everything is OK - proceed to the next step.</li>
 +
</ol>
  
= INVESTIGATION 2 - LISTS =
+
= INVESTIGATION 3: USING LISTS =
Lists are ones of the most powerful data-types in Python. A list is a series of comma separated values found between square brackets. Values in a list can be anything: strings, integers, objects, even other lists. In this section we will introduce lists and how to use them effectively, we will come back to lists again in later labs.
 
  
 +
:'''Lists''' are one of the most powerful '''data-types''' in Python. A list is a series of '''comma separated values found between square brackets'''. Values in a list can be anything: '''strings''', '''integers''', '''objects''', even '''other lists'''. In this section, you will introduce lists and how to use them effectively, you will further user lists in later labs. It is important to realise that although lists may appear very similar to arrays in other languages, they are different in a number of aspects including the fact that they don't have a fixed size.
  
 
== PART 1 - Navigating Items in Lists ==
 
== PART 1 - Navigating Items in Lists ==
 
  
 
:'''Perform the Following Steps'''
 
:'''Perform the Following Steps'''
  
:#Start the ipython3 shell<source>
+
:#Create a new Python file for testing things in this section.
ipython3
+
:#Create a few lists with different values: list1 contains only '''integers''', list2 contains only '''strings''', list3 contains a combination of both '''integers and strings'''
</source>
+
:#<source lang="python">
:#Create a few lists with different values: list1 contains only integers, list2 contains only strings, list3 contains a combination of both.<source>
 
 
list1 = [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
 
list1 = [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
 
list2 = [ 'uli101', 'ops235', 'ops335', 'ops435', 'ops535', 'ops635' ]
 
list2 = [ 'uli101', 'ops235', 'ops335', 'ops435', 'ops535', 'ops635' ]
 
list3 = [ 'uli101', 1, 'ops235', 2, 'ops335', 3, 'ops435', 4, 'ops535', 5, 'ops635', 6 ]
 
list3 = [ 'uli101', 1, 'ops235', 2, 'ops335', 3, 'ops435', 4, 'ops535', 5, 'ops635', 6 ]
 +
</source>The best way to access individual '''elements''' in a list is using the list '''index'''.<br>The index is a number starting from 0 to ('''number_of_items - 1'''), the list index starts counting at '''0'''.<br><br>
 +
:#Inspect specified elements in your lists:<source lang="python">
 +
print(list1[0])  # First element in list1
 +
print(list2[1])  # Second element in list2
 +
print(list3[-1]) # Last element in list3
 
</source>
 
</source>
:#The best way to get individual items from a list is using the list index. The index is a number starting from 0 to (number_of_items - 1), the index starts counting at 0.<source>
+
:#You can also retrieve ranges of items from a list (these are called slices): <source lang="python">
list1[0] # First item in list1
+
print(list1[0:5]) # Starting with index 0 and stopping before index 5
list2[1] # Second item in list2
+
print(list2[2:4]) # Starting with index 2 and stopping before index 4
list3[-1] # Last item in list3
+
print(list3[3:]) # Starting with index 3 and going to the end
</source>
 
:#Instead of just getting the first and last, lists can give ranges of items. <source>
 
list1[0:5] # Starting with index 0 and stopping before index 5
 
list2[2:4] # Starting with index 2 and stopping before index 4
 
list3[3:]  # Starting with index 3 and going to the end
 
</source>
 
:#Lists can also contain other lists. This means lists can contain: lists and strings and integers all together. <source>
 
list4 = [ [1, 2, 3, 4], ['a', 'b', 'c', 'd'], [ 5, 6, 'e', 'f' ] ]
 
</source>
 
:#This list still only has 3 index locations. Each index points to another list. <source>
 
list4[0]
 
list4[1]
 
list4[2]
 
</source>
 
:#To access a list inside another list, a second index is needed. Spend some time trying out the syntax and try and navigate to a specific spot in the list.<source>
 
list4[0][0]  # First item in first list
 
list4[0][-1]  # Last item in first list
 
list4[2][0:2] # First two items in third list
 
</source>
 
:#Using different items from different lists to create new lists.<source>
 
first_only_list = [ list1[0], list2[0], list3[0] ]
 
first_only_list
 
 
</source>
 
</source>
  
 
'''Practice Using Functions and Using the List Index'''
 
'''Practice Using Functions and Using the List Index'''
 +
 
:'''Perform the Following Instructions'''
 
:'''Perform the Following Instructions'''
:#Create the '''~/ops435/lab3/lab3e.py''' script. The purpose of this script is to have a number of functions that output a different part of the list. Each function will return either a single item from the list OR will create a new list and return the entire new list.
 
:#The template function names and boiler plate if statement:<source>
 
!/usr/bin/env python3
 
  
# Put the list here
+
:#Create a Python script called: '''~/ops435/lab3/lab3e.py'''<br>The purpose of this script is to have a number of functions that output a different data storage in various elements of a list. Each function will return either a single item from the list OR will create a new list and return the entire new list.<br><br>
 +
:#The template function names and the special if statement:<source lang="python">
 +
#!/usr/bin/env python3
 +
 
 +
# Create the list called "my_list" here, not within any function defined below.
 +
# That makes it a global variable. We'll talk about that in another lab.
  
  
 
def give_list():
 
def give_list():
     # Returns the entire list unchanged
+
    # Does not accept any arguments
 +
     # Returns all of the global variable my_list unchanged
  
 
def give_first_item():
 
def give_first_item():
     # Returns a single string that is the first item in the list
+
    # Does not accept any arguments
 +
     # Returns a single string that is the first item in the global my_list
  
 
def give_first_and_last_item():
 
def give_first_and_last_item():
     # Returns the a list that includes the first and last items in the list
+
    # Does not accept any arguments
 +
     # Returns a list that includes the first and last items in the global my_list
  
 
def give_second_and_third_item():
 
def give_second_and_third_item():
     # Returns the a list that includes the second and third items in the list
+
    # Does not accept any arguments
 +
     # Returns a list that includes the second and third items in the global my_list
  
if __name__ == '__main__':
+
if __name__ == '__main__':   # This section also referred to as a "main code"
 
     print(give_list())
 
     print(give_list())
 
     print(give_first_item())
 
     print(give_first_item())
Line 463: Line 466:
 
     print(give_second_and_third_item())
 
     print(give_second_and_third_item())
 
</source>
 
</source>
:::*The script should have a '''Shebang line'''
+
 
:::*The script should have a list called my_list
+
:::'''Additional Requirements'''
:::*The list my_list should have the values: 100, 200, 300, 'six hundred'
+
 
:::*The script should have a function called give_list() which returns a list
+
:::*The script should declare a list called '''my_list''' created BEFORE any function definition
:::*The script should have a function called give_first_item() which returns a string
+
:::*The list called '''my_list''' should have the values: '''100''', '''200''', '''300''', and ''''six hundred''''
:::*The script should have a function called give_first_and_last_item() which returns a list
+
:::*The script should '''implement''' the empty functions - i.e. you have to fill in the bodies for these functions
:::*The script should have a function called give_second_and_third_item() which returns a list
+
 
:::3. Sample Run 1:<source>
+
:::'''Sample Run 1:'''<source>
run  lab3e.py
+
./ lab3e.py
 
[100, 200, 300, 'six hundred']
 
[100, 200, 300, 'six hundred']
 
100
 
100
Line 477: Line 480:
 
[200, 300]
 
[200, 300]
 
</source>
 
</source>
:::4. Sample Import 1:<source>
+
:::'''Sample Run 2 (with import from another script):'''<source>
 
import lab3e
 
import lab3e
 
 
lab3e.give_list()
 
lab3e.give_list()
[100, 200, 300, 'six hundred']
+
# Will print [100, 200, 300, 'six hundred']
 
 
 
lab3e.give_first_item()
 
lab3e.give_first_item()
100
+
# Will print 100
 
 
 
lab3e.give_first_and_last_item()
 
lab3e.give_first_and_last_item()
[100, 'six hundred']
+
# Will print [100, 'six hundred']
 
 
 
lab3e.give_second_and_third_item()
 
lab3e.give_second_and_third_item()
[200, 300]
+
# Will print [200, 300]
 
 
 
</source>
 
</source>
:::5. Exit the ipython3 shell, download the checking script and check your work. Enter the following commands from the bash shell.<source>
+
:::3. Download the checking script and check your work. Enter the following commands from the bash shell.<source>
 
cd ~/ops435/lab3/
 
cd ~/ops435/lab3/
 
pwd #confirm that you are in the right directory
 
pwd #confirm that you are in the right directory
ls CheckLab3.py || wget matrix.senecac.on.ca/~acoatley-willis/CheckLab3.py
+
ls CheckLab3.py || wget https://raw.githubusercontent.com/Seneca-CDOT/ops435/master/LabCheckScripts/CheckLab3.py
 
python3 ./CheckLab3.py -f -v lab3e
 
python3 ./CheckLab3.py -f -v lab3e
 
</source>
 
</source>
:::6. Before proceeding, make certain that you identify any and all errors in lab3e.py. When the check script tells you everything is ok before proceeding to the next step.
+
:::4. Before proceeding, make certain that you identify any and all errors in lab3e.py. When the checking script tells you everything is OK - proceed to the next step.
  
 
== PART 2 - Manipulating Items in Lists ==
 
== PART 2 - Manipulating Items in Lists ==
There are a number of ways to get information about lists, as well as change what is inside a list. This section will cover the different ways to manipulate lists.
+
 
 +
:There are a number of ways to obtain information about lists as well as change the data that is contained within a list. In this section, you will learn how to manipulate lists.
  
 
:'''Perform the Following Steps:'''
 
:'''Perform the Following Steps:'''
:#First start with the smallest change. Change a single item at a single point in a list.<source>
+
 
 +
:#Let's perform a simple change to a list element. Try the following code:<source lang="python">
 
courses = [ 'uli101', 'ops235', 'ops335', 'ops435', 'ops535', 'ops635' ]
 
courses = [ 'uli101', 'ops235', 'ops335', 'ops435', 'ops535', 'ops635' ]
courses[0]
+
print(courses[0])
 
courses[0] = 'eac150'
 
courses[0] = 'eac150'
courses[0]
+
print(courses[0])
courses
+
print(courses)
</source>
 
:#Now lets use the dir() and help() functions to see what functions and attributes lists have. The help() function will also give us tips on how to use some functions.<source>
 
dir(courses)
 
help(courses)
 
 
</source>
 
</source>
:#Next search and find more information on a number list functions for changing lists.<source>
+
:#Below are some examples of using built-in functions to '''manipulate''' lists. Take your time to see how each function can be a useful tool for making changes to existing lists:<source lang="python">
help(courses.append)
 
 
courses.append('ops235')    # Add a new item to the end of the list
 
courses.append('ops235')    # Add a new item to the end of the list
courses
+
print(courses)
  
help(courses.insert)
 
 
courses.insert(0, 'hwd101') # Add a new item to the specified index location
 
courses.insert(0, 'hwd101') # Add a new item to the specified index location
courses
+
print(courses)
  
help(courses.remove)
 
 
courses.remove('ops335')    # Remove first occurrence of value
 
courses.remove('ops335')    # Remove first occurrence of value
courses
+
print(courses)
  
help(courses.sort)
+
sorted_courses = courses.copy() # Create a copy of the courses list
sorted_list = courses.copy() # Create a copy of the courses list
+
sorted_courses.sort()          # Sort the new list
sorted_list.sort()          # Sort the new list
+
print(courses)
courses
+
print(sorted_courses)
sorted_courses
 
  
 
</source>
 
</source>
:#Using Python functions we can get more information out of lists.<source>
+
:#In addition to using functions to manipulate lists, there are functions that are useful to provide '''information''' regarding the list such as number of elements in a list, the smallest value and largest value in a list:<source lang="python">
 
list_of_numbers = [ 1, 5, 2, 6, 8, 5, 10, 2 ]
 
list_of_numbers = [ 1, 5, 2, 6, 8, 5, 10, 2 ]
len(list_of_numbers)    # Returns the length of the list
+
length_of_list = len(list_of_numbers)    # Returns the length of the list
min(list_of_numbers)   # Returns the smallest value in the list
+
smallest_in_list = min(list_of_numbers) # Returns the smallest value in the list
max(list_of_numbers)   # Returns the largest value in the list
+
largest_in_list = max(list_of_numbers)   # Returns the largest value in the list
</source>
+
 
:#Now on to some of the more powerful features of Python lists. Searching for values inside lists and finding locations of values in a list. The index() function allows searching inside a list for a value, it will return the index number of the first occurence. <source>
+
# Notice how the long line below is wrapped to fit on one screen:
number = 10
+
print("List length is " + str(length_of_list) +
help(list_of_numbers.index)
+
      ", smallest element in the list is " + str(smallest_in_list) +
list_of_numbers.index(number)           # Return index of the number searched for
+
      ", largest element in the list is " + str(largest_in_list))
</source>
 
:#The problem that comes up here is if the item searched for doesn't exist, Python will throw a error. Lets make sure it exists before asking for the index location. To find out if a value is in a list, just ask using a if statement, if the statement is True, then the value is found in the list.<source>
 
list_of_numbers = [ 1, 5, 2, 6, 8, 5, 10, 2 ]
 
number = 10
 
if number in list_of_numbers:                  # Returns True if value in list, returns False if item not in list
 
    number_index = list_of_numbers.index(number)
 
else:                                          # If the statement is False, the else will run
 
    print(str(number) + ' is not in list_of_numbers'
 
 
</source>
 
</source>
  
 
== PART 3 - Iterating Over Lists ==
 
== PART 3 - Iterating Over Lists ==
  
This final section explains the best part about lists. The ability to quickly loop through every value in the list. '''For loops''' have a set number of times they loop. The '''for loop''' will one by one run all indented code for each item in the list.  
+
:This last section demonstrates an extremely useful for lists: the ability to quickly '''loop through every value in the list'''. '''For loops''' have a set number of times they loop. The '''for''' loop will execute all indented code for each item (element) in the list.
  
 
:'''Perform the Following Steps'''
 
:'''Perform the Following Steps'''
  
:#The '''for loop''' will create a new variable that contains the value from the list of the current iteration.<source>
+
::The following '''for''' loop will store the value of each element from list_of_numbers within a variable named '''item''' and run code indented below the loop for each item.<br><br>
 +
:#Run this from a temporary Python file:<source lang="python">
 
list_of_numbers = [ 1, 5, 2, 6, 8, 5, 10, 2 ]
 
list_of_numbers = [ 1, 5, 2, 6, 8, 5, 10, 2 ]
 
for item in list_of_numbers:
 
for item in list_of_numbers:
 
     print(item)
 
     print(item)
 
</source>
 
</source>
:#Now instead of running functions over and over, from our previous sections, we can put them in a loop. The next sequence of code will apply a function to every item in the list.<source>
+
:#As you can see: instead of writing eight function calls for each element of the list, we can call the function in a loop. And we won't have to rewrite code if the length of the list changes.<br><br>
 +
:#Run the following code:<source lang="python">
 
list_of_numbers = [ 1, 5, 2, 6, 8, 5, 10, 2 ]
 
list_of_numbers = [ 1, 5, 2, 6, 8, 5, 10, 2 ]
 +
 
def square(num):
 
def square(num):
 
     return num * num
 
     return num * num
  
 
for value in list_of_numbers:
 
for value in list_of_numbers:
     square(value)
+
     print(square(value))
 
      
 
      
</source>
+
</source>The code above only prints the squares and does not save them for future use. The next example uses a function that loops through list, squares the values, and also saves the squares in a new list.<br><br>
:#But this only prints out each new value. Lets try making a new function that loops through lists, squares the values, and returns a new list.<source>
+
:#Run the following code:<source lang="python">
 
list_of_numbers = [ 1, 5, 2, 6, 8, 5, 10, 2 ]
 
list_of_numbers = [ 1, 5, 2, 6, 8, 5, 10, 2 ]
  
Line 587: Line 574:
  
 
new_list_of_numbers = square_list(list_of_numbers)
 
new_list_of_numbers = square_list(list_of_numbers)
new_list_of_numbers
+
print(list_of_numbers)
</source>
+
print(new_list_of_numbers)
:#The above is just one example of quick, powerful, for loops mixed with lists. But be careful when passing lists into functions. When you give a function a list, it is the actual list reference and NOT a copy. This means a function can completely change the list without making a new list. While you do have to be careful this is also useful, a function can modify any given list, without have to return or store it.<source>
+
</source>The above is just one example of a quick use of for loops mixed with lists. But be careful when passing lists into functions. When you give a function a list as an argument, it is the actual list reference and NOT a copy. This means a function can change the list without making a new list. While you do have to be careful, this can also be useful. A function can modify any given list ''without'' have to return it.<br><br>
 +
:#To demonstrate, run the following code:<source lang="python">
 
list_of_numbers = [ 1, 5, 2, 6, 8, 5, 10, 2 ]
 
list_of_numbers = [ 1, 5, 2, 6, 8, 5, 10, 2 ]
 
def delete_numbers(numbers):
 
def delete_numbers(numbers):
Line 597: Line 585:
 
     numbers.remove(5)
 
     numbers.remove(5)
 
delete_numbers(list_of_numbers)
 
delete_numbers(list_of_numbers)
list_of_numbers
+
print(list_of_numbers)
 
</source>
 
</source>
  
 +
'''Practice Functions, Lists, Loops'''
  
'''Practice Functions, Lists, Loops'''
 
 
:'''Perform the Following Instructions:'''
 
:'''Perform the Following Instructions:'''
:#Create the '''~/ops435/lab3/lab3f.py''' script. The purpose of this script is to use functions to modify items inside a list. <source>
 
# Place my_list here
 
  
def add_item_to_list(my_list):
+
:#Create the '''~/ops435/lab3/lab3f.py''' script. The purpose of this script is to use functions to modify items inside a list. <source lang="python">
    # Appends new item to end of list which is the (last item + 1)
+
#!/usr/bin/env python3
  
def remove_items_from_list(my_list, items_to_remove):
+
# Place my_list below this comment (before the function definitions)
 +
 
 +
 
 +
 
 +
def add_item_to_list(ordered_list):
 +
    # Appends new item to end of list with the value (last item + 1)
 +
 
 +
def remove_items_from_list(ordered_list, items_to_remove):
 
     # Removes all values, found in items_to_remove list, from my_list
 
     # Removes all values, found in items_to_remove list, from my_list
  
 +
# Main code
 
if __name__ == '__main__':
 
if __name__ == '__main__':
 
     print(my_list)
 
     print(my_list)
Line 620: Line 614:
 
     remove_items_from_list(my_list, [1,5,6])
 
     remove_items_from_list(my_list, [1,5,6])
 
     print(my_list)
 
     print(my_list)
 +
</source>
  
 +
'''Additional Requirements'''
  
</source>
+
:::*The missing list  should have the values: '''1, 2, 3, 4, 5'''
 +
:::*The program should have a function called '''add_item_to_list(ordered_list)'''<dd><dl>This function takes a single argument which is a list name itself. It will then look at the value of the last existing item in the list, it will then append a new value that is one unit bigger (i.e. '''+1''' and modifying that same list without returning any value).</dl></dd>
 +
:::*The script should have a function called '''remove_items_from_list(ordered_list, items_to_remove)'''<dd><dl>This function takes two arguments: a list, and a list of numbers to remove from the list. This function will then check if those items exist within that list, and if they exist, then they will be removed. This function will modify the list without returning any value.</dl></dd>
  
:::*The script should have a '''Shebang line'''
+
:::'''Sample Run 1:'''<source>
:::*The list '''my_list''' should have the values: '''1, 2, 3, 4, 5'''
 
:::*The script should have a function called add_item_to_list(my_list)
 
:::*The script should have a function called remove_items_from_list(my_list, items_to_remove)
 
:::*The function add_item_to_list(my_list) takes a single argument which is a list. This function will look at the value of the last item in the list, it will then append a new value that is +1 bigger then the previous number. This function modifies the list without returning any value
 
:::*The function remove_items_from_list(my_list, list_of_numbers_to_remove) takes two arguments, a list, and a list of numbers to remove from the list. This function will then check if those items are in the list, if they are it will remove them. This function modifies the list without returning any value.
 
:::2. Sample Run 1:<source>
 
 
run lab3f.py
 
run lab3f.py
 
[1, 2, 3, 4, 5]
 
[1, 2, 3, 4, 5]
Line 636: Line 628:
 
[2, 3, 4, 7, 8]
 
[2, 3, 4, 7, 8]
 
</source>
 
</source>
:::3. Sample Import 1:<source>
 
from lab3f import *                                                                                                                                                            [1/1899]
 
 
my_list
 
[1, 2, 3, 4, 5]
 
  
 +
:::'''Sample Run 2 (with import):'''<source>
 +
from lab3f import *                                                                                                                                                            print(my_list)
 +
# Will print [1, 2, 3, 4, 5]
 
add_item_to_list(my_list)
 
add_item_to_list(my_list)
 
add_item_to_list(my_list)
 
add_item_to_list(my_list)
 
add_item_to_list(my_list)
 
add_item_to_list(my_list)
 
+
print(my_list)
my_list
+
# Will print [1, 2, 3, 4, 5, 6, 7, 8]
[1, 2, 3, 4, 5, 6, 7, 8]
 
 
 
 
remove_items_from_list(my_list, [1,5,6])
 
remove_items_from_list(my_list, [1,5,6])
 
+
print(my_list)
my_list
+
# Will print [2, 3, 4, 7, 8]
[2, 3, 4, 7, 8]
 
 
</source>
 
</source>
:::4. Exit the ipython3 shell, download the checking script and check your work. Enter the following commands from the bash shell.<source>
+
:::2. Download the checking script and check your work. Enter the following commands from the bash shell.<source>
 
cd ~/ops435/lab3/
 
cd ~/ops435/lab3/
 
pwd #confirm that you are in the right directory
 
pwd #confirm that you are in the right directory
ls CheckLab3.py || wget matrix.senecac.on.ca/~acoatley-willis/CheckLab3.py
+
ls CheckLab3.py || wget https://raw.githubusercontent.com/Seneca-CDOT/ops435/master/LabCheckScripts/CheckLab3.py
 
python3 ./CheckLab3.py -f -v lab3f
 
python3 ./CheckLab3.py -f -v lab3f
 
</source>
 
</source>
:::5. Before proceeding, make certain that you identify any and all errors in lab3f.py. When the check script tells you everything is ok before proceeding to the next step.
+
:::3. Before proceeding, make certain that you identify any and all errors in lab3f.py. When the checking script tells you everything is OK - proceed to the next step.
  
 
= LAB 3 SIGN OFF (SHOW INSTRUCTOR) =
 
= LAB 3 SIGN OFF (SHOW INSTRUCTOR) =
Line 670: Line 657:
 
::<span style="color:green;font-size:1.5em;">&#x2713;</span> Output of: <code>./CheckLab3.py -f -v</code>
 
::<span style="color:green;font-size:1.5em;">&#x2713;</span> Output of: <code>./CheckLab3.py -f -v</code>
 
::<span style="color:green;font-size:1.5em;">&#x2713;</span> Output of: <code>cat lab3a.py lab3b.py lab3c.py lab3d.py lab3e.py lab3f.py</code>
 
::<span style="color:green;font-size:1.5em;">&#x2713;</span> Output of: <code>cat lab3a.py lab3b.py lab3c.py lab3d.py lab3e.py lab3f.py</code>
::<span style="color:green;font-size:1.5em;">&#x2713;</span> Lab3 logbook notes completed
+
 
 +
:'''Be able to answer any questions about the lab to show that you understood it!'''
 
<br><br>
 
<br><br>
  
= Practice For Quizzes, Tests, Midterm &amp; Final Exam =
+
= LAB REVIEW =
 +
 
 +
:# What is the purpose of using functions in a Python script?
 +
:# Write Python code to define a function called '''greetings()''' that when called will greet the user by name and on the next line display the current date
 +
:# Why is it useful for functions to accept '''arguments''' passed-up upon function execution?
 +
:# What is the purpose of the '''import''' command? What can be the consequence if the import command is not used prior to running a function by name?
 +
:# Write Python code to define a function called '''join()''' that excepts two arguments which will be be stored as the variables called '''word1''' and '''word2''' respectively during the execution of the function.
 +
:# What is the command to return a value from a function?
 +
:# What is the purpose of the '''system()''' function?
 +
:# What is the purpose of a '''list'''?
 +
:# Assume that the following list has been defined:  '''mylist = [ 'apple', 1, 'grape', 2, 'banana', 3, ]'''<br>Based on that, what will the following contain?<source lang="python">mylist[0]
 +
mylist[3]
 +
mylist[-1]
 +
mylist[0:1]</source>
 +
:# Assume that the following list has been defined: '''combined_list = [ [7, 5], ['x', 'y'], [ 5, 'f' ] ]'''<br>Based on that, what will the following contain?<source lang="python">
 +
combined_list[0]
 +
combined_list[1]
 +
combined_list[1][0]
 +
combined_list[2][0:2]</source>
 +
:# Briefly explain the purpose of each of the following functions (methods) that can be used with lists: '''append''', '''insert''', '''remove''', '''sort''', '''copy'''.</li>
 +
:# Write the '''functions''' that perform the following operations on a list:<ol type="a"><li>Returns the length of the list</li><li>Returns the smallest value in the list</li><li>Returns the largest value in the list</li></ol>
 +
:# Write a Python script to display all of the elements within a simple list.
  
:# x
+
[[Category:OPS435-Python]]
:# x
 
:# x
 

Latest revision as of 08:26, 21 January 2020

** DO NOT USE - TO BE UPDATED FOR CENTOS 8.0 **

LAB OBJECTIVES

In previous labs, you learned some programming tools in order to make your Python scripts more functional and allowed your Python script to run differently based on different data or situations. These tools included objects/variables, condition statements and loops. The utilization of these basic tools not only apply to Python scripts, but basically all programming languages including interpreted (including Perl scripts, Bash Shell scripts, JavaScript, etc ) and compiled languages (including C, C++, Java, etc).
In this lab, you will learn functions, lists, and loops, with the primary focus on creating reusable code.
Objectives
Write Python code in order to:
  • Create reusable functions that can be imported by other python scripts
  • Using and manipulating lists to allow for processing a large amount of data quickly
  • Looping through lists. Looping (iteration) is the ability for your program to repeatedly run the same code over and over. In this way, you can run a loop that contains a list to better send data to functions for better, more efficient execution of your Python script.



INVESTIGATION 1: CREATING THE SIMPLEST FUNCTIONS

A very simple definition of using functions is to create and reuse smaller programs within a larger program. In programming languages such as C, C++ and Java, commonly used functions are pre-packaged in libraries. This relates to dependency issues that were discussed when compiling C programming code in your OPS235 course: if a supporting library is missing, the program would not be able to run the called function.
Usually, a function will contain programming code in some part of the python file (most likely near the top of the file, before the main program). We refer to that as a "function declaration".
When a program is run, the function's code is read into internal memory, ready to be run when the function is executed (referred to as calling the function). Until a Function is specifically told to execute, its code will sit (in internal memory) unused.
When creating programs that define and use functions, a large programming task can be broken-down into smaller elements (or modules). This is why creating programs that use functions is referred to as "modular programming".

PART 1 - How User-Defined Functions are Declared and Run

Functions may be designed:
  • not to accept arguments or return a value,
  • to not accept arguments but return a value,
  • to accept arguments and not return a value,
  • or to both accept arguments and return a value.

In this investigation, we will focus on creating functions that either do NOT return a value, or return a value.

Functions and Strings

You will now learn how to define and run functions that will return string data when a function is called.
Perform the Following Steps:
  1. Create a new python file for testing code in this section.
  2. Whenever you want to create a function, you must start with the keyword "def". The def keyword is used to start the definition of the function, it does not run the code you write. Functions, just like if statements, must have all code under them indented.
    def hello():
        print('Hello World')
        print('Inside a Function')
  3. Executing your file you should have noticed that nothing happened. Well actually, something did happen... the function called hello() has been defined and stored in internal memory in order for it to run when called by its function name. Now that our function was created, we can use it over and over.
  4. To execute the code inside the function, run the function name with "()" brackets at the end of the function name.
    Try running the hello() function by name three times like this:
    hello()
    hello()
    hello()
    You should notice that the function just does the same thing over-and-over no matter how many times your call the function by name. By the way, that is OK. On the other hand, you may want to create and use a function to do something, like perform error checking or some other task that returns a value to the main program for further processing. For example, a true or false value if the error checking function that was called was detected no errors or detected an error. But let's stick to some simple examples first, before tackling more complex use of functions.

  5. Let's create a function that returns some data after the function is called. This function does not print out any text: instead; it creates new variables and at the end returns the value of one of the variables.
    def return_text_value():
        name = 'Terry'
        greeting = 'Good Morning ' + name 
        return greeting
  6. Call the function like this:
    return_text_value()
    One major difference between a function returning a value and simply printing a value is that returned values can be caught and stored in variables used in the program (that called the function) for later use. Once the returned value has been stored, it can be printed, manipulated, compared in IF statements, etc. Below will cover how to store a returned value.

  7. Notice that this syntax looks just the call to the input() function which you've used in the last lab:
    text = return_text_value()
  8. Now the returned text from the function has been stored in the variable "text". It can be used like any string value now.
    print(text)

Functions and Numbers (Integers)

You will now learn how to define and run functions that will return integer data when a function is called. In this section, you will define a function that will be returning integer values instead of text. There is not a big difference, but when returning number values, care needs to be taken if you try combining it with a string!
Perform the Following steps:
  1. Define the return_number_value() function:
    def return_number_value():
        num1 = 10
        num2 = 5
        num3 = num1 + num2
        return num3
  2. And call it:
    number = return_number_value()
    print(number)
    print(number + 5)
    print(return_number_value() + 10)
    What do you notice?

  3. Now, display both strings and numbers:
    number = return_number_value()
    print('my number is ' + number)
    What do you notice? You should notice a warning message. This occurs because the returning value is a number and NOT a string! Combining numbers and strings in a statement (such as print()) can cause errors. The error message should appear similar to the one displayed below:
    Traceback (most recent call last):
      File "test.py", line 2, in <module>
        print('my number is ' + number)
    TypeError: cannot concatenate 'str' and 'int' objects
  4. If a number needs to be combined with a string, use the str() predefined function that was discussed in a previous lab in order to convert the returned number into a string:
    number = return_number_value()
    print('my number is ', number)
    print('my number is ' + str(number))
    print('my number is ' + str(return_number_value()))

PART 2 - Creating a Python Script with Functions and Importing Functions

Creating a Python Script

Now it's time to create a Python script that uses two functions. One function returns a string value to greet the user, where the other function returns the result of adding two values (stored in variables within the function).
Perform the following Instructions:
  1. Create a new script ~/ops435/lab3/lab3a.py
Input / Output Requirements
  • The script should have a Shebang line
  • Below the Shebang line, add an empty line followed by a comment stating: # return_text_value() function
  • Add an empty line followed by the return_text_value() function definition that you previously entered in the shell.
  • Add another empty line followed by a comment stating: # return_number_value() function
  • Add another empty line following by the return_number_value() function definition that you previously entered in the shell.
  • Add a couple of empty lines, following by a comment stating: # Main Program
  • Add another couple of empty lines, followed by the statements displayed below:
    if __name__ == '__main__':
        print('python code')
        text = return_text_value()
        print(text)
        number = return_number_value()
        print(str(number))
Running your program you should have seen three lines being displayed: the text "python code", a greeting, and a result of a math calculation. The if statement in the code above is a special if statement needed to make sure that your "main" code only runs when you want it to. More on that later.

Importing Functions From other Python Scripts

In order to use functions from other scripts, you use the import statement.

  1. Let's see what happens if we forget to import functions from your lab3a.py script prior to calling a function. Create a new python file and try to call the return_text_value() function:
    text = lab3a.return_text_value()
    You should notice an error indicating "name 'lab3a' is not defined". This error occurs since you failed to instruct python to import or "load existing defined functions from your lab3a.py script" to internal memory.

  2. Modify your program like this:
    import lab3a
    text = lab3a.return_text_value()
    print(text)
    lab3a.return_number_value()
    You should notice that all of the function calls should now work.
  3. Download the checking script and check your work. Enter the following commands from the bash shell.
    cd ~/ops435/lab3/
    pwd #confirm that you are in the right directory
    ls CheckLab3.py || wget https://raw.githubusercontent.com/Seneca-CDOT/ops435/master/LabCheckScripts/CheckLab3.py
    python3 ./CheckLab3.py -f -v lab3a
  4. Before proceeding, make certain that you identify any and all errors in lab3a.py. When the checking script tells you everything is OK before proceeding to the next step.



INVESTIGATION 2: CREATING FUNCTIONS WITH ARGUMENTS AND RETURN VALUES

PART 1 - Providing Functions With Arguments

Functions can receive arguments - data to be used for processing. In this section, you will learn how to define functions that accept arguments and learn how to call functions with arguments (such as mathematical operations or testing conditions, which is useful for error-checking).

Passing up Single and Multiple Arguments to a Function

Perform the Following Steps:
  1. Create a new Python file for testing.
  2. When passing arguments to functions, you put data such as strings, numbers, or variable names within brackets immediately following the function name.

    NOTE: If a function accepts arguments, then those arguments must be declared (using variable names) when the function is declared. Those declared variable names are then used within the function for processing. Also, when you call a function with arguments, the number of arguments passed up to the function must match the number of arguments that were specified in the function declaration.

  3. Define a function called square():
    def square(number):
        return number ** 2
    FYI:You may have learned that you multiple a number by itself in order to "square" the number. In python, the ** operator will raise the operand on the left to the power of the operand on the right.

    When calling functions with multiple arguments, the arguments are separated by commas. See what happens if you provide strings, strings without using quotes, or numbers with decimals in the following examples.
  4. Test your square() function:
    square(5)
    square(10)
    square(12)
    square(square(2))
    square('2')
    Notice that nothing is printed, you need to print the values the functions return to see what they are.
  5. The last function call should produce an error message. This is caused by sending a string instead of a number that is processed by the function. We could use the int() function to convert any value passed in as a string by mistake to an integer number.

  6. Declare the function sum_numbers():
    def sum_numbers(number1, number2):
        return int(number1) + int(number2)
  7. Call that function to see what happens:
    sum_numbers(5, 10)
    sum_numbers(50, 100)
  8. You can also do what looks like calling a function within another function, but it's actually just calling sum_numbers() first, then calling square() with the return from sum_numbers as an argument:
    square(sum_numbers(5, 5))
    NOTE: Running functions with multiple arguments is the same. When call a function as an argument of another function, the inner-most function will run first, and the return the value from that will be used as the argument for the outer function. In the example below, sum_numbers(5, 5) will return 10, thus providing that result to be square with that value square(10).

Practice Creating a Function that Accepts Arguments and Returns a Value

It is time to practice creating a shell script that uses a function that accepts arguments, and returns a value.
Perform the Following Instructions:
  1. Create a new script ~/ops435/lab3/lab3b.py. Refer to the Python Script template and the Additional Requirements sections when creating your Python script. Refer to Sample Run and Sample Imports displayed below for exact prompt and output
Python Script Template
#!/usr/bin/env python3

def sum_numbers(number1, number2):
    # Make this function add number1 and number2 and return the value

def subtract_numbers(number1, number2):
    # Make this function subtract number1 and number2 and return the value
    # Remember to make sure the function accepts 2 arguments

def multiply_numbers(number1, number2):
    # Make this function multiply number1 and number2 and return the value
    # Remember to make sure the function accepts 2 arguments

if __name__ == '__main__':
    print(sum_numbers(10, 5))
    print(subtract_numbers(10, 5))
    print(multiply_numbers(10, 5))
Additional Requirements
  • All functions should accept two arguments
  • All functions should return an integer
  • The script should contain no errors
Sample Run:
./lab3b.py
15
5
50
Other examples:
import lab3b

lab3b.sum_numbers(10, 5)
# Will return 15
lab3b.sum_numbers(25, 25)
# Will return 50
lab3b.subtract_numbers(10, 5)
# Will return 5
lab3b.subtract_numbers(5, 10)
# Will return -5
lab3b.multiply_numbers(10, 5)
# Will return 50
lab3b.multiply_numbers(10, 2)
# Will return 20
2. Download the checking script and check your work. Enter the following commands from the bash shell.
cd ~/ops435/lab3/
pwd #confirm that you are in the right directory
ls CheckLab3.py || wget https://raw.githubusercontent.com/Seneca-CDOT/ops435/master/LabCheckScripts/CheckLab3.py
python3 ./CheckLab3.py -f -v lab3b
3. Before proceeding, make certain that you identify any and all errors in lab3b.py. When the checking script tells you everything is OK - proceed to the next step.

Passing up Multiple Arguments and Using Conditional Statements

You will now create a more complex function that will not only pass arguments, but also include logic to control the flow of the function, and affect how your Python script will be run. You will create a function that uses an if/elif/else statement.
Perform the Following Steps:
  1. Use a temporary Python file to define the following function:
    def describe_temperature(temp):
        if temp > 30:
            return 'hot'
        elif temp < 0:
            return 'cold'
        elif temp == 20:
            return 'perfect'
        return 'ok'
    The final return "ok" will only take place if a previous return has not taken place before it. Once return has been used in a function, the function immediately exits and returns the value.
  2. Call describe_temperature like this to confirm the results:
    print(describe_temperature(50))
    # Will return 'hot'
    print(describe_temperature(20))
    # Will return 'perfect'
    print(describe_temperature(-50))
    # Will return 'cold'
    print(describe_temperature(25))
    # Will return 'ok'
    print(describe_temperature(10))
    # Will return 'ok'

Create a Python Script Receiving Multiple Arguments

Perform the Following Instructions:
  1. Create the ~/ops435/lab3/lab3c.py script. The purpose of the script is to have a single function that can perform addition, subtraction, or multiplication on a pair of numbers. But the function will allow us to choose exatly what operation we are performing on it when we call it. If the operate function does NOT understand the operator given, it should return an error message (e.g. calling the function to 'divide' two numbers).
  2. Use this template to get started:
    #!/usr/bin/env python3
    
    def operate(number1, number2, operator):
        # Place logic in this function
    
    if __name__ == '__main__':
        print(operate(10, 5, 'add'))
        print(operate(10, 5, 'subtract'))
        print(operate(10, 5, 'multiply'))
        print(operate(10, 5, 'divide'))
  • The operate() function should use conditional statements
      FYI: Remember that you MUST consistently indent ALL code for within each section (or test).
  • The operate() function should accept three arguments.
  • The operate() function should return the result.
  • The operate() function should return an error message if the operation is unknown
      FYI: Use single quotes or double-quotes to pass a string value.
  • The script should contain show the exact output as the sample.
  • The script should contain no errors.
  • As an extra exercise, try to write your function with only one return statement.
Sample Run 1:
./lab3c.py
15
5
50
Error: function operator can be "add", "subtract", or "multiply"
Sample Run 2 (using import from another Python file):
import lab3c
lab3c.operate(10, 20, 'add')
# Will return 30
lab3c.operate(2, 3, 'add')
# Will return 5
lab3c.operate(100, 5, 'subtract')
# Will return 95
lab3c.operate(10, 20, 'subtract')
# Will return -10
lab3c.operate(5, 5, 'multiply')
# Will return 25
lab3c.operate(10, 100, 'multiply')
# Will return 1000
lab3c.operate(100, 5, 'divide')
# Will return Error: function operator can be "add", "subtract", or "multiply"
lab3c.operate(100, 5, 'power')
# Will return Error: function operator can be "add", "subtract", or "multiply"
3. Download the checking script and check your work. Enter the following commands from the bash shell.
cd ~/ops435/lab3/
pwd #confirm that you are in the right directory
ls CheckLab3.py || wget https://raw.githubusercontent.com/Seneca-CDOT/ops435/master/LabCheckScripts/CheckLab3.py
python3 ./CheckLab3.py -f -v lab3c
4. Before proceeding, make certain that you identify any and all errors in lab3c.py. When the checking script tells you everything is OK - proceed to the next step.



PART 2 - Running System Commands with Subprocess

The remainder of this investigation will allow you to run operating system commands via your Python script. Although there are different ways in which to issue operating system commands, you will learn two of them.

Perform the Following Steps:

  1. Create a new python file for testing.
  2. Import the os module in your python file.
  3. You can issue operating system commands by using the system() function. Try it:
    os.system('ls')
    os.system('whoami')
    os.system('ifconfig')
    Notice that the output from the programs is printed in your script. Consider that may not always be what you want.

  4. Try this also:
    os.system('ipconfig')
    You should notice an error message: 'ipconfig: command not found'. That error occurs since that command was an MS Windows command, and our current platform is Linux.

    It is not always a good idea to run system commands in Python, this makes your Python code less portable and makes it require a specific operating system or a system that has those commands available. You should think about that when you decide whether you should or should not use a system command to accomplish some task or stick to pure Python code only.

    As you may recall from lab2, you issued import sys to import special variables from the system. You can import a subprocess in order to run common non OS specific commands securely.

  5. Import the subprocess module in your python file.
  6. There are many features available as part of the subprocess module, we are interested in "Popen". This method subprocess.Popen() can be used to run system commands as a child process to the Python script. The code below output will create a new child process, in Python we can control this through the new Python object we just created, "p". "p" now has a collection of methods(functions that are apart of a object) available.

  7. To demonstrate, issue the following:
    p = subprocess.Popen(['date'], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    This function call and the following step is full of details we haven't yet talked about which is why it may look a little scary. By the time we're finished with the course - you will be able to look at code like this and not be intimidated. If you're curious and want to look ahead - you can find the definition for the Popen function in the Python reference manual.
  8. This next step is going to communicate with the process and get the retrieve it's output (stdout).
    output = p.communicate()
    print(output)
    print(output[0])
    # The above stdout is stored in bytes
    # Convert stdout to a string and strip off the newline characters
    stdout = output[0].decode('utf-8').strip()
    print(stdout)
  9. Sometimes you will be able to use purely python code to get your job done, but often you will need to call existing system commands. It's important to learn how to call them and how to interact with those external processes.

Practice Running System Commands From Python

Perform the Following Instructions:
  1. Create the "~/ops435/lab3/lab3d.py" script. The purpose of this script is to create a Python function that can return the linux system's root directory free space.
    • The script should import the correct module
    • The script should use the linux command: df -h | grep '/$' | awk '{print $4}'
    • The script should contain the function called: free_space()
    • The function free_space() should return a string which is in utf-8 and has newline characters strip
    • Note: your output may be completely different, the free/available disk space on every computers root directory may be different.
    Sample Run 1:
    ./lab3d.py
    9.6G
    Sample Run 2 (using import from another Python file):
    import lab3d
    lab3d.free_space()
    # Will return 9.6G
  2. Download the checking script and check your work. Enter the following commands from the bash shell.
    cd ~/ops435/lab3/
    pwd #confirm that you are in the right directory
    ls CheckLab3.py || wget https://raw.githubusercontent.com/Seneca-CDOT/ops435/master/LabCheckScripts/CheckLab3.py
    python3 ./CheckLab3.py -f -v lab3d
  3. Before proceeding, make certain that you identify any and all errors in lab3d.py. When the checking script tells you everything is OK - proceed to the next step.

INVESTIGATION 3: USING LISTS

Lists are one of the most powerful data-types in Python. A list is a series of comma separated values found between square brackets. Values in a list can be anything: strings, integers, objects, even other lists. In this section, you will introduce lists and how to use them effectively, you will further user lists in later labs. It is important to realise that although lists may appear very similar to arrays in other languages, they are different in a number of aspects including the fact that they don't have a fixed size.

PART 1 - Navigating Items in Lists

Perform the Following Steps
  1. Create a new Python file for testing things in this section.
  2. Create a few lists with different values: list1 contains only integers, list2 contains only strings, list3 contains a combination of both integers and strings
  3. list1 = [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
    list2 = [ 'uli101', 'ops235', 'ops335', 'ops435', 'ops535', 'ops635' ]
    list3 = [ 'uli101', 1, 'ops235', 2, 'ops335', 3, 'ops435', 4, 'ops535', 5, 'ops635', 6 ]
    The best way to access individual elements in a list is using the list index.
    The index is a number starting from 0 to (number_of_items - 1), the list index starts counting at 0.

  4. Inspect specified elements in your lists:
    print(list1[0])  # First element in list1
    print(list2[1])  # Second element in list2
    print(list3[-1]) # Last element in list3
  5. You can also retrieve ranges of items from a list (these are called slices):
    print(list1[0:5]) # Starting with index 0 and stopping before index 5
    print(list2[2:4]) # Starting with index 2 and stopping before index 4
    print(list3[3:])  # Starting with index 3 and going to the end

Practice Using Functions and Using the List Index

Perform the Following Instructions
  1. Create a Python script called: ~/ops435/lab3/lab3e.py
    The purpose of this script is to have a number of functions that output a different data storage in various elements of a list. Each function will return either a single item from the list OR will create a new list and return the entire new list.

  2. The template function names and the special if statement:
    #!/usr/bin/env python3
    
    # Create the list called "my_list" here, not within any function defined below.
    # That makes it a global variable. We'll talk about that in another lab.
    
    
    def give_list():
        # Does not accept any arguments
        # Returns all of the global variable my_list unchanged
    
    def give_first_item():
        # Does not accept any arguments
        # Returns a single string that is the first item in the global my_list
    
    def give_first_and_last_item():
        # Does not accept any arguments
        # Returns a list that includes the first and last items in the global my_list
    
    def give_second_and_third_item():
        # Does not accept any arguments
        # Returns a list that includes the second and third items in the global my_list
    
    if __name__ == '__main__':   # This section also referred to as a "main code"
        print(give_list())
        print(give_first_item())
        print(give_first_and_last_item())
        print(give_second_and_third_item())
Additional Requirements
  • The script should declare a list called my_list created BEFORE any function definition
  • The list called my_list should have the values: 100, 200, 300, and 'six hundred'
  • The script should implement the empty functions - i.e. you have to fill in the bodies for these functions
Sample Run 1:
./ lab3e.py
[100, 200, 300, 'six hundred']
100
[100, 'six hundred']
[200, 300]
Sample Run 2 (with import from another script):
import lab3e
lab3e.give_list()
# Will print [100, 200, 300, 'six hundred']
lab3e.give_first_item()
# Will print 100
lab3e.give_first_and_last_item()
# Will print [100, 'six hundred']
lab3e.give_second_and_third_item()
# Will print [200, 300]
3. Download the checking script and check your work. Enter the following commands from the bash shell.
cd ~/ops435/lab3/
pwd #confirm that you are in the right directory
ls CheckLab3.py || wget https://raw.githubusercontent.com/Seneca-CDOT/ops435/master/LabCheckScripts/CheckLab3.py
python3 ./CheckLab3.py -f -v lab3e
4. Before proceeding, make certain that you identify any and all errors in lab3e.py. When the checking script tells you everything is OK - proceed to the next step.

PART 2 - Manipulating Items in Lists

There are a number of ways to obtain information about lists as well as change the data that is contained within a list. In this section, you will learn how to manipulate lists.
Perform the Following Steps:
  1. Let's perform a simple change to a list element. Try the following code:
    courses = [ 'uli101', 'ops235', 'ops335', 'ops435', 'ops535', 'ops635' ]
    print(courses[0])
    courses[0] = 'eac150'
    print(courses[0])
    print(courses)
  2. Below are some examples of using built-in functions to manipulate lists. Take your time to see how each function can be a useful tool for making changes to existing lists:
    courses.append('ops235')    # Add a new item to the end of the list
    print(courses)
    
    courses.insert(0, 'hwd101') # Add a new item to the specified index location
    print(courses)
    
    courses.remove('ops335')    # Remove first occurrence of value
    print(courses)
    
    sorted_courses = courses.copy() # Create a copy of the courses list
    sorted_courses.sort()           # Sort the new list
    print(courses)
    print(sorted_courses)
  3. In addition to using functions to manipulate lists, there are functions that are useful to provide information regarding the list such as number of elements in a list, the smallest value and largest value in a list:
    list_of_numbers = [ 1, 5, 2, 6, 8, 5, 10, 2 ]
    length_of_list = len(list_of_numbers)    # Returns the length of the list
    smallest_in_list = min(list_of_numbers)  # Returns the smallest value in the list
    largest_in_list = max(list_of_numbers)   # Returns the largest value in the list
    
    # Notice how the long line below is wrapped to fit on one screen:
    print("List length is " + str(length_of_list) + 
          ", smallest element in the list is " + str(smallest_in_list) +
          ", largest element in the list is " + str(largest_in_list))

PART 3 - Iterating Over Lists

This last section demonstrates an extremely useful for lists: the ability to quickly loop through every value in the list. For loops have a set number of times they loop. The for loop will execute all indented code for each item (element) in the list.
Perform the Following Steps
The following for loop will store the value of each element from list_of_numbers within a variable named item and run code indented below the loop for each item.

  1. Run this from a temporary Python file:
    list_of_numbers = [ 1, 5, 2, 6, 8, 5, 10, 2 ]
    for item in list_of_numbers:
        print(item)
  2. As you can see: instead of writing eight function calls for each element of the list, we can call the function in a loop. And we won't have to rewrite code if the length of the list changes.

  3. Run the following code:
    list_of_numbers = [ 1, 5, 2, 6, 8, 5, 10, 2 ]
    
    def square(num):
        return num * num
    
    for value in list_of_numbers:
        print(square(value))
    The code above only prints the squares and does not save them for future use. The next example uses a function that loops through list, squares the values, and also saves the squares in a new list.

  4. Run the following code:
    list_of_numbers = [ 1, 5, 2, 6, 8, 5, 10, 2 ]
    
    # Squares each item in a list of numbers, returns new list with squared numbers
    def square_list(number_list):
        new_list = []
        for number in number_list:
            new_list.append(number * number)
        return new_list
    
    new_list_of_numbers = square_list(list_of_numbers)
    print(list_of_numbers)
    print(new_list_of_numbers)
    The above is just one example of a quick use of for loops mixed with lists. But be careful when passing lists into functions. When you give a function a list as an argument, it is the actual list reference and NOT a copy. This means a function can change the list without making a new list. While you do have to be careful, this can also be useful. A function can modify any given list without have to return it.

  5. To demonstrate, run the following code:
    list_of_numbers = [ 1, 5, 2, 6, 8, 5, 10, 2 ]
    def delete_numbers(numbers):
        numbers.remove(5)
        numbers.remove(6)
        numbers.remove(8)
        numbers.remove(5)
    delete_numbers(list_of_numbers)
    print(list_of_numbers)

Practice Functions, Lists, Loops

Perform the Following Instructions:
  1. Create the ~/ops435/lab3/lab3f.py script. The purpose of this script is to use functions to modify items inside a list.
    #!/usr/bin/env python3
    
    # Place my_list below this comment (before the function definitions)
    
    
    
    def add_item_to_list(ordered_list):
        # Appends new item to end of list with the value (last item + 1)
    
    def remove_items_from_list(ordered_list, items_to_remove):
        # Removes all values, found in items_to_remove list, from my_list
    
    # Main code
    if __name__ == '__main__':
        print(my_list)
        add_item_to_list(my_list)
        add_item_to_list(my_list)
        add_item_to_list(my_list)
        print(my_list)
        remove_items_from_list(my_list, [1,5,6])
        print(my_list)

Additional Requirements

  • The missing list should have the values: 1, 2, 3, 4, 5
  • The program should have a function called add_item_to_list(ordered_list)
    This function takes a single argument which is a list name itself. It will then look at the value of the last existing item in the list, it will then append a new value that is one unit bigger (i.e. +1 and modifying that same list without returning any value).
  • The script should have a function called remove_items_from_list(ordered_list, items_to_remove)
    This function takes two arguments: a list, and a list of numbers to remove from the list. This function will then check if those items exist within that list, and if they exist, then they will be removed. This function will modify the list without returning any value.
Sample Run 1:
run lab3f.py
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5, 6, 7, 8]
[2, 3, 4, 7, 8]
Sample Run 2 (with import):
from lab3f import *                                                                                                                                                            print(my_list)
# Will print [1, 2, 3, 4, 5]
add_item_to_list(my_list)
add_item_to_list(my_list)
add_item_to_list(my_list)
print(my_list)
# Will print [1, 2, 3, 4, 5, 6, 7, 8]
remove_items_from_list(my_list, [1,5,6])
print(my_list)
# Will print [2, 3, 4, 7, 8]
2. Download the checking script and check your work. Enter the following commands from the bash shell.
cd ~/ops435/lab3/
pwd #confirm that you are in the right directory
ls CheckLab3.py || wget https://raw.githubusercontent.com/Seneca-CDOT/ops435/master/LabCheckScripts/CheckLab3.py
python3 ./CheckLab3.py -f -v lab3f
3. Before proceeding, make certain that you identify any and all errors in lab3f.py. When the checking script tells you everything is OK - proceed to the next step.

LAB 3 SIGN OFF (SHOW INSTRUCTOR)

Students should be prepared with all required commands (system information) displayed in a terminal (or multiple terminals) prior to calling the instructor for signoff.


Have Ready to Show Your Instructor:
Output of: ./CheckLab3.py -f -v
Output of: cat lab3a.py lab3b.py lab3c.py lab3d.py lab3e.py lab3f.py
Be able to answer any questions about the lab to show that you understood it!



LAB REVIEW

  1. What is the purpose of using functions in a Python script?
  2. Write Python code to define a function called greetings() that when called will greet the user by name and on the next line display the current date
  3. Why is it useful for functions to accept arguments passed-up upon function execution?
  4. What is the purpose of the import command? What can be the consequence if the import command is not used prior to running a function by name?
  5. Write Python code to define a function called join() that excepts two arguments which will be be stored as the variables called word1 and word2 respectively during the execution of the function.
  6. What is the command to return a value from a function?
  7. What is the purpose of the system() function?
  8. What is the purpose of a list?
  9. Assume that the following list has been defined: mylist = [ 'apple', 1, 'grape', 2, 'banana', 3, ]
    Based on that, what will the following contain?
    mylist[0]
    mylist[3]
    mylist[-1]
    mylist[0:1]
  10. Assume that the following list has been defined: combined_list = [ [7, 5], ['x', 'y'], [ 5, 'f' ] ]
    Based on that, what will the following contain?
    combined_list[0]
    combined_list[1]
    combined_list[1][0]
    combined_list[2][0:2]
  11. Briefly explain the purpose of each of the following functions (methods) that can be used with lists: append, insert, remove, sort, copy.</li>
  12. Write the functions that perform the following operations on a list:
    1. Returns the length of the list
    2. Returns the smallest value in the list
    3. Returns the largest value in the list
  13. Write a Python script to display all of the elements within a simple list.