开始使用Nim(二)
来源:互联网 发布:网站流量统计软件 编辑:程序博客网 时间:2024/06/02 05:50
原文:https://akehrer.github.io/nim/2015/01/14/getting-started-with-nim-pt2.html
上一次写了关于我学习Nim的兴趣为了增强我的技能,并且以创建一个简单的统计模块开始。我们跳过了一些的学习语言的细微差别,以建立一个高斯分布模型为开始。今天我们来看看一些事情,我发现我弄懂了在模块中的其他一些过程。
NaN
在内嵌的math 模块中一些过程以NaN作为返回值,但是我不能在Nim中找到一种容易的方法验证它。幸好math.h 标准库包含 isnan()过程,我们能够重用它。在这种情况下我创建了一个附加过程,从C过程把整型结果转换为布尔型。你能看到我用我的代码创建了一个NAN常量。
import mathconst NAN = 0.0/0.0 # floating point not a number (NaN)proc cIsNaN(x: float): int {.importc: "isnan", header: "<math.h>".} ## returns non-zero if x is not a numberproc isNaN*(x: float): bool = ## converts the integer result from cIsNaN to a boolean if cIsNaN(x) != 0: true else: false
More Statistics
随着NaN问题的解决,我开始写更多的描述统计的过程,比如median,kurtosis和 quantile.下面是median的代码:
import algorithm # needed for `sort`proc median*(x: openArray[float]): float = ## computes the median of the elements in `x`. ## If `x` is empty, NaN is returned. var sx = @x # convert to a sequence since sort() won't take an openArray sx.sort(system.cmp[float]) try: if sx.len mod 2 == 0: var n1 = sx[(sx.len - 1) div 2] var n2 = sx[sx.len div 2] result = (n1 + n2) / 2.0 else: result = sx[(sx.len - 1) div 2] except IndexError: result = NAN
· median 过程用一个openArray 类型作为它的输入,与math 模块中mean 过程是相似的。Nim中的Open arrays 使不同大小的数组能够传入到过程。openArray类型有一些基本的操作符可以使用,但是我们不能传送一个openArray类型到sort过程,因此我们首先要把它转换为一个序列(通过使用 @功能在 x 上)。
·当计算排序后的序列的下标是使用了div 过程,因为它做的是整数除法,不像 / 会得到一个float值。· Nim有一个与python 相似的 try....except 语法,它用在这是为了捕获空数组被传进这个过程中。
·同样记录我们上面创建的正在使用的NAN常量。
现在我们有一个正在工作的median 过程,让我们添加一些测试:
when isMainModule: # Setup some test data var data1: array[0..6, float] var data2: array[0..7, float] var data3 = newSeq[float]() var data4: array[1, float] var data5: array[2, float] data1 = [1.4, 3.6, 6.5, 9.3, 10.2, 15.1, 2.2] data2 = [1.4, 3.6, 6.5, 9.3, 10.2, 15.1, 2.2, 0.5] data4 = [2.3] data5 = [2.2, 2.5] # Test median() assert(abs(median(data1) - 6.5) < 1e-8) assert(abs(median(data2) - 5.05) < 1e-8) assert(isNaN(median(data3))) # test an empty sequence assert(abs(median(data4) - 2.3) < 1e-8) assert(abs(median(data5) - 2.35) < 1e-8)
得到的值是浮点数,我们不能用 "== "测试,我也回去和确定了在第一篇中用于GaussDist的测试。
当我使用其它过程时我遇上了Nim的静态类型,有时代码看起来足够像python以至于我忘记检查过程正在使用的适当类型。下面是以quantile过程作为例子的代码:
1 proc quantile*(x: openArray[float], frac: float): float = 2 ## Computes the quantile value of `x` determined by the fraction `frac` 3 ## If `x` is empty, NaN is returned. 4 ## `frac` must be between 0 and 1 so for the 25th quantile 5 ## the value should be 0.25, any other value returns `NaN` 6 if x.len == 0: 7 result = NAN 8 elif frac < 0.0 or frac > 1.0: 9 result = NAN10 elif frac == 0.0:11 result = x.min12 else:13 var sx = @x # convert to a sequence since sort() won't take an openArray14 sx.sort(system.cmp[float])15 16 var n = sx.len - 1 # max index17 var i = int(math.floor(float(n) * frac)) # quantile index18 19 if i == n:20 result = sx[n]21 elif sx.len mod 2 == 0:22 # even length23 var n1 = sx[i]24 var n2 = sx[i+1]25 result = (n1 + n2) / 2.026 else:27 # odd length28 result = sx[i]
你能够看到在17行,我们需要在n与 frac(a float) 相乘前把n转换为一个float型。这是因为Nim 将不会自动的转换一个int型到float型[ref]。结果然后再转换为int 型,所以它才能作为一个序列的标号。值得庆幸的是当程序运行错误时Nim会提供有用的反馈,还会试着指出正确的方向。这里是没有把n转换为float时编译出现的错误。
Error: type mismatch: got (int, float)but expected one of:system.*(x: set[T], y: set[T]): set[T]system.*(x: int, y: int): intalgorithm.*(x: int, order: SortOrder): intsystem.*(x: int64, y: int64): int64system.*(x: int32, y: int32): int32system.*(x: int8, y: int8): int8system.*(x: float, y: float): floatsystem.*(x: float32, y: float32): float32system.*(x: int16, y: int16): int16
所以可以看到 *过程需要的是两个相同类型的参数,但是它得到了一个int型和一个float型。解决这个问题程序将能正确运行。
总而言之,我喜欢目前已经了解到的Nim。我感觉它是容易学会和开始的。它的文档是充足的但是还不完整,这对于一个年轻的语言来说并不奇怪。到目前为止,我使用它更像是在编译python,还没有太深入其独特的特性。对于它是否可以用来创建python模块,这将是有趣的,也许能通过cython接口。但这是之后要做的事。
你能在这里找到我的 nim-statistics 模块代码。Reference
Part 1
- 开始使用Nim(二)
- 开始使用Nim(二)
- 开始使用Nim
- 开始使用Nim
- nyoj 135 取石子(二) 【NIM】
- Nim教程翻译(二)
- nim manual(二)
- 开始Ext(二)
- 从头开始(二)
- C++--开始(二)
- AnkhSvn中文文档(二)---开始使用(Getting started)
- 开始使用Android Sutdio(二)配置Android Studio
- OkHttp+ Retrofit使用从0开始(二)
- 正则使用从0开始学习(二)
- 博弈论之Nim博弈与sg函数(二)
- 初始博弈【二】Nim(hdu 1849,poj1704)
- Nim(Nim博弈变形)
- Misere Nim (Nim博弈)
- LightningChart Ultimate使用教程:使用SampleDataSeries进行实时监测
- socket编程整理
- JSON数据解析(GSON方式)
- 如何衡量软件设计的质量
- html页面上传图片并进行展示
- 开始使用Nim(二)
- Kerberos安全体系简介
- monkey log分析说明
- Spark RDD写入RMDB(Mysql)方法二
- 黑马程序员——Java基础---面向对象
- 新UI框架-Butter Knife
- 天气预报接口
- 自定义AlertDialog(仿微信)
- LeetCode_20---Valid Parentheses