cs101 udacity homework

Upload: ubaid-umar

Post on 06-Apr-2018

241 views

Category:

Documents


0 download

TRANSCRIPT

  • 8/2/2019 CS101 Udacity Homework

    1/44

    Unit 1

    Q1

    1,2,3

    Q2

    AllQ3

    print 7*7*24*60

    Q4

    3

    Q5

    1,2

    Q6

    1,2,5

    Q7

    print 299792458*100*(1.0/1000000000)Q8

    speed_of_light = 299792458.0

    cycles_per_second = 2700000000.0

    print speed_of_light/cycles_per_second

    Q9

    5

    Q10

    4

    Q11

    #Write python code that defines the variable#age to be your age in years, and then prints

    #out the number of days you have been alive.

    age=20

    print age*365.25

    Q12

    1,5

    Q13

    # Define a variable, name, and assign to it a string that is your name.

    name = "ubaid umar"

    Q14

    1,2,5

    Q15

    # Write Python code that prints out Udacity (with a capital U),

    # given the definition of s below.

    s = 'audacity'

  • 8/2/2019 CS101 Udacity Homework

    2/44

    print "U"+s[2:]

    Q16

    1,2,5

    Q17

    3,4

    Q18

    1,3,4,5

    Q19

    None

    Q20

    #Write Python code that initializes the variable

    #start_link to be the value of the position

    #where the first '

  • 8/2/2019 CS101 Udacity Homework

    3/44

    #Write Python code that prints out the number of hours in 7 weeks.

    #DO NOT USE IMPORT

    weeks = 7

    days_per_week = 7

    hours_per_day = 24

    hours_in_7_weeks = weeks*days_per_week*hours_per_day

    print hours_in_7_weeks

    Q3

    1,3,4,5

    Q4

    #Write Python code that stores the distance

    #in meters that light travels in one

    #nanosecond in the variable, nanodistance.

    #These variables are defined for you:

    speed_of_light = 299800000. #meters per second

    nano_per_sec = 1000000000. #1 Billion

    #After your code,running

    #print nanodistance

    #should output 0.2998

    #Note that nanodistance must be a decimal number.

    #DO NOT USE IMPORT

    s='aaa'

    print s[0:]

    nanodistance = speed_of_light/nano_per_sec

    print nanodistance

    Q5

    1,2,4

    Q6

    #Given the variables s and t defined as:

    s = 'udacity'

    t = 'bodacious'

    #write Python code that prints out udacious

    #without using any quote characters in

    #your code.

    #DO NOT USE IMPORT

    print s[0:3]+t[4:]

    Q7

    #Assume text is a variable that

    #holds a string. Write Python code

    #that prints out the position

    #of the first occurrence of 'hoo'

  • 8/2/2019 CS101 Udacity Homework

    4/44

    #in the value of text, or -1 if

    #it does not occur at all.

    text = "first hoo"

    #DO NOT USE IMPORT

    #ENTER CODE BELOW HERE

    #ANY CODE ABOVE WILL CAUSE

    #HOMEWORK TO BE GRADED

    #INCORRECT

    print text.find('hoo')

    Q8

    #Assume text is a variable that

    #holds a string. Write Python code

    #that prints out the position

    #of the second occurrence of 'zip'

    #in text, or -1 if it does not occur

    #at least twice.

    #For example,

    # text = 'all zip files are zipped' -> 18

    # text = 'all zip files are compressed' -> -1

    text = "all zip files are zipped"

    #DO NOT USE IMPORT

    #ENTER CODE BELOW HERE

    #ANY CODE ABOVE WILL CAUSE

    #HOMEWORK TO BE GRADED

    #INCORRECT

    first_zip = text.find('zip')

    second_zip = text.find('zip',first_zip+1)

    print second_zip

    Q9

    #Given a variable, x, that stores

    #the value of any decimal number,

    #write Python code that prints out

    #the nearest whole number to x.

    #You can assume x is not negative.

  • 8/2/2019 CS101 Udacity Homework

    5/44

    # x = 3.14159 -> 3 (not 3.0)

    # x = 27.63 -> 28 (not 28.0)

    x = 3.14159

    #DO NOT USE IMPORT

    #ENTER CODE BELOW HERE

    #ANY CODE ABOVE WILL CAUSE

    #HOMEWORK TO BE GRADED

    #INCORRECT

    y = round(x)

    z = str(y)

    a = z.find('.')

    print z[0:a]

    HomeWork 2

    HW2.1 Udacify:

    # Define a procedure, udacify, that takes as

    # input a string, and returns a string that

    # is an uppercase 'U' followed by the input string.

    # for example, when we enter

    # print udacify('dacians')

    # the output should be the string 'Udacians'

    # Make sure your procedure has a return statement.

    def udacify(s):

    return 'U' + s

  • 8/2/2019 CS101 Udacity Homework

    6/44

    All that needs to be done is to prepend capital letter 'U' (i.e. the string, containing just one character,

    which is capital letter 'U') before the string, passed into the function as its argument and then return

    the result. String concatenation operator will do the job.

    HW2.2 Proc

    Original procedure:

    def proc(a,b):

    if test(a):

    return b

    return a

    Procedure #1:

    def proc1(x,y):

    if test(x):

    return y

    else:

    return x

    This is about the same as original procedure, just names of parameters were changed, which has no

    effect whatsoever on the algorihm. Therefore, this is equivalent to the original procedure.

    Procedure #2:

    def proc2(a,b):

    if not test(b):

    return a

    else:

    return b

    This is not equivalent. The if statement tries to look as original just being written "upside-down", but

    that is not the case, since we do not know what the test function does. E.g. lets have a = 2, b =

    4 and testfunction returning True if called with an even number, False otherwise. Original procedure

    will then return b, since a is an even number, but procedure #2 will return a, since b is an even

    number, as well.

    Procedure #3:

    def proc3(a,b):

  • 8/2/2019 CS101 Udacity Homework

    7/44

    result = a

    if test(a):

    result = b

    return result

    This is equivalent. in case test(a) returns True, vriable result is assigned value b inside the if-

    block, which than gets returned. Otherwise (test(a) returns False), variable result will contain its

    original value aand this value gets returned. This is exactly the same behavior as the original

    procedure, it is just written differently.

    Procedure #4:

    def proc4(a,b):

    if not test(a):

    b = 'udacity'

    else:

    return b

    return a

    This one is the most interesting and is indeed equivalent to original procedure, although it does not

    look like that for the first glance. In case test(a) returns True, result of the if's condition is negated

    by not keyword and else branch will be executed. It just returns value b, which is the same behavior

    as the original procedure. In case test(a) returns False, original procedure returns value a.

    Procedure #4 is behaving in exactly the same way, except it will also set some "magic constant" to

    variable b, but variable b is never used afterwards and thus the assignment has no effect

    whatsoever.

    HW2.3 Median

    There are lots of correct solutions for this problem. Mine looks like this:

    # Define a procedure, median, that takes three

    # numbers as its inputs, and outputs the median

    # of the three numbers.

    # Make sure your procedure has a return statement.

    def bigger(a,b):

  • 8/2/2019 CS101 Udacity Homework

    8/44

    if a > b:

    return a

    else:

    return b

    def biggest(a,b,c):

    return bigger(a,bigger(b,c))

    def median(a, b, c):

    smaller = b

    bigger = a

    if a < b:

    smaller = a

    bigger = b

    if bigger < c:

    return bigger

    if c < smaller:

    return smaller

    return c

    First, it starts with a and b and decides which of them is smaller and which is bigger, assigning

    correct values to respective variables (named smaller and bigger). This will effectively cut the set of

    all numbers into three parts:

    -------- -------- --------

    All that needs to be done then, is to find out which part the value of c falls into and return the correctvalue:

    #1: if bigger < c, i.e. c falls into the rightmost interval:

    -------- -------- -------- --------

    The correct value to be returned is bigger, because it is in the middle between smaller and c.

    #2: if c < smaller, i.e. c falls into the leftmost interval:

  • 8/2/2019 CS101 Udacity Homework

    9/44

    -------- -------- -------- --------

    The correct value to be returned is smaller, because it is in the middle between c and bigger.

    #3: All other cases:

    -------- -------- -------- --------

    or

    -------- -------- --------

    or

    -------- -------- --------

    Either c falls into the middle interval, i.e. it is between smaller and bigger, thus c is the correct value

    to return, or c is equal to either smaller or bigger and c is again the correct value to return (as well

    as one of smaller or bigger, but we have no idea which one of them it is).

    #4: Extreme border cases:

    Make sure, you always take a great care to identify and thoroughly test especially border cases like

    these (not just in this particular homework assignment, but always and everywhere, including real-

    life code), because these are the most frequent source of most errors.

    a == b == c:

    It really does not matter which of the values the function returns, since all of them are medians.

    (Value stored in c gets returned in my solution, i.e. case #3 from above.)

    a == b < c:

    One of values a or b (smaller or bigger) needs to be returned and it indeed will be, since thissituation will be handled by the case #1 from above:

    -------- -------- --------

    c < a == b:

    One of values a or b (smaller or bigger) needs to be returned and it again will be, because this

    situation will be handled by the case #2 from above:

    -------- -------- --------

    HW2.4 Blastoff:

    # Define a procedure, countdown, that takes a

    # positive whole number as its input, and prints

    # out a countdown from that number to 1,

    # followed by Blastoff!

  • 8/2/2019 CS101 Udacity Homework

    10/44

    def countdown(n):

    i = n

    while 0 < i:

    print i

    i -= 1

    print 'Blastoff!'

    Actually, for loop is much better suited for this kind of problem (it is more readable), but since it was

    not introduced in units 1 and 2, while loop will do for now. Everything that needs to be done is just

    loop over numbers from n to 1 and print them out. Then print the "Blastoff!" string and we're done.

    My version of solution is probably not as well readable as the following one, which is as much

    correct as the above one. It is just that from C++, I am accustomed to prefer "less-than" operator

    before all others, I do not like to change values of function's arguments (which is just my own policy

    and it is neither good nor bad - I just feel there are less bad surprises in the code this way) and I am

    pretty lazy to type i = i - 1, so I used its shorthand equivalent i -= 1.

    def countdown(n):

    while n >= 1:

    print n

    n = n - 1

    print 'Blastoff!'

    HW2.5 Finish

    Loop #1:

    n =

    i = 0

    while i

  • 8/2/2019 CS101 Udacity Homework

    11/44

    i = 1

    while True:

    i = i * 2

    n = n + 1

    if i > n:

    break

    This one has some math in it. Loop's condition is, and always will be True, thus it is infinite loop. It is

    terminated by the break statement inside the if and therefore the if's condition i > n needs to be

    satisfied in order to end the loop. That condition states that i must be greater than n and

    both i and n are updated during each cycle (iteration). Both of them can be represented as

    mathematic functions. The one describing iis growing exponentially (i = i * 2), while the one

    describing n is growing only linearry (n = n + 1). Therefore, given enough cycles, i, which is growing

    much faster, will be at the end greater than n, regardless of n's starting value, which is exactly thecondition for breaking the loop. I.e. correct answer is "always finishes".

    Loop #3:

    n =

    while n != 1:

    if n % 2 == 0: # the % means remainder, so this tests if n is even

    n = n / 2

    else:

    n = 3 * n + 1

    This one can be solved almost without actually reading the code ( although it is really a good idea to

    actually check that code does exactly the thing, we are expecting it to do :) ), thanks to hint and

    oddly looking third option saying "unknown to anyone in the known Universe". Thehintpoints to

    xkcd comic, saying something about Collatz Conjecture. If you put this keyword e.g. toWikipedia,

    you will find nice, big banner containing the correct answer right in the right-top corner of the page. It

    says:

    Unsolved problems in mathematics: Does the Collatz sequence from initial value n eventuallyreach 1, for all n > 0?

    The problem is not solved yet by anyone in the known Universe (known by humans anyway), thus

    the correct option is the third one.

    This is probably the best question in the second homework, because it demonstrates little example

    of how is most of problems really solved in real life. On of my past colleagues had a saying "You are

    http://www.xkcd.com/710/http://www.xkcd.com/710/http://www.xkcd.com/710/http://en.wikipedia.org/wiki/Collatz_conjecturehttp://en.wikipedia.org/wiki/Collatz_conjecturehttp://en.wikipedia.org/wiki/Collatz_conjecturehttp://en.wikipedia.org/wiki/Collatz_conjecturehttp://www.xkcd.com/710/
  • 8/2/2019 CS101 Udacity Homework

    12/44

    highly probably not the first one with this kind of problem. Go and look outside for the solution

    instead of inventing the weel!" and it is very true - Google programmer's best friend, because it

    knows answers to most of the questions.

    HW2.6 Find Last:

    # Define a procedure, find_last, that takes as input

    # two strings, a search string and a target string,

    # and outputs the last position in the search string

    # where the target string appears, or -1 if there

    # are no occurences.

    #

    # Example: find_last('aaaa', 'a') returns 3

    # Make sure your procedure has a return statement.

    def find_last(haystack, needle):

    ret = -1

    while True:

    i = haystack.find(needle, ret+1)

    if i == -1:

    break

    ret = i

    return ret

    This is nice example of a problem, which can be solved by carefully noticing how are you yourself

    doing it manually:

    You look at the search string (haystack) and try to find the first occurence of the target string

    (needle).

  • 8/2/2019 CS101 Udacity Homework

    13/44

    In case you found something, you note down its position (ret variable) and continue with the

    previous step, just starting one character after the noted down position.

    In case you did not found anything, you look at your last note and that is your result. Special case

    is the one when you did not find even one occurence of the target string - you do not have any

    position of found string noted down, i.e. your notes sheet (ret variable) is blank (blank notes

    sheet is represented by value -1 assigned to ret variable).

    And this is exactly what the algorighm above does. It is not very effective and can be indeed

    optimized in many ways, but it works and tools for those optimizations were not presented in the

    lectures anyway.

    HW2.7 Multiplication table:

    #2 GOLD STARS

    #Define a procedure,

    #print_multiplication_table,

    #that takes as input a positive whole

    #number, and prints out a multiplication,

    #table showing all the whole number

    #multiplications up to and including the

    #input number. The order in which the

    #equations are printed must match exactly.

    #print_multiplication_table(2)

    #1 * 1 = 1

    #1 * 2 = 2

    #2 * 1 = 2

    #2 * 2 = 4

    def print_multiplication_table(n):

    i = 1

    while i

  • 8/2/2019 CS101 Udacity Homework

    14/44

    j = 1

    while j 31

    #how_many_days(9) => 30def how_many_days(m):

    return days_in_month[m-1]

    print how_many_days(1)

    Q3

    #Given the variable countries defined as:

    # Name Capital Populations (millions)

  • 8/2/2019 CS101 Udacity Homework

    15/44

    countries = [['China','Beijing',1350],

    ['India','Delhi',1210],

    ['Romania','Bucharest',21],

    ['United States','Washington',307]]

    #Write code to print out the capital of India

    #by accessing the array.

    print countries[1][1]

    Q4

    #Given the variable countries defined as:

    # Name Capital Populations (millions)

    countries = [['China','Beijing',1350],

    ['India','Delhi',1210],

    ['Romania','Bucharest',21],

    ['United States','Washington',307]]

    #What multiple of Romania's population is the population

    #of China? Please print your result.

    print countries[0][2]/countries[2][2]

    Q5

    #We defined:

    stooges = ['Moe','Larry','Curly']

    #but in some Stooges films, Curly was

    #replaced by Shemp.

    #Write one line of code that changes

    #the value of stooges to be:

    ['Moe','Larry','Shemp']

    #but does not create a new List

    #object.

    stooges[2]='Shemp'

    Q6

    8

    Q7

    #Define a procedure, replace_spy,

    #that takes as its input a list of

    #three numbers, and modifies the

  • 8/2/2019 CS101 Udacity Homework

    16/44

    #value of the third element in the

    #input list to be one more than its

    #previous value.

    spy = [0,0,7]

    #replace_spy(spy)

    #print spy => [0,0,8]

    def replace_spy(pro):

    pro[2]=pro[2]+1

    return pro

    print replace_spy(spy)

    Q8

    5

    Q9

    3

    Q10

    300000

    0.12

    3.6

    Q11

    0.01

    2098

    Q12

    i 12

    def sum_list(p):

    s=0

    for e in p:

    s=s+e

    return s

    print sum_list([1,7,4])

    Q14

    #Define a procedure, measure_udacity,

    #that takes its input a list of Strings,

  • 8/2/2019 CS101 Udacity Homework

    17/44

    #and outputs a number that is a count

    #of the number of elements in the input

    #list that start with the letter 'U'

    #(uppercase).

    #For example,

    #measure_udacity(['Dave','Sebastian','Katy']) => 0

    #measure_udacity(['Umika','Umberto']) => 2

    def measure_udacity(U):

    count=0

    for e in U:

    if e[0]=='U':

    count = count + 1

    return count

    print measure_udacity(['Dave','Sebastin','Katy'])

    print measure_udacity(['Umika','Umberto'])

    Q15

    #Define a procedure, find_element,

    #that takes as its inputs a List

    #and a value of any type, and

    #outputs the index of the first

    #element in the input list that

    #matches the value.

    #If there is no matching element,

    #output -1.

    #find_element([1,2,3],3) => 2

    #find_element(['alpha','beta'],'gamma') => -1

    def find_element(p,t):

    if t not in p:

    return -1

    return p.index(t)

    print find_element([1,2,3],3)

    Q16

    #Define a procedure, union,

    #that takes as inputs two lists.

    #It should modify the first input

  • 8/2/2019 CS101 Udacity Homework

    18/44

    #list to be the set union of the two

    #lists.

    a = [1,2,3]

    b = [2,4,6]

    #union(a,b)

    #a = [1,2,3,4,6]

    #b = [2,4,6]

    def union(p,q):

    for e in q:

    if e not in p:

    p.append(e)

    return p,q

    print union(a,b)

    Q17

    1,2,4

    Q18

    []

    Q19

    links.append(url)

    Q20

    return links

    Q21

    3

    Q22

    [seed]

    []

    Q23

    Tocrawl.pop()

    Q24

    page is not in crawled

    Q25

    def get_next_target(page):

    start_link = page.find('

  • 8/2/2019 CS101 Udacity Homework

    19/44

    for e in q:

    if e not in p:

    p.append(e)

    def get_all_links(page):

    links = []

    while True:

    url,endpos = get_next_target(page)

    if url:

    links.append(url)

    page = page[endpos:]

    else:

    break

    return links

    def crawl_web(seed):

    tocrawl = [seed]

    crawled = []

    while tocrawl:

    page = tocrawl.pop()

    if page not in crawled:

    union(tocrawl, get_all_links(get_page))

    crawled.append(page)

    return crawled

    HomeWork 3

    HW3.1 Lists

    If nothing else, this one is relatively easy to solve by bruteforce using few lines of Python code. The

    "bruteforceless" solution is relatively easy as well.

    Let's take it from the end:

    We want p[2] to be 3. At the time of setting p[2], both p[0] and p[1] should have their final

    correct values, i.e. 1and 2, respectively. Thus, this one will resolve itself if we got right the rest. Next one is p[1], which should be set to 2. At the time, when it is assigned its final

    value, p[0] should be final as well and thus we can be sure, it will equal 1. Calculating initial

    value of p[2] is then as easy as p[2] = 2 - 1, which is 1.

    The last one is p[0], which should be set to 1. Its value will be calculated as its original value plus

    value of p[1]. This means that p[0] and p[1] should be initially set to any two values, which add

    up to 1. Therefore, there is infinite number of solutions, e.g. 0,1 or 1,0 or -1,2 etc.

  • 8/2/2019 CS101 Udacity Homework

    20/44

    Chosen solution might be checked with this simple code (copy-pasted from the homework

    assignment):

    p = [0,1,1]

    p[0] = p[0] + p[1]

    p[1] = p[0] + p[2]

    p[2] = p[0] + p[1]

    print p # => [1,2,3]

    HW3.2 Mutating Lists

    Procedure #1:

    def proc1(p):

    p[0] = p[1]

    As explained in Unit3.13 Replace Spy, this procedure will clearly modify its argument. In case it is

    not clear to you, look again at videos 7 to 13 in Unit 3.

    It should be noted, that this function will not even work with lists of less than 2 elements. However,

    this fact has nothing to do with the question being asked.

    Procedure #2:

    def proc2(p):

    p = p + [1]

    This one does not modify the original argument. That is because the + operator creates new

    instance of list object and makes p to refer to that new instance.

    Procedure #3:

    def proc3(p):

    q = p

    p.append(3)

    q.pop()

    This will indeed modify the argument, but it will also undo all the changes done. When you look

    closer at it, you will find out that q and p are referencing the same instance of list object, thus the

  • 8/2/2019 CS101 Udacity Homework

    21/44

    element (integer 3) appended using p "alias", will be popped-out using q "alias", which will leave the

    original list in the exactly the same state as it was in the beginning.

    Procedure #4:

    def proc4(p): q = [] while p: q.append(p.pop()) while q: p.append(q.pop())

    This one is the most interesting of all four. It will gradually pop-out all elements from p and append

    them to the different list, referenced by q. The q-list will contain all elements from p, just in the

    opposite order and p will be left empty. Then, whole process is repeated again in the opposite

    direction: elements are gradually popped-out from q and appended to p, leaving q empty again

    and p with all elements from q, just in the opposite order. Lot's of work done, big pile of bricks moved

    from one heap (LIFO stack in fact) to another and then back, but the result is exactly the same as if

    nothing was done at all.

    You can test it by running the code below:

    def proc1(p):

    p[0] = p[1]

    def proc2(p):

    p = p + [1]

    def proc3(p):

    q = p

    p.append(3)

    q.pop()

    def proc4(p):

    q = []

    while p:

    q.append(p.pop())

    while q:

    p.append(q.pop())

  • 8/2/2019 CS101 Udacity Homework

    22/44

    def init():

    ret = []

    for i in range(10):

    ret.append(i)

    return ret

    def init():

    ret = []

    for i in range(10):

    ret.append(i)

    return ret

    a = init()

    proc1(a)

    print "1:", a

    a = init()

    proc2(a)

    print "2:", a

    a = init()

    proc3(a)

    print "3:", a

    a = init()

    proc4(a)

    print "4:", a

    HW3.3 Product List:

  • 8/2/2019 CS101 Udacity Homework

    23/44

    This is the first assignment from series with subtitle "Setting initial value correctly" (HW3.3, HW3.4

    and HW3.5). It is also about for-loop, but it can be solved also using while-loop from Unit2 (and I

    think that if one grasps concept of while-loop, then for-loop is about the same, just with slightly

    different syntax and actually easier).

    Regarding the initial value, there was very nice answer from@larry96inthisthread. Thisinformation just needs to be written down:

    #Define a procedure, product_list,

    #takes as input a list of numbers,

    #and returns a number that is

    #the result of multiplying all

    #those numbers together.

    #product_list([9]) => 9

    #product_list([1,2,3,4]) => 24

    def product_list(p):

    # set the initial value to 1 - not 0, not anything else (see fnenu's post)

    product = 1

    # go through all values in the list and sequentialy multiply them

    for val in p:

    product = product * val

    # finally return the computed value

    return product

    The equivalent solution using while instead of for would look as ugly as this (that is why we

    have for-loops):

    def product_list(p):

    http://www.udacity-forums.com/cs101/cs101/users/3037/larry96http://www.udacity-forums.com/cs101/cs101/users/3037/larry96http://www.udacity-forums.com/cs101/cs101/users/3037/larry96http://www.udacity-forums.com/cs101/questions/23274/homework-33-specification/23299http://www.udacity-forums.com/cs101/questions/23274/homework-33-specification/23299http://www.udacity-forums.com/cs101/questions/23274/homework-33-specification/23299http://www.udacity-forums.com/cs101/questions/23274/homework-33-specification/23299http://www.udacity-forums.com/cs101/cs101/users/3037/larry96
  • 8/2/2019 CS101 Udacity Homework

    24/44

    # set the initial value to 1 - not 0, not anything else (see fnenu's post)

    product = 1

    # initialize loop-controlling variables

    i = 0

    length = len(p) # see Unit3.15 and Unit3.16 for explanation of len() function

    # go through all values in the list (from its beginning to its end)

    # and sequentialy multipy them

    while i < length:

    product = product * p[i]

    i = i + 1 # I am constantly forgetting to write put this line in

    $ finally return the computed value

    return product

    This assignment is yet another example of noticing how are you doing it manually as I mentionedinHW2 post:

    You note down the product you have at the beginning (i.e. 1).

    Then you go through all elements of the list, one by one

    And for each of them, you overwrite your noted product by new number computed

    as *

    At the end, you have the final result written in your note

    HW3.4 Greatest:

    The second one from "Setting initial value correctly" series. It reminds me of very simillar exampleinStroustrup's book, where he is computing minimum temperature measured at some place during

    one month and mistakenly sets the initial maximum value to zero. And then winter month, with all

    temperatures below zero comes... (Disclaimer: The example was not exactly this one, but I have

    borrowed my copy of that book to one of my friends and I do not remember it exactly - message is

    the same, however.)

    #Define a procedure, greatest,

    http://www.udacity-forums.com/cs101/questions/24872/homework2-correct-solutionshttp://www.udacity-forums.com/cs101/questions/24872/homework2-correct-solutionshttp://www.udacity-forums.com/cs101/questions/24872/homework2-correct-solutionshttp://www.udacity-forums.com/cs101/questions/22952/need-book-about-algorithms-and-logichttp://www.udacity-forums.com/cs101/questions/22952/need-book-about-algorithms-and-logichttp://www.udacity-forums.com/cs101/questions/22952/need-book-about-algorithms-and-logichttp://www.udacity-forums.com/cs101/questions/22952/need-book-about-algorithms-and-logichttp://www.udacity-forums.com/cs101/questions/24872/homework2-correct-solutions
  • 8/2/2019 CS101 Udacity Homework

    25/44

    #that takes as input a list

    #of positive numbers, and

    #returns the greatest number

    #in that list. If the input

    #list is empty, the output

    #should be 0.

    #greatest([4,23,1]) => 23

    #greatest([]) => 0

    def greatest(p):

    # at first check for empty list

    if not p:

    return 0

    # this is the best initial value I can think of,

    # however 0 would do as well in this assignment,

    # because "takes as input a list of POSITIVE numbers"

    max = p[0]

    # go through all the values in the list

    for val in p:

    # and if some of them is higher than any of them before

    if max < val:

    # update the maximum value

  • 8/2/2019 CS101 Udacity Homework

    26/44

    max = val

    # finally, return result

    return max

    It is actually not necessary to cycle also through the first element of the list, since variable max was

    initially set to its value, but it would be pretty ugly to use while-loop (see HW3.3) and other means of

    doing it were not yet discussed in lectures.

    To repeat myself again, all you need to do is carefully observe all the steps you do, while computing

    the result manually:

    You note down the initial value (0 is sufficient here, but the value of the first element, or at least

    negative infinity, i.e. the lowest possible value, would be better in general).

    Then you go through all elements of the list, one by one

    And for each of them, you compare the noted-down value with the element's value.

    In case the element's value is higher than the noted-down value, you overwrite noted-

    down value by the element's value.

    At the end, you have the final result written in your note

    HW3.5 Lists of Lists:

    And finally the concluding part of the series. However, this one is, besides for loop, also about lists

    of lists. It is about understanding the concept of list-inside-a-list and for-loop going through elements

    of a list.

    #Define a procedure, total_enrollment,

    #that takes as an input a list of elements,

    #where each element is a list containing

    #three elements: a university name,

    #the total number of students enrollect,

    #and the annual tuition.

    #The procedure should return two numbers,

    #not a string,

    #giving the total number of students

    #enrolled at all of the universities

  • 8/2/2019 CS101 Udacity Homework

    27/44

    #in the list, and the total tuition

    #(which is the sum of the number

    #of students enrolled times the

    #tuition for each university).

    udacious_univs = [['Udacity',90000,0]]

    usa_univs = [ ['California Institute of Technology',2175,37704],

    ['Harvard',19627,39849],

    ['Massachusetts Institute of Technology',10566,40732],

    ['Princeton',7802,37000],

    ['Rice',5879,35551],

    ['Stanford',19535,40569],

    ['Yale',11701,40500] ]

    #>>> print total_enrollment(udacious_univs)

    #(90000,0)

    #>>> print total_enrollment(usa_univs)

    #(77285,3058581079L)

    def total_enrollment(univs):

    # be sure that you choose correct initial values

    # (we are going to produce sum, thus initially we need 0)

    students = 0

    tuition = 0

  • 8/2/2019 CS101 Udacity Homework

    28/44

    # go through all elements of the list

    for val in univs:

    # elements of the list turn out to be lists, again:

    # - there is number of enrolled students at index 1

    students = students + val[1]

    # - and annual tuition per student at index 2

    # (parentheses around multiplication are actually not needed,

    # but they do no harm and I have a rule, which works very well

    # for me quite a few years already: "If you are not 100% sure

    # about operator precedences, use parentheses.")

    tuition = tuition + (val[1] * val[2])

    # function returns not one, but two values (see Unit2.6)

    return students, tuition

    I will not repeat the "observe your manual steps" story again, because it is the same all the time and

    this post is getting long anyway (In case someone is interested in it anyway, please post a note and I

    will write it to you as a reply.) What I will do, though, is that I will stress again that there are quite a

    lot of problems, which can be solved just using this very simple "technique".

    HW3.6 Max Pages:

    I can imagine that this one would look pretty scary at the first glance, but it turns out that it is not that

    bad. The only thing, which needs to be done is to introduce a counter of pages, which has been

    crowled, initialize it to 0 at the start ({1}), increment it for each page we crawl ({2}) and add

    condition, which will stop us when the counter reaches desired value ({3}).

    #Modify the crawl_web procedure

    #to take a second parameter,

    #max_pages, that limits the

  • 8/2/2019 CS101 Udacity Homework

    29/44

    #number of pages to crawl.

    #Your procedure should

    #terminate the crawl after

    #max_pages different pages

    #have been crawled, or when

    #there are no more pages to crawl.

    def crawl_web(seed,max_pages):

    tocrawl = [seed]

    crawled = []

    # {1}: no pages have been crawled, yet

    pages = 0

    # {3}: the second part of condition

    while tocrawl and pages < max_pages:

    page = tocrawl.pop()

    if page not in crawled:

    union(tocrawl, get_all_links(get_page(page)))

    crawled.append(page)

    # {2}: a page has been crawled, increment counter

    pages = pages + 1

    return crawled

    HW3.7 Max Depth:

  • 8/2/2019 CS101 Udacity Homework

    30/44

    This is where homework #3 starts to be challenging. In fact, I think that this two-star assignment is

    more difficult than HW3.8, which had three stars.

    The basic thing, which needs to be solved here is how to store the current depth value, which needs

    to be compared against desired maximum. One possible, and very obvious to someone, with

    programming experience, is to make crawl_web functionrecursivelycall itself, justwith max_depth lowered by one, for each URL returned by get_all_links function, until it needs to

    make call with max_depth < 0. We would not even need tocrawl variable anymore, but we would

    need to pass crawled (or make it global variable, which is kind of ugly) - it is thus not viable solution,

    here, because we do not want to modify crawl_web's header.

    The thing about recursion is, each and every recursive function has its non-recursive equivalent

    using loops. The very same applies to above described solution:

    #TWO GOLD STARS#

    #Modify the crawl_web procedure

    #to take a second parameter,

    #max_depth, that limits the

    #minimum number of consecutive

    #links that would need to be followed

    #from the seed page to reach this

    #page. For example, if max_depth

    #is 0, the only page that should

    #be crawled is the seed page.

    #If max_depth is 1, the pages

    #that should be crawled are the

    #seed page and every page that links

    #to it directly. If max_depth is 2,

    #the crawl should also include all pages

    #that are linked to by these pages.

    def crawl_web(seed,max_depth): tocrawl = [[0,[seed]]] crawled = []

    while tocrawl:

    http://en.wikipedia.org/wiki/Recursion_%28computer_science%29http://en.wikipedia.org/wiki/Recursion_%28computer_science%29http://en.wikipedia.org/wiki/Recursion_%28computer_science%29http://en.wikipedia.org/wiki/Recursion_%28computer_science%29
  • 8/2/2019 CS101 Udacity Homework

    31/44

    pages = tocrawl.pop()

    add_tocrawl = []

    for page in pages[1]: # {1}

    if page not in crawled:

    if pages[0] < max_depth: # {2}

    union(add_tocrawl, get_all_links(get_page(page)))

    crawled.append(page)

    if add_tocrawl: # {3}

    tocrawl.append([pages[0]+1, add_tocrawl])

    return crawled

    The depth of each URL (actually, of each set of URLs) is stored directly in tocrawl variable. Its

    format goes like this:

    tocrawl = [[,

    [, , ..., ]],

    [,

    [, , ..., ]],

    ...

    [,

    [, , ..., ]]]

    This is not particularily nice, but it works and it can be written much nicer using classes and other

    tools of the language, which were not yet discussed in the lecture.

    The rest of modifications to the function, after we solved the biggest problem of storing depth, is

    relatively straight forward. We need to add for-loop ({1}) to go through all URLs in pages[1] - that is

    new place for storing list of URLs to be crawled (pages[0] stores their depth - see above). The

    second modification is augmentation of algorithm for adding URLs to tocrawl list. We want to do that

    only in case we did not reach our max_depth, yet ({2}). Because we have changed structure

  • 8/2/2019 CS101 Udacity Homework

    32/44

    of tocrawl, we do not want to add URLs to it right after we find them - we want to collect as many as

    we can into the add_tocrawl, mark them all with the depth value and insert whole such "package" (if

    it is not empty, of course) into tocrawl variable ({3}).

    It should be noted, that above described solution is not the simplest one. It is not necessary to use

    an optimization, I have used, i.e. each URL might have its own depth-tag. In that case, for-loop ({1})nor add_tocrawl variable would not be needed.

    HW3.8 Sudoku:

    Note: I posted my "unit-test" inthis thread. Just copy-paste the code at the end of your code and

    run it.

    There waslot of discussionabout 9-lines long solutions. I did not try to provide one so I do not

    know how does it look like and thus I can not judge it. However, I would like to emphasize that the

    better measure of code quality are its readability andcomplexity. Do not take me wrong, however -

    it was explicitely stated by several people in that discussion that they agree with this and that the

    thread's purpose is just to provide kind of brain teaser for more experienced students (which is onlycommendable).

    One more interesting thing in that discussion was post by@PeterUdacity, who wrote that in real

    Pythonic way, it can be done just on 4 lines of code. And this is very true, because in real life, you do

    not try to reinvent the wheel. There are lots of libraries out there, which can be used freely - and that

    is the "Pythonic way": "I just imported antigravity"... Thus I would say that this 4-liner would look

    something like this (Disclaimer: I just know that there is some sudoku library for Python, but I do not

    know anything about it, thus the below code is just an example):

    1 import sudoku

    2

    3 def check_sudoku(sudoku):

    4 return sudoku.check(sudoku)

    Anyway, my solution (those, who do have mentioned 9-liners correct, please paste them in answers,

    and especially, I would like to ask@Angelto past his solution, which I was reading handles many

    very interesting cases) goes like this:

    #Define a procedure, check_sudoku,

    #that takes as input a square list

    #of lists representing an n x n

    #sudoku puzzle solution and returns

    #True if the input is a valid

    #sudoku square and returns False

    http://www.udacity-forums.com/cs101/questions/35230/hw38-testhttp://www.udacity-forums.com/cs101/questions/35230/hw38-testhttp://www.udacity-forums.com/cs101/questions/35230/hw38-testhttp://www.udacity-forums.com/cs101/questions/32928/anyone-solved-sudoku-with-less-than-9-lines-of-codehttp://www.udacity-forums.com/cs101/questions/32928/anyone-solved-sudoku-with-less-than-9-lines-of-codehttp://www.udacity-forums.com/cs101/questions/32928/anyone-solved-sudoku-with-less-than-9-lines-of-codehttp://en.wikipedia.org/wiki/Big_ohhttp://en.wikipedia.org/wiki/Big_ohhttp://en.wikipedia.org/wiki/Big_ohhttp://www.udacity-forums.com/cs101/cs101/users/4/peterudacityhttp://www.udacity-forums.com/cs101/cs101/users/4/peterudacityhttp://www.udacity-forums.com/cs101/cs101/users/4/peterudacityhttp://www.udacity-forums.com/cs101/cs101/users/248/angelhttp://www.udacity-forums.com/cs101/cs101/users/248/angelhttp://www.udacity-forums.com/cs101/cs101/users/248/angelhttp://www.udacity-forums.com/cs101/cs101/users/248/angelhttp://www.udacity-forums.com/cs101/cs101/users/4/peterudacityhttp://en.wikipedia.org/wiki/Big_ohhttp://www.udacity-forums.com/cs101/questions/32928/anyone-solved-sudoku-with-less-than-9-lines-of-codehttp://www.udacity-forums.com/cs101/questions/35230/hw38-test
  • 8/2/2019 CS101 Udacity Homework

    33/44

    #otherwise.

    #A valid sudoku square satisfies these

    #two properties:

    # 1. Each column of the square contains

    # each of the numbers from 1 to n exactly once.

    # 2. Each row of the square contains each

    # of the numbers from 1 to n exactly once.

    def check_sudoku(sudoku):

    n = len(sudoku)

    if n < 1:

    return False

    for i in range(n):

    if len(sudoku[i]) != n:

    return False

    row_chk = []

    col_chk = []

    for k in range(n):

    row_chk.append(False)

    col_chk.append(False)

  • 8/2/2019 CS101 Udacity Homework

    34/44

    for j in range(n):

    row_val = sudoku[i][j]

    if row_val < 1 or n < row_val or row_chk[row_val-1]:

    return False

    else:

    row_chk[row_val-1] = True

    col_val = sudoku[j][i]

    if col_val < 1 or n < col_val or col_chk[col_val-1]:

    return False

    else:

    col_chk[sudoku[j][i]-1] = True

    return True

    We just go through all rows and columnsi ({1}) (in the same time - there is no point to do it twice,

    first time for rows and second time for columns, but this does not make much of a difference) and

    use auxiliary variables row_chk and col_chkto check that each row and each column contain one

    and exactly one occurence of each number from set {1 .. n}. Initially, those two auxiliary variablesare set to be lists, containing only False values ({2}) and each time we find some number, we set

    corresponding False to True ({3}).

    All the rest are just "paranoid" sanity checks (which, and much more of them, are really required in

    real-life scenario). E.g. we are checking value being out of range (otherwise, the algorithm would

    crash on "index out of range" error) ({4}).

    Q1

    1,0,1

    Q2

    2,4

    Examples

    p=['hi','you']

    def proc1(p):

  • 8/2/2019 CS101 Udacity Homework

    35/44

    p[0]=p[1]

    return p

    print proc1(p)

    p=['hi','you']

    def proc1(p):

    p=p + [1]

    return p

    print proc1(p)

    p=['hi','you']

    def proc1(p):

    q=p

    p.append(3)

    q.pop()

    return p

    print proc1(p)

    p=['hi','you']

    def proc1(p):

    q=[]while p:

    q.append(p.pop())

    while q:

    p.append(q.pop())

    return p

    print proc1(p)

    Q3

    #Define a procedure, product_list,

    #takes as input a list of numbers,

    #and returns a number that is

    #the result of multiplying all

    #those numbers together.

    #product_list([9]) => 9

    #product_list([1,2,3,4]) => 24

    def product_list(p):

    s=1

    for e in p:

    s=s*e

    return s

    print product_list([9])

    print product_list([1,2,3,4])

    Q4

    #Define a procedure, greatest,

    #that takes as input a list

  • 8/2/2019 CS101 Udacity Homework

    36/44

    #of positive numbers, and

    #returns the greatest number

    #in that list. If the input

    #list is empty, the output

    #should be 0.

    #greatest([4,23,1]) => 23

    #greatest([]) => 0

    def greatest(p):

    if len(p)!=0:

    greatest = p[0]

    for i in range(len(p)):

    if greatest < p[i]:

    greatest = p[i]

    if len(p)==0:

    greatest=0

    return greatest

    print greatest([4,23,1])

    print greatest([])

    Q5

    #Define a procedure, total_enrollment,

    #that takes as an input a list of elements,

    #where each element is a list containing

    #three elements: a university name,

    #the total number of students enrollect,

    #and the annual tuition.

    #The procedure should return two numbers,

    #not a string,

    #giving the total number of students

    #enrolled at all of the universities

    #in the list, and the total tuition

    #(which is the sum of the number

    #of students enrolled times the

    #tuition for each university).

    udacious_univs = [['Udacity',90000,0]]

    usa_univs = [ ['California Institute of Technology',2175,37704],

    ['Harvard',19627,39849],

    ['Massachusetts Institute of Technology',10566,40732],

  • 8/2/2019 CS101 Udacity Homework

    37/44

    ['Princeton',7802,37000],

    ['Rice',5879,35551],

    ['Stanford',19535,40569],

    ['Yale',11701,40500] ]

    #>>> print total_enrollment(udacious_univs)

    #(90000,0)

    #>>> print total_enrollment(usa_univs)

    #(77285,3058581079L)

    def total_enrollment(list):

    ans1 = 0

    ans2 = 0

    ans3 = 0

    for e in list:

    ans1 = ans1 + e[1]

    ans2 = ans2 + e[2]

    ans3 = ans3 + (e[1] * e[2])

    return ans1, ans3

    print total_enrollment(usa_univs)

    print total_enrollment(udacious_univs)

    Q6

    #The web crawler we built at the

    #end of Unit 2 has some serious

    #flaws if we were going to use

    #it in a real crawler. One

    #problem is if we start with

    #a good seed page, it might

    #run for an extremely long

    #time (even forever, since the

    #number of URLS on the web is not

    #actually finite). The final two

    #questions of the homework ask

    #you to explore two different ways

    #to limit the pages that it can

    #crawl.

    #######

  • 8/2/2019 CS101 Udacity Homework

    38/44

    #Modify the crawl_web procedure

    #to take a second parameter,

    #max_pages, that limits the

    #number of pages to crawl.

    #Your procedure should

    #terminate the crawl after

    #max_pages different pages

    #have been crawled, or when

    #there are no more pages to crawl.

    #The following definition of

    #get_page provides an interface

    #to the website found at

    #http://www.udacity.com/cs101x/index.html

    #The function output order does not affect grading.

    #crawl_web("http://www.udacity.com/cs101x/index.html",1) =>

    ['http://www.udacity.com/cs101x/index.html']

    #crawl_web("http://www.udacity.com/cs101x/index.html",3) =>

    ['http://www.udacity.com/cs101x/index.html', 'http://www.udacity.com/cs101x/flying.html',

    'http://www.udacity.com/cs101x/walking.html']

    #crawl_web("http://www.udacity.com/cs101x/index.html",500) =>

    ['http://www.udacity.com/cs101x/index.html', 'http://www.udacity.com/cs101x/flying.html',

    'http://www.udacity.com/cs101x/walking.html', 'http://www.udacity.com/cs101x/crawling.html',

    'http://www.udacity.com/cs101x/kicking.html']

    def get_page(url):

    try:

    if url == "http://www.udacity.com/cs101x/index.html":

    return ' This is a test page for learning to crawl!

    It is a good idea to learn to crawl before you try to walk or fly.

    '

    elif url == "http://www.udacity.com/cs101x/crawling.html":

    return ' I have not learned to crawl yet, but I am quite good at kicking. '

    elif url == "http://www.udacity.com/cs101x/walking.html":

    return ' I cant get enough crawling! '

  • 8/2/2019 CS101 Udacity Homework

    39/44

    elif url == "http://www.udacity.com/cs101x/flying.html":

    return ' The magic words are Squeamish Ossifrage! '

    except:

    return ""

    return ""

    def get_next_target(page):

    start_link = page.find('

  • 8/2/2019 CS101 Udacity Homework

    40/44

    print crawl_web("http://www.udacity.com/cs101x/index.html",0) # =>

    ['http://www.udacity.com/cs101x/index.html']

    print crawl_web("http://www.udacity.com/cs101x/index.html",1) #=>

    ['http://www.udacity.com/cs101x/index.html', 'http://www.udacity.com/cs101x/flying.html',

    'http://www.udacity.com/cs101x/walking.html', 'http://www.udacity.com/cs101x/crawling.html']

    print crawl_web("http://www.udacity.com/cs101x/index.html",50) #=>

    ['http://www.udacity.com/cs101x/index.html', 'http://www.udacity.com/cs101x/flying.html',

    'http://www.udacity.com/cs101x/walking.html', 'http://www.udacity.com/cs101x/crawling.html',

    'http://www.udacity.com/cs101x/kicking.html']

    Q7

    #The web crawler we built at the

    #end of Unit 2 has some serious

    #flaws if we were going to use

    #it in a real crawler. One

    #problem is if we start with

    #a good seed page, it might

    #run for an extremely long

    #time (even forever, since the

    #number of URLS on the web is not

    #actually finite). The final two

    #questions of the homework ask

    #you to explore two different ways

    #to limit the pages that it can

    #crawl.

    #######

    #Modify the crawl_web procedure

    #to take a second parameter,

    #max_pages, that limits the

    #number of pages to crawl.

    #Your procedure should

    #terminate the crawl after

    #max_pages different pages

    #have been crawled, or when

    #there are no more pages to crawl.

  • 8/2/2019 CS101 Udacity Homework

    41/44

    #The following definition of

    #get_page provides an interface

    #to the website found at

    #http://www.udacity.com/cs101x/index.html

    #The function output order does not affect grading.

    #crawl_web("http://www.udacity.com/cs101x/index.html",1) =>

    ['http://www.udacity.com/cs101x/index.html']

    #crawl_web("http://www.udacity.com/cs101x/index.html",3) =>

    ['http://www.udacity.com/cs101x/index.html', 'http://www.udacity.com/cs101x/flying.html',

    'http://www.udacity.com/cs101x/walking.html']

    #crawl_web("http://www.udacity.com/cs101x/index.html",500) =>

    ['http://www.udacity.com/cs101x/index.html', 'http://www.udacity.com/cs101x/flying.html',

    'http://www.udacity.com/cs101x/walking.html', 'http://www.udacity.com/cs101x/crawling.html',

    'http://www.udacity.com/cs101x/kicking.html']

    def get_page(url):

    try:

    if url == "http://www.udacity.com/cs101x/index.html":

    return ' This is a test page for learning to crawl!

    It is a good idea to learn to crawl before you try to walk or fly.

    '

    elif url == "http://www.udacity.com/cs101x/crawling.html":

    return ' I have not learned to crawl yet, but I am quite good at kicking. '

    elif url == "http://www.udacity.com/cs101x/walking.html":

    return ' I cant get enough crawling! '

    elif url == "http://www.udacity.com/cs101x/flying.html":

    return ' The magic words are Squeamish Ossifrage! '

    except:

    return ""

    return ""

    def get_next_target(page):

    start_link = page.find('

  • 8/2/2019 CS101 Udacity Homework

    42/44

    end_quote = page.find('"', start_quote + 1)

    url = page[start_quote + 1:end_quote]

    return url, end_quote

    def union(p,q):

    for e in q:

    if e not in p:

    p.append(e)

    def get_all_links(page):

    links = []

    while True:

    url,endpos = get_next_target(page)

    if url:

    links.append(url)

    page = page[endpos:]

    else:

    break

    return links

    def crawl_web(seed,max_pages):

    tocrawl = [seed]

    crawled = []

    while tocrawl:

    page = tocrawl.pop()

    if page not in crawled:

    union(tocrawl, get_all_links(get_page(page)))

    crawled.append(page)

    return crawled

    Q8

    #THREE GOLD STARS

    #Sudoku [http://en.wikipedia.org/wiki/Sudoku]

    #is a logic puzzle where a game

    #is defined by a partially filled

    #9 x 9 square of digits where each square

    #contains one of the digits 1,2,3,4,5,6,7,8,9.

    #For this question we will generalize

    #and simplify the game.

  • 8/2/2019 CS101 Udacity Homework

    43/44

    #Define a procedure, check_sudoku,

    #that takes as input a square list

    #of lists representing an n x n

    #sudoku puzzle solution and returns

    #True if the input is a valid

    #sudoku square and returns False

    #otherwise.

    #A valid sudoku square satisfies these

    #two properties:

    # 1. Each column of the square contains

    # each of the numbers from 1 to n exactly once.

    # 2. Each row of the square contains each

    # of the numbers from 1 to n exactly once.

    correct = [[1,2,3],

    [2,3,1],

    [3,1,2]]

    incorrect = [[1,2,3,4],

    [2,3,1,3],

    [3,1,2,3],

    [4,4,4,4]]

    def check_sudoku(sln):

    i = 1

    while i 1:

    return False

    j = 1

    found = 0

    while j

  • 8/2/2019 CS101 Udacity Homework

    44/44

    found = found + 1

    j = j + 1

    if found > 1:

    return False

    i = i + 1

    return True

    print check_sudoku(correct)

    print check_sudoku(incorrect)