Ad
  • Custom User Avatar

    I don't think this should be tagged as "fundamentals". Math and problem solving may be "fundamental" in some sense to programming, but fundamentals katas are about training with a language against the simplest possible problem that exercises the language skills. This means that they are primarily about practicing syntax, not problem solving or math.

  • Custom User Avatar

    This comment is hidden because it contains spoiler information about the solution

  • Custom User Avatar

    A numerical edge case is understandable, but this is a text formatting edge case. The lack of spaces in the string the test means you have to write a specific return case JUST to satisfy that requirement. It's not difficult or interesting, just "if count is this value, return this specific string." If the test were rewritten to say "0 = 0" instead of "0=0" it'd be better and correctly represent programatically dealing with the edge case where the count argument is zero.

    If the intent really is to have a text formatting edge case... well, you can do that. It feels tacked-on and doesn't seem to match up with the spirit of the problem, especially considering how easy it is to solve. It's more of a "gotcha", as it's written now.

  • Custom User Avatar

    "0=0" is an edge case added on request.

  • Custom User Avatar

    The requirements for cases of count<0 are trivial and don't add anything to the kata. Suggest making this a "positive only" kata.

    As others have mentioned the "0=0" solution with no spaces is inconsistent with the other solutions.

  • Custom User Avatar

    Learned from top solution:

    split() already exists. By default it splits a string into 'words' which are any series of strings separated by some form of whitespace.

    #Fighting the last war!

  • Custom User Avatar

    string.join(sequence) produces a string which is all the elements of sequence, with the string interspersed between them. So: "abc".join(["1", "2", "3"]) is "1abc2abc3". I'm not sure what you're doing with it here, but finalstring.join(shorten(workingword)) seems very strange.

    Your solution is a bit longer than mine. I think that's because you're doing explicit tracking/bookkeeping of the workingword -- I just reset s to be the remainder of the string, so workingword is always s[0:index].

    You have two different places where you check whether the word is 3 letters or less -- probably that could have gone into shorten.

    I forgot to consider the case where there are two non-alphabetics in a row, but I got lucky because my shorten just returns the given string if it's less than three characters, i.e. when it's empty. So I'm just needlessly concatenating empty strings.

  • Custom User Avatar
  • Custom User Avatar
    • Learned that .reverse() returns NoneType. If I want to reverse something, I just call reverse() and can't/don't need to set it equal to a new variable.
    • Learned from solutions that int() can be used to convert between bases.
    • Learned from solutions that map() can be used to apply a function to elements of an iterable.
  • Custom User Avatar

    Actually I'm not sure how the third solution works at all. It looks like it produces a 100% win rate in the case of 'rock' so it should fail every time. I tried forking the solution and running it but there seem to be issues with doing that - even when I fork my own working solutions I get errors trying to run them.

    I see that your commentary is the more general (and more correct) version of the things I was observing in these cases. I'll come back to this for reference.

    The Python "trueval if condition else falseval" seemed intuitively understandable when I first looked at it. But the longer I think about it, the quirkier it seems.

    I guess I knew that you had to return "something that evaluates to a value", ie. an expression. I would have expected conditionals to not be an expression, but it looks like a sort of exception was made for it?

  • Custom User Avatar

    Yes, anything defined outside a function is in a "global scope", and anything defined within the function is (normally) in a "local scope". Scopes are common to most programming languages, but how they function exactly can vary. (For instance, Python tends to just have local and global scopes, but in e.g. C, C++, or Java, a function can have many scopes, and a variable might only exist within the body of a loop or whatever.)

    Yes, a dictionary is basically a list, but instead of each element having a "number" index, you can use anything as the index. In other languages, these are sometimes called "maps" (Java, C++) or "hashes" (Perl, Ruby). I've also heard the term "associative array".

    Yes, a "lookup" expression like foo[k] produces a value, and you can perform more lookups on that result using foo[k][k2]. You often see this with attributes and methods -- foo.bar.baz or foo.bar().baz(). For example, you might have done request.POST.iteritems(). From the point of view of "abstract syntax", a "lookup expression" is E1[E2] where both E1 and E2 can be expressions. The concept of expressions is deeply recursive so you can build up expressions of arbitrary complexity like foo[k1][bar.baz[k2]]. This is IMO one of the most beautiful ideas in computer science, but expressions above a certain threshhold of complexity should probably get broken out into separate variables. I think return dict[choice][outcome] is fine and good, but if you felt like it wuold aid readability, you might do

    # outcome = 0 for loss, 1 for win, or whatever
    responses = dict[choice]
    return responses[outcome]
    

    Re: the return foo if ..... solution. In other programming languages, there is a special if/then/else expression. In the C family of languages, it's written condition ? trueval : falseval. So console.log(win ? "you won!" : "you lost"); . For a long time, Python didn't have this kind of expression, but eventually it was added with a (IMO) very quirky syntax: trueval if condition else falseval, so print("you won!" if win else "you lost") . The Python community thinks that this emphasizes the "default" case where the condition is true. Anyhow, so you can see that the "if/else" thing here is an expression, not a statement, and you can return any expression. (You can't do e.g. return while .....) I'm not actually sure how his solution works -- it seems like it will sometimes produce scissors-scissors ties, which I thought was forbidden?

  • Custom User Avatar

    Learned some interesting things from the best solutions:

    From https://www.codewars.com/kata/reviews/57e155dded4102075c000087/groups/57e19efe621bcafa9e0014c6

    • Learned that I can import things "as name". Interesting for blandly named imported functions.
    • Observed that I can refer to an element of a dictionary as if I were referring to an element of a list, using a variable for a key inside the brackets.

    From https://www.codewars.com/kata/reviews/57e155dded4102075c000087/groups/57e2545ca396b333e20001c8

    • Observed that I could have defined the dictionary outside the function and the function still would have understood it.
    • Observed that I can refer to an element of a list inside a dictionary by calling dictionary[variable_equal_to_dict_key][index]

    From https://www.codewars.com/kata/reviews/57e155dded4102075c000087/groups/57e247e1ec7d24785a0002df

    • Observed that I could include much more on one line if needed. Return may also come before if, else, and other logical statements.
  • Custom User Avatar

    Thanks! I'm checking the solutions that others have done for each problem, once I write my own code. The top solution for this problem includes both your suggestions. The ".join()" aspect of the solution also came up in the best solution to the previous problem I worked on.

    I tried to use both "for char in s" and ".join()" when writing this solution, but I couldn't make them work with the knowledge in my head. If I can't write the function with the knowledge in my head, I'll write what I can for a solution. Then, I'll carefully review the best solution and work on similar problems, repeating until I can write the code from my head. This way I learn about features of the language, then I practice memorizing the syntax every time I write a solution.

    Eventually the solutions that I write will improve. I find that refactoring the code after seeing a better solution does very little to make the knowledge of how to write the improved code stick in my head, as it never really enters working memory. I'm not sure if I should avoid refactoring completely, though. Maybe I should refactor, but only after some amount of time has passed.