Moment, I do not know if I understand you right.
so I would use the given method and use on the instance another function that takes care of the converting to or a valid time object or for example convert it to minutes and on display take care that a valid time is shown.
Do I understand you right ?
I send this personal because I cannot send to the mailing list according to some spam list
I don't think you do, but it's a little difficult to determine.
Time hours: 0 minutes: 70 should throw an out of range exception on the second argument.
Time fromMinutes: 70 "should" answer an instance equivalent to 01:00. (I say should in quotes, because Time is a point in time. Duration is something that makes more sense to have Duration minutes: 70 be acceptable.)
This discussion assumes your model of time uses just hours and minutes. Normally, Time includes seconds, and often fractions of seconds. But, you are working on an exercise, so a reduced scope Time may be appropriate.
Rather than talking about Time class>>#fromMinutes:, let's go a little more extreme and discuss a hypothetical Time class>>#fromHours: method. We understand and agree that Time can represent hours from 0 through 23. There is no 24 o'clock. So, if you wrote Time fromHours: 25, what would you expect to get for a result? What would someone who comes along later and uses your code expect to get? It's not well defined. So extrapolate from that case to the other cases. 70 minutes is not a time. "I'll meet you at 70 minutes" said no one ever. :-) ["in 70 minutes" is a duration from the present moment, implying a time 70 minutes in the future.]
I have come across a lot of code in my life. The hardest code to work with and to enhance is code that says it will try to accept whatever it's given. If it wants a number, it will accept a string of digits and "figure out" what number was meant. Life is so much easier when the author says "That's rubbish. Give me a proper number." or "That's too big. Give me a proper number of hours.", etc.
In general, make your APIs precise and predictable. Range check the passed values and complain when they aren't proper. If the clock you are modelling has a precision of minutes, your API is #hours:minutes: and maybe just #hours: for convenience. (In general, I wouldn't do so.) And it's reasonable to have methods to answer the number of increments from the start of the day of your clock's precision and to create a new instance from that number. So, with a precision of minutes, you can have an instance method named e.g. #asMinutes or perhaps #totalMinutes or even #minutesSinceMidnight, and to have a corresponding class method #fromMinutes: or #minutesFromMidnight: which answers the corresponding instance of Time. If your clock has a precision of seconds, which is more normal for us, those "minutes" methods would actually be similarly named "seconds" methods instead. (If your clock has a precision finer than seconds, I would expect to see corresponding methods for the finer gradations of time that would be common, in addition to the various "seconds" methods. e.g. milliseconds or microseconds since midnight. And likely both if the clock resolution was microseconds, just because we do tend to think of milliseconds or microseconds when we talk of more precise times.)
Just as the advice I gave you some months ago was to be unambiguous and precise when naming things, be unambiguous and precise about your APIs (all your methods, really!). People who end up using your code will thank you.
Op 1-9-2020 om 00:22 schreef Richard Sargent:
Sorry to be throwing ideas but it is not better to keep everything in for examples minutes . So when I add minutes or substract minutes there does not have to make a new clock all the time.
I could then make the converting from minutes to hours and minitues when I want to display it.
So I have more flexiblility when for example the output format needs to be changed.
I recommend against modifying time instances once created. Likewise for dates and timestamps.You don't know if the time instance has been shared with another object. It's best to treat them as immutable once created.
Do not make the mistake of trying to avoid creating new objects. It will lead to contorted code and all sorts of complications. (Of course, be careful not to create a bazillion objects unnecessarily!)
The same advice applies to creating classes. Some languages have a high cost to define a new class, usually psychological. This leaves their programmers "allergic" (or acting as if they were) to creating a new class that would make a solution better. In Smalltalk, a class is just an object.
In terms of how to model time, you could have the time object just store the count of intervals since the start of the day. But, if you want Times with microsecond resolution or nanosecond resolution, you would always be working with a LargeInteger internally.
VA Smalltalk Time has ('hours' 'minutes' 'seconds' 'milliseconds' 'millisecondsFromMidnight')
VisualWorks Time has ('hours' 'minutes' 'seconds' 'milliseconds' 'partialNanosecond')
Pharo (5.0) Time has ('seconds' 'nanos')
It can be useful to trade space efficiency for comprehensibility. Often, focussing on space efficiency results in convoluted code for little other benefit. It's a good idea to start by modelling the concepts that we discuss when describing something. My cookoo clock has an hour hand and a minute hand. It has no concept of seconds, per se. It has a time tick, but whether that is exactly one second, I don't know. Probably not. The pendulum doesn't move that fast. So, if modelling a cookoo clock, modelling the hours and minutes it shows is a reasonable design.
In some respects, modelling your Time as a number of minutes into the day would simplify normalizing the arguments to the instance creation methods. Just compute the requested number of minutes, perform the modulus to limit the size of a day, and you are done. In the absence of a constraint imposed by the author of the problem, you are free to implement a solution that presents the expected results.
On Mon, Aug 31, 2020 at 10:12 PM Roelof Wobben <[hidden email]> wrote:
oke, then I would work with hour and minutes as the challenge wanted,
On some way I think or I do something wrong or I did misunderstood you.
I did this in Pharo
Object subclass: #Clock
instanceVariableNames: 'hour minute'
I made a asscesors on the instance side.
then I did this on the class side :
hour: anInteger minute: anInteger2
self hour: anInteger2 % 60 + anInteger;
self minute: anInteger2 / 60;
but I see a message that hour and minutes are not known.
What is the value of self when the error occurred? The debugger should show you this.
Another way to determine this is to look at the code and think about where the sending method is implemented and where the invoked method is implemented (assuming that there really is one).
On Tue, Sep 1, 2020 at 10:11 AM Roelof Wobben <[hidden email]> wrote:
Op 1-9-2020 om 19:21 schreef Richard Sargent:
self is a Clock
"self is a Clock" is an imprecise statement. Did you mean that it is an instance of the Clock class or that it is the Clock class itself?
On Tue, Sep 1, 2020 at 10:33 AM Roelof Wobben <[hidden email]> wrote:
Op 1-9-2020 om 21:11 schreef Richard Sargent:
> You will discover an error when you write your tests, but that's fine.
> It's why you write tests. :-)
> #validateTime:minute: is a poor name choice for a few reasons.
> - there is no validation going on. Validation would report an error
> for invalid data.
> - there is nothing to suggest what the first argument is, the
> counterpart to "minute:".
> - it doesn't suggest there will be a new Time ("Clock") created.
> - it's a "verb phrase" saying it will *do* something rather than
> answer something (I'm being vague here. Sorry.)
> I suggest #normalizedForHour:minute:.
> It explains that it will normalize the values and that it will answer
> a normalized result (it still isn't great, as it doesn't explain what).
> Perhaps better would be #newNormalizedForHour:minute:.
I think I found the error
and solved it
hour: anInteger minute: anInteger2
^ self new
hour: (anInteger2 // 60 + anInteger) % 24;
minute: anInteger2 % 60;
instance side :
nextPutAll: self hour asTwoCharacterString;
nextPutAll: self minute asTwoCharacterString
and the tests are green
now time to sleep and tomorrow time to figure out how to add and
As I remember it right you gave already the answer to me somewhere in
Op 1-9-2020 om 21:40 schreef Roelof Wobben:
Op 1-9-2020 om 21:11 schreef Richard Sargent:
Making it a class method makes things very difficult
In reply to this post by Pharo Smalltalk Users mailing list
Richard Sargent is giving good advice that you cannot use in Exercism.
Your code MUST pass the exercism tests and that means it MUST NOT
limit the hour or minute ranges.
On Tue, 1 Sep 2020 at 08:58, Roelof Wobben via Pharo-users <[hidden email]> wrote:
|Free forum by Nabble||Edit this page|