import random min = 1 max = 6 roll_again = "yes" while roll_again == "yes" or roll_again == "y": print "Rolling the dices..." print "The values are...." print random.randint(min, max) print random.randint(min, max) roll_again = raw_input("Roll the dices again?)
# Hello World program in Python class MyClass(): def __init__(self,name,age): self.name=name self.age=age def prin(self): print(self.name) p1=MyClass("AARTI",32) p1.prin() print ("Hello World!"); class Student(MyClass): pass p=Student("sakshi",27) p.prin()
# Hello World program in Python class Sample(): def __init__(self,name,age): self.name=name self.age=age p1=Sample("Ritu",21) print(p1.name) print(p1.age)
# Week 4 Cohort Questions # Get DNA Base Count def get_base_counts(dna): dna_list = list(dna) ans = {} bases = ['A', 'C', 'G', 'T'] for k in dna_list: if k == 'A' or k == 'C' or k == 'G' or k == 'T': pass else: return 'The input DNA string is invalid' for i in bases: count = 0 for a in dna_list: if a == i: count += 1 ans[i] = count return ans def leap_year(year): if year%4 != 0: return False elif year%100 != 0: return True elif year%400 != 0: return False else: return True def day_of_week_jan1(year): day = (1 + 5*((year - 1)%4)+4*((year - 1)%100)+6*((year - 1)%400))%7 return day def num_days_in_month(month_num, leap_year): num = 0 if month_num == 2: if leap_year == True: num = 29 elif True: num = 28 if month_num == 1 or month_num == 3 or month_num == 5 or month_num == 7 or month_num == 8 or month_num == 10 or month_num == 12: num = 31 elif month_num == 4 or month_num == 6 or month_num == 9 or month_num == 11: num = 30 return num def day_of_year(month, leap_year): day = 0 for i in range(1, month+1): day += num_days_in_month(i-1, leap_year) return day def first_day_of_month(year, month): day = day_of_week_jan1(year) + (day_of_year(month, leap_year(year)))%7 while day >= 7: day -= 7 return day def construct_cal_month(month_num, first_day_of_month, num_days_in_month): Month = month[month_num] num = num_days_in_month num_list = list(range(1, num + 1)) day_list = list() for i in num_list: day_list.append("{0:3d}".format(i)) line = "" p = 0 if first_day_of_month == 7: line = line else: line = line + " " * first_day_of_month while p < len(day_list): line += day_list[p] p += 1 linelist = list(line) linelist.insert(21, "+") linelist.insert(43, "+") linelist.insert(65, "+") linelist.insert(87, "+") linelist.insert(109 ,"+") breaker = "" linestring = breaker.join(linelist) #print(linestring) newlist = linestring.split("+") #print(newlist) result = [] result.append(Month) for i in newlist: result.append(i) if result[len(result)-1] == "": result.pop() return result def construct_cal_year(year): yearlist = [] yearlist.append(year) for i in range(1,13): yearlist.append(construct_cal_month(i,first_day_of_month(year, i), num_days_in_month(i, leap_year(year)))) return yearlist def display_calendar(year): output = construct_cal_year(year) outputstring = "" for i in output: if i == year: pass else: outputstring += i[0]+"\n" outputstring += " S M T W T F S\n" k = 1 while k < len(i): outputstring += i[k] +"\n" k += 1 if len(i) > 5: outputstring += "\n" outputstring = outputstring.rstrip() return outputstring # Game: Craps is a popular dice game played in casinos. Write a program allowing you to play a variation of the game. This is how the game would be played: # (a) For the first round, roll two dice. Each die has six faces, and each face reflects a value from 1 to 6. Check the sum of the two dice. # 1. If the sum is 2, 3 or 12 (called craps), you lose # 2. If the sum is 7 or 11 (called natural), you win # 3. If the sum is another value (i.e. 4,5,6,8,9, or 10), you earn points equal to the sum obtained. # (b) Continue to roll the dice until the sum of both dice is either a 7 or the points obtained in the first round. # 1. If 7 is rolled, you lose # 2. If the sum obtained is equal to the points you obtained in the first round, you win # 3. For other sums, continue to roll the dice #Your program acts as a single player, and should print the output you see below when the #various conditions are met. The function play_craps() should return 0 if you lose and #1 if you win. The main program is given here, together with the sub functions you will #need to dene. Hint: if you are unsure how to start, take a look at the main function #play_craps() and see how the sub functions are being called by the main function, to get #a better idea of what is required of each sub function. import random as rng craps=set([2,3,12]) naturals=set([7,11]) rng.seed(a = None) def roll_two_dices(): n1 = rng.randrange(1, 7) n2 = rng.randrange(1, 7) return [n1, n2] def print_lose(): print('You lose') def print_win(): print('You win') def print_point(p): print('Your points are' ,p) def is_craps(n): for i in craps: if n == i: return True return False def is_naturals(n): for i in naturals: if n == i: return True return False # ATTENTION! # You shouldn't need to edit the function below def play_craps(): point=-1 while True: n1,n2=roll_two_dices() sumn=n1+n2 print ('You rolled %d + %d = %d'%(n1,n2,sumn)) #initial points obtained here if point==-1: #At the initialisation of point == -1 (see line 29) if is_craps(sumn): #if the sum is in the set of craps print_lose() #then it is an immediate loss return 0 elif is_naturals(sumn): #if the sum is in the set of naturals print_win() #then it is an immediate win return 1 point=sumn print_point(point) else: if sumn==7: print_lose() return 0 elif sumn==point: print_win() return 1 #goal of the game is to keep rolling dice until the sum == points obtained # Calendar Year month = {1:"January", 2:"February", 3:"March",4:"April", 5:"May", 6:"June", 7:"July", 8:"August", 9:"September", 10:"October", 11:"November", 12:"December"} def leap_year(year): if year%4 != 0: return False elif year%100 != 0: return True elif year%400 != 0: return False else: return True def day_of_week_jan1(year): day = (1 + 5*((year - 1)%4)+4*((year - 1)%100)+6*((year - 1)%400))%7 return day def num_days_in_month(month_num, leap_year): num = 0 if month_num == 2: if leap_year == True: num = 29 elif True: num = 28 if month_num == 1 or month_num == 3 or month_num == 5 or month_num == 7 or month_num == 8 or month_num == 10 or month_num == 12: num = 31 elif month_num == 4 or month_num == 6 or month_num == 9 or month_num == 11: num = 30 return num def day_of_year(month, leap_year): day = 0 for i in range(1, month+1): day += num_days_in_month(i-1, leap_year) return day def first_day_of_month(year, month): day = day_of_week_jan1(year) + (day_of_year(month, leap_year(year)))%7 while day >= 7: day -= 7 return day def construct_cal_month(month_num, first_day_of_month, num_days_in_month): Month = month[month_num] num = num_days_in_month num_list = list(range(1, num + 1)) day_list = list() for i in num_list: day_list.append("{0:3d}".format(i)) line = "" p = 0 if first_day_of_month == 7: line = line else: line = line + " " * first_day_of_month while p < len(day_list): line += day_list[p] p += 1 linelist = list(line) linelist.insert(21, "+") linelist.insert(43, "+") linelist.insert(65, "+") linelist.insert(87, "+") linelist.insert(109 ,"+") breaker = "" linestring = breaker.join(linelist) #print(linestring) newlist = linestring.split("+") #print(newlist) result = [] result.append(Month) for i in newlist: result.append(i) if result[len(result)-1] == "": result.pop() return result def construct_cal_year(year): yearlist = [] yearlist.append(year) for i in range(1,13): yearlist.append(construct_cal_month(i,first_day_of_month(year, i), num_days_in_month(i, leap_year(year)))) return yearlist def display_calendar(year): output = construct_cal_year(year) outputstring = "" for i in output: if i == year: pass else: outputstring += i[0]+"\n" outputstring += " S M T W T F S\n" k = 1 while k < len(i): outputstring += i[k] +"\n" k += 1 if len(i) > 5: outputstring += "\n" outputstring = outputstring.rstrip() return outputstring # Factorial def fact_rec(n): if n == 1 or n == 0: return 1 else: return n*fact_rec(n-1) # Modular Design # NB: you do not need to submit the 'get_data' function def get_data(): integer1 = input('Enter first integer: ') integer2 = input('Enter second integer: ') return integer1, integer2 def extract_values(values): str_list = values.split() for i in range(len(str_list)): str_list[i] = int(str_list[i]) int_tuple = (str_list[0], str_list[1]) return int_tuple def calc_ratios(values): try: return values[0]/values[1] except ZeroDivisionError: return None # Week 6 Cohort Questions # Reverse String def reverse(string): r = [] for i in range(len(string)-1, -1, -1): r.append(string[i]) return ''.join(r) # Check Password Validity def check_password(password): if len(password)<8: return False for i in password: if 48<=ord(i)<=57 or 65<=ord(i)<=90 or 97<=ord(i)<=122: pass else: return False count = 0 for i in password: if 48<=ord(i)<=57: count += 1 if count < 2: return False return True # Longest Common Prefix def longest_common_prefix(string1, string2): ans = "" a = 0 while True: if string1[a] == string2[a]: ans += string1[a] elif string1[a] != string2[a]: break if len(ans)==len(string1) or len(ans)==len(string2): break a += 1 return ans # Week 6 Homework # Strings: Binary to Decimal def binary_to_decimal(binstr): return int(binstr,2) # Compressed string to uncompressed string def uncompress(string): numbers = [] strings = [] for i in string: if i.isdigit(): numbers.append(i) else: strings.append(i) ans = '' k = 0 for a in numbers: ans += int(a)*strings[k] k += 1 return ans # DNA Base counts def get_base_counts2(dna): dna_list = list(dna) ans = {} bases = ['A', 'C', 'G', 'T'] for k in dna_list: if k == 'A' or k == 'C' or k == 'G' or k == 'T': pass for i in bases: count = 0 for a in dna_list: if a == i: count += 1 ans[i] = count if len(ans)==0: return 'The input DNA string is invalid' return ans # Files and I/O f = open('text_files/constants.txt', 'r') def get_fundamental_constants(f): ff = f.readlines() ans = {} for i in ff: nameget = False for a in i.split(): isname = True if nameget == False: for b in a: if 65<=ord(b)<=90 or 97<=ord(b)<=122: continue else: nameget = True isname = False break if isname==True and nameget==False: name = a try: num = float(a) except ValueError: pass try: num = int(a) except ValueError: pass try: ans[name] = num except UnboundLocalError: pass return ans # Files: Process Scores f = open('text_files/scores.txt') def process_scores(f): ff = f.readline() total = 0 for i in ff.split(): total += float(i) fff = ff.split() avg = total/(len(fff)) return total, avg # Week 8 Cohort Questions ## CS1 COORDINATE CLASS## class Coordinate: def __init__(self, x=0, y=0): self.x = x self.y = y def magnitude(self): return (self.x ** 2 + self.y ** 2) ** .5 def translate(self, dx, dy): self.x += dx self.y += dy return self def __eq__(self, other): return (self.x, self.y) == (other.x, other.y) ## CS2 CELCIUS CLASS ## class Celsius: def __init__(self, temperature=0): self.C = temperature def to_fahrenheit(self): return (9 / 5. * self.C) + 32 def get_temperature(self): return self.C def set_temperature(self, value): if value > -273: self.C = value else: self.C = -273 temperature = property(get_temperature, set_temperature) ## CS3 STOPWATCH CLASS ## import time class StopWatch: def __init__(self): self.start_time = time.time() self.end_time = -1 def start(self): self.start_time = time.time() self.end_time = -1 def stop(self): self.end_time = time.time() def elapsed_time(self): if self.end_time == -1: return None elif self.end_time - self.start_time < 0: return None else: return round(self.end_time - self.start_time, 1) ## CS4 STRAIGHTLINE CLASS ## class Line: def __init__(self, c0, c1): self.c0 = c0 self.c1 = c1 def __call__(self, x): return float(self.c0 + self.c1 * x) def table(self, L, R, n): s = '' if R == L: n = 1 import numpy as np for x in np.linspace(L, R, n): y = self(x) s += '%10.2f%10.2f\n' % (x, y) return 'Error in printing table' if s == '' or L > R else s line = Line(3, 4) print(line(2)) print(Line.table(line, 3, 2, 15)) ## HW1 TIME CLASS ## class Time: def __init__(self, hours=0, minutes=0, seconds=0): self._hours = hours % 24 self._minutes = minutes % 60 self._seconds = seconds % 60 def get(time): minutes = time._hours * 60 + time._minutes seconds = minutes * 60 + time._seconds return seconds def __str__(self): return "Time: %d:%d:%d" % (self._hours, self._minutes, self._seconds) def seconds(self, seconds): self._hours = seconds // 3600 % 24 seconds -= self._hours * 3600 self._minutes = seconds // 60 % 60 seconds -= self._minutes * 60 self._seconds = seconds % 60 return seconds elapsed_time = property(get, seconds) t = Time(100, 19, 10) print(t.elapsed_time) t.elapsed_time = 45550 print(t.elapsed_time) print(t) ## HW2 BANK ACCOUNT CLASS ## class Account: def __init__(self, owner, account_number, amount): self._owner = owner self._account_number = account_number self._balance = amount def deposit(self, amount): self._balance += amount return self def withdraw(self, amount): self._balance -= amount return self def __str__(self): return '%s, %s, balance: %s' % (self._owner, self._account_number, self._balance) ## HW3 NUMERICAL DIFFERENTIATION ## class Diff: def __init__(self, f, h=1e-4): self.f = f self.h = float(h) def __call__(self, x): f, h = self.f, self.h return (f(x + h) - f(x)) / h ## HW4 POLYNOMIAL CLASS ## class Polynomial: def __init__(self, coefficients): self.coeff = coefficients def zip_longest(a, b): for i in range(max(len(a), len(b))): if i >= len(a): yield [b[i]] elif i >= len(b): yield [a[i]] else: yield [a[i], b[i]] i += 1 def __add__(self, target): return Polynomial([sum(i) for i in Polynomial.zip_longest(self.coeff, target.coeff)]) def __sub__(self, target): return Polynomial([sum(i) for i in Polynomial.zip_longest(self.coeff, [-i for i in target.coeff])]) def __call__(self, x): val = [] for i, j in enumerate(self.coeff): val.append(j * x ** i) return sum(val) def __mul__(self, target): ls = [0] * (len(self.coeff) * len(target.coeff) - 1) for i, j in enumerate(self.coeff): for k, l in enumerate(target.coeff): ls[i + k] += j * l end = len(ls) for i in ls[::-1]: if i != 0.: break else: end -= 1 return Polynomial(ls[0:end]) def differentiate(self): ls = [0] * (len(self.coeff) - 1) for i, j in enumerate(self.coeff): ls[i - 1] += i * j self.coeff = ls def derivative(self): deriv = [] power = 1 for i in range(1, len(self.coeff)): deriv.append(self.coeff[i] * power) power += 1 return Polynomial(deriv) p1 = Polynomial([1, -1]) p2 = Polynomial([0, 1, 0, 0, -6, -1]) p3 = p1 + p2 print(p3.coeff) [1, 0, 0, 0, -6, -1] p4 = p1 * p2 print(p4.coeff) [0, 1, -1, 0, -6, 5, 1] p5 = p2.derivative() print(p5.coeff) [1, 0, 0, -24, -5] p = Polynomial([1, 2, 3]) q = Polynomial([2, 3]) r = p - q print(r.coeff) [-1, -1, 3] r = q - p print(r.coeff) [1, 1, -3] P = Polynomial([1, -1]) Q = Polynomial([0, 1, 0, 0, -6, -1]) R = P - Q print(R.coeff) print(R(3)) E = Polynomial([1, 3, 5, 7, 9]) E.differentiate() print(E.coeff) ## EX1 FUNCTION CLASS ## from math import * class F: def __init__(self, a, w): self.a = a self.w = w def __call__(self, x): return (exp(-self.a * x)) * sin(self.w * x) ## EX2 STRAIGHTLINE ALTERNATIVE ## class Line0: def __init__(self, p1, p2): self.p1 = p1 self.p2 = p2 def __call__(self, x): m = (self.p1[1] - self.p2[1]) / (self.p1[0] - self.p2[0]) c = self.p1[1] - m * self.p1[0] return m * x + c # Week 9 ## CS1 COKE ## from libdw import sm class CM(sm.SM): start_state = 0 def get_next_values(self,state, inp): if state == 0 and inp == 50: return (1, (50, '--',0)) if state == 1 and inp == 50: return (0, (0, 'coke',0)) if state == 1 and inp == 100: return (0, (0,'coke',50)) if state == 0 and inp == 100: return (0, (0,'coke',0)) else: return (0, (0,'--',inp)) ## CS2 SIMPLE ACCOUNT ## from libdw import sm class SimpleAccount(sm.SM): def __init__(self, start_deposit): self.M = start_deposit def get_next_values(self, state, inp): state = self.M if self.M < 100 and inp < 0: self.M = state + inp - 5 return self.M, self.M else: self.M = state + inp return self.M, self.M ## HW1 COMMENTS ## from libdw import sm class CommentsSM(sm.SM): start_state = 0 def get_next_values(self, state, inp): if state == 0 and inp != '#': return (0, None) if state == 0 and inp == '#': return (1, inp) if state == 1 and inp !='\n': return (1, inp) if state == 1 and inp == '\n': return (0, None) ## HW2 FIRST WORD ## from libdw import sm class FirstWordSM(sm.SM): start_state = 0 def get_next_values(self, state, inp): if state == 0 and inp in [' ','\n']: return (0, None) if state == 0 and inp not in [' ','\n']: return (1, inp) if state == 1 and inp == ' ': return (2, None) if state == 1 and inp != ' ': return (1, inp) if state == 2 and inp !='\n': return (2, None) if state == 2 and inp == '\n': return (0, None) # Consider a state machine with: Q1: # inputs: 0, 1, 2 # states: 0, 1, 2, 3 # outputs: 0, 1, 2, 3 # initial state: 0 # transition function: # # States 00 0 0 1 2 # old state: 0 1 3 0 # old state: 1 2 0 0 # old state: 2 3 1 0 # old state: 3 0 2 0 # output function: same as transition function # It maybe helpful for you to draw a state diagram of this machine, to visualize its operation. # # What is the best description of this machine? # # Ans: # # It counts forward and backward mod 4, and has a reset input. Q2: # Input: [0,0,2,0,0,0,1,1,1] Output: [1,2,0,1,2,3,2,1,0] Q3: # Output: [3,2,0,1,2,3] Input: [1,1,2,0,0,0] # Midterms 2016 # Q.1 [10 points] # State the similarities and differences between list and dictionary data structures. State what kind of data is suitable for each data structure and give examples. # # Similarities: # # Both lists and dictionaries are mutable. # Both lists and dictionaries can be generated via comprehensions. # Both lists and dictionaries are part of the 'collections' module. # Both lists and dictionaries contain elemets that can be of any combination of data types. # Differences: # # Lists mantain order of thier elements while dictionaries are unordered. # Lists allow duplication while dictionary items are unique. # List items are accessed by index while dictionary items are accessed by keys. # Lists are implemented internally as variable-length arrays while dictionaries are implemented internally as resizable hash tables. # Examples: # # Use dictionaries to associate values with keys for efficient 'by key' seaching: # Telephone { 'Drake' : '1-800-468-546325464' } # Address { 'Sponge Bob' : '124 Conch Street, Bikini Bottom, Pacific Ocean' } # Translation { "EN" : "DE", "red" : "rot", "green" : "grün", "blue" : "blau", "yellow":"gelb" } # Use lists for an ordered sequence of items: # Race standings [ 'me', 'me', 'me again', 'you' ] # Instructions [ 'To add in pot:', 'shark', 'cuttlefish', 'squid', 'mantis shrimp', 'anemone' ] # Sensor readings [ '0.21532', '0.98765', '1.12353', '9999.99999' ] # Q.2 [10 points] # A student wrote the following Python program to instruct the robot to move. From the written code, answer the following: # # a) Explain briefly what the student tries to do with the code. Give some numerical values in your explanation related to the speed of the robot. [3 pts] # # b) How many times is the function increasePower()being called? Explain briefly how you arrived at your answer.[3 pts] # # c) Explain what will happen if the sleep(2) statement is removed from the code? [4 pts] from time import sleep from eBot import eBot ebot = eBot.eBot() ebot.connect() power = 0.1 def increasePower(power): power += 0.1 return power while power <= 1: ebot.wheels(power,power) sleep(2) power=increasePower(power) ebot.disconnect() # # a) The student is trying to accelerate the robot from the speed equivalent of power = 0.1 to that of power = 1 at increments of 0.1 every 2 seconds. # # b) The functions increasePower() is called 9 times. This is as there are 9 intervals between 0.1 and 1 with increment of 0.1. # # c) The robot will accelerate from the speed equivalent of power 0.1 to that of power= 1 instantly. This is as without the sleep(2) command, there is virtually no delay between the sucessive increasePower() commands until the while condition of power = 1 is met. # # Q.3 [5 points] # Write a function norm(z1,z2,z3) that returns the Euclidean norm in 3-dimensional complex space $C^{3}$, where z1, z2,and z3 are complex numbers. The norm is calculated using the following formula: # # $$ ||\ Z\ ||\ :=\ \sqrt{z_1 \overline{z_1}\ +\ z_2 \overline{z_2}\ +\ z_3 \overline{z_3}} $$ # The function should return a real number rather than a complex number, and the number should be rounded to three decimal places. #from numpy.linalg import norm #normal = lambda z1, z2, z3: round(norm([z1,z2,z3]),3) def normal(z1,z2,z3): return round(abs((z1*z1.conjugate() +z2*z2.conjugate()+ z2*z2.conjugate())**.5), 3) ## TEST CASES ## print ('test 1') z1=1+3j z2=-1+3j z3=-1-3j ans=normal(z1,z2,z3) print (ans) print ('test 2') z1=1+2j z2=-1+2j z3=-1-2j ans=normal(z1,z2,z3) print (ans) print ('test 3') z1=1+1j z2=-1+1j z3=-1-1j ans=normal(z1,z2,z3) print (ans) # Q.4 [10 points] # Write a function factors(n) that takes an integer n as an input and returns a list that includes all # the positive number factors of n, where n ≥ 1. The output returns the list of all the factors in an ascending order. def factors(n): return [i for i in range(1,n+1) if n % i == 0] ## TEST CASES ## print ('test 1') ans=factors(6) print (ans) print ('test 2') ans=factors(12) print (ans) print ('test 3') ans=factors(7) print (ans) print ('test 4') ans=factors(15) print (ans) print ('test 5') ans=factors(21) print (ans) print ('test 6') ans=factors(1) print (ans) print ('test 7') ans=factors(9) print (ans) # Q.5 [10 points] # Write a function combinations(n1,n2) that takes in two integers n1 and n2, and returns a list of tuples of all # possible combinations of two integers, both of which range from n1 to n2. The function also returns a second output # which is the total number of all combinations. The output combinations must start from the lower number to the higher # number as shown in the expression below and in the output test cases. You are not allowed to use any built-in function # that gives the same result immediately. def combinations(a,b): return([] if any([a,b])==0 else [(i,j) for i in range(a,b) for j in range(a+1,b+1) if i<j]), len([] if any([a,b])==0 else [(i,j) for i in range(a,b) for j in range(a+1,b+1) if i<j]) ## TEST CASES ## print ('test 1') ans=combinations(1,7) print (ans) print ('test 2') ans=combinations(3,5) print (ans) print ('test 3') ans=combinations(-1,2) print (ans) print ('test 4') ans=combinations(0,0) print (ans) # Q.6 [Total: 40 points] # # Gaussian Elimination is an algorithm for solving systems of linear equations. In this question, you will write a # # program to perform Gaussian Elimination. Note that the indices of the rows and columns for the matrices startfrom 0. # # You will need to write and submit four functions: # # a) readMatrix(f) # # b) mulRowByC(matOp,i,c) # # c) addRowMulByC(matOp,i,c,j) # # d) gaussElimination(data) # PART A ## def readMatrix(f): list = [] output = dict() for line in (f): if line == 'DATA\n': continue elif line == 'OP\n': output['matrix'] = list list = [] continue elif line == 'END': break else: sublist = line.strip('\n') sublist = sublist.split(' ') sublist = [float(i) for i in sublist] list.append(sublist) output['op'] = list return output ## PART C ## def addRowMulByC(matOp, i, c, j): m = [x*c for x in matOp[int(i)]] new = [] for x in range(len(m)): new.append(m[x] + matOp[int(j)][x]) matOp[int(j)] = new return matOp ## PART B ## def mulRowByC(matOp, i, c): return (addRowMulByC(matOp, i, c-1, i)) ## PART D ## import copy def gaussElimination(data): matA = copy.copy(data['matrix']) matOp = data['matrix'] operations = data['op'] for i in operations: if len(i) == 4: addRowMulByC(matOp, *(i[1:])) elif len(i) == 3: mulRowByC(matOp, *(i[1:])) return(matA, [[round(float(i), 2) for i in nested] for nested in matOp]) # OVERALL TEST CASES # # replace filename with either 'gauss1.txt' or 'gauss2.txt' f=open('/Users/[your name]/Desktop/midterm2016/midterm2016/gauss1.txt','r') #Change accordingly data=readMatrix(f) matA,result=gaussElimination(data) print (matA) print (result) f.close() # # Q.7 [15 points]This question comprises of two parts: (a) Programming, and (b) Written. # Write a function maxProductThree(num)that returns the maximum product from any three numbers in a list of integers. # The list may contain both positive, zero, negative integers,and duplicates, but the maximum product can only be either # a negative or a positive number. You can assume that the list contains at least three non-zero numbers so the maximum # product will never be zero. # Sample Solution 1: Brute Force (~30 seconds) def maxProductThree(num): ls = [] for i in num: for j in num: if j != i: for k in num: if k != j and k!= i: ls.append(i*j*k) return max(ls) ## TIMER ## import time start_time = time.time() num=[6,-3,-10,0,2] print (maxProductThree(num)) num = [4, -139, -848, -142, -779, 406, 899, -932, 565, -678, -197, 442, 145, -711, -495, -743, 602, 841, 312, 104, 814, 771, 772, 292, -718, -151, 503, -265, -812, 792, 209, -734, -343, -674, 129, -421, -138, 826, -739, 625, 529, 391, 367, -166, 764, -178, -104, -380, -204, 697, -471, -811, -580, 207, -980, -983, -478, -551, -591, 121, -51, -424, 922, -521, -789, 30, -121, 847, 862, -232, -669, 990, -878, 690, 408, -452, -713, -644, -163, 526, -929, 767, -174, 110, 477, 188, 575, 328, 685, 93, 596, -865, -987, -321, 28, 383, -53, 405, 271, 783, 25, -255, -885, 747, -375, -44, -515, 598, 100, 830, 915, -663, -32, 112, -686, -796, 647, -397, -592, -309, -6, -706, -47, 116, 528, 454, -201, -303, -927, -418, -177, -858, -294, -449, 738, 573, -143, -331, 392, 958, -964, 742, -472, -650, 725, 555, 34, -130, -769, 835, -659, 849, 500, -850, 933, -70, -504, -729, 366, -224, -531, 780, -974, 83, -373, 273, -956, 187, 106, 549, -961, 509, 837, 72, -785, -871, 821, -915, 676, 185, 261, -558, 692, 37, -474, -641, -498, 949, 873, 494, 582, -698, 239, -153, 186, 167, -169, 198, -754, 409, 431, 437, -4, 147, 804, 157, 35, 332, -78, 18, -483, -487, -813, 160, -210, -493, 396, 280, 97, -445, -649, -306, 56, 965, 305, 231, -690, -681, 163, 325, -862, 492, 15, -903, -685, 558, -968, 307, 768, -112, 179, 267, 781, -268, 576, -429, 63, -828, 832, -798, -85, -56, 171, 11, -579, -897, 663, -337, 463, 518, 6, -437, 820, 33, 330, -280, 745, -179, -654, -79, -301, -106, -628, 840, 486, 643, 535, 664, 438, 612, -363, -757, -503, -857, -843, 143, -661, 831, 38, -444, -494, 656, 661, -906, -803, 991, -451, 336, 283, -243, 258, 40, -863, -920, -295, 372, -621, 128, 897, -762, 253, 774, -550, 445, -349, -118, 760, -642, 534, -683, -338, -252, 809, 574, -966, -208, -392, -889, 58, 174, -619, -446, 300, 952, 434, -538, 469, -809, -205, -780, 932, 653, -72, 715, 50, -367, 220, -501, 333, -296, 892, -788, 196, 749, 375, 240, 581, -516, -396, -901, -473, -967, 560, -870, -537, 217, 646, 483, 401, 282, 592, -833, 590, -340, 813, -583, 740, -186, -45, -390, 470, -251, 127, -202, 317, 137, 998, 793, -466, 569, 732, 381, 491, 140, -573, -786, 269, 517, -119, 674] print (maxProductThree(num)) print("--- %s seconds ---" % (time.time() - start_time)) # Sample Solution 2: Cases (~0.003 seconds) def maxProductThree(num): i = [i for i in sorted(num) if i != 0] return max([i[-3]*i[-2]*i[-1],i[-1]*i[0]*i[1]]) ## TIMER ## import time start_time = time.time() num=[6,-3,-10,0,2] print (maxProductThree(num)) num = [4, -139, -848, -142, -779, 406, 899, -932, 565, -678, -197, 442, 145, -711, -495, -743, 602, 841, 312, 104, 814, 771, 772, 292, -718, -151, 503, -265, -812, 792, 209, -734, -343, -674, 129, -421, -138, 826, -739, 625, 529, 391, 367, -166, 764, -178, -104, -380, -204, 697, -471, -811, -580, 207, -980, -983, -478, -551, -591, 121, -51, -424, 922, -521, -789, 30, -121, 847, 862, -232, -669, 990, -878, 690, 408, -452, -713, -644, -163, 526, -929, 767, -174, 110, 477, 188, 575, 328, 685, 93, 596, -865, -987, -321, 28, 383, -53, 405, 271, 783, 25, -255, -885, 747, -375, -44, -515, 598, 100, 830, 915, -663, -32, 112, -686, -796, 647, -397, -592, -309, -6, -706, -47, 116, 528, 454, -201, -303, -927, -418, -177, -858, -294, -449, 738, 573, -143, -331, 392, 958, -964, 742, -472, -650, 725, 555, 34, -130, -769, 835, -659, 849, 500, -850, 933, -70, -504, -729, 366, -224, -531, 780, -974, 83, -373, 273, -956, 187, 106, 549, -961, 509, 837, 72, -785, -871, 821, -915, 676, 185, 261, -558, 692, 37, -474, -641, -498, 949, 873, 494, 582, -698, 239, -153, 186, 167, -169, 198, -754, 409, 431, 437, -4, 147, 804, 157, 35, 332, -78, 18, -483, -487, -813, 160, -210, -493, 396, 280, 97, -445, -649, -306, 56, 965, 305, 231, -690, -681, 163, 325, -862, 492, 15, -903, -685, 558, -968, 307, 768, -112, 179, 267, 781, -268, 576, -429, 63, -828, 832, -798, -85, -56, 171, 11, -579, -897, 663, -337, 463, 518, 6, -437, 820, 33, 330, -280, 745, -179, -654, -79, -301, -106, -628, 840, 486, 643, 535, 664, 438, 612, -363, -757, -503, -857, -843, 143, -661, 831, 38, -444, -494, 656, 661, -906, -803, 991, -451, 336, 283, -243, 258, 40, -863, -920, -295, 372, -621, 128, 897, -762, 253, 774, -550, 445, -349, -118, 760, -642, 534, -683, -338, -252, 809, 574, -966, -208, -392, -889, 58, 174, -619, -446, 300, 952, 434, -538, 469, -809, -205, -780, 932, 653, -72, 715, 50, -367, 220, -501, 333, -296, 892, -788, 196, 749, 375, 240, 581, -516, -396, -901, -473, -967, 560, -870, -537, 217, 646, 483, 401, 282, 592, -833, 590, -340, 813, -583, 740, -186, -45, -390, 470, -251, 127, -202, 317, 137, 998, 793, -466, 569, 732, 381, 491, 140, -573, -786, 269, 517, -119, 674] print (maxProductThree(num)) print("--- %s seconds ---" % (time.time() - start_time)) # b) There are only 2 potential cases: the product of the 3 largest intergers in the list or the product of the largest # interger with the 2 smallest intergers from the list. The higher of the 2 cases yields the solution. # DW midterm 2017 Solutions import math def combination(credit): credit = (credit - 10.0)/20.0 # 3 out = 2.0*credit - 1.5 return out def activation(a): probability = 1.0/(1 + math.exp(-a)) print(probability) credit = 16.0 output = activation( combination(credit) ) # 14 print(credit) print(output) # 16 # Q1(a) A student calculates that when line 3 is executed, credit will have a value of 0.3. However, when line 15 is # executed, he is surprised to see 16.0 displayed on the screen. Explain why this is the case. (4 points) # Sample answer 1: # 'credit' in the function 'combination' refers to the function parameter credit from the local namespace, instead of # the 'credit' from the global namespace. This is because the local namespace takes precedence over the global namespace. # Hence 'credit' at line 3 is the assigned value resulting for the set of operations on the right. The change value # of 'credit' from the local namespace does not affect 'credit' from the global namespace. Hence 'credit' in the global # namespace remains as 16.0 as is printed as such. # # Sample answer 2: # The student expects 0.3 to be displayed instead of 16.0 and is thus surprised. This suggests that the student expects # the value of 'credit' from the local namespace of function 'combination' instead. However, since print(credit)is # located at the outermost indentation level, 'credit' value of 16 from the global namespace is printed instead. # To obtain the student's expected output of 0.3, the student should shift print(credit) to the line just after #3 at' \ # ' the same indentation level. This is because the local namespace takes precedence over the ' \ # 'global namespace within the same indentation level of the function. # # Additional notes: # We have seen that multiple namespaces can exist independently from each other and that they can contain the same # variable names on different hierachy levels. The “scope” defines on which hierarchy level Python searches for a # particular “variable name” for its associated object. Now, the next question is: “In which order does Python # search the different levels of namespaces before it finds the name-to-object’ mapping?” # To answer is: It uses the LEGB-rule, which stands for Local -> Enclosed -> Global -> Built-in, where the arrows # should denote the direction of the namespace-hierarchy search order. # - Local can be inside a function or class method, for example. # - Enclosed can be its enclosing function, e.g., if a function is wrapped inside another function. # - Global refers to the uppermost level of the executing script itself, and # - Built-in are special names that Python reserves for itself. # So, if a particular name:object mapping cannot be found in the local namespaces, the namespaces of the enclosed # scope are being searched next. If the search in the enclosed scope is unsuccessful, too, Python moves on to the # global namespace, and eventually, it will search the built-in namespace (side note: if a name cannot found in # any of the namespaces, a NameError will is raised). # # (b) When line 14 is executed, describe the sequence of the function calls and how data is passed among these # functions and back to the variable output. Hence, explain why when line 16 is executed, None is displayed on # the screen. (6 points) # Sample answer: # - activation is called, but it requires an argument a # - combination is called, and passes credit as a argument # - combination returns out, which is passed into activation # - activation only prints probability but does not return anything # - output is None, and is printed as such in line 16. # # Additional notes: # A parameter is a variable in a method definition. When a method is called, the arguments are the data you # pass into the method's parameters. Parameter is variable in the declaration of function. # Argument is the actual value of this variable that gets passed to function. # # Q.2 [10 points] # A student was asked to write a function to rotate the robot on itself a given number of times, either in clockwise # or counterclockwise rotation. The student notes that it takes about 5 seconds to do a full rotation at 100% speed on # one of the wheels. However, when testing his program, he realized something went wrong. # # A) Can you spot any syntax error in the code (including type errors) that would prevent the program to run? # Please indicate the lines and how would you correct them. (3 points) # # B) After fixing syntax errors, can you spot any logical mistakes in the code? Please indicate the lines and how # would you correct them. Briefly summarize the behavior of the robot for the given test case if the logical mistakes # are not fixed. (7 points) from eBot import eBot # import import time # SYNTHAX ERROR: double import import time # Rotate and conquer def one_round(direction): # LOGICAL ERROR: direction not speed if direction == 'clockwise': # SYNTAX ERROR: == instead of = ebot.wheels(0, 1) elif direction == 'counter clockwise': # SYNTAX ERROR: == instead of = ebot.wheels(1, 0) time.sleep(2.5) def rotate(times, direction): # print ('Rotating' + times + ' times in direction: ' + direction) # SYNTHAX ERROR: int + str type print('Rotating' + str(times) + ' times in direction: ' + str(direction)) for i in range(1, times): one_round(direction) # LOGICAL ERROR: direction not speed time.sleep(3) # LOGICAL ERROR: delay for loop before next iteration ebot = eBot.eBot() # create an eBot object ebot.connect() # connect to the eBot via Bluetooth # Test case, this should rotate 3 full times clockwise... rotate(3, clockwise) # Prof! My code does not work! ebot.disconnect() # disconnect the Bluetooth communication # The robot will only rotate clockwise once.¶ # Q.3 [5 points] # A regular polygon is an n-sided polygon in which all sides are of the same length and all angles have the same degree. # The formula for computing the area of a regular polygon is: $$ Area = \frac{n\times s^{2}}{4\times tan(\frac{n}{\pi})} $$ # Here, s is the length of a side. Write a function named area_r_polygon that takes the number of sides and the length # of a side as arguments, then returns the area of the regular polygon up to 3 decimal places. # Note: Use math.pi to obtain an accurate value for pi. import math def area_r_polygon(n,s): return round(n*s**2/(4*math.tan(math.pi/n)),3) # area_r_polygon = lambda n,s: (round(n*s**2/(4*math.tan(math.pi/n)),3)) ## TEST CASES ## print('Test case 1: n=5, s=6.5') print(area_r_polygon(5, 6.5)) print('Test case 2: n=7, s=3.25') print(area_r_polygon(7, 3.25)) print('Test case 3: n=2, s=12.5') print(area_r_polygon(2, 12.5)) # Q.4 [10 points] # The number 3, 5, 6, and 9 are all integers below 10 that are multiples of either 3 or 5; the sum of 3, 5, 6, 9 is 23. # Similarly, 2, 4, 6, 8, 10 are all integers below 12 that are multiples of either 2 or 4; the sum of 2,4, 6, 8, 10 is 30. # # Write a function mysum(a,b,limit) that accepts three arguments: a, b and limit. The arguments a and b are integers # greater than zero and lesser than limit. The function mysum(a,b,limit) should return the sum of all the multiples of # a or b, the multiples being lesser than limit. If the user enters a or b to be less than zeroor non-integers, the # function should return the error message “Wrong input” as a string. def mysum(a,b,limit): try: if a >= limit or b >= limit or a <= 0 or b <= 0: return 'Wrong input' if type(a) != int or type(b) != int: return 'Wrong input' except: return 'Wrong input' sum_ = 0 for i in range(int(limit/a)+1): if i*a < limit: sum_ += i*a for j in range(int(limit/b)+1): if j*b < limit: sum_ += j*b for k in range(int(limit/(a*b))+1): if k*a*b < limit: sum_ -= k*a*b return sum_ # TEST CASES # print(mysum(3,5,10)) print(mysum(2,4,12)) print(mysum(3,3,15)) print(mysum(7,9,100)) print(mysum(21,34,10000)) print(mysum(0,5,10)) print(mysum(0.5,5,10)) print(mysum(3,'x',10)) print(mysum(2,3,0)) # Returns 'Wrong input' as a and b should be lesser than limit # Q.5 [10points] # Write a function called get_students(students, course)which takes in a list and a string. The input list ismade up of # a sequence of binary tuples, each with a student name and a list of courses that the student has enrolled in. # The second argument is astring containing the name of a course. Your function should return a list of the names # of students who are enrolled in that course. If no students are taking the course the function should return an empty list. students = [("Alan", ["CompSci", "Physics", "Math"]), ("Justin", ["Math", "CompSci", "Stats"]), ("Edward", ["CompSci", "Philosophy", "Economics"]), ("Margaret", ["InfSys", "Accounting", "Economics", "CommLaw"]), ("Philip", ["Sociology", "Economics", "Law", "Stats", "Music"]), ("Mary", ["Math", "CompSci", "Stats"]), ("Vera", ["CompSci", "Philosophy", "Economics"]), ("Mike", ["InfSys", "Accounting", "Economics", "CommLaw"]), ("Donna", ["Sociology", "Economics", "Law", "Stats"])] def get_students(students, subject): lst = [] for i in range(len(students)): if subject in students[i][1]: lst.append(students[i][0]) return lst ## TEST CASES ## print(get_students(students, 'Philosophy')) print(get_students(students, 'History')) print(get_students(students, 'Math')) print(get_students(students, 'CompSci')) # Q.6 [Total: 30 points] # SUTDBook is a social network website founded by one of SUTD graduates. They are currently hiring some software # engineers to develop an algorithm to suggest new ‘friends’ to their user. Your task in this question is to build # this new friends suggestion algorithm. # # Network of users can be represented as a graph of connected nodes where each user is a node. The connection between # two nodes statesa friend relationship between the two users. # # a) [5points] # Write a function called get_nodes(fid) which takes in a file object as its input arguments and outputs a list # of tuples. Each tuple shows a friend connection between two users and each user is represented by an integer. # # b) [10 points] # Write a function create_graph(nodes) which takes in a list of tuples and returns a graph of friend connection as # a dictionary. The list of tuples is obtained from the output of get_nodes(fid)in part (a) and represents a friend # connection between two users. The outputof the function is a dictionary with each user as a key. The value is also # a dictionarythat contains key-value pair of each of the user’s friends. # # c) [5points] # Write a functioncalled get_friends(G,node) that takes in two arguments. The first argument is a dictionary that # contains the network of friends and the second argument is the node(or user)of interest. # The function get_friends(G,node)returns a list of friends that particular user has. # # d) [10 points] # Write a function called suggested_new_friends(G,node) that takes in a dictionary describing the friends network and # an integer representing a user. The function returns a list of suggested new friends for the input user. # PART A ## def get_nodes(fid): lines = fid.readlines() lines_s = [line.strip("\n") for line in lines] lines_r = [line.strip("\r") for line in lines_s] tuples_ = [line.split(" ") for line in lines_r] tuples_i = [tuple([int(number) for number in pair]) for pair in tuples_] return tuples_i ## PART B ## def create_graph(nodes): g ={} for a, b in nodes: g.setdefault(a, {}).update({b:1}) a,b = b,a g.setdefault(a, {}).update({b:1}) return g ## PART C ## def get_friends(G,user): return list(G[user]) #get_friends = lambda G,user: list(G[user]) ## PART D ## def most_frequent(lst): count_dict = {} for i in lst: if count_dict.get(i) == None: count_dict.update({i : lst.count(i)}) return [x for x in count_dict.keys() if count_dict[x] == max(count_dict.values())], max(count_dict.values()) def suggested_new_friends(G,node): friends_list = get_friends(G,node) friend_friend_list = [] for friend_friend in friends_list: for friend_friend in get_friends(G,friend_friend): if friend_friend != node: friend_friend_list.append(friend_friend) return most_frequent(friend_friend_list) # OVERALL TEST CASES # f=open('/Users/[yourname]/Desktop/midterm2017/midterm2017/facebook_less.txt','r') #Change accordingly nodes= get_nodes(f) G= create_graph(nodes) print ('Friends of 1from facebook_less.txt') print (get_friends(G,1)) print ('Suggested new friends for 1') print (suggested_new_friends(G,1)) f.close() f=open('/Users/[yourname]/Desktop/midterm2017/midterm2017/sutdbook1.txt','r') #Change accordingly nodes= get_nodes(f) G= create_graph(nodes) print ('Friends of 0 from sutdbook1.txt') print (get_friends(G,0)) print ('Suggested new friends for 0') print (suggested_new_friends(G,0)) f.close() f=open('/Users/[yourname]/Desktop/midterm2017/midterm2017/sutdbook2.txt','r') #Change accordingly nodes= get_nodes(f) G= create_graph(nodes) print ('Friends of 0 from sutdbook2.txt') print (get_friends(G,0)) print ('Suggested new friends for 0') print (suggested_new_friends(G,0)) f.close() # Q.7 [15 points] # Design an efficient algorithm that determines the number of ways 5 non-negative integers can sum up to N. # Your code must be able to handle large N values (150+) under 20 seconds. (Timer included to each cell as proof) # Negative Example: Brute Force (Don't even try to time it) def nos(n): ans = 0 for i in range(n+1): for j in range(n+1): for k in range(n+1): for l in range(n+1): for m in range(n+1): if i + j + k + l + m == n: ans += 1 return ans # Sample Solution 1: Recursion + Nested Loops (~10 seconds) def nos(n, x = 5): if x == 1: return 1 if n == 0: return 1 else: solutions = 0 for i in range(x): for j in range(n): solutions += nos(j, i) return solutions ## TIMER ## import time start_time = time.time() print(nos(150,5)) print("--- %s seconds ---" % (time.time() - start_time)) # Sample Solution 2: Pure Recursion (~4 seconds) def nos(n, x=5): if x == 1: return 1 if n == 1: return x if n == 0: return 1 return sum([nos(n-m,x-1) for m in range(n+1)]) ## TIMER ## import time start_time = time.time() print(nos(5,5)) print("--- %s seconds ---" % (time.time() - start_time)) # Sample Solution 3: Top-down DP with Memomisation & Decorators (Sample 1: ~0.1 seconds; Sample 2: ~0.04 seconds) def memo_nos(f): nos_ans = {} def helper_nos(*args): if str(args) not in nos_ans: nos_ans[str(args)] = f(args[0],args[1]) return nos_ans[str(args)] return helper_nos @memo_nos # COPY PASTE EITHER SAMPLE 1 OR SAMPLE 2 CODE HERE ## TIMER ## import time start_time = time.time() print(nos(150,5)) print("--- %s seconds ---" % (time.time() - start_time)) # Sample Solution 4: Combinatorics (<0.001 seconds; so fast that Python might return 0 seconds) from scipy.special import comb def nos(n, x=5): return int(comb(n+x-1 , x-1, exact=False, repetition=False)) #nos = lambda n, x=5: comb(n+x-1 , x-1, exact=False, repetition=False) ## TIMER ## import time start_time = time.time() print(nos(150,5)) print("--- %s seconds ---" % (time.time() - start_time)) # Sample Solution 5: Combinatorics with loops (~1 second; Uses the same logic as solution 4)¶ def nos(n ,x=5): sol = 0 for a in range(n + 1): for b in range(n + 1 - a): for c in range(n + 1 - a - b): for d in range(n + 1 - a - b - c): sol += 1 return sol ## TIMER ## import time start_time = time.time() print(nos(150,5)) print("--- %s seconds ---" % (time.time() - start_time)) # DW mid-terms 2018 solutions # These solutions are student compiled and might contain errors (especially for qn 1 & 2) # Credit goes to Team Anonymous on Piazza # # Part A x = 'aces' y = 1.23 z = x x = y y = z print(x, y) # Q1(a) After the above code is executed, at line 6, what is seen on the screen is 1.23aces. # # By explaining what each line of the code below (for lines 1 to 5) does, show how the code below switches the objects # assigned to variables x and y. # # Your explanation must state when objects are created and their data types, and also how names are assigned to these # objects. Diagrams could be helpful in your explanation. (6 points) # Sample answer 1: # At line 1, string object 'aces' is assigned to frame 'x'. At line 2, float object of value 1.23 is assigned to frame # 'y'. At line 3, a shallow copy of string object 'aces' from frame 'x' is assigned to frame 'z'. At line 4, a shallow # copy of the float object of value 1.23 from frame 'y' is assigned to frame 'x' and overwirtes the string object 'aces'. # At line 5, a shallow copy of string object 'aces' from frame 'z' is assigned to frame 'y' and overwrites the float # object of value 1.23. The final result is: # Stack | Object after line 3 > 4 > 5 # x | 'aces' > 1.23 > 1.23 # y | 1.23 > 1.23 > 'aces' # z | 'aces' > 'aces' > 'aces' # The contents of both x & y are fetched when print(x,y) is executed at line 6. Thus, 1.23aces is printed # in the order of x then y. # # Q1(b) When the following code is executed, after line 12, what is seen on the screen is True. # # i) Using how names are assigned to objects in memory, explain why. Diagrams could be helpful in your explanation. # (3 points) # # ii) The intention of the programmer is to create two lists showing the words for ‘seven’, ‘eight’ and ‘nine’ for both # Greek and French. State one modification to the code at line 8 so that line 13 prints out the correct output. (1point) french= [ 'sept', 'huit', 'neuf'] # the words mean 'seven','eight','nine'. greek = french # this is line 8 greek[0] = 'epta' # 'seven' greek[1] = 'okto' # 'eight' greek[2] = 'enea' # 'nine' print(greek is french) # this is 'line 12' print(french, greek) # Sample answer 1: # i) At line 1, a list object is created for frame 'french'. At line 2, frame 'greek' is assigned to refer to the same # list object as frame 'french'. Thus, even after the contents of the list is changed, line 12's shallow equivalence # check 'is' returns true as both frames 'french' and 'greek' still refers to the same list object in memory. # # ii) I would repace line 8 with 'greek = list(french)' to another list object similar in contents to frame 'french' # is created for frame 'greek'. # # Q2 [10 points] # a) Is there anything wrong with the following program? If yes, what is wrong? (2 points) import = int(input("Enter a number: ")) if import==2: print("Yes") else: print("No") # Sample solution 1: # Synthax error. 'import' is a reserved keyword in python and neither be used as a variable name nor be assigned to # an 'int' type object. # # b) If break is removed from the following programand the program is run, what will be printed out? (2 points) my_string = "Computing" for character in my_string: print(character) if character == "u": print("Found 'u' :)") # Solution: # C # o # m # p # u # Found 'u' :) # t # i # n # g # # c) Look at the following function: def my_function(n): return_value = None if n == 0 or n == 1: return_value = False # not run i=2 while i*0.5: if n%i==0: return_value = False # not run break # not run i += 1 return_value = True return return_value my_function(37) # Let the function tested to be my_function(37) # # a) What will be the output? (1 point) # # b) Identify the lines of the program which will be executed when the input is 37. # Do this by entering the codes from those lines to eDimension. (2 points) # Solution: # a) True. # b) (enter those lines of code not tagged by # not run) # # d) In the context of the 1D projects you have completed so far in this course, look at the following function: def forward(speed, duration): robot.wheels(speed, speed) robot.sleep(duration) robot.wheels(0,0) # a) Why is it not necessary to have a return statement in this function? (1 point) # # b) If we change robot.wheels(speed, speed) to robot.wheels(speed1, speed2) and the function header is also modified # to take in speed1 and speed2, how will the movement of the robot change? You can assume that speed1 and speed2 are # different and both speed1 and speed2 are positive numbers. (1 point) # Sample solution 1: # a) In the above function to move the robot forward at some speed for some duration, no values are expected to be # reused or caught by the function. Hence, no return statement is required. # # b) If speed1 > speed2, the robot will still travel forward but with a leftwards dispalcement. If speed1 < speed2, # the robot will still travel forward but with a rightwards dispalcement. # # Part B # # Q3 [10 points] # # A frustum is a parallel truncation of a right pyramid. A piece of metal is in the shape of a frustum with a square # base. The side length of the top square is s1 and the side length of the bottom square is s2. # The height of the frustum is H. # # The volume of the frustum is given by the formula: # $$Volume = \frac{H}{3}(A1 + A2 + \sqrt{A1 \text{ x } A2})$$ where A1 is the area of the upper square, A2 is the # area of the lower square, and H is the height of the frustum. # a) Write a python function area_square(s) that takes the side of a square as an input argument s, and returns the # area of the square. # # b) Write a python function vol_frustum(top_area, bottom_area, height) that takes three arguments, a top area, # a bottom area and a height in that order, and returns the volume of the frustum. # # c) Write a python function get_volume(s1, s2, height) that takes three arguments, a top side length, a bottom # side length and a height and returns the volume of a frustum based on those dimensions. # This function should first call area_square to obtain the two needed areas, and then call vol_frustum to evaluate # the volume. # # All input arguments and return values are floats. Please round only your final output of get_volume to three # decimal places. Please use math.sqrt() to compute the square root in your python code. Note that you get only # full marks if your get_volume function makes use of the other two functions. import math def area_square(s): return s ** 2. def vol_frustum(top_area, bottom_area, height): return (height / 3) * (top_area + bottom_area + math.sqrt(top_area * bottom_area)) def get_volume(s1, s2, height): return round(vol_frustum(area_square(s1), area_square(s2), height), 3) ## TEST CASES ## print('{:.3f}'.format(area_square(2))) print('{:.3f}'.format(area_square(3))) print('{:.3f}'.format(vol_frustum(1, 4, 2))) print('{:.3f}'.format(vol_frustum(2, 2, 2))) print('{:.3f}'.format(get_volume(1, 2, 2))) print('{:.3f}'.format(get_volume(1.5, 3.3, 5.0))) print('{:.3f}'.format(get_volume(3.6, 6.4, 4.0))) # Q4 [10 points] # # Implement a function determinant(matrix) that takes a matrix as input (represented as a nested list) and returns # its determinant as output. The function should satisfy the following requirements: # # 1) If the input matrixis not of dimension n x n (for 1 ≤n ≤3), the function should return None # # 2) The function is to be implemented withoutimporting any libraries. def determinant(matrix): M = matrix try: a = len(M) a = len(M[0]) except: return None if len(M) == 1: for row in M: if len(row) != 1: return None return M[0][0] if len(M) == 2: for row in M: if len(row) != 2: return None return M[0][0] * M[1][1] - M[0][1] * M[1][0] if len(M) == 3: for row in M: if len(row) != 3: return None return (M[0][0] * M[1][1] * M[2][2] + M[1][0] * M[2][1] * M[0][2] + M[2][0] * M[0][1] * M[1][2] - M[0][2] * M[1][1] * M[2][0] - M[1][0] * M[0][1] * M[2][2] - M[0][0] * M[2][1] * M[1][2]) ## TEST CASES ## print(determinant([[100]])) print(determinant([[-5, -4], [-2, -3]])) print(determinant([[2, -3, 1], [2, 0, -1], [1, 4, 5]])) print(determinant([[0, 3, 5], [5, 5, 2], [3, 4, 3]])) print(determinant([[23], [-4, 4]])) # Q5 [15 points] # # The Newton-Raphson (NR) method is an iterative method that approximates the root of a function. # The accuracy of the answer is enhanced in successive iterations. # # You need two create two functions: nrootand nroot_complex. The function nroot(n, i, num) is to determine # the root of non-negative num. The function nroot_complex(n,i,num) to determine the root of negative num. # Thefunction nroot_complex should call nroot to do the NR approximation. Note the output should give a constant$*$1j # where j is the imaginary square root of -1. For odd n the output should give a negative value instead of constant$*$1j. # This means that: # • When num is a non-negative number, nroot_complex should give the same result as nroot. # • When num is a negative number and n is even, nroot_complex should give a complex number with no real part, # and its magnitude is the same as the output of nrootwhen num is positive. # • When numis a negative number and n is odd, nroot_complex should give a negative real number, and its magnitude is # the same as the output of nroot when numis positive. # # Round the output of nroot to 3 decimal places.Use x = 1 as your initial value. def nroot(n, t, num): x = 1 for i in range(t): x -= ((x ** n - num) / (n * (x ** (n - 1)))) return round(x, 3) def nroot_complex(n, t, num): if num > 0 or num == 0: return nroot(n, t, num) if num < 0 and n % 2 == 1: return -nroot(n, t, -num) else: return str(nroot(n, t, -num)) + 'j' ## TEST CASES ## print(nroot(2, 5, 2)) print(nroot_complex(2, 5, -4)) print(nroot_complex(3, 5, -8)) # Q6 [30 points] # # In this problem you will write a program to find a path through MRT stations from a starting station to # an ending station with a maximum of one interchange. # # The overall function is called find_path and it takes three arguments: (1) a file object to a text file # containing the MRT lines and stations, (2) the starting station, and (3) the ending station. # # This function should return a list of stations from a starting station to an ending station with a maximum # of one interchange. The problem is decomposed by writing several other functions, described in the following parts. # # For simplicity, the information given to you in this question is limited to the North South line and the East West line. # Also, the branch line to Changi Airport is treated as a separate line. Hence the three lines are labelled # in this question as follows: (1) NorthSouthLine (2) EastWestLine (EW) and (3) EastWestLine (CG). # # a) read_stations(f): This function takes in a file object and returnsa dictionary. The dictionary has the MRT lines # as its keys. The value of each key is a list of stations in that MRT line. # # b) get_stationline(mrt): This function takes in a dictionary of MRT lines (i.e. the output of part (a) ). # The function returns another dictionary which contains all the stations as its keys. The value for each key is a list # of the MRT lines for that particular station. Note that if the station is an interchange, the list should contain all # the lines calling at that station. # # c) get_interchange(stationline): This function takes in a dictionary of stations and their lines # (i.e. the output of part (b)). The function returns another dictionary which contains all the interchange stations as # its keys. The value for each key is a list of the MRT lines for that particular interchange stations. # # d) find_path(f, start, end): This function takes in three arguments: (1) the file object to a text file # containing all the MRT lines and stations, (2) the startingstation, and (3) the endingstation. The function should # return a list of stations starting from the starting station to the ending station with a maximum of one interchange. # If there are more than one possible paths, the following considerations should be taken into account: # # • If there is a path without changing MRT lines, the result should return this path. # • If the path must involve changing MRT lines, it will return the path with a minimum number of stations and # containing only one interchange station. # • If no such path can be found as above, it will return None. ## PART A ## def read_stations(s): st = ''.join(s.readlines()).split("=") ans = {} for i in range(int((len(st) - 1) / 2)): ans[st[2 * i + 1]] = (st[2 * (i + 1)].strip("\n")).split(", ") return ans ## PART B ## def get_stationline(mrt): ans = {} for lines in mrt: for station in mrt[lines]: if station not in ans: ans[station] = [] ans[station].append(lines) else: ans[station].append(lines) return ans ## PART C ## def get_interchange(stationline): ans = {} for stations in stationline: if len(stationline[stations]) > 1: ans[stations] = stationline[stations] return ans ## PART D ## def create_graph(f): stations = read_stations(f) stationline = get_stationline(stations) interchange = [*get_interchange(stationline)] network = {} # Create a dictionary where station (key) is linked to all its connected stations (values) for line in stations: stations_ = stations.get(line) network[stations_[-1]] = [stations_[-2]] # End stations only conencted to one other station for station in range(0, len(stations_) - 1): network.setdefault(stations_[station], [stations_[station - 1]]).append(stations_[station + 1]) if stations_[0] not in interchange: network[stations_[0]] = [stations_[1]] # Removing non interchange connections that loops network['City Hall'].append('Dhoby Ghaut') # Add this pesky back edge for key in network: network[key] = set(network.get(key)) # Apply set structure to dictionary values return network def bfs_paths(graph, start, goal): # Since we only want the shortest path, we use Breath First Search on a queue structure for efficiency queue = [(start, [start])] while queue: (vertex, path) = queue.pop(0) for next in graph[vertex] - set(path): if next == goal: yield path + [next] else: queue.append((next, path + [next])) import collections as c def find_path(f, start, end): try: graph = create_graph(f) possible_paths = list(bfs_paths(graph, start, end)) f.seek(0) # remember to reset readlines() counter to 0 stations = read_stations(f) stationline = get_stationline(stations) interchange = [*get_interchange(stationline)] ans = [] for path in possible_paths: line_counter = [] for station in path: line_counter.append(stationline.get(station)[0]) # We count the total number of line types present. More than 1 interchange used if line type > 2 if len(c.Counter(line_counter)) <= 2: ans.append(path) return ans[0] # Since we used BFS, first path found is always the shortest except: # A general catch block to return None return None ## TEST CASES ## print('Test 1') f = open('mrt_lines_short.txt', 'r') # Make sure directory is correct ans = find_path(f, 'Boon Lay', 'Clementi') print(ans) f.close() print('Test 2') f = open('mrt_lines_short.txt', 'r') # Make sure directory is correct ans = find_path(f, 'Changi Airport', 'Orchard') print(ans) f.close() print('Test 3') f = open('mrt_lines_short.txt', 'r') # Make sure directory is correct ans = find_path(f, 'Boon Lay', 'Bukit Gombak') print(ans) f.close() print('Test 4') f = open('mrt_lines_short.txt', 'r') # Make sure directory is correct ans = find_path(f, 'Tanah Merah', 'Orchard') print(ans) f.close() # Q7 [15 points] # # Write a function decompose(pence), that takes as input some number of pence (as an integer), and returns as output # an integer expressing how many different ways that the amount can be made up by using the available coins. # At present, there are eight coins in general circulation: # # 1p, 2p, 5p, 10p, 20p, 50p, £1, and £2 # # Note that the function decompose(pence) can be implemented in a number of different ways, # including by using brute force (i.e. exhaustive search). However, brute force implementations may only score a # maximum of 12 points; the full 15 are only available for more elegant/efficient solutions. # Sample Solution 1: Naive for loops (Brute force; Don't even try to time it) def decompose(pence): coins = [1, 2, 5, 10, 20, 50, 100, 200] count = 0 for x1 in range(pence): for x2 in range(pence): for x3 in range(pence): for x4 in range(pence): for x5 in range(pence): for x6 in range(pence): for x7 in range(pence): for x8 in range(pence): if (x1 * coins[0] + x2 * coins[1] + x3 * coins[2] + x4 * coins[3] + x5 * coins[4] + x6 * coins[5] + x7 * coins[6] + x8 * coins[7]) == pence: count += 1 # Cancer return count + 1 ## TEST CASES ## import time start_time = time.time() print(decompose(1)) print(decompose(5)) print(decompose(7)) print(decompose(130)) print(decompose(200)) print(decompose(700)) print("--- %s seconds ---" % (time.time() - start_time)) # Sample Solution 2: Pure recursion (Exhasutive; ~10mins) def decompose(pence, num_types=len(coins)): coins = [1, 2, 5, 10, 20, 50, 100, 200] # If pence = 0 then there is only 1 solution if (pence == 0): return 1 # If n is less than 0 then no solution exists if (pence < 0): return 0; # If there are no coins and n is greater than 0, then no solution exist if (num_types <= 0 and pence >= 1): return 0 # Recursion step return decompose(pence, num_types - 1) + decompose(pence - coins[num_types - 1], num_types); ## TEST CASES ## import time start_time = time.time() print(decompose(1)) print(decompose(5)) print(decompose(7)) print(decompose(130)) print(decompose(200)) print(decompose(700)) print("--- %s seconds ---" % (time.time() - start_time)) # Sample Solution 3: Recursion with some memomisation (Exhasutive with some elegance; ~5mins) def decompose(pence, coins=[1, 2, 5, 10, 20, 50, 100, 200]): # If pence = 0 then there is only 1 solution if pence == 0: return 1 # If n is less than 0 then no solution exists if pence < 0: return 0 num_ways = 0 # Store previously computed sub-problems in a dictionary to avoid re-computing it dic_ways = {} for i in range(len(coins)): coin = coins[i] if pence - coin not in dic_ways: # Recursion step num_ways += decompose(pence - coin, coins[i:]) dic_ways[pence - coin] = True return num_ways ## TEST CASES ## import time start_time = time.time() print(decompose(1)) print(decompose(5)) print(decompose(7)) print(decompose(130)) print(decompose(200)) print(decompose(700)) print("--- %s seconds ---" % (time.time() - start_time)) # Sample solution 4: Expansion of partition equation into series (Elegant but inefficient; ~30s) from sympy import * def decompose(pence): x = symbols('x') partition_series = series(1/(( 1 - x)*(1-x**2)*(1-x**5)*(1-x**10) *(1-x**20)*(1-x**50)*(1-x**100)*(1-x**200)), n = pence+2) coef = Poly(partition_series.removeO(),x) return coef.all_coeffs()[1] ## TEST CASES ## import time start_time = time.time() print (decompose(1)) print (decompose(5)) print (decompose(7)) print (decompose(130)) print (decompose(200)) print (decompose(700)) print("--- %s seconds ---" % (time.time() - start_time)) # Sample solution 5: Smart brute force (Efficent but inelegant; 1.5s) def decompose(pence): count = 0 for x1 in range(0,pence+1,200): for x2 in range(x1,pence+1,100): for x3 in range(x2,pence+1,50): for x4 in range(x3,pence+1,20): for x5 in range(x4,pence+1,10): for x6 in range(x5,pence+1,5): for x7 in range(x6,pence+1,2): count+=1 return count ## TEST CASES ## import time start_time = time.time() print (decompose(1)) print (decompose(5)) print (decompose(7)) print (decompose(130)) print (decompose(200)) print (decompose(700)) print("--- %s seconds ---" % (time.time() - start_time)) # Sample solution 6: Top-down Dynamic Programming; Recursion with memoization & decorators # (Efficient & quite elegant; ~0.002s) def memoize(func): cache = dict() def memoized_func(*args): if args in cache: return cache[args] result = func(*args) cache[args] = result return result return memoized_func ## The above code is a quick and dirty memo fucntion that can be used widely ## ## to speed up problems with overlapping sub-problems (avoid recomputation) ## @memoize ## Pure recursion from sample solution 2 ## def decompose(pence, num_types=len(coins)): coins = [1, 2, 5, 10, 20, 50, 100, 200] # If pence = 0 then there is only 1 solution if (pence == 0): return 1 # If n is less than 0 then no solution exists if (pence < 0): return 0; # If there are no coins and n is greater than 0, then no solution exist if (num_types <= 0 and pence >= 1): return 0 # Recursion step return decompose(pence, num_types - 1) + decompose(pence - coins[num_types - 1], num_types); ## TEST CASES ## import time start_time = time.time() print(decompose(1)) print(decompose(5)) print(decompose(7)) print(decompose(130)) print(decompose(200)) print(decompose(700)) print("--- %s seconds ---" % (time.time() - start_time)) # Sample Solution 7: Bottom-up Dynamic Programming (Most elegant & efficient; ~0.001s) def decompose(pence): try: coins = [1, 2, 5, 10, 20, 50, 100, 200] num_types = len(coins) # table[i] will be storing the number of solutions for # value i. We need n+1 rows as the table is constructed # in bottom up manner using the base case (pence = 0) # We first initialize all table values as 0 table = [0 for accumulative_num_of_ways in range(pence + 1)] # If pence = 0 then there is only 1 solution table[0] = 1 # Pick all coins one by one and update the table[] values # after the index greater than or equal to the value of the # picked coin for type_ in range(0, num_types): for value in range(coins[type_], pence + 1): table[value] += table[value - coins[type_]] # We only want the number of ways to find change for value = pence return table[pence] except: # Our bottom up approach innately deals with special cases # this line catches invalid arguments return 0 ## TEST CASES ## import time start_time = time.time() print(decompose(1)) print(decompose(5)) print(decompose(7)) print(decompose(130)) print(decompose(200)) print(decompose(700)) print("--- %s seconds ---" % (time.time() - start_time))
#!/usr/bin/python3 # Fibonacci numbers module def fib(n): # return Fibonacci series up to n result = [] a, b = 0, 1 while b < n: result.append(b) a, b = b, a + b return result if __name__ == "__main__": f = fib(200) print(f)
while True: try: entrada = int(input()) except: break if entrada == 0: break else: vetor = [None] * entrada aux = 1 for i in range(entrada): vetor = [] k = 0 while k < entrada: vetor.append(aux) if aux == 4: aux += 4 else: aux += 2 k += 1 if aux == entrada: vetor.append(aux) aux = 4 k+=1 print('Discarded cards: ', end = ' ') for j in range(len(vetor)): if j == len(vetor)-1: print('\nRemaining card: ', vetor[j]) elif j == len(vetor)-2: print(vetor[j], end = '') else: print(vetor[j], end = ', ')
We use cookies to provide and improve our services. By using our site, you consent to our Cookies Policy. Accept Learn more