We're sorry but this page doesn't work properly without JavaScript enabled. Please enable it to continue.
Feedback

Introduction to Programming for Business Analytics - Exercise 2: Elementary Data Types

00:00

Formal Metadata

Title
Introduction to Programming for Business Analytics - Exercise 2: Elementary Data Types
Title of Series
Number of Parts
22
Author
License
CC Attribution 4.0 International:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal purpose as long as the work is attributed to the author in the manner specified by the author or licensor.
Identifiers
Publisher
Release Date
Language
Producer
Computer animationLecture/Conference
Computer animation
Computer animation
Computer animation
Computer animation
Computer animation
Lecture/ConferenceComputer animation
Transcript: English(auto-generated)
Hi, welcome to the second exercise video for the introduction to programming for business analytics class. Today we are going to walk through the solutions for the second exercise sheet.
I'm assuming that you have already solved the second exercise sheet by yourself, or that you have at least tried to solve it. If you haven't, please pause the video now and give the second exercise sheet a try before
you continue watching. With that said, let's get started with task one. For task one, we have to give for each of the following data types an example for a Julia expression that evaluates to a value of this data type. Okay, so the first data type is float64.
And we can give a Julia expression just by typing in a float64 literal. And Julia automatically chooses float64 as a data type for numeric literals with decimal digits, for instance, 1.0.
I can execute this cell now and it will just show me the value. And as the task says, verify the correctness of your answer by calling the function type off with the value your expression evaluates to as its argument. So we're going to do that type of 1.0.
And as you can see, it shows float64. We can do the same for the second data type in 64. And Julia will choose int64 as a data type for numeric literals, which are sufficiently small and which are in the range that int64 can represent.
The simplest example would be zero. And again, we can pass zero to the type of function, which will tell us the type of the element in this case int64.
And for the third data type, big int, we have multiple options, we could just enter a very big integer literal, but I don't want to type all of these digits, which is why I would just enter an expression that has the that has a big integer as its value, this case
big int of two to the 128. And I can verify that this is indeed a big int value by passing it to type of again.
For task two, we shall use the official Julia documentation to find two built in functions that tell us the minimum and maximum values of a given type, you can use the link to go to the documentation. And there you will find that the function that tells you the minimum value of a given
type is called type min, you have to pass the type now, for instance, float64, the minimum value I float 64 can represent is minus infinity. For an integer int 64, it would be minus two to the power 63, which is this.
The other function is called type max, which will give you the maximum value of a given type. And if we put in int 64, it will show us two to the 63 minus one.
And for float 64, it will be plus infinity, respectively. For task three, we have to give an example for a Julia expression and whose evaluation and in 64 overflow occurs. You know from the lecture that an overflow occurs when the result of a calculation involving
in 64 arguments cannot be represented by in 64 because it's too large or too small. And you also know that the range that can be represented in 64 is from minus two to
the power 63 up until two to the power 63 minus one. So we just have to enter an expression, which results in a value that is larger or smaller than this range. And an example for that would be to enter two to the power of 63 minus one and then
to this to add one, which will give us minus two to the power of 63. Incorrect, mathematically speaking, but expected behavior when we use int 64 as a data type.
In task four, we have to give float 64 expressions, which evaluates to one of the three given values. The first value is not a number. And not a number is generally used to represent undefined values.
And one example for an undefined value would be the result of the expression zero over zero, which will give which gives us an m minus zero can be achieved by just multiplying some negative number for instance minus 23 with zero and infinity can be achieved in
multiple ways. For instance, you could do an addition or multiplication that exceeds the range of float
64. But you can also divide a positive number by zero, which is not really correct, mathematically speaking, dividing something by zero isn't defined. But in the standard behind the float 64 values, it's required that this is the result.
Task five is the question which data type is more precise in 64 or float 64 find arguments in favor of both possible answers. Okay, so from my intuition, at first, one would think that in 64 is more precise, because
when you do calculations and in 64, at least certain calculations that is, the result will always be perfectly precise and correct. There is no rounding involved when you add one plus two, for example.
But of course, there are many values that can be represented within 64. For example, very large and very small values, and also all the rational numbers, right, all the fractions. So you could also argue that in 64 is in fact not precise, when you try to calculate a,
the result of the expression one over two, for example, right, one half just cannot be represented as an in 64. So in this context, it's very imprecise, because it could round to either zero or one, both
which are not very good options here. Which is why float 64 would be more suited for such a context. But of course, as you know, from the lecture float 64 is also slightly imprecise, especially
when the differences between two numbers are only visible in in very insignificant decimal places, then these differences might not be representable with float 64.
And also, there are many values that cannot be represented precisely as a float 64 value at all and will always be approximated, for instance, 0.3. And many, many others. So this is an argument in the favor of in 64 is precision here, I guess the final answer
to the question is it depends on the context. Task six is about Unix time. And to solve task six, we have to write Julia code, which calculates in what year the latest representable point in time occurs, and representable in the sense that we want to represent it
as a so called Unix timestamp stored in an int 32 data type. And the Unix timestamp is just a way to represent a point in time.
And you would represent this point in time by storing the number of seconds until the point you want to represent, which have passed since January 1 1970 0am. So for example, if you wanted to store the time, January 2 1970 0am, you would just have
to store the number of seconds in one day. And before I get started writing the code, maybe I can give a high level overview, what we will essentially do is we will add the maximum number of seconds that can be stored
in an in 32 to January 7 1970 0am, which will give us the time the law of the latest representable time in such a timestamp. And then we have to find out in which year this time occurs.
So we will convert it to years and then round to whole years. Okay, so let's get started. The largest representable number in an in 32 data type can be calculated using the function
type max, which you know from the previous exercise. And it's this number. Let's call this max seconds because it's the maximum number of seconds we can represent
in an in 32. Now to convert this into years, we first convert to minutes by dividing the maximum seconds by 60. And then again, two hours by dividing the maximum minutes by 60.
This in turn we will convert to days by dividing by 24 because there is 24 hours in a day.
And now we can very roughly convert this to years by dividing by 365.
Of course, this doesn't account for years that have 366 days, which is every four years but since we are only interested in the latest year, not in the latest month or week, this
should be fine. Let's see what we got here. So the maximum number of years, I should I should not call this year, I should call this
years to make it more clear. The maximum number of years is 68.1 approximately. And we are only interested in whole years, right?
Because we want to know the year in which the representable point in time occurs, which is why we can use the function floor to round down to whole years.
Oops, floor not flute. Okay, 68. Now all we have to do is add this to 1970.
And this will give us the answer, which was 2038. Maybe we can make the result a little more nice by printing a little sentence that gives
the answer. So the latest point in time representable as a int 32 Unix timestamp will be in the
year and then prints the year 2038. That's the first half of task six done. For the second half, we're asked to solve the task again, but for a computer that uses
int 64 instead of in 32 to store the timestamp. And this is actually exactly the same. But instead of in 32, we just have to enter into 64.
And we should also change it here in the sentence. And as you can see, the the latest point in time representable as an in 64 Unix timestamp is almost comically large. So I assume that nobody who owns a 64 bit computer will have to worry about that.
And anytime soon. For task seven, we're asked to list the two Bool literals, also called Boolean literals. And there are only two.
So the first is true, which has the meaning that some logical statement is true and false, which has the opposite meaning. That's it. For task eight, we are asked to give three examples for Julia expression that involves
two numeric literals and evaluates to a Bool value. And the key to this task is to use numeric comparison operators. You know some of them from your math lectures in school already.
For instance, the comparison operator smaller is just this just this digit in Julia code, which evaluates to the value, the Bool value true because one is indeed smaller than two.
Another comparison operator is the equality operator, which is written as two equal signs in Julia and also many other programming languages. And this in this case is what evaluate to false because two is not equal to three. And there are also other comparison operators.
For example, the operator is larger than or equals, which is written like this. And again, it will evaluate to a Bool value of false in this case, because 4.9 is not
larger or equal to 5.0. Task nine asks us to use the official Julia documentation to find built in functions with which we can convert a Bool value to its int counterpart and vice versa.
And we're asked to write a line of Julia for each of the two use cases. If you go to the linked documentation page, you will find that the function you can use to do this conversion is just called convert. And it has two parameters. For the first parameter, you have to supply the data type you want to convert into as
an argument. Let's start with converting to integer. And as the second argument, you have to supply the value you want to convert to, to integer. In this case, let's start by converting the value false.
As we can see, it's being converted to a zero value rule is converted to one. And that's all the Boolean values there are. So we're done here. Let's try the other way around.
Let's convert a zero to Bool. Okay, it gives us false as expected. One gives true also as expected. So we can see the conversion is symmetric. Let's try other integer values. What about minus one? Okay, we can see that minus one raises an error called an inexact error because the
conversion cannot be made in an exact fashion. And this is because in Julia, you can only convert the integer values zero and one to Bool and no other integer values.
For task 10, we are given the question suppose you want to compare to Julia variables for equality after a numeric value has been assigned to each variable. Can you use the equality operator equals equals in any case?
What do you have to consider and why? This answer really depends on the data type of the numeric value which isn't given in the question. So let's think about what different data types for numeric values we know. In the lecture, we have seen three different data types in 64 float 64 and big int.
And in fact, we can use the equality operator to compare in 64 numbers and big int numbers in any case. So the equality operator always works as expected, and just compares the two values.
However, it's this is not really true for float 64 numbers. Because for float 64 numbers, the equality operator doesn't really compare the values that are represented in the float 64. Instead, it compares how they are represented.
And you know that there can be different ways to represent the value 0.3, for example, because a float 64 representation is always just an approximation of the represented value. And there's more than one way to approximate 0.3, for example, or many other values.
This is why the equality operator gives results which are quite unintuitive. So this is why we can't use the equality operator, or rather, we can't use the equality operator
if we want to compare the represented values, which is most often the case if we should want to compare the representations of the values, then we could use the equality operator. But this is really use case that is very rarely the thing we need in a situation. Instead of the equality operator, we can use a built in function in Julia, which is called
is approx, which is short for is approximately, and this will compare the represented values as you would expect. In task 11, we are asked to give two examples for a char literal.
You know from the lecture that a char literal is two single quotes, two or two apostrophes you could say, and between them, you just put the value your char should have. This can be any letter of the alphabet. So all the different numbers, all the different digits, sorry, special symbols, like this
one that's only available on the German keyboard. It can also be white space or symbols, a symbol you can't really see. And it can also be a so called escape sequence.
And an escape sequence is a sequence that's initiated with a backslash, and then you have the value you want to represent, or sometimes also a code for the value you want to represent.
If you want to represent a backslash as a character, you can type backslash backslash. And this, this char literal has the the one backslash as its value.
But in Julia code, it is represented as apostrophe backslash backslash backslash apostrophe. And similarly, you could also have the tab character as a char literal, or also the new line symbol like this.
For task 12, we are asked to give two examples for a string literal. You know from the lecture that string literals are put in these double quotation marks. The simplest string literal is just the empty string.
And a more interesting string literal could be the string hello world. Okay, that's it for task 12. Off to task 13, we've already talked about escape sequences in the char task. But now we are asked to give a string literal involving an escape sequence.
Why not start with the tab escape sequence, which will look quite boring when we just
enter the string literal. Because in the output in the Jupyter Notebook, it just shows the literal as we put it in. But if we hand this to the println function or the print function, then the escape sequence
will be converted into the value it represents this case the tab white space. So we will have this long white space between our two words. We can also put the backslash here, or maybe the new line character.
And we can do we can do it similarly for the other string literal we asked to give
like this.
For task 14. We are asked to write a Julia expression that evaluates to the string value, quote programming is fun, unquote, including the quotation marks. And we're asked to not use any literals in our expression. If we could use literals, then it would be very easy to complete this task.
We would just have to write the string literal programming is fun. And that would be it. But we can't use literals.
So this is not the right answer. Instead, we are given these five variables here, called string one, up until string five. And we have to combine these now to create the string quote programming is fun, unquote. And there are multiple ways to do this.
One way would be to use string interpolation. But I think it's not as readable as the other way, which is concatenation. And you could also think that maybe you can just pass all the values to the print function,
because the print function will also print the value programming is fun, quote unquote, if you handed the correct arguments, but this is actually not the right answer, because the task says to write a Julia expression that evaluates to the string value.
And if you call the print function, it doesn't evaluate to its argument. It just puts out the argument on the output, which is a side effect. And the value it evaluates to is actually nothing. So let's use concatenation to provide the correct answer.
The string we should create starts with a quotation mark. So we can use the string variable which includes the quotation mark first, which is called string five. To this we concatenate using the concatenate operator, concatenation operator, asterisk.
To this we concatenate the string variable which has the value programming. We continue with the space string four, then again with the value is string two.
Let's see what we got so far. All string fives not defined. That's why that's because I didn't execute this cell, but now it should work okay. So far we have quotation mark programming is. So let's put another space there, string four, and now the word fun, which is assigned
to the variable string three. And we should end the string with another quotation mark, whoops, with another quotation mark. So string five again. And there we have it, the output quotation mark programming is fun quotation mark as
a string value, which is here represented as a string literal, which is why the quotation marks are escaped with a backslash. And it's all enclosed in another pair of quotation marks.
Now for task 15, which is called emphasize, we are asked to write a Julia function called emphasize, that receives one string parameter called word. Okay, right now, I can already complete a part of the task, which is to write a Julia
function called emphasize that receives one string parameter called word, I just have to put the function name, right as in every function definition. In this case, it's already given emphasize the delimiters for the parameter list, and then the one string parameter called word.
And then we continue our function definition with the assignment operator. Okay, so this part of the task is already done. Now let's see what our functions body should be. And the task description continues saying the function concatenates word and two exclamation marks and returns the result.
For example, the expression emphasize Hello should evaluate to Hello, exclamation mark exclamation mark, the expression emphasize I like trains exclamation mark should evaluate to I like trains three exclamation marks, and so on.
Test your function by calling it with different arguments. Okay. So we take our one argument called word and we concatenate it with two exclamation marks simple enough. That should do the trick. So let's test our function by calling it with different arguments as the task says, let's
try Hello first. There we have it Hello, with two exclamation marks. Now what about I like trains exclamation mark. And there we have it. I like trains three exclamation marks. In task 16, we have to write three Julia functions called first letter, last letter and middle
respectively. All three should have one string parameter called word. We can expect that word has at least three characters and the functions should return the first letter of word the last letter of word and word without the first and last letter
respectively. Okay, let's get started. The first function should be called first letter f1 parameter called word. Okay, first half of the function definition is done. We can continue in a similar fashion with the other functions we should write.
Oh, sorry, it's called middle middle word. So we're defining three functions.
Now let's think about what the bodies of the functions should be. The first function should return the first letter of the argument word. So to do this, we can use a technique which is called slicing.
And string slicing is a way to extract parts of a string from a string. Let's first start with an example. Let's say we have the string Hello.
Now we can slice this string using the so called bracket operator. This is the bracket operator right here. And I have to pass an argument to the bracket operator, which can be either a single number, or it can be a so called range, which is two numbers separated by a column.
I will show you both. So the number one just returns the first character of our string Hello, in this case, it's age. You should be able to guess what the number two will return just here.
So the second character of the string. And we can also use the special value end to always get the last character in our string.
And we can also subtract from end. For instance, we can subtract two which will give us the, or rather, let's subtract three, which will give us the character that is three positions before the last character. In this case, it's the E in Hello. So this is it for retrieving one character of the string, but we can also take a portion
of the string from it by passing a range to the bracket operator like this. For instance, we've just sliced el out of the word Hello.
Because E is the character at the second place in the string, and L is the character at the third place. So we've taken this as a slice. All right, this should give us enough knowledge to complete the body of our three functions
first letter, last letter and middle. To to return the first letter of word, we just have to slice with the one with the number one. To return the last letter of word, we have to slice with a special value end.
And to return the middle, which is here defined as the word without the first and last letter respectively, we will now pass a range from two to end minus one.
Okay, let's let's test our functions here. Let's call the function letter. And let's pass as an argument, something like Hello, maybe. Yeah, and it returns the first letter of Hello.
Now, for our second function, let's call last letter now. Let's again use Hello as an example for the argument. Okay, we received the letter O from the value Hello. So the last letter, very fine.
And the last function middle, let's also call that again with Hello. And we will receive our ELL as our results. So this is what's called in the purpose of this task, the middle of this argument.
So with that, we're done with this task. Task 17 is the question from the lecture, you know that strings are immutable in Julia. Is the following code a counter example to this fact, justify your answer.
And the following code is in the first line, we assign to the variable my string, the value Hello, comma space represented as a string literal. And in the second line, we assign to the same variable called my underscore string, the value world exclamation mark.
So have we been lying to you in the lecture? The answer is no, obviously, the following code is not a counter example to the fact that strings are immutable in Julia. But one could think so right because my string, the first line is assigned to value Hello.
And aren't we changing the value when we assign world exclamation mark in the second line? Well, the answer is no, because to say we are changing it would be a misunderstanding of the Julia semantics.
When we assign a value to a variable to which a value has already been assigned, we do not change the previously assigned value. Instead, we replace the previously assigned value. So in this example, we replace the value Hello, comma space with the value world exclamation
mark. But this does not mean that we change the string Hello, comma space, we merely replace it. So the thing we set in the lecture is true strings are immutable in Julia. In task 18, we are asked to give three examples for a vector literal.
We know from the lecture that a vector literal is a comma separated list of values, which are the values stored inside of the vector. And this comma separated list is put into brackets, which now then makes them a vector
literal. And what's the simplest comma separated list? Well, it's the list which has no members, so just the empty bracket operators. And this gives us a vector literal, which has nothing in it.
And Julia calls this a any vector, because the things inside the vector have no type which Julia represents as any. But of course, there are also more interesting vector literals, for instance, the vector
literal 1234, which Julia now represents as a vector of type in 64. And also, we can have mixed type vector literals, for instance, 1.0 is our first member in the
vector, maybe the empty vector as the second element, just integer three as the third element, and maybe a string as the fifth fourth element of the vector here, which will again give us a four element vector of type any because there is no, there's no common type for these
numbers. But yeah, still, you can have a mixed type vector in Julia, just like that. Task 19 vectors versus strings.
The two next code cells second lines contain identical Julia statements, both reading sequence bracket operator two. To this we assign that character x. In the context of the first cell, the statement is legal.
But in the context of the second cell, the statement is illegal and causes an error message explain why this is the case in one sentence. Okay, so let's start with having a look at the error message. Okay, the the error message is no method matching set index exclamation mark string char in 64.
Not a very helpful error message right there. Yeah, I could explain to you now that set index is in fact, the function that Julia calls behind the scenes when the bracket operator is used in such a way, but that's not really
the point of the task. Instead, we just have to look at the context of the code of the of the line and line two, to find out what's wrong here.
In the first code cell, the variable sequence is a vector, right and the first line we make a new vector, and we assign it to the variable sequence and then we assign to the second element in the vector, the character x, and then we print the sequence, which results
in a XC. And this is possible because vectors are a mutable container data type and Julia key word in this sentence is the word mutable. We can mutate or change mutable data types.
For instance, we can change a vector by assigning something to a place inside of the vector. So this is perfectly possible. In the second code cell, however, sequence is no longer a vector instead, it is now a
string, the string ABC. And as you know, from the previous task and also from the lecture, strings are immutable in Julia, which is why we cannot assign something to a position in the string. This is why it prints an error message. Task 20 reads, suppose the following three code cells could be executed without any error
being thrown. deduce the type of the variables A, B and C from this information. We cannot execute the three code cells without an error being thrown, because they contain
what's known as a free variable. The first code cell A is a free variable, and a free variable is a variable, which is used before it has been assigned to. In the second code cell, it's the variable B, which is a free variable. And the third code cell, it's the variable C.
What we can do is we can look at how the variables are being used. And from this, we can deduce the data type, which must have been assigned to the variable if they could be executed without an error being thrown. In the first code cell, we see that the variable A is passed as the first argument to the function
push exclamation mark. And the second argument to the function is the character literal y. From the lecture, we know just one data type, which can be used as the first argument to
the push exclamation mark function. And this is the data type vector. From this we can deduce that the that a must be a vector. So let's try to assign a vector to a and to push something at the end of the vector.
And voila, it gives us a two element vector with the character value x in the first place,
and the character value y in the second place of the vector. In the second code cell, we can see that the so called bracket operator is used on the variable B. We know two data types from the lecture with which the bracket operator can
be used. And these data types are string and array. Furthermore, we see that the results of applying the bracket operator to be the results are then passed to the binary operator asterisk.
And this could either be the multiplication operator or the concatenation operator. We know the multiplication operator from from numeric values, right, we can just multiply numeric values. And we know the concatenation operator from strings. So we have, we have two sets of information given from the asterisk, we know that the
result of applying the concatenation operator is either a string or a number. From the bracket operator, we know that B must either be a string or an array. And if we combine this information together and take the intersection of the two sets,
we end up with just the data type string. So let's try to assign a string to be here. And voila, it slices the string in two places, and then concatenates the results into what
is printed here. In the third code cell, what do we see, we can see that we assign the character x to
the bracket operator applied to the variable C. And to the bracket operator, the position three is passed. And after that, a slice of C is printed.
And we know only two data types with which we can use the bracket operator, the data types are string and vector. And only one of them is mutable, which is the vector.
So this is why we know that C must again be a vector in this case. So let's make C a vector. And also, we know that C must be a vector, which has at least three elements, because
we're assigning something to the third element. So ABC, this is a vector of three elements. And let's see the result. Okay, we get a bounce error, attempt to access a three element vector index five colon 10.
Yeah, this is because C is sliced in the last line. So three values aren't actually sufficient. Let's put some more values.
Okay, that should do it. And voila, we can see that x is assigned at the position three. After that, the slice of five until 10 is printed.
So C is here a vector with at least 10 elements. That was it for the solution video for the second exercise for the course introduction to programming for business analytics. I hope you found this video helpful in understanding how to solve the task of the second exercise
sheet. If not, please reach out to us and ask your questions for instance via Moodle or by writing us an email. In any case, see you next time.