diff options
Diffstat (limited to 'lib')
-rwxr-xr-x | lib/pure/math.nim | 14 | ||||
-rwxr-xr-x | lib/pure/strutils.nim | 66 | ||||
-rwxr-xr-x | lib/system.nim | 15 |
3 files changed, 87 insertions, 8 deletions
diff --git a/lib/pure/math.nim b/lib/pure/math.nim index 8e3dd4bdb..d347006b7 100755 --- a/lib/pure/math.nim +++ b/lib/pure/math.nim @@ -226,21 +226,27 @@ proc push*(s: var TRunningStat, x: float) = inc(s.n) # See Knuth TAOCP vol 2, 3rd edition, page 232 if s.n == 1: + s.min = x + s.max = x s.oldM = x s.mean = x s.oldS = 0.0 else: + if s.min > x: s.min = x + if s.max < x: s.max = x s.mean = s.oldM + (x - s.oldM)/toFloat(s.n) s.newS = s.oldS + (x - s.oldM)*(x - s.mean) # set up for next iteration: s.oldM = s.mean s.oldS = s.newS - s.sum = s.sum + x - if s.min > x: s.min = x - if s.max < x: s.max = x - + +proc push*(s: var TRunningStat, x: int) = + ## pushes a value `x` for processing. `x` is simply converted to ``float`` + ## and the other push operation is called. + push(s, toFloat(x)) + proc variance*(s: TRunningStat): float = ## computes the current variance of `s` if s.n > 1: result = s.newS / (toFloat(s.n - 1)) diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim index 81ca75417..f6de035a8 100755 --- a/lib/pure/strutils.nim +++ b/lib/pure/strutils.nim @@ -464,6 +464,69 @@ proc align*(s: string, count: int): string {. else: result = s +iterator tokenize*(s: string, seps: set[char] = Whitespace): tuple[ + token: string, isSep: bool] = + ## Tokenizes the string `s` into substrings. + ## + ## Substrings are separated by a substring containing only `seps`. + ## Examples: + ## + ## .. code-block:: nimrod + ## for word in tokenize(" this is an example "): + ## writeln(stdout, word) + ## + ## Results in: + ## + ## .. code-block:: nimrod + ## (" ", true) + ## ("this", false) + ## (" ", true) + ## ("is", false) + ## (" ", true) + ## ("an", false) + ## (" ", true) + ## ("example", false) + ## (" ", true) + var i = 0 + while true: + var j = i + var isSep = s[j] in seps + while j < s.len and (s[j] in seps) == isSep: inc(j) + if j > i: + yield (copy(s, i, j-1), isSep) + else: + break + i = j + +proc wordWrap*(s: string, maxLineWidth = 80, + splitLongWords = true, + seps: set[char] = whitespace, + newLine = "\n"): string {. + noSideEffect, rtl, extern: "nsuWordWrap".} = + ## word wraps `s`. + result = "" + var SpaceLeft = maxLineWidth + for word, isSep in tokenize(s, seps): + if len(word) > SpaceLeft: + if splitLongWords and len(word) > maxLineWidth: + result.add(copy(word, 0, spaceLeft-1)) + var w = spaceLeft+1 + var wordLeft = len(word) - spaceLeft + while wordLeft > 0: + result.add(newLine) + var L = min(maxLineWidth, wordLeft) + SpaceLeft = maxLineWidth - L + result.add(copy(word, w, w+L-1)) + inc(w, L) + dec(wordLeft, L) + else: + SpaceLeft = maxLineWidth - len(Word) + result.add(newLine) + result.add(word) + else: + SpaceLeft = SpaceLeft - len(Word) + result.add(word) + proc startsWith*(s, prefix: string): bool {.noSideEffect, rtl, extern: "nsuStartsWith".} = ## Returns true iff ``s`` starts with ``prefix``. @@ -879,6 +942,7 @@ when isMainModule: assert align("abc", 4) == " abc" assert align("a", 0) == "a" assert align("1232", 6) == " 1232" - + echo wordWrap(""" this is a long text -- muchlongerthan10chars and here + it goes""", 10, false) diff --git a/lib/system.nim b/lib/system.nim index dad8d2d79..8eabe797a 100755 --- a/lib/system.nim +++ b/lib/system.nim @@ -1099,6 +1099,15 @@ iterator items*(a: cstring): char {.inline.} = yield a[i] inc(i) +iterator enumerate*[TContainer, TItem](a: TContainer): tuple[ + index: int, item: TItem] {.inline.} = + ## iterates over each item of `a` via `items` and yields an additional + ## counter/index starting from 0. + var j = 0 + for it in items(a): + yield (j, a) + inc j + proc isNil*[T](x: seq[T]): bool {.noSideEffect, magic: "IsNil".} proc isNil*[T](x: ref T): bool {.noSideEffect, magic: "IsNil".} proc isNil*(x: string): bool {.noSideEffect, magic: "IsNil".} @@ -1108,20 +1117,20 @@ proc isNil*(x: cstring): bool {.noSideEffect, magic: "IsNil".} ## Fast check whether `x` is nil. This is sometimes more efficient than ## ``== nil``. -proc `&` *[T](x, y: openArray[T]): seq[T] {.noSideEffect.} = +proc `&` *[T](x, y: seq[T]): seq[T] {.noSideEffect.} = newSeq(result, x.len + y.len) for i in 0..x.len-1: result[i] = x[i] for i in 0..y.len-1: result[i+x.len] = y[i] -proc `&` *[T](x: openArray[T], y: T): seq[T] {.noSideEffect.} = +proc `&` *[T](x: seq[T], y: T): seq[T] {.noSideEffect.} = newSeq(result, x.len + 1) for i in 0..x.len-1: result[i] = x[i] result[x.len] = y -proc `&` *[T](x: T, y: openArray[T]): seq[T] {.noSideEffect.} = +proc `&` *[T](x: T, y: seq[T]): seq[T] {.noSideEffect.} = newSeq(result, y.len + 1) for i in 0..y.len-1: result[i] = y[i] |