Greetings,
I am in need of a way to go to the end of a do loop. myCollection do: [ :item | (blah blah) ifTrue: “we found an item of the first type” next item. (blah blah) ifTrue: “we found an item of the second type” next item. (blah blah) ifTrue: “we found an item of the third type” next item. (blah blah) ifTrue: “we found an item of the fourth type” next item. (blah blah) ifTrue: “we found an item of the fifth type” ]. Some other languages have “break” or “next” or “goto LABEL” to skip the processing of the rest of the loop in case the item is found in the first test. How do I implement this in Squeak? Sincerely, Joe. PS. This is not a homework project. _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
On Mon, 2016-05-09 at 12:51 -0500, Joseph Alotta wrote:
> Greetings, > > I am in need of a way to go to the end of a do loop. > > myCollection do: [ :item | > > (blah blah) ifTrue: “we found an item of the first > type” > next item. > > (blah blah) ifTrue: “we found an item of the second > type” > next item. > > (blah blah) ifTrue: “we found an item of the third > type” > next item. > > (blah blah) ifTrue: “we found an item of the fourth > type” > next item. > > (blah blah) ifTrue: “we found an item of the fifth > type” > > ]. > > > Some other languages have “break” or “next” or “goto LABEL” to skip > the processing of the rest of the loop in case the item is found in > the first test. > > How do I implement this in Squeak? > Smalltalk doesn't have a switch/case statement but there are a few ways to implement the equivalent logic: 1) Nest the additional conditions inside ifFalse: statements: cond1 ifTrue: [trueLogic...] ifFalse: [cond2 ifTrue: [trueLogic] ifFalse: [otherLogic...]] This is the simplest method but can get hard to follow/edit pretty quickly re: brackets and formatting. You could also add a 'done' variable to avoid the nesting (and avoid multiple conditions from being satisfied in a single pass): done:=false. cond1 ifTrue: [trueLogic. done:=true]. (cond2 and: [done not]) ifTrue: [trueLogic. done:=true]. (cond3 and: [done not]) ifTrue: [trueLogic. done:=true]. done ifFalse: [otherLogic]. 2) Store the conditional blocks as values in a dictionary: switchBlock := Dictionary new at: condValue1 put: [block1]; at: condValue2 put: [block2]; at: condValue3 put: [block3]; yourself. then to evaluate it: (switchBlock at: condValue) value 3) Implement a switch method and call it: switchMethod: switchVal switchVal = cond1 ifTrue: [trueLogic. ^ whatever]. switchVal = cond2 ifTrue: [trueLogic. ^ whatever]. swit chVal = cond3 ifTrue: [trueLogic. ^ whatever]. otherLogic This is one area where I wish Smalltalk had nicer syntax / syntactic sugar for... any of the above is a bit clunky and you need it often enough where this can get tedious. > Sincerely, > > Joe. > > > PS. This is not a homework project. > > > > _______________________________________________ > Beginners mailing list > [hidden email] > http://lists.squeakfoundation.org/mailman/listinfo/beginners Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
On 09.05.2016, at 20:35, Phil (list) <[hidden email]> wrote:
> > Smalltalk doesn't have a switch/case statement True, but Squeak does: aValue caseOf: { [firstValue] -> [firstBlock]. [secondValue] -> [secondBlock]. } otherwise: [elseBlock] - Bert - _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners smime.p7s (5K) Download Attachment |
In reply to this post by Joseph Alotta
Am 09.05.16 um 19:51 schrieb Joseph Alotta:
> Greetings, > > I am in need of a way to go to the end of a do loop. > > myCollection do: [ :item | > > (blah blah) ifTrue: “we found an item of the first type” > next item. > > (blah blah) ifTrue: “we found an item of the second type” > next item. > > (blah blah) ifTrue: “we found an item of the third type” > next item. > > (blah blah) ifTrue: “we found an item of the fourth type” > next item. > > (blah blah) ifTrue: “we found an item of the fifth type” > > ]. > > > Some other languages have “break” or “next” or “goto LABEL” to skip the processing of the rest of the loop in case the item is found in the first test. > > How do I implement this in Squeak? interface for iterating over collections, >>do: is not the only one. Alas there is no-one I am aware of that supports what is needed here (something like a split into different sub-collections). >>select: could be used to get all the items for one of your conditions. Thus, for your problem you would need five select:-loops, which is sub-optimal performance-wise. Maybe your problem can be rephrased such that Smalltalk's collection interface offers a better solution. Nevertheless, I suggest to take a closer look at the remaining selectors like >>select:, >>reject:, >>collect, ... Regards Andreas _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
In reply to this post by Bert Freudenberg
On Mon, 2016-05-09 at 20:51 +0200, Bert Freudenberg wrote:
> On 09.05.2016, at 20:35, Phil (list) <[hidden email]> wrote: > > > > > > Smalltalk doesn't have a switch/case statement > True, but Squeak does: > > aValue caseOf: { > [firstValue] -> [firstBlock]. > [secondValue] -> [secondBlock]. > } otherwise: [elseBlock] > > - Bert - > Hah... learn something new every day (I don't remember noticing that method before.) This is definitely an improvement. > > > _______________________________________________ > Beginners mailing list > [hidden email] > http://lists.squeakfoundation.org/mailman/listinfo/beginners _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
In reply to this post by Joseph Alotta
Hi Joseph,
On 09.05.2016, at 19:51, Joseph Alotta <[hidden email]> wrote: > Greetings, > > I am in need of a way to go to the end of a do loop. > > myCollection do: [ :item | > > (blah blah) ifTrue: “we found an item of the first type” > next item. > > (blah blah) ifTrue: “we found an item of the second type” > next item. > > (blah blah) ifTrue: “we found an item of the third type” > next item. > > (blah blah) ifTrue: “we found an item of the fourth type” > next item. > > (blah blah) ifTrue: “we found an item of the fifth type” > > ]. Can you go a little into detail? Typically, I'd put whatever is to be done when you "know of what type" your items are into its Class, relying on polymorphism. For example, given you have ducks, cats, and dogs and want them to call, you'd do: Dog>>call self sound: 'Waff Waff'. Cat>>call self sound: 'Meow'. Duck>>call self sound: 'Quak!'. So you can use it like this: {Dog new. Cat new. Dog new. Duck new. Duck new} do: [:animal | animal call]. "=> 'Waff Waff', 'Meow', 'Waff Waff', 'Quak!', 'Quak!' What happens when you have a Centipede that does not call at all? Well, let's assume the animals are organized all together in a common super class, Animal. In Animal, we say Animal>>call ^ self to say a 'generic' animal does not do anything when calling. We could do Centipede>>call ^ self or Centipede>>call ^ super call but that superfluous given Animal>>call. So, what do we have now? {Dog new. Cat new. Centipede new. Dog new. Duck new. Centipede new. Duck new} do: [:animal | animal call]. "=> 'Waff Waff', 'Meow', 'Waff Waff', 'Quak!', 'Quak!' That way, no 'goto' or 'continue' is necessary. Best regards -Tobias _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
I don’t think any of the solutions work for my case.
I want to evaluate several different variable for each step, make calculations and if all of the conditions are met, then skip to the next item, otherwise, do the next step of calculations. The project is reading comma deliminated bank or credit card files, taking a column of data, counting various characters, and trying to determine what kind of data it is. For example, a column of data with two slash characters and eight digits per line is likely to be a date field. A column of data with more than 3 letter characters and a percentage of digits and a percentage of hash signs is likely to be a payee field. A column of data with no spaces, no digits, no special characters is likely to be a type of transaction field. A column of data with one period per item, and only digits or a minus sign is likely to be a amount field, and a column of data with a high percentage of zero length items and the rest having C or K and a pound sign and four or more digits is likely to be a check number field. I am doing a lot of tests for each field and I don’t think the switch is a good fit. Sincerely, Joe. _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
Am 09.05.16 um 23:00 schrieb Joseph Alotta:
> I don’t think any of the solutions work for my case. > > I want to evaluate several different variable for each step, make calculations and if all of the conditions are met, then skip to the next item, otherwise, do the next step of calculations. > > The project is reading comma deliminated bank or credit card files, taking a column of data, counting various characters, and trying to determine what kind of data it is. For example, a column of data with two slash characters and eight digits per line is likely to be a date field. A column of data with more than 3 letter characters and a percentage of digits and a percentage of hash signs is likely to be a payee field. A column of data with no spaces, no digits, no special characters is likely to be a type of transaction field. A column of data with one period per item, and only digits or a minus sign is likely to be a amount field, and a column of data with a high percentage of zero length items and the rest having C or K and a pound sign and four or more digits is likely to be a check number field. > > I am doing a lot of tests for each field and I don’t think the switch is a good fit. > What you probably need is a parser for the things you want to detect and consume. SmaCC or PetitParser comes to my mind... Regards Andreas _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
In reply to this post by Joseph Alotta
> On 09.05.2016, at 23:00, Joseph Alotta <[hidden email]> wrote: > > I don’t think any of the solutions work for my case. > > I want to evaluate several different variable for each step, make calculations and if all of the conditions are met, then skip to the next item, otherwise, do the next step of calculations. > > The project is reading comma deliminated bank or credit card files, taking a column of data, counting various characters, and trying to determine what kind of data it is. For example, a column of data with two slash characters and eight digits per line is likely to be a date field. A column of data with more than 3 letter characters and a percentage of digits and a percentage of hash signs is likely to be a payee field. A column of data with no spaces, no digits, no special characters is likely to be a type of transaction field. A column of data with one period per item, and only digits or a minus sign is likely to be a amount field, and a column of data with a high percentage of zero length items and the rest having C or K and a pound sign and four or more digits is likely to be a check number field. > > I am doing a lot of tests for each field and I don’t think the switch is a good fit. Sounds like my first suggestion would work then. Create a method “processColumn:” that tries to match each pattern and, if successful, reads the data and returns. This should work, but you would have to put a lot of code into one single method, which is bad style. Better to have a set of parsing methods (e.g. parseAsDate:, parseAsPayee: etc) that would return true if they succeeded, and if not, the next one would be tried. And instead of having a couple of methods you could have a couple of parser classes that each would try to parse the item. You would put the parsers in a collection and try each of them until one successfully parsed. This would probably be the most object-oriented solution. - Bert - _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners smime.p7s (5K) Download Attachment |
In reply to this post by Joseph Alotta
Hi Joe,
You can map your collection to a stream and then use the stream methods to traverse the collection. stream := ReadStream on: myCollection. [stream atEnd] whileFalse: [:item | item := stream next. "I'm not sure upToEnd is the right method here but it is close. Look around, I'm sure you will find what you need." item doSomeWork. (when you think you are done with item) ifTrue: [stream upToEnd]. ]. Lou On Mon, 9 May 2016 16:00:58 -0500, Joseph Alotta <[hidden email]> wrote: >I dont think any of the solutions work for my case. > >I want to evaluate several different variable for each step, make calculations and if all of the conditions are met, then skip to the next item, otherwise, do the next step of calculations. > >The project is reading comma deliminated bank or credit card files, taking a column of data, counting various characters, and trying to determine what kind of data it is. For example, a column of data with two slash characters and eight digits per line is likely to be a date field. A column of data with more than 3 letter characters and a percentage of digits and a percentage of hash signs is likely to be a payee field. A column of data with no spaces, no digits, no special characters is likely to be a type of transaction field. A column of data with one period per item, and only digits or a minus sign is likely to be a amount field, and a column of data with a high percentage of zero length items and the rest having C or K and a pound sign and four or more digits is likely to be a check number field. > >I am doing a lot of tests for each field and I dont think the switch is a good fit. > >Sincerely, > >Joe. Louis LaBrunda Keystone Software Corp. SkypeMe callto://PhotonDemon _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
In reply to this post by Joseph Alotta
On Mon, 2016-05-09 at 16:00 -0500, Joseph Alotta wrote:
> The project is reading comma deliminated bank or credit card files, It sounds like you're processing something along the lines of Quicken/MS Money data files that you download from your bank / credit card company. If that's the case, Andreas' solution re: a parser would be the way I'd go. _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
In reply to this post by Louis LaBrunda
Lou,
I was trying to use the ReadStream, but the issue is to get execution to go back to the top. If I send the upToEnd message, it still executes from the same line and goes through the rest of the tests. Sincerely, Joe. > On May 9, 2016, at 3:56 PM, Louis LaBrunda [via Smalltalk] <[hidden email]> wrote: > > Hi Joe, > > You can map your collection to a stream and then use the stream methods to traverse the > collection. > > stream := ReadStream on: myCollection. > [stream atEnd] whileFalse: [:item | > item := stream next. > "I'm not sure upToEnd is the right method here but it is close. Look around, I'm sure you will > find what you need." > item doSomeWork. > (when you think you are done with item) ifTrue: [stream upToEnd]. > ]. > > Lou > > On Mon, 9 May 2016 16:00:58 -0500, Joseph Alotta <[hidden email]> wrote: > > >I dont think any of the solutions work for my case. > > > >I want to evaluate several different variable for each step, make calculations and if all of the conditions are met, then skip to the next item, otherwise, do the next step of calculations. > > > >The project is reading comma deliminated bank or credit card files, taking a column of data, counting various characters, and trying to determine what kind of data it is. For example, a column of data with two slash characters and eight digits per line is likely to be a date field. A column of data with more than 3 letter characters and a percentage of digits and a percentage of hash signs is likely to be a payee field. A column of data with no spaces, no digits, no special characters is likely to be a type of transaction field. A column of data with one period per item, and only digits or a minus sign is likely to be a amount field, and a column of data with a high percentage of zero length items and the rest having C or K and a pound sign and four or more digits is likely to be a check number field. > > > >I am doing a lot of tests for each field and I dont think the switch is a good fit. > > > >Sincerely, > > > >Joe. > -- > Louis LaBrunda > Keystone Software Corp. > SkypeMe callto://PhotonDemon > > _______________________________________________ > Beginners mailing list > [hidden email] > http://lists.squeakfoundation.org/mailman/listinfo/beginners > > > If you reply to this email, your message will be added to the discussion below: > http://forum.world.st/next-or-break-in-a-loop-tp4894095p4894128.html > To start a new topic under Squeak - Beginners, email [hidden email] > To unsubscribe from Squeak - Beginners, click here. > NAML |
Joe,
At each test for the type of data you can also test to see if you found type, something like this: stream := ReadStream on: myCollection. [stream atEnd] whileFalse: [:item | | notFound | item := stream next. notFound := true. (notFound and: [your column test1]) ifTrue: [notFound := false. stream upToEnd]. (notFound and: [your column test2]) ifTrue: [notFound := false. stream upToEnd]. (notFound and: [your column test3]) ifTrue: [notFound := false. stream upToEnd]. ]. Not pretty but it should work. You should also look into the #caseOf: method Bert suggested. I have my own Case class in VA Smalltalk that I expect is similar but I'm not familiar with #caseOf:, so you should look it up. I expect it will make the code a little cleaner. Lou On Tue, 10 May 2016 08:57:03 -0700 (PDT), Joseph Alotta <[hidden email]> wrote: >Lou, > >I was trying to use the ReadStream, but the issue is to get execution to go back to the top. If I send the upToEnd message, it still executes from the same line and goes through the rest of the tests. > > >Sincerely, > >Joe. > > > >> On May 9, 2016, at 3:56 PM, Louis LaBrunda [via Smalltalk] <[hidden email]> wrote: >> >> Hi Joe, >> >> You can map your collection to a stream and then use the stream methods to traverse the >> collection. >> >> stream := ReadStream on: myCollection. >> [stream atEnd] whileFalse: [:item | >> item := stream next. >> "I'm not sure upToEnd is the right method here but it is close. Look around, I'm sure you will >> find what you need." >> item doSomeWork. >> (when you think you are done with item) ifTrue: [stream upToEnd]. >> ]. >> >> Lou >> >> On Mon, 9 May 2016 16:00:58 -0500, Joseph Alotta <[hidden email]> wrote: >> >> >I don?t think any of the solutions work for my case. >> > >> >I want to evaluate several different variable for each step, make calculations and if all of the conditions are met, then skip to the next item, otherwise, do the next step of calculations. >> > >> >The project is reading comma deliminated bank or credit card files, taking a column of data, counting various characters, and trying to determine what kind of data it is. For example, a column of data with two slash characters and eight digits per line is likely to be a date field. A column of data with more than 3 letter characters and a percentage of digits and a percentage of hash signs is likely to be a payee field. A column of data with no spaces, no digits, no special characters is likely to be a type of transaction field. A column of data with one period per item, and only digits or a minus sign is likely to be a amount field, and a column of data with a high percentage of zero length items and the rest having C or K and a pound sign and four or more digits is likely to be a check number field. >> > >> >I am doing a lot of tests for each field and I don?t think the switch is a good fit. >> > >> >Sincerely, >> > >> >Joe. >> -- >> Louis LaBrunda >> Keystone Software Corp. >> SkypeMe callto://PhotonDemon >> >> _______________________________________________ >> Beginners mailing list >> [hidden email] >> http://lists.squeakfoundation.org/mailman/listinfo/beginners >> >> >> If you reply to this email, your message will be added to the discussion below: >> http://forum.world.st/next-or-break-in-a-loop-tp4894095p4894128.html >> To start a new topic under Squeak - Beginners, email [hidden email] >> To unsubscribe from Squeak - Beginners, click here. >> NAML Louis LaBrunda Keystone Software Corp. SkypeMe callto://PhotonDemon _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
> On May 10, 2016, at 12:03 PM, Louis LaBrunda [via Smalltalk] <[hidden email]> wrote: > > Joe, > > At each test for the type of data you can also test to see if you found type, something like > this: > > stream := ReadStream on: myCollection. > [stream atEnd] whileFalse: [:item | | notFound | > item := stream next. > notFound := true. > (notFound and: [your column test1]) ifTrue: [notFound := false. stream upToEnd]. > (notFound and: [your column test2]) ifTrue: [notFound := false. stream upToEnd]. > (notFound and: [your column test3]) ifTrue: [notFound := false. stream upToEnd]. > ]. > > Not pretty but it should work. I added a flag and set it as one of the conditions. Also, to make reading simpler, I stacked all the booleans. bool := bool and: (condition). bool := bool and: (another condition). It is not pretty, but it avoids endless seas of parentheses. Sincerely, Joe. |
Free forum by Nabble | Edit this page |