Re: [Pharo-users] what must be instead of the ??

2018-11-09 Thread Joachim Tuchel
So I guess that floor > 0 is your condition, right? In Smalltalk, the idea is 
that you evaluate the condition and ask the result of it (usually true or 
false) to do something.

Right so far? That would mean the receiver of your wanted message is either the 
result of the evaluation or or a Block which will be evaluated in a construct 
like ifTrue: or something like whileTrue:

HTH

Joachim



> Am 09.11.2018 um 08:24 schrieb Roelof Wobben :
> 
> Hello,
> 
> I try to solve a adventofcode challenge where I must find out when santa is 
> first at the basement. the floor is there -1.
> So I thought I use a while loop like this :
> 
> santaFloorOnBasement
> "calculates which step take Santa to the basement"
>  | index|
>  index := 1.
>  ??? when: (floor >=0 ) do:
> [ floor := (input at: index = '(' )
> ifTrue: [ floor + 1 ]
> ifFalse: [ floor - 1 ].
>  index := index + 1 ].
> 
> but I cannot find out what must be instead of the ??
> 
> index is the index of the string which has to start with a 1.
> floor  and input are both instance variables. floor contains the current 
> floor and input the input of the challenge.
> 
> Can someone help me figure this out so the next time I can do this on my own.
> 
> Roelof
> 
> 
> 




Re: [Pharo-users] what must be instead of the ??

2018-11-09 Thread Tim Mackinnon
To add to what Joachim has said, and to help you help yourself, look at what 
methods are implemented in BlockClosure and Boolean and see how things work 
(the code is there for you to understand it quite easily - there is little 
magic going on). You can find all kinds of interesting and helpful things and 
can even implement your own if you ever want to.

Tim

Sent from my iPhone

> On 9 Nov 2018, at 16:02, Joachim Tuchel  wrote:
> 
> So I guess that floor > 0 is your condition, right? In Smalltalk, the idea is 
> that you evaluate the condition and ask the result of it (usually true or 
> false) to do something.
> 
> Right so far? That would mean the receiver of your wanted message is either 
> the result of the evaluation or or a Block which will be evaluated in a 
> construct like ifTrue: or something like whileTrue:
> 
> HTH
> 
> Joachim
> 
> 
> 
>> Am 09.11.2018 um 08:24 schrieb Roelof Wobben :
>> 
>> Hello,
>> 
>> I try to solve a adventofcode challenge where I must find out when santa is 
>> first at the basement. the floor is there -1.
>> So I thought I use a while loop like this :
>> 
>> santaFloorOnBasement
>>"calculates which step take Santa to the basement"
>> | index|
>> index := 1.
>> ??? when: (floor >=0 ) do:
>>[ floor := (input at: index = '(' )
>>ifTrue: [ floor + 1 ]
>>ifFalse: [ floor - 1 ].
>> index := index + 1 ].
>> 
>> but I cannot find out what must be instead of the ??
>> 
>> index is the index of the string which has to start with a 1.
>> floor  and input are both instance variables. floor contains the current 
>> floor and input the input of the challenge.
>> 
>> Can someone help me figure this out so the next time I can do this on my own.
>> 
>> Roelof
>> 
>> 
>> 
> 
> 




Re: [Pharo-users] what must be instead of the ??

2018-11-09 Thread Ben Coman
On Fri, 9 Nov 2018 at 15:25, Roelof Wobben  wrote:

> Hello,
>
> I try to solve a adventofcode challenge where I must find out when santa
> is first at the basement. the floor is there -1.
> So I thought I use a while loop like this :
>
> santaFloorOnBasement
>  "calculates which step take Santa to the basement"
>   | index|
>   index := 1.
>   ??? when: (floor >=0 ) do:
>  [ floor := (input at: index = '(' )
>  ifTrue: [ floor + 1 ]
>  ifFalse: [ floor - 1 ].
>   index := index + 1 ].
>
> but I cannot find out what must be instead of the ??
>

I've never used #when:do: so I can't comment on that.
I'd be using #whileTrue: which looks like this...  [ condition block ]
whileTrue: [ action block ]

<<< ??? when: (floor >=0 ) do:
>>>[floor>=0] whileTrue:

For further examples review the "senders" of #whileTrue:
i.e. highlight then press  on MS Windows



> index is the index of the string which has to start with a 1.
> floor  and input are both instance variables. floor contains the current
> floor and input the input of the challenge.
>
> Can someone help me figure this out so the next time I can do this on my
> own.
>

btw you have a problem here...
 floor := (input at: index = '(' )

Its not doing what you think and you'll get "Error: only integers should be
used as indices"
Consider you that two messages are being sent:
   * the keyword message...  #at:
   * the binary message  #=
Homework :)... what is the third type of message and the evaluation
priority of all three.

Homework 2...  Review the "implementors" of message #=
 on MS Windows

cheers -ben


P.S. As it current stands,  you'll get a "SubscriptOutOfBounds" error if
the input ends before Santa gets to the basement.
An exercise, fix that using the existing loop.

Then consider using an iterator...
input do: [ :bracket |
 (bracket = $( ) ifTrue:  [ floor := floor + 1 ]  .
 (bracket = $( ) ifTrue:  [ floor := floor + 1 ]].

and maybe something else for you to experiment with...
movement := Dictionary new.
movement  at: $( put: 1.
movement  at: $) put: -1.
input do: [ :char |  floor := floor + (movement at: char ifAbsent: [0])
].

cheers -ben


Re: [Pharo-users] what must be instead of the ??

2018-11-09 Thread Roelof Wobben

  
  
Thanks all. 
  
  This code seems to do the job
  
  santaFloorOnBasement
      "calculates which step take Santa to the basement"
   | index| 
   index := 1.  
   [floor ~= -1 ] whileTrue:  
      [ floor := ((input at: index) = '(' ) 
      ifTrue: [ floor + 1 ]
      ifFalse: [ floor - 1 ].
   index := index + 1 ].
    
      ^ index -1
  
  
  Roelof
  
  
  
  
  Op 9-11-2018 om 09:51 schreef Ben Coman:


  
  

  


  On Fri, 9 Nov 2018 at 15:25, Roelof Wobben
 wrote:
  
  Hello,

I try to solve a adventofcode challenge where I must
find out when santa 
is first at the basement. the floor is there -1.
So I thought I use a while loop like this :

santaFloorOnBasement
 "calculates which step take Santa to the basement"
  | index|
  index := 1.
  ??? when: (floor >=0 ) do:
 [ floor := (input at: index = '(' )
 ifTrue: [ floor + 1 ]
 ifFalse: [ floor - 1 ].
  index := index + 1 ].

but I cannot find out what must be instead of the ??
  
  
  
  I've never used #when:do: so I can't comment on that.
  I'd be using #whileTrue: which looks like this...  [
condition block ] whileTrue: [ action block ]
      
  
  <<<     ??? when: (floor >=0 ) do:
  >>>    [floor>=0] whileTrue: 
  
  
  
  For further examples review the "senders" of
#whileTrue:
i.e. highlight then press  on MS Windows 
  
  
   
  index is the index of
the string which has to start with a 1.
floor  and input are both instance variables. floor
contains the current 
floor and input the input of the challenge.

Can someone help me figure this out so the next time I
can do this on my 
own.
  
  
  
  btw you have a problem here...
       floor := (input at: index = '(' ) 
  
  
  Its not doing what you think and you'll get "Error:
only integers should be used as indices"
  Consider you that two messages are being sent:
     * the keyword message...  #at:
     * the binary message  #=
  Homework :)... what is the third type of message and
the evaluation priority of all three.
  
  
  Homework 2...  Review the "implementors" of message
#=
   on MS Windows
  
  
  cheers -ben
  
  
  
  
  P.S. As it current stands,  you'll get a
"SubscriptOutOfBounds" error if the input ends before
Santa gets to the basement. 
  An exercise, fix that using the existing loop.
  
  
  
  Then consider using an iterator...
      input do: [ :bracket | 
           (bracket = $( ) ifTrue: 
[ floor := floor + 1 ]  .
  
         (bracket = $( ) ifTrue: 
  [ floor := floor + 1 ]].

  
  and maybe something else for you to experiment
with...
      movement := Dictionary new.
      movement  at: $( put: 1.
      movement  at: $) put: -1.
      input do: [ :char |  floor := floor + (movement
at: char ifAbsent: [0]) ]. 
  
  
  cheers -ben
  

  

  


  




Re: [Pharo-users] what must be instead of the ??

2018-11-09 Thread Peter Uhnak
On Fri, Nov 9, 2018 at 1:26 PM Roelof Wobben  wrote:

> Thanks all.
>
> This code seems to do the job
>
> santaFloorOnBasement
> "calculates which step take Santa to the basement"
>  | index|
>  index := 1.
>  [floor ~= -1 ] whileTrue:
> [ floor := ((input at: index) = '(' )
> ifTrue: [ floor + 1 ]
> ifFalse: [ floor - 1 ].
>  index := index + 1 ].
>
> ^ index -1
>


You can also think of it from the perspective of data processing and not
instruction coding (and mangling of indexes).

stepChanges := input collect: [ :c |
floor := floor + (c = '(' ifTrue: [ 1 ] ifFalse: [ -1 ]).
floor
].

stepChanges detectIndex: [ :each | each = -1 ] ifNone: [ 'invalid input yo'
].

Peter


Re: [Pharo-users] what must be instead of the ??

2018-11-09 Thread Roelof Wobben

  
  
Op 9-11-2018 om 16:44 schreef Peter
  Uhnak:


  
  

  
  
On Fri, Nov 9, 2018 at 1:26 PM Roelof Wobben
   wrote:


  
Thanks
  all. 
  
  This code seems to do the job
  
  santaFloorOnBasement
      "calculates which step take Santa to the basement"
   | index| 
   index := 1.  
   [floor ~= -1 ] whileTrue:  
      [ floor := ((input at: index) = '(' ) 
      ifTrue: [ floor + 1 ]
      ifFalse: [ floor - 1 ].
   index := index + 1 ].
    
      ^ index -1

  





You can also think of it from the perspective of data
  processing and not instruction coding (and mangling of
  indexes).



  stepChanges := input collect: [ :c |
  
  	floor := floor
+ (c = '(' ifTrue: [ 1 ] ifFalse: [ -1 ]).
  	floor
  ].
  
  
  stepChanges detectIndex: [ :each | each = -1 ]
ifNone: [ 'invalid input yo' ].



Peter
  

  


oke, I see how it works, 
first you calculate all the floors Santa is visiting and then you
look for the first -1. 
I have thought of something but I found it wierd that you do steps
when you have already the answer. 

but how do I find now the answer do I have to do something like  
puzzle1  stepChanges detectIndex ?  

Roelof


  




Re: [Pharo-users] what must be instead of the ??

2018-11-09 Thread Roelof Wobben

  
  
hmm. 
  
  When I try this on P7 
  
  |input stepChanges floor| 
  input := '((('.
  floor := 0.
  stepChanges := input collect: [ :c |
      floor := floor + (c = '(' ifTrue: [ 1 ] ifFalse: [ -1 ]).
      floor
  ].
  
  stepChanges detectIndex: [ :each | each = -1 ] ifNone: [ 'invalid
  input yo' ].
  
  then I see this error message :  Improper store to indexable
  object. 
  
  Roelof
  
  
  Op 9-11-2018 om 17:39 schreef Roelof Wobben:


  
stepChanges := input collect: [ :c |

	floor := floor + (c =
  '(' ifTrue: [ 1 ] ifFalse: [ -1 ]).
	floor
].


stepChanges detectIndex: [ :each | each = -1 ] ifNone: [
  'invalid input yo' ].
  


  




Re: [Pharo-users] what must be instead of the ??

2018-11-09 Thread Gabriel Cotelli
It's bug in the collect: implementation used in String. I've opened
https://pharo.fogbugz.com/f/cases/22652/collect-over-Strings-is-broken

On Fri, Nov 9, 2018 at 2:17 PM Roelof Wobben  wrote:

> hmm.
>
> When I try this on P7
>
> |input stepChanges floor|
> input := '((('.
> floor := 0.
> stepChanges := input collect: [ :c |
> floor := floor + (c = '(' ifTrue: [ 1 ] ifFalse: [ -1 ]).
> floor
> ].
>
> stepChanges detectIndex: [ :each | each = -1 ] ifNone: [ 'invalid input
> yo' ].
>
> then I see this error message :  Improper store to indexable object.
>
> Roelof
>
>
> Op 9-11-2018 om 17:39 schreef Roelof Wobben:
>
> stepChanges := input collect: [ :c |
> floor := floor + (c = '(' ifTrue: [ 1 ] ifFalse: [ -1 ]).
> floor
> ].
>
> stepChanges detectIndex: [ :each | each = -1 ] ifNone: [ 'invalid input
> yo' ].
>
>
>


Re: [Pharo-users] what must be instead of the ??

2018-11-09 Thread Alistair Grant
On Fri, 9 Nov 2018 at 18:38, Gabriel Cotelli  wrote:
>
> It's bug in the collect: implementation used in String. I've opened 
> https://pharo.fogbugz.com/f/cases/22652/collect-over-Strings-is-broken

Strings store characters, not integers, so change your example to:

'aa' collect: [ :a | $1 ]

and you'll see that (I think) it is working as expected.

You could do:

'aa' collect: [ :a | 1 ] as: Array.

Roelof, revisit your example, taking the above in to account :-)

HTH,
Alistair



Re: [Pharo-users] what must be instead of the ??

2018-11-09 Thread Peter Uhnak
>
> but how do I find now the answer do I have to do something like   puzzle1
> stepChanges detectIndex ?


How do you mean? It would be the same

santaFloorOnBasement
"calculates which step take Santa to the basement"

stepChanges := input collect: [ :c |
floor := floor + (c = '(' ifTrue: [ 1 ] ifFalse: [ -1 ]).
floor
].

stepChanges detectIndex: [ :each | each = -1 ] ifNone: [ 'invalid input
yo' ].

then I see this error message :  Improper store to indexable object.


Because earlier you were comparing strings and not characters, I assumed
your input was an array of strings like #('(' '(' '('). but you can fix
that by changing `input collect:` -> `input asArray collect:` and `c = '('`
-> `c = $(`.

I have thought of something but I found it wierd that you do steps when you
> have already the answer.


That is indeed true, personally I would decide based on how often the
method is called and how large the input is. Because this cumulative change
makes it much easier to debug any issues... and usually I prefer
debuggability over performance (unless it is an actual bottleneck).

Peter


On Fri, Nov 9, 2018 at 6:38 PM Gabriel Cotelli  wrote:

> It's bug in the collect: implementation used in String. I've opened
> https://pharo.fogbugz.com/f/cases/22652/collect-over-Strings-is-broken
>
> On Fri, Nov 9, 2018 at 2:17 PM Roelof Wobben  wrote:
>
>> hmm.
>>
>> When I try this on P7
>>
>> |input stepChanges floor|
>> input := '((('.
>> floor := 0.
>> stepChanges := input collect: [ :c |
>> floor := floor + (c = '(' ifTrue: [ 1 ] ifFalse: [ -1 ]).
>> floor
>> ].
>>
>> stepChanges detectIndex: [ :each | each = -1 ] ifNone: [ 'invalid input
>> yo' ].
>>
>> then I see this error message :  Improper store to indexable object.
>>
>> Roelof
>>
>>
>> Op 9-11-2018 om 17:39 schreef Roelof Wobben:
>>
>> stepChanges := input collect: [ :c |
>> floor := floor + (c = '(' ifTrue: [ 1 ] ifFalse: [ -1 ]).
>> floor
>> ].
>>
>> stepChanges detectIndex: [ :each | each = -1 ] ifNone: [ 'invalid input
>> yo' ].
>>
>>
>>


Re: [Pharo-users] what must be instead of the ??

2018-11-09 Thread Alistair Grant
Hi Peter,

On Fri, 9 Nov 2018 at 18:51, Peter Uhnak  wrote:
>>
>> but how do I find now the answer do I have to do something like   puzzle1  
>> stepChanges detectIndex ?
>
>
> How do you mean? It would be the same
>
> santaFloorOnBasement
> "calculates which step take Santa to the basement"
>
> stepChanges := input collect: [ :c |
> floor := floor + (c = '(' ifTrue: [ 1 ] ifFalse: [ -1 ]).
> floor
> ].
>
> stepChanges detectIndex: [ :each | each = -1 ] ifNone: [ 'invalid input 
> yo' ].
>
>> then I see this error message :  Improper store to indexable object.
>
>
> Because earlier you were comparing strings and not characters, I assumed your 
> input was an array of strings like #('(' '(' '('). but you can fix that by 
> changing `input collect:` -> `input asArray collect:` and `c = '('` -> `c = 
> $(`.

Using '(' instead of $( is indeed an error, but it isn't the cause of
the Improper store error.

Roelof, I really suggest you trigger this error again, start the
debugger and then take a look in the call stack (I'm assuming you're
familiar with at least one other programming language, so should be
able to figure out the debugger).

Cheers,
Alistair



Re: [Pharo-users] what must be instead of the ??

2018-11-09 Thread Alistair Grant
Hi Peter,

On Fri, 9 Nov 2018 at 19:00, Alistair Grant  wrote:
>
> Hi Peter,
>
> On Fri, 9 Nov 2018 at 18:51, Peter Uhnak  wrote:
> >>
> >> but how do I find now the answer do I have to do something like   puzzle1  
> >> stepChanges detectIndex ?
> >
> >
> > How do you mean? It would be the same
> >
> > santaFloorOnBasement
> > "calculates which step take Santa to the basement"
> >
> > stepChanges := input collect: [ :c |
> > floor := floor + (c = '(' ifTrue: [ 1 ] ifFalse: [ -1 ]).
> > floor
> > ].
> >
> > stepChanges detectIndex: [ :each | each = -1 ] ifNone: [ 'invalid input 
> > yo' ].
> >
> >> then I see this error message :  Improper store to indexable object.
> >
> >
> > Because earlier you were comparing strings and not characters, I assumed 
> > your input was an array of strings like #('(' '(' '('). but you can fix 
> > that by changing `input collect:` -> `input asArray collect:` and `c = '('` 
> > -> `c = $(`.
>
> Using '(' instead of $( is indeed an error, but it isn't the cause of
> the Improper store error.

I was too quick to respond here, I didn't look at the #asArray.  Sorry!

But still suggest Roelof looks at the debugger...

> Roelof, I really suggest you trigger this error again, start the
> debugger and then take a look in the call stack (I'm assuming you're
> familiar with at least one other programming language, so should be
> able to figure out the debugger).

Cheers,
Alistair



Re: [Pharo-users] what must be instead of the ??

2018-11-09 Thread Roelof Wobben

  
  
oke, I see , I thought earlier that
  stepChanges was a function but its a variable 
  
  Roelof
  
  
  Op 9-11-2018 om 18:50 schreef Peter Uhnak:


  
  
but
  how do I find now the answer do I have to do something like  
  puzzle1  stepChanges detectIndex ?  


How do you mean? It would be the same


santaFloorOnBasement
    "calculates which step
take Santa to the basement"

  

  
    stepChanges := input
  collect: [ :c |

	floor :=
  floor + (c = '(' ifTrue: [ 1 ] ifFalse: [ -1 ]).
	floor
    ].


    stepChanges
  detectIndex: [ :each | each = -1 ] ifNone: [ 'invalid
  input yo' ].
  
  

then
  I see this error message :  Improper store to indexable
  object.  


Because earlier you were comparing strings and not
  characters, I assumed your input was an array of strings like
  #('(' '(' '('). but you can fix that by changing `input
  collect:` -> `input asArray collect:` and `c = '('` ->
  `c = $(`.


I
  have thought of something but I found it wierd that you do
  steps when you have already the answer.   


That is indeed true, personally I would decide based on how
  often the method is called and how large the input is. Because
  this cumulative change makes it much easier to debug any
  issues... and usually I prefer debuggability over performance
  (unless it is an actual bottleneck).


Peter


  
  
  
On Fri, Nov 9, 2018 at 6:38 PM Gabriel Cotelli
   wrote:


  
It's bug in the collect: implementation used
  in String. I've opened https://pharo.fogbugz.com/f/cases/22652/collect-over-Strings-is-broken

  
  
  
On Fri, Nov 9, 2018 at 2:17 PM Roelof Wobben
   wrote:


  
hmm.
  
  
  When I try this on P7 
  
  |input stepChanges floor| 
  input := '((('.
  floor := 0.
  stepChanges := input collect: [ :c |
      floor := floor + (c = '(' ifTrue: [ 1 ] ifFalse: [
  -1 ]).
      floor
  ].
  
  stepChanges detectIndex: [ :each | each = -1 ] ifNone:
  [ 'invalid input yo' ].
  
  then I see this error message :  Improper store to
  indexable object. 
  
  Roelof
  
  
  Op 9-11-2018 om 17:39 schreef Roelof Wobben:


  
stepChanges := input collect: [ :c |

	floor
  := floor + (c = '(' ifTrue: [ 1 ] ifFalse: [ -1
  ]).
	floor
].


stepChanges detectIndex: [ :each | each = -1 ]
  ifNone: [ 'invalid input yo' ].
  


  

  

  


  




Re: [Pharo-users] what must be instead of the ??

2018-11-09 Thread Roelof Wobben

hmm, got a idea

I could use this part :

|input floor stepChanges|
input := '))('.
floor := 0.
stepChanges := input asArray collect: [ :c |
floor := floor + (c = $( ifTrue: [ 1 ] ifFalse: [ -1 ]).
 ].


two times if the outcome would be a collection.
The challenge is 2 parts.

1) find out where santa stops. that would be the last number in the 
collection..
2) find out when santa enters the basement. That could be the function 
that is mentioned here.


Time to experiment with this idea.

Roelof


Op 9-11-2018 om 19:13 schreef Alistair Grant:

Hi Peter,

On Fri, 9 Nov 2018 at 19:00, Alistair Grant  wrote:

Hi Peter,

On Fri, 9 Nov 2018 at 18:51, Peter Uhnak  wrote:

but how do I find now the answer do I have to do something like   puzzle1  
stepChanges detectIndex ?


How do you mean? It would be the same

santaFloorOnBasement
 "calculates which step take Santa to the basement"

 stepChanges := input collect: [ :c |
floor := floor + (c = '(' ifTrue: [ 1 ] ifFalse: [ -1 ]).
floor
 ].

 stepChanges detectIndex: [ :each | each = -1 ] ifNone: [ 'invalid input 
yo' ].


then I see this error message :  Improper store to indexable object.


Because earlier you were comparing strings and not characters, I assumed your input 
was an array of strings like #('(' '(' '('). but you can fix that by changing `input 
collect:` -> `input asArray collect:` and `c = '('` -> `c = $(`.

Using '(' instead of $( is indeed an error, but it isn't the cause of
the Improper store error.

I was too quick to respond here, I didn't look at the #asArray.  Sorry!

But still suggest Roelof looks at the debugger...


Roelof, I really suggest you trigger this error again, start the
debugger and then take a look in the call stack (I'm assuming you're
familiar with at least one other programming language, so should be
able to figure out the debugger).

Cheers,
Alistair







Re: [Pharo-users] what must be instead of the ??

2018-11-09 Thread Roelof Wobben

Given up for today

I have this :

calculateFloors
| stepChanges floor|
floor := 0.
stepChanges := input asArray collect: [ :c |
floor := floor+ (c = $( ifTrue: [ 1 ] ifFalse: [ -1 ]).
].
floors addFloor: floor.

but now I see this error message :

temp values not written or read.

floors and input are instance variables where input is the input the 
user wants to use and floors is a Collection new.


Roelof



Op 9-11-2018 om 20:07 schreef Roelof Wobben:

hmm, got a idea

I could use this part :

|input floor stepChanges|
input := '))('.
floor := 0.
stepChanges := input asArray collect: [ :c |
floor := floor + (c = $( ifTrue: [ 1 ] ifFalse: [ -1 ]).
 ].


two times if the outcome would be a collection.
The challenge is 2 parts.

1) find out where santa stops. that would be the last number in the 
collection..
2) find out when santa enters the basement. That could be the function 
that is mentioned here.


Time to experiment with this idea.

Roelof


Op 9-11-2018 om 19:13 schreef Alistair Grant:

Hi Peter,

On Fri, 9 Nov 2018 at 19:00, Alistair Grant  
wrote:

Hi Peter,

On Fri, 9 Nov 2018 at 18:51, Peter Uhnak  wrote:
but how do I find now the answer do I have to do something like   
puzzle1  stepChanges detectIndex ?


How do you mean? It would be the same

santaFloorOnBasement
 "calculates which step take Santa to the basement"

 stepChanges := input collect: [ :c |
floor := floor + (c = '(' ifTrue: [ 1 ] ifFalse: [ -1 ]).
floor
 ].

 stepChanges detectIndex: [ :each | each = -1 ] ifNone: [ 
'invalid input yo' ].



then I see this error message : Improper store to indexable object.


Because earlier you were comparing strings and not characters, I 
assumed your input was an array of strings like #('(' '(' '('). but 
you can fix that by changing `input collect:` -> `input asArray 
collect:` and `c = '('` -> `c = $(`.

Using '(' instead of $( is indeed an error, but it isn't the cause of
the Improper store error.

I was too quick to respond here, I didn't look at the #asArray. Sorry!

But still suggest Roelof looks at the debugger...


Roelof, I really suggest you trigger this error again, start the
debugger and then take a look in the call stack (I'm assuming you're
familiar with at least one other programming language, so should be
able to figure out the debugger).

Cheers,
Alistair











Re: [Pharo-users] what must be instead of the ??

2018-11-09 Thread Richard O'Keefe
We are talking to a beginner here.
One of the important things for a beginner to
understand is the idea of hiding stuff and
thinking in terms of asking objects to do things
for you.  For example, in Java you historically
did
final int n = aString.length();
for (int i = 0; i < n; i++) {
final char c = aString.charAt(i);
...
}

Here all the loop control is *outside* the string, and
if you wanted to use some other data structure you
would have to change the code.  But in Smalltalk, you
ask the *object* to manage the iteration.

For collections in general, we have
  aCollection do: [:anElement | ... ]
For sequences we also have
  aSequence withIndexDo: [:anElement :itsIndex | ...]
where the sequence need not be a stored sequence and
need not be efficiently indexable.  (And indeed, in
Java these days, Strings *aren't* efficiently
indexable, thanks to using UTF-16 internally.)

Using enumeration methods
(a) makes your code easier to read
(b) makes your code easier to write (as there
is lots of fiddly detail you don't write at
all, it's there once and for all in the class)
(c) makes your code more adaptable (the object
needs to support #withIndexDo: and that is
*all* you demand of it).

   indexWhereBasementFirstReached: input
 "The input is a sequence in which the character
  ( means to go up a floor and the character )
  means to go down a floor.  Answer the index
  of the character where the floor below the
  initial floor is first reached.  If that
  floor is not reached, e.g., if the input is
  empty, answer 0. This is the same convention
  as #indexOf:."
 |floor|
 floor := 0.
 input withIndexDo: [:char :index |
   char = $( ifTrue: [floor := floor + 1].
   char = $) ifTrue: [floor := floor - 1].
   floor = -1 ifTrue: [^index]].
  ^0

For example, we could add the #withIndexDo: method to
Stream, which already has #do:

withIndexDo: elementAndIndexBlock
  "Iterate over the 'future values' remaining in
   this stream, passing each in turn to the block
   argument, together with an index starting at 1
   for the first value passed to the block."
  |index|
  index := 0.
  self do: [:each |
elementAndIndexBlock value: each value: (index := index + 1)].

Now the #indexWhereBasementFirstReached: method will
work on input streams as well as strings, so it could,
for example, handle a terabyte long sequence held in a
file.

On Sat, 10 Nov 2018 at 06:17, Roelof Wobben  wrote:

> hmm.
>
> When I try this on P7
>
> |input stepChanges floor|
> input := '((('.
> floor := 0.
> stepChanges := input collect: [ :c |
> floor := floor + (c = '(' ifTrue: [ 1 ] ifFalse: [ -1 ]).
> floor
> ].
>
> stepChanges detectIndex: [ :each | each = -1 ] ifNone: [ 'invalid input
> yo' ].
>
> then I see this error message :  Improper store to indexable object.
>
> Roelof
>
>
> Op 9-11-2018 om 17:39 schreef Roelof Wobben:
>
> stepChanges := input collect: [ :c |
> floor := floor + (c = '(' ifTrue: [ 1 ] ifFalse: [ -1 ]).
> floor
> ].
>
> stepChanges detectIndex: [ :each | each = -1 ] ifNone: [ 'invalid input
> yo' ].
>
>
>