Chapter 1 - Introduction


Terminology

Abstract Data Type: a logical description of how we view the data and the operations that are allowed without regard to how they will be implemented.

Class: a description of what the data look like (the state) and what the data can do (the behavior). Classes are analogous to abstract data types because a user of a class only sees the state and behavior of a data item. Data items are called objects in the object-oriented paradigm. An object is an instance of a class.

Lists, strings, and tuples are ordered collections.

Sets and dictionaries are unordered collections.

Raised Exception - when a program run into the logical error

Handle Exception - a programmer can intervene with exception (hanlde it) by using a try statement


Built-in Data Types (Collections)

Lists - mutable Operations:

  • indexing([])
  • concatenations(+)
  • repetition(*)
  • membership(in)
  • length(len)
  • slicing([:])

Methods:

>>> alist.append(item)
>>> alist.insert(pos, item)
>>> alist.pop()        # remove and return the last item in the list
>>> alist.pop(i)       # remove and return the ith item in the list
>>> alist.sort()       # modifies a list to be sorted
>>> alist.reverse()    # modifies a list to be in reverse order
>>> del alist[pos]     # delete an item in the ith position
>>> alist.index(item)  # return the index of the first occurance of item
>>> alist.count(item)  # returns the number of occurances of item
>>> alist.remove(item) # removes the first occurance of item

Strings - immutable Methods:

>>> astring.center(w)    # returns a string centered of size w
>>> astring.count(item)  # returns the number of occurances of item
>>> astring.ljust(w)     # returns a string left-justified of size w
>>> astring.lower()      # returns a string in all lowercase
>>> astring.find(item)   # return the index of first occurance of item
>>> astring.split(schar) # splits a string into substrings of schar

Tuples - immutable

  • same methods as lists, but cannot change

Sets - immutable Operations:

>>> membership (in)
>>> length (len)
>>> aset | otherset  # returns a new combined set
>>> aset & otherset  # returns a new set with elements common to both sets
>>> aset - otherset  # returns a new set with items in first not in second
>>> aset <= otherset # asks if all elements in first are in second

Methods:

>>> aset.union(otherset)        # a new set with elements from both sets
>>> aset.intersection(otherset) # a new set with elements common to both
>>> aset.difference(otherset)   # a new set with elements from first not second
>>> aset.issubset(otherset)     # asks whether all elements of one set are in the other
>>> aset.add(item)              # adds item to the set
>>> aset.remove(item)           # removes item from the set
>>> aset.pop()                  # removes an arbitrary element from the set
>>> aset.clear()                # removes all elements from the set

Dictionaries - mutable Operations:

>>> adict[k]       # returns the value associated with k, otherwise an error
>>> key in adict   # returns True if key is in the dictionary, False otherwise
>>> del adict[key] # removes the entry from the dictionary

Methods:

>>> adict.keys()     # returns the keys of the dictionary in a dict_keys(list) object
>>> adict.values()   # returns the values of the dictionary in a dict_values(list) object
>>> adict.items()    # returns the key-value pairs in a dict_items(tuple) object
>>> adict.get(k,alt) # returns the values associated with k, alt otherwise

String Formatting and List Comprehensions

>> print("hello world", sep/end="***")
>> print("%s is %d years old." % (aName, age))

>> sqlist = [x*x for x in range(1,11) if x%2 != 0]
>> upper = [ch.upper() for ch in 'comprehension' if ch not in 'aeiou']

Format Characters:

>>> d # integer
>>> i # integer
>>> u # unsigned integer
>>> f # floating point as m.ddddd
>>> e # floating point as m.dddde+/-xx
>>> E # floating point as m.ddddE+/-xx
>>> g # use %e for exponents less than -4 or greater than +5, otherwise %f
>>> c # single character
>>> s # string or any python data object that can be converted to a string using the **str** function
- % # insert a literal % character

Format Modifier

>>> %20d     # field width of 20
>>> %-20d    # 20 characters wide, left-justified
>>> %+20d    # 20 characters wide, right-justified
>>> %020d    # 20 characters wide, fill in with leading zeros
>>> %20.2f   # 20 characters wide with 2 characters to the right of the decimal point
>>> %(name)d # get the value from the supplied dictionary using name as the key

Use .format method for clarity


Exception Handling

Syntax Error:

  • a syntactical error while writing a program:
    >>> for i in range(10)
    SyntaxError: invalid syntax (<pyshell#61>, line 1)
    

Logical Error:

  • program executes but gives the wrong result
  • this can be due to an error in the underlying algorithm or an error in the translation of that algorithm
  • for example:
    • trying to divide by zero
    • trying to access an item in a list where the index of the item is outside the bounds of the list
  • the logic error will lead to a runtime error that causes the program to terminae
  • these types of runtime errors are typically called exceptions

Hanlding Exceptions:

  • there is a way to handle these exceptions
  • there is a way to write custom exceptions
  • use try statement to catch/handle exceptions

Below is the case when a negative value was entered into math.sqrt():

>>> anumber = int(input("Please enter an integer "))
Please enter an integer -23
>>> print(math.sqrt(anumber))
Traceback (most recent call last):
  File "<pyshell#102>", line 1, in <module>
    print(math.sqrt(anumber))
ValueError: math domain error

To handle the exception use the try/except block:

try:
    print(math.sqrt(anumber))
except:
    print("Bad Value for square root")
    print("Using absolute value instead")
    print(math.sqrt(abs(anumber)))

Bad Value for square root
Using absolute value instead
4.79583152331

Let's create our own RuntimeError exception:

if anumber < 0:
   raise RuntimeError("You can't use a negative number")
else:
    print(math.sqrt(anumber))
...
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
RuntimeError: You can't use a negative number

Self-Check Challenge: The Infinite Monkey Theorem

Problem:

The theorem states that a monkey hitting keys at random on a typewriter keyboard for an infinite amount of time will almost surely type a given text (i.e. the complete works of William Shakespeare). Let's start with generating a simple sentence: methinks it is like a weasel

Solution:
  1. Write a function that generates a string of 27 characters long by choosing random letters from the 26 letters in the alphabet, plus the space.
  2. Write another function that will score each generated string by comparing the randomly generated string to the goal.
  3. Write a third function that will repeatedly call generate and score functions, then if 100% of the letters are correct, we are done! If the letters are note correct then we will genereate a whole new string. To make it easier to follow your program's progress this third function should print out the best string generated so far and its score every 1000 tries.
  4. Then improve the algorithm by keeping letters that are correct and only modifying one character in the best string so far. This is a type of algorithm in the class of hill climbing algorithms, that is we only keep the result if it is better than the previous one.

In [12]:
"""
    inf_monkey.py - Yevheniy Chuba - 10/18/2016
    1. func_1 - Generate a string of 27 characters chosen randomly from 26 letters + space character
    2. func_2 - Score the generated string by comparing to the goal string: "methinks it is like a weasel"
    3. func_3 - Repeatedly call generate(func_1) and score(func_2), until 100% match is found
              - Print out the best string generated so far and its score after 1000 tries
"""
import random
import string

def random_string(length=1):
    """
    Generates a string of random characters
    of length length.
    
    :arg str length:
        The random string length. 
    """
    random_text = ''.join([random.choice(string.ascii_letters + " ") for n in range(length)])
    return random_text


def score_string(goal_str, generated_str):
    pass


Out[12]:
'GNRownQaSmwvXNTvbNundjazssi'

In [ ]: