OmniAICreator/Qiita-1.07M huggingface dataset:
【Playdate】動画を再生する

## Playdate用の動画作成

Playdateで動画を再生するにはpdv形式の動画ファイルと音声ファイルに分割されたものを用意する必要があります。
ここではmac環境でのpdvファイルの生成方法を説明します。
以下のdevforumのスレッドに`1bitvideo.app.zip`というファイルがリンク付けられていますのでそちらをダウンロードします。
（※こちらのファイル実行は各個人で判断の上行ってください）

https://devforum.play.date/t/video-encoder-work-in-progress-mac-only/1390/23

解凍するとappファイルが生成されるのでプライバシーとセキュリティから実行を許可した上で開きます。
以下のようなappのGUIが表示されます。

<img width="552" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100912/ca571fc6-0e0b-98d6-4d0d-2d742a18a228.png">

「Open...」から動画を読み込み、下の設定を操作したあと「Save...」で任意の名前で保存します。
ここでは`movie.pdv``movie.aif`で保存しました。


## ファイル配置

保存したファイルをプロジェクトファイルに配置します。

```
myProjectName/
    source/
        main.lua
        Videos/
            movie.pdv
            movie.aif
```

## 動画再生スクリプト

動画再生スクリプトはここではmain.luaに記述します。

```main.lua
import "CoreLibs/object"
import "CoreLibs/graphics"

local disp <const> = playdate.display
local gfx <const> = playdate.graphics
local snd <const> = playdate.sound

local video = gfx.video.new("Videos/movie") -- movie.pdv を読み込む
local audio, loaderr = snd.sampleplayer.new("Videos/movie") -- movie.aif を読み込む
local prevframe = 0

function setUp()
	disp.setRefreshRate(0) -- フレームバッファが利用可能になったらplaydate.update()を呼び出すように
	
	-- 音声
	if audio ~= nil then
		audio:play(0)
	else
		print("audio error:"..loaderr)
	end
	-- 動画
	video:useScreenContext()
	video:renderFrame(0)
end

setUp()

function playdate.update()
	if audio:isPlaying() == true then
		-- 音声の再生位置から動画のフレーム位置を求める
		local frame = math.floor(audio:getOffset() * video:getFrameRate())
	
		if frame ~= prevframe then
			video:renderFrame(frame)
			prevframe = frame
		end
	end
end
```

`playdate.graphics.video.new("Videos/movie")`でmovie.pdv を読み込み、`video`に格納、
`playdate.sound.sampleplayer.new("Videos/movie")`でmovie.aif を読み込み、`audio`に格納しています。

次にsetUp関数で初期化を行っています。
`playdate.display.setRefreshRate(0)`はフレームバッファが利用可能になったらplaydate.update()を呼び出すようにする設定です。
`audio:play(0)`で音声の再生を行い、動画の初期化を行います。
`video:useScreenContext()`はレンダリングコンテキストとして表示フレームバッファを設定し、
`video:renderFrame(0)`は動画の最初のフレームをレンダリングコンテキストに描画しています。

毎フレームの描画処理はplaydate.update()で行います。
音声再生状態のとき、音声の再生位置から動画の現在のフレーム位置を求め、前のフレーム位置と差分があれば描画するようにしています。
冪等なノートブック

3年くらいデータサイエンティストをしています。仕事柄いろいろな環境でPythonを使うのですが、Jupyter Notebookなどノートブック形式のものを触ることも多いです[^notebook]。

[^notebook]: 分かりやすいところだとGoogle ColabやKaggle Notebookは使っている人も多そう。databricksや、各種クラウドにもSagemakerなど該当するサービスがある。Python以外だと、jupyterのjuはjuliaのjuだし、Rにも（Rmarkdownとは別に）R Notebookがあるし、マイナーどころだがStataにも3年前くらいにNotebook機能がついている。

そんななかで、なんとなく意識している「ノートブックの冪等性」について書いてみます。

# 冪等とは何か
読み方は「べきとう」で、漢字が難しいので「べき等」と表記されることも多い。英語だと「idempotent」という超キュートな単語である。

雑に説明すると、冪等とは**ある操作を何回行っても結果が同じである**ことをいう。数式で書くと、以下が成り立つとき $f$ は冪等である[^1]。

$$f(f(x)) = f(x)$$

[^1]: このあたりは非常にざっくりとした理解で、正確な表現ではないです。

おそらく最初は数学用語として登場したもので、統計学界隈だと線形回帰の時に登場する射影行列が冪等行列である[^p]。それがエンジニアにも使われるようになり、Web系やデータエンジニアリングの本とかでちらほら見かける。おそらく、ネットワークが不安定とかで処理が上手いこと終わらなくて再実行したとしても変な結果にならないように冪等性を意識しているとかそんな感じ。

[^p]: https://ja.wikipedia.org/wiki/%E5%86%AA%E7%AD%89%E8%A1%8C%E5%88%97#%E5%BF%9C%E7%94%A8


# 冪等でないと何が起きるか
ノートブックで汚くデータの加工・集計しているときに困るのも、同じことではないかと思う。

例で見ていく。
エラーが起きるようなコードを適当に実行してみる（2行目がダメ。apply難しいよね）。

<img width="70%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/665792/f67b74a4-4cc1-3f59-3592-233d6ef836df.png">

これを修正して再実行を行う。

<img width="70%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/665792/a7ad0340-12c2-ce21-18a2-9ffe9e33d9bf.png">

今度はうまくいった。やったね！

…やったね？？？

実はこれだと問題が生じている。jupyter notebookはセルの途中でエラーがあったときも、その前までの処理は完遂されている。つまり**1行目は2回実行されており、`v1` は元の100倍になってしまっている**のだ。

<img width="70%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/665792/78bbee3c-a07a-71ab-9d9e-250c3f381ce1.png">


これは**このセルが冪等でない**ことに起因する。


<details><summary>参考：pythonコード（クリックして展開）</summary>

```python
import pandas as pd

df = pd.DataFrame({'v1': [2,4,6], 'v2': [10, 6, 11]})
df['v1'] = df['v1'] * 10
df['v3'] = df.apply(lambda x: 1 if x.v2 > 0 else 0)  # これだとエラーが発生する
# df['v3'] = df.apply(lambda x: 1 if x.v2 > 0 else 0, axis=1)  # これに直せば実行できるが。。
```
</details>


# 対処法
#### 1. 毎回頭から全部実行する
それは流石に待てねえよ、あんちゃん
（とは言え長すぎるノートブックは事故の元なので、これも大事）

#### 2. 別名で保存
違う名前のオブジェクトを都度作る。あるいはデータフレームだと、別の列を作って対処する。
が、保守的がすぎるような印象はある。

<details><summary>先ほどの例だと…（クリックして展開）</summary>

こうすれば冪等なセルになる。

```python
import pandas as pd

df = pd.DataFrame({'v1': [2,4,6], 'v2': [10, 6, 11]})
df['v1_times_10'] = df['v1'] * 10
df['v3'] = df.apply(lambda x: 1 if x.v2 > 0 else 0, axis=1)
```
</details>


#### 3. 関数にする
関数にすると途中で止まってくれるので、エラーを吐いて再実行という罠は逃れられる[^fn]。
kaggleだと `make_FE` みたいな関数にしているのをよく見る（あれはたぶんテストデータにも同じ処理をするためだけど）

[^fn]: これも副作用がある関数にしちゃったりすると結局意味ないですが。。

#### 4. 放置。でもこの危険性があることは認識しておく
正直これでもいいと思う。前後行き来して試行錯誤しながらコーディングできることがnotebookの良い点なので、ここにカロリーをかける必要はない

ただし、この危険性があることは注意しておく必要がある。


# 最後に
調べてたらいくつか言及はありましたが[^ref]、ほぼヒットしなかったのでこんな概念は一般的ではない（あるいは違う言葉を使ってる？）ような気がします。ただ、みんな無意識にやっていることだとは思うので、Python初心者でノートブックをよく使う方など意識してみてはいかがでしょうか。


[^ref]: https://smacke.net/papers/nbsafety-cidr-gong.pdf  や、 https://www.bradford-delong.com/2018/02/jupyter-notebook-programming-dos-and-donts-a-running-list.html など
[Day12] プロトタイプ, 継承

本記事は一人アドベントカレンダー企画の一つです。
[30代未経験エンジニアが25日後にJavaScriptをマスターするカレンダー](https://qiita.com/advent-calendar/2022)

[JAVASCRIPT.INFO](https://ja.javascript.info/)を元にJavaScriptを勉強していき、そこで学んだ知識をアウトプットしていきます。
２５日でJAVASCRIPT.INFOをやりきり、未経験エンジニアがJavaScriptをマスターする過程を投稿していきます。



## ８.1 プロトタイプ継承
### 知らない単語
- リテラルとは
    - 定数の事

### 学んだこと
プロトタイプ継承は
元のオブジェクトを僅かに変更した新しいオブジェクトを作った時、メソッドのコピーや再実装ではなく、その上に新しいオブジェクトを作成することで、元のオブジェクトが持っているものを再利用するので、それを補助する事


JavaScriptのオブジェクトはPrototypeプロパティを持っており、それは別のオブジェクトかnullである

Prototypeプロパティにアクセスするために obj.__proto__ を使うことができ、Prototypeによるオブジェクトの参照は「プロトタイプ」と呼ぶ
objのプロパティを読む、またはメソッドを呼び出したいが、存在しない場合はプロトタイプの中で見つけようとする
書き込み、削除操作はオブジェクトに対して直接動作し、プロトタイプを使わない


### 感想
プロパティを読んだりメソッドを呼ぶ時に何を使うか、どんな処理の流れになるかをしっかり覚えておく。


## ８.2 F.prototype
### 知らない単語
- 無し

### 学んだこと
新しいオブジェクトは new F() のように、コンストラクタ関数で生成でき、
F.prototype がオブジェクトの場合、new 演算子は新しいオブジェクトでPrototypeをセットする

F.prototype は F 上の prototype と名付けられた通常のプロパティを意味している事を間違えないように気をつける、用語としてのプロトタイプとは別である
例として
```javascript
let animal = {
  eats: true
};

function Rabbit(name) {
  this.name = name;
}

Rabbit.prototype = animal;
let rabbit = new Rabbit("White Rabbit"); //  rabbit.__proto__ == animal
alert( rabbit.eats ); // true
```
Rabbit.prototype = animal の設定は、new Rabbit が生成される時、その Prototype へ animal を割り当てる

- デフォルトの F.prototype, constructor プロパティ

通常のオブジェクトでは、prototype は特別なものではない
```javascript
let user = {
  name: "John",
  prototype: "Bla-bla" // no magic at all
};
```

すべての関数は、prototypeプロパティを持っている
デフォルトの prototype は constructor というプロパティだけを持つオブジェクトで、関数自体を指す


### 感想
初心者だと、F.prototypeの prototype と用語としてのプロトタイプが別物だと気付けない可能性があるので、間違えないように覚えておきたい。


## ８.3 ネイティブのプロトタイプ
### 知らない単語
- 無し

### 学んだこと
- Object.prototype

空のオブジェクトを出力する
```javascript
let obj = {};
alert( obj ); // "[object Object]" ?
```
obj は空であり、文字列 "[object Object]" を生成するコードは toString メソッドである
obj = {} は obj = new Object() と同じで、Object.prototype を持っている


- プリミティブ

プリミティブもラッパーオブジェクトのプロトタイプにメソッドを保持する
Number.prototype, String.prototype, Boolean.prototypeなど
undefined と null にはラッパーオブジェクトは無い

- プロトタイプ

組み込みのプロトタイプを変更したり、新しいメソッドを実装することができるが、変更はしない方がよい


### 感想
空のオブジェクトを出力する方法で、objがObject.prototypeを持っている事や[object Object]を生成するメソッドの使用方法など、処理の流れや使うメソッドをしっかり覚えておきたい。


## ８.4 __proto__ なしでの プロトタイプ メソッド, オブジェクト
### 知らない単語
- ディスクリプタ
    - プログラムからファイルを操作する際、操作対象のファイルを識別・同定するために割り当てられる番号の事

### 学んだこと
下記はプロトタイプをセットアップしたり直接アクセスするためのメソッドである

Object.create(proto[, descriptors]) – 与えられた proto を [[Prototype]] として、任意のプロパティディスクリプタで空のオブジェクトを作る
Object.getPrototypeOf(obj) – obj の [[Prototype]] を返す
Object.setPrototypeOf(obj, proto) – obj の [[Prototype]] に proto をセットする

組み込みの __proto__ は古くいので、エラーが発生する可能性もあり、あまり推奨されない

- “非常にシンプルな” オブジェクト

オブジェクトはキー/値ペアを格納するための連想配列として使うことができる
ユーザから提供された キーを格納する場合、「__proto__」以外はうまく動作する
「__proto__」は [[Prototype]] の getter/setterであり、Object.prototype に存在するが、Object.create(null) によってプロトタイプなしのオブジェクトを作ればキーとしての「__proto__」の問題は無くなる


### 感想
使用するメソッドも多い上に、「__proto__」はオブジェクトの中でも特殊だと思うので、特性をちゃんと理解して正しく使いたい。

# 最後に
[[Prototype]]の役割や使用するメソッドなどが多く、混乱してしまいそうなので、整理してもう1度この章を復習して次に進んでいく。
【SwiftUI】HomeIndicatorを非表示にする

# はじめに
iOS16からHomeIndicatorを非表示にする機能がSwiftUIの公式のAPIとして提供されました。
使ってみたので記録しておきます。

# HomeIndicatorとは
ホームボタンのない端末で下の方に表示される棒です。
![IMG_1758.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/03eab896-a04e-5d46-2bcb-83b990a4ed80.png)

# 動画
ちょっとわかりにくいですが、下の棒が消えています。
![Simulator Screen Recording - iPhone 14 - 2022-12-10 at 21.00.04.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/597b1623-bd77-546c-fc82-7650e67218f9.gif)

# 実装
```diff_swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        VStack {
            Image(systemName: "globe")
                .imageScale(.large)
                .foregroundColor(.accentColor)
            Text("Hello, world!")
        }
+       .persistentSystemOverlays(.hidden)
    }
}
```

# おわり
iOS16より前で同じ動きを実装したい場合、下記の記事が参考になります。

https://thwork.net/2022/03/19/swiftui_homeindicatorautohidden/
サービスプログラムを作成できるようになるまで（４）_サービスプログラムの実行

## はじめに

前回は、プログラム内でサービスプログラムの作成方法についてご紹介しました。
今回は、サービスプログラムの実行方法についてご紹介します。

この記事は、プログラム開発をする上で欠かせないサービスプログラムの、一から学習した記録をシリーズに分けてご紹介しています。

## バインド・ディレクトリーの作成

まず、バインド・ディレクトリーの作成`CRTBNDDIR`やバインド・ディレクトリー項目の処理`WRKBNDDIRE`でバインド・ディレクトリーの作成をします。
そして、作成したバインド・ディレクトリーにサービスプログラムを追加します。

![createServiceProgram-04_01.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2962887/cf0a71d3-b37e-e132-eba7-c8b303847b14.png)

## バインド・ディレクトリーの定義

次に、サービスプログラムを実行したいプログラムの制御仕様書（Ｈ仕様書）にバインド・ディレクトリーを定義します。

```rpgle
H BNDDIR('*LIBL/BLG0006DIR')
```

## プロシージャーの呼び出し

そして後はサービスプログラムに宣言したプロシージャーを記述することで、予め作成していた処理を実行することができます。

```rpgle
C                   EVAL      GDHNM       = BLG0006R_GET_HNM(               品名
C                                           GIHNC                           品名コード
C                                           )
```

## おわりに

シリーズの最後にサービスプログラムの実行方法についてご紹介しました。

お読み頂きありがとうございました。

## 関連した投稿

[サービスプログラムを作成できるようになるまで（１）_サービスプログラムの前提](https://qiita.com/tamaday/items/f99e1c307ff69ee42ee0)
[サービスプログラムを作成できるようになるまで（２）_サービスプログラムが実行される流れ](https://qiita.com/tamaday/items/6f25b6a0b4b9f2d252d4)
[サービスプログラムを作成できるようになるまで（３）_サービスプログラムの作成](https://qiita.com/tamaday/items/3aabbb492d01eb86bfe0)
for文の追加によってテスト環境が停止しかけた話【PHP】

# 0.はじめに
SaaSの開発・保守運用をしています。
今日は、**たった数行の改修**で、大規模サービスのテスト環境が全て停止しかけた話をします。

# 1.経緯

PHPで書かれたシステムの改修時に発生した問題になります。

```php
for ($i = 0; $i <= $num; $i++) {
    // ～～～数百行に渡る処理
}
```

上記のような処理があり、`$num`にはユーザーが任意で入力した1～100の値が入ります。

この処理の内部を改修する事になりました。

```php
for ($i = 0; $i <= $num; $i++) {
    // ～～～数百行に渡る処理

    for ($i = 0; $i <= 3; $i++) {
        // ～～～簡単な処理
    }

    // ～～～数百行に渡る処理（PDOを介したデータベースへのインサート処理）
}
```

大雑把な内容はこのような改修になります。

この時点で何が起きるかは分かると思いますが、外側のループ変数に使われる`$i`は、内部ループに入った時にリセットされ、`$i = 0`からセットされ、最終的に`$i = 4`がセットされた状態で外側のループ先頭に戻る事になります。

その際に判定に使われるループ変数はもちろん`$i = 4`で固定されるため、つまり、、、

「`$num`が5以上に設定された場合には処理が無限ループ、更に4以下の場合は1度しかループしない」という結果になります。

しかもこちらはウェブアプリケーション上で実行されていましたが、該当処理の前に
```php
set_time_limit(0);
```
の記述があり、タイムアウトも期待できない状態になりました。

# 2.予見

最初の予見は朝、テストサーバー全体がなんとなく重いと言われた事でした。

平日の朝はそもそもテストサーバーへアクセスが集中しやすいため、アクセス負荷はある程度ありましたが、ウェブサーバーのプロセス数、CPU使用率、LA、メモリ等のスタッツは普段の同時間帯と変わらず、特に違和感に気づく事はできませんでした。

その後も感覚的に重いなと感じる状況は何度かありましたが、明らかな原因は分からず、即時何か対応は行いませんでした。

# 3.発覚

昼になり、まだ重いと声が上がっていて、何か起きているのかと再度確認を行いました。

その際にようやく気付きましたが、書き込み用のデータベースサーバーのストレージ使用率が95%近くになっていました。

GeneralLogの保存は行っていなかったため、とりあえずshow processlistを連打したところ、あるレコードのインサートが毎秒何十回も送られている事に気づきました。

直近のソースの変更履歴を確認した際に、上記ループ文が無限ループとなる可能性がある事に気づきました。

# 4.対処

ソースコードはもちろん発覚後、2，3分で修正を行いました。

```php
for ($i = 0; $i <= $num; $i++) {
    // ～～～数百行に渡る処理

    for ($cnt = 0; $cnt <= 3; $cnt++) {
        // ～～～簡単な処理
    }

    // ～～～数百行に渡る処理（PDOを介したデータベースへのインサート処理）
}
```

この時点でマスターデータベースの容量は98%に達していました。
（容量を圧迫していた直接の原因はバイナリログでした）

ソースコードを修正しましたが、走り出したプロセスは止まる事無く、修正前のソースコードでインサートを続けていました。

次にMySQLのトランザクションをキルしました。

しかし新たなトランザクションが作成され続け、まだインサートは止まりませんでした。

最終的にすべてのウェブサーバーを再起動し、プロセス毎強制停止し、インサートが停止しました。

# 5.その後の対応

無限にインサートされたレコードは関係テーブルを合わせて計数千万レコードに及んでしました。

予期せずインサートされてしまったすべてのレコードの削除を行いました。

一気にすべてのレコードをDELETEした際に、大幅なレプリケーション遅延が発生する可能性があったため、10万レコードずつDELETEを行いました。

その後、データベースの断片化解消を行うため、OPTIMIZE TABLEを実行し、復旧となりました。

# 6.発生要因

冒頭に書いたようなソースコードですが、あの状態で見れば一目危ない事に気づけますが、実際にはその間に数百行のソースコードが入っており、外側のループ変数で何が使われていたか、気づく事はできませんでした。

gitのウェブ上でコードレビューを行った際にも、表示されるのは多少の前後行のみで、ループの冒頭を確認する事はありませんでした。

# 7.対策

forループを使う際は`$i`以外のループ変数を使うか、range関数で生成した配列をforeachするようにしました。
```php
foreach (range(0, 10) as $num) {
    // ～～～処理
}
```

# 8.良かった事

本番環境ではなく、テスト環境で発覚したため、最悪の事態は回避できました。

あと発覚が数十分ほど遅れてしまった場合は新たなバイナリログの出力ができなくなり、マスターデータベースのMySQLが停止していたので、テスト環境を再構築するハメになっていました。

ギリギリで間に合ったことは不幸中の幸いでした。

# 9.悪かった事

朝から再三、確認する機会があったものの、この状況に達するまで気づく事ができませんでした。

何かあった際に確認するスタッツは一覧化した上で正常な値のレンジをドキュメント化しておく必要があると思いました。

# 10.反省

テスト環境にアップする前のコードレビューの段階で気づく必要があったので、その後はループ変数をしっかり確認するようになりました。

良ければ他の記事も読んでください

https://qiita.com/ryoya1122/items/c31b3e6b9c562d9a2349

https://qiita.com/ryoya1122/items/9927cba929ba33860c43

https://qiita.com/ryoya1122/items/502c07410197746e79e4
Go製プレゼンツール「present」のインストール手順

この記事は [Go Advent Calendar 2022](https://qiita.com/advent-calendar/2022/go) の7日目（代打）の記事です．

## はじめに

愛用しているGo製プレゼンツール「[present](https://pkg.go.dev/golang.org/x/tools/present)」ですが、毎回インストール手順を忘れてしまっているのでここに記します。（go module 対応してからコマンド一発で起動しなくなったので余計に...）

- [present package - golang.org/x/tools/present - Go Packages](https://pkg.go.dev/golang.org/x/tools/present)

## 作業手順

今回は macOS Ventura 13.0.1 で行っています。

### 事前準備

Go本体のインストールを、お忘れなく！

- [Downloads - The Go Programming Language](https://go.dev/dl/)

### Goのワークスペースを作成

ホームディレクトリー配下に `go/` ディレクトリーを作成します。

```zsh
% cd
% mkdir go
```

### PATHを通しておく

ホームディレクトリー配下の `.zshrc` ファイルにて、インストールした `present` コマンドを実行できるようにパスを通しておきます。`bin/` ディレクトリーはインストール時に自動作成されます。

```zsh
% cat .zshrc
...
export PATH=$PATH:$HOME/go/bin
...
```

### インストール

現時点で最新版である Go 1.19.4 を使用しているので `go install` コマンドでインストールします。Go 1.18 から `go get` コマンドでインストールできなくなったことはGo存じですよね？

```zsh
% go install golang.org/x/tools/cmd/present@latest
```

### 実行

`present` コマンドを実行するとエラーになります。

```zsh
% present
Couldn't find gopresent files: no required module provides package golang.org/x/tools/cmd/present: go.mod file not found in current directory or any parent directory; see 'go help modules'

By default, gopresent locates the slide template files and associated
static content by looking for a "golang.org/x/tools/cmd/present" package
in your Go workspaces (GOPATH).

You may use the -base flag to specify an alternate location.
```

`-base` オプションで、スライドのテンプレート場所を指定して起動します。

`x/tools` の後に指定するバージョンは次のサイトで確認できます。

- [present package versions - golang.org/x/tools/present - Go Packages](https://pkg.go.dev/golang.org/x/tools/present?tab=versions)

`@latest` を指定してインストールしたので最新を確認。バージョンは 2022年12月6日の  `@v0.4.0` です。

```zsh
% present -base /Users/[ユーザー名]/go/pkg/mod/golang.org/x/tools@v0.4.0/cmd/present
2022/12/10 19:40:32 Open your web browser and visit http://127.0.0.1:3999
```

Webブラウサーにて `http://127.0.0.1:3999` にアクセスすれば完了です。

## さいごに

今回の方法は `present` コマンドとのいうよりも、ソースコードからGo製コマンドをインストールする方法ですね。Go参考までに！q@w@p
python 時間取得

目的：pythonで時間を取得し、見やすい形に直す
環境：Python 3.10.2　datetime 4.7　pytz 2022.5
下の実行結果：12月10日 20:17

```py
#ライブラリのインポート
import datetime
import pytz

#時刻の取得(年-月-日 時:分:秒.マイクロ秒)
time=datetime.datetime.now(pytz.timezone('Asia/Tokyo'))

#見やすい形に変更(○○月○○日 00:00)
time=time.strftime('%m月%d日 %H:%M')

print(time)
```
CASLⅡでシーザー暗号

**おそばせながら、12月10目のアドベントカレンダーです。**
## はじめに
今回は学校で習ったCASLⅡを使ってシーザー暗号を解いてみたです。
CASLⅡを実行できる環境がなかったので『[CASLシミュレーター](https://www.officedaytime.com/dcaslj/)』をお借りしました。
なんとなくでやってみようと考えて行動に起こした結果、地獄を見た回でした。

## 目次
1. 大枠を考えた
2. 副プログラム書いた
3. 合わせてみた
4. 汎用化？
5. 感想

## 大枠を考えた
作ろうとは考えたのですが、何をしたらいいのか分からなかったので、
想像しているプログラムを絵にかいて考えました。それを文字にしたものが
下のようになります。
```
ループ{
    判定
    （大文字）｛文字ずらし｝
    （小文字）｛文字ずらし｝
    （その他）｛そのまま格納｝
}
出力
```
大枠の作り方はあっているのでしょうか。。。
書いている当初はCASLⅡのことを理解していなかったので、このまま作業に
入ってしまいました。

## 副プログラム
分岐した後の文字をずらす作業を副プログラムでしたいと考えました。
そして完成したものがこちらです。

<img src="https://i.imgur.com/j2cWZFA.png
" width="50%">　　　　　<img src="https://i.imgur.com/BbOCv35.png
" width="20%">
とても楽しい。これは大文字を三文字移動させるプログラムです。
この子を基に小文字を移動のプログラムを作成しました。ここまでは順調でした。

## 合わせてみた
試しに大文字だけ呼び出せるかやってみました。
<img src="https://i.imgur.com/CatsEvp.png
" width="50%">　　　　　　<img src="https://i.imgur.com/AFUiiBD.png
" width="20%">
うごかない、てかなにこれ？という状態になってしまいました。

### 出力画面から分かったこと
* 必要以上の出力→副プログラムのOUTの消し忘れ
* すべてD→副プログラムの最初のLAD消し忘れ

### 修正①
<img src="https://i.imgur.com/by5nCRs.png
" width="20%">

まだ変ですね。最後の文字が最初にも入ってしまています。よくコードを見てみると、副プログラムのSTが残ってました。

### 修正②
<img src="https://i.imgur.com/6OVbV1R.png
" width="50%">　　　　　　　<img src="https://i.imgur.com/lpYbGtL.png
" width="20%">

**きたーーーーーーー！！！！！** 
副プログラムもちゃんと作動しました。

## 汎用化？
小文字の分の処理を増やして、それ以外の文字はずらさないように判定を付ければ、、、
```
RS	    START
    	IN	    BUF,LEN
        IN      NUM,LEN2
    	LAD 	GR1,BUF
    	LAD	    GR2,0
LOOP	LD      GR4,0,GR1
        CPA     GR4,=#0041
        JMI     NEXT
        CPA     GR4,=#005A
        JPL     NEXT
        CALL    SHO1
        JUMP    PUT
NEXT    CPA     GR4,=#0061
        JMI     POS
        CPA     GR4,=#007A
        JPL     POS
        CALL    SHO2
        JUMP    PUT
POS     LD      GR0,0,GR1
PUT	    ST	    GR0,GFT,GR2
    	LAD 	GR1,1,GR1
    	LAD 	GR2,1,GR2
    	CPA 	GR2,LEN
    	JMI 	LOOP
    	OUT 	GFT,LEN
FIN  	RET
SHO1	RPUSH
    	LD  	GR0,0,GR1
        LD      GR3,NUM
        SUBA    GR3,=#0030
        ADDA    GR0,GR3
        CPA     GR0,='Z'
        JMI     OK1
        JZE     OK1
        LD      GR3,=#001A
        SUBA    GR0,GR3
OK1     RPOP
    	RET
SHO2	RPUSH
        LD      GR0,0,GR1
        LD      GR3,NUM
        SUBA    GR3,=#0030
        ADDA    GR0,GR3
        CPA     GR0,='z'
        JMI     OK2
        JZE     OK2
        LD      GR3,=#001A
        SUBA    GR0,GR3
OK2     RPOP
    	RET
LEN	    DS  	1
LEN2    DS      1
NUM     DS      1
BUF 	DS  	256
GFT  	DS  	256
        END
```
<img src="https://i.imgur.com/PslWdYm.png
" width="30%">

**完成ー！！！**

## 感想
授業ではその場で解くだけでしたが、実際書いてみると本当に難しい言語でした。
また、どこの処理が間違っているのかを探すのがとても大変だと感じました。
かなり汚いプログラムが出来てしまったので、きれいなプログラムを書けるように
勉強したいです。

## 参考資料
[アセンブリ言語 CASL2 入門]([https://arcanum.work/contents?id=10])

## アドベントカレンダー
・[IPFactoryアドベントカレンダー]([https://qiita.com/advent-calendar/2022/ipfactory])
・12月10日　[ゲーム制作を通してプログラミングを勉強しよう]([https://qiita.com/iscsec_haru/items/798e8cad8da148d4f7e2])　　[HARU]([https://qiita.com/iscsec_haru])さん
効率的な学習方法でモチベーションが継続できる！たった3つのポイント

この記事は、[Ateam LifeDesign Advent Calendar 2022 #2](https://qiita.com/advent-calendar/2022/ateam-life-design)の 25日最終記事になります。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34731/12342fb1-d85c-a429-c2ee-c7c7b8da6352.png" width="400">

**※ 本を読もうとすると毎回閉じてくるうちの愛猫です**

## はじめに
[株式会社エイチームライフデザイン](https://life-design.a-tm.co.jp/) の @kopugです。

先日社内のエンジニアたちと **どんな勉強の仕方をしている？** というテーマで話す機会があったので、そこでの内容を今年のアドベントカレンダーの記事にしてみます。

## 対象読者
* 時間に限りがある中で、日常に追われ中々時間がとれない
* 世の中は日々変化していくので焦りはあるが、何から手をつけたら良いかわからない
* そして継続ができない

そんな悩みが少しは解消できる3つのポイントを書いていきます。

## 1. アウトプットをゴールに設定し、計画をたてる

本を読むでも、Udemyで動画を観るでも何でも良いのですが、勉強の最初に一歩はインプットから始まると思います。
ここで大事なのはそのインプットをした後に何をアウトプットするのかを最初に決めておくことです。（後からアウトプットが変わってもOK）
色々本を読んだり、ソースコードを追いかけたりしても、本当に自分はそれを身につけられているのか？成長しているのか？どこまで理解できたのか？インプットだけだとそこが中々見えてこずに、最後までやりきるのが難しくなった経験はありませんか？
知識を得て結果変わるのは自身の行動に繋がるところなので、その知識を得たからこそできるアウトプットをしていくとこの部分が見やすくなります。

例えば、本を読んだらそこで得た教訓や新しい知識はなんだったのか。そして今までの自分とこれからの自分では何が変わるのか？を文章としてアウトプットするというのも一つの方法です。（読書感想文とかこれに近いのかもしれません）

私は新しいプログラミング言語を学ぶ時は、シンプルなTwitterクローンを作るのを目標にしたり、何らかのフレームワークを使う場合はそこで使えるちょっとしたpluginを作ったり、それが有用だと思えばOSSとして公開したりしていました。

出来上がっていく過程の中で、今自分が分かることと分からないことが見えてきたり、しばらく進めていくとより良いやり方を知りそれを取り入れたりしていく事で、学習量に比例してアウトプットの質が変わっていくのを実感できるようになります。

## 2. 一気に手を広げない

これは良く自分がやってしまっていた失敗体験でもあるのですが、今回学ぼうとしていた事以外の分野にまで新たに手を広げてしまう事ってありませんか？
上の例のTwitterクローンを作る話でいうと、当初学ぼうとしていたのがGolangだったとして、学んで作っていく過程の中でUIが気になりだして、今まで使ったことがないフロントエンドフレームワークに手を出し始めるたり、インフラでいうとAWSじゃなくて今回はGCPでやってみようだとか・・。

どうせ作るなら、今まで使ったことがなく気になっていた環境で構築したいという誘惑に駆られる事があると思いますが、これをやっていくと終わらない未来が待っています。。(；´∀｀)

それぞれの技術領域は一朝一夕で身につくものではないので、調べれば調べるほど奥深いものばかりです。
今回学ぶべき領域をフォーカスした上で、それ以外の分野は今の自分でもやれることだけにしておくのが無難です。
あとから新たに別分野を学ぶ際にここで作ったものをカスタマイズする等をして、まずは完成させることを目指します。

## 3. ツァイガルニク効果を活用する

勉強をするにしても、何かコードを書くにしてもキリが良いところまでやろうとしませんか？
それを中断したほうが効率が良いというやり方の話になります。

ツァイガルニク効果の説明を下記に引用します。
> ツァイガルニク効果（ツァイガルニクこうか、Zeigarnik effect）は、人は達成できなかった事柄や中断している事柄のほうを、達成できた事柄よりもよく覚えているという現象。ツァイガルニック効果、ゼイガルニク効果、ゼイガルニック効果とも表記する。
> [出典: フリー百科事典『ウィキペディア（Wikipedia）』](https://ja.wikipedia.org/wiki/%E3%83%84%E3%82%A1%E3%82%A4%E3%82%AC%E3%83%AB%E3%83%8B%E3%82%AF%E5%8A%B9%E6%9E%9C)

ツァイガルニク効果は色々なところで使われており、例えばシリーズもののテレビドラマや漫画でも、続きが気になる場所で終わることが多くありませんか？
中途半端なところで終わるからこそ、印象に残りやすく早く続きが観たいという欲求に掻き立てられる効果があるようです。

勉強をするにしても同様で、30分だけやる、90分だけやるみたいに時間を最初に決めておいて、時間が来たらどんな状態だったとしてもそこで中断するというのを意識的にやるようにすると、次に再開する時に集中できるまでの時間が早くなるという効果もあります。
この部分がまさにツァイガルニク効果の説明にある **人は達成できなかった事柄や中断している事柄のほうを、達成できた事柄よりもよく覚えているという現象** を上手く活用し、効率的に集中を持続させるやり方になります。

まとまった時間を確保出来ることに越したことはありませんが、少ない時間しか確保できなかったとしてもキリの良いところまでやらずに中断をし、次に繋げていくことができれば、効率良くモチベーションも継続されていくことになるのでしょうね。

## まとめ

年齢を重ねるごとに集中できる時間が短くなっていったり、ライフステージによっては自分のためだけに使える時間も限られていく事がありますが、効率良く自分に合うスタイルをみつけていきながら、生涯エンジニアリングを楽しんでいきたいですね！
Mac mini で連係カメラが認識されない問題の原因と対策

## macOS 13.x Ventura の連係カメラ
　macOS の Ventura では、Apple ID が同じ Mac と iPhone のカメラを連携させる「連係カメラ」機能がワイアレスで使えるようになった、（前のバージョンでも Lightning ケーブルで接続することで iPhoneのカメラをWebカメラのように使うことができていた）
　Appleのデモでは MacBook に iPhone を装着して使用しているが、MacBookは iSightカメラが付いているので、「デスクビュー」（手元を同時に写す）機能以外では必要性が薄い。むしろカメラが付いていない Mac mini ではオンライン会議などで使いたい機能だ。
### Mac mini に接続したディスプレイにiPhoneを装着
　外付けディスプレイに iPhoneを装着するマウンターは belkin などから販売されているが、それらは MacBook系をターゲットにしていて、フックの幅が狭く、筐体が厚いディスプレイでは使えないので、マウンターを自作した。
![IMG_8508D.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16491/305dd0b8-f361-005b-09c1-c4bbde3aba8c.jpeg)
![PXL_20221210_103331454.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16491/41ac564d-7561-2426-c35e-ab8901a712b1.jpeg)
## カメラが認識されない
　いざ、連係カメラを使おうとしたら、カメラが認識されない。FaceTime、QuickTime ともにだめ。メモアプリや Keynote で iPhoneで写真を撮るという連携はできるのだが、動画のカメラとしては認識されないのだった。
　試しに Lightningケーブルで Mac mini と iPhone を接続してみると、カメラが認識されて使うことができた。その状態でケーブルを外すとワイアレス接続に切り替わって使えるのだが、一旦アプリを終了して、再度起動するとカメラが認識されないのだった。なぜ？
![スクリーンショット 2022-12-10 15.45.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16491/c35b2a9a-e83a-8273-1eba-a1365d923d1e.png)
![スクリーンショット 2022-12-10 15.44.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16491/6297d622-e653-e6a3-60bb-2857d6b8cdbd.png)
## Appleのサポートと連携して原因調査
　Apple のサポートに連絡し、チャット対応してくれた担当では解決せず、上席の担当から電話をもらって、二人で相談しながら、検証していった。例えば...
　ログイン時に起動される項目も一通り調べ不要なものを削除。
　念の為Safeモードで起動してみても、原因が解消されない。

## 原因は本体と iPhone の距離
　諦めかけた時、試しにと Mac mini 本体に iPhone をもたれかかるほど近づけてみたら、なんということでしょう！　カメラをワイアレスで認識しました。
　一度、認識されると、ディスプレイの位置まで離しても連携は継続され、そのまま Webカメラのように使用することができました。
　しかし、一旦、使用をやめ、もう一度連携しようとするとだめ。本体にくっ付くほど近づけて連携させてから使用する場所に移して使う必要があります。

## 解決方法
　Mac mini で連係カメラを使用するには、
1. ディスプレイと本体を近くに置く
2. 離れてる場合は、一度 iPhone を Mac本体に近づけておいて、アプリを起動し連係カメラが動作してから、 iPhone を使用したい場所に移して使う
という方法です。
（現状、これが解決方法でしょう）
## 考察
　MacBook系で問題なく使えていたのは本体との距離が近いからということと、連係カメラの利用環境の中に Bluetooth がオンになっていることを考え合わせると、動画カメラを利用しようとした際、近くに連携できる iPhone があるかを BLE の近距離で探していると推察される。
　本来、Mac と iPhone は Bluetooth のペアリングができないはずなのに、連係カメラの利用条件にあるということで推察できたことかもしれない。
## おわりに
　今回、一緒に原因究明を手伝ってくれた Appleのサポートさんに感謝します。
担当してくれた方は「今まで Mac mini で連係カメラの不具合は報告されていたが、原因が距離だっとということが判明したのはとても良い情報が得られました。」と言っていたので、今後なんらかの改善に向かうことを期待します。）
　今回、私のところでは以上のような結果になりましたが、他に何か情報がありましたら、コメントをよろしくお願いいたします。
他クラスで変数を使いたい場合どこにfindViewByIdを記述するのか

this.で指定するだけ

備忘録であるため説明は短い

```java
public class MainActivity extends AppCompatActivity{
    TextView countText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
            this.countText = (TextView) findViewById(R.id.textView1);
    }

    //省略

    他クラス{
        countText.setText(String.valueOf(sec));
    }
}
```
「リーダブルコード」要約_11章

**11章 一度に１つのことを**

一度に複数のタスクを行うコードは理解しにくい。
コードは１つずつタスクを行うように構成するのが望ましい。

一度に1つのタスクをするコードを書く基本的な手順は以下の通り。

* コードが行なっているタスクを全て列挙する。
* 列挙したタスクを、できるだけ異なる関数に分割する。
少なくとも、異なる領域に分割する。

具体的な方法を紹介していく。

**タスクは小さくできる**
例えば、投票機能を例に考える。

具体的な機能としては、
 ユーザーが賛成or反対のどちらかをクリックしたら、
* 現時点の投票スコアを取得する
* 賛成がクリックされたなら投票スコアを+1、反対なら-1をしてスコアを更新する

という２つの処理を行う関数を作る。

この処理を1つの関数内で行うと、１度に複数のタスクを行うせいで理解しづらくなる。
また、タイプミスやバグがあっても気が付きにくくなる。

この分かりにくさを解決するためには、タスクごとに関数を作成して処理を分割するのが良い。

* 関数１： ユーザーが賛成を押したら+1、反対を押したら-1を返す
* 関数２：現時点のスコアを取得し、関数1で返ってきた値を使ってスコアを再計算する

タスクごとに関数を分割したことで、楽に理解できるようになるはずだ。

**11章のまとめ**
読みにくいコードがあれば、そこで行われているタスクを全て列挙する。
タスクごとに関数やクラスに分割し、1度に1つのタスクを行う領域を作っていく。
そうすれば、コードが読みやすくなる。
Windowsバッチファイルで株価を分析する方法（NASDAQ100版）

# 1. はじめに
今回は、自分自身への備忘録を兼ねて、Windowsバッチファイルで株価を分析する方法（NASDAQ100版）を、お伝えしたいと思います

- 参考文献：[yahoo!finace](https://finance.yahoo.com/quote/%5ENDX/history/?guccounter=1&guce_referrer=aHR0cHM6Ly93d3cuZ29vZ2xlLmNvLmpwLw&guce_referrer_sig=AQAAALQc8DphYZV4ql2clrwBP7-dm1kvbwMZsxsllA7x0YHc8RAv0zcBhUJf5H8uILCOP4S1bD5EiEumwwlGCUx3lhWzWgIOmJ7xhhZXOxfu053qNNXFWg1AKeuDHsfbh2ztKeDm9EI8xBBeDg5kbEYq78Lrk9PLq17_Io5_NsxGHWEs)
- 参考文献：[任意の文字列を表示(ECHO)](https://www.javadrive.jp/command/bat/index3.html)
- 参考文献：[バッチ作成における比較演算子の紹介](https://www.miraclejob.com/recommend/detail?cd=681)

# 2. この記事を読んでできること
- Windowsバッチファイルで株価を分析（NASDAQ100版）することができるようになる

# 3. 注意事項
- ダウンロードURLに、yahoo!finaceのオープンデータ CSVファイルを利用させていただいております。（感謝）

# 4. 必要なもの
- Windows OS PC（Windows11を想定）
- テキストエディタ（サクラエディタを利用）

# 5. インターネットショートカットを作成しファイルをダウンロードするバッチファイル
- .batファイルを作成し、実行する

```bat:nasdaq100_download.bat
@echo off
cd /d %~dp0
setlocal enabledelayedexpansion

rem ファイル名をフルパスで設定
set FILENAME=NDX.csv
set FILENAMEFULLPATH=%~dp0%FILENAME%

rem NASDAQ100csvをダウンロード
rem  "https://query1.finance.yahoo.com/v7/finance/download/%5ENDX?period1=1639107906&period2=1670643906&interval=1d&events=history&includeAdjustedClose=true"
curl "https://query1.finance.yahoo.com/v7/finance/download/%%5ENDX?period1=1639107906&period2=1670643906&interval=1d&events=history&includeAdjustedClose=true" -o %FILENAMEFULLPATH%

rem ファイル内容を画面出力
rem type "%FILENAMEFULLPATH%"

echo;
echo;
echo △▼
echo NASDAQ100 checking ...
echo △▼
echo Date Open Close Volume

rem 行読み込み
for /f "tokens=1-12 delims=,." %%a in (%FILENAME%) do (
    rem echo %%a %%b %%h %%l

    set verBigLong=%%~b
    if "!verBigLong:~0,5!" leq "10900" (
        rem echo !verBigLong!
        echo △hit the big long
        echo %%a %%b %%h %%l
        echo;
    )
    
    set verBigShort=%%~b
    if "!verBigShort:~0,5!" geq "16400" (
        rem echo !verBigShort!
        echo ▼hit the big short
        echo %%a %%b %%h %%l
        echo;
    )
    
)

rem 続行するには何かキーを押してください . . .
pause

rem 終了
endlocal
exit /b

```

---

# 6. おわりに
いかがでしたでしょうか？Windowsバッチファイルで株価を分析（NASDAQ100版）することができたのではないかと思います
今回の記事が、みなさまの学習の参考になれば幸いです

2022/12/10 TAKAHIRO NISHIZONO

---

- 参考：[Investing.com](https://jp.investing.com/charts/live-charts)
![Investing.com 2022-12-10 200616.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240522/02b69812-60d2-1401-1ca0-31ebeb7dc271.png)
Power BIで和暦の日付変換でつまづいた話

# はじめに
Power BIを使ってPower Queryでのデータ変換の勉強をしていた時につまづいた話を紹介します。ちょっとしたつまづきかもしれませんが、一つの学びを得られたので経緯をまとめたいと思います。

# 首相官邸のWebサイトから歴代内閣の一覧を取得
そもそもは、Power BIのデータの取得元としてWebサイトから取れるので、試してみようと思ったところからでした。
何を取ろうかと思ってとりあえず見てみたのが首相官邸ホームページの歴代内閣のページ。

https://www.kantei.go.jp/jp/rekidainaikaku/index.html

上記のURLをデータの取得元として指定してからPower Queryを開くと案外きれいにとれていました。あとは下図の「Column5」のように在職日数がFrom～Toで一項目となっているのをFrom,Toで2項目に分け、和暦表示でテキスト形式になっているのを日付形式にしようと考えました。

![キャプチャ5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2517315/b5322a39-c8c7-79bf-0b35-b5605b294935.png)

# 最初にやったこと（エラーになった操作）
「例からの列」を使用して、From-ToのFromの和暦を入力するとそれっぽく取れました。

![キャプチャ6.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2517315/3f86288d-e3a2-37fa-62f9-74c323f9132b.png)

表示される変換式も、以下のようにおかしくなかったので、そのまま「OK」で確定させました。

Text.BeforeDeliminater([Column5],"～")

同様に「例からの列」を使ってFrom-ToのToの和暦を入力し、同様に不自然でなかったので「OK」で確定させました。

すっかり満足したので、それぞれの項目のデータ型を「日付」に変換して「閉じて適用」でPower Queryを終了させました。

ところがそこで意外なエラーが。

![キャプチャ7.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2517315/59d71876-c7a2-f2c5-c775-447269354833.png)

# 原因
エラーとなった原因を確認するため、まず「表示」タブから「データのプレビュー」にある「列の品質」にチェックをつけます。
確かに該当項目にエラーがあります(ちょうど100件なので3個=3%)。

![キャプチャ8.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2517315/1ea41e18-d86b-7d5c-ebca-e63de52ecb1e.png)


下にスクロールすると確かにErrorとなっているデータがありました。クリックすると下にエラーの原因が出てきます。

![キャプチャ9.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2517315/482f6673-6103-12e7-18ae-c006cdc72b96.png)


・・・なるほど、和暦のテキストから日付に変換するときに、「元年」はうまく変換できないということがわかりました。

# 対応
うーんと考えた結果、抽出した和暦の"元"の文字を"1"に置き換えることで対応しました。

Text.Replace([区切り記号の前のテキスト], "元", "1")

これで無事エラーが解消されました。

# おわりに
画面に表示されている範囲には元年のレコードが含まれていなかったので、その場でエラーに気づけませんでした。いずれにせよ、「原因」で触れたように「列の品質」を使えばエラーの割合が表示されるので、エラーの割合が0から3%になった、と途中で気づけたかもしれません。

「データのプレビュー」では、ほかにも「列の分布」や「列のプロファイル」といった、直感的にデータを変換、クリーンアップ、解釈するための機能が提供されています。

https://learn.microsoft.com/ja-jp/power-query/data-profiling-tools

今までこれらの機能の持つ意味がピンと来ていなかったのですが、今後はこのような便利な機能を活用し（既定では最初の1000件でプロファイリングすることに注意ですが）、ステップごとに意図せぬエラーを生んでいないか確認しながら操作を進めたほうがよいと学べました。
【備忘録】"API" "REST" "JSON"についてまとめ


## はじめに
### 前提
超駆け出しエンジニアが勉強したことをアウトプットして知識の定着を図る為に始めたQiita投稿の第一弾です。

私のテスト案件現場では何かバグが起こるたびに"API"やら"JSON"やら色々難しい言葉が飛び交う毎日。。

バグはそれらが要因で発生している事が多いからよく耳に入るんでしょうが、
「一体何のこっちゃかよく分からん、、、勉強しなければ、、、」
って事で勉強した事をまとめました。

### 大まかな流れ
今回の勉強内容の重要なキーワードは"API","REST","JSON"の3つ。

◯インプット : "API", "REST", "JSON"とは何？
↓
◯アウトプット : 実際にAPIを作って理解を深める
↓
◯まとめ

### ゴール
インプットした内容を備忘録としてアウトプットすることで知識を整理する！




## 勉強内容
### ◯インプット
#### API（<font color='red'>A</font>pplication <font color='red'>P</font>rogramming <font color='red'>I</font>nterface）:
➡︎ソフトウェアやプログラム、Webサービスの間をつなぐインターフェースのこと。

「便利機能を外部向けに提供するもの」と言い方を変えるとしっくりくる。。？

例）天気予報アプリで現在の東京の気温の情報が欲しい
→「時刻」「場所」「欲しい情報」をリクエストすればその情報をレスポンスしてくれるAPI
（情報を提供）

→更にその情報を通知として飛ばしてくれるAPI
（機能を提供）




#### REST（<font color='red'>RE</font>presentational <font color='red'>S</font>tate <font color='red'>T</font>ransfer）:
➡︎多くのAPIで用いられている４つの原則・ルール
・アドレス可能性
（一つのURIを用いて全ての機能を表現できるようにすること）
・ステートレス性
（全てのリクエストが完全に分離していて、セッションなどの状態管理は行われないこと）
・接続性
（情報に「別の情報へのリンク」を含める事ができる事を指し、リンクを含めることで別の情報に接続することが可能になる。）
・統一インターフェース
（情報の取得、作成、更新、削除といった操作一式は全てHTTPメソッドを利用）




#### JSON（<font color='red'>J</font>ava<font color='red'>S</font>cript <font color='red'>O</font>bject <font color='red'>N</font>otation）:
    ➡︎サーバーに対してリクエスト、レスポンスのやり取りを行うデータの記述形式の一種。
 もっとも基本的な形式は、データのキーと値を{ }の中にコロンで区切って記載。

例）
```json:example1.json
{
 "Key": "Value",
 "キー": "値",
 "Key1": "Value1"
}
```

配列[]を使用することも可能
```json:example2.json
{
 [
 　"ID": 1,
 　"Name": "Taro",
 　"Height": 160
 ],
 [
  "ID": 2,
  "Name": "Hanako",
  "Height": 150
 ],
 [
  "ID": 3,
  "Name": "Yuji",
  "Height": 180
 ]
}
```




### ◯アウトプット
なんとなくAPIについてイメージが付いたところで簡易的なAPIを作成し、実際に動くかテストしてみた。

今回作成したAPI:『従業員の詳細情報が載っているDBに登録、参照、更新、削除するAPI』

#### ①環境構築
(初めてMacBookで一から環境構築したので正直だいぶ手こずった。。)
・STS(Spring Tool Suite)
・Spring Intializrでアプリケーション作成
(Maven, Java, Spring Boot2.7.6, Jar, Java8, Spring Web, Spring Data JPA, MySQL Driver)
・MySQL
・MySQL Workbench（DB,Table,カラムの作成）



#### ②コード作成
（この辺りは過去の経験の復習。）
・パッケージ作成（repository, controller, model, service）
・クラス作成
➡︎特にServiceの'method=RequestMethod.POST'等のHTTPメソッドでの処理の分け方は初めて知った。



#### ③"Postman"を用いたAPIテスト
（現場でよく使うPostmanはこういう時の為のものだったのかと初めて知った。）
・HTTPメソッド（GET,POST,PUT,DELETE）の処理をJSON含めて作成



#### 結果
うまくいった。。ふぅ。

作ったAPIの概要↓
| HTTPメソッド |    内容     |  JSON |
|---:|-------------|-------------|
| GET |DBに登録されている従業員の情報を全て取得|無|
| POST  |DBに新しく従業員の情報を登録|有|
| PUT  |DBに登録されている指定の従業員の情報を更新|有|
| DELETE  |DBに登録されている指定の従業員の情報を削除|無|


### まとめ
何かと初めてなものが多すぎて非常に手間取ったが、
こうやって実際にインプットだけでなくアウトプットでAPIを作成して中の仕組みを知ることで
より知識の定着が深まった。

まだまだ簡易的すぎるものしか出来ていないので、
これを起点に次々新しいことに挑戦して一つ一つ知識を付けていきたい・・・。




## おわりに
今回はあくまで備忘録なので、今後は知識を与えられるような記事が書けるよう
レベルアップしていきたい。




## 参考記事
・[JavaとSpring BootでREST APIを作成する方法](https://www.twilio.com/blog/create-rest-apis-java-spring-boot-jp)
・[Springbootの環境構築から Hello worldまで on Mac](https://k-sasaking.net/programing/springboot-env-helloworld/)
・[【Mac&Homebrew】MySQLのインストールとMySQL Workbenchを使った接続方法を丁寧に紹介](https://ai-trend.jp/programming/db/mysql-mac-install/)
同期呼び出ししたLambdaがエラーを起こした時に別のLambdaを起動したい

# なぜこれが必要？
* 非同期呼び出しでLambdaを起動した場合は、Lambda自体の機能で別のLambdaを起動できる
* しかし、同期呼び出しの場合そういうのがなさそうなので別のサービスを組み合わせる必要がある

# やること

* エラー監視したいLambdaに紐づくCloudwatchのログを開いて、Lambdaサブスクリプションフィルターを作成するをクリック
![スクリーンショット 2022-12-10 19.20.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176335/91b1adb6-4919-a065-a6b2-77fa3910298c.png)

* 設定項目をいい感じに設定して作成する
![スクリーンショット 2022-12-10 19.18.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176335/6f5aefc4-625d-d824-4768-10453e77d259.png)

* ↑の設定でセットした「Lambda関数」に下記のような内容を入れてデプロイ

``` 実装例.py
import base64
import datetime
import gzip
import json
from urllib.parse import quote_plus

JST = datetime.timezone(datetime.timedelta(hours=9), "JST")


def lambda_handler(event, context):
    # print(event)

    # event["awslogs"]["data"])にデータが入っている
    # ログをgzip -> base64でエンコード されているのでデコードする
    b64decoded = base64.b64decode(event["awslogs"]["data"])
    gzip_decomporesed = gzip.decompress(b64decoded)
    gzip_decomporesed_str = gzip_decomporesed.decode("utf-8")
    data_parsed = json.loads(gzip_decomporesed_str)

    # quote_plusを二回叩いている理由は参考記事を参照
    # /も対象にしたいので、quoteではなくquote_plusを使った方が楽
    # quote_plusだと%が残っちゃうので、cloudwatch logsのURLに合わせて% -> $に置き換え
    log_group = quote_plus(quote_plus(data_parsed["logGroup"])).replace("%", "$")
    log_stream = quote_plus(quote_plus(data_parsed["logStream"])).replace("%", "$")
    
    # cloudwatch logsでフィルターを使いたい場合の記述例
    # こっちは一回置き換えでいい感じの文字列になるっぽい？
    # pattern = quote_plus("?filterPattern=ERROR").replace("%", "$")
    pattern = ""

    log_url = f"https://ap-northeast-1.console.aws.amazon.com/cloudwatch/home?region=ap-northeast-1#logsV2:log-groups/log-group/{log_group}/log-events/{log_stream}{pattern}"

    error_events = [
        {
            "message": log_event["message"],
            "errorAt": datetime.datetime.fromtimestamp(
                log_event["timestamp"] / 1000, tz=JST
            ).strftime("%Y-%m-%d %H:%M:%S"),
        }
        for log_event in data_parsed["logEvents"]
    ]

    # 必要ならこの辺で何かしらの通知なりなんなりを呼ぶ

    body = {"logUrl": log_url, "errorEvents": error_events}
    # print(body)

    return {"statusCode": 200, "body": body}
```

# 参考記事
https://bbh.bz/2019/09/16/how-to-subscription-filter/

https://qiita.com/yoohya/items/3ef1124ae9dd945e3b9f
構造形と誘導形

# はじめに
経済学のテキストで出てくる「構造形」と「誘導形」という用語のメモ書きです。

# 構造形と誘導形
- 構造形（構造型）: 経済理論に基づいたモデル
- 誘導形（誘導型）: 内生変数を外生変数の関数として表したもの（経済理論上の意味が明確ではない）

## 構造推定と誘導形推定
構造形を推定することを構造推定、誘導形を推定することを誘導形推定と呼び、（あくまでも一般的には）下記の分析を得意としています。
- 構造推定: 因果関係のメカニズムの定量的解明や政策の事前評価
- 誘導形推定: 政策の事後評価や探索的・記述的分析

もっと具体的には
- 構造推定
    - 説明変数として明示的に考慮された要因のうち、検証に使用された標本外の効果予測
    - 説明変数として明示的に考慮されていない仮想的要因の因果効果の検証
- 誘導形推定
    - 理論予測の検証
    - 説明変数として明示的に考慮された要因のうち、検証に使用された標本内の効果予測
    
を得意としています。

## 構造形と誘導形の例
構造形と誘導形という用語は、同時方程式を考える際によく出てきます。

同時方程式体系のモデルは、経済変数の関係を経済モデルに基づいて数式化した式（構造形）からなっているものの、その回帰式は内生変数と外生変数を含むためそのままOLSで推定できません。

そこで、構造形からなる連立方程式を変形し、
- 被説明変数: 内生変数
- 説明変数: 外生変数

とする連立方程式（誘導形）を導出します。そして、誘導形の回帰式をOLSにて推定します。

例えば、次のようなモデルを考えます
$$Y_i = \beta_0 + \beta_1 X_i + u_i \tag{1}$$
ここで、興味のあるパラメータは$\beta_1$であり、$Cov(X_i, u_i) \neq 0$（$X_i$は内生変数）とします。このとき、回帰式(1)のパラメータの解釈は背後にある経済理論に依っているとします（構造形）

しかし、内生性が生じているため$\beta_1$を識別することはできません。

そこで、$Cov(Z_i, X_i) \neq 0$かつ$Cov(Z_i, u_i)=0$となる操作変数$Z_i$を利用することで
$$\hat{\beta^{IV}_1} = \frac{\sum_i (Z_i - \bar{Z})(Y_i - \bar{Y})}{\sum_i (Z_i - \bar{Z})(X_i - \bar{X})}$$ と推定することができます（導出は割愛）

上記の推定方法を「操作変数法(IV法)」と言います。

同様の推定量は別のアプローチでも得られます。まず
$$X_i = \pi_0 + \pi_1 Z_i + v_i \tag{2}$$
を考え、2段階の手順で推定するアプローチです。ここで、$v_i$は$E(v_i)=0$かつ$E(Z_i v_i)=0$を満たすとします。このとき、内生変数$X_i$を外生変数$Z_i$の関数として表しています（誘導形）

1. (2)のモデルをOLSで推定し、$X_i$の予測値$\hat{X_i} = \hat{\pi_0} + \hat{\pi_1} Z_i$を求める
1. (1)の$X_i$を$\hat{X_i}$で置き換えて、OLSで$\beta_1$を推定

という2段階の手順でパラメータを推定すると
$$\hat{\beta^{2SLS}_1} = \frac{\sum_i(\hat{X_i} - \bar{\hat{X}})(Y_i - \bar{Y})}{\sum_i (\hat{X_i} - \bar{\hat{X}})^2}$$という推定量が得られます（導出は割愛）

このように2段階の手順による推定方法を「2段階最小二乗法(2SLS法)」と言い、操作変数と内生変数の数が同じ場合には、$$\hat{\beta^{2SLS}_1}=
\hat{\beta^{IV}_1}$$となります。


# 終わりに
最後まで読んでいただきありがとうございました。

zennにて「Python×データ分析」をメインテーマに記事を執筆しているので、ご一読いただけますと幸いです。

https://zenn.dev/s1ok69oo

また、過去にLTや勉強会で発表した資料が下記リンクにてまとめてありますので、こちらもぜひご一読くださいませ。

https://speakerdeck.com/s1ok69oo

# 参考文献
- 小西(2020)「EBPMにおける構造推定と誘導形推定」 『環境経済・政策研究』 Vol.13, No.1, 1‒11
- 末石(2015)「計量経済学」日本評論社
- 西山他(2019)「計量経済学」有斐閣
【Google 検索コマンド】Google検索テクニック

# Google検索テクニック

プログラミングの記事検索時に役立ちそうなテクニックを共有します。

### 期間を指定検索する
`before:` 指定の年数より前を検索
`after:`  指定の年数より以後を検索

```
next.js css after:2020
=> 2020年以降のnext.js cssに関連するサイトが表示
```


### 表示するサイトを絞り込む
`site:` 絞り込みたいサイトを入力

```
next.js css site:https://qiita.com/
=> https://qiita.com/ を含むサイトだけが表示
```


`-site:` 絞り込みに除外したいサイトを入力

```
next.js css -site:https://qiita.com/
=> https://qiita.com/ を含まないサイトが表示
```


### 完全一致検索
検索ワードを`""`で完全一致検索

```
next.js css "CSS in JS"
=> CSS in JSを含むサイトが表示
```


### あいまい検索
検索ワードを`*`にすることであいまい検索


```
TypeError: xxx is not a function　
↓
TypeError: * is not a function
=> エラー文コピペより、より精度が高く検索可能に
```

※随時更新していきます
【Streamlit】簡易データサイエンスAPPのデモ！

![4272-data-dashboard.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2290515/4f41cc4a-8ea5-96e1-e66e-7e528911e7e0.gif)


こんにちは。[おもちゃで遊ぶAdvent Calendar](https://qiita.com/advent-calendar/2022/solo-omocha)11日目の記事です。

「俺はJupyter Notebookができるから立派なデータサイエンティストだぜ！」と思ったあなたに！ちょっと待った！もちろんJupyter Notebookは素晴らしい。データ分析、EDA、機械学習、深層学習まで、（ちゃんとしたら）分かりやすく共有することができる。が、**Jupyter Notebookだけじゃないんだ！**

今回のおもちゃは、もしJupyter Notebookに飽きたら、またはデータサイエンスのおもちゃを作りたい時のためのものになります。

# Streamlitとは
Streamlitとは、多くのデータサイエンティストが愛用する`Python`のみで、フロントエンドまで構築し、デプロイできるフレームワークです。

公式サイトはこちら。

https://docs.streamlit.io/


# 作りたいおもちゃ

本来ならデータサイエンスっぽいおもちゃを作りたかったが、今回は`Streamlit`の機能を一通りのせたものを作って、まずは土台を作りたいと思います。

# デモ

Streamlitの基本機能を一通り実装したが、それがどれほど簡易なのかを、ここで`Markdown`と`画像`機能を用いて紹介します。

## Markdown

ソースコード
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2290515/796804df-ec7c-f4ee-4419-74f18deca316.png)

結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2290515/d5b4670d-5004-0316-add5-3beda023a798.png)

## 画像

ソースコード
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2290515/e5b10ef2-ca28-5066-120b-bff98ef2a3dd.png)

結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2290515/014c7f76-f8e3-e99f-e640-299e4aa72171.png)

めっちゃ簡単です！

# ソースとアプリ

Github Repo：

https://github.com/kayeungadrian-tam/streamlit-demo

アプリ：

https://kayeungadrian-tam-streamlit-demo-appapp-wbrzeh.streamlit.app/


# 次回

Streamlitを使ってデータサイエンスを作るぜ！え、え、えぇぇぇぇぇ！！
JavaScript　配列=配列(Array=Array)　

```javascript:Array
var a = [];
var b = a;
```
という状況になると，bはaの引用となる，C言語のpointer(*)と同じ原理．
つまり，以下の状況になる
```javascript:Array
b[0] = 1;
a[0]     // ==> 1　となる．
a === b   //==> true
```
もしbを新たな配列にしたい場合，for循環で要素を一個づつ渡すべき．

補足:
このような状況は，変数bが別の変数を与えられると，変数aに影響がない.
例は，「@think49」さんのコメントに参照.
Rustを勉強する part3【制御文】

# 記事について
次のTour of Rustを用いて学んだ内容のメモになります。

https://tourofrust.com/

# if / else if / else
C言語とは異なり、条件文を囲む括弧はない。
論理演算子として、`==`,`!=`,`<`,`>`,`<=`,`>=`,`!`,`||`,`&&`などが使用できる。
```rust
fn main() {
    let x = 42;
    if x < 42 {
        println!("42 より小さい");
    } else if x == 42 {
        println!("42 に等しい");
    } else {
        println!("42 より大きい");
    }
}
```

# loop (無限ループ)
無限ループは`loop`文にて記述し、ループから抜けるには`break`文を使う。
```Rust
fn main() {
    let mut x = 0;
    loop {
        x += 1;
        if x == 42 {
            break;
        }
    }
    println!("{}", x);
}
```

### 値を返す loop 
loop内のbreak文は、ループを抜けて値を返すことができる。
```
fn main() {
    let mut x = 0;
    let v = loop {
        x += 1;
        if x == 13 {
            break "13 を発見";
        }
    };
    println!("loop の戻り値: {}", v);
}

```


# while
条件付きループで、条件がfalseとなると終了する。
```Rust
fn main() {
    let mut x = 0;
    while x != 42 {
        x += 1;
    }
}
```

# for
Rustでは`for`文が強力に改良されている。
イテレータとして評価される式を反復処理する。
(イテレータ：項目がなくなるまで、次の項目を返してくれるオブジェクト)
Rustでは整数のシーケンスを生成するイテレータを簡単に扱うことができる。
* `..`演算子：開始番号から終了番号の手前までの数値を生成するイテレータを作成する
* `・・=`演算子：開始番号から終了番号までの数値を生成するイテレータを作成する

```Rust
fn main() {
    for x in 0..5 {
        println!("{}", x);
    }

    for x in 0..=5 {
        println!("{}", x);
    }
}
```

# match
`match`キーワードを用いることで、ある値について条件にマッチしたものの処理をすべて実行することができる。
記述したすべてのケースについて処理される。
```Rust
fn main() {
    let x = 42;

    match x {
        0 => {
            println!("found zero");
        }
        // 複数の値にマッチ
        1 | 2 => {
            println!("found 1 or 2!");
        }
        // 範囲にマッチ
        3..=9 => {
            println!("found a number 3 to 9 inclusively");
        }
        // マッチした数字を変数に束縛
        matched_num @ 10..=100 => {
            println!("found {} number between 10 to 100!", matched_num);
        }
        // どのパターンにもマッチしない場合のデフォルトマッチが必須
        _ => {
            println!("found something else!");
        }
    }
}
```

# ブロック文から値を返す
`if`,`match`,関数等のブロックは、同じ方法で値を返すことができる。
ブロックの最後が`；`のない式であれば、それが戻り値として使用される。
`if`文で使用すると三項演算子のように使用できる。
```Rust
fn example() -> i32 {
    let x = 42;
    // Rust の三項式
    let v = if x < 42 { -1 } else { 1 };
    println!("if より: {}", v);

    let food = "ハンバーガー";
    let result = match food {
        "ホットドッグ" => "ホットドッグです",
        // 単一の式で値を返す場合、中括弧は省略可能
        _ => "ホットドッグではありません",
    };
    println!("食品の識別: {}", result);

    let v = {
        // ブロックのスコープは関数のスコープから分離されている
        let a = 1;
        let b = 2;
        a + b
    };
    println!("ブロックより: {}", v);

    // Rust で関数の最後から値を返す慣用的な方法
    v + 4
}

fn main() {
    println!("関数より: {}", example());
}
```

# まとめ
基本的な制御分においても、Rustの特徴が垣間見える。
イテレータを使用することで、柔軟かつ簡単に反復処理を記述できる。
また、各ブロック文が戻り値を返すことができるという点で、より簡潔にコーディングが可能なようになっている。
チームが上手く回ったと思えるn個の施策

# :art: はじめに
こんにちは、これは何ですか？
これは [トラストバンク Advent Calendar 2022](https://qiita.com/advent-calendar/2022/trustbank) の19日目の記事です

# :basketball_player_tone3: 前語り
現代社会にはチームという概念があり、そこにはチーム開発という手法があります

さて、みなさんのチームは上手く回っていますか？
上手く回っているという定義は、そのチームが何を目指しているかによって異なりますが、
大体は事業に貢献する、リリースをn回する、ユーザーに価値を届けるといった事になると思います

では、それを阻む存在とは何でしょうか？
例えばコミュニケーション、例えば社内フロー、例えば上下関係などなど。
これも確たる定義はなく社風や文化、チームに求められている事などによって様々です

では、阻む存在を倒しましょう

# :cactus: まずやる事
まず、チームはどのような状態であるべきかを検討します
私はよく「距離感が近ければ近いほどよいフランクな状態」であるべきだと考えています
このような状態になれば、円滑なコミュニケーションが取りやすい状態、それ即ち意見や相談事、報告や困っている事が活発に上がり、それらを解消すれば自然と良い結果が出るのでは？という思惑です

これを元に試した事で成功したと思える事とあまり成功しなかったなという事を挙げようと思います

# :ok_woman: 成功したと思える施策

### 1. チームメンバーは平等たれ
チームメンバーには上も下もなく皆平等の立場で良いという考えです
例え決定権を決めるリーダーであっても、決定権を保持するだけであってチーム内では皆と水平な位置が望ましいと考えます

### 2. 堅苦しい言葉を控える
前述の通り平等であればそこに堅苦しい言葉は不要なはずです
例えば「ここの修正をお願いします！」となった時「承知しました」や「かしこまりました」というやり取りがある場合、論理的な根拠は無いですがチームとして上手く結果を出せない事が多い気がします

:::note alert
「承知しました」「かしこまりました」
:::

:::note info
「はい！」「了解です！」 などなど
:::

### 3. されど尊重や礼儀は忘れずに
いくら立場が平等で、堅苦しい言葉が存在しないチームでも、人としてこれは忘れてはいけません
ちゃんとお礼は言いましょう

:::note alert
他人を傷つける事や批判する事はダメ絶対！
:::

# :no_good: あまり成功とは言えなかった施策
### 1. 綿密な計画
管理という視点では大事ですが、これをやるとそれに対して萎縮や縛り、プレッシャーを感じるという意見が多々ありました
作っても1～2週間先の計画、心理的安全性の確保としてこの計画は変更可能だと伝える事、1人で計画するのではなく相手を巻き込んで計画するという事がリカバリー策かなと思います

:::note alert
計画を建てました
:::

:::note info
計画を建てたいので相談させてください、○○はどれくらいに終わりそうですか？
:::

### 2. ランチ会
コミュニケーション目的のために月水金でランチ会をしていたのですが、頻度が多すぎるのと強制力が強すぎました
買いに行く時間や作る時間、そもそも食べない人、時間をずらしたい人などがいる中でのランチ会はキツイという意見があったので、やっても週に1回、また強制ではなく任意で良かったなと思います

# :sun_with_face: 終わり
「そのチームにとって何が正解か？」という哲学的とも思える問題ですが、これからも悩みながら続けて行きたいと思います :)


![END.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67207/ff8c3ba6-c25a-4942-b1a5-a51b6307256f.png)

---

トラストバンクではチームビルディングに対して悩みに悩みながら結果を出してくれるエンジニアを募集中です！

https://www.wantedly.com/companies/trustbank/projects
ソースコードにこそ、UI/UXの追求が必要である

## 前書き

今や、デザインに関してはUI/UXの追求が当たり前となっていますが、

「 **ソースコードにこそ、UI/UXの追求が必要である** 」

と考えます。

「 **ソースコードに美しさの概念を取り入れて実践しているかどうか** 」で、 **プロダクト全体の品質が大きく左右される** と感じます。

「 **ソースコードを芸術の域にまで到達させる** 」ことが、 **プログラマーの本懐である** と考えます。

## UI/UXの追求とは

### 1. 見えないところに気を配る

**顧客、エンドユーザーに見えない（見てもわからない）からと言って、ソースコードが汚くて良いわけはない**

汚いソースコードは、システムにとって「 **害** 」でしかありません。
見えないところにこそ、より一層の気配りが必要だと考えます。

その気配りが、プロダクトを **健全な状態（安定して長期的に稼働する、変更に強い）** に保ち続けていきます。

### 2. 自動テストに依存しない

**自動テストに任せていると、ソースコードはどんどん汚くなる**

近い将来、コーディング自体が自動になり、ある一定のレベルに達していないエンジニア（いわゆる **コピペプログラマー** ）は不要になっていくだろう、と想定しています。
タイポやバグを大量に含ませた汚いコードを増殖させていくエンジニアより、AIによって生成されたコードの方が、圧倒的に価値があります。

自動テストを書くことに意識を集中させすぎてしまい、自身のコーディングスキルに向き合わないでいると、一定のレベルに達することができなくなると思います。
自動テストに頼らなくてもよいコーディングスキルに達しているのかと言うことを、まずは振り返ってみた方が良いと思います。

管理層からの視点だと、自動テストやリファクタリングは「 **予算の無駄遣い（予算をかける価値があるか検討すべきモノ）** 」と言う認識です。
「 **最初から綺麗で品質の良いコードを書いてくれよ。それがプロでしょ？** 」と言いたくなります。

自動テストは不要、とまでは断定しませんが、「 **それ以前に注目しないといけない要素がある** 」と考えます。

### 3. 人間にしかできないことに磨きをかける

**自動化できないことに磨きをかけていく必要がある**

いずれコーディングも自動化されると言う想定のもと、「 **人間にしかできないこと** 」を磨いていく必要があると考えます。

「 **見やすさ、美しさ、伝わりやすさ** 」と言った、「 **AIでは再現が難しい、ファジーで繊細なこと** 」を、徹底的に追求していく必要があります。

### 4. 圧倒的創造性を追求する

**ソースコードを見た人が「芸術」だと感じるほどの、「圧倒的創造性」が必要である**

エンジニアに限らず、 **プログラミングに対する知識を持っていない全ての人** が、

- 美しいと見惚れる（ **究極の芸術性・可読性** ）
- 眺めているだけで情報が流れ込んでくる（ **究極の論理性・伝達性** ）

ほどの「 **圧倒的創造性** 」が必要だと考えます。

**美しいと感じる感性** は、人間の **武器** であり、 **優位性** だと考えます。
**優位性を活かし、ソースコードの価値を最大まで高める** ことが、 **システムの品質を高めていく** ことに繋がります。

### 5. プログラミング言語の成り立ち

**プログラミング言語は、「人が読んで理解するためのモノ」である**

そもそも「 **プログラミング言語（高級言語）** 」は、「 **人間が理解しやすい命令や構文規則を備えたプログラミング言語** 」として発明されたものです。

「 **人間が理解しやすいためのモノ** 」と発明されているのに、「 **美しさ** 」の概念を取り入れていないことは、 **異常ですらある** と考えます。

「 **読む** 」と言う概念が無ければ、 **機械語（低水準言語）をそのまま書けば良い** わけです。

故に、 **UI/UXの概念を持たないことは、「プログラミング言語（高級言語）」を否定することになる** 、とまで考えます。
先人達が発明してきた **資源や思想を有効に活用** し、さらなる発展に繋げていくことが、エンジニアの **責務** であり、 **本懐** だと考えます。

## 結論

エンジニアにとって最大の責務である「 **コーディング** 」に、「 **美しさ** 」と言う概念を取り入れていないため、いつまで経っても「 **品質が悪い** 」と言う課題に悩むことになります。

デザインと同様に、「 **UI/UXの追求** 」が必要不可欠であると考えます。
それこそが、「 **プロダクト開発を成功に導く鍵の１つである** 」と結論づけます。

プロダクトには、「 **成功と言う同じ目標を掲げた、ありとあらゆる人** 」が携わっています。
エンジニアだけではなく、「 **発注元、他職種のメンバー、エンドユーザー、etc...** 」と言った、ありとあらゆる人です。

エンジニアは、「 **プロダクトに携わる全ての人が「美しい」と感じるソースコード** 」を書くことを「 **必達のミッション** 」とするべきだと考えます。

様々な人々の **エネルギー** や **想い** が込められたプロダクトの「 **核** 」を担う、最も重要な役割が「 **エンジニア** 」なのです。
その役割にふさわしい、「 **プロフェッショナル** 」であるべきです。

次世代に繋いでいくためにも、「 **ソースコードの美しさ** 」にこだわりを持っていきましょう。
サービスプログラムを作成できるようになるまで（３）_サービスプログラムの作成

## はじめに

前回は、[プログラム内でサービスプログラムが呼び出されるまでの流れ](https://qiita.com/tamaday/items/6f25b6a0b4b9f2d252d4)についてご紹介しました。
今回は、サービスプログラムの作成方法についてご紹介します。

この記事は、プログラム開発をする上で欠かせないサービスプログラムの、一から学習した記録をシリーズに分けてご紹介しています。

## サブプロシージャーの定義

まず、サブプロシージャーの定義のため、主に以下を記述します。

1. プロトタイプ
2. プロシージャーの開始
3. プロシージャー・インターフェース
4. 処理に必要な変数等
5. 演算仕様書（実行したい処理）
6. プロシージャーの終了

1.プロトタイプ
```rpgle
D BLG0006R_GET_HNM...
D                 PR            62
D  IN_HNC                        9S 0 VALUE                                 品名コード
```

2.プロシージャーの開始
```rpgle
P BLG0006R_GET_HNM...
P                 B                   EXPORT
```

3.プロシージャー・インターフェース
```rpgle
D BLG0006R_GET_HNM...
D                 PI            62
D  IN_HNC                        9S 0 VALUE                                 品名コード
```

4.処理に必要な変数等
```rpgle
D OUT_HNM         S             62                                          品名
```

5.演算仕様書
```rpgle
C     B6KEY1        KLIST
C                   KFLD                    K@6HNC
C     *LIKE         DEFINE    BG06HNC       K@6HNC
C*
C                   Z-ADD     IN_HNC        K@6HNC                          品名コード
C     B6KEY1        CHAIN(N)  BLG0006R1
C                   IF        %FOUND
C                   MOVEL(P)  BG06HNM       OUT_HNM
C                   ELSE
C                   MOVEL(P)  *BLANK        OUT_HNM
C                   ENDIF
C*
C                   RETURN    OUT_HNM                                       品名
```

6.プロシージャーの終了
```rpgle
P                 E
```

## エクスポートリストの作成

次に、エクスポートリストに前項で作成したプロシージャーを記述します。
```bnd
  STRPGMEXP

    EXPORT SYMBOL('BLG0006R_GET_HNM')

  ENDPGMEXP
```

## モジュール＆サービスプログラムの作成

最後に「サブプロシージャーの定義」の際に作成した RPGLE のモジュールの作成`CRTRPGMOD`とサービスプログラムの作成`CRTSRVPGM`を実行します。

## おわりに

今回はサービスプログラムの作成方法についてご紹介しました。

最後までお読み頂きありがとうございます。

## 関連した投稿

[サービスプログラムを作成できるようになるまで（１）_サービスプログラムの前提](https://qiita.com/tamaday/items/f99e1c307ff69ee42ee0)
[サービスプログラムを作成できるようになるまで（２）_サービスプログラムが実行される流れ](https://qiita.com/tamaday/items/6f25b6a0b4b9f2d252d4)
[サービスプログラムを作成できるようになるまで（４）_サービスプログラムの実行](https://qiita.com/tamaday/items/a5181ed4faa9949e0707)