<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Introductory exercices
Step2:  Prod
Python has a function sum that sums the elements of a list. Write a function that calculates the product of all the elements of a list.
Step4:  Sum has an optional argument. Implement the same optional argument in your function.
Step5:  Sum of lists
If you have 2 lists, a and b, a+b does not add the elements of the list. Write a function that does that. There is already a python function called sum. Try what happens if you call your function sum. 
The zip function can be helpful. Try zip([1,2,3], [4,5,6]).
Step6:  Prime numbers
Write a module that implements a function that returns all the prime numbers up to a limit. (Use the Sieve of Erastothenes method)
Step7:  Optional and default arguments
Imagine a function to submit jobs to a queue. Here you see its first lines.
Step8:  Try to predict and understand the output of these calls to the function
Step9:  The follwing function uses argument unpacking. This is a powerful technique.
Step10:  Call this function with different arguments and understand its output
Step11:  Call it several times (with a without arguments) and see what happens. Execute it in Pythontutor and see if you can understand better the behaviour.
This blog entry gives a further explanation. The main idea is that the def statement is executed when the function is defined
Step12:  Now you should be able to predict the result of this cell (example from here)
Step13:  But how is this solved? How to create an empty list of dictionary as a default argument. Here is a way to do it
<ASSISTANT_TASK:>
Python Code:
def heaviside(x):
    #finish
#check it
print(heaviside(-5.4), heaviside(7), heaviside(0))
Explanation: Introductory exercices: Functions
Heaviside function
Write a function that returns the Heaviside function.
End of explanation
def prod(x):
    
    sum(iterable) -> value
    
    #Finish
#Test it
prod([1,2,3])
Explanation: Prod
Python has a function sum that sums the elements of a list. Write a function that calculates the product of all the elements of a list.
End of explanation
def prod(x, start = 1):
    
    sum(iterable[, start]) -> value
    
    Return the product of an iterable of numbers (NOT strings) times the value
    of parameter 'start' (which defaults to 1).  When the iterable is
    empty, return start.
    
    # Finish
prod([1,2,3], 10)
Explanation: Sum has an optional argument. Implement the same optional argument in your function.
End of explanation
def lists_sum(a,b):
    #Finish
lists_sum([4,3,2], [4,1,3])
Explanation: Sum of lists
If you have 2 lists, a and b, a+b does not add the elements of the list. Write a function that does that. There is already a python function called sum. Try what happens if you call your function sum. 
The zip function can be helpful. Try zip([1,2,3], [4,5,6]).
End of explanation
def primes_sieve_list(limit):
    #Do it...
# see also http://rosettacode.org/wiki/Sieve_of_Eratosthenes#Python
Explanation: Prime numbers
Write a module that implements a function that returns all the prime numbers up to a limit. (Use the Sieve of Erastothenes method)
End of explanation
def submit(job, priority=10, nprocs=1):
    print("Job {} submitted with priority {} and {} processors.".format(job, priority, nprocs))
    # And here you would do the actual submission...
Explanation: Optional and default arguments
Imagine a function to submit jobs to a queue. Here you see its first lines.
End of explanation
submit()
submit('job1')
submit('job1', nprocs=5)
submit('job1', 5)
submit('job1', 5, nprocs=2)
submit('job1', 5, priority=5)
Explanation: Try to predict and understand the output of these calls to the function:
End of explanation
def print_args(*args, **kwargs):
    for i, arg in enumerate(args):
        print('positional argument {} = {}'.format(i,arg))
    for key in kwargs:
        print('keyword argument {} = {}'.format(key, kwargs[key])
Explanation: The follwing function uses argument unpacking. This is a powerful technique.
End of explanation
def f(data=[]):
    data.append(1)
    return data
Explanation: Call this function with different arguments and understand its output:
print_args(), print_args(5,6,5), print_args([5,4]), print_args(time = 0.0), print_args('a', b', c='c'), print_args(c = 'c', 'a', 'b'),print_args('a', c = 'c', 'b'), etc.
We have not covered all the possibilities of function arguments. Check the documentation for things link forcing the use of only keyword arguments.
Tricky default arguments
The use of default mutable arguments is a source of confusion for novice Python users. Imagine you need to write a function that has an optional argument, which is a list. This function appends something to that list, or creates it if called without arguments. A naive approach would be:
End of explanation
def f(x):
    print("In f(x), x =",x)
    return x*2
def g(x=f(3)):
    print("In g(x), x =",x)
    return None
g()
Explanation: Call it several times (with a without arguments) and see what happens. Execute it in Pythontutor and see if you can understand better the behaviour.
This blog entry gives a further explanation. The main idea is that the def statement is executed when the function is defined:
End of explanation
fruits = ("apples", "bananas", "loganberries")
def eat(food=fruits):
    print(food)
eat()
fruits = ("blueberries", "mangos")
eat()
Explanation: Now you should be able to predict the result of this cell (example from here):
End of explanation
def f(data=None):
    if data is None:
        data = []
    data.append(1)
    return data
Explanation: But how is this solved? How to create an empty list of dictionary as a default argument. Here is a way to do it:
End of explanation
<END_TASK>