HollingBerries問題をSqueak Smalltalkで
Any other Smalltalkers want to take a crack at github.com/apauley/Hollin… my take is already there #smalltalk
— Dale Henrichsさん (@dhenrichs) 6月 20, 2012
経由で、
Squeak Smalltalk を使って、Dale Henrichs さんのとはちょっと違った方向からアプローチしてみました。恥ずかしながら Git と GitHub の使い方がよく分からないダメダメさは近々 えにしテックに伺ったときにでも教えていただくことにして、とりあえず書いたものはこちら(はてダ)に貼ってお茶を濁しておくことにします。
CSV パーザーとして SqueakSource にあった Avi Bryant さんのを使わせていただいてます。
CSV-JohnnyT.10.mcz を入手してドラッグ&ドロップするか、コメントアウトした Installer ss …という行を do it することでもインストールできます。
" Squeak 4.1, 4.2, 4.3 " " Installer ss project: 'CSV'; install: 'CSV'. " | pathToCsv pathToOut keys kindOf markup sellby troubleSupplierIDs trouble premiumSupplierIDs premium outStream output | pathToCsv := 'produce.csv'. pathToOut := 'pricefile.txt'. keys := #(suppID prodCode prodDesc delivDate unitPrice numUnits). kindOf := [:data | | pcode | pcode := (data at: #prodCode) asNumber. true caseOf: { [(1100 to: 1199) includes: pcode] -> [#apple]. [(1200 to: 1299) includes: pcode] -> [#banana]. [(1300 to: 1399) includes: pcode] -> [#berry]. [(1000 to: 1999) includes: pcode] -> [#fruit]}]. markup := [:data | | rate | rate := (kindOf value: data) caseOf: { [#apple] -> [1.4s3]. [#banana] -> [1.35s3]. [#berry] -> [1.55s3]} otherwise: [1.5s3]. data at: #retailPrice put: (data at: #unitPrice) * rate]. sellby := [:data | | after | after := (kindOf value: data) caseOf: { [#apple] -> [2 weeks]. [#banana] -> [5 days]} otherwise: [1 week]. data at: #sellbyDate put: (data at: #delivDate) asDate + after]. troubleSupplierIDs := #('32' '101'). trouble := [:data | (troubleSupplierIDs includes: (data at: #suppID)) ifTrue: [ data at: #sellbyDate put: (data at: #sellbyDate) - 3 days. data at: #retailPrice put: (((data at: #retailPrice) - 2) max: 0s3)]]. premiumSupplierIDs := #('219' '204'). premium := [:data | (premiumSupplierIDs includes: (data at: #suppID)) ifTrue: [ data at: #retailPrice put: (((data at: #unitPrice) * 0.1s3 + (data at: #retailPrice)) roundUpTo: 1s3)]]. outStream := nil. output := [:data | | price priceStr | price := (data at: #retailPrice) roundTo: 0.01s3. priceStr := (price asString allButLast: 3) forceTo: 8 paddingStartWith: $ . (data at: #numUnits) asInteger timesRepeat: [ outStream nextPutAll: 'R', priceStr. outStream nextPutAll: ((data at: #sellbyDate) yyyymmdd replaceAll: $- with: $/). outStream nextPutAll: ((data at: #prodDesc) forceTo: 31 paddingWith: $ ). outStream cr]]. StandardFileStream oldFileNamed: pathToCsv do: [:csvFile | | csv fields | csv := CSVParser on: csvFile. csv nextRow. StandardFileStream forceNewFileNamed: pathToOut do: [:outFile | outStream := outFile. [(fields := csv nextRow) notEmpty] whileTrue: [ | data | data := Dictionary new. keys with: fields do: [:key :str | data at: key put: str]. data at: #unitPrice put: (data at: #unitPrice) / 100s3. {markup. sellby. trouble. premium. output} do: [:each | each value: data]]. ] ]. (StandardFileStream fileNamed: pathToOut) edit