MIME-Version: 1.0 Content-Location: file:///C:/90861A53/Week13.htm Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset="us-ascii" Week 13

Week = 13
Loop Review and File Systems<= /span>

Indiana University

Computer Science A202 / A598

and Informatics I211

 

Loop revi= ew

<= ![if !supportLists]>n   See loops.py

<= ![if !supportLists]>q   <= /span>The use of functions that take other functions as arguments, such as map and filter, is an advanced topic<= /o:p>

<= ![if !supportLists]>n   &nb= sp; they are a powerful programming tool

<= ![if !supportLists]>n   &nb= sp; you are not responsible for using them creatively<= /p>

<= ![if !supportLists]>n   &nb= sp; you are not responsible for the lambda expression that is han= dy for creating anonymous functions

<= ![if !supportLists]>n   You are responsible for a reading knowledge of keyword arguments

<= ![if !supportLists]>q   <= /span>but not for using them creatively

File systems

<= ![if !supportLists]>n   A file system is a collection of files managed by an operating system in a similar way

<= ![if !supportLists]>n   In addition to storing files, file systems also organize and protect files

<= ![if !supportLists]>n   Most file systems organize files in a hierarchical fashion using directories (al= so know as folders)

<= ![if !supportLists]>n   Directory entries may be files, subdirectories, and links (shortcuts) to files and directories



Direc= tories and paths

<= ![if !supportLists]>n    In most operating systems directories can accessed like files, but written only using directory commands

<= ![if !supportLists]>n    Files (and directories) are identified by a path

<= ![if !supportLists]>n    An absolute path extends from a root through nested subdirectories, to the indicated file

<= ![if !supportLists]>n    In Unix the root is / and in Windows it is a (sometimes virtual) disk drives indicated by a letter followed by a colon

<= ![if !supportLists]>q   <= /span>elements of the path are separated by a backward slash "\" character in Windows and a forward slash "/" in Unix =

<= ![if !supportLists]>q   <= /span>some applications accept either as a path separator

<= ![if !supportLists]>n    Windows example: m:\a1\futval.py (futval= .py file in a1 directory of CFS drive m:)

<= ![if !supportLists]>n    Unix example: /l/www/classes/a202-hayn/a/3 (assignment 3 directory of this course's web on the computer science department's web server)

Relat= ive paths

<= ![if !supportLists]>n   The operating system associates with each program a current directory

<= ![if !supportLists]>q   the current directory is sometimes called the current working directory, abbreviated cwd

<= ![if !supportLists]>q   <= /span>one dot (.) indicates the current directory=

<= ![if !supportLists]>n   A relative path is one that begins with the current directory, instead of a r= oot directory

<= ![if !supportLists]>q   example: if the current directory was m: the relative path a1\futval.py is equivalent= to the absolute path m:\a2\futval.py

<= ![if !supportLists]>n   Two dots (..) indicates the parent of a directory

<= ![if !supportLists]>q   example: if the current directory is m:\a1, the path ..\a2\statistics.py is equivalen= t to m:\a2\statistics.py

File permissions

<= ![if !supportLists]>n   Files may have permissions associated with them for security

<= ![if !supportLists]>n   Common permissions are

<= ![if !supportLists]>q   <= /span>read       

<= ![if !supportLists]>q   write<= /span>

<= ![if !supportLists]>q   <= /span>execute (for files that are run by the operating system as programs)

<= ![if !supportLists]>n   Permissions may be combined

<= ![if !supportLists]>q   <= /span>example: a file may have both read and write permission


Some operating system module functions

<= ![if !supportLists]>n    The os (operating system) mod= ule provides a number of functions for manipulating files on disk

<= ![if !supportLists]>q   <= /span>os.chdir(dirPath) changes the current directory to that indic= ated by dirPath

<= ![if !supportLists]>q   <= /span>os.listdir(dirPath) returns a list of entries in the indicated directory

<= ![if !supportLists]>q   <= /span>os.remove(filename<= span style=3D'font-size:9.0pt;font-family:Arial;mso-bidi-font-family:Arial;mso-b= idi-language: #AC45'>) deletes the file indicated by the string filename

<= ![if !supportLists]>n   &nb= sp; be careful with this one!

<= ![if !supportLists]>q   <= /span>os.rename(oldName, newName) changes the name of file oldName to newName=

<= ![if !supportLists]>n   &nb= sp; under Windows, if newName file already exists, it must be rem= oved first (not so under Unix)

<= ![if !supportLists]>q   os.access(= path, mode) is a predicate (boolean-valued function) indicating if the file (or directory) indicated by path has the indicated mode

<= ![if !supportLists]>q   <= /span>integer constants in the os module give names to modes        &= nbsp;  

<= ![if !supportLists]>n   &nb= sp; os.F_OK : the file exists=

<= ![if !supportLists]>n   &nb= sp; os.R_OK : the file has read permission

<= ![if !supportLists]>n   &nb= sp; os.W_OK : the file has write permission

<= ![if !supportLists]>n   &nb= sp; os.X_OK : the file has execute permission

Examp= le: file renaming

<= ![if !supportLists]>n   Implement a function renameForUnix that takes a directory path and renames all files in the directory that have spaces in their name, replacing the spaces with underscores

<= ![if !supportLists]>q   <= /span>file names with spaces are common in Windows, but frequently cause problems in Unix systems, which was not originally designe= d to support them

def renameForUnix(dirPath):

    os.chdir(dirPath)

    for fileN= ame in os.listdir('.'):

        if ' ' in fileName:

        =     os.rename(fileName,

        =             &nb= sp; fileName.replace(' ', '_'))

Advan= ced: sendMail

def sendMail(smtpServer, sender=3DNone, to=3D[], cc=3D[], bcc=3D[], = subject=3D'', text=3D''):

    import os= , smtplib, email.MIMEText

    msg =3D email.MIMEText.MIMEText(text)

    if not se= nder:

        sender =3D os.environ['USERNAME'] + '@indiana.edu'=

    msg['From= '] =3D sender

    if subjec= t: msg['Subject'] =3D subject

    if to: msg['To'] =3D ';'.join(to)

    if cc: ms= g['Cc'] =3D ';'.join(cc)

    if bcc: msg['Bcc'] =3D ';'.join(bcc)

    s =3D smtplib.SMTP()

    s.connect(smtpServer)

    print msg.as_string()

    s.sendmail(sender, to+cc+bcc, msg.as_string())=

    s.close()=

Forma= tive evaluation

<= ![if !supportLists]>n      On a sheet of paper without your name (unless you wish: this is not a hand-in) please indicate the following to help improve the course:=

<= ![if !supportLists]>q    On average, about how many hours have you spent on each assignment?

<= ![if !supportLists]>q    Have you been doing the reading assigned for most weeks before lab?

<= ![if !supportLists]>q    Have you tried doing the exercises at the end of e= ach chapter, and if so, did you find them helpful?

<= ![if !supportLists]>q    About how many of the text's end-of-chapter programming exercises have you done (that were not part of assignments)?

<= ![if !supportLists]>q    List a few things you like about the course.<= /o:p>

<= ![if !supportLists]>q    List a few things about the course that you think = need improvement.

 

loops.py

def check(exp, returns, localEnvironment=3DNone):
    value =3D eval(exp, globals(), localEnvironment or locals())
    if value !=3D returns:
        print 'EXPRESSION:', exp
        print 'RETURNED:', value
        print 'EXCECTED:', returns

'''Write a function that takes a list of numbers and returns a list whose
elements are each the square of the value of the corresponding element in the
given list.'''

def testSquares():
    check('squares([1, 2, 3])', [1, 4, 9])

def squares(numbers):
    answer =3D []
    for x in numbers:
        answer.append(x * x)
    return answer

testSquares()

'''The solution above iterates the elements of the list. Implement it again,
iterating instead over the indices of the elements in the list.'''

def squares2(numbers):
    answer =3D []
    for i in range(len(numbers)):
        answer.append(numbers[i] ** 2)
    return answer

check('squares2([1, 2, 3])', [1, 4, 9])

'''Modify the above solution to use a while loop instead of a for loop.'''
def squares3(numbers):
    answer =3D []
    i =3D 0
    while i < len(numbers):
        answer.append(numbers[i] ** 2)
        i +=3D 1
    return answer

check('squares3([1, 2, 3])', [1, 4, 9])

'''The solutions above build the answer list incrementally. Implement it again,
without using append or list concatenation, by first creating the answer list
with its final length with an arbitrary initial element values (using the
sequence repetition operator *) and then assigning the correct element values
with a for loop. This is closest to the approach you would take in languages like
Java with fixed-length arrays.'''

def squares4(numbers):
    answer =3D ['ignored'] * len(numbers)
    for i in range(len(numbers)):
        answer[i] =3D numbers[i] ** 2
    return answer

check('squares4([1, 2, 3])', [1, 4, 9])

'''Write a function that takes a list of strings and returns a list whose
elements are each the length of the corresponding element in the given list.'''

def testLengths():
    check("lengths(['a', 'list', 'of', 'strings'])", [1, 4, 2, 7])

def lengths(strings):
    answer =3D []
    for s in strings:
        answer.append(len(s))
    return answer

testLengths()

'''Write a function that takes a function and a list and returns a list whose
elements are each obtained by applying the function to the corresponding element
in the given list.'''

def testMap():
    def square(x):
        return x * x
    check('map(square, [1, 2, 3])', [1, 4, 9], locals())
    check('map(lambda x: x * x, [1, 2, 3])', [1, 4, 9])
    check("map(len, ['a', 'list', 'of', 'strings'])", [1, 4, 2, 7])

def map(function, lst):
    answer =3D []
    for value in lst:
        answer.append(function(value))
    return answer

testMap()

'''Write a function that takes a list of numbers and returns a list of those
elemenets of the given list that are greater than zero.'''

def testPositiveElements():
    check('positiveElements([1, -3, 0, 2, -1])', [1, 2])

def positiveElements(numbers):
    answer =3D []
    for x in numbers:
        if x > 0:
            answer.append(x)
    return answer

testPositiveElements()

'''Write a function that takes a list of strings and returns a list of those
elements of the given list that contain no upper case letters.'''

def testNoUppers():
    check("noUppers(['no uppers here', 'but an UPPER here', 'lower only'])",
          ['no uppers here', 'lower only'])

def noUppers(strings):
    answer =3D []
    for s in strings:
        if s.lower() =3D=3D s: # no upper case letters
            answer.append(s)
    return answer

testNoUppers()

'''Write a function that takes a predicate of one argument and a list and
returns a list containing those elements of the given list for which the
predicate returns true. That is, this function filters out those elements for
which the predicate is false.'''

def testFilter():
    def positive(x):
        return x > 0
    check('filter(positive, [1, -3, 0, 2, -1])', [1, 2], locals())
    check('filter(lambda x: x > 0, [1, -3, 0, 2, -1])', [1, 2])
    def isLowerCase(s):
        return s.lower() =3D=3D s
    check("""filter(isLowerCase,
                    ['no uppers here', 'but an UPPER here', 'lower only'])""",
          ['no uppers here', 'lower only'], locals())
    check("""filter(lambda s: s.lower() =3D=3D s,
                    ['no uppers here', 'but an UPPER here', 'lower only'])""",
          ['no uppers here', 'lower only'])

def filter(predicate, lst):
    answer =3D []
    for v in lst:
        if predicate(v):
            answer.append(v)
    return answer

testFilter()

'''Write a function that takes two lists of equal length and returns a list of
pairs (two element tuples) associating corresponding elements of the given
lists.'''

def testZip():
    check("zip([1, 2, 3], ['a', 'b', 'c'])", [(1, 'a'), (2, 'b'), (3, 'c')])

def zip(lst1, lst2):
    answer =3D []
    for i in range(len(lst1)):
        answer.append((lst1[i], lst2[i]))
    return answer

testZip()

'''Write a function that takes a list of pairs and returns two lists whose
elements of the same index are pairs containing the elements of the same index
in the given lists.'''

def testUnzip():
    check("unzip([(1, 'a'), (2, 'b'), (3, 'c')])", ([1, 2, 3], ['a', 'b', 'c']))

def unzip(lst):
    answer1 =3D []
    answer2 =3D []
    for v1, v2 in lst:
        answer1.append(v1)
        answer2.append(v2)
    return answer1, answer2

testUnzip()

'''Define two functions that take a list and return a list with the same
elements, but in reverse order. In one, use range(start, stop, step), which
returns a list of numbers from start to but not including stop with step
difference between successive elements (step may be negative). In the other,
use range(stop).'''

def testReverse():
    check('reverse1([1, 2, 3])', [3, 2, 1])
    check('reverse2([1, 2, 3])', [3, 2, 1])

def reverse1(lst):
    answer =3D []
    for i in range(len(lst)-1, -1, -1):
        answer.append(lst[i])
    return answer

def reverse2(lst):
    answer =3D []
    for i in range(len(lst)):
        answer.append(lst[len(lst)-1 - i])
    return answer

testReverse()

'''Write a function that takes two lists of equal length and returns one list
that is a perfect shuffle (interleaving) of the elements of the two given
lists.'''

def testShuffle():
    check("shuffle([1, 2, 3], ['a', 'b', 'c'])", [1, 'a', 2, 'b', 3, 'c'])

def shuffle(lst1, lst2):
    answer =3D []
    for i in range(len(lst1)):
        answer.append(lst1[i])
        answer.append(lst2[i])
    return answer

testShuffle()

'''Write a function that takes a shuffled list (of even length) and retunrs two
lists that each contain every other element of the given list (thus reversing
the shuffle operation).'''

def testUnshuffle():
    check("unshuffle([1, 'a', 2, 'b', 3, 'c'])", ([1, 2, 3], ['a', 'b', 'c']))

def unshuffle(lst):
    answer1 =3D []
    answer2 =3D []
    for i in range(len(lst)/2):
        answer1.append(lst[i*2])
        answer2.append(lst[i*2 + 1])
    return answer1, answer2

testUnshuffle()

print 'Done'