OmniAICreator/Qiita-1.07M huggingface dataset:
Modeler scriptでパラメーター値を取得する

Modeler scriptでModelerのパラメーター値は以下で取得可能です。
```python
stream.getParameter('<パラメータ名>')
```
# パラメータ名を指定して取得
以下のようなパラメーター（例：Param1）の値(例：1234)を取得したい場合は、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/65de9320-dd08-6545-7a2d-c4875087b9f1.png)

以下のようなModeler Scriptで取得できます。
```python
import modeler.api
stream = modeler.script.stream()
print(stream.getParameter('Param1'))
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/fc964973-ee79-1ae4-9cb6-7bea735b1cf8.png)

# パラメータ名から取得
stream.getParameterNames()でパラメータ名も取得できます。

```python
for x in stream.getParameterNames():
        print x + ":" + str(stream.getParameter(x))
```
以下の二つのパラメーターを登録していると、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/bd66181a-c58e-8013-67f6-2a0451a20d0c.png)

以下のようにパラメータと値を取得できます。

```output:結果
Param2:abc
Param1:1234
```

■サンプルストリーム

https://github.com/hkwd/spssmodelerscript/raw/master/220427getParameter/modelerscriptgetParameter.str

■テスト環境
Modeler 18.3
Windows 10 64bit
plunkerでshadertoy sandbox その 4

# 概要
plunkerでshadertoyのglsl動かしてみた。
iChannel0、実装してみた。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/54eb0629-a931-6e9b-c545-01dd0fbaa3bf.png)

# 成果物

https://embed.plnkr.co/plunk/AhLosXNYhd2mkADF

以上。
docker-composeでrailsの環境構築時に出るエラーについて

下記のようなエラーに出くわしたので備忘録。

```
mbp:sample_app kentaroyoshizumi$ docker-compose run web rails new . --force --database=mysql --skip-bundle
Pulling db (mysql:8.0)...
8.0: Pulling from library/mysql
4be315f6562f: Already exists
96e2eb237a1b: Already exists
8aa3ac85066b: Already exists
ac7e524f6c89: Already exists
f6a88631064f: Already exists
15bb3ec3ff50: Already exists
ae65dc337dcb: Already exists
573c3c7fa18d: Pull complete
9d10771b98b8: Pull complete
3d8ef442614b: Pull complete
7dc17a6cea26: Pull complete
752752efdaea: Pull complete
Digest: sha256:2dafe3f044f140ec6c07716d34f0b317b98f8e251435abd347951699f7aa3904
Status: Downloaded newer image for mysql:8.0
Building web

Traceback (most recent call last):
  File "compose/cli/main.py", line 81, in main
  File "compose/cli/main.py", line 203, in perform_command
  File "compose/metrics/decorator.py", line 18, in wrapper
  File "compose/cli/main.py", line 968, in run
  File "compose/cli/main.py", line 1426, in run_one_off_container
  File "compose/project.py", line 664, in up
  File "compose/service.py", line 364, in ensure_image_exists
  File "compose/service.py", line 1111, in build
  File "compose/service.py", line 1841, in build
compose.service.BuildError: (<Service: web>, {'message': 'dockerfile parse error line 4: unknown instruction: //'})

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "docker-compose", line 3, in <module>
  File "compose/cli/main.py", line 92, in main
TypeError: can only concatenate str (not "dict") to str
[93647] Failed to execute script docker-compose
```

結論Dockerfile内のコマンドの記述が誤っていた。

```Dockerfile
FROM ruby:2.5
RUN apt-get update -qq && \           //←バックスラッシュが抜けていたり、コメントアウトがきいていなかったりする。
  apt-get install -y build-essential libpq-dev nodejs

RUN mkdir /myapp
WORKDIR /myapp

COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock

RUN bundle install
COPY . /myapp
```

ここを修正してうまく構築できた。
[AtCoder] 個人的に使用頻度が高いitertoolsまとめ

AtCoderで組み合わせ問題など抽出方法をどうしようか迷いますよね。
自作するのも一つの手ですが、itertools関数を使った方がバグらないです。
※一度自作して処理を考えることをお勧めします

## 表示用関数用意
```python
import itertools

def printitertools(itertool_return, describe):
    print(describe)
    for i in itertool_return:
        print(i)
    print("")


```

## デカルト積(product)
全bit探索にも使えます。

```python
printitertools(itertools.product(range(2), repeat=3), "product")

#product
#(0, 0, 0)
#(0, 0, 1)
#(0, 1, 0)
#(0, 1, 1)
#(1, 0, 0)
#(1, 0, 1)
#(1, 1, 0)
#(1, 1, 1)

```

## 順列（Permutation）

高校時代勉強した3P2です。
```python
printitertools(itertools.permutations([1, 2, 3], 2), "permutations")

#permutations
#(1, 2)
#(1, 3)
#(2, 1)
#(2, 3)
#(3, 1)
#(3, 2)

```

## 組み合わせ(combinations)
高校時代勉強した3C2です。
```python
printitertools(itertools.combinations([1, 2, 3], 2), "combinations")

#combinations
#(1, 2)
#(1, 3)
#(2, 3)

```

## 組み合わせ(combinations_with_replacement)

同じ項目を２つ選ぶの可能なバージョンです。

```python
printitertools(itertools.combinations_with_replacement([1, 2, 3], 2), "combinations_with_replacement")

#combinations_with_replacement
#(1, 1)
#(1, 2)
#(1, 3)
#(2, 2)
#(2, 3)
#(3, 3)

```

## 対応した項目だけ抽出(compress)

```python
printitertools(itertools.compress([1, 2, 3], [True, False, True]), "compress")

#combinations
#1
#3
```
Databricks SQL on Google Cloudのご紹介 - パブリックプレビュー

[Databricks SQL Is now available in public preview on Google Cloud \- The Databricks Blog](https://databricks.com/blog/2022/04/25/introducing-databricks-sql-on-google-cloud-now-in-public-preview.html)の翻訳です。

:::note warn
本書は抄訳であり内容の正確性を保証するものではありません。正確な内容に関しては原文を参照ください。
:::

本日[Google Cloud](https://databricks.com/jp/product/google-cloud)上の[Databricks SQL](https://databricks.com/jp/product/databricks-sql)が[**パブリックプレビュー**](https://docs.gcp.databricks.com/sql/index.html)になったことを発表できて嬉しく思っています。この発表により、[標準的なSQL](https://databricks.com/blog/2021/11/16/evolution-of-the-sql-language-at-databricks-ansi-standard-by-default-and-easier-migrations-from-data-warehouses.html)を用いた[Databricks SQLのデータウェアハウスワークロードに対する世界記録の性能](https://qiita.com/taka_yayoi/items/b9b25d2050685706a20b)を活用してGoogle Cloudにおけるデータウェアハウスやビジネスインテリジェンスのワークロードを実行することで、お客様はさらにレイクハウスアーキテクチャの導入を促進することができます。

[Databricks on Google Cloud](https://databricks.com/jp/product/google-cloud)との密連携によって、企業はデータウェアハウスとデータレイクの長所を組み合わせた、シンプルかつ[オープンなレイクハウス](https://databricks.com/jp/product/data-lakehouse)プラットフォーム上で分析やAIのワークロードを実行できる柔軟性を手に入れることができます。

Databricks SQLを用いることで、Google Cloudと[Databricksレイクハウスプラットフォーム](https://databricks.com/jp/product/data-lakehouse)上でデータウェアハウスや分析ワークロードを実行するために必要な全ての機能を手に入れることができます。

- 分析ワークロードでは典型的な低レーテンシー、高い同時実行性のクエリーに対するインスタントかつ弾力性のあるサーバレスの計算資源。計算資源はストレージから分離されているので不安なくスケールすることができます。
- お使いのBIツールに対して最適化かつインテグレーションされたコネクターによって、新たなソリューションを学ぶことなしにデータから価値を導き出すことができます。
- 標準的なSQLによってシンプル化された管理とデータガバナンスによって、クイックかつ自信を持ってセルフサービスの分析を進めることができます。
- [GoogleワークスペースベースのSSO](https://docs.databricks.com/administration-guide/users-groups/single-sign-on/gsuite20.html)に対するネイティブサポートによるシンプルなユーザー管理。
- SQLクエリーエディタ、可視化、インタラクティブダッシュボードによるファーストクラス、ビルトインの分析体験。
![](https://databricks.com/wp-content/uploads/2022/04/db-148-blog-img-1.jpg)

# 使い始めてみる

Databricks SQLはGoogle Cloud上で全てのお客様に対してパブリックプレビューとなっており、高性能なクエリー実行を用いてマルチクラウドのレイクハウスアーキテクチャを操作できるようになっています。すなわち、Google Cloud上のDatabricks SQLのパブリックプレビューによって、Google Cloud上のデータとAIサービスをサポートでき、お客様は自身の組織がシームレスに作業できるようになるのでwin-winの関係となっています。Google Cloud上のDatabricks SQLについて理解を深めたいのでしたら、[Data Partner Spotlight](https://cloudonair.withgoogle.com/events/data-partner-spotlight)あるいは次回のハンズオンの[Quickstart Lab](https://databricks.com/p/webinar/databricks-on-google-cloud-quickstart-labs)に参加してみてください。

### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)
[mermaid] git graphについて

# 使う前に

使う前に、`mermaid`のversionを確認しましょう

リリースノートにより、[9.0.0](https://github.com/mermaid-js/mermaid/releases/tag/9.0.0)以降
`gitGraph`のgrammarが変更された部分があります。

最新版を使いたいなら、
過去version(~8.14.0)の一部grammarが使えなくなります
2022/04/28時点、Qiitaは`8.14.0`を使っていました

## 8.14.0

```8.14.0
gitGraph:
  commit
```

## 9.0.0
```9.0.0
gitGraph
  commit
```

`9.0.0`以降を確認したい場合、
[Mermaid Live Editor](https://mermaid.live/edit)で確認できます

# git command

- commit
- branch
- checkout
- merge

上記四つ`command`を使い、下記の図を描ける

```mermaid
gitGraph
   commit
   commit
   branch develop
   checkout develop
   commit
   commit
   checkout main
   merge develop
   commit
   commit
```

古いバージョンを使うと、エラーが表示される
```mermaid
gitGraph:
commit
commit
branch develop
checkout develop
commit
commit
checkout master
commit
merge develop
commit
commit
```

# Reference

http://mermaid.js.org/syntax/gitgraph.html#gitgraph-diagrams
100日後くらいに個人開発するぞ！day010

## 今日はレイアウトを作ってみた！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2632394/48523ba7-5632-2fb6-a894-0e00660eade5.png)

## 今日のアウトプット
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2632394/e3176636-ac5b-51c8-cc70-9928a89aa670.png)



## 今日の学び

### カーソルを乗せた時に色を変える方法
 - カーソルが乗った状態をhoberという
 - セレクタ:hoberでカーソルが乗った状態のCSSを指定できる
    - 例：ボタンにカーソルが乗った時赤くするCSS
        - `.button :hober{background-color:red;}`


### ボタンを角丸にする方法
- 要素の角を丸めるにはbroder-radiusプロパティを用いる
    - 例：角を半径10pxの円にしたい
        - `.button{border-radius:10px;}`


### テキストを中央に寄せる方法
- text-alignプロパティを用いるとテキスト・インライン要素・インラインブロック要素の配置を指定できる
    - left：左寄せ
        - 例：`text-align:left`
    - center：中央揃え
        - 例：`text-align:center`
    - right：右寄せ
        - 例：`text-align:right`
- `margin:0 auto`と`text-align:center`の使い分け
    - `margin:0 auto`：広い範囲を囲うようなブロック要素を中央揃えにしたい時に用いる
    -  `text-align:center`：テキストやボタンのようなインライン要素・インラインブロック要素を中央揃えにしたい時に用いる


### アイコンを用いる方法
- アイコンを表示するにはFont Awesomeを使うと便利
    - https://fontawesome.com
- Font Awesomeは以下の手順で使用できる
    -　Font AwesomeのCSSファイルをHTMLの<head>タグで読み込む
        -　`<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">`
    - <span>タグにfaクラスとfa-アイコン名クラスを指定する
        - `<span class="fa fa-twitter"></span>`
PHP　unset　変数削除

## 用途
定義した変数を削除したい時に使う。
配列から指定した値を削除したい時に使う。
処理の終わりに毎回変数をリセットしたい時などにも使える。

## 使用方法
```php:変数削除
$hoge = "ほげほげ";
unset($hoge); // $hogeという変数を削除

var_dump(isset($hoge)); // bool(false)
```
isssetの結果、falseが返ってきているから削除できている。

```php:配列から指定した値を削除
$hoge = array(0, 1, 2, 3, 4, 5);
unset($hoge[1]); // 配列の「1」が削除される

print_r($hoge);
// 結果
[0] => 0
[2] => 2
[3] => 3
[4] => 4
```
※配列の場合は、削除したいインデックスを指定する。
Excel-A1セルに戻して終了するマクロ

グループ化しているものは閉じる&フォント=Meiryo UIに変える&A1セルにカーソル戻す&100%表示にして保存して閉じるコード
(※ワークブック=1つの際のアプリケーションquitが働いていないためデバッグ中)


```vb
Sub 保存して閉じる()
'
' close Macro
' 画面更新をさせない（チカチカするため）
Application.ScreenUpdating = False
'
Dim ws As Worksheet
' 各シートを順番に見ていく
For Each ws In Worksheets
' シート保護されてるか確認
If ws.ProtectContents = True Then
'保護されてたら何もしない
Else
    ws.Activate
    ws.UsedRange.Select
' フォントを「Meiryo UI」に変える
    With ws.Cells.Font
           .Name = "Meiryo UI"
'もし英数字だけArialに変えたい場合、↓の1行のシングルクォーテーションをとってください
           '.Name = "Arial"
    End With
    
' カーソルをA1に移動
    ws.Select
    Range("A1").Select
' 表示位置を左上端に移動
    ActiveWindow.ScrollColumn = 1
    ActiveWindow.ScrollRow = 1
' 表示倍率を１００％に戻す
    ActiveWindow.Zoom = 100


ws.Outline.ShowLevels rowLevels:=1, columnLevels:=1
End If
Next ws
' １枚目のシートに移動
Sheets(1).Select
'画面更新を再開させておく
Application.ScreenUpdating = True
If Workbooks.Count > 1 Then
    ActiveWorkbook.Save
    ActiveWorkbook.Close
Else
    ActiveWorkbook.Save
    Application.Quit
End If
'
'
End Sub
```
Google Drive API v3でthumbnailLinkが出ないとき

# きっかけ
`GET https://www.googleapis.com/drive/v3/files`など、Google Drive API v3を使ってファイルの情報を取得したときに、2022年2月時点は返されるフィールドにサムネイル画像のリンク先を表す`thumbnailLink`があったのに、2022年4月にはなくなっていたので解決法を確認した。

# 結論
スコープで少なくともファイルの中身を見ることができる`drive.readonly`以上を指定する。

# 参考になるドキュメント
## Google Drive APIの[Filesのリソースリファレンス](https://developers.google.com/drive/api/v3/reference/files#resource)

> thumbnailLink
> A short-lived link to the file's thumbnail, if available. Typically lasts on the order of hours. **Only populated when the requesting app can access the file's content.** If the file isn't shared publicly, the URL returned in Files.thumbnailLink must be fetched using a credentialed request.

## Google Drive APIの[スコープ一覧](https://developers.google.com/identity/protocols/oauth2/scopes#drive)
| スコープ | 説明 |
|:-:|:-:|
| https://www.googleapis.com/auth/drive  | すべてのGoogleドライブファイルを表示、編集、作成、および削除します  |
|  https://www.googleapis.com/auth/drive.appdata |  Googleドライブで独自の構成データを表示および管理する |
| https://www.googleapis.com/auth/drive.file  | このアプリで開いた、または作成したGoogleドライブのファイルとフォルダを表示および管理しま  |
|  https://www.googleapis.com/auth/drive.metadata | Googleドライブ内のファイルのメタデータを表示および管理する  |
| https://www.googleapis.com/auth/drive.metadata.readonly  | Googleドライブ内のファイルのメタデータを表示する  |
| https://www.googleapis.com/auth/drive.photos.readonly  |  Googleフォトで写真、ビデオ、アルバムを表示する |
| https://www.googleapis.com/auth/drive.readonly  |  すべてのGoogleドライブファイルを表示してダウンロードします |
| https://www.googleapis.com/auth/drive.scripts  |  Google AppsScriptスクリプトの動作を変更する |

2022年2月に書いたときは`drive.metadata.readonly`でも`thumbnailLink`のフィールドが返されていたのに、ファイルの中身が見えるスコープでないと返さないようになった模様。
json_encode()で日本語が文字化け　Unicodeエスケープさせない

## 用途
json_encode()で日本語の表示が文字化けしないようにしたい時に使う。

## 使用方法
```php:例
$hoge = [ "hoge" => "ほげほげほげほげ" ];
json_encode($hoge, JSON_UNESCAPED_UNICODE);    

// 結果 {"hoge":"ほげほげほげほげ"}
```
### 解説
`JSON_UNESCAPED_UNICODE` オプションを `json_encode()` の第2引数に指定することで、日本語の文字化けを防げる。（Unicodeエスケープさせないようにする）
Makefile 内のコマンドに .env file の環境変数を渡す

# Makefile 内のコマンドに環境変数を渡す
Makefile は 長い コマンド等の手軽なコマンド化を行うのに便利です。
一方で、 Makefile 内では、複数行でコマンドを渡すと、１つ１つが別々なプロセスで扱われるなど、 bash に コマンドを1つ1つ実行するのとは違う挙動を示します。

本記事では、 Makefile 内で実行するコマンドに実行時に環境変数を渡す方法を記載します。

Makefile の サンプルは以下のリポジトリに保存しています。

https://github.com/ikasumi/makefile_env_file


# 環境変数を .env ファイルから渡すユースケース
Google Cloud Storage や Azure の Blob Storage 等のサービスアカウントやアクセスキーの秘密にすべき情報のベストプラクティスの１つは、環境変数経由で渡すようにし、gitにはコミットしないようにするということがあります。

Make での実行時には、実行環境の環境変数は引き継がれますが、 Makefile の実行時に環境変数を渡したいということがあります。

例えば `Makefile` 以下のように記載して実行すると、 `${MY_SECRET_KEY}` の値は空になり、 `MY_SECRET_KEY` は渡せていません。
```Makefile
run-non-secure:
	export MY_SECRET_KEY="hoge" && echo ${MY_SECRET_KEY}
```

実行例
```
$ make run-non-secure

# 何も出力されない
```

なぜか。

# Makefile 内の変数の種別
Makefile内で利用する変数には以下の3つがあります。
- 環境変数: シェルで定義される変数。定義を実行したプロセスと、そのプロセスを親とする子プロセスまで引き継がれる。
- シェル変数: シェルで定義される変数。定義を実行したプロセスでしか有効ではありません。
- make変数: Makefile の中で定義される変数。 Makefile の中でのみ有効です。

参考: 
[ちょっとMakefileくん！ .envに書いた環境変数読んで！！！！！なんで読んでくれないの！？](
https://zenn.dev/canalun/articles/7d31ba0fb12be2#%E3%81%84%E3%81%8F%E3%81%A4%E3%81%8B%E3%81%AE%E9%A9%9A%E3%81%8D%E3%81%AE%E4%BA%8B%E5%AE%9F)



makefile 内では、＄一つの `${ENV_KEY_NAME}` は make 変数として扱われます。
一方で、 export しているのは、 シェルで定義するので、 環境変数として定義されてしまうため、
定義している場所と参照している場所がことなるため、内容が読めていませんでした。

環境変数やシェル変数にアクセスするためには、 Makefile 内では、
変数名に `$$` ２つをつけて以下のようにすると読むことができます。

```makefile
run-non-secure-env-var:
	export MY_SECRET_KEY="hoge" && echo $${MY_SECRET_KEY}
```

実行例
```
$ make run-non-secure-env-var
hoge
```

# セキュアにするには
先程の例では export の 内容を Makefile に直書きしていました。
しかし、セキュリティ上 git 上に Secret Key を残すことは良くないので、
Secret については、 `.env` ファイルを別に用意して、 git にコミットする以外の方法で受け渡すようにすることが望ましいです。

なので以下のようにします。

```secrets.env ※ git に含めないファイル
# 本来はこのファイルは git には含めません
MY_SECRET_KEY="hoge"
```

set -a && source secrets.env && set +a を行うことで、 secrets.env の内容を 今の環境変数に追加できます。
```makefile
run-secure-env-var:
	set -a && source secrets.env && set +a && echo $${MY_SECRET_KEY}
```


実行例
```
$ make run-secure-env-var 
hoge
```


# 参考記事
[Makefileで、実行するコマンドに環境変数を渡す方法](https://redj.hatenablog.com/entry/2021/08/09/230719)
[ちょっとMakefileくん！ .envに書いた環境変数読んで！！！！！なんで読んでくれないの！？](https://zenn.dev/canalun/articles/7d31ba0fb12be2)
[makeで環境変数とMakefileの変数、引数の値の内どの値が参照されるか](https://www.sambaiz.net/article/314/)
PHP　$_SESSION　一連の流れ

## 用途
サーバー側に、サイトを訪れたユーザの情報を個別に保存しておいて、情報をもとにさまざまなページで処理をしたい時に使う。

## 使用方法
### 一連の流れ
#### 1.セッションに保存する
```php:ファイル①（セッションに保存するファイル）
<?php
    session_start(); // セッションをスタート
    $_SESSION['name'] = 'hoge'; // セッションのnameに情報を保存
    $name = $_SESSION['name']; // セッションの情報を$nameに代入
    var_dump($name); // "hoge"が表示される
?>
```
※セッションは連想配列で保存される。

#### 2.セッションに保存したものを別ファイルで使用する
```php:ファイル②（上記のファイルで保存したものを他のファイルでも使えることを解説するファイル）
<?php
    session_start(); // セッションをスタート
    $name = $_SESSION['name']; // ファイル①でセッションで保存してあるnameを取得して、$nameに代入
    var_dump($name); // "hoge"　が表示される
?>
```

#### 3.セッションに保存したものを削除する
```php:ファイル③（セッションで保存してある情報を削除する方法を解説するファイル）
// 削除するセッションを指定する場合
<?php
    session_start(); // セッションをスタート
    $_SESSION['name'] = 'tanaka'; // セッションのnameに情報を保存
    $_SESSION['number'] = 5; // セッションのnumberに情報を保存
    unset($_SESSION['name']); // セッションのnameの値を削除する
    var_dump($_SESSION); // array(1) { ["number"]=> int(5) }　が表示される
?>

// 全てのセッションを削除する場合
<?php
    // 削除するセッションを指定する場合
    session_start(); // セッションをスタート
    $_SESSION['name'] = 'tanaka'; // セッションのnameに情報を保存
    $_SESSION['number'] = 5; // セッションのnumberに情報を保存
    $_SESSION = array(); // セッションを空配列にする
    var_dump($_SESSION); // array(0) { }　が表示される
?>
```

#### 4. セッションを終了・破棄する
```php:ファイル④（セッションを終了・破棄する方法を解説するファイル）
// セッションを破棄
<?php
    session_start();
    $_SESSION['name'] = 'hoge'; // セッションのnameに情報を保存
    session_destory(); // セッションを破棄する
?>

// セッションを保存しないで終了
<?php
    session_start();
    $_SESSION['name'] = 'hoge'; // セッションのnameに情報を保存
    session_abort(); // セッションを保存しないで終了する
?>

// セッションを保存して終了
<?php
    session_start();
    $_SESSION['name'] = 'hoge'; // セッションのnameに情報を保存
    session_write_close(); // セッションを保存して終了する
?>
```
※コメントでご指摘をいただき修正しました。

## その他
### セッションが保存される有効期限を設定する
```php:ファイル⑤（セッション有効期限を設定する方法を解説するファイル）
<?php
    session_start();
    ini_set('session.gc_maxlifetime', 100); // セッションの有効期限を100秒に設定する
?>
```
`ini_set` で有効期限を設定する。
第1引数には、有効期限の設定の `session.gc_maxlifetime ` を入力する。
第2引数には、設定したい有効期限を「秒数」で指定する。
※デフォルトではプラウザが閉じるまで有効になっている。

:::note warn
注意
正確にいうと、 `session.gc_maxlifetime` はセッションの有効期間そのものを設定する項目ではない。
:::


`session.gc_maxlifetime` はセッションを削除する「セッション破棄処理（ガベージコレクション(gc)）」が起動してからの秒数を設定している。
「セッション破棄処理（ガベージコレクション(gc)）」が起動する確率は下記で設定されている。
`session.gc_probability / session.gc_divisor`
※ デフォルトは1/100(1%)
なのでアクセス頻度が低いと「セッション破棄処理（ガベージコレクション(gc)）」を起動する判定回数が少なくなる。
→ 起動確率が低くなり、**長い間セッションが残る場合もある。**
※コメントでご指摘をいただき修正しました。

```:session.gc_probabilityの確認方法
$ grep "session.gc_probability" /etc/php.ini
```
```:session.gc_divisorの確認方法
$ grep "session.gc_divisor" /etc/php.ini
```
GithubのコミットやPR作成通知をSlackに投げる 個人メモ

# 概要

- GithubのブランチごとのコミットやPR作成通知をSlackに投げる方法をまとめる。

# ご注意

- 共有ワークスペースでこの作業を行うと他の人の迷惑になる可能性があります。
- 筆者は自身専用のワークスペースで作業を行っています。

# 方法

1. Slackにて任意の名前のチャンネルを作成
1. GithubのSlackアプリを当該ワークスペースに導入
1. 下記のコマンドを先に作成したチャンネルに投稿（普通に人とやり取りするときにメッセージ打ち込むところに打って送信）

    ```
    /github signin
    ```

1. 当該チャンネルにGithubのSlackアプリから「Connect GitHub account」のリンク or ボタンが送られるのでクリックして遷移先画面でGithubの認証情報を入力してログイン
1. 下記のコマンドを先に作成したチャンネルに投稿

    ```
    /github subscribe オーナー名/リポジトリ名 reviews,comments,branches,commits:all
    ```

1. これで当該のリポジトリにコミットやPR作成が行われたときに当該のSlackチャンネルに通知が来るようになる。
1. ちなみに筆者は各リポジトリ毎にチャンネルを分けて通知するようにしている。
Gitのコマンドを短縮する方法（エイリアス）

・Gitのコマンドを短縮する方法（エイリアス）
git config --global alias.新コマンド名 元のコマンド名
```
git config --global alias.ci commit
=>commitコマンドをciだけで使用可能とする
　=「git commit」=「git ci」となる
```
WebArena Indigo 環境設定7）Swapの設定

WebArena Indigo 環境設定6）/tmpフォルダのファイルの削除処理の変更
https://qiita.com/naga_kt/items/c18089ebecb6e26374f4
の続き。

　デフォルトではSwapが全く設定されていなかった。

~~~linux
$ free -h
              total        used        free      shared  buff/cache   available
Mem:           991M         83M        766M         18M        142M        747M
Swap:            0B          0B          0B
$ swapon -s
~~~

　容量を確認したところ余裕があった。

~~~linux
$ df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/vda1        20G  5.4G   15G  27% /
devtmpfs        474M     0  474M   0% /dev
tmpfs           496M     0  496M   0% /dev/shm
tmpfs           496M   13M  484M   3% /run
tmpfs           496M     0  496M   0% /sys/fs/cgroup
tmpfs           100M     0  100M   0% /run/user/1001
~~~


　4GのSwapを設定することにした。

## Swap領域に割り当てるファイルの作成(CentOS7/RockyLinux8)

　以下のコマンドでSwap領域に割り当てるファイル/swapfileを作成した。

~~~linux
$ sudo dd if=/dev/zero of=/swapfile bs=4M count=1024
1024+0 records in
1024+0 records out
4294967296 bytes (4.3 GB) copied, 39.3812 s, 109 MB/s
~~~

## Swap領域に割り当てるファイルの作成(Ubuntu20.04LTS)

　Ubuntuでは以下のように行う。

~~~linux
$ sudo fallocate -l 4G /swapfile
~~~

## パーミッションの変更

　パーミッションを変更してrootのみが参照できるファイルにする。

~~~linux
$ ls -lh /swapfile
-rw-r--r-- 1 root root 4.0G Apr 26 14:55 /swapfile
$ sudo chmod 600 /swapfile
$ ls -lh /swapfile
-rw------- 1 root root 4.0G Apr 26 14:55 /swapfile
~~~

## Swap領域の割り当て

~~~linux
$ sudo mkswap /swapfile
Setting up swapspace version 1, size = 4194300 KiB
no label, UUID=………
~~~

## Swapの有効化

~~~linux
$ sudo swapon /swapfile
~~~

## Swap領域の状態確認

　以下のようにして4GのSwapが割り当てられていることが確認できる。

~~~linux
$ swapon -s
Filename                                Type    Size    Used    Priority
/swapfile                               file    4194300 0       -1
$ free -h
              total        used        free      shared  buff/cache   available
Mem:           991M         79M         73M         18M        838M        721M
Swap:          4.0G          0B        4.0G
~~~

## Swap設定の永続化(CentOS7/RockyLinux8)

　OS再起動時もSwap設定を行なうようにするために/etc/fstabを編集して下記一行を追記する。バックアップは取っておくようにする。

~~~linux
/swapfile     swap    swap    defaults        0       0
~~~

## Swap設定の永続化(Ubuntu20.04LTS)

　Ubuntuでは/etc/fstabは以下の一行を追記する。

~~~linux
/swapfile     none    swap    sw      0       0
~~~

---

WebArena Indigo 環境設定8) httpdの設定
https://qiita.com/naga_kt/items/47e9dd08272c1ff552a1
に続く

---

### 参考記事

CentOS
Linux Swap設定方法（CentOS 7）
https://oji-cloud.net/2019/07/01/post-2242/

Ubuntu
Ubuntu 20.04にスワップ領域を追加する方法
https://www.digitalocean.com/community/tutorials/how-to-add-swap-space-on-ubuntu-20-04-ja
僕がDXライブラリのコミュニティーにコミットする事をやめたわけ

# DXライブラリとは
DXライブラリとは
https://dxlib.xsrv.jp/
にて公開されているDirectXをラップしたゲーム制作用のC++言語のライブラリである。

# DXライブラリと私
　このライブラリの作者の方には大変お世話になった。yaneSDK3rdのやねうらおさんと共にとても影響を受けたプログラマーのうちの1人である。
　掲示板での作者の方とのやりとりを含め自サイトでのDXライブラリの技術情報の記事を書いたりと、私にはDXライブラリと共にするプログラミング生活はとても充実した日々だった。時は２００３年前後であった。

　だが、たった数年でこの牧歌的なコミュニティーは卑しい行動をするユーザによって穢されることになった。私はそれに辟易しDXライブラリに関する技術記事を書くことをストップした。そのいきさつに関して詳しく書こうと思う。

# DXライブラリのユーザーは卑怯者ばかりになった
　今はどうだか知らないが、２００８年前後は確かにそうだった。
## いきさつ
　それは数年ぶり、２００８年前後にDXライブラリの掲示板に訪れた時、「DXライブラリのWIKIがあると便利ですね」と投稿されていた。WIKIの運用にはノウハウがあったので「私が作ってみましたがどうですか？」と返信した。無論、DXライブラリの作者への負担を軽くするための善意からである。
　しかし、思った方と違った観点から非難されることになる。WIKIに広告が貼ってあったので「お前はWIKIで金儲けしようとしている」「卑しい奴だ」という旨（俗にいう嫌儲である）の批判が当時の２ｃｈで行われ始めたのである。
　それが気に入らないならば広告を外したものを作ったのでどうですか？と返信したら黙殺された。
　さらに、DXライブラリの掲示板で、「２ｃｈであなたが批判されています。反省や謝罪をされてはどうですか？」という旨の書き込みがあった。実際に掲示板を見てみたが、論理性が欠如している嫌儲思想に溢れた言葉でアホだのバカだのと罵り、私の公式サイトを晒し、罵詈雑言を並べ立ててた。とても批判というようなものではない。ただの中傷である。
　ＤＸライブラリの掲示板を汚さず、学校裏サイトのような匿名掲示板で行う点が実に卑怯だ。
　
　それからしばらくウォッチしていると、偽物の私？なる人物が掲示板に現れ、いかにも私が悔しがっているというような言動、異常なかっこわるい言動を掲示板に投稿し、あたかも私が書き込んでいるかのように見せ、その様を楽しむ、嗤うというような、下卑た趣味が透けて見える２ｃｈの掲示板の投稿者の投稿に嫌気がさした。

　そして、その２ｃｈの投稿を真に受けるＤＸライブラリのユーザにも嫌気がさした。
　それ以降、私はＤＸライブラリのコミュニティーには近づかなくなった。

## 坊主憎けりゃ袈裟まで憎いである
 私はいきさつに書いた通りの経緯からすっかりゲームプログラミングに関しての意欲を失ってしまった。ＤＸライブラリのユーザが憎い。将来のゲームプログラマーが憎い。こんな連中と机を並べて仕事をしたくない。強くそう思った。
　私の当時の夢はゲームプログラマーになる事であったが、この一件でゲームプログラマーの卵たちがこんな下卑た趣味を持っているということをまじまじと感じたため、憧れこそあったが、その業界に入ることをあきらめた。
　もちろん、DXライブラリのコミュニティーの発展のために何かしらコミットする意欲も失せた。

## その後どうなったの？

　結論から言うと、私がゲーム業界に入らないのは正解だった。
https://onl.sc/Uz3BNRG
にあるようにゲーム業界は収入が厳しい。理由はよくわからないが、やりがい搾取が主だと思われる。だが、２ｃｈで下卑た投稿をありがたがっている当時のゲームプログラマーの卵の奴らには当然の報いだろうと思い、私の留飲を下げる要素となっている。

今は悠々自適の暮らしをしている。この暮らしが無ければ私は２ｃｈで馬鹿にされた一生子供部屋おじさんというような学校でいじめられた人が将来にわたってトラウマに苦しみ続けるようなみじめな人となっていただろう。

# 最後に
私は当時のＤＸライブラリのユーザーの精神性を忘れない。今、２０代後半から３０代後半のDXライブラリを触ったことのあるゲームプログラマーの心は信頼に値するものではないのだ。自戒を込めて。
【iTerm2】特定の操作スペースのみに表示する方法

# 

## はじめに
本記事は、プログラミング初学者が学習を進めていて疑問に思った点について調べた結果を備忘録も兼ねてまとめたものです。  
そのため、記事の内容に誤りが含まれている可能性があります。ご容赦ください。  
間違いを見つけた方は、お手数ですが、ご指摘いただけますと幸いです。  

## iTerm2で特定の操作スペースのみに表示する方法
複数の操作スペース（デスクトップ）を開いてiTerm2を使用すると、他の操作スペースへ移動した際にiTerm2の画面もついてきてしまいます。

![image220428_012458.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/03e59b1d-bc1f-dcec-8a0f-a2fd1129429a.png)

![image220428_012511.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/00b16dea-31a3-f38a-45f7-7da123378e31.png)


「デスクトップ3」から「デスクトップ4」に移動するとiTerm2の画面もついてきています。  

iTerm2の設定することで特定の操作スペースのみでiTerm2を使用できます。  

まず、iTerm2を開き、`cmd + ,`で設定画面を開きます。  

![image220428_012744.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/fc342053-1b04-bc04-7637-3cadd54261b1.png)

`Profiles` > `Window`とクリックします。  

![image220428_013037.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/5b262edd-6886-f15f-bfd6-88ea164f417c.png)

下画像`Space`の箇所を`Current Space`または特定のスペース番号に変更します。  

![image220428_013153.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/1149556c-7f1e-da58-4ad2-df95e461a36d.png)

以上の設置することで特定の操作スペースでのみ使用できるようになります。  

![image220428_013628.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/55486737-64dc-d660-71bb-413db6400426.png)

![image220428_013715.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/ce693108-ff77-2060-acad-d5045c686416.png)

「デスクトップ3」から「デスクトップ4」に移動してもiTerm2の画面はついてきません。
asyncio、コルーチン、async/await

# asyncio

>async/await 構文を使い 並行処理の コードを書くためのライブラリです
https://docs.python.org/ja/3/library/asyncio.html

では、`async/await`とは？


# async/await

* 非同期で実装する際に使用する
* awaitは、処理の完了を待っている間にも他の処理を並行して行える

```sample.py
async def edit():
    results = await get()
    return results
```

次の様にawaitを使わない場合、

```sample.py
async def edit():
    print(get())
# > RuntimeWarning: coroutine 'SampleController.get' was never awaited
```

「コルーチンがawaitされていない」と。
**コルーチンを単に呼び出しただけでは実行出来ず、コルーチンオブジェクトが返るため**

コルーチンとは?

# コルーチン

async/await 構文で宣言された関数はコルーチンと呼ばれる

https://docs.python.org/ja/3/glossary.html#term-coroutine
Goのインターフェースについての備忘録

# インターフェイスとは？
変数の値だけでなく、 __変数の型情報__ も同時に保持することができる言語組み込みの __特殊な構造体__ のこと。

# どんな時に使うの？
いろいろな型の変数を引数として受け取ることのできる汎用的な関数を書くときに使う！(使い方の一つ)

Go言語は静的型付け言語なので、変数宣言の際に変数の型を宣言しないといけない。

しかし、これでは汎用的な関数を書く際に引数に来る可能性のある型の数だけ関数を作成しなければならない。

インターフェースは任意の型の変数を格納できるので、汎用的な関数をひとつ書くだけでよくなる！

# インターフェースの宣言

```interface.go
var i interface{}

a := 1
i = a
fmt.Println(i) // 1

b := "str"
i = b
fmt.Println(i) //str
```

# 格納されている型を調べる
格納されている型ごとにごにょごにょしたい場合は以下のような方法で型が取得できる。

```type.go
import (
	"fmt"
	"reflect"
)

func Type(t interface{}) {
	fmt.Println(reflect.TypeOf(t))
}


func interface_test() {
	var i1, i2 interface{}

	i1 = 1
	i2 = "str"

	Type(i1) //int
	Type(i2) //string
}
```

# まとめ
今回はGo言語の特殊な構造体であるインターフェースについてまとめた。
まだ具体的にどのように使うのかイメージがついていないところがあるのでアプリの作成などを行って理解を深めていきたい。
JavaScriptでシーン管理

# 前書き

Vue.jsとかthree.jsとかとは無縁のVanillaJS的な話です。
ぶっちゃけ99.9%の人にとってどうでもいいし、一生使わないような話です。
なんでこんな面倒なことしてんの？ライブラリやフレームワーク使えばいいのにとか言わないでください。
ほぼ自分用です。

jQuery使ってますが別にVanillaJSでも書けます。

# 言葉の定義

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649673/dde0cca6-98b0-a62b-fd42-2b7c052be98b.png" width=800>

上図のようなスタート画面、ゲームのメイン画面、ゲームオーバー画面などをシーンとここでは呼ぶことにします。

# 何がしたいの？

ゲームなどでは各画面でUI、キーのイベントなどが異なるためシーンごとに定義したい。

# で？

次のクラスを作ってください。

```javascript:scene.js
class Scene {
    $app;
    start() {}
    keydown(key) {}
}
```

```javascript:sceneManager.js
const SceneManager = (function() {
    const $window = $(window);
    const $app = $("#app");
    let currentScene = new Scene();

    $window.keydown(function(e) {
        return currentScene.keydown(e.key);
    });

    return {
        start(SceneClass) {
            currentScene = new SceneClass();
            currentScene.$app = $app;
            currentScene.start();
        }
    }
})();
```

```html:index.html
<div id="app"></div>
```

# 実際にどう使うのか？

Sceneクラスを継承して好きに実装してください。

startメソッドでシーンの初期表示
keydownメソッドでシーンのkeydownイベントの処理を書いてください。

また、
```javascript
SceneManager.start(Sceneクラスを継承したクラス);
```
と書くことによりSceneクラスを継承したクラスのシーンが開始されます。

具体的なソースとかは

https://github.com/mogamoga1024/VimHJKLRensyu/tree/main/js/scene

とか参考にしてください。

少し中身が異なりますが、これも考え方は同じです。

https://github.com/mogamoga1024/SnakeGame/tree/main/js/scene

以上
RailsアプリにPython3系の実行環境構築する

## まえおき
Railsを使ったプロジェクトにて大量レコードをエクセルに書き込む処理があるのだが、
使用していたRubyライブラリの「RubyXL」ではメモリ効率や出力速度に限界があり、「数十時間出力にかかる」、「出力する前にメモリ枯渇」するなどの問題があった。
Rubyには他にもエクセルのライブラリがあるが、書式設定などが自由にできないものが多く採用に至らず。
調査したところ現状の仕様を満たすかつ、メモリ効率が高いライブラリとしてPythonに「openpyXL」というものあったので導入した。
そこでRailsアプリ内でPythonを実行するための環境を用意する必要が出てきた。
なお単発的にRubyファイルからシェルスクリプトを経由してPythonファイルを実行する想定。
特にバージョン管理は必要ないのでPyenvは無し。


## 環境
- GCE
- OS：CentOS7
- 言語：Ruby(2.2.2)
- フレームワーク：Rails(4.2.5)


## 環境のチェックなど
①OSのバージョン確認
cat /etc/redhat-release
>CentOS Linux release 7.6.1810 (Core)

②デフォルトのpythonのバージョン確認
python --version
>Python 2.7.5

※CentOS7系はpython2系に依存している部分があるっぽいのでアンインストールなどはしない。

③pythonのインストール詳細状況の確認
ls /usr/bin | grep python
>abrt-action-analyze-python
>python
>python2
>python2.7


## Pythonのインストール

■yumの準備
①リポジトリの追加
yum install -y https://repo.ius.io/ius-release-el7.rpm

②リポジトリが作成できたか確認
ls /etc/yum.repos.d | grep ius
>ius-archive.repo
>ius-testing.repo
>ius.repo

■python3のインストール
①最新版のpythonを探します。
yum search python36

②必要なパッケージをインストールします。
yum install -y python36u python36u-libs python36u-devel python36u-pip


③パッケージが実際に追加されたことを確認
ls /usr/bin/ | grep python
>abrt-action-analyze-python
>python
>python2
>python2.7
>python3
>python3-config
>python3.6
>python3.6-config
>python3.6m
>python3.6m-config
>python3.6m-x86_64-config


インストールしただけでは、pythonコマンドはversion2を参照します。
python --version
>Python 2.7.5

python3を参照するにはpython3コマンドを利用します。
python3 --version
>Python 3.6.8

## エイリアス設定

①pythonコマンドでpython3が実効されるようにaliasで指定
alias python='/usr/bin/python3'

alias | grep python
>alias python='/usr/bin/python3'

python --version
>Python 3.6.8

②.bashrcに書き込み
再起動したときにエイリアスの設定がキャッシュクリアされてしまうので、.bashrcにエイリアス追加しておく。

vi ~/.bashrc

```Bash
#.bashrc

#Source global definitions
if [ -f /etc/bashrc ]; then
        . /etc/bashrc
fi

#Uncomment the following line if you don't like systemctl's auto-paging feature:
#export SYSTEMD_PAGER=

#User specific aliases and functions
alias python='/usr/bin/python3'
```


## ライブラリのインストール
ライブラリマネージャであるpipをインストールし、pipでエクセル関連のライブラリをインストールする。


①pipのインストール
python -m pip install --upgrade pip

②openpyXLのインストール
pip install openpyxl

③lxmlのインストール
pip install lxml


## 参考文献
https://www.ino-shika-cho.com/index.php/2020/10/16/post-1212/
【Pandas】両者のDataframeの差分を確認したい！


同じカラムだけど、データ量が違う2つのdataframeがあったとする。

- dataframe 1

|index|a|b|c|
|---|---|---|---|
|0|1|2|3|
|1|4|5|6|

- dataframe 2 

|index|a|b|c|
|---|---|---|---|
|0|1|2|3|
|1|4|5|6|
|2|5|6|7|

データ量が同じであれば、[compare関数](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.compare.html)を使うことができるが、
両者のデータ量が異なる場合、compare関数を利用すると
エラーとなってしまう。

```
ValueError: Can only compare identically-labeled DataFrame objects
```

そこで、両者のどこに差があるのかを確認する方法を紹介する。

# 差分の確認方法

以下のように、merge関数とquery関数をくみあわせればいい。

```python
pd.merge(df1,df2, on=["両者を紐付けるカラム名1", "両者を紐付けるカラム名2"], how ="outer", indicator=True).query(f'_merge != "both"')
```
上の式は何をやっているかというと、
両者のDataFrameを外部結合する。merge関数のindicatorをTrueにしておくと、
- 両者に同じデータがある部分には, `both`
- 右のDataFrameにだけデータがある場合は, `right_only `
- 左のDataFrameにだけデータがある場合は, `left_only `

が記載される。

このデータフレームからquery関数を利用して、両者同じデータがない部分のデータだけを抜き出してくる

## 例
先程の上の２つのdataframeでみてみる。

```python
import pandas as pd
df1 = pd.DataFrame({'a': [1, 4], 'b': [2, 5], 'c': [3, 6]})
df2 = pd.DataFrame({'a': [1, 4, 5], 'b': [2, 5,6], 'c': [3, 6, 7]})

pd.merge(df1,df2, on=["a","b","c"],how='outer',indicator=True)
```

結果はいかのようになり、右側つまり、dataframe2にだけ5,6,7のデータが余分に存在することがわかる。

|index|a|b|c|\_merge|
|---|---|---|---|---|
|2|5|6|7|right\_only|

# まとめ
両者のdataframe(df1, df2)の差分確認方法

```python
pd.merge(df1,df2, on=["両者を紐付けるカラム名1", "両者を紐付けるカラム名2"], how ="outer", indicator=True).query(f'_merge != "both"')
```

# 最後に
今回は、両者のデータフレームの差分の確認方法について紹介しました。
なにか疑問点等ありましたら、コメントお待ちしております。
補数と固定小数点(未完成)

## 補数
コンピュータの内部で負数を表現する方法の一つ。
<b><font color=blue>補数</font>とは、「ある数」を「決められた数」にするために、「補う数」のこと。

<b>N進数には「N-1の補数」と「Nの補数」がある。
例：10進数には「9の補数」と「10の補数」がある。

<b>「ある数」に「N-1の補数」を補うと、与えられた桁数の最大値となる。
例：10進数3桁で表現する場合、123の「9の補数」は876になる。そうすると999になり、10進数3桁の最大値になる。

<b>「ある数」に「Nの補数」を補うと、与えられた桁数の次に桁上がりする。
例：123の「10の補数」は877になる。そうすると1000になり、次の桁に上がる。
この場合10進数3桁で表現しているので、桁上がりした1は無視されるので000になる。
つまり、10の補数877は123の対の負数(-123)の意味になっている。

<b>2進数には「<font color=blue>1の補数</font>」と「<font color=blue>2の補数</font>」の２つの補数がある。
2進数4ビットで表現する場合、<font color=blue>1の補数</font>を補うと2進数4ビットの最大値になる。<font color=blue>2の補数</font>を補うと次のビットに桁上がりする。ここで、1は無視される。よって、対の負数になる。

## 固定小数点
<b><font color=blue>固定小数点</font>は、小数点の決められた場所に固定して、表現するもの。


参考文献： イメージ&クレバー方式でよくわかる 栢木先生の基本情報技術者教室
「CPUの創りかた」のTD4を少しアレンジして作ってみた

# 概要

　「CPUの創りかた」のTD4で使用されているロジックICとは一部異なるものを使用して互換CPUを製作してみました。この記事では便宜的に「TD4alt」と呼ぶことにします。

# 主な相違点

| |TD4|TD4alt|
|-|-|-|
|レジスタ|74HC161(4bitカウンタ) * 4個|74HC174(Dフリップフロップ) * 3個|
|プログラムカウンタ|74HC161の機能を利用|74HC283を使用|
|レジスタの出力選択|74HC153(4チャネル2回路) * 2個<br>SELECT AとSELECT B|74HC157(2チャネル4回路) * 3個<br>S0とS1|
|レジスタの入力選択|74HC161の/LOADピン<br>/LOAD0～/LOAD3(**負論理**)|74HC157のSELECTピン<br>T0～T3(**正論理**)|
|ROM|8回路DIPスイッチ * 16個|SRAM SRM2B256LMX55 * 1個など|
|命令デコーダ|一部で3入力NANDを使用|2入力のAND/ORとNOTを使用<br>プログラム入力モードに対応|
|ブザー|あり|なし|


# レジスタと入出力選択

　TD4altで使用する74HC174にはDフリップフロップが6回路入っているので、これを3つ用いてレジスタA・B・OUT・PC・CFを構成しました(1回路余ります)。また、74HC157を用いて入出力制御を行いました。どの様な配線になっているかを模式的に表した図を以下に載せます。

![TD4alt簡易図-clipping-reg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185799/5cbecd25-5fb7-f559-4819-5869df4d1bad.png)

# ROM(というかプログラムメモリ)

　TD4altではSRM2B256LMX55という32キロバイトのSRAMをROMとして16バイトだけ使用します。まずは配線の模式図をご覧ください。

![TD4alt簡易図-clipping-mem.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185799/fddb5726-0717-6b3e-55d6-1ebac46cdab2.png)

　このSRAMは以下の様に動作します。
* A3:0でアドレスを指定する
* D7:4とD3:0でデータの入出力を行う
* /OEがLowの間、指定アドレスのデータが出力される
* /WEがLowになった時に指定アドレスにデータが入力される

　各スイッチの役割は以下の様になります。プログラムを入力する時以外は全てOFFにする必要があります。
* SW2をONにするとプログラム入力モードになる
* DIPSW-8で入力データを指定する
* SW1で指定アドレスに指定データが入力される


**プログラム実行時のROM周辺の流れ**

1. CLKがHighになる
1. /OEがHighになりSRAMからのデータの出力が無効になる
1. 同時にPCレジスタから次のアドレス信号が入力される
1. CLKがLowになる
1. /OEがLowになりSRAMから次のデータ(命令)が出力される<br>(下位4bitはIm3:0からALUへ、上位4bitはOp3:0から命令デコーダへ伝わる)

**プログラム入力時のROM周辺の流れ**

1. DIPSW-8で命令コードをD7:4とD3:0に指定する
1. SW1を押して/WEをLowにして指定したデータをSRAMに書き込む
1. 手動でCLK信号を送り、PCを次に進める

　入力時は、SW2によってWRITE信号がHighのため、74HC125(3ステートバッファ)がD7:4の命令コードを遮断し(High-Z)、Op3:0は代わりにGNDに繋がって信号は全てLowになります。WRITE信号のNOTとのAND回路でも十分かと思いますが、便利そうで買ってしまった74HC125にしました。

# 命令デコーダ

　TD4altでは2入力のAND/ORとNOTで代用しました。また、負論理の/LOAD0～3ではなく、正論理のT0～3で出力レジスタを指定するのと、プログラム入力モード(WRITE信号)があるため、TD4とはちょっとだけ違う回路になっています。模式図を以下に示します。

![TD4alt簡易図-clipping-dec.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185799/221a8ba7-2f32-c677-6dc1-0751810bcd62.png)

　プログラム入力モードにおいては、入力した命令(特にジャンプ命令)が即座に実行されては困りますので、Op3:0を強制的にLowにしています。Op3:0が全てLowの時、もしWRITE信号がLowであればT0がHighになり「A ← A + Im」が実行されますが、WRITE信号がHighであればT0～T3が全てLowになり「A + Im」が実行されるだけでどのレジスタにも代入されません。唯一CF(キャリーフラグ)を保持するレジスタが影響を受けますが入力時の動作に問題はありません。

　また、結果論ですが、ANDが4回路、ORが4回路、NOTが5回路となり、各ロジックIC1個ずつに収められました。

# さいごに

　これまで電子工作はブレッドボード上でマイコン使ってセンサーを読んで7SEGで表示くらいのことしかやったことがなく、未だにろくに回路図も書けないなかで、いきなりアレンジしたものに挑戦しましたが、なんとか無事ゴールできました。実は当初8bitCPUにいきなり挑戦するつもりでしたが、TD4altでもブレッドボードもワイヤーもジャンパーピンも色々な部品を買い足す必要があって、念のため4bitCPUにしておいて良かったです。

　CPUの仕組み自体は「CPUの創りかた」だけでなく「コンピュータの構成と設計」などでつまみ食いして分かった気になってましたが、実際に作って動かしてみると感動もさることながら、夢と配線の広がりが尋常ではないですね。

　また、勢いでDE10-Liteも買ってしまったりしましたが、今はとりあえずTD4altをユニバーサル基板で実装しようと作業を進めています。何か特筆すべき点があったら記事にしたいと思います。

# ふろく

[CPUの創りかた - 渡波 郁](https://www.amazon.co.jp/dp/4839909865)
[回路図エディタBSch3V - 水魚堂](https://www.suigyodo.com/)
複数のWebConfigがある場合のとりまとめ

## 基本指針
IIS上でいう「サイト」のWebConfigと「アプリケーション」のWebconfigがある場合、既定では「サイト」のWebConfigが「アプリケーション」に継承される。
(しいて言えば、Machine.configから継承される)

## 継承されると困ること
何も知らずに「サイト」と「アプリケーション」に同じ内容を記載すると、エラーが発生する。
これは、WebConfigに追加したキー項目が重複しているため


## どうすればよいの？
いくつか方法はある。

どれがベストプラクティスなのかは、私もわからないので、やり方を列挙する

### (1)Clearする
<Clear>タグを入れてから追加する。ただ、どこまでClearされるのかは正直不明。
自分がしたいだけのものならよいが、今まで設定されてきたものもすべてClearとかだとちょっと怖い。

### (2)remove
追加する前にremoveする。でも、タグによって使える、使えないがある模様

### (3)inheritInChildApplicationsを使う
こんな感じ
< location inheritInChildApplications = "false">～～ < /location>

このlocationは、親のほうで設定する項目だと思う。
アプリケーションが複数あるような環境だと、それぞれ設定が必要と想定される。

参考URI
https://docs.microsoft.com/en-us/troubleshoot/developer/webapps/aspnet/development/application-directory-configuration
https://blog.shibayan.jp/entry/20150613/1434177284
https://docs-microsoft-com.translate.goog/en-us/troubleshoot/developer/webapps/aspnet/development/application-directory-configuration?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja&_x_tr_pto=op,wapp
https://stackoverflow.com/questions/23367347/entry-has-already-been-added-two-separate-app-pools

https://docs.microsoft.com/ja-jp/previous-versions/dotnet/netframework-3.0/b5ysx397(v=vs.85)

https://codezine.jp/article/detail/81
【コピペで使う】選択可能テーブル

ジャカジャーン！

<p class="codepen" data-height="300" data-default-tab="result" data-slug-hash="QWaeKBB" data-user="mugentaishibyo" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/mugentaishibyo/pen/QWaeKBB">
  選択可能テーブルデモ</a> by mugentaishibyo (<a href="https://codepen.io/mugentaishibyo">@mugentaishibyo</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>


こんなカンジで、レコードをクリックしたら反転して、
Form要素の子要素にコピーも出来るテーブルを作りました。

使い方
1 JQueryを使える状態にしておく。
2 選択可能にしたいTable要素に 「table-selectable」クラスを指定する。

以上！

Form要素に連携したい場合は、以下も行ってください。
1 Table要素に「data-sl-formclass」属性を追加して、適当な値を指定する。
2 td要素に「data-value」属性を追加して、適当な値を指定する。
3 Form要素に1で指定した値と同じ名前のクラスを指定する。
4 3でクラスを指定したForm要素以下にある子要素にdata-value属性を追加して、
　2で指定したdata-value属性と同じ値を指定する。

…特に色を変えたり出来るほどに作り込んでるわけではないので、
自分のソースコードにコピペした後は適当に改造してあげてください。

ソースコード
```HTML:index.html
<!DOCTYPE html>
<head>
	<script type="text/javascript" src="js/selectable.js"></script>
	<link rel="stylesheet" href="css/selectable.css"/>
	<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" ></script>
	<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
</head>
<body>
	<table data-sl-formclass="data_holder" class="table-selectable table w-75">
		<thead>
			<tr>
				<th class="w-25">ヘッダ列</th>
				<th>項目１</th>
			</tr>
		</thead>
		<tbody>
			<tr>
				<th>th要素１</th>
				<td data-value="col1" >td要素１</td>
			</tr>
			<tr>
				<th>th要素２</th>
				<td data-value="col1" >td要素２</td>
			</tr>
		</tbody>
	</table>
	<form class="data_holder" method="post">
		<input type="text" readonly data-value="col1">
	</form>
</body>
```

```CSS:selectable.css
.table-selectable tbody tr:hover td{
    background-color:azure;
}
.table-selectable tbody tr.selected td{
    background-color: aquamarine;
}
```

```Javascript:selectable.js
//HTMLが読み込み終わった後に実行
$(function () {
    //選択可能テーブルの要素をクリックした時のイベント
    $('.table-selectable tbody').find('tr').on('click',
        function () {
            //すべてのtr要素の選択を解除
            var selected_row_bf = $(this).parent().children('tr.selected');
            selected_row_bf.toggleClass('selected');

            //対象のtr要素を選択
            $(this).toggleClass('selected');

            //連携先Form要素の取得
            var form_class = $(this).parents('table').attr('data-sl-formclass')
            //取得に失敗した場合は処理終了
            if (typeof form_class == "undefined") return;

            //取得したidを持つform要素を検索
            var form = $('.' + form_class);

            //選択したテーブルの情報をInput要素の同名クラスへコピー
            $(this).children('td').each(function (index, element) {
                //data-name属性の値を取得して、同じ属性値のフォームへコピー
                var data_value = 'input[data-value=\"' + element.getAttribute('data-value') + '\"]';
                form.find(data_value).val(element.textContent);

            });
        }
    )
});
```
【メモ】ファイル内の文字列をVimとコマンドで他アプリにコピペする

# 環境

Arch Linux, Bash, vim, CopyQ, Tmux

# 目的

Vimで表示中のファイル内の文字列をコピーしてブラウザに貼り付けたいです。

# 障害

初期設定においては、vim内でヤンクした文字列を、vim外のクリップボードマネージャで扱うということができません。
これを実現する設定が存在するのかどうかは知りません。

# 解決

下記の手順でコピーできます。

1. 対象ファイルをvimで開く
1. 行番号を表示する
1. コピーしたい行の行番号を控えておく
1. bashにて次のコマンドを実行する `copyq copy "$(sed -n 行番号P 対象ファイル)"`
e.g. target.txt内の10行目をコピーする：`copyq copy "$(sed -n 10P target.txt)"`

以上でコピーできたので貼り付けたいところに貼り付けられます。

# あとがき

私は手順1--3と手順4をTmuxにて別窓で実行しています。

手順4は、他のクリップボードマネージャを使っていたら書き換えが必要です。
その場合、sedコマンド部分以前のところを書き換えるだけです(手順4はクリップボードマネージャのクリップボードに、sedで抽出した行を登録しているだけですから)。
業務外でのスキルアップを目指して

現在、ローコード開発の案件をこなしているエンジニア一年目です。(半年未満)


入社して、オラクルのjava silver、オラクルマスター silverを取得しました。

将来的に転職を考えており、
現在の業務の経験だけでは、今後転職を考えるに当たって不利じゃないか？と言うことで、資格取得以外にも行動していこうと考えています。

具体的には、

①qiitaで定期的に現在の知識をアウトプットしていく。


②githubで、すこしずつコードを書いていく



③基本情報、JavaGOLD、aws関連の資格を取得する



といった行動を取るようにします。


実務経験はローコード開発しか出来ないので、実務外で武器になるものを探したいです。
『現場で役立つシステム設計の原則』を読んだ感想

# はじめに

技術書『現場で役立つシステム設計の原則』を読んだので、感想や学んだことのまとめ。

# 書籍について

https://gihyo.jp/book/2017/978-4-7741-9087-7

著者：増田 亨 [@masuda220](https://twitter.com/masuda220)

# 全体の印象

とても読みやすい。
システム設計の書籍ではあるが「○○の法則」などのとっつきにくい言葉はほとんど使われていない。
実際の現場でよくあるコードや状況から、それは何が原因なのか、どのように解決するのか、という構成になっているので設計に関する書籍の中では読みやすいと思う。

また章立てについて、最初は変数や数行のコードについて話から、クラス設計、データベース設計、画面設計、アプリケーション連携経て、開発プロセスに進む構成になっている。
これにより、システム設計は単にコードを書いたりクラス図を作ったりするものではなく、開発プロセスまでも含めた一連の活動ということが意識される構成だと感じた。

# 学んだこと

## データとロジックを１つのクラスにまとめる

これまで「データがシステムの主役」という考えからデータを中心に設計をしていたが、結果として業務ロジックが整理されていない状態になっていたと思う。
データを正確に定義することと同じく、それを扱う業務ロジックも含めてこそ価値が生まれるのだと学んだ。

## データベースはコトを記録する

イミュータブルなデータベース設計に触れる機会がなかったので、考えを広げるヒントになった。
選択肢として活用できるよう、理解を深めていきたい。

# 疑問点など

## 削除はDELETEではなくPOSTで依頼する

> DELETEを要求する側と応答する側に、削除に関するさまざまな決め事が必要になります。

決め事が必要になるものというイメージがあるので、それぞれの違いがイメージしきれない。

## プログラミングの専門知識がなくても業務の知識があれば、進捗を適切に判断できるようになる

実際の現場でどのようにやっているのか知りたい。

# まとめ

「とりあえず動くコードを書けるようになった」という人にお勧めしたい書籍。
大抵はそこから先の良いコード・良い設計へ小さなステップで向かえる道は無く、相当な努力をして辿り着くか、あるいは苦しい開発を受けれてしまうのではないだろうか。
この書籍はそこから次の段階へ向かうのに受け入れられ易いと思う。

とはいえ後半の部分は環境によるところが大きい。
例えば画面はシステム開発とは別の人・工程で作られていることがあり、そういう環境では「変更を困難にしている」という認識も無いと思う。
システム開発が単なるエンジニアの業務や手続きという位置付けだと、こうした問題がなかなか認知されない。
これについてはモデリングなどを活用して見える化することで解決の足がかりにできるのではないかと期待している。
img.onerror発生時に<img>を<div>に置き換える方法

###### (An English translation is available [here](https://dev.to/tomoyukiaota/replacing-with-when-imgonerror-is-called-20l5).)

# はじめに

`img.onerror`発生時に、正常に表示されない画像をそのままにするのではなく、`img.src`を書き換えて代替画像を表示したり、`img.style.display = 'none'`を設定してDOMから`<img>`を削除するという方法があります。
 - [How to replace HTML img broken by missing or erroring image src](https://stackoverflow.com/a/64610546/7947548)
 - [How to hide image broken Icon using only CSS/HTML?](https://stackoverflow.com/a/22051972/7947548)

私の場合は、`<img>`の代わりに適当な`<div>`を表示したかったのですが、Google検索してもその方法が見つからず・・・。自分で実験してみてうまくいった方法があるので紹介します。

# 方法

簡潔に言うと、`img.outerHTML`を設定すれば`<div>`に置き換えられると分かりました。

<p class="codepen" data-height="300" data-default-tab="js,result" data-slug-hash="yLpmaVq" data-user="tomoyukiaota" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/tomoyukiaota/pen/yLpmaVq">
  Untitled</a> by Tomoyuki Aota (<a href="https://codepen.io/tomoyukiaota">@tomoyukiaota</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

上記のコードでは`targetImage.outerHTML = "<div>Invalid Image!</div>";`としています。
この`<div>`にstyleを設定すればいい感じになります。

実際のケースとして、私が開発中の[Photo Data Viewer](https://photo-data-viewer.vercel.app/)というアプリがあります。
このアプリは、ブラウザ上で写真ファイルのExifを確認するためのアプリです。`<img>`で表示できないファイル、つまり写真ファイル以外を指定された場合は、写真を表示できない代わりに`<div>`を使ってUnsupported File Formatと表示します。
実際のコードは[こちら](https://github.com/TomoyukiAota/photo-data-viewer/blob/07bfc5f09184468fa4368c692a7ad023122880d3/src/components/photo-image/PhotoImage.tsx#L65-L72)です。
Next.jsを使っているので`onerror`を設定する箇所など違いますが、`outerHTML`を設定するというのは同じです。

何かのお役に立てば幸いです。
【Swift】AdMobメディエーションについて

# メディエーションとは？
> メディエーションは、アプリに広告を配信するすべての広告ソースを 1 か所で管理できる AdMob の機能です。メディエーションを使用すると、届いた広告リクエストを複数の広告ソースに送信し、使用可能かつ最適な広告ソースを確実に見つけて広告を掲載することができます。メディエーションでは、メディエーション グループを使用します。これにより、最適化された掲載結果に基づいてすべての広告ソースをランク付けして、収益を最大化することができます。
[AdMob メディエーションの概要](https://support.google.com/admob/answer/3063564?hl=ja)

なんか難しそうですね
あってるかは知りませんが僕の解釈はこうです。
「色んな広告会社を競わせて1番価値の高い広告を表示できるよ」
こんな感じで思ってます。

仕組みなんて正直どうでもいいんです
「収益を最大化することができます」ここが重要なんです笑
ここしかみてません

# メディエーションには2種類ある！？
**入札**
リアルタイムに競わせて1番高い広告を表示

**ウォーターフォール**
あらかじめ設定された金額を比較して1番高い広告を表示

# メディエーション(入札)を設定するには？
以前からメディエーションのことは知っていましたがSDKとか導入してめんどくさいんでしょ？って思って避けていました。
しかしそんなことなかったのです！
「SDKの導入なし&コード変更なし&支払いがAdMobから」こんな素敵な広告ソースがありました
今回は楽ちんな広告ソースを設定して収益をあげちゃおうって記事です

必要なことは以下です。

- 広告ソースとの契約
- AdMobでのメディエーショングループの設定

これだけでした
こんな簡単ならもっと早くからやっておけばよかった。。。

# 手順
![スクリーンショット 2022-04-27 22.41.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/082fc9cc-0b5f-c76b-fd46-c19d56604fc1.png)

AdMobのメニューから「メディエーション」を選択します。

![スクリーンショット 2022-04-27 22.43.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/3a5f8b66-0879-43e8-2e58-6c99dfd897d1.png)

「メディエーショングループを作成」を選択します。

![スクリーンショット 2022-04-27 22.44.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/23b818b1-a44c-204b-524f-c20c94089d32.png)

①広告のフォーマット
②プラットフォーム

上記2項目を入力します。

![スクリーンショット 2022-04-27 22.46.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/998b239c-75ad-8f99-d81d-14e8deeae2b2.png)
![スクリーンショット 2022-04-27 22.48.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/321f2f80-a33a-4c36-dd50-bedf93a2e90c.png)

①名前 -> {アプリ名} - {広告フォーマット} 
(僕はいつもこうしてます)

②広告ユニットのフォーマット -> 変更なし

③プラットフォーム -> 変更なし

④IDFA使用の可否 -> 変更なし

⑤地域 -> 変更なし

⑥ステータス -> 変更なし

⑦広告ユニット -> メディエーションを適用する広告ユニットを選択

![スクリーンショット 2022-04-27 22.51.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/78e032e4-346a-ee0b-607a-2e3e52ad6d6a.png)

広告ユニットを選択すると「入札」と「ウォーターフォール」が追加されます。

今回は「入札」を設定していきます。

![スクリーンショット 2022-04-27 22.53.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/6035a83f-eab1-4116-4aac-9b99f3b35811.png)

「広告ソースを追加」を選択します。

![スクリーンショット 2022-04-27 22.55.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/41532b1f-1567-e267-fe46-fd4140431015.png)

このようなポップアップが表示されます

ここまで来たら各広告ソースとのパートナーシップを契約すれば完了です

![スクリーンショット 2022-04-27 23.02.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/2e888f9c-cafc-9904-b629-8355a71d8129.png)
契約は広告ソースを検索して「選択」を押すと「パートナー契約に署名する」が表示されます。
あとは遷移先の指示に従ってれば大丈夫です

---

楽ちんなおすすめ広告ソースを紹介します

**「SDKなし&コード変更なし&支払いがAdMobから」の広告ソース**
- Ad Generation
- Fluct
- Mobfox
- Rubicon

他にもありますが審査に条件があったり契約のやり方が難しかったりしたので除外しました。

**Ad Generation**
審査期間: 4日
2回ほどメールのやり取り

**Fluct**
審査期間: 10日
2回ほどメールのやり取り

**Mobfox**
審査期間: 1日
メールやり取りなし

**Rubicon**
審査期間: 6日
メールやり取りなし

# メディエーションの結果
![twitter_FM3CSv8acAA_IRH.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/817af6c7-75a7-d278-7e3f-7a0a47f00029.jpeg)
メディエーション導入した次の日にeCPMが爆上がりしました笑
jupyter環境に自動でライブラリをインポートする

## 初めに
Jupyterでよく使うライブラリを毎回インポートしたり同じ設定を書くといった何気ないめんどくさい作業を自動化できないかと思い調べたので共有します。

## 方法

`~/.ipython/profile_default/startup/start.py`に記述した内容がIpythonが立ち上がるタイミングで毎回実行されるため、この機能を利用します。
例えば、以下のような内容を記述しておくと、ライブラリのインポートの他にも設定などを統一できます。

```python
import pandas as pd
import numpy as np

# Pandas options
pd.options.display.max_columns = 30
pd.options.display.max_rows = 20

from IPython import get_ipython
ipython = get_ipython()

# If in ipython, load autoreload extension
if 'ipython' in globals():
    print('\nWelcome to IPython!')
    ipython.magic('load_ext autoreload')
    ipython.magic('autoreload 2')

# Display all cell outputs in notebook
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = 'all'

# Visualization
import plotly.plotly as py
import plotly.graph_objs as go
from plotly.offline import iplot, init_notebook_mode
init_notebook_mode(connected=True)
```

## 終わりに
こういう細かいチップスで生産性高めていきましょう👍
クリティカル・シンキングとは

## クリティカル・シンキングとは

「批判的思考」と訳されるが、欠点を指摘するための思考法ではなく、「本当にこれで良いか？」「そもそも目的はなんだったか？」と一度立ち止まり思考することで、物事の本質を捉えながら結論を導く思考法。

## クリティカル・シンキングの特徴

#### ① 目的は何かを常に意識する

思考していく間に目的としているゴールがズレてしまわないように、そもそも「何のために思考するのか」、「何のために作っているのか」といった部分を明確にしながら思考する。今議論する必要のないことまで議論してしまい、本来解決したい課題までたどり着かない、みたいなことを防ぐ。

#### ② 思考の癖があることを前提に考える

人間は今までの経験や記憶による主観がある。主観により物事の考え方にも偏りがでてしまう。予め思考には癖や偏りがあることを理解して、「主観だけで考えていないか」を自分に問いながら思考に客観性を持たせる。

#### ③ 本質まで考え続ける

考えて結論が出たとしても「なぜ？」「これが最善な方法か？」「これで本当に課題は解決できるか？」と、何度も本質まで考え続ける。

## まとめ
- ① 目的は何かを常に意識する
    - 「そもそも何のためにやるのか？」
    - 「そもそも何のために作っているのか？」
- ② 思考の癖があることを前提に考える
    - 「主観のみで考えていないか？」
- ③ 本質まで考え続ける
    - 「これが最善の方法か？」
    - 「これで本当に課題は解決できるか？」
- 前提がズレていないかも確認する
    - そもそも前提が間違えていると、正しい結論を導くことができない

## 所感

プログラムを書く時にも有用な思考法だと感じた。必死になってプログラムを書いていると、目的を見失って煩雑なコードになったり、無駄な処理を含むコードを書いてしまうことがある。そういった時に「クリティカル・シンキング」の思考法を取り入れて、振り返りながらプログラミングをすることで、より良いコードを書いていきたい。

## 参考にした記事
- [クリティカル・シンキングとは？とその考え方](https://qiita.com/bs_tamura/items/958d68a5894d24c7c8db)
- [あなたのコード複雑怪奇になっていませんか？](https://qiita.com/tak001/items/02f0b6fcdb2dbcb66f16)
- [クリティカルシンキング（批判的思考）とは？ 思考法、4ステップの手順、活用例](https://www.kaonavi.jp/dictionary/criticalthinking/)