exercism / pharo-smalltalk

Exercism exercises in Pharo.
https://exercism.org/tracks/pharo-smalltalk
MIT License
34 stars 28 forks source link

Building a training set of tags for pharo-smalltalk #596

Closed ErikSchierboom closed 1 year ago

ErikSchierboom commented 1 year ago

Hello lovely maintainers :wave:

We've recently added "tags" to student's solutions. These express the constructs, paradigms and techniques that a solution uses. We are going to be using these tags for lots of things including filtering, pointing a student to alternative approaches, and much more.

In order to do this, we've built out a full AST-based tagger in C#, which has allowed us to do things like detect recursion or bit shifting. We've set things up so other tracks can do the same for their languages, but its a lot of work, and we've determined that actually it may be unnecessary. Instead we think that we can use machine learning to achieve tagging with good enough results. We've fine-tuned a model that can determine the correct tags for C# from the examples with a high success rate. It's also doing reasonably well in an untrained state for other languages. We think that with only a few examples per language, we can potentially get some quite good results, and that we can then refine things further as we go.

I released a new video on the Insiders page that talks through this in more detail.

We're going to be adding a fully-fledged UI in the coming weeks that allow maintainers and mentors to tag solutions and create training sets for the neural networks, but to start with, we're hoping you would be willing to manually tag 20 solutions for this track. In this post we'll add 20 comments, each with a student's solution, and the tags our model has generated. Your mission (should you choose to accept it) is to edit the tags on each issue, removing any incorrect ones, and add any that are missing. In order to build one model that performs well across languages, it's best if you stick as closely as possible to the C# tags as you can. Those are listed here. If you want to add extra tags, that's totally fine, but please don't arbitrarily reword existing tags, even if you don't like what Erik's chosen, as it'll just make it less likely that your language gets the correct tags assigned by the neural network.


To summarise - there are two paths forward for this issue:

  1. You're up for helping: Add a comment saying you're up for helping. Update the tags some time in the next few days. Add a comment when you're done. We'll then add them to our training set and move forward.
  2. You not up for helping: No problem! Just please add a comment letting us know :)

If you tell us you're not able/wanting to help or there's no comment added, we'll automatically crowd-source this in a week or so.

Finally, if you have questions or want to discuss things, it would be best done on the forum, so the knowledge can be shared across all maintainers in all tracks.

Thanks for your help! :blue_heart:


Note: Meta discussion on the forum

ErikSchierboom commented 1 year ago

Exercise: two-fer

Code

"
I return a string based on a given (or not) name
"
Class {
    #name : #TwoFer,
    #superclass : #Object,
    #category : #'Exercism-TwoFer'
}

{ #category : #'two-fer' }
TwoFer >> who [
    ^ self who: 'you'
]

{ #category : #'two-fer' }
TwoFer >> who: aString [
    ^ 'One for ' , aString , ', one for me.'
]

Tags:

paradigm:object-oriented
paradigm:imperative
construct:method
construct:named-argument
construct:parameter
construct:property
construct:getter
construct:setter
construct:string
construct:class
construct:return
uses:Collection>>#,

Status: Work-in-progress TODO: duck-typing (or message sending, string concatenation

ErikSchierboom commented 1 year ago

Exercise: reverse-string

Code

"
#  ReverseString
"
Class {
    #name : #ReverseString,
    #superclass : #Object,
    #category : #'Exercism-ReverseString'
}

{ #category : #acccessing }
ReverseString >> reverseValue: aString [
    ^ aString
        inject: String new
        into: [ :reversedString :char | String with: char withAll: reversedString ]
]

Tags:

paradigm:object-oriented
paradigm:imperative
technique:enumeration
technique:higher-order-functions
construct:class
construct:constructor
construct:lambda
construct:method
construct:named-argument
construct:parameter
construct:string
construct:return
uses:Collection>>#inject:into:
ErikSchierboom commented 1 year ago

Exercise: leap

Code

"
I calculate whether a year is a leap year or not
"
Class {
    #name : #Leap,
    #superclass : #Object,
    #category : #'Exercism-Leap'
}

{ #category : #'leap-year' }
Leap >> isLeapYear: anInteger [
    ^ (anInteger isDivisibleBy: 400)
        or: ((anInteger isDivisibleBy: 4) and: (anInteger isDivisibleBy: 100) not)
]

Tags:

paradigm:object-oriented
paradigm:imperative
technique:boolean-logic
construct:class
construct:method
construct:named-argument
construct:parameter
construct:return
construct:logical-and
construct:logical-or
construct:logical-not
construct:boolean
construct:number
construct:integral-number
uses:Number>>#isDivisibleBy:
ErikSchierboom commented 1 year ago

Exercise: leap

Code

Class {
    #name : #Leap,
    #superclass : #Object,
    #category : #'Exercism-Leap'
}

{ #category : #utilties }
Leap >> leapYear: anInteger [
    "Answer true if the year is a leap year"

"   ^ Year isLeapYear: anInteger"
    ^ (anInteger \\ 4 ~= 0
        or: [ (anInteger isDivisibleBy: 100) and: [ anInteger \\ 400 ~= 0 ] ])
        not
]

Tags:

paradigm:object-oriented
paradigm:imperative
technique:boolean-logic
construct:lambda
construct:class
construct:method
construct:named-argument
construct:parameter
construct:return
construct:logical-and
construct:logical-or
construct:logical-not
construct:boolean
construct:number
construct:integral-number
uses:Number>>#isDivisibleBy:
uses:Number>>#\\
ErikSchierboom commented 1 year ago

Exercise: leap

Code

"
# LeapYear
"
Class {
    #name : #Leap,
    #superclass : #Object,
    #category : #'Exercism-Leap'
}

{ #category : #calculations }
Leap >> leapYear: aYear [
    | isStandardLeapYear isCentury isQuadCentury |
    isStandardLeapYear := aYear \\ 4 = 0.
    isCentury := aYear \\ 100 = 0.
    isQuadCentury := aYear \\ 400 = 0.
    ^ isStandardLeapYear & (isCentury not | isQuadCentury)
]

Tags:

paradigm:object-oriented
paradigm:imperative
technique:boolean-logic
construct:assignment
construct:class
construct:method
construct:named-argument
construct:parameter
construct:variable
construct:return
construct:logical-and
construct:logical-or
construct:logical-not
construct:boolean
construct:pattern-matching
construct:number
construct:integral-number
uses:Number>>#\\
ErikSchierboom commented 1 year ago

Exercise: hamming

Code

'From Pharo7.0.3 of 12 April 2019 [Build information: Pharo-7.0.3+build.158.sha.0903ade8a6c96633f07e0a7f1baa9a5d48cfdf55 (64 Bit)] on 16 May 2019 at 6:56:05.325376 pm'!Object subclass: #Hamming   instanceVariableNames: ''   classVariableNames: ''  poolDictionaries: ''    category: 'Exercise@Hamming'!!Hamming commentStamp: 'RichardOKeefe 5/16/2019 18:51' prior: 0!Here we groan again.!!Hamming methodsFor: 'as yet unclassified' stamp: 'RichardOKeefe 5/16/2019 18:55'!distanceStrand1: a strand2: b   |d| d := 0. a size = b size ifFalse: [      a isEmpty ifTrue: [self error: 'left strand must not be empty'].        b isEmpty ifTrue: [self error: 'right strand must not be empty'].       self error: 'left and right strands must be of equal length'].  a with: b do: [:x :y |      x = y ifFalse: [d := d + 1]].   ^d! !

Tags:

paradigm:object-oriented
paradigm:imperative
technique:boolean-logic
technique:exceptions
technique:higher-order-functions
construct:assignment
construct:variable
construct:lambda
construct:class
construct:method
construct:named-argument
construct:parameter
construct:return
construct:boolean
construct:pattern-matching
construct:number
construct:add
construct:list
construct:integral-number
uses:SequencableCollection>>#with:do: 
uses:Object>>#error: 
uses:Collection>>#size
uses:Collection>>#isEmpty
uses:Boolean>>ifTrue:
uses:Boolean>>ifFalse:
uses:Character>>#=
uses:Integer>>#+
ErikSchierboom commented 1 year ago

Exercise: space-age

Code

Tested on: 2021-08-07 18:46
8 run, 8 passes, 0 skipped, 0 failures, 0 errors 

Tags:

No tags generated

TODO: put a proper solution here

ErikSchierboom commented 1 year ago

Exercise: isogram

Code

Tested on: 2019-04-25 22:41
13 run, 13 passes, 0 skipped, 0 failures, 0 errors 

Tags:

construct:boolean
construct:class
construct:comment
construct:method
construct:nested:class
construct:parameter
construct:send
construct:sequence
construct:throw
construct:visibility
paradigm:object-oriented
technique:exceptions

TODO: put a proper solution here

ErikSchierboom commented 1 year ago

Exercise: isogram

Code

Class {
    #name : #Isogram,
    #superclass : #Object,
    #category : #'Exercise@Isogram'
}

{ #category : #predicates }
Isogram >> isIsogramPhrase: aString [
    | set |
    set := Set new.
    aString asLowercase onlyLetters do: [ :each | 
        set addIfNotPresent: each ifPresentDo: [ ^ false ] ].
    ^ true.
]

Tags:

paradigm:object-oriented
paradigm:imperative
technique:boolean-logic
technique:higher-order-functions
construct:assignment
construct:set
construct:variable
construct:lambda
construct:class
construct:method
construct:named-argument
construct:parameter
construct:return
construct:boolean
construct:pattern-matching
construct:string
uses:Object>>#new 
uses:String>>#asLowercase
uses:String>>#onlyLetters
uses:Set>>#addIfNotPresent:ifPresentDo:
ErikSchierboom commented 1 year ago

Exercise: grade-school

Code

Tested on: 2019-04-25 23:44
8 run, 8 passes, 0 skipped, 0 failures, 0 errors 

Tags:

No tags generated

TODO: put a proper solution here

ErikSchierboom commented 1 year ago

Exercise: etl

Code

'From Pharo7.0.3 of 12 April 2019 [Build information: Pharo-7.0.3+build.158.sha.0903ade8a6c96633f07e0a7f1baa9a5d48cfdf55 (64 Bit)] on 15 May 2019 at 9:40:28.846338 pm'!Object subclass: #Etl   instanceVariableNames: ''   classVariableNames: ''  poolDictionaries: ''    category: 'Exercise@Etl'!!Etl commentStamp: 'RichardOKeefe 5/15/2019 21:35' prior: 0!I am the usual dummy class for an Exercism task.  Guess which?I have no state and no identity-dependent behaviour.In fact I have only one method.Pathetic, isn't it.!!Etl methodsFor: 'as yet unclassified' stamp: 'RichardOKeefe 5/15/2019 21:39'!transformData: aDictionary  |mapping|   mapping := Dictionary new: 29.  aDictionary keysAndValuesDo: [:key :value | |score|     score := key asInteger.     value do: [:each |          mapping at:  each asLowercase put: score]]. ^mapping! !

Tags:

construct:assignment
construct:asLowercase
construct:comment
construct:dictionary
construct:do:
construct:double
construct:floatingPointNumber
construct:implicitConversion
construct:instanceVariable
construct:invocation
construct:method
construct:methodDeclaration
construct:nestedBlock
construct:number
construct:return
construct:variableDeclaration
construct:visibility
paradigm:functional
paradigm:imperative
paradigm:object-oriented
technique:higher-orderFunctions
uses:Dictionary
ErikSchierboom commented 1 year ago

Exercise: etl

Code

'From Pharo7.0.5 of 29 June 2020 [Build information: Pharo-7.0.5+build.177.sha.fd8c156d959653f52be6fd7f8c71edf8cfb8fe90 (64 Bit)] on 19 May 2021 at 11:56:47.429451 pm'!Object subclass: #Etl   instanceVariableNames: 'result' classVariableNames: ''  poolDictionaries: ''    category: 'Exercise@Etl'!!Etl commentStamp: 'TonyGiaccone 5/19/2021 12:18' prior: 0!extract transform load!!Etl methodsFor: 'initialization' stamp: 'TonyGiaccone 5/19/2021 23:54'!initialize   super initialize.   result := Dictionary new! !!Etl methodsFor: 'transforming' stamp: 'TonyGiaccone 5/19/2021 23:55'!map: key value: item   result at: key asLowercase put: item asInteger! !!Etl methodsFor: 'transforming' stamp: 'TonyGiaccone 5/19/2021 23:51'!transformData: input result := Dictionary new.   input       keysDo: [ :points |             (input at: points)              do: [ :letter | self map: letter value: points ]                 ]. ^ result! !

Tags:

construct:assignment
construct:block
construct:category
construct:class
construct:comment
construct:dictionary
construct:implicit-casting
construct:instance-variable
construct:invocation
construct:lambda
construct:method
construct:method-declaration
construct:nested-closure
construct:return
construct:super
construct:variable
construct:visibility-modifiers
paradigm:functional
paradigm:object-oriented
technique:higher-order-functions
uses:Dictionary
uses:OrderedCollection
ErikSchierboom commented 1 year ago

Exercise: clock

Code

'From Pharo7.0.3 of 12 April 2019 [Build information: Pharo-7.0.3+build.158.sha.0903ade8a6c96633f07e0a7f1baa9a5d48cfdf55 (64 Bit)] on 15 May 2019 at 9:13:12.228756 pm'!Object subclass: #Clock instanceVariableNames: 'minutes'    classVariableNames: ''  poolDictionaries: ''    category: 'Exercise@Clock'!!Clock commentStamp: 'RichardOKeefe 5/15/2019 20:50' prior: 0!I represent a Time on a 24-hour clock at a resolution of 1 minute,so I don't have to worry about leap seconds.To simplify comparison and arithmetic, I keep the time as thenumber of minutes since midnight.  0 <= minutes < 1440.!!Clock methodsFor: 'arithmetic' stamp: 'RichardOKeefe 5/15/2019 21:11'!+ delta  (delta isKindOf: Integer) ifFalse: [delta error: 'not Integer'].    ^self copy pvtMinutes: minutes + delta! !!Clock methodsFor: 'arithmetic' stamp: 'RichardOKeefe 5/15/2019 21:11'!- delta (delta isKindOf: Integer) ifFalse: [delta error: 'not Integer'].    ^self copy pvtMinutes: minutes - delta! !!Clock methodsFor: 'converting' stamp: 'RichardOKeefe 5/15/2019 21:04'!asString    ^self hour asTwoCharacterString , ':' , self minute asTwoCharacterString ! !!Clock methodsFor: 'equality' stamp: 'RichardOKeefe 5/15/2019 21:02'!= other    ^other class == self class and: [other minutes = self minutes]! !!Clock methodsFor: 'equality' stamp: 'RichardOKeefe 5/15/2019 21:01'!hash  ^minutes! !!Clock methodsFor: 'initializing' stamp: 'RichardOKeefe 5/15/2019 21:10'!pvtMinutes: m   minutes := m \\ 1440.   ^self! !!Clock methodsFor: 'acccessing' stamp: 'RichardOKeefe 5/15/2019 21:03'!hour ^minutes // 60! !!Clock methodsFor: 'acccessing' stamp: 'RichardOKeefe 5/15/2019 21:03'!minute  ^minutes \\ 60! !!Clock methodsFor: 'acccessing' stamp: 'RichardOKeefe 5/15/2019 21:03'!minutes     ^minutes! !"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!Clock class instanceVariableNames: ''!!Clock class methodsFor: 'instance creation' stamp: 'RichardOKeefe 5/15/2019 21:10'!hour: h minute: m (h isKindOf: Integer) ifFalse: [h error: 'not Integer'].    (m isKindOf: Integer) ifFalse: [m error: 'not Integer'].    ^self basicNew pvtMinutes: h*60+m! !

Tags:

construct:string
construct:,@
construct:assignment
construct:basicNew
construct:bitwiseAnd
construct:category
construct:class
construct:classVariable
construct:comment
construct:divide
construct:error
construct:ifTrue
construct:instanceVariable
construct:integralNumber
construct:invocation
construct:lambda
construct:logicalAnd
construct:method
construct:methodDeclaration
construct:multiply
construct:number
construct:parameter
construct:send
construct:smalltalk
construct:string
construct:subtract
construct:variable
construct:visibility
paradigm:functional
paradigm:imperative
paradigm:object-oriented
technique:bitwiseOperations
technique:booleanLogic
technique:exceptions
uses:Date
uses:Time
ErikSchierboom commented 1 year ago

Exercise: twelve-days

Code

Tested on: 2020-11-22 16:06
15 run, 15 passes, 0 skipped, 0 failures, 0 errors 

Tags:

No tags generated

TODO: put a proper solution here

ErikSchierboom commented 1 year ago

Exercise: atbash-cipher

Code

'From Pharo7.0.3 of 12 April 2019 [Build information: Pharo-7.0.3+build.158.sha.0903ade8a6c96633f07e0a7f1baa9a5d48cfdf55 (64 Bit)] on 15 May 2019 at 8:40:50.045143 pm'!Object subclass: #AtbashCipher  instanceVariableNames: ''   classVariableNames: ''  poolDictionaries: ''    category: 'Exercise@AtbashCipher'!!AtbashCipher commentStamp: 'RichardOKeefe 5/15/2019 20:08' prior: 0!I am a dummy class for the Atbash Cipher exercise.Everything that is not a letter or digit is discarded,and letters are converted to lower case.a..z are mapped to z..a, and the result is broken intogroups of five characters with spaces between.!!AtbashCipher methodsFor: 'as yet unclassified' stamp: 'RichardOKeefe 5/15/2019 20:29'!decodePhrase: aString    ^aString select: [:each | each isAlphaNumeric] thenCollect: [:each | |c|        c := each asLowercase.      c isLetter          ifTrue:  [Character codePoint: $a codePoint + $z codePoint - c codePoint]           ifFalse: [c]]! !!AtbashCipher methodsFor: 'as yet unclassified' stamp: 'RichardOKeefe 5/15/2019 20:29'!encodePhrase: aString    |s n|   s := self decodePhrase: aString.    "We want to split s into groups of 5 characters, with perhaps a short block at the end.  #groupsOf:atATimeCollect: is tantalisingly close to what we want, but it discards any   short block at the end.  So we have to get creative."  n := s size.    ^' ' join: ((1 to: n by: 5) collect: [:each | s copyFrom: each to: (each + 4 min: n)])          ! !

Tags:

construct:add
construct:assignment
construct:char
construct:class
construct:comment
construct:ifTrue:ifFalse:
construct:implicitVariable
construct:indexedAccess
construct:invocation
construct:lambda
construct:letter
construct:method
construct:methodDeclaration
construct:number
construct:parameter
construct:return
construct:select:thenCollect:
construct:subtract
construct:variable
construct:visibility
paradigm:functional
paradigm:imperative
paradigm:object-oriented
technique:higher-order-functions
ErikSchierboom commented 1 year ago

Exercise: collatz-conjecture

Code

'From Pharo7.0.3 of 12 April 2019 [Build information: Pharo-7.0.3+build.158.sha.0903ade8a6c96633f07e0a7f1baa9a5d48cfdf55 (64 Bit)] on 16 May 2019 at 6:25:44.434271 pm'!Object subclass: #CollatzConjecture instanceVariableNames: ''   classVariableNames: ''  poolDictionaries: ''    category: 'Exercise@CollatzConjecture'!!CollatzConjecture commentStamp: 'RichardOKeefe 5/16/2019 18:14' prior: 0!Another no-data one-method Exercism class.  Guess which problem?!!CollatzConjecture methodsFor: 'as yet unclassified' stamp: 'RichardOKeefe 5/16/2019 18:25'!stepsFrom: aNumber    |steps current| ((aNumber isKindOf: Integer) and: [aNumber strictlyPositive]) ifTrue: [     steps := 0.     current := aNumber.     [current = 1] whileFalse: [         current := current even ifTrue: [current // 2] ifFalse: [current*3 + 1].            steps := steps + 1].        ^steps].    (aNumber isKindOf: Integer) ifFalse: [aNumber error: 'not an integer']. aNumber error: 'Only positive numbers are allowed'.! !

Tags:

construct:add
construct:and
construct:assignment
construct:block
construct:boolean
construct:class
construct:comment
construct:divide
construct:error
construct:ifTrue:
construct:instanceVariable
construct:integer
construct:invocation
construct:isKindOf:
construct:method
construct:multiply
construct:number
construct:parameter
construct:return
construct:string
construct:variable
construct:whileTrue:
paradigm:imperative
paradigm:object-oriented
technique:looping
ErikSchierboom commented 1 year ago

Exercise: armstrong-numbers

Code

Tested on: 2021-04-26 05:30
8 run, 8 passes, 0 skipped, 0 failures, 0 errors 

Tags:

No tags generated

TODO: put a proper solution here

ErikSchierboom commented 1 year ago

Exercise: secret-handshake

Code

Tested on: 2019-04-26 03:46
11 run, 11 passes, 0 skipped, 0 failures, 0 errors 

Tags:

No tags generated

TODO: put a proper solution here

ErikSchierboom commented 1 year ago

Exercise: isbn-verifier

Code

'From Pharo7.0.3 of 12 April 2019 [Build information: Pharo-7.0.3+build.158.sha.0903ade8a6c96633f07e0a7f1baa9a5d48cfdf55 (64 Bit)] on 16 May 2019 at 5:53:42.592513 pm'!Object subclass: #IsbnVerifier  instanceVariableNames: ''   classVariableNames: ''  poolDictionaries: ''    category: 'Exercise@IsbnVerifier'!!IsbnVerifier commentStamp: 'RichardOKeefe 5/16/2019 17:07' prior: 0!Yet another no-data one-pure-function method dummy class for Exercism.!!IsbnVerifier methodsFor: 'testing' stamp: 'RichardOKeefe 5/16/2019 17:52'!isValidIsbn: aString   "This is supposed to be an *elegant* implementation.     Here I mean no object creation (other than SmallIntegers)   and minimal language resources."   |s m c| s := 0. m := 10.    1 to: aString size do: [:i |        c := aString at: i.     c = $- ifFalse: [           m isZero ifTrue: [^false].          c isDigit             ifTrue:  [c := c digitValue]            ifFalse: [(c = $X and: [m = 1])                          ifTrue:  [c := 10]                             ifFalse: [^false]].            s := (m * c + s) \\ 11.             m := m - 1]].  ^s isZero and: [m isZero]   ! !

Tags:

construct:add
construct:assignment
construct:bitwise-and
construct:boolean
construct:char
construct:class
construct:comment
construct:divide
construct:do
construct:ifFalse:
construct:ifTrue:
construct:int
construct:integer
construct:invocation
construct:lambda
construct:logical-and
construct:method
construct:multiply
construct:number
construct:parameter
construct:return
construct:subtract
construct:variable
construct:visibility
paradigm:functional
paradigm:imperative
paradigm:object-oriented
technique:bit-manipulation
technique:boolean-logic
technique:higher-order-functions
Bajger commented 1 year ago

@ErikSchierboom I'm up for helping! Is there a deadline for this?

ErikSchierboom commented 1 year ago

Around the 20th this month.

Bajger commented 1 year ago

@ErikSchierboom : There are few comments that don't include solution but text file that is generated alongside with submission for mentors, how unit tests ran (this was before test runner was active and it includes some debug stuff, like version of image and VM). Could I paste there *.st file instead (that includes solution)? So I can put there a proper tags. Thanks!

Bajger commented 1 year ago

Also, some code examples uses legacy format used in older versions of Pharo (it was used mainly for serialization of code from Pharo image to file), is is one liner and hard to read, e.g.: 1baa9a5d48cfdf55 (64 Bit)] on 15 May 2019 at 9:40:28.846338 pm'!Object subclass: ... Can I paste there a better example that is easy to read? Or for purpose of AI neural network learning it doesn't really matter.

iHiD commented 1 year ago

@Bajger If you want to take your own solutions and mark those up instead of the ones we've given, I'm 100% fine with that.

I'd ask two things:

  1. Could you do this in a new issue (just do the same, one comment per solution)
  2. Explicitly specify the exercise and who's solution it is (probably yours!) in each comment.

That'll just ensure we can keep things in a sane shape in the database. Thanks! :)

Bajger commented 1 year ago

@iHiD Hi Jeremy. I will create new issue with appropriate comments. I'm picking public community solutions that are available / published on each exercise, so it shoudn't be a problem. Should I revert my comments on this issue? I've already modified code in one comment I think...

iHiD commented 1 year ago

Should I revert my comments on this issue? I've already modified code in one comment I think...

No need thanks

@iHiD Hi Jeremy. I will create new issue with appropriate comments. I'm picking public community solutions that are available / published on each exercise, so it shoudn't be a problem.

Great. Just let me know what solution the code is so I can link it back in the database. Thanks :)

ErikSchierboom commented 1 year ago

This is an automated comment

Hello :wave: Next week we're going to start using the tagging work people are doing on these. If you've already completed the work, thank you! If you've not, but intend to this week, that's great! If you're not going to get round to doing it, and you've not yet posted a comment letting us know, could you please do so, so that we can find other people to do it. Thanks!

Bajger commented 1 year ago

Will finish this week!

ErikSchierboom commented 1 year ago

Closed in favor of https://github.com/exercism/pharo-smalltalk/issues/598