#!/usr/bin/env python
# Source: http://stoma.name/
# started by Falko Krauze, continued by Szymon Stoma
#
# This module contains excercises in the form of functions.
# The functions always expect a level code as input argument.
# If you solved the exercise the function will return the level code of the next level.
# start with level 0 by calling the function level0

try:
        import IPython
except ImportError:
        print 'no Ipython available :('

#///////////////////////////////////////////////////////////////
def levelCodeOrFail(lc=True):
        if lc:
                print '''Please enter the level code as first argument!'''
        else:
                print '''Sorry this is not correct, please try again.'''

#///////////////////////////////////////////////////////////////
def level0(level_code=''):
        if not level_code:
                print '''
To complete this exercise you need to call this function with the
level code: 8Xsu33Hn
here is an example:
In [1]: level0('
levelcode')

HINTS:
Please substitute the string '
levelcode' with real code '8Xsu33Hn'
                '
''
        elif level_code=='8Xsu33Hn':
                print '''
Hoooray you made it!
You can go to the next level.
The level code is: 9fCkmGsy
You will reach the next level by calling
level1('
9fCkmGsy')
'
''
        else:
                print 'wrong level code'

#///////////////////////////////////////////////////////////////
def level1(level_code='',input=''):
        if not level_code:
                levelCodeOrFail()
        elif level_code=='9fCkmGsy':
                if not input:
                        print '''
To complete this exercise insert a list of integers from 0 to 941 into this function
here is an example:
In [1]: level1('
levelcode',[0,1,2,3])

HINTS:
1. Instead of typing numbers from 0 to 941 ;) consider using range() function..
In [1]: help range

2. Alternatively use for loop and append to the list:
l = []
l.append(1)
l.append(2)
for i in l:
  print i

'
''
                elif input==range(942):
                        print '''
Good!
The next level code is: YXHIY9AF
call level2('
YXHIY9AF')
'
''
                else:
                        levelCodeOrFail(False)
        else:
                print 'wrong level code'

#///////////////////////////////////////////////////////////////
def level2(level_code='',input=''):
        if not level_code:
                levelCodeOrFail()
        elif level_code=='YXHIY9AF':
                if not input:
                        print '''
To complete this exercise insert the sum of the integers from 0 to 941 into this function
here is an example:
In [1]: level2('
levelcode',1234)

HINTS:
1. You can use a loop like it was suggested in the previous level
'
''
                elif input==443211:
                        print '''
You made it!
The next level code is: L34XSOq9
call level3('
L34XSOq9')
'
''
                else:
                        levelCodeOrFail(False)
        else:
                print 'wrong level code'


#///////////////////////////////////////////////////////////////
def level3(level_code='',input=''):
        if not level_code:
                levelCodeOrFail()
        elif level_code=='L34XSOq9':
                if not input:
                        print '''
To complete this exercise insert the string:

I like 2 go 2 the next level

here is an example:
In [1]: level3('
levelcode','answer string')
'
''
                elif input=='I like 2 go 2 the next level':
                        print '''
Right on!
The next level code is: XahS6y6l
call level4('
XahS6y6l')
'
''
                else:
                        levelCodeOrFail(False)
        else:
                print 'wrong level code'

#///////////////////////////////////////////////////////////////
def level4(level_code='',input=''):
        if not level_code:
                levelCodeOrFail()
        elif level_code=='XahS6y6l':
                if not input:
                        print '''
To complete this exercise insert the string from level 3 as a list of words
here is an example:
In [1]: level4('
levelcode',['answer', 'string'])

HINTS:
1. consider using split function:
s = '
aaa bb c'
print s.split()
'
''
                elif input==['I', 'like', '2', 'go', '2', 'the', 'next', 'level']:
                        print '''
Congratulations!
The next level code is: acjYW08p
level5('
acjYW08p')
'
''
                else:
                        levelCodeOrFail(False)
        else:
                print 'wrong level code'

#///////////////////////////////////////////////////////////////
def level5(level_code='',input=''):
        if not level_code:
                levelCodeOrFail()
        elif level_code=='acjYW08p':
                if not input:
                        print '''
To complete this exercise insert only the 3rd element of the list of words from level 4
HINTS:
1. you can access list elements with list[index]

2. list start with the index 0
'
''
                elif input=='2':
                        print '''
Cowabonga!
The next level code is: B861yGOX
level6('
B861yGOX')
'
''
                else:
                        levelCodeOrFail(False)
        else:
                print 'wrong level code'
#///////////////////////////////////////////////////////////////
def level6(level_code='',input=''):
        if not level_code:
                levelCodeOrFail()
        elif level_code=='B861yGOX':
                if not input:
                        print '''
To complete this exercise insert the string from level 3 as an array of words.
This time insert only the first two elements and the last two elements as one list.

HINTS:
1. you can extract sub lists by with list[begin:end]
l = [1,2,3]
l[1:2] # [2]
l[-2] # [2] # second element from right
l[2] #  [3] # third elements (they are numered from 0)
2. you can concatenate lists with the + sign
l + l # [1,2,3,1,2,3]
'
''
                elif input==['I', 'like', 'next', 'level']:
                        print '''
Phantastic!
The next level code is: S8MvpTKz
level7('
S8MvpTKz')
'
''
                else:
                        levelCodeOrFail(False)
        else:
                print 'wrong level code'
#///////////////////////////////////////////////////////////////
def level7(level_code='',input=''):
        if not level_code:
                levelCodeOrFail()
        elif level_code=='S8MvpTKz':
                try:
                        if not input:
                                print '''
write a function that returns (not prints!) the string
hello world
insert your function as argument into this functions
In [1]: level7('
levelcode',myfunction)

HINTS:
To define a function use a similar syntax (arg1 is voluntary):
def f(arg1):
  return True

'
''
                        elif input()=='hello world':
                                print '''
all right!
The next level code is: tRT72s8m
level8('
tRT72s8m')
'
''
                        else:
                                levelCodeOrFail(False)

                except:
                        print "\nHint:  Insert the function not its result!"
        else:
                print 'wrong level code'

#///////////////////////////////////////////////////////////////
def level8(level_code='',input=''):
        if not level_code:
                levelCodeOrFail()
        elif level_code=='tRT72s8m':
                try:
                        if not input:
                                print '''
write a function that takes one input argument
if the input is 42 the function should return the bool True
if the input is any other number lager than zero it should return the bool False
if the input is a number smaler or equal to zero it should not return anything
insert your function as argument

HINTS:
To define a function use a similar syntax (arg1 is voluntary):
def f(arg1):
  return True
'
''
                        elif input(42) and not input(23) and input(0)==None and input(-34)==None:
                                print '''
Hoooray!
The next level code is: e82OApRu
level9('
e82OApRu')
'
''
                        else:
                                levelCodeOrFail(False)

                except:
                        print "\n:( this cant be right"
        else:
                print 'wrong level code'
#///////////////////////////////////////////////////////////////
def level9(level_code='',input=''):
        if not level_code:
                levelCodeOrFail()
        elif level_code=='e82OApRu':
                if not True:
                        pass
                else:
                        try:
                                import myexercise
                                reload(myexercise)
                        except ImportError:
                                print '''
write a module called

myexercise

the module should contain a function called

myfunction

the function should take one input argument and return the input as a string
if you are ready recall this function
level9('
e82OApRu')

HINTS:
1. You need to use external editor to create a file in the current directory.
The file should be named myexercise.py

2. Inside of this file you need to specify a funtion named myfunction:
def f():
  return True

3. Remember that function needs to be named myfunction (correct 2. accordingly)

4. Remember that function needs to take one argument (correct 2. accordingly)

5. Remember that function needs to return its input as a string (correct 2. accordingly)

6. To convert any value to string please use:
i = 5
str(i)
'
''
                                print "could not import the module myexercise ..yet"
                                return
                        else:
                                try:
                                        if myexercise.myfunction(1)=='1' and myexercise.myfunction(1.0)=='1.0' and myexercise.myfunction(True)=='True' and myexercise.myfunction('a')=='a':
                                                print '''
You made it!

Here is your Bunny

                    _ _
                   /_/_      .'
'.
                =O(_)))) ...'
    `.
                   \_\              `.    .''B'zzzzzzzzzzz
                                      `..'


                            /|      __  
                           / |   ,-~ /  
                          Y :|  //  /    
                          | jj /( .^  
                          >-"~"-v"  
                         /       Y    
                        jo  o    |  
                       ( ~T~     j  
                        >._-' _./  
                       /   "
~"  |    
                      Y     _,  |      
                     /| ;-"
~ _  l    
                    / l/ ,-"~    \
                    \//\/      .- \
                     Y        /    Y*  
                     l       I     !
                     ]\     _\   /"
\
                    (" ~----( ~   Y.  )  
            ~~~~~~~~~~~~~~~~~~~~~~~~~~    

'''
                                        else:
                                                print 'import went well, but the function did not work properly'
                                except AttributeError:
                                        print '''module imported but I could not find the function myfunction'''


        else:
                print 'wrong level code'

#///////////////////////////////////////////////////////////////

#///////////////////////////////////////////////////////////////
if __name__=="
__main__":
        print '''
This module contains excercises in the form of functions.
The functions always expect a level code as input argument.
If you solved the exercise the function will return the level code of the next level.
start with level 0 by calling the function level0

PLEASE TYPE: level0()
        '''
        from IPython.Shell import IPShellEmbed
        ipshell = IPShellEmbed()
        ipshell() # this call anywhere in your program will start IPython