#13-1###################################################
"""
Write a function called rectangle that takes two integers
m and n as arguments and prints out an mx n box consisting
of asterisks. Shown below is the output of rectangle(2,4)
****
****

"""

##def rectangle(m,n):
##    for i in range(0,m):
##        out = n * "*"
##        print(out)
##rectangle(2,4)



#13-2####################################################
"""(a) Write a function called add_excitement that takes
a list of strings and adds an exclamation point (!) to
the end of each string in the list. The program should
modify the original list and not return anything.
(b) Write the same function except that it should not
modify the original list and should instead return a
new list."""


##def add_exictement(x):
##    x=[words + "!" for words in x]
##def add_exictement2(x):
##    new_c =[]
##    for words in x:
##        new_word =words + "!"
##        new_c.append(new_word)
##    return new_c



#13-3######################################################
"""Write a function called sum_digits that is given an
integer num and returns the sum of the digits of num."""


##def sum_digits(num):
##    num_list = []
##    for numbers in range(num):
##        num_list.append(numbers)
##    print(sum(num_list))    
##sum_digits(4)
    

#13-4######################################################
"""The digital root of a number n is obtained as follows:
Add up the digits n to get a new number. Add up the digits
of that to get another new number. Keep doing this until
you get a number that has only one digit. That number is
the digital root. For example, if n = 45893, we add up the
digits to get 4 + 5 + 8 + 9 + 3 = 29. We then add up the
digits of 29 to get 2 + 9 = 11. We then add up the digits
of 11 to get 1 + 1 = 2. Since 2 has only one digit, 2 is
our digital root. Write a function that returns the digital
root of an integer n. [Note: there is a shortcut, where the
digital root is equal to n mod 9, but do not use that here.]"""

##def digital_root(num):
##    num = str(num)
##    sum=0
##    for i in range(len(num)):
##        sum = sum + int(num[i]) % 9
##    if(sum == 0):
##       return 9
##    else:
##        return sum % 9
##print(digital_root(45893))



#13-5######################################################
"""Write a function called first_diff that is given two
strings and returns the first location in which the strings
differ. If the strings are identical, it should return -1."""

##def first_diff(x,y):
##    if len(x) == len(y):
##        for i in range(1,len(x) + 1):
##            if x[:] == y[:]:
##                print("-1")
##            elif x[:i] != y[:i]:
##                print("They differ at the ",i, "Character",x[:i],y[:i])
##                break
##    else:
##        print("These are non identical Strings")
##first_diff("h2nry","henry")


#13-6######################################################
"""Write a function called binom that takes two integers n
and k and returns the binomial coefficient
  n!
k!(n􀀀k)! .

"""


##def binomialCoeff(n, k):
##    if k > n:
##        return 0
##    if k == 0 or k == n:
##        return 1
##    # Recursive Call
##    return binomialCoeff(n - 1, k - 1) + binomialCoeff(n - 1, k)
##print(binomialCoeff(5,2))
###credit https://www.geeksforgeeks.org/binomial-coefficient-dp-9/


#13-7######################################################
"""Write a function that takes an integer n and returns a
random integer with exactly n digits. For instance, if n is
3, then 125 and 593 would be valid return values, but 093
would not because that is really 93, which is a two-digit
number."""

##import random
##def generate_num(n):
##    random_num =random.randint(0, 10 ** n - 1)
##    if random_num >100:
##        print("Valid",random_num)
##    else:
##        print("invalid",random_num)
##generate_num(3)



#13-8######################################################
"""Write a function called number_of_factors that takes an
integer and returns how many factors the number has."""

##def factors_num(n):
##    count = 0
##    for  num in range(1,n):
##         if n % num ==0:
##            count += 1
##    print(count)
##factors_num(28)


#13-9######################################################
"""Write a function called factors that takes an integer
and returns a list of its factors."""

##def factors(n):
##    list_factors=[]
##    for i in range(n):
##        if i > 0 and n % i == 0 :
##            list_factors.append(i)
##    print(list_factors)
##factors(12)


#13-10######################################################
"""Write a function called closest that takes a list of
numbers L and a number n and returns the largest element in
L that is not larger than n. For instance, if L=[1,6,3,9,11]
and n=8, then the function should return 6, because 6 is the
closest thing in L to 8 that is not larger than 8. Don’t
worry about if all of the things in L are smaller than n."""



##def closest(L,n):
##    for i in range(len(L)):
##        new_list=[]
##        for number in L:
##            if number < n:
##                new_list.append(number)
##    print(max(new_list))
##closest([1,6,3,9,11],8)


#13-11######################################################
"""Write a function called matches that takes two strings as
arguments and returns how many matches there are between the
strings. A match is where the two strings have the same
character at the same index. For instance, 'python' and
'path' match in the first, third, and fourth characters, so
the function should return 3."""

##def matches(x,y):
##    count = 0
##    for i in range(len(x)):
##        for j in range(len(y)):
##            if x[i] == y[j]:
##                count += 1
##    print(count)    
##matches("python","path")


#13-12######################################################
"""Recall that if s is a string, then s.find('a') will find
the location of the first a in s. The problem is that it
does not find the location of every a. Write a function
called find all that given a string and a single character,
returns a list containing all of the locations of that
character in the string. It should return an empty list if
there are no occurrences of the character in the string."""


##import re
##def find_all(a_str, sub):
##    start = 0
##    while True:
##        start = a_str.find(sub, start)
##        if start == -1: return
##        yield start
##        start += len(sub) # use start += 1 to find overlapping matches
##print(list(find_all("Henrye","e")))


#13-14######################################################    
"""Write a function called is_sorted that is given a list
and returns True if the list is sorted and False otherwise."""


##def is_sorted(l):
##    if l ==sorted(l):
##        print (True)
##    else:
##        print(False)
##is_sorted([1,4,2,5])
##array = [3,5,-4,8,11,1,-1,6]





#13-15######################################################   
"""Write a function called root that is given a number x and
an integer n and returns x1=n. In the function definition,
set the default value of n to 2."""

##def root(x,n=2):
##    print(x**(1/n))
##root(36)


#13-16######################################################   
"""Write a function called one_away that takes two strings
and returns True if the strings are of the same length and
differ in exactly one letter, like bike/hike or water/wafer."""

"""
count = 0
if len(a) == len(b)
    for i in a:
        for j in b:
            if i != j:
            count += 1
       if count == 1:
       print(true)
        

"""

##def one_way(a,b):
##   u = zip(a,b)
##   count =0
##   if len(a) == len(b):
##       for i , j in u:
##           if i != j:
##               count += 1
##       if count == 1:
##          print(True)
##   else:
##       print("Not the same length")    
##one_way("Henry","Henrxf")
    
    

#13-17######################################################   
"""(a) Write a function called primes that is given a number
n and returns a list of the first n primes. Let the default
value of n be 100. (b) Modify the function above so that
there is an optional argument called start that allows the
list to start at a value other than 2. The function should
return the first n primes that are greater than or equal to
start. The default value of start should be 2."""


##def primes(n=10):
##    primes_l=[]
##    for number in range(1, 10):
##      if number >1:
##          for i in range(2, number):
##
##              if (number % i) == 0:
##                  break
##          else:
##              primes_l.append(number)
##    print(primes_l)
##primes(10)


#13-18######################################################   
"""Our number system is called base 10 because we have ten
digits: 0, 1, . . . , 9. Some cultures, including the Mayans
and Celts, used a base 20 system. In one version of this
system, the 20 digits are represented by the letters A
through T. Here is a table showing a few conversions:
10 20 10 20 10 20 10 20
0 A 8 I 16 Q 39 BT
1 B 9 J 17 R 40 CA
2 C 10 K 18 S 41 CB
3 D 11 L 19 T 60 DA
4 E 12 M 20 BA 399 TT
5 F 13 N 21 BB 400 BAA
6 G 14 O 22 BC 401 BAB
7 H 15 P 23 BD 402 BAC
Write a function called base20 that converts a base 10 number
to base 20. It should return the result as a string of base
20 digits. One way to convert is to find the remainder when
the number is divided by 20, then divide the number by 20,
and repeat the process until the number is 0. The remainders
are the base 20 digits in reverse order, though you have to
convert them into their letter equivalents.

"""

##def base20():
##    pass


#13-19######################################################   
"""Write a function called verbose that, given an integer
less than 1015, returns the name of the integer in English.
As an example, verbose(123456) should return one hundred
twenty-three thousand, four hundred fifty-six."""



##def verbose(num):
##    d ={0:"zero",1:"one",2:"two",3:"three",4:"four",5:"five",6:"six",7:"seven",8:"eight",9:"nine",10:"ten",
##        11:"eleven",12:"twelve",13:"thirteen",14:"fourteen",15:"fiftheen",16:"sixteen",17:"seventeen",18:"eighteen",
##        19:"nineteen",20:"twenty",30:"30",40:"fourty",50:"fifthy",60:"sixty",70:"Seventy",80:"eighty",90:"Ninety"}
##    if num <20:
##       return d[num]
##    if num <100 :
##        if num % 10 == 0:
##            return d[num]
##        else:
##            return d[num //10 * 10] + verbose(num % 10)
##    if num < 10 **3:
##       if num % 100 == 0:
##          return d[num] + "hundred"
##       else:
##           return d[num//100] + "hundred and " + verbose(num % 100)
##    if num < 10 **6:
##       if num % 10**3 == 0:
##          return verbose(num) + "Thousand"
##       else:
##          return verbose(num//10**3)+ "Thousand " + verbose(num % 10**3)
##    if num < 10 ** 9:
##       if num % 10 **6 == 0:
##          return verbose(num//10**6) + "Million"
##       else:
##           return verbose(num // 10**6) + " Million " + verbose(num % 10**6)
##print(verbose(123456))


#13-20######################################################   
"""Write a function called merge that takes two already
sorted lists of possibly different lengths, and merges them
into a single sorted list.
(a) Do this using the sort method.
(b) Do this without using the sort method."""


##def merge_withsort(l1,l2):
##    result = l1 + l2
##    print((sorted(result)))    
##merge_withsort([1,3,4,6],[2,4,5,6,7])
##def merge_withoutsort(l1,l2):
##    l3 =l1+l2
##    for i in range(len(l3)):
##        for j in range(1+i,len(l3)):
##            if l3[i] > l3[j]:
##                l3[i], l3[j] = l3[j], l3[i]
##    print(l3)
##merge_withoutsort([2,5,4,6,1],[7,6,5,4,3,0])


    




  
