Pillow 是 PIL的对Python3支持的另外一个分支,当然他对Python2也兼容,由于PIL安装起来比较烦,而使用pip可以很轻松的安装Pillow,所以我选择Pillow使用,但是其核心还是PIL库的。


Python的图形处理库如PIL一直很强大,但是要想使用好它必须对图片有一定的知识储备。
使用起来很简单

from PIL import Image

引用Image包

im = Image.open('1.png')

打开图片,得到一个im对象,我们接下来就可以对这个对象进行操作(前提有这个1.png图片)

我们先看一下他的一些属性

>>> print im.format, im.size, im.mode
PNG (83, 81) RGB

第一个我们输出图片的格式,图片有很多种格式,常用的有jpg、png还有gif动图啊,PIL支持很多种格式,我们可以使用PIL轻松的将格式转换,im.save('1.jpg'),当然你可以选择格式假如你没选好后缀名的话,im.size就是图片大小,他返回的是一个元组第一个长度第二个是宽度,单位是像素。
现在就谈谈 这三个属性对应的关系吧
首先我们使用一张像素图来说吧

我们存贮图片的时候是将整个图像分成很多个相同的小方块,每个小方块我们称为像素,当然一张图片分的越小,像素越多,那么图片就越接近真实图片,上面的im.size属性就告诉我们,这张图片分成了,长为83px,宽为81px的图片,那么一共有83*81=6723个像素点,每个像素点里面存什么呢,这就是im.mode属性告诉我们的,贴一下属性有什么吧

  1. 1 (1-bit pixels, black and white, stored with one pixel per byte)
  2. L (8-bit pixels, black and white)
  3. P (8-bit pixels, mapped to any other mode using a color palette)
  4. RGB (3x8-bit pixels, true color)
  5. RGBA (4x8-bit pixels, true color with transparency mask)
  6. CMYK (4x8-bit pixels, color separation)
  7. YCbCr (3x8-bit pixels, color video format)
  8. I (32-bit signed integer pixels)
  9. F (32-bit floating point pixels)

像素存贮就是涉及到颜色的存贮,在早期的黑白游戏机,只有黑和白两种,那么每个像素点就只有1位颜色来存贮,1位只能存贮两种颜色,八位色就能存256种颜色,像八位我们能用256个油漆桶/256色调色板来形容,像上面我们使用的RGB是由三种三原色红绿蓝混合而成,我们知道大自然所有的颜色都可以用红绿蓝三种颜色调配出来,所以RGB又被称为真彩(true color),每种颜色我们都分成256种,所以我们一共有256256256=16777216种颜色可以调配,像素的其他模式我们不介绍太多,有兴趣的可以自己钻研。
那么我们知道每个像素占多少字节,又知道共有多少个像素,那我们是不是就可以直接计算出来图片大小,来验证一下

以第一张图片为例,共有8381=6723个像素点,用RGB模式,每个像素三个字节,共有67233=20667b=20kb,但是我这张图片只有11.6kb,误差太大了吧,这时候我们就要介绍一下上面那个im.format属性了,这张图片采用png格式,我们先尝试一下把他转成JPG格式吧

im.save('1.jpg')

我们再查看一下这个1.jpg的大小,只有2.24kb了,我们用PIL打开这张图片

>>> im2 = Image.open('1.jpg')
>>> print im2.format, im2.size, im2.mode 
JPEG (83, 81) RGB

图片大小没有改变,但是format变成了JPEG,而且文件大小变成原来的1/5,
JPEG和GIF和PNG是三种图片压缩技术,他们使用压缩算法把图片压缩成很小,当我们打开图片时,解密算法把他还原出来,所以我们算出来的大小与压缩后的大小是不一样的。
有了这些概念我们就能更好的使用PIL提供给我们的magic方法,下次在谈我对PIL的高级应用吧。

最近在学习大数据,书看了不少,但是总是觉得很迷茫,不知道怎么学下去,今天
突然想写点什么来
总结一下这些天.

起因

逛博客的时候看到一篇分享如何修炼成大数据高手感觉很有趣

买了两本书

大数据时代

失控

这两本书都是很多年前写的,但是最近这几年随着”大数据”被大家越炒越热,随即被大家所看重.

这两个作者很牛,在30年前大数据还只是萌芽的时候就提出未来大数据的重要性和价值.

大数据是什么了,现在为什么这么火,以前没有大数据吗?

大数据的产生就像是科技带来的附带品一样,原来我们把信息存贮在图书馆里面,因为人类的活动产生的信息越来越多,图书馆也越来越大,但是由于管理和存贮的成本越来越多,我们被迫要缩减浓缩我们的信息,我们想出了很多很方法来对付这种情况,比如抽样,只要抽取一部分的代表信息存在图书馆里面然后记录主要特征和平均分量,我们就可以把信息降低几个数量级.

但是现在不同.

芯片做的越来越小,容量做的越来越大,我们有能力存贮所以的信息,一些先驱发现我们用另一种思维去对待信息.

用全体数据而不是随机样本

用混杂性而不是精确性

用相关关系而不是因果性

>

由于要做一个三级菜单存贮菜单和文章,由于菜单在很多地方用的到,于是想做一个可扩展性的菜单以便以后使用。

由于以前从来没有做过动态的菜单,所以走了很多弯路,尤其搭配EF Code First更是坑了我一把,我想把我碰到坑给大家分享一下。

1.类库的实现

首先我选择树这个数据结构来存贮我的菜单,我定义菜单Menus来作为一个最小单元,定义一个bool类型IsFoot来定义是否为根菜单,每个Menus有一个父级菜单Menus,有一群子菜单,下面是我定义的Menu库。

  [Description("菜单")]
public class Menus
{
    [Key]
    [Display(Name="菜单ID")]
    public int MenusID { get; set; }
    [Required]
    [Display(Name="是否为根节点")]
    public bool IsFoot { get; set; }
    [Required]
    [StringLength(25)]
    [Display(Name="目录名字")]
    public string Name { get; set; }
    [Display(Name="是否删除")]
    public bool IsDelete { get; set; }
    [Display(Name="包含的文章")]
    public virtual List<Article> articles { get; set; }
    [Display(Name = "父级菜单")]
    public virtual Menus fatherMenus { get; set; }
    [Display(Name = "子菜单")]
    public virtual List<Menus> sonList { get; set; }


}

每个Menus都包含了一个文章集合,虽然有些菜单不一定有文章但是EF可以允许我们0对多,或1对多。

2. 生成数据库


EF比较人性化的是,当我们数据库里面没有我们想要生成的表时,我们不需要多余的代码,只要当成数据库有表,像平时一样添加数据然后EF会帮我们自动在数据库里面建好表,当然你如果有相同名字的表话它报错,会提醒你数据库里面有如果想保存数据要做好数据迁移工作,数据迁移不是我们的重点,如果想了解的话,点击这里

生成的数据库包含两个表,一个Menus表,一个是Article表(PS:上面没有给出Article的类型定义,想要的可以自己写),对于这个来说,我们并没有在表里面定义外键属性,只是用来一个引用属性,引用属性是一种“虚属性”,我们通过这个属性来建立起两个对象的虚拟联系,比如说父与子,这种关系是虚拟的对于两者之间的联系是通过血缘来联系的,这个血缘是存在的,相对应就是数据库里面的外键联系,外键也可以看做是表中的一个字段,它记录了一种关系。

由于EF的智能关系,当我们Code First时,他会帮我们自动建好外键如果我们不定义的话,当我们使用EF的时候是不需要考虑外键的值的初始化,如果我们没有给他赋值EF会自动给他赋值。


讲完了EF的建立,现在就谈谈使用Code First在项目中遇到的问题。


这个问题主要出在给创建子菜单上,当我们创建子菜单时,我们用的是我们自己的类库代码进行初始化数据库,我们先得到菜单的ID然后在EF里面查询这个菜单,我们查询到这个实体,然后在菜单实体里面添加子菜单,在SaveChange()时候就报错了,EF称检测到有循环赋值的可能,让我们添加外键以避免冲突,我不记得看到的那篇博客看到有人也遇到相同的问题,如果只是普通的一对多(假如是A对1,2,3,4···),当我们给A那个新建一个5时,这个外键的位置是知道的,我们只要在5的外键位置存贮A的主键,然而当我们建立这种父级菜单时,每个菜单里面的外键可以是存贮父级的主键,也可以是子集的主键,所以EF并不能解决冲突,解决这个问题的方法有两种一种是在表中添加外键
如:

       [ForeignKey("sonList")]
public int sonListMenusID{get;set;}

或者用Fluent API 在继承的方法 onModelCreate中添加

modelBuilder.Entity<Menus>().HasRequired(p=>p.sonList).WithMany(l=>l.Menus).HasForeignKey(p=>p.sonListMenusID)

通过这种创建方式当我们创建子集菜单时我们就可以成功利用EF特性帮我们自动添加上外键,以及建立好实体关系。

关于更详细的外键知识可以点击这里

由于有其他编程语言基础,所以对于python的学习并不吃力,但是整体感觉python的确与前面学习c、c———

1. 实时编译VS静态编译

不需要输入任何前缀,直接将代码放在python解释器上面就能运行,虽然window下不支持直接点开文件就能使用,但是只要安装了python解释器就能很轻松的运行。

分量轻是他的特点吧!相比打开vs等半天然后,编译连接最后执行。python是一门很轻巧的语言,没有满屏的分号,大括号,基本类型比如int、string、float不区分直接拿来用就可以了,任何一个变量都是一个对象,对象可以千变万化,感觉python是一门很野的熊孩子什么都不在乎,比如说你什么了相同的两个变量

这门强类型语言则不允许,在同级作用域内他只允许声明一次,python或许已经没有声明了,每个名字只是一个对象而已并没有他的归属。

2.动态语言VS静态语言

给我感受是一颗静止的树的话,那么python就是一匹‘野马’,C

学了鸟哥的书前面基础后,突然想在Linux下用gcc玩C语言,然后了解到了Vim这个神一样的编译器,接下来经过超长时间虐心的安装无数插件无数依赖包,突然有种打自己一顿的感觉,还好终于把Vim装的和VS差不多了,接下来我介绍我安装Vim的经验吧。

我虚拟机下的Linux原来是红旗6的,但是我改了一下yum的包源成CentOS的并且全部update一下后就神奇的变成了CentOS6,虽然他们两个是同一家公司,但是总给我一种由盗版成了正版的感觉。。

闲话不多说,刚开始装第一个插件是Ctags

刚开始装的时候我是在X-Windows里面的这里下载再转回shell敲

$ tar -xzvf ctags-5.6.tar.gz
$ cd ctags-5.6
$ make

make install

后来我发现不用这么复杂直接在X-Window下面复制到Terminal里面就可以了,毕竟后面安装的代码都是十几行,根本扛不住。。。。

装完三个感觉整个我太苦逼,简直是辛苦啊,不是说好的敲几下键盘就可以吗。
后来了解到linux有几个软件可以帮忙安装而且解决依赖性,比如ubuntu的apt-get,redhat的rmp,yum,但是问题来了,我的黄狗(yum:yellow dog)怎么没用啊,全都装不上,一查错误提示,原来我没用被授权,原来RedHat更新软件是要收钱的,但是CentOS不用,然后我就用了CentOS的源,当时我就想只想装个git,然后就没用然后了。终于全部更新完了,yum也可以用了,用yum果然爽多了,直接

yum install git    

git就装好了。如果想知道怎么改源,点击这里


好了装好了源接下来装软件就敲一敲代码就行,不用去网上找包下载再安装。

装好一些热门的插件后,我碰到了第一个最难装的插件YouCompleteMe(YCM),装完之后感觉就是神器一般的存在,但是装完之前一直在感慨,我去怎么没个卵用啊,而且装llvm(安装YCM必须先安装的软件)时,我用编译安装方法因为一些库的缺失一直报错,后面采用二进制安装方法安装完llvm才成功按上YCM。
推荐新手采用二进制安装方法安装llvm,想知道怎么安装YCM这些点击这里

安上一些实用的插件后,最后安装调试神器gdb,有三种方式使vim可以调试程序(与gdb一起工作),

vimgdb,pyclewn,clewn,三个我都试了,第一个要编译一下vim,我失败了,第二个要用python2.4+支持,我python2.6然并卵,每次都说不支持python2,第三个是用c写的,终于成功,安装非常简单,
点击这里了解详情.
装完了,我终于可以使用clewn打开gdb和gvim,然并卵,我写的程序并不能在gdb里面运行,一直说无法识别。。。。。。搜了一下原来是编译的时候的问题,用gcc编译的程序要带上-g参数才能在gdb里面用(我还以为我clewn没装好)
例如

gcc -g test.c -o test

加上-g参数就行了。终于我的vim可以用了。。。。。。