Reputation: 41
Write a Boolean function between that takes two
MyTime
objects,t1
andt2
, as arguments, and returns True if the invoking object falls between the two times. Assumet1 <= t2
, and make the test closed at the lower bound and open at the upper bound, i.e. return True ift1 <= obj < t2
.
Now from the wording of this question, it seems like there should only be two arguments in the function, but I cannot see a way to make such a function by only using two arguments. I mean I guess you could make another function that creates a variable that is a MyTime
object, but I was only going to keep it to one function and not make two. The wording of the question makes it seem like you should have Object(Function(t1,t2))
but I dont think that is possible. Is it possible to make the 'between' function with only two arguments? Here is my code
class MyTime:
""" Create some time """
def __init__(self,hrs = 0,mins = 0,sec = 0):
"""Splits up whole time into only seconds"""
totalsecs = hrs*3600 + mins*60 + sec
self.hours = totalsecs // 3600
leftoversecs = totalsecs % 3600
self.minutes = leftoversecs // 60
self.seconds = leftoversecs % 60
def __str__(self):
return '{0}:{1}:
{2}'.format(self.hours,self.minutes,self.seconds)
def to_seconds(self):
# converts to only seconds
return (self.hours * 3600) + (self.minutes * 60) + self.seconds
def between(t1,t2,x):
t1seconds = t1.to_seconds()
t2seconds = t2.to_seconds()
xseconds = x.to_seconds()
if t1seconds <= xseconds < t2seconds:
return True
return False
currentTime = MyTime(0,0,0)
doneTime = MyTime(10,3,4)
x = MyTime(2,0,0)
print(between(currentTime,doneTime,x))
Upvotes: 2
Views: 428
Reputation: 1388
You are 100% correct, it does need three parameters. If you write it as a member function of the MyTime
class, it gets a third parameter, self
:
class MyTime():
# the guts of the class ...
def between(self, t1, t2):
t1seconds = t1.to_seconds()
t2seconds = t2.to_seconds()
myseconds = self.to_seconds()
return t1seconds <= myseconds < t2seconds
You can use this method with:
currentTime = MyTime(0, 0, 0)
doneTime = MyTime(10, 3, 4)
x = MyTime(2, 0, 0)
x.between(currentTime, doneTime)
The self
argument is passed in automatically by calling the method on an instance of the class.
Upvotes: 5
Reputation: 365953
The problem seems to be written as a trick question—or maybe just accidentally so. So, let's get some terminology straight, so we can really understand what it's asking for.
The variable names in a function definition are parameters.
The expressions inside the parentheses of a function call are arguments.
Of course in the simplest case, each parameter gets bound to exactly one argument, but that isn't true in cases involving, e.g., *args
or **kw
(on either side), or default values, or method calls.
So, between
obviously needs three parameters—but that doesn't mean it needs three arguments, if you can find some other reasonable way to specify the value for one of those parameters.
And, while the way the problem is worded disguises the most obvious answer, it's still the most obvious answer: what you want here is a method, defined inside the class MyTime:
definition, exactly as described in illiteratecoder's answer (which I'll copy here):
def between(self, t1, t2):
t1seconds = t1.to_seconds()
t2seconds = t2.to_seconds()
myseconds = self.to_seconds()
return t1seconds <= myseconds < t2seconds
Of course if you really want to, you can call this with three arguments:
MyTime.between(x, currentTime, doneTime)
But normally, you won't call the function directly, you'll call it as a bound method:
x.between(currentTime, doneTime)
Of course, as the glossary entry for methods implies, under the covers, this method call with two arguments gets turned into a function call with three arguments, by some code inside the guts of types.MethodType
. But there's no three-argument call in your code, or anywhere else.
Apparently, x
(or obj
, in the original statement) is what the problem meant by the phrase "invoking object", even though that's a very weird use of terminology.1
If you're curious, the code (or, rather, the Python equivalent of the C code) that does that looks like this:
def __call__(self, *args, **kw):
return self.__func__(self.__self__, *args, **kw)
… where self.__func__
is MyTime.between
and self.self
is x
.
1. I've never heard "invoking object" used in Python. It is used in Smalltalk and related languages, but it means the self
in scope at the lexical location of the message send (method call), which is meaningless here, and generally meaningless in Python (unlike, e.g., JavaScript). The equivalent of the x
in x.between
is definitely not the invoking object, it's the receiving object. So, if this is a trick question, I think they overstepped the bounds between misleading but still technically accurate and just plain wrong, which is cheating. But if, on the other hand, your teacher or book or whatever has been consistently using this idiosyncratic terminology, then it's not really wrong, just a little weird, and you probably need to go back and study some notes to make sure you understand their terminology, at least while trying to get through this course.
Upvotes: 1