<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 30,  comments - 3,  trackbacks - 0
      2012年8月6日
    https://www.jianshu.com/p/ebf2e5b34aad
    posted @ 2018-11-18 16:56 Seraphi 閱讀(158) | 評論 (0)編輯 收藏
    今天換了Macbook pro來寫畢業論文,發現有一大堆中文相關的問題導致編譯錯誤。經過一晚上的研究,終于解決。主要有以下要點:

    1. 由于MacTex對CTex的支持并不如TexLive那么好,在用pkuthss 1.7.3模板寫論文的時候,首先需要對pkuthss.cls文件進行修改:
    需要將原來的\LoadClass[hyperref, cs4size, fntef, fancyhdr]{ctexbook}[2011/03/11]一行改為如下形式:
    \LoadClass[fontset = windowsold,cs4size,UTF8,fancyhdr,hyperref,fntef,openany]{ctexbook}[2011/03/11]

    2.在進行上述改動后,發現還是不行。提示simhei.ttf, simsong.ttc, simfang.ttf找不到。這個時候,需要將上述三種字體超鏈接到tex的目錄下。

    具體方法如下:
    (1)在tex對應的下列目錄建立Chinese文件夾:/usr/local/texlive/2016/texmf-dist/fonts/truetype/
    (2)將SimHei SimSong Fangsong三種字體超鏈接到上述目錄。這三種字體可以在/Library/Fonts/Microsoft中找到,注意的是放到tex下時,文件名需要小寫,黑體和仿宋后綴名為.ttf,宋體為.ttc
    (3)sudo texhash

    3.再編譯的時候發現已經可以了!Yeah~~~
    posted @ 2017-02-28 22:13 Seraphi 閱讀(529) | 評論 (0)編輯 收藏

    I have successfully run your code after doing the following two steps:

    1. Download GLPK from

      http://sourceforge.net/projects/winglpk/files/latest/download (as mentioned by oyvind)

    2. Unzip it into (for example) : C:\glpk_is_here\
    3. Add GLPK binaries to your system path before running python C:\>set PATH=%PATH%;C:\glpk_is_here\glpk-4.55\w64

    4. Using the same cmd window from (3), use python/ipython to run your code:
      C:\>ipython your_code.py

    5. See the results Out[4]: 2.0

    Good luck.

    posted @ 2016-05-27 14:25 Seraphi 閱讀(669) | 評論 (0)編輯 收藏

    Windows7&IIS7.5部署Discuz全攻略

    原貼:http://www.cnblogs.com/ajunForNet/archive/2012/09/12/2682063.html

    組長說在內網部署一個論壇,這可難不倒我,裝個Discuz嘛。
    部署環境就一臺普通的PC,四核i3,Windows7。這就開搞了。

    準備工作

    系統是Windows 7 專業版,自帶IIS7.5(家庭版不帶)。IIS7開始帶了FastCgi,對PHP支持好了許多,所以也不必裝Apache啦。
    下載 PHP 5.4、 MySQL 5.5 以及Discuz X2。

    對于IIS7 FastCgi,我們應當選擇VC9編譯的線程安全的版本。

    安裝PHP

    解壓PHP,我給的路徑是C:\PHP,大伙兒隨意
    把php.ini-production改名為php.ini(用于開發環境的話,就改那個development)

    修改擴展路徑

    extension_dir = "./ext"

    啟用MySQL擴展(即去掉分號)

    extension=php_MySQL.dll

    修改時區

    date.timezone=Asia/Shanghai

    完了可以嘗試在命令行中執行以下PHP:

    cd C:\PHP
    php -v

    可以看到php的版本信息,如果把dll文件不存在的擴展打開了的話,會有提示。

    配置IIS

    IIS容易對付,不過先得把確保這幾項已經裝上:

    1、添加模塊映射
    啟動IIS管理器,對服務器設置“處理程序映射”,”添加模塊映射“:
    (圖)
    注意,設置可執行文件路徑的時候,要選擇exe。

    2、添加index.php為默認文檔
    對服務器設置“默認文檔”,添加index.php


    3、創建新站點
    接著在創建一個新的站點,并創建一個目錄存放你的網站,C:\Forum
    主機名填你想要綁定的域名,對于一臺服務器上有多個網站的情況,域名幾乎是必須的。
    當然啦,內網的話,就改hosts隨便弄個上去吧。

    4、設置程序池
    去應用程序池,設置剛才創建的站點對應的程序池,把.Net framework版本設成無托管代碼。

    重啟IIS,在網站目錄下放一個index.php,內容很簡單:
    <?php phpinfo(); ?>

    訪問網站,設置無誤的話應該能看到PHP的系統信息。

    安裝MySQL

    安裝MySQL挺容易的,按照Discuz給出的教程就可以了。
    因為我下的是UTF8版本的Discuz,所以在選擇字符編碼那一步選的UTF8。

    至于改數據庫目錄以及移動那個dll,看上去完全沒那個必要,我也就沒弄。

    安裝Discuz

    最煩的都搞定了,最后把安裝包里upload里面的東西都復制到網站目錄下,
    訪問網站下的install目錄就能看到安裝界面
    剩下的不用說了吧···

    得記得安裝完了以后,進UCenter->全局->域名設置->應用域名,把論壇的域名給設好了,
    否則論壇首頁就是個500

    Over.

    posted @ 2013-03-11 11:09 Seraphi 閱讀(585) | 評論 (0)編輯 收藏
    nohup + 命令 + & 后臺運行程序(連接服務器時,運行程序)
    posted @ 2013-03-06 10:38 Seraphi 閱讀(254) | 評論 (0)編輯 收藏
         摘要: LaTeX( LATEX,音譯“拉泰赫”)是一種基于TeX的排版系統,由 美國 計算機學家 萊斯利·蘭伯特(Leslie Lamport)在20世紀80年代初期開發,利用這種格式,即使使用者沒有排版和程序設計的知識也可以充分發揮由TeX所提供的強大功能,能在幾天,甚至幾小時內生成很多具有書籍質量的印刷品。 你可以在...  閱讀全文
    posted @ 2013-02-16 13:51 Seraphi 閱讀(267) | 評論 (0)編輯 收藏

    Python正則

    初學Python,對Python的文字處理能力有很深的印象,除了str對象自帶的一些方法外,就是正則表達式這個強大的模塊了。但是對于初學者來說,要用好這個功能還是有點難度

    ,我花了好長時間才摸出了點門道。由于我記性不好,很容易就忘事,所以還是寫下來比較好一些,同時也可以加深印象,整理思路。

    由于我是初學,所以肯定會有些錯誤,還望高手不吝賜教,指出我的錯誤。

    1 Python正則式的基本用法

    Python的正則表達式的模塊是‘re’,它的基本語法規則就是指定一個字符序列,比如你要在一個字符串s=’123abc456’中查找字符串’abc’,只要這樣寫:

    >>> import re

    >>> s='123abc456eabc789'

    >>> re.findall(r’abc’,s)

    結果就是:

    ['abc', 'abc']

    這里用到的函數”findall(rule , target [,flag] )” 是個比較直觀的函數,就是在目標字符串中查找符合規則的字符串。第一個參數是規則,第二個參數是目標字符串,后面

    還可以跟一個規則選項(選項功能將在compile函數的說明中詳細說明)。返回結果結果是一個列表,中間存放的是符合規則的字符串。如果沒有符合規則的字符串被找到,就返

    回一個空列表。

     

    為什么要用r’ ..‘字符串(raw字符串)?由于正則式的規則也是由一個字符串定義的,而在正則式中大量使用轉義字符’/’,如果不用raw字符串,則在需要寫一個’/’的地

    方,你必須得寫成’//’,那么在要從目標字符串中匹配一個’/’的時候,你就得寫上4個’/’成為’////’!這當然很麻煩,也不直觀,所以一般都使用r’’來定義規則字符

    串。當然,某些情況下,可能不用raw字符串比較好。

     

    以上是個最簡單的例子。當然實際中這么簡單的用法幾乎沒有意義。為了實現復雜的規則查找,re規定了若干語法規則。它們分為這么幾類:

    功能字符:    ‘.’ ‘*’ ‘+’ ‘|’ ‘?’ ‘^’ ‘$’ ‘/’等,它們有特殊的功能含義。特別是’/’字符,它是轉義引導符號,跟在它后面的字符一般有特殊的含義。

    規則分界符: ‘[‘ ‘]’ ‘(’ ‘)’ ‘{‘ ‘}’等,也就是幾種括號了。

    預定義轉義字符集:“/d”  “/w” “/s” 等等,它們是以字符’/’開頭,后面接一個特定字符的形式,用來指示一個預定義好的含義。

    其它特殊功能字符:’#’ ‘!’ ‘:’ ‘-‘等,它們只在特定的情況下表示特殊的含義,比如(?# …)就表示一個注釋,里面的內容會被忽略。

     

    下面來一個一個的說明這些規則的含義,不過說明的順序并不是按照上面的順序來的,而是我認為由淺入深,由基本到復雜的順序來編排的。同時為了直觀,在說明的過程中盡量

    多舉些例子以方便理解。

    1.1基本規則

     

    ‘[‘  ‘]’字符集合設定符

    首先說明一下字符集合設定的方法。由一對方括號括起來的字符,表明一個字符集合,能夠匹配包含在其中的任意一個字符。比如[abc123],表明字符’a’ ‘b’ ‘c’ ‘1’ 

    ‘2’ ‘3’都符合它的要求。可以被匹配。

    在’[‘ ‘]’中還可以通過’-‘ 減號來指定一個字符集合的范圍,比如可以用[a-zA-Z]來指定所以英文字母的大小寫,因為英文字母是按照從小到大的順序來排的。你不可以

    把大小的順序顛倒了,比如寫成[z-a]就不對了。

    如果在’[‘ ‘]’里面的開頭寫一個‘^’ 號,則表示取非,即在括號里的字符都不匹配。如[^a-zA-Z]表明不匹配所有英文字母。但是如果‘^’不在開頭,則它就不再是表示

    取非,而表示其本身,如[a-z^A-Z]表明匹配所有的英文字母和字符’^’。

     

    ‘|’    或規則

    將兩個規則并列起來,以‘|’連接,表示只要滿足其中之一就可以匹配。比如

    [a-zA-Z]|[0-9]表示滿足數字或字母就可以匹配,這個規則等價于[a-zA-Z0-9]

    注意:關于’|’要注意兩點:

    第一,           它在’[‘ ‘]’之中不再表示或,而表示他本身的字符。如果要在’[‘ ‘]’外面表示一個’|’字符,必須用反斜杠引導,即’/|’ ; 

    第二,           它的有效范圍是它兩邊的整條規則,比如‘dog|cat’匹配的是‘dog’和’cat’,而不是’g’和’c’。如果想限定它的有效范圍,必需使用一個無捕獲組‘

    (?: )’包起來。比如要匹配‘I have a dog’或’I have a cat’,需要寫成r’I have a (?:dog|cat)’,而不能寫成r’I have a dog|cat’



    >>> s = ‘I have a dog , I have a cat’

    >>> re.findall( r’I have a (?:dog|cat)’ , s )

    ['I have a dog', 'I have a cat']                #正如我們所要的

    下面再看看不用無捕獲組會是什么后果:

    >>> re.findall( r’I have a dog|cat’ , s )

    ['I have a dog', 'cat']                                   #它將’I have a dog’和’cat’當成兩個規則了

    至于無捕獲組的使用,后面將仔細說明。這里先跳過。

     

    ‘.’    匹配所有字符

    匹配除換行符’/n’外的所有字符。如果使用了’S’選項,匹配包括’/n’的所有字符。

          例:

           >>> s=’123 /n456 /n789’

           >>> findall(r‘.+’,s)

           ['123', '456', '789']

           >>> re.findall(r‘.+’ , s , re.S)

           ['123/n456/n789']

     

    ‘^’和’$’匹配字符串開頭和結尾

    注意’^’不能在‘[ ]’中,否則含意就發生變化,具體請看上面的’[‘ ‘]’說明。在多行模式下,它們可以匹配每一行的行首和行尾。具體請看后面compile函數說明的’M

    ’選項部分

     

    ‘/d’匹配數字

    這是一個以’/’開頭的轉義字符,’/d’表示匹配一個數字,即等價于[0-9]

    ‘/D’匹配非數字

    這個是上面的反集,即匹配一個非數字的字符,等價于[^0-9]。注意它們的大小寫。下面我們還將看到Python的正則規則中很多轉義字符的大小寫形式,代表互補的關系。這樣很

    好記。

     

    ‘/w’匹配字母和數字

    匹配所有的英文字母和數字,即等價于[a-zA-Z0-9]。

    ‘/W’匹配非英文字母和數字

    即’/w’的補集,等價于[^a-zA-Z0-9]。

     

    ‘/s’匹配間隔符

    即匹配空格符、制表符、回車符等表示分隔意義的字符,它等價于[ /t/r/n/f/v]。(注意最前面有個空格)

    ‘/S’匹配非間隔符

    即間隔符的補集,等價于[^ /t/r/n/f/v]

     

    ‘/A’匹配字符串開頭

    匹配字符串的開頭。它和’^’的區別是,’/A’只匹配整個字符串的開頭,即使在’M’模式下,它也不會匹配其它行的很首。

    ‘/Z’匹配字符串結尾

    匹配字符串的結尾。它和’$’的區別是,’/Z’只匹配整個字符串的結尾,即使在’M’模式下,它也不會匹配其它各行的行尾。

    例:

    >>> s= '12 34/n56 78/n90'

    >>> re.findall( r'^/d+' , s , re.M )          #匹配位于行首的數字

    ['12', '56', '90']

    >>> re.findall( r’/A/d+’, s , re.M )        #匹配位于字符串開頭的數字

    ['12']

    >>> re.findall( r'/d+$' , s , re.M )          #匹配位于行尾的數字

    ['34', '78', '90']

    >>> re.findall( r’/d+/Z’ , s , re.M )        #匹配位于字符串尾的數字

    ['90']

     

    ‘/b’匹配單詞邊界

    它匹配一個單詞的邊界,比如空格等,不過它是一個‘0’長度字符,它匹配完的字符串不會包括那個分界的字符。而如果用’/s’來匹配的話,則匹配出的字符串中會包含那個

    分界符。

    例:

    >>> s =  'abc abcde bc bcd'

    >>> re.findall( r’/bbc/b’ , s )         #匹配一個單獨的單詞‘bc’ ,而當它是其它單詞的一部分的時候不匹配

    ['bc']                                           #只找到了那個單獨的’bc’

    >>> re.findall( r’/sbc/s’ , s )          #匹配一個單獨的單詞‘bc’ 

    [' bc ']                                         #只找到那個單獨的’bc’,不過注意前后有兩個空格,可能有點看不清楚

    ‘/B’匹配非邊界

    和’/b’相反,它只匹配非邊界的字符。它同樣是個0長度字符。

    接上例:

    >>> re.findall( r’/Bbc/w+’ , s )     #匹配包含’bc’但不以’bc’為開頭的單詞

    ['bcde']                                       #成功匹配了’abcde’中的’bcde’,而沒有匹配’bcd’

     

    ‘(?:)’無捕獲組

    當你要將一部分規則作為一個整體對它進行某些操作,比如指定其重復次數時,你需要將這部分規則用’(?:’ ‘)’把它包圍起來,而不能僅僅只用一對括號,那樣將得到絕對

    出人意料的結果。

    例:匹配字符串中重復的’ab’

    >>> s=’ababab abbabb aabaab’

    >>> re.findall( r’/b(?:ab)+/b’ , s )

    ['ababab']

    如果僅使用一對括號,看看會是什么結果:

    >>> re.findall( r’/b(ab)+/b’ , s )

    ['ab']

    這是因為如果只使用一對括號,那么這就成為了一個組(group)。組的使用比較復雜,將在后面詳細講解。

     

    ‘(?# )’注釋

    Python允許你在正則表達式中寫入注釋,在’(?#’ ‘)’之間的內容將被忽略。

     

    (?iLmsux) 編譯選項指定

    Python的正則式可以指定一些選項,這個選項可以寫在findall或compile的參數中,也可以寫在正則式里,成為正則式的一部分。這在某些情況下會便利一些。具體的選項含義請

    看后面的compile函數的說明。

    此處編譯選項’i’等價于IGNORECASE ,L 等價于 LOCAL ,m 等價于 MULTILINE,s等價于 DOTALL ,u等價于UNICODE , x 等價于 VERBOSE。

    請注意它們的大小寫。在使用時可以只指定一部分,比如只指定忽略大小寫,可寫為‘(?i)’,要同時忽略大小寫并使用多行模式,可以寫為‘(?im)’。

    另外要注意選項的有效范圍是整條規則,即寫在規則的任何地方,選項都會對全部整條正則式有效。

     

     

    1.2重復

    正則式需要匹配不定長的字符串,那就一定需要表示重復的指示符。Python的正則式表示重復的功能很豐富靈活。重復規則的一般的形式是在一條字符規則后面緊跟一個表示重復

    次數的規則,已表明需要重復前面的規則一定的次數。重復規則有:

    ‘*’   0或多次匹配

    表示匹配前面的規則0次或多次。

    ‘+’   1次或多次匹配

    表示匹配前面的規則至少1次,可以多次匹配

    例:匹配以下字符串中的前一部分是字母,后一部分是數字或沒有的變量名字

    >>> s = ‘ aaa bbb111 cc22cc 33dd ‘

    >>> re.findall( r’/b[a-z]+/d*/b’ , s )             #必須至少1個字母開頭,以連續數字結尾或沒有數字

    ['aaa', 'bbb111']

    注意上例中規則前后加了表示單詞邊界的’/b’指示符,如果不加的話結果就會變成:

    >>> re.findall( r’[a-z]+/d*’ , s )

    ['aaa', 'bbb111', 'cc22', 'cc', 'dd']    #把單詞給拆開了

    大多數情況下這不是我們期望的結果。

     

    ‘?’   0或1次匹配

    只匹配前面的規則0次或1次。

    例,匹配一個數字,這個數字可以是一個整數,也可以是一個科學計數法記錄的數字,比如123和10e3都是正確的數字。

    >>> s = ‘ 123 10e3 20e4e4 30ee5 ‘

    >>> re.findall( r’ /b/d+[eE]?/d*/b’ , s )

    ['123', '10e3']

    它正確匹配了123和10e3,正是我們期望的。注意前后的’/b’的使用,否則將得到不期望的結果。

     

    1.2.1 精確匹配和最小匹配

    Python正則式還可以精確指定匹配的次數。指定的方式是

    ‘{m}’      精確匹配m次

    ‘{m,n}’   匹配最少m次,最多n次。(n>m)

    如果你只想指定一個最少次數或只指定一個最多次數,你可以把另外一個參數空起來。比如你想指定最少3次,可以寫成{3,}(注意那個逗號),同樣如果只想指定最大為5次,可

    以寫成{,5},也可以寫成{0,5}。

    例尋找下面字符串中

    a:3位數

    b: 2位數到4位數

    c: 5位數以上的數

    d: 4位數以下的數

    >>> s= ‘ 1 22 333 4444 55555 666666 ‘

    >>> re.findall( r’/b/d{3}/b’ , s )            # a:3位數

    ['333']

    >>> re.findall( r’/b/d{2,4}/b’ , s )         # b: 2位數到4位數

    ['22', '333', '4444']

    >>> re.findall( r’/b/d{5,}/b’, s )           # c: 5位數以上的數

    ['55555', '666666']

    >>> re.findall( r’/b/d{1,4}/b’ , s )         # 4位數以下的數

    ['1', '22', '333', '4444']

     

    ‘*?’ ‘+?’ ‘??’最小匹配

    ‘*’ ‘+’ ‘?’通常都是盡可能多的匹配字符。有時候我們希望它盡可能少的匹配。比如一個c語言的注釋‘/* part 1 */ /* part 2 */’,如果使用最大規則:

    >>> s =r ‘/* part 1 */ code /* part 2 */’

    >>> re.findall( r’//*.*/*/’ , s )

    [‘/* part 1 */ code /* part 2 */’]

    結果把整個字符串都包括進去了。如果把規則改寫成

    >>> re.findall( r’//*.*?/*/’ , s )                    #在*后面加上?,表示盡可能少的匹配

    ['/* part 1 */', '/* part 2 */']

    結果正確的匹配出了注釋里的內容

     

    1.3   前向界定與后向界定

    有時候需要匹配一個跟在特定內容后面的或者在特定內容前面的字符串,Python提供一個簡便的前向界定和后向界定功能,或者叫前導指定和跟從指定功能。它們是:

    ‘(?<=…)’前向界定

    括號中’…’代表你希望匹配的字符串的前面應該出現的字符串。

    ‘(?=…)’  后向界定

    括號中的’…’代表你希望匹配的字符串后面應該出現的字符串。

    例:你希望找出c語言的注釋中的內容,它們是包含在’/*’和’*/’之間,不過你并不希望匹配的結果把’/*’和’*/’也包括進來,那么你可以這樣用:

    >>> s=r’/* comment 1 */  code  /* comment 2 */’

    >>> re.findall( r’(?<=//*).+?(?=/*/)’ , s )

    [' comment 1 ', ' comment 2 ']

    注意這里我們仍然使用了最小匹配,以避免把整個字符串給匹配進去了。

    要注意的是,前向界定括號中的表達式必須是常值,也即你不可以在前向界定的括號里寫正則式。比如你如果在下面的字符串中想找到被字母夾在中間的數字,你不可以用前向界

    定:

    例:

    >>> s = ‘aaa111aaa , bbb222 , 333ccc ‘

    >>> re.findall( r’(?<=[a-z]+)/d+(?=[a-z]+)' , s )          #錯誤的用法

    它會給出一個錯誤信息:

    error: look-behind requires fixed-width pattern

     

    不過如果你只要找出后面接著有字母的數字,你可以在后向界定寫正則式:

    >>> re.findall( r’/d+(?=[a-z]+)’, s )

    ['111', '333']

    如果你一定要匹配包夾在字母中間的數字,你可以使用組(group)的方式

    >>> re.findall (r'[a-z]+(/d+)[a-z]+' , s )

    ['111']

    組的使用將在后面詳細講解。

     

    除了前向界定前向界定和后向界定外,還有前向非界定和后向非界定,它的寫法為:

    ‘(?<!...)’前向非界定

    只有當你希望的字符串前面不是’…’的內容時才匹配

    ‘(?!...)’后向非界定

    只有當你希望的字符串后面不跟著’…’內容時才匹配。

    接上例,希望匹配后面不跟著字母的數字

    >>> re.findall( r’/d+(?!/w+)’ , s )

    ['222']

    注意這里我們使用了/w而不是像上面那樣用[a-z],因為如果這樣寫的話,結果會是:

    >>> re.findall( r’/d+(?![a-z]+)’ , s )

    ['11', '222', '33']

    這和我們期望的似乎有點不一樣。它的原因,是因為’111’和’222’中的前兩個數字也是滿足這個要求的。因此可看出,正則式的使用還是要相當小心的,因為我開始就是這樣

    寫的,看到結果后才明白過來。不過Python試驗起來很方便,這也是腳本語言的一大優點,可以一步一步的試驗,快速得到結果,而不用經過煩瑣的編譯、鏈接過程。也因此學習

    Python就要多試,跌跌撞撞的走過來,雖然曲折,卻也很有樂趣。

     

    1.4組的基本知識

    上面我們已經看過了Python的正則式的很多基本用法。不過如果僅僅是上面那些規則的話,還是有很多情況下會非常麻煩,比如上面在講前向界定和后向界定時,取夾在字母中間

    的數字的例子。用前面講過的規則都很難達到目的,但是用了組以后就很簡單了。

    ‘(‘’)’       無命名組

    最基本的組是由一對圓括號括起來的正則式。比如上面匹配包夾在字母中間的數字的例子中使用的(/d+),我們再回顧一下這個例子:

    >>> s = ‘aaa111aaa , bbb222 , 333ccc ‘

    >>> re.findall (r'[a-z]+(/d+)[a-z]+' , s )

    ['111']

    可以看到findall函數只返回了包含在’()’中的內容,而雖然前面和后面的內容都匹配成功了,卻并不包含在結果中。

     

    除了最基本的形式外,我們還可以給組起個名字,它的形式是

    ‘(?P<name>…)’命名組

    ‘(?P’代表這是一個Python的語法擴展’<…>’里面是你給這個組起的名字,比如你可以給一個全部由數字組成的組叫做’num’,它的形式就是’(?P<num>/d+)’。起了名字之

    后,我們就可以在后面的正則式中通過名字調用這個組,它的形式是

    ‘(?P=name)’調用已匹配的命名組

    要注意,再次調用的這個組是已被匹配的組,也就是說它里面的內容是和前面命名組里的內容是一樣的。

    我們可以看更多的例子:請注意下面這個字符串各子串的特點。

    >>> s='aaa111aaa,bbb222,333ccc,444ddd444,555eee666,fff777ggg'

    我們看看下面的正則式會返回什么樣的結果:

    >>> re.findall( r'([a-z]+)/d+([a-z]+)' , s )             #找出中間夾有數字的字母

    [('aaa', 'aaa'), ('fff', 'ggg')]

    >>> re.findall( r '(?P<g1>[a-z]+)/d+(?P=g1)' , s ) #找出被中間夾有數字的前后同樣的字母

    ['aaa']

    >>> re.findall( r'[a-z]+(/d+)([a-z]+)' , s )             #找出前面有字母引導,中間是數字,后面是字母的字符串中的中間的數字和后面的字母

    [('111', 'aaa'), ('777', 'ggg')]

     

    我們可以通過命名組的名字在后面調用已匹配的命名組,不過名字也不是必需的。

    ‘/number’             通過序號調用已匹配的組

    正則式中的每個組都有一個序號,序號是按組從左到右,從1開始的數字,你可以通過下面的形式來調用已匹配的組

    比如上面找出被中間夾有數字的前后同樣的字母的例子,也可以寫成:

    >>> re.findall( r’([a-z]+)/d+/1’ , s )

    ['aaa']

    結果是一樣的。

    我們再看一個例子

    >>> s='111aaa222aaa111 , 333bbb444bb33'

    >>> re.findall( r'(/d+)([a-z]+)(/d+)(/2)(/1)' , s )           #找出完全對稱的數字-字母-數字-字母-數字中的數字和字母

    [('111', 'aaa', '222', 'aaa', '111')]

     

    Python2.4以后的re模塊,還加入了一個新的條件匹配功能

    ‘(?(id/name)yes-pattern|no-pattern)’ 判斷指定組是否已匹配,執行相應的規則

    這個規則的含義是,如果id/name指定的組在前面匹配成功了,則執行yes-pattern的正則式,否則執行no-pattern的正則式。

    舉個例子,比如要匹配一些形如usr@mail的郵箱地址,不過有的寫成< usr@mail >即用一對<>括起來,有點則沒有,要匹配這兩種情況,可以這樣寫

    >>> s='<usr1@mail1>  usr2@maill2'

    >>> re.findall( r'(<)?/s*(/w+@/w+)/s*(?(1)>)' , s )

    [('<', 'usr1@mail1'), ('', 'usr2@maill2')]

    不過如果目標字符串如下

    >>> s='<usr1@mail1>  usr2@maill2 <usr3@mail3   usr4@mail4>  < usr5@mail5 '

    而你想得到要么由一對<>包圍起來的一個郵件地址,要么得到一個沒有被<>包圍起來的地址,但不想得到一對<>中間包圍的多個地址或不完整的<>中的地址,那么使用這個式子并

    不能得到你想要的結果

    >>> re.findall( r'(<)?/s*(/w+@/w+)/s*(?(1)>)' , s )

    [('<', 'usr1@mail1'), ('', 'usr2@maill2'), ('', 'usr3@mail3'), ('', 'usr4@mail4'), ('', 'usr5@mail5')]

    它仍然找到了所有的郵件地址。

    想要實現這個功能,單純的使用findall有點吃力,需要使用其它的一些函數,比如match或search函數,再配合一些控制功能。這部分的內容將在下面詳細講解。

     

    小結:以上基本上講述了Python正則式的語法規則。雖然大部分語法規則看上去都很簡單,可是稍不注意,仍然會得到與期望大相徑庭的結果,所以要寫好正則式,需要仔細的體

    會正則式規則的含義后不同規則之間細微的差別。

    詳細的了解了規則后,再配合后面就要介紹的功能函數,就能最大的發揮正則式的威力了。

     

    2 re模塊的基本函數

    在上面的說明中,我們已經對re模塊的基本函數‘findall’很熟悉了。當然如果光有findall的話,很多功能是不能實現的。下面開始介紹一下re模塊其它的常用基本函數。靈活

    搭配使用這些函數,才能充分發揮Python正則式的強大功能。

    首先還是說下老熟人findall函數吧

    findall(rule , target [,flag] )

    在目標字符串中查找符合規則的字符串。

    第一個參數是規則,第二個參數是目標字符串,后面還可以跟一個規則選項(選項功能將在compile函數的說明中詳細說明)。

    返回結果結果是一個列表,中間存放的是符合規則的字符串。如果沒有符合規則的字符串被找到,就返回一個空列表。

    2.1使用compile加速

    compile( rule [,flag] )

    將正則規則編譯成一個Pattern對象,以供接下來使用。

    第一個參數是規則式,第二個參數是規則選項。

    返回一個Pattern對象

    直接使用findall ( rule , target )的方式來匹配字符串,一次兩次沒什么,如果是多次使用的話,由于正則引擎每次都要把規則解釋一遍,而規則的解釋又是相當費時間的,

    所以這樣的效率就很低了。如果要多次使用同一規則來進行匹配的話,可以使用re.compile函數來將規則預編譯,使用編譯過返回的Regular Expression Object或叫做Pattern對

    象來進行查找。



    >>> s='111,222,aaa,bbb,ccc333,444ddd'

    >>> rule=r’/b/d+/b’

    >>> compiled_rule=re.compile(rule)

    >>> compiled_rule.findall(s)

    ['111', '222']

    可見使用compile過的規則使用和未編譯的使用很相似。compile函數還可以指定一些規則標志,來指定一些特殊選項。多個選項之間用’|’(位或)連接起來。

    I      IGNORECASE 忽略大小寫區別。

     

    L   LOCAL  字符集本地化。這個功能是為了支持多語言版本的字符集使用環境的,比如在轉義符/w,在英文環境下,它代表[a-zA-Z0-9],即所以英文字符和數字。如果在一個法

    語環境下使用,缺省設置下,不能匹配"é"或"ç"。加上這L選項和就可以匹配了。不過這個對于中文環境似乎沒有什么用,它仍然不能匹配中文字符。

     

    M    MULTILINE  多行匹配。在這個模式下’^’(代表字符串開頭)和’$’(代表字符串結尾)將能夠匹配多行的情況,成為行首和行尾標記。比如

    >>> s=’123 456/n789 012/n345 678’

    >>> rc=re.compile(r’^/d+’)    #匹配一個位于開頭的數字,沒有使用M選項

    >>> rc.findall(s)

    ['123']             #結果只能找到位于第一個行首的’123’

    >>> rcm=re.compile(r’^/d+’,re.M)       #使用M選項

    >>> rcm.findall(s)

    ['123', '789', '345']  #找到了三個行首的數字

    同樣,對于’$’來說,沒有使用M選項,它將匹配最后一個行尾的數字,即’678’,加上以后,就能匹配三個行尾的數字456 012和678了.

    >>> rc=re.compile(r’/d+$’)

    >>> rcm=re.compile(r’/d+$’,re.M)

    >>> rc.findall(s)

    ['678']

    >>> rcm.findall(s)

    ['456', '012', '678']

     

    S     DOTALL       ‘.’號將匹配所有的字符。缺省情況下’.’匹配除換行符’/n’外的所有字符,使用這一選項以后,’.’就能匹配包括’/n’的任何字符了。

     

    U   UNICODE       /w,/W,/b,/B,/d,/D,/s和/S都將使用Unicode。

     

    X     VERBOSE     這個選項忽略規則表達式中的空白,并允許使用’#’來引導一個注釋。這樣可以讓你把規則寫得更美觀些。比如你可以把規則
    >>> rc = re.compile(r"/d+|[a-zA-Z]+")       #匹配一個數字或者單詞

    使用X選項寫成:
    >>> rc = re.compile(r"""  # start a rule/d+                   # number| [a-zA-Z]+           # word""", re.VERBOSE)在這個模式下,如果你想匹配一個空格,你必須

    用'/ '的形式('/'后面跟一個空格)

     

     

    2.2 match與search

    match( rule , targetString [,flag] )

    search( rule , targetString [,flag] )

    (注:re的match與search函數同compile過的Pattern對象的match與search函數的參數是不一樣的。Pattern對象的match與search函數更為強大,是真正最常用的函數)

    按照規則在目標字符串中進行匹配。

    第一個參數是正則規則,第二個是目標字符串,第三個是選項(同compile函數的選項)

    返回:若成功返回一個Match對象,失敗無返回

    findall雖然很直觀,但是在進行更復雜的操作時,就有些力不從心了。此時更多的使用的是match和search函數。他們的參數和findall是一樣的,都是:

    match( rule , targetString [,flag] )

    search( rule , targetString [,flag] )

    不過它們的返回不是一個簡單的字符串列表,而是一個MatchObject(如果匹配成功的話).。通過操作這個matchObject,我們可以得到更多的信息。

    需要注意的是,如果匹配不成功,它們則返回一個NoneType。所以在對匹配完的結果進行操作之前,你必需先判斷一下是否匹配成功了,比如:

    >>> m=re.match( rule , target )

    >>> if m:                       #必需先判斷是否成功

            doSomethin

    這兩個函數唯一的區別是:match從字符串的開頭開始匹配,如果開頭位置沒有匹配成功,就算失敗了;而search會跳過開頭,繼續向后尋找是否有匹配的字符串。針對不同的需

    要,可以靈活使用這兩個函數。

    關于match返回的MatchObject如果使用的問題,是Python正則式的精髓所在,它與組的使用密切相關。我將在下一部分詳細講解,這里只舉個最簡單的例子:

    例:

    >>> s= 'Tom:9527 , Sharry:0003'

    >>> m=re.match( r'(?P<name>/w+):(?P<num>/d+)' , s )

    >>> m.group()

    'Tom:9527'

    >>> m.groups()

    ('Tom', '9527')

    >>> m.group(‘name’)

    'Tom'

    >>> m.group(‘num’)

    '9527'

     

    2.3 finditer

    finditer( rule , target [,flag] )

    參數同findall

    返回一個迭代器

    finditer函數和findall函數的區別是,findall返回所有匹配的字符串,并存為一個列表,而finditer則并不直接返回這些字符串,而是返回一個迭代器。關于迭代器,解釋起來

    有點復雜,還是看看例子把:

    >>> s=’111 222 333 444’

    >>> for i in re.finditer(r’/d+’ , s ):

            print i.group(),i.span()          #打印每次得到的字符串和起始結束位置

    結果是

    111 (0, 3)

    222 (4, 7)

    333 (8, 11)

    444 (12, 15)

    簡單的說吧,就是finditer返回了一個可調用的對象,使用for i in finditer()的形式,可以一個一個的得到匹配返回的Match對象。這在對每次返回的對象進行比較復雜的操作

    時比較有用。

     

    2.4字符串的替換和修改

    re模塊還提供了對字符串的替換和修改函數,他們比字符串對象提供的函數功能要強大一些。這幾個函數是

    sub ( rule , replace , target [,count] )

    subn(rule , replace , target [,count] )

    在目標字符串中規格規則查找匹配的字符串,再把它們替換成指定的字符串。你可以指定一個最多替換次數,否則將替換所有的匹配到的字符串。

    第一個參數是正則規則,第二個參數是指定的用來替換的字符串,第三個參數是目標字符串,第四個參數是最多替換次數。

    這兩個函數的唯一區別是返回值。

    sub返回一個被替換的字符串

    sub返回一個元組,第一個元素是被替換的字符串,第二個元素是一個數字,表明產生了多少次替換。

    例,將下面字符串中的’dog’全部替換成’cat’

    >>> s=’ I have a dog , you have a dog , he have a dog ‘

    >>> re.sub( r’dog’ , ‘cat’ , s )

    ' I have a cat , you have a cat , he have a cat '

    如果我們只想替換前面兩個,則

    >>> re.sub( r’dog’ , ‘cat’ , s , 2 )

    ' I have a cat , you have a cat , he have a dog '

    或者我們想知道發生了多少次替換,則可以使用subn

    >>> re.subn( r’dog’ , ‘cat’ , s )

    (' I have a cat , you have a cat , he have a cat ', 3)

     

    split( rule , target [,maxsplit] )

    切片函數。使用指定的正則規則在目標字符串中查找匹配的字符串,用它們作為分界,把字符串切片。

    第一個參數是正則規則,第二個參數是目標字符串,第三個參數是最多切片次數

    返回一個被切完的子字符串的列表

    這個函數和str對象提供的split函數很相似。舉個例子,我們想把上例中的字符串被’,’分割開,同時要去掉逗號前后的空格

    >>> s=’ I have a dog   ,   you have a dog  ,  he have a dog ‘

    >>> re.split( ‘/s*,/s*’ , s )

    [' I have a dog', 'you have a dog', 'he have a dog ']

    結果很好。如果使用str對象的split函數,則由于我們不知道’,’兩邊會有多少個空格,而不得不對結果再進行一次處理。

     

    escape( string )

    這是個功能比較古怪的函數,它的作用是將字符串中的non-alphanumerics字符(我已不知道該怎么翻譯比較好了)用反義字符的形式顯示出來。有時候你可能希望在正則式中匹

    配一個字符串,不過里面含有很多re使用的符號,你要一個一個的修改寫法實在有點麻煩,你可以使用這個函數,

    例在目標字符串s中匹配’(*+?)’這個子字符串

    >>> s= ‘111 222 (*+?) 333’

    >>> rule= re.escape( r’(*+?)’ )

    >>> print rule

    /(/*/+/?/)

    >>> re.findall( rule , s )

    ['(*+?)']

    3     更深入的了解re的組與對象

    前面對Python正則式的組進行了一些簡單的介紹,由于還沒有介紹到match對象,而組又是和match對象密切相關的,所以必須將它們結合起來介紹才能充分地說明它們的用途。

    不過再詳細介紹它們之前,我覺得有必要先介紹一下將規則編譯后的生成的patter對象

    3.1編譯后的Pattern對象

    將一個正則式,使用compile函數編譯,不僅是為了提高匹配的速度,同時還能使用一些附加的功能。編譯后的結果生成一個Pattern對象,這個對象里面有很多函數,他們看起來

    和re模塊的函數非常象,它同樣有findall , match , search ,finditer , sub , subn , split這些函數,只不過它們的參數有些小小的不同。一般說來,re模塊函數的第一個

    參數,即正則規則不再需要了,應為規則就包含在Pattern對象中了,編譯選項也不再需要了,因為已經被編譯過了。因此re模塊中函數的這兩個參數的位置,就被后面的參數取

    代了。

    findall , match , search和finditer這幾個函數的參數是一樣的,除了少了規則和選項兩個參數外,它們又加入了另外兩個參數,它們是:查找開始位置和查找結束位置,也就

    是說,現在你可以指定查找的區間,除去你不感興趣的區間。它們現在的參數形式是:

    findall ( targetString [, startPos [,endPos] ] )

    finditer ( targetString [, startPos [,endPos] ] )

    match ( targetString [, startPos [,endPos] ] )

    search ( targetString [, startPos [,endPos] ] )

    這些函數的使用和re模塊的同名函數使用完全一樣。所以就不多介紹了。

     

    除了和re模塊的函數同樣的函數外,Pattern對象還多了些東西,它們是:

    flags       查詢編譯時的選項

    pattern查詢編譯時的規則

    groupindex規則里的組

    這幾個不是函數,而是一個值。它們提供你一些規則的信息。比如下面這個例子

    >>> p=re.compile( r'(?P<word>/b[a-z]+/b)|(?P<num>/b/d+/b)|(?P<id>/b[a-z_]+/w*/b)' , re.I )

    >>> p.flags

    2

    >>> p.pattern

    '(?P<word>//b[a-z]+//b)|(?P<num>//b//d+//b)|(?P<id>//b[a-z_]+//w*//b)'

    >>> p.groupindex

    {'num': 2, 'word': 1, 'id': 3}

    我們來分析一下這個例子:這個正則式是匹配單詞、或數字、或一個由字母或’_’開頭,后面接字母或數字的一個ID。我們給這三種情況的規則都包入了一個命名組,分別命名

    為’word’ , ‘num’和‘id’。我們規定大小寫不敏感,所以使用了編譯選項‘I’。

    編譯以后返回的對象為p,通過p.flag我們可以查看編譯時的選項,不過它顯示的不是’I’,而是一個數值2。其實re.I是一個整數,2就是它的值。我們可以查看一下:

    >>> re.I

    2

    >>> re.L

    4

    >>> re.M

    8



    每個選項都是一個數值。

    通過p.pattern可以查看被編譯的規則是什么。使用print的話會更好看一些

    >>> print p.pattern

    (?P<word>/b[a-z]+/b)|(?P<num>/b/d+/b)|(?P<id>/b[a-z_]+/w*/b)

    看,和我們輸入的一樣。

    接下來的p.groupindex則是一個字典,它包含了規則中的所有命名組。字典的key是名字,values是組的序號。由于字典是以名字作為key,所以一個無命名的組不會出現在這里。

     

     

    3.2組與Match對象

    組與Match對象是Python正則式的重點。只有掌握了組和Match對象的使用,才算是真正學會了Python正則式。

    3.2.1 組的名字與序號

    正則式中的每個組都有一個序號,它是按定義時從左到右的順序從1開始編號的。其實,re的正則式還有一個0號組,它就是整個正則式本身。

    我們來看個例子

    >>> p=re.compile( r’(?P<name>[a-z]+)/s+(?P<age>/d+)/s+(?P<tel>/d+).*’ , re.I )

    >>> p.groupindex

    {'age': 2, 'tel': 3, 'name': 1}

    >>> s=’Tom 24 88888888  <=’

    >>> m=p.search(s)

    >>> m.groups()                           #看看匹配的各組的情況

    ('Tom', '24', '8888888')

    >>> m.group(‘name’)                   #使用組名獲取匹配的字符串

    ‘Tom’

    >>> m.group( 1 )                         #使用組序號獲取匹配的字符串,同使用組名的效果一樣

    >>> m.group(0)                           # 0組里面是什么呢?

    'Tom 24 88888888  <='

    原來0組就是整個正則式,包括沒有被包圍到組里面的內容。當獲取0組的時候,你可以不寫這個參數。m.group(0)和m.group()的效果是一樣的:

    >>> m.group()

    'Tom 24 88888888  <='

     

    接下來看看更多的Match對象的方法,看看我們能做些什么。

    3.2.2 Match對象的方法

    group([index|id]) 獲取匹配的組,缺省返回組0,也就是全部值

    groups()               返回全部的組

    groupdict()           返回以組名為key,匹配的內容為values的字典

    接上例:

    >>> m.groupindex()

    {'age': '24', 'tel': '88888888', 'name': 'Tom'}

    start( [group] )     獲取匹配的組的開始位置

    end( [group] )              獲取匹配的組的結束位置

    span( [group] )     獲取匹配的組的(開始,結束)位置

     

    expand( template )根據一個模版用找到的內容替換模版里的相應位置

    這個功能比較有趣,它根據一個模版來用匹配到的內容替換模版中的相應位置,組成一個新的字符串返回。它使用/g<index|name>或/index來指示一個組。

    接上例

    >>> m.expand(r'name is /g<1> , age is /g<age> , tel is /3')

    'name is Tom , age is 24 , tel is 88888888'

     

    除了以上這些函數外,Match對象還有些屬性

    pos         搜索開始的位置參數

    endpos  搜索結束的位置參數

    這兩個是使用findall或match等函數時,傳入的參數。在上面這個例子里,我們沒有指定開始和結束位置,那么缺省的開始位置就是0,結束位置就是最后。

    >>> m.pos

    0

    >>> m.endpos

    19

    lastindex 最后匹配的組的序號

    >>> m.lastindex

    3

    lastgroup       最后匹配的組名

    >>> m.lastgroup

    'tel'

    re    產生這個匹配的Pattern對象,可以認為是個逆引用

    >>> m.re.pattern

    '(?P<name>[a-z]+)//s+(?P<age>//d+)//s+(?P<tel>//d+).*'

    得到了產生這個匹配的規則

    string 匹配的目標字符串

    >>> m.string

    'Tom 24 88888888  <='

    轉自:http://hi.baidu.com/yangdaming1983/item/e6a8146255a5442169105b91
    posted @ 2013-02-11 16:28 Seraphi 閱讀(278) | 評論 (0)編輯 收藏
         摘要: 1        概述1.1     什么是捕獲組捕獲組就是把正則表達式中子表達式匹配的內容,保存到內存中以數字編號或顯式命名的組里,方便后面引用。當然,這種引用既可以是在正則表達式內部,也可以是在正則表達式外部。捕獲組有兩種形式,一種是普通捕獲組,另一種是命名捕獲組,...  閱讀全文
    posted @ 2013-02-11 16:26 Seraphi 閱讀(1952) | 評論 (0)編輯 收藏

    Python讀寫文件

    Python讀寫文件
    1.open
    使用open打開文件后一定要記得調用文件對象的close()方法。比如可以用try/finally語句來確保最后能關閉文件。

    file_object = open('thefile.txt')
    try:
         all_the_text = file_object.read( )
    finally:
         file_object.close( )

    注:不能把open語句放在try塊里,因為當打開文件出現異常時,文件對象file_object無法執行close()方法。

    2.讀文件
    讀文本文件
    input = open('data', 'r')
    #第二個參數默認為r
    input = open('data')

     

    讀二進制文件
    input = open('data', 'rb')
     

    讀取所有內容
    file_object = open('thefile.txt')
    try:
         all_the_text = file_object.read( )
    finally:
         file_object.close( )
     

    讀固定字節
    file_object = open('abinfile', 'rb')
    try:
        while True:
             chunk = file_object.read(100)
            if not chunk:
                break
             do_something_with(chunk)
    finally:
         file_object.close( )
     

    讀每行
    list_of_all_the_lines = file_object.readlines( )

    如果文件是文本文件,還可以直接遍歷文件對象獲取每行:

    for line in file_object:
         process line
     

    3.寫文件
    寫文本文件
    output = open('data', 'w')
     

    寫二進制文件
    output = open('data', 'wb')
     

    追加寫文件
    output = open('data', 'w+')
     

    寫數據
    file_object = open('thefile.txt', 'w')
    file_object.write(all_the_text)
    file_object.close( )
     

    寫入多行
    file_object.writelines(list_of_text_strings)

    注意,調用writelines寫入多行在性能上會比使用write一次性寫入要高。

    在處理日志文件的時候,常常會遇到這樣的情況:日志文件巨大,不可能一次性把整個文件讀入到內存中進行處理,例如需要在一臺物理內存為 2GB 的機器上處理一個 2GB 的日志文件,我們可能希望每次只處理其中 200MB 的內容。
    在 Python 中,內置的 File 對象直接提供了一個 readlines(sizehint) 函數來完成這樣的事情。以下面的代碼為例:

    file = open('test.log', 'r')sizehint = 209715200   # 200Mposition = 0lines = file.readlines(sizehint)while not file.tell() - position < 0:       position = file.tell()       lines = file.readlines(sizehint)

    每次調用 readlines(sizehint) 函數,會返回大約 200MB 的數據,而且所返回的必然都是完整的行數據,大多數情況下,返回的數據的字節數會稍微比 sizehint 指定的值大一點(除最后一次調用 readlines(sizehint) 函數的時候)。通常情況下,Python 會自動將用戶指定的 sizehint 的值調整成內部緩存大小的整數倍。

    file在python是一個特殊的類型,它用于在python程序中對外部的文件進行操作。在python中一切都是對象,file也不例外,file有file的方法和屬性。下面先來看如何創建一個file對象:


    file(name[, mode[, buffering]]) 
    file()函數用于創建一個file對象,它有一個別名叫open(),可能更形象一些,它們是內置函數。來看看它的參數。它參數都是以字符串的形式傳遞的。name是文件的名字。
    mode是打開的模式,可選的值為r w a U,分別代表讀(默認) 寫 添加支持各種換行符的模式。用w或a模式打開文件的話,如果文件不存在,那么就自動創建。此外,用w模式打開一個已經存在的文件時,原有文件的內容會被清空,因為一開始文件的操作的標記是在文件的開頭的,這時候進行寫操作,無疑會把原有的內容給抹掉。由于歷史的原因,換行符在不同的系統中有不同模式,比如在 unix中是一個\n,而在windows中是‘\r\n’,用U模式打開文件,就是支持所有的換行模式,也就說‘\r’ '\n' '\r\n'都可表示換行,會有一個tuple用來存貯這個文件中用到過的換行符。不過,雖說換行有多種模式,讀到python中統一用\n代替。在模式字符的后面,還可以加上+ b t這兩種標識,分別表示可以對文件同時進行讀寫操作和用二進制模式、文本模式(默認)打開文件。
    buffering如果為0表示不進行緩沖;如果為1表示進行“行緩沖“;如果是一個大于1的數表示緩沖區的大小,應該是以字節為單位的。

    file對象有自己的屬性和方法。先來看看file的屬性。


    closed #標記文件是否已經關閉,由close()改寫 
    encoding #文件編碼 
    mode #打開模式 
    name #文件名 
    newlines #文件中用到的換行模式,是一個tuple 
    softspace #boolean型,一般為0,據說用于print

    file的讀寫方法:


    F.read([size]) #size為讀取的長度,以byte為單位 
    F.readline([size]) 
    #讀一行,如果定義了size,有可能返回的只是一行的一部分 
    F.readlines([size]) 
    #把文件每一行作為一個list的一個成員,并返回這個list。其實它的內部是通過循環調用readline()來實現的。如果提供size參數,size是表示讀取內容的總長,也就是說可能只讀到文件的一部分。 
    F.write(str) 
    #把str寫到文件中,write()并不會在str后加上一個換行符 
    F.writelines(seq) 
    #把seq的內容全部寫到文件中。這個函數也只是忠實地寫入,不會在每行后面加上任何東西。 
    file的其他方法:


    F.close() 
    #關閉文件。python會在一個文件不用后自動關閉文件,不過這一功能沒有保證,最好還是養成自己關閉的習慣。如果一個文件在關閉后還對其進行操作會產生ValueError 
    F.flush() 
    #把緩沖區的內容寫入硬盤 
    F.fileno() 
    #返回一個長整型的”文件標簽“ 
    F.isatty() 
    #文件是否是一個終端設備文件(unix系統中的) 
    F.tell() 
    #返回文件操作標記的當前位置,以文件的開頭為原點 
    F.next() 
    #返回下一行,并將文件操作標記位移到下一行。把一個file用于for ... in file這樣的語句時,就是調用next()函數來實現遍歷的。 
    F.seek(offset[,whence]) 
    #將文件打操作標記移到offset的位置。這個offset一般是相對于文件的開頭來計算的,一般為正數。但如果提供了whence參數就不一定了,whence可以為0表示從頭開始計算,1表示以當前位置為原點計算。2表示以文件末尾為原點進行計算。需要注意,如果文件以a或a+的模式打開,每次進行寫操作時,文件操作標記會自動返回到文件末尾。 
    F.truncate([size]) 
    #把文件裁成規定的大小,默認的是裁到當前文件操作標記的位置。如果size比文件的大小還要大,依據系統的不同可能是不改變文件,也可能是用0把文件補到相應的大小,也可能是以一些隨機的內容加上去。


    本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/adupt/archive/2009/08/11/4435615.aspx

    posted @ 2013-02-10 23:31 Seraphi 閱讀(1313) | 評論 (0)編輯 收藏
    posted @ 2013-02-02 16:01 Seraphi 閱讀(361) | 評論 (0)編輯 收藏

    linux 下的iconv命令可以把Windows默認GBK編碼的文件轉成Linux下用的UTF-8編碼。

     Example: $ iconv -f GBK -t UTF-8 file_name -o file_name



             1. 安裝命令行版的texlive: sudo apt-get install texlive-full

              2. 安裝一個比較有幫助性的編輯器: sudo apt-get install texmaker

              3. 安裝中文環境: sudo apt-get install latex-cjk-all

      

             A useful webiste http://chixi.an.blog.163.com/blog/static/29359272201262952120729/


        To install/upgrade to TeX Live 2012:

    1. Open a terminal with Ctrl+Alt+T
    2. Add the texlive-backports PPA by typing the below (enter your password when prompted):

      sudo apt-add-repository ppa:texlive-backports/ppa 
    3. Then type:

      sudo apt-get update 
    4. Installation:

      • If you are installing TeX Live for the first time, type:

        sudo apt-get install texlive 
      • If you already have TeX Live installed and are upgrading, type:

        sudo apt-get upgrade 

        Warning: this will also upgrade all other packages on your Ubuntu system for which upgrades are available. If you do not wish to do this, please use the previous sudo apt-get install texliveinstead.

        轉自:
        http://blog.csdn.net/lsg32/article/details/8058491

    posted @ 2013-02-02 15:27 Seraphi 閱讀(286) | 評論 (0)編輯 收藏
    在新版本的UBUNTU里不支持WINDOWS的wubi安裝,要用如下方式:
    Ubuntu 12.04 wubi的安裝
     
    一、在12.04里,在Windows內安裝那個選項被禁用了,只能通過以下指令開啟,X為光驅盤符:
    代碼:
    X:\wubi.exe --force-wubi
    posted @ 2013-02-01 12:27 Seraphi 閱讀(257) | 評論 (0)編輯 收藏
    1、學會latex
    2、熟練python
    3、NLP相關知識,主要是gibbs sampling;以及這學期所學到的東西
    4、Deep learning
    5、改論文
    6、加強算法方面的練習
    posted @ 2013-01-17 00:24 Seraphi 閱讀(189) | 評論 (0)編輯 收藏
    【招聘須知】  Facebook正在全球招聘,對中國頂尖大學的Engineering專業學生尤其歡迎。  具體職位信息可以在https://www.facebook.com/careers上找到,申請的時候一般都是選 擇Software Engineer (University Recruiting),Facebook的制度是并不預先定向你去 哪個組。在入職的第一個月統一進行培訓,培訓結束的兩周后進行統一的Team Selectio n,每個組的大Manager過來將自己的組做的東西,你可以和感興趣的組聊,雙向選擇后最 終決定去哪里。所以是很自由的文化,決定你去哪里的最重要的是Potential,而不是你 已經在這個area的experience,這也是FB的文化,希望培養每個Engineer成為多面手,對 任何問題的Fast learner。   【基本要求】  專業不限要求有限,可以分成兩個類,看看你符合哪一類  1. 第一類:  - ACM/ICPC 區域銀牌以上,或者在大型比賽上得過不錯的名次(前15%),這里大型比賽 指包括NOIP, NOI, APOI,省級選拔賽,Topcoder, Google Code Jam, 百度之星,有道難 題等等 - 在以下公司有過實習經驗:Google, Microsoft Research Asia, Hulu, EMC/VMware,  Microstrategy (這些公司只是在經驗范圍內實習生非常靠譜,并沒有對其他公司不尊重 的意思,只是接觸的不多而已,見諒) - 本科成績年級前10%,核心課程算法,數據結構,C++,離散,組合數學等等絕大部分為 優秀 - 頂級會議上發表一二作論文,頂級會議的定義是專業領域內公認的大會,例如IR/ML領 域的SIGIR, ICML, WWW, ICDM等等  以上符合任意一條的話,請聯系我  2. 第二類:  - <Crack the Coding Interview> 從頭到尾詳細閱讀并且做完所有的例題和習題 - www.leetcode.com 全部做完所有的題   符合以上所有條件的,請聯系我,附上代碼   PS: CTCI書課后有答案,leetcode網上有不錯的人做了發表,比如 https://github.com/zwxxx/LeetCode https://github.com/anson627/leetcode  做的時候請不要參考,做完以后可以和參考答案對比改進,直接抄答案是沒有意義的,答 案只是幫你提高的工具。對于代碼的要求是,寫的塊,風格簡潔,易于理解     【聯系方式】  請發郵件到郵箱zhangchitc@gmail.com,附上簡單的自我介紹,并著名是符合上述哪些要 求,如果第二類請用zip壓縮包打包代碼附在附件中  BTW: 第一類滿足的話最終還是要將第二類里面的材料全部做了的。。。。     【面試過程】   職位都是美國總部,不排除可能外派海外Site,不過基本應該都是前者。在推薦以后一 周之內應該總部會安排工程師使用skype進行2到3輪電話面試,通過以后提供機票到美國 進行onsite面試。3到5輪不等。基本都是算法面試,在白板上寫程序。全程英文,不需要 英語標準考試成績,但是對基本的聽力和口語要求比較高,要能自由和工程師進行交流, 語法有問題的可以完全不用擔心  住宿和交通費用全包。     【注意事項】  - 理論上是可以推實習的,不過對中國學生來講實習不是很現實,本科生太忙,研究生完 全2、3個月在外面導師應該說不過去 - 基本沒有deadline,全年都可以聯系我,但是考慮到大陸學生過去的H1B簽證申請,如 果拿到offer需要在每年4月前遞交申請,所以最晚開始面試應該是2月,越快申請越好 - 因為FB在中國沒有公開的招聘渠道,所以請不要傳播本帖(雖然知道基本是白說,但是 希望至少本校的同學不要傳播出去)招聘的細節我不能說太多,接觸以后可以聊 - 滿足條件就請大膽申請,在整個過程中我都可以為大家提供幫助和建議。根據HR的反饋 來看本人的推薦還是挺靠譜的,目前為止有7位同學通過我的推薦成功拿到了offer,目測 很快在一周之內會達到10個
    posted @ 2013-01-11 00:24 Seraphi 閱讀(2280) | 評論 (2)編輯 收藏
    Windows Registry Editor Version 5.00
    [HKEY_CLASSES_ROOT\CLSID\{B416D21B-3B22-B6D4-BBD3-BBD452DB3D5B}]
    @="Internet Explorer"
    "InfoTip"="@C:\\WINDOWS\\system32\\zh-CN\\ieframe.dll.mui,-881"
    "LocalizedString"="@C:\\WINDOWS\\system32\\zh-CN\\ieframe.dll.mui,-880"
    [HKEY_CLASSES_ROOT\CLSID\{B416D21B-3B22-B6D4-BBD3-BBD452DB3D5B}\DefaultIcon]
    @="C:\\Program Files\\Internet Explorer\\iexplore.exe,-32528"
    [HKEY_CLASSES_ROOT\CLSID\{B416D21B-3B22-B6D4-BBD3-BBD452DB3D5B}\Shell\NoAddOns]
    @="在沒有加載項的情況下啟動"
    [HKEY_CLASSES_ROOT\CLSID\{B416D21B-3B22-B6D4-BBD3-BBD452DB3D5B}\Shell\NoAddOns\Command]
    @="C:\\Program Files\\Internet Explorer\\iexplore.exe about:NoAdd-ons"
    [HKEY_CLASSES_ROOT\CLSID\{B416D21B-3B22-B6D4-BBD3-BBD452DB3D5B}\Shell\Open]
    @="打開(O)"
    [HKEY_CLASSES_ROOT\CLSID\{B416D21B-3B22-B6D4-BBD3-BBD452DB3D5B}\Shell\Open\Command]
    @="C:\\Program Files\\Internet Explorer\\iexplore.exe"
    [HKEY_CLASSES_ROOT\CLSID\{B416D21B-3B22-B6D4-BBD3-BBD452DB3D5B}\Shell\屬性(R)]
    @=""
    [HKEY_CLASSES_ROOT\CLSID\{B416D21B-3B22-B6D4-BBD3-BBD452DB3D5B}\Shell\屬性(R)\Command]
    @="Rundll32.exe Shell32.dll,Control_RunDLL Inetcpl.cpl"
    [HKEY_CLASSES_ROOT\CLSID\{B416D21B-3B22-B6D4-BBD3-BBD452DB3D5B}\ShellFolder]
    @=""
    "Attributes"=dword:00000010
    "HideFolderVerbs"=""
    "WantsParseDisplayName"=""
    "HideOnDesktopPerUser"=""
    @="C:\\WINDOWS\\system32\\ieframe.dll,-190"
    "HideAsDeletePerUser"=""
    Windows Registry Editor Version 5.00
    [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\CLSID\{B416D21B-3B22-B6D4-BBD3-BBD452DB3D5B}]
    @="Internet Explorer"
    Windows Registry Editor Version 5.00
    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Desktop\NameSpace\{B416D21B-3B22-B6D4-BBD3-BBD452DB3D5B}]
    @="Windows Media"
    posted @ 2013-01-06 15:13 Seraphi 閱讀(179) | 評論 (0)編輯 收藏
    set tags=tags;
    set backspace=indent,eol,start
    set shiftwidth=4 
    set tabstop=4
    set expandtab
    set encoding=utf8
    set fileencodings=utf8,gbk
    set nocompatible "去掉討厭的有關vim一致性模式,避免以前版本的一些bug和局限.
    set number "顯示行號.
    set background=dark "背景顏色暗色.(我覺得不錯,保護眼睛.)
    syntax on "語法高亮顯示.(這個肯定是要的.)
    set history=50 "設置命令歷史記錄為50條.
    set autoindent "使用自動對起,也就是把當前行的對起格式應用到下一行.
    set smartindent "依據上面的對起格式,智能的選擇對起方式,對于類似C語言編.
    set tabstop=4 "設置tab鍵為4個空格.
    set shiftwidth=4 "設置當行之間交錯時使用4個空格
    set showmatch "設置匹配模式,類似當輸入一個左括號時會匹配相應的那個右括號
    set incsearch "搜索選項.(比如,鍵入"/bo",光標自動找到第一個"bo"所在的位置.)
    hi Comment ctermfg=darkmagenta
    hi String ctermfg=darkred
    hi Number ctermfg=darkblue
    "是否生成一個備份文件.(備份的文件名為原文件名加“~“后綴
    "(我不喜歡這個備份設置,一般注釋掉.)
    "if has(“vms.
    " set nobackup
    "else
    " set backup
    "endif


    關于注釋字體顏色的修改,可以參考:http://blog.csdn.net/a670449625/article/details/48051249
    posted @ 2012-11-09 19:44 Seraphi 閱讀(193) | 評論 (0)編輯 收藏
    http://www.coli.uni-saarland.de/~csporled/page.php?id=tools

    這個站點列舉出了幾乎所有NLP和IR領域能夠直接使用的好用的工具包~
    posted @ 2012-10-29 10:25 Seraphi 閱讀(303) | 評論 (0)編輯 收藏

    轉載自:cool shell,作者:陳皓
    From:http://coolshell.cn/articles/7992.html 

    先說明一下,我不希望本文變成語言爭論貼。希望下面的文章能讓我們客觀理性地了解C++這個語言。(另,我覺得技術爭論不要停留在非黑即白的二元價值觀上,這樣爭論無非就是比誰的嗓門大,比哪一方的觀點強,毫無價值。我們應該多看看技術是怎么演進的,怎么取舍的。)

    事由

    周五的時候,我在我的微博上發了一個貼說了一下一個網友給我發來的C++程序的規范和內存管理寫的不是很好(后來我刪除了,因為當事人要求),我并非批判,只是想說明其實程序員是需要一些“疫苗”的,并以此想開一個“程序員疫苗的網站”,結果,@簡悅云風同學直接回復到:“不要用 C++ 直接用 C , 就沒那么多坑了。”就把這個事帶入了語言之爭。

    我又發了一條微博

    @左耳朵耗子 新浪個人認證 : 說C++比C的坑更多的人我可以理解,但理性地思考一下。C語言的坑也不少啊,如果說C語言有90個坑,那么C++就是100個坑(另,我看很多人都把C語言上的坑也歸到了C++上來),但是C++你得到的東西更多,封裝,多態,繼承擴展,泛型編程,智能指針,……,你得到了500%東西,但卻只多了10%的坑,多值啊

    結果引來了更多的回復(只節選了一些言論):

    • @淘寶褚霸也在微博里說:“自從5年前果斷扔掉C++,改用了ansi c后,我的生活質量大大提升,沒有各種坑坑我。
    • @Laruence在其微博里說: “我確實用不到, C語言靈活運用struct, 可以很好的滿足這些需求.//@左耳朵耗子: 封裝,繼承,多態,模板,智能指針,這也用不到?這也學院派?//@Laruence: 問題是, 這些東西我都用不到… C語言是工程師搞的, C++是學院派搞的

    那么,C++的坑真的多么?我還請大家理性地思考一下

    C++真的比C差嗎?

    我們先來看一個圖——《各種程序員的嘴臟的對比》,從這個圖上看,C程序員比C++的程序員在注釋中使用fuck的字眼多一倍。這說明了什么?我個人覺得這說明C程序員沒有C++程序員淡定

    Google Code 中程序語言出現 fuck 一詞的比率

    不要太糾結上圖,只是輕松一下,我沒那么無聊,讓我們來看點真正的論據。

    相信用過C++的程序員知道,C++的很多特性主要就是解決C語言中的各種不完美和缺陷:(注:C89、C99中許多的改進正是從C++中所引進的

    • 用namespace解決了很C函數重名的問題。
    • 用const/inline/template代替了宏,解決了C語言中宏的各種坑。
    • 用const的類型解決了很多C語言中變量值莫名改變的問題。
    • 用引用代替指針,解決了C語言中指針的各種坑。這個在Java里得到徹底地體現。
    • 用強類型檢查和四種轉型,解決了C語言中亂轉型的各種坑。
    • 用封裝(構造,析構,拷貝構造,賦值重載)解決了C語言中各種復制一個結構體(struct)或是一個數據結構(link, hashtable, list, array等)中淺拷貝的內存問題的各種坑。
    • 用封裝讓你可以在成員變量加入getter/setter,而不會像C一樣只有文件級的封裝。
    • 用函數重載、函數默認參數,解決了C中擴展一個函數搞出來像func2()之類的ugly的東西。
    • 用繼承多態和RTTI解決了C中亂轉struct指針和使用函數指針的諸多讓代碼ugly的問題。
    • 用RAII,智能指針的方式,解決了C語言中因為出現需要釋放資源的那些非常ugly的代碼的問題。
    • 用OO和GP解決各種C語言中用函數指針,對指針亂轉型,及一大砣if-else搞出來的ugly的泛型。
    • 用STL解決了C語言中算法和數據結構的N多種坑。
    (注意:上面我沒有提重載運算符和異常,前者寫出來的代碼并不易讀和易維護(參看《恐怖的C++語言》后面的那個示例),坑也多,后者并不成熟(相對于Java的異常),但是我們需要知道try-catch這種方式比傳統的不斷地判斷函數返回值和errno形成的大量的if-else在代碼可讀性上要好很多)

    上述的這些東西填了不知有多少的C語言編程和維護的坑。少用指針,多用引用,試試autoptr,用用封裝,繼承,多態和函數重載…… 你面對的坑只會比C少,不會多。

    C++的坑有多少?

    C++的坑真的不多,如果你能花兩到三周的時候讀一下《Effecitve C++》里的那50多個條款,你就知道C++里的坑并不多,而且,有很多條款告訴我們C++是怎么解決C的坑的。然后,你可以讀讀《Exceptional C++》和《More Exceptional C++》,你可以了解一下C++各種問題的解決方法和一些常見的經典錯誤。

    當然,C++在解決了很多C語的坑的同時,也因為OO和泛型又引入了一些坑。消一些,加一些,我個人感覺上總體上只比C多10%左右吧。但是你有了開發速度更快,代碼更易讀,更易維護的500%的利益。

    另外,不可否認的是,C++中的代碼出了錯誤,有時候很難搞,而且似乎用C++的人會覺得C++更容易出錯?我覺得主要是下面幾個原因:

    • C和C++都沒學好,大多數人用C++寫C,所以,C的坑和C++的坑合并了。
    • C++太靈活了,想怎么搞就怎么搞,所以,各種不經意地濫用和亂搞。

    另外,C++的編譯對標準C++的實現各異,支持地也千差萬別,所以會有一些比較奇怪的問題,但是如果你一般用用C++的封裝,繼承,多態,以及namespace,const, refernece,  inline, templete, overloap, autoptr,還有一些OO 模式,并不會出現奇怪的問題。

    而對于STL中的各種坑,我覺得是程序員們還對GP(泛型編程)理解得還不夠,STL是泛型編程的頂級實踐!屬于是大師級的作品,一般人很難理解。必需承認STL寫出來的代碼和編譯錯誤的確相當復雜晦澀,太難懂了。這也是C++的一個詬病。

    這和Linus說的一樣 —— “C++是一門很恐怖的語言,而比它更恐怖的是很多不合格的程序員在使用著它”。注意我飄紅了“很多不合格的程序員”!

    我覺得C++并不適合初級程序員使用,C++只適合高級程序員使用(參看《21天學好C++》和《C++學習自信心曲線》),正如《Why C++》中說的,C++適合那些對開發維護效率和系統性能同時關注的高級程序員使用。

    這就好像飛機一樣,開飛機很難,開飛機要注意的東西太多太多,對駕駛員的要求很高,但你不能說飛機這個工具很爛,開飛機的坑太多。(注:我這里并不是說C++是飛機,C是汽車,C++和C的差距,比飛機到汽車的差距少太多太多,這里主要是類比,我們對待C++語言的心態!)

    C++的初衷

    理解C++設計的最佳讀本是《C++演化和設計》,在這本書中Stroustrup說了些事:

    1)Stroustrup對C是非常欣賞,實際上早期C++許多的工作是對于C的強化和凈化,并把完全兼容C作為強制性要求。C89、C99中許多的改進正是從C++中所引進。可見,Stroustrup對C語言的貢獻非常之大。今天不管你對C++怎么看,C++的確擴展和進化了C,對C造成了深遠的影響

    2)Stroustrup對于C的抱怨主要來源于兩個方面——在C++兼容C的過程中遇到了不少設計實現上的麻煩;以及守舊的K&R C程序員對Stroustrup的批評。很多人說C++的惡夢就是要去兼容于C,這并不無道理(Java就干的比C++徹底得多,但這并不是Stroustrup考慮的,Stroustrup一邊在使盡渾身解數來兼容C,另一方面在拼命地優化C。

    3)Stroustrup在書中直接說,C++最大的競爭對手正是C,他的目的就是——C能做到的,C++也必須做到,而且要做的更好。大家覺得是不是做到了?有多少做到了,有多少還沒有做到?

    4)對于同時關注的運行效率和開發效率的程序員,Stroustrup多次強調C++的目標是——“在保證效率與C語言相當的情況下,加強程序的組織性;能保證同樣功能的程序,C++更短小”,這正是淺封裝的核心思想。而不是過渡設計的OO。(參看:面向對象是個騙局

    5)這本書中舉了很多例子來回應那些批評C++有運行性能問題的人。C++在其第二個版本中,引入了虛函數機制,這是C++效率最大的瓶頸了,但我個人認為虛函數就是多了一次加法運算,但讓我們的代碼能有更好的組織,極大增加了程序的閱讀和降底了維護成本。(注:Lippman的《深入探索C++對象模型》也說明了C++不比C的程序在運行性能低。Bruce的《Think in C++》也說C++和C的性能相差只有5%)

    6)這本書中還講了一些C++的痛苦的取舍,印象最深的就是多重繼承,提出,拿掉,再被提出,反復很多次,大家在得與失中不斷地辯論和取舍。這個過程讓我最大的收獲是——a) 對于任何一種設計都有好有壞,都只能偏重一方,b) 完全否定式的批評是不好的心態,好的心態應該是建設性地批評

    我對C++的感情

    我先說說我學C++的經歷。

    我畢業時,是直接從C跳過C++學Java的,但是學Java的時候,不知道為什么Java要設計成這樣,只好回頭看C++,結果學C++的時候又有很多不懂,又只得回頭看C最后發現,C -> C++ -> Java的過程,就是C++填C的坑,Java填C++的坑的過程

    注,下面這些東西可以看到Java在填C/C++坑:

    • Java徹底廢棄了指針(指針這個東西,絕對讓這個社會有幾百億的損失),使用引用。
    • Java用GC解決了C++的各種內存問題的詬病,當然也帶來了GC的問題,不過功大于過。
    • Java對異常的支持比C++更嚴格,讓編程更方便了。
    • Java沒有像C++那樣的template/macro/函數對象/操作符重載,泛型太晦澀,用OO更容易一些。
    • Java改進了C++的構造、析構、拷貝構造、賦值。
    • Java對完全拋棄了C/C++這種面向過程的編程方式,并廢棄了多重繼承,更OO(如:用接口來代替多重繼承)
    • Java比較徹底地解決了C/C++自稱多年的跨平臺技術。
    • Java的反射機制把這個語言提升了一個高度,在這個上面可以構建各種高級用法。
    • C/C++沒有一些比較好的類庫,比如UI,線程 ,I/O,字符串處理等。(C++0x補充了一些)
    • 等等……

    當然時代還在前進,這個演變的過程還在C#和Go上體現著。不過我學習了C -> C++  -> Java這個填坑演進的過程,讓我明白了很多東西:

    • 我明白了OO是怎么一回事,重要的是明白了OO的封裝,繼承,和多態是怎么實現的。(參看我以前寫過的《C++虛函數表解析》和《C++對象內存布局》)
    • 我明白了STL的泛型編程和Java的各種花哨的技術是怎么一回事,以及那些很花哨的編程方法和技術。
    • 我明白了C,C++,Java的各中坑,這就好像玩火一樣,我知道怎么玩火不會燒身了。

    我從這個學習過程中得到的最大的收獲不是語言本身,而是各式各樣的編程技術和方法,和技術的演進的過程,這比語言本身更重要在這個角度上學習,你看到的不是一個又一個的坑,你看到的是——各式各樣讓你可以爬得更高的梯子

    我對C++的感情有三個過程:先是喜歡地要死,然后是恨地要死,現在的又愛又恨,愛的是這個語言,恨的是很多不合格的人在濫用和凌辱它。

    C++的未來

    C++語言發展大概可以分為三個階段(摘自Wikipedia):

    • 第一階段從80年代到1995年。這一階段C++語言基本上是傳統類型上的面向對象語言,并且憑借著接近C語言的效率,在工業界使用的開發語言中占據了相當大份額;
    • 第二階段從1995年到2000年,這一階段由于標準模板庫(STL)和后來的Boost等程式庫的出現,泛型程式設計在C++中占據了越來越多的比重性。當然,同時由于Java、C#等語言的出現和硬件價格的大規模下降,C++受到了一定的沖擊;
    • 第三階段從2000年至今,由于以Loki、MPL等程式庫為代表的產生式編程和模板元編程的出現,C++出現了發展歷史上又一個新的高峰,這些新技術的出現以及和原有技術的融合,使C++已經成為當今主流程式設計語言中最復雜的一員。

    在《Why C++? 王者歸來》中說了 ,性能主要就是要省電,省電就是省錢,在數據中心還不明顯,在手機上就更明顯了,這就是為什么Android 支持C++的原因。所以,在NB的電池或是能源出現之前,如果你需要注重程序的運行性能和開發效率,并更關注程序的運性能,那么,應該首選 C++。這就是iOS開發也支持C++的原因。

    今天的C++11中不但有更多更不錯的東西,而且,還填了更多原來C++的坑。(參看:C++11 WikiC++ 11的主要特性

     

    總結

    • C++并不完美,但學C++必然讓你受益無窮。
    • 是那些不合格的、想對編程速成的程序員讓C++變得坑多。

    最后,非常感謝能和“@簡悅云風”,“@淘寶諸霸”,“@Laruence”一起討論這個問題!無論你們的觀點怎么樣,我都和你們“在一起”,嘿嘿嘿……

    (全文完)

    posted @ 2012-08-06 12:58 Seraphi 閱讀(424) | 評論 (0)編輯 收藏

    轉載Cool Shell,作者:陳皓

    From:http://coolshell.cn/articles/2250.html 

    下面是一個《Teach Yourself  C++ in 21 Days》的流程圖,請各位程序員同仁認真領會。如果有必要,你可以查看這個圖書以作參照:http://www.china-pub.com/27043

    看完上面這個圖片,我在想,我學習C++有12年了,好像C++也沒有學得特別懂,看到STL和泛型,還是很頭大。不過,我應該去考慮研究量子物理和生物化學,這樣,我才能重返98年殺掉還在大學的我,然后達到21天搞定C++的目標。另外,得要特別提醒剛剛開始學習C++的朋友,第21天的時候,小心被人殺害。呵呵。

    當然,上面只是一個惡搞此類圖片,學習一門技術,需要你很長的時間,正如圖片中的第三圖和第四圖所示,你需要用十年的時間去不斷在嘗試,并在錯誤中總結經驗教訓,以及在項目開發中通過與別人相互溝通互相學習來歷練自己。你才能算得上是真正學會。

    這里有篇文章叫《Teach Yourself Programming in Ten Years》,網上有人翻譯了一下,不過原文已被更新了,我把網上的譯文轉載并更新如下:

    用十年來學編程
    Peter Norvig

    為什么每個人都急不可耐?

    走進任何一家書店,你會看見《Teach Yourself Java in 7 Days》(7天Java無師自通)的旁邊是一長排看不到盡頭的類似書籍,它們要教會你Visual Basic、Windows、Internet等等,而只需要幾天甚至幾小時。我在Amazon.com上進行了如下搜索
    pubdate: after 1992 and title: days and (title: learn or title: teach yourself)
    (出版日期:1992年后 and 書名:天 and (書名:學會 or 書名:無師自通))
    我一共得到了248個搜索結果。前面的78個是計算機書籍(第79個是《Learn Bengali in 30 days》,30天學會孟加拉語)。我把關鍵詞“days”換成“hours”,得到了非常相似的結果:這次有253本書,頭77本是計算機書籍,第78本是《Teach Yourself Grammar and Style in 24 Hours》(24小時學會文法和文體)。頭200本書中,有96%是計算機書籍。
    結論是,要么是人們非常急于學會計算機,要么就是不知道為什么計算機驚人地簡單,比任何東西都容易學會。沒有一本書是要在幾天里教會人們欣賞貝多芬或者量子物理學,甚至怎樣給狗打扮。在《How to Design Programs》這本書里說“Bad programming is easy. Idiots can learn it in 21 days, even if they are dummies.” (壞的程序是很容易的,就算他們是笨蛋白癡都可以在21天內學會。)
    讓我們來分析一下像《Learn C++ in Three Days》(3天學會C++)這樣的題目到底是什么意思:
    • 學會:在3天時間里,你不夠時間寫一些有意義的程序,并從它們的失敗與成功中學習。你不夠時間跟一些有經驗的程序員一起工作,你不會知道在C++那樣的環境中是什么滋味。簡而言之,沒有足夠的時間讓你學到很多東西。所以這些書談論的只是表面上的精通,而非深入的理解。如Alexander Pope(英國詩人、作家,1688-1744)所言,一知半解是危險的(a little learning is a dangerous thing)
    • C++:在3天時間里你可以學會C++的語法(如果你已經會一門類似的語言),但你無法學到多少如何運用這些語法。簡而言之,如果你是,比如說一個Basic程序員,你可以學會用C++語法寫出Basic風格的程序,但你學不到C++真正的優點(和缺點)。那關鍵在哪里?Alan Perlis(ACM第一任主席,圖靈獎得主,1922-1990)曾經說過:“如果一門語言不能影響你對編程的想法,那它就不值得去學”。另一種觀點是,有時候你不得不學一點C++(更可能是javascript和Flash Flex之類)的皮毛,因為你需要接觸現有的工具,用來完成特定的任務。但此時你不是在學習如何編程,你是在學習如何完成任務。
    • 3天:不幸的是,這是不夠的,正如下一節所言。

    10年學編程

    一些研究者(Bloom (1985)Bryan & Harter (1899)Hayes (1989)Simmon & Chase (1973))的研究表明,在許多領域,都需要大約10 年時間才能培養出專業技能,包括國際象棋、作曲、繪畫、鋼琴、游泳、網球,以及神經心理學和拓撲學的研究。似乎并不存在真正的捷徑:即使是莫扎特,他4 歲就顯露出音樂天才,在他寫出世界級的音樂之前仍然用了超過13年時間。再看另一種音樂類型的披頭士,他們似乎是在1964年的Ed Sullivan節目中突然冒頭的。但其實他們從1957年就開始表演了,即使他們很早就顯示出了巨大的吸引力,他們第一次真正的成功——Sgt. Peppers——也要到1967年才發行。Malcolm Gladwell 研究報告稱,把在伯林音樂學院學生一個班的學生按水平分成高中低,然后問他們對音樂練習花了多少工夫:

    在這三個小組中的每一個人基本上都是從相同的時間開始練習的(在五歲的時候)。在開始的幾年里,每個人都是每周練習2-3個小時。但是在八歲的時候,練習的強度開始顯現差異。在這個班中水平最牛的人開始比別人練習得更多——在九歲的時候每周練習6個小時,十二歲的時候,每周8個小時,十四歲的時候每周16個小時,并在成長過程中練習得越來越多,到20歲的時候,其每周練習可超過30個小時。到了20歲,這些優秀者在其生命中練習音樂總共超過 10,000 小時。與之對比,其它人只平均有8,000小時,而未來只能留校當老師的人僅僅是4,000 小時。

    所以,這也許需要10,000 小時,并不是十年,但這是一個magic number。Samuel Johnson(英國詩人)認為10 年還是不夠的:“任何領域的卓越成就都只能通過一生的努力來獲得;稍低一點的代價也換不來。”(Excellence in any department can be attained only by the labor of a lifetime; it is not to be purchased at a lesser price.) 喬叟(Chaucer,英國詩人,1340-1400)也抱怨說:“生命如此短暫,掌握技藝卻要如此長久。”(the lyf so short, the craft so long to lerne.)
    下面是我在編程這個行當里獲得成功的處方:
    • 對編程感興趣,因為樂趣而去編程。確定始終都能保持足夠的樂趣,以致你能夠將10年時間投入其中。
    • 跟其他程序員交談;閱讀其他程序。這比任何書籍或訓練課程都更重要。
    • 編程。最好的學習是從實踐中學習。用更加技術性的語言來講,“個體在特定領域最高水平的表現不是作為長期的經驗的結果而自動獲得的,但即使是非常富有經驗的個體也可以通過刻意的努力而提高其表現水平。”(p. 366),而且“最有效的學習要求為特定個體制定適當難度的任務,有意義的反饋,以及重復及改正錯誤的機會。”(p. 20-21)《Cognition in Practice: Mind, Mathematics, and Culture in Everyday Life》(在實踐中認知:心智、數學和日常生活的文化)是關于這個觀點的一本有趣的參考書。
    • 如果你愿意,在大學里花上4年時間(或者再花幾年讀研究生)。這能讓你獲得一些工作的入門資格,還能讓你對此領域有更深入的理解,但如果你不喜歡進學校,(作出一點犧牲)你在工作中也同樣能獲得類似的經驗。在任何情況下,單從書本上學習都是不夠的。“計算機科學的教育不會讓任何人成為內行的程序員,正如研究畫筆和顏料不會讓任何人成為內行的畫家”, Eric Raymond,《The New Hacker’s Dictionary》(新黑客字典)的作者如是說。我曾經雇用過的最優秀的程序員之一僅有高中學歷;但他創造出了許多偉大的軟件(XEmacsMozilla),甚至有討論他本人的新聞組,而且股票期權讓他達到我無法企及的富有程度(譯注:指Jamie Zawinski,Xemacs和Netscape的作者)。
    • 跟別的程序員一起完成項目。在一些項目中成為最好的程序員;在其他一些項目中當最差的一個。當你是最好的程序員時,你要測試自己領導項目的能力,并通過你的洞見鼓舞其他人。當你是最差的時候,你學習高手們在做些什么,以及他們不喜歡做什么(因為他們讓你幫他們做那些事)。
    • 接手別的程序員完成項目。用心理解別人編寫的程序。看看在沒有最初的程序員在場的時候理解和修改程序需要些什么。想一想怎樣設計你的程序才能讓別人接手維護你的程序時更容易一些。
    • 學會至少半打編程語言。包括一門支持類抽象(class abstraction)的語言(如Java或C++),一門支持函數抽象(functional abstraction)的語言(如Lisp或ML),一門支持句法抽象(syntactic abstraction)的語言(如Lisp),一門支持說明性規約(declarative specification)的語言(如Prolog或C++模版),一門支持協程(coroutine)的語言(如Icon或Scheme),以及一門支持并行處理(parallelism)的語言(如Sisal)。
    • 記住在“計算機科學”這個詞組里包含“計算機”這個詞。了解你的計算機執行一條指令要多長時間,從內存中取一個word要多長時間(包括緩存命中和未命中的情況),從磁盤上讀取連續的數據要多長時間,定位到磁盤上的新位置又要多長時間。(答案在這里
    • 嘗試參與到一項語言標準化工作中。可以是ANSI C++委員會,也可以是決定自己團隊的編碼風格到底采用2個空格的縮進還是4個。不論是哪一種,你都可以學到在這門語言中到底人們喜歡些什么,他們有多喜歡,甚至有可能稍微了解為什么他們會有這樣的感覺。
    • 擁有盡快從語言標準化工作中抽身的良好判斷力。

    抱著這些想法,我很懷疑從書上到底能學到多少東西。在我第一個孩子出生前,我讀完了所有“怎樣……”的書,卻仍然感到自己是個茫無頭緒的新手。30個月后,我第二個孩子出生的時候,我重新拿起那些書來復習了嗎?不。相反,我依靠我自己的經驗,結果比專家寫的幾千頁東西更有用更靠得住。

    Fred Brooks在他的短文《No Silver Bullets》(沒有銀彈)中確立了如何發現杰出的軟件設計者的三步規劃:

    • 盡早系統地識別出最好的設計者群體。
    • 指派一個事業上的導師負責有潛質的對象的發展,小心地幫他保持職業生涯的履歷。
    • 讓成長中的設計師們有機會互相影響,互相激勵。

    這實際上是假定了有些人本身就具有成為杰出設計師的必要潛質;要做的只是引導他們前進。Alan Perlis說得更簡潔:“每個人都可以被教授如何雕塑;而對米開朗基羅來說,能教給他的倒是怎樣能夠不去雕塑。杰出的程序員也一樣”。

    所以盡管去買那些Java書;你很可能會從中找到些用處。但你的生活,或者你作為程序員的真正的專業技術,并不會因此在24小時、24天甚至24個月內發生真正的變化。

    (全文完)




    posted @ 2012-08-06 12:56 Seraphi 閱讀(349) | 評論 (0)編輯 收藏
    主站蜘蛛池模板: 亚洲日韩在线中文字幕第一页| 免费视频一区二区| 亚洲AV无码XXX麻豆艾秋| 亚洲精品资源在线| 亚洲精品**中文毛片| 久久综合亚洲鲁鲁五月天| 亚洲色图校园春色| 亚洲日韩乱码久久久久久| 亚洲大香人伊一本线| 亚洲精品日韩专区silk| 亚洲国产精品综合久久2007| 亚洲国产精品成人综合色在线婷婷 | 亚洲av成人一区二区三区观看在线 | 免费日本黄色网址| 亚洲国产小视频精品久久久三级 | 中文字幕免费在线| 91麻豆最新在线人成免费观看| 97性无码区免费| 卡一卡二卡三在线入口免费| 日本久久久免费高清| 亚洲综合色在线观看亚洲| 亚洲日韩国产精品第一页一区| 亚洲va在线va天堂va四虎| 亚洲免费闲人蜜桃| 99亚洲乱人伦aⅴ精品| 国产成人无码精品久久久免费 | 人妻18毛片a级毛片免费看| 香蕉免费在线视频| 一区二区三区在线免费看| 国产福利在线免费| 四虎永久在线精品免费观看地址 | 1000部啪啪未满十八勿入免费| 无码人妻一区二区三区免费手机| 精品无码国产污污污免费| 亚洲国产成人精品无码久久久久久综合 | 99热在线免费观看| 免费无码又爽又刺激高潮| 亚洲天堂在线视频| 久久久久亚洲av无码专区导航| 国产亚洲中文日本不卡二区 | 亚洲日本在线观看|