how to model this a better way

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
28 messages Options
12
Reply | Threaded
Open this post in threaded view
|

how to model this a better way

Roelof Wobben
Hello,

I know I have asked earlier but im still stuck on this one : https://github.com/exercism/problem-specifications/blob/master/exercises/robot-simulator/description.md

I tried with all double dispatch but that will be a lot of duplicate classes

The problem I cannot solve right is that a robot can move or turn. when a robot turns only the direction the robot is facing changes and the position not. when a robot moves the facing direction stays the same but the position changes. but the change is dependend on the facing. Also the new facing direction is dependend on the old facing direction/
How can I model this the best.

I already have a object Robot that contains the facing direction and the current position
or tried without it but then I use a lot of if then's


so it  there  a better way to model this problem so it will be all nice and readable code.

Roelof

Reply | Threaded
Open this post in threaded view
|

Re: how to model this a better way

Richard Sargent
Administrator
On Thu, Apr 18, 2019 at 8:57 AM Roelof Wobben <[hidden email]> wrote:
Hello,

I know I have asked earlier but im still stuck on this one : https://github.com/exercism/problem-specifications/blob/master/exercises/robot-simulator/description.md

I tried with all double dispatch but that will be a lot of duplicate classes

The problem I cannot solve right is that a robot can move or turn. when a robot turns only the direction the robot is facing changes and the position not. when a robot moves the facing direction stays the same but the position changes. but the change is dependend on the facing. Also the new facing direction is dependend on the old facing direction/
How can I model this the best.

I already have a object Robot that contains the facing direction and the current position
or tried without it but then I use a lot of if then's


so it  there  a better way to model this problem so it will be all nice and readable code.

If I remember correctly, Richard O'Keefe gave you a viable design. 1) Use a Point for your direction vector. 2) Use a second Point for your position.

e.g. if you align the compass with a Cartesian plane, 0@1 is North, 0@-1 is South, 1@0 is East, and -1@0 is West. When you move, you add the direction vector to your current position. If you allow movements of greater than a single unit, you multiply the direction vector by the distance before adding that product to the position.


Roelof

Reply | Threaded
Open this post in threaded view
|

Re: how to model this a better way

Roelof Wobben
yep, I have read that one
but I never gets a answer how I can "convert"  a point to something like north, east

because the challenge wants this to be the answer :

(Dictionary new
                add: 'direction' -> 'north';
                add:
                    'position'
                        ->
                            (Dictionary new
                                add: 'x' -> 0;
                                add: 'y' -> 0;
                                yourself);
                yourself)


and I think I need then to use if then , which I try to avoid as much as possible.

Roelof



Op 18-4-2019 om 18:33 schreef Richard Sargent:
On Thu, Apr 18, 2019 at 8:57 AM Roelof Wobben <[hidden email]> wrote:
Hello,

I know I have asked earlier but im still stuck on this one : https://github.com/exercism/problem-specifications/blob/master/exercises/robot-simulator/description.md

I tried with all double dispatch but that will be a lot of duplicate classes

The problem I cannot solve right is that a robot can move or turn. when a robot turns only the direction the robot is facing changes and the position not. when a robot moves the facing direction stays the same but the position changes. but the change is dependend on the facing. Also the new facing direction is dependend on the old facing direction/
How can I model this the best.

I already have a object Robot that contains the facing direction and the current position
or tried without it but then I use a lot of if then's


so it  there  a better way to model this problem so it will be all nice and readable code.

If I remember correctly, Richard O'Keefe gave you a viable design. 1) Use a Point for your direction vector. 2) Use a second Point for your position.

e.g. if you align the compass with a Cartesian plane, 0@1 is North, 0@-1 is South, 1@0 is East, and -1@0 is West. When you move, you add the direction vector to your current position. If you allow movements of greater than a single unit, you multiply the direction vector by the distance before adding that product to the position.


Roelof


Reply | Threaded
Open this post in threaded view
|

Re: how to model this a better way

Richard Sargent
Administrator
On Thu, Apr 18, 2019 at 10:01 AM Roelof Wobben <[hidden email]> wrote:
yep, I have read that one
but I never gets a answer how I can "convert"  a point to something like north, east

because the challenge wants this to be the answer :

(Dictionary new
                add: 'direction' -> 'north';
                add:
                    'position'
                        ->
                            (Dictionary new
                                add: 'x' -> 0;
                                add: 'y' -> 0;
                                yourself);
                yourself)

If you have previously defined a "representation map", you would be golden.

e.g.
Dictionary new
at: self northDirectionVector put: 'north';
at: self eastDirectionVector put: 'east';
at: self southDirectionVector put: 'south';
at: self westDirectionVector put: 'west';
yourself.

Then:
(Dictionary new
                add: 'direction' -> (self directionRepresentationMap at: self directionVector);
...



and I think I need then to use if then , which I try to avoid as much as possible.

Roelof



Op 18-4-2019 om 18:33 schreef Richard Sargent:
On Thu, Apr 18, 2019 at 8:57 AM Roelof Wobben <[hidden email]> wrote:
Hello,

I know I have asked earlier but im still stuck on this one : https://github.com/exercism/problem-specifications/blob/master/exercises/robot-simulator/description.md

I tried with all double dispatch but that will be a lot of duplicate classes

The problem I cannot solve right is that a robot can move or turn. when a robot turns only the direction the robot is facing changes and the position not. when a robot moves the facing direction stays the same but the position changes. but the change is dependend on the facing. Also the new facing direction is dependend on the old facing direction/
How can I model this the best.

I already have a object Robot that contains the facing direction and the current position
or tried without it but then I use a lot of if then's


so it  there  a better way to model this problem so it will be all nice and readable code.

If I remember correctly, Richard O'Keefe gave you a viable design. 1) Use a Point for your direction vector. 2) Use a second Point for your position.

e.g. if you align the compass with a Cartesian plane, 0@1 is North, 0@-1 is South, 1@0 is East, and -1@0 is West. When you move, you add the direction vector to your current position. If you allow movements of greater than a single unit, you multiply the direction vector by the distance before adding that product to the position.


Roelof


Reply | Threaded
Open this post in threaded view
|

Re: how to model this a better way

Ben Coman
In reply to this post by Roelof Wobben
>> e.g. if you align the compass with a Cartesian plane, 0@1 is North, 0@-1 is South, 1@0 is East, and -1@0 is West.

On Fri, 19 Apr 2019 at 01:01, Roelof Wobben <[hidden email]> wrote:
>
> yep, I have read that one
> but I never gets a answer how I can "convert"  a point to something like north, east

Maybe you are looking for something like this...
    map := Dictionary newFromPairs: {
        'north'.  0 @  1 .
        'south'.  0 @ -1 .
        'east'.   1 @  0 .
        'west' . -1 @  0 }.
    (map at: 'north') inspect.
    (map keyAtValue: 0 @ -1) inspect.

cheers -ben

>
> because the challenge wants this to be the answer :
>
> (Dictionary new
>                 add: 'direction' -> 'north';
>                 add:
>                     'position'
>                         ->
>                             (Dictionary new
>                                 add: 'x' -> 0;
>                                 add: 'y' -> 0;
>                                 yourself);
>                 yourself)
>
>
> and I think I need then to use if then , which I try to avoid as much as possible.
>
> Roelof
>
>
>
> Op 18-4-2019 om 18:33 schreef Richard Sargent:
>
> On Thu, Apr 18, 2019 at 8:57 AM Roelof Wobben <[hidden email]> wrote:
>>
>> Hello,
>>
>> I know I have asked earlier but im still stuck on this one : https://github.com/exercism/problem-specifications/blob/master/exercises/robot-simulator/description.md
>>
>> I tried with all double dispatch but that will be a lot of duplicate classes
>>
>> The problem I cannot solve right is that a robot can move or turn. when a robot turns only the direction the robot is facing changes and the position not. when a robot moves the facing direction stays the same but the position changes. but the change is dependend on the facing. Also the new facing direction is dependend on the old facing direction/
>> How can I model this the best.
>>
>> I already have a object Robot that contains the facing direction and the current position
>> or tried without it but then I use a lot of if then's
>>
>>
>> so it  there  a better way to model this problem so it will be all nice and readable code.
>
>
> If I remember correctly, Richard O'Keefe gave you a viable design. 1) Use a Point for your direction vector. 2) Use a second Point for your position.
>
> e.g. if you align the compass with a Cartesian plane, 0@1 is North, 0@-1 is South, 1@0 is East, and -1@0 is West. When you move, you add the direction vector to your current position. If you allow movements of greater than a single unit, you multiply the direction vector by the distance before adding that product to the position.
>
>>
>> Roelof
>>
>

Reply | Threaded
Open this post in threaded view
|

Re: how to model this a better way

Roelof Wobben
In reply to this post by Richard Sargent
oke

Maybe I understand something not right,

Lets say we have this scenario.

Robot is on position (0,0)
now it turns left so the robot faces East

or this scenario

Robot is on position (0,0)
now it turns right so the robot faces west.

it looks that dictionary cannot provide this answer.
or do I overlook something

Roelof



Op 18-4-2019 om 19:17 schreef Richard Sargent:
On Thu, Apr 18, 2019 at 10:01 AM Roelof Wobben <[hidden email]> wrote:
yep, I have read that one
but I never gets a answer how I can "convert"  a point to something like north, east

because the challenge wants this to be the answer :

(Dictionary new
                add: 'direction' -> 'north';
                add:
                    'position'
                        ->
                            (Dictionary new
                                add: 'x' -> 0;
                                add: 'y' -> 0;
                                yourself);
                yourself)

If you have previously defined a "representation map", you would be golden.

e.g.
Dictionary new
at: self northDirectionVector put: 'north';
at: self eastDirectionVector put: 'east';
at: self southDirectionVector put: 'south';
at: self westDirectionVector put: 'west';
yourself.

Then:
(Dictionary new
                add: 'direction' -> (self directionRepresentationMap at: self directionVector);
...



and I think I need then to use if then , which I try to avoid as much as possible.

Roelof



Op 18-4-2019 om 18:33 schreef Richard Sargent:
On Thu, Apr 18, 2019 at 8:57 AM Roelof Wobben <[hidden email]> wrote:
Hello,

I know I have asked earlier but im still stuck on this one : https://github.com/exercism/problem-specifications/blob/master/exercises/robot-simulator/description.md

I tried with all double dispatch but that will be a lot of duplicate classes

The problem I cannot solve right is that a robot can move or turn. when a robot turns only the direction the robot is facing changes and the position not. when a robot moves the facing direction stays the same but the position changes. but the change is dependend on the facing. Also the new facing direction is dependend on the old facing direction/
How can I model this the best.

I already have a object Robot that contains the facing direction and the current position
or tried without it but then I use a lot of if then's


so it  there  a better way to model this problem so it will be all nice and readable code.

If I remember correctly, Richard O'Keefe gave you a viable design. 1) Use a Point for your direction vector. 2) Use a second Point for your position.

e.g. if you align the compass with a Cartesian plane, 0@1 is North, 0@-1 is South, 1@0 is East, and -1@0 is West. When you move, you add the direction vector to your current position. If you allow movements of greater than a single unit, you multiply the direction vector by the distance before adding that product to the position.


Roelof



Reply | Threaded
Open this post in threaded view
|

Re: how to model this a better way

Roelof Wobben
In reply to this post by Ben Coman
Ben,

I have such a dictionary in my first attempt to solve this one.
and another one for the facing.


Lets say we have this scenario:

Robot begins at (0,0) facing north
then it turns right so it faces west
then it moves one step so the new position is (-1,0)
then it turns left so it faces north again
then it moves one step so the  new position is (-1,1)

so if I see it , the position has nothing to do with the direction the
robot is facing
this is only important for finding out a new direction or  to find out
if the x or the y needs to change.

Roelof



Op 18-4-2019 om 19:27 schreef Ben Coman:
> map := Dictionary newFromPairs: {
>          'north'.  0 @  1 .
>          'south'.  0 @ -1 .
>          'east'.   1 @  0 .
>          'west' . -1 @  0 }.
>      (map at: 'north') inspect.
>      (map keyAtValue: 0 @ -1) inspect



Reply | Threaded
Open this post in threaded view
|

Re: how to model this a better way

Richard Sargent
Administrator
In reply to this post by Roelof Wobben
On Thu, Apr 18, 2019 at 10:33 AM Roelof Wobben <[hidden email]> wrote:
oke

Maybe I understand something not right,

Lets say we have this scenario.

Robot is on position (0,0)
now it turns left so the robot faces East

I don't understand what position has to do with direction nor why that would be a problem. They are two distinct attributes.
Point and Dictionary are sufficient classes to model the limited requirements of this exercise.
You could model a new class DirectionVector which internalizes the Point used to provide the direction and provides its own name, eliminating the need for a look up of any kind.


or this scenario

Robot is on position (0,0)
now it turns right so the robot faces west.

it looks that dictionary cannot provide this answer.
or do I overlook something

Roelof



Op 18-4-2019 om 19:17 schreef Richard Sargent:
On Thu, Apr 18, 2019 at 10:01 AM Roelof Wobben <[hidden email]> wrote:
yep, I have read that one
but I never gets a answer how I can "convert"  a point to something like north, east

because the challenge wants this to be the answer :

(Dictionary new
                add: 'direction' -> 'north';
                add:
                    'position'
                        ->
                            (Dictionary new
                                add: 'x' -> 0;
                                add: 'y' -> 0;
                                yourself);
                yourself)

If you have previously defined a "representation map", you would be golden.

e.g.
Dictionary new
at: self northDirectionVector put: 'north';
at: self eastDirectionVector put: 'east';
at: self southDirectionVector put: 'south';
at: self westDirectionVector put: 'west';
yourself.

Then:
(Dictionary new
                add: 'direction' -> (self directionRepresentationMap at: self directionVector);
...



and I think I need then to use if then , which I try to avoid as much as possible.

Roelof



Op 18-4-2019 om 18:33 schreef Richard Sargent:
On Thu, Apr 18, 2019 at 8:57 AM Roelof Wobben <[hidden email]> wrote:
Hello,

I know I have asked earlier but im still stuck on this one : https://github.com/exercism/problem-specifications/blob/master/exercises/robot-simulator/description.md

I tried with all double dispatch but that will be a lot of duplicate classes

The problem I cannot solve right is that a robot can move or turn. when a robot turns only the direction the robot is facing changes and the position not. when a robot moves the facing direction stays the same but the position changes. but the change is dependend on the facing. Also the new facing direction is dependend on the old facing direction/
How can I model this the best.

I already have a object Robot that contains the facing direction and the current position
or tried without it but then I use a lot of if then's


so it  there  a better way to model this problem so it will be all nice and readable code.

If I remember correctly, Richard O'Keefe gave you a viable design. 1) Use a Point for your direction vector. 2) Use a second Point for your position.

e.g. if you align the compass with a Cartesian plane, 0@1 is North, 0@-1 is South, 1@0 is East, and -1@0 is West. When you move, you add the direction vector to your current position. If you allow movements of greater than a single unit, you multiply the direction vector by the distance before adding that product to the position.


Roelof



Reply | Threaded
Open this post in threaded view
|

Re: how to model this a better way

Roelof Wobben
oke, and how must I see those classes and elemating the need for a lookup.

it may be explained in pseudo-code.

Roelof



Op 18-4-2019 om 20:28 schreef Richard Sargent:
On Thu, Apr 18, 2019 at 10:33 AM Roelof Wobben <[hidden email]> wrote:
oke

Maybe I understand something not right,

Lets say we have this scenario.

Robot is on position (0,0)
now it turns left so the robot faces East

I don't understand what position has to do with direction nor why that would be a problem. They are two distinct attributes.
Point and Dictionary are sufficient classes to model the limited requirements of this exercise.
You could model a new class DirectionVector which internalizes the Point used to provide the direction and provides its own name, eliminating the need for a look up of any kind.


or this scenario

Robot is on position (0,0)
now it turns right so the robot faces west.

it looks that dictionary cannot provide this answer.
or do I overlook something

Roelof



Op 18-4-2019 om 19:17 schreef Richard Sargent:
On Thu, Apr 18, 2019 at 10:01 AM Roelof Wobben <[hidden email]> wrote:
yep, I have read that one
but I never gets a answer how I can "convert"  a point to something like north, east

because the challenge wants this to be the answer :

(Dictionary new
                add: 'direction' -> 'north';
                add:
                    'position'
                        ->
                            (Dictionary new
                                add: 'x' -> 0;
                                add: 'y' -> 0;
                                yourself);
                yourself)

If you have previously defined a "representation map", you would be golden.

e.g.
Dictionary new
at: self northDirectionVector put: 'north';
at: self eastDirectionVector put: 'east';
at: self southDirectionVector put: 'south';
at: self westDirectionVector put: 'west';
yourself.

Then:
(Dictionary new
                add: 'direction' -> (self directionRepresentationMap at: self directionVector);
...



and I think I need then to use if then , which I try to avoid as much as possible.

Roelof



Op 18-4-2019 om 18:33 schreef Richard Sargent:
On Thu, Apr 18, 2019 at 8:57 AM Roelof Wobben <[hidden email]> wrote:
Hello,

I know I have asked earlier but im still stuck on this one : https://github.com/exercism/problem-specifications/blob/master/exercises/robot-simulator/description.md

I tried with all double dispatch but that will be a lot of duplicate classes

The problem I cannot solve right is that a robot can move or turn. when a robot turns only the direction the robot is facing changes and the position not. when a robot moves the facing direction stays the same but the position changes. but the change is dependend on the facing. Also the new facing direction is dependend on the old facing direction/
How can I model this the best.

I already have a object Robot that contains the facing direction and the current position
or tried without it but then I use a lot of if then's


so it  there  a better way to model this problem so it will be all nice and readable code.

If I remember correctly, Richard O'Keefe gave you a viable design. 1) Use a Point for your direction vector. 2) Use a second Point for your position.

e.g. if you align the compass with a Cartesian plane, 0@1 is North, 0@-1 is South, 1@0 is East, and -1@0 is West. When you move, you add the direction vector to your current position. If you allow movements of greater than a single unit, you multiply the direction vector by the distance before adding that product to the position.


Roelof




Reply | Threaded
Open this post in threaded view
|

Re: how to model this a better way

Richard Sargent
Administrator
Your system would have instance variables holding the cardinal directions and another holding the current direction vector.
e.g.
north := DirectionVector x: 0 y: 1 name: 'north'.

Your robot would implement e.g. #faceNorth to assign the "north" direction vector to the current direction vector instance variable.



On Thu, Apr 18, 2019 at 12:17 PM Roelof Wobben <[hidden email]> wrote:
oke, and how must I see those classes and elemating the need for a lookup.

it may be explained in pseudo-code.

Roelof



Op 18-4-2019 om 20:28 schreef Richard Sargent:
On Thu, Apr 18, 2019 at 10:33 AM Roelof Wobben <[hidden email]> wrote:
oke

Maybe I understand something not right,

Lets say we have this scenario.

Robot is on position (0,0)
now it turns left so the robot faces East

I don't understand what position has to do with direction nor why that would be a problem. They are two distinct attributes.
Point and Dictionary are sufficient classes to model the limited requirements of this exercise.
You could model a new class DirectionVector which internalizes the Point used to provide the direction and provides its own name, eliminating the need for a look up of any kind.


or this scenario

Robot is on position (0,0)
now it turns right so the robot faces west.

it looks that dictionary cannot provide this answer.
or do I overlook something

Roelof



Op 18-4-2019 om 19:17 schreef Richard Sargent:
On Thu, Apr 18, 2019 at 10:01 AM Roelof Wobben <[hidden email]> wrote:
yep, I have read that one
but I never gets a answer how I can "convert"  a point to something like north, east

because the challenge wants this to be the answer :

(Dictionary new
                add: 'direction' -> 'north';
                add:
                    'position'
                        ->
                            (Dictionary new
                                add: 'x' -> 0;
                                add: 'y' -> 0;
                                yourself);
                yourself)

If you have previously defined a "representation map", you would be golden.

e.g.
Dictionary new
at: self northDirectionVector put: 'north';
at: self eastDirectionVector put: 'east';
at: self southDirectionVector put: 'south';
at: self westDirectionVector put: 'west';
yourself.

Then:
(Dictionary new
                add: 'direction' -> (self directionRepresentationMap at: self directionVector);
...



and I think I need then to use if then , which I try to avoid as much as possible.

Roelof



Op 18-4-2019 om 18:33 schreef Richard Sargent:
On Thu, Apr 18, 2019 at 8:57 AM Roelof Wobben <[hidden email]> wrote:
Hello,

I know I have asked earlier but im still stuck on this one : https://github.com/exercism/problem-specifications/blob/master/exercises/robot-simulator/description.md

I tried with all double dispatch but that will be a lot of duplicate classes

The problem I cannot solve right is that a robot can move or turn. when a robot turns only the direction the robot is facing changes and the position not. when a robot moves the facing direction stays the same but the position changes. but the change is dependend on the facing. Also the new facing direction is dependend on the old facing direction/
How can I model this the best.

I already have a object Robot that contains the facing direction and the current position
or tried without it but then I use a lot of if then's


so it  there  a better way to model this problem so it will be all nice and readable code.

If I remember correctly, Richard O'Keefe gave you a viable design. 1) Use a Point for your direction vector. 2) Use a second Point for your position.

e.g. if you align the compass with a Cartesian plane, 0@1 is North, 0@-1 is South, 1@0 is East, and -1@0 is West. When you move, you add the direction vector to your current position. If you allow movements of greater than a single unit, you multiply the direction vector by the distance before adding that product to the position.


Roelof




Reply | Threaded
Open this post in threaded view
|

Re: how to model this a better way

Tim Mackinnon
You quickly find it’s a more interesting exercise than just a “point and dictionary”, particularly if you want to do it in an elegant Smalltalk way (but not over do it either).

The interesting bit is that when facing a new direction, you need to know how to advance in that direction , and also what “left” and “right” of that direction are too. So it teases out having some objects and techniques for this.

For those interested - join exercism-Pharo (https://exercism.io/tracks/pharo-smalltalk/installation) in non mentor mode and you can easily download it with the tests and try it out yourself (without running through the other exercises).

Tim

Sent from my iPhone

On 18 Apr 2019, at 21:41, Richard Sargent <[hidden email]> wrote:

Your system would have instance variables holding the cardinal directions and another holding the current direction vector.
e.g.
north := DirectionVector x: 0 y: 1 name: 'north'.

Your robot would implement e.g. #faceNorth to assign the "north" direction vector to the current direction vector instance variable.



On Thu, Apr 18, 2019 at 12:17 PM Roelof Wobben <[hidden email]> wrote:
oke, and how must I see those classes and elemating the need for a lookup.

it may be explained in pseudo-code.

Roelof



Op 18-4-2019 om 20:28 schreef Richard Sargent:
On Thu, Apr 18, 2019 at 10:33 AM Roelof Wobben <[hidden email]> wrote:
oke

Maybe I understand something not right,

Lets say we have this scenario.

Robot is on position (0,0)
now it turns left so the robot faces East

I don't understand what position has to do with direction nor why that would be a problem. They are two distinct attributes.
Point and Dictionary are sufficient classes to model the limited requirements of this exercise.
You could model a new class DirectionVector which internalizes the Point used to provide the direction and provides its own name, eliminating the need for a look up of any kind.


or this scenario

Robot is on position (0,0)
now it turns right so the robot faces west.

it looks that dictionary cannot provide this answer.
or do I overlook something

Roelof



Op 18-4-2019 om 19:17 schreef Richard Sargent:
On Thu, Apr 18, 2019 at 10:01 AM Roelof Wobben <[hidden email]> wrote:
yep, I have read that one
but I never gets a answer how I can "convert"  a point to something like north, east

because the challenge wants this to be the answer :

(Dictionary new
                add: 'direction' -> 'north';
                add:
                    'position'
                        ->
                            (Dictionary new
                                add: 'x' -> 0;
                                add: 'y' -> 0;
                                yourself);
                yourself)

If you have previously defined a "representation map", you would be golden.

e.g.
Dictionary new
at: self northDirectionVector put: 'north';
at: self eastDirectionVector put: 'east';
at: self southDirectionVector put: 'south';
at: self westDirectionVector put: 'west';
yourself.

Then:
(Dictionary new
                add: 'direction' -> (self directionRepresentationMap at: self directionVector);
...



and I think I need then to use if then , which I try to avoid as much as possible.

Roelof



Op 18-4-2019 om 18:33 schreef Richard Sargent:
On Thu, Apr 18, 2019 at 8:57 AM Roelof Wobben <[hidden email]> wrote:
Hello,

I know I have asked earlier but im still stuck on this one : https://github.com/exercism/problem-specifications/blob/master/exercises/robot-simulator/description.md

I tried with all double dispatch but that will be a lot of duplicate classes

The problem I cannot solve right is that a robot can move or turn. when a robot turns only the direction the robot is facing changes and the position not. when a robot moves the facing direction stays the same but the position changes. but the change is dependend on the facing. Also the new facing direction is dependend on the old facing direction/
How can I model this the best.

I already have a object Robot that contains the facing direction and the current position
or tried without it but then I use a lot of if then's


so it  there  a better way to model this problem so it will be all nice and readable code.

If I remember correctly, Richard O'Keefe gave you a viable design. 1) Use a Point for your direction vector. 2) Use a second Point for your position.

e.g. if you align the compass with a Cartesian plane, 0@1 is North, 0@-1 is South, 1@0 is East, and -1@0 is West. When you move, you add the direction vector to your current position. If you allow movements of greater than a single unit, you multiply the direction vector by the distance before adding that product to the position.


Roelof




Reply | Threaded
Open this post in threaded view
|

Re: how to model this a better way

Ben Coman
In reply to this post by Roelof Wobben
On Fri, 19 Apr 2019 at 01:33, Roelof Wobben <[hidden email]> wrote:
>
> oke
>
> Maybe I understand something not right,
>
> Lets say we have this scenario.
>
> Robot is on position (0,0)
> now it turns left so the robot faces East

I think the required method was mentioned previously, but here is how
to discover it yourself...

+ Tool > Finder > Examples
+ Enter...    (0@1) . (1@0)     <Search>

finds...  Point>>leftRotated
e.g. (0@1) leftRotated   ==>   (1@0)

On Fri, 19 Apr 2019 at 01:39, Roelof Wobben <[hidden email]> wrote:
>
> Ben,
>
> I have such a dictionary in my first attempt to solve this one.
> and another one for the facing.

This sounds strange that you have two Dictionaries.
It can be useful to encapsulate the mapping to avoid that being
littered around your Robot code...

Object subclass: #Facing
    instanceVariables: 'map directionVector'

Facing >> initialize
    map := Dictionary newFromPairs: {
        'north'. (0@1) .
        'west' . (0@1) leftRotated .
        'south'. (0@1) leftRotated leftRotated.
        'east' . (0@1) rightRotated }.
   directionVector := map atRandom.

Facing >> directionString
     ^ map keyAtValue: directionVector

Facing >> printOn: aStream
    " Facing new inspect "
    aStream nextPutAll: self className, '-', self directionString

"The above is produces a minimum-viable object that displays nicely in Inspector
to facilitate incrementally coding your scenario in TDD way..."

> Lets say we have this scenario:

    TestCase subclass: FacingTest

    FacingTest>>testAllTogether
           |position facing|

           "Robot begins at (0,0) facing north"
           position := 0@0.
           facing := Facing new face: 'north'.
           self assert: facing printString equals: 'Facing-north'.

           "then it turns right so it faces >>EAST<<"
           facing turnRight.
           self assert: facing printString equals: 'Facing-east'.

            "then it moves one step so the new position is (-1,0)"
            position := position + (facing movementSteps: 1).
            self assert: position equals: (-1@0).

            "then it turns left so it faces north again"
           facing turnLeft.
           self assert: facing printString equals: 'Facing-north'.

            "then it moves one step so the new position is (-1,1)"
            position := position + (facing movementSteps: 1).
            self assert: position equals: (-1@1).


Which I'll leave as an exercise for you to complete with these hints...

    Facing >> face: aDirectionString
       directionVector := ...

    Facing >> turnRight
        directionVector := ...

    Facing >> turnLeft
        directionVector := ...

    Facing >> movementSteps: steps
        ^ ...


> so if I see it , the position has nothing to do with the direction the
> robot is facing

yes. they only interact when the robot moves


> this [position] is only important for finding out a new direction

no - position has no impact for determining the new direction


> or to find out if the x or the y needs to change.

You don't need to treat x and y separately.
Using Points for both the "position" and "directionVector" facilitates
simple addition.

cheers -ben


>
> Roelof
>
>
>
> Op 18-4-2019 om 19:17 schreef Richard Sargent:
>
> On Thu, Apr 18, 2019 at 10:01 AM Roelof Wobben <[hidden email]> wrote:
>>
>> yep, I have read that one
>> but I never gets a answer how I can "convert"  a point to something like north, east
>>
>> because the challenge wants this to be the answer :
>>
>> (Dictionary new
>>                 add: 'direction' -> 'north';
>>                 add:
>>                     'position'
>>                         ->
>>                             (Dictionary new
>>                                 add: 'x' -> 0;
>>                                 add: 'y' -> 0;
>>                                 yourself);
>>                 yourself)
>
>
> If you have previously defined a "representation map", you would be golden.
>
> e.g.
> Dictionary new
> at: self northDirectionVector put: 'north';
> at: self eastDirectionVector put: 'east';
> at: self southDirectionVector put: 'south';
> at: self westDirectionVector put: 'west';
> yourself.
>
> Then:
> (Dictionary new
>                 add: 'direction' -> (self directionRepresentationMap at: self directionVector);
> ...
>
>>
>>
>> and I think I need then to use if then , which I try to avoid as much as possible.
>>
>> Roelof
>>
>>
>>
>> Op 18-4-2019 om 18:33 schreef Richard Sargent:
>>
>> On Thu, Apr 18, 2019 at 8:57 AM Roelof Wobben <[hidden email]> wrote:
>>>
>>> Hello,
>>>
>>> I know I have asked earlier but im still stuck on this one : https://github.com/exercism/problem-specifications/blob/master/exercises/robot-simulator/description.md
>>>
>>> I tried with all double dispatch but that will be a lot of duplicate classes
>>>
>>> The problem I cannot solve right is that a robot can move or turn. when a robot turns only the direction the robot is facing changes and the position not. when a robot moves the facing direction stays the same but the position changes. but the change is dependend on the facing. Also the new facing direction is dependend on the old facing direction/
>>> How can I model this the best.
>>>
>>> I already have a object Robot that contains the facing direction and the current position
>>> or tried without it but then I use a lot of if then's
>>>
>>>
>>> so it  there  a better way to model this problem so it will be all nice and readable code.
>>
>>
>> If I remember correctly, Richard O'Keefe gave you a viable design. 1) Use a Point for your direction vector. 2) Use a second Point for your position.
>>
>> e.g. if you align the compass with a Cartesian plane, 0@1 is North, 0@-1 is South, 1@0 is East, and -1@0 is West. When you move, you add the direction vector to your current position. If you allow movements of greater than a single unit, you multiply the direction vector by the distance before adding that product to the position.
>>
>>>
>>> Roelof
>>>
>>
>

Reply | Threaded
Open this post in threaded view
|

Re: how to model this a better way

Andres Valloud-4
In reply to this post by Roelof Wobben
I can't escape the feeling that this answer is leaving a lot on the
table because the question is asked from a narrow perspective.

On 4/18/19 10:01 , Roelof Wobben wrote:

> because the challenge wants this to be the answer :
>
> (Dictionary new
>                 add: 'direction' -> 'north';
>                 add:
>                     'position'
>                         ->
>                             (Dictionary new
>                                 add: 'x' -> 0;
>                                 add: 'y' -> 0;
>                                 yourself);
>                 yourself)
Reply | Threaded
Open this post in threaded view
|

Re: how to model this a better way

Richard Sargent (again)
You are so right!

Q: now that I've gotten to the bottom of the Grand Canyon and found a narrow spot, how do I cross the river?

A: WTF are you doing down there????


On April 18, 2019 11:41:48 PM PDT, Andres Valloud <[hidden email]> wrote:
I can't escape the feeling that this answer is leaving a lot on the 
table because the question is asked from a narrow perspective.

On 4/18/19 10:01 , Roelof Wobben wrote:
because the challenge wants this to be the answer :

(Dictionary new
add: 'direction' -> 'north';
add:
'position'
->
(Dictionary new
add: 'x' -> 0;
add: 'y' -> 0;
yourself);
yourself)
Reply | Threaded
Open this post in threaded view
|

Re: how to model this a better way

Roelof Wobben
yep,

there are some 14 tests and I do not want to put them all on this ML.

That is why I pointed to the orginal question

but to give another case.

the robot can also facing north and turn and facing north and turn right or move.
but it can also be  facing south, turn left or facing south and turn right or move.
and so on

Roelof



Op 19-4-2019 om 08:50 schreef Richard Sargent:
You are so right!

Q: now that I've gotten to the bottom of the Grand Canyon and found a narrow spot, how do I cross the river?

A: WTF are you doing down there????


On April 18, 2019 11:41:48 PM PDT, Andres Valloud [hidden email] wrote:
I can't escape the feeling that this answer is leaving a lot on the 
table because the question is asked from a narrow perspective.

On 4/18/19 10:01 , Roelof Wobben wrote:
because the challenge wants this to be the answer : (Dictionary new add: 'direction' -> 'north'; add: 'position' -> (Dictionary new add: 'x' -> 0; add: 'y' -> 0; yourself); yourself)

Reply | Threaded
Open this post in threaded view
|

Re: how to model this a better way

Andres Valloud-4
In reply to this post by Richard Sargent (again)
I wanted to go for coffee! :P

On 4/18/19 23:50 , Richard Sargent wrote:

> You are so right!
>
> Q: now that I've gotten to the bottom of the Grand Canyon and found a
> narrow spot, how do I cross the river?
>
> A: WTF are you doing down there????
>
>
> On April 18, 2019 11:41:48 PM PDT, Andres Valloud
> <[hidden email]> wrote:
>
>     I can't escape the feeling that this answer is leaving a lot on the
>     table because the question is asked from a narrow perspective.
>
>     On 4/18/19 10:01 , Roelof Wobben wrote:
>
>         because the challenge wants this to be the answer :
>
>         (Dictionary new
>         add: 'direction' -> 'north';
>         add:
>         'position'
>         ->
>         (Dictionary new
>         add: 'x' -> 0;
>         add: 'y' -> 0;
>         yourself);
>         yourself)
>
Reply | Threaded
Open this post in threaded view
|

Re: how to model this a better way

Richard O'Keefe
In reply to this post by Tim Mackinnon
I already discoursed on this at some length.
(1) In my own answer, I used code to map direction names to vectors.
    But the Dictionary answers are absolutely fine.
(2) I pointed out that there are ALREADY "turn left" and "turn right"
    operations on Points.
(3) An elegant solution is one which wastes no effort.
    Introducing classes that you don't need is definitely wasted
    effort.
WARNING: untested first draft code (can't find the tested stuff).
    obey: commands
      |position direction|
      position  := 0@0.
      direction := 1@0.
      commands do: [:each |
        each caseOf: {
          [$A] -> [position  := position  + direction].
          [$L] -> [direction := direction leftRotated].
          [$R] -> [direction := direction rightRotated]
        }].
      ^{position. direction}
You will need to fiddle with this a bit to get the mapping between
problem coordinates and solution coordinates right, and you'll
need that Dictionary mapping directions to direction names, but
that's pretty much it.  If you define more than one class for this
problem, your code is not elegant.


On Fri, 19 Apr 2019 at 08:05, Tim Mackinnon <[hidden email]> wrote:
You quickly find it’s a more interesting exercise than just a “point and dictionary”, particularly if you want to do it in an elegant Smalltalk way (but not over do it either).

The interesting bit is that when facing a new direction, you need to know how to advance in that direction , and also what “left” and “right” of that direction are too. So it teases out having some objects and techniques for this.

For those interested - join exercism-Pharo (https://exercism.io/tracks/pharo-smalltalk/installation) in non mentor mode and you can easily download it with the tests and try it out yourself (without running through the other exercises).

Tim

Sent from my iPhone

On 18 Apr 2019, at 21:41, Richard Sargent <[hidden email]> wrote:

Your system would have instance variables holding the cardinal directions and another holding the current direction vector.
e.g.
north := DirectionVector x: 0 y: 1 name: 'north'.

Your robot would implement e.g. #faceNorth to assign the "north" direction vector to the current direction vector instance variable.



On Thu, Apr 18, 2019 at 12:17 PM Roelof Wobben <[hidden email]> wrote:
oke, and how must I see those classes and elemating the need for a lookup.

it may be explained in pseudo-code.

Roelof



Op 18-4-2019 om 20:28 schreef Richard Sargent:
On Thu, Apr 18, 2019 at 10:33 AM Roelof Wobben <[hidden email]> wrote:
oke

Maybe I understand something not right,

Lets say we have this scenario.

Robot is on position (0,0)
now it turns left so the robot faces East

I don't understand what position has to do with direction nor why that would be a problem. They are two distinct attributes.
Point and Dictionary are sufficient classes to model the limited requirements of this exercise.
You could model a new class DirectionVector which internalizes the Point used to provide the direction and provides its own name, eliminating the need for a look up of any kind.


or this scenario

Robot is on position (0,0)
now it turns right so the robot faces west.

it looks that dictionary cannot provide this answer.
or do I overlook something

Roelof



Op 18-4-2019 om 19:17 schreef Richard Sargent:
On Thu, Apr 18, 2019 at 10:01 AM Roelof Wobben <[hidden email]> wrote:
yep, I have read that one
but I never gets a answer how I can "convert"  a point to something like north, east

because the challenge wants this to be the answer :

(Dictionary new
                add: 'direction' -> 'north';
                add:
                    'position'
                        ->
                            (Dictionary new
                                add: 'x' -> 0;
                                add: 'y' -> 0;
                                yourself);
                yourself)

If you have previously defined a "representation map", you would be golden.

e.g.
Dictionary new
at: self northDirectionVector put: 'north';
at: self eastDirectionVector put: 'east';
at: self southDirectionVector put: 'south';
at: self westDirectionVector put: 'west';
yourself.

Then:
(Dictionary new
                add: 'direction' -> (self directionRepresentationMap at: self directionVector);
...



and I think I need then to use if then , which I try to avoid as much as possible.

Roelof



Op 18-4-2019 om 18:33 schreef Richard Sargent:
On Thu, Apr 18, 2019 at 8:57 AM Roelof Wobben <[hidden email]> wrote:
Hello,

I know I have asked earlier but im still stuck on this one : https://github.com/exercism/problem-specifications/blob/master/exercises/robot-simulator/description.md

I tried with all double dispatch but that will be a lot of duplicate classes

The problem I cannot solve right is that a robot can move or turn. when a robot turns only the direction the robot is facing changes and the position not. when a robot moves the facing direction stays the same but the position changes. but the change is dependend on the facing. Also the new facing direction is dependend on the old facing direction/
How can I model this the best.

I already have a object Robot that contains the facing direction and the current position
or tried without it but then I use a lot of if then's


so it  there  a better way to model this problem so it will be all nice and readable code.

If I remember correctly, Richard O'Keefe gave you a viable design. 1) Use a Point for your direction vector. 2) Use a second Point for your position.

e.g. if you align the compass with a Cartesian plane, 0@1 is North, 0@-1 is South, 1@0 is East, and -1@0 is West. When you move, you add the direction vector to your current position. If you allow movements of greater than a single unit, you multiply the direction vector by the distance before adding that product to the position.


Roelof




Reply | Threaded
Open this post in threaded view
|

Re: how to model this a better way

Ben Coman
On Mon, 22 Apr 2019 at 23:15, Richard O'Keefe <[hidden email]> wrote:
>
> I already discoursed on this at some length.
> (1) In my own answer, I used code to map direction names to vectors.
>     But the Dictionary answers are absolutely fine.
> (2) I pointed out that there are ALREADY "turn left" and "turn right"
>     operations on Points.
> (3) An elegant solution is one which wastes no effort.
>     Introducing classes that you don't need is definitely wasted
>     effort.

Elegance in art is in the eye of the beholder.  You've got one position on it.
I'll just balance it with an alternative view for students to consider
around "classes that you don't need".

> WARNING: untested first draft code (can't find the tested stuff).
>     obey: commands
>       |position direction|
>       position  := 0@0.
>       direction := 1@0.
>       commands do: [:each |
>         each caseOf: {
>           [$A] -> [position  := position  + direction].
>           [$L] -> [direction := direction leftRotated].
>           [$R] -> [direction := direction rightRotated]
>         }].
>       ^{position. direction}
> You will need to fiddle with this a bit to get the mapping between
> problem coordinates and solution coordinates right, and you'll
> need that Dictionary mapping directions to direction names, but
> that's pretty much it.

> If you define more than one class for this problem, your code is not elegant.

If the purpose of the problems is simply to solve the problem, then
doing the absolute minimum is a reasonable view of elegance.
After all, its throw away code.  You're never going to be maintaining it.

But if the purpose of problems is to lead students in new ways of
thinking about structuring OO solutions
for maintainability within Pharo, then I feel its lacking.  I remember
an instructor from my youth
advising that "practicing a kata poorly is the habit that will be
reproduced automatically (in a crisis)"

>       ^{position. direction}

For me, viewing   {2@3. 1@0 }  in a debugger is a much greater
cognitive load than {2@3.  'Facing east'}
to determine which direction its facing.  So I consider the latter
more elegant.  TDD helps minimise class over-engineering,
but for me the latter is a "need".  In terms of throw-away exercises,
its about what habits students want to gain from doing them.

Just another perspective.
cheers -ben

Reply | Threaded
Open this post in threaded view
|

Re: how to model this a better way

Richard O'Keefe
Let me tell you a story.
The story is about someone I knew back when I was doing my MSc.
He was really bright, but he had to repeat a year in the papers
part of his MSc.
Why?  Because he didn't get statistics.
Differential equations?  No problem.
Topology?  No problem.
Operations research (which was his actual topic)?  A walk in the park.
Statistics?  He just couldn't get it.

Why not?
"I read the book, and I think I understand, and then I come to the
examples, and I can't see why they use the method they use, why
that is a good method for that problem."

I hope it made a difference to him when I replied
"You can't see why method X is a good choice for problem Y
because it isn't.  If your goal is to illustrate the workings
of method X, problem Y will do.  But if your goal is to
actually solve problem Y, method X is the last thing you should
try."

I actually worked through a couple of famous textbooks,
example by example, and found that for more than half of the
problems, if you followed the advice in the book about how
to select a method, you would never select the method in the
example, and the method you would select instead gave better
and on occasion much better results.

In this particular case, I don't give a damn about what
{1@0. 0@} looks like in a debugger, BECAUSE IT NEVER DID
APPEAR IN A DEBUGGER.

The one method needed to solve the problem is 18 lines.
The test code, including all available test cases, is 27
lines, of which 18 lines is the test data.  Tests were
needed primarily to sort out what the problem actually *was*;
exercism doesn't even try to provide good specifications.
No debugging time at all was needed, precisely because the
code was so simple and obvious.  If it *had* been needed,
viewing the result right next to the expression that yielded
it would have given me all the context I needed, in one window.

If you want to learn how to design a good set of classes,
this is an absolutely dreadful problem.  In fact ALL of the
exercism problems are going to be dreadful for *that*
purpose because they are provided for languages that do not
*have* classes.  If you want to learn how to *solve problems*,
then you need to learn to write code that is simple, clear,
testable, and so on.  You certainly need to learn how to use
what is already there in the language (except where that is
expressly forbidden). 

I completely agree that designing a good set of classes is
a very very important skill for anyone who wants to do OOP.
I completely agree that practising this on problems you can
hold in your head is a good idea.
I completely agree that if *that* is your objective,
writing minimalist code is not the best strategy.

The problem with exercism is that while it does have a
criterion by which you can tell whether you have *solved the
problem*, it provides *no* way to assess your class design.
You don't get told "this is good, that is bloated"; there is
no feedback about the *quality* of your code except via
comments from those few people who can be bothered to look
at other people's solutions and comment on them.  And since
many of them will also be beginners, their comments may not
always help.

This particular problem is very similar to a "Langton's Ant"
problem my old department gave to students, who were expected
to solve it in two or three hours.  And ALWAYS, the thing that
held them back was creating classes they didn't need and
agonising over what data and methods should go where (and then
getting it wrong, such is the nature of Java).

When a problem can be solved quite directly in 18 lines of
clean code, you are going to have a very hard time persuading
me that even one more class pays for itself, especially in a
system with a rich class library of stuff you don't have to write.

"You Aren't Gunna Need It" is a good slogan.
"If you didn't write it you didn't wrong it" is another.

Reply | Threaded
Open this post in threaded view
|

Re: how to model this a better way

Richard O'Keefe
In reply to this post by Ben Coman
TL;DR version:
  "But if the purpose of problems is to lead students in new ways of
   thinking about structuring OO solutions for maintainability"
That is not the purpose of the exercism problems.  It would be very good
if somebody did craft such a set of exercises, and Pharo would be a very
good environment for them.  The exercism exercises will not do.

Betrand Meyer has an OOP course that gets students started *modifying* a
non-trivial program, a traffic simulator I believe, instead of writing
free-standing toy programs.  Worth thinking about.

On Wed, 24 Apr 2019 at 04:58, Ben Coman <[hidden email]> wrote:
On Mon, 22 Apr 2019 at 23:15, Richard O'Keefe <[hidden email]> wrote:
>
> I already discoursed on this at some length.
> (1) In my own answer, I used code to map direction names to vectors.
>     But the Dictionary answers are absolutely fine.
> (2) I pointed out that there are ALREADY "turn left" and "turn right"
>     operations on Points.
> (3) An elegant solution is one which wastes no effort.
>     Introducing classes that you don't need is definitely wasted
>     effort.

Elegance in art is in the eye of the beholder.  You've got one position on it.
I'll just balance it with an alternative view for students to consider
around "classes that you don't need".

> WARNING: untested first draft code (can't find the tested stuff).
>     obey: commands
>       |position direction|
>       position  := 0@0.
>       direction := 1@0.
>       commands do: [:each |
>         each caseOf: {
>           [$A] -> [position  := position  + direction].
>           [$L] -> [direction := direction leftRotated].
>           [$R] -> [direction := direction rightRotated]
>         }].
>       ^{position. direction}
> You will need to fiddle with this a bit to get the mapping between
> problem coordinates and solution coordinates right, and you'll
> need that Dictionary mapping directions to direction names, but
> that's pretty much it.

> If you define more than one class for this problem, your code is not elegant.

If the purpose of the problems is simply to solve the problem, then
doing the absolute minimum is a reasonable view of elegance.
After all, its throw away code.  You're never going to be maintaining it.

But if the purpose of problems is to lead students in new ways of
thinking about structuring OO solutions
for maintainability within Pharo, then I feel its lacking.  I remember
an instructor from my youth
advising that "practicing a kata poorly is the habit that will be
reproduced automatically (in a crisis)"

>       ^{position. direction}

For me, viewing   {2@3. 1@0 }  in a debugger is a much greater
cognitive load than {2@3.  'Facing east'}
to determine which direction its facing.  So I consider the latter
more elegant.  TDD helps minimise class over-engineering,
but for me the latter is a "need".  In terms of throw-away exercises,
its about what habits students want to gain from doing them.

Just another perspective.
cheers -ben

12