# Noget eksemplekode, som man kan bruge til at forstå flow-of-control
# ved kald af funktioner (C# og Java: metoder).
# 
# Man opfordres til at følge flow-of-control (og størrelsen af
# systemets stak) ved at udføre koden i hånden først og checke mod
# output.

######################################################################

print()
print("## Basis eksempel: tre funktioner, som kalder hinanden ###############")
print()

def salute(name):
    print("Hej " + name + "!")
    salute1(name)

def salute1(name):
    print("Hej " + "igen " + name + "!")
    salute2(name)
          
def salute2(name):
    print("Hej " + "igen " * 2 + name + "!")
          
salute("Kim")

######################################################################

print()
print("## Samme funktioner, marker start og slut af kald ####################")
print()

def salute(name):
    print(" -> Start af kald til salute")
    print("Hej " + name + "!")
    salute1(name)
    print(" <- Slut på kald til salute")

def salute1(name):
    print(" -> Start af kald til salute1")
    print("Hej " + "igen " + name + "!")
    salute2(name)
    print(" <- Slut på kald til salute1")
          
def salute2(name):
    print(" -> Start af kald til salute2")
    print("Hej " + "igen " * 2 + name + "!")
    print(" <- Slut på kald til salute2")
          
salute("Kim")

######################################################################

print()
print("## Rekursiv udgave af basis eksempel, to rekursionsdybder ############")
print()
# 
# Her laves samme output som i det første eksempel, men der er kun ÉN
# funktion, som kalder sig selv (med nye parametre hver gang). En
# funktion, som kalder sig selv, kaldes REKURSIV.

def saluteRecursive(name,current,max):
    if current <= max:
        print("Hej " + "igen "*current + name + "!")
        saluteRecursive(name,current+1,max)
    else:
        pass # do nothing

saluteRecursive("Kim",0,2)

# Bemærk, at denne version endda er mere generel, da man nemt kan
# variere antallet af kald (dybden af rekursionen):

print()
saluteRecursive("Kim",0,3)

######################################################################

print()
print("## Rekursiv udgave, marker start og slut af kald, to dybder ##########")
print()
#
# Den samme rekursive funktion, nu med markering af start og slut af
# kald.

def saluteRecursive(name,current,max):
    print(f" -> Start af kald til saluteRecursive med {current} og {max}")
    if current <= max:
        print("Hej " + "igen "*current + name + "!")
        saluteRecursive(name,current+1,max)
    else:
        pass # do nothing
    print(f" <- Slut på kald til saluteRecursive med {current} og {max}")

saluteRecursive("Kim",0,2)

print()

saluteRecursive("Kim",0,3)

######################################################################

print()
print("## To kald per funktion ##############################################")
print()
# 
# Illustration af, at en funktion kan kalde en anden funktion flere
# gange.

def saluteMore(name):
    print("Hej " + name + "!")
    saluteMore1(name)
    saluteMore1(name)

def saluteMore1(name):
    print("Hej " + "igen " + name + "!")
    saluteMore2(name)
    saluteMore2(name)
    
def saluteMore2(name):
    print("Hej " + "igen " * 2 + name + "!")

saluteMore("Kim")

######################################################################

print()
print("## To kald per funktion, rekursiv udgave, to rekursionsdybder ########")
print()
#
# Dette gælder også, selv om man kalder sig selv.

def saluteMoreRecursive(name,current,max):
    if current <= max:
        print("Hej " + "igen "*current + name + "!")
        saluteMoreRecursive(name,current+1,max)
        saluteMoreRecursive(name,current+1,max)
    else:
        pass # do nothing

saluteMoreRecursive("Kim",0,2)

# Igen er den rekursive version mere generel, da man nemt kan variere
# dybden af rekursionen:

print()
saluteMoreRecursive("Kim",0,3)

######################################################################

print()
print("## To kald per funktion, rekursiv udgave, marker start og slut #######")
print()
# 
# Den samme rekursive funktion, nu med markering af start og slut af
# kald.

def saluteMoreRecursive(name,current,max):
    print(f" -> Start af kald til saluteMoreRecursive med {current} og {max}")
    if current <= max:
        print("Hej " + "igen "*current + name + "!")
        saluteMoreRecursive(name,current+1,max)
        saluteMoreRecursive(name,current+1,max)
    else:
        pass # do nothing
    print(f" -> Slut på kald til saluteMoreRecursive med {current} og {max}")

saluteMoreRecursive("Kim",0,2)
