Archive for 算法-编程

if语句的判断式必须是bool类型的,不能有隐式的转换。如果if分支里边最后是一个值,那么每一个分支都必须是一个值。 match语句类似c的switch。当找到一个匹配项,只执行改分支,不需要加一个break。一个分支匹配多个不同的值用“|”分隔。可以用“M..N”表示两个数字值范围。下划线匹配任何单个值。 每一个分支之间用逗号分隔,如果用大括号包含就可以省略逗号。

match my_number {
  0     => println!("zero"),
  1 | 2 => println!("one or two"),
  3..10 => println!("three to ten"),
  _     => println!("something else")
}
use std::f64;
use std::num::atan;
fn angle(vector: (f64, f64)) -> f64 {
    let pi = f64::consts::PI;
    match vector {
      (0.0, y) if y < 0.0 => 1.5 * pi,
      (0.0, _) => 0.5 * pi,
      (x, y) => atan(y / x)
    }
}
变量名可以匹配任意值,并且这个变量名绑定匹配到的值,可在分支里进行操作。“variable @ pattern”后边是匹配规则,前边是绑定的变量名。任何一个match分支可以有一个if语句,在匹配成功后进行判断。 循环。while的条件也必须是bool类型,break停止循环,continue进行下次循环。loop相当于while ture。for的两个例子:
for n in range(0, 5) {
    println!("{}", n);
}
let s = "Hello";
for c in s.chars() {
    println!("{}", c);
}
for可用于任何迭代器。  

Continue

好久没写博客了,越来越懒。碰到问题,文档上有的,或者可以搜索到的就懒得总结了,也经常要找多次。准备经常更新。 rust很早之前看过,那时候感觉标准库太少了,特别网络相关的根本找不到。0.9的时候我看好像有了,现在0.1了网络相关的已经有了,准备学习一下rust语言。 hello.rs  

fn main() {
    println!("hello?你好");
}
custc hello.rs ./hello rust所有的声明必须在函数里边,rust可以编译成库文件被别的程序包含,甚至是非rust程序。 println!这种标示符后面跟一个叹号的是宏调用。宏调用感觉好强大,还没仔细看。先记几个连接 http://static.rust-lang.org/doc/0.10/guide-macros.html http://static.rust-lang.org/doc/master/std/fmt/index.html#%3Ccode%3Eformat_args!%3C/code%3E http://static.rust-lang.org/doc/master/std/macros/macro.println.html http://static.rust-lang.org/doc/master/std/macros/builtin/macro.format_args.html rust类c语言,使用大括号界定代码块,包括选择/循环结构。函数调用myfunc(arg1,arg2).运算符和c的一样,优先级也基本相同。注视也一样,模块名通过两个冒号分离,像c++. if和while的括号不是必须的,他们的结构体必须在大括号里边,单条语句也不行。。 let关键字定义一个局部变量,变量默认是不可变的。需要改变的变量用let mut定义。 rust可以推断局部变量的类型,你可以在let后面加一个冒号,并指定变量的类型。常量的声明必须跟有变量类型。 static MONSTER_FACTOR: f64 = 57.8; let monster_size = MONSTER_FACTOR * 10.0; let monster_size: int = 50; 上边代码回产生一个变量未使用的警告,可以在变量名前加下划线屏蔽警告。 static声明Static items(constant value),可以被全局使用。rust的标示符以字母或者下划线开头,后面跟字母数字下划线。函数,变量,模块名用小写字母,使用下划线分割。定义的类型名用驼峰命名方式,rust原始类型名是小写。
let my_variable = 100;
type MyType = int;
let price;
if item == "salad" {
    price = 3.50;
} else if item == "muffin" {
    price = 2.25;
} else {
    price = 2.00;
}
let price =
    if item == "salad" {
        3.50
    } else if item == "muffin" {
        2.25
    } else {
        2.00
    };
上面两种写法相同,第二种最后有一个分号。大括号里的最后一行代码没有分号的话,他的值将作为整个表达式的值。 所以上面第二种写法,分支里边的数值不能加分号,加上的话回返回()或者空。 rust中除声明(变量,函数,traits, enum types),都是表达式。
fn is_four(x: int) -> bool {
   x == 4
}
不需要写return,表达式的结果将作为结果返回。 整型:int uint,分为8位,16位,32位,64位。数后面跟的字符代表类型i for int, u for uint, i8 for the i8,如果不跟,默认当做int类型 浮点: f32,f64。浮点数可以写成:0.0, 1e6, or 2.1e-4。 bool:true,false char: 单引号,类c 原始字符串,不包含转义:r"" 操作符类c,as操作符将左边的数值转换成右边的类型。as只能用于基本的数字类型和指针,不支持重载。transmute  

Continue

不定义的话默认差不多有一分钟,具体不知道 一种方法:engine = sqlalchemy.create_engine(db_connect_str, connect_args={'connect_timeout': 10}) 还可以直接写到db_connect_str后边,connect_args就是连接字符串后面跟的参数。

"mysql://user:password@host/test?connect_timeout=1"

Continue

蒙提霍尔问题的规则是 参赛者会看见三扇关闭了的门,其中一扇的后面有一辆汽车或者是奖品,选中后面有车的那扇门就可以赢得该汽车或奖品,而另外两扇门后面则各藏有一只山羊或者是后面没有任何东西。当参赛者选定了一扇门,但未去开启它的时候,知道门后情形的节目主持人会开启剩下两扇门的其中一扇,露出其中一只山羊。主持人其后会问参赛者要不要换另一扇仍然关上的门。问题是:换另一扇门会否增加参赛者赢得汽车的机会率? 我今天在微博上看到分享http://www.geekfan.net/7241/。然后区维基百科查了一下游戏的规则,开始我认为概率都是50%,然后又仔细看了作者的代码和结果,感觉我的感觉是错的0 0。我就仔细想了一下,发现却是错了。高中的时候就挺喜欢概率题,感觉挺有意思的 如果你不换,但是中奖,那就是你开始的选择, 三选一 。 如果你换,中奖,说明开始你选择错误,三选二。其实也是,像作者想的差不多,主持人帮你排除一个,相当于从bc选择了两次(选了b并且选了c)。 说白了好像是一个,你第一次选择错误的概率是多少。

Continue

golang博客里有一个例子。下面两段程序的结果是相同的。

package main
import (
    "fmt"
    "reflect"
)

type A struct {
    Name string
}
func (p A) test(){}
func (p A) Test1(){
    fmt.Println("df")
}

type AInterface interface {
    Test1()
    test()
}

func main() {
    var a A
    a.Name = "hha"
    var value reflect.Value = reflect.ValueOf(a)
    p := value.Interface().(AInterface)
    p.Test1()
}
package main
import (
    "fmt"
    "reflect"
)

type A struct {
    Name string
}
func (p A) test(){}
func (p A) Test1(){
    fmt.Println("df")
}

func main() {
    var a A
    a.Name = "hha"
    var value reflect.Value = reflect.ValueOf(a)
    vf := value.MethodByName("Test1")
    in := make([]reflect.Value, 0)
    vf.Call(in)
}
遗憾的是第一种方法事先定义好了interface,如果你加入的新方法应该是不能成功的。

Continue

从上上个周开始,就开始进行了。为啥起了这么蛋疼的一个名字,0 0当时建目录的时候不知道起啥名字,然后就起了一个the first web framework(tfwf),然后在bitbucket上开了一个私有项目,就开始写了。 先说说目的:一直都在用别人写的东西,包括接触的n多东西,一直想自己也实现一个。终于下决心用go准备写一个web框架,因为对这个还算是熟悉的了。选择go的原因是,写了可能会有别人用,但是我的出发点是学习并玩玩。不懂设计,不懂高深的理论,能有点样子就好了。 其实go自带的包写web应用已经非常方便了,现在主要实现的功能有: url的正则匹配,并且可以定义`^/aa/(?P<second>\d+)/`这样的样式。 网站的基本设置,像域名,名字,templedir等 控制器模仿tornado的样子写的,感觉蹩脚的很0 0. 启动时模板的导入。 就这些了。   说说从一开始写的过程,现在只记得七七八八了,时间有点长了。 准备写web框架的时候,我先去大略看了一遍谢大的 goweb编程那本书,第3.4节是对web框架开头路由的编写起了关键性的作用。 然后我就直接从http包 函数找到源码,把那里的代码意思看懂,就开始写了支持正则匹配的路由,然后对应的handler是函数。之后我就想写成python里边面向对象可以重载的方法,就研究了一下go的面向对象的编程,写成了接口的模式,什么走路像鸭子就是鸭子0 0。。写这里的时候我遇到一点问题:从接口取到对应struct的元素和方法,我有去看来reflect包的内容。 这期间我找了,web.go和beego的代码,大体看来一遍,发现beego的控制器写的跟我想的基本一样,直接看代码,借鉴了很多代码- -算不算抄袭。像url里匹配的变量,我发现go不支持继承的方法参数啥的必须一样。我就在context里边加了一个属性args,感觉真二。 今天开会的时候又加上了temple的启动时集中导入功能,功能的来源beego。再可耻一下0 0.settings和templates都是全局的,这些都不需要修改,第一次启动添加,应该不会有问题。 现在还有好多细节没处理好。还有很多必要的功能没有,像:错误提示,我自己写的时候测试,都发现非常困难,只是自己比较了解,能快速定位刚才修改的代码。我现在很多代码的错误验证都还没有0 0.、 对 一个主要的功能准备,明天实现:异步的问题,现在还没头绪,明天仔细研究一下,并测试一下在普通http请求这两个差别真的很大吗。我现在只是直接调用方法。觉得挺直观明白的0 0. 代码明天实现异步在上传到github上,现在也没格式化。我觉得我应该用我自己写的框架写点能用的东西,才知道还有哪里需要修改的更好0 0.

Continue

写的dht协议搜索的程序,这几天优化了一下发现速度确实快了好多。但是出现了一个新的问题,内存直接飙升,我开了十个爬虫占用内存800m。开始我以为是节点太多了,找了几个小问题修改一下,发现没用。后来就到网上查找python内存分析的工具,查了一点资料发现python有个meliae库操作非常方便,就使用分析了一下,发现不是节点太多的原因0 0,是保存发送的t_id,用来标示返回的消息是那个发出的一个字典过大了。 从分析的结果非常容易的定位了某个对象的数量和大小,非常容易分析。我开始以为是因为好多发送查询信息以后,对面没返回造成这个字典里的元素没有释放造成的,我就用过期时间判断了一下,进行过期删除。发现是小了,但是不是非常显著,好像少了几十不到100M。后来又减少了查找一个随机hash的时间,以前是1分钟查一次,我改成了就第一次查!,发现没减少0 0.不知道是啥的原因。应该就是查找hash,询问节点,然后返回然后询问里边的节点,最后数量越来越多,但是我不明白的是,怎么会这么多运行一分钟就有60万条。也就是说当时内存没释放的对象就有这么多。达到这个内存占用后,基本就不再变化,有很小很慢的提升,因为还开的其他程序,不确定是不是这些程序其他对象的增加造成的。等分阶段dump测试一下。 安装直接pip install meliae 就ok了,我看好久没更新的项目了,不知道还有没有好的替代品不过用着还不错。 将内存dump到文件

	from meliae import scanner
	scanner.dump_all_objects('/tmp/dump%s.txt' % time.time())
分析文件:
	from meliae import loader
	#加载dump文件
	om = loader.load('/opt/log/dump.txt')
	#计算各Objects的引用关系
	om.compute_parents()
	#去掉各对象Instance的_dict_属性
	om.collapse_instance_dicts()
	#分析内存占用情况
	om.summarize()
字段意义如下: Index : 行索引号 Count : 该类型的对象总数 %(Count) : 该类型的对象总数 占 所有类型的对象总数 的百分比 Size : 该类型的对象总字节数 %(Size) : 该类型的对象总字节数 占 所有类型的对象总字节数 的百分比 Cum : 累积行索引后的%(Size) Max : 该类型的对象中,最大者的字节数 Kind : 类型 分析某个对象,找出它的引用关系
	#得到所有的POP3ClientProtocol对象
	p = om.get_all('POP3ClientProtocol')
	#查看第一个对象
	p[0]
	#可以查看该对象的所有引用
	p[0].c
	#查看谁引用了这个对象
	p[0].p

Continue

今天在网上看到type的一段代码 ,然后查了一下文档,才知道type还有三个参数的用法。 http://docs.python.org/2/library/functions.html#type 以前只是知道type可以检测对象类型。然后发现了一个有趣的用法。 def println(self): a = 1 + 1 print "%s,%s" % (self.aa, a) A = type('A',(),{'aa':'print a', 'println': println}) a = A() type(a) Out[11]: __main__.A a.println() print a,2 第一个参数是类的名字,第二个元组是父类,第三个是属性。 哈哈,我觉得很好笑,虽然我函数里边第一个参数还是写的self,但是如果写一段代码都用这种方法定义类,然后再不注意类名的规范,代码会变的很难读。

Continue

从看了小虾的博文以后就也想写一个爬虫,一直写到现在才有点眉目。。其中还参考了http://codemacro.com上写的思路,不过有很多功能还没涉及到。 已经实现的功能,创建一个节点,能在dht网络中友好的生存并获取info_hash,好多技巧还没用到。实现插入数据库中,现在直接访问django写的应用(主要也是测试功能,两个功能分开了还没合到一起,直接用django的orm肯定要快好多),然后我在django里边写了下载种子文件和解析种子文件信息的功能。发现有许多hash找不到种子,下载不下来,后面还要在看一下怎么生成种子文件。分析种子信息的代码是从网上找的,然后修改了一下。 一个节点可能有点偏,不计算重复,开始时平均一分钟2个,计算重复一份钟一个。 前段时间又想到以前看群里讨论的关于p2p的应用,想自己实现一下,正好现在对协议了解了。不准备用 python写了,再看一个新语言折腾一下。

Continue

从昨天到今天,是决定写东西用的语言,准备用一个函数式语言。前几天连想没想用cl找库开搞,不过这个过程是困难的,找到没几个相关库,还感觉很不如意,文档只有简单的介绍,我这刚学会语法的水平简直用不了,对库调用什么的,我直接找了sbcl的io-net包,但是还是放弃了,准备先用cl写点小程序再说。 其实golang写这个东西是个不错的选择,但是对打括号闭合感觉太不有爱,也对golang相对熟悉不想再研究了。今天中午编译了两个 小时的rust,看了一下很不错,要用的东西基本有,现成的没有,如果不考虑花费时间会很长,就会边学边用了。然后相继看了ocaml,haskell,scheme这几个听的多的,比较了一下官网,库,和文档,最后选择了haskell。scheme 语法比较合我意,但是目测和cl应该一样的悲剧。总的来说,从官网内容丰富程度,我选择了scheme。scheme官网上还有很多本scheme的书,很好。

Continue