[Newbies] Re: Adding menu options to Omnibrowser
Hi Rob, I haven't done this in a while but I believe you need to do this: - Create a subclass of OBCommand. This class will be responsible for indicating when the menu option should be shown, how it is shown and how it should be performed. I think there's more, but I don't know what. - Implement #isActive to indicate when your menu option should be shown. For example, I think this will limit you to class side methods: isActive ^ (target isKindOf: OBMethodNode) and: [(target classNode isKindOf: OBMetaclassNode) and: [requestor isSelected: target]] You may want to add a constraint to limit this to unary selectors otherwise you'll have to prompt for arguments. - Implement #execute. This will actually do the work. If you're just dealing with unary methods then something like this is probably what you need: execute target theNonMetaClass perform: target selector So here you could prompt for arguemnts, inspect the result, do whatever. - Implement #label, #longDescription, #group, #keystroke to control the display of your menu. Have a look at the other OBCommand subclasses for hints. - Link up your command by adding a cmdXXX method to OBCodeBrowser. Basically you need a method like: cmdClassMethodDoIt ^MyCmdClassMethodDoIt Have a look at the "commands" protocol to see what I mean. The next browser you open should have your new menu option. There are many existing OBCommand subclasses you can examine for inspiration. Hope this helps, Zulq. Rob Rothwell wrote: I thought it would be nice to add a right click option to class methods that "ran" that method...for use with examples and such. So, for example, instead of typing "MyClass exampleThisOrThat," when browsing you could just right click and "run it." Any tips on where to start? I have no knowledge of OB... Rob ___ Beginners mailing list Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners ___ Beginners mailing list Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners
[Newbies] Re: [on] how to match partial regexes? how to match and delete string prefixes?
Hi Oscar, Oscar Nierstrasz wrote: Hi Folks, Is there a way ask a regex if it matches any part of a string? matches: wants an exact match, and matchesPrefix: clearly only matches a prefix. The best I found was to abuse matchesIn: and check the size of the response, but this is not very clean. Have a look at #search: as I think this will help you. --- A second question: I would like to strip a string prefix if it matches. Since this is a literal string, I should not need regexes. But I cannot find a nice existing method to do this. With regexes I must escape all special regex chars: I can't think of anything off the top of my head but the great thing about smalltalk is you can easily add what you need. For example, you could use #beginsWith: when adding a method to String. copyReplacePrefix: prefix with: replacement self beginsWith: prefix ifTrue: [^ replacement , (self copyFrom: prefix size to: self size)] ^ self Then you will be able to do: 'abracadabra' copyReplacePrefix: 'abra' with: '' Next step would be to write a few unit tests and then attach both as to an enhancement request at http://bugs.squeak.org. aliasesAsRegexes aliasesAsRegexes ifNil: [ aliasesAsRegexes := aliases collect: [:alias | alias := '\/' asRegex copy: alias replacingMatchesWith: '\/'. alias := '\~' asRegex copy: alias replacingMatchesWith: '\~'. alias := '\:' asRegex copy: alias replacingMatchesWith: '\:'. alias := '\.' asRegex copy: alias replacingMatchesWith: '\.'. alias asRegex ]]. ^ aliasesAsRegexes I don't think /, ~ or : have any special meaning so why do you need to escape them? Even if you did, a better way might be to do: alias copyWithRegex: '[/~:.]' matchesTranslatedUsing: [:ea | '\' , ea] But if you're just replacing '.' then you can use: alias copyReplaceAll: '.' with: '\.' Hope this helps. Zulq ___ Beginners mailing list Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners
[Newbies] Re: Why do lengthy installations "shut down" Squeak?
Hi Rob, Rob Rothwell wrote: Just wondering why, since Squeak has processes, when install something large via the Universe Browser, etc... I can't do anything else in Squeak while it is installing? Is this by design? It seems like it could just be a low priority background task and you could keep working... Was hoping a Monticello/Universe expert would chip in but since they haven't here's my 2 pence. Firstly, I suspect no one has tried to do background code loading. Apart from some very large packages like Magma, it's usually bearable. And, if they did try and do background loading it wouldn't be straightforward. For instance, if you're loading a package that makes signficant UI code changes such as Polymorph then I suspect it would be dangerous to keep working. Or if you're making changes to classes that are being loaded your changes may be clobbered or vice versa, Hope this helps. - Zulq ___ Beginners mailing list Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners
[Newbies] Re: Number formatting printf/sprintf for Squeak?
Hi Lukas, Lukas Renggli wrote: testSwissCurrency | printer | printer := WASequentialPrinter new , 'CHF ' , WASignPrinter new , (WANumberPrinter new separator: $'; precision: 2; accuracy: 0.05; yourself). self assert: (printer print: 12.34) = 'CHF 12.35'. self assert: (printer print: -12.39) = 'CHF -12.40' Are there any plans to develop this into a more compact form? For example (ugly, sorry!): 'CHF {f+-,.05}' % #(12.34). I'm always disappointed with Squeak's string formatting/generation facilities and if Seaside has this framework, maybe it is a good base for compact string format language? Thanks, Zulq. ___ Beginners mailing list Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners
[Newbies] Re: Splitting Excel csv into lines
Hi Stephan, It's a bit hard to understand. Especially without tests. I would probably split it into a few methods such that each method tells the reader a manageable chunk of what is going on. I've sketched a few other things as well to give you some ideas: splitIntoLines: aString | in | in := aString readStream. ^ Array streamContents: [:out | [in atEnd] whileFalse: [ out nextPut: (self readLine: in) ] ] readLine: aStream inQuote := false. "instance variable " " Use a stream to build the string instead of #, " ^ String streamContents: [:out | | char | " Give clear indication of what an end of line is " [((char := aStream next) = Character cr) and: [inQuote not]] whileFalse: [self readNext: aStream onto: out]. " Use stream methods where you can" aStream peekFor: Character lf] readNext: inStream onto: outStream | char | char := inStream last. " the loop calls next for us " " This used to be ifTrue: [ ifTrue: [ with no ifFalse: " (char = $" and: [inQuote]) ifTrue:[ " Common tasks given to helper methods " char := self lookFor: Character tab on: inStream. char := self lookFor: Character tab on: inStream ifFound: [inQuote := false]. ]. char = (Character tab) ifTrue:[ inQuote ifTrue: [inQuote := false] ifFalse: [ self lookFor: Character tab in: aStream ifFound: [inQuote := false]. ] ]. " BTW, not sure this was right - don't you want CRs that aren't part of EOLs? " char = (Character cr) ifFalse: [out nextPut: char] lookFor: aCharacter in: aStream ^ self lookFor: aCharacter in: aStream ifFound: [] lookFor: aCharacter in: aStream ifFound: aBlock aStream peek = aCharacter ifTrue: [ aBlock value. ^ aStream next. ]. ^ aStream last Hope this helps, Zulq. step...@stack.nl wrote: String lines doesn't handle separating Excel copy-and-paste very well, because soft enters in a cell get splitted into separate lines. Ive done now: splitIntoLines: aString "Return a collection with the string-lines of the receiver." | input char temp inQuote| input := aString readStream. ^ Array streamContents: [ :output | temp := ''. inQuote := false. [ input atEnd ] whileFalse: [ char := input next. char = $" ifTrue: [ inQuote ifTrue:[ input peek = (Character tab) ifTrue: [ char := input next.]. input peek = (Character cr) ifTrue: [ char := input next. inQuote := false]]]. char = (Character tab) ifTrue:[ inQuote ifTrue: [ inQuote := false] ifFalse: [ input peek= $" ifTrue: [ input next. inQuote:=true]]]. char = (Character cr) ifFalse: [temp := temp, char asString] ifTrue: [ inQuote ifFalse: [ output nextPut: temp. temp:=''. input peek = Character lf ifTrue: [input next] I would be interested in (speed & elegance & mistakes) improvements to it. Stephan ___ Beginners mailing list Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners
[Newbies] Re: Squeak Guilt
Hi Ryan, How about taking some Java libraries relevant to your area of interest and porting them to Squeak/Smalltalk? I've ended up using Python for most of my work because of the libraries available (BeautifulSoup is one). Although Python is OK, I would love to be working in a Smalltalk environment. To keep involved in Squeak/Smalltalk I have been porting some of the libraries that forced the decision. This meant reading and understanding a lot of relevant Python code and working in Squeak on something the community may find useful. It seems like a good compromise to me. Now if only I had time to release something useable? ;) - Zulq Ryan Zerby wrote: I'm in a position where I want to learn Squeak/Smalltalk because it's cool, but I find myself thinking that I should spend my time working on something that might actually advance my career. I used to be a Java Programmer, but am now a Build Engineer, so I don't directly program anymore. I feel that I should be keeping my Java skills up... but that just isn't as spiffy Anyone else in this boat? Is there a Squeak Support Group? A 12 step program? Anyone have a good rationale why I can go ahead and spend my time on Squeak without feeling guilty? :) :) ___ Beginners mailing list Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners
[Newbies] Re: Saving DNU for later
Hi Tim, You can use mail out bug report. You get to preview the email before it is sent. You can then either change the To: and send it yourself or copy the text you require. - Zulq. tjohn...@iwu.edu wrote: Hi, I was saving a few DNU debug opportunities "to be investigated later" just by minimizing their windows. Today though I have been clearing out cruft. It appears that my few DNU saves are holding on to some objects I would like to get rid of, but I don't want to get rid of these DNUs! How can I save them for later? If I "fileOut" from the debug stack's menu, it only files out the class method. I could "mail out bug report," but then I think it will go to the squeak-dev mailing list and people will yell at me. I could get out a piece of paper and a pencil, but that would take a while. I guess I could take a screenshot... I could have sworn there was some way to just get the stack as text and save to a file, wasn't there? Thanks, TimJ [super-ideally, I could just hit a button, and the issue would be sent to someone who cares, or to Mantis, or into some other bit bucket, so I'm not sitting here pretending I can debug Morphic or streams...] ___ Beginners mailing list Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners
[Newbies] Re: new vs. initialize
Hi Greg, My comments are below... Greg A. Woods; Planix, Inc. wrote: > Now I read on the WWW that the added sending of #initialize from > Behaviour>>new was added in 3.9. Where did you read this? I've been using Squeak for a few years and as far as I know the default implementation of #new has always sent #initialize. The history of Behaviour>>new shows one version dated 23-8-2003. This is well before 3.9. Just for fun I did a search for senders of #basicNew and I found quite a few which are from #new methods in classes which subclass directly from Object and which are in classes that also define their own #initialize method. The curious bit is how some of these #new methods do send #initialize, but not all. I'm guessing some that don't are for abstract classes, but is it true that all are? There are a number of reasons one might call #basicNew, e.g. compatibility with other dialects, limiting use of #new by signalling an error, avoiding the normal initialisation from an alternative constructor, etc. In most cases "super new" would also work. Those that call intitialize may do so because they still need that method to be called, perhaps after doing something else. Some call it for compatability... Also, doesn't this still create an _enormous_ portability problem with other Smalltalks? Have a look at what Seaside and other cross dialect projects do. I believe but am not sure they all have some sort of "self basicNew initialize" on all their top level classes. - Zulq ___ Beginners mailing list Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners
[Newbies] Re: Inspector instances
Once you have the window you can #delete it. There may better (safer?) ways. (Inspector allInstances gather: [:e | e dependents collect: [:d | d window]]) asSet do: [:e | e delete] - Zulq Claus Kick wrote: Hello everyone, I tried to update my Squeak image a bit. Since I wanted an uninterrupted update, I changed ReleaseBuilderFor3dot10>>loadTogether:merge: a bit, as not to throw a walkback window saying "The changes should be reviewed". Unfortunately, I forgot to comment out opening the inspector as well. Then I started the update and had dinner. I think one or two warnings kept creeping up (replacing changed classes - where can you get rid of that message btw?) So, now I have an updated 3.10 Image and a million (at least it feels as if) Inspectors open. Now, in other Smalltalks you do just that Inspector allInstances do:[:win | win close] or Inspector allInstances do:[:in | in mainWindow close]. I tried getting the SystemWindow of each Inspector instance, but sending #close to it just yields yet another walkback. How do you do that in Squeak? I spent the last half hour browsing through Morph, its Subclasses and ToolSet (trying to understand what acutally happens if you inspect an Object). Please help a poor updater :D ___ Beginners mailing list Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners
[Newbies] Re: Transcript usage
This is probably not the best way but has worked for me... To create a new transcript: t := TranscriptStream new. t open. With #open you can create any number of windows on the same transcript stream. All of these views are kept in the ivar 'dependents'. So you could do: (t dependents at: 1) minimize. (t dependents at: 1) restore. (t dependents at: 1) maximize. t dependents do: [:e | e restore]. Note that there may be other things in the dependents collection such as any basic inspectors you have open on the object. The global var 'Transcript', which you probably use in your code, refers to the instance of TranscriptStream available via the menu World->open...transcript. So if you want to manipulate the "main" transcript: Transcript dependents: [:e | e restore] Hope this helps. Z. Sophie (itsme213) wrote: How do I programatically: - Find an existing Transcript window, or create a new one - View it (if it was previously docked or minimized) Thanks ___ Beginners mailing list Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners
[Newbies] Re: pretty printing
An awkward pretty print is a good sign you need to simplify. I would use another method for the case statement. You couldn't use collect because for each character as you are not collecting characters but strings when you escape. Perhaps something like... escapeString: aString ^ String streamContents: [:aStream | aString do: [:eachCharacter | aStream nextPutAll: (self escapeCharacter: eachCharacter)] escapeCharacter: aCharacter aCharacter = $< ifTrue: [^ '<']. aCharacter = $> ifTrue: [^ '>']. aCharacter = $' ifTrue: [^ ''']. aCharacter = $& ifTrue: [^ '&']. ^ aCharacter asString I use #streamContents: a lot as #, causes a lot of unnecessary Strings to be created and also unnecessary work. I rarely use the pretty printer but instead aim to keep my methods short and simple. Regards, Zulq. Mark Volkmann wrote: Here is how one of my methods was pretty printed. escape: aString "escapes special characters in XML text" | result | result := ''. aString do: [:char | result := result , (char caseOf: { [$<] -> ['<']. [$>] -> ['>']. [$'] -> [''']. [$"] -> ['"']. [$&] -> ['&']} otherwise: [char asString])]. ^ result Yikes! To my beginner eyes, that doesn't look good. What's the deal with the excessive indentation? BTW, comments better ways to do what this code does are welcomed. Could I use collect for this? --- Mark Volkmann ___ Beginners mailing list Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners
[Newbies] Re: Tools flap icon order
Hi Mark, Not sure if this is the best way but you can change the order of the tools flap by modifying Flaps(class)>>#defaultsQuadsDefiningToolsFlap. When you are done do: "Flaps replaceToolsFlap". Note that the current order may not match the defaults defined in #defaultsQuadsDefiningToolsFlap. I suspect this is because the flap object has evolved to it's current state. This was the case in my image. Regards, Zulq. Mark Volkmann wrote: Is there an easy way to change the order of the buttons on the Tools flap? It seems like they should either be in alphabetical order or in order by how frequently they are used. To my beginner eyes it doesn't seem that either is the case since Browser is at the bottom. --- Mark Volkmann ___ Beginners mailing list Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners
[Newbies] Re: What is the simplest way to create a collection from a text file in CSV format?
I ususally do something like this: (((FileStream readOnlyFileNamed: 'file.csv') contentsOfEntireFile " read and close " findTokens: String crlf) " split into lines " reject: [:e | e isEmpty]) " lose empty lines " collect: [:e | e findTokens: $,] " split into fields " Regards, Zulq. Andy Burnett wrote: I have a small database containing questionnaire responses. The DB can output the responses (mainly descriptive paragraphs) in CSV format. Ideally, I would like to read each of the records into a collection of some kind. I was hoping that there might be a 'fromCSV:' method, but I haven't found one. One approach I had thought about was to edit the text so in order to create a series of array definitions, and then paste that into a workspace. However, that does lack a bit of elegance! So, is there a neat way of doing this? Cheers AB ___ Beginners mailing list Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners ___ Beginners mailing list Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners
[Newbies] Re: Binary file I/O performance problems
Hi David, You could try using stream next: 4 to read the 4 bytes in one go: [StandardFileStream readOnlyFileNamed: 'Base.image' do: [:stream | [stream atEnd] whileFalse: [stream next. stream next. stream next. stream next.]]] timeToRun " 328505 " [StandardFileStream readOnlyFileNamed: 'Base.image' do: [:stream | stream binary. [stream atEnd] whileFalse: [stream next: 4]]] timeToRun " 144469 " If you can, read larger chunks: [StandardFileStream readOnlyFileNamed: 'Base.image' do: [:stream | stream binary. [stream atEnd] whileFalse: [stream next: 2048]]] timeToRun " 343 " [StandardFileStream readOnlyFileNamed: 'Base.image' do: [:stream | stream binary. [stream atEnd] whileFalse: [stream next: 2048]]] timeToRun " 197 " I'm surprised there isn't a generic class for this, like java.io.BufferedInputStream. Perhaps I haven't discovered it yet. Anyone? Regards, Zulq. David Finlayson wrote: There are at 4 calls to stream next for each integer and sure enough, a profile of the code (attached below) shows that most of the time is being lost in the StandardFileStream basicNext and next methods. There must be a better way to do this. Scaled up to operational code, I will need to process about 40 Gb of data per day. My C code currently takes about 16 cpu hours to do this work (including number crunching). In Squeak, just reading the data would take 3 cpu months! ___ Beginners mailing list Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners
[Newbies] Re: Howto find all subclass responsibilities for a given Class
Hi Felix, A method may be required explicitly: requiredMethod self subclassResponsibility or implicity: method self requiredMethod where #requiredMethod has not been implemented. You can see all of these by sending your class #requiredSelectors, for example: MyMorph requiredSelectors asArray "prints: #(#addWorldHaloMenuItemsTo:hand: #slotName etc..." Or alternativlely, if you are using the OmniBrowser you can install DynamicProtocols which will add a "-- required --" protocol dynamically when you are browsing. The required dynamic protocol will include all the methods returned by #requiredSelectors. If you select one of these methods you will be shown a simple template for implementing the method. Regards, Zulq. Felix Dorner wrote: Hi, I am playing around with Morphs to create a Board for the ancient Go game. Given that I'd like to create a completely new kind of Morph (i.e. a Class that extends Morph), I'd like to find out which methods in the Morph class are defined as subclass responsibilities. Is there any fast way to do such a kind of search? Thanks, Felix ___ Beginners mailing list Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners
[Newbies] Re: Fighting again with MC
Hi Giuseppe, I'm not familiar with the code in question but it seems like somehow you have a category named '' (empty string). If I am correct, then the following should evaluate to true: InciGestApp organization categories includes: '' And, if it does, it may or may not have methods: InciGestApp allMethodsInCategory: '' I am not sure how this could have happened or how to fix it, but if it is the case perhaps someone else could suggest a safe solution. Regards, Zulq. Giuseppe Luigi Punzi wrote: Still with the same problem :( The class giving me problems is InciGestApp, a WebApplication children. But, IncigestApp is under Aida category, under InciGest package. All seems ok. I uploaded a DebugReport if someone can take a look. http://www.lordzealon.com/mc/debugreport Cheers. Giuseppe Luigi Punzi escribió: Hi all, Is the second time I'm having troubles with simple changes to my package :S, and I can't figure out what I'm doing bad. I'm working in a little app. I did it 2 minor changes writing some comments on Doc side of a class, one line on a method commented and so on. Now, I'm trying to commit to my MC repository, and I get an: Error: Subscript Out Of Bounds: 1 Following the debugger, seems the error is in: foreignExtensionMethodsForClass: aClass ^ (self foreignExtensionCategoriesForClass: aClass) gather: [:cat | (aClass organization listAtCategoryNamed: cat) collect: [:sel | self referenceForMethod: sel ofClass: aClass]] where 'cat' is nil. But I don't know wich Category is this. Some advice? Note: Debug Report attached. ___ Beginners mailing list Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners ___ Beginners mailing list Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners
[Newbies] Re: if absent put nil (Riaan)
I would probably do as Klaus suggests but you could also use a cascade and then #ifEmpty:. For example: self workSession attendees do: [:each | html text: each person displayString] separatedBy: [html text: '; '] ; ifEmpty: [html text: 'NO ATTENDEES'] Note the cascade ";" at the end of the third line. This sends #do:seperatedBy: and then sends #ifEmpty: to the collection returned by #attendees. Of course, #ifEmpty: and #do:separatedBy: will only do something if the collection is either empty or not. Regards, Zulq. Riaan van Aarde (SpeCon Eng.) wrote: I have the following code renderAttendeesOn: html self workSession attendees do: [:each | html text: each person displayString] separatedBy: [html text:'; '.] if there is no attendees for my worksession, it needs to display : NO ABSENTEES. Please assist. ___ Beginners mailing list Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners
[Newbies] Re: Another extension proposal -> subsets
Nicolas Cellier wrote: Zulq, the algorithm you are proposing is very simple but has major problems: 1) it is not efficient for large size n: it will do (n factorial) loops when only (2 raisedTo: n) are necessary It's better than N! because it will not loop over a set already processed. For instance, for a set of 5 elements it will try 81 sets but only process 32 of these. Not 120 in either case (5 factorial). 2) each loop will result in a costly hash lookup. Your hashBlock involve LargeInteger of size (B raisedTo: p) where It doesn't need to. That was just a very rough attempt at producing a hash that didn't evaluate to only 16 values. It should be possible to create one that produces SmallIntegers but with a higher cardinality. 3) the algorithm must store all partitions even if we don't want to collect but just to iterate on partitions. Yes. No offense, but you'd better not bother opening a mantis issue for this time. Agreed. I was just curious about why the naive algorithm was so slow and then as a seperate question how one gets such changes in. Z. ___ Beginners mailing list Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners
[Newbies] Re: Another extension proposal -> subsets
Klaus D. Witzel wrote: Squeak looks to be already fast in this case, your routine is almost optimal :) Implementing it in Set so that Set's internal can be of benefit won't bring these figures down much -- what remains is (aSet includes: another), times #copyWithout: loop, and that seems to be unavoidable. It's significantly faster with a more appropriate hashing function: {2->0 . 3->0 . 4->1 . 5->1 . 6->3 . 7->9 . 8->22 . 9->59 . 10->138 . 11->305 . 12->686 . 13->1640 . 14->4366 . 15->10550 . 16->28104 . 17->93373 . 18->303425} combinations | combinations | combinations := (PluggableSet new: (2 raisedTo: self size)) hashBlock: [:aSet | aSet inject: aSet size into: [:hash :each | hash * each hash + each]]; yourself. self combinationsInto: combinations. ^ combinations combinationsInto: aSet (aSet includes: self) ifTrue: [^ self]. aSet add: self. self do: [:each | (self copyWithout: each) combinationsInto: aSet]. I think the problem is that most of the sets contain similar data so the hashes (calculated with bitXor) tend towards to a small set of values. This means there are a lot of collisions and each #add: and #includes: is very expensive. How about naming Collection>>#asPowerset ^ self asSet powersetInto: (Set new: (2 raisedTo: self size)) with Set>>#powersetInto: and putting that into the next release. Even now, I'm still not clear on how one takes a change like this and drives it into a squeak release - Tests, Mantis, then what? Z. ___ Beginners mailing list Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners
[Newbies] Re: Another extension proposal -> subsets
Actually, we don't need #permutationsDo: as we're only looking for combinations. With a few optimisations: combinations ^ self combinationsInto: (Set new: (2 raisedTo: self size)) combinationsInto: aSet (aSet includes: self) ifTrue: [^ self]. "optimisation" aSet add: self. self do: [:each | (self copyWithout: each) combinationsInto: aSet]. ^ aSet [(1 to: 8) asSet combinations] timeToRun "215" [(1 to: 9) asSet combinations] timeToRun "918" [(1 to: 10) asSet combinations] timeToRun "3989" [(1 to: 11) asSet combinations] timeToRun "16349" [(1 to: 12) asSet combinations] timeToRun "68780" So a little better, but I was expecting much more. What's worrying is this: (1 to: 10) asSet combinations size "1024" ((1 to: 10) asSet combinations collect: [:e | e hash]) asSet size "16" So, 1024 distinct Sets have only 16 distinct hashes between them? That seems pretty bad. It would probably be possible to get a little bit more out of the routine with a better (more appropriate) hash function. Even so, I don't think it will ever be as fast as your method but will happily be proved wrong! :) Z. cdrick wrote: Set>>subsets | subsets | subsets := Set with: self. self asArray permutationsDo: [:e | subsets add: e asSet]. self do: [:e | subsets addAll: (self copyWithout: e) subsets]. ^ subsets nice too and frustrating how you got it quick :) I tried a recursive method too first but found the byte ressemblance so... My only consolation is that the recursive solution (subsets2) is slower and hardly work for Set with more than 10 elements. set := #(1 2 3 4 5) asSet. [ set subsets ] timeToRun ." 1" [ set subsets2 ] timeToRun. " 8" set := #(1 2 3 4 5 6 7) asSet. [ set subsets ] timeToRun ." 5" [ set subsets2 ] timeToRun. " 233" set := #(1 2 3 4 5 6 7 8 ) asSet. [ set subsets ] timeToRun . " 11" [ set subsets2 ] timeToRun. " 1683" set := (1 to: 10) asSet. [ set subsets ] timeToRun . " 46" set := (1 to: 15) asSet. [ set subsets ] timeToRun ." 2484" set := (1 to: 20) asSet. [ set subsets ] timeToRun . "559953" "but here the result has (2 raisedTo: 20) 1 048 576 Sets :)" set := (1 to: 50) asSet. [ set subsets ] timeToRun ."I got a "space is low wow" :) I have to go, That was fun :) See you Cédrick ___ Beginners mailing list Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners ___ Beginners mailing list Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners
[Newbies] Re: Another extension proposal -> subsets
Couldn't find anything obvious but remembered #permutationsDo: which may help. Not sure if these does what you want, but maybe it can be adapted? Set>>subsets | subsets | subsets := Set with: self. self asArray permutationsDo: [:e | subsets add: e asSet]. self do: [:e | subsets addAll: (self copyWithout: e) subsets]. ^ subsets #(1 2) asSet subsets. "a Set(a Set(1 2) a Set() a Set(2) a Set(1))" #(1 2 3) asSet subsets. "a Set(a Set(1 2) a Set() a Set(2) a Set(1 2 3) a Set(2 3) a Set(3) a Set(1 3) a Set(1))" Z. cdrick wrote: When we don't find method, we reinvent the wheel. Ok, so this is what happened with my quest on rounding float. So here is another example. I needed a method subsets ... to have all subsets of a Set... #(1 2 ) asSet subsets " -> a Set(a Set(1 2) a Set(1) a Set(2) a Set()) " Is there already something ? I couldn't find so here is what I did ? probably hackish (because of the binary mask) so feel free to comment ;) Set>>subsets | subsetsSize subsets workArray | workArray := self asArray. subsetsSize := 2 raisedTo: self size. subsets := OrderedCollection new. 1 to: subsetsSize do: [:ea | subsets add: ((workArray masquedBy: (ea printStringBase: 2)) asSet)]. "masque par une conversion binaire" ^subsets asSet "could be an array of sets" ArrayedCollection>>masquedBy: aBitString | result entry bitString | entry := self reverse. bitString := aBitString reverse. result := OrderedCollection new. 1 to: (self size) do: [:ea | ((bitString at: ea ifAbsent: []) = $1) ifTrue: [result add: (entry at: ea)]]. ^result reverse Cédrick ___ Beginners mailing list Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners ___ Beginners mailing list Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners
[Newbies] Re: Rouding Floats up to a number of decimals - Method Finder
Are #truncateTo: and #roundTo: what you want? 1.2288 roundTo: 1 "1" 1.2288 roundTo: 0.1 "1.2" 1.2288 roundTo: 0.01 "1.23" 1.2288 roundTo: 0.001 "1.229" 1.2288 roundTo: 0.0001 "1.2288" 1.2288 roundTo: 0.05 "1.25" 1.2288 roundTo: 0.002 "1.228" 1.2288 truncateTo: 1 "1" 1.2288 truncateTo: 0.1 "1.2" 1.2288 truncateTo: 0.01 "1.22" 1.2288 truncateTo: 0.001 "1.228" 1.2288 truncateTo: 0.0001 "1.2288" 1.2288 truncateTo: 0.05 "1.2" 1.2288 truncateTo: 0.002 "1.228" Z. cdrick wrote: So anybody has an idea of methods that truncate/round Floats ? ___ Beginners mailing list Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners
[Newbies] Re: How to shorten a method (using inject: into: ?)
Yes, it's not a good idea to couple your classes with others for frivolous reasons. I just wanted to see how tersely it could be expressed with #inject:into:. Z. stan shepherd wrote: Is there a style issue with introducing an object type which is not part of the problem? Is point often used like this- it's being treated as a shorthand form of an array of 2 elements which has some handy methods, is it not? ___ Beginners mailing list Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners
[Newbies] Re: How to shorten a method (using inject: into: ?)
Using #inject:into and Point objects to store the totals: testMaleMeiosis4 | totals | totals := Forecaster testMale meiose inject: [EMAIL PROTECTED] into: [:subtotals :strand | subtotals + (strand maternalCount @ strand maternalCount)]. self should: [totals = [EMAIL PROTECTED] The point notation makes it look very clean (to me). Z stan shepherd wrote: So until the next cunning suggestion ___ Beginners mailing list Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners
[Newbies] Re: How to shorten a method (using inject: into: ?)
Hi Stan, How about using #detectSum:? testMaleMeiosis2 pTotal := Forecaster testMale meiose detectSum: [:strand | strand testRun paternalCount]. mTotal := Forecaster testMale meiose detectSum: [:strand | strand testRun maternalCount]. self should: [mTotal = 100 and: [pTotal = 100]] Other methods of this variety include #detectMin:, #detectMax: and #count: and possibly others. Regards, Zulq. stan shepherd wrote: Hi, I have the following method, that code critics flags as long: testMaleMeiosis2 | testSet mCount pCount mTotal pTotal | pTotal := 0. mTotal := 0. Forecaster testMale meiose do: [:strand | testSet := strand testRun. mCount := testSet maternalCount. pCount := testSet paternalCount. mTotal := mTotal + mCount. pTotal := pTotal + pCount]. self should: [mTotal = 100 and: [pTotal = 100]] I'm trying to shorten it, including various attempts with inject: into: , but with no success. Any tips please? Stan ___ Beginners mailing list Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners
[Newbies] Re: Regular Expression Question
pbohuch wrote: testString := 'this is a test'. testCollection := '(^\s*)|(\s)|\w+' asRegex matchesIn: testString. If I execute this in a workspace, I get an infinite loop. I think it's a problem with the expression - don't ^\s* and \w+ look for the same thing? Anyway, wouldn't '\w+|\s+' do what you want? 'this is a test' allRegexMatches: '\w+|\s+' "=> ('this' ' ' 'is' ' ' 'a' ' ' 'test')" Or if you just want the words, '\w+'. And, if you just want the words then you can probably just use #findTokens: 'this is a test' findTokens: ' ' "=> ('this' 'is' 'a' 'test')" Regards, Zulq. ___ Beginners mailing list Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners
[Newbies] Re: Overriding methods
In response to "(I guess it's possible in this way to create an object that destabilizes the system?)", I was demonstrating how one might introduce instability. I would normally send super new. Randal L. Schwartz wrote: "Zulq" == Zulq Alam <[EMAIL PROTECTED]> writes: Zulq> In VW, where initialize isn't called by default, I do this all the time: Zulq> new Zulq>^ self new initialize You mean "basicNew", unless you like infinite loops. :) ___ Beginners mailing list Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners
[Newbies] Re: Overriding methods
In VW, where initialize isn't called by default, I do this all the time: new ^ self new initialize ;) Blake wrote: I not even 100% clear on how it could be so terrible beyond that particular class. (I guess it's possible in this way to create an object that destabilizes the system?) ___ Beginners mailing list Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners
[Newbies] Re: parenthesis always inserted in pairs?
These are "smart characters". You can disable them via the preference ecompletionSmartCharacters available in the Preference Browser. Regards, Zulq. Ch Lamprecht wrote: Hi, is there a way to switch off the 'paired' insert of () [] ? Christoph ___ Beginners mailing list Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners
[Newbies] Re: Perform
And, instead of concatenating your selector with ':', you can send a symbol the message #asMutator (which does it for you). For example: #phone1 asMutator "prints #phone1:" #phone2 asMutator "prints #phone2:" Which you can use like this: phoneBook perform: aSelector asMutator with: aValue Regards, Zulq. Mathieu Suen wrote: Hi Jakub, #perform: is for unary message If you want to pass arguments you have to use #perform:with:"On argument" #perform:with:with: "Two arguments" ... #perform:withArguments: "Several arguments inside an Array" so in your case it should be: phonebook perform: #phone1 with: aValue HTH On Jan 14, 2008, at 2:58 PM, Jakub wrote: hello i have class with two setters phone1: aValue phone2: aValue and i want call it dynamically aSelector is phone1 or phone2 string setPhohne: aSelector by: aValue phoneBook perform aSelector, ':' aValue but this is not working how can i do this when i try this iwth getters it works fine Transcript show: (phoneBook perform aSelector); cr. -- Jakub. ___ Beginners mailing list Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners Mth ___ Beginners mailing list Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners
[Newbies] Re: Efficiently writing to a file
Hi Ian, You can get significant improvements by, writing to the file in one go, avoiding any intermediate strings, and taking a good guess at the size of your buffer. | bs fs bt ft | bs := WriteStream on: (String new: 6). bt := Time millisecondsToRun: [1 to: 1 do: [:i | i printOn: bs. bs nextPut: Character cr; nextPut: Character lf]]. fs := StandardFileStream fileNamed: 'c:/test4.txt'. ft := Time millisecondsToRun: [[fs nextPutAll: bs contents] ensure: [fs close]]. Transcript show: bt asString; show: ' / '; show: ft asString; show: ' / '; show: bt + ft asString; cr. The above runs in about 162ms on my machine where as your initial code takes about 275ms. If, however, I load the VisualWorks implementations of these methods (change set attached) the above runs in about 65ms. I wouldn't use this change set if I were you - I've probably broken something! I think number printing could be improved considerably without any primitives. Thanks, Zulq. Ian Oversby wrote: Is this a reasonable way of writing to a file? It seems to run a little slower than I would expect. Thanks, Ian | myFile | myFile := StandardFileStream fileNamed: 'c:/test.txt' Transcript show: (Time millisecondsToRun: [ 1 to: 1 do: [ :x | myFile nextPutAll: ((x asString) , String crlf) ]]) asString , ' millseconds' ; cr. myFile close. 'From Squeak3.9 of 7 November 2006 [latest update: #7067] on 22 April 2007 at 11:36:08 pm'! !Integer methodsFor: 'vw' stamp: 'za 4/22/2007 23:06'! printDigitsOn: aStream base: b "Print a representation of the receiver on the stream, aStream, in base b where 2<=b<=256. The receiver is known to be non-negative." self >= b ifTrue: [self // b printDigitsOn: aStream base: b]. aStream nextPut: (Character digitValue: self \\ b)! ! !Integer methodsFor: 'vw' stamp: 'za 4/22/2007 23:06'! printOn: aStream base: b "Print a representation of the receiver on the stream, aStream, in base b where 2<=b<=256." b < 2 ifTrue: [self error: (#errInvalidBase << #dialogs >> 'Invalid base: <1p>' expandMacrosWith: b)]. self < 0 ifTrue: [aStream nextPut: $-. self negated printOn: aStream base: b] ifFalse: [self printDigitsOn: aStream base: b]! ! !Integer reorganize! ('arithmetic' * + - / // \\\ alignedTo: crossSumBase: quo:) ('benchmarks' benchFib benchmark tinyBenchmarks) ('bit manipulation' << >> allMask: anyBitOfMagnitudeFrom:to: anyMask: bitAnd: bitClear: bitInvert bitInvert32 bitOr: bitShift: bitShiftMagnitude: bitXor: highBit highBitOfMagnitude lowBit noMask:) ('comparing' < = > hash) ('converting' adaptToComplex:andSend: adaptToFraction:andSend: adaptToScaledDecimal:andSend: asCharacter asColorOfDepth: asComplex asFloat asFloatSimply asFraction asHexDigit asInteger asScaledDecimal: asYear) ('enumerating' timesRepeat:) ('explorer' explorerContents hasContentsInExplorer) ('mathematical functions' factorial gcd: lcm: raisedToInteger:modulo: raisedTo:modulo: take:) ('printing' asStringWithCommas asStringWithCommasSigned asTwoCharacterString asWords destinationBuffer: digitBuffer: isLiteral printOn:base:showRadix: printPaddedWith:to: printPaddedWith:to:base: printStringRadix:) ('printing-numerative' byteEncode:base: printOn:base:length:padded: printStringBase: printStringBase:length:padded: printStringHex printStringLength: printStringLength:padded: printStringPadded: printStringRoman radix: storeOn:base: storeOn:base:length:padded: storeStringBase:length:padded: storeStringHex) ('system primitives' lastDigit replaceFrom:to:with:startingAt:) ('testing' even isInteger isPowerOfTwo isPrime) ('tiles' asPrecedenceName) ('truncation and round off' asLargerPowerOfTwo asPowerOfTwo asSmallerPowerOfTwo atRandom atRandom: ceiling floor normalize rounded truncated) ('private' copyto: digitAdd: digitCompare: digitDiv:neg: digitLogic:op:length: digitLshift: digitMultiply:neg: digitRshift:bytes:lookfirst: digitSubtract: growby: growto: isProbablyPrimeWithK:andQ: print:on:prefix:length:padded: romanDigits:for:on:) ('vw' printDigitsOn:base: printOn:base:) ! ___ Beginners mailing list Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners
[Newbies] Re: array literal - a misunderstanding?
Hi Thomas, The Terse guide to Squeak at http://wiki.squeak.org/squeak/5699 may help. Zulq. Thomas Fischer wrote: PS: Is there anywhere in the net a *COMPLETE AND COMPACT* list of all "cryptical" syntax characteristics for smalltalk/squeak? ___ Beginners mailing list Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners