Menu

Day 4 - Loops, loops, loops...

Sep 01, 2015 at 08:31 am, by Pierre Liard

How many fingers do you think I am holding up ? No, I am not going back to childhood, but it was what was actually hidden behind the title "The Guessing Game". I was a bit disappointed, I was hoping for more, but building this app shows me something interesting: how to generate a random number in Swift.

But first I asked myself if it is really possible to generate a random number. In an article ( rand(3) / random(3) / arc4random(3) / et al. ), Matt Thompson wrote in the closed, digital universe of CPU cycles, processes, and threads, there is no true randomness, only pseudorandomness. Computer randomness is comparable to cryptography. It uses different techniques (like hash, salt and seed ) to return a "random" value based on the current time of the system. This reflexion is more an academic exercise that something programmers will care about, but it demonstrates that, in a certain way, coding can get quickly very philosophical.

Coming back to our game, the app needs a number between zero and five to compare it to the value inputted by the user. Because the random number given by the computer is not really a variable, Swift uses the keyword let to indicate that the value cannot be changed anymore. In other words, let is used to introduce a constant.

let randonNumber = arc4random_uniform(6)

The number in parenthesizes represents the upper-range of the number to be sorted out "randomly". For this function to work properly, it may be necessary to convert it to a string or an integer, depending on the code. In our app, Rob chose to convert it to a string because the input textfield is of type string. I tested however the contrary, by converting the textfield to an integer, and it also worked. There was a little bit more work because of the variable unwrapping, but globally the result was identical.

let randonNumber = String(arc4random_uniform(6))

The two next lectures delve into loops. A loop is simply a series of instructions that will be repeated until a certain condition is reached. Let's have a look to an example:

for (var i = 1; i <= 10; i = i + 1;){
print(i)
}

The first element var i = 1; indicates where the counter must start, the second sets the range (number comprised between 1 and 10), and the last one the incrementation (by the way I wrote the incrementation in a easily readable way, but it is usually written i++. It is exactly the same as writing i = i +1, but it is much shorter and elegant.) As soon as the loop is done with the first value, it will increment the variable i by 1 and tests it against the condition. The loop will repeat this process, until it reaches the upper-limit defined in the statement.

Loops are very powerful tools to find information. They allow to search a database to find for example for the number of posts of a specific user. The above example uses a for loop. There is also a while loop : the principle is identical to the for loop, but the code is slightly different, in particular the counter is outside of the while loop. These two types of loops are used commonly with a slight advantage to the while loop, because it offers more possibilities than the for loop. For example, it is not possible to change values in a array with a for loop, but it is realizable with a while loop:

var myArray = [3, 56, 7, 89, 32, 45, 90]
var i = 0 // the counter is set to zero because an array's index starts at zero

while(i < myArray.count) { // loop until index 6 is reached
     print(myArray[i] - 1) // print each value in the array minus 1
     i++
}

The result of this loop gives of course an array of [2, 55, 6, 88, 31, 44, 89].

As I wrote yesterday, the playground is very useful when you need to test a piece of code before inserting it into a project. Rob followed exactly this methodology when creating the second app of this section "Finding primes". A prime number is a number greater than one and it has no divisor other than one or itself. For example, 7 is prime because it is only divisible by 1 or by 7. In programing, a way to determine if a number is prime or not, is to use what is called a modulo. A modulo operation finds the remainder of a division of one number by another. Swift uses the % sign to do that. So for example, to find the remainder of seven divided by two, the code is as follows:

var remainder = 7 % 2

The remainder of this division is 1, whereas the remainder of eight divided by two is zero. Consequently, a prime number will always have a remainder of 1, when a non-prime number will have a final remainder of zero. For example, to find if 25 is prime, the code should try each possible divider for 25 to see if there is a remainder of zero. Because 25 has a remainder of zero when divided by 5, it is not a prime number. This short analysis of the problem is essential before writing any code. By doing so first, it should be easier then to write the proper code to solve the issue at stake. Here is below Rob's solution and I will explain it afterwards:

var number = 7
var isPrime = true

if (number == 1){
   isPrime = false
}

if (number != 2 && number != 1){
    for (var i = 2; i < number; i++){
      if (number % i == 0){
          isPrime = false
    } 
  }
}
print(isPrime)

The first thing to do is to choose a starting point we can build from. We know for sure than 7 is a prime number. Consequently, it will always be true: it is what the boolean expression var isPrime = true is for. Based on this corner stone, the for loop sets at first the counter at two, because one is not considered by mathematicians as a prime number. Then the upper-range of the variable - the number itself - is determined, and finally the incrementation. The loop will start with the variable set in the counter, and divides the inputted number. If the remainder is equal to zero, the loop will immediately exit, set the boolean variable as false, and print the result. If there is a remainder, the loop will continue until it finds no remainder, if any. The loop will last as long as the counter hasn't reached his upper-limit, in this case six. The two if statements are checking if the input is not equal to one, and again if it is not equal to one AND two. The loop will work however without these checks, but it makes the code more robust and protected against unsuitable inputs.

It is worth noting that, once you know the conventions used in a coding language, your code should be self-explanatory. It is the case here, and I simply paraphrased what the code said much more elegantly. Some developers prefer to comment their code to make it easily accessible to somebody else, but the code itself may also become unreadable by useless or superfluous comments. That's why I personally don't comment very often my code, only when it is necessary and when I haven't be able to make it clear enough. Nevertheless comments are always good when they support your code, and it is in this perspective they should be used.

I really liked how Rob constructs this app by testing the principal piece of code in the playground. Other IDEs do not offer this convenience, but I guess it is always possible to create a separate file for the code you want to try and, when it is ready, to export it into the main project. Tomorrow we will finish building this app by first creating the graphic interface, and then importing the code we just tested.


Leave a comment

Login to comment a post