OmniAICreator/Qiita-1.07M huggingface dataset:
共同編集WikiであるHedgeDocの最新版をdocker-composeでサクっと立ち上げる

# HedgeDoc?

HackMDのオープンソース版という位置付けのプロジェクトのようです。
元々はCodiMDと呼ばれるプロジェクトでしたが、名前が変わったようです

https://github.com/hedgedoc/hedgedoc

このHedgeDocですが現在2.x系の開発が活発に進んでいます。

が、まだリリースはされておらず、利用方法のドキュメントなどは1.x系のものが充実しています。

新しいもの好きの自分は、ちょっと最新版のHedgeDocも試してみたいということで、簡単に試す方法を調べてみました

# 安定版を使いたい

HedgeDocの安定版であるv1.9.4を同じようにdocker-composeで試す方法は公式ドキュメントによくまとまっています

https://docs.hedgedoc.org/setup/docker/

# docker-composeを使ったデプロイ

最新版である2.x系も安定版と同じようにdocker-composeで動かせると楽なのに・・ということでその方法を調べました。
HedgeDocの2.x系はフロントエンドとバックエンドが分離されており、それぞれを連携させて動作させる必要があります。

こういう時に便利なのがdocker-composeです。

ということでdocker-compose.ymlを用意します

```docker-compose.yml
services:
  proxy:
    image: caddy
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
    ports:
      - "8080:8080"
    links:
      - frontend
      - backend
  frontend:
    image: ghcr.io/hedgedoc/react-client:main
    environment:
      - HD_EDITOR_BASE_URL=http://localhost:8080/
  backend:
    image: ghcr.io/hedgedoc/hedgedoc:develop
    environment:
      - HD_AUTH_LOCAL_ENABLE_LOGIN=true
      - HD_AUTH_LOCAL_ENABLE_REGISTER=true
      - HD_DOMAIN=http://localhost:8080
      - HD_MEDIA_BACKEND=filesystem
      - HD_MEDIA_BACKEND_FILESYSTEM_UPLOAD_PATH=uploads/
      - HD_DATABASE_TYPE=sqlite
      - HD_DATABASE_NAME=./hedgedoc.sqlite
      - HD_SESSION_SECRET=hogehoge
```

フロントエンドとバックエンドはURLのパスによって呼び分ける必要があります。

ここでCaddyというリバースプロキシを使ってこれを実現しています。

Caddyの設定ファイルは以下です。

```Caddyfile
:8080

log {
	output stdout
}

reverse_proxy /realtime http://backend:3000
reverse_proxy /api/* http://backend:3000
reverse_proxy /public/* http://backend:3000
reverse_proxy /* http://frontend:3001
```

これら2つのファイルを用意して`docker-compose up`を実行すると　　`http://localhost:8080/`でHedgeDocの最新版を試すことができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100375/c5d8b0a1-6a2b-24fd-fd31-1f947a9e0279.png)

# まとめ

リアルタイム共同編集でMarkDownを扱うことができるWebアプリケーションとしてHackMDや、そのオープンソース版であるHedgeDocは非常に良いものです。

docker-composeで簡単に試せるので気になる方は是非動かしてみてください。

# 参考

https://github.com/hedgedoc/react-client/tree/main/dev-reverse-proxy にDockerを使わずローカル環境でHedgeDocの最新版を動かす方法が書かれていたので、この記事ではこれをdocker-composeを使う方法に変換しただけです。
Next.jsでの開発時はnext/imageを使うと良いかも

Next.jsにはnext/imageという画像表示を最適化してくれるサービスがあります。
普通のimgを使うより、どう違うのか比べてみます。

## next/imageを使うメリット
#### １、画像の最適化
next/imageを使うことで画像を表示する際にサーバー側で最適な拡張子、サイズに調整してくれます。
最近登場したwebpに自動で変換してくれることが多いです。

#### ２、画像のリサイズ
表示するブラウザのサイズによって自動的にサイズを変更してくれます。

#### 3、自動で遅延読み込みしてくれる
遅延して読み込むとで大量に画像を表示する場合でも高速化してくれます。

#### その他
その他にも色々と通常のimgタグを使用するよりメリットがある反面、実装がちょっと大変だったりします。

## 実装
```
<>
    <Image src="/images/sample3.png" alt="" width={1000} height={250} /> // next/imageを使用
    <img src="/images/sample3.png" alt="" width={1000} height={250} /> // 通常のimgを使用
</>
```
↑プロジェクト内の画像を参照するときはimgタグと同じような感じで実装できますが、
URLでの指定となるとドメインを設定したりと若干面倒です。

公式：https://nextjs.org/docs/api-reference/next/image
myLoaderというプロパティに定義する必要があります。

## ブラウザの検証ツールで確認
networkタブで確認してみると、next/imageで表示した方の拡張子はwebpになってて、細部も3分の１、表示も2分の１になってます！
凄い
![IMG_1383.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1812049/9c970f7f-e054-eb70-d47e-eacdd33a1a8b.jpeg)
macOS Monterey 12.6でtkinter(tcl-tk)をちゃんと動かす

# 困っていたこと
macOS Monterey 12.6にする前から発生していたのですが、Windowsで正しく動いていたtkinterのアプリをMacに持ってきたところ、Tkinterで作成したウィンドウが真っ黒に表示されて使い物になりませんでした。
そこで、いろいろと調べたところ、Macにビルトインされているtkinter(tcl-tk)のバージョンでは不具合があり、新しいバージョンに変更すれば良いことが分かりましたが、一癖ありかなり手間取りましたので、備忘録的に書き残します。
ざっくり書くと、最新のtcl-tkをインストール（アップデート）して、それだけだとPythonが新しいVersionを認識しないので、PATHを通したり、環境変数をセットして、Pythonを上書きでアップデートする。
これで、私の場合はうまく行きました。

# 使っている環境
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314541/ba513a4b-b8c6-20ef-9c43-fc4076343958.png)
シェル: zsh(標準環境）
pyenv: stable 2.3.4

# 異常な（困った）表示
基本的に下記のコマンドを打って、困った表示が出ている人向けの記事です。
```
% python -m tkinter
```
↓↓↓↓↓困った表示↓↓↓↓↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314541/106fbe9e-ebc7-ce50-a49a-22fe03f5a7e5.png)
本来であれば、白のバックグラウンドに黒の文字でVersion情報が表示されます。tkinterのコードを書いて他の色のバックグラウンド色を指定しても真っ黒になります。

困ったなの時に実際に動いているTkinterのVersion↓　8.6がインストールされていても、単にアップデートしただけでは、Pythonからは認識されておらず、下記の例では8.5.9が使われてしまっています。
```
% python
Python 3.10.4 (main, Sep 29 2022, 07:25:02) [Clang 14.0.0 (clang-1400.0.29.102)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import tkinter
>>> tkinter.Tcl().eval('info patchlevel')
'8.5.9'
>>> 
```
### 導入されているtcl-tkのVersion
導入されているtcl-tkのVersionを確認してみます。
```
% brew info tcl-tk
tcl-tk: stable 8.6.12 (bottled) [keg-only]
Tool Command Language
https://www.tcl-lang.org
/opt/homebrew/Cellar/tcl-tk/8.6.12_1 (3,045 files, 52MB)
  Poured from bottle on 2022-07-04 at 16:22:40
```
上記の例では、8.6.12が入っているにも関わらず、実際には、8.5.9が使われているということになります。
正しく動かすには8.6以降のVersionが入っている必要があるので、そもそもtcl-tkが入っていなかったり、8.5などの場合は下記のコマンドでインストール（アップデート)します。
```
% brew install tcl-tk
```

改めて再度tcl-tkのVersionを確認してみます。
```
% brew info tcl-tk
```
# 準備ができたので、Pythonで使いたいtcl-tkを紐づけるための作業を実施

### PythonのVersionの確認
```
% python --version
Python 3.10.4
```
### ~/.zshrc に下記のステートメントを追加します。
```
export PATH="/usr/local/opt/tcl-tk/bin:$PATH"
export LDFLAGS="-L/usr/local/opt/tcl-tk/lib"
export CPPFLAGS="-I/usr/local/opt/tcl-tk/include"
export PKG_CONFIG_PATH="/usr/local/opt/tcl-tk/lib/pkgconfig"
```
これらは、brewでインストールしたものは、PATHを通さないとつかえないので、PATHを追加しているのと、このあとPYTHONの再構築の時に使うための環境変数をセットしています。これらは、% brew info tcl-tk で出てくる情報に書かれています。

### Pythonを上書きしてtcl-tk8.6を認識させる様にします。
```
% PYTHON_CONFIGURE_OPTS="--with-tcltk-includes='-I/usr/local/opt/tcl-tk/include' --with-tcltk-libs='-L/usr/local/opt/tcl-tk/lib -ltcl8.6 -ltk8.6'" pyenv install 3.10.4
```
最後の3.10.4は、前に確認したPythonのVersionと合わせてあります。また、このプロセスで使われるPYTHON_CONFIGURE_OPTS環境変数でtcl-tk8.6関連の指定をしつつ、pyenvを実行しているコマンドとなります。

# Pythonが認識しているtcl-tkのVersionを確認
```
% python
Python 3.10.4 (main, Sep 29 2022, 07:25:02) [Clang 14.0.0 (clang-1400.0.29.102)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import tkinter
>>> tkinter.Tcl().eval('info patchlevel')
'8.6.12'
>>> 
```
# tkinterのテストプログラムが正しく動くことを確認

```
% python -m tkinter
```

正常な表示
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314541/e7f0aef9-2872-4bbc-63fe-68a7414a9b0a.png)

### これで私のMacの環境でも思い通りのtkinterプログラムを楽しめる様になりました。
お母さんでもわかるtransformとtransition

# 経緯
JavaScriptを勉強していく上で**transform**、**transition**を知っておかないと、自分の思い描いた挙動を実現できないと思ったからです！

## transform
transformには４種類の使い分けがあります。
### ①translate() 要素を移動させることができる

```index.html
 <div class="wrapper">
    <div class="inner">
    </div>
 </div>
```
```style.css
wrapper {
  width: 100%;
  height: 500px;
  background-color: aqua;
  padding: 20px;
}

.inner {
  width: 100px;
  height: 100px;
  background-color: brown;
  transition: 2s;/*2秒かける*/
}

.inner:hover {
  transform: translate(100px, 50px);/*X軸に100px,Y軸に50px*/
}
```

上記のコードは「2秒かけて、innerを右に100pxと下に50px移動させる」という意味。


![Alt text](https://gyazo.com/547e3199f31bdb2d3924bd2ac8c1214f/raw)

ちなみにpositionと組み合わせることで、要素をど真ん中に持っていくことができる。
```style.css
.wrapper {
  width: 100%;
  height: 500px;
  background-color: aqua;
  padding: 20px;
  position: relative;
}

.inner {
  width: 100px;
  height: 100px;
  background-color: brown;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
```
positionの設定だけだと、「左上が基準」になるからど真ん中には来ない。
そこで、指定した要素自体を基準にしてくれるtranslateを50%で指定することで微調整をしてくれている。
(わかりずらいけど、下記画像はイメージです)
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782070/2e3cad60-23d2-582c-c2b9-c95232bcd382.jpeg">

### ②transform:rotate()　要素を回転させる
rotateX()　→　X軸(横線)を軸として回転。
rotateY()　→　Y軸(縦線)を軸として回転。
rotateZ()　→　ど真ん中を軸として回転。=rotate()

```style.css
.wrapper {
  width: 100%;
  height: 500px;
  background-color: aqua;
  padding: 20px;
}

.inner {
  width: 100px;
  height: 100px;
  background-color: brown;
  transition: 2s;
}

.inner:hover {
  transform: rotate(45deg);
}
```
ホバーしたら真ん中を中心として、右に45度回転させる。

### ③transform:scale()　要素の拡大、縮小
### ④transform:skew()　歪み
③と④に関しても使い方に関しては類似しているので説明は割愛します・・・。

# まとめ
私はまだ使いこなせていないですが、これらをプログラミングと組み合わせることで表現の幅が格段に上がると思います。
【夏休み企画】#IT用語一問一答【毎朝投稿26日目】TLS

# この記事を読むと、、
- 「関連用語」を使って「TLS」を説明できるようになる
- 「TLS」がもっと好きになる(多分)

# 関連用語
SSL / DTLS / forward secrecy / AE

[**復習用**] 記事の内容を見る前に上記の言葉で「TLS」を説明してみよう！

# 企画説明
- クラウドって何？って人に聞かれて説明してるけど俺もよく知らないや、、
- ドキュメント読んでみてるけど半分くらい何言ってるか分かんない、、
- 今日の夕飯はナスの炒めものにしよっかな〜、あれ、NASってなんだっけ？

みたいなことが結構あったので、知ったかしていたIT用語を毎日一個ずつちゃんと学んでいこうっていう企画です！

昨日の記事はこちら↓

https://qiita.com/acta/items/5e20e484018524a463d8

# TLSとは
TLS = Transport Layer Security = セキュアな通信を実現するプロトコル

- cf. **SSL** = Secure Sockets Layer = TLSの元となったプロトコル
    - Netscape社が開発
    - SSL 1.0, SSL 2.0, SSL 3.0があるがいずれも脆弱性があり使われなくなった

- cf. **DTLS** = Datagram Transport Layer Security = UDPやDCCP上でセキュアな通信を実現するプロトコル
    - TLSは主にTCP上で用いられる

- TLSは以下の2つのプロトコル層に分けられる
    - TLS handshake protocol = クライアント、サーバー間でmaster secretという鍵を共有するプロトコル
    - TLS record protocol = master secretを用いてセキュアな通信をするプロトコル

- TLSにはTLS 1.0, TLS 1.1, TLS 1.2, TLS 1.3のバージョンがある
    - TLS 1.3で残されたcipher suite(=暗号スイート)には以下の特徴がある
        - **forward secrecy**
            - (ざっくりいうと)秘密鍵の一つがもれても、過去の通信が盗聴されないという性質
                - ex. DHE = ディフィー・ヘルマン鍵共有
                - ex. ECDHE = 楕円曲線ディフィー・ヘルマン鍵共有

        - **AE** = Authenticated Encryption = 認証付き暗号
            - 復号できた際に機密性や完全性を保証してくれる暗号化方法

# 参考資料
- https://en.wikipedia.org/wiki/Transport_Layer_Security
- https://en.wikipedia.org/wiki/Forward_secrecy
- https://en.wikipedia.org/wiki/Authenticated_encryption
- https://developers.google.com/tink/aead
Azure Fundamentals(AZ-900)：クラウドの概念について説明する「サービスモデルの種類」と「責任共有モデル」

Microsoft Learnを用いたMicrosoft Azure Fundamentals(AZ-900)の試験内容をまとめる投稿です。
この投稿ではMicrosoft Learnで学ぶ内容をできるだけ簡潔にまとめております。
Azureの勉強を一から始める方の参考になれば幸いです。

## 今回の学習内容
**◆「サービスモデルの種類」と「責任共有モデル」**
◇対応するMicrosoft Learn ラーニングパス
[Microsoft Azure の基礎: クラウドの概念について説明する](https://learn.microsoft.com/ja-jp/training/paths/microsoft-azure-fundamentals-describe-cloud-concepts/)
◇対応するモジュール
[共同責任モデルについて説明する](https://learn.microsoft.com/ja-jp/training/modules/describe-cloud-compute/4-describe-shared-responsibility-model)

※前回の投稿は下記から確認できます。
[Azure Fundamentals(AZ-900)：クラウドの概念について説明する「クラウドの定義」](https://qiita.com/fsd-jume/items/d033d7fe532f705c7b30)

## サービスモデルの種類
**◆IaaS(イアースまたはアイアース)**
[Infrastructure as a Service：サービスとして提供されるインフラストラクチャー]
情報システムの構築に必要なサーバやネットワークなどのインフラ・開発環境をインターネット上で提供

**◆PaaS(パース)**
[Platform as a Service：サービスとして提供されるプラットフォーム]
OSやミドルウェア、データベースなど、アプリ開発に必要なプラットフォーム一式をインターネット上で提供

**◆SaaS(サース)**
[Software as a Service：サービスとして提供されるソフトウェア]
これまでパッケージ製品として提供されていたソフトウェアを、インターネット上で提供
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2851723/c33cfde9-6034-7fb2-2a7a-2e88c44e1386.png)

## 責任共有モデル
**「クラウド事業者」と「利用者」間における役割分担(責任共有)でクラウドを分類する考え方**

**◆役割分担が常に確定している項目**
**◇利用者**
・クラウドに格納されている情報とデータ
・クラウドへの接続が許可されているデバイス(携帯電話、PCなど)
・組織内のユーザ、サービス、デバイスのアカウント/ID

**◇クラウド事業者**
・物理データセンタ
・物理ネットワーク
・物理ホスト/ストレージ

**◆各サービスモデルにより異なる役割分担(Microsoftが示す分担)**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2851723/fec1f042-c8d4-4ea8-815a-a36fcf84395e.png)


## 次の学習内容
**◆クラウドモデル(実装モデル)**

https://qiita.com/fsd-jume/items/647aacf7147ece299fa1

## 学習内容をまとめたページの一覧

https://qiita.com/fsd-jume/items/e4ec76959adb547ac5e8

## 参考
* [総務省 ICTスキル総合習得プログラム コース2-2 クラウドのサービスモデル・実装モデル](https://www.soumu.go.jp/ict_skill/pdf/ict_skill_2_2.pdf)
Apache FlexでWorkerを利用する

# はじめに

Apache FlexでのWorkerの使い方を簡単にまとめます。
時間がかかる処理を実行すると画面側での待ち時間が発生しますが、
Workerを利用して並行して実行することで、画面側での待ち時間が発生しなくなります。

# 簡単な例

例として、Sub.asに時間がかかる処理を記述していて、Main.mxmlでその処理を呼び出して実行したいとする。

Main.mxmlで以下のようにしてSub.swfを読み込み後、
```as
[Embed(source="../Sub.swf", mimeType="application/octet-stream")]
private var subClass:Class;
```

以下のようにすることで実行することができる。
```as
var worker:Worker = WorkerDomain.current.createWorker(new subClass());
worker.start();
```

Main.mxml、Sub.asの内容は後述。
（時間がかかる処理の代わりとして、5秒スリープするだけの処理を記述している）

「Mainで実行」ボタンをクリックした時は、画面側での待ち時間が発生するが、
「Subで実行」ボタンをクリックした時は、Workerを利用しているため、画面側での待ちは発生しない。

今回の場合、以下のように先にSub.asをコンパイルしてSub.swfを作成しておく必要がある。
```
> amxmlc src/Sub.as -output Sub.swf -debug=true
> amxmlc src/Main.mxml -output Main.swf
```
※Sub.asの```trace("Sub finished");```の出力内容を確認するため、Sub.asの方は```-debug=true```を指定してコンパイルしている。

## Main.mxml

```mxml:Main.mxml
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
                       xmlns:s="library://ns.adobe.com/flex/spark"
                       xmlns:mx="library://ns.adobe.com/flex/mx">
    <fx:Style>
        * { 
            fontFamily: "Meiryo";
        }
    </fx:Style>

    <fx:Script>
        <![CDATA[
            import mx.controls.Alert;

            [Embed(source="../Sub.swf", mimeType="application/octet-stream")]
            private var subClass:Class;

            private function sleepMain():void {
                // 5秒スリープ
                var time:Number = new Date().getTime();
                while (new Date().getTime() - time < 5000) {
                }

                Alert.show("完了");
            }

            private function sleepSub():void {
                var worker:Worker = WorkerDomain.current.createWorker(new subClass());
                worker.start();

                Alert.show("完了");
            }
        ]]>
    </fx:Script>

    <s:Button label="Mainで実行" left="10" top="10" click="sleepMain();" />
    <s:Button label="Subで実行" left="10" top="40" click="sleepSub();" />
</s:WindowedApplication>
```

## Sub.as

```as:Sub.as
package {
    import flash.display.Sprite;

    public class Sub extends Sprite {
        public function Sub() {
            // 5秒スリープ
            var time:Number = new Date().getTime();
            while (new Date().getTime() - time < 5000) {
            }

            trace("Sub finished");
        }
    }
}
```
要求分析の肝

## 人とコンピュータの役割分担を明確にする
なんでもかんでもシステム化するのは間違い
人間も優秀なシステムと認識するべし！
リスク分析（リスク頻度×リスク影響度）から人間が担う部分（運用ルール化）を評価する
　
## 要求の価値を見極める
優先順位をつけて制約（QCD）に合わせる
優先順位をつけて後回しにできるものを明確にする
　
## 品質、費用、納期
優先するのはなに、犠牲にするのはなに？
　
## やることだけでなく、やらないことを見積もる
やらないことでどれくらい品質、費用、納期を改善できるか
　
## 機能ではなく業務レベルで抽象化する
分割統治法で問題をシンプルに
改善すべきは業務
業務改善が済んでからシステム化すべし！
　
## 手順ではなく情報
５W1H：何の情報がどこで、いつ、だれが、なぜ必要か、を明確にし、提供方法を定義する
　
## 抽象化は重要
詳細レベルでは、全体的な問題を発見しずらい
詳細レベルでは、要求が発散する
　
## 要求者を信じない
要求者は要求内容をすべて抑えていない
要求者は要求内容を正しく伝えられない
　
## 条件を複雑化しない
1条件1行
　
## アジャイル手法を採用する
初期のイテレーションで小さな機能を要件からリリースまで通してみる
その中で、コミュニケーション方法や各種管理手順などを調整して大きな流れを確立する
　
## 用語集を作る
言葉の意味が違うと要件内容も異なる
【Laravel】Eloquent モデルのプロパティ

Eloquent の理解を深めるため、プロパティの概要をまとめました。
（[公式のドキュメント](https://laravel.com/docs/9.x)では各セクションにチラホラ
登場するだけで、一覧としてまとまっていなかったので…）

| プロパティ名 | 概要 |
|---|---|
|$table|モデルに関連付けるテーブル名を指定する。<br>デフォルトは __モデル名の複数形__。|
|$primaryKey|主キーを指定する。デフォルトは __id__。<br>※主キーのカラム名が id 以外の場合に設定する必要あり。<br>複合主キーには非対応。|
|$keyType|モデルの主キーの型を指定する。デフォルトは __int__。<br>※モデルの主キーが整数でない場合に設定する必要あり。|
|$incrementing|主キーを自動インクリメントするかを指定する。<br>デフォルトは __true__。|
|$fillable|create() や fill() 等で追加、更新を許可する属性を指定する。<br>※\\$fillable, $guarded はどちらかのみ指定可能|
|$guarded|create() や fill() 等で追加、更新を許可しない属性を指定する。|
|$attributes|モデルの属性のデフォルト値を指定する。|
|$casts|モデルによりDBからデータ取得、および<br>データ追加する際にキャストする属性を指定する。|
|$hidden|モデルを配列や JSON に変換する際に<br>非表示にする属性を指定する。|
|$visible|モデルを配列や JSON に変換する際に<br>表示する属性を指定する。|
|$appends|モデルを配列や JSON に変換する際に<br>付加する属性を指定する。|
|$timestamps|Eloquent による created_at, updated_at の自動更新を<br>許可するかを指定する。デフォルトは __true__。|
|$dateFormat|DBにモデルの日付を保存するときに使用する<br>フォーマットを指定する。デフォルトは __'Y-m-d H:i:s'__ 。|
|$dates|Carbon インスタンスに自動変換する日付カラムを指定する。|
|CREATED_AT, UPDATED_AT<br>※const|タイムスタンプに使用するカラム名を指定する。<br>デフォルトは __created_at__, __updated_at__。|
|$touches|タイムスタンプを自動更新する親モデルを指定する。|
|$perPage|peginate() で取得するデータのデフォルト件数を指定する。<br>デフォルトは __15__。|
|$with|モデルの取得と併せて常に取得する関連モデルを指定する。|
|$connection |モデルが使用するDB接続を指定する。<br>※アプリケーション用に設定したデフォルトの<br>DB接続以外を使用する場合に設定する。|
|$dispatchesEvents|モデルによりDB操作が行われるタイミングで<br>実行するイベントクラスを指定する。|

よく使われるものから使いどころが難しそうなものまで、
意外と多くのプロパティがあることがわかりました。
他にもあれば追記していこうと思います。今回は以上です。
脳波解析におけるPhaseLockingValueの注意喚起と代替案〜相関と因果の混同の撲滅を目指して〜

# この記事の対象者
- 脳波解析をする人
- 波形解析で相関とか見る人
- 相関と因果を混同している人

# TLDR;
相関と因果は違います。
脳波解析はその辺りが曖昧にされていることの多い領域の一つです。

脳波解析屋さんは一つの脳内のコネクティビティ解析の時に相関の指標であるPhase locking value(PLV)を使うのを特殊な場合[^tokushu]を除いて辞めましょう。
代わりにまずは…例えば下記のいずれかを検討しましょう。

[^tokushu]: 例えば、AさんとBさんが同時に実験を受けて、それにたいしてどのくらい同じように反応するかを見る…とかする実験系なら良いとは思います。結構ニッチな実験ですよね？

- Imaginary coherence
- Weighted imaginary coherence
- Phase lag index
- Phase slope index

# PLVとは何か
波形解析によってある地点とある地点に
コネクティビティ(繋がり)があるかどうかを調べる指標で、
脳波解析の文脈で広く使われるものです。

...いや、広く使われていたものです。
**この指標は理由がない限り因果関係の考察に使わないで下さい。**
というのがこの記事の内容です。

# PLVの計算方法
フーリエ変換とかWavelet変換では位相の情報が出てきます。その為、波形同士の相関を計算することが可能になります。素敵ですね！

Wavelet変換で計算した二つの波の複素数のノルムを1に補正したものを掛け合わせて、互いに足し合わせて平均をとれば、特定の周波数に関してどの程度似ているか分かります。ここで、波xとyの相関関数をSxyとすると下記の式になります。

$$E{\frac{Sxy}{|Sxy|}}$$

二つの波が同時に高くなったり低くなるなら、波同士は相関があります。

**もし、相関具合が高ければ、因果関係がある…君はそう思ったかい？
それは間違いだ！**

# 相関と因果を間違ってはいけない
相関関係と因果関係は違います。

例えば…地震や味噌汁に例えます。
(僕は地震についてはよく知らないのであくまで例えです)

### 問1・震源地の話
今京都で地震が起こったとします。東京と福岡にその地震が波及してきました。さて、京都と東京と福岡、どの場所に因果関係があるでしょうか？
- 京都→東京
- 京都→福岡

ってなるだろ…常識的に考えて。

だけど、PLVだと東京と福岡が最も強く相関する、と出ます。
何故でしょうか？

### 回答例
京都から東京に波が波及するときに時間がかかります。つまり、京都と東京は位相がずれています。一方、東京と福岡は同じくらいずれています。

PLV「京都だけ位相が遅れていない。京都は仲間はずれだ！東京と福岡は同じくらい遅れている。だから東京と福岡には関係がある。京都の地震は東京や福岡の地震とは無関係だ！！！」

PLVでは東京と福岡に相関が高いため、東京と福岡を関連づけて考えるのです。

### 問2・交絡因子の話
味噌汁を食べる人は寿命が長いそうです。ここに、寿命と味噌汁に因果関係が見つかった！寿命を伸ばしたければ味噌汁をがぶ飲みしよう！
しかし、冷静に考えると塩分のとりすぎは身体に悪いはずだ。
因果関係に対して反論して下さい。

### 回答例2
味噌汁を食べる人は全体的にきちんとした食生活を送っているから、寿命が長いのです。塩分を取り過ぎになるのを差し引いても、味噌汁を食べるだけの余裕がある人はいつもインスタントラーメンしか食べる余裕のない人より全体的に健康的な暮らしをしているはずです。
先程の「京都」にあたるのが「健康的な暮らし」、「東京と福岡」が「寿命と味噌汁」ですね。

# 位相の差分を考慮しよう
波の相関関数等を用いた場合は震源地からの波及によって値がおかしくなります。
脳波解析であれば、例えば目をキョロ動かした時におかしなことが起こります。人間の眼球は帯電しています。眼球運動による脳波のノイズは脳波を遥かに超える大きさなのです。
キョロキョロした場合、脳全体に同じ様な電位が生じます。つまり、PLVだと脳全体に波及した眼球ノイズが出現すると「脳全体に互いに関連のある波形が出現した！」となります。
脳波解析屋さんはそういう風に「脳機能が向上した！」なんて言ってしまえるのです。ここは知識と倫理が求められますね。

位相の差分を考慮に入れた指標が求められますし、実際複数開発されています。
(ここにも落とし穴はあるのですが今回は語りません)

# まとめ
PLVはコネクティビティの考察に使う場合には大きな落とし穴がある。
代替案の例としては下記がある。

- Imaginary coherence
- Weighted imaginary coherence
- Phase lag index
- Phase slope index

使うなら震源地に関して考察して、大丈夫と判断できる時だけにしようね、僕と君との約束だ！
aws lambda の Runtimeをnodejs12.xからnodejs16.xにaws cli を使って 一括で切り替えたメモ

## 概要
AWSからnode12がEOLになるので、nodejs12.xのlambdaを更新してくれとメールが来ていた。
11月になる前に対応したいので、cliを使って一括でnodejs16.xに更新した。
なお、cdkで作ったものは14.xを明示的に指定しているので、ここで更新が必要なものはCloudFormationが自動生成したLambdaであった。


<details><summary>メール</summary>

> Hello,
We are contacting you as we have identified that your AWS Account currently has one or more Lambda functions using Node.js 12 runtime.
We are ending support for Node.js 12 in AWS Lambda. This follows Node.js 12 End-Of-Life (EOL) reached on April 30, 2022 [1].

>As described in the Lambda runtime support policy [2], end of support for language runtimes in Lambda happens in two stages. Starting November 14, 2022, Lambda will no longer apply security patches and other updates to the Node.js 12 runtime used by Lambda functions, and functions using Node.js 12 will no longer be eligible for technical support. In addition, you will no longer be able to create new Lambda functions using the Node.js 12 runtime. Starting December 14, 2022, you will no longer be able to update existing functions using the Node.js 12 runtime.

>We recommend that you upgrade your existing Node.js 12 functions to Node.js 16 before November 14, 2022.

>End of support does not impact function execution. Your functions will continue to run. However, they will be running on an unsupported runtime which is no longer maintained or patched by the AWS Lambda team.

> The following command shows how to use the AWS CLI [3] to list all functions in a specific region using Node.js 12. To find all such functions in your account, repeat this command for each region:

```
aws lambda list-functions --function-version ALL --region us-east-1 --output text --query "Functions[?Runtime=='nodejs12.x'].FunctionArn"
```

</details>

## 環境

* gitbash
* jq-1.6
* aws-cli/2.7.35 Python/3.9.11 Windows/10 exe/AMD64 prompt/off

## cli

```
aws lambda list-functions --query "Functions[?Runtime=='nodejs12.x'].FunctionName" | jq -r ".[]" | sed "s/^ *\\| *$//" | xargs -I{} aws lambda update-function-configuration --runtime nodejs16.x --function-name "{}"
```

## 参考
[AWS Lambda のランタイムを変更する方法](https://blog.serverworks.co.jp/lambda-runtime-change)
[list-functions](https://docs.aws.amazon.com/cli/latest/reference/lambda/list-functions.html)
[update-function-configuration](https://docs.aws.amazon.com/cli/latest/reference/lambda/update-function-configuration.html)
リーダブルコードまとめ(第11章:一度に1つのことを)

# 第11章:一度に1つのことを
## 概要
複数の処理を一度に行うのは分かりにくいので、それぞれを分離して書く必要性を説明している。

### まとめ
とにかく、一度に複数の処理を行わすのではく、それぞれ引き離して記述して、ビジネスロジックをわかりやすく、また処理の再利用にも貢献できるコードを書くようにとのこと

### 学んだ点
・コードは1つずつタスクを行うようにしなければならない。
・関数に限らず、いろんな面でこの考えは活用できる。
・一度に1つのタスクをするために筆者が使っている手順
1.コードが行なっている「タスク」を全て列挙する。
※この「タスク」という言葉はゆるく使っているので、「オブジェクトが妥当かどうかを確認する」ように小さいこともあれば、「ツリーのすべてのノードをイテレートする」のように曖昧なこともある。
2.タスクをできるだけ異なる関数に分割する。少なくとも異なる領域に分割する。
・コードを分割すると、コードのことを考えやすくなる。その結果、もっと上手くリファクタリングできる方法を思いつく可能性がある。例えば、if文が連続していると、分かりにくく注意して読まなければいけないが、分割することでコードを読む時間をもっと時間を節約できる。
・コードを改善する手法の一つとして、ヘルパー関数を導入することも1つの手である。

### 感想と振り返り
本章は、具体例のコードを使って説明してくれているのでぜひ読んでいただきたいが、一貫して処理を分割して書くことを主張していた。しかしながら、コードを書く中で、他の処理に付随して行なってほしい処理もあったりするので、その際は切り離したほうがいいのかどうかも念頭に置いて考えて実装したいですね！
"Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/containers/json": dial unix /var/run/docker.sock: connect: permission denied"エラーを解決

最近VagrantやDockerを使った学習をしています！私の業務上、両スキル必須ですのでどちらも学習が欠かせません。

# 1.エラー発生
vagrantを立ち上げて、ssh接続を実施した後、dockerコマンドを打つもエラーが発生
````
[vagrant@localhost ~]$ docker ps
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/containers/json": dial unix /var/run/docker.sock: connect: permission denied

````

これは明らかな権限エラーっぽい。

## 2.解決
要するに、unix:///var/run/docker.sockの実行権限がないので、実行グループに割り当てたらいいですね。
````
[vagrant@localhost ~]$sudo chown $(whoami) ///var/run/docker.sock
````
これで解決します。
しかし、これではvagrantを再起動するたびにリセットされてしまいます。そのたびに上記コマンドを打つのは面倒くさいですよね。
そこで、vagrantを起動させるたびにコマンドを自動で実行してくれるように.bashrcファイルに記載しましょう。

````/home/vagrant/.bashrc
#一番下に記載
sudo chown $(whoami) ///var/run/docker.sock

````
一度sshからexitしましょう。そしてもう一度ssh接続してdockerコマンドを打ってみると...
````
[vagrant@localhost ~]$ docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
````
無事にできました。

## 3.最後に
docker関係のエラーは、dockerがストップしている、権限不足、イメージ・コンテナが存在しない等が多いです。エラーが出たときは最初に確認してみましょう。
古代C++でenum classを使いたかったある冒険者の日記

C++03でenum classっぽい物を使いたかった備忘録です  

# ネタバレ

classかnamespaceで囲ってしまう   

```cpp
//class,structでも良い
namespace Type{
enum t{
    kHoge,
    kFuga
};
}
typedef Type::t Type_t;
```

# 序章. 冒険の始まり

止むに止まれぬ色々な事情で
2022年の昨今もC++03はバリバリ現役である。[^1]

C++03にはscoped enumが無いので
ヘッダ等で安直な名前を使うと、衝突する恐れがある。

```cpp
#ifndef HOGE_H
#define HOGE_H
enum Type{
    kOk //衝突の可能性あり
};
#endif
```

回避方法として、ユニークな接頭辞を付ける手がある。  
```cpp
enum Type{
    kHogeTypeOk
};
```

しかし、個人的には  
無駄な情報をenum値に付け加えたくない。  

# 解消法第一話 ラッパクラスで囲ってしまう

最初に思いついたのは、クラスでラップしてしまう方法

```cpp
#include <iostream>

class Type {
 public:
  enum t {
    kHoge,
    kFuga,
  };

 private:
  t enum_value;

 public:
  Type(t enum_value) : enum_value(enum_value) {}
  Type(const Type& type) : enum_value(type.enum_value) {}
  virtual ~Type() {}
  Type& operator=(t enum_value) {
    this->enum_value = enum_value;
    return *this;
  }
  operator t() { return enum_value; }
};

int main() {
  Type t = Type::kFuga;
  Type t2 = t;
  Type t3(t);
  t2 = Type::kHoge;
  std::cout << t << "," << t2 << "," << t3 << std::endl;
}
```

enum classっぽく書けるけど
enumが増える度にこれ書くのはつらい  
ソース読むのも時間かかる  

# 解消法第二話 代替方法の思いつき

でどーするかと考えていたが

要はenum classの名の通り、enumへscope指定できれば良いだけなので  
classなりnamespaceなりで囲った後
typedefすれば良いだけだと気づいた。

```cpp
#include <iostream>

namespace Type{
enum t{
    kHoge,
    kFuga
};
}
typedef Type::t Type_t;

int main() {
  Type_t t = Type::kFuga;
  Type_t t2 = t;
  Type_t t3(t);
  t2 = Type::kHoge;
  std::cout << t << "," << t2 << "," << t3 << std::endl;
}
```

_t付けるのがやや面倒だけど  
シンプルにenumへスコープ指定出来る。

# 終話

もっといい方法あったら教えてください  
あと誰かぼくにC++20をください  


[^1]: 個人の感想です。感想で終わってほしい。
ColabやiPythonでファイルをオート・リロード

Colabなどで開発しているとき、別ファイルのモジュールを書き換えてインポートしても、変更が反映されません。
呼び出しごとに別ファイルモジュールをリロードするには、以下を実行してから呼び出します。

```shell
%load_ext autoreload
%autoreload 2
```

これで別ファイルの変更が反映されます。

🐣
****
フリーランスエンジニアです。
お仕事のご相談こちらまで
rockyshikoku@gmail.com

Core MLやARKitを使ったアプリを作っています。
機械学習／AR関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
[GitHub](https://github.com/john-rocky)
文脈力こそが知性である

https://www.amazon.co.jp/s?k=%E6%96%87%E8%84%88%E5%8A%9B%E3%81%93%E3%81%9D%E3%81%8C%E7%9F%A5%E6%80%A7%E3%81%A7%E3%81%82%E3%82%8B&i=stripbooks&adgrpid=54867095713&gclid=CjwKCAjw4c-ZBhAEEiwAZ105RSpxLaftJETP0caFY1fM3Nz1baWloA2AdHxWZSha0FtX9E19M0NPrhoCYjoQAvD_BwE&hvadid=553963557839&hvdev=c&hvlocphy=1009255&hvnetw=g&hvqmt=e&hvrand=12735162504281573441&hvtargid=kwd-357386424394&hydadcr=4073_13159854&jp-ad-ap=0&tag=googhydr-22&ref=pd_sl_2epq1473yh_e

背景
読解力を身に着けたいと思って、いろんな本を読んでいる中で本書を手に取りました。
齋藤孝さんの本で「大人の読解力を」鍛えるという本も読んだのですが、大変おもしろかったです。
https://qiita.com/Mune_robo/items/cb68212a74bfc2e3f291

齋藤孝さんの書く本は個人的にすごく面白くて、読みやすかったのですが、文脈力にも興味が湧いて本書も読んでみました。

本書のテーマ
文脈力とは斎藤孝さんが作った造語ですが、「文脈を捕まえる力」や「文章をつなぐ力」というものを一つの概念として提示したものです。
文脈力について書いた本は他にもあるのですが、改めて文脈力をアップデートして、知性を磨いていくというのがこの本のテーマになっています。

個人的なポイント
1.語彙力を輝かせるのが文脈力
語彙は文脈の中ではじめて活きてくる。どんなに素晴らしい言葉を知っていてもそれを自由に使えなければ意味がない。

2.頭の良さの本質は「蓄積された知識に基づいて何ができるのか」
頭の良さにもランクがあり、記憶したことを再生できるだけでは足りない。最も難しいことは「新たな概念や型、方法を生み出せること」

3.頭がいいとは何かと何かが繋がったとき
ひととはなしていて、「これはこれと関連している」とかっていう感じで返されるとはっとするというか、発見があったと感じることがあります。
頭のいい状態とはこういうつながりを発見する力であり、この努力を積み重ねていくことで知的な人になっていけます。

4.空気を読まない人とは
文脈を外してしまう人のことです。置かれた状況で自分に何が求められているのか。相手や場に関わっっている人たちの感情や機微に気づいて想像力を及ばす。人と人との間にあるものを予測し、配慮するのが大事です。
コミュニケーション能力に通ずるものだと思います。

5.求められるのはスピーディーな言語化
必要なときにさっと必要な言葉が出せるべきです。短時間で素早く脳を働かせ言語化する回路が開かれてないといけません。常に思考力と瞬発力を求められます。

6.スピーディーな言語化を実現するために
齋藤孝さんは「しゃべくり勉強法」というのを中学生時代にやっていたそうです。試験が近くなると、覚えたことを友人に説明する。これをやったことで普段も知識を出すスピードが早まったそうです。
他にもニュースのキーワードを説明する方法や新書を読んで３つのキーワードをピックアップし説明する方法なども公開していました。

7.哲学書や古文、英語の本からも文脈を読み解く
齋藤孝さんは何かを鍛えるために様々な手法を紹介してくれます。その一例が上記なのですが、特に読みづらくとっつきづらいジャンルのものでも、こうやって読めば発見があるということを教えてくれています。

8.知者は惑わず
論語に「知者は惑わず、仁者は憂えず、勇者は懼れず」という言葉があります。まさにここの「知」を養うことでもっと幸せになれると思います。

一番心に残ったポイント
知性のランクがわかりやすくて心に残っています。
A~Dまで定義しているのですが、その内容は以下です。
A：記憶したことを再生できる
B：記憶に基づいて自分の言葉で再構築できる
C：知識や情報を組み合わせて、そこからアイデアを出せる
D：新たな概念や型、方法を生み出せる

私は仕事柄、Bまでの能力が平均的に求められるのですが、ここまでに至るのもなかなか難しいです。
そして、学者や博士はDに値するのだろうと考えると、全くレベルが違うんだなと気付かされました。
ただ、漠然と自分が求められていることをイメージしていたので、Bというランクだったことにほっとした部分もあります笑
これに気づけただけでも、すごくありがたいです。

まとめ
読解力、文脈力を学ぶ上で、本当に最高峰にいい本と出会えたと思いました。
読解力を身につけるには本を読むことが大事だと動画で見てから、いろんな本を読み、アウトプットをしてきました。
いままでの人生でこんなに本を読んできたことはありませんでしたが、読書が加わることでこんなにも意識は変わるものなんだと実感しています。

「愚者は経験に学び、賢者は歴史に学ぶ」というオットー・フォン・ビスマルクの格言がありますが、私はまさに前者でした。むしろ、歴史から学ぶということがなにかもわかっていませんでしたが、読書を通して著者の考え方や経験を学べることがそれであり、貴重なものだったんだと思います。

読解力だけでなく、様々な分野に興味が出てきたので、引き続き様々なジャンルの本を読んでアウトプットしていきます。
【Bubble】条件を満たすデータをすべて更新する方法

bubbleのTipsメモです

# 概要
bubbleで条件を満たすデータをすべて更新する方法です
基本的には「Make changes to things…」アクションを利用して、
１件ずつデータを更新していると思います。


今回は、Make changes to a list of things…を使用して
一括でデータを更新する方法を解説します。

# Workflow
一括でデータを更新する場合は
「Click here to add an action」→「Data(Things)」→「Make changes to a list of things」

![画像１.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95299/3aed1d12-e3a3-7b88-8e9f-336f54b29dd8.png)

## Make changes to a list of things…設定方法
Type of things: 更新対象のデータ種類
List of change: 「Search for things」や「:filtered」　 ※更新対象のデータを検索する条件
更新する値： （※例はRead = "yes"）

## list filter…設定方法
更新する条件： （※例はRead <> "yes"とCreator <> Current User）

## 完成したもの
![Qiita用１.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95299/bdefa1d8-9490-9c1d-f4bd-04f807bc0df6.jpeg)
Seeed XIAO RP2040でパルス幅・周波数を測定する

# 概要
Seeed XIAO RP2040のパルス幅・周波数を測定してみる。
普通のArduinoと同じソースで使えるので説明するほどではないが、覚え書きとして投稿。

ボードライブラリはearlephilhower氏のArduino-picoを使用する。
ボード設定を変えればRaspberry Pi Picoでも同じソースで動作すると思われる。

# 実行環境
MCU：Seeed XIAO RP2040
IDE：Arduino IDE 1.8.19

# 参考サイト
http://www.musashinodenpa.com/arduino/ref/index.php?f=0&pos=2450

# 環境構築・事前準備
省略

※参考サイト

https://garchiving.com/use-raspberry-pi-pico-with-arduino-ide/

ボード設定は「Raspberry Pi RP2040 Boards」の「Seeed XIAO RP2040」を選ぶ。

# サンプルコード
テストとしてGPIO28に入力された信号の周波数を0.5秒ごとに出力する。
パルス幅の測定結果はマイクロ秒で出力されること、1周期の半分の値が出力されることを考慮して周波数に換算する。

```c
const int TACHO_PIN = 28;

void setup() {
  /* シリアル通信の設定 */
  Serial.begin(115200);
  /* ピンをインプットに設定 */
  pinMode(TACHO_PIN, INPUT);
}

void loop() {
  /* パルス幅(HIGHの時間)を測定 */
  int pulse_width = pulseIn(TACHO_PIN, HIGH);
  /* パルス幅を周波数に換算する */
  float freq = (1000000.0 / ((float)(pulse_width) * 2.0));
  /* 測定した値をシリアル通信で出力 */
  Serial.println(freq);

  delay(500);
}
```

# 動作テスト
オシロスコープのテストピンを使用して1kHzの信号を入力。
![2022-09-29 (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321914/66f6b371-e1a6-cb2e-8c8e-85319c668f98.png)
Seeed XIAO RP2040のADC機能を使う

# 概要
Seeed XIAO RP2040のADC機能を使ってみる。
普通のArduinoとほぼ同じソースで使えるので説明するほどではないが、覚え書きとして投稿。

※詳細内容は別サイトに移転しました。

https://cotechworks.ltt.jp/2022/07/03/post-375/
Seeed XIAO RP2040でPWMを使う

# 概要
Seeed XIAO RP2040を使用してPWM信号を出力する。
ボードライブラリはearlephilhower氏のArduino-picoを使用する。
参考サイトではRaspberry Pi Picoを使用しているので、同じソースで動作すると思われる。

※詳細内容は別サイトに移転しました。

https://cotechworks.ltt.jp/2022/07/03/post-375/#
Djangoで途中でテーブルの定義を変更したらpytestが動かなくなった話

## 何があったか
ある時に実装に必要な修正を行うために既存のテーブルの定義を返る必要があり、別の方がマイグレーションを行った。
その後APIの修正のためにpytestの修正を行い、テストを実行しようとしたところテスト用のデータベースをマイグレーションするところで引っかかり実行できなくなってしまった。
調査をすると今回マイグレーションで修正したテーブルはそのテーブル作成時のマイグレーションで`loaddata`を使ってjsonから初期データを登録していたことがわかった。
定義を変更したマイグレーションをAとし、テーブル作成時のマイグレーションをBとするとテスト用のデータベースのマイグレーションはBのタイミングで止まっていた。

## 原因
まずpytestでは特に設定等していない限り、テストを実行すると必要なテーブルを作成するためにDjangoのmigrationファイルに基づいて頭から順次migrateを行う。
しかしソースコードを読むと、`loaddata`の実態はfixture配下の指定されたjsonを読んでそれをDeserializeし、対象のmodelにマッピングするような処理になっていた。
つまり、pytestはマイグレーションBを行おうとするが対象のmodelはすでにマイグレーションAの仕様になっているのでカラムやデータが合わないから`loaddata`できないよと怒られるということだった。
では、読み込むjsonの方をmodelに合わせて修正したり、`loaddata`のオプションで`ignorenonexistent`というものがありそれを使うと作成時から定義が変わった部分を無視(空文字を入れる)できるというものがあるので、それでいいのではとなるがそうすると今度はマイグレーションBの時点のテーブルの定義と外れてしまうのでエラーは解消できなかった。

## 対策
マイグレーションBで行っている`loaddata`をマイグレーションAに移して、`migration.RunSQL`で対象のテーブルのデータを削除した後に実行するように修正する。
あるいはその一連のDelete Insertの処理を新しいマイグレーションファイルを作成してそこに書く。
そうすると

マイグレーションBでテーブル作成(中身は空) → マイグレーションAで定義変更 → 定義変更に合わせたデータをDelete Insert

という動きになるので解決はする。
ただし、これだとローカル環境でのmigrateは容易に済むがステージングや本番環境など該当のテーブルのデータが初期データではない場合はリリースの際にデータが吹っ飛んでしまうので予めバックアップを取り、改めてそれをDelete Insertしないといけない。
または元データが別のリソース(Redshiftとかsnowflakeとか)にある場合は同様に改めてデータを取得したのちそれをDelete Insertする必要がある。

## あとがき
ちなみにpytest(というかpytest-django)にはDjango側のマイグレーションを無視し、原因のmodelを参照してそこからテストテーブルを作成する`--no-migrations`というオプションがあるが、マイグレーションがあるのに無視してしまってはテストとしてどうなのよということで採用はしなかった。
また少し古いStackOverFlowになるけれども[こういう例](https://stackoverflow.com/questions/25960850/loading-initial-data-with-django-1-7-and-data-migrations)もある。
こっちのほうがいいような気もするけれど一見だと何やってるか分かりづらいのと、結局マイグレーションを弄るし、今回はfixtureも修正して初期データの中身も増やす必要があるのでそれなら新しいマイグレーションにloaddataを移動させてDelete Insertするほうがいいかも。

マイグレーションA自体はすでにレビュー済みでMergeされていたし、pytestのマイグレーションは必ず1からやるので当然テーブルの作成かつ旧仕様の初期データを追加 → その後定義変更のマイグレーションが普通に行われるものだと思っていたが飛んだところに罠が潜んでいたなと。
エラーが起きたときに何が悪いのかイマイチ掴めず、先輩に指導頂きながらようやく原因がわかったときは軽いアハ体験だった。
マイグレーションAのタイミングでpytestを実行したり、或いは担当者が気を回せていればもう少しうまいことやれたのかもしれない。
もしこれを読まれた方でもっと良い方法があれば教えていただけると幸いです。

## 参考
[pytest-django --no-migrations](https://pytest-django.readthedocs.io/en/latest/database.html#no-migrations-disable-django-migrations)
[loaddata](https://docs.djangoproject.com/en/3.2/ref/django-admin/)
【PHP】ファイルアップロードにおけるPermission設定について

**【PHP】ファイルアップロードにおけるpermission設定について**
*この記事ではCentOS Linux 7にインストールしたPHP 7.1.29を使っています。*
*Server version: Apache/2.4.6 (CentOS)*


# はじめに
画像ファイルをアップロードしようとしたところ、permissionエラーが発生。
原因とエラー解決までを纏めました。


# 自分の置かれた状況
画像アップロード
```html:upload.html
    <form method="POST" action="img_save.php" enctype="multipart/form-data">

        <input type="file" name="img" accept="image/*">
        <input type="submit">

    </form>
```

画像をimagesディレクトリに保存
```PHP:img_save.php
    $img_name = $_FILES['img']['name'];

    //画像を保存
    move_uploaded_file($_FILES['img']['tmp_name'], './images/' . $img_name);
```

エラー発生
**`Warning: move_uploaded_file(./images/$img_name): failed to open stream: Permission denied `**


# 原因
アップロードのディレクトリ(images)に書き込み権限が与えられていなかった為でした。

```
$ ls -l
-rw-rw-r-- ハードリンク数　所有者とグループ　ファイルサイズ　タイムスタンプ　 images
```

`-rw-rw-r--`は下記の状態となっています。

Owner ・・・読み取り・書き込み
Group ・・・読み取り・書き込み
Other ・・・読み取り


# 解決策
「Apache」はPermissionのユーザー分類としては、「Other」に分類されます。
Apacheの書き込みを許可を与えるために、権限を変更を行いました。

```
$ chmod 666 images
```

`-rw-rw-rw-`

Owner ・・・読み取り・書き込み
Group ・・・読み取り・書き込み
Other ・・・読み取り・**書き込み**


# おわりに
画像アップロード処理エラーで二日ぐらい頭を抱えていました。
分かりにくい箇所あるかと思いますが、誰かの役に立てたら嬉しいです。
これから引き続き投稿していきます。
Python環境を整理する

## 前提
MacのPython環境がローカルやらスタンドアロンコマンドラインツールやら仮想環境やらでごちゃごちゃしていたので整理した

## 不要なPythonの削除
1. アプリケーションからゴミ箱に入れる
1. 削除 ```rmーrf /Library/Frameworks/Python.framework```
1. ``` ls -l /usr/local/bin | grep Python ```で表示されたリンクを```unlink python```で削除
1. zshrc等のpython記述を削除

## 管理ツール類の整理
#### Homebrew
macのツール管理マスタ 最新版へのアップデートや世代管理、バージョン切り替えを行う
そのままmysqlやらなんやら入れるとバージョンの切り替えや管理に苦労する
#### pyenv
pythonのバージョンを管理する
グルーバル環境、ローカル環境それぞれで3.7系から3.8系の切り替えが容易になる
#### venv
pythonの仮想環境
パッケージ管理を目的とし、プロジェクトごとにパッケージ管理を行うために必要

## 手順
1. homobrewからpyenvを入れる
1. pyenvでpythonのバージョンを管理するようにする
1. venvでプロジェクトごとに仮想環境を作ってパッケージ管理する

## インストールコマンド　使い方
- pyenv
```
 brew install pyenv
 pyenv install --list
 pyenv install [listのいずれか ex:3.9.13]
 pyenv global 3.9.13
```
- venv
```
 ## 仮想環境フォルダ作成 (後者がフォルダ名)
 pyenv -m venv venv
 ## 利用するとき
 source venv/bin/activate
 ## 無効化
 deactivate
```

- pyenvのPATH .zshrc等に追記
```
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
```
テスト項目書の書き方について

# はじめに
ある現場にて画面打鍵によるブラックボックステストを担当したのですが、
あまりにもテスト項目書が杜撰すぎたので愚痴ベースで雑多に吐き出します。

※世のエンジニア方々は「言われるまでもない」と思うことかもしれません

## 理想：考えているおおよそのテスト項目書
差はあれど、例としてだいたいの方がこのようなテスト項目書を想像すると思います。
(Markdown表記なので見辛い部分はご了承ください)

| No | 大 | 中 | 小 | 実施内容 | 期待結果 | 結果 | 備考 |
|:--- |:--- |:--- |:--- |:--- |:--- |:--- |:--- |
| 1 | ログイン情報入力 | 入力チェック | 異常系(ID非一致) | 初期表示される「ログイン」画面の「ID・パスワード」に、表X-Yに示す「ID・パスワード」を入力後、[ログイン]ボタンを押下する | 「IDまたはパスワードが～」とエラーメッセージ表示されログインに失敗する | 〇 or ✕ | △△ |

## 現実：第三者が読んで本当に理解できると思っていますか？
まず、理想のような表は存在しませんでした。(なので以降、表は一切登場しません)

結論として一番言いたいこと。
これはテスト項目書に限らず他の手順書などにも言えることですが
__誰かに伝えるということを意識しましょう__

以下、担当したテストでの気になったポイントを箇条書き形式で記述していきます。
(※流石にテスト項目をそのまま書くわけにはいかないので脚色している箇所があります)

- __ログインできるということはログインするということなんです__
　「そんな事あるはずが…」と思うかもしれませんが、
　　おおよそ以下のように記載されていることがありました。
　__※ログインするための各種情報は項目書に記載されていませんでした
　　(自身による質問後、口頭で説明されました)__
　・想定結果：ログインできること / 操作：ユーザ名とパスワードを入力しログインする
　・想定結果：ログインできないこと / 操作：ユーザ名とパスワードを入力しログインに失敗する

- __「ログインし〇〇画面を表示」とはどういう操作なのですか？__
　・どのIDとパスワードを入力し、どのユーザとしてログインした後、
　　ログイン直後に表示される画面で何を操作し、◯◯画面に遷移できるのでしょうか。
　・本番環境の作業手順書ならrootユーザでログインして好き放題できますが…

-  __1つの道筋で順に実施できるようになっていますか？(余力があれば考えてみてください)__
　・異常系から正常系のチェックをすれば無駄に複数のデータを登録せず済むと思います。
　　(例：ユーザ登録 => 各種項目のエラーをチェック => 全項目にエラーがなく登録できること)
　・結合テストになればより重要視して考えなければならない項目だと思います。

- __実装者の意図(このように動くはずだ)は関係なく公平に確認できますか？__
　・テスト項目を書くのはいいですが、
　　ちゃんとテストフェーズ前に動作確認できている前提ありきです。
　・例えば「そもそも表示されるデータの項目が表示されない」など
　　テスト以前の問題を残すのはやめてください。

- __ホワイトボックステスト、ブラックボックステストの区別を意識できていますか？__
　・「〇〇画面にて～をした結果DB✕✕の△△テーブルが更新されることを確認する」のように
　　　記述することはやめてください。
　・システム利用者がDBのテーブルを
　　「ああ、なるほど」と言って直接参照できますか？できませんよね。
　　　テーブルの中身を参照できる画面があるのであれば、
　　　参照に到るまでの手順を明示してください。

- __正確に伝えることを意識できていますか？__
　・必要であれば「どこを」「何(左・右)クリックする」などの
　　　レベルで記述することが必要だと思います。
　・「クリックと指示されれば無意識にクリック」できますが
　　　マウスを利き手と逆で操作してみると考えが変わると思います。

# さいごに

- 「舟を編む」から学ぶ
　・メディア化もされましたが「著：三浦しをん」の
　「舟を編む」という小説に以下の一節があります
　　問：「“右”という言葉を説明できるかい？」
　　答：「・・・西を向いた時、北に当たる方・・・が右」
　・「伝わりやすさを考慮するのは当然でしょう」と考えていましたが、
　　「当たり前」だと思っている言葉を更に細分化してみる、
　　ということについて考えるきっかけになりました。

- 専門職でない人にも伝えることを想定してみる
　・私自身は開発がメインなのである程度は汲み取ることができると思っていますが
　　専門職ではない「オペレーター」のような方々にテストを依頼する場合を考えてみてください。
　　前述のような書き方をしたら指摘や質問の嵐になり、
　　最終的に双方にとってデメリットが多発する結果が容易に想像できます。
　・そうなる前に今一度「自分はどうだろう」と考慮してみる価値はあると思います。


「はじめに」に記載した通り「愚痴ベースで雑多に吐き出し」ているので
文体が統一できていない箇所や表現が雑になっている箇所もあるかと思いますがご容赦ください。

最後までお付き合いいただきありがとうございました。
VSCodeのおすすめ拡張機能

## はじめに
今回は、私がVSCodeに追加している拡張機能を紹介します！

## 拡張機能一覧
### Activitus Bar
アクティビティバーが邪魔だと感じたことがある人におすすめです
作業範囲を広げることができます

https://marketplace.visualstudio.com/items?itemName=Gruntfuggly.activitusbar

https://qiita.com/nwtgck/items/50a9675990b26c6c70b1

### Auto Close Tag
HTML/XMLの終了タグが自動的に補完されるようになります

https://marketplace.visualstudio.com/items?itemName=formulahendry.auto-close-tag

### Auto Rename Tag
ペアになっている HTML/XML タグの名前を自動的に修正できます

https://marketplace.visualstudio.com/items?itemName=formulahendry.auto-rename-tag

### Bookmarks
任意の行をブックマークしてすぐに遷移できるようになります

https://marketplace.visualstudio.com/items?itemName=alefragnani.Bookmarks

### change-case
スネークケース→キャメルケース　キャメルケース→スネークケース　の変換がコマンド１つでできます

https://marketplace.visualstudio.com/items?itemName=wmaurer.change-case

### Code Spell Checker
スペルミスがあれば波線で表示されます

https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker

### endwise
if文などのendが自動的に入力されます

https://marketplace.visualstudio.com/items?itemName=kaiwood.endwise

### Git History
コミット履歴の表示や検索ができます
ファイル、行単位で履歴の確認もできます

https://marketplace.visualstudio.com/items?itemName=donjayamanne.githistory

### GitLens
カーソルを合わせた行を変更した人、日、コミットメッセージを確認できます

https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens

Git HistoryとGitLensはまだまだできることがあるのでこちらを参考にしてください

https://codelikes.com/vscode-git-plugin/#toc1

### indent-rainbow
インデントを色付けしてわかりやすくできます

https://marketplace.visualstudio.com/items?itemName=oderwat.indent-rainbow

### Log Viewer
ログファイルに対して色付けしてわかりやすくできます
大きなファイルを表示することもできます

https://marketplace.visualstudio.com/items?itemName=berublan.vscode-log-viewer

### Output Colorizer
VSCodeのターミナル対して色付けしてわかりやすくできます

https://marketplace.visualstudio.com/items?itemName=IBM.output-colorizer

### Path Autocomplete
Pathの入力補完です

https://marketplace.visualstudio.com/items?itemName=ionutvmi.path-autocomplete

### Terminals Manager
ターミナルの起動を自動化できます

https://marketplace.visualstudio.com/items?itemName=fabiospampinato.vscode-terminals

https://qiita.com/mayobimu/items/9a3e5623cb69bb8816a6

### TODO Highlight
TODO:,FIXME:と記載された部分が強調表示されます

https://marketplace.visualstudio.com/items?itemName=wayou.vscode-todo-highlight


### Trailing Spaces
余計な空白が強調表示されます

https://marketplace.visualstudio.com/items?itemName=shardulm94.trailing-spaces

### vscode-icons
アイコンがいい感じになります

https://marketplace.visualstudio.com/items?itemName=vscode-icons-team.vscode-icons
## おわりに
他にもおすすめの拡張機能があればコメントで教えてください:relaxed:
Linux dmesg --clearとクラッシュダンプについて

●dmesg --clear
リングバッファはマシンの再起動やシャットダウンによってリセットされるが、運用中に一杯になると古い情報から上書きされる。手動でリングバッファの内容をクリアするには、rootユーザで「dmesg --clear」を実行。
dmesgはシステムの起動時にカーネルが出力したログを閲覧するためのコマンド。dmesgコマンドはカーネルが出力するメッセージが格納されるリングバッファの内容を出力。

●クラッシュダンプの取得
システムが何らかの原因で異常終了（クラッシュ）した時に、その時のメモリの内容をファイルに出力（ダンプ）することをクラッシュダンプという。
クラッシュダンプにはメモリ上に展開されていた実行状態やメッセージなどが保存される。
Linuxカーネルのクラッシュダンプを取得するには「kdump」というカーネルの機能を使用。カーネルがクラッシュすると通常はメモリの内容は失われますが、kdumpではダンプキャプチャカーネルという別のカーネルを起動してメモリの内容をダンプできるようにします。ダンプキャプチャカーネルを起動するのは、動作中のカーネルから他のカーネルを起動する「kexec」というシステムコール（OSの機能を呼び出すための仕組み）。

kdumpはRed Hat 7系ディストリビューションではデフォルトで有効。
PlantUMLにおける相互作用概要図の記述方法

# はじめに
プロジェクト初期段階でのシステムの振る舞い検討や、開発に大きく関わっていない方への説明の際に、UMLの相互作用概要図を使いたくなることがよくあります。

一方で私はUMLの描画ツールにPlantUMLを使っていますが、Webで「相互作用概要図 PlantUML」とか「Interaction Overview Diagram PlantUML」と検索をかけても、PlantUMLで相互作用概要図の記述方法がほとんどでてきません。

そのため、本記事ではPlantUMLで相互作用概要図の書き方について紹介します。また、初心者の方にも今回やっている内容を理解していただけるようにUMLとPlantUMLに関して概要をはじめに記載いたします。PlantUMLの開発環境構築手順などに関しては、本記事では取り上げませんのでご注意ください(別サイトで多くご紹介されておりますので、そちらを参照ください)。

# 本読者のターゲット
- PlantUMLについてよく知らないため、何ができるかざっくり知りたい
- PlantUMLで相互作用図の記述方法を知りたい

# 作業環境
 - OS: Windows11
 - エディタ: VSCode

# UMLとPlantUMLの概要
相互作用概要図の書き方だけ知りたいという方は、本章を読み飛ばしてください。
本章では、UMLとPlantUMLを知らない方向けに、それぞれの用語について概要を少しだけ紹介します。

UMLとはUnified Modeling Languageの略で、ソフトウェアを形式化するための統一モデリング言語です。UMLは表記法であり、ソフトウェアな静的構造を表す6種類の図と、ソフトウェアの動的振る舞いを表す7種類の図、合計13種類の図が定義されています。

```plantuml
@startmindmap
* 静的構造
** クラス図
** オブジェクト図
** 合成構造図
** パッケージ図
** コンポーネント図
** 配置図
* 動的振る舞い
** ユースケース図
** アクティビティ図
** ステートマシン図（状態遷移図）
** 相互作用図
*** シーケンス図
*** コミュニケーション図（コラボレーション図）
*** 相互作用概要図
*** タイミング図
@endmindmap
```

UMLは様々な場面で活用できますが、例えば要件定義で活用した場合、要件定義の設計段階では要件漏れの防止に役立ち、要件定義の合意段階ではシステム全体を俯瞰できるため効率的な議論に役立ちます。

一方でPlantUMLは、テキストベースでUML図を描画するためのオープンソースソフトウェアのツールです。位置調整や線の接続調整に悩まされず、単純なコードでUMLなどの図を記述でき、またテキストベースなのでGitHubなどでのバージョン管理と相性が良いため重宝しています。

上に記載したマインドマップもPlantUMLを用いて下記のように記述して書いています。

```bash
@startmindmap
* 静的構造
** クラス図
** オブジェクト図
** 合成構造図
** パッケージ図
** コンポーネント図
** 配置図
* 動的振る舞い
** ユースケース図
** アクティビティ図
** ステートマシン図（状態遷移図）
** 相互作用図
*** シーケンス図
*** コミュニケーション図（コラボレーション図）
*** 相互作用概要図
*** タイミング図
@endmindmap
```

相互作用概要図以外の各図の記述方法は[PlantUML言語リファレンスガイド](https://pdf.plantuml.net/PlantUML_Language_Reference_Guide_ja.pdf)で体系的にまとめられているので、そちらをご参照いただければと思います。

# PlantUMLでの相互作用概要図の記述方法
さて、本題ですが相互作用概要図の書き方です。ここでは、相互作用概要図として一般的に使われるアクティビティ図とシーケンス図の組み合わせを取り扱います。
書き方は単純で、通常通りアクティビティ図の記述をした後、各アクション二重中括弧`{{}}`で囲みます。

##### 相互作用概要図：アクティビティ図＆シーケンス図
```markdown:IOD.pu
@startuml
Start

if () then (Condition1)
:action1
{{
actor user
Participant system

Mainframe task1
user -> system : message
user <-- system : response
}}
;

else (Condition2)
:action2;
:action3
{{
actor user
Participant system

Mainframe task2
user -> system : message
user <-- system : response
}}
;

endif
stop
@enduml
```
```plantuml
@startuml

Start

if () then ([Condition1])
:action1
{{
actor user
Participant system

Mainframe task1
user -> system : message
user <-- system : response
}}
;

else ([Condition2])
:action2;
:action3
{{
actor user
Participant system

Mainframe task2
user -> system : message
user <-- system : response
}}
;

endif
stop
@enduml
```

本当はシーケンス図の周りをアクションブロックで覆わないで書くのが一般的だと思いますが、いろいろ試してもうまくいかなかったので、今後の課題とさせてください。

# まとめ
今回はPlantUMLの使い方として、相互作用概要図の記述方法を紹介しました。
個人的にはPlantUMLで上記のやり方が書けないことにしんどさを感じていて、ツール移行も考えていたので今回紹介した記法を発見した時は感動しました。

できたらUML活用情報の紹介記事をシリーズ化していけたらな～と思っています。直近では、他のUML描画ツールとPlantUMLのビジュアルとか使い勝手のレビュー記事とか、PlantUMLを用いたドメイン駆動設計について書きたいと思っています。
30分で作るDAO 老技術者が夜更けにDAOを作った話 　2. DAOに社員を入れる

# はじめに
DAOは10分で作れたので，次はこのDAOに新入社員を迎えることにした．高卒女子営業チームを作るとするか，とわけわからんこと言いながら老技術者は今宵もブロックチェーンで遊ぶのだった．
（1.DAOを作る　https://qiita.com/oldEng/items/bd5f8b9e36e579d87bed
は先に読んでおいていただきたい．）

## リンク
1.DAOを作る  　https://qiita.com/oldEng/items/bd5f8b9e36e579d87bed
3.DAOから送金する  https://qiita.com/oldEng/items/93f2682ec2a9cc6c9afe

# 2. 社員を1人増やす
## 2-1 Assign Tokensをクリック
1でこしらえたDAOのHomeからAssign Tokensをクリックする．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/e4c9f24b-56ed-437b-f1f2-5662824d084a.png)

## 2-2 Add tokensをクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/7572ffaa-ac30-a60d-bc71-1d5be2151740.png)

## 2-3 社員として追加したいアカウントをRECIPIENTに入れNUMBERS OF TOKENS TO ADDに入れてAdd tokens

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/76d4ae41-7926-e3c1-13c0-6963c1648bbf.png)

<img width = 300 src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/42bf9bc8-e832-5cec-61ef-1116ea63a880.png">

## 2-4 ちょっと待った！

さすがDAOである．創業者であっても投票(Voting）しないと社員採用もできないのだった．
まずはアカウントをアサインするトランザクションを作成してしまい，ガス代払って確定してしまった後でVotingとなる．

<img width = 300 src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/6e1928e7-24a2-c052-2ddd-439f61feef76.png">

<img width = 300 src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/12d3a780-2242-64de-8dfd-6e66e55db8b2.png">

## 2-5 Votingする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/dec33088-82e3-d306-389d-5a9d42d23ca3.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/e30aa29d-4ac2-bac9-3807-908648a3202a.png)

<img width = 300 src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/dbf88712-0c0c-aa54-854d-6b8a47f3a6e2.png">

<img width = 300 src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/0dab5f2e-221e-7386-dc19-2355a7bc5f7f.png">

## 2-6 可決された
創業者が1人で投票して，可決されるとやっと1人の社員を採用できる．なんと民主的な！？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/09a13ea5-bcef-1097-b6b9-8aa964d5091e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/dc44bb8e-bbba-3e02-803d-cba8bb2988eb.png)

## 2-7 社員が出勤してきた

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/2a469691-bcfb-6e75-1efb-b72893805c93.png)

## 2-8 社員から見たDAO：社員のアカウントでAragonに入りOpen an existing organization

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/138c04c2-314f-4eb2-e0e4-a12151a4cf51.png)

## 2-9 先ほど入社したDAOを開く

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/37f9dfcb-cf19-e200-fc10-03a7b16952db.png)

## 2-10 ちゃんとアサインされている

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/86f41b50-b683-5590-e4ad-64b759c33731.png)

## リンク
1.DAOを作る  　https://qiita.com/oldEng/items/bd5f8b9e36e579d87bed
3.DAOから送金する  https://qiita.com/oldEng/items/93f2682ec2a9cc6c9afe
Twitter APIとPythonでツイートデータを取得する

こんばんは。

前に書いた記事を消してしまったため、再掲させてください。
やることは標題の通りです。

# 今回やることの大まかな流れと、準備

### 最終的に出力したいこと

**「特定のワードでツイートを取得し、結果を見える形で出力する」。**

### 方法

1.PythonでtwitterAPIを利用し、ツイートデータを取得します。
2.特定のワードで絞ります。
3.結果をCSVで出力します。

### 準備

**・TwitterAPIのデベロッパーアカウントを取得する。**
→データの公開などtwitter社の規約などに触れないか確認します。

**・Pythonを書くエディタを用意する**
→anacondaでやろうと思ったのですが、ハマったので今回はVisual Studioでいこうと思います。

### 取り組む前に悩んだこと

元記事は **「KDDIが約款に抵触したかどうか、検証したい（失敗した）」** というものでした。それを踏まえて以下のことについて考えていました。

**・どのように出力すれば判定可能か**
いわゆる効果測定というところでしょうか（良い用語が思いつかないのであったら教えてください）。あんまり統計学とか分からないなとも思ってどうしたものかと。
→今回はツイートの取得が目的なので、そこまで厳密に考えないことにしました。

**・ワードの選択**
自然言語処理とか形態素分析とか、言語学の範囲の話になってくると思います。
→こちらも今回は触れないでいきます。

とりあえずコーディングしながら考えます。

# コード
```test_t_api.py
import tweepy
import pytz
import pandas as pd
import collections
import matplotlib.pyplot as plt

#twitterAPIに接続
consumer_key = ''
consumer_secret = ''
access_token = ''
access_token_secret = ''

auth = tweepy.OAuthHandler('',  '')
auth.set_access_token('','')

api = tweepy.API(auth)


#ツイートを検索する
#ワードは半角スペースで区切ると複数検索できる
tweets = tweepy.Cursor(api.search_tweets, q = '検索ワード',lang = 'ja').items(1000)

#検索から取得したデータを配列に入れる
tw_data = []

for tweet in tweets:
    tw_data.append([
        tweet.text
                       ])

#CSVファイルに出力するときの列の名前を定義
labels=[
    'ツイート本文'
    ]
#tw_dataのリストをpandasのDataFrameに変換
df = pd.DataFrame(tw_data,columns=labels)

#CSVファイルに出力する
#CSVファイルの名前を決める
file_name='tw_data_test.csv'

#CSVファイルを出力する
df.to_csv(file_name,encoding='utf-8-sig',index=False)
```

# 今回省いていること

### **・日付を指定したり、複雑な検索をしていない。**
TwitterAPIって有償アカウントじゃないと、できること結構限られますよね。

### **・ワード検索の「AND」「OR」など。**
多分できますが割愛させてください。

# ハマったところ

### **・Twitter社からAPI利用申請の許可がおりない**

はじめから駄目で草でした。英文で何通かやりとりしました。
（Google翻訳です。後日友人に「DeepL使いなよ…」と言われました。確かに。）
審査に時間がかかったとかではなく、私の利用目的が分からん！と言われていました。
最終的に **「貴社の規約に沿って使用することを誓うよ」** と強めに書いて、通りました。

### **・anacondaがローカルホスト側から切れる**

これなんでだろう？
権限周りとか確認していきたいですが、とりあえず今はおいておきます。
でもJupiterとか使うとグラフ出力できたりしますもんね。
この機会に再チャレンジしようかな。

### **・Python、久しぶり。**

書き方忘れてる。たくさん調べました。特に配列とか。

# 参考

https://norari-kurari-way.com/twitter_api_tweets_data/

--------
ツイートデータの取得自体は本当に初歩的なことなんだろうな、と思いつつ。
でも久しぶりの言語で、慣れないエディタで良いリハビリになりました。
Visual Studioも今後使うことがありそうなので精進します。

いろいろ省いていますが、Twitter社への申請・エディタのインストールから、CSV出力までトータルで７時間くらいでした。多分遅いんですが、使い慣れないツールでやってたのでこんなもんなんじゃないかな…と言い訳します。

プログラマとしての実務経験はあるものの、実際何をどうやってできるのか？を示すのは難しいですね。前の記事にも書きましたが、どの言語とかどのツールとかは、どうでも良くて、 **「『成果物から逆算してこれを実装するにはどのような要素が必要か？』など自分で調べること」** が大切なんじゃないかと考えています。

実務で開発に携われることって実は恵まれたことなんじゃないかと思います。現場は保守がほとんどじゃないかな、と。だから、どちらかというとコードリーディングとかgitの社内での使い方（上長にプルリクするとか）の方が大変だし、私は苦手だなあと思うので、gitもそうですが、チームワークにかかわるものを優先して学習していきたいと思います。

おしまい。
Fire TV Stick (第3世代)を買ったのでダイソーのBluetoothイヤホンをつなぐ(いろいろしたいので)


目的
イヤホンを繋ぎたい


1. 設定

2. コントロールとBluetoothデバイス

3. その他のBluetoothデバイス

4. EA9745

![o_con812.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/6c3bcc90-f99d-07e5-5dd1-980785a3c7ad.jpeg)


![o_con819.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/a7eae94a-1375-51c5-8cff-e9d56630fff0.jpeg)


![o_con820.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/4d9d2b49-69d8-d3ae-22c7-76502b556a5b.jpeg)


![o_con821.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/e9dd1639-6f35-ea06-ec3f-7db66e4809e7.jpeg)