befs_anneの日記

雰囲気でネットワークをやっている

【競プロ】defaultdictとCounter

概要

データサイエンスに関する本を買ってみたものの、サイエンスするための基礎知識が圧倒的に足りておらず身が入らない始末。サイエンス関連のアウトプットはひとまず置いといて、「2章 Python速習コース」の中で競プロに役に立ちそうなテクニックをメモして、3,200円 + 税はムダじゃなかったと思いたいがための記事。

ゼロからはじめるデータサイエンス ―Pythonで学ぶ基本と実践

ゼロからはじめるデータサイエンス ―Pythonで学ぶ基本と実践

defaultdict

文字列やリストに含まれている要素の種類をカウントする時、defaultdictクラスを使うとシンプルに書ける。

from collections import defaultdict

document = "zabbix"
count_dict = defaultdict(int) # 引数は初期値(int()は0らしい)

for cal in document:
        count_dict[cal] += 1

print(dict(count_dict))
# {'z': 1, 'a': 1, 'b': 2, 'i': 1, 'x': 1}

素で書くと、キーが既にある場合と新規の場合の両方を考慮しなくちゃならない。

# defaultdict使わない版

document = "zabbix"
count_dict = {}

for cal in document:
    if cal in count_dict:
        count_dict[cal] += 1
    else:
        count_dict[cal] = 1

print(count_dict)
# {'z': 1, 'a': 1, 'b': 2, 'i': 1, 'x': 1}

初期値はintだけではなく、dictや別の関数も指定可能。

Counter

defaultdictの「初期値指定できない代わりに短く書ける版」みたいな感じ。

from collections import Counter

document = "zabbix"
count_dict = Counter(document)

print(dict(count_dict))
# {'z': 1, 'a': 1, 'b': 2, 'i': 1, 'x': 1}

【競技プログラミング】標準入力の受け付けと各桁の合計

概要

競技プログラミングの復習。

近況

直近の記事から早2ヶ月。CCIEの勉強もロクにせず、僕は『ゼロからはじめるデータサイエンス』の写経もそこそこに、CTFや競技プログラミングに手を付けていた……。

ゼロからはじめるデータサイエンス ―Pythonで学ぶ基本と実践

ゼロからはじめるデータサイエンス ―Pythonで学ぶ基本と実践

Pythonでの標準入力の受け付け

「競プロやってみよう」と思い立ったその日から、AtCoder Programming Gude for BeginnersでC++のお勉強をしてたんだけど、身の回りの競プロに勤しんでいる人たちがPythonでやってるのを見て、自分もPyhtonistaとして参戦することを決意した(仕事でも使ってるし)。

先日のCodeFlyerが初参戦。結果は2完。事前にPythonでの練習をしていなかったので、問題以前に標準入力の受け付け方が分からず、慌ててググるなど。

Pythonで競技プログラミングする時に知っておきたいtips(入出力編)

input()

標準入力から1行読み込んで、末尾の改行を除いて標準出力に出す。複数行を読み込みたい場合、ケースに合わせて工夫が必要(行数が固定ならfor in range(行数)でリスト内包する、など…引用記事中にケース毎の説明があるのでいったん割愛)。

$ cat input.py 
N = input()

print("input is " + N)

# 文字列型の場合
$ echo "ABC" | python input.py 
input is ABC
$

# 数値型の場合
$ echo 123 | python input.py 
input is 123
$

# 複数行の場合
$ python -c "print('THIS\n IS\n TEST')" | python input.py 
input is THIS
$ 

各桁の合計を求める

……必要のある問題が出てきて、これも先人の知恵を頼った。

http://suzu6.hatenablog.com/entry/2017/09/22/004355

def digitSum(n):
    s = str(n) # 1
    array = list(map(int, list(s))) #2
    return sum(array) #3
  1. 値nをstr()で文字列に変換する
  2. map()でsを1文字ずつint型に変換してリスト(array)に追加する
  3. sumでarrayの合計を算出し、returnする

map()

mapは第1引数に関数、第2引数にイテレータを指定して、第2引数の各要素を引数として第1引数を実行した結果をイテレータとして返す関数っぽい。どうやらPython3の場合、そのままだとmapオブジェクト(print()すると「」みたいなのが出力される)なので、リストとして扱いたい場合はlist()で包んでやればよい。

2. 組み込み関数 — Python 3.6.5 ドキュメント

引用したブログ記事内にも説明がある通り、リスト内包で同じことができる。

array = list(int(i) for i in list(s))

2018年(度)の抱負

はじめに

さっそく約束を破っていて幸先が悪い。

技術

ネットワーク

実務ではコアな技術はあまり必要なくCCNPも失効したので、CCNP再取得するぐらいならCCIEを取ってしまいたい。Labスキル的にも金銭的にも厳しいけど、Writtenならなんとかなるだろう(フラグ

年内でがんばります。VIRLも契約するよ。

Linux(低レイヤ)

数年前までネットワークのことしか分からず、検証でSyslogサーバーやNTPサーバーを立てる必要が出てくるとガクガク震えだすという始末だったんだけど、環境の変化(サーバーをいじらないと仕事ができない)や周囲の助けで最低限のことはできるようになった。自分を助けられるようになってきたので、他人を助けられるレベルにまで引き上げていきたい。とは言え、仕事で触れるミドルウェアはたいてい周りも自分と同等かそれ以上に触れる。そんな折に手にとったのが「Linuxのしくみ」。

[試して理解]Linuxのしくみ ~実験と図解で学ぶOSとハードウェアの基礎知識

[試して理解]Linuxのしくみ ~実験と図解で学ぶOSとハードウェアの基礎知識

「パッケージ管理システムすらややこしくて苦手なのに、低レイヤなんてやってられるかー」と思ってたけど、この本の分かりやすいのなんの。色んなミドルを触る機会もないし、低レイヤの知見を組織に提供できるようになる方向でLinuxに詳しくなることにした。とりあえずお勉強野郎になって、サーバーのサイジングの時とか「同じようなサーバーを○コア、メモリ○GBで作ったから今回も一緒で~」みたいな根拠をチケットに書いてたのをもうちょっと内容を変えるところから始めようと思う。

セキュリティ

BurpやOWASP ZAPあたりをモノにする。CTFも低レイヤの勉強がてらやっていく。仕事で役に立つ機会は(今のところ)ないので、趣味がてら続けたい。

仕事

担当するプロダクトをモノにする

仕事で使うプロダクトはその仕事の範囲に似つ様なことしか調べなかったけど、ドキュメント全部読んで仕事に関係のないことまで身につけるようにする。

カネを稼ぐ

カネを稼ぎたい。オリンピック後は地獄だと聞いているので今のうちに稼ぎ逃げしたい。

vagrant upで生成された秘密鍵が666なせいでVMにSSHできない

……ということが発生した。

環境

事象

vagrant sshが失敗してパスワード認証に切り替わってしまう原因が分からず、sshの-p、-iオプションでそれぞれポート番号と秘密鍵を指定してログイン試行したところ、以下のエラーメッセージが出力されて同様にパスワード認証に切り替わった。

Permissions 0666 for '/home/shino/vagrant/testdir/.vagrant/machines/testhost/virtualbox/private_key' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
bad permissions: ignore key: /home/shino/vagrant/testdir/.vagrant/machines/testhost/virtualbox/private_key
Password:

秘密鍵を666にするのはオープンにも程があるでしょう!」とのことなので実際に確認してみたら本当に666だった。

-rw-rw-rw- 1 shino shino 1679 Jan 28 22:46 /home/shino/vagrant/testdir/.vagrant/machines/testhost/virtualbox/private_key

対策

chmod 600 /home/shino/vagrant/testdir/.vagrant/machines/testhost/virtualbox/private_keyして解決。

※参考

yachibit.hatenablog.jp

調査は頓挫

他の方が公開しているVagrantfileで発生した事象で、原因を突き詰めようと自分で簡単なVagrantfileを作ってupしてみたら600で生成されていた。他に目的があってVagrantに手を付けているので、原因究明は置いておいて一旦対策だけメモしておく。バグではなくVagrantへの理解が足らないだけな気もしている。

「WSLのVagrantからWindowsのVagrantが見えない」的なエラーの解消

概要

タイトルの通り。最初は「WSLとWindowsVagrantのバージョンが違う」というエラーが出ていて、Windows側をWSLと同じバージョンまで上げたらWindows側のVagrantのバージョンがUnknownになった。エラーメッセージに従って環境変数をいじるなどしたが効果なし。

解消方法

(bashではなく)コマンドプロンプトで以下を実行したら解決したっぽい。

vagrant plugin repair

実際に出力されたメッセージとかもメモしておきたかったけど、コマンドプロンプトはログが残せないのが不便……。

WSL + Cmderがいい感じなので、CmderのデフォルトターミナルをWSLにする

概要

WindowsコマンドプロンプトUbuntuを触るのにも慣れてきた頃、Cmderという100倍使いやすいターミナルが存在することを知って驚愕している。

qiita.com

この記事ではWSLを開くTaskを作るところまでを紹介しているが、このままだとデフォルトターミナルがコマンドプロンプトのままなので、これをUbuntuに変更する。

方法

至って簡単。

WSLを開くタスクを作成

  • タスクバーのメニューからSettingsをクリックし、左側のメニュー内のTasksをクリックする。
  • 「+」ボタンをクリックして新しいTaskを作成する。Task名はご自由に。
項目 内容
Task Parameters -icon "%USERPROFILE%\AppData\Local\lxss\bash.ico"
Commands C:\Windows\System32\bash.exe -cur_console:p

作成したTaskをStartup optionsに追加

  • 左側のメニューからStartupをクリックする。
  • 「Specified named task」のラジオボタンを選択し、さっき作成したTaskを選択する。
  • 右下のSave settingsをクリックする。

おわりに

ターミナルは色々あるようで、どれを使ったら良いのか迷う。不満もないので、しばらくはCmderを使ってみる。

qiita.com

3年越しでネットワークスペシャリストに合格した人の反省

概要

3回目の挑戦にしてようやく、合格率13.6%の壁を乗り越えてネットワークスペシャリスト試験に合格した。その振り返り。

結論

とにかく午後Ⅱをやれ

勉強時間

勉強時間はStudyplusで記録していたのだが、勉強開始日から最後の9/27の記録分までで37時間だった。試験日前日まで根詰めてやってたので、多分トータルで60時間には達しているはず。そのうえ延べ3年かかっていることと、本業がネットワークであることも考えると計り知れない。ただ、合格に延べ3年の時間 + 実務経験は全然必要なくて、今年の60時間分の勉強と、実務で培った知識だけでも合格できたはず。つまり、合格できなかった2年間にやってた勉強はネスペの合格に寄与するものではなかったのだと思う。

合格の要因

前回、前々回と不合格の憂き目に遭ったのは、午後Ⅱ対策をめんどくさがってしなかったから。そして今回合格できたのは、午後Ⅱ対策をきちんとしたから。これに尽きる。

午後Ⅱとそれ以外

午前Ⅰ、午前Ⅱ、午後Ⅰおよび午後Ⅱそれぞれで問われる能力は以下のように異なる。

  • 午前Ⅰ: ITに関する広く浅い知識
  • 午前Ⅱ: ある技術領域における専門的な知識
  • 午後Ⅰ: ある技術領域における専門的な知識 + 業務での利用
  • 午後Ⅱ: ある技術領域における専門的な知識 + 業務での利用(応用) + 「試験勉強」

ある程度の年数IT業界にいて、「自分は地頭は悪くないほうだ」っていう人は、無勉でも案外午後Ⅰ合格まではこじつけられる。

しかし、午後Ⅱは違う。午後Ⅱは知識と実務経験ではどうにもならない、ガチガチの「試験勉強」が絶対に必要だと思う。

午後Ⅱ対策で養わなければならない能力

午後Ⅱの問題は、大きく3種類に分かれると思う。複数の要素が含まれる問題もある。実例は全て平成29年午後Ⅱ問Ⅰから。

  1. 技術知識を問う問題
  2. 思考力・想像力を問う問題
  3. 要件の理解度を問う問題

技術知識

1は、問題のタイプで言うなら午後Ⅰまでに出題される問題とそう変わらない。例えば設問2はほぼ1ページまるまる埋め尽くすシーケンス図に面食らうが、実際はARPのやり取りがほとんどなので、ARP解決の流れを知っていれば解ける。ただし、OpenFlowスイッチが挟まっているせいでパケットの流れが複雑なので、ていねいに追う必要がある。応用力を試すためのひねりを加えて問題の難易度を上げるのは、午後Ⅱの常套手段だ。

思考力・想像力

2は、よく分からないけどそれっぽいこと書いておいたら部分点が狙える問題。例えば設問4(5)はパブリッククラウドにおいて国外リージョンを利用した場合の(国内リージョン利用と比較した)メリットを問われており、「国外だから日本で大地震が起きても関係ねーな」ぐらいのことを想像して書ければ点がもらえる。

午後Ⅱ対策に手をつけたがらなかった理由のひとつとして、この手の問題の自己採点のしようがないところがある。自分としては間違っていないつもりだけど、回答例とは全然違う、みたいなことが多くてモチベーションが減退する。いつの問題だったか忘れたけど、「このような作業ミスを防ぐにはどうすればよいか?」という問題の回答が「手順書通りに作業するよう徹底させる」で、仕組みから解決する回答を記載した私はげんなりした記憶がある。これに関しては「そういうもの」だと思うしかない。私のようにTwitterで「問題作ったやつ現場知らねーだろ」などと文句を言って手を止めてしまうよりも、「回答とは違うけど、俺の回答もまた真だろ」と思って進めたほうが効率的にも精神衛生的にも良い。結局当日は自分が思うままの回答を書くほかないし、厳密な正否も分からないのだから。

要件の理解

午後Ⅱはとにかく問題文が長く、問題で問われる問題がパラパラと散りばめられている。1回読んで全て覚えられるような超人以外は、3のような問題に直面した時に問題文から必要な要件をどれだけ早く見つけるか、という訓練が必要だ。そしてそれを可能にする第一歩は、午後Ⅱを繰り返し解いて「3のような問題は問題文中のどこかに必ず答えが隠れている」という確信を得ることだと思う。今年の問1で言うならば、設問4(1)がそれに当たると思う。WebサーバーがLBの配下にいることを把握できれば、すべきことは自ずと分かる。

要件の理解を養うことは、いわば狭義の午後Ⅱ対策と言える。それなりの知識と業務経験がありながらも2年連続で不合格だったのは、結局のところこれを怠っていたからだと反省している。

短時間で設問を選択する能力

忘れてはならないのがこれ。午後Ⅱは2つの問から1つ選択し回答する。試験時間は2時間と長めだが、各設問の問題を丁寧に読んでから決めるのはさすがに時間がもったいない。各問の冒頭や使われている用語から傾向を把握するのは難しくないが、そのうえでどちらの問を解くかを決めるには、日頃の勉強を通して自分の得手不得手を知っておく必要がある。今回は問1がSDN(OpenFlow)とパブリッククラウド利用、問2はIEEE 802.11acエンタープライズネットワーク設計をテーマとした問題で、私は前者を選んだ。SDNやパブリッククラウドは興味があって触ったり調べたりしていたのであまり抵抗がなかった反面、無線や社内ネットワークに使われる認証系の技術は明らかに弱く、即座に決断できた。

午後Ⅰまでの対策

午後Ⅰまでの勉強を全くやらなかったかというと、もちろんそんなことはない。しかし、今年に限った話をすれば、費やした時間は(午前Ⅰはセスペ合格で免除なので)午前Ⅱ、午後Ⅰのぶんを合計しても午後Ⅱ対策に充てた時間よりも少ない。過去2年は午後Ⅰまでの対策を結構やっていたが、答えられる問題を解いて正解する快感におぼれていただけだったような気がする。ある程度の知識と実務経験がある人が、勉強時間を確保できないまま試験まであとⅠ週間になってしまった…みたいなシチュエーションならば、午後Ⅱ対策を最優先にしていい。

勉強方法

午後Ⅱどころかたぶんネスペ、IPA試験に限った話ではないのだが、とにかく1冊の問題集(過去問)を完璧になるまで解く。最初の1~2周は時間がかかるが、慣れてくれば答えを覚えるので回転が速くなる。答えを覚えることに罪悪感を覚える必要はないが、その答えになる理由も一緒に覚えること。分からない問題はどれだけ考えても分からないと割り切って、早めに答えを確認する。これで午後Ⅱを各問3~4周した。

さいごに

時間がかかった分よろこびもひとしおだが、本来かける必要のない時間だったということを考えると反省の多い3年間だった。ある程度基礎知識のある分野の高度試験を受ける時は、優先的に午後Ⅱ対策に取り組んで、最短距離で合格を目指そうと思う。

極端なことを言えば、午後Ⅰまでで問われる能力のほとんどは午後Ⅱでも必要なので、午後Ⅱに9割の時間を費やしても案外合格できるかもしれない。次回の試験で、自分自身で検証してみたい。