Multi Dimensional Arrays - mistakes in syllabus and hints

Hi again, dear Collin,

I’ve just finished the exercise above and - I’m sorry - have to report little mistakes and want to make some suggestions…
And have an idea…

#1 In the Concept it says:
A similar issue arises when querying the size of an array. length() gives the total number of elements, size() gives a tuple of ndims() elements with the length of each dimension.

I guess it should be:
→
…size() gives a 1-tuple of elements with the length of each dimension.
(1-tuple containing the number of elements of af DataFrame or a DataFrameRow)

ndims() gives the number/amount of dimensions of an array.

#2 after starting “Exercism Matrix” in the editor…
code with empty functions and parameters are shown…
With an empty constant E=nothing as the specification for the matrix.

In the functions it is also named as ‘E’.
A friend of mine was confused because he uses uppercase for constants and lowercase for variables,
that’s what he learned at university.

The question:

shouldn’t ‘e’ in the function be lowercase, as it is variable?

#3 Hints, Task 5: The dots (e.g. 1, 2, etc.) and 0s need to be changed to Xs and Os, respectively.

→ The dots (e.g. 1, 2, etc.) and 0s need to be changed to Xs and ' 's, respectively.

And…
some suggestions to Collin:

When I started this exercise I used map(x → x,E) which is possible, but maybe a bit inept.
Could you please
add copy() in the first array concept AND
write about indexing that was very confusing to me (as I come from PASCAL where I remember the syntax was [x][y]) in the meantime before having read about it here!

And: a lot of times during the syllabus I sit and wonder how the solution might be…
Later I find that it was so difficult, because thinks were missing or not totally correct or I did not really get it yet.
Because of this I have made a few considerations:

while doing this exercise it was still not fully clear to me
how to

  • copy an array (copy) as it wasn’t mentioned in the syllabus before and
  • use map for easy tasks
    I guess I mentioned it before but it still has impact on me:
    In the concept Functions (“anonymous function”; optional arguments/parameters)
    where map first was mentioned it just said:
    “Anonymous functions are common in Julia code, especially when combined with higher-order functions such as map() and filter() (which will be covered in more detail in a later concept).”

So for me I thought: well, map isn’t important it will be explained later.
And didn’ have the idea that this could be important.

Could you please reedit this concept and write a bit more about map so that it is clear it’s important (especially for the coming exercise) and how to use it in a basic way. ?!

I would be looking forward to see this being included and think that this would improve the syllabus and make it more easy to figure out solutions for newbies.

And I have an idea:
what about adding a smal quiz after each concept (see below) to improve learning for the students?

thanks for your time and reading this and taking it into your considerations.

with kind regards,

Nisang

And here a quiz for Concept: [Functions] II (Functions in Julia on Exercism)

**Question 1 – anonymous function
What is an anonymous function in Julia, and
when to use it?

Question 2 – positional vs. keyword arguments
What is the difference of positional arguments and keyword arguments in Julia
– and why are keyword arguments crucial for analysis- or functions for optimisation?

Question 3 - optional Arguments
What is the difference between a optionalen positional argument and a keyword argument with default-value?
State a practical advantage of keyword arguments.

Question 4 – Splat ( ... )
What is the use of splatting in Julia
and cite a typical practical example of it (positional or keyword)?

Question 5 Slurp ( ... in the definition)
What is the difference between splat and slurp and when to use slurp reasonably?

**Question 6 catch question! **

Situation

function f(x, y; opts...)

return x + y

end

args = (1, 2)

kw = (y=10,)

Frage

1️Which of these funktion calls do work?
2️ describe exactly what will happen!

A) f(args...)

B) f(args...; kw...)

C) f(; kw...)

D) f(args; kw…)

how do you like that?

With limited time today, I can only give a partial answer below. I’ll discuss the rest with @depial, but that may take a few days (depending on availability).

This is a convention in several languages, but not Julia. Once we get the Linear Algebra concepts live, you will see that the (strong!) convention in that branch of mathematics is Uppercase for matrices (2-D arrays), lowercase for vectors (1-D arrays).

These concepts are documents-only until we can think of exercises to pair with them:

Also, e is not what I would choose for a variable name, because it looks too much like Euler’s number. That is actually a predefined constant in Julia, though you have to enter it \euler then tab. Unfortunately, it renders very small here:

julia> ℯ
ℯ = 2.7182818284590...

Nothing here is a DataFrame. That would need DataFrames.jl, which is not included in the test runner (only the R track has dataframes as standard).

2 Likes

This is correct as stated in the docs. A 1-tuple is of the form (n,). size() gives a ndims()-tuple. So for a 3x3 matrix M, size(M) returns (3, 3) which is a 2-tuple as expected from ndims(M) returning 2. (size() will only return a 1-tuple for a one dimensional array, such as a Vector.)

Thanks for catching this! However, the hints have recently been updated (in response to your previous post asking for help) and this was changed in the update. You should be able to see the new hints if you revert your exercise to the start.

1 Like

@AnandNisang Can I ask if you’ve read this reply? Is there anything about why we don’t explain map() yet that is confusing or that you disagree with?

As you do exercises, it might be helpful to remember that the exercises are not designed to be as easy as possible for the student, but just possible for the student based on what we’ve taught before.

Naturally, as we become more proficient in a language, we find more powerful functionality which can make things “easier”. This is why you are encouraged to go back to older exercises and use your new knowledge to iterate your solution, making it “cleaner” or “more idiomatic”.

1 Like

Good evening Colin,
okay.
thanks for your answer

yes, that’s true
I looked it up in the REPL once again
what I meant is:
in this sentence:
size() gives a tuple of ndims() elements with the length of each dimension.
I had the felling of something’s missing.
But Depial gave the answer above (as quoted below)

But what made me being confused is that

" after tuple of ndims() elements "
there is no -
after ndims()
Depial added that and that made it clear to me
(in Geman a ‘-’ is used to make it clear what belongs together)

My Suggestion, still:
change the text as follows
"e.g. * size() gives a tuple of elements with the length of each dimension.
and also after ndims() :
gives the number of dimensions of an array.

or add Depial’s further explanations.:

thanks for your interest

Nisang

Dear Depial,

okay, until now I didn’t understand
this explanation makes it clear!

Dear Depial,
Yes, I’ve read it and must admit
I didn’t really get the example
I will try them in the REPL to understand them.

And: about map() and copy:
yes, I know I can solve it traditionally.
but want to learn the new functionallity of Julia.
And as I still had the feeling of “this would be helpful to have a basic understanding.” I can accept if you’d leave it as it is but wanted to mention this once again…

“If you don’t feel comfortable with these options, then there is always the for loop, but you can also do research into how to use any of them if you’d like, which is one reason we mention them. Otherwise you can continue in the syllabus and they will be covered in later concepts.”

Yes, I know

“Instead of immediately trying to use everything, maybe a good technique for you to try at this stage would be to use basic functionality (e.g. for loops) to pass the tests, then try to refactor your code using alternatives that you have researched (e.g. map, comprehensions, etc). This is a good way to explore other options, but it requires curiosity and motivation to further explore a topic on your own because it is neither necessary nor expected.”

that’s what I’m doing for quite a while.

But when I read, that an “easy” exercise should take me “about 5 minutes”…
an then encountering it takes me 3:10 h…
I feel inadequate
and try to make it more easy even for other students coming after me…

with kind regards,

Nisang

Great! I’m glad that helped.

I realize that my example tells why map() is unnecessary, but it doesn’t give a detailed explanation as to the pedagogical reasons we don’t introduce it there.

The short explanation is: We want to teach students to walk before they run.

More verbosely: These ideas are abstractions of more basic functionality. If we introduce one idea in the context of an early (basic) exercise, we have to introduce all of them and explain their connection to the basic functionality. If we don’t introduce all of them, we will effectively be guiding a student to a particular solution and tacitly telling them that is the “correct” way, when, in fact, there are various ways. Not to mention that this would overload the student with information since teaching these abstractions was not the original aim.

Pushing abstractions on a student too early can also have negative side-effects on their future learning, such as:

  • Lack of understanding of underlying functionality and connections to other functions, which can lead to misuse.
  • Over-reliance on functionality that is seen as a “silver bullet”, which then can decrease curiosity about related functionality (i.e. turns them into a “one-trick-pony”).

When I said previously that exercises are not meant to be “as easy as possible”, it was related to this. Our number one goal is to make the exercises as instructive as possible while still being passable and the easiest road is often not the most instructive.

In the end, a programmer that becomes over-reliant on abstractions may be able to program, but they won’t be able to do so as well as someone who truly understands the fundamentals too.

Let me know if you have any questions about this reasoning and I’ll be happy to give more detail.

I think that “should take about 5 minutes” is not really a great description. I try to think of “easy” as being in absolute terms (from an expert’s point of view), and I would probably label “easy” exercises as “beginner” exercises to represent the difficulty in more relative terms. In that light, there is no guarantee that an “easy” exercise is actually easy for a beginner and can indeed appear fairly difficult.

Also as a learner, it’s helpful to remember that spending 3 hours on an exercise likely means a lot more knowledge has been gained than spending only 5 minutes on it. No need to feel inadequate, indeed you should feel empowered by your determination.

All in all, it seems like you are navigating the syllabus admirably and we appreciate your suggestions. Keep up the good work!

All the best,
depial

1 Like

Hi Depial,

thanks for your quick detailed answer.

Yes, I will

this is a very good explanation!

So what about introducing
copy() at that state?

I agree totally!

I agree totally!

Thanks for your feedback and appreciation!

Nisang

Is that the reason you didn’t introduce exception handling and throw() in “Perfect Numbers”?

okay,
but then the question arises why E is chosen also for the constant as for the parameter?

copy() is also just one of several ways of copying a vector and is the first thing that comes up in a Google search, so a full section is not likely necessary, though I’m happy to discuss it. In the meantime, I’ve opened a PR to add some extra hints that it is a function in a couple of documents. Feel free to comment.

In related news, you may want to have a look at Vector Operations again, since we have recently updated it with a part on in-place broadcasting (which can produce a copy).

A few ways to copy a vector
julia> v = [1, 2, 3];

julia> vcopy = copy(v);

julia> vcopy = collect(v);

julia> vcopy = zeros(Int, 3);

julia> vcopy .= v

Perfect Numbers is a practice exercise, rather than a Concept Exercise. These are stand alone exercises which can have prerequisites and which can practice a concept. I’ve added Errors as a prerequisite in the above PR since it seems appropriate.

Good evening Colin, good evening Depial,

wow!
the concept has been heavily expanded.
I had to pause in between to digest it’s content.

I have a background in linear algebra and liked this extra explanations.
I would complete the heading as follows:
" Un-dotted operators: a cautionary tale - linear algebra"

and add a question at the end:
What happens if you calculate v .* u?
Or u .* v?

the section " Logical indexing" was first a bit theoretical for me but with help of the REPL I got it’s meaning.

Okay, I should allow myself in a more recent state to use the search!
I will keep that in mind!

Thanks for that
I feel joy!

Just a reminder, in the Julia track, the concepts accessed through the syllabus page are usually longer and more comprehensive (these have the heading About “Concept”), while the ones seen in the exercise are trimmed down versions which usually just have information directly relevant to the attached exercise (these have the heading Introduction).

In fact (and unfortunately??), the way the website handles these pages is more subtle than that. It still sometimes confuses me, even after creating so many of them.

There are 3 files, which are entirely separate on GitHub but Exercism has its own algorithms (at the Ruby on Rails level) for which to display.

  1. The concept about.md with level 1 heading # About
  2. The concept introduction.md with heading # Introduction
  3. The exercise introduction.md with heading # Introduction

In each case, the level 1 heading is just a (necessary) placeholder and Ruby code replaces it.

Authors vary in how they write these files, but (following Exercism guidelines) we try to make the About detailed, with lots of links; the concept introduction more concise, and the exercise introduction aggressively reduced to the minimum useful for the exercise.

When clicking on the concept title in the syllabus tree, which do you see?
image

If you have not completed the corresponding concept exercise, usually the introduction.

After completing the concept, you get the more detailed About to act as a long-term reference.

Complicating things a bit, anyone not logged in to Exercism can follow a URL and see the About (handy for Google searches, and for search engine optimization). I don’t know about anyone logged in to the site, but not entered on that track - like I said, it’s subtle!

Bottom lines:

  • There should be a LOT of information in the About, some of it relatively hard to find elsewhere.
  • The Julia maintainers are scientists at heart (chemistry/medicine for me, physics for @depial). We are far from being experts in web site design!
1 Like

Good morning Colin,

Okay, might be,

some considerations I’d like you to follow:

and is it really a good idea, to name the parameter in the function the same way as the constant (as suggested in the code frame that is given through excercism)?

I followed your course so far - in the believe - that I’d get all that I need to solve the exercise in the concepts…

this isn’t the case.

after opening this thread
I declared a global variable (e.g. ab) and wondered why it was not accessable in the function - I had to assign it as global ab.

with kind regards,

Nisang