Amicable numbers are two different numbers so related that the sum of the proper divisors of each is equal to the other number. A proper divisor of a number is a positive factor of that number other than the number itself. For example, the proper divisors of 6 are 1, 2, and 3. 220 and 284 are amicable as the sum of the proper divisors of 220 is 284 and the sum of the proper divisors of 284 is 220. We will be using amicable numbers in a simple procedure to encode and decode messages. Let's call the procedure Amicable Encryption.

The process of Amicable Encryption is described in the example below:

- Shaniqua generates a key by finding a pair of amicable numbers within a specified range, for example between 200 and 300. This key will be used to encrypt/encode and decrypt/decode messages. She sends one of the numbers from the pair that forms the key to her bff Shontelle.
- Shaniqua, wishing to send a message to Shontelle about Bob, uses the same number she sent to Shontelle -from the key- and her message as inputs to a function that generates the encoded message. She sends this message to Shontelle.
- Shontelle uses the number she received from Shaniqua and the encoded message as inputs to another function which generates Shaniqua's original message.

Having read the message Shontelle exclaims “OMG, for real?” Let's write the functions that will enable these girls to share their secrets. You do not need to consider error conditions in your code, just assume the expected inputs are always entered.

1. Write a function called sumDivs that accepts a single, positive integer and calculates the sum of all of its proper divisors. Use a for loop to find and sum the proper divisors of the given integer. For example,

>>> sumDivs(8)

7

2. Now write a function called findAmicable. This function takes two(2) positive integers (a lower and an upper bound) as inputs and uses these to find the first pair (if any) of amicable numbers that exist within the range specified by the two numbers. If a pair of amicable numbers is found, the function returns them as a tuple, otherwise it returns (0,0). For example,

>>> findAmicable(100,200)

(0,0)

>>> findAmicable(200,300)

(220,284)

Use a for loop to cycle through the numbers within the range specified by the function's two inputs. findAmicable must use sumDivs to perform its calculations.

3.Write a function called encrypt. This function takes a single character and a positive integer as its inputs. encrypt does the following:

(a) gets the ord of the character

(b) calls sumDivs with the integer input as its argument

(c) calculates the sum of the results of parts (a) and (b)

(d) returns the chr of the result of part (c)

For example,

>>> encrypt('C',220)

's'

4. Now write function decrypt which takes a single character and a positive integer as its inputs and does the following:

(a) gets the ord of the character

(b) calls sumDivs with the integer input as its argument

(c) calculates the difference of the results of parts (a) and (b)

(d) returns the chr of the result of part (c)

For example,

>>> decrypt('s',220)

'C'

5. Write the function called encryptMessage. This function takes a string and a positive

integer and encrypts the string using the integer as the key. It is a recursive function that

loops through each character of the string and calls encrypt that you wrote above to

encode each character. It concatenates (joins) the encoded characters and returns the

encoded message. For example,

>>> encryptMessage('COMP 1126',220)

'suuUlooOOE'

6. Write the function called decryptMessage. This function takes a string and a positive

integer and decrypts the string using the integer as the key. It is a recursive function that

loops through each character of the string and calls decrypt that you wrote above to

decode each character. It concatenates the decoded characters and returns the original

message. For example,

>>> decryptMessage('suuUlooOOE',220)

'COMP 1126'

Solution:

def sumDivs(num): sum = 0 for i in range(num): if(i>0): if(num%i==0): sum=sum+i return sum def findAmicable(lower, upper): tup1 = (0,0) for i in range(lower,upper): properDiv1 = sumDivs(i); if(properDiv1>=lower and properDiv1<=upper): properDiv2 = sumDivs(properDiv1); if(properDiv2 == i): tup1 = (properDiv2,properDiv1) return tup1 return tup1 def encrypt(mychar, myint): getORD = ord(mychar) myNum = sumDivs(myint) mySum = getORD + myNum return chr(mySum) def decrypt(mychar, myint): getORD = ord(mychar) myNum = sumDivs(myint) myDiff = getORD - myNum return chr(myDiff) def encryptMessage(myString, myInt): if(len(myString) <= 1): return encrypt(myString, myInt) return encrypt(myString[0], myInt) + encryptMessage(myString[1:], myInt) def decryptMessage(myString, myInt): if(len(myString) <= 1): return decrypt(myString, myInt) return decrypt(myString[0], myInt) + decryptMessage(myString[1:], myInt)