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

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

動画感想…武富士の亡霊に取り憑かれた弁護士【しくじり企業L】~東京ミネルヴァ~


武富士の亡霊に取り憑かれた弁護士【しくじり企業L】~東京ミネルヴァ~

主に「事業」という観点からの感想です。

  • 本質的に終わりが存在する事業の場合、事業の立ち上げ時点から、「事業の畳み方」について計画を持っていなければならない
    • 「過払金返還訴訟」しかり、「天然資源掘削」しかり
    • 「大風呂敷を広げて畳めなくなった」となれば、多くの人に迷惑をかける
  • そもそも「その事業は、いつか本質的な終わりがやってくる類の事業なのか」という事柄についても、よくよく検討しておかねばならない
  • 弁護士は、法律のプロではあっても経営のプロではない
    • 経営以外のプロが事業を行なうにあたっては、悪辣な「経営のプロ」によって食い物にされる危険がある
    • 経営以外のプロが新たに事業を立ち上げるにあたっては、「悪い人」を寄せ付けないようにするためにも、最低限の経営知識は必要である

Pythonあれこれ 2021-02-23 - Flaskにおけるリダイレクト等

概要

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

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

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

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

Flaskにおいてリダイレクトを設定する際のPythonコード

from flask import Flask, render_template, request, redirect
from vsearch import search4letters

app = Flask(__name__)

@app.route('/')
def hello() -> '302':
  return redirect('/entry')


@app.route('/entry')
def entry_page() -> str:
  return render_template(
    'entry.html',
    the_title='Web版のsearch4lettersにようこそ!'
  )


app.run()

上記コードをpyコマンドで実行した上で、http://127.0.0.1:5000にアクセスすると、実行されているWebアプリケーションは以下のようなログを返します。

127.0.0.1 - - [23/Feb/2021 09:53:34] "GET / HTTP/1.1" 302 -
127.0.0.1 - - [23/Feb/2021 09:53:35] "GET /entry HTTP/1.1" 200 -

HTTPステータスコードの300番台はリダイレクトを表します。この例では、Webアプリケーションは以下のような動作をしているわけです。

  1. /GETメソッドでアクセスされると、/entryへのリダイレクトを返す
  2. 1.の動作により、/entryへのGETリクエストが送出される
  3. /entryへのGETリクエストが正常に処理される
  4. Webブラウザentry.htmlの内容が返される

redirect関数のインポート

Flaskにおいてリダイレクトを行わせるには、flaskライブラリに含まれるredirect関数を使用します。当然ながら、redirect関数のインポートという操作が必要になります。以下は、redirectを含むflaskライブラリの関数・クラス群をインポートするimport文の例です。

from flask import Flask, render_template, request, redirect

Flaskにおいて複数のWebページのロケーションに同一関数を割り付ける際のPythonコード

Flaskでは、複数のWebページのロケーションに同一の関数を割り付けることも可能です。下記コードは、「entry_page関数を、//entryという2つのリソースに割り付ける」というPythonコードの例です。

from flask import Flask, render_template, request
from vsearch import search4letters

app = Flask(__name__)


@app.route('/')
@app.route('/entry')
def entry_page() -> str:
  return render_template(
    'entry.html',
    the_title='Web版のsearch4lettersにようこそ!'
  )


app.run()

上記コードをpyコマンドで実行した上で、http://127.0.0.1:5000にアクセスすると、実行されているWebアプリケーションは以下のようなログを返します。

127.0.0.1 - - [23/Feb/2021 09:55:47] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [23/Feb/2021 10:11:17] "GET /entry HTTP/1.1" 200 -

この例では、Webアプリケーションは以下のような動作をしています。

  1. /へのGETリクエストが正常に処理される
  2. Webブラウザentry.htmlの内容が返される

/ではなく/entryに直接アクセスした場合も同様の動作となります。

entry_page関数を、//entryという2つのリソースに割り付ける」という記述は、Pythonコード側における以下の記述が対応しています。

@app.route('/')
@app.route('/entry')
def entry_page() -> str:

単純に@app.routeデコレータをentry_page関数の定義の前に2つ書いているだけですね。このように記述しておけば、あとはFlaskが良い感じに処理してくれます。

Pythonあれこれ 2021-02-20 - Webアプリケーションに、テンプレートに基づいたHTMLを返す動作を実装する

概要

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

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

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

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

Webアプリケーションのコード

from flask import Flask, render_template, request
from vsearch import search4letters


# ...略...


@app.route('/search4', methods=['POST'])
def do_search() -> str:
  phrase = request.form['phrase']
  letters = request.form['letters']
  return str(search4letters(phrase, letters))

上記は、Flaskを用いて構築した、POSTリクエストを受け付けるWebアプリケーションの例となります。

コード各部分について解説

HTTPのリクエストデータを扱うためのオブジェクトをインポートする

from flask import Flask, render_template, request

flaskライブラリに含まれる関数・クラスのうち、Flaskクラスとrender_template関数は、これまでに実装してきた機能を使うために必要であった関数・クラスです。

今回新たに、requestという組み込みオブジェクトをflaskライブラリからインポートしています。requestオブジェクトは、HTTPのリクエストデータをWebアプリケーションで扱うために必要となる関数です。

HTMLフォームのデータを新規の変数に代入する

phrase = request.form['phrase']
letters = request.form['letters']

flaskライブラリのrequestオブジェクトには、ポストされてきたHTTPリクエストに含まれるHTMLフォームのデータにアクセスするための辞書属性formが含まれます。request.formの内容はPythonの辞書で、各要素のキーはHTMLフォームの各name属性の値となります。例えば、name属性の値がphraseであるinput要素の内容にWebアプリケーション側からアクセスするためには、request.form['phrase']という属性にアクセスすればよいということになるわけです。

<form method='POST' action='/search4'>
<p>このフォームを使って検索リクエストを送ってください。</p>
<table>
<tr><td>フレーズ:</td><td><input name='phrase' type='TEXT' width='60'></td></tr>
<tr><td>文字:</td><td><input name='letters' type='TEXT' value='aeiou'></td></tr>
</table>
<p>準備ができたら、以下のボタンを押してください。</p>
<p><input value='実行!' type='SUBMIT'></p>
</form>

上述HTMLマークアップは、上述Pythonコードで処理するための入力データを生成するHTMLフォームの例です。このHTMLフォームのSUBMIT処理を実行すると、上述Pythonコードは以下の動作を行います。

  • ポストされてきたHTMLフォームのうち、name属性の値がphraseであるinput要素に入力された文字列を変数phraseに代入する
  • ポストされてきたHTMLフォームのうち、name属性の値がlettersであるinput要素に入力された文字列を変数lettersに代入する

curlコマンド等を用い、当該HTMLフォームにより生成されるリクエストと同等のPOSTリクエストを直接投入することも可能です。当該リクエストの必要条件は以下となります。

  • リクエストの種類がPOSTであること
  • HTMLフォーム形式でエンコードされた、以下のパラメータがリクエストに含まれていること
    • phraseパラメータ
    • lettersパラメータ

作成した変数を別の関数で使用し、その戻り値を得る

return str(search4letters(phrase, letters))

このreturn文に対応する関数do_searchは、「/search4というURLを持つリソースに対するPOSTリクエスト」に割り付けられたものです。前項で内容を定義したphraseおよびletters両変数を引数として、search4letters関数を呼び出しています。結果、当該search4letters関数の戻り値は、POSTリクエストの結果としてWebアプリケーションからWebブラウザに返されることとなるわけです。

実際にPOSTリクエストを行ってみる

WindowsでHTTPのPOSTリクエストを直接投げるためには、curl.exeを用いるのが手っ取り早い方法です。

  • Windows 10 Ver.1803以降であれば、curl.exeは標準で付属している
  • cmd.exeやPowerShellといったターミナルから使うことができる
  • -X POSTというオプション指定で、POSTリクエストを投げるようにする
  • HTMLフォーム形式のパラメータをリクエストに含めたい場合は、-F 'パラメータ名=パラメータ値'というオプションを付ける
    • 複数のパラメータをリクエストに含めたい場合は、-Fオプションを必要な数だけ列挙する

事前に対象となるWebアプリケーションを起動した上で、http://127.0.0.1:5000/search4phraseパラメータとlettersパラメータを含むPOSTリクエストを送出するコマンドを送出してみます。実行結果は、例えば以下のようになります。

PS C:\webapp> curl.exe -X POST -F 'phrase=hogehoge' -F 'letters=aeiou' http://127.0.0.1:5000/search4
{'o', 'e'}

Pythonあれこれ 2021-02-20 - Webアプリケーションに、テンプレートに基づいたHTMLを返す動作を実装する

概要

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

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

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

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

Webアプリケーションのコード

from flask import Flask, render_template
from vsearch import search4letters

app = Flask(__name__)


# ...略...


@app.route('/entry')
def entry_page() -> str:
  return render_template('entry.html',
                         the_title='Web版のsearch4lettersにようこそ!')

app.run()

コード各部分について解説

テンプレートエンジンを使うための関数をインポートする

from flask import Flask, render_template

FlaskによるWebアプリケーションでテンプレートエンジンを使う操作は、flaskライブラリのrender_template関数1に定義されています。Webアプリケーションに「テンプレートに基づいたHTMLを返す」という動作を実装するためには、同関数をインポートする必要があります。

というわけで、flaskライブラリからインポートする関数として、render_templateを新たに追加しています。Flaskクラスのほうは、基本的なWebアプリケーションを定義する段階で既にインポートしていたものです。

テンプレートとキーワード引数に基づき、HTMLを生成して返す関数を定義する

@app.route('/entry')
def entry_page() -> str:
  return render_template('entry.html',
                         the_title='Web版のsearch4lettersにようこそ!')

先程importしたflaskライブラリのrender_template関数を用いて、/entryというURLにアクセスした際に返されるHTMLの内容を定義しています。Webブラウザの利用者側から見た全体動作としては、「第1引数で与えたテンプレートの内容を元にして、内部でJinja2テンプレートエンジンを用い、キーワード引数の内容も含めたHTTPレスポンスボディ内容を返す2」という動作をします。

render_templateの第1引数であるentry.htmlの内容については、下記記事のうち、項「入力フォーム」に記載しています。ベーステンプレートであるbase.htmlは、entry.htmlの内部で呼び出されています。

rapidliner0.hatenablog.com

render_templateのキーワード引数the_titleは、テンプレート中の以下の記述に対応するものです。

<title>{{ the_title }}</title>

↑ベーステンプレートbase.html中のtitle要素の中身

<h2>{{ the_title }}</h2>

↑入力フォームテンプレートentry.html中のh2要素の中身

キーワード引数the_titleが存在することにより、実際に生成されるHTMLのうち、上記2つの要素の内容には「Web版のsearch4lettersにようこそ!」という文字列が設定されることになります。


  1. jinja2ライブラリの使用については、render_template関数が適切に行なってくれます。

  2. 対応するHTTPレスポンスヘッダの内容は、Flask側で適切に生成されます。

Pythonあれこれ 2021-02-17 - Jinja2を使って、入力内容がPythonで処理されるWebページを作成する

概要

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

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

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

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

構築したいWebページはどのようなものか

入力フォーム.svg

↑入力フォームのイメージ

処理結果.svg

↑処理結果のイメージ

上述表示内容のWebページを得るために、以下3つのJinja2テンプレートを定義します。

  • ベーステンプレート
    • Webサイトのルック&フィールを定義する
  • 入力フォーム
  • 処理結果の表示

Jinja2とは

Flaskで用いられるテンプレートエンジンです。Flaskにおいては、以下の目的でJinja2テンプレートエンジンを用いています。

  • HTMLに、既存テンプレートを継承して用いる機能を追加する
  • PythonコードからHTMLの内容の一部を受け取る機能を追加する

jinja.palletsprojects.com

Webページのマークアップについて解説

ベーステンプレート

<!DOCTYPE html>
<html>
  <head>
    <title>{{ the_title }}</title>
    <link rel="stylesheet" href="static/hf.css">
  </head>
  <body>
    {% block body %}

    {% endblock %}
  </body>
</html>

他のHTMLファイルの内容をインポートして使うためのテンプレートです。解説は以下の通りです。

  • Webサイト全体に共通する内容についての記述である
  • 以下の内容のみが定義されている
    • DOCTYPE宣言
      • このHTMLが、HTML5標準に準拠するものであることを示す
    • HTML全体の基底要素であるhtml要素
    • head要素の記述
  • スタイルシートとしては、static/hf.cssというファイルの内容が用いられる
    • 同ファイルが必要である
  • body要素以下の内容は、他のHTMLファイルをインポートすることを前提とする
    • インポートされるHTMLファイルの内容は、{% block body %}から{% endblock %}までの間が置き換えられて埋め込まれる
  • 本ベーステンプレート自身は直接呼び出されない
    • 本ベーステンプレートの記述だけでは、完全な内容のHTMLは構築できない
    • 実際に呼び出されるのは、本ベーステンプレートを継承した各種テンプレートである

入力フォーム

{% extends 'base.html' %}

{% block body %}

<h2>{{ the_title }}</h2>

<form method='POST' action='/search4'>
<table>
  <p>このフォームを使って検索リクエストを送ってください。</p>
<tr><td>フレーズ:</td><td><input name='phrase' type='TEXT' width='60'></td></tr>
<tr><td>文字:</td><td><input name='letters' type='TEXT' value='aeiou'></td></tr>
</table>
<p>準備ができたら、以下のボタンを押してください。</p>
<p><input value='実行!' type='SUBMIT'></p>
</form>

{% endblock %}

入力フォームのHTMLマークアップの内容です。解説は以下の通りです。

  • 上述base.htmlを継承し、その中にインポートされる
    • {% block_body %}から{% endblock %}までの間が、entry.htmlの同内容に置き換えられる
  • Webページのタイトルは、Pythonコードによって与えられる
    • テンプレートの呼び出し元となるPythonの関数には、the_titleというキーワード引数が必要となる
  • 1つのHTMLフォームを定義している
    • 「実行!」ボタンがクリックされると、フォームの入力内容がHTTPのPOSTメソッドによって/search4というリソースに渡される
    • phraseという属性名で、文字列を内容とする属性を渡す
    • lettersという属性名で、文字列を内容とする属性を渡す
    • リソース/search4に割り付けられるアプリケーションには、以下の処理を行う機能が必要となる
      • POSTメソッドのリクエストを受け付ける機能
      • 属性名がphraseで、内容が文字列である属性を処理する機能
      • 属性名がlettersで、内容が文字列である属性を処理する機能

処理結果の表示

{% extends 'base.html' %}

{% block body %}

<h2>{{ the_title }}</h2>

<p>以下のデータを送信しました。</p>
<table>
<tr><td>フレーズ:</td><td>{{ the_phrase }}</td></tr>
<tr><td>文字:</td><td>{{ the_letters }}</td></tr>
</table>

<p>「{{ the_phrase }}から{{ the_letters }}」を検索すると、次の結果を返します。</p>
<h3>{{ the_results }}</h3>
{% endblock %}
  • 上述base.htmlを継承し、その中にインポートされる
    • {% block_body %}から{% endblock %}までの間が、entry.htmlの同内容に置き換えられる
  • Webページのタイトルは、Pythonコードによって与えられる
    • テンプレートの呼び出し元となるPythonの関数には、the_titleというキーワード引数が必要となる
  • 本文中に、Pythonコードによって与えられる表示内容が3つ定義されている
    • 具体的には以下の3つ
      • the_phrase
      • the_letters
      • the_results
    • テンプレートの呼び出し元となるPythonの関数には、以上3つのキーワード引数が必要となる

Pythonあれこれ 2021-02-14 - 既存関数の機能をWebに公開する

概要

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

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

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

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

この記事では、「Pythonで書いた既存関数の機能を、Flaskを用いてWebに公開する」という内容について解説しています。

既存関数の内容

def search4letters(phrase: str, letters: str = 'aeiou') -> set:
    """phrase内のlettersの集合を返す。"""
    return set(letters).intersection(set(phrase))

上記内容のモジュールが、vsearchとしてsite-packages1にインストールされていることを前提とします。

FlaskによるWebアプリケーションの内容

from flask import Flask
from vsearch import search4letters

app = Flask(__name__)

@app.route('/')
def hello() -> str:
  return 'Hello world from Flask!'

@app.route('/search4')
def do_search() -> str:
  return str(search4letters(
    phrase='life, the universe, and everything!',
    letters='eiru!'
  ))

app.run()

実際のWebアプリケーションのPythonコードは上記となります。動作の解説は以下です。

  • Webサーバの/search4というパスに対し、do_search()関数の結果を出力する
  • do_search()関数の中で、search4letters()関数を呼び出している
    • search4letters()関数を呼び出すために、vsearchモジュールからsearch4letters関数をインポートしている
  • search4letters()関数の結果は、str()メソッドを用いて明示的に文字列に変換している
    • search4letters()関数の結果は、そのままだとPythonの集合形式となるため

上記内容のコードを、任意の場所にhello_flask.pyとして保存します。

実行結果

前述のhello_flask.pyを実行し、Webサーバーを起動します。

Webサーバーの起動後にWebブラウザhttp://127.0.0.1:5000/search4にアクセスすると、ブラウザ画面に「{'e', 'i', '!', 'u', 'r'}」と出力されます2

f:id:rapidliner0:20210214125128p:plain
Webサーバの起動後、Webブラウザhttp://127.0.0.1:5000/search4にアクセスした結果

また、Flaskアプリケーションが実行されているコンソールに以下のメッセージが表示されます。

127.0.0.1 - - [09/Feb/2021 06:15:41] "GET / HTTP/1.1" 200 -

なお、現時点でリソース/に割り付けられているのは上述hello()関数であるため、http://127.0.0.1:5000/にアクセスすると、"Hello world from Flask!"というメッセージが表示されます。


  1. Pythonにおける、サードパーティ製のパッケージが格納される場所です。既存モジュールをsite-packagesに追加するにはpipコマンドを用います。

  2. {‘e’, ‘i’, ‘!’, ‘u’, ‘r’}という順序ではないかもしれません。Pythonの集合は順序を持たないコレクションであるため、文字列とした場合の出力順序が異なっても、それは仕様の範囲内です。

Pythonあれこれ 2021-02-12 - Webアプリケーションで起こること

概要

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

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

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

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

今回は、「最も基本的なWebアプリケーション」の各行の動作についての解説です。

Webアプリケーションで起こること概説

from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello() -> str:
  return 'Hello world from Flask!'

app.run()

上記は、「Flaskを用いてWebアプリケーションを定義し、実際にWebサーバーを起動する」という動作をする最も基本的なコードです。具体的には以下の動作をします。

  1. flaskモジュールからFlaskクラスをインポートする
  2. Flaskクラスのインスタンスappを生成する
  3. 関数をURLでデコレートする
  4. 3.でデコレートされる関数を定義する
  5. Webサーバを起動する

Flaskクラスのインポート

from flask import Flask

flaskモジュールからFlaskクラスをインポートします。

  • モジュール名とクラス名の大文字・小文字について
    • Pythonは大文字小文字を区別する
    • モジュール名は小文字の'f'から始まる
    • クラス名は大文字の'F'から始まる
  • 「クラス」は、「一群のデータと、関係する関数をひとかたまりとした設計図」といえる
    • フィールド…一群のデータ
    • メソッド…関係する関数
  • 今回用いるFlaskクラスは、「Webサーバーを稼働させるために必要なデータと関数をひとかたまりとした設計図」といえる

Flaskクラスのインスタンスの生成

app = Flask(__name__)

Flaskクラスのインスタンスを生成し、新たな変数appに代入します。

  • クラスは、その実体たるインスタンスを生成しなければ、実際に使用することはできない
  • Pythonにおけるインスタンスの生成は、クラス名と同名のメソッドを呼び出すことにより行われる
  • 引数の__name__は、「アクティブなモジュールの名前」を意味するPythonの特殊キーワードである
    • 「dunder name(ダンダー・ネーム)」と読まれる場合が多い
    • 「アクティブなモジュールの名前」を管理するのは、Pythonインタプリタの役割である

関数をURLでデコレート

@app.route('/')

Pythonのデコレータ機能を用いて、関数をURLに割り付けます。ここでは@app.route('/')というデコレータを定義しています。

  • Pythonにおける「デコレータ」は、「既存の関数の振る舞いを、当該関数のコードを書き換えることなく変更する」という操作を実現するための機能・構文である
    • @で始まる文がデコレータ構文
  • @app.route('/')というデコレータ構文の意味
    • 次の行に書かれる関数が、Webサーバのロケーション「/」に割り付けられることを意味する
    • routeデコレータがいかなる意味を持つか」については、Flaskクラスにて定義されている

デコレート対象の関数の定義

def hello() -> str:
  return 'Hello world from Flask!'

@app.route('/')というデコレータが適用される関数は、hello()関数です。hello()関数そのものは、一般的なPythonの関数です。

Webサーバの起動

app.run()

Flaskクラスのインスタンスrun()メソッドを実行すると、Webサーバが起動されます。

  • WebサーバのデフォルトのURLは127.0.0.1である
  • Webサーバのデフォルトのポート番号はTCP5000番である