Lecture 18 Importing Classes, Functions. (plus some miscellaneous Python interview questions)

1. Naming variables and classes conventions

With Pascal Case, the first letter of every word in the identifier is upper case (called Proper case), the rest lower case and merged without space, thus FirstName='Jack'.

With Camel Case, the first letter of the first word in the identifier is lower case, and all subsequent words use proper case, thus firstName='Jack'.

This is not a rule but people usually use Camel Case for variables and use Pascal Case for Classes.

So please be used to use Camel Case in the future if you are not.

I love using the Camel Case, it looks very Humble unoffensive, isn't it? :-))

2. Import files, classes, variables, and functions

If you have modules of .py files, classes, and functions, you can import them in your main function:



I have my main.py and the subFunction.py in the same directory. Now I'll try to call the class and functions in the subFunction.py file in my main.py file.

In the subFunction file, I have class 'Person' defined and a couple of methods come with it.



In the main function, I can import the class 'Person' from the file subFunction.py.



The results after run the main.py function:


Still remember when we used the 'math' package when we are trying to use 'pi'. There are two equivalent options:

Option 1. 'import math'  then  use  'math.pi'
Option 2. 'from math import pi'  then use  'pi' directly.

It is the same case here. If we only do 'import subFunction' then we have to use 'subFunction.Person' in your main function.



Please notice the differences between these two methods.

Of course, you can also import an independent function or a variable only:

Import variables from a file:
Step 1: Define them in your subFunction.py:


Step 2: Import one of them in your main.py file:


Import an independent function from a file:
Step 1: Define the function in your subFunction.py file:


Step 2: Import it from your main.py file:


The importing function is beneficial particularly when the code is very long and there are several methods or classes are in mudules. They should be put in different files to make your main function shorter and more readable.

3. Some Leftovers on Exception Handling

Exceptions are unexpected events that occur during the execution of a program. An exception might result from a logical error or an unanticipated situation. In Python, exceptions (also known as errors) are objects that are raised (or thrown) by code that encounters an unexpected circumstance. The Python interpreter can also raise an exception should it encounter an unexpected condition, like running out of memory. A raised error may be caught by a surrounding context that “handles” the exception in an appropriate fashion. If uncaught, an exception causes the interpreter to stop executing the program and to report an appropriate message to the console. In this section, we examine the most common error types in Python, the mechanism for catching and handling errors that have been raised, and the syntax for raising errors from within user-defined blocks of code.

Common Exception Types



3.1 Raising an Exception

You can directly raise an error message using the 'raise' function.



If you don't handle the exception in the code, you will see the default error message in the console.



You can handle it using the following method.



Same as the ValueError:



Handle it on your own:



Running without an error:



3.2 Catching an Exception

One philosophy for managing exceptional cases is to “look before you leap.” The goal is to entirely avoid the possibility of an exception being raised through the use of a proactive conditional test. Revisiting our division example, we might avoid the offending situation by writing:



A second philosophy, often embraced by Python programmers, is that “it is easier to ask for forgiveness than it is to get permission.” This quote is attributed to Grace Hopper, an early pioneer in computer science. The sentiment is that we need not spend extra execution time safeguarding against every possible exceptional case, as long as there is a mechanism for coping with a problem after it arises. In Python, this philosophy is implemented using a try-except control structure. Revising our first example, the division operation can be guarded as follows:



So just try it without checking anything and catch the exception only when it happens.
For this reason, the try-except clause is best used when there is reason to believe that the exceptional case is relatively unlikely, or when it is prohibitively expensive to proactively evaluate a condition to avoid the exception.

You can use a 'while loop' to let the user know there was an error catched and give the user more chances until the input type is valid.



4. Some Python Interview Questions

4.1. What is the difference between list and tuples?



Interesting and good to know. Why tuples are faster than lists:

In python lists comes under mutable objects and tuples comes under immutable objects. Tuples are stored in a single block of memory. Lists are allocated in two blocks: the fixed one with all the Python object information and a variable sized block for the data. It is the reason creating a tuple is faster than List.

4.2. What are the key features of Python?

* Python is an interpreted language. That means that, unlike languages like C and its variants, Python does not need to be compiled before it is run. Other interpreted languages include PHP and Ruby.
Interpreters and compilers are similar, since they both recognize and process source code. However, a compiler does not execute the code like and interpreter does. Instead, a compiler simply converts the source code into machine code, which can be run directly by the operating system as an executable program. Interpreters bypass the compilation process and execute the code directly.

An interpreted language is a high-level language run and executed by an interpreter (a program which converts the high-level language to machine code and then executing) on the go; it processes the program a little at a time. A compiled language is a high-level language whose code is first converted to machine-code by a compiler (a program which converts the high-level language to machine code) and then executed by an executor (another program for running the code).

* Python is dynamically typed, this means that you don’t need to state the types of variables when you declare them or anything like that. You can do things like x=111 and then x="I'm a string" without error

* Writing Python code is quick but running it is often slower than compiled languages. Fortunately,Python allows the inclusion of C based extensions so bottlenecks can be optimized away and often are. The numpy package is a good example of this, it’s really quite quick because a lot of the number crunching it does isn’t actually done by Python.
NumPy is mostly written in C. The main advantage of Python is that there are a number of ways of very easily extending your code with C (ctypes, swig,f2py) / C++.

* Python finds use in many spheres – web applications, automation, scientific modelling, big data applications and many more. It’s also often used as “glue” code to get other languages and components to play nice.

4.3. What is the difference between deep and shallow copy?

Shallow copy is used when a new instance type gets created and it keeps the values that are copied in the new instance. Shallow copy is used to copy the reference pointers just like it copies the values. These references point to the original objects and the changes made in any member of the class will also affect the original copy of it. Shallow copy allows faster execution of the program and it depends on the size of the data that is used. Deep copy is used to store the values that are already copied.

Deep copy doesn’t copy the reference pointers to the objects. It makes the reference to an object and the new object that is pointed by some other object gets stored. The changes made in the original copy won’t affect any other copy that uses the object. Deep copy makes execution of the program slower due to making certain copies for each object that is been called.

4.4. What is dictionary in Python?

The built-in datatypes in Python is called dictionary. It defines one-to-one relationship between keys and values. Dictionaries contain pair of keys and their corresponding values. Dictionaries are indexed by keys.

4.5. What does this mean: *args, **kwargs? And why would we use it?

We use *args when we aren’t sure how many arguments are going to be passed to a function, or if we want to pass a stored list or tuple of arguments to a function. **kwargsis used when we don’t know how many keyword arguments will be passed to a function, or it can be used to pass the values of a dictionary as keyword arguments. The identifiers args and kwargs are a convention, you could also use *bob and **billy but that would not be wise.

For example:



You must be wondering can we organize the data in a Tuple or in a List?

Yes you can.



Of course, you can also do this:



But not this:



Then, what about passing the data in a dictionary into a function? You can also do it, and you will need two asterisks (**), and usally we use **kwargs.

The double asterisk form of **kwargs is used to pass a keyworded, variable-length argument dictionary to a function. Again, the two asterisks (**) are the important element here, as the word kwargs is conventionally used, though not enforced by the language. Like *args, **kwargs can take however many arguments you would like to supply to it. However, **kwargs differs from *args in that you will need to assign keywords. First, let’s simply print out the **kwargs arguments that we pass to a function. We’ll create a short function to do this:



And please notice that the name of the keyword has to be consistent in this case. If you change the name of the keys, you have to keep them consistent in the function arguments and the inside the function.



4.6. Write a one-liner that will count the number of capital letters in a file

The regular form looks like this:



You can write it in a one-liner format:



It will be a little easier if you can be used to write the 'for loops' and the 'if statement' in the one-liner format.

How do you understand the POWERFUL ONE LINER for loops:
For example, you want to double the numbers in a list. Of course you can make an empty list, access to every item in the old list, double it, and then append it into the empty list.



However, you can use one line to replace the bulky script of the 'for loop' in the example above:



4.7. What are negative indexes and why are they used?

The sequences in Python are indexed and it consists of the positive as well as negative numbers. The numbers that are positive uses ‘0’ that is uses as first index and ‘1’ as the second index and the process goes on like that. The index for the negative number starts from ‘-1’ that represents the last index in the sequence and ‘-2’ as the penultimate index and the sequence carries forward like the positive number.

The negative index can be usd to remove the last element in your data when you don't know how long is the data.



4.8. How do you randomize items in a list

The method shuffle() randomizes the items of a list in place.



4.9. How do you sort the items (strings) in the following list: list = ["1", "4", "0", "6", "9"]

Method 1:


Method 2:


See the second method is more concise.

4.10. Looking at the below code, write down the final values of A0, A1, …An



Please do type these items in Spyder and verify if you are right.

What the 'sorted()' function does?




Tasks

1. Define your own Math package called 'mathCE232.py'. In this file, define these constants: newPi=3.15, newE=2.8, and newG=9.9. Use a main.py function to import these constants in the following three different ways:
a. import SOMETHING
b. import SOMETHING as SOMETHING (means rename the imported thing)
c. from SOMETHING import SOMETHING

Use these three methods separetely for the following calculation in your main.py:

pi*10**2, e^2, and 100*g.

2. Read through all sections in this tutorial.

3. Re-do the examples in sections: 2, 3.1,
4.5,  4.6,  4.10 in this tutorial above.