# Python 2.7 – Fundamentals – Functions

Sometimes you have some tasks in Python which are repetitive in nature. For instance the steps to calculate the sale price of a product requires you to add the cost price with taxes and shipping charges. This calculation may be needed in different parts of a program. Rather than repeat the same lines of code in separate places, we can create a function which will contain this logic and then we simply call the function wherever we need it.

This not only prevents duplication of code but also makes it easy to make changes and fix bugs. Tomorrow if there is a change in the way you compute sale price, you just have to change it within the function instead of making the change in several places.

So lets take an example of a Python program which computes the sale price of items. We have a list of items and their cost prices. Sale price is computed by adding the tax percent and the shipping cost. These two figures are different for domestic and international sales. Here is a sample of the code:

```domestic_tax_percent = 10.50
international_tax_percent = 20.00
domestic_shipping = 15.00
international_shipping = 100.00

item_names = ('Soap', 'Brush', 'Shoes', 'Cream')
item_costs = (5.60, 1.20, 14.50, 5.00)

print item_names
print item_costs

count = len(item_names)

for i in range(0, count):
print item_names[i], "costs", item_costs[i]
domestic_tax_amount = (item_costs[i] * domestic_tax_percent)/100
domestic_sale_price = item_costs[i] + domestic_tax_amount + domestic_shipping
intl_tax_amount = (item_costs[i] * international_tax_percent)/100
intl_sale_price = item_costs[i] + intl_tax_amount + international_shipping
print item_names[i], "sells for ", domestic_sale_price, " domestically and ", intl_sale_price, "internationally"
```

Here is the output:

```('Soap', 'Brush', 'Shoes', 'Cream')
(5.6, 1.2, 14.5, 5.0)
Soap costs 5.6
Soap sells for 21.188 domestically and 106.72 internationally
Brush costs 1.2
Brush sells for 16.326 domestically and 101.44 internationally
Shoes costs 14.5
Shoes sells for 31.0225 domestically and 117.4 internationally
Cream costs 5.0
Cream sells for 20.525 domestically and 106.0 internationally```

Now lets convert the code for computing the sale price into a function.

```def getSalePrice(tax, shipping, cost):
tax_amount = (cost * tax)/100
sale_price = cost + tax_amount + shipping
return sale_price

domestic_tax_percent = 10.50
international_tax_percent = 20.00
domestic_shipping = 15.00
international_shipping = 100.00

item_names = ('Soap', 'Brush', 'Shoes', 'Cream')
item_costs = (5.60, 1.20, 14.50, 5.00)

print item_names
print item_costs

count = len(item_names)

for i in range(0, count):
print item_names[i], "costs", item_costs[i]
domestic_sale_price = getSalePrice(domestic_tax_percent, domestic_shipping, item_costs[i])
intl_sale_price = getSalePrice(international_tax_percent, international_shipping, item_costs[i])

print item_names[i], "sells for ", domestic_sale_price, " domestically and ", intl_sale_price, "internationally"
```

Here is the output:

```('Soap', 'Brush', 'Shoes', 'Cream')
(5.6, 1.2, 14.5, 5.0)
Soap costs 5.6
Soap sells for 21.188 domestically and 106.72 internationally
Brush costs 1.2
Brush sells for 16.326 domestically and 101.44 internationally
Shoes costs 14.5
Shoes sells for 31.0225 domestically and 117.4 internationally
Cream costs 5.0
Cream sells for 20.525 domestically and 106.0 internationally```

As you can see the output is exactly the same as before. What we have done is define a function called getSalePrice and we call that to compute the sale prices for domestic and international sales.

The advantage is that if somewhere later in the program we again need to compute the sale price we just called the function instead of writing the logic again.

### Components of a Function

Lets look at the structure of a function. A function is declared with the def keyword followed by the function name. If some data has to be passed into the function then we declare parameters within the brackets , if not then the we keep the brackets empty (). In the function declaration , the data being passed into the function are called parameters. In the main code which calls the function, the data which is passed are called the arguments. So basically a parameter is a formal definition of a data that will be passed and an argument is the actual data value that is being passed into that parameter.

A function can return a value by using the return keyword followed by the return data. Any kind of data can be returned. If no return value has to be passed back then a simple return without any data is written. Even if you do not write the return keyword, a function automatically returns  None value.

In other languages, you have the concept of parameters being passed by value or by reference. Passing a parameter by value means that the argument being passed will retain its original value even if it is changed within the function. The reason being that the function creates a copy of the data being passed as an argument rather than the actual data itself. Passing a parameter by reference means the actual data item is passed into the function and if the function changes the value  then the data item will have the changed value when the function finishes processing.

In Python, all parameters are passed by reference. However, the laws of data immutability apply. For eg.if you pass a list as an argument, then the function can make changes to the list, but if you pass a tuple, then the function cannot make changes since a tuple is immutable.

Parameters are of three types:

• Required
• Default
• Keyword

Required

By default all parameters are required. If a function requires 3 parameters, then you need to call the function with 3 arguments otherwise it will give an Exception.

Default

A parameter can be made optional if it has a default value. It means that if a parameter has a default value assigned then it need not be passed when the function is called. An example is given below:

```def myFunction(age, name="Amit"):
print "name=", name, "age is ", age

myFunction(20)
myFunction(30, "Tom")```

The parameter name has a default value. So if it is not passed while calling the function it takes on the default value.

Keyword

By default function arguments are evaluated according to their position. So in the above example the first argument is name and the second argument is the age. You can change the sequence of argument passing by using keywords when calling the function. An example is given below:

```def myFunction(p1, p2, p3, p4):
print p1, p2, p3, p4

myFunction("p1", "p2", "p3", "p4")
myFunction(p4="p4", p2="p2", p1="p1", p3="p3")```

In the next post , we will look at the basics of Classes and Objects.