EBCDIC

概要

EBCDIC ( Extended Binary Coded Decimal Interchange Code)は、IBMにより定義された8ビットの文字コード。

BCDの0~9 (0000~1001)を8ビットに拡張し、上位ビットをF (1111)として10進の数値を充てており、アルファベット文字や記号をそれぞれ特定の位置に定義している。

制御文字

EBCDICの制御文字は16進で00~3FとFFに割り当てられている。

FF:EO

00 01 02 03
0 NUL DLE DS (予約)
1 SOH DC1 SOS (予約)
2 STX DC2 FS SYN
3 ETX DC3 WUS IR
4 SEL RES/EMP BYP/IMP PP
5 HT NL LF TRN
6 RNL BS ETB NBS
7 DEL POC ESC EOT
8 GE CAN SA SBS
9 SPS EM SFE IT
A RPT UBS SM/SW RFF
B VT CU1 CSP CU3
C FF IFS MFA DC4
D CR IGS ENQ NAK
E SQ/LS1 IRS ACK (予約)
F SI/LS0 IUS/ITB BEL SUB

図形文字

共通配置

EBCDICの各コードページに共通する配置は以下のとおりで、文字が定義されていない空白位置には、各コードページごとに制御文字や他の印字可能文字が割り当てられる。

 

40 50 60 70 80 90 A0 B0 C0 D0 E0 F0
0 SP & 0
1 / A J 1
2 B K S 2
3 C L T 3
4 D M U 4
5 E N V 5
6 F O W 6
7 G P X 7
8 H Q Y 8
9 I R Z 9
A :
B . , #
C < * % @
D ( ) _
E + ; > =
F ?

カナ拡張

IBMによるカナ拡張の例。

40 50 60 70 80 90 A0 B0 C0 D0 E0 F0
0 SP & 0
1 / a j A J 1
2 b k s B K S 2
3 c l t C L T 3
4 d m u D M U 4
5 e n v E N V 5
6 f o w F O W 6
7 g p x G P X 7
8 h q y H Q Y 8
9 i r z I R Z 9
A :
B . , #
C < * % @
D ( ) _
E + ; > =
F ?

 

 

Atom – 覚え書き

エディター

スタイルの編集

  • File→Settings→Themes
  • 冒頭”your stylesheet”をクリック
  • styles.lessの内容を編集

コメントの色

styles.lessの以下の部分を編集(colorの値はテーマによる)。

その他

VagrantにSFTP接続

 

Python3 – cURL

基本形~GET

Python3で指定したURLのサイトからレスポンスを得る手順は以下のとおり。

  1. urllib.request.urlopenで接続のオブジェクトを得る
  2. 接続オブジェクトに対してreadメソッドを実行する

ただし結果はバイト列で得られる。

urlopenの引数にURLを指定

以下はurlopenの引数にURLを指定した手順。

  1. urlopenの戻り値(Responseオブジェクト)を変数responseに保存
  2. responsereadメソッドメソッドでレスポンスの内容を取得

レスポンスの内容はバイト列で返される。

文字列でレスポンスを得るには、decodeメソッドでバイト列を文字列にデコードする。

urlopenの引数にRequestオブジェクトを指定

まずURLを指定してurllib.request.Requestオブジェクトを生成し、これをurlopenの引数として接続を開く。

POST

ポストの流れは以下のとおり。

  • urllib.requesturllib.parseをインポートする
  • urlopenの引数にRequestオブジェクトを渡す
  • Requestオブジェクト生成時にdata引数を指定するとPOSTメソッドになる(method='POST'がなくてもよい)
  • dataへ渡す引数は、以下のように処理
    • 元のパラメータ群を辞書で準備
    • そのデータをurllib.parse.urlencodeでエンコード(utf-8のエンコードも加える)

以下はhttpbin.orgを利用して確認した例。httpbin.org/postからのレスポンスがJSON形式なので、jsonライブラリーをインポートしてレスポンスを整形している。

 

Python3 – json

概要

JSONの文字列が与えられたときの扱い。

  1. json.loadsで文字列をPythonの変数に変換(デコード)
  2. json.dumpsでPythonの変数を文字列に変換(エンコード)
    • ensure_ascii=Falseでユニコード文字をエスケープさせない
    • indent=nでJSONの構造に即した改行・インデントを適用

json.loads

json.loadsメソッドは、JSON文字列をPythonの変数にデコードする。Pythonの辞書になっていることがわかる。

JSONのキーと値が辞書のキーと値に対応している。

json.dumps

そのままエンコードした場合

json.dumpsは、辞書に変換されたJSONの内容を文字列にエンコードする。

ただしこのとき、ユニコードはエスケープされ、改行を含まない文字列となる。

引数設定によるJSONの構造表現

以下の2つの引数を指定する。

ensure_ascii=False
ユニコードをエスケープせずそのままの表現とする。
indent=n
JSONの構造に即した改行・インデントを適用する。

これによって、ユニコード文字列はエスケープされず、JSONの構造に即した改行・インデントが適用された文字列が得られる。

 

 

PHP – json

概要

JSONの文字列が与えられたときの扱い。

  1. json_decodeで文字列をPHPの変数に変換
  2. json_encodeでPHPの変数を文字列に変換
    • このとき、JSON_UNESCAPED_UNICODEJSON_PRETTY_PRINTのフラグを立てる

json_decode

json_decode関数は、引数で与えられたJSON文字列をPHPの変数に変換する。

JSONのキーや単体の要素はstringに、{ ... }stdClassのオブジェクトに変換され、キー=>値がオブジェクトのプロパティーとなっている。

json_encode

そのままエンコードした場合

json_encodeは、PHPの変数で表現されたJSONコードを文字列に変換する。

ただしこのとき、ユニコードはエスケープされ、改行を含まない文字列となる。

オプションフラグの設定

以下の2つのフラグをセットする。

JSON_UNESCAPED_UNICODE
ユニコード文字をエスケープせずに扱う。
JSON_PRETTY_PRINT
JSONの構造に即した改行・インデントを適用する。

これによって、ユニコード文字列はエスケープされず、JSONの構造に即した改行・インデントが適用された文字列が得られる。

 

Python3 – bytesとString

概要

Pythonでの文字列表現をバイト列に変換するにはencodeメソッドを用い、バイト列を文字列に変換するにはdecodeメソッドを用いる。encode/decodeの引数には文字コードを指定する。

バイト列をPythonのprint文で出力すると、b'文字列'で表現され、改行文字などはエスケープコード(\nなど)で表示される。

ASCII文字列

encode/decode

ASCII文字列はencode/decodeの引数を'ascii'とする。

ASCIIの場合は引数が'utf-8''shift_jis'としても結果は同じ。

16進表現

bytes.hexメソッドの引数にバイト列を与えると、その16進表現の文字列が得られる。

UTF-8/Shift_JIS

encode/decode

マルチバイト文字の場合、encodedecodeで文字コードを整合させる。

encodedecodeで文字コードが違うと、文字化けするのではなくエラーになる。

ただしerrors引数の設定をデフォルトの'strict’から変更すると、文字化けした文字列などが返される。

16進表現

マルチバイト文字の16進表現はバイト列の表現のとおりになる。

 

Python3 – ファイル操作

ファイル操作の流れ

大まかな流れは以下のとおり。

  • モードを指定してファイルを開く~open
  • ファイルへの読み書きを実行
  • ファイルを閉じる~close

具体的には、openでファイルオブジェクトを取得し、読み書きやcloseなどの操作はファイルオブジェクトに対して実行。

基本形

以下のファイルを準備。行末は全て改行コードで終わっている。

以下のコードは、ファイルを読み込みモードで開き、内容を一つの文字列に一括して読み込んで表示している。

実行結果は以下のとおり。

ファイルの各行末に改行コードがあるため、そこで改行されて表示される。さらにprint関数で自動的に改行コードが付加されるため、最後に空白行が入っている。

with文

with文でopenを指定することにより、withブロック終了時に自動的に終了処理(close)が実行される。

ファイルからの読み込み

read~一括読み込み

readメソッドはファイルの全内容を一つのテキストとして読み込む。

readline~一行読み込み

readlineは実行のたびにファイルから1行ずつ読み込み、ポインターを次の行に進める。読み込む内容がない場合には''を返す。

以下はファイルの内容を2行だけ読みだす例。

以下はファイル内容の全行を1行ずつ取り出す例。

readlines~行に分割して読み込み

readlinesはファイルの内容を行に分解し、各行の内容を要素としたリストを返す。

ファイルへの書き込み

ファイルに書き込む場合、オプションに'w'を指定。既にファイルが存在する場合、その内容は無視されて上書きされる。

write文

write文は引数の文字列を単に書き込む。

print文

print文のfile引数にファイルオブジェクトを指定すると、ファイルに書き込むことができる。この場合、書式設定などを活用することができる。

ファイルへの追記

既存のファイルに追記するには'a'オプションを指定。以下の例では、上で作成されたtest.txtに1行追記している。

ファイルが存在しない場合は、'w'と同様にファイルが作成されて新規に書き込みされる。

 

PHP – cURL

流れ

  1. curl_initでセッションハンドルを得る
  2. ハンドルを使ってcurl_setoptcurl_executeなどを実行する
  3. curl_closeでセッションを閉じる

基本形

curl_initでURLを指定する例

curl_init実行時に引数にURLを与え、そのターゲットに対して実行する例。実行結果は上述と同じ。

実行後、コンソールにサーバーから送られてきたレスポンスが表示される。

curl_setoptでURLを指定する例

curl_initを引数なしで実行後、curl_setoptでURLを指定する例。

ヘッダーも取得

curl_setoptCURLOPT_HEADERtrueに設定すると、レスポンスでヘッダーも取得できる。

実行結果にヘッダーが含まれている。

レスポンスを文字列として受け取る

デフォルトではリクエストに対するレスポンスはコンソールに出力される。

curl_setoptCURLOPT_RETURNTRANSFERtrueに設定すると、curl_execの戻り値としてレスポンスの文字列が返される。このとき画面には出力されない。

POST

  • フォームパラメーターを連想配列で設定する
  • curl_setoptCURLOPT_POSTtrueに設定して、POSTメソッドを指定する
  • curl_setoptCURLOPT_POSTFIELDSとフォームパラメーターの連想配列を指定

フォームパラメーターがセットされている。

 

Django – Tutorial4 – フォーム

フォームの配置

このページはDjangoのDocumentation、Writing your first Django app, part 4に対応している。

detailページの機能

チュートリアルのテンプレートのところで作成したindexページでは、データベースのquestionテーブルに保存されたQuestionデータの一覧が表示される。

各Questionデータのリンクをクリックすると、polls.viewsモジュールのdetail関数にルーティングされ、detailテンプレートが呼ばれてページが表示される。

現状でこのページでは、"You're looking at question 1."のようにクリックしたQuestionデータのidを含むテキストが表示されるだけ。

ここでdetailページに以下のような機能を持たせる。

  • クリックしたQuestionデータのquestion_textを表示する
  • そのQuestionデータに関連付けられた(すなわちその回答選択肢となる)Choiceデータ群を、ラジオボタンとともに表示する
  • Voteボタンを押すと、選択した回答のidが送信される

id送信後の振る舞いについては後に実装することとして、ここでは上の機能をテンプレートで実装していく。

コードの変更

pollsアプリケーションのdetailテンプレートを以下の内容に変更する。

テンプレートがビューから受け取る変数

questionオブジェクトとerror_message(テキスト)が渡されることを想定している(上記コードのL4, 6, 8)。

form要素のactionとmethod

form要素のオプション設定は以下の通り。

  • actionの呼び出し先はpollsアプリケーションのname='vote'ルート→vote関数で、questionデータのidをURLパラメーターで渡す
  • メソッドはPOST

csrf_tokenタグ

form要素内の最初にCSRF/XSRF (cross-site request forgery)対策として{% csrf_token %}を置いている。form要素にこのタグを置かないと、Djangoによりアクセス禁止のエラーとなる。

qustion_textの表示

ビューから受け取ったquestionオブジェクトのquestion_textプロパティーの内容をh1要素として表示させる。

エラー表示

ビューの処理でエラーになった場合error_message変数が定義されることを前提としている。DTLのifタグにより、error_messageがセットされているときはこれが表示され、選択肢とラジオボタンが表示される。

選択肢の表示

questionデータに対する選択肢はChoiceデータが関連付けられていて、そのコレクションはDTLのドット検索によりquestion.choice_set.allで得られる。

フォームでは、このコレクションの要素(各Choiceデータ)をDTLのforタグで1つずつ取出している。そして、各choiceについてラジオボタンとラベルテキストを生成している。

ラジオボタンの属性は以下のとおり。

name=”choice”
すべての選択肢に同じname属性を適用してグループ化している。
id=”choice{{ forloop.counter }}”
label要素で参照するidで、先頭から連番でchoice1, choice2, …のような値となる。forloop.counterDTLのforタグの変数で、ループカウンターの値が得られる。
value=”{{ choice.id }}”
選択されたラジオボタンに対応する値で、Choiceデータのidが充てられる。このidによって、データベース上の指定したデータが得られる。

このテンプレートがレンダリングされたときのHTMLは以下のとおり。valueの値が1, 2, 4となっているが、データの削除・追加によってAUTO_INCREMENTの値は必ずしも連続にならない。一方、forloop.counterを利用したidの数字部分は連番となっている。

ここでindexページのQuestionデータのうち"What's up?"をクリックすると、レンダリングされたdetail.htmlにより以下のページが表示される。

この段階でVoteボタンを押すと、polls.viewsモジュールのvote関数にルーティングされるが、この段階では”You’re voting on question 1.”とだけ表示される。

vote関数の実装

vote関数での処理

ここではフォームのアクション先であるvote関数の処理を実装する。処理内容は、Questionの持つ選択肢のうちditailページで選択・送信されたChoiceデータのvoteカウンターを1つ増やしてデータベースを変更するというもの。

コード

vote関数の内容を以下のように変更する。

モジュールのインポート

パッケージ先頭でHttpResponseRedirectモジュールをインポートしている。このモジュールは、URLconfで定義したルート名とパラメーターを与えてレスポンスを返す。

またChoiceモデルを扱うために、Questionに加えてChoiceモジュールもインポートしている。

Questionの取得

フォームのaction属性で、Questionデータのidをクエリーパラメーターで渡すようになっていて、vote関数の引数でこれを受け取る。

そのidQuestionデータを取得し、存在しなければ404エラーとなる。

投票登録:try~except~elseブロック

このブロックで、Questionデータに対する選択肢をデータベースから取得し、エラーならエラー処理をし、成功したならその選択肢の得票数を1つ増やす。詳細は以下の通り。

try節

try節では、前段で得られたQuestionデータの選択肢Coiceデータのうちフォームで選択されたものを取得する。

  • getメソッドでpkPOST['choice']に等しいデータを取り出している
  • POST['choice']はフォームにおいてname='choice'INPUT要素から得られるvalue属性の内容
  • 今回のフォームではラジオボタンのグループが'choice'であり、POST['choice']から選択されたボタンのvalue属性の値が得られる
  • フォームではvalue={{ choice.id }}としているので、この値は選択された選択肢に対応するChoiceデータのidの値

except節

except節では、引数で指定したKeyErrorChoice.DoesNotExistの2つの例外をキャッチしている。いずれかの例外が発生した場合に、現在処理中のQuestionデータを与えて元のdetailページを表示させるが、このときエラーメッセージをセットしているのでこれも表示される。

KeyErrorPOST['choice']でデータを取り出すときに'choice'というキーが存在しない場合に発生する。このような状況は次の場合に発生する。

  • 選択肢を持たないQuestionデータに対してVoteボタンを押した場合(今回の例の場合question_text"Hou're you doing?"のデータ)
  • HTMLのラジオボタンのname属性が改ざんされた場合

Choice.DoesNotExistの方は、getメソッドで条件に合うデータがデータベース上にないときに発生する。ただ今回のコードでは、DB上のデータが取得できない場合はget_object_or_404により404エラーへと飛ぶようになっているので、ここでDoesNotExist例外は発火しないのではないか。

else節

else節はtry節の処理が正常終了した場合に実行される。今回の場合、フォームで選択された選択肢のChoiceデータが無事取得できたことになるので、データベース上の得票数カウンターを1つ増やして投票結果表示のresultページにリダイレクトする。

得票数のカウントアップは簡単で、取得済みのデータについて以下を実行。

ただしこれはデータベースからメモリー上に取得されたデータを変更しただけなので、変更後のデータをデータベースに登録する必要がある。

最後に戻り値としてHttpResponseRedirectを返している。これはDjangoに特化したものではなく、HTTPでの処理の標準的な手筋。

動作確認

 

折れ線と曲線の近似誤差

円弧の長さと弦の長さの差

半径r、内角θの円弧の長さLa

(1)    \begin{equation*} L_a = r \theta \end{equation*}

これに対する弦の長さは

(2)    \begin{align*} L_c &= \sqrt {r^2 + r^2 - 2 r^2 \cos \theta} \\ &= r \sqrt {2 (1 - cos \theta)} \end{align*}

ここでLcLaの比を計算すると、rを含まないθのみの関数となる。

(3)    \begin{equation*} \frac{L_c}{L_a} = \frac{\sqrt {2 ( 1 - \cos \theta ) }}{\theta} \end{equation*}

θを度単位としてこの比をグラフにすると以下のようになる。

角度変化が30度弱で誤差が2%程度、20度で0.5%程度、10度になるとかなり誤差は小さくなっている。

そこでこの付近の誤差を計算してみる。

角度 5度 10度 15度 20度 25度 30度
Lc/La 0.9997 0.9987 0.9971 0.9949 0.9921 0.9886
誤差 0.03% 0.13% 0.29% 0.51% 0.79% 1.14%

道路線形の例

道路ネットワークのリンクを折れ線で近似する場合の誤差を考える。

式((3)の誤差率の計算結果から、円弧の内角が20~30度程度以内であれば、弧と弦の長さの差はかなり小さくなりそうだと予想される。

そこで角度に対して曲線半径rを掛けて曲線部の道路の長さを計算し、さらに誤差から曲線の道路の長さと直線で近似した長さの差を計算してみる。

角度 rad 弧長(60) 弧長(710) 差分(60) 差分(710)
5 0.08727 5.236m 61.959m 1.7mm 1.9cm
10 0.17453 10.472m 123.918m 1.3cm 15.7cm
15 0.26180 15.708m 185.878m 4.5cm 53cm
20 0.34907 20.944m 247.837m 10.6cm 1.26m
25 0.43633 26.180m 309.796m 20.7cm 2.45m
30 0.52360 31.416m 371.755m 35.8cm 4.23m

ネットワークデータの用途により、許容される誤差が決まり、必要な補完点の密度が変わってくる。

たとえばメートル単位の経路案内であれば10cmオーダーの誤差は許容され、交差点での停止になると数cmなど。後者の様にミクロなコントロールや自動運転に直接データを活用する場合は、数cm程度以下の精度が必要となると想定される。