Tuesday, May 14, 2013

Perl undefined array / hash


要把  array 和 hash 清掉一樣有兩種作法

@array = ();
%hash = ();

undef @array;
undef %hash;
簡單的名詞解釋:

An array is initialized or not ->
    call scalar() to check the number of elements or call defined()
    if scalar() return false (the number of elements) is 0, then the array is uninitialized.


但是以下是錯誤示範

This would fill the array with one element at index zero with a value of undefined. 
equal to $array[0] = undef;

my @array = undef;     # WRONG!!!!

Round floating points in Perl

四捨五入是很常見的問題

 Perl 中有兩種簡單的方法可以達到:

一種是加上 0.5 後取 int() (positive numbers)

另一種是 sprintf %.0f 控制

不過浮點數本身便有其限制,預設的浮點數在高精度需求的運算是無意義的

底下的範例可以看到,當要求很高的精度時,會有誤差需小心



use 5.016;
say int(9.9+0.5);                            # 10
say int(9.50000000+0.5);                     # 10
say int(9.49999999+0.5);                     # 9
say int(9.49999999999999+0.5);               # 9
say int(9.49999999999999999999+0.5);         # 9?
 
say "-"x20;
 
say sprintf("%0.f", 9.9);                    # 10
say sprintf("%0.f", 9.50000000);             # 10
say sprintf("%0.f", 9.49999999);             # 9
say sprintf("%0.f", 9.499999999999999);      # 9
say sprintf("%0.f", 9.49999999999999999999); # 9?

=output
10
10
9
9
10
--------------------
10
10
9
9
10
=cut

Wednesday, May 1, 2013

Python format string

更多請參考: PEP-3101



基本的  format string 使用方法:

# basic
In [1]: "Hello, {}".format("xatier")
Out[1]: 'Hello, xatier'


# {0} means the first argument in format()
In [2]: "Hello, {0}".format("xatier")
Out[2]: 'Hello, xatier'


# {1} means the second argument
In [3]: "{1} {0}".format("xatier", 3)
Out[3]: '3 xatier'


# pass arguments one by one
In [4]: "{} {}".format("xatier", 3)
Out[4]: 'xatier 3'


# use doubled { to represent '{'
In [5]: "{} {{".format("xatier")
Out[5]: 'xatier {'


# get item: use [] to get fields in a dictionary
In [10]: my_dog = {'name': "Jack", 'age': 3}

In [11]: "My dog's name: {0[name]}, {0[age]} years old.".format(my_dog)
Out[11]: "My dog's name: Jack, 3 years old."


# do the same thing in an anonymous dictionary
In [15]: "My name is {0[name]}".format({'name': 'Fred'})
Out[15]: 'My name is Fred'

In [16]: "My name is {0[name]}".format(dict(name='Fred'))
Out[16]: 'My name is Fred'


# get attribute: use '.' to get attributes in a class/object
In [18]: import sys

In [19]: "{0.stdin}".format(sys)
Out[19]: "<open file '<stdin>', mode 'r' at 0x7f88ecd94150>"

In [20]: "{0.stdin.write}".format(sys)
Out[20]: '<built-in method write of file object at 0x7f88ecd94150>'


# get object's data
In [30]: class Foo:
   ....:     def __init__(self, name="yoo"):
   ....:         self.name = name
   ....:

In [31]: a = Foo()

In [32]: "{0.name}".format(a)
Out[32]: 'yoo'

In [33]: a = Foo("my name ^.<")

In [34]: "{0.name}".format(a)
Out[34]: 'my name ^.<'

Only two operators are supported: the '.' (getattr) operator, and the '[]' (getitem) operator.
The reason for allowing these operators is that they don't normally have side effects in non-pathological code.



排版:


The general form of a standard format specifier is:
        [[fill]align][sign][#][0][minimumwidth][.precision][type]

    The brackets ([]) indicate an optional element.



# fill with space
In [42]: "My name is {0:8}".format('Fred')
Out[42]: 'My name is Fred    '


# string force to left/right
In [44]: "My name is {0:<8}".format('Fred')
Out[44]: 'My name is Fred    '

In [45]: "My name is {0:>8}".format('Fred')
Out[45]: 'My name is     Fred'


# floating point
In [72]: "{0:f}".format(123.45)
Out[72]: '123.450000'

In [73]: "{0:.3f}".format(123.45)
Out[73]: '123.450'

In [75]: "{0:>10.3f}".format(123.45)
Out[75]: '   123.450'


# show the + sign
In [76]: "{0:>+10.3f}".format(123.45)
Out[76]: '  +123.450'

In [77]: "{0:<+10.3f}".format(123.45)
Out[77]: '+123.450  '


# = means fill with
In [78]: "{0:<=10.3f}".format(123.45)
Out[78]: '<<<123.450'

In [79]: "{0:A=10.3f}".format(123.45)
Out[79]: 'AAA123.450'

In [80]: "{0:0=10.3f}".format(123.45)
Out[80]: '000123.450'