Expecco Code Snippets/en: Unterschied zwischen den Versionen
Cg (Diskussion | Beiträge) (→HTML) |
Cg (Diskussion | Beiträge) (→XML) |
||
Zeile 548: | Zeile 548: | ||
retrieve a set of any child with matching tag (recursive) |
retrieve a set of any child with matching tag (recursive) |
||
===== Example: ===== |
|||
|doc nodes firstBla secondBla| |
|doc nodes firstBla secondBla| |
||
Version vom 5. Februar 2022, 15:42 Uhr
Inhaltsverzeichnis
- 1 Code Snippets for Common Tasks
Code Snippets for Common Tasks[Bearbeiten]
Warning: this page is for geeks, programmers and coding freaks
This page is for coders of elementary actions which are to execute inside expecco (i.e. Smalltalk and JavaScript elementary actions). For bridged actions, the corresponding programming language/environment determines the syntax and set of possible operations and is outside the control of expecco.
You will find code snippets for common tasks here. Although most (or all) could also be implemented using existing actions from the standard library, it is often more convenient to write a little elementary action eg. to extract data from received binary messages or from a textual document.
You can copy-paste these snippets into the code editor and modify as appropriate. You can also paste them into a Workspace window and execute them there. Finally, you may also find those snippets via the Method Finder, when entering the desired result value.
Input and Output Pins[Bearbeiten]
To read a value from a pin named inPinName, use:
Smalltalk:
|x| x := inPinName value.
JavaScript and NodeJS:
var x; x = inPinName.value().
Python:
x = inPinName.value()
To write a value x to an output pin named outPinName, use:
Smalltalk:
outPinName value: x
JavaScript and NodeJS:
outPinName.value(x);
Python:
outPinName.value(x)
Bits & Bytes[Bearbeiten]
Set, Clear or Toggle a Bit[Bearbeiten]
Smalltalk:
|numIn result| numIn := 0b10011001. "/ using masks result := numIn bitOr: 0b00110000. "/ to set the two bits result := numIn bitAnd: 0b11110000. "/ to mask bits result := numIn bitClear: 0b00000011. "/ to clear bits result := numIn bitXor: 0b00001100. "/ to toggle bits result := numIn bitTest: 0b00001100. "/ to test if masked bits are all set result := numIn lowBits: 5. "/ to extract a number of lowBits "/ using bit numbers (index starts with 1 for the least significant bit) result := numIn bitAt: 1. "/ to extract the first bit result := numIn setBit: 2. "/ set the second bit result := numIn clearBit: 2. "/ clear the second bit result := numIn invertBit: 2. "/ toggle the second bit
JavaScript:
var numIn, result; numIn = 0b10011001; // using masks result = numIn | 0b00110000; // to set the two bits result = numIn & 0b11110000; // to mask bits result = numIn & ˜0b00000011; // to clear bits result = numIn ^ 0b00001100; // to toggle bits result = (numIn & 0b00001100) != 0; // to test if masked bits are all set result = numIn.lowBits(5); // to extract a number of lowBits // using bit numbers (index starts with 1 for the least significant bit) result = numIn.bitAt(1); // to extract the first bit result = numIn.setBit(2); // set the second bit result = numIn.clearBit(2); // clear the second bit result = numIn.invertBit(2); // toggle the second bit
Counting, Highest and Lowest Bit[Bearbeiten]
Smalltalk:
|numIn result| numIn := 0b10011001. result := numIn highBit. "/ index of highest bit result := numIn lowBit. "/ index of lowest bit result := numIn bitCount. "/ count ones
JavaScript:
var numIn, result; numIn = 0b10011001; result = numIn.highBit(); // index of highest bit result = numIn.lowBit(); // index of lowest bit result = numIn.bitCount(); // count ones
Shifting and Byte Access[Bearbeiten]
Smalltalk:
|numIn result| numIn := 0xABCD. result := numIn bitShift: 8. "/ left shift by 8 result := numIn bitShift: -8. "/ right shift by 8 result := numIn << 8. "/ alternative left shift result := numIn >> 8. "/ alternative right shift result := numIn digitByteAt:1. "/ the lowest 8 bits result := numIn digitByteAt:2. "/ the next 8 bits result := numIn digitBytes. "/ bytes as ByteArray
JavaScript:
var numIn, result; numIn = 0xABCD; result = numIn << 8; // left shift by 8 result = numIn >> 8; // right shift by 8 result = numIn.digitByteAt(1); // as above
Accessing Bytes/Ints/Floats in a ByteArray[Bearbeiten]
Typical tasks when receiving binary encoded communication protocol messages are to extract bytes, ints, floats and strings.
Smalltalk:
|bytes result| "/ constant byte array here; "/ could also come from a file, stream, message or document (see below) bytes := #[ 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 ]. result := bytes at:1. "/ 1 based index here result := bytes[1]. "/ alternative syntax; also 1 based result := bytes signedInt16At:2. "/ signed int16 in machine's native byte order result := bytes signedInt16At:3 MSB:false. "/ in explicit lsb-order result := bytes signedInt16At:3 MSB:true. "/ in explicit msb-order result := bytes signedInt32At:2. "/ same options as above result := bytes signedInt64At:2. "/ same options as above result := bytes signedInt128At:1. "/ same options as above result := bytes unsignedInt16At:2. "/ same for unsigned ints result := bytes unsignedInt16At:3 MSB:false. result := bytes unsignedInt16At:3 MSB:true. result := bytes unsignedInt32At:2. result := bytes unsignedInt64At:2. "/ writing into a byte array bytes int16At:4 put:0x1234. "/ again in native byte order bytes int16At:4 put:0x1234 MSB:true. "/ or explicit order "/ floats and doubles result := bytes floatAt:4. "/ extract a 32bit float result := bytes floatAt:4 MSB:true "/ in given byte order result := bytes doubleAt:4. "/ extract a 64bit float result := bytes doubleAt:4 MSB:true "/ in given byte order bytes floatAt:4 put:1.234. "/ encode a 32bit float (native byte order) bytes floatAt:4 put:1.234 MSB:true. "/ encode a 32bit float MSB bytes doubleAt:4 put:1.234. "/ encode a 64bit float (native byte order) "/ strings result := bytes stringAt:2 size:4. "/ extract bytes as a string result := bytes zeroByteStringAt:3 maximumSize:3 "/ extract from a 0-terminated C-string
JavaScript:
var bytes, result; // constant byte array here; // could also come from a file, stream, message or document (see below) bytes = [ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 ].asByteArray(); result = bytes[1]; // 1 based index here result = bytes.signedInt16At(2); // signed int16 in machine's native byte order result = bytes.signedInt16At_MSB(3, false); // in explicit lsb-order result = bytes.signedInt16At_MSB(3, true); // in explicit msb-order result = bytes.signedInt32At(2); // same options as above result = bytes.signedInt64At(2); // same options as above result = bytes.signedInt128At(1); // same options as above result = bytes.unsignedInt16At(2); // same for unsigned ints result = bytes.unsignedInt16At_MSB(3,false); result = bytes.unsignedInt16At_MSB(3,true); result = bytes.unsignedInt32At(2); result = bytes.unsignedInt64At(2); // writing into a byte array bytes.int16At_put(4,0x1234); // again in native byte order bytes.int16At_put_MSB(4,0x1234,true); // or explicit order // floats and doubles result = bytes.floatAt(4); // extract a 32bit float result = bytes.floatAt_MSB(4,true); // in given byte order result = bytes.doubleAt(4); // extract a 64bit float result = bytes.doubleAt_MSB(4,true); // in given byte order bytes.floatAt_put(4, 1.234); // encode a 32bit float in native byte order bytes.floatAt_put_MSB(4, 1.234, true); // encode a 32bit float in MSB bytes.doubleAt_put(4, 1.234); // encode a 64bit float // strings result = bytes.stringAt_size(2,4); // extract bytes as a string result = bytes.zeroByteStringAt_maximumSize(3,3); // extract from a 0-terminated C-string
Byte Order and Sign Extension[Bearbeiten]
Smalltak:
rslt := numberIn byteSwapped. "/ swap pairwise rslt := numberIn byteSwapped16. "/ only the lowest 2 bytes rslt := numberIn byteSwapped32. "/ only the lowest 4 bytes rslt := numberIn byteSwapped64. "/ only the lowest 8 bytes rslt := numberIn signExtendedByteValue. "/ sign extent from bit 8 rslt := numberIn signExtendedShortValue. "/ sign extent from bit 16 rslt := numberIn signExtended24BitValue. "/ sign extent from bit 24 rslt := numberIn signExtendedLongValue. "/ sign extent from bit 32
Numeric[Bearbeiten]
Smalltalk:
numberIn sin. "/ sine; also cos, tan, sin, cosh, arcSin, arcCos etc. "/ (all trigonometric args in radians) numberIn degreesToRadians sin "/ converting degrees first n sqrt "/ square root n cbrt "/ cubic root n nthRoot:5 "/ fifth root n ln "/ natural logarithm n log "/ decimal logarithm n log2 "/ binary logarithm n raisedTo:e "/ raised to the power n ** e "/ alternative n1 agm: n2 "/ arithmetic-geometric mean n1 min: n2 "/ the minimum (smaller) of the two n1 max: n2 "/ the maximum
JavaScript:
numberIn.sin(); // similar Math.sin(numberIn); // alternative numberIn.degreesToRadians().sin(); n.sqrt(); n.cbrt(); n.ln(); n.log(); n.log2();
n ** e // raised to the power n.raisedTo(e) // alternative n1.agm(n2); // geometric mean Math.min(n1. n2) // minimum Math.max(n1, n2) // maximum
Number Vectors[Bearbeiten]
v := #f32( 1.0 2.0 3.0 ). "/ a float32 (ieee single) vector "/ (elements must be constant) v := #f64( 1.0 2.0 3.0 ). "/ a float64 (ieee double) vector v min. "/ min and max values v max. v minMax. "/ both as 2-element array v sum. "/ sum and product of elements v product. v arithmeticMean. "/ statistic functions v geometricMean. v harmonicMean. v median. v standardDeviation. v variance.
SI Units and Physical Values[Bearbeiten]
Smalltalk:
1 kilo "/ multiplied by 1000 1 deci "/ divided by 10 1 mega / giga / tera "/ various SI multipliers 1 milli / micro / nano / pico "/ 1 meter "/ physical length 1 kilo meter 1 milli meter 1 ohm / volt / ampere / newton / watt. "/ various physical units 10 milli volt / 1 kilo ohm "/ computing with units (results is ampere) 10 degreesCelsius asFahrenheit 40 degreesFahrenheit asCelsius 100 centi meter asInches
JavaScript:
1.deci().meter() 10.milli().volt() / 1.kilo().ohm() "/ as above
Converting Numbers to Strings and Vice Versa[Bearbeiten]
Smalltalk:
num printString "/ number to string (decimal) num printStringRadix:2 "/ number to string (binary) num printStringRadix:16 "/ number to string (hex) num printStringRadix:16 leftPaddedTo:5 with:$0. "/ left padded string '%3d %02x' printf:{num1 . num2}. "/ C-printf like formatting e'the result is: {3*num1}' "/ string with embedded expression Integer readFrom:'1234' "/ string to number Integer readFrom:s radix:16. "/ hex '%d %02x' scanf: '1234 AF' "/ C-scanf like reading (returns an array)
String/Text Processing[Bearbeiten]
Searching[Bearbeiten]
Smalltalk:
|s| s := 'some String with multiple Words'. s includes:$S "/ is character included? s includesString:'WITH' "/ no - case difference s includesString:'WITH' caseSensitive:false. "/ yes s indexOf:$S. "/ find index of character (1 based) s indexOfString:'Wo'. "/ find index of substring s indexOfString:'WO' caseSensitive:false. "/ case insensitive s lastIndexOf:$e. "/ find last index of character "/ and similar for string and last string s indexOf:$e startingAt:5 "/ start search at index "/ and similar for string and last string s includesAny:'abc' "/ any of those characters included? s indexOfAny:'abc' "/ index of any of those characters included? s indexOfSeparator "/ first whitespace s lastIndexOfSeparator "/ last whitespace
Splitting / Truncating[Bearbeiten]
s asCollectionOfWords "/ split into words s splitOn:Character space "/ ditto s splitOn:[:ch | ch isUppercase]. "/ split with rule s withoutSeparators "/ trim whitespace at both ends s withoutLeadingSeparators "/ at one end s withoutTrailingSeparators
JavaScript:
var s = "some String with multiple Words"; s.splitOn($' '); s.splitOn(function (ch) { return ch.isUppercase(); })
Searching/Extracting Parts from a Document[Bearbeiten]
|s lines| s := someFile asFilename contentsAsString. "/ read a file into a string s := someFile asFilename contents. "/ read as collection of lines lines := s asCollectionOfLines. "/ convert string to a list of lines lines findFirst:[:l | l startsWith:'foo']. "/ search for a line; return the index lines detect:[:l | l startsWith:'foo']. "/ search but retrieve the line lines count:[:l | l endsWith:'foo']. "/ count lines for which lines select:[:l | l includesString:'foo'] "/ extract only those lines lines copyTo:100 "/ the first 100 lines lines copyLast:100 "/ the last 100 lines lines copyFrom:2 to:10. "/ some of those lines lines copyFrom:2 butLast:10. "/ trim off some at either end lines copyFrom:(lines findFirst:...) "/ search and copy from found lines select:[:l | l matchesRegex: '[0-9]+ [0-9]+' ]. "/ extract lines matching regex pattern lines select:[:l | l matches: '[0-9]+*' ]. "/ extract lines matching GLOB pattern
File I/O[Bearbeiten]
Opening a file, reading, closing[Bearbeiten]
Smalltalk:
|inStream line| inStream := 'foo/bar' asFilename readStream. [inStream atEnd] whileFalse:[ "/ lines, words, strings line := inStream nextLine. "/ one line char := inStream next. "/ one character more := inStream next:10. "/ 10 characters word := inStream nextAlphanumericWord. "/ one word some := inStream upToAll:':'. "/ up to but excluding separator some := inStream throughAll:':'. "/ up to and including separator
"/ binary data byte := inStream nextByte. "/ one byte short := inStream nextUnsignedInt16MSB:false. "/ a short in LSB order short := inStream nextSignedInt16MSB:false. "/ a signed short in LSB order ]. inStream close.
to get the whole contents as one big string:
'foo/bar' asFilename contentsAsString
to get it as a collection of lines:
'foo/bar' asFilename contents
to get it as one big binary ByteArray:
'foo/bar' asFilename binaryContents
it is good practice to ensure that the file is closed:
inStream := 'foo/bar' asFilename open. [ ... ] ensure:[ inStream close ]
which is done by the convenient helper:
'foo/bar' asFilename readingFileDo:[:inStream | [inStream atEnd] whileFalse:[ ... ] ].
JavaScript:
var inStream, line; inStream = "foo/bar".asFilename().readStream(); while (! inStream.atEnd() ) { line = inStream.nextLine(); } inStream.close();
get the whole contents as one big string:
"foo/bar".asFilename().contentsAsString();
get it as a collection of lines:
"foo/bar".asFilename().contents();
get it as one big binary ByteArray:
"foo/bar".asFilename().binaryContents();
using the convenient helper:
"foo/bar".asFilename().readingFileDo( function (inStream) { while (! in stream.atEnd()) { ... } });
Sockets[Bearbeiten]
Sockets inherit from streams, thus all of the next/nextLine/nextPut/nextPutLine operations can be used on sockets as well.
Connecting, sending, receiving, closing[Bearbeiten]
Smalltalk:
|sock| sock := Socket connectTo:hostname port:portNr. in := sock nextLine. sock nextPutLine:'some message for you'. sock nextPutByte:123. "/ binary data sock nextBytes:100. "/ read binary data sock close
Providing a service[Bearbeiten]
|listenSocket connection| listenSocket := Socket new. listenSocket listenFor:1. [serving] whileTrue:[ connection := listenSocket accept. "/ fork a handler thread for this connection [ [connection atEnd] whileFalse:[ connection nextLine. connection nextPutLine:'hello'. ... ]. connection close. ] forkNamed:'server process' ].
HTML[Bearbeiten]
Parsing[Bearbeiten]
parse an HTML string, to get a DOM (Document Object Model) node:
domNode := HTML::HTMLParser parseText:aString
ask a node for its tag, attributes or children:
domNode tag domNode attributes domNode children
enumerate the children (all of them, recusrive):
domNode allChildrenDo: [:eachChild | ... ]
xpath-like access:
domNode / 'tagName' retrieve a set of immediate children with matching tag domNode // 'tagName' retrieve a set of any child with matching tag (recursive)
Example:[Bearbeiten]
|dom nodes firstAnchor| dom := HTML::HTMLParser parseText:'<html><body><a href="http://foo">bla</a>some text</body></html>'. t := dom tag. "/ t now: 'html' nodes := dom // 'a'. "/ nodes now: a collection containing the anchor DOM node firstAnchor := nodes first. firstAnchor href. "/ generates 'http://foo'
XML[Bearbeiten]
Parsing[Bearbeiten]
parse an XML string, to get a DOM (Document Object Model) node:
domNode := XML::XMLParser parse:aString
ask a node for its tag, attributes or children:
domNode tag domNode attributes domNode children
enumerate the children (all of them, recusrive):
domNode allChildrenDo: [:eachChild | ... ]
xpath-like access:
domNode / 'tagName' retrieve a set of immediate children with matching tag domNode // 'tagName' retrieve a set of any child with matching tag (recursive)
Example:[Bearbeiten]
|doc nodes firstBla secondBla| doc := XML::XMLParser parse:'<foo><bla>123</bla><bla>abc</bla></foo>'. t := doc root tagName. "/ t now: 'foo' nodes := doc // 'bla'. "/ nodes now: a collection containing the bla DOM node firstBla := nodes first. firstBla characterData. "/ generates '123' secondBla := nodes at:2. secondBla characterData. "/ generates 'abc'
JSON[Bearbeiten]
Encoding to JSON[Bearbeiten]
Smalltalk:
|obj json| obj := Dictionary new. obj at:'foo' put:123. obj at:'baz' put:#(1 2 3). "/ an array obj['bar'] := 'someString'. "/ alternative syntax json := JSONPrinter toJSON:obj.
JavaScript:
var obj, json; obj = new Dictionary; obj['foo'] = 123; obj['baz'] = [1, 2, 3]; obj['bar'] = "someString"; json = JSONPrinter.toJSON(obj);
Decoding from JSON[Bearbeiten]
var json, obj; json = "{\"foo\":123,\"baz\":[1,2,3],\"bar\":\"someString\"}"; obj = JSONReader.fromJSON(json); Transcript.showCR(obj['foo']); Transcript.showCR(obj['bar']); Transcript.showCR(obj.baz()); // alternative: use getter