...

Python入門 : 4日間コース社内トレーニング

by yuichi-ito

on

Report

Category:

Software

Download: 1

Comment: 0

56,395

views

Comments

Description

Download Python入門 : 4日間コース社内トレーニング

Transcript

  • Python  入門   Cisco  Systems,  Japan  TAC   伊藤  裕一  (twi7er:  @yuichi110)  
  • 本スライドは  Cisco  Japan  社内で開催した  TAC  (トラブル シューティングを専門とするネットワークエンジニア)  向 けの python  トレーニングを一部修正したものです。   演習込みで 4時間  x  4日 で開催しています  
  • トレーニングの目的   •  Python  を使えるようになる   •  プログラミングの概念を理解   •  ソースコード(diffなど)を読む   •  SDN関連のSRをさばく   •  pythonで解析ツールを作ってチームに貢献   3  Python  入門  
  • トレーニングの対象者   •  WindowsなりMacなりを使いこなせるユーザ   •  プログラミングに興味がある   •  トレーニングの時間  +  自習時間を持てる   •  ネットワークエンジニア   4  Python  入門  
  • 補足   トレーニングの内容は        Alan  Gauld  さんの  Learning  to  proguram  ver  2   を参照して作成。     Python  入門   5   Learning  to  Program   h7p://www.alan-­‐g.me.uk/   また、O’REILLY  の「初めてのPython」も参照して います。  
  • プログラミングとは   Python  入門   6  
  • プログラミングとは   •  電子機器を「自分が意図する通り」に動かす手段   •  制御文で処理の流れを決める   •  各処理は連続した命令で成り立つ   7  Python  入門  
  • Ping  の挙動   •  ICMP  echo  を cisco.com  に3回送信し、その   reply  が届いた割合とRTTを算出   Python  入門   8   yuichi$  ping  -­‐c  3  cisco.com   PING  cisco.com  (72.163.4.161):  56  data  bytes   64  bytes  from  72.163.4.161:  icmp_seq=0  7l=238  cme=149.949  ms   64  bytes  from  72.163.4.161:  icmp_seq=1  7l=238  cme=149.783  ms   64  bytes  from  72.163.4.161:  icmp_seq=2  7l=238  cme=149.826  ms     -­‐-­‐-­‐  cisco.com  ping  stacsccs  -­‐-­‐-­‐   3  packets  transmi4ed,  3  packets  received,  0.0%  packet  loss   round-­‐trip  min/avg/max/stddev  =  149.783/149.853/149.949/0.070  ms  
  • Pingの実装   (1)宛先アドレスを入力(cisco.com)   (2)宛先に向けて  ICMP  echo  request  を打つ   (3)結果を表示    -­‐  ICMP  echo  reply  がかえってきた場合            到着時刻  -­‐  送信時刻 の  RTT  を表示   -­‐  ICMP  echo  reply  が帰ってこなかった場合            lost  したことを表示   (4)  (2)-­‐(3)  をあと2回繰り返す   (5)3回のICMPの結果を集計し、表示   S   D 1回目表示   2回目表示   3回目表示   3回の結果を表示   9  Python  入門   echo  request   echo  reply   PC   サーバ   ping  の実装  
  • プログラムを組むということ   •  コードによる建築作業   •  簡単なモノなら少ない知識で作れる   •  巨大なモノは高度な専門知識が必要   Python  入門   10   とりあえずの目標地点  
  • PYTHON   Python  入門   11  
  • プログラミング言語   •  プログラムを記述するための言語   •  コンピュータ(機械語)と人間(自然言語)の仲介言語   •  いくつかの種類がある   12  Python  入門   00100101001101010  print('hello  world')  'hello  world'を表示させる   プログラミング言語  人がやりたいこと   機会が解釈可能な命令  
  • なぜ Python  ?     •  文法がシンプルで初心者向け   •  パワフルな言語   •  オブジェクト型指向言語   13  Python  入門  
  • Python  以外の選択肢   •  C:  ハードに近い概念を意識する必要がある                    OSに近いことをしないと開発が非効率   •  Java:  良い言語だが、覚えることが多い                              Python  のほうが簡単   •  その他Script系言語:  cisco機器が非サポート   •  Web系言語:  cisco  で重要度が低い   •  その他:  中級者-­‐>  上級者 になりたい人向け   14  Python  入門  
  • C,  Java,  Python  の比較   •  現在のディレクトリ以下の構造を書き出すプログラム   Python  入門   15   [/Users/yuichi/Documents/_TRAINING]   CCIE   Java   listFile.py   python   [/Users/yuichi/Documents/_TRAINING/CCIE]   ccie-­‐lab.key   [/Users/yuichi/Documents/_TRAINING/Java]   Java  Basic  Training  Day  2.pptx   Java  Basic  Training  Day  3.pptx   Java  Basic  Training  Day  4.pptx   Java  Basic  Training  Day1.pptx   [/Users/yuichi/Documents/_TRAINING/python]   adfunc.py   dict-­‐test.py   excepcon.py   func.py   _TRAINING   CCIE   Java   Python   ccie-­‐lab.key   Java  Basic  Training  Day2   .....   adfunc.py   .....   lismile.py   プログラムの出力  
  • C  言語での例   Python  入門   16  
  • Javaでの例   Python  入門   17  
  • Python  での例   Python  入門   18   IDLE  
  • 比較結果   Python  入門   19   •  Python  は簡単にプログラムが書ける  
  • Python  入門   20  
  • Agenda   •  Day1:  インストール、基本文法、データ型   •  Day2:  続データ型、モジュールと関数   •  Day3:  オブジェクト指向、アルゴリズム   •  Day4:  正規表現、エラー処理、データベース   21  Python  入門  
  • Agenda  Day  1   •  Python  のインストール   •  プロンプトとIDLEの使い方   •  型と変数   •  条件分岐   •  ループ   •  標準入力   •  関数とモジュールの利用   •  演習   22  Python  入門  
  • PYTHON  のインストール   Python  入門   23  
  • Python  Installacon   •  Macはターミナルで最初から使える   •  開発環境を作るためにバイナリからインストール   •  バージョンは  2.7  系の最新版   Python  公式ページ   24  Python  入門  
  • Python  のバージョン   •  Version  3.3.x:  最新版のバージョン   •  Version  2.7.x:  まだまだ主流のバージョン   •  Cisco:  2.7.x  を利用   25  Python  入門  
  • Windows  へのインストール   Python  入門   26  
  • Mac  へのインストール   Python  入門   27  
  • PROMPT  と  IDLE  の利用   Python  入門   28  
  • Prompt  で  python  を呼び出す   •  Windows:  Start  -­‐>  python2.7  (command  line)   •  Mac:  terminal  で  python2.7  と打つ   Python  入門   29  
  • Prompt  で  python  を呼び出す   •  Windows:  Start  -­‐>  python2.7  (command  line)   •  Mac:  terminal  で  python2.7  と打つ   Python  入門   30  
  • Prompt  の利用   •  Prompt  で以下のようなコマンドを発行してみる   Python  入門   31   print('hello  world')     6+1*3   (6+1)*3     5/2   5/2.0   5/0   print("{}  +  {}  =  {}".format(2,3,5))     print  """hello   I  love  Cisco   I  love  Python  too   """     import  sys   sys.exit()  
  • コマンドで  script  ファイルを実行   •  ファイルに処理を記述し、それをコマンドで実行   •  Python  のスクリプトファイルは拡張子が  .py   •  Windows  は必要あればpython  をパス指定する   Python  入門   32   print  “hello  Cisco”   print  “hello  Python”   print  “done!”   test.py   Mac  の実行画面   $  python  ファイル名  
  • コマンドで  script  ファイルを実行   •  ファイルに処理を記述し、それをコマンド実行   •  Python  のスクリプトファイルは拡張子が  .py   •  Windows  は必要あればpython  をパス指定する   Python  入門   33   ※  時間のあるときにパスの設定を加えておくと楽   Windows  の実行画面  
  • IDLE   •  このトレーニングのメインの開発環境   •  Windows:  startup  -­‐>  python  -­‐>  idle   •  Mac:  applicacon  -­‐>  python  -­‐>  idle   Python  入門   34   IDLE   プロンプト画面  
  • IDLE  の利用   •  IDLE  のエディタを使った開発   •  メニューより先ほど作った test.py  を開く   •  エディタ画面を選択し、F5  を押すと実行   Python  入門   35  
  • コメントアウト   •  コメント:  プログラムの注釈。処理系に無視される   •  一行のコメントアウト:  #  コメント文   •  複数業のコメントアウト:  """  複数行指定可能  """   Python  入門   36  
  • 型と変数   Python  入門   37  
  • 型   •  データには型(種類)がある   •  整数型(Integer):  1,5,-­‐1   •  文字列型(String):  "Cisco",  "Python"   Python  入門   38  
  • 型と制御   •  型とプログラムの制御には密接な関係がある   – 文字列を数字で割ることはできない   – 文字列と数字を結合できない   •  よくある処理は手続き方法を覚える   – 文字列と数字の結合は、数字を文字列に変換し てから結合する   Python  入門   39  
  • 変数   •  変数:  Dataを保存する容器   Python  入門   40   5   print(5)        =>  5     x  =  5       print(x)        =>  5   5   変数  X   データ(定数  5)   代入   print  (                                )  5   print  (                                )  5  
  • 変数と型   •  型宣言:  この変数はこの型を格納するという宣言   •  Python  の変数には型宣言がない   •  変数にどのような型でもいれられる   Python  入門   41   int  x  =  5;   x  =  "Java"  //Error   x  =  5;   print(x)     x  =  "Python"  #  OK     print(x)  Java   Python  
  • Python  の型   •  組み込み型   – 数字:  int,  float  など   – 文字列:  英語、日本語   – リスト:  配列に似ている   – Bool:  True  or  False   – 関数:  Python  では関数も型の一つ   – その他   •  ユーザが定義した型(Class)   Python  入門   42  
  • 数字   •  整数(int)と実数(float)、複素数がある   •  上限は気にしなくてよい   Python  入門   43   使える演算子   説明   M  +  N   足し算   M  –  N   引き算   M  *  N   かけ算   M  /  N   割り算   M  %  N   剰余(あまり)   M**N   べき乗  (M  *  M  *  M  …  をN回)     >>>  1234567  *  3456789   4267637625363    (42兆)  
  • 数字   •  インクリメントは使えない   •  代入演算子で代用   Python  入門   44   演算子   説明   M  +=  N   M  =  M  +  N   M  -­‐=  N   M  =  M  –  N   M  *=  N   M  =  M  *  N   M  /=  N   M  =  M  /  N   M  %=  N   M  =  M  %  N   Java      int  i  =  0      i++   Python      i  =  0      i  +=  1    ß  i  =  i+1  
  • 文字列型   •  3種類の記述方式   Python  入門   45   シングルクオテーション   string  =  ‘  Hello  Python’     ダブルクオテーション   string  =  “Hello  Python”     トリプル・ダブルクオテーション   string  =  “””Hello  World   Hello  Python  #  this  isn’t  comment   Hello  CIsco”””   改行や特殊記号も   そのまま文字列に。  
  • 文字列型   •  文字列も演算記号を使える   Python  入門   46   print  “I  love  “  +  “python”      =>  “I  love  Python”     print  “hello  “  *  3      =>  “hello  hello  hello  “     print  “I  say  “  +  (“hello  “  *  3)    =>  “I  say  hello  hello  hello”   x  =  “I  love  “   y  =  “Python”   print(x+y)    =>  "I  love  Python"    
  • Bool型   •  いわゆる  True,  False  を持つ型   •  If  文などの制御分でよく利用される   Python  入門   47   演算子   意味   A  and  B   A  も  B  も  True  なら  True   A  or  B   A  か  B  が  True  なら  True   A  ==  B   A  と  B  が同じなら  True   A  !=  B   A  と  B  が違えば  True   A    B   同上   not  A   A  が  False  なら  True  
  • Bool型   •  いわゆる  True,  False  を持つ型   •  If  文などの制御分でよく利用される   Python  入門   48   演算子   意味   A  >  B   A  が  B  より大きければ  True   A  >=  B   A  が  B  以上なら  True   A  <  B   A  が  B  より小さければ  True   A  
  • List型   •  拡張ができる配列  [x,y,z]  という形式で作成   •  演算子  [x]  で、配列の  x  番目にアクセスする   •  何番目か(index)の指定は0から数える   Python  入門   49   list1  =  [3,4,5]   print(list1)      =>  [3,  4,  5]     list2  =  [“I”,  “Love”,  “Python”]   print(list2[2])      =>  “Python”   list3  =  [[1,2],  ['A',”B”]]   print(list3)      =>  [[1,  2],  [“A”,  “B”]]   print(list3[1][1])      =>  “B”   print(list3[5][0])      =>  #  index  out  of  range  の                        Error  表示  
  • List型   •  配列長を取得:  len(X)   •  オブジェクトの  index  を取得:  index(X)   •  配列にオブジェクトを追加:  append(x)   •  配列からオブジェクトを削除:  del   Python  入門   50   list1  =  [1,2,3,4,5]   print(list1.index(3))      =>  2     print(len(list1))      =>  5   list1.append(6)   print(list)      =>  [1,2,3,4,5,6]     del  list2[1]   print(list2)      =>  [1,3,4,5,6]  
  • その他の型(後日)   •  Tuple   •  Dicconary   •  File   •  Dates,  Times   •  ユーザ定義の型(クラス)   •  関数   Python  入門   51  
  • 演習1   Python  入門   52  
  • 演習  (演算)   •  以下の図形の面積をプログラムで計算してくださ い   •  余裕があれば、import  以外は一行(ワンライナ ー)としてください   Python  入門   53   4cm   3cm   10cm   5cm   2cm   8cm   半径   2cm   ※  円周率は  math  module  の  π  を              使ってください   >>>  import  math   >>>  math.pi   3.141592653589793  
  • 演習  (ドキュメント)   •  数字  1984  と文字列  “cisco”  を文字列結合し、表 示してください  (そのまま結合するとエラーになる ので、数字を文字列に変換する必要あり)   •  ググるのではなく、以下のページから必要な「組 み込み関数」を探してください Python  入門   54   Python  標準ライブラリ h7p://docs.python.jp/2/library/index.html   (英)  h7p://docs.python.org/2.7/library/index.html#python    
  • 制御構造   Python  入門   55  
  • 制御構造   •  簡単なバッチ処理:  上から下に一行ずつ実行していく   •  プログラミング   –  上から下に実行していく   –  決められた文法と単語(予約語)で処理方法を記述   –  if文、loop文などでプログラムの流れを制御する   –  クラスや関数などを使って処理をまとめる   Python  入門   56  
  • プログラムの処理の流れ   •  プログラムの基本的な流れは上から下へ   Python  入門   57   Step1   Step2   Step3  
  • 予約語   •  空白で区切られた単語の連続でプログラムを記述する   •  予約語:  プログラムの制御のための「特別」な単語   •  予約語以外:  定数、変数、関数、クラス名など自由につ けられる名前   Python  入門   58   プログラムの制御      if,  for,  while   宣言      class,  def   予約語の例  
  • コードブロックとインデント   •  C,Javaなど:  {}  という記号で処理をまとめる   •  Python:  インデント(字下げ)で処理をまとめる   Python  入門   59   for(int  i=0;  i
  • 条件分岐   Python  入門   60  
  • 条件分岐  IF   •  特定の条件を満たす場合のみ処理を行う     Python  入門   61   Step1   Test   Condicon   Path2  Path1  
  • 条件分岐  IF   •  特定の条件を満たす場合のみ処理を行う     Python  入門   62   if(条件A):          条件AがTrueなら実行          ….   elif(条件B):          条件AがFalseかつ条件BがTrueなら実行          ….   else:          条件AもBもFalseなら実行          ….     if  の条件分岐の結果に関わらず実行   ….  
  • 条件分岐  IF   •  Python  のコード     Python  入門   63   i  =  5   if  (i  >  10):          print  “This  is  never  printed”   else:          print  “This  might  be  printed”  
  • (補足)条件分岐  SWITCH-­‐CASE   •  実装されていない。If文で作る   Python  入門   64   switch(条件){          case  A:  条件がAの場合の処理                                      break;          case  B:  条件がBの場合の処理                                      break          default:  それ以外の場合の処理   }   if(条件  ==  A):          条件がAの場合の処理   elif(条件  ==  B):          条件がBの場合の処理   else:          それ以外の場合の処理   Java   Python  
  • ループ処理   Python  入門   65  
  • ループ処理  for   •  特定の処理を決められた回数こなす   •  Pythonではリストの走査に使用     Python  入門   66   Repeated  Steps   Test   Condicon  
  • リストとfor   •  CやJavaなどのforとは別物   •  CやJavaと同じような使い方もできる   Python  入門   67   A   B   C   D  リスト   (1)  Aを使って処理を実行   (2)  Bを使って処理を実行   (3)  Cを使って処理を実行   (4)  Dを使って処理を実行  
  • for文の書式   Python  入門   68   for  変数  in  リスト:          実行する処理   リストの0番目を変数に代入して処理を実行   リストの1番目を変数に代入して処理を実行   .....   string  =  ""   for  char  in  ["H","e","l","l","o"]:          string  +=  char   print(string)   >>>     Hello  
  • forによる一定回数の処理   •  一定回数の処理には  range  関数を併用   •  range(x):  0  から  x-­‐1  までの連番のリストを返す   •  range(x,y):  x  から  y-­‐1  までの連番のリストを返す   Python  入門   69   for(int  i=0;  i
  • (補足)イテレータ   •  python  の for  は  iterator  と呼ばれる仕組み   •  タプルや、文字列、辞書なども  key  として使える   Python  入門   70   for  char  in  "hello":            print(char)      =>   h   e   l   l   o  
  • ループ処理  while   •  特定条件を満たすまでループを繰り返す   •  「〜  の間はずっとループ」というようなイメージ   •  For  ほどは使われない   Python  入門   71  
  • while  に適したループ処理   •  何周すればいいか分からない処理に使う   •  無限ループにならないように注意が必要   Python  入門   72   x  =  6789329   i  =  1   while(2**i  <  x):          i  +=  1     print("2  ^  {}  >  {}".format(i,x))   与えられた数を2進数で表現するのに必要な桁数を求める   2  ^  23  >  6789329  
  • 演習2   Python  入門   73  
  • 演習  (条件分岐)   •  1  –  100  までの偶数の値を持つ  List  を作成する   •  1  –  10000  までの素数を表示する。       素数:  1と自分以外の整数で割れない整数   •  Fizz  buzz  を  100  まで行う                        1-­‐100までを表示。                                3で割り切れる時は  fizz,  5で割り切れる時は  buzz  と表示                                3でも5でも割り切れる時は  fizz  buzz  と表示する   Python  入門   74  
  • 関数とモジュールの利用   Python  入門   75  
  • 関数の呼び出し   •  特定の処理を行うための呼び出し口   •  関数名に引数を与えて呼び出す   •  関数は返り値を返す   Python  入門   76   関数名(引数)   返り値   >>>  length  =  len([1,2,3,4,5])   >>>  print(length)   5  
  • 関数で複雑な処理を隠す   •  関数を使うことでコードがわかりやすくなる   Python  入門   77   i  =  -­‐5     if(i  5   ぱっと見、何をやって   いるか分からない   i  =  -­‐5     i  =  abs(i)     print  i        =>  5   関数名ですぐ「絶対数を   得るプログラム」とわかる  
  • 関数でコードの重複を減らす   •  コードの重複をなくし、保守性を向上させる   Python  入門   78   i  =  -­‐5   j  =  8     If(i  8   i  =  -­‐5   j  =  8     関数  abs  の定義     print(abs(i))        =>  5   print(abs(j))      =>  8  
  • モジュール   •  モジュールはプログラムの整理整頓手法   Python  入門   79   vs   モジュールがない   モジュールを利用  
  • モジュールによる階層化   •  機能ごとによるプログラムの整理   Python  入門   80   math   file   system   os   自分が作成   組み込み   (デフォルトで   使える)  
  • モジュールへのアクセス   •  モジュールを利用するには  import  する必要がある   Python  入門   81   >>>  random()   Traceback  (most  recent  call  last):     File  “”,  line  1,  in                                       NameError:  name  'random'  is  not  defined       >>>  import  random                                       >>>  random.random()                             0.6019003331149728                               import  していないと   利用できずにエラー   「モジュール名.関数」   でモジュールの関数を利用  
  • 関数とモジュールの作成   •  作成の仕方などについては  day2  で扱う   Python  入門   82  
  • 標準入力   Python  入門   83  
  • 標準入力   •  ユーザからの入力を受け取る   Python  入門   84   input  =  raw_input()        ユーザからの入力を待つ   print(input)        =>  “hello”   “hello”  と入力される   入力待ちが解除される  
  • 標準入力   •  無限  echo  プログラム   Python  入門   85   while(True):        print  “please  input:”        input  =  raw_input()        print  input   ※ Ctr-­‐C  で抜ける  
  • コマンドライン引数   Python  入門   86  
  • コマンドライン引数   •  スクリプトを「パラメータ」つきで起動する   •  スクリプト内に直接書き込むより融通性がある   Python  入門   87   pingのプログラム   (1)  宛先を引数で受け取る   (1)  宛先へ icmp  echo  request  を送る   (2)  宛先から icmp  echo  reply  を受け取る   (3)  受信結果を表示   ping.py   cisco.com   python.org   #python  ping.py  cisco.com   #python  ping.py  python.org  
  • sys.argv   •  コマンドライン引数にアクセスするには  sys  モジュー ルを  import  する   •  引数がargvにリストとして格納されている   Python  入門   88   import  sys     print("-­‐-­‐-­‐-­‐  args  -­‐-­‐-­‐-­‐")   print(len(sys.argv))   print(sys.argv[0])   print(sys.argv[1])   print(sys.argv[2])   print("-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐")     a  =  int(sys.argv[1])   b  =  int(sys.argv[2])   print("{}  +  {}  =  {}".format(a,b,a+b))   $  python  test.py  1  5   -­‐-­‐-­‐-­‐  args  -­‐-­‐-­‐-­‐   3   test.py   1   5   -­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐   1  +  5  =  6   test.py   出力  
  • 演習3   Python  入門   89  
  • 演習(標準入力)   •  ユーザが入力した文字列の文字数を表示す るプログラムを作成   •  入力は何度でも受け付けるが、文字列  exit  を 受け取ると終了すること   Python  入門   90  
  • 次回予告   •  関数を作る   •  高度な型を使う   •  ファイル処理   Python  入門   91   •  できるようになること   – テキスト処理によるログの解析   – OSを操作するためのシェルスクリプトの作成  
  • Python  入門   92  
  • Python  入門   Learning  to  Program     For  Cisco  Network  Engineers   Day  2/4     Japan  TAC  DC  Team.   Yuichi  Ito  
  • Agenda  Day  2   •  Python   •  続データ型   •  関数の作成   •  モジュールの作成   •  演習1(Map)   •  文字列処理   •  ファイル処理   •  OSコマンドの利用   •  演習2(ログ解析、Linuxのスクリプト)   94  Python  入門  
  • PYTHONの歴史   Python  入門   95  
  • Python   •  登場時期:  1990年   •  設計者:  グイド・ヴァンロッサム   •  型付け:  強い動的型付け   Python  入門   96   •  1.x:  1994年   •  2.x:  2000年。メジャー言語化   •  3.x:  2008年。後方互換性なし  
  • 続データ型   Python  入門   97  
  • Python  の型   •  ユーザ定義の型(Class)   •  組み込み型(pythonが提供)     Python  入門   98   数値型    -­‐  整数    -­‐  長製数    -­‐  浮動小数点    -­‐  複素数     シーケンス型    -­‐  文字列    -­‐  リスト    -­‐  タプル    -­‐  xrange型   マップ型    -­‐  辞書     ファイル型      -­‐  ファイルオブジェクト  
  • 用語   •  オブジェクト   •  インデックス   •  エレメント   •  リテラル   •  代入   •  引数   •  返り値   Python  入門   99  
  • 辞書型   •  Key  と  Value  のペアを保持するデータ型   •  KeyからValueを取得する   Python  入門   100   Apple  :  Red   Lemon  :  Yellow   Grape  :  Purple   Dicconary   Appleの色は?   Red  !!   X  :  Y   追加   取得  
  • 辞書の操作   •  辞書の形式:  {key1:value1,  key2:value2}   •  値の取得:  辞書オブジェクト[key]   •  値の追加(更新):  辞書オブジェクト[key]  =  value   •  値の削除:  del  辞書オブジェクト[key]   •  key一覧の取得:  辞書オブジェクト.keys()   •  keyを持っているか:  辞書オブジェクト.has_key(key)   Python  入門   101  
  • 辞書型の操作   #  辞書オブジェクトを作成   >>>  d  =  {"Apple":"Red",  "Lemon":"Yellow"}   #  key  から  Value  を取得   >>>  d["Apple"]   'Red'   #  辞書オブジェクトに要素を追加   >>>  d["Grape"]  =  "Purple"   >>>  d   {'Grape':  'Purple',  'Lemon':  'Yellow',  'Apple':  'Red'}   #  辞書オブジェクトの要素を削除   >>>  del  d["Apple"]   >>>  d   {'Grape':  'Purple',  'Lemon':  'Yellow'}   Python  入門   102  
  • 辞書とリストの違い   •  リスト型は線形にデータ保持   •  辞書型はハッシュを利用してデータ保持   •  要素数が増えた場合の検索が高速   Python  入門   103   ハッシュの仕組み  
  • 辞書型のサンプル   •  Arp  Table  を  List  と 辞書で実装(クラスなし)   Python  入門   104   ipList  =  []   macList  =  []     def  registerMAC1(ip,  mac):          if  ip  in  ipList:                  index  =  ipList.index(ip)                  macList[index]  =  mac          else:                  ipList.append(ip)                  macList.append(mac)     def  getMAC1(ip):          if  ip  in  ipList:                  index  =  ipList.index(ip)                  return  macList[index]          else:                  return  None   arpTable  =  {}     def  registerMAC2(ip,  mac):          arpTable[ip]  =  mac     def  getMAC2(ip):          return  arpTable.get(ip)   Listによる実装:  探索コスト  Order(N)   辞書による実装:  探索コスト  Order(1)   Listによる実装   辞書による実装  
  • セット   •  重複、順序のない複数のデータを保持する型   •  Value  のない  Map  に近い   Python  入門   105   >>>  a  =  set([1,2,3,4,5,3,2])   >>>  print(a)   set([1,  2,  3,  4,  5])   >>>  a  =  set("hello")   >>>  b  =  set("world")     >>>  print(a)   set(['h',  'e',  'l',  'o'])   >>>  print(b)   set(['d',  'r',  'o',  'w',  'l'])   >>>  print(a  &  b)   set(['l',  'o'])  
  • セットの操作   •  初期化:  set(シーケンス型のオブジェクト)   •  追加:  setオブジェクト.add(value)   •  削除:  setオブジェクト.discard(value)   Python  入門   106  
  • タプル型   •  不可変なデータ構造   •  要素の数が決まった「一組のデータ」   Python  入門   107   Link  down   OSPF  Neighbor  XXX  down   Admin  up   Link  up   OSPF  Neighbor  XXX  up   ....   #  show  logging   行数(要素数)は伸びる      =>  List型   社員情報   Yuichi   Ito   2011-­‐04-­‐01   Tokyo   TAC   行数(要素数)は伸びない   順不同      =>  Tuple  型  
  • タプル型の操作   •  Tuple  の作成:  tupleObject  =  (elem1,  elem2,...)   •  要素の取得:  item  =  tupleObject[index]   •  複数の要素の取得:     •  要素の更新:  できない   Python  入門   108  
  • タプル型の操作   #  Tuple  の作成   >>>  yuiito  =  ("Yuichi",  "Ito",  2011)   >>>  yuiito   ('Yuichi',  'Ito',  2011)   #  要素の参照   >>>  yuiito[1]   'Ito'   >>>  yuiito  =  ("Yuichi",  "Ito",  2011)   >>>  (name,  famName,  year)  =  yuiito   >>>  year   2011   #  要素の更新   >>>  yuiito[2]  =  2009   Traceback  (most  recent  call  last):      File  "",  line  1,  in     TypeError:  'tuple'  object  does  not  support  item  assignment   Python  入門   109  
  • タプル型サンプル   •  データ構造を作成可能(クラスの簡易版)   •  不可変なオブジェクト   Python  入門   110   def  getMinMax(numList):          minNum  =  numList[0]          maxNum  =  numList[0]                    for  n  in  numList:                  if  n  <  minNum:                          minNum  =  n                  if  n  >  maxNum:                          maxNum  =  n            return  (minNum,  maxNum)  
  • None   •  何もないことを明示するための特殊な型   •  C,  Java  の  NULL  とは違うが、ほぼ同じ   Python  入門   111  
  • 関数の概念   Python  入門   112  
  • 関数   •  特定の処理を行う受付窓口   •  細かい処理を隠蔽   Python  入門   113   成果物(パン)  プログラム(パンの作成関数)   あんぱん   カレーパン  
  • あんぱんの製造工程   Python  入門   114   こねる     材料を用意   粉などをまぜる   こねる   発酵       生地を整形   放置   あんぱんの形作り     生地を適量とる   餡をいれる   丸める   焼く     オーブンを温める   パンをいれる   一定時間待つ   取り出す  
  • カレーパンの製造工程   Python  入門   115   こねる     材料を用意   粉などをまぜる   こねる   発酵     生地を整形   放置   カレーパンの形作り     生地を適量とる   カレーをいれる   丸める   揚げる     油を温める   パンをいれる   一定時間待つ   取り出す  
  • 関数を使わないベタ書き   •  処理の区切りが分かりづらく、重複が多い   Python  入門   116   材料を用意   粉を混ぜる   こねる   生地を整形   放置   生地を適量とる   餡を入れる   整形   オーブンを温める   パンをいれる   一定時間待つ   取り出す   AnPan.py   材料を用意   粉を混ぜる   こねる   生地を整形   放置   生地を適量とる   カレーを入れる   整形   油を温める   パンをいれる   一定時間待つ   取り出す   CurryPan.py  
  • 関数による処理単位の整理   Python  入門   117   こねる   発酵   あんぱん形作り   焼く   カレーパン形作り   揚げる   重複の排除  
  • 関数によるコードの整理   Python  入門   118   関数:  こねる          材料を用意          粉を混ぜる          こねる     関数:  発酵          生地を整形          放置     関数:  あんぱん形作り          生地を適量とる          餡を入れる          整形     関数:  焼く          オーブンを温める          パンをいれる          一定時間待つ          取り出す       Pan.py  (つづき)     関数:  makeあんぱん          こねる          発酵          あんぱん形作り          焼く     関数:makeカレーパン          こねる          発酵          カレーパン形作り          揚げる     …..   Pan.py  
  • 関数名   •  関数を区別するための名前   •  組み込み関数と被らないように注意が必要   Python  入門   119  
  • 引数   •  関数を呼び出す際に関数に与える値   •  仮引数(関数の定義側で受け取る変数)   •  実引数(関数の呼び出し側で与える値)   Python  入門   120   def  関数名(仮引数)          関数内の処理   関数名(実引数)   定義   呼び出し  
  • 返り値   •  関数で処理されたデータを呼び出し元に返す   •  返り値がない場合もある(副作用のみの関数)   Python  入門   121   length  =  len([1,2,3,4,5])   len([1,2,3,4,5])  length   5   返り値  
  • 関数の実装   Python  入門   122  
  • 関数作成の書式1   •  引数、返り値なしの書式   •  返り値を明示しない場合は  None  が返る   Python  入門   123   def  関数名():        処理   def  printHello():          print("hello")             printHello()        =>  hello  
  • 関数作成の書式2   •  引数、返り値あり   •  引数は関数名の後の()に必要な数だけ指定   •  返り値は  return  で明示的に書く   Python  入門   124   def  関数名(引数):        処理        return  返り値   def  adder(a,  b):          return  a  +  b     print(adder(3,4))      =>  7  
  • 関数のサンプル   def  power(x):          return  x*x     def  absolute(x):          if(x  36   print(absolute(-­‐5))    -­‐>  5   Python  入門   125  
  • 引数のデフォルト値   •  指定しない場合に設定される引数   Python  入門   126   def  func(a,  b=1)          print(a)          print(b)       func(5,6)      -­‐>  5                6   func(5)      -­‐>  5                5  
  • global   •  関数内でグローバル変数にアクセスするための宣言   Python  入門   127   gv  =  0     def  func1():          gv  =  1     def  func2():          global  gv          gv  =  2   print(gv)      -­‐>  0     func1()   print(gv)      -­‐>  0     func2()   print(gv)      -­‐>  2  
  • 演習1   Python  入門   128  
  • 演習   •  day2-­‐1.py.zip  をダウンロードし解凍   •  text  =  """〜"""  として事前定義されている文字列の 単語出現数をカウントするプログラムを作成   •  「単語:出現数」というフォーマットで出力する   •  文字列の分割:  文字列.split()  -­‐>  [単語の配列]   Python  入門   129   dog:1   cat:2   ...   •  出現数が多い単語順にソートして表示する   •  ヒントは次ページ   発展編  
  • 演習補足   •  リストを使った簡易ソートアルゴリズム   •  sort関数を使っても実装可能だが、まだ教えてない テクニックが必要   Python  入門   130   list1  =  [3,6,2,9,0,1,5]   list2  =  []   while(0  !=  len(list1)):          maxValue  =  max(list1)          index  =  list1.index(maxValue)          list2.append(maxValue)          del  list1[index]     print(list2)      -­‐>  [9,  6,  5,  3,  2,  1,  0]  
  • モジュール   Python  入門   131  
  • モジュールの必要性   •  モジュール   •  ユーザ作成モジュール:  1つのpythonファイル   Python  入門   132  
  • モジュールへのアクセス   •  機能ごとによるプログラムの整理   Python  入門   133   math   file   system   os   自分が作成   組み込み   (デフォルトで   使える)  
  • ユーザによるモジュールの作成   Python  入門   134   ファイル  200行   ファイル  50000行   •  プログラムの開発によりコードが巨大に。  
  • モジュールの分割   •  巨大なファイルは「どこに何があるか」わかりにくい   •  適切な粒度でファイルを分割する   Python  入門   135   010101010101010101010101 010101010010101010101010 101010101010101010010101 010101010101010101010101 010010101010101010101010 101010101010010101010101 010101010101010101010010 101010101010101010101010 101010010101010101010101 010101010101010010101010   010101010 101010101 010101010 101010010 101010101   010101010 101010101 010101010 101010010 101010101   010101010 101010101 010101010 101010010 101010101   010101010 101010101 010101010 101010010 101010101   巨大なファイル   複数の小さなファイル  
  • モジュールの参照   Python  入門   136   010101010 101010101 010101010 101010010 101010101   010101010 101010101 010101010 101010010 101010101   010101010 101010101 010101010 101010010 101010101   010101010 101010101 010101010 101010010 101010101   010101010 101010101 010101010 101010010 101010101 010101010 101010101   モジュールを使うプログラム   全体の流れを記述   モジュールを使うプログラム   全体の流れを記述  
  • import   •  import  することでモジュールが使える   Python  入門   137   import  mymath     print(mymath.add(2,3))      #  -­‐>  5   print(mymath.minus(2,3))  #  -­‐>  -­‐1   print(mymath.mulcply(2,3))  #  -­‐>  6   print(divide(2,3))  #ERROR  HAPPEN     Traceback  (most  recent  call  last):      File  "~/main.py",  line  6,  in            print(divide(2,3))   NameError:  name  'divide'  is  not  defined     def  add(a,b):          return  a  +  b     def  minus(a,  b):          return  a  -­‐  b     def  mulcply(a,  b):          return  a  *  b     def  divide(a,  b):          return  a  /  b    
  • from   •  from  ファイル名(パッケージ名)  import  *  でファイル名 の指定なしに呼び出しが可能になる   Python  入門   138   def  add(a,b):          return  a  +  b     def  minus(a,  b):          return  a  -­‐  b     def  mulcply(a,  b):          return  a  *  b     def  divide(a,  b):          return  a  /  b     from  mymath  import  *     print(add(2,3))  #  -­‐>  5   print(minus(2,3))  #  -­‐>  -­‐1   print(mulcply(2,3))  #  -­‐>  6   print(mymath.divide(2,3))  #  ERROR  HAPPEN     Traceback  (most  recent  call  last):      File  "~/main.py",  line  6,  in            print(divide(2,3))   NameError:  name  'mymath'  is  not  defined  
  • (補足)  循環参照   •  ファイルAとBが互いに参照しあっている   •  望ましくなく、エラーになる場合がある   Python  入門   139   import  file2     print("file1")   import  file1     print("file2")   file1.py   $  python  file1.py   file1   file2   file1   file2.py   なんで2回?  
  • 文字列   Python  入門   140  
  • 文字列の処理1   •  文字列の作成:  str1="文字列",  str2='  文字列'   •  文字列の結合:  文字列  +  文字列   •  エスケープ記号:  \  に続けて特定の文字   •  長さの取得:  len(文字列)   Python  入門   141  
  • サンプル:文字列の処理1   #  文字列の作成   >>>  str1  =  "hello"   >>>  str2  =  '  world'   #  結合   >>>  print(str1  +  str2)   hello  world   #  エスケープ   >>>  print(str1  +  "\t"  +  str2  +  "\ncisco")   hello    world   cisco   #  長さの取得   >>>  len(str1)   5   Python  入門   142  
  • 文字列の処理2   •  繰り返し:  文字列  *  繰り返し回数   •  文字列化:  str(文字列以外のオブジェクト)   •  文字列の一文字を取得 文字列[index]   •  文字列の範囲取得:  文字列[start:end]   Python  入門   143  
  • サンプル:文字列の処理2   #  繰り返し   >>>  print("cisco"  *  3)   ciscociscocisco   #  文字列化   >>>  print("value:  "  +  str(5))  #  非文字列を文字列化してから結合   value:  5   #  文字列の一文字を取得   >>>  "hello  world"[4]   'o'   #  文字列の一部を取得   >>>  "hello  world"[4:8]   'o  wo'     Python  入門   144  
  • 文字列の処理3   •  置き換え:  文字列.replace(old,  new)   •  分割:  文字列.split("区切り文字")   •  含むか:  "探す文字列"  in  "探される文字列"   •  位置:  文字列.find("探す文字")   Python  入門   145  
  • サンプル:文字列の処理3   #  置き換え   >>>  "hello  world".replace("world",  "python")   'hello  python'   #  分割   >>>  "hello  world".split("  ")   ['hello',  'world']   #  含むか   >>>  "hell"  in  "hello  world"   True   #  位置   >>>  "hello  world".find("o")   4   >>>  "hello  world".find("X")   -­‐1      #  指定した文字列が含まれていない場合は  -­‐1   Python  入門   146  
  • 正規表現   Python  入門   147  
  • 正規表現とは   •  文字列"パターン"の定義   •  柔軟に文字列のパターンマッチングを行うこ とができる   – パターンマッチングに該当するか   – 該当する文字列の取得   Python  入門   148  
  • 正規表現の有効性   •  文字列が整数かどうか判定するためのプロ グラムを作成する   •  正規表現の有無でコード量が大幅に違う       Python  入門   149   def  isIntegerString(string):          numberList  =  ['1','2','3','4','5','6','7','8','9','0']          if  len(string)  ==  0:                  return  false                    for  char  in  string:                  if  char  not  in  numberList:                          return  False            return  True   import  re   def  isIntegerString2(string):          return  re.match('^[\d]*$',  string)  !=  None   正規表現なし   正規表現あり  
  • python  の正規表現作法   •  re:  正規表現のパッケージ    import  re   •  match  :  合致する文字列群を抜き出す    re.match(パターン文字列,  文字列)   •  search:  合致する文字列の位置を返す    re.search(パターン文字列、文字列)   Python  入門   150  
  • 正規表現   Python  入門   151   >>>  m  =  re.match("^[\d]*$",  "12345")   >>>  print(m)     >>>  m.group()   '12345'   >>>  m.start(),  m.end()   (0,  5)  
  • ファイル処理   Python  入門   152  
  • ファイル処理の流れ   •  ファイル処理の流れ   1.  fileをオープンして  fileオブジェクトを取得   2.  fileオブジェクトに対して処理を行う   3.  fileをクローズする   Python  入門   153  
  • ファイルオブジェクト   •  ファイルオブジェクトの作成   open(ファイルパス,  オープンするモード)   –  ファイルパス:  相対  or  絶対   –  モード(デフォルトは"r")   –  r:  読み込みモード   –  w:  新規書き込みモード   –  a:  追加書き込みモード   •  ファイルオブジェクトのクローズ   f.close()     Python  入門   154  
  • 読み込み処理   •  Read   –  readline():  一行読み込み   –  readlines():  全ての行を  list  として読み込み   Python  入門   155   >>>  f  =  open("file.txt",  "r")   >>>  f.readline()   'hello  world1\n'   >>>  f.readline()   'hello  world2\n'   >>>  f.readlines()   ['hello  world3\n',  'hello  world4\n']   hello  world1   hello  world2   hello  world3   hello  world4   file.txt  
  • 書き込み処理   •  Write   – write(文字列)  :  文字列を書き込み   – writelines(文字列のリスト)  :  リストを書き込み   – flush()  :  バッファをディスクにフラッシュ   Python  入門   156   >>>  f2  =  open("file2.txt",  "w")   >>>  f2.write("hello")   >>>  f2.write("world")   >>>  f2.write("\n")   >>>  wlist  =  ["abc",  "def",  "ghi"]   >>>  f2.writelines(wlist)   >>>  f2.flush()   >>>  f2.close()   helloworld   abcdefghi   file2.txt  
  • 上書きと追記   •  上書き:  ファイルの内容を消してから書き込む   •  追記:  ファイルの末尾に追加で書き込む   Python  入門   157  
  • PICKEL   Python  入門   158  
  • Pickel   •  プログラムの実行状態はプログラムを停止すると消失   •  Pickel  はオブジェクトをファイルに永続的に保存する手法   •  Pickel   –  dump:  オブジェクトをファイルに書き出し   –  load:  ファイルからオブジェクトを読み出し   Python  入門   159  
  • Pickel   Python  入門   160   yuichi$  python   >>>  data  =  ["hello",  "world",  1,  2,  3]   >>>  import  pickle   >>>  f  =  open("dump.txt",  "w")   >>>  pickle.dump(data,  f)   >>>  f.close()   >>>  exit()   (lp0   S'hello'   p1   aS'world'   p2   aI1   aI2   aI3   a.   $  python   >>>  f  =  open("dump.txt")   >>>  import  pickle   >>>  data  =  pickle.load(f)   >>>  print(data)   ['hello',  'world',  1,  2,  3]   dump.txt  
  • PATH   Python  入門   161  
  • パス   •  OS上のファイルやディレクトリの所在地を示す   Python  入門   162   /Users/yuichi/Documents/python.pptx   /   Users/   yuichi/   Documents/   python.pptx   etc/   var/   Shared/   Desktop/   Pictures/   java.pptx   VM/  
  • 絶対パスと相対パス   •  絶対パス:  ルートから辿るパス   •  相対パス:  現在の自分の位置から辿るパス   –  ./  :  自分がいるディレクトリ   –  ../  :  自分の上の階層のディレクトリ   Python  入門   163   /   Users/   yuichi/   Documents/   python.pptx   etc/   var/   Shared/   Desktop/   test.txt   java.pptx   VM/   /Users/yuichi/test.txt   ../test.txt  
  • パスの取得   •  現在のカレントディレクトリを取得:  os.getcwd()   •  ディレクトリの移動:  os.chdir(移動先のパス)   •  絶対パスの取得:  os.path.abspath(path)   •  OS非依存のパスの取得方法 os.path.join(TUPLE)   Python  入門   164   yuichi$  ls  |  grep  Documents   Documents   yuichi$  python   >>>  import  os   >>>  os.getcwd()   '/Users/yuichi'   >>>  os.path.abspath("Documents")   '/Users/yuichi/Documents'   >>>  os.path.join("/","dir1","dir2","file1")   '/dir1/dir2/file1'  
  • パスに関する関数   •  ファイル or  ディレクトリの存在確認:  os.path.exists(パス)   •  ディレクトリか:  os.path.isdir(パス)   •  ファイルか:  os.path.isfile(パス)   Python  入門   165  
  • パスの操作関数   Python  入門   166   >>>  os.path.exists("/Users/yuichi")   True   >>>  os.path.isfile("/Users/yuichi")   False   >>>  os.listdir("./")   ['dir1',  'file1']   >>>  os.mkdir("dir2")   >>>  os.rmdir("dir2")   >>>    
  • ディレクトリの操作関数   •  ディレクトリの作成:  os.mkdir(ディレクトリのパス)   •  ディレクトリの削除:  os.rmdir(ディレクトリのパス)   •  ディレクトリの中身一覧:  os.listdir(パス)   •  ファイル、ディレクトリの削除:  os.remove(パス)   •  ディレクトリの再帰的削除:  os.removedirs(パス)   Python  入門   167  
  • PYTHON  AS  シェルスクリプト   Python  入門   168  
  • シェルスクリプト   •  プログラミング:  C  や  Java  のようなシェルを意識しな いスタイル   •  シェルスクリプト:  シェル自体を操作するプログラミン グスタイル   Python  入門   169   import  os     currentDir  =  os.getcwd()   files  =  os.listdir(currentDir)   for  fname  in  files:          print(fname)   import  commands     files  =  commands.getoutput("ls").split()   for  fname  in  files:          print(fname)   通常のプログラミングスタイル   シェルスクリプトのスタイル  
  • シェルスクリプト記述のコツ   •  可能な限り既存のコマンドを使う   •  コマンドとコマンドの接続に  python  を使う   Python  入門   170   (1)  結果  =  コマンドの発行   (2)  結果を処理   (3)  処理結果にもとづいて次のコマンドを作成   (4)  (1)へ  
  • コマンドの呼び出し   Python  入門   171   •  os.system("コマンド")  :  出力が不要な場合   •  commands.getoutput("コマンド")  :  出力が必要な場合   >>>  commands.getoutput("ls").split("\n")   ['CONFIG_FILE',  'Cisco  Mac  Support.webloc',  'Desktop',   'Documents',  'Downloads',  'Dropbox',  'Library',  'MATERIAL',   'Movies',  'Music',  'Pictures',  'Public',  'SR',  'STP-­‐BA-­‐Dispute_Japan-­‐ RSVT.pptx',  'VM',  'appProperces',  'bingo.py',  'bingo.pyc',   'dump.txt',  'file.txt',  'file2.txt',  'get-­‐fpath-­‐info.py',  'mki-­‐fp-­‐ capture.zip',  'tcpdump',  'tcpdump.zip',  'test',  'unctled  folder']  
  • command.getoutput()   Python  入門   172   import  commands     result  =  commands.getoutput("ping  -­‐c  5  cisco.com")   lines  =  result.split("\n")   for  line  in  lines:          print(line)   PING  cisco.com  (72.163.4.161):  56  data  bytes   64  bytes  from  72.163.4.161:  icmp_seq=0  7l=239  cme=195.865  ms   64  bytes  from  72.163.4.161:  icmp_seq=1  7l=239  cme=200.497  ms   64  bytes  from  72.163.4.161:  icmp_seq=2  7l=239  cme=197.125  ms   64  bytes  from  72.163.4.161:  icmp_seq=3  7l=239  cme=197.620  ms   64  bytes  from  72.163.4.161:  icmp_seq=4  7l=239  cme=197.553  ms     -­‐-­‐-­‐  cisco.com  ping  stacsccs  -­‐-­‐-­‐   5  packets  transmi7ed,  5  packets  received,  0.0%  packet  loss   round-­‐trip  min/avg/max/stddev  =  195.865/197.732/200.497/1.519  ms  
  • exping  の実装   •  複数の宛先のping到達率を測定   Python  入門   173   import  commands     def  ping(dest):          result  =  commands.getoutput("ping  -­‐c  5  {}".format(dest))          lines  =  result.split("\n")          length  =  len(lines)          packetLoss  =  lines[length  -­‐2].split()[6]          r7  =  lines[length  -­‐1].split()[3].split("/")[1]          return  (dest,  packetLoss,  r7)             dests  =  ["cisco.com",  "google.com",  "yahoo.com"]   for  dest  in  dests:          print(ping(dest))   ('cisco.com',  '0.0%',  '196.756')   ('google.com',  '0.0%',  '13.317')   ('yahoo.com',  '0.0%',  '262.060')  
  • Linuxホスト上でのping   •  特定IPアドレスのホスト間のみ通信できない   •  事象発生確立は 1/16  程度   Python  入門   174   Nexus2000   FEX   L2  Switch   Source   Dest   Nexus5500   Primary   Nexus5500   Secondary   VPC(VSS)   ホスト50台   ホスト50台   50  x  50  -­‐>  2500  flow   VLAN  X   VLAN  Y  
  • ping  到達率の測定プログラム   Python  入門   175  
  • 演習   Python  入門   176  
  • 演習   •  未完成のログ抽出プログラムを完成させる   •  バグは3箇所にある   Python  入門   177   yuichi$  python  log.py  -­‐f  log.log  -­‐s  "2014  Jan  28  12:30:50"  -­‐e  "2014  Jan  29  16:06:15"  -­‐k  "port-­‐channel"     -­‐f  :  ファイル名   -­‐s  :  スタート時刻   -­‐e  :  終了時刻   -­‐k  :  キーワード   dhcp-­‐10-­‐141-­‐56-­‐250:Documents  yuichi$  python  log.py  -­‐f  log.log  -­‐s  "2014  Jan  28  12:30:50"  -­‐e  "2014  Jan  29  16:06:15"  -­‐k  "port-­‐channel"   2014  Jan  29  12:14:20  N6K-­‐2  %ISIS_FABRICPATH-­‐5-­‐ADJCHANGE:    isis_fabricpath-­‐default  [5150]    P2P  adj  L1  n7kb-­‐MKI-­‐FP  over  port-­‐channel50  -­‐  DOWN  (New)  on  MT-­‐0   2014  Jan  29  12:14:20  N6K-­‐2  %ISIS_FABRICPATH-­‐5-­‐ADJCHANGE:    isis_fabricpath-­‐default  [5150]    P2P  adj  L1  n7kb-­‐MKI-­‐FP  over  port-­‐channel50  -­‐  INIT  on  MT-­‐0   2014  Jan  29  12:14:20  N6K-­‐2  %ISIS_FABRICPATH-­‐5-­‐ADJCHANGE:    isis_fabricpath-­‐default  [5150]    P2P  adj  L1  n7kb-­‐MKI-­‐FP  over  port-­‐channel50  -­‐  UP  on  MT-­‐0   2014  Jan  29  12:24:58  N6K-­‐2  %ISIS_FABRICPATH-­‐5-­‐ADJCHANGE:    isis_fabricpath-­‐default  [5150]    P2P  adj  L1  n7kb-­‐MKI-­‐FP  over  port-­‐channel50  -­‐  DOWN  (Delete  All)  on  MT-­‐0   2014  Jan  29  12:27:01  N6K-­‐2  %ISIS_FABRICPATH-­‐5-­‐ADJCHANGE:    isis_fabricpath-­‐default  [5150]    P2P  adj  L1  n7kb-­‐MKI-­‐FP  over  port-­‐channel50  -­‐  DOWN  (New)  on  MT-­‐0   2014  Jan  29  12:27:01  N6K-­‐2  %ISIS_FABRICPATH-­‐5-­‐ADJCHANGE:    isis_fabricpath-­‐default  [5150]    P2P  adj  L1  n7kb-­‐MKI-­‐FP  over  port-­‐channel50  -­‐  INIT  on  MT-­‐0   2014  Jan  29  12:27:01  N6K-­‐2  %ISIS_FABRICPATH-­‐5-­‐ADJCHANGE:    isis_fabricpath-­‐default  [5150]    P2P  adj  L1  n7kb-­‐MKI-­‐FP  over  port-­‐channel50  -­‐  UP  on  MT-­‐0  
  • コード(バグは2箇所)   Python  入門   178   import  sys,  os       def  getTimeString(line):          return  line[0:20]       def  parseTime(string):          monthDict  =  {"Jan":1,  "Feb":2,  "Mar":3,  "Apr":4,  "May":5,  "Jun":6,                                    "Jul":7,  "Aug":8,  "Sep":9,  "Oct":10,  "Nov":11,  "Dec":12}          d1  =  string.split("  ")          d2  =  d1[3].split(":")          return  (int(d1[0]),  monthDict[d1[1]],  int(d1[2]),                          int(d2[0]),  int(d2[1]),  int(d2[2]))       def  printFile(fname,  start,  end,  keyword):          if(not  os.path.isfile(fname)):                  print("File  \"{}\"  isn't  exist.  exit".format(fname))                  sys.exit()            f  =  open(fname)          for  line  in  f.readlines():                  line  =  line.rstrip()                  t  =  parseTime(getTimeString(line))                  within  =  (start  
  • 演習   Python  入門   179   発展編   キーワードを正規表現で指定できるようにする   正規表現にマッチした場合のみ表示を行う     オプション  -­‐r  に続けて正規表現を指定  
  • 演習   •  ラボのLinux(10.71.224.172)にログイン(guest,   c1sco123)し、以下のスクリプトを作成し実行する   •  ファイル名は  .py  とする   Python  入門   180   以下の機器の開いているポート一覧を取得する    -­‐  rws1  (1.0.0.1)    -­‐  gateway  (1.0.0.100)    -­‐  linux(  1.110.120.173)    -­‐  esxi  (  10.71.224.170)    -­‐  Nexus7000  (1.110.8.1)    
  • 利用するコマンド   Python  入門   181   yuichi$  ssh  -­‐l  guest  10.71.224.172   pass:  c1sco123     [guest@fedora172  ~]$  nmap  127.0.0.1     Starcng  Nmap  6.01  (  h7p://nmap.org  )  at  2014-­‐02-­‐08  13:05  EST   Nmap  scan  report  for  fedora172.localdomain  (127.0.0.1)   Host  is  up  (0.0016s  latency).   Not  shown:  995  closed  ports   PORT        STATE  SERVICE   22/tcp    open    ssh   23/tcp    open    telnet   25/tcp    open    smtp   111/tcp  open    rpcbind   631/tcp  open    ipp  
  • 表示形式   Python  入門   182   アドレス1   TCP:  xxx,  yyy,  zzz,  ...   UDP:  xxx,  yyy,  zzz,  ...     アドレス2   TCP:  xxx,  yyy,  zzz,  ...   UDP:  xxx,  yyy,  zzz,  ...     ...     アドレス3   TCP:  xxx,  yyy,  zzz,  ...   UDP:  xxx,  yyy,  zzz,  ...    
  • 次回予告   •  オブジェクト指向   •  クラス   •  アルゴリズム   •  pexpect  によるCisco機器のプログラム操作   Python  入門   183  
  • Python  入門   184  
  • Python  入門   Learning  to  Program     For  Cisco  Network  Engineers   Day  3/4     Japan  TAC  DC  Team.   Yuichi  Ito  
  • Agenda  Day  3   •  クラスの概念   •  クラスの作成   •  演習   •  ドラクエの実装で学ぶオブジェクト指向   •  演習1-­‐3   •  pexpect  による  Cisco  機器の操作法   •  演習   186  Python  入門  
  • プログラミング言語の流派   Python  入門   187  
  • プログラミングの流派   •  手続き型   •  関数型   •  オブジェクト指向型   Python  入門   188  
  • オブジェクト指向の概念   Python  入門   189  
  • なぜオブジェクト指向が必要か   あえてコード記述作法にルールを課すことでプロ グラムのカオス化を防ぐ    -­‐  実装の境界が明確になる     Python  入門   190   ルールにしたがって   プログラムを整理  
  • なぜオブジェクト指向が必要か   オブジェクト指向の機能で開発効率を向上させる    -­‐  継承による機能の引き継ぎ    -­‐  ポリモーフィズム   Python  入門   191   Bu7on   Hello  World   ボタンを押したら  hello  world  と   表示するプログラム     10数行で作れる(継承のおかげ)  
  • 人間の思考方法   •  「誰が何をするか」が重要   •  誰にどういう「メッセージ」を送ったら、どういう「結 果」が得られるか   Python  入門   192   [内部処理]   仕事をする   [メッセージ]   この仕事をしてください   [結果]   成果物はこれです。  上司   部下  
  • 関数 vs  メソッド   Python  入門   193   関数チックな考え方   オブジェクト指向の考え方   「仕事をさせる」(部下A、仕事)   「部下A」に「仕事をさせる」(仕事)  
  • 関数 vs  メソッド   •  関数:  オブジェクトを「引数として」使う   •  メソッド:  オブジェクト「から」処理を呼び出す   Python  入門   194   >>>  string  =  "hello  world  python"   #  関数   >>>  length  =  len(string)     #  メソッド   >>>  words  =  string.split()   文字列の処理  
  • 関数 vs  メソッド   •  関数:  データと処理の結びつきが弱い   •  メソッド:  データと処理の結びつきが強い   Python  入門   195   len(        )   string.split()   処理にデータを与える   データに処理をさせる   関数   メソッド   len  は何にでも使える   split  は  string  にしか使えない  
  • オブジェクト指向   •  誰(インスタンス)にメッセージを送る(メソッドを呼び 出す)とどういう結果(返り値)が得られるか   •  細かい内部の仕組みは気にしない   Python  入門   196   返り値  =  誰.メソッド(パラメータ)   記述ルール  
  • •  内部の細かい挙動は考えず状態のみを意識する   データをHDDに書き込みたい   (1)  Block  N  に書き込み   書き込み処理   (1)Block  N  のDisk  を選択   (2)Block  N  のセクタを指定   (3)書き込みを行なう ストレージオブジェクト   (専門家がプログラムを作成) ユーザアプリケーションの   オブジェクト   (ストレージを使うだけ) 処理、情報の隠蔽   ※  現在のヘッド位置などは気にしない  
  • まとめ   •  オブジェクト指向のコンセプト   – 「誰が何をするか」   – 「誰が誰とどう協力するか」   – 「複雑な処理、データは外部に見せない」   •  コードの秩序化   – 権限を持たないものは操作ができない   Python  入門   198  
  • クラスの概念   Python  入門   199  
  • クラス   •  オブジェクトの種類   •  クラスは属性としてデータと処理を持つ   Python  入門   200   属性   [データ]    -­‐  ガソリンの量     [処理]    -­‐  走る    -­‐  止まる    -­‐  曲がる  
  • インスタンス   •  クラス自体で処理するのではなく、クラスから作るイ ンスタンスで処理をする   •  部下という概念(クラス)ではなく部下の◯◯(インスタ ンス)が仕事をする   Python  入門   201   [内部処理]   仕事をする   [メッセージ]   この仕事をしてください   [結果]   成果物はこれです。  クラス:  上司   インスタンス:  BOB   クラス:  部下   インスタンス:  TOM  
  • クラスとインスタンスの関係   •  クラス:  インスタンスを作るための雛形   •  インスタンス:  クラスから作られるオブジェクト   •  型(クラス)  とその値(インスタンス)という理解でOK   Python  入門   202   クラス   インスタンス  インスタンス化   型(Class)  String   値(Instance)  "Hello  Python",  "Hello  Cisco"  
  • コンポジション   •  クラスは別のクラス(インスタンス)を持つことがある   Python  入門   203   クラス車は    -­‐  エンジンクラスを1インスタンス    -­‐  タイヤクラスを4インスタンス    -­‐  ハンドルクラスを1インスタンス   持っている  
  • クラスの作成   Python  入門   204  
  • クラスの宣言   •  以下の要件を満たすクラスを作る   Python  入門   205   string:  保持する文字列   set_string:  stringをセット   get_string:  stringを取得   double:  stringを繰り返す   クラス:  MyClass   属性:  インスタンス変数   属性:  メソッド   データとして文字列を内部に持つ   その文字列を設定するメソッド   その文字列を取得するメソッド   文字列を「文字列+文字列」にするメソッド  
  • クラスの宣言   •  クラスの宣言は  class  クラス名:   •  メソッドの宣言:  第一引数が self  として定義   •  属性へのアクセスは self.属性 とする   Python  入門   206   class  MyClass:          string  =  ""                    def  set_string(self,  string):                  self.string  =  string                            def  get_string(self):                  return  self.string                    def  double(self):                  self.string  *=  2   class  の宣言   メソッドの宣言   第一引数を  self  とするのは  python  のルール   class  が保持するデータの宣言   属性へのアクセス   self.属性 とする   (そうしないと関数だけのローカル変数となる)  
  • インスタンスの利用   •  クラス名()  でインスタンス化   •  メソッドを呼び出す際は第一引数(self)は指定しない   Python  入門   207   class  MyClass:          string  =  ""                    def  set_string(self,  string):                  self.string  =  string                            def  get_string(self):                  return  self.string                    def  double(self):                  self.string  *=  2   #  インスタンス化   >>>  mc  =  MyClass()     #  メソッド呼び出し   >>>  mc.set_string("hello  ")   >>>  print(mc.get_string())   hello       >>>  mc.double()   >>>  print(mc.get_string())   hello  hello    
  • 演習   •  class  Counter  を作成   •  内部にカウンタを持つ。初期値は1   •  get_value  メソッドで現在のカウンタ値を返す   •  count_up  メソッドで現在のカウンタ値を  +1  する   •  clear_counter  メソッドでカウンタを1に戻す   Python  入門   208  
  • コンストラクタの利用   •  コンストラクタ:  インスタンス作成時に呼び出されるメソッド   •  コンストラクタの引数はインスタンス作成時に指定   Python  入門   209   class  MyClass:          string  =  ""            def  __init__(self,  string):                  print("__init__  is  called")                  self.string  =  string              def  set_string(self,  string):                  self.string  =  string                            def  get_string(self):                  return  self.string                    def  double(self):                  self.string  *=  2   #  インスタンス化   >>>  mc  =  MyClass("python  ")   __init__  is  called     #  メソッド呼び出し   >>>  print(mc.get_string())   python     >>>    
  • 演習   •  class  Counter  を改良   •  内部にカウンタを持つ。初期値はコンストラクタで指定   •  clear_counter  メソッドでカウンタを初期値に戻す   Python  入門   210  
  • 補足)動的なメンバ変数   •  動的にメンバ要素を追加できる   •  Javaとは異なるので要注意!!   Python  入門   211   class  MyClass:      def  func(self):          print("func")   >>>  mc  =  MyClass()   >>>  mc.a  =  "Hello  World"   >>>  mc.a   'Hello  World'   定義されていない   メンバ変数  a  に代入   メンバ変数  a  は   定義されていない  
  • クラスサンプル   Python  入門   212   #  bingo.py   import  random     class  BingoMachine:          ballList  =  []          def  __init__(self,  min,  max):                  self.ballList  =  range(min,  max  +  1)            def  getBall(self):                  if(len(self.ballList)  ==  0):                          return  -­‐1                  index  =  int(random.uniform(0,  len(self.ballList)))                  return  self.ballList.pop(index)   #  実行結果   >>>  from  bingo  import  *   >>>  b  =  BingoMachine(1,5)   >>>  b.getBall()   1   >>>  b.getBall()   5   >>>  b.getBall()   2   >>>  b.getBall()   3   >>>  b.getBall()   4   >>>  b.getBall()   -­‐1   ビンゴマシーン   数字 n  –  m  の間の数字をランダムに返す   一度返した値は返さない  
  • クラスまとめ1   •  メソッドの第一引数は自分自身のオブジェクト   •  メンバ変数やメソッドを呼ぶにはこのオブジェクトの指定が必要   Python  入門   213   class  MyClass:          var  =  0          def  method1(self):                  self.var  =  1                  print("method1")          def  method2(self):                  print(self.var)                  self.method1()                  print("method2")   メソッド定義の第一引数が  self  になっている   メソッド呼び出しは定義の第一引数は飛ばす   メンバ変数やメソッドを  self.名前 として   呼び出している  
  • クラスまとめ2   Python  入門   214   class  MyClass2:          var  =  0          def  __init__(self,  var):                  self.var  =  var          def  method(self,  var):                  print(str(self.var)  +  "  "  +  str(var))                  print("method")     m2  =  MyClass2(5)   m2.method(8)    -­‐-­‐>  5  8                method   •  インスタンス化: クラス名(コンストラクタに渡す引数)   •  コンストラクタ:  __init__  というメソッド名  
  • ドラクエで理解するオブジェクト指向   Python  入門   215  
  • 演習の目的   Python  入門   216   •  大きなプログラムの作成方法を学ぶ   – 複数のクラスの連携   – どのようにしてコードを広げていくか   – 題材はドラクエ1  
  • ドラゴンクエスト   Python  入門   217   主人公   全てを作るのは無理なので  Map  のみ実装する   町人   前後左右に動く   ただし、マップの外には出ない   町人に話しかける   主人公に応答する  
  • AA版ドラゴンクエスト(完成図)   Python  入門   218   a:Left,  s:Right,  w:Up,  x:Down   d:Talk,  Ctrl-­‐C:Exit     +-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐+   |                |   |                |   |  B<          |   |                |   |              M|   |                |   |                |   |    P          |   +-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐+     #######################   Hello  I'm  Bukiya   #######################   主人公   メッセージ欄   前後左右に動く   ただし、マップの外には出ない   町人に話しかける   向いている向きでアイコンが変わる   主人公に応答する   町人   マップ  
  • 作成プログラムの要素   Python  入門   219   町人(複数)   主人公   (イベント処理)   マップ(全体の管理)   入力   キー入力管理クラス   (実装済み)  
  • クラス町人   Python  入門   220   クラス:  町人        メンバ変数          x座標          y座標          外見の種類          セリフ        メソッド:            respond:  主人公に応答する   外見     B:  武器屋   M:  商人   P:  神父  
  • クラス町人のインスタンス   Python  入門   221   インスタンス 町人A      メンバ変数          x:  8          y:  4          外見:  男A          セリフ:  "こんにちは"        メソッド:          respond:  主人公に応答する   インスタンス 町人B      メンバ変数          x:  4          y:  2          外見:  魔法使い          セリフ:  "いい天気じゃのう"        メソッド:          respond:  主人公に応答する  
  • 主人公   Python  入門   222   主人公のアイコン     <  :  左向き   >  :  右向き   ^  :  上向き   V  :  下向き   クラス:  主人公        メンバ変数          x座標          y座標          向いている方向          セリフ        メソッド:            run:  キー入力を待つ(標準入力の無限ループ)            move:  キー入力で上下左右に動く            talk:  向いている方向の町人と話す  
  • マップ   Python  入門   223   クラス:  Map      メンバ変数          -­‐  主人公のインスタンス          -­‐  町人たちのインスタンス          -­‐  マップ情報        メソッド:          -­‐  render:  マップを書き出す          -­‐  主人公と町人を管理するメソッド群     +-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐+   |                |   |                |   |  B<          |   |                |   |    P          |   +-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐+     外枠   主人公   町人(複数)  
  • クラスとクラスの相互関係   •  十字キーを操作すると勇者が動く   •  地図はその情報を反映しなければならない   Python  入門   224   インスタンス   勇者   インスタンス   Map   入力(keyInput)   自分のX,Y情報を   アップデート   描画を依頼   画面出力  
  • マップ描画の全体の流れ   Python  入門   225   Class:  Field      変数:  hero      変数:  peopleMap      変数:  地形情報        renderMap()   描画(render)   地形情報  +  勇者  +  町人達   Class:  Hero      move()      talk()      getXY()      getImage()      keyInputEvent()   Class: People          respond()          getImage()   入力(keyInput)   x,y座標や見た目   などの情報を取得   ディスプレイに出力   ①   ②   ③   ④   +-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐+  |                |   |                |   |  B<          |   |                |   |    P          |   +-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐+    
  • 演習1   Python  入門   226  
  • マップ   •  何もないマップを描画   •  縦と横の長さを指定可能   •  行(row)指向で描画する   227   +-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐+   |                |   |                |   |                |   +-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐+   4隅は 「+」   y座標0,  最大値は 「–」   x座標0,  最大値は 「|」   それ以外は空白   class  DQMap:          max_x  =  0          max_y  =  0                    def  __init__(self,  max_xy):                  (self.max_x,  self.max_y)  =  max_xy            def  render_map(self):                  map_string_list  =  []                                  for  y  in  range(self.max_y):                          for  x  in  range(self.max_x):                                  if(y  ==  0  or  y  ==  self.max_y  -­‐  1):                                          if(x  ==  0  or  x  ==  self.max_x  -­‐  1):                                                  map_string_list.append("+")                                          else:                                                  map_string_list.append("-­‐")                                  else:                                          if(x  ==  0  or  x  ==  self.max_x  -­‐  1):                                                  map_string_list.append("|")                                          else:                                                  map_string_list.append("  ")                          map_string_list.append("\n")                    map_string  =  "".join(map_string_list)                  print(map_string.rstrip())  
  • 主人公   •  キー入力で主人公のx,y座標と「向き」をアップデートする   •  Ctrl-­‐C  でプログラムを終了する   228   import  getch,  sys     class  Hero:          x  =  0          y  =  0          direccon  =  "N"                    def  __init__(self,  x,  y):                  self.x  =  x                  self.y  =  y                  self.direccon  =  "N"                            def  run(self):                  gc  =  getch.Getch()                  while(True):                          keycode  =  ord(gc())                          self.move(keycode)                          print("x:{},  y:{},  dir:{}".format(self.x,  self.y,  self.direccon))                          if(keycode  ==  3):                                  sys.exit()    def  move(self,  keycode):                          if(keycode  ==  97):  #Le                                  self.x  -­‐=  1                                  self.direccon  =  "W"                          elif(keycode  ==  115):  #Right                                  self.x  +=  1                                  self.direccon  =  "E"                          elif(keycode  ==  119):  #Up                                  self.y  -­‐=  1                                  self.direccon  =  "N"                          elif(keycode  ==  122):  #Down                                  self.y  +=  1                                  self.direccon  =  "S"     hero  =  Hero(10,10)   hero.run()    
  • マップと主人公(課題)   •  マップの中に主人公を描画   •  向いている方向で主人公のアイコンを変える   •  マップの範囲外に主人公がアクセスしない   •  プログラムの起点は main.py   229   実装のヒント   DQMap:    -­‐  DQMap  が  Hero  のインスタンスを持つ    -­‐  主人公と同じ x,  y  座標の場合は主人公のアイコンを表示          (主人公のインスタンスからアイコンを取得)     Hero:    -­‐  新しい座標が  Map  範囲内である場合だけ、x,y  をアップデート          (範囲外へのアクセスは x,y  をアップデートしない)      -­‐  表示する主人公のアイコンは主人公の向きで決まる          (向きの応じたアイコンを返すメソッドを実装)  
  • 演習2   Python  入門   230  
  • 町人の実装   Python  入門   231   class  People:          icon  =  ""          x  =  0          y  =  0          comment  =  ""            def  __init__(self,  icon,  x,  y,  comment):                  self.icon  =  icon                  self.x  =  x                  self.y  =  y                  self.comment  =  comment            def  get_icon(self):                  return  self.icon                    def  get_xy(self):                  return  (self.x,  self.y)                    def  get_response(self):                  return  self.comment   町人は    -­‐  アイコン(一文字)    -­‐  x,y    -­‐  セリフ   をコンストラクタで設定     「ゲッターメソッド」を実装    ※  パラメータを取得するためのメソッド    
  • マップと町人の実装   Python  入門   232   class  DQMap:          ...          people_map  =  {}                    def  __init__(self,  max_xy,  hero_xy,  people_paramList):                  ....                  for  params  in  people_paramList:                          (icon,  x,  y,  comment)  =  params                          self.people_map[(x,y)]  =  people.People(icon,  x,  y,  comment)    def  render_map(self,  comment):                  map_string_list  =  []                  (hx,  hy)  =  self.hero.get_xy()                                    for  y  in  range(self.max_y):                          for  x  in  range(self.max_x):                                  if((x,y)  ==  (hx,  hy)):                                          map_string_list.append(self.hero.get_icon())                                  elif(self.people_map.has_key((x,  y))):                                          p  =  self.people_map[(x,  y)]                                          map_string_list.append(p.get_icon())   コンストラクタで町人の   情報をリスト形式で指定   町人のインスタンスを作成   (x,y)をキーにし辞書で町人を管理   描画の際に、x,  y  に町人がいるか確認   もしいれば町人を描画する  
  • 主人公と町人の実装(課題)   •  主人公が町人と被らないようにする   Python  入門   233   Hint   次に動こうとする先に町人がいるか確認   いる場合は主人公の  x,  y  をアップデートしない  
  • 演習3   Python  入門   234  
  • 会話機能の実装   •  主人公が向いている方向に町人がいるか確認   •  町人がいれば町人のレスポンスを取得し表示   •  いなければ誰もいない旨のメッセージを表示   •  DQMapのメソッドrender_mapにコメントを渡して描画(実装済)     Python  入門   235   +-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐+   |                |   |                |   |  B            |   |                |   |            >M|   |                |   |                |   |    P          |   +-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐+     #######################   Hello  I'm  Merchant   #######################   +-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐+   |                |   |                |   |  B            |   |            ^  |   |              M|   |                |   |                |   |    P          |   +-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐+     #######################   No  one  exists  on  that  way   #######################  
  • その他   Python  入門   236  
  • __name__   •  __name__    •  __name__  が "__main__"  のときは起点   Python  入門   237   import  uclity     def  func():          print("func  on  main.py")     print("global  on  main.py")   func()   uclity.func()     if  __name__  ==  "__main__":          print("__name__  is  __main__  on  main.py")   def  func():          print("func()  on  uclity.py")     print("global  on  uclity.py")   func()     if  __name__  ==  "__main__":          print("__name__  is  __main__  on  uclity.py")   main.py   uclity.py  
  • __name__   Python  入門   238   def  func():          print("func()  on  uclity.py")     print("global  on  uclity.py")   func()     if  __name__  ==  "__main__":          print("__name__  is  __main__  on  uclity.py")   #  python  uclity.py     global  on  uclity.py   func()  on  uclity.py   __name__  is  __main__  on  uclity.py   True   実行結果  
  • __name__   Python  入門   239   import  uclity     def  func():          print("func  on  main.py")     print("global  on  main.py")   func()   uclity.func()     if  __name__  ==  "__main__":          print("__name__  is  __main__  on  main.py")   def  func():          print("func()  on  uclity.py")     print("global  on  uclity.py")   func()     if  __name__  ==  "__main__":          print("__name__  is  __main__  on  uclity.py")   main.py   uclity.py  True   False   #python  main.py     global  on  uclity.py   func()  on  uclity.py   global  on  main.py   func  on  main.py   func()  on  uclity.py   __name__  is  __main__  on  main.py   実行結果  
  • コピーと参照   •  コピー:  異なるオブジェクト   •  参照:        同一オブジェクトを複数箇所で利用   •  参照に対しては副作用の注意が必要   Python  入門   240   >>>  a  =  [1,2,3,4]   >>>  b  =  a   >>>  b.append(5)   >>>  a   [1,  2,  3,  4,  5]  
  • PEXPECT   Python  入門   241  
  • Pexpect   •  EXPECT  を  Python  で使うためのパッケージ   •  Ciscoの機器やLinuxといったCLI操作を必要とする機器を プログラミングで規定通りに動かすために利用   Python  入門   242   Python   Script  
  • Expect   •  LinuxなどのインタラクティブなCLIを制御する ためのプログラム   •  pexpect  の元になったプログラム   •  Teraterm  Macro  に似ている   Python  入門   243   The  Expect  Home  Page   h7p://expect.sourceforge.net/   Expect   Script  
  • Expect  の動作   •  spawn:  セッションを開始   •  expect:  期待する標準入力(from  リモート)を待つ   •  send:  リモートに出力を送る   Python  入門   244   dhcp-­‐10-­‐141-­‐56-­‐250:~  yuichi$  telnet  -­‐l  yuiito  rws1   Trying  10.71.231.245...   Connected  to  rws1.cisco.com.   Escape  character  is  '^]'.   Password:  cisco123   Last  login:  Thu  Jan  23  14:53:37  from  dhcp-­‐10-­‐141-­‐56-­‐250.cisco.com   unknown  terminal  "xterm-­‐256color"   unknown  terminal  "xterm-­‐256color"   [yuiito@rws1  yuiito]$  echo  hello  >  test   [yuiito@rws1  yuiito]$  ls   snmpget.sh    test   青がリモートからの標準入力   赤がリモートへの標準出力  
  • expect  サンプル   •  Linux  へのログインと操作   Python  入門   245   Password:   cisco123   yuiito$     echo  hello  >  test     #!  /usr/bin/expect     spawn  telnet  -­‐l  yuiito  rws1   expect  "Password:"   send  "cisco123\n"   expect  "yuiito\]\\\$"   send  "touch  hello\n"   interact   yuichi$  expect  login-­‐to-­‐rws1.exp     login-­‐to-­‐rws1.exp   呼び出し  
  • Pexpect     •  pip  を使ってインストール   •  コード pexpect.py  同一フォルダに配置(利用)   •  import  pexpect   Python  入門   246  
  • Pexpect  の作法   •  spawn   session  =  pexpect.spawn("telnet等のコマンド")   •  expect   session.expect("入力されるのを待つ文字列")   •  sendline   session.sendline("送信する文字列。自動で改行 コードがつく")   Python  入門   247  
  • pexpect   •  マッチした文字列当を抽出   Python  入門   248   session.aer:  マッチした文字列   session.before:  マッチした文字列までの文字列   session.buffer:    
  • pexpect  のサンプル   •  rws1  にログインしてファイル pexpect  を作成   Python  入門   249   import  pexpect     child  =  pexpect.spawn("telnet  -­‐l  yuiito  rws1")   child.expect("Password:")   child.sendline("cisco123")   child.expect("yuiito\]\$")   child.sendline("touch  pexpect")  
  • pexpextのサンプル   •  Nexusの設定をファイル名を日時にしてFTPサーバに保存   Python  入門   250   import  pexpect,  datecme     def  getLines(string):          lines  =  lines  =  [x.strip()  for  x  in  string.split("\n")]          return  filter(lambda  x:  x!=  '',  lines)     def  getHostName(exp):          exp.sendline("show  hostname")          exp.expect("#")          return  getLines(exp.before)[1]     def  getToDay():          d  =  datecme.datecme.today()          return  "{}_{}_{}-­‐{}_{}_{}".format(d.year,  d.month,     d.day,  d.hour,  d.minute,  d.second)             def  makeFileName(exp):          hostName  =  getHostName(exp)          today  =  getToDay()          return  "{}-­‐{}.conf".format(hostName,  today)   def  login(exp,  password):          exp.expect("Password:")                  exp.sendline(password)          exp.expect("#")          exp.sendline("terminal  length  0")          exp.expect("#")     def  saveFile(exp,  saveFrom,  saveTo,  vrf,  username,  password):          command  =  "copy  {}  {}".format(saveFrom,  saveTo)          exp.sendline(command)          exp.expect("Enter  vrf")          exp.sendline(vrf)          exp.expect("Enter  username:")          exp.sendline(username)          exp.expect("Password:")          exp.sendline(password)          exp.expect("#")             child  =  pexpect.spawn("telnet  -­‐l  admin  10.71.156.229")   login(child,  "cisco")   saveTo  =  "p://10.71.224.115/yuiito/"  +  makeFileName(child)   saveFile(child,  "running-­‐config",  saveTo,  "management",    "anonymous",  "")   child.close()  ファイル名やコマンドの生成が  python  任せ  
  • pexpect   •  showコマンドや設定変更はほぼ同じような手 順で実装される   •  継承やクロージャを使うことで各処理を実装 すれば簡単に機能を増やせる   Python  入門   251  
  • 演習   •  Nexusの現在のバージョンを取得するプログ ラムを作成する   Python  入門   252   Nexus   ip:  1.110.8.1   user-­‐name:  admin   pass:  cisco   踏み台   ip:  10.71.224.172   user-­‐name:  guest   pass:  c1sco123  
  • Python  入門   253  
  • Python  入門   Learning  to  Program     For  Cisco  Network  Engineers   Day  4/4     Japan  TAC  DC  Team.   Yuichi  Ito  
  • Agenda  Day4   •  Pythonのプログラム配布手法   •  Tkinter  (GUI)   •  Tkinter  で学ぶ継承   •  例外処理   •  NETWORKプログラミング   •  Pexpect   Python  入門   255  
  • プログラム配布手法   Python  入門   256  
  • ソースコードの配布   •  長所:  配布が簡単   •  短所:  ライブラリに依存。コードが丸見え   Python  入門   257   python   ソース コード   python   ソース コード   python   ソース コード   開発者   利用者   利用者  
  • バイナリ化して実行環境ごと配布   •  長所:  利用者が使いやすい。   •  短所:  作成が難しい   Python  入門   258   python   ソース コード   開発者   利用者(Windows)   利用者(Mac)   .exe   .app  
  • 関数(メソッド)の引数   Python  入門   259  
  • 関数とパラメータ   •  関数(メソッド)にはデフォルト値を使える   •  呼び出し側で引数を好きな順序で指定可能   Python  入門   260   def  func(a,  b="python",  c="cisco"):          print("hello  {}  {}  {}".format(a,b,c))     func("world",  "PYTHON",  "CISCO")    #  =>  "hello  world  PYTHON  CISCO"     func("world")      #  =>  "hello  world  python  cisco"     func(b="world",  a="python")    #  =>  "hello  python  world  cisco"   引数  b,  c  にはデフォルト値を指定   引数 a,b,c  に全て任意の値を設定   引数  a  のみ指定して呼び出し   任意の順序で引数を指定  
  • GUI  TKINTER   Python  入門   261  
  • GUI  の学習目的   •  アプリケーションにGUI一般的   •  見た目に分かりやすいので中級者向き   •  継承の概念などを理解するのに最適な題材   Python  入門   262  
  • Tkinter   •  Python  の標準的なGUIライブラリ   •  インストールなしに利用可能   •  他のGUIライブラリ(Qt,  wxpython)と概念が似ている   Python  入門   263  
  • Hello  Tkinter   Python  入門   264   import  Tkinter  as  tk     font=("Helevecca",  32,  "bold")   label  =  tk.Label(text="Hello  Cisco",  font=font,  bg="red")   label.pack()   label.mainloop()  
  • Hello  Tkinter   •  GUI  作成の流れ   – Widgetと呼ばれるパーツを初期化   – パーツを配置   – GUIアプリケーションを起動   Python  入門   265   Widget  はGUIの部品。   ボタンやテキストボックスなどの全てのパーツはWidget  
  • Hello  Tkinter  の解説   Python  入門   266   import  Tkinter  as  tk     font=("Helevecca",  32,  "bold")   label  =  tk.Label(text="Hello  Cisco",  font=font,  bg="red")   label.pack()   label.mainloop()   Tkinter  というモジュールをインポート。呼び出し時は tk  という別称を使う     Widget  の Label  を作成する。引数として文字列とフォント、背景色を指定   pack()  メソッドで配置   mainloop()  メソッドを呼び出すことでアプリケーションを実行  
  • 演習1   •  ラベルに表示する文字列を  Hello  Python  に変更   •  フォントサイズを  44  にする   •  背景色を  blue  にする   発展   •  アンダーラインを付ける   •  幅を50にする   Python  入門   267   An  IntroducYon  to  Tkinter  (Work  in  Progress)   h7p://eot.org/tkinterbook/  
  • Frame   •  Widget  を配置するための  Widget   •  Frame  in  Frame  も可能(複雑な構成を作れる)   Python  入門   268   Frame1   Frame2   Frame3   widget   1   widget   2   widget   3   widget   4   widget  5   widget  6   Frame1            |            |-­‐-­‐  Frame  2            |                    |  -­‐-­‐  Widget1            |                    |  -­‐-­‐  Widget2            |                    |  -­‐-­‐  Widget3            |                    |  -­‐-­‐  Widget4            |            |  -­‐-­‐  Frame3                                    |  -­‐-­‐  Widget5                                    |  -­‐-­‐  Widget5  
  • Hello  Frame   Python  入門   269   import  Tkinter  as  tk     frame  =  tk.Frame()   font=("Helevecca",  32,  "bold")   label1  =  tk.Label(frame,  text="Hello  Cisco",  font=font,  bg="red")   label2  =  tk.Label(frame,  text="Hello  Python",  font=font,  bg="blue")   label1.pack()   label2.pack()   frame.pack()   frame.mainloop()  
  • Hello  Frame  の解説   •  Frame  のインスタンスを作成   •  Frame  の子要素(中にある)は第一引数を  Frame  の インスタンスにする   •  トップレベルの  widget  で mainloop()  を呼び出す   Python  入門   270   import  Tkinter  as  tk     frame  =  tk.Frame()   font=("Helevecca",  32,  "bold")   label1  =  tk.Label(frame,  text="Hello  Cisco",  font=font,  bg="red")   label2  =  tk.Label(frame,  text="Hello  Python",  font=font,  bg="blue")   label1.pack()   label2.pack()   frame.pack()   frame.mainloop()  
  • 演習   •  3つのラベルが表示されるように改造する   •  3番目の背景色は  green   Python  入門   271   •  Hello  Cisco,  Hello  World  の横の空白を埋める   •  Hint:  widgetの  pack  に  fill=tk.X  を指定   発展編  
  • Frame  の縦横   •  Frameが並ぶのはデフォルト縦方向   •  子要素の  pack()  メソッドの引数に方向を指定   •  横方向は  side=LEFT  を指定   272   import  Tkinter  as  tk     frame  =  tk.Frame()   font=("Helevecca",  32,  "bold")   label1  =  tk.Label(frame,  text="Hello  Cisco",  font=font,  bg="red")   label2  =  tk.Label(frame,  text="Hello  Python",  font=font,  bg="blue")   label1.pack(side=tk.LEFT)   label2.pack(side=tk.LEFT)   frame.pack()   frame.mainloop()  
  • 演習   •  Frame  に  Frame  を入れて以下のウィンドウを 作成する   Python  入門   273  
  • 演習の解答例   Python  入門   274   import  Tkinter  as  tk     frame1  =  tk.Frame()   frame2  =  tk.Frame()   font=("Helevecca",  32,  "bold")   label1  =  tk.Label(frame2,  text="Hello  Cisco",  font=font,  bg="red")   label2  =  tk.Label(frame2,  text="Hello  Python",  font=font,  bg="blue")   label1.pack(side=tk.LEFT)   label2.pack(side=tk.LEFT)   label3  =  tk.Label(frame1,  text="Hello  Wodld",  font=font,  bg="green")   label3.pack()   frame2.pack()   label3.pack()   frame1.pack()   frame1.mainloop()  
  • 継承の概念   Python  入門   275  
  • 継承   Python  入門   276   •  クラスが別のクラスの特性を引き継ぐための機能   •  元のクラスをスーパークラス(親クラス)と呼ぶ   •  派生されたクラスをサブクラス(子クラス)と呼ぶ   親クラス(車)   子クラス(ジープ)   子クラス(スーパーカー)  
  • TKinter  の継承   •  Label  や  Bu7on  は継承で作成されている   •  継承元で根本の描画処理などを実装   •  Label  や  Bu7on  は差分のみ実装   Python  入門   277   Widget   Bu7on   Hello  World   描画の仕組みの実装   ボタン特有の機能の実装   ラベル特有の機能の実装  
  • 継承のメリット   •  子クラスの実装を単純化できる   •  クラス自体もそれを使う側もコードの保守性が増す   Python  入門   278   Label  も  Bu7on  も  Frame  の   子要素となることができる   Label  と  Bu7on  のスーパークラスが   Frame  の子要素となることができる  
  • Tkinter  の自作クラス   •  継承してクラスを作ると、Frameにいれること ができるパーツが作れる   Python  入門   279   Frame  Frame   継承していない場合   Frame  にいれられない   継承している場合   Frame  にいれられる  
  • 継承されたクラスの特徴   •  親クラスのメンバ変数にアクセス可能   •  親クラスのメソッドにアクセス可能   •  子クラスのコンストラクタ内で親クラスのコン ストラクタを呼び出す   Python  入門   280   親クラス  子クラス   継承のイメージ  
  • 継承クラスの作成   Python  入門   281  
  • クラス継承の作法   クラスの宣言   class  子クラス(親クラス):     子クラスのコンストラクタで親クラ スのコンストラクタを呼び出す   親クラスのコンストラクタの引数 は全て指定。     子クラスは親クラスの変数とメ ソッドにアクセス可能   (上書きも可能)   Python  入門   282   class  Parent:          text  =  ""          def  __init__(self,  text):                  print("Parent.__init__()")                  self.text  =  text            def  get_text(self):                  return  self.text     class  Child(Parent):          def  __init__(self,  text):                  print("Child.__init__()")                  Parent.__init__(self,  text)            def  double(self):                  self.text  *=  2  
  • 演習   •  クラス  Counter  を継承して  Counter2  を作る   •  Counter2  に以下のメソッドを実装する            -­‐  double:  現在のカウンターの値を2倍する            -­‐  clear_counter:  カウンターを初期化する   Python  入門   283   class  Counter:          value  =  -­‐1          def  __init__(self,  value):                  self.value  =  value            def  get_value(self):                  return  self.value            def  count_up(self):                  self.value  +=  1  
  • Tkinter  の  Bu7on   •  ボタンを押された際に特定の関数(メソッド)を呼び出す   •  Bu7on(command=「呼び出す関数(メソッド)名」)   Python  入門   284   import  Tkinter  as  tk     def  clicked():          print("clicked")     bu7on  =  tk.Bu7on(text="Click",  command=clicked)   bu7on.pack()   bu7on.mainloop()   >>>     clicked   click  する   表示される  
  • 継承を使わないカウンターの実装   Python  入門   285   import  Tkinter  as  tk     class  Counter:          label  =  None          value  =  -­‐1            def  clicked(self):    #  Click時に呼ばれる                  self.value  +=  1                  self.label.configure(text=self.getText())            def  getText(self):    #  表示する文字を作成                  return  "Count:{}".format(self.value)        def  __init__(self,  value):                  self.value  =  value                  frame  =  tk.Frame()                  font  =  ("Helevecca",  32,  "bold")                  self.label  =  tk.Label(frame,                                                              text=self.getText(),                                                              font=font,  bg="red")                  bu7on  =  tk.Bu7on(frame,  text="Click",                                                        command=self.clicked)                  self.label.pack()                  bu7on.pack()                  frame.pack()                  frame.mainloop()     c  =  Counter(0)  
  • 継承を使うカウンタの実装   Python  入門   286   import  Tkinter  as  tk     class  Counter(tk.Frame):          label  =  None          value  =  -­‐1            def  clicked(self):                  self.value  +=  1                  self.label.configure(text=self.getText())            def  getText(self):                  return  "Count:{}".format(self.value)        def  __init__(self,  master=None,  value=0):                  tk.Frame.__init__(self,  master)                  self.value  =  value                  font  =  ("Helevecca",  32,  "bold")                  self.label  =  tk.Label(self,                                                              text=self.getText(),                                                              font=font,  bg="red")                  bu7on  =  tk.Bu7on(self,  text="Click",                                                        command=self.clicked)                  self.label.pack()                  bu7on.pack()     c  =  Counter(value=0)   c.pack()   c.mainloop()  
  • •  クラス  Counter  自身も  Widget   Python  入門   287   継承を使うカウンタの実装   frame  =  tk.Frame()   c1  =  Counter(master=frame,  value=0)   c2  =  Counter(master=frame,  value=5)     c1.pack(side=tk.LEFT)   c2.pack(side=tk.LEFT)   frame.pack()   frame.mainloop()  
  • 演習   •  継承を使ったクラス  Counter  に  Clear  ボタンを 追加する   •  Clear  ボタンをクリックするとカウンタを初期値 に戻す   Python  入門   288  
  • 例外処理   Python  入門   289  
  • 例外   •  プログラムの継続実行を妨げる意図しない挙動   Python  入門   290   1:  2     Traceback  (most  recent  call  last):      File  "/Users/yuichi/Documents/python-­‐training/excepcon.py",  line  3,  in            b  =  5  /  0   ZeroDivisionError:  integer  division  or  modulo  by  zero   a  =  1  +  1   print("1:  "  +  str(a))   b  =  5  /  0   print("2:  "  +  str(b))   c  =  a  +  1   print("3:  "  +  str(c))   0  での割り算。ここで例外が発生し、処理を中断!!   0  での割り算は数学的に許容されない   Python  が例外を発生させる  
  • 例外   •  プログラム自身に起因する例外   – 0での割り算   – 配列長外にアクセス   •  プログラムの外の環境に起因する例外   – ネットワークに接続できない   – ユーザからの入力が不正な値   Python  入門   291  
  • 例外の対処方法   •  例外の「キャッチ(補足)」   Python  入門   292   a  =  1  +  1   print("1:  "  +  str(a))   b  =  5  /  0   print("2:  "  +  str(b))   c  =  a  +  1   print("3:  "  +  str(c))   例外を補足した場合の処理   例外が発生   例外を補足  
  • try/except   •  例外の補足には  try,  except  を利用   •  補足する  Except  は例外の種類に対応してい る必要がある   Python  入門   293   try:          例外が発生する可能性のある処理   except  エラークラス:          例外処理     ※  エラークラスは先の「例外の種類」のクラス  
  • try/except   Python  入門   294   try:          a  =  1  +  1          print("1:  "  +  str(a))          b  =  5  /  0          print("2:  "  +  str(b))          c  =  a  +  1          print("3:  "  +  str(c))   except  Excepcon:          print("Error  happens")     print("Done")   1:  2   Error  happens   Done  
  • NETWORK(おまけ)   Python  入門   295  
  • 通信の手順   Python  入門   296   ソケットをオープン   通信を待つ  ソケットをオープン   通信を開始   Hello   相互にやりとり   ソケットをクローズ   クライアント   サーバ  
  • ソケットを使ったサーバ   •  ソケットをオープンしてデータを待つ   •  ソケットには受信IPとポートを指定する   Python  入門   297   import  socket     IP  =  socket.gethostbyname(socket.gethostname())   PORT  =  12345   BUFF_SIZE  =  2048     ssock  =  socket.socket(socket.AF_INET,                                              socket.SOCK_STREAM)   ssock.bind((IP,  PORT))   ssock.listen(10)     while(True):          (csock,  ip)  =  ssock.accept()          while(True):                  data  =  csock.recv(BUFF_SIZE)                  if(not  data):                          break                  print(data)      
  • ソケットを使ったクライアント   •  ソケットをオープンしてデータを送る   •  ソケットには宛先IPとPORTを指定   Python  入門   298   import  socket     IP  =  socket.gethostbyname(socket.gethostname())   PORT  =  12345   BUFF_SIZE  =  2048     csock  =  socket.socket(socket.AF_INET,  socket.SOCK_STREAM)   csock.connect((IP,  PORT))   csock.send("Hello  World")   csock.close()  
  • サンプルプログラム   •  チャット用アプリケーション   Python  入門   299   自分のIP   宛先IPとメッセージ   送信元IPとメッセージ  
  • 演習   •  チャット用のアプリケーションには送信先に問 題があるとクラッシュするという問題がある。 これを解決する。   •  ヒント:  クラッシュは例外に対処できていない ため発生している   Python  入門   300  
  • Python  入門   301  
  • Next  Plan   •  Network  Programming   •  GUI  Programming(tkinter,  wxPython,  Qt)   •  Big  Data  Broker   •  Python  on  Nexus   •  XML,  json,  Rest  API   •  Advanced  Object  Oriented  Programming   •  Funcconal  Programming   •  Algorithm   Python  入門   302  
  • ボツ  スライド   Python  入門   303  
  • メソッドの属性   •  メソッドには複数種類ある   •  通常のメソッド:  第3回で扱ったもの   •  クラスメソッド   •  スタティックメソッド   Python  入門   304  
  • クラスメソッド   Python  入門   305  
  • スタティックメソッド   Python  入門   306  
  • クラスの継承   Python  入門   307  
  • 名前空間(NAMESPACE)   Python  入門   308  
  • 名前空間   •  変数名などの重複を防ぐための仕組み   Python  入門   309   10万行以上の巨大なプログラム   ....   global  変数  index     ....   global  変数  index   違う目的の変数を複数回定義(名前が衝突)   意図せず変数の中身が書き換わる  
  • 名前空間   •  変数名などの重複を防ぐための仕組み   Python  入門   310   10万行以上の巨大なプログラム   ....   global  変数  index1     ....   global  変数  index2     ....   global  変数  index3   10万行以上の巨大なプログラム   ....   変数  index   ....   ....   変数  index   ....   ....   変数  index   ....   ....   変数  index   ....   名前空間なし:  変数名で衝突を防ぐ   名前空間あり:  衝突範囲が狭い   名前空間A   名前空間B   名前空間C   名前空間D  
  • 名前空間   •  スコープ   •  代表的なスコープ   1.  ビルトインスコープ   2.  グローバルスコープ   3.  Classや関数のスコープ   4.  for文などのローカルスコープ   Python  入門   311  
  • クロージャ   •  関数を生成する関数。別名はファクトリ関数   •  似たような関数を大量生成する際に使う   Python  入門   312   def  getPrintFunccon(string):          def  f():                  print(string)          return  f     hello  =  getPrintFunccon("hello")   python  =  getPrintFunccon("python")   cisco  =  getPrintFunccon("cisco")   hello()   python()   cisco()  
  • try/except   •  複数の  except  節を使って細かい制御が可能   Python  入門   313   try:          例外が発生する可能性のある処理   except  エラークラス1:          例外処理1   except  エラークラス2:          例外処理2     ※  エラークラスは先の「例外の種類」のクラス  
  • try/except/else   •  else節で「例外がない場合の処理」を書ける   Python  入門   314   try:          a  =  1  +  1          print("1:  "  +  str(a))          b  =  5  /  0          print("2:  "  +  str(b))          c  =  a  +  1          print("3:  "  +  str(c))   except  Excepcon:          print("Error  happens")   else:          print("No  problem")   print("Done")   try:          a  =  1  +  1          print("1:  "  +  str(a))          #b  =  5  /  0          #print("2:  "  +  str(b))          c  =  a  +  1          print("3:  "  +  str(c))   except  Excepcon:          print("Error  happens")   else:          print("No  problem")   print("Done")   1:  2   Error  happens   Done   1:  2   3:  3   No  problem   Done  
  • 例外を発生させる   Python  入門   315   try:          print(1)          raise  Excepcon("Hello")          print(2)   except  Excepcon:          print("Error  happens")   print(3)   1   Error  happens   3  
  • デバッグ   Python  入門   316  
  • デバッグの役割   •  プログラムの問題を発見する   – プログラムを運用させる前に発見し修正するため   – 運用後に見つかった問題を修正するため   Python  入門   317  
  • プリントデバッグ   •  一番手軽にできる基本的な  debug  手法     Python  入門   318  
  • モジュールレベルのデバッグ   if  __name__  ==  "__main__":          モジュールのテストコード   Python  入門   319  
  • assercon   •  デバッグに特化した rise  処理   Python  入門   320  
  • PyUnit  によるユニットテスト   Python  入門   321  
  • pdbによるデバッグ   Python  入門   322  
  • デバッグ処理   Python  入門   323  
  • オブジェクト指向(発展編)   Python  入門   324  
  • オブジェクトツリー   Python  入門   325  
  • ガーベジコレクション   Python  入門   326  
  • 型チェック   Python  入門   327  
  • ポリモーフィズム   Python  入門   328  
  • ダックタイピング   Python  入門   329  
  • リスト発展編   Python  入門   330  
  • map  関数   •  List  の各要素に対して関数を適用する関数   Python  入門   331   N  =  10   def  double(x):          return  x  *  2   list1  =  map(double,  range(N))     list2  =  []   for  i  in  range(N):          list2.append(i*2)     print(list1)  =>  [0,  2,  4,  6,  8,  10,  12,  14,  16,  18]   print(list2)  =>  [0,  2,  4,  6,  8,  10,  12,  14,  16,  18]   map(関数,  リスト)  
  • filter  関数   •  List  の各要素に対して関数を適用し、True  に なった要素のみで  List  を作る   Python  入門   332   def  isOver0(x):          return  x  >  0     list1  =  range(-­‐5,5)   list2  =  filter(isOver0,  list1)     print(list1)  =>  [-­‐5,  -­‐4,  -­‐3,  -­‐2,  -­‐1,  0,  1,  2,  3,  4]   print(list2)  =>  [1,  2,  3,  4]    
  • lamda式   •  関数をその場で定義するための手法   •  関数を返す   Python  入門   333   lamda(引数):  処理   >>>  power  =  lambda  x:  x**2   >>>  list1  =  range(10)   >>>  map(power,  list1)   [0,  1,  4,  9,  16,  25,  36,  49,  64,  81]     >>>  map(lambda  x:  x**2,  range(10))   [0,  1,  4,  9,  16,  25,  36,  49,  64,  81]  
  • reduce   •  「たたみ込み」と呼ばれる処理   Python  入門   334   >>>  getSum  =  lambda  x,  y:  x+y   >>>  reduce(getSum,  range(10))   45  
  • yield   Python  入門   335  
  • リスト内包表記   •  if  文を使って要素を絞れる   Python  入門   336   >>>  [x**2  for  x  in  range(10)  if  x  %  2  ==  0]   [0,  4,  16,  36,  64]     1.  リストから偶数のみ抜き出す   2.  偶数のリストに対して  2乗する処理を適用   [処理  for  要素  in  リスト  if  条件式]   リストの要素から条件式がTrueになるもののみ抽出   それに対して処理を適用  
  • Python  入門   337  
  • ドキュメント   Python  入門   338  
  • dir   •  クラスやパッケージの中身を確認する関数   Python  入門   339   >>>  dir(str)   ['__add__',  '__class__',  '__contains__',  '__dela7r__',  '__doc__',  '__eq__',   '__format__',  '__ge__',  '__geta7ribute__',  '__gectem__',  '__getnewargs__',   '__getslice__',  '__gt__',  '__hash__',  '__init__',  '__le__',  '__len__',  '__lt__',   '__mod__',  '__mul__',  '__ne__',  '__new__',  '__reduce__',  '__reduce_ex__',   '__repr__',  '__rmod__',  '__rmul__',  '__seta7r__',  '__sizeof__',  '__str__',   '__subclasshook__',  '_forma7er_field_name_split',  '_forma7er_parser',   'capitalize',  'center',  'count',  'decode',  'encode',  'endswith',  'expandtabs',  'find',   'format',  'index',  'isalnum',  'isalpha',  'isdigit',  'islower',  'isspace',  'isctle',  'isupper',   'join',  'ljust',  'lower',  'lstrip',  'parccon',  'replace',  'rfind',  'rindex',  'rjust',   'rparccon',  'rsplit',  'rstrip',  'split',  'splitlines',  'startswith',  'strip',  'swapcase',  'ctle',   'translate',  'upper',  'zfill']  
  • help   •  man  コマンドに近い関数   Python  入門   340   >>>  help(int)   Help  on  class  int  in  module  __builcn__:     class  int(object)    |    int(x=0)  -­‐>  int  or  long    |    int(x,  base=10)  -­‐>  int  or  long    |        |    Convert  a  number  or  string  to  an  integer,  or  return  0  if  no  arguments          |    Methods  defined  here:    |        |    __abs__(...)    |            x.__abs__()    abs(x)    |        |    __add__(...)    |            x.__add__(y)    x+y  
  • PYTHON  ON  NEXUS   Python  入門   341  
  • Python  Script  on  Nexus   •  Nexus  内で特定の処理をさせることが可能   •  機器の状態に応じたコマンドの発行   •  定期的な複雑なログの取得     Python  入門   342  
  • 強力なEEMとしての利用   •  従来の  EEM  のイベントで  python  script  を呼び出す   •  show  コマンドの発行、解析を  python  にさせる   •  結果に応じてclear  mac  や、shut/no  shutコマンドの発行   Python  入門   343  
  • Python  Script  on  Nexus   VPC+  障害時における  RIB  と  FIB  Inconsistency  解消   Python  入門   344   N7K-­‐1   SID:71   N6K-­‐1   SID:61   N7K-­‐2   SID:72   N6K-­‐2   SID62   Z   Z   N7K-­‐A(OK)   N7K-­‐B(OK)   IXIA-­‐1   IXIA-­‐2   Z   Z   Z   Z   FP  NETWORK   keep  alive   keep  alive   secondary   primary   事象(2013年末に発生)   N7K1-­‐2  においてVPC+の冗長構成が   壊れた際にFabricPath  Route  の  FIB  が   更新されない。   その結果として間違ったスイッチに   転送を継続し続けて  Dropが発生     解消法   VPC+  の  secondary  側のFP網に接する   物理リンクを  shut  させることで  FIBを   強制的に更新させる  
  • Python  入門   345   MKI-­‐VDC2#  show  file  boomlash:if-­‐mon.py   #  VPC  の状態確認コマンドを発行。VPC  のステートを得る   shVpc  =  cli  ("show  vpc")   shVpcLines  =  shVpc.splitlines()   stateList  =  shVpcLines[11].split()   vpcState  =  stateList[len(state_list)-­‐1]     #  もしVPCが  secondary  なら、特定インタフェースを落とす   if  (vpcState  ==  "secondary"):          print("shutdown  fp  interface")          cli("conf  t  ;  int  e7/9,e9/9  ;  shut")   EEM  で  peer-­‐link  のダウンを検出   (コンソール表示をチェック)   検出したら、以下のスクリプトを実行  
  • 検証での  python  script  の利用   •  多量のコマンドの出力結果を何度も得る   •  定期的にコマンドを発行   Python  入門   346   手元のメモ帳に取得コマンド一覧を作って流し込む    -­‐  作るのが簡単    -­‐  融通が効かない(書き出しファイル名の変更などが大変)     python  script  を呼び出す    -­‐  作るのが若干大変    -­‐  修正が簡単    -­‐  融通が効く  
  • FPの検証プログラム   •  実際に検証で使ったプログラムのCSC版   Python  入門   347   Python  Script  を利用したログの取得方法   h7ps://suppormorums.cisco.com/docs/DOC-­‐39662  
  • Python  入門   348   if  __name__  ==  "__main__":          if(len(sys.argv)  ==  4):                                  fileName  =  sys.argv[1]                  sleepInterval  =  int(sys.argv[2])                  sleepCount  =  int(sys.argv[3])                                    print("taking  Rate  logs")                  writeTime(fileName)                  writeRateLogs(fileName,  sleepInterval,                                sleepCount)                  print("taking  FP  logs")                  writeTime(fileName)                  writeFPLogs(fileName)                  writeOldLogs(fileName)   def  makeEcho(string,  fileName):          return  'echo  \"'  +  string  +  '\"  >>  boomlash:'  +  fileName     def  makeShow(string,  fileName):          return  string  +  "  >>  boomlash:"  +  fileName     def  makeCombi(string,  fileName):      #コマンドの時刻,  名前,  結果を書く          return                    makeShow("show  clock",  fileName)  +  "  ;"  +                    makeEcho("#"  +  string,  fileName)  +  "  ;"  +                    makeShow(string,  fileName)  +  "  ;"  +                    makeEcho("",  fileName)     def  writeRateLogs(fileName,  interval,  n):      #  Rate  を定期測定          for  i  in  range(0,  n):                  cli(makeCombi(SHOW_RATE_BETWEEN_N6K_AND_N7K,  fileName))                  cli(makeCombi(SHOW_RATE_AT_PEER_LINK,  fileName))                  cli(makeEcho("",  fileName))                  cme.sleep(n)                     def  writeFPLogs(fileName):      #  コマンドの羅列          cli(makeCombi(SHOW_FP_ISIS_ROUTE,  fileName))          cli(makeCombi(SHOW_FWM_L2MP_NEXT_HOP,  fileName))          cli(makeCombi(SHOW_FWM_HWSTM,  fileName))          cli(makeCombi(SHOW_FWM_L2MP_ROUTE,  fileName))          cli(makeCombi(SHOW_FWM_MAC_HSRP_VMAC,  fileName))          cli(makeCombi(SHOW_FWM_L2MP_VLAN,  fileName))          cli(makeCombi(SHOW_FWM_L2MP_TOPO_0,  fileName))  
  • ライブラリ紹介   Python  入門   349  
  • 日付   Python  入門   350  
  • 数学   Python  入門   351  
  • スレッド   Python  入門   352  
  • データベース   Python  入門   353  
  • ネットワークプログラミング   Python  入門   354  
  • webアプリケーション   Python  入門   355  
  • GUI     Python  入門   356  
Fly UP