Re: [Pharo-users] mentor question 4

2020-05-02 Thread Roelof Wobben via Pharo-users
--- Begin Message ---

Op 1-5-2020 om 08:35 schreef Roelof Wobben:

Op 1-5-2020 om 02:51 schreef Richard O'Keefe:

(oddSum + evenSum) dividedBy: 10

You previously had _ isDivisibleBy: 10
which certainly works.

Squeak, Pharo, and ST/X have #isDivisibleBy:
VisualWorks. Dolphin, and GNU Smalltalk do not.

Here's the code from Number.st in ST/X.
isDivisibleBy:aNumber
 "return true, if the receiver can be divided by the argument,
aNumber without a remainder.
  Notice, that the result is only worth trusting, if the receiver
is an integer."

 aNumber = 0 ifTrue: [^ false].
 aNumber isInteger ifFalse: [^ false].
 ^ (self \\ aNumber) = 0

The comment is wrong: the question makes sense for any combination
of exact numbers.
When, as in this case, aNumber is a literal integer, all
#isDivisibleBy: really adds is overhead.

(oddSum + evenSum) \\ 10 = 0

is quite clear, and completely portable.



On Fri, 1 May 2020 at 02:16, Roelof Wobben  wrote:

Op 30-4-2020 om 16:06 schreef Richard O'Keefe:

This sounds very much like the Luhn test task at RosettaCode.
https://rosettacode.org/wiki/Luhn_test_of_credit_card_numbers
except that there it is described as working on the digits of an
integer.

(1) There are two approaches to traversing a sequence in reverse.
  (A) Reverse the sequence, then traverse the copy forward.
  aString reverse do: [:each | ...]
  (B) Just traverse the sequence in reverse
  aString reverseDo: [:each | ...]
  My taste is for the second.

(2) There are two approaches to deleting spaces.
  (A) Make a copy of the string without spaces.
  x := aString reject: [:each | each = Character space].
  x do: ...
  (B) Ignore spaces as you go:
  (i) aString do: [:each | each = Character space ifFalse: 
[...]]
  (ii) aString select: [:each | each ~= Character space] 
thenDo:

[:each | ...]

Combining (1A) and (2A) you get very obvious code:
  (aString reject: [:each | each = Character space]) reverse do:
[:digit } ...]
Combining (1B) and (2Bi) you get more efficient code:
  aString reverseDo: [:digit |
  digit = Character space ifFalse: [ ...]]

By the way, let's start by checking that the character in the 
string *are*

digits or spaces:
  (aString allSatisfy: [:each | each isDigit or: [each = 
Character s[ace]])

  ifFalse: [^false],

(3) There are two approaches to doubling the even digits.
  (A) Make a new string that starts as a copy and change every 
second

   digit from the right.
  (B) Simply *act* as if this has been done; keep track of 
whether the
  current digit position is even or odd and multiply by 1 
or 2 as

  appropriate.
  nextIsOdd := true.
  aString reverseDo: [:digit |
  digit = Character space ifFalse: [
  nextIsOdd
  ifTrue:  [oddSum := ...]
  ifFalse: [evenSum := ...].
  nextIsOdd := nextIsOdd not]].

I *like* code that traverses a data structure exactly once and
allocates no intermediate garbage, so I'd be making (B) choices.


For me  , I use this to practice solving problems  and doing the 
"right"

steps.
So I love it , that so many people share there way of solving it.
I can learn a lot from it
Expecially when they explain there thinking process so detailed.

I like this code also a lot.
Am  I correct for testing if it is a valid string by doing this ^
(oddSum + evenSum) dividedBy: 10

Roelof




oke,

so this is better

cardNumber := '8273 1232 7352 0569'.
oddSum := 0.
evenSum := 0.
nextIsOdd := false.
 cardNumber reverseDo: [:character |
      digit := character digitValue.
 character = Character space ifFalse: [
 nextIsOdd
 ifFalse:  [oddSum := oddSum + digit ]
 ifTrue: [(digit >= 5 )
    ifTrue: [evenSum := evenSum + (digit * 2) - 9 ]
    ifFalse: [ evenSum := evenSum + (digit * 2) ]].
    nextIsOdd := nextIsOdd not]].
^ evenSum + oddSum // 10 == 0.


where I could even make a seperate method of the ifTrue branch when 
the digit is greater then 5.




nobody who can say if this is a good solution ?

Roelof

--- End Message ---


[Pharo-users] Spec2 SpStringTableColumn

2020-05-02 Thread Tomaž Turk

Dear all,

I'm exploring the new Spec2, looking for possibilities to create an 
'editable grid'. Tables are very close to this concept, and I wonder 
what exactly is SpStringTableColumn>>#beEditable supposed to do - I 
cannot find any references to variable 'editable', so it looks like it's 
not implemented yet?


Could editable grid be mimicked somehow with SpCompositeTableColumn?

Besides this, I wonder whether Spec2 could control keyboard events?

Many thanks and best wishes,
Tomaz

Re: [Pharo-users] Thinking aloud about project at hand

2020-05-02 Thread eftomi
> I'm thinking about implementing a software solution in Pharo (as one of the
candidate environments), it's
> a project that I'm dealing with professionally. The goal is to develop a
> financial planning/simulation
> application on the country level, which is at present developed as a set
> of interrelated Excel spreadsheets.
> The requirement is that the solution should be more "manageable",
> resilient and straightforward than
> Excel permits, that it should present a workflow to the user - i.e. , that
> the tasks the user should do are
> suggested through the GUI.

Thanks again for all the ideas regarding my project. So far I prepared the
domain model and all the calculations. The model might be changed in the
future, but that's basically it. Now I'm going to focus on the user's
workflow and GUI.

I have to say that I'm positively surprised by Pharo. Besides Pharo, I
explored the feasibility of using other environments for the same project,
namely VBA, .NET, Python. What took me in VBA and C#.NET roughly two weeks -
and these are my 'native' programming environments - I finished in five days
in Pharo. If GUI and finalization will go smoothly, this will be a success.
I'm playing with Pharo for some time, but until now I haven't done any
serious work with it. Nice!

Best wishes,
Tomaz





--
Sent from: http://forum.world.st/Pharo-Smalltalk-Users-f1310670.html



Re: [Pharo-users] mentor question 4

2020-05-02 Thread Richard Sargent
It's a good solution.

On Sat, May 2, 2020, 00:52 Roelof Wobben via Pharo-users <
pharo-users@lists.pharo.org> wrote:

> Op 1-5-2020 om 08:35 schreef Roelof Wobben:
> > Op 1-5-2020 om 02:51 schreef Richard O'Keefe:
> >> (oddSum + evenSum) dividedBy: 10
> >>
> >> You previously had _ isDivisibleBy: 10
> >> which certainly works.
> >>
> >> Squeak, Pharo, and ST/X have #isDivisibleBy:
> >> VisualWorks. Dolphin, and GNU Smalltalk do not.
> >>
> >> Here's the code from Number.st in ST/X.
> >> isDivisibleBy:aNumber
> >>  "return true, if the receiver can be divided by the argument,
> >> aNumber without a remainder.
> >>   Notice, that the result is only worth trusting, if the receiver
> >> is an integer."
> >>
> >>  aNumber = 0 ifTrue: [^ false].
> >>  aNumber isInteger ifFalse: [^ false].
> >>  ^ (self \\ aNumber) = 0
> >>
> >> The comment is wrong: the question makes sense for any combination
> >> of exact numbers.
> >> When, as in this case, aNumber is a literal integer, all
> >> #isDivisibleBy: really adds is overhead.
> >>
> >> (oddSum + evenSum) \\ 10 = 0
> >>
> >> is quite clear, and completely portable.
> >>
> >>
> >>
> >> On Fri, 1 May 2020 at 02:16, Roelof Wobben  wrote:
> >>> Op 30-4-2020 om 16:06 schreef Richard O'Keefe:
>  This sounds very much like the Luhn test task at RosettaCode.
>  https://rosettacode.org/wiki/Luhn_test_of_credit_card_numbers
>  except that there it is described as working on the digits of an
>  integer.
> 
>  (1) There are two approaches to traversing a sequence in reverse.
>    (A) Reverse the sequence, then traverse the copy forward.
>    aString reverse do: [:each | ...]
>    (B) Just traverse the sequence in reverse
>    aString reverseDo: [:each | ...]
>    My taste is for the second.
> 
>  (2) There are two approaches to deleting spaces.
>    (A) Make a copy of the string without spaces.
>    x := aString reject: [:each | each = Character space].
>    x do: ...
>    (B) Ignore spaces as you go:
>    (i) aString do: [:each | each = Character space ifFalse:
>  [...]]
>    (ii) aString select: [:each | each ~= Character space]
>  thenDo:
>  [:each | ...]
> 
>  Combining (1A) and (2A) you get very obvious code:
>    (aString reject: [:each | each = Character space]) reverse do:
>  [:digit } ...]
>  Combining (1B) and (2Bi) you get more efficient code:
>    aString reverseDo: [:digit |
>    digit = Character space ifFalse: [ ...]]
> 
>  By the way, let's start by checking that the character in the
>  string *are*
>  digits or spaces:
>    (aString allSatisfy: [:each | each isDigit or: [each =
>  Character s[ace]])
>    ifFalse: [^false],
> 
>  (3) There are two approaches to doubling the even digits.
>    (A) Make a new string that starts as a copy and change every
>  second
> digit from the right.
>    (B) Simply *act* as if this has been done; keep track of
>  whether the
>    current digit position is even or odd and multiply by 1
>  or 2 as
>    appropriate.
>    nextIsOdd := true.
>    aString reverseDo: [:digit |
>    digit = Character space ifFalse: [
>    nextIsOdd
>    ifTrue:  [oddSum := ...]
>    ifFalse: [evenSum := ...].
>    nextIsOdd := nextIsOdd not]].
> 
>  I *like* code that traverses a data structure exactly once and
>  allocates no intermediate garbage, so I'd be making (B) choices.
> 
> 
> >>> For me  , I use this to practice solving problems  and doing the
> >>> "right"
> >>> steps.
> >>> So I love it , that so many people share there way of solving it.
> >>> I can learn a lot from it
> >>> Expecially when they explain there thinking process so detailed.
> >>>
> >>> I like this code also a lot.
> >>> Am  I correct for testing if it is a valid string by doing this ^
> >>> (oddSum + evenSum) dividedBy: 10
> >>>
> >>> Roelof
> >>>
> >
> >
> > oke,
> >
> > so this is better
> >
> > cardNumber := '8273 1232 7352 0569'.
> > oddSum := 0.
> > evenSum := 0.
> > nextIsOdd := false.
> >  cardNumber reverseDo: [:character |
> >   digit := character digitValue.
> >  character = Character space ifFalse: [
> >  nextIsOdd
> >  ifFalse:  [oddSum := oddSum + digit ]
> >  ifTrue: [(digit >= 5 )
> > ifTrue: [evenSum := evenSum + (digit * 2) - 9 ]
> > ifFalse: [ evenSum := evenSum + (digit * 2) ]].
> > nextIsOdd := nextIsOdd not]].
> > ^ evenSum + oddSum // 10 == 0.
> >
> >
> > where I could even make a seperate method of the ifTrue branch when
> > the digit is greater then 5.
> >
> >
> nobody who can say if this is a good solution ?
>
> Roelof
>
>


Re: [Pharo-users] mentor question 4

2020-05-02 Thread Ben Coman
On Sat, 2 May 2020 at 15:52, Roelof Wobben via Pharo-users <
pharo-users@lists.pharo.org> wrote:

> Op 1-5-2020 om 08:35 schreef Roelof Wobben:
> >> On Fri, 1 May 2020 at 02:16, Roelof Wobben  wrote:
> >>> Op 30-4-2020 om 16:06 schreef Richard O'Keefe:
>  This sounds very much like the Luhn test task at RosettaCode.
>  https://rosettacode.org/wiki/Luhn_test_of_credit_card_numbers
>  except that there it is described as working on the digits of an
>  integer.
> 
>  (1) There are two approaches to traversing a sequence in reverse.
>    (A) Reverse the sequence, then traverse the copy forward.
>    aString reverse do: [:each | ...]
>    (B) Just traverse the sequence in reverse
>    aString reverseDo: [:each | ...]
>    My taste is for the second.
> 
>  (2) There are two approaches to deleting spaces.
>    (A) Make a copy of the string without spaces.
>    x := aString reject: [:each | each = Character space].
>    x do: ...
>    (B) Ignore spaces as you go:
>    (i) aString do: [:each | each = Character space ifFalse:
>  [...]]
>    (ii) aString select: [:each | each ~= Character space]
>  thenDo:
>  [:each | ...]
> 
>  Combining (1A) and (2A) you get very obvious code:
>    (aString reject: [:each | each = Character space]) reverse do:
>  [:digit } ...]
>  Combining (1B) and (2Bi) you get more efficient code:
>    aString reverseDo: [:digit |
>    digit = Character space ifFalse: [ ...]]
> 
>  By the way, let's start by checking that the character in the
>  string *are*
>  digits or spaces:
>    (aString allSatisfy: [:each | each isDigit or: [each =
>  Character s[ace]])
>    ifFalse: [^false],
> 
>  (3) There are two approaches to doubling the even digits.
>    (A) Make a new string that starts as a copy and change every
>  second
> digit from the right.
>    (B) Simply *act* as if this has been done; keep track of
>  whether the
>    current digit position is even or odd and multiply by 1
>  or 2 as
>    appropriate.
>    nextIsOdd := true.
>    aString reverseDo: [:digit |
>    digit = Character space ifFalse: [
>    nextIsOdd
>    ifTrue:  [oddSum := ...]
>    ifFalse: [evenSum := ...].
>    nextIsOdd := nextIsOdd not]].
> 
>  I *like* code that traverses a data structure exactly once and
>  allocates no intermediate garbage, so I'd be making (B) choices.
> 
> 
> >>> For me  , I use this to practice solving problems  and doing the
> >>> "right"
> >>> steps.
> >>> So I love it , that so many people share there way of solving it.
> >>> I can learn a lot from it
> >>> Expecially when they explain there thinking process so detailed.
> >>>
> >>> I like this code also a lot.
> >>> Am  I correct for testing if it is a valid string by doing this ^
> >>> (oddSum + evenSum) dividedBy: 10
> >>>
> >>> Roelof
> >>>
> >
> >
> > oke,
> >
> > so this is better
> >
> > cardNumber := '8273 1232 7352 0569'.
> > oddSum := 0.
> > evenSum := 0.
> > nextIsOdd := false.
> >  cardNumber reverseDo: [:character |
> >   digit := character digitValue.
> >  character = Character space ifFalse: [
> >  nextIsOdd
> >  ifFalse:  [oddSum := oddSum + digit ]
> >  ifTrue: [(digit >= 5 )
> > ifTrue: [evenSum := evenSum + (digit * 2) - 9 ]
> > ifFalse: [ evenSum := evenSum + (digit * 2) ]].
> > nextIsOdd := nextIsOdd not]].
> > ^ evenSum + oddSum // 10 == 0.
> >
> >
> > where I could even make a seperate method of the ifTrue branch when
> > the digit is greater then 5.
> >
> >
> nobody who can say if this is a good solution ?
>

You didn't actually ask a question :)

btw, Its good you are stretching yourself to do it the most complicated
way,
but pay attention that when Richard says HE "likes code that traverses a
data structure exactly once"
its because he is starting with the philosophy to OPTIMISE for EFFICIENCY.
Often in programming that is the LAST thing you should do because to do so
your code often becomes more complex,
and Kernagan's law applies...
https://talixa.com/blog/why-i-write-simple-code/

In general, you want to avoid premature optimization.
https://effectiviology.com/premature-optimization/

The catch-phrase I see around this forum priorities things in this order:
1. Make it work.
2. Make it right.
3. Make it fast.
and often you can stop at 2 because it is already "fast enough".

Considering your code above, if I take TIME to go through it, I can
evaluate that it seems right
but I remain feeling that I could have missed something.

Something like Richard's (A) examples without loops  I would consider to be
"more good".
since each line can be

Re: [Pharo-users] mentor question 4

2020-05-02 Thread Roelof Wobben via Pharo-users
--- Begin Message ---

  
  
Op 2-5-2020 om 19:33 schreef Ben Coman:


  
  




  On Sat, 2 May 2020 at 15:52,
Roelof Wobben via Pharo-users 
wrote:
  
  Op 1-5-2020 om 08:35
schreef Roelof Wobben:
>> On Fri, 1 May 2020 at 02:16, Roelof Wobben  wrote:
>>> Op 30-4-2020 om 16:06 schreef Richard O'Keefe:
 This sounds very much like the Luhn test
task at RosettaCode.
 https://rosettacode.org/wiki/Luhn_test_of_credit_card_numbers
 except that there it is described as
working on the digits of an
 integer.

 (1) There are two approaches to traversing
a sequence in reverse.
   (A) Reverse the sequence, then
traverse the copy forward.
   aString reverse do: [:each | ...]
   (B) Just traverse the sequence in
reverse
   aString reverseDo: [:each | ...]
   My taste is for the second.

 (2) There are two approaches to deleting
spaces.
   (A) Make a copy of the string without
spaces.
   x := aString reject: [:each |
each = Character space].
   x do: ...
   (B) Ignore spaces as you go:
   (i) aString do: [:each | each =
Character space ifFalse: 
 [...]]
   (ii) aString select: [:each |
each ~= Character space] 
 thenDo:
 [:each | ...]

 Combining (1A) and (2A) you get very
obvious code:
   (aString reject: [:each | each =
Character space]) reverse do:
 [:digit } ...]
 Combining (1B) and (2Bi) you get more
efficient code:
   aString reverseDo: [:digit |
   digit = Character space ifFalse:
[ ...]]

 By the way, let's start by checking that
the character in the 
 string *are*
 digits or spaces:
   (aString allSatisfy: [:each | each
isDigit or: [each = 
 Character s[ace]])
   ifFalse: [^false],

 (3) There are two approaches to doubling
the even digits.
   (A) Make a new string that starts as
a copy and change every 
 second
    digit from the right.
   (B) Simply *act* as if this has been
done; keep track of 
 whether the
   current digit position is even or
odd and multiply by 1 
 or 2 as
   appropriate.
   nextIsOdd := true.
   aString reverseDo: [:digit |
   digit = Character space ifFalse:
[
   nextIsOdd
   ifTrue:  [oddSum := ...]
   ifFalse: [evenSum := ...].
   nextIsOdd := nextIsOdd not]].

 I *like* code that traverses a data
structure exactly once and
 allocates no intermediate garbage, so I'd
be making (B) choices.


>>> For me  , I use this to practice solving
problems  and doing the 
>>> "right"
>>> steps.
>>> So I love it , that so many people share there
way of solving it.
>>> I can learn a lot from it
>>> Expecially when they explain there thinking
process so detailed.
>>>
>>> I like this code also a lot.
>>> Am  I correct for testing if it is a valid
string by doing this ^
>>> (oddSum + evenSum) dividedBy: 10
>>>
>>> Roelof
>>>
>
>
> oke,
>
> so this is better
>
> cardNumber := '8273 1232 7352 0569'.
> oddSum := 0.
> evenSum := 0.
> nextIsOdd := false.
>  cardNumber reverseDo: [:character |
>       digit := character digitValue.
>  character = Character space ifFalse: [
>  nextIsOdd
>  ifFalse:  [oddSum := oddSum + digit ]
>  ifTr

Re: [Pharo-users] mentor question 4

2020-05-02 Thread Roelof Wobben via Pharo-users
--- Begin Message ---

Op 2-5-2020 om 21:09 schreef Roelof Wobben via Pharo-users:


but this seems to work :

cardNumber := '4539 1488 0343 6467'.
cleanDigits := cardNumber copyWithout: Character space.
preWrapDigits := (cleanDigits asArray reverse collectWithIndex: [ :char 
:idx | (idx even) ifTrue: [ 2 * char digitValue ] ifFalse:[char 
digitValue]]).
wrappedDigits :=  preWrapDigits collect: [ :d | d > 9 ifFalse: [ d ] 
ifTrue: [ d-9 ] ].

^ wrappedDigits sum isDivisibleBy: 10.

Can the code be more improved ?

Roelof


--- End Message ---


Re: [Pharo-users] mentor question 4

2020-05-02 Thread Stéphane Ducasse
check with the finder and example

S. 


> On 2 May 2020, at 21:09, Roelof Wobben  wrote:
> 
> 
> From: Roelof Wobben 
> Subject: Re: [Pharo-users] mentor question 4
> Date: 2 May 2020 at 21:09:12 CEST
> To: Ben Coman , Any question about pharo is welcome 
> 
> 
> 
> Op 2-5-2020 om 19:33 schreef Ben Coman:
>> 
>> 
>> On Sat, 2 May 2020 at 15:52, Roelof Wobben via Pharo-users 
>> mailto:pharo-users@lists.pharo.org>> wrote:
>> Op 1-5-2020 om 08:35 schreef Roelof Wobben:
>> >> On Fri, 1 May 2020 at 02:16, Roelof Wobben > >> > wrote:
>> >>> Op 30-4-2020 om 16:06 schreef Richard O'Keefe:
>>  This sounds very much like the Luhn test task at RosettaCode.
>>  https://rosettacode.org/wiki/Luhn_test_of_credit_card_numbers 
>>  
>>  except that there it is described as working on the digits of an
>>  integer.
>> 
>>  (1) There are two approaches to traversing a sequence in reverse.
>>    (A) Reverse the sequence, then traverse the copy forward.
>>    aString reverse do: [:each | ...]
>>    (B) Just traverse the sequence in reverse
>>    aString reverseDo: [:each | ...]
>>    My taste is for the second.
>> 
>>  (2) There are two approaches to deleting spaces.
>>    (A) Make a copy of the string without spaces.
>>    x := aString reject: [:each | each = Character space].
>>    x do: ...
>>    (B) Ignore spaces as you go:
>>    (i) aString do: [:each | each = Character space ifFalse: 
>>  [...]]
>>    (ii) aString select: [:each | each ~= Character space] 
>>  thenDo:
>>  [:each | ...]
>> 
>>  Combining (1A) and (2A) you get very obvious code:
>>    (aString reject: [:each | each = Character space]) reverse do:
>>  [:digit } ...]
>>  Combining (1B) and (2Bi) you get more efficient code:
>>    aString reverseDo: [:digit |
>>    digit = Character space ifFalse: [ ...]]
>> 
>>  By the way, let's start by checking that the character in the 
>>  string *are*
>>  digits or spaces:
>>    (aString allSatisfy: [:each | each isDigit or: [each = 
>>  Character s[ace]])
>>    ifFalse: [^false],
>> 
>>  (3) There are two approaches to doubling the even digits.
>>    (A) Make a new string that starts as a copy and change every 
>>  second
>> digit from the right.
>>    (B) Simply *act* as if this has been done; keep track of 
>>  whether the
>>    current digit position is even or odd and multiply by 1 
>>  or 2 as
>>    appropriate.
>>    nextIsOdd := true.
>>    aString reverseDo: [:digit |
>>    digit = Character space ifFalse: [
>>    nextIsOdd
>>    ifTrue:  [oddSum := ...]
>>    ifFalse: [evenSum := ...].
>>    nextIsOdd := nextIsOdd not]].
>> 
>>  I *like* code that traverses a data structure exactly once and
>>  allocates no intermediate garbage, so I'd be making (B) choices.
>> 
>> 
>> >>> For me  , I use this to practice solving problems  and doing the 
>> >>> "right"
>> >>> steps.
>> >>> So I love it , that so many people share there way of solving it.
>> >>> I can learn a lot from it
>> >>> Expecially when they explain there thinking process so detailed.
>> >>>
>> >>> I like this code also a lot.
>> >>> Am  I correct for testing if it is a valid string by doing this ^
>> >>> (oddSum + evenSum) dividedBy: 10
>> >>>
>> >>> Roelof
>> >>>
>> >
>> >
>> > oke,
>> >
>> > so this is better
>> >
>> > cardNumber := '8273 1232 7352 0569'.
>> > oddSum := 0.
>> > evenSum := 0.
>> > nextIsOdd := false.
>> >  cardNumber reverseDo: [:character |
>> >   digit := character digitValue.
>> >  character = Character space ifFalse: [
>> >  nextIsOdd
>> >  ifFalse:  [oddSum := oddSum + digit ]
>> >  ifTrue: [(digit >= 5 )
>> > ifTrue: [evenSum := evenSum + (digit * 2) - 9 ]
>> > ifFalse: [ evenSum := evenSum + (digit * 2) ]].
>> > nextIsOdd := nextIsOdd not]].
>> > ^ evenSum + oddSum // 10 == 0.
>> >
>> >
>> > where I could even make a seperate method of the ifTrue branch when 
>> > the digit is greater then 5.
>> >
>> >
>> nobody who can say if this is a good solution ?
>> 
>> You didn't actually ask a question :)
>> 
>> btw, Its good you are stretching yourself to do it the most complicated way, 
>> but pay attention that when Richard says HE "likes code that traverses a 
>> data structure exactly once"
>> its because he is starting with the philosophy to OPTIMISE for EFFICIENCY.
>> Often in programming that is the LAST thing you should do because to do so 
>> your code often becomes more complex,
>> and Kernagan's law applies...
>> https://talixa.com/blog/why-i-write-si

Re: [Pharo-users] Thinking aloud about project at hand

2020-05-02 Thread Stéphane Ducasse


> 
>> I'm thinking about implementing a software solution in Pharo (as one of the
> candidate environments), it's
>> a project that I'm dealing with professionally. The goal is to develop a
>> financial planning/simulation
>> application on the country level, which is at present developed as a set
>> of interrelated Excel spreadsheets.
>> The requirement is that the solution should be more "manageable",
>> resilient and straightforward than
>> Excel permits, that it should present a workflow to the user - i.e. , that
>> the tasks the user should do are
>> suggested through the GUI.
> 
> Thanks again for all the ideas regarding my project. So far I prepared the
> domain model and all the calculations. The model might be changed in the
> future, but that's basically it. Now I'm going to focus on the user's
> workflow and GUI.
> 
> I have to say that I'm positively surprised by Pharo. Besides Pharo, I
> explored the feasibility of using other environments for the same project,
> namely VBA, .NET, Python. What took me in VBA and C#.NET roughly two weeks -
> and these are my 'native' programming environments - I finished in five days
> in Pharo. If GUI and finalization will go smoothly, this will be a success.
> I'm playing with Pharo for some time, but until now I haven't done any
> serious work with it. Nice!
> 

Thanks Tomaz.
This is a really interesting story. 
Let us know and we will do our best to help you. 
Spec20 has still some rough edges. But one step at a time. 
I think that we will get to a point where we can start to breath a bit around 
Spec2.0.

S. 




Re: [Pharo-users] mentor question 4

2020-05-02 Thread Richard Sargent
On Sat, May 2, 2020 at 12:38 PM Roelof Wobben via Pharo-users <
pharo-users@lists.pharo.org> wrote:

> Op 2-5-2020 om 21:09 schreef Roelof Wobben via Pharo-users:
>
>
> but this seems to work :
>
> cardNumber := '4539 1488 0343 6467'.
> cleanDigits := cardNumber copyWithout: Character space.
> preWrapDigits := (cleanDigits asArray reverse collectWithIndex: [ :char
> :idx | (idx even) ifTrue: [ 2 * char digitValue ] ifFalse:[char
> digitValue]]).
> wrappedDigits :=  preWrapDigits collect: [ :d | d > 9 ifFalse: [ d ]
> ifTrue: [ d-9 ] ].
> ^ wrappedDigits sum isDivisibleBy: 10.
>
> Can the code be more improved ?
>

As a general guideline, the best code will correspond closely to the
documented algorithm.

In this latest example, you have two visible loop iterations plus to hidden
loop iterations. It also includes object creation from both #asArray and
#reverse, the two messages with the hidden loop iteration.

For this exercise, the number of loops and object creations isn't relevant.
However, you always want to understand when you are doing such things. They
will have an impact if they are used inside a high frequency loop. Again,
that's not the case with this exercise. It often is in real world
applications.

But again, you should not optimize for performance at the expense of
clarity and readability until you need to. And when you do need to, you
annotate the code to explain how the implementation corresponds to or
differs from the more comprehensible implementation. (Comments should
explain the why and/or the background rather than the what.)



> Roelof
>
>
>


Re: [Pharo-users] [ANN] Pharo Compendium

2020-05-02 Thread Gabriel Cotelli
Really cool Torsten!. A much needed tool :)

On Sat, May 2, 2020 at 5:35 PM Torsten Bergmann  wrote:

> Hi,
>
> time flows and Pharo-Project is improving on all ends since its inception
> in 2008. As you know over time for the code project hosting we used
> SqueakSource, SS3 repos and other and later switched to SmalltalkHub
> available on http://smalltalkhub.com.
> Starting with Iceberg in Pharo 6 many community projects are now hosted
> elsewhere - most of them moved to GitHub. Pharo's git support allows
> also for GitLab, BitBucket and other git hosting services.
>
> I still think easy and quick accessibility to external (re)sources
> directly from the image is key - especially for new users who often get lost
> among all the various things that are available. Back in 2013 I therefore
> provided a small tool called ConfigBrowser as a replacement for
> MetacelloConfigurationBrowser to easily load Metacello configs directly
> into Pharo.
>
> Later we improved quick loading with a primary tool called "Catalog"
> written by Esteban. Catalog is indexing every 24 hours all configs within
> specific meta-repositories on SmalltalkHub (per Pharo version) like
>
>   http://www.smalltalkhub.com/#!/~Pharo/MetaRepoForPharo80
>
> to automatically build
>
>http://catalog.pharo.org/
>
> and also a JSON source
>
>http://catalog.pharo.org/catalog/json
>
> The last one feeds the catalog browser and catalog spotter search within
> the Pharo image.
>
> So Catalog helped us and especially new Pharo users to find what is
> available as external project or package. Unfortunately some package
> maintainers
> are too lazy and do not maintain their configs over old and new Pharo
> versions. Also SmalltalkHub.com is now seen as legacy and will only be
> available
> in a read only mode or as a browseable archive soon.
>
> So we have to think about others steps beyond Catalog and (triggered by a
> recent discussion on Discord) I started now a simple tool that helped me
> finding all GitHub projects marked with "pharo" as GitHub topic. I
> additionally also added previous catalog loading. More sources could be
> added
> as well as some kind of custom stores/plugins. Maybe this tool could be
> the base for a future replacement of the catalog tool.
>
> Long story short - let me introduce "Pharo Compendium":
>
> Compendium is a new UI tool to list, browse and load Pharo artefacts from
> the web like:
>
>  - GitHub Projects
>  - Catalog Projects
>
> and other
>
> By default there are two plugin packages available for GitHub and Catalog
> - but you can implement own ones easily to connect to other sources
> on the web. Compendium is available on:
>
>https://github.com/astares/Pharo-Compendium
>
> It is implemented using the new Spec2 UI framework - so you need a recent
> Pharo 9 image to give it a try. Just run:
>
> Metacello new
> repository: 'github://astares/Pharo-Compendium/src';
> baseline: 'Compendium';
> load
>
> to load the tool. Then go to "Tools" -> "Compendium Browser". Attached is
> a screenshot demoing the primary functionality.
>
> If you want your GitHub project to be listed in the tool you simply need
> to add the topic "pharo" to the GitHub repository on the GitHub webpage.
>
> Feel free to comment or help improving the tool by sending PR's.
>
> Thx
> T. (aka astares)
>
>
>


Re: [Pharo-users] mentor question 4

2020-05-02 Thread Ben Coman
On Sun, 3 May 2020 at 03:09, Roelof Wobben  wrote:

> Op 2-5-2020 om 19:33 schreef Ben Coman:
>
>
>
> On Sat, 2 May 2020 at 15:52, Roelof Wobben via Pharo-users <
> pharo-users@lists.pharo.org> wrote:
>
>> Op 1-5-2020 om 08:35 schreef Roelof Wobben:
>> >> On Fri, 1 May 2020 at 02:16, Roelof Wobben  wrote:
>> >>> Op 30-4-2020 om 16:06 schreef Richard O'Keefe:
>>  This sounds very much like the Luhn test task at RosettaCode.
>>  https://rosettacode.org/wiki/Luhn_test_of_credit_card_numbers
>>  except that there it is described as working on the digits of an
>>  integer.
>> 
>>  (1) There are two approaches to traversing a sequence in reverse.
>>    (A) Reverse the sequence, then traverse the copy forward.
>>    aString reverse do: [:each | ...]
>>    (B) Just traverse the sequence in reverse
>>    aString reverseDo: [:each | ...]
>>    My taste is for the second.
>> 
>>  (2) There are two approaches to deleting spaces.
>>    (A) Make a copy of the string without spaces.
>>    x := aString reject: [:each | each = Character space].
>>    x do: ...
>>    (B) Ignore spaces as you go:
>>    (i) aString do: [:each | each = Character space ifFalse:
>>  [...]]
>>    (ii) aString select: [:each | each ~= Character space]
>>  thenDo:
>>  [:each | ...]
>> 
>>  Combining (1A) and (2A) you get very obvious code:
>>    (aString reject: [:each | each = Character space]) reverse do:
>>  [:digit } ...]
>>  Combining (1B) and (2Bi) you get more efficient code:
>>    aString reverseDo: [:digit |
>>    digit = Character space ifFalse: [ ...]]
>> 
>>  By the way, let's start by checking that the character in the
>>  string *are*
>>  digits or spaces:
>>    (aString allSatisfy: [:each | each isDigit or: [each =
>>  Character s[ace]])
>>    ifFalse: [^false],
>> 
>>  (3) There are two approaches to doubling the even digits.
>>    (A) Make a new string that starts as a copy and change every
>>  second
>> digit from the right.
>>    (B) Simply *act* as if this has been done; keep track of
>>  whether the
>>    current digit position is even or odd and multiply by 1
>>  or 2 as
>>    appropriate.
>>    nextIsOdd := true.
>>    aString reverseDo: [:digit |
>>    digit = Character space ifFalse: [
>>    nextIsOdd
>>    ifTrue:  [oddSum := ...]
>>    ifFalse: [evenSum := ...].
>>    nextIsOdd := nextIsOdd not]].
>> 
>>  I *like* code that traverses a data structure exactly once and
>>  allocates no intermediate garbage, so I'd be making (B) choices.
>> 
>> 
>> >>> For me  , I use this to practice solving problems  and doing the
>> >>> "right"
>> >>> steps.
>> >>> So I love it , that so many people share there way of solving it.
>> >>> I can learn a lot from it
>> >>> Expecially when they explain there thinking process so detailed.
>> >>>
>> >>> I like this code also a lot.
>> >>> Am  I correct for testing if it is a valid string by doing this ^
>> >>> (oddSum + evenSum) dividedBy: 10
>> >>>
>> >>> Roelof
>> >>>
>> >
>> >
>> > oke,
>> >
>> > so this is better
>> >
>> > cardNumber := '8273 1232 7352 0569'.
>> > oddSum := 0.
>> > evenSum := 0.
>> > nextIsOdd := false.
>> >  cardNumber reverseDo: [:character |
>> >   digit := character digitValue.
>> >  character = Character space ifFalse: [
>> >  nextIsOdd
>> >  ifFalse:  [oddSum := oddSum + digit ]
>> >  ifTrue: [(digit >= 5 )
>> > ifTrue: [evenSum := evenSum + (digit * 2) - 9 ]
>> > ifFalse: [ evenSum := evenSum + (digit * 2) ]].
>> > nextIsOdd := nextIsOdd not]].
>> > ^ evenSum + oddSum // 10 == 0.
>> >
>> >
>> > where I could even make a seperate method of the ifTrue branch when
>> > the digit is greater then 5.
>> >
>> >
>> nobody who can say if this is a good solution ?
>>
>
> You didn't actually ask a question :)
>
> btw, Its good you are stretching yourself to do it the most complicated
> way,
> but pay attention that when Richard says HE "likes code that traverses a
> data structure exactly once"
> its because he is starting with the philosophy to OPTIMISE for EFFICIENCY.
> Often in programming that is the LAST thing you should do because to do so
> your code often becomes more complex,
> and Kernagan's law applies...
> https://talixa.com/blog/why-i-write-simple-code/
>
> In general, you want to avoid premature optimization.
> https://effectiviology.com/premature-optimization/
>
> The catch-phrase I see around this forum priorities things in this order:
> 1. Make it work.
> 2. Make it right.
> 3. Make it fast.
> and often you can stop at 2 because it is already "fast enough".
>
> Considering your c