共 36 页, « 第一页 ... « 2 3 4 [5] 6 7 8 » ... 最后一页 »
Excel 2003中只能从调色版中选择颜色,但调色版中只有56种颜色,这就意味着一个工作簿中最多只能同时有56种颜色。 通过“工具->选项->颜色”可以设置调色版。
选中单元格后,从格式工具栏的背景色/字体颜色按钮中只能选取40种常用颜色,而在单元格属性对话框(用Ctrl-1打开)中, 则可以为单元格设置所有56种颜色。
阅读全文 »之前发过一篇在Windows下安装Trac的方法,不过Trac更多的是在Linux下使用, 所以这里介绍一下在Linux下的安装方法。时过境迁,Trac现在已正式发布了0.11版, 与之前的0.9、0.10相比,这个版本的代码浏览器增加了许多功能, 最好用的就是它支持subversion的Blame了,可以查看到源代码的每一行是在哪个版本由谁修改的。
这篇文章是在Fedora Core 8上进行的,其他的RedHat系的Linux应该大同小异。
阅读全文 »经过两个多月的努力,这本名为《Web开发修炼之道——创建高可用性的Web内容》 (豆瓣链接, 出版社预告, 勘误表)的书终于要与大家见面了。 这恐怕是国内第一本讨论可用性(Accessibility)的中文书籍——在豆瓣上搜索“可用性”, 找到的都是usability、availability等,没发现 accessibility。 可能这也是中国的网站在可用性方面做得很差的原因之一吧。

原书名为《Design Accessible Web Sites》(豆瓣链接),
书很不错,刚刚开始翻译时fcicq还在豆瓣上推荐了一把。
不过我现在还没拿到书的ISBN,所以暂时没法将中文版放到豆瓣上,抱歉。拿到时再补上吧。
简单介绍一下书的内容吧。可用性(Accessibility)就是说让网站能在任何平台、任何浏览器上运行, 并且残障人士也能毫无障碍地使用网站。这就要求开发网站时必须做到:
- 符合标准(以便跨浏览器跨平台)
- 为图片、视频等加上文字描述(供不支持图片的浏览器使用,同时考虑盲人所用的屏幕阅读器)
- 使用易于阅读的字体和颜色(考虑弱视、色盲)
- 使用简洁易懂的语言(考虑理解能力弱的用户)
- 足够大的导航和链接(让运动不方便的用户容易点击)
- 避免使用闪烁效果(防止诱发癫痫症)
不幸的是,国内的网站在这些方面做得极其差劲(原谅我用极其这个词), 特别是本该为残障人士周全地考虑的政府网站,在这方面简直是一片空白。 希望这本书能为国内的网站设计提供参考。
下面是本书的内容简介,请点开阅读。
阅读全文 »今天发现,制作的某个rpm包在执行 rpm -i --nodeps <packagename.rpm>时会出现以下的警告信息:
warning: cannot get shared lock on /var/lib/rpm/Packages
但如果不加--nodeps参数,就不会出现这个信息。
网上查了半天没找到相关资料,最后用排除法发现,SPEC文件的%post中有一行 rpm -qa,就是这行命令导致了该警告的发生。 原因尚且不明,估计是在安装过程中,rpm正在执行,此时在%post中再次启动rpm,当然会发生共享锁的错误。
不知为何最近右下角的托盘图标都显示不出来了,只剩下杀毒软件、虚拟光驱和MSN,其他的都看不到。 也不是折叠的问题。插上USB设备后,安全删除USB设备的图标也不出来,只能去设备管理器里面去删除,很麻烦。
上网查了查,虽然没能解决托盘图标消失的问题,但找到了如何安全删除USB的命令:
rundll32 shell32.dll, Control_RunDLL hotplug.dll
运行上述命令即可打开“安全删除硬件”的对话框。做成快捷方式就比较方便了。
Ver 2: 2008/11/7
Ver 1: 2008/11/3
基本概念
- Python居然支持复数。如(-5+4j)。但要注意虚数单位单独使用时要写成 1j,不能写成 j。
- 与Perl和PHP的区别:单引号和双引号没有任何区别。没有插值功能。
- 三引号:''' 和 """ 相当于Perl的heredoc。
- 行尾不需要用分号,分号仅用于一行写多条语句的情况。跟BASIC的冒号有些相似。
- 缩进是有语义的!建议使用TAB缩进
- 逻辑运算符只有 and or not,没有 && || !
- 没有自增自减运算符,--a 相当于 -(-a),a--语法错
- 赋值语句不是表达式,如 y = (x = 1) 语法错
- 字符串切片是很好用的: 'Hello'[0] == 'H',以前只有Basic才有这个功能,其他语言都没有。当然Python比Basic要强大得多
- cmp函数相当于Perl的 <=> 和 cmp,由于python有类型,所以无需像perl那样用两个运算符
- []、()、{} 的布尔值是False,跟JavaScript不同(JavaScript中空数组和空对象都是true)。与Perl类似,但Perl可以用环境来解释。
运算符与表达式
- 运算符 ** 乘幂,Perl也有。
- 字符串的 * 表示重复,相当于Perl的 x 运算符。
- 居然还有专用于整除的 // 。别跟Perl 6的 // 混淆了。
控制流
- if-elif-else,Perl为if-elsif-else,bash为if-elif-fi
- if、elif等控制流语句后面要加冒号,很像PHP的语法
- while和for循环可以带else,循环正常结束时就会执行else。不用像C语言那样,循环结束时要检查循环变量是否等于终值,以判断是否正常结束。赞
- range函数生成的结果不包括终点。比较:Perl的 .. 运算符包括终点。所以,Python的range(a,b)理解成C语言的 for(i=a;i<b,i++) 好些。
- 什么都不做的pass语句,算是个python特色
- enumerate能同时迭代key和value,很不错。for key, value in enumerate(LIST):
函数
- 函数中使用全局变量需要用global关键字,类似于PHP
- DocString,又一个python特色,函数的第一个逻辑航的字符串作为文档字符串。类似于POD和javadoc,不过是写在函数体内的。还能通过"函数名.__doc__"访问
- lambda:类似于perl的闭包
- int()函数在字符串转整数时,不能用来转浮点数字符串,也不能转包含字母的字符串。如int("1.2")、int("123abc")都是语法错误,而并不返回 1、123。
数据结构
- 列表:定义方式为 a=[1,2]。等价于perl的数组/列表
- 元组(tuple):定义方式为 a=(1,2)。
- 要注意列表中的列表不会被打散,如 a=[1,2], b=[a,3,4],结果就是 b=[[1,2],3,4]。这一点与Perl不同。
- 字典:定义方式为 c={'a':1, 'b':2}。等价于perl的散列。注意两点:
- 定义和访问时,key必须用引号引起来。
- 使用{}定义,使用[]访问,即c['a']。与Perl不同。
- 列表赋值是引用赋值。要想拷贝,必须用切片:b = a[:]。Perl程序员要注意。
- 列表的sort会改变原列表。
例外
- try-except-finally,相当于java的try-catch-finally
- 还有else,当没有发生异常、正常结束try块时执行。跟for/while的else块一样
- 故意抛出异常叫raise,java里面叫throw
面向对象
- 数字和字符串(对象)是不可变的。那么如何理解a=a+1?实际上是a+1创建了一个新对象赋给a,而a原来的对象被回收了。学习Python必须改变原来的“变量是个盒子”的看法
- (-1, 100)之间的整数会被缓存,就是说即使写成 a=10; b=10; ,a和b还是同一个对象(a is b == True)
- python的长整型是无限大的
- 类的__init__函数类似于C++的构造函数;__del__函数类似于C++的析构函数。
- 类方法定义的第一个参数必须为self,调用时这个参数会被传递为对象本身。类似于perl,perl中第一个参数也会被传递为对象本身,不过需要程序员自己写 my $self = shift; 来接收。
- 用C++的话来说,所有成员函数都是虚函数。
- 调用基类方法时要手工传递self,如 Parnet.__init__(self, name)。
模块
- import foo; 相当于perl的 use foo;
- from foo import bar 相当于perl的 use foo qw/bar/;
代码写多了,程序就会变得臃肿;程序臃肿了,就会变慢。 这时提高代码执行效率就非常重要了。 但是,代码优化并不是几条best practice就能完成的。 那些无关痛痒的空间分配、减少复制等优化措施,虽然有效,但却微乎其微。 优化的关键,是要找出瓶颈并解决之,这样才能以最小的代价获得最佳的效果。
这就用到Perl的一个强大的工具:DProf。 它可以测定程序执行的每个函数所花费的时间, 通过它,你可以迅速找到瓶颈在什么地方,再对症下药。
最近我做的一次性能分析是这样的。 我们的系统在某种条件下发送邮件时特别慢, 甚至等待十几分钟也无法结束。究竟问题出在哪里却不得而知。 于是DProf上场了。
首先写了个脚本,专门调用发送邮件的功能,排除其他功能的影响。 然后运行命令:
$ perl -d:DProf ./sendmail.pl
运行结束之后,会在当前目录下生成一个tmon.out文件。 使用dprofpp即可查看统计信息:
$ dprofpp Total Elapsed Time = 19.70195 Seconds User+System Time = 18.52195 Seconds Exclusive Times %Time ExclSec CumulS #Calls sec/call Csec/c Name 83.5 15.46 15.770 11 1.4059 1.4337 Foo::Bar::crypt 9.34 1.730 1.730 2 0.8650 0.8650 Net::Cmd::datasend 1.24 0.230 0.305 17459 0.0000 0.0000 Crypt::Blowfish::encrypt 0.70 0.129 0.818 36 0.0036 0.0227 base::import 0.59 0.110 0.709 24 0.0046 0.0296 Foo::Bar::FooBarList::BEGIN 0.44 0.082 0.082 9108 0.0000 0.0000 IO::Wrap::read 0.40 0.075 0.075 17647 0.0000 0.0000 Crypt::Blowfish::crypt 0.27 0.050 0.887 7 0.0071 0.1268 main::BEGIN
统计信息的意思分别是:
- ExclSec: 函数自身的执行时间(不包括函数调用的其他函数)
- CumulS: 函数的执行时间(包括函数调用的其他函数)
- #Calls: 调用次数
- sec/call: ExceSec/#Calls
- Csec/c: CumulS/#Calls
- Name: 函数名称
从上面的统计信息中可以看出,Foo::Bar::crypt占用了最多的时间(83.5%)。 而且更为重要的信息是,CumulS - ExclSec = 15.770 - 15.46 = 0.31, 也就是说,绝大部分时间都耗在了 Foo::Bar::crypt 函数本身,而不是它调用的其他函数。 这样,只需针对Foo::Bar::crypt函数进行分析就可以了。
还可以使用另一个性能测试工具Devel::SmallProf。
| 类型 | 标量环境 | 列表环境 |
| 标量'hello' | 标量本身 | 标量本身 |
| 列表('a','b','c') | 最后一个标量'c' | 列表本身 |
| 数组 | 数组中的元素个数 | 数组元素的列表 |
| 散列 | 斜线分隔的已用空间和分配的总空间的值组成的字符串 | 键值对的列表 |
| 行输入操作符<FH> | 文件的一行 | 文件剩余所有行组成的列表 |
| 文件名glob <*.xml> | 一个文件名 | 所有文件名的列表 |
| 范围操作符 .. | 左操作数为真时,返回真,直到右操作数为真后,返回假 | 左操作数到右操作数之间的所有值 |
| each %hash | 散列的一个键 | 散列的一个键值对 |
| gmtime | ctime(3)风格的字符串 | struct tm结构的9个值 |
| localtime | ctime(3)风格的字符串 | struct tm结构的9个值 |
| grep EXPR LIST | grep表达式匹配的次数 | 匹配表达式的所有值 |
| keys %hash | 散列中键的数目 | 散列的所有键 |
| m// | 表示匹配是否成功的布尔值 | 捕获的$1、$2、$3...的列表 |
| m//g | 执行一次匹配并返回表示是否成功的布尔值 | 反复执行匹配,返回所有捕获组成的列表 |
| readdir | 一个文件名 | 剩余所有文件名的列表 |
| readline | 文件的一行 | 文件剩余所有行组成的列表 |
| reverse LIST | 连接LIST中的所有元素成字符串,然后将这个字符串的字符顺序反转 | LIST的反转列表 |
| split | 分割结果的子字符串的数量 | 分割的子字符串 |
| stat | 表示执行是否成功的布尔值 | 文件的统计信息(包含13个元素的列表) |
在处理多语言编码、使用UTF-8时,偶尔会遇到这个我称之为“c3c2问题”的问题。花了一天时间好不容易找到了原因所在,写在这里希望对遇到的人有所帮助。基于Perl语言写的,可能是Perl的专有问题,不过其他的语言若遇到类似的现象也可作为参考。
现象
进行编码转换时出现乱码。转换后的结果类似于下面的样子:
c3 a3 c2 81 c2 82 ...
看起来就像是正确的字符序列中加入了许多\xc3、\xc2的字符。
原因
对非utf-8字符序列进行 utf8::encode 或者 Encode::from_to($str, 'utf8', '...') 等,就会出现 c3 a3 c2 81... 一样的字符。 也就是说,把不是utf8编码的东西当作utf8编码来使用,就出现这个现象。
例如下面的例子。
#!/usr/bin/perl use Encode; $str1 = "あああ"; utf8::decode($str1); $str1 .= "あああ"; utf8::encode($str1); print $str1; print "----"; $str2 = "あああ"; Encode::from_to($str2, "UTF-8", "Shift_JIS"); utf8::encode($str2); print $str2;
执行结果如下:
$ perl mojibake.pl | xxd 0000000: e381 82e3 8182 e381 82c3 a3c2 81c2 82c3 ................ 0000010: a3c2 81c2 82c3 a3c2 81c2 822d 2d2d 2dc2 ...........----. 0000020: 82c2 a0c2 82c2 a0c2 82c2 a0 ...........
这里$str1是utf8字符流和字节流的混合体(实际上这是不对的),$str2是将shift-jis的字节流进行encode。其结果都会产生大量的\xc3和\xc2。
可能的原因:
- 将decode过的字符串和未decode的字符串连接在一起使用
- 对字符串连续进行两次 utf8 -> 其他编码的转换
这个题目似乎有些不太合适,因为这并不是我们常说的引用传递和值传递。但是我想提醒大家这一点,否则很容易犯错误。
问题:map语句的代码段中使用的 $_,是列表中的值本身,还是将列表中的值复制到 $_ 中?
例如,下面这段程序的运行结果是什么呢?
#!/usr/bin/perl
$,=',', $\="\n";
$a = [1,2,3];
print map { ++$_; } @$a; # (A)
print @$a; # (B)
C程序员们通常会认为map会将@$a中的每个值复制到 $_ 中,加一后返回(这里我特地用了 ++$_ 使得它返回加一之后的值), 因此(A)行输出 2,3,4 ,而(B)行输出 1,2,3 。实则不然。运行结果为
2,3,4 2,3,4
可见,并非@$a中的元素复制到$_中,而是$_本身就是@$a中的元素。而map的目的就是要改变操作数的值。 下面这个例子可以很清楚地看到这一点。
map { ++$_ } (1,2,3); # 运行时出错,++$_ 不能改变常量
类似地,grep的结果也是数组本身,返回值就是由操作数中的符合条件的元素本身组成的列表。如上例:
map { ++$_; } grep { $_ > 1 } @$a; # 运行后 $a 为 [1,3,4]
如果实在不想让map改变操作数的值,可以将操作数转成引用之后再强制转成数组:
map { ++$_; } @{[ @$a ]}; # 运行后 $a 为 [1,2,3]
当然,上面例子中 ++ 操作符很明显会改变操作数的值,因此意识到上面的问题并不困难。 不过如果是 s/// 运算符,可能就不那么明显了。
类似的情况还有函数调用时的 @_ ,它代表调用函数时的实际参数本身,而不是实际参数的拷贝。 对@_进行修改,会直接影响到实参(就像C语言里面的传指针一样)。
一般我们在定义函数时都这么写:
sub foo {
my $arg1 = shift;
}
参数多时可能会这么写:
sub foo {
my ($arg1, $arg2, $arg3) = @_;
}
这样写之后,@_的值就被赋给了$arg1、$arg2等变量,以后对$arg1、$arg2的修改不会影响到实际参数。 但如果想修改实际参数,就要这样做:
my $arg1 = \$_[0]; $$arg1 = 'Hello!'; # 调用函数时的第一个实参会变成 Hello!
