Ad
  • Custom User Avatar

    The tests don't (and should not) check that all the operations you performed are correct. The overall of tests should control that the code works correctly with sufficiently distinct inputs. The true issue, and it has been raised years ago, is that there are no random tests.

  • Custom User Avatar

    It failed with recursion error when I tried, though.

  • Custom User Avatar

    I would not be quite as critical, but for sure this is aligned with my comment.
    This is just not a class or OOP kata at all.
    It's a like, an algo, data type kata dropped inside a class that the kata creator made on their own to start the example for you.

  • Custom User Avatar

    no spoiler flag, here, I answered in the description of the fork.

  • Custom User Avatar

    @beniolenio:

    Thing is, renaming vars and splitting differently a code, it can improve a lot its readability. So if you're aiming for this, that's pretty often the way to go, imo.

    Now about your algo, let's see...

    • g is an iterator => g should stand for [*g]
    • path strings are continuously split/joined (the values of js) => do that one time for all, then manage the resultant data structure (whatever it is). Or maybe use something like str.split(sep,n)? I never use that, might be appropriate, here.
    • files strings are split two times in js, first to group, then to build the values. => split once, then work on the split data. This makes the previous point useless (edit: well, I wrote this thinking about something like what I used. But you can use the suggestion of the previous point to keep your approach and end up wih a better managment of the js step).
    • personal taste: I'd tend to identify the folder, then do the recursive call, rather then identifying the files and bypassing the recursion. That makes the intent less clear, imo (here at least)
    • the trick about your managment of root is quite disturbing. To me, that means you're merging two different functions in one.

    If I go further, I guess that means I'll fork your solution...

    edit: btw... why js??

  • Default User Avatar

    @Blind4Basics:

    True, valid points. I haven't mastered OOP design at all, so I'm bound to make mistakes like the ones you point out. In my defense, I do try to stick to just the requirements of the kata (i.e. the only "user" here is me, when creating the object in the tree() function). As far as I'm concerned, the "user" never sees anything beyond the existence of the tree() function.
    As for the sorting stuff, yeah it's not ideal. I can't remember exactly (this was a while ago) but based on my docstrings I believe I may have been running into performance issues. These kind of restrictions often influence my solutions, and they won't be obvious after the fact.
    In a real world setting a class would rarely ever be truly "finished", as a project progresses, I'd keep making changes. But on CW, the implementation is done exactly when the solution passes all the tests (there are thousands of other katas waiting :)
    Thanks for the feedback!

  • Default User Avatar

    Sure, no doubt you have your conventions and as long as you stick to them, you know what they mean. Here's two challenges though:

    1. Can anyone else come along and understand your code? How much mental effort do they have to put in while reading a single line (e.g. "wait, what was g again? Is x iterable? Where did js come from?"). How easy would it be to change some of the functionality?
    2. If you came back in a few months, and looked at your code (without other context such as the kata description etc.), would you know what your code does?
      If you can answer these with "sure", then you're golden. E.g. in my case, after seeing your notification, I just had to glance at my code for a minute or two and I immediately knew what the kata was and how my code solved it. That's my personal preference; long, verbose and clear, because I'm not smart enough to understand a one-liner I wrote a year ago. That's why I skip all the code golf challenges and others like them: I personally find brevity a useless skill outside of pure entertainment settings like these. But that's just me. If it works for you, then that's all that really matters.

    As for your last point, I totally agree, I have that experience with almost every kata at 5kyu and above. Other always seem to find the most concise and simple way of solving it, and I always take the complicated route. Comes from experience, I suppose.

  • Custom User Avatar

    Hi,

    I'm sorry, but I don't like this kind of longer code ;) Too short isn't good, yeah, but the longer the code, the harder it is to not introduce inconsistencies in the logic.

    For example, your current design isn't coherent about the sorting step. Sorting shouldn't be done as a separate action but should instead be trigered during the iteration. Moreover, your class needs the user to triger it manually. Meaning the designed class is relying on user actions to behave correctly which is just... not a good design (at all..) (talking about encapsulation).

    There is one simple way to encapsulate the current version to hide this problem, but you still do all the sorting steps even when useless (hence, you lose the advantage of the generator version):

    tree=PathObject.from
    

    where PathObject.from is a class method holding the current code of the tree function. This way, you at least keep something clean about encapsulation of the logic (but again, the sorting still isn't made in an appropriate way, to my taste).

    Cheers :)

  • Default User Avatar

    Thanks! I wouldn't say it's necessarily more elegant, but it is definitely more readable. List comprehensions, while powerful and often performant, tend to be hard to reason about, especially because we have a tendency to try and cram it all into as few lines as possible, so we use variable names like "k", "x", "g", which say nothing about what their role is.
    Being able to reason about the code I'm reading is much more valuable than brevity (which I believe is why you say mine is more elegant); I'd rather read 100 lines of code and know exactly what is happening, than read 3 lines of deeply nested comprehensions and have to put on my genius hat to figure out what is going on.
    I think the biggest difference between our approaches is that yours is a "lazy" generator, it creates the values only when they're requested. Mine generates the entire tree structure upfront and then just iterates over the results. Yours is probably more efficient in that regard.

  • Custom User Avatar
  • Custom User Avatar

    (there actually is a "somewhat way", but not bullet proof...)

  • Custom User Avatar

    Sure, I can't prevent all these things in python, so feel free to find ways around the current restrictions.

  • Custom User Avatar
  • Custom User Avatar

    The |is called a guard.

  • Custom User Avatar

    Syntactic sugar for a case expression.

    four n | n == 4 = 7
           | n == 7 = 4
           | otherwise = 0
    
  • Loading more items...