2013年2月25日 星期一

某防毒公司的python面試題目

最近有想去找別的工作
不過能力太差,只好自己投奴隸銀行
去的幾間公司都有基本的能力測驗
基本上都不難
考題都是針對資料的操作跟基本觀念
記得某防毒公司的題目是這樣出的
有一資料結構長得如下
people_birthday = {
    "alex": "1982.04.30",
    "andrew": "2008.8.19",
    "diego": "2010/02/20",
    "fanny": "1978/11/29",
    "peggy": "1985/4/10",
}
要求如下:
1. 依月份排序資料
2. 印出完整的英文月份名稱,如一月為January,二月為Febreary
3. 印出當月生日的人數
4. 印出當月生日的人名,字首需大寫,且按字母排序
5. 依格式印出資料,格式為" 月份 (人數) 人名, 人名
6. 將內容寫入一檔案

考試時手寫的程式
回來靠印象寫了一次
發現有不少小地方有錯
改過後的版本如下
PS. 有使用內建的函數,所以程式稍稍短了一些
import calendar
import datetime

stastics = dict(enumerate([[] for x in range(len(calendar.month_name[1:]))], start = 1))

for name, birthday in people_birthday.items():
    sep = "/" if "/" in birthday else "."
    year, month, day = birthday.split(sep)
    stastics[int(month)].append(name)

with open("interview.txt", "w") as fp:
    for month_index, people in stastics.items():
        result = "%10s (%d) %s\n" % (
            calendar.month_name[month_index],
            len(people),
            ", ".join([person.capitalize() for person in sorted(people)])
        )
        print result
        fp.write(result)

個人的錯誤大概有幾個
1. 建立stastics時,不該使用[[] * len(calendar.month_name[1:])],這樣會產生多個相同內容的陣列
2. 記錯寫檔的函數,應該為write,且結尾應該分行符號"\n"

2013年2月1日 星期五

OSX Terminal中使用Home/End/Page Up/Page Down

在OSX Terminal中是無法使用Home/End/Page Up/Page Down的功能
如果很常用到,例如需要用VIM編輯文件,就得靠下面的方式去解決
首先開啟Termianl的偏好設定(通常快捷鍵為Command+,)
切換到右方的"鍵盤"設定
左方的"按鍵"列表,是代表你的按鍵組合
右方的"動作"列表,是代表你按了這個按鍵組合後,要作的動作
依下方的對應,把動作換掉即可(\033這個是按esc的動作)
Home      \033[1~
End       \033[4~
Page Up   \033[5~
Page Down \033[6~

2013年1月28日 星期一

django openstack auth

最近在使用django_openstack_auth去透過keystone做認證
結果花了三四天還搞不定,直到今天才把所有問題都解決
原來有幾個地方要注意,下面做個簡單的記錄方便

首先,也是最白爛的一點,請先把機器做好網路對時
因為keystone的token是有過期時間的,結果當初找問題時一直沒想到
直到最後追程式碼才發現,原來伺服器跟客戶端的時間不一樣,所以一直發給逾期的token
所以請先將機器的時間做好對時,網路上都有相關的文章,在此就不重復了

設定settings.py
LOGIN_URL = "/auth/login/"
LOGOUT_URL = "/auth/logout/"
LOGIN_REDIRECT_URL = "/"

OPENSTACK_KEYSTONE_URL = "http://${server_ip}:5000/v2.0"
AUTHENTICATION_BACKENDS = ("openstack_auth.backend.KeystoneBackend", )

INSTALLED_APPS += ("openstack_auth", )

設定urls.py
from openstack_auth.utils import patch_middleware_get_user

patch_middleware_get_user()

urlpatterns += patterns("",
    url(r"^auth/login/$", "openstack_auth.views.login", name = "login"),
    url(r"^auth/logout/$", "openstack_auth.views.logout", name = "logout"),
)
記得patch_middleware_get_user一定要加,否則認證過也會無法取得使用者物件

設定template,openstack_auth預設login及logout的樣板會在
${template_dir}/auth/login.html and ${template_dir}/auth/logout.html
主要是如果你有客制化自己的form,請記得加上下面二個設定
    {{ form.tenant }}
    {{ form.region }}

另外,如果你有客制化自己的keystone伺服器,請一定要把service category打開,因為認證會需要這個設定值

做完以上設定,就可以正常透過keystone登入django了
不過由於keystone跟django的使用者及群組是沒有綁定在一起
所以能取得到的使用者資料相對較少
詳細的屬性及方法可以參照https://github.com/4P/python-django-openstack-auth的程式碼

2013年1月27日 星期日

chef入門

chef是一套configuration management system
前陣子工作上的需要,所以有小小的研究了一下
研究的不太深入,但基本的入門應該夠了等有時間(藉口)再來玩

新增安裝來源
Add APT repository:
echo "deb http://apt.opscode.com/ `lsb_release -cs`-0.10 main" | sudo tee /etc/apt/sources.list.d/opscode.list

Import GPG key:
Offical:
sudo mkdir -p /etc/apt/trusted.gpg.d
gpg --keyserver keys.gnupg.net --recv-keys 83EF826A
gpg --export packages@opscode.com | sudo tee /etc/apt/trusted.gpg.d/opscode-keyring.gpg > /dev/null
(Recommend)Non offical:
gpg --keyserver keys.gnupg.net --recv-keys 83EF826A
gpg --export --armor 83EF826A | sudo apt-key add -

Update repository index:
sudo apt-get -y update


Chef server的設定
Install chef(you may need to input some data):
sudo apt-get -y install chef-server
**After server is start, it will create /etc/chef/validation.pem and /etc/chef/webui.pem file.
The validation.pem is used for validate client.
The webui.pem is used for manage chef-server.


Chef cleint的設定
Install chef
sudo apt-get -y install chef
**For connect to chef-server, you need to copy the /etc/chef/validation.pem from chef server and put it to the same place.
After connect to chef-server, it will create a node and client naming by client hostname.
So please make sure you have unique hostname in clients.


Chef工具(Knife)
**Please copy the /etc/chef/validation.pem from chef server and put it to the same place

Config knife with create an administration account(Must be execute at chef server)
sudo knife configure -i
Please enter the chef server URL:
請輸入Chef server的位址,預設的連接埠為4000 EX: http://172.17.114.201:4000
Please enter a clientname for the new client:
請輸入Client的名稱,系統會依此名稱建立對應的金鑰
Please enter the existing admin clientname:
使用預設值
Please enter the location of the existing admin client's private key:
請確定檔案及路徑正確,有錯誤請修改
Please enter the validation clientname:
使用預設值
Please enter the location of the validation key:
請確定檔案及路徑正確,有錯誤請修改
Please enter the path to a chef repository (or leave blank):
請留空白即可
**It will create ~/.chef/${client_name}.pem.

Config knife without create an administration account
sudo knife configure
Please enter the chef server URL:
請輸入Chef server的位址,預設的連接埠為4000 EX: http://172.17.114.201:4000

Please enter an existing username or clientname for the API:
請輸入使用者名稱或是客戶端的名稱
Please enter the validation clientname:
使用預設值
Please enter the location of the validation key:
請確定檔案及路徑正確,有錯誤請修改
Please enter the path to a chef repository (or leave blank):
請留空白即可


List registered client:*(User to manage chef)
knife client list


List registered node:*(Machines to run recipe)
knife node list


Register node to server:
(Recommend)Method 1:
sudo service chef-client start
**Chef will use the hostname as node name and client name.
Please make sure you hostname is unique.
Method 2:
sudo chef-client --node-name ${node_name} --user root --group root [--daemonize]
**Specify the node name


Assign a node to run cookbook:
knife node run_list add {client_name} 'recipe[{cookbook_name}]’


Assign a node to run special recipe in cookbook:
knife node run_list add {client_name} 'recipe[{cookbook_name}::special]'


List uploaded cookbooks:
knife cookbook list


編寫Cookbook
Config cookbook information:
vim knife.rb

cookbook_copyright "Kuntelin"
cookbook_license "MIT"
cookbook_email "kuntelin@gmail.com"

Create cookbook:
knife cookbook create ${cookbook_name} -o ${cookbook_path}


Write a recipe:
vim ${cookbook_path}/${cookbook_name}/recipes/default.rb


Write a special recipe:
vim ${cookbook_path}/${cookbook_name}/recipes/special.rb

Upload cookbook:
knife cookbook upload ${cookbook_name} -o ${cookbook_path}