tag:blogger.com,1999:blog-57667262674481294122024-02-06T18:17:35.512-08:00HVNSweetingvim ~/thought.txtHhttp://www.blogger.com/profile/18301396724192709702noreply@blogger.comBlogger557125tag:blogger.com,1999:blog-5766726267448129412.post-43975106439632487202014-06-22T12:32:00.001-07:002014-06-22T12:32:40.419-07:00Less is more<p>Do I need quora on my phone? No! It is distracted, affect my sleep time.<br>
Do I need FB on my phone? No, waste of time<br>
...<br>
Less is <u>more</u></p>
Hhttp://www.blogger.com/profile/18301396724192709702noreply@blogger.com1tag:blogger.com,1999:blog-5766726267448129412.post-68286683105658907352014-02-13T23:47:00.002-08:002014-02-13T23:47:57.918-08:00Configuring RsyslogTurn on debug mode with<br />
<br />
<blockquote class="tr_bq">
rsyslogd -d -n</blockquote>
<br />
To match a msg exactly, use <br />
<br />
:msg, isequal, " YOURMSG"<br />
<br />
NOTICE the space before your MSGHhttp://www.blogger.com/profile/18301396724192709702noreply@blogger.com0tag:blogger.com,1999:blog-5766726267448129412.post-52289158740484588122014-01-26T01:10:00.000-08:002014-01-26T01:10:15.106-08:00New words for playing "Robot odyssey" (DroidQuest)<span class="exampleGroup exGrBreak">http://www.droidquest.com/ </span><br />
<br />
<span class="exampleGroup exGrBreak">crescent <n> hình lưỡi liềm </span><br />
<br />
<span class="exampleGroup exGrBreak">Thrust <v> đẩy. </span><br />
<span class="exampleGroup exGrBreak">Thruster <em class="example"><n> động cơ đẩy </em></span><br />
<br />
<span class="exampleGroup exGrBreak"><em class="example">updating...</em></span><br />
<span class="exampleGroup exGrBreak"><em class="example"><br /></em></span>Hhttp://www.blogger.com/profile/18301396724192709702noreply@blogger.com1tag:blogger.com,1999:blog-5766726267448129412.post-38921350308357549242013-11-21T07:07:00.002-08:002013-11-21T07:44:20.387-08:00[Python2] Everything you want to know about argparse standard libTo see all kwargs that you can pass to ArgumentParser.add_argument(), run python/ipython and type:<br />
<br />
<blockquote class="tr_bq">
>>> import argparse<br />
>>> help(argparse.Action)</blockquote>
<br />
Regarding to action kwarg, below is all action that you can pass:<br />
<blockquote class="tr_bq">
# register actions<br />
self.register('action', None, _StoreAction)<br />
self.register('action', '<span style="color: red;"><b>store</b></span>', _StoreAction)<br />
self.register('action', '<span style="color: red;"><b>store_const</b></span>', _StoreConstAction)<br />
self.register('action', '<span style="color: red;"><b>store_true</b></span>', _StoreTrueAction)<br />
self.register('action', '<span style="color: red;"><b>store_false</b></span>', _StoreFalseAction)<br />
self.register('action', '<span style="color: red;"><b>append</b></span>', _AppendAction)<br />
self.register('action', '<span style="color: red;"><b>append_const'</b></span>, _AppendConstAction)<br />
self.register('action', '<span style="color: red;"><b>count</b></span>', _CountAction)<br />
self.register('action', '<span style="color: red;"><b>help</b></span>', _HelpAction)<br />
self.register('action', '<span style="color: red;"><b>version</b></span>', _VersionAction)<br />
self.register('action', '<span style="color: red;"><b>parsers</b></span>', _SubParsersAction)</blockquote>
Example:<br />
<pre><span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s">"-v"</span><span class="p">,</span> <span class="s">"--verbose"</span><span class="p">,</span> <span class="n">action</span><span class="o">=</span><span class="s">"store_true"</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="s">"increase output verbosity"</span><span class="p">)</span></pre>
<pre><span class="p"> <a name='more'></a></span></pre>
<pre><span class="p">More example </span></pre>
<pre><span class="p">http://docs.python.org/2.7/howto/argparse.html </span></pre>
Hhttp://www.blogger.com/profile/18301396724192709702noreply@blogger.com2tag:blogger.com,1999:blog-5766726267448129412.post-41231496713444565812013-11-17T23:16:00.001-08:002013-11-17T23:16:39.205-08:00[Debug] Postfix, Dovecot, OpenLDAPVài khái niệm/ câu lệnh quan trọng khi debug stack : postfix - dovecot - openldap, với dovecot là imap server đồng thời thực hiện SASL authenticate sử dụng backend LDAP.<br />
<br />
1. Tắt hết TLS / SSL option đi.<br />
2. Kiểm tra xem LDAP có hoạt động bình thường không<br />
NOTE: nếu dùng TLS, LDAP vẫn listen ở port 389<br />
Dùng SSL mới listen 636.<br />
<br />
$ ldapsearch -x -H ldap://127.0.0.1 -D 'uid=hvn@example.com,ou=people,dc=example,dc=com' -W -ZZ -b'dc=example,dc=com' # (bỏ -ZZ nếu chỉ dùng LDAP không SSL/TLS)<br />
<br />
3. Bật verbose cho slapd: đặt oldLog = 16383 <br />
<br />
Sau khi ldap đã hoạt động bình thường, kiểm tra dovecot.<br />
<br />
Dùng dovecot -a để xem cấu hình của dovecot hiện tại. <br />
<br />
<br />
4. Thử telnet với postfix:<br />
<a name='more'></a><br />
root@u1204: ~ () # telnet localhost 25 <br />Trying 127.0.0.1...<br />Connected to localhost.<br />Escape character is '^]'.<br />220 example.com ESMTP Postfix<br />ehlo example.com<br />250-example.com<br />250-PIPELINING<br />250-SIZE 10240000<br />250-VRFY<br />250-ETRN<br />250-AUTH PLAIN<br />250-AUTH=PLAIN<br />250-ENHANCEDSTATUSCODES<br />250-8BITMIME<br />250 DSN<br />auth plain<br />334 <br />AGh2bkBleGFtcGxlLmNvbQBodm5odm4= #output của $ echo -en "\000hvn@example.com\000hvnhvn" | base64<br />235 2.7.0 Authentication successful<br />MAIL FROM: <hvn@example.com><br />250 2.1.0 Ok<br />RCPT TO: <hvn@example.com><br />250 2.1.5 Ok<br />DATA<br />354 End data with <CR><LF>.<CR><LF><br />ihihihihihi<br />.<br />250 2.0.0 Ok: queued as A199E60D72<br />
<br />
5. Thử telnet với dovecot<br />
<br />
root@u1204: ~ () # telnet localhost 143<br />Trying 127.0.0.1...<br />Connected to localhost.<br />Escape character is '^]'.<br />* OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE AUTH=PLAIN] Dovecot ready.<br />a1 login hvn@example.com hvnhvn<br />a1 OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS MULTIAPPEND UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS] Logged in<br />b1 list "" "*"<br />* LIST (\HasNoChildren) "/" "INBOX"<br />b1 OK List completed.<br />c1 examine INBOX<br />* FLAGS (\Answered \Flagged \Deleted \Seen \Draft)<br />* OK [PERMANENTFLAGS ()] Read-only mailbox.<br />* 0 EXISTS<br />* 0 RECENT<br />* OK [UIDVALIDITY 1384754818] UIDs valid<br />* OK [UIDNEXT 1] Predicted next UID<br />* OK [HIGHESTMODSEQ 1] Highest<br />c1 OK [READ-ONLY] Select completed.<br />^]<br />telnet> <br />
<br />
<br />
# tcpdump -ni any 'tcp port 389'<br />Hhttp://www.blogger.com/profile/18301396724192709702noreply@blogger.com0tag:blogger.com,1999:blog-5766726267448129412.post-49888930001362664392013-08-20T03:26:00.003-07:002013-08-20T03:34:24.662-07:00Multi-nodes graphite clusterI done set up a graphite cluster on 2 nodes:<br />
- Each node have 1 webapp, 1 carbon-relay that relay to n carbon-cache.<br />
- Each node talk to each other ONLY through webapp. You have to config in local_config at cluster section.<br />
- Note that double check your graphite django url file. Do not require login to get metric, or you will get 302 error when webapp talk to each others.<br />
<br />
On each node:<br />
- Set up each carbon-cache listen on a separate port.<br />
- All webapp must use exactly same database and memcached (if you use memcached) <br />
- Then, in relay config, set DESTIONATIONS to a list of all local carbon-cache. Look like this:<br />
<br />
<a name='more'></a><br />
<br />
[relay]<br />
LINE_RECEIVER_INTERFACE = 0.0.0.0<br />
LINE_RECEIVER_PORT = 2003<br />
PICKLE_RECEIVER_INTERFACE = 0.0.0.0<br />
PICKLE_RECEIVER_PORT = 2004<br />
RELAY_METHOD = consistent-hashing<br />
REPLICATION_FACTOR = 1<br />
<br />
DESTINATIONS =127.0.0.1:2014:a, 127.0.0.1:2024:b, 127.0.0.1:2034:c, 127.0.0.1:2044:d<br />
<br />
- Webapp need to config talk to all of local carbon-cache as relay do:<br />
CARBONLINK_HOSTS = ["127.0.0.1:7012:a", "127.0.0.1:7022:b", "127.0.0.1:7032:c", "127.0.0.1:7042:d"]<br />
<br />
#list all server in cluster (each server had 1 webapp) <br />
CLUSTER_SERVERS = ['192.168.122.12', '192.168.122.93']<br />
# and add same value to ALLOWED_HOSTS<br />
ALLOWED_HOSTS = ['192.168.122.12', '192.168.122.93']Hhttp://www.blogger.com/profile/18301396724192709702noreply@blogger.com0tag:blogger.com,1999:blog-5766726267448129412.post-80014365563142574472013-07-17T06:27:00.001-07:002013-07-17T06:27:11.743-07:00Install salt-minion on Raspberry Pi (Raspbian)root@raspberrypi:~# apt-get install msgpack-python python-crypto python-jinja2 python-yaml python-zmq<br /><br />Then download and install two this deb files with dpkg<br />
<br />
http://debian.saltstack.com/debian/pool/main/s/salt/salt-common_0.15.1-1_all.deb<br />
http://debian.saltstack.com/debian/pool/main/s/salt/salt-minion_0.15.1-1_all.deb<br />
<br />
<br />
dpkg -i common_0.15.1-1_all.deb minion_0.15.1-1_all.deb<br />
<br />
<a name='more'></a><br />
That's all<br />
<br />
<blockquote class="tr_bq">
root@raspberrypi:~# salt-call --version<br />salt-call 0.15.1<br /> seem it worked </blockquote>
<br />
<br />
Install saltstack on raspbian<br />
Install salt on raspbian<br />
Install salt on raspberry pi Hhttp://www.blogger.com/profile/18301396724192709702noreply@blogger.com1tag:blogger.com,1999:blog-5766726267448129412.post-9688802635339527372013-06-23T11:28:00.000-07:002013-06-23T11:28:14.190-07:00[TIL] Chạy command từ python scriptvà liên thiên về ruby, bash...<br />
<br />
Trong python 2.7, có đến vài cách để chạy 1 câu lệnh linux. Điều này thực sự trái với triết lý của Python:<br />
<blockquote class="tr_bq">
There should be one-- and preferably only one --obvious way to do it.</blockquote>
Các cách để chạy 1 command:<br />
<ul>
<li>dùng lệnh os.system</li>
<li>dùng module subprocess</li>
<li>dùng module commands</li>
<li>dùng Popen</li>
</ul>
ai cũng hiểu rằng python có khả năng xử lý tốt hơn bash, nhưng hãy nhìn ví dụ đơn giản dưới đây khi cần lấy output của một câu lệnh:<br />
<br />
bash:<br />
<blockquote class="tr_bq">
<span style="color: #3d85c6;"><b>ls_output=`ls -la | grep hvn`</b></span></blockquote>
hoặc <br />
<blockquote class="tr_bq">
<span style="color: #3d85c6;"><b>ls_output=$(ls -la | grep hvn)</b></span><br />
<a name='more'></a></blockquote>
<b>python2:</b><br />
<b><br /></b><blockquote>
<span style="color: #3d85c6;"><b>from commands import etstatusoutput </b><br /><b>status, ls_output = getstatusoutput('ls -la | grep hvn')</b></span></blockquote>
<br />
hoặc:<br />
<br />
<blockquote class="tr_bq">
<br />
<span style="color: #3d85c6;"><b>from subprocess import check_output<br />ls_output = check_output('ls -la | grep hvn', shell=True)</b></span></blockquote>
<br />
Dễ thấy việc gọi các câu lênh từ python rất dài dòng so với bash.<br />
<br />
Trong khi với ruby thì mọi chuyện lại đơn giản hơn nhiều (thực hiện trên ruby 2.0) :<br />
<blockquote class="tr_bq">
<span style="color: #3d85c6;"> <b>ls_output = `ls -la | grep hvn`</b></span></blockquote>
<br />
Ruby cho phép bạn thực hiện việc này giống hệt với bash.<br />
Đồng thời ruby cho khả năng xử lý string tương đương với python.<br />
<br />
Python hơn Ruby về tốc độ, về số lượng và chất lượng thư viện, nhưng trong trận đấu khi mà bạn cần một ngôn ngữ có khả năng xử lý mạnh hơn bash nhưng cú pháp gọi câu lệnh đơn giản như bash thì ruby là người chiến thắng.<br />
<br />
Nếu đó CHÍNH XÁC là điều bạn cần, hãy chọn ruby :DHhttp://www.blogger.com/profile/18301396724192709702noreply@blogger.com0tag:blogger.com,1999:blog-5766726267448129412.post-62735366553080707932013-06-17T10:24:00.000-07:002013-06-17T10:24:02.644-07:00[TIL] Luôn setup logging cho python scriptKhi bắt tay vào viết 1 python script / program nào, cần setup logging ngay từ đầu. Quá trình code sẽ không cần sử dụng print nữa, vì có thể add handler stdout / stderr cho logger, nhờ vậy logger tương đương với các lệnh print. Khi xong, chỉ cần bỏ cái handler hoặc set debug level khác là được, không mất công xóa print.<br />
<br />
(Một khi đã dùng python nghĩa là công việc khá phức tạp, dùng vài dòng bash không thể làm / khó làm)Hhttp://www.blogger.com/profile/18301396724192709702noreply@blogger.com0tag:blogger.com,1999:blog-5766726267448129412.post-57036193765863305982013-06-02T06:49:00.001-07:002013-06-02T06:52:34.649-07:002013 TODO list - Emacs for python<br />
- Python debugger<br />
- Unittest<br />
- Dive in python 3<br />
- Which first (Haskell - (Scheme + SICP)) ?<br />
- Networking - TCP/IP illustrated vol 1<br />
- Archlinux && FreeBSD<br />
- Django || Flask ?Hhttp://www.blogger.com/profile/18301396724192709702noreply@blogger.com0tag:blogger.com,1999:blog-5766726267448129412.post-88029116412788987402013-05-31T09:06:00.000-07:002013-05-31T09:06:02.002-07:00[TIL] luôn sử dụng argparsePython 2.7<br />
<br />
Khi viết script python có pass các argument, cách đơn giản nhất là dùng sys.argv nhưng chỉ cần việc xử lý phức tạp hơn 1 chút, xuất hiện khoảng 3,4 argument, hay đang trong giai đoạn thiết kế thì cách tốt nhất là dùng thư viện argparse. Mất công học một tí nhưng với vài dòng là đã có 1 argparser xịn, dễ dùng.<br />
<br />
<br />Hhttp://www.blogger.com/profile/18301396724192709702noreply@blogger.com0tag:blogger.com,1999:blog-5766726267448129412.post-39081197001957568572013-05-29T19:17:00.001-07:002013-05-29T19:17:17.729-07:00Start reading Dive Python 3This famous book <a href="http://getpython3.com/diveintopython3/">http://getpython3.com/diveintopython3/</a><br />
<br />
Why?<br />
<ul>
<li>My Python knowledge is collected from anywhere but a book. Most of them from StackOverFlow. So I'm not sure what I've missed. Maybe I need a reference book but this book is good enough, and it was written in practical manner</li>
<li>Re-learn python means I'm sharping my skill/ knowledge</li>
<li>Learn python 3, which is the future of python</li>
</ul>
How:<br />
<ul>
<li>Daily read this book, from-cover-to-cover</li>
<li>Try to use python commandline debugger as much as possible</li>
<li>Try emacs </li>
<li>Conclude what I learned on this blog. But wrote them in Vietnamese</li>
</ul>
Today is 30-05-2013Hhttp://www.blogger.com/profile/18301396724192709702noreply@blogger.com0tag:blogger.com,1999:blog-5766726267448129412.post-69725590967745315122013-05-06T09:46:00.002-07:002013-05-06T09:46:57.635-07:00Remove package when lack of its config fileThis is very bad situation.<br />
Try below solutions:<br />
- Reinstall that package<br />
- Reinstall packages that your package depends on. (Eg: some xxx-common package)<br />
- Copy config from other machineHhttp://www.blogger.com/profile/18301396724192709702noreply@blogger.com0tag:blogger.com,1999:blog-5766726267448129412.post-5382706982180050652013-04-22T10:37:00.000-07:002013-05-28T21:00:52.082-07:00Things I Wish I'd Known Before Installed slapd on Ubuntu 12.04slapd is OpenLDAP server.<br />
<br />
This post is my experiences from install slapd on Ubuntu 12.04 <br />
<br />
<b>0. x86 and x64</b><br />
Please do use x86 instead of x64 machine for openldap. As I experiment with Ubuntu 12.04 x64 version, I got some annoying bugs relate to TLS. At least, I can sure that for package from Ubuntu repo, use x86 will save you from many headache.<br />
<br />
<b>1. Logging / Debug</b><br />
olcLogFile is not easy
to use (I don't know how to use it), if you want logging to a separate
file, change rsyslog config (/etc/rsyslog.d/50-....).<br />
Let local4.* outputs to a dedicated file.<br />
<br />
<b>Debug server:</b><br />
Change your config : olcLogLevel : none<br />
to 256, 16383 to get more verbose output<br />
or run :<br />
slapd --debug <br />
<br />
<b>Debug client:</b><br />
add -d 1 -d 2 ... or -d 5 after your command<br />
<br />
<br />
<b>2. GNUTLS vs openssl</b><br />
On Ubuntu 12.04, slapd / ldap-utils is compiled with GNUTLS. You should know this and use certificates/key created by gnutls-bin (certtool) when add SSL/TLS to it.<br />
<br />
Or if you use openssl cert/key, do compile your own a slapd / ldap-utils with openssl.<br />
<br />
Use mix slapd (built with gnutls) with openssl cert wil cause endless headache to you. DON'T DO THAT!<br />
<br />
<b>3. Certificate/ Key</b><br />
Certificate MUST be created which cn = your hostname FQDN.<br />
<br />
To check that, use:<br />
hostname --fqdn<br />
<br />
If you wan to change it to example.com, add example.com into /etc/hosts, before the result you've got.<br />
Hhttp://www.blogger.com/profile/18301396724192709702noreply@blogger.com0tag:blogger.com,1999:blog-5766726267448129412.post-22113209187836489052012-12-13T00:19:00.002-08:002012-12-13T00:19:55.603-08:00Ternary in python Example:<br />
xxx = ..... something <br />
msg = xxx if xxx else "hello world"<br />
<br />
or better:<br />
msg = xxx or "hello world"<br />
<br />Hhttp://www.blogger.com/profile/18301396724192709702noreply@blogger.com1tag:blogger.com,1999:blog-5766726267448129412.post-1404596437071776452012-12-08T22:56:00.000-08:002012-12-08T22:56:14.162-08:00Install Archlinux on KVM, and ssh to play with itToday, I've installed Archlinux on KVM virtual machine. I tried do it some times before but never done because the feeling something will be complicated with format HDD / config anything by hand. The truth is, it's nothing more than learn some simple command.<br />
<br />create a virtual machine and install archlinux on it:<br />
<br />
<span style="color: red;">root@lappy: ~ # virt-install --connect qemu:///system --name archfirst --ram 512 --disk path=~/archfirst.img,size=8 --cdrom=/home/hvn/Downloads/archlinux-2012.08.04-dual.iso </span><br />
<br />
<a name='more'></a><br />
ram 512MB, 8GB HDD => that's enough for playing<br />
<br />
follow install guide<br />
https://wiki.archlinux.org/index.php/Beginners%27_Guide<br />
<br />
after done, install openssh on it to ssh from host machine:<br />
<span style="color: red;">[root@hvnarch hvn]# pacman -S openssh</span><br />
<br />
<br />
<br />
<br />
you have to config sshd first:<br />
<span style="color: red;">[root@hvnarch hvn]# vi /etc/ssh/sshd_config </span><br />
uncomment some line, after changed, it looks like this:<br />
<span style="color: #6aa84f;"># The strategy used for options in the default sshd_config shipped with<br /># OpenSSH is to specify options with their default value where<br /># possible, but leave them commented. Uncommented options override the<br /># default value.<br /><br />Port 22<br />AddressFamily any<br />ListenAddress 0.0.0.0<br />ListenAddress ::<br /><br /># The default requires explicit activation of protocol 1<br />Protocol 2<br /></span><br />
<br />
then enable it use systemctl :<br />
<br />
<span style="color: red;">[root@hvnarch hvn]# systemctl enable sshd.socket<br />[root@hvnarch hvn]# systemctl enable sshd.service</span><br />
<br />
<br />
it will look like this:<br />
<br />
<br />
<span style="color: red;">[root@hvnarch hvn]# systemctl list-unit-files | grep ssh<br />sshd.service enabled <br />sshd@.service static <br />sshdgenkeys.service static <br />sshd.socket enabled </span><br />
<br />now, just ssh from your host machine into it.<br />
If you want your archlinux start with your host machine, run below command:<br />
<br />
<span style="color: red;">hvn@lappy: ~ $ sudo virsh autostart archfirst</span> Hhttp://www.blogger.com/profile/18301396724192709702noreply@blogger.com0tag:blogger.com,1999:blog-5766726267448129412.post-24656187016815800352012-11-16T09:24:00.003-08:002012-11-16T09:25:44.442-08:00Quick look into Python default modulesHave you ever seen code in Python default modules, let's take a look:<br />
<br />
First, find out where are they with "locate" command:<br />
<br />
<b>hvn@lappy: / $ locate subprocess</b><br />
/usr/lib/python2.7/subprocess.py<br />
/usr/lib/python2.7/subprocess.pyc<br />
<br />
we've locate subprocess module, which has a name specific enough. All python default module are in /usr/lib/python2.7/<br />
<br />
<a name='more'></a><br />
you will see many .py and .pyc file there, but we only need .py file to dive into source code. Run bellow command to find out how big they are:<br />
<br />
<b>hvn@lappy: /usr/lib/python2.7 $ for i in *.py; do wc -l $i; done | sort -n | cat -n | less</b><br />
<br />
got this, so impressive, there are close to 30 file with COL < 100:<br />
<br />
1 1 __phello__.foo.py<br />
2 3 struct.py<br />
3 4 antigravity.py<br />
4 7 sitecustomize.py<br />
5 13 sre.py<br />
6 14 md5.py<br />
7 15 sha.py<br />
8 17 new.py<br />
9 18 dbhash.py<br />
10 18 statvfs.py<br />
11 28 this.py<br />
12 36 tty.py<br />
13 41 dircache.py<br />
14 48 user.py<br />
15 49 sunaudio.py<br />
16 55 mutex.py<br />
17 65 atexit.py<br />
18 66 nturl2path.py<br />
19 78 dummy_threading.py<br />
20 78 glob.py<br />
21 84 types.py<br />
22 85 anydbm.py<br />
23 88 UserList.py<br />
24 90 commands.py<br />
25 92 bisect.py<br />
26 93 keyword.py<br />
27 96 stat.py<br />
28 97 macurl2path.py<br />
29 98 io.py<br />
30 100 functools.py<br />
<br />
dive in them, they are gem on your computer, no need to go anywhere!Hhttp://www.blogger.com/profile/18301396724192709702noreply@blogger.com0tag:blogger.com,1999:blog-5766726267448129412.post-74072925752108175652012-11-08T01:58:00.000-08:002012-11-08T02:08:44.055-08:00Nose – Fix nosetests finding 0 tests<h1 class="entry-title">
nosetests<br />Ran 0 tests in 0.000s</h1>
<h1 class="entry-title">
</h1>
<span style="font-size: x-large;"><b><span style="color: red;">Just recheck, your test file must have "test" in </span>filename</b></span>Hhttp://www.blogger.com/profile/18301396724192709702noreply@blogger.com0tag:blogger.com,1999:blog-5766726267448129412.post-22546192272325045482012-10-14T00:46:00.000-07:002012-10-14T00:46:03.113-07:00Language, language, language... I want to be a polyglotI've tried many time to get Function Programming but I can't. Just learn some syntax then forgot all because it's very hard to get them if you don't really use them.<br />
<br />
Of cause, everyone will argue, Haskell or a dialect of LISP?<br />
Some answer can be found here: http://programmers.stackexchange.com/questions/18838/haskell-and-lisp-vs-haskell-or-lisp<br />
<br />
Haskell like, Smalltalk. They are so pure, and you should learn them for learning many thing.<br />
<br />
<div class="post-text">
"Haskell and Lisp are two totally different beasts.<br />
Haskell is kindof "pure functional programming in an ivory tower"<br />
Lisp is kindof "code-is-data / data-is-code / make your own language
constructs". You can manipulate your code in whatever way you can
imagine.<br />
They are very different. Both share the "functional programming"
aspect, but that's really a tiny little common point compared to their
differences. Just try them out and you will see how different they are!"<br />
<br />
so go for haskell first, then lisp.<br />
Happy coding!<br />
<br />
One thing I hate about Haskell is its compile (ghc) is too heavy weight! <br />
</div>
Hhttp://www.blogger.com/profile/18301396724192709702noreply@blogger.com2tag:blogger.com,1999:blog-5766726267448129412.post-70984584102402443602012-10-13T08:24:00.001-07:002012-10-13T08:24:19.443-07:00[BASH] Count frequency of each letter in an English document use only coreutils of Linux<br />
<br />
first, convert all upper to lower by <b>tr</b> command, then <b>grep</b> with<b> -o</b> option, <b>sort</b>, <b>uniq</b>, then <b>sort</b> again!<br />
<br />
<span style="color: red;"><b>hvn@lappy:~/Downloads$ tr '[:upper:]' '[:lower:]' < prideandprejudice.txt | grep -o [a-z] | sort -nr | uniq -c | sort -nr<br /> 71194 e<br /> 48159 t<br /> 42695 a<br /> 41379 o<br /> 38944 i<br /> 38721 n<br /> 34582 h<br /> 33870 s<br /> 33468 r<br /> 22843 d<br /> 22071 l<br /> 15510 u<br /> 15124 m<br /> 14060 c<br /> 13033 y<br /> 12573 w<br /> 12381 f<br /> 10444 g<br /> 9363 b<br /> 8683 p<br /> 5840 v<br /> 3342 k<br /> 970 j<br /> 938 z<br /> 867 x<br /> 638 q</b></span>Hhttp://www.blogger.com/profile/18301396724192709702noreply@blogger.com0tag:blogger.com,1999:blog-5766726267448129412.post-42992142964869283042012-09-18T10:09:00.001-07:002012-09-22T21:44:05.902-07:00SSH into a VM from host machineI'm using Virtualbox 4.1.2 on Ubuntu 12.04 LTS<br />
After installed an Ubuntu server 12.04 into a VM machine, I want to ssh to it.<br />
<br />
<b>1. Config network</b><br />
The fastest way to do this is enable a new adapter, attach it to Bridged Adapter. You have to turn off your VM. Then choose setting<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHparbkBnerVrzJkFH0i13fJTn0x01zhi6aEsTUPvp0JaYJmi8sOohRoepvLI3dchRKBPbI_9x2PFAxmn8j3nV1GOADi7-VL4Pw8aYzSWI3GAPDk32P78q5EwV8iU1NSP2iMXI3kaXKd8/s1600/rsz_2012-09-18-234311_1366x768_scrot.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="292" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHparbkBnerVrzJkFH0i13fJTn0x01zhi6aEsTUPvp0JaYJmi8sOohRoepvLI3dchRKBPbI_9x2PFAxmn8j3nV1GOADi7-VL4Pw8aYzSWI3GAPDk32P78q5EwV8iU1NSP2iMXI3kaXKd8/s400/rsz_2012-09-18-234311_1366x768_scrot.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Add caption</td></tr>
</tbody></table>
<br />
<br />
Start your VM. Now you need to config ip address for new interface:<br />
<br />
<a name='more'></a><br />
<br />
<blockquote class="tr_bq">
hvn@server:~$ ip ad<br />
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN <br />
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00<br />
inet 127.0.0.1/8 scope host lo<br />
inet6 ::1/128 scope host <br />
valid_lft forever preferred_lft forever<br />
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000<br />
link/ether 08:00:27:e8:da:87 brd ff:ff:ff:ff:ff:ff<br />
inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0<br />
inet6 fe80::a00:27ff:fee8:da87/64 scope link <br />
valid_lft forever preferred_lft forever<br />
<b>3: eth1...</b><br />
<br /></blockquote>
Now open /etc/network/interfaces to config it:<br />
<br />
<blockquote class="tr_bq">
hvn@server:~$ cat /etc/network/interfaces <br />
# This file describes the network interfaces available on your system<br />
# and how to activate them. For more information, see interfaces(5).<br />
<br />
# The loopback network interface<br />
auto lo<br />
iface lo inet loopback<br />
<br />
auto eth0<br />
iface eth0 inet dhcp<br />
#Add bellow lines<br />
<b>auto eth1<br />iface eth1 inet dhcp</b></blockquote>
<br />
Restart networking:<br />
<blockquote class="tr_bq">
hvn@server:~$ sudo /etc/init.d/networking restart</blockquote>
<b></b>When this done, you will see ip of your new interface eth1:<br />
<br />
<blockquote class="tr_bq">
hvn@server:~$ ip ad<br />
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN <br />
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00<br />
inet 127.0.0.1/8 scope host lo<br />
inet6 ::1/128 scope host <br />
valid_lft forever preferred_lft forever<br />
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000<br />
link/ether 08:00:27:e8:da:87 brd ff:ff:ff:ff:ff:ff<br />
inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0<br />
inet6 fe80::a00:27ff:fee8:da87/64 scope link <br />
valid_lft forever preferred_lft forever<br />
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000<br />
link/ether 08:00:27:f7:65:dd brd ff:ff:ff:ff:ff:ff<br />
<b>inet 192.168.0.107/24</b> brd 192.168.0.255 scope global eth1<br />
inet6 fe80::a00:27ff:fef7:6 5dd/64 scope link <br />
valid_lft forever preferred_lft forever</blockquote>
<br />
You can set static ip for eth1.I will add it later here...<br />
<br />
<b>2. Set up and config SSH</b><br />
First, you have to install SSH server on VirtualMachine.<br />
<blockquote class="tr_bq">
sudo apt-get install openssh-server </blockquote>
and install SSH client on your machine:<br />
<blockquote class="tr_bq">
sudo apt-get install openssh-client</blockquote>
Create a key<br />
<blockquote class="tr_bq">
ssh-keygen -t rsa <br />
<br />
<pre>Generating public/private rsa key pair.
<span class="anchor" id="line-2-1"></span>Enter file in which to save the key (/home/b/.ssh/id_rsa):
<span class="anchor" id="line-3-1"></span>Enter passphrase (empty for no passphrase):
<span class="anchor" id="line-4"></span>Enter same passphrase again:
<span class="anchor" id="line-5"></span>Your identification has been saved in /home/b/.ssh/id_rsa.
<span class="anchor" id="line-6"></span>Your public key has been saved in /home/b/.ssh/id_rsa.pub.</pre>
<pre> </pre>
</blockquote>
<pre><span style="font-family: inherit;">You should not enter file to save the key, just let it empty, the program will set default to </span></pre>
<pre><span style="font-family: inherit;">~/.ssh/id_rsa</span></pre>
<pre><span style="font-family: inherit;"> </span></pre>
<pre><span style="font-family: inherit;">Then copy it to Virtual Machine:</span></pre>
<blockquote class="tr_bq">
<pre><span style="font-family: inherit;"><span class="anchor" id="line-1-4"></span>ssh-copy-id <username>@<host> </span></pre>
</blockquote>
<pre><span style="font-family: inherit;">
</span></pre>
<pre>Now have to add the key that you've created:</pre>
<blockquote class="tr_bq">
<pre>ssh-add ~/.ssh/id_rsa</pre>
<pre><enter your passphrase></pre>
</blockquote>
<pre>
</pre>
<pre>Done, connect to your Virtual Machine</pre>
<blockquote class="tr_bq">
<pre>ssh <username>@<host></pre>
</blockquote>
<br />
See more here:<br />
<a href="https://help.ubuntu.com/community/SSH/OpenSSH/Keys">https://help.ubuntu.com/community/SSH/OpenSSH/Keys</a><br />
Hhttp://www.blogger.com/profile/18301396724192709702noreply@blogger.com0tag:blogger.com,1999:blog-5766726267448129412.post-81983088932842677392012-09-16T01:13:00.000-07:002012-09-16T08:48:08.347-07:00[Python] with - context manager<b>1. Context manager</b> <br />
Context manager : là một đối tượng chịu trách nhiệm đóng resource khi resource ấy không cần dùng nữa.<br />
<br />
Khi sử dụng context manager, người dùng (developer) sẽ chỉ cần khai báo và sử dụng resource, không cần lo phải đóng nó lại.<br />
<br />
file là một ví dụ, bình thường khi dùng file, ta sẽ phải mở - dùng - đóng. Từ phiên bản python2.5 trở đi, file đã được implement để trở thành 1 context manager. Khi dùng nó với câu lệnh with, ta không cần đóng nó nữa:<br />
<br />
<blockquote>
>>> with open("/etc/hosts") as f:<br />
... f.read()<br />
... <br />
'127.0.0.1\tlappy\n::1\t\tlappy ip6-localhost ip6-loopback\nfe00::0\t\tip6-localnet\nff00::0\t\tip6-mcastprefix\nff02::1\t\tip6-allnodes\nff02::2\t\tip6-allrouters\n\n'<br />
>>> f.read()<br />
Traceback (most recent call last):<br />
File "<stdin>", line 1, in <module><br />
ValueError: I/O operation on <span style="color: red;"><b>closed file</b></span><br />
>>> <br />
<a name='more'></a></blockquote>
Một cách hàn lâm hơn, dưới đây là định nghĩa về context manager:<br />
<blockquote class="tr_bq">
A context manager is an object that defines the runtime context to be
established when executing a with statement. The context manager handles
the entry into, and the exit from, the desired runtime context for the
execution of the block of code. Context managers are normally invoked
using the with statement (described in section The with statement), but
can also be used by directly invoking their methods.<br />
Typical uses of context managers include saving and restoring various
kinds of global state, locking and unlocking resources, closing opened
files, etc. </blockquote>
<br />
Để một đối tượng trở thành 1 context manager, nó cần implement giao thức "context management" hay nói cách khác. Chỉ cần thêm vào đối tượng đó 2
method:<br />
__enter__() : định nghĩa một runtime context<br />
__exit__(): thoát khỏi runtime context <br />
khi đó đối tượng ấy trở thành 1 context manager và có khả năng định nghĩa 1 "runtime context".<br />
Ví dụ:<br />
từ python2.5 trở đi, mỗi file là một context manager:<br />
<blockquote class="tr_bq">
>>> afile = open("/etc/hosts")<br />
>>> type(afile)<br />
<b><type 'file'></b><br />
>>> dir(afile)<br />
['__class__', '__delattr__', '__doc__', '<span style="color: red;"><b>__enter__</b></span>', '<span style="color: red;"><b>__exit__</b></span>', '__format__', '__getattribute__', '__hash__', '__init__', '__iter__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'close', 'closed', 'encoding', 'errors', 'fileno', 'flush', 'isatty', 'mode', 'name', 'newlines', 'next', 'read', 'readinto', 'readline', 'readlines', 'seek', 'softspace', 'tell', 'truncate', 'write', 'writelines', 'xreadlines']</blockquote>
<br />
Đối với class file,<br />
__enter__ trả về chính đối tượng gọi nó (return self)<br />
__exit__ thực hiện đóng file (self.close())<br />
<br />
<br />
<br />
<b>2. with</b><br />
Dạng của câu lệnh with<br />
<blockquote class="tr_bq">
<pre><b id="grammar-token-with_stmt">with_stmt</b> ::= "with" with_item ("," with_item)* ":" <a class="reference internal" href="http://docs.python.org/reference/compound_stmts.html#grammar-token-suite"><tt class="xref docutils literal"><span class="pre">suite</span></tt></a>
<b id="grammar-token-with_item">with_item</b> ::= <a class="reference internal" href="http://docs.python.org/reference/expressions.html#grammar-token-expression"><tt class="xref docutils literal"><span class="pre">expression</span></tt></a> ["as" <a class="reference internal" href="http://docs.python.org/reference/simple_stmts.html#grammar-token-target"><tt class="xref docutils literal"><span class="pre">target</span></tt></a>]</pre>
</blockquote>
<pre> </pre>
<pre>Trong lập trình, bạn sẽ thường xuyên phải dùng đến đoạn code có dạng dưới :</pre>
<pre> set things up
try:
do something
finally:
tear things down</pre>
<pre> </pre>
Từ khóa with được đưa ra để viết nó dưới dạng ngắn gọn hơn bằng việc sử dụng context manager. Đối tượng ngay sau with (with_item) phải là một context manager.<br />
<br />
Qúa trình chạy một câu lệnh with:<br />
The execution of the <a class="reference internal" href="http://docs.python.org/reference/compound_stmts.html#with"><tt class="xref std std-keyword docutils literal"><span class="pre">with</span></tt></a> statement with one “item” proceeds as follows:<br />
<ol class="arabic">
<li><div class="first">
The context expression (the expression given in the <a class="reference internal" href="http://docs.python.org/reference/compound_stmts.html#grammar-token-with_item"><tt class="xref std std-token docutils literal"><span class="pre">with_item</span></tt></a>) is
evaluated to obtain a context manager.</div>
</li>
<li><div class="first">
The context manager’s <a class="reference internal" href="http://docs.python.org/reference/datamodel.html#object.__exit__" title="object.__exit__"><tt class="xref py py-meth docutils literal"><span class="pre">__exit__()</span></tt></a> is loaded for later use.</div>
</li>
<li><div class="first">
The context manager’s <a class="reference internal" href="http://docs.python.org/reference/datamodel.html#object.__enter__" title="object.__enter__"><tt class="xref py py-meth docutils literal"><span class="pre">__enter__()</span></tt></a> method is invoked.</div>
</li>
<li><div class="first">
If a target was included in the <a class="reference internal" href="http://docs.python.org/reference/compound_stmts.html#with"><tt class="xref std std-keyword docutils literal"><span class="pre">with</span></tt></a> statement, the return value
from <a class="reference internal" href="http://docs.python.org/reference/datamodel.html#object.__enter__" title="object.__enter__"><tt class="xref py py-meth docutils literal"><span class="pre">__enter__()</span></tt></a> is assigned to it.</div>
<div class="admonition note">
<div class="first admonition-title">
Note</div>
<div class="last">
The <a class="reference internal" href="http://docs.python.org/reference/compound_stmts.html#with"><tt class="xref std std-keyword docutils literal"><span class="pre">with</span></tt></a> statement guarantees that if the <a class="reference internal" href="http://docs.python.org/reference/datamodel.html#object.__enter__" title="object.__enter__"><tt class="xref py py-meth docutils literal"><span class="pre">__enter__()</span></tt></a> method
returns without an error, then <a class="reference internal" href="http://docs.python.org/reference/datamodel.html#object.__exit__" title="object.__exit__"><tt class="xref py py-meth docutils literal"><span class="pre">__exit__()</span></tt></a> will always be called. Thus, if
an error occurs during the assignment to the target list, it will be treated the
same as an error occurring within the suite would be. See step 6 below.</div>
</div>
</li>
<li><div class="first">
The suite is executed.</div>
</li>
<li><div class="first">
The context manager’s <a class="reference internal" href="http://docs.python.org/reference/datamodel.html#object.__exit__" title="object.__exit__"><tt class="xref py py-meth docutils literal"><span class="pre">__exit__()</span></tt></a> method is invoked. If an exception
caused the suite to be exited, its type, value, and traceback are passed as
arguments to <a class="reference internal" href="http://docs.python.org/reference/datamodel.html#object.__exit__" title="object.__exit__"><tt class="xref py py-meth docutils literal"><span class="pre">__exit__()</span></tt></a>. Otherwise, three <a class="reference internal" href="http://docs.python.org/library/constants.html#None" title="None"><tt class="xref py py-const xref docutils literal"><span class="pre">None</span></tt></a> arguments are
supplied.</div>
If the suite was exited due to an exception, and the return value from the
<a class="reference internal" href="http://docs.python.org/reference/datamodel.html#object.__exit__" title="object.__exit__"><tt class="xref py py-meth docutils literal"><span class="pre">__exit__()</span></tt></a> method was false, the exception is reraised. If the return
value was true, the exception is suppressed, and execution continues with the
statement following the <a class="reference internal" href="http://docs.python.org/reference/compound_stmts.html#with"><tt class="xref std std-keyword docutils literal"><span class="pre">with</span></tt></a> statement.<br />
If the suite was exited for any reason other than an exception, the return value
from <a class="reference internal" href="http://docs.python.org/reference/datamodel.html#object.__exit__" title="object.__exit__"><tt class="xref py py-meth docutils literal"><span class="pre">__exit__()</span></tt></a> is ignored, and execution proceeds at the normal location
for the kind of exit that was taken.<br />
</li>
</ol>
Lệnh open(path_of_file) trả về 1 context manager nên được gọi là context expression.<br />
<br />
Từ phiên bản 2.7, python cho phép sử dụng nhiều context manager lồng nhau với câu lệnh with thay vì sử dụng contextlib.nested() :<br />
<br />
<blockquote class="tr_bq">
<pre>with A() as a, B() as b:
suite</pre>
</blockquote>
<br />
<b>3. contextlib</b><br />
contextlib hỗ trợ tạo các contextmanager để dùng với câu lệnh with<br />
thư viện này chứa 1 decorator là contextmanager() cho phép bạn viết một hàm generator thay vì định nghĩa 1 class mới.Generator này chỉ được yield đúng 1 lần:<br />
<blockquote class="tr_bq">
<pre>from contextlib import contextmanager
@contextmanager
def tag(name):
print "<%s>" % name
yield
print "</%s>" % name
>>> with tag("h1"):
... print "foo"
...
<h1>
foo
</h1></pre>
</blockquote>
<br />
đoạn code trước <b>yield</b> sẽ chạy như method __enter()__ và giá trị trả về sẽ được gán cho biến theo sau từ khóa "as" của lệnh "with".<br />
Code sau yeild sẽ chạy như __exit__(). Các exception sẽ được raise bởi lệnh <b>yield</b><br />
<br />
~~~~<br />
PS:<br />
CHÚ Ý: context manager vẫn tồn tại ngoài khối lệnh with <br />
<br />
<blockquote class="tr_bq">
>>> f = 12<br />
>>> print f<br />
12<br />
>>> with open("/etc/hosts") as f:<br />
... print f<br />
... <br />
<open file '/etc/hosts', mode 'r' at 0x7f54e54cb390><br />
>>> print f<br />
<closed file '/etc/hosts', mode 'r' at 0x7f54e54cb390></blockquote>
<br />
http://docs.python.org/reference/compound_stmts.html<br />
http://docs.python.org/library/contextlib.html<br />
http://requires-thinking.blogspot.com/2009/02/this-is-python-context-managers-and.htmlHhttp://www.blogger.com/profile/18301396724192709702noreply@blogger.com0tag:blogger.com,1999:blog-5766726267448129412.post-44219484147050798202012-09-10T08:05:00.001-07:002012-09-10T08:05:25.461-07:00Maher Zain - So Soon Chút âm nhạc đến từ châu Á!<br />
<br />
<br><br />
<iframe width="480" height="270" src="http://www.youtube.com/embed/sXN7PjP08To?fs=1" frameborder="0" allowFullScreen=""></iframe>Hhttp://www.blogger.com/profile/18301396724192709702noreply@blogger.com0tag:blogger.com,1999:blog-5766726267448129412.post-47446503660038090952012-08-15T10:51:00.000-07:002012-08-15T10:54:13.623-07:00Python assigment, shallow copy, and deep copyI 've copy many text from below links, but deleted them all. Never copy, never copy, never copy ^6^<br />
<br />
Below links are MUST read, if you really use python<br />
<br />
Must read, because you will write python code, not C/Java...<br />
<a href="http://www.python.net/%7Egoodger/projects/pycon/2007/idiomatic/handout.html" rel="nofollow">Code Like a Pythonista</a><br />
Must read, to get to know about mutable and immutable object. Things seem not important to beginner but will cause many problems if you don't really understand it.<br />
<a href="http://docs.python.org/reference/datamodel.html%20">http://docs.python.org/reference/datamodel.html </a><br />
Must read, because you must understand how does assigment, shallow and deep copy work.<br />
<a href="http://docs.python.org/library/copy.html">http://docs.python.org/library/copy.html</a><br />
<br />
If you dont, prepace to face many bug because lack of knowledge :)<br />
<br />
<blockquote class="tr_bq">
"numbers, strings
and tuples are immutable, while dictionaries and lists are mutable."</blockquote>
<br />
<a name='more'></a><br />
Every object has an identity (currently is implemented as its memory address), a type, and a value. To get id of each object, we use id(object). Let experience with list:<br />
<br />
<blockquote class="tr_bq">
>>> li = [1, 2, 3]<br />
>>> la = li<br />
>>> id(li)<br />
3073615404L<br />
>>> id(la)<br />
3073615404L<br />
>>> li is la<br />
True</blockquote>
<blockquote>
>>> la<br />
[1, 2, 3]</blockquote>
as you can see, assignment "la = li" just bind the name "la" to object that "li" binded to.<br />
<br />
Now, let check int :<br />
<blockquote class="tr_bq">
>>> a = 5<br />
>>> b = a<br />
>>> id(a)<br />
155356512<br />
>>> id(b)<br />
155356512<br />
>>> a = 7<br />
>>> id(a)<br />
155356488<br />
>>> a<br />
7<br />
>>> b<br />
5<br />
>>> id(5)<br />
155356512<br />
>>> id(6)<br />
155356500<br />
>>> id(7)<br />
155356488</blockquote>
<br />
after assigned "b = a", the name "b" is binded to object which name "a" is binded to. That object has id = 155356512, that is id of immutable object 5 (= id(5)).<br />
Back to list again, now we will see how slice work (it will do a shallow copy)<br />
<br />
<blockquote class="tr_bq">
>>> li = [1, 2, 3]<br />
>>> id(li)<br />
<b style="color: #3d85c6;">3073693068L</b><br />
>>> la = li[:]<br />
>>> id(la)<br />
<b style="color: red;">3073693292L</b><br />
>>> li[0] = 0<br />
>>> la<br />
[1, 2, 3]<br />
>>> li<br />
[0, 2, 3]</blockquote>
"li" and "la" has different id, so when you change "li", "la" will not change. Objects that "li" and "la" contain are numbers(type int) and they are immutable objects. When you assign "li[0] = 0", you are binding the first element of list "li" to immutable object 0, you NOT change value of 1 to 0 (and you can't because it is immutable).Hhttp://www.blogger.com/profile/18301396724192709702noreply@blogger.com0tag:blogger.com,1999:blog-5766726267448129412.post-78606702138827093812012-08-07T20:17:00.002-07:002012-08-07T20:17:49.933-07:00Why crontab does not work?I've try to set my python script run daily use crontab.<br />
If your dont know what is cron, learn it now:<br />
<a href="http://www.thegeekstuff.com/2009/06/15-practical-crontab-examples/">http://www.thegeekstuff.com/2009/06/15-practical-crontab-examples/</a> <br />
<br />
If your crontab is working well now, skip this post. Otherwise, try to figure out why it does not work.<br />
<br />
<b>0. Find out whether cron daemon running or not</b><br />
<br />
<blockquote class="tr_bq">
hvn@squeeze:~/Apps/birth-reminder$ pgrep cron<br />1530</blockquote>
<br />
<a name='more'></a><br />If you got a number, it is running. If not, start it up<br />
<blockquote class="tr_bq">
<pre><code>sudo service cron start</code></pre>
</blockquote>
<br />
<b>1. Make sure your time is set right</b><br />
If your clock is wrong, then crontab will not run task on time<br />
You should check your hardware time instead of system time.<br />
Hardware time:<br />
<blockquote class="tr_bq">
<b>sudo hwclock</b></blockquote>
<br />
System time:<br />
<blockquote class="tr_bq">
<b>date</b></blockquote>
<br />
<br />
<b>2. Test your script.</b><br />
Eg, if you want to use a python script, it may work perfectly when you run it with<br />
<blockquote class="tr_bq">
<b>python script_name.py</b></blockquote>
<br />
or<br />
<blockquote class="tr_bq">
<b>chmod a+x script_name.py</b><br />
<b>./script_name.py</b></blockquote>
<br />
maybe it not run with full absolute path. Try run it with full path. Eg:<br />
<blockquote class="tr_bq">
<b>/home/hvn/bin/script_name.py</b></blockquote>
If it not work, fix it with this solution:<br />
<br />
<a href="http://stackoverflow.com/questions/11354912/why-does-directly-run-script-not-work-but-python-script-name-py-does">http://stackoverflow.com/questions/11354912/why-does-directly-run-script-not-work-but-python-script-name-py-does</a><br />
<br />
<b>3. Check some popular reasons make cronjob not run task</b><br />
From this list:<br />
<a href="http://askubuntu.com/questions/23009/reasons-why-crontab-does-not-work">http://askubuntu.com/questions/23009/reasons-why-crontab-does-not-work</a><br />
<br />
<b>4. Read log, mail and see what happened.</b><br />
Change your cronjob to run every minute to "debug" it<br />
<br />
In Ubuntu(12.04)/Debian(6.0), read log file:<br />
hvn@squeeze:~$ sudo tail -f /var/log/syslog<br />[sudo] password for hvn: <br />Aug 8 09:42:26 squeeze crontab[2039]: (hvn) BEGIN EDIT (hvn)<br />Aug 8 09:42:37 squeeze crontab[2039]: (hvn) REPLACE (hvn)<br />Aug 8 09:42:37 squeeze crontab[2039]: (hvn) END EDIT (hvn)<br />Aug 8 09:43:01 squeeze /usr/sbin/cron[1530]: (hvn) RELOAD (crontabs/hvn)<br /><b>Aug 8 09:43:01 squeeze /USR/SBIN/CRON[2073]: (hvn) CMD (~/Apps/birth-reminder/reminder.py)</b><br />Aug 8 09:45:02 squeeze crontab[2223]: (hvn) BEGIN EDIT (hvn)<br />Aug 8 09:45:13 squeeze crontab[2223]: (hvn) REPLACE (hvn)<br />Aug 8 09:45:13 squeeze crontab[2223]: (hvn) END EDIT (hvn)<br />Aug 8 09:45:17 squeeze crontab[2227]: (hvn) LIST (hvn)<br />Aug 8 09:46:01 squeeze /usr/sbin/cron[1530]: (hvn) RELOAD (crontabs/hvn)<br />Aug 8 09:46:34 squeeze anacron[1456]: Job `cron.daily' started<br />Aug 8 09:46:34 squeeze anacron[2256]: Updated timestamp for job `cron.daily' to 2012-08-08<br />
<br />
when your cronjob run, you will see a log with<br />
CMD (PATH_TO_YOUR_SCRIPT)<br />
<br />
<b>Read mail:</b><br />
Each time cronjob run, it will send an email to your mailbox host on your computer. You may find it in /var/mail/your_name<br />
See what happened in mail content<br />
<br />
hvn@squeeze:~$ tail -n 15 /var/mail/hvn<br />
Date: Wed, 08 Aug 2012 09:43:20 +0700<br />Message-Id: <E1SywEy-0000Xr-T6@squeeze><br />From: root@squeeze (Cron Daemon)<br />To: hvn@squeeze<br />Subject: Cron <hvn@squeeze> ~/Apps/birth-reminder/reminder.py<br />Content-Type: text/plain; charset=UTF-8<br />X-Cron-Env: <SHELL=/bin/sh><br />X-Cron-Env: <HOME=/home/hvn><br />X-Cron-Env: <PATH=/usr/bin:/bin><br />X-Cron-Env: <LOGNAME=hvn><br /><br />Sent to ['bot.c2k8pro@gmail.com']<br />Today is 08/08<br />Tomorrow is Trịnh Thị Thu Hiền's birthday<br />18 mails: <br />
....<br />
<br />
You may got a log from log said that you have no email agent. So install one MTA (Eg: postfix, exim4...)<br />
<br />
<br />
<span style="color: white;">crontab, why does crontab not run, crontab not run, crontab doesnt run, why doesn't crontab work</span>Hhttp://www.blogger.com/profile/18301396724192709702noreply@blogger.com0