# NPTEL The Joy Of Computing Using Python Week 6 Assignment 1 July 2023 | NPTEL

## What will be the output of the following code?

```import string

def shift(word, value):
letters = string.ascii_lowercase
new = ""

for i in range(len(word)):
if word[i] in letters:
index = letters.index(word[i])
new = new + letters[(index + value) % 26]
else:
new = new + word[i]

return new
```
a. Shift every letter in a given word by value.
b. Shift every letter in a given word by 1.
c. Shift every letter in a given word by 26.
d. Returns the same word.

a. Shift every letter in a given word by value.

Given code snippet is for a basic implementation of a Caesar cipher, which is a simple encryption technique that shifts letters by a certain value.

Code Example:
```import string

def shift(word, value):
letters = string.ascii_lowercase
new = ""

for i in range(len(word)):
if word[i] in letters:
index = letters.index(word[i])
new = new + letters[(index + value) % 26]
else:
new = new + word[i]

return new

# Example usage
word = "hello"
shifted_word = shift(word, 3)
print(shifted_word)  # Output will be "khoor"

```

## In the list L = [4,6,7,4,6,2,1], What is the index of element ‘7’?

a. 0
b.1
c. 2
d. 3

c. 2

In Python, list indices start from 0, so the first element of a list has index 0, the second element has index 1, and so on

## Which of the following is true about recursion?

a. Recursion always performs better than non-recursive code.
b. Recursive code is easier to debug.
c. The base case is necessary for recursion.
D. Recursive code can be shorter than non-recursive code

c. The base case is necessary for recursion.

Recursion requires a base case to define the endpoint or termination condition of the recursive process. Without a base case, the recursion could potentially continue infinitely, leading to a stack overflow or excessive resource consumption. The base case is a crucial element that ensures the recursion eventually stops and returns the desired result.

Therefore, the statement "The base case is necessary for recursion" is true. Recursive code can be shorter than non-recursive code, but this is not always the case, and it depends on the problem being solved. The other two statements, "Recursion always performs better than non-recursive code" and "Recursive code is easier to debug" are false.

## What will be the output of the following program?

```def recursive(num):
if num == 1:
return 1

return num*(num - 1)```
a. Calculating sum of first n terms.
b. Calculating product of first n terms.
c. Calculating power of first n terms.
d. Calculating sum of last n terms.

Calculating product of last n terms.Here n = 2

```def recursive(num):
if num == 1:
return 1

return num*(num - 1)

print(recursive(6))

Output:
30

```

## In Caesar cipher,the mediator needs to make maximum of how many trails to break the code?

a. 1
b. 26
c. no trail needed
d. 10

b. 26

In a Caesar cipher, where there are 26 possible shift values (one for each letter of the alphabet), the mediator needs to make a maximum of 26 trials to break the code. Each trial involves trying all possible shift values to decipher the message. After trying all 26 shifts, one of them will result in the correct decryption.

26

## What is the output of the following program?

`  `
a. 3628800
b. Runs into an infinite loop
c. 55
d. Syntax error

b. Runs into an infinite loop

IndexError: list index out of range

Given Code is missing base case, which is necessary to stop the recursion. Here's the corrected code:

```Corrected Code:
def recursive(L):
if len(L) == 0:
return 1
return L[-1] * recursive(L[:-1])

print(recursive([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]))
With this corrected code, the output will be the product of all the numbers in the list, which is 3628800, as previously explained.
```

## What's the correct code for Binary search?

```def Binary(L, find, start, end):
mid = (start + end) // 2

if start == end:
if L[end] == find:
return end
else:
return -100

if L[mid] == find:
return mid
elif find > L[mid]:
return Binary(L, find, mid + 1, end)
else:
return Binary(L, find, start, mid - 1)

# Example usage
sorted_array = [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
target = 11
result = Binary(sorted_array, target, 0, len(sorted_array) - 1)

if result != -100:
print(f"Target {target} found at index {result}")
else:

```

## Which of the following is TRUE about MIN-MAX strategy?

a. Maximize the chances of your winning and minimize the changes of the opponent winning
b. The game with min-max strategy can never be drawn
c. Minimize the chances of your winning and maximize the chances of the opponent winning
d. All the above are true

a. Maximize the chances of your winning and minimize the changes of the opponent winning

The Minimax strategy is a decision-making algorithm used in game theory to determine the optimal move for a player in a two-player zero-sum game, where one player's gain is the other player's loss. In the Minimax strategy, the two players are called the maximizer and the minimizer. The maximizer tries to get the highest score possible, while the minimizer tries to get the lowest score possible. Therefore, the statement "Maximize the chances of your winning and minimize the chances of the opponent winning" is true. The game with Minimax strategy can be drawn, and it depends on the game being played. Therefore, the statement "The game with Minimax strategy can never be drawn" is false. The statement "Minimize the chances of your winning and maximize the chances of the opponent winning" is false because it is the opposite of what the Minimax strategy aims to achieve. Therefore, the correct answer is that "Maximize the chances of your winning and minimize the chances of the opponent winning" is true.

## A program that is written recursively cannot be written in a non-recursive manner.

a. True
b. False

b. False
Writing a program recursively often allows for an alternative non-recursive version through the utilization of iterative techniques such as loops. Recursion and iteration represent distinct strategies for problem-solving. Frequently, problems solvable via recursion can also be addressed iteratively. However, specific problems may exhibit a greater compatibility with one approach over the other. Deciding between recursion and iteration hinges on considerations like code readability, performance, and the inherent structure of the problem at hand.

## what will be the output of the following program?

```def recursive(num):
if(num==1):
print('*')
return

if(nums%2==0):
print('*'*num)
recursive(num-1)
return

else:
recursive(num-1)
return

recursive(10)

a.
**********
*********
********
*******
******
*****
****
***
**
*

b.
*********
*******
*****
***
*

c. Runs into infinite loop

d.
**********
********
******
****
**
*```