2. Python Language Fundamentals

About this Tutorial –

Objectives –

Python is a powerful and popular object-oriented scripting language. This course provides a comprehensive introduction to the core syntax and functions provided by Python, including full coverage of its object-oriented features. The course also explores some of Python’s powerful APIs and techniques, including file handling, XML processing, object serialization, and Web service

Audience

This training course is aimed at new developers and experienced developers

Prerequisites

No previous experience in Python programming is required. But any experience you do have in programming will help. Also no experience in IDLE is required. But again any experience you do have with programming development environments will be a valuable.

Contents

The python course covers these topics and more:

  • Strings and Regular Expressions: Overview of strings in Python; Basic string manipulation; Introduction to regular expressions
  • XML Processing: XML essentials; Parsing XML documents; Searching for XML content; Generating XML data
  • Web Services: Overview of Web services; Implementing Web services using Python; Caching; Compression; Handling redirects

Download Solutions

HTML tutorial


Overview

Estimated Time – 1 Hour

Not what you are looking? Try the next tutorial – Flow Control

Lab 1: Defining and using modules

Lab 1: Defining and using modules
  1. The Python Standard Library
    • Python defines an extensive and powerful standard library
      • Comprises a large number of modules
    • Built-in modules are implemented in C
      • Provide access to low-level system functionality
      • E.g. file I/O
    • Other modules are implemented in Python
      • See the Lib/modules folder in the Python installation folder
    • For full info, see:
      • https://docs.python.org/3.4/library/
  2. Understanding Modules
    • It’s easy to create new modules. Simply create a new Python script file, typically with a lowercase file name and the .py file extension.
      • The example below shows a very simple module named greetings.py, which just defines three variables. In reality, modules can define variables, functions, and classes
        morning = "Good morning"
        afternoon = "Good afternoon"
        evening = "Good evening"
    • To use a module in Python script, use the import keyword. There are several ways to do this:
      • import modulename – Imports the specified module. To use items from the module, you must use the module name as a qualifier. For example, if you import the greetings module, you can access items using syntax such as greetings.morning
        import greetings
        print(greetings.morning)
      • from modulename import name1, name2, etc … – Imports the specified names from the specified module. This causes the named items to be added into the global symbol table of the importing module, so these names can now be used unqualified. For example, if you import the morning and afternoon items from the greetings module, you can access these items directly via the names morning and afternoon
        from greetings import morning, afternoon
        print(morning + " " + afternoon)
      • from modulename import * – Imports all names from the specified module into the global symbol table of the importing module, so all these names can now be used unqualified. You should be careful using this, as it can easily cause name clashes when you import multiple modules.
        from greetings import *
        print(morning + " " + afternoon + " " + evening)
  3. More About Modules
    • You can use the __name__ property to get the name of the current module, or the name of a module you’ve imported
      • For example, when we run usegreetings.py below, it outputs the following:
        import greetings
        print("Name of current module is %s" % __name__)
        print("Name of greetings module is %s" % greetings.__name__)
        #Name of current module is __main__
        #Name of greetings module is greetings
    • If you try to import the same module several times in your code, Python will only actually import it once
      • This is because the module might contain raw code that is performed immediately the module is loaded (the greetings.py module does this).
      • Python ensures this code will only be executed once, the first time you import the module
      • If you really do want to reload a module (i.e. you want to re-run the module’s initialization code), you can call the reload() function as follows:
        reload(module_name)
    • Python looks in a prescribed sequence of locations in order to find Python modules:
      • The directory containing the input script (or the current directory)
      • The directory specified by PYTHONPATH
      • The installation-dependent default. For example, in Windows, this is the Lib/modules folder in the Python installation folder.
  4. Listing the Names in a Module
    • You can use the dir() built-in function to list all the names in a specified module. If you don’t supply a parameter, it returns all the names defined in the current module.
    • This example shows the names in the math module, plus all the names in the current module. In this example, note that the current module includes the names morning and afternoon, which we imported from the greetings module for illustration purposes.
      import math
      from greetings import morning, afternoon
      print("Names in the math module:")
      print(dir(math))
      print("\nNames in the current module:")
      print(dir())
    • T2P1

    • Note that dir() doesn’t list the names of built-in functions and variables. If you want a list of those, they are defined in the standard module __builtin__. You can list them as follows:
      import __builtin__
      dir(__builtin__)
Lab
  1. Using numeric types
    • Create a new module, and import the math module ready to do some mathematical calculations. Ask the user to enter the radius of the circle or sphere, r, as a floating point value. Then perform the following calculations:
      import math
      r = float(input("Enter radius: "))

      • The diameter of a circle (2r)
        diameter = 2 * r
      • The area of a circle (pr^2)
        circle_area = math.pi * r ** 2
        circumference = math.pi * diameter
      • The area of a sphere (4pr^2)
        sphere_area = 4 * math.pi * r ** 2
      • The volume of a sphere (4/3 pr^3)
        sphere_volume = (4/3) * math.pi * r ** 3
      • View Code File

    • Output the results nicely. Run the code several times with different values for the radius, to ensure you get the correct results
      print("Circle values: %g %g %g" % (diameter, circle_area, circumference))
      print("Sphere values: %g %g" % (sphere_area, sphere_volume))

Lab 2: Defining and using packages

Lab 2: Defining and using packages
  1. Overview of Packages
    • Packages are a way of structuring multiple related modules into a hierarchical folder structure.
      • Client code can then use “dotted module named” to access modules from a package.
      • In technical terms, a Python package is a folder that contains a special file named __init__.py
      • Note that this file can be empty; the mere existence of this file is enough to tell Python to treat the folder as a package.
      • You can also put initialization code in __init__.py, and we’ll show why this is useful shortly.
    • Consider the example below, and note the following points:
      • The utils folder has a file named __init__.py, so Python will treat utils as a package rather than as a regular folder.
      • The utils folder has a sub-folder named constants. This folder has an __init__.py file, so it’s a package too (we say that constants is a sub-package of utils). The constants package contains several module files, which the client code will be able to import as utils.constants.metric and utils.constants.physics.
      • The utils folder has another sub-folder named messages. This folder has an __init__.py file too, so it’s a package as well. The package contains several module files, which the client code can import as utils.messages.french and utils.messages.norwegian.
      • utils/           Top-level package, named utils.
          __init__.py      Initialize the utils package.
           
          constants/      Sub-package for constants.
            __init__.py    Initialize the constants package.
            metric.py
            physics.py
               ...
          messages/       Sub-package for messages.
            __init__.py    Initialize the messages package.
            french.py
            norwegian.py
               ...

  2. Example Modules
    • Here are the modules we’ve defined in the utils package
      • Modules in the utils.constants sub-package:
        # metric.py
        INCH_TO_CM = 25.4
        MILE_TO_KM = 1.61
        # physics.py
        ELECTRONIC_CHARGE = 1.602e-19
        PLANCKS_CONSTANT = 6.626e-34
      • Modules in the utils.messages sub-package:
        # french.py
        HELLO = "Bonjour"
        GOODBYE = "Au revoir"
        # norwegian.py
        HELLO = "Hei"
        GOODBYE = "Ha det bra"
  3. Importing Specific Modules
    • Client code can use dotted module name syntax to import modules from a package
      • You specify the name of the package, followed by a dot, followed by the name of the module you want to import.
      • If you have lots of nested packages, just step down the hierarchy using dots and sub-package names.
      • . Note that you can only apply a dot to a package name (i.e. a folder that has an __init__.py file in it).
    • Consider the examples:
      • In the first example, the import statement specifies the utils package, followed by the constants sub-package, followed by the metric module. You can then access names in that module by using fully qualified names, e.g. utils.constants.metric.INCH_TO_CM.
        import utils.constants.metric
        print("Inch to centimetre: %.4f" % utils.constants.metric.INCH_TO_CM)
        print("Mile to kilometre: %.4f" % utils.constants.metric.MILE_TO_KM)
      • The second example is similar, but it adds the metric module to the current symbol table. You can therefore use the metric module name directly, e.g. metric.INCH_TO_CM rather than having to qualify it with the package name, e.g. utils.constants.metric.INCH_TO_CM.
        from utils.constants import metric
        print("Inch to centimetre: %.4f" % metric.INCH_TO_CM)
        print("Mile to kilometre: %.4f" % metric.MILE_TO_KM)
      • The third example takes this a step further and actually imports specific names from the metric module into the current symbol table. You can therefore use names such as INCH_TO_CM directly, rather than having to qualify them e.g. utils.constants.metric.INCH_TO_CM.
        from utils.constants.metric import INCH_TO_CM, MILE_TO_KM
        print("Inch to centimetre: %.4f" % INCH_TO_CM)
        print("Mile to kilometre: %.4f" % MILE_TO_KM)
  4. Importing All Modules
    • The * wildcard character indicates you want to import all the modules from a package. However, Python won’t automatically import everything from the package, because this could potentially drag in a very large number of modules and cause general chaos in your code.
      from utils.messages import *
      print("Hello in French: %s" % utils.messages.french.HELLO)
      print("Goodbye in French: %s" % utils.messages.french.GOODBYE)
      print("Hello in Norwegian: %s" % utils.messages.norwegian.HELLO)
      print("Goodbye in Norwegian: %s" % utils.messages.norwegian.GOODBYE)
    • In order to tell Python which modules to import from a package, the package’s __init__.py file must define a global variable named __all__. This variable must specify a list of all the module names to be imported.
      Consider the example above:

      • The client code in useutils.py attempts to import everything from the utils.messages package.
      • The utils.messages package has an __init__.py file, which defines a global variable named __all__. This variable indicates that “all modules” for this package means “import the french and norwegian modules”.
      • The client code can use names from the utils.messages.french and utils.messages.norwegian modules.
        __all__ = ["french", "norwegian"]
Lab
  1. Using strings
    • Create a new module, and prompt the user to enter the following textual information:
      • Honorific, e.g. Mr. or Mrs
      • First name
      • Last name
        honorific = input("Honorific, e.g. Mr. or Mrs.: ")
        firstname = input("First name: ")
        lastname = input("Last name: ")
    • Create a variable to hold their name in the following format, and then output the value:
      • Honorific
      • A space character
      • First letter of their first name, in upper case
      • A period, followed by a space
      • Last name, ensuring that it starts with a uppercase letter and then all lowercase thereafter
        formattedName = "{0} {1}. {2}".format(honorific.title(),
                           firstname[0].upper(),
                           lastname.title())
      • View Code File

    • Output their name:
      print("Your name is %s" % formattedName)
    • Test this in Idle by pressing F5 or by clicking “Run” -> “Run Module”; once you are happy with this we can add some more functionality
    • Add some more code to ask the user to input their email address and (fictional!) 4-digit pin code. Get these values as strings, and then validate them as follows:
      • The e-mail address must contains an “@” character. The easiest way to test if a character is in a string is as follows (we’ve assumed your email address variable is named email):
        "@" in email
      • The pin code must be 4 characters long. The easiest way to test the length of a string and other sequences is via the built-in len() function (we’ve assumed your pin code variable is named pincode here):
        len(pincode) == 4
      • The pin code must contain just digits. Use the String class’s isdigit() method here:
        pincode.isdigit()
    • If everything is valid, output the details in lowercase. If anything is invalid, output an error. Use an if: else: construct here
    • Example code for this lab:
      email  = input("Email address: ")
      pincode = input("4-digit pin code (fictional): ")
      is_valid = "@" in email and len(pincode) == 4 and pincode.isdigit()
      if is_valid:
        print("Email address %s, pin code %s" % (email.lower(), pincode))
      else:
        print("Your details are valid")
    • View Code File

Lab 3: Basic data types

Lab 3: Basic data types
  1. Numbers
    • Python has just three numeric types:
      • Integers – these are whole numbers, with unlimited precision.
      • Floats – these are 32-bit floats, similar to the double data type in C.
      • Complex numbers – these contain a real and imaginary part. The imaginary part is denoted by a letter j after a number. The real and imaginary parts are both float types.
    • The example below shows various examples of how to create numeric values. Note the following points in particular:
      • The int(), float(), and complex() functions are constructors. They create a number of the appropriate type from a string. The int() function can take an optional base as a second parameter, e.g. 16 means hexadecimal.
      • When we print out numbers, %g means “general”. It allows Python to choose the best way to output the number (e.g. as a whole number, or as a fraction using E notation).
      • When we print out the complex numbers, note that complex numbers have real and imag properties to get/set the real and imaginary parts of the number.
        i1 = 12345
        i2 = 1234567890123456789
        i3 = int("123", 8)
        print("%d %d %d" % (i1, i2, i3))
        f1 = 1.23
        f2 = 4.56e-34
        f3 = 7.89e+34
        f4 = float("123.45")
        print("%g %g %g %g" % (f1, f2, f3, f4))
        c1 = 1 + 2j
        c2 = 3 - 4j
        c3 = 5j
        c4 = complex("6+7j")
        print("%g + %gi" % (c1.real, c1.imag))
        print("%g + %gi" % (c2.real, c2.imag))
        print("%g + %gi" % (c3.real, c3.imag))
        print("%g + %gi" % (c4.real, c4.imag))
  2. Numeric Operators
    • Python supports the following operators on numbers
      • x ** y, pow(x, y), divmod(x, y), c.conjugate()
      • complex(re, im), float(x), int(x), abs(x)
      • +x, -x, x % y, x // y
      • x / y, x * y, x – y, x + y
    • You can use these operators for all types of numbers, except complex numbers. Note the following general points:
      • ** is the power operator, i.e. it’s equivalent to calling the pow() function.
      • divmod() returns the pair of values (x // y, x % y).
      • conjugate() conjugates the complex number.
      • % returns the remainder of x / y.
      • // returns the floored quotient of x and y, i.e. it performs integer division.
      • / returns the quotient of x and y.
  3. Bitwise Operators
    • Python supports the following bitwise operators on integers
      • ~x – returns the bit-wise negation, i.e. all the bits are inverted.
      • x >> n – shifts the bits right by the specified number of bits.
      • x << n - shifts the bits left by the specified number of bits.
      • x & y – performs a bit-wise “and” of the two operands.
      • x ^ y – performs a bit-wise “exclusive or” of the two operands.
      • x | y – performs a bit-wise “inclusive or” of the two operands.
  4. Using the math Module
    • The math module defines several useful mathematical constants and functions
      • For details, see https://docs.python.org/3.4/library/math.html
    • Example:
      import math
      print(dir(math))
      print("pi is %f" % math.pi)
      print("360 degrees in radians is %g" % math.radians(360))
      print("2 * pi radians in degrees is %g" % math.degrees(2 * math.pi))
      print("sin(90 degrees) is %.4f" % math.sin(math.pi / 2))
      print("cos(90 degrees) is %.4f" % math.cos(math.pi / 2))
      print("acos(0) is %g degrees" % math.degrees(math.acos(0)))
      print("hypoteneuse of right-angled triangle (sides 3, 4) is %g" % math.hypot(3, 4))
      print("5 factorial is %g" % math.factorial(5))
  5. Booleans
    • Python doesn’t have a specific boolean data type
      • You can test any object for truth or falsehood
    • The following values are considered false:
      • None
      • False
      • Zero of any numeric type, e.g. 0,0.0,0j
      • Any empty sequence, e.g. ”,(),[]
      • Any empty mapping, e.g.{}
    • All other values are considered true
    • Note that operations and built-in functions that return a boolean result always return 0 or False to represent falsehood, and 1 or True to represent truth.
  6. Relational Operators
    • Python supports the following relational operators
      • <, <=, >, >=
      • ==, !=, is, is not
    • No great surprises here, but a few observations:
      • The is operator tests for object identity, i.e. do two variables point to the same object. We’ll come back to this point later in the course, when we cover objects and classes.
      • The is not operator tests for negated object identity, i.e. do two variables point to different object.
      • The <,<=,> and >= operators raise a TypeError exception if you compare a complex number with another built-in numeric type; or if you compare objects of different types that can’t be compared; or if you compare objects where there is no defined ordering.
      • Non-identical instances of a class normally compare as non-equal unless the class defines the __eq__() method.
      • Objects of different types never compare equal.
  7. Boolean Logic Operators
    • Python has three boolean logic operators:
      • not
      • and
      • or
    • Python uses the keywords not, and, and or for boolean logic. These operators have the precedence shown below (from high priority to low priority), in case you want to string them together into complex logic statements. Note that and and or are short-circuit operators, so they only evaluate the second operand if necessary to determine the overall result:
      • and will only evaluate the second operand if the first operand is true.
      • or will only evaluate the second operand if the first operand is false.
        month = int(input("Enter a month number [1-12]: "))
        is_summer = month >=6 and month <= 8 is_winter = month == 12 or month == 1 or month == 2 is_transition_season = not(is_winter or is_summer) print("%s %s %s" % (is_summer, is_winter, is_transition_season))
  8. Operator Precedence
    • This table shows the precedence of all the operators in Python
      T2P2
    • This table shows the precedence of all the operators in Python, listed from lowest precedence to highest precedence. Operators in the same box have the same precedence.
      We've covered most of these operators in this chapter. We'll cover the other operators later in the course.
  9. Strings
    • A string is an immutable sequence of Unicode characters meaning all the methods that seem to modify strings actually return a mutated copy, and leave the original string in-tact.
      • Can enclose in single quotes, double quotes, or triple quotes
        str1 = "The computer says 'No' I'm afraid."
        str2 = 'Click here for the BBC'
        str3 = """Birthday present ideas:
         - Bugatti
         - 4xHD OLED 64-inch TV
         - Socks"""
        print("%s\n%s\n%s" % (str1, str2, str3))
    • The String class defines many methods
      • For details, see https://docs.python.org/3.4/library/string.html
    • There's also excellent support for regular expressions
      • For details, see https://docs.python.org/3.4/library/re.html
  10. Other Built-In Types
    • Basic sequence types:
      • List - a mutable sequence.
      • Tuple - an immutable sequence.
      • Range - an immutable sequence of numbers, typically used in for loops.
    • Binary sequence types:
      • bytes - an immutable sequence of single bytes, typically used for passing ASCII characters over networks.
      • bytesarray - a mutable counterpart to bytes.
      • memoryview - an object that allows Python code to access the internal data of an object that supports the buffer protocol (e.g. a bytes or bytesarray object) without copying.
    • Set types:
      • set - an unordered mutable collection of distinct objects.
      • frozenset - an unordered immutable counterpart to set.
    • Mapping type:
      • dict - a mutable collection of key-value pairs.
Lab
  1. Using complex numbers
    • This exercise is quite mathematical - it's based on quadratic equations and how you solve them. If your maths isn't what it used to be, you might want to skip this question and give yourself a different challenge instead (e.g. experiment with functions in the math module, explore the String class, etc.)
    • If you're still reading, a quadratic equation is an equation involving x^2 such as the following:
      ax^2 + bx + c = 0
    • To solve a quadratic equation, you have to find values for x such that when you plug these values into the equation, the result is 0. In general, there are two values for x that solve a quadratic equation. Mathematically, we call these the roots of the equation. There's a general formula for finding the roots of a quadratic equation:
      T2P3
    • Your task is to solve a quadratic equation. The first step is to ask the user to enter values for a, b, and c (as integers, let's say). Then you have to plug the values into the formula, to find the two values for x that solve the equation. Note that it's very important whether the value of (b^2 - 4ac), known as the discriminant, is positive or negative
      import math
      a = int(input("Enter coefficient of x-squared: "))
      b = int(input("Enter coefficient of x: "))
      c = int(input("Enter coefficient of units: "))
      discriminant = b ** 2 - 4 * a * c
      denominator = 2 * a

      View Code File

      • If the discriminant is positive, you can get its square root via the math.sqrt() function. You can then add the value and subtract the value as shown in the formula, to get the two roots for the equation.
        if discriminant >= 0:
          part2 = math.sqrt(discriminant)  
          root1 = (-b + part2)/denominator
          root2 = (-b - part2)/denominator
        ...
      • If the discriminant is negative, it's a bit more tricky. You can't find the square root of a negative number. In this case, we say that the equation doesn't have real roots. Or to put it another way, the roots will be complex numbers. What you have to do here is convert the discriminant to a positive number (so you can find its square roots), and then treat the result as the imaginary part of a complex number.
        else:
          imag = math.sqrt(-discriminant) / denominator
          root1 = complex(-b/denominator, +imag)
          root2 = complex(-b/denominator, -imag)
      • Then printing the results once you have obtained them from above
        print("Root 1 : %s" % root1)
        print("Root 2 : %s" % root2)
      • View Code File

    • Run using F5 - You can use the examples below to test the conditional
      • Real Solution - a=1, b=-2, c=-3
      • Complex Solution - a=1, b=3, b=3

Well done. You have completed the tutorial in the Python course. The next tutorial is

3. Flow Control


Back to beginning
Copyright © 2016 TalkIT®






If you liked this post, please comment with your suggestions to help others.
If you would like to see more content like this in the future, please fill-in our quick survey.
Scroll to Top