5 kyu
Function Overloading for Types
97Kacarott
Loading description...
Decorator
Language Features
Metaprogramming
View
This comment has been reported as {{ abuseKindText }}.
Show
This comment has been hidden. You can view it now .
This comment can not be viewed.
- |
- Reply
- Edit
- View Solution
- Expand 1 Reply Expand {{ comments?.length }} replies
- Collapse
- Spoiler
- Remove
- Remove comment & replies
- Report
{{ fetchSolutionsError }}
-
-
Your rendered github-flavored markdown will appear here.
-
Label this discussion...
-
No Label
Keep the comment unlabeled if none of the below applies.
-
Issue
Use the issue label when reporting problems with the kata.
Be sure to explain the problem clearly and include the steps to reproduce. -
Suggestion
Use the suggestion label if you have feedback on how this kata can be improved.
-
Question
Use the question label if you have questions and/or need help solving the kata.
Don't forget to mention the language you're using, and mark as having spoiler if you include your solution.
-
No Label
- Cancel
Commenting is not allowed on this discussion
You cannot view this solution
There is no solution to show
Please sign in or sign up to leave a comment.
This comment has been hidden.
You are probably right, and If I were to make the kata again I would probably do so, however I think changing it now would require quite some changes to the test code, and may invalidate a lot of solutions, so I think its better to leave it as it is.
Python newbie here. Very nice kata, helped me with understanding decorators.
My solution fails both recursive test with KeyError exception. I've tried locally to feed factorial function to my solution with no problem. Can I have a code for "rec_test" function so I can test is locally? Or some hint on how to debug it?
This comment has been hidden.
I looked into it, for some reason
rec_test
was not defined in the global scope, and so was contradicting the description:I have moved
rec_test
to top level, and I think that your code actually works now. Have a try and let me know if it is still broken.Thanks for lightning-fast answer. Yep, it is working perfectly now.
So this rec function was a sub function and sub method... I will try to replicate it locally, it is interesting to make it work in sub case as well.
Thanks again for awesome kata!
Love katas like this, Python always amazes me with its flexibility
My code fails at the following test: Methods can access 'self' var, even when not named 'self'.
Traceback (most recent call last): File "/workspace/default/src/codewars-test/codewars_test/test_framework.py", line 111, in wrapper func() File "tests.py", line 212, in access_test test.assert_equals(the_ob.self_access('World'), 'World2')
I'm not sure what else to verify...can you be more specific about the test case?
That test checks whether object methods can access the implicitely passed variable (normally called
self
). Note this should work, whether the variable is calledself
or something else. Looking at your code, I think you are having trouble with that second part.As an example, this code should work:
Based on the feedback, it seems people generally like the concept of the Kata but I have a big problem with test coverage, not being clear with what is expected, and the sample tests not being representative enough.
I'm gonna leave this up for the moment while I rewrited the Kata to be a lot more thorough, then I will rerelease it. (Since the added thoroughness and requirements I want to add will likely break every existing solution, and will essentially be a different kata.)
Of course feel free to keep leaving feedback, just know this kata will be replaced (hopefully soon) with a better (harder?) version, that actually works well.
If you want, I can do a sweep on the kata (description + tests)
mmmh, I missed that part of your message, earlier.
Don't do that. The average rank will be totally biased if you do so. Or be sure it' doesn't fall too far from the current requirements. What do you have in mind, exactly?
Well that's why I was gonna republish this (republish is probably the wrong word. I mean take this one down and put up a fresh new one with a similar name/theme.) Because then the ratings and reviews will have to be fresh.
For the new kata ideas I am trying to implement are:
@staticmethod
and@classmethod
(applied in any order)@overload
(different from@overload()
)my_func[int, str]
would return that specific function.)And lots of extra tests, for example:
del my_func[int, str]
)__init__
,__new__
,__call__
,__add__
etc)cls
andself
properly, even when differnt names are usedWhat do you think? Is that too much? Obviously first I need to make sure I can even write my own solution.
Edit: I also want your opinion on an idea I had for tests. I thought I would make all the tests also available as sample tests, but for the real tests, I would randomize the order (to avoid hardcoding?). That way everything I am testing would be very clear. Or is there any obvious flaw in that?
mmh, ok.
Q: why not keep that one, tho?
Warning with static and class methods... Their actual behaviour (the way they are accessed, I mean) is imo rather a mess than anything. I'm really not sure it's a good idea to dig there. Dunno. But for sure, you can try. Maybe your way with decorators rather than metaprogramming (see the other kata linked below: the author wanted to do so too and we tried a bit, but reaslized the fucking mess, then...) can make the thing possible, yes.
All your ideas are pretty nice/interesting, but that seems very ambitious too. ;)
errr... randomization isn't enough, generally. You can put a lot of things in the sample tests. Just don't forget that sample tests aren't there to patch an incomplete description. :)
In any case, you'll still have to build some actual random tests for the full test suite.
cheers
I still think the answer here is explicit registration, trying to figure it out implicitly will surely lead to surprising behaviour. Imagine you have this big carousel of functions, they come from all over the place and need to be decorated by various requirements. Just because two functions are defined in the same location or decorated in the same location doesn't mean they belong together. Global state seems rather unhygenic in general. There's also going to be that one guy who starts decorating stuff in different threads. Maybe there are two threads running in the same scope and they both are decorating functions there. Do they belong together? Maybe maybe not, both could be right, but you have to choose one.
Maybe you are right Blind. I'll try get this one up to scratch as an 'easier' version, and if I can make the 'ambitious' one work then I'll add it as a new one.
Regarding
@classmethod
and@staticmethod
I'm aware they are rather... messy. I do have an implementation that seems to handle them reasonably well, although I have yet to do a full test suite on it. This is partly because my knowledge of these decorators are somewhat sketchy. My implementation at the moment successfully creates overloaded functions that are accessible through class or object, and are passed the owner class or not (for@classmethod
and@staticmethod
respectively). But I would not be surprised if there are other mechanics or features that are getting lost along the way.As for explicit registration, I don't really understand the need. A naive approach stores the functions within the
solution
module as a global variable, which need not be imported. I could add a namespace requirement thatoverload
is the only global variable introduced in the module, but that only helps if someone plans to usefrom solution import *
. Unless the idea is the insert the solution code directly into another project maybe.My understanding of how 'correct scoping' should look would be imagining that every overload is in fact creating a new function (
overload(int); def my_func(x): pass
==def my_func_int(x): pass
). And so anywhere else in the code, ifmy_func_int
is accessible, then so should the int overload ofmy_func
. Assuming someone understands normal variable scope, then they should not be surprised by the overload. Of course, as to whether all that is even possible, I am not quite sure.global state, not global variable. IMO each group should have its own state. you requirements demand that there be a single storage point so that you can compare new function names and scopes to previously seen ones.
My understanding of correct scoping is that there's no such thing, the term is ambiguous, it doesn't specify what to do.
are g and h in the same group? (they're not defined in the same scope, but how are you gonna tell those scopes apart? xD maybe that's possible but oh boy you're going to have to explain that in the description somehow) So you have this really vague thing with scopes going on which probably defies explanation and is probably really magical to implement - and all of that goes away if they are instead registered together. This also gets rid of global state.
It also saves the end user from guessing what does and does not group, because they are the ones saying what a group is. And it doesn't impose arbitrary limits on how when and where they can be defined.
Good Kata! Decorators still do my head in, although they are conceptually so simple, but once inside it's hard to wrap (ha!) my head around where what why is going on. That said, I was torn between rating this as 4 or 3 kyu. In the end I went with 3 just because of the requirement that it work on bound methods. My solution passes but it is so simplistic I gotta suspect that there's something the tests aren't quite covering. I literally just check for the existence of a parameter named "self". Granted this would work on 99% of code out there, but maybe some programmer transitioning from another language prefers to write "this" instead...
ok, so: there are things that aren't described properly and should be put in the sample tests too.
mult(int,int)
functions. So far, nothing of that kind can be expected from the description, and that's what totally tripped me up. (I was going for__name__
instead of something more appropriate...)cheers
So that's why it wasn't working!
I added a lot more examples and clarity (I hope) to the description, making it clear what is being tested and what is not.
I also added a few tests to reflect that, and changed others to be consistent. If the description/tests are still not clear enough or if I forgot anything, let me know. For now I am going to mark as resolved.
Wait. You want us to dispatch on function NAME as well? Or do you want us to figure out which scope they're in, to dispatch by scope -> name -> types ? What about lambdas? No, they cannot be used with decorator syntax, but they can be decorated:
the pypi package multipledispatch is arguably broken:
I was looking at this library to tell you how they solved it, expecting to see them use registration like
functools.singledispatch
or clever inspection to figure out the scope. But nah, it's broken. xDI marked this as a question (and I haven't even solved it) so I guess I should be asking something. Should there perhaps be some mention or acknowlegement of this? Maybe at least be mentioning that yes, it should be dispatching on function name? Seeing as how shady that is it should be supported and blessed by the description I think, instead of having solvers go out on a limb.
Either acknowledge and bless it, or do like
functools.singledispatch
IMO and from what I can tell to be reasonable.Or maybe I misunderstand and there's a reasonable way to do it.
You make a good point, I hadn't considered scope. While I do have an idea to deal with scope, I don't actually test it at all (and I think if I did it would break the existing solutions.)
So just ignore scope and dispatch by
name -> types
and I will update the description to mention this.If I get a nice solution that includes scope maybe i'll mention it here.
But should you be asking people to implement something that is broken? Especially without telling them that it's going to be broken.
I also suspect that telling
self
apart from other args could be really broken or puzzle-like if not specified how that should behave. I expect I can do it but by using introspection in ways that really makes me question what the kata's intention is when it isn't mentioned at all what should be done. Again withfunctools
as an example - it uses a separatesingledispatchmethod
for that case. It doesn't help that the example methods behave like static methods (ignoring self) and therefore do not show how they should behave with regard toself
. And I never want to see a method that ignores self, such methods should me marked static there's no excuse!In particular, how do I tell apart a static method that accepts a class instance as first argument from a method that binds to a class instance? I expect to be able to tell the difference, but it's real awkward.
Hi,
So far, so good, but you need to put more things into the sample tests. Right now, I'm failing on
Returns correct values
andCan be used in lambdas
and I'll be forced to poke in the dark to get what the problem is because I don't know the definitions/context used.well, I changed the approach, now I pass all fixed tests, but don't pass any of the random ones... :/
ok, that's not pleasant anymore... :/
I'm at my fourth variation and I still got failures, but not always at the same places. It seems to me you're approach might actually be overriding some functions in some specific cases and that it's not described. Does it?
I tried to make the descriptions for the tests a bit better, and I am about to go add a few more tests to the samples.
As for the random ones, are you still having trouble passing them? I had an bug earlier where a function might (unluckily) be overwritten by another with the same 'type signature' of arguments, but that seems to be now fixed as my solution passes consistently (unless I am just very lucky)
Would if help if I would reveal the functions being tested for the random test each time?
I added a few more tests, and provided a bit more information back from the random tests. I don't think I am overriding any functions in specific cases, but let me know if the problem persists.
Sometimes tests randomly fail, probably due to collisions in the input types.
This was definitely an error I had earlier, which I think I have fixed (My solution passes consistently 10+ times, until I got a
Too many requests
from the server).There're still failues once every couple thousand of tests. It seems the source of the problem is the classes.
Edit:
while params == [] or params in inputs
- guess what this line does when you generate new instances ofC_A
,C_B
,C_C
in a loop, and none of them have__eq__
overriden.Yes I just found that, thanks for the help. My solution now passes more than 15000 tests in a row.
https://www.codewars.com/kata/5f24315eff32c4002efcfc6a ?
yeah, sounds like a somewhat duplicate, doesn't it?
(maybe not, let's see...)
IMHO they are different enough (metaclesses/decorators, only methods/all functions, ...).
yep :+1:
That kata only differentiates between the number of arguments, not the types.
Tests should use
it
blocks.They should be all using it now. If you think I need to split them up even more, let me know.
The first batch of the sample tests is still not enclosed in an
it
block.Sorry I keep forgetting to look at the sample tests. Fixed now.
Sample tests are broken.
Oops. Fixed now.
Use
test.expect_error
to check exceptions: https://github.com/Codewars/codewars.com/wiki/Codewars-Python-Test-Framework-V2#error-testThanks for the suggestion, I changed it.
Please let me know any tests I have forgotten, and any issues of course. I am also very uncertain about the difficulty level so please tell me what you think about it.