paloma blog

NWエンジニアやってます。主に自宅環境のお遊びを書きます。Pythonもちょっと。タイトルは好きなカクテルから。

パルスのファルシのルシがコクーンでパージをランダムで展開する

インフラ屋としてシェル芸勉強中の身ですが、こんなtweetが流れてきました。

f:id:paloma69:20171223112858p:plain

このtweetを見てなぜかこれを思い出したので、
(FF13ですよね。未プレイですが)

dic.nicovideo.jp

この文をpythonでやってみようと思ったのがこちら。

ちなみに2点候補があるようですが私は未プレイのため個人的に語感のいい1を正解とします。

  1. パルスのファルシのルシがコクーンでパージ
  2. パルスのファルシのルシがパージでコクーン
#! python3

import random

pulse = ['パルス', 'ファルシ', 'ルシ', 'パージ', 'コクーン']

shuffle = random.sample(pulse, 5)

print('{0}の{1}の{2}が{3}で{4}'.format(*shuffle))

やりたいこと

  • 文字列のリストをシャッフルして出力する
  • 文字列の重複はしない

シャッフルはrandomモジュールを使用します。
シャッフルしたリストを返してほしいのでsample関数を使用します。
(shuffle関数だと一回シャッフルするだけなので、値は返らない)

また、最後のリストを展開する際に前に*をつけないとエラーになるようです。

>>> print('{0}の{1}の{2}が{3}で{4}'.format(shuffle))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: tuple index out of range # これは後で調べる

実行してみる

環境はfedora python classroom の vagrant版です。

(python3) [vagrant@localhost vagrant]$ python FF13.py
パージのコクーンのファルシがパルスでルシ

できました!
シャッフル率ってどのくらいなんですかねえ。
試しに20回ほど回してみます。

(python3) [vagrant@localhost vagrant]$ for a in {1..20} ; do python FF13.py ; done
パージのルシのパルスがコクーンでファルシ
ルシのコクーンのパージがファルシでパルス
パルスのファルシのルシがコクーンでパージ  # 正解
パルスのパージのコクーンがファルシでルシ
パージのファルシのルシがコクーンでパルス
パルスのコクーンのファルシがパージでルシ
コクーンのパルスのファルシがパージでルシ
ルシのパルスのコクーンがファルシでパージ
パルスのルシのパージがコクーンでファルシ
ルシのコクーンのファルシがパルスでパージ
コクーンのルシのファルシがパージでパルス
ルシのファルシのコクーンがパージでパルス
パージのコクーンのパルスがファルシでルシ
ルシのファルシのコクーンがパージでパルス
パージのコクーンのルシがファルシでパルス
パージのファルシのルシがパルスでコクーン
ファルシのパルスのルシがパージでコクーン
パルスのルシのファルシがパージでコクーン
ルシのコクーンのファルシがパルスでパージ
ルシのコクーンのパルスがパージでファルシ
(python3) [vagrant@localhost vagrant]$

一回でてきましたね。 1/20だから正解率は5%でしょうか。

とは書いたものの、未プレイのためどの文章が本当は正しいかわかりません...

参考サイト

qiita.com

シェルだとこちら

echo "パルス,ファルシ,ルシ,コクーン,パージ"  \
  | tr "," "\n" | sort -R | tr "\n" " " | awk '{print $1"の"$2"の"$3"が"$4"で"$5}'
(python3) [vagrant@localhost vagrant]$ echo "パルス,ファルシ,ルシ,コクーン,パージ"  \
>   | tr "," "\n" | sort -R | tr "\n" " " | awk '{print $1"の"$2"の"$3"が"$4"で"$5}'
パルスのパージのファルシがコクーンでルシ
(python3) [vagrant@localhost vagrant]$

上と同じ仕組みですが、寿司バージョン

echo "寿司,ご飯,魚,神" \
| tr "," "\n" | sort -R | tr "\n" " " | awk '{print $1"は"$2"の上に"$3"が乗ってるから"$4}'
(python3) [vagrant@localhost vagrant]$ 
ご飯は魚の上に寿司が乗ってるから神
(python3) [vagrant@localhost vagrant]$

スクレイピングでFワードを数える

映画が好きでよく見るんですが、パルプフィクションが面白くて3回くらい見てしまいました。
映画を見ていても感じるんですが、Wikiにもこんな記載があります。

パルプ・フィクション - Wikipedia

  • 劇中でのfxxkの使用回数は250回を超える。
    ※一応全編通して伏字にします。

本当に250回も言っているのか?
勉強中のスクレイピングで検証します。

コード

スクレイピングの書き方は勉強中のこちら
Automate the Boring Stuff with Python

#! python3

import requests, bs4
from collections import Counter, defaultdict

url = 'http://www.imsdb.com/scripts/Pulp-Fiction.html'

res = requests.get(url)
res.raise_for_status()

soup = bs4.BeautifulSoup(res.text, "html.parser")

# Search script
script = soup.pre.text
dict = Counter(script.split())

# Convert to lower case
lower_d = defaultdict(int)

for key, val in dict.items():
    lower_d[key.lower()] += val

# Search f-word
for key, val in lower_d.items():
    if key.find('fxxk') >= 0:
        print(key.ljust(40), str(val).rjust(1))

実行してみる

メインマシンは環境が汚いので、Fedora Python ClassroomのVagrant版で実行します。

(python3) [vagrant@localhost work]$ python pulp.py
fxxking                                  3
fxxkin'                                  91
motherfxxkers'                           1
fxxk                                     30
fxxk,                                    1
motherfxxkers!                           2
fxxked                                   7
motherfxxkin-house,                      1
motherfxxker                             5
motherfxxker.                            8
motherfxxker,                            2
english-motherfxxker-can-you-speak-      1
motherfxxkin'                            4
motherfxxkers                            3
fxxker                                   1
fxxks                                    1
fxxk's                                   3
motherfxxker!                            2
motherfxxker's                           1
fxxked-up                                1
motherfxxker"                            1
(python3) [vagrant@localhost work]$

取れました!
いろんなバリエーションがありますね。 

数を計算すると...169個!
あれ...全然少ない。
アドリブで言ってるってこと?
とりあえずうまいことスクレイピングできたので良しとします。

あとがき

復習がてらコードの解説も書こうと思ったけど長くなりそうなのでやめます。
簡単なコードですが、世の中に公開する私の初めてのコードになります。
これからもっと頑張って勉強したいと思います。
でも本業のインフラの勉強もやらないと!

おまけ

shellでやれば一発でした。

(python3) [vagrant@localhost work]$ curl -s http://www.imsdb.com/scripts/Pulp-Fiction.html | tr " " "\n" | grep [fF]xxk  | sort | uniq -c | awk '{s += $1} END {print s}'
169

詳細

(python3) [vagrant@localhost work]$ curl -s http://www.imsdb.com/scripts/Pulp-Fiction.html | tr " " "\n" | grep [fF]xxk  | sort | uniq -c
      1 English-motherfxxker-can-you-speak-
     25 fxxk
      1 fxxk,
      5 fxxk
      7 fxxked
      1 fxxked-up
      1 fxxker
     89 fxxkin'
      2 fxxkin'
      3 fxxking
      1 fxxks
      3 fxxk's
      3 motherfxxker
      2 motherfxxker,
      2 motherfxxker!
      8 motherfxxker.
      2 Motherfxxker
      1 Motherfxxker"
      3 motherfxxkers
      1 motherfxxker's
      2 motherfxxkers!
      1 motherfxxkers'
      4 motherfxxkin'
      1 motherfxxkin-house,

退屈なことはPythonにやらせよう4

仕事のトラブルで気づいたら2週間近く更新してなかった。 読み進めてるので溜まってるので書けるとこまで。

今読んでる章

Chapter 9 – Organizing Files

覚えた構文

Chapter 7 正規表現

  • import re
  • re.compile(r'文字列')

    • 文字列をコンパイルし検索を早くする
    • r(raw)はバックスラッシュ等も表示
  • search

    • 文字列の検索
  • group
    • マッチした文字列の出力
  • findall
    • マッチした部分をすべて表示

Chapter 8 ファイルの読み書き

  • open
    • ファイルオープン
    • open('filename', 'mode')
      • mode: r(read), w(write), a(append)
  • close
    • ファイルクローズ
    • 閉じないとPythonがプロセス持ち続けてしまう
  • shelve
    • 別ファイルにデータを格納する
      • .bak, .dat, .dir (使い分けは調べる)
    • 消したくないデータはこのモジュールを使う
    • DBを使うほどではないが消したくないときに使うのがよいらしい

Chapter 9 ファイルのコピーとか

  • import shutil
  • os.walk
    • ディレクトリ内のファイル、フォルダを表示できる
    • TreeをとるにはForで回す
  • import zipfile
    • zipの作成、展開ができる
    • close()を忘れずに
code
  • 多いので割愛

実行環境にAnacondaを入れてみた。 今日からJupyterを使って動作確認しています。 正しい使い方ではないかもしれないがログがとりやすくなった...と思う。

こんな感じ f:id:paloma69:20171111223532p:plain

退屈なことはPythonにやらせよう3

昨日の続き

今読んでる章

Chapter 6 – Manipulating Strings

覚えた構文

code
  • 章の最後にあるプログラムを作ろうコーナー

  • コード内に記載のパスワードをクリップボードにコピーする
    pyperclipというモジュールを使ってクリップボードに保管するらしいが、pyperclipのエラーが出て今く動かない...
    もう少し調べる。

#! python3
# pw.py - An insecure password locker program.

PASSWORDS = {'email': 'xxxxxxxx',
             'blog': 'xxxxxxx'}

import sys, pyperclip
if len(sys.argv) < 2:
    print('Usage: python pw.py [account] - copy account password')
    sys.exit()

account = sys.argv[1] # first command line arg is the account name

if account in PASSWORDS:
    pyperclip.copy(PASSWORDS[account])
    print('Password for ' + account + ' copied to clipboard.')
else:
    print('There is no account named ' + account)

退屈なことはPythonにやらせよう2

英語なので不明な単語は飛ばしつついきます。

今読んでる章

Chapter 6 – Manipulating Strings

覚えた構文

  • upper()
  • lower()
    • 文字列を大文字、小文字にする
  • isalpha()
    • 文字のみであればTrueを返す
  • isalnum()
    • 文字と数字があればTrueを返す
  • isdecimal()
    • 数字のみであればTrueを返す
  • isspace()
    • スペース、タブ、改行のみであればTrueを返す
  • istitle()

    • 大文字で始まり小文字が続く語句であればTrueを返す(間違ってるかも)
  • isX系のmethodはvalidationに使われるらしい。

  • startwith()

  • endwith()

    • 文字列の開始、終わり系
  • join()

  • split()

    • 文字列の分割、結合
  • rjust()

  • ljust()
  • center()
    • 文字列の詰め系

code

def printPicnic(itemsDict, leftWidth, rightWidth):
    print('PICNIC ITEMS'.center(leftWidth + rightWidth, '-'))
    for k, v in itemsDict.items():
        print(k.ljust(leftWidth, '.') + str(v).rjust(rightWidth))
picnicItems = {'sandwiches': 4, 'apples': 12, 'cups': 4, 'cookies': 8000}
printPicnic(picnicItems, 12, 5)
printPicnic(picnicItems, 20, 6)
---PICNIC ITEMS--
sandwiches..    4
apples......   12
cups........    4
cookies..... 8000
-------PICNIC ITEMS-------
sandwiches..........     4
apples..............    12
cups................     4
cookies.............  8000
  • Stringの説明はusefulが多くて全部書くとリファレンスの和訳になってしまうので割愛します。
  • 文字列はいろんな表現に活用できるようでいろいろ紹介されているだけあって覚えたほうがよさそう。

退屈なことはPythonにやらせよう1

ちょっとさぼったら間が空いていけませんね。
首記の英語版が無料で読めるので通勤の電車で読んでます。

Udacityと違ってわからないとこは飛ばせるのでこっちを書いていこう。

途中の章からですが、とりあえず一日一個書き続けなければ。

今読んでる章

Chapter 5 – Dictionaries and Structuring Data

覚えた構文

辞書型

  • {}で囲む
  • 順序性はない
method
  • key()
    • keyを出力
  • value()
    • 値を出力
  • items()
    • 両方出力
code
spam = {'color': 'red', 'age': 42}
for k, v in spam.items():
    print('Key: ' + k + ' Value: ' + str(v))

pritunl作ってみたのでメモ

VPNサーバでも立てて遊ぼうかなといろいろ調べてたらpritunlというGUIで管理できるオープンソースを見つけたのでメモ。

なんて読むのかわかりませんね。

http://pritunl.com/

openvpnベースらしいです。 インストールは公式ページのままできました。 ローカルPCの仮想マシン(centos7)に入れてます。

インストールは割愛してインストール完了後。

[root@localhost ~]# 
[root@localhost ~]# systemctl start mongod pritunl
[root@localhost ~]# 
[root@localhost ~]# systemctl enable mongod pritunl
mongod.service is not a native service, redirecting to /sbin/chkconfig.
Executing /sbin/chkconfig mongod on
Created symlink from /etc/systemd/system/multi-user.target.wants/pritunl.service to /etc/systemd/system/pritunl.service.
[root@localhost ~]# 
[root@localhost ~]# ps aux|grep pri
root      2121  9.2  3.8 900784 38684 ?        Ssl  07:22   0:03 /usr/lib/pritunl/bin/python2 /usr/lib/pritunl/bin/pritunl start
root      2166  0.5  0.3  30972  4056 ?        Sl   07:22   0:00 pritunl-web
root      2215  1.0  0.0 112660   924 pts/0    S+   07:23   0:00 grep --color=auto pri
[root@localhost ~]# 
[root@localhost ~]# 
[root@localhost ~]# netstat -antl
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 127.0.0.1:27017         0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN     
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN     
tcp        0      0 192.168.100.133:22      192.168.100.1:47997     ESTABLISHED
tcp6       0      0 :::80                   :::*                    LISTEN     
tcp6       0      0 :::22                   :::*                    LISTEN     
tcp6       0      0 ::1:25                  :::*                    LISTEN     
tcp6       0      0 :::443                  :::*                    LISTEN     
tcp6       0      0 ::1:9755                :::*                    LISTEN     
[root@localhost ~]# 

9700ポートでアクセスすると出てきますが、443でアクセスできました。
調べきれてませんがバージョンの差分でしょうか。

f:id:paloma69:20160819215020p:plain

mongodbをセットして・・・。(chromeなので苗字がでてしまいましたw)

f:id:paloma69:20160819215250p:plain

ログインパスを入れて・・・。

f:id:paloma69:20160819215329p:plain

初期のセットアップをしたら・・・。

f:id:paloma69:20160819215440p:plain

できたっぽいです。

あとはOganaizations、ユーザ、サーバの設定をして起動できました。

クライアントの接続はGUIからユーザの証明書をダウンロードして接続できるようです。
クライアントも公式に手順があるのですが、 私のクライアントはopensuse使ってたので手順がなかったのでCLIでやりました。

sudo openvpn <証明書>.ovpn

あとはユーザ名とPINを入力してとりあえずVPN張れました。   ログはとってなかったのでないですm(__)m

これでいろいろつなげて遊べそうですね。