If you’ve put an approach together for an exercise in C#, please paste a link to the article below:
I have done just a draft (in the mentoring notes for now) for Pralindrome Product.
One of the problems I’m seeing is that there are two parts of the problem and each of the two can be approached in a number of different way. What should I do in this case?
Hi, @bobahop, unfortunately that doesn’t solve my problem, I’ll need a different approach
If you look at the link I included you will see what I mean. There are two sets of three approaches. One set deals with finding the palindrome pairs. The other one is more specific about checking if a number is a palindrome or not.
Thinking about it some more, the problem is connected to the discussion I started bout accidental complexity and its benefits or pitfalls. There are two problems in this challenge and each can have multiple approaches. When we add error validation those can have their own approaches. How do we handle things like that?
I haven’t solved Palindrome Products, so I’m no help there. Not sure how much error handling is really needed. I tend to stay away from whatever is not required by the tests, to simplify the solution.
Since you have three iterative approaches and three IsPalindrome approaches, you might use a different IsPalindrome approach in each iterative approach. You could put in a note that other IsPalindrome approaches are in the other iterative approaches. I think that’s how I would organize it, but someone else may have a better idea.
The Python track already has Approaches for Palindrome Products. (Though I find it incomplete.)
@michalporeba I can think of three approaches to Palindrome Products.
- Generate factor pairs, filter for producing palindromic products.
- Filter for palindromes first, then try to factor these.
- Generate palindromes and try to factor these.
Some/all of these approaches also factor into solutions of subproblems.
There sure is a lot to discuss. Fortunately the docs on the Approaches overview say:
- Keep the content fairly high-level
So you could use the Approaches overview to lay out all the different (overall + subproblem) approaches. No need to go into much depth here: you can link to individual Approach documents.
Also fortunately, the docs do not speak against having individual Approach documents discuss only partial solutions. So if you want you can use these to focus on e.g. just checking for palindromicity or just filtering (explicitly assuming the predicate).
Also, reminder: Articles exist. Right now I am not inclined to use them here, but you might!
Thank you all for increasingly generic (and generous) advice. Sadly, I’m not getting out of it what I was hoping, and that is to be closer to publishing my first approaches, and perhaps a video to go with it. How could I get there? Could I get some comments on the specific content I produced, please? Perhaps recommendation for the next concrete steps I should take? @ErikSchierboom any comments from you?
I guess I misunderstood your question? My reply was specifically about how to go about organizing Approaches for Palindrome Products. I also pointed out an omission in your WIP.
Palindrome Products strikes me as a difficult exercise to write comprehensive Approaches for. Difficult as in a lot of work. It might not be ideal as a first exercise to write Approaches for.
Is there anything specific you would like to know about your writings?
- It looks quite alright to me, but that isn’t very instructive.
- Statements about performance could use some concrete numbers. Not runtimes please, but illustrations like «For X range, this function tries Y factor pairs, but only Z of these give rise to palindromes».
- Feel free to skip benchmarks. I feel they’re unhealthy.
- I agree with your intuition to factor out the solutions to subproblems, e.g.
IsPalindrome
,DivisorsInRange
.
Very much based on what works for me personally:
- Create all the files (except
config.json
) that you will need, now. Being able to already put the right content in the right places may help free up your mind. - Focus on what you wish to say before you focus on how you will say it. Specifically, hold off on trying to produce valid or beautiful sentences. Only start writing properly when you have your story down.
- I need a better view on the problem you are facing to be able to offer more advice.
I think I understand the issue that you’re having! There are a couple of ways in which you could handle it:
- Duplicate content between approaches: For example, if there are two idiomatic ways to do error handling, list them both in each approach document
- Create articles for shared content and link to those from the approaches
I think both are equally valid. Does that help?
Hi @MatthijsBlom,
Thanks for such a detail response. The problem I wanted to focus on is approaches to approaches rather than specific solutions to the given problem. I agree, that perhaps I’ve chosen not the easiest exercise to write my first approaches for.
I would like to know more why you think benchmarks are unhealthy? I started with this solution as I spent a lot of time on the problem with one of my mentees who was very curious about performance but struggled to see how big the impact is just when talking about big-O notation. Illustrating the difference with benchmarking helped a lot and he has learnt how to benchmark solutions too.
But I agree, that first there should be more generic discussion about number of operations.
Thanks for the more specific hints on how to write the approaches, I think I’ll give it a go this week.
And with this? The problem is probably that I’m starting at the deep end!
I have done some more thinking about it over the weekend (while away from the keyboard). There are, really, two distinct problems in the exercise. Wouldn’t it make more sense to separate them and then link to each other? Could we (me?) create a “Is number a palindrome” exercise which only deals with checking if the number is a palindrome, do an Approach for it, and then link to it in the approach for the “Is Palindrome Product”?
Let me know what you think. I’d like to do either that, or try to write a more complex single approach to the larger problem later this week.
It is important to note that this feeling of mine is largely reactionary.
Benchmarks are tools, and hence (by definition of tool) occasionally useful. I do not object to useful benchmarks, and of course do not think that these are unhealthy.
However, ‘benchmarks’ are very often misused, misinterpreted, or both. Sometimes it even seems like this is the norm. [Please imagine me ranting about this for a bit here; I did not manage to find the right words.]
There are many students here asking how to ‘optimize’ or ‘make more efficient’ their solution to Guido’s Gorgeous Lasagna. I do not think it healthy to say to these students: «let’s try some things and measure!». Likewise, when someone asks which of a for
loop and a comprehension is fastest, I think generally the proper response is along the lines of: «you shouldn’t care». (Of course I would say it in a friendlier manner, and elaborate liberally.)
Benchmarks, being numerical measurements, are easily misinterpreted as being meaningful. Often however they aren’t really. Small differences tend to not really matter. How to determine when they do? Here is a rule of thumb: if you can experience the difference, then it might matter. Here by experience I mean through your natural sense of time, or by consciously counting seconds, or maybe by using a stopwatch. (Oh, and e.g. witnessing your computer running out of RAM and crashing, and such.)
I caution against including pointless benchmarks in Approaches in order not to contribute to widely held misguided feelings about ‘optimization’, performance, and benchmarks.
I think using measurements to illustrate how complexity manifests itself in the real world can be a good use of benchmarks. Here, not the numbers themselves matter, nor their relative differences, but only the pattern. E.g. if the input size is doubled then the run time roughly quadruples / grows stupendously / increases by a fixed amount every time. Often the same point can be made through abstact discussion of operations, but this becomes difficult when the operations differ between approaches, in which case comparing graphs can help.
I think benchmarks are really useful for this exercise in particular, as it is one of the more resource intensive exercise. So an article on performance would be fantastic.
That’s not how approaches work though, as they should describe one solution to the exercise, possibly with little variations in it.
Maybe in order to move forward, could you show the code you’d want to be including in the approaches?
In case you missed it: I proposed
Abstract example
That would be a not unsignificant deviation from how existing approaches are being written. I’d like to see the actual code that is being referred to first before we continue exploring different ways to tackle this. Could you provide that @michalporeba ?
edit: nevermind. It’s this document, right?
Looking at exercism-website-copy/mentoring.md at csharp-mentoring-palindromeproduct · michalporeba/exercism-website-copy · GitHub, I think you have two core approaches:
- Generate all pairs and filter out palindromes
- Find the smallest and largest palindrome and then its factors
Approach number three is not much more than a variant of the second approach. You could solve this in two ways:
- Create three approaches, where approach 2 and 3 have the same core approach but use a different path to get there. This means they’ll like have some duplicated content, but that’s perfectly fine.
- Create two approaches and for the second approach choose one option as the idiomatic one (I’d argue this is the LINQ one). With the approach then you could start with the
for
loop and then refactor to theLINQ
version if you wanted to still show thefor
loop (this option has my preference)
Then there is the calculation of the palindrome, which I think is perfect for an article. You could choose one of the three options to be used in the approaches and link to the document for more information. You’ll want to use the most idiomatic/simplest solution in the approaches, unless it really harms performance too much.
edit: in my mind, determining the palindrome is not core to the exercise, but finding the palindrome products is
Does this help @michalporeba ?
We are going on a side topic here, so for a moment let’s forget about earlier questions I’ve asked (I’ll come back to them in subsequent comment).
Would checking if a number is a palindrome be an interesting exercise in its own right? We have a task to check if a string is, and while similar checking if the number is a palindrome has some interesting considerations if we are not using string reversal techniques.
If we had an exercise like that we could have approaches for that problem alone.
If that was the case the palindrome products problem become the problem of finding the right palindrome and its products which has its own approaches, but the IsPalindrome
function can be presented in a single version, as it is not part of the problem.
Thanks @MatthijsBlom, indeed I have missed it!
That’s exactly why I wanted to stay focused on the approach to approaches rather than more possible approaches to the problem itself. Two, I thought, was enough to make the point.
The example is very helpful! Thanks, again.