# A Concise Notes on Functional Programming with Python

Original article was published on Artificial Intelligence on Medium Breaking down your program into multiple parts gives us great flexibility over the code. The concept of functional programming enables a programmer to write better programs with higher simplicity. Even though python is object-oriented in nature the implementation of function concepts in python is very simple. This article will help you to understand the basics of function creation and some advanced functional programming concepts.

# What is a function?

A function is a small piece of code that does something in the program with or without getting input parameters. Function usually prints the output or returns a value to the place from where the function is called. Still, confusing? Let me try to simplify the concept of functions using a scenario. Imagine you are going to buy a birthday cake for your friend. Who will you approach to make a cake? A doctor or a baker? That will be a baker. Because bakers are someone who can prepare a cake for you. It doesn’t mean a doctor cannot bake a cake. Instead of one person doing all kinds of work, we can categorize people into multiple professions. Here each professional has its unique type of services by getting unique types of requirements from the consumer.

The function works in the same manner. A function is a unique code snippet created by the developer to use wherever he needs the same kind of operations. Look at the following code sample without any function definition.

`name_1 = input("Your Name Here:")year_of_birth_1 = int(input())name_2 = input("Your Name Here:")year_of_birth_2 = int(input())name_3 = input("Your Name Here:")year_of_birth_3 = int(input())print("Check",name_1,"'s YOB is Leap or Not:")if(year_of_birth_1%4==0): if(year_of_birth_1%100==0): if(year_of_birth_1%400==0): print("Leap Year") else: print("Not Leap Year") else: print("Leap Year")else: print("Not Leap Year")print("Check",name_2,"'s YOB is Leap or Not:")if(year_of_birth_2%4==0): if(year_of_birth_2%100==0): if(year_of_birth_2%400==0): print("Leap Year") else: print("Not Leap Year") else: print("Leap Year")else: print("Not Leap Year")print("Check",name_3,"'s YOB is Leap or Not:")if(year_of_birth_3%4==0): if(year_of_birth_3%100==0): if(year_of_birth_3%400==0): print("Leap Year") else: print("Not Leap Year") else: print("Leap Year")else: print("Not Leap Year")`

The output of the above program is given below.

`Your Name Here:Felix2000Your Name Here:Antony1998Your Name Here:Alex2004Check Felix 's YOB is Leap or Not:Leap YearCheck Antony 's YOB is Leap or Not:Not Leap YearCheck Alex 's YOB is Leap or Not:Leap Year`

In the above program, the same operations are performed in three different places. Imagine this kind of program in which the same kind of operations is conducted many times. The final code will be a complex one. Now take a look at the following program in which a function called `check_leap `is created used wherever required.

`def check_leap(YOB): if(year_of_birth_3%4==0): if(year_of_birth_3%100==0): if(year_of_birth_3%400==0): print("Leap Year") else: print("Not Leap Year") else: print("Leap Year") else: print("Not Leap Year")name_1 = input("Your Name Here:")year_of_birth_1 = int(input())name_2 = input("Your Name Here:")year_of_birth_2 = int(input())name_3 = input("Your Name Here:")year_of_birth_3 = int(input())print("Check",name_1,"'s YOB is Leap or Not:")check_leap(year_of_birth_1)print("Check",name_2,"'s YOB is Leap or Not:")check_leap(year_of_birth_2)print("Check",name_3,"'s YOB is Leap or Not:")check_leap(year_of_birth_3)`

It gives the same output as the previous program but it is really easy to understand. The statements required for checking leap year is written only one time in the program. That is why functional programming gives us easy debugging chances.

`Your Name Here:Felix2000Your Name Here:Antony1998Your Name Here:Alex2004Check Felix 's YOB is Leap or Not:Leap YearCheck Antony 's YOB is Leap or Not:Not Leap YearCheck Alex 's YOB is Leap or Not:Leap Year`

# Classification of Functions

I hope you have understood the basic need for functions in programming. In python, we can further classify the functions into two different types. They are user-defined functions and in built functions. The in built functions are functions that are readily available to be called in the program. In the definition before the first program, I have mentioned that I am going to write a program without function definition not without function. Yes! We have already used some functions in that program too. The functions `input`and `print`are some examples of in built functions. These in built functions are created by the developers of the language with some inner engineering like the `check_leap`function. This `check_leap `is an example of user-defined functions that are created by the programmer as per the requirement.

## Definition and Call of a function

The instructions written under the `check_leap` function are called function definition. This defined instructions will be executed whenever a function is called from a particular place.

The `check_leap` function with a value passed through it is called a function call. The function can be called with or without any value. The value passed through the function is called parameter or arguments. Based on the arguments passed and return value the user-defined function can be classified into four groups.

• Function without Argument and without Return Value
• Function without Argument and with Return Value
• Function with Argument and without Return Value
• Function with Argument and with Return Value

## Function without argument and without return value

The value returned by the function is called the return value. We can return a value from a user-defined function by using a keyword called `return`. Some functions don’t require any arguments to be passed and return nothing. These kinds of functions fall under this category. The following program is an example of a function without argument and the return value.

`def eligible(): print("You are Eligible to take the Exam")def not_eligible(): print("You are not Eligible to take the Exam")age = int(input("Enter Your Age:"))if(age<20): not_eligible()elif(age>=20 and age<35): eligible()else: not_eligible()`

Output

`Enter Your Age:24You are Eligible to take the Exam`

In the above program, there are two user-defined functions are created. In the function definition, you can see that there is no argument is defined inside the function. So we don’t need any parameters to call these functions.

## Function without argument and with return value

In some cases, a function will return a value without taking any argument or parameter. These types of functions are the functions without argument and with a return value. Look at the following example program for understanding the concept better.

`def low_dosage(): return 75def med_dosage(): return 100def high_dosage(): return 150age = int(input("Patient's Age:"))temp = float(input("Body Temperature:"))if(age<10 and temp>98 and temp<99): print("The medicine with ",low_dosage(),"mgs is enough.")elif(age<10 and temp>99): print("The medicine with",med_dosage(),"mgs is enough.")elif(age>10 and temp>98 and temp<99): print("The medicine with",med_dosage(),"mgs is enough.")elif(age>10 and temp>99): print("The medicine with",high_dosage(),"mgs is enough.")`

Output

`Patient's Age:35Body Temperature:100The medicine with 150 mgs is enough.`

The called functions are highlighted in the program. Whenever a function returns a value using the keyword `return` the value can be stored in a variable or formatted using the `print` function.

## Function with arguments and without return value

Some functions will take some parameters to it and does not return any value back. The following code will help you to understand the concept.

`def low(amount,year): rate = 6.5 interest = amount * year * rate/100 if(year<5): print("Your interest will be",interest * 1.2) else: print("Your interest will be",interest * 1.4)def high(amount,year): rate = 8.5 interest = amount * year * rate/100 if(year<5): print("Your interest will be",interest * 1.2) else: print("Your interest will be",interest * 1.4)amount = int(input("Investment Amount:"))year = int(input("No of Years:"))if(amount<100000): low(amount,year)else: high(amount,year)`

Output

`Investment Amount:120000No of Years:6Your interest will be 85680.0`

The two functions `low` and `high` both functions getting two values as their arguments and it returns nothing. Simply we can say that the output is formatted in the function itself. But that is not true always. We can create a function for doing nothing.

## Function with arguments and with return value

This type of user-defined function is the majorly used in many situations. It takes some arguments into it and returns some values to the function call. Let us try to rewrite the previous program for this type of user-defined function.

`def low(amount,year): rate = 6.5 interest = amount * year * rate/100 if(year<5): return interest*1.2 else: return interest*1.4def high(amount,year): rate = 8.5 interest = amount * year * rate/100 if(year<5): return interest*1.2 else: return interest*1.4amount = int(input("Investment Amount:"))year = int(input("No of Years:"))if(amount<100000): print("Your Interest will be",low(amount,year))else: print("Your Interest will be",high(amount,year))`

Output

`Investment Amount:98000No of Years:4Your Interest will be 30576.0`

Instead of printing the value inside the function, the `return` keyword returns the interest value to the place from which the value is called. The function call is highlighted with bold letters.

Here I have written a program which contains all the four types of functions in it. Try to understand each type and usage of that in a particular place.

`def question(): print("Your Name:")def type(): print("Type of Account")def savings(): return 1.8def fixed(): return 2.3def interest_calc(amount,year,rate): interest_amt=amount * year * rate/100 return interest_amtdef total_calc(amount,interest): return amount+interestdef info(name,total,year): print(name,"'s Total amount after",year,"is",total)question()name = input()type()t=int(input("Savings(1)/Fixed(2)"))if(t==1): rate = savings()elif(t==2): rate = fixed()amount = int(input("Amount:"))year = int(input("Year:"))interest = interest_calc(amount,year,rate)total = total_calc(amount,interest)info(name,total,year)`

Output

`Your Name:FelixType of AccountSavings(1)/Fixed(2)1Amount:18000Year:5Felix 's Total amount after 5 is 19620.0`

# Scope of Variable

Every variable defined in the program has its own scope. That is there will be a range in which we can access the value with a particular variable name. Usually, a variable can accessible within the function only. Let me demonstrate the scope of a variable using the following program.

`def info(): value = 5 print("The value is",value)def test(): print("The value is",value)info()test()`

Output

`The value is 5Traceback (most recent call last): File "main.py", line 7, in <module> test() File "main.py", line 5, in test print("The value is",value)NameError: name 'value' is not defined`

You get some exceptions over the program. This is because the scope of the variable `value` is constrained between the range of function `info()`. So that it cannot be accessible by other functions.

# Global Variables in Python

Global variables are variables that can be accessed anywhere in the program. Usually, the variables defined in the main function are global variables. We don’t need any extra syntax to make global variables. But if we need to create a global variable inside any function we can use the keyword called `global`.

Syntax: global variable_name

Here I modified the previous program with the keyword `global` .

`def info(): global value value = 5  print("The value is",value)def test(): print("The value is",value)info()test()`

# *args and **kwargs in Python

In previous programs, we exactly know how many parameters are going into a function. But what if we don’t know the number of arguments in advance. Here is how the list arguments and keyword arguments come to play. These are some methods to pass a collection of values with only one name. Look at the following example for `*args` method.

`def function(*args): for x in args: print(x)function("Felix","Antony")`

Output

`FelixAntony`

The function takes more than one value at a time in the format of a tuple. The tuple can be accessed by the index with `args` as tuple name. Here is another example that contains more than one argument.

`def function(name ,*args): print(name) for x in args: print(x)function("Felix Antony", "Medium", "Writer")`

Output

`Felix AntonyMediumWriter`

Here the first preference is given to the single arguments. Usually, we have to keep `*args` and `**kwargs` in the last place in the arguments list.

The `**kwargs` also working same as the previous one. But instead of a tuple, we are using dictionary data type here. The dictionary value can be accessed by its key values. That is why it is called as keyword arguments.

`def myfunction(**kwargs): for x,y in kwargs.items(): print(y)myfunction(First_name = "Felix", Last_name = "Antony")`

Output

`AntonyFelix`

`*args` and `**kwargs` are the common convention. We can choose our own name for implementing these arguments. But keeping the common name will be a better option.

# Lambda function in Python

Lambda is an anonymous function that helps us to write a function in one line. It can take many arguments but only one expression. The syntax for using the lambda function is given below.

Syntax: function_name = lambda variables : expression

Here the function name is the variable that stores the value returned by the expression.

`x = lambda a, b, c : a+b-cprint(x(5,6,3))`

Output

`8`

I hope you have learned something useful from this article. Practice more by yourself for getting stronger in functional programming which is personally I prefer always. If you want your code to be more clear then you have to put more practice on these simple concepts explained in this article. Here I have listed some useful articles on python. Happy coding !