0% found this document useful (0 votes)
172 views23 pages

Python Week 4 GA Sols ?

The code takes in a matrix as input and calculates the sum of all elements in the matrix. It first takes the number of rows (n) as input. It then initializes an empty list M to store the rows. In a for loop from 0 to n-1, it takes each row as input separated by commas, splits it on comma, converts to integers and appends to the current row list. This row list is appended to M. It then initializes some_var to 0 and has two for loops from 0 to n-1 to iterate over each element of the matrix, summing it to some_var. It finally prints some_var which will be the total sum of all elements in the input matrix.

Uploaded by

Gautam Bhardwaj
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
Download as pdf or txt
0% found this document useful (0 votes)
172 views23 pages

Python Week 4 GA Sols ?

The code takes in a matrix as input and calculates the sum of all elements in the matrix. It first takes the number of rows (n) as input. It then initializes an empty list M to store the rows. In a for loop from 0 to n-1, it takes each row as input separated by commas, splits it on comma, converts to integers and appends to the current row list. This row list is appended to M. It then initializes some_var to 0 and has two for loops from 0 to n-1 to iterate over each element of the matrix, summing it to some_var. It finally prints some_var which will be the total sum of all elements in the input matrix.

Uploaded by

Gautam Bhardwaj
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
Download as pdf or txt
Download as pdf or txt
You are on page 1/ 23

Week-4, Graded

This document has questions.


Question-1
Statement
Let X be a vector. We wish to compute the dot product of X with itself and store it in a variable
called dp . Select the correct code snippet(s) from the options given below. (MSQ)

Options
(a)

1 dp = 0
2 for elem in X:
3 dp += elem * elem

(b)

1 dp = 0
2 for i in range(len(X)):
3 dp += X[i] ** 2

(c)

1 dp = 0
2 for i in range(X):
3 dp += X[i] * X[i]

(d)

1 i, dp = 0, 0
2 while i <= len(X):
3 dp += X[i] ** 2
4 i += 1

(e)

1 i, dp = 0, 0
2 while i < len(X):
3 dp += X[i] ** 2
4 i += 1

Answer
(a), (b), (e)
Feedback
Correct options

Option-(a): Here, we pick up each element from X , multiply it with itself and add it to dp .
Option-(b): The only difference from the previous option is the use of indices.
Option-(e): This uses a while loop while the other two correct solutions use for .

This is to demonstrate that there are multiple approaches to compute the dot product.

Wrong options

As far as option-(c) is concerned, do you think range(X) makes sense when X is a list?
What is the difference between options (d) and (e)?
Common Data for Questions 2, 3
Statement
Execute the following snippet of code and then answer questions 2 and 3.

1 import random
2
3 rolls = [ ]
4 for i in range(100000):
5 # randint includes the endpoints
6 roll = random.randint(1, 6)
7 rolls.append(roll)
8
9 count = 0
10 primes = [2, 3, 5]
11 for roll in rolls:
12 if roll in primes:
13 count += 1
Question-2
Statement
What is the size of the list rolls ? (NAT)

Answer
100000

Feedback
The idea of the program is to simulate rolls of a dice. This is accomplished using
Python's built-in random library:

1 import random
2
3 rolls = [ ]
4 for i in range(100000):
5 # randint includes the endpoints
6 roll = random.randint(1, 6)
7 rolls.append(roll)

It is a good idea to run this locally and see what you get. len(rolls) will be in this case.
Question-3
Statement
Execute the following snippet of code.

1 some_var = count / len(rolls)

What does the variable some_var represent?

Options
(a)

It represents the probability that a number chosen at random between 1 and 100000 is a prime.

(b)

It represents the number of primes between 1 and 100000

(c)

It represents the number of prime numbers in the list rolls .

(d)

It represents the probability that a number chosen at random from the list rolls is a prime.

(e)

It represents the probability that a number chosen at random from the list primes is a prime.

Answer
(d)

Feedback
Questions to ask yourself:

What is the purpose of the for-loop from lines 11-13?


What does the variable count represent?
When does the expression roll in primes in line-12 evaluate to True ?
Common data for questions 4 and 5
Statement
Assume that L is a non-empty list of positive integers. Also assume that the list is a distinct
collection of numbers, i.e., no two numbers are alike. Consider the following code. Answer
questions 4 and 5 based on this code.

1 S = 0
2 for x in L:
3 S += x
4
5 flag = False
6 y = -1
7 for x in L:
8 if x * len(L) == S:
9 flag = True
10 y = x
11 break
Question-4
Statement
If flag is True at the end of execution of the code given above, which of the following
statements are true? Note that the options should be true for any list L that satisfies the
conditions given in the common data. Multiple options could be correct.

Options
(a)

y is an element in the list L

(b)

y is the smallest number in the list

(c)

y is the greatest number in the list

(d)

y is the average (arithmetic mean) of the numbers in the list

(e)

y is the element at index len(L) // 2 in the list L

Answer
(a), (d)

Feedback
The basic idea is this: if we replace all the elements in the list L with one of its elements, say y ,
the sum of the resulting list is the same as the old list. What does this say about the element y ?
How is this element related to the average (arithmetic mean) of the numbers in the old list?

As a concrete example, consider the following list:

1 L1 = [5, 1, 4, 3, 2]

Here, if we replace all the elements with the arithmetic mean of the list, we get:

1 L2 = [3, 3, 3, 3, 3]

We see that sum(L1) == sum(L2) . For this specific example, we see why (a) and (d) should be
correct. But these options hold good for any non-empty list L of distinct positive integers. A more
abstract argument is as follows. Consider a list of numbers, not necessarily in sorted order:
For the if-condition to be True , there should be some element in the list such that:

Dividing both sides by , we get:

Thus, we see that is nothing but the arithmetic mean of the elements in the list.
Question-5
Statement
Assume that L is a list of the first positive integers, where . Under what conditions will
the variable flag be True at the end of execution of the code given above?

Options
(a)

n is an odd integer

(b)

n is an even integer

Answer
(a)

Feedback
Continuing with the argument, we have:

For to be an integer, has to be odd.


Question-6
Statement
Consider the following code snippet.

1 L = input().split(' ') # there is a single space between the quotes


2 for i in range(len(L) - 1):
3 if len(L[i]) > len(L[i + 1]):
4 L[i], L[i + 1] = L[i + 1], L[i]
5
6 count = 0
7 for i in range(len(L)):
8 if len(L[i]) <= len(L[-1]):
9 count += 1
10
11 print(count)

What is the output of the code given above for the following input?

Input

1 seriously this world needs heroes like you now more than ever

There is exactly one space between consecutive words. There are no spaces before the first word
after the last word.

Answer
11

Feedback
Recall that x, y = y, x is the way to swap the values in the two variables.

Here, the code bubbles the longest word to the rightmost end of the list. This is an important step
in a sorting algorithm called bubble sort. In bubble sort, you swap two adjacent elements in the
list, whenever the left-element is bigger (whatever this means) than the right element. Let us see
how this works with numbers first.

Example

Consider a list of length . The idea is to loop through the list and compare a pair of adjacent
elements, say , in each iteration. If , then the two elements are swapped.
If , then we don't disturb their positions. The rationale behind this is to "bubble" the
largest element and push it to the right end of the list:

1 L = [5, 10, 3, 2, 4]
2 for i in range(len(L) - 1):
3 if L[i] > L[i + 1]:
4 L[i], L[i + 1] = L[i + 1], L[i]
5 print(f'After iteration {i + 1}: {L}')
This is the output:

1 After iteration 1: [5, 10, 3, 2, 4]


2 After iteration 2: [5, 3, 10, 2, 4]
3 After iteration 3: [5, 3, 2, 10, 4]
4 After iteration 4: [5, 3, 2, 4, 10]

Note the position of across all iterations. In the first iteration, we compare . Since is
to the right of , we leave it as it is. But in the next three iterations, we make the following
comparisons:

: swap
: swap
: swap

Now, you can use this idea of bubble sort to understand the original question. Here, the longest
word is being bubbled to the right. Once this is done, the following code is executed:

1 count = 0
2 for i in range(len(L)):
3 if len(L[i]) <= len(L[-1]):
4 count += 1

Here, count will be the length of the list L , which is the same as the number of words in the
sentence. Why is this the case?
Question-7
Statement
Consider the following sequence:

Let be the smallest element in this sequence that is divisible by . How many digits does
have?

Hint: Think about while loops.

Answer
1001

Feedback
One doesn't necessarily have to use lists to solve this problem. Here is one using lists:

1 L = [7]
2 last = L[-1]
3 while last % 2003 != 0:
4 num = L[-1] * 10 + 7
5 L.append(num)
6 last = L[-1]
7 print(len(L))

Here is one that doesn't use lists:

1 num = 7
2 count = 1
3 while num % 2003 != 0:
4 num = num * 10 + 7
5 count += 1
6 print(count)
Question-8
Statement
Consider the following snippet of code.

Hint: 'a b c'.split(' ') results in the list ['a', 'b', 'c'] .

1 n = int(input())
2 M = [ ]
3 for i in range(n):
4 row = [ ]
5 for num in input().split(','):
6 row.append(int(num))
7 M.append(row)
8
9 some_var = 0
10 for i in range(n):
11 for j in range(n):
12 some_var += M[i][j]
13
14 print(some_var)

Find the output of the code if the input is:

1 5
2 1,2,3,4,5
3 6,7,8,9,10
4 11,12,13,14,15
5 16,17,18,19,20
6 21,22,23,24,25

Answer
325

Feedback
We shall try to break the code into two parts. Line-8, an empty line, provides a natural point of
separation:

Part-1

We are accepting a matrix as input here. Based on the code given below, does have to be a
square matrix?

1 n = int(input())
2 M = [ ]
3 for i in range(n):
4 row = [ ]
5 for num in input().split(','):
6 row.append(int(num))
7 M.append(row)
Part-2

1 some_var = 0
2 for i in range(n):
3 for j in range(n):
4 some_var += M[i][j]

For this particular problem, it turns out that we are working with a square matrix of size .
some_var is storing the sum of the elements of the matrix.
Question-9
Statement
What is the output of the following snippet of code?

Hint:

(1) If L = [1, 2, 3, 4, 5] , then L[1: 3] is the list [2, 3] . Slicing a list is very similar to slicing
a string. All the rules that you have learned about string-slicing apply to list-slicing.

(2) If P = [1, 2, 3] and Q = [4, 5, 6] then P + Q is the list [1, 2, 3, 4, 5, 6] . Again, list
concatenation is very similar to string concatenation.

1 L = [90, 47, 8, 18, 10, 7]


2 S = [L[0]] # list containing just one element
3 for i in range(1, len(L)):
4 flag = True
5 for j in range(len(S)):
6 if L[i] < S[j]:
7 before_j = S[: j] # elements in S before index j
8 new_j = [L[i]] # list containing just one element
9 after_j = S[j: ] # elements in S starting from index j
10 # what is the size of S now?
11 S = before_j + new_j + after_j
12 # what is the size of S now?
13 flag = False
14 break
15 if flag:
16 S.append(L[i])
17 print(S)

Options
(a)

1 [90, 47, 8, 18, 10, 7]

(b)

1 [7, 10, 18, 8, 47, 90]

(c)

1 [7, 8, 10, 18, 47, 90]

(d)

1 [90, 47, 18, 10, 8, 7]


(e)

1 [90, 7, 8, 10, 18 47]

Answer
(c)

Feedback
The code in question is a sorting algorithm called insertion sort. The core idea behind insertion
sort is to insert an item into an already sorted list and iteratively use this idea to sort the entire
list. Initially, the sorted list, , has just one element, namely the first element of the original list, .
In each subsequent step, we pick up the next element from the original list and insert it in the
right place in the sorted list . Eventually, we end up with a list which has the same elements as
but in sorted order. Let us first see the algorithm's execution on the list in question:

Step-1

In this step, is the list to be sorted. is a singleton list that has the first element of L and is
already sorted.

Step-2

We now pick up the second element in . Since , that is inserted before in .

Step-3

We now pick up the third element in . Since , that is inserted before in .

Step-4

We now pick up the fourth element in . Since is not less than , we compare it with the next
element in . Here, , so this is the right place to insert in .

Step-5

We now pick up the fifth element in . You must have a fair idea of what is happening.
Step-6

Finally, we pick up .

Code

How do we code this up? Notice that there is a nested loop. The outer loop iterates through the
elements of . We start iterating from as we have already taken care of the zeroth element in
. We will use zero-indexing for the rest of the explanation.

1 for i in range(1, len(L)):


2 flag = True

flag is a variable that tells us if the element has been inserted into the list or not. The
moment is inserted into within the inner loop, flag becomes False . Now, the inner loop
does the insertion part. It iterates through the list :

1 for j in range(len(S)):
2 if L[i] < S[j]:
3 before_j = S[: j] # elements in S before index j
4 new_j = [L[i]] # list containing just one element
5 after_j = S[j: ] # elements in S starting from index j
6 # what is the size of S now?
7 S = before_j + new_j + after_j
8 # what is the size of S now?
9 flag = False
10 break

Note the comparison of with each element in the list . The moment we see that
for some , we know that it is time to insert into . To this end, we create two
sub-lists before_j and after_j .

before_j represents the first elements in . That is,


after_j represents all elements after the element in . That is,
.

Since , we see that is going to become the new . This is how the insertion
happens:

1 S = before_j + new_j + after_j

Note that all three objects in the RHS of the above assignment are lists. The moment insertion is
done flag is updated to False . Now, some of you might be wondering what the following lines
do in the original code:

1 if flag:
2 S.append(L[i])
This is left as an exercise to you. One additional note, for some iterations in this code, we notice
that . In such a case before_j is . This is nothing but an empty list. Also,
is nothing but itself. This scenario occurs when is smaller than the smallest (zeroth)
element in . For example, consider the value of just before step-6.

Here, and , so:

1 before_j = [ ]
2 new_j = [7]
3 after_j = [8, 10, 18, 47, 90]

is the concatenation of these three lists.


Question-10
Statement
A square matrix is said to be symmetric if for . Note the
use of zero-based indexing here.

Assume that a square matrix M is already defined. Select all correct implementations of a
program that prints YES if it is a symmetric matrix and NO if it is not a symmetric matrix. (MSQ)

Options
(a)

1 # M is a square matrix which is already defined.


2 sym = True
3 for i in range(len(M)):
4 for j in range(len(M)):
5 if(M[i][j] == M[j][i]):
6 sym = True
7 else:
8 sym = False
9 if sym:
10 print('YES')
11 else:
12 print('NO')

(b)

1 # M is a square matrix which is already defined.


2 sym = True
3 for i in range(len(M)):
4 for j in range(len(M)):
5 if(M[i][j] == M[j][i]):
6 sym = True
7 else:
8 sym = False
9 break
10 if sym:
11 print('YES')
12 else:
13 print('NO')

(c)
1 # M is a square matrix which is already defined.
2 sym = True
3 for i in range(len(M)):
4 for j in range(len(M)):
5 if(M[i][j] == M[j][i]):
6 sym = True
7 break
8 else:
9 sym = False
10 if sym:
11 print('YES')
12 else:
13 print('NO')

(d)

1 # M is a square matrix which is already defined.


2 sym = True
3 for i in range(len(M)):
4 for j in range(i):
5 if(M[i][j] == M[j][i]):
6 sym = True
7 else:
8 sym = False
9 break
10 if sym:
11 print('YES')
12 else:
13 print('NO')

(e)

1 # M is a square matrix which is already defined.


2 sym = True
3 for i in range(len(M)):
4 for j in range(i):
5 if(M[i][j] != M[j][i]):
6 sym = False
7 break
8 if not sym:
9 break
10 if sym:
11 print('YES')
12 else:
13 print('NO')

Answer
(e)
Feedback
Consider the matrix :

In Pythonic terms, this matrix is:

1 M = [[3, 6, 1], [5, 3, 2], [1, 2, 3]]

Note that parts of the matrix may be symmetric. For example, in this matrix all the blue
elements conform to the specification for a symmetric matrix. The only two elements which break
this are and .

We iterate through the rows of the matrix in the outer-loop. Ideally, the moment we see a pair of
elements that break the property in any given row, we must break the iterative process. The
important point is, we have to break out of both the loops to entirely terminate the process. With
this understanding let us look at the correct option.

Correct option

1 # M is a square matrix which is already defined.


2 sym = True
3 for i in range(len(M)):
4 for j in range(i):
5 if(M[i][j] != M[j][i]):
6 sym = False
7 break
8 if not sym:
9 break
10 if sym:
11 print('YES')
12 else:
13 print('NO')

sym is a state-variable that is set to True in line-2. That is, we are optimistically assuming
that the matrix is symmetric to begin with. In line-5, we are checking if a pair of elements are
breaking the property. If they do so, then we update sym to False and break out of the
inner loop. But it is not enough to just break out of the inner loop, we also need to break out
of the outer loop. This is why we have an additional condition in line-8.
Another interesting point to note is the range that is used for the inner loop. In the row,
we are only going from till . We are not interested in the diagonal
elements . But more importantly, the elements in this row with column-index ,
will be eventually covered in subsequent iterations of the outer loop. This kind of iteration
can be pictured as follows:
Wrong options

Option-(a) is wrong as we are not breaking out of the loop anywhere when sym becomes
False . This is a problem because the bottom right element in will always make sym
True because for this case.
In option-(b), we are breaking out of the inner loop but not out of the outer loop.
Option-(c) is totally wrong as we are breaking at the wrong place.
Option-(d) is not breaking twice.

You might also like