In the previous post on functions, we started with defining and calling functions.
Today we will go a bit deeper into function parameters or popularly called arguments.
Parameters are the inputs for the function.
If you recall from the previous video, this is the factorial function we studied. This factorial function has only one parameter i.e. number.
func factorial (number: Int) -> Int{
var factorial = 1
var temp = number
while(temp>1){
factorial = factorial * temp
temp = temp - 1
}
return factorial
}
Here the number is the input for the factorial function.
There are functions with one parameter and function with more than one parameters also.
To see an example of the function with zero parameters we will remove the parameter number from the function factorial. And add a constant number 7 inside the function.
func factorial () -> Int{
let number = 7
var factorial = 1
var temp = number
while(temp>1){
factorial = factorial * temp
temp = temp - 1
}
return factorial
}
//functionName(paramName: paramValue)
print("Factorial is \(factorial(number: 7))")
But we see an error in the print function where we call our function. The error says, “Argument passed to call that takes no arguments”
This is happening because the function we defined has no parameters but the function we are calling has one parameter. To remove the error we remove number: 7 from the function call. And now there is no error and we get our output 5040.
func factorial () -> Int{
let number = 7
var factorial = 1
var temp = number
while(temp>1){
factorial = factorial * temp
temp = temp - 1
}
return factorial
}
//functionName(paramName: paramValue)
print("Factorial is \(factorial())")
Now to study an example of a function with two parameters, we will define a function product, having two parameters x and y, both integers, and the function will return the product of x and y as an integer.
//product of two numbers
func product(x: Int, y: Int) -> Int {
return x*y
}
print("Product of 6 and 14 is \(product(x: 6, y: 14))")
We can see that this function has two parameters in the definition x and y. And we call the function product with values of x as 6 and y as 14 and get the product 84.
Similarly, there can be functions with three or even four or five parameters.
With this, we complete the function parameters. In next post, we will focus on the return types.
From the past few posts, we have been learning swift one step at a time. In our previous post, we completed control flow. The code for this post is available here.
Starting today next few posts will be on functions. Function definition and function call willbe covered in this post. Subsequent posts will focus on parameters, return types and argument labels respectively.
So, what are functions?
Functions are self-contained blocks of code that solve a specific purpose. For example, the factorial function that you see here is used to find the factorial of a given number.
func factorial (number: Int) -> Int{
var factorial = 1
var temp = number
while(temp>1){
factorial = factorial * temp
temp = temp - 1
}
return factorial
}
Or this print that we use so much. The print is also a function which is used to print the results on the console.
It is clear that the function definition can be broken down into three main parts:
Function name through which we can call this function.
Parameters list which is actually list of inputs for this function
Return type which defines the type of result the function is going to return.
Let’s see this factorial function definition to better understand function definition
As we can see, the function name is defined as factorial. The parameter name is number. And the Parameter type is an integer. Return Type is also Integer. Then we have a code inside the curly brackets which calculates the factorial and stores it into a factorial variable and returns it. The data type of factorial variable is Integer, similar to the return type mentioned in the first line of the function.
How to call a function?
Now that we have defined factorial, how do we use it? How do we call it? How can we find the factorial of number 7 using this function?
The syntax for the function call is given below:
functionName(paramName: paramValue)
Like in this example we use print factorial of a number is factorial(number: 7). 7 is an integer and we have defined the parameter of the number as an integer.
print("Factorial is \(factorial(number: 7))")
In the next post, we will begin going deeper into functions.
Right now if marksOfStudents is greater than 100. We will get an output of “Student Fails” which is wrong. As marks should never be greater than 100. Therefore to handle values more than 100 or less than zero, we will have to add one more condition.
We can see addition of one else-if block now handles the condition in proper way. And we have an output Out of range for values -10 and 185.
As conditions increase, number of else-if blocks will increase. And the code will become more complex.
In this case, which involves multiple conditions, it is better to use switch statement.
Switch statements have been designed to handle multiple conditions only. You might have seen them in Java or Python.
The syntax of switch statements in Swift is generally like this:
switch conditionalValue {
case value 1:
//execute this block
case value 2:
//execute this block
case value 3, value 4:
//execute this block
case value5...value6:
//execute this block
default:
otherwise, do something else
Switch statement is followed by case statements which have a block of code associated with them.
Switch compares the conditionalValue with the values given in case statement(value 1, value2, etc). When a match is found, code associated with that case is executed.
default case is used to handle values not covered in the case statements.
Unlike other languages like java or python, swift allows compound cases and ranges and a lot of other options. Switch statements in Swift are very powerful and flexible.
For example we can have same case catering to two values like value3 and value4 here. Or we can have a range of values like value5 to value6.
Let’s see some examples to better understand these.
First we will convert the above if-else code. into switch code
var marksOfStudents = 85
switch marksOfStudents {
case 75...100:
print("First Division")
case 31...75:
print("Second Division")
case 0...30:
print("Student Fails")
default:
print("Out of range")
}
Since we are checking the value of marksOfStudents in the if-else block, we can use marksOfStudents as our conditional variable of switch statement.
The first if-else condition covers marks between 75 and 100 (range of values between 75 and 100). This infers our first case statement will check for values between 75 and 100 using range operator.
Similarly the second case will cater to range of 31 and 75. And the third case will take range of 0 and 30. For any values less than 0 or greater than 100 we will add a default case.
With marksOfStudents = 85 we get the output of first division as expected.
Let’s check the outputs when marksOfStudents equals 25 or 60 or 105.
Now check with marksOfStudents equals 75.
Although 75 is included in the second case too, we get the output first division. Because swift checks the conditions one by one and executes the code associated with the first match. So in our case, as soon as first case 75…100 matches, first division is printed. And the second case 31..75 is ignored.
Let’s consider another example: To count the number of vowels in a sentence.
var sentence = "I am learning swift"
var countVowels = 0
for letter in sentence.characters{
switch letter {
case "a","A","e","E","i","I","o","O","u","U":
countVowels += 1
default:
countVowels += 0
}
}
print("Number of vowels = \(countVowels)")
Instead of writing separate cases for each vowel in upper or lowercase letter, we can compound all the values in one case itself as shown in example.
In above example itself, we will find the number of spaces in the sentence. For this we will add a case ” ” and a counter to store number of spaces. The code will look like.
var sentence = "I am learning swift"
var countVowels = 0
var countSpaces = 0
for letter in sentence.characters{
switch letter {
case "a","A","e","E","i","I","o","O","u","U":
countVowels += 1
case " ":
countSpaces += 1
default:
countVowels += 0
}
}
print("Number of vowels = \(countVowels)")
print("Number of spaces = \(countSpaces)")
This completes switch statement. Next we will start with functions.
In this post, we will start with conditional statements.
In conditional statements, the execution of a statement depends upon the condition.
Swift provides if–else and switch as conditional statements.
For now, we will concern ourselves to if-else statements.
The following block of code specifies how the if-else statements are written in swift.
if ( condition ){
//execute block1
} else {
//execute this block2
}
If the condition is true, block1 executes else block2 executes.
This will be more clear once we look into some examples.
If Statement
Example: We have a variable marksOfStudents. If the marks are less than 30, we will print fail. The code will be like this
var marksOfStudents = 25
if ( marksOfStudents <= 30 ){
print("Student Fails")
}
Here we check in the condition whether marks are less than and equal to 30. Since the condition is true “Student Fails” gets printed.
Suppose the condition is false. marksOfStudent = 45 (> 30). Let’s see what happens
var marksOfStudents = 45
if ( marksOfStudents <= 30 ){
print("Student Fails")
}
There is no output. Because we have not coded the false condition.
Else Statement
To code the false condition, else is used. The code will now become:
var marksOfStudents = 45
if ( marksOfStudents <= 30 ){
print("Student Fails")
} else {
print("Student Passes")
}
We can see from the output, “Student Passes” is printed as condition is false.
Else-If Statement
Suppose we want to print division and fail base upon the marks. If marks are greater than 75, we want to award “First Division”. If marks are greater than 30 but less than 75, we want to award “Second Division”, If marks are less than 30, we want to declare “Student fails”
We can see there are multiple conditions here, which cannot be handled using only if-else. So here, we will use if-else-if. The else-if statement is used to handle additional conditions.
Let’s see how the code for this one would look like:
var marksOfStudents = 45
if ( marksOfStudents >= 75 ){
print("First Division")
} else if (marksOfStudents >30 && marksOfStudents < 75) {
print("Second Division")
} else {
print("Student fails")
}
As we can see from the code, first we check the condition whether marks are greater than or equal to 75 using if. Next we check the middle condition whether marks are between 30 and 75 using the else if. Finally we use else to handle the situation when both the conditions become false.
The output is second division. Here the else-if condition becomes true as 45 is less than 75 and greater than 30.
“Control Flow” can be defined as the order in which statements in our programs gets executed.
Today we will delve into loops. Swift provides the for-in loop, while loop and repeat-while loop.
For-in Loops
If you know java or python, you would have encountered for loops. They are used to execute a block of statements multiple times.
The for loops in swift are written using the following syntax.
for index in range{
//statements
}
Example: to print the square of numbers from 1 to 5.
for number in 1...5 {
print("Square of \(number) is \(number*number)")
}
“…” is a closed range operator. It is used to select the range of our iteration, inclusive of the start and end index. Here the range is {1,2,3,4,5}. Our variable number is initialized with the value “1”, ie the starting value of the range. Then the print statement is executed, and our number variable increments to “2”, then again the print statement. This loop is repeated until the value of index reaches the end of our range.
Hence our output stops at 5.
For-in loops are also used to iterate over arrays, strings, and dictionaries. Let’s see examples of few:
Consider an array of colors. We will print all colors present in the array using for loop.
var color = ["Red", "Green", "Yellow"]
for element in color{
print("\(element) is a color")
}
Here element is our variable whose value changes and range is the color array. One by one all elements present in our array is printed.
Consider another example of a dictionary. Each dictionary item returns a key, value pair when iterated. And these keys and values can be used as variables in the for-in loop.
var groceryList = ["potatoes" : 4, "carrots" : 6, "onions" : 10]
for (vegetables, quantity) in groceryList{
print("We need \(quantity) \(vegetables) from the market")
}
Here vegetables are keys and quantity are values in our dictionary. We use them as variables to iterate over the dictionary and print it.
While loops
Next, comes the while loops. A while loop performs an iteration until the condition becomes false.
Swift provides two types of while loops – while and repeat-while.
While
The while checks the condition at the start of the iteration.
First, the condition is checked, if it is true then only the statements are executed.
For our example, we will find the factorial of a number. Factorial of a number, let’s say 5 is calculated as a product of all the numbers from 5 to 1, ie 5,4,3,2,1. It is 120.
This can also be written as 5 * (5-1) * 3 * 2 * 1 or 5 * (5-1) * (5-2) * 2 * 1
This will lead to an algorithm like this:
We will start with two variables num and factorial. num will store our integer 5 and factorial will store our product. Initially, factorial will be set to 1.
The second step is, we will assign product of factorial and num to variable factorial.
The third step will decrease the number by 1
Next, we will check the condition whether num > 1 or not. Based on that steps 2 and 3 will be repeated.
Suppose at present we have num= 5 and factorial= 1
After step 2 and step 3, factorial will be equal to 1 * 5 ie 5 and num will be equal to 5-1 ie 4
Then in step 3, we check the condition whether num > 1, Currently num = 4 which is greater than 1. Hence the condition is true, so we will again do step 2 and 3. And so on until num becomes 1.
We can see that steps 2 and 3 are going to be repeated 4 times until num becomes 1.
Now, we will convert this algorithm to our code in swift.
We will take a variable number as 5 and another variable factorial with initial value as 1
Our while will have a condition “number>1” as we saw in our algorithm. We will calculate factorial as the product of factorial and number.
//while loops
//Factorial of a Number
var number = 5
var factorial = 1
while(number>1){
factorial = factorial * number
}
print("Factorial is \(factorial)")
Hold on a minute. I am getting an error. Something like “Execution was interrupted“. Also, see that this loop has executed 28 times. According to us, our loop should have executed only 4 times.
This happens because our number’s value is always 5. It is not decreasing. So the condition in while statement remains true always. When we write “number = number – 1“. The code runs smoothly. We can print the result. And it shows 120.
//while loops
//Factorial of a Number
var number = 7
var factorial = 1
while(number>1){
factorial = factorial * number
number = number - 1
}
print("Factorial is \(factorial)")
Also if you change the number, for example to 7. Now our factorial should be 5040.
And we can see our code also gives us the same output.
If you want to check an individual value of factorial and number changing over each result. Click on show result. You might see a graph. To change to values, give a two finger click and select “value history”.
See the value changing. First, we have 7 which is the product of 7 and 1, then 42 which is the product of 6 and 7 and so on.
Similarly, you can see the decreasing value of a number by clicking on show result and again change to value history. Here the loop has run 6 times until number becomes 1.
Repeat-While
Next is repeat-while, which executes the code first and checks condition in the end.
For this one, we will write code to generate the binary representation of a decimal number.
The binary representation of 8 is “1000”. We do this using division. The number is divided by 2 and then the quotient is divided by 2 and so on until we get the quotient as 1 or 0. Simultaneously we save the remainders. Starting with this 1, we join all the remainders to finally have the binary representation.
The algorithm is like this:
We will have two variables: num storing the integer and bin which will store our binary string.
In the second step, we will first find the remainder by dividing num by 2 and add it to our binary string.
In the third step, we will divide num by 2.
In the final step, we check whether the number is not equal to zero, if yes, repeat step 2 or 3.
Suppose at present we have num equals 8
After step 2 and 3, bin = bin + 8%2 = “” + 0 = 0, and num = 8 /2 = 4.
Now when we check num != 0, it is not 0, and so step 2 and 3 will be repeated again and so on until num becomes 0.
When we see the final result, it is 0001, sort of reverse to our correct answer which is 1000.
We can change this by changing our expression for step 2 to bin = num%2 + bin. As you see here, now the final string becomes 1000.
Let’s do this in swift now:
First, we will initialize a decimalNumber variable. Then a string binary.
Inside our loop, first, we need to save the remainder as a string in our variable binary.
//repeat-while
//Binary representation of a number//
var decimalNumber = 8
var binary = ""
repeat{
binary = (decimalNumber % 2) + binary
decimalNumber = decimalNumber / 2
}while(decimalNumber != 0)
print("Binary representation is \(binary)")
But when we write binary += decimalNumber % 2, we get an error.
This error occurs because we are assigning an int value to a string variable. So we need to type cast this value into a string. Let’s do that.
//repeat-while
//Binary representation of a number//
var decimalNumber = 8
var binary = ""
repeat{
binary = (String)(decimalNumber % 2) + binary
decimalNumber = decimalNumber / 2
}while(decimalNumber != 0)
print("Binary representation is \(binary)")
Followed by while with a condition of decimalNumber != 0.
Now when we print binary, we get an output of “1000” as expected.
Let’s check for 25, the output should be “11001“. And we get the same output.
Here also we can check the individual value using show result and then value history for both binary and decimal values.
Now that we have learned arrays and sets, it’s time to finish collections by learning dictionaries.
Dictionaries. What do you think about when you hear the word dictionary. Well, I think about the dictionaries, the English dictionaries we used when we were kids to find the meaning of words. I use them still. Just that the dictionary is now on the internet.
Think about how we used to search a meaning of the word, for example, “rock” in the dictionary. We will straight away go to the r section of the book, then search for a word starting with “ro” and finally zero in on our word rock. Read its meaning and close.
We wouldn’t start with words starting with a, followed by b, and so on to reach the words starting with “r”. That is going to take a lot of time. Am I right? We will just straight away jump to the words starting with “r”
One important thing to note here is that rock is the key and its meaning is the value. We find the key, we find the meaning.
Just like those English dictionaries, dictionaries in swift are generally pairs/associations of keys and values. These keys and values can be of the same type or different. Also, every value is associated with a key, which is now an identifier for that value.
Like sets, dictionaries also have no ordering.
A dictionary is written as [“key” : “value”]
Example, a dictionary of antonyms : [“hot” : “cold”, “dark” : “light”, “big” : “small”]
Here “hot’ will be a key and “cold” its value.
The swift dictionary type is written using Dictionary[“Key” : “Value”]. This can also be written as [“Key”: “Value”]. The latter form is widely used.
Coming back to the playground, let’s learn how to initialize and use these dictionaries.
The first method, just like in arrays and sets, uses the initializer syntax.
Here we will use the antonyms example.
var antonyms = [String : String]()
This will generate variable antonyms which can store keys of type String and values also of type string. Currently, it is initialized as an empty dictionary.
Let’s print this and see
print(antonyms)
This symbol here [:] shows the dictionary is empty.
Now comment this line and the print line and again initialize the dictionary as empty.
var antonyms = [:]
This throws an error “Empty collection literal requires an explicit type”
This happens because the compiler doesn’t know the type of key and values. So we cannot use this way to initialize a dictionary.
When we uncomment our first line. Then remove “var” from this one the error vanishes.
Let’s add few antonyms to our dictionary. And remove the comment from print statement.
Well, now we know how to initialize the dictionary. so let’s have a look at the operations we can perform on it.
The first operation is “Insert”
We use subscript syntax to insert into dictionaries. In this method, we will use a new key having the same type as Keys and assign to it new value having the same type as Values.
Now we will add tomatoes and squash to our dictionary.