today::エンジニアに憧れる非エンジニア

今のところは、エンジニアとは言えないところの職種です。しかしエンジニア的なものの考え方に興味津津。

Pythonあれこれ 2021-01-31 - クォート

概要

「Head First Python 第2版」を進めていった中で考えたことの記録です。

Head First Python 第2版 ―頭とからだで覚えるPythonの基本

Head First Python 第2版 ―頭とからだで覚えるPythonの基本

  • 作者:Paul Barry
  • 発売日: 2018/03/24
  • メディア: 単行本(ソフトカバー)

Pythonにおけるクォートの使い方

  • Pythonにおいては、文字列を囲むために以下のクォート類を用いる
    • シングルクォート(')
    • ダブルクォート(")
    • 三重クォート("""または''')

シングルクォートおよびダブルクォートで文字列を囲む用法

  • Pythonにおいて、文字列リテラルを表す一般的な記法である
  • Pythonにおいては、文字列リテラルを表す囲み記号はダブルクォートよりシングルクォートのほうが主流である
print('Hitch-hiker')
# => Hitch-hiker

# 対象となる文字列にアポストロフィそのものを含む場合は、囲み記号にダブルクォートを用いるのが一般的である
# アポストロフィの前にエスケープ記号を置く煩雑さを避けるのが主な理由
print("Don't panic!")
# => Don't panic!

# エスケープ記号としては`\`を用いる
print('Don\'t panic!')
# => Don't panic!

三重クォートで文字列を囲む用法

  • 複数行から成る文字列を記述するために用いる場合がある
    • 他言語を含む同様の概念は、一般に「ヒアドキュメント(here document)」と呼ばれる
  • Pythonにおいては、関数のドキュメンテーションを記述する際に多用される
    • 当該文字列は「docstring」と呼ばれる
  • Pythonにおいては、三重クォートを表現するためには二重引用符を用いるのが一般的
    • 単引用符を使うこともできるが、Pythonの三重クォートで単引用符を使うのは主流ではない
print("""このように
複数行の文字列を
一つの文字列リテラルとして扱うことができます。
改行部分は、そのまま
改行として扱われます。""")
# => このように
# => 複数行の文字列を
# => 一つの文字列リテラルとして扱うことができます。
# => 改行部分は、そのまま
# => 改行として扱われます。

↑複数行の文字列を一つの文字列リテラルとして扱うために三重クォートを用いる用法

def a_descriptive_name(optional_arguments):
    """ドキュメンテーション文字列"""
    # ...略...

↑docstringとして三重引用符を用いる用法

Pythonあれこれ 2021-01-30 - 複合データ構造

概要

「Head First Python 第2版」を進めていった中で考えたことの記録です。

Head First Python 第2版 ―頭とからだで覚えるPythonの基本

Head First Python 第2版 ―頭とからだで覚えるPythonの基本

  • 作者:Paul Barry
  • 発売日: 2018/03/24
  • メディア: 単行本(ソフトカバー)

組み込みデータ構造を組み合わせる

  • Pythonでは、組み込みデータ構造を任意に組み合わせたデータ構造を作ることができる
    • Pythonの組み込みデータ構造には、あらゆるオブジェクトを格納できる
    • 当然ながら、自作クラスのインスタンスも組み込みデータ構造に格納することができる
    • 組み込みデータ構造を自作クラスのフィールドとして使うこともできる
  • 組み込みデータ構造を組み合わせる例
    • 辞書の辞書
    • リストのリスト
    • リストの集合
    • 辞書のタプル
  • 改めて組み込みデータ構造の特徴
    • リスト・辞書・集合は、必要に応じて拡張や縮小が可能である
    • リスト・辞書・集合の拡張や縮小を行った場合でも、メモリの割り当てや解放はPythonインタプリタが自動で行う
people = {}
people['フォード'] = {'名前': 'フォード・プリーフェクト',
                      '性別': '男性',
                      '職業': '研究者',
                      '母星': 'ベテルギウス第7星'}
people['アーサー'] = {'名前': 'アーサー・デント',
                      '性別': '男性',
                      '職業': 'サンドイッチ職人',
                      '母星': '地球'}
people['トリリアン'] = {'名前': 'トリシア・マクミラン',
                        '性別': '女性',
                        '職業': '数学者',
                        '母星': '地球'}
people['ロボット'] = {'名前': 'マーヴィン',
                      '性別': '不明',
                      '職業': '偏執症アンドロイド',
                      '母星': '不明'}

↑以下、上述コードの説明

  • peopleという辞書を定義し、辞書peopleの各行に辞書を代入している
  • peopleという辞書には、代入が済んだ時点で4つのキーが存在する
    • 'フォード'
    • 'アーサー'
    • 'トリリアン'
    • 'ロボット'
print(people)
# => {'フォード': {'名前': 'フォード・プリーフェクト', '性別': '男性', '職業': '研究者', '母星': 'ベテルギウス第7星'}, 'アーサー': {'名前': 'アーサー・デント', '性別': '男性', '職業': 'サンドイッチ職人', '母星': '地球'}, 'トリリアン': {'名前': 'トリシア・マクミラン', '性別': '女性', '職業': '数学者', '母星': '地球'}, 'ロボット': {'名前': 'マーヴィン', '性別': '不明', '職業': '偏執症アンドロイド', '母星': '不明'}}

↑以下、上述コードの説明

  • 先程4つの行を追加した
  • データ構造は、{{key: value, ...},{key: value, ...},{key: value, ...},{key: value, ...}}となっている
    • {}が5つずつ存在する
  • 全て1行(右端で折り返し)で表示されており、人間には見づらい
import pprint
pprint.pprint(people)
# => {'アーサー': {'名前': 'アーサー・デント', '性別': '男性', '母星': '地球', '職業': 'サンドイッチ職人'},
# =>  'トリリアン': {'名前': 'トリシア・マクミラン', '性別': '女性', '母星': '地球', '職業': '数学者'},
# =>  'フォード': {'名前': 'フォード・プリーフェクト', '性別': '男性', '母星': 'ベテルギウス第7星', '職業': '研究者'},
# =>  'ロボット': {'名前': 'マーヴィン', '性別': '不明', '母星': '不明', '職業': '偏執症アンドロイド'}}

↑以下、上述コードの説明

  • pprintモジュールのpprint関数は、複合データ構造を人間がわかりやすい形に整形して標準出力に出力する
    • 関数名pprintは'pretty print'の略
    • 辞書people各行が、画面上の1行として表示されている
  • pprint関数を使っても、辞書peopleのデータ構造そのものに変化はない
    • {}が5つずつ存在する

複合データ構造のデータにアクセスする

print(people['アーサー'])
# => {'名前': 'アーサー・デント', '性別': '男性', '職業': 'サンドイッチ職人', '母星': '地球'}

↑辞書peopleの、'アーサー'というキーを持つ行にアクセスする

print(people['アーサー']['職業'])
# => 'サンドイッチ職人'

↑辞書peopleの、'アーサー'というキーを持つ行の'職業'というキーを持つ属性にアクセスする

Pythonあれこれ 2021-01-30 - タプル

概要

「Head First Python 第2版」を進めていった中で考えたことの記録です。

Head First Python 第2版 ―頭とからだで覚えるPythonの基本

Head First Python 第2版 ―頭とからだで覚えるPythonの基本

  • 作者:Paul Barry
  • 発売日: 2018/03/24
  • メディア: 単行本(ソフトカバー)

タプルというコレクションについて

  • 順序付きコレクションの一種
    • その性質はリストに類似する
  • 一度生成したタプルの内容は、後から変更することができない
    • このような性質を持つオブジェクトは「イミュータブルなオブジェクト」と呼ばれる
  • タプルはハッシュ化可能
    • 例えば、辞書のキーとしてタプルを用いることができる
    • 一方で、リストはハッシュ化不可
  • タプルを表すリテラル記法は()である
    • これに対し、リストを表すリテラル記法は[]である

タプルに関するコード例

vowels = list('aeiou')
vowels2 = tuple('aeiou')
print(type(vowels))
# => <class 'list'>
print(type(vowels2))
# => <class 'tuple'>

↑同じ文字列からリストとタプルを生成し、それぞれの型を出力させた例。

vowels = list('aeiou')
vowels2 = tuple('aeiou')
print(vowels)
# => ['a', 'e', 'i', 'o', 'u']
print(vowels2)
# => ('a', 'e', 'i', 'o', 'u')

↑順序付きコレクションの[]はリストであることを表す。()はタプルであることを表す。

vowels = list('aeiou')
vowels[2] = 'I'
print(vowels)
# => ['a', 'e', 'I', 'o', 'u']

vowels2 = tuple('aeiou')
vowels2[2] = 'I'
# => TypeError: 'tuple' object does not support item assignment
print(vowels2)
# => ('a', 'e', 'i', 'o', 'u')

↑リストの内容は変更できるが、タプルの内容は変更できない。

vowels2 = tuple('aeiou')
print(hash(vowels2))
# => -2063250890487547481   # ※一例

vowels = list('aeiou')
print(hash(vowels))
# => TypeError: unhashable type: 'list'

↑タプルのhashを得ることはできるが、リストのhashを得ることはできない。

Pythonあれこれ 2021-01-30 - 集合

概要

「Head First Python 第2版」を進めていった中で考えたことの記録です。

Head First Python 第2版 ―頭とからだで覚えるPythonの基本

Head First Python 第2版 ―頭とからだで覚えるPythonの基本

  • 作者:Paul Barry
  • 発売日: 2018/03/24
  • メディア: 単行本(ソフトカバー)

集合というコレクションについて

  • 学校教育で学んだ「集合」と同様の特徴を持つコレクション
  • Pythonにおける集合の主な特徴
    • 重複値を持つことができない
    • (辞書と同様に)順序を持たないデータ構造である
    • 高速な検索のために最適化されている
  • Pythonの集合に定義されているメソッド
    • 集合を結合するunion()メソッド
    • 自分にあって相手にない要素を示すdifference()メソッド
    • 自分と相手両方にある要素を示すintersection()メソッド
vowels = { 'a', 'e', 'e', 'i', 'o', 'u', 'u' }
print(vowels)
# => {'e', 'i', 'o', 'u', 'a'}

↑上記コードの要点

  • 集合を表すリテラル記法は中括弧{}である
    • オブジェクトの区切りはカンマ,である
    • 辞書とは異なり、「コロン:によるキーと値の区切り」は存在しない

集合を結合するunion()メソッド

  • 集合オブジェクトのインスタンスを呼び出し元とする
  • 引数として、1つ以上の集合を与える
  • union()メソッドの呼び出し元の集合と、引数として与えた集合の和を求める
  • 戻り値は、集合の和として得られた新たな集合オブジェクト
vowels = set('aeiou')
word = 'hello'
u = vowels.union(set(word))
print(u)
# => {'e', 'h', 'l', 'i', 'u', 'o', 'a'}

自分にあって相手にない要素を示すdifference()メソッド

  • 集合オブジェクトのインスタンスを呼び出し元とする
  • 引数として、1つ以上の集合を与える
  • difference()メソッドの呼び出し元の集合のうち、引数として与えた集合の全てに存在しない要素から成る新たな集合を得る
    • 「引数として与えられた集合に存在し、呼び出し元の集合に存在しない要素」は含まれない
  • 戻り値は、上記演算により得られた新たな集合オブジェクト
vowels = set('aeiou')
word = 'hello'
d = vowels.difference(set(word))
print(d)
# => {'u', 'i', 'a'}

difference()メソッドの戻り値として得られた集合dに'h'および'l'が含まれないことに注意。

自分と相手両方にある要素を示すintersection()メソッド

  • 集合オブジェクトのインスタンスを呼び出し元とする
  • 引数として、1つ以上の集合を与える
  • intersection()メソッドの呼び出し元の集合、および引数として与えた集合の全てに共通して存在する要素から成る新たな集合を得る
  • 戻り値は、上記演算により得られた新たな集合オブジェクト
vowels = set('aeiou')
word = 'hello'
i = vowels.intersection(set(word))
print(i)
# => {'e', 'o'}

Pythonあれこれ 2021-01-29

概要

「Head First Python 第2版」を進めていった中で考えたことの記録です。

Head First Python 第2版 ―頭とからだで覚えるPythonの基本

Head First Python 第2版 ―頭とからだで覚えるPythonの基本

  • 作者:Paul Barry
  • 発売日: 2018/03/24
  • メディア: 単行本(ソフトカバー)

データ型の一種としてのコレクション

  • コレクションは、オブジェクトの集まりを表すデータ型一般を指す
  • Pythonにおけるコレクションの例
    • リスト
    • タプル
    • 辞書(連想配列Pythonにおける実装)
    • 集合
    • frozenset
    • 文字列
  • その他有名なコレクションの例
    • 配列
    • テーブル
    • ツリー
    • グラフ
  • コレクションに用意されている操作の一般的な例
    • 新しい空のコレクションを作成する
    • コレクションの要素の数を取得する
    • コレクションの任意の要素を取得する
    • コレクションの内容を空にする
    • コレクションに新たな要素を追加する
    • コレクションの要素を削除する

Pythonの辞書について

  • 「一意なキーと、キーに対応する任意の値のペア」を要素とするコレクション
    • キーと値のペアは、任意個含むことができる
    • キーと値のペアを「行」とも呼ぶ
  • タプルやリストとは異なり、順序を持たないデータ構造である
    • 各要素の格納順は保証されない
    • 出力時に各要素の出力順を決め打ちする場合、組み込み関数sorted()を用いる
  • 辞書を表すリテラルは中括弧{}である
    • オブジェクトの区切りはカンマ,である
    • キーと値の区切りはコロン:である
  • 辞書に対する反復処理について
    • 辞書そのものに反復処理を行った場合、当該辞書内全てのキーをコンテナとして取得する動作になる
    • keys()メソッドにより、当該辞書内全てのキーをコンテナとして取得することができる
    • values()メソッドにより、当該辞書内全ての値をコンテナとして取得することができる
    • items()メソッドにより、当該辞書内全ての行をコンテナとして取得することができる
      • for文に2つの変数を与えることにより、1番目の変数に各行のキーを、2番目の変数に各行の値を取得することができる
  • 辞書のキーは初期化しなければならない
    • 存在しないキーを参照しようとすると、例外KeyErrorをスローする
    • 「存在しないキーを参照するとデフォルト値を返す」というget()関数も辞書に定義されている
  • 辞書に対してin演算子を使用した場合、「指定されたキーを持つ行が辞書に存在するか否か」を返す
    • 左辺には「ハッシュ化可能なオブジェクト」、右辺には「辞書」を置く
    • 戻り値はTrueまたはFalseである

Pythonの辞書に関するコード例

found = {}
print(found)
# => {}

↑空の辞書foundを定義し、その内容を標準出力に出力する

found = {}
found['a'] = 0
found['e'] = 0
found['i'] = 0
found['o'] = 0
found['u'] = 0
print(found)
# => {'a': 0, 'e': 0, 'i': 0, 'o': 0, 'u': 0}

↑以下、上記コードの動作について解説

  • 空の辞書foundを定義し、行5つを初期化する
    • 各行の初期値は0
  • 行の初期化順と辞書における行の並び順が一致しているのは偶然である
    • 辞書においては、各要素の格納順は保証されない
print(found)
# => {'a': 0, 'e': 0, 'i': 0, 'o': 0, 'u': 0}
for kv in found:
    print(kv)
# => a
# => e
# => i
# => o
# => u

↑辞書そのものに反復処理を行った場合、当該辞書内全てのキーをコンテナとして取得する動作になる

print(found)
# =>{'a': 0, 'e': 2, 'i': 0, 'o': 0, 'u': 0}
for k in found:
    print(k, 'の出現回数は', found[k], '回。')

# => a の出現回数は 0 回。
# => e の出現回数は 2 回。
# => i の出現回数は 0 回。
# => o の出現回数は 0 回。
# => u の出現回数は 0 回。

↑以下、上記コードの動作についての解説

  • キーと値のセットを得るコードの一例
    • 値を辞書名[キー]という形で得ている
print(found)
# =>{'a': 0, 'e': 2, 'i': 0, 'o': 0, 'u': 0}
print(sorted(found))
# => ['a', 'e', 'i', 'o', 'u']
print(sorted(found.items()))
# => [('a', 0), ('e', 2), ('i', 0), ('o', 0), ('u', 0)]

↑以下、上記コードの動作についての解説

  • 辞書を引数としてsorted()関数を使った場合、戻り値はリストとなる
  • 辞書のitems()メソッドの結果を引数としてsorted()関数を使った場合、戻り値は「タプルから成るリスト」となる
    • タプルの1番目の要素は、元の辞書のキーの1つ
    • タプルの2番目の要素は、元の辞書において当該キーに対応する行の値
for k,v in sorted(found.items()):
    print(k, 'の出現回数は', v, '回。')

↑以下、上記コードの動作についての解説

  • 辞書founditems()メソッドを呼び出し、反復ごとに各行にアクセスする
    • 各行のキーは変数kに取得する
    • 各行の値は変数vに取得する
  • 辞書のitems()メソッドの結果を引数としてsorted()関数を使った場合、戻り値は「タプルから成るリスト」となる
  • 取得したkおよびvを用いて出力メッセージを作成し、標準出力に出力する

集合住宅において、自分の住戸の真上で火災があった際、直後に何が起こるか

概要

およそ4ヶ月前、今住んでいる住戸の前に住んでいた住戸において、「自分の住戸の真上で火災が発生」という事態に遭遇しました。それから4ヶ月経過し、手続き関係も一段落してしばらく経った…というのが、私の今の状況です。

「自分の住戸の真上で火災があった人が、事態が一段落したところで、罹災直後に何があったかを振り返る」というのがこの記事の趣旨となります。

実際に発生したこと

消火活動により、自分の住戸に水漏れが発生する

有楽町火災 新幹線運転見合わせ 2014/1/3

火災が発生した場合、当然ながら火元の住戸では消火活動が行われることとなります。消火活動では水が使われます。消火活動で使われた水は、最終的には下に落ちていきます。結果として何が起こるか。「火元真下の住戸に向かって、消火活動で使われた水が落ちてくる」という事態です。

集合住宅において、浴室・トイレ・洗面所を除く居室の床や天井は、一般に防水加工がされていないものです。結果、火元真下の住戸の天井裏は水浸しになり、天井のどこかの部分から水が滴り落ちたり、壁を伝って水が落ちてきたりするようになります。住戸内への水漏れです。

「自分の住戸の真上で火災が発生した」という場合は、避難時に持ち出せない大事な物品は、浴室に退避させておくのが良いと思います。一般に浴室は防水構造となっており、消火活動による浸水の影響は受けないと考えることができるためです。

自分の住戸への電力供給が遮断される

一般に、住宅の天井裏には電気配線が張り巡らされているものです。そのため、「天井裏に浸水」という状況で電気を通すと、漏電の危険があります。

漏電の危険がある状態で電気を通すわけにはいきません。結果、消火活動におけるいずれかの段階で、火元真下の住戸への電力供給も遮断されることになります。

固定回線によるインターネット接続ができなくなる

電力供給が遮断されるので、固定回線によるインターネット接続もできなくなります。

少なからぬ廃棄物が発生する

火災発生直後には、以下の物品を廃棄することとなりました。

  • 壁に貼ってあったカレンダー1つ
    • 水濡れにより、継続使用できる状況ではなくなった
  • 冷蔵庫・冷凍庫に入っていた食材
    • 電気遮断から数時間アクセスできなかったため

退避住戸が手配される

自分の住戸の真上で火災が発生すると、消火活動による浸水で、それまで住んでいた自分の住戸は住める状態ではなくなります。そのため、(管理者・大家によるのかもしれませんが)管理者・大家1により退避住戸が手配されました。退避住戸が手配され鍵が渡されるまでは、火災発生から数時間でした。

なお、私の事例の場合、以下の各種コストは全て大家側負担となりました。

  • 退避住戸における電気代・水道代・ガス代
  • 退避住戸に用意されている什器の使用コスト
    • 布団類
    • 掃除機
    • 電気ポット
    • トイレ
    • 給湯設備
  • ポケットWi-Fiに関する諸費用
    • 固定回線によるインターネット接続ができなくなったため、貸し出しを受けました
退避住戸へのガス開通の際に発生した不具合

退避住戸におけるガス開通の際、「風呂釜までガスは来ているが、風呂釜でガスが燃焼せず、風呂釜やシャワーからお湯が出ない」という不具合がありました。即日「管理者を通じてメーカーに修理依頼」という対応がなされました。「風呂釜における給湯メカニズムにおいて、部品の損傷が発生していた」というのが原因であったそうです。

改めて謝辞

皆様には大変お世話になりました。遅くなりましたが、改めて感謝申し上げます。


  1. 火災遭遇時に私が住んでいた(現在も同一住棟別室に住んでいます)のは、とあるUR賃貸住宅でした。なので、「管理者・大家」というのは、「都市再生機構ないしはその関連法人」ということになりますね。

Pythonあれこれ 2021-01-23 - Pythonにおけるスライス

概要

「Head First Python 第2版」を進めていった中で考えたことの記録です。

Head First Python 第2版 ―頭とからだで覚えるPythonの基本

Head First Python 第2版 ―頭とからだで覚えるPythonの基本

  • 作者:Paul Barry
  • 発売日: 2018/03/24
  • メディア: 単行本(ソフトカバー)

スライスとは

letters[*開始*:*終了*:*刻み*]

Pythonのシーケンスオブジェクトにおける「スライス」は、「開始・終了・刻みの3つの要素を指定して、シーケンスオブジェクトから情報を取り出す方法」を指します。

以下の箇条書きは、スライスの開始・終了・刻みの説明です。

  • 開始…スライスを開始するインデックス位置
    • 省略時は0を指定したものとみなされる
  • 終了…スライスを終了するインデックス位置
    • 当該インデックス位置の要素そのものは含まない
    • 省略時はリストで利用可能な最大値を指定したものとみなされる
  • 刻み…スライスの間隔
    • 省略時は1を指定したものとみなされる

スライスの戻り値

スライスの戻り値は、元のシーケンスオブジェクトと同じ型となります。

以下のサンプルは、文字列・リスト・タプルに対し、開始・終了・刻みの全てを省略したスライス操作を行った結果です。「戻り値の型は、元のオブジェクトの型と同じになる」という特徴を踏まえて見てみましょう。

print("Don't panic!"[::])
# => "Don't panic!"
print(list("Don't panic!")[::])
# => ['D', 'o', 'n', "'", 't', ' ', 'p', 'a', 'n', 'i', 'c', '!']
print(tuple("Don't panic!")[::])
# => ('D', 'o', 'n', "'", 't', ' ', 'p', 'a', 'n', 'i', 'c', '!')

スライス操作の結果が、「文字列に対して文字列、リストに対してリスト、タプルに対してタプルを戻す」というものであることがわかります。

スライスの実例

saying = "Don't panic!"
letters = list(saying)

print(letters[0:10:3])
# => ['D', "'", 'p', 'i']

print(letters[3:])
# => ["'", 't', ' ', 'p', 'a', 'n', 'i', 'c', '!']

print(letters[:10])
# => ['D', 'o', 'n', "'", 't', ' ', 'p', 'a', 'n', 'i']

print(letters[::2])
# => ['D', 'n', 't', 'p', 'n', 'c']

それぞれ以下のようなスライスとなります。

  • letters[0:10:3]
    • 開始インデックス位置は0
    • 終了インデックス位置は10(10自身は含まない)
    • 間隔は3
    • => インデックス位置10までの2つおきの文字
  • letters[3:]
    • 開始インデックス位置は3
    • 終了インデックス位置は省略
    • 間隔は省略
    • => 最初3文字を飛ばし、残りすべての文字
  • letters[:10]
    • 開始インデックス位置は省略
    • 終了インデックス位置は10
    • 間隔は省略
    • => インデックス位置10までのすべての文字
  • letters[::2]
    • 開始インデックス位置は省略
    • 終了インデックス位置は省略
    • => 1つおきのすべての文字