OmniAICreator/Qiita-1.07M huggingface dataset:
[Ecto] one-to-many Associationについての注意点

ectoのassociationについて大変わかりやすく説明されている記事を参考にさせていただきながらone-to-many relationshipについて自分なりに内容をまとめてみました。

https://qiita.com/sand/items/5581497972473e308f05

以下、Userが親テーブル、Postが子テーブルです。

# スキーマ
User側

```:myApp/lib/myApp/context/user.ex
has_many :posts, MyApp.Post 
# postsは複数形にする慣例。これをつけることでEcto.build_assoc/3を使うときにPostの構造体が生成されるようになる
```
Post側

```:myApp/lib/myApp/context/post.ex
belongs_to :user, MyApp.User 
# クエリするときに第一引数に_idをつけた形でDBの該当テーブルからカラムを探すので、user_idとしてはいけない
```

# マイグレーション
User側

```:MyApp/priv/repo/migraions/xxxxxxxxxx_create_user.exs
# 何もしない
```
Post側

```:MyApp/priv/repo/migraions/xxxxxxxxxx_create_post.exs
add :user_id, references(:users, on_delete: :nothing)　
# UserID（キャメルケース）ではなく、必ずスネークケース
```

# 関連性の構築
```:大まかな手順
1. userの構造体を作る
2. userの実体を作る
3. postの構造体をEcto.build_assoc/3で手順2で作成したuserと一緒に作る
4. postの実態を作る
```
これで手順１で作成したuserのidを持ったpostを作成できる。
iexで行う。

```:iex
iex(1)> alias MyApp.{Repo, User, Post}
iex(2)> user = %User{name: "John Doe", email: "john.doe@example.com"}　<- idなし
iex(3)> user = Repo.insert!(user) <- id付与
iex(4)> post = Ecto.build_assoc(user, :posts, %{col1: "col1", col2: "col2"})
iex(5)> post = Repo.insert!(post) <- user_idが関連づけられる
```
＊ Repo.insertすることでidが付与されて構造体が実体化する
＊ Ecto.build_assoc/3を使うことでuserのidを読み込んだpostを作成できる
＊ (5)の段階でpostにidが付与され、postが実体となり、user_idに指定されていたuserとの関連性ができる

# 実践的なuser, post間のデータ参照
通常のクエリと違うのは関連するpostをプリロードするという点のみ。
iexでは以下のコードで確認できる

```:iex
iex(6)> user = Repo.get(User, user.id) |> Repo.preload(:posts)
```
アプリで使う場合は、

```elixir
# userと関連する全てのpost
user = Repo.all from u in User, preload: [:posts]
# structの中のデータを扱う場合の具体例
user.posts.name -> postの名前

# postと関連するuser
post = Repo.get(Post, id) |> Repo.preload(:user)
# structの中のデータを扱う場合の具体例
post.user.name -> userの名前
```
など。


参考文献

https://hexdocs.pm/ecto/Ecto.Query.html#preload/3
VSCode拡張機能「ToDo Tree」でコード修正のToDoコメントの修正漏れをなくそう！

# 対象読者
- VSCodeを使って開発をしている方
- コードを修正しながらもコメントでTODOを頻繁に書く方
    - TODOコメントをよく消し忘れる、修正漏れをする方

# はじめに

私は日頃の開発でVSCodeを使って開発しております。
コードを書きながら、全体が出来上がった後にリファクタリングしたい部分、
後ほど追加要件が見込まれる場合にはタスク管理ツール以外にもコード上でTODOを残します。
(リリース後に必要な修正など自分以外の人が後で対応必要なことも含めて)

ただ、たまにTODO修正が漏れたり、コメントを消し忘れてしまいレビューで指摘されることが多いです。

エディタの検索機能やgit grepなどでTODOをさらうことも可能ですが、
もっと手軽に確認できる方法はないかな〜と考えていました。

# VSCode Extension 「Todo Tree」

そんな時にVSCodeのExtesionのMarketPlaceで**「ToDo Tree」**を見つけました。
VSCodeのマーケットプレイスで `ToDo Tree` で検索してください。

ダウンロードして木のようなアイコンをクリックして開くだけで、開いてるファイル内の
TODOコメント、FIXMEコメントを表示してくれます。

![スクリーンショット 2021-10-12 17.13.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530688/4e905416-0540-84e8-0943-27d9e44252bc.png)

コメントをクリックすれば該当箇所までコードジャンプしてくれてハイライト表示されます。
一覧で見れるのが嬉しい。

![スクリーンショット 2021-10-12 17.14.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530688/f7c158ff-1210-f432-a0be-f8a4875b53da.png)


コード内の簡易TODOリストが作成されるので、漏れがなくなり、作業見立てもしやすくなりました。

設定で他のコメントをprefixとして拾うこともできるようなので、自分のコメントスタイルに合わせてカスタマイズして使えそうです。

地味な機能だけど最近のお気に入りです。

最後まで読んで頂きありがとうございました。
Xcode13 iOS15でアプリアイコンが表示されないバグについて

#はじめに
Xcode13・iOS15にアップデートしてから、アプリをXcodeでビルドしてインストールしてもアプリアイコンが反映されなかったので、一時的な方法ではありますが解決方法を残しておきたいと思います。
#解決方法
シュミレーターでビルドした場合はインストールしたアプリを一度削除(アプリのアイコンを長押で消せます)してからもう一度ビルドすると反映されます。
実機転送でビルドした場合は、アプリインストール後に端末を再起動すると反映されます。
その他のアプリアイコンの作成などはいつも通りに行っていただいて問題ないと思われます。

iPhoneのバージョンが最新ではない場合はiOS15.0.1からiOS15.0.2にアップデートしてからビルドすると通常通りアプリアイコンの反映がされました。
おそらくiOS15.0.1のバグだったと思われるので、アイコンの反映がされていない場合はまずバージョンが最新か確認をしてから行うと大丈夫そうです。
#最後に
簡単な解決方法でしたが、この方法に行き当たるまで３０分ほどしどろもどろしたので、同じ問題で悩んでいる方々のお役に立てると嬉しいです。
#参考サイト
[iOS 15 に対応する (Xcode 13.0)](https://zenn.dev/ariiyu/scraps/0e309cc095cd3f)
[Blank App Icon (physical device) - iOS 15 Xcode 13 betas](https://developer.apple.com/forums/thread/682648)
📕参考書籍
[SwiftUI対応 たった2日でマスターできるiPhoneアプリ開発集中講座 Xcode 12/iOS 14対応](https://www.amazon.co.jp/SwiftUI%E5%AF%BE%E5%BF%9C-%E3%81%9F%E3%81%A3%E3%81%9F2%E6%97%A5%E3%81%A7%E3%83%9E%E3%82%B9%E3%82%BF%E3%83%BC%E3%81%A7%E3%81%8D%E3%82%8BiPhone%E3%82%A2%E3%83%97%E3%83%AA%E9%96%8B%E7%99%BA%E9%9B%86%E4%B8%AD%E8%AC%9B%E5%BA%A7-Xcode-iOS-14%E5%AF%BE%E5%BF%9C-ebook/dp/B08VJJM3TN/ref=sr_1_2?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&dchild=1&keywords=swiftui&qid=1634030901&sr=8-2)
[Swift UI対応 たった2日でマスターできる iPhoneアプリ開発集中講座 Xcode13/iOS15/Swift 5.5対応](https://www.amazon.co.jp/dp/4802613415?tag=newbooksit-22)
ユーザビリティなフォームの作成②


## 前回の続き

https://qiita.com/tkht2401/items/87711716672b9b3c087e

から実装した方がわかりやすいかもしれません。
今回は、
####STEP1 フォームにフォーカスしたらボタンを表示
####STEP2 フォームに文字を入力したらボタンの色を変化させたいと思います。

#完成例

###入力前

![入力前.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1061608/408603f3-84da-6449-6510-9bd088d3be4b.png)

###STEP1　フォーカス後

![ユーザビリティ後.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1061608/f416dcc5-787a-41f2-d83b-24298858d831.png)


###STEP2　入力後

![ユーザビリティボタン.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1061608/9708a7c5-ada7-0d5b-348d-f507459c5e84.png)

このように、フォーカスしたらボタンを表示して、
入力されたらボタンの色をグレーから緑に変えたいと思います。

#STEP1

###ボタンの設定

 v-ifで条件分岐し、isEditing か titleExistsのどちらかがtrueの時だけボタンを表示します。

```vue
<button type="submit"
        class="add-button"
        v-if="isEditing || titleExists">
  Add
</button>
```

###CSSの設定

```css
.addable .add-button {
  background-color: #00d78f;
  pointer-events: auto;
  cursor: pointer;
}
```
#STEP2

```js
data: function() {
  return {
    title: '',
    isEditing: false,
  }
},
computed: {
  classList() {
    const classList = ['addlist']

    if (this.isEditing) {
      classList.push('active')
    }
    // ２. cssを追加し、動的にボタンの色を変える
    if (this.titleExists) {
      classList.push('addable')
    }
    return classList
  },
　// １. 文字が入力されたら、titleExistsがtrueになる
  titleExists() {
    return this.title.length > 0
  }
}
```
###動的に変わる流れ

①文字が入力されたら、titleExistsがtrueになる
②trueになったことでcomputedのif文を実行して、cssを追加して動的にボタンの色を変える

これで文字を入力したら、ボタンの色が動的に変わると思います！！
VM（VirtualBOX＋Vagrant）上でchalice localを動かす

業務でchaliceを扱うことになりそうなので、動かせる環境を作ってみました。

# バージョン

ソフト | バージョン
--|--
VirtualBOX | 6.1.222
Vagrant | 2.2.16

# VM構築

`Vagrantfile`に以下を指定してVM立ち上げ

```Vagrantfile
Vagrant.configure("2") do |config|
  config.vm.box = "centos/7"
  config.vm.network "private_network", ip: "192.168.33.10"
  config.vm.network :forwarded_port, guest: 8000, host: 8000
end
```

※`chalice local`のデフォルトポートが8000なので、ポートフォワーディングしておきます
　IP指定（192.168.33.10:8000）でアクセスできまが、これ追記しておくとlocalhost:8000でアクセスできるようになります

```bash
$ vagrant up
```


# VM内

### 準備

- python3.8のインストール
- chaliceのインストール
  - 参考：https://aws.github.io/chalice/quickstart.html

記事執筆時のバージョン

```bash
$ python3 --version
Python 3.8.11
$ chalice --version
chalice 1.26.0, python 3.8.11, linux 3.10.0-1160.42.2.el7.x86_64
```

### chaliceプロジェクトの作成

```bash
$ chalice new-project helloworld
$ cd helloworld
```

### chaliceプロジェクトのローカル起動

```bash
$ chalice local --host=0.0.0.0
Serving on http://0.0.0.0:8000
```

※`--host=0.0.0.0`を指定します


# ホスト（Windows）側からブラウザでアクセス

`http://localhost:8000`にアクセス


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325108/891672ad-0210-7f51-3e2a-7e520baba3a9.png)

こんな感じで値が返ってきました！


ちなみに、存在しないパスにアクセスすると403が返ってくるみたいです

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325108/ad8bf910-2ee3-3af6-7da6-4f5a93f15eb6.png)
Go+gRPCでシンプルなEchoサーバ(令和最新版)

# はじめに
GoのインストールからシンプルなEchoサービスをgRPCで実装するまでの手順。

# 各ツールのインストール

## Go
```
$ wget https://golang.org/dl/go1.17.linux-amd64.tar.gz
$ sudo tar xf go1.17.linux-amd64.tar.gz -C /usr/local
$ echo "GOPATH=${HOME}/go" >>.bashrc
$ echo "PATH=${PATH};/usr/local/go/bin" >>.bashrc
$ source .bashrc
```

## protoc
```
$ wget https://github.com/protocolbuffers/protobuf/releases/download/v3.18.1/protoc-3.18.1-linux-x86_64.zip
$ unzip -d ${HOME}/.local protoc-3.18.1-linux-x86_64.zip
$ echo "PATH=${PATH};${HOME}/.local/bin" >>.bashrc
$ source .bashrc
```

## Goライブラリ
```
$ go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.26
$ go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.1
$ go get -u google.golang.org/grpc
```

# Echoサービス実装

## プロジェクトの雛形作成
```
$ mkdir -p myproj
$ mkdir -p myproj/cmd/{client,server}
$ mkdir -p myproj/internal/grpc
$ export PROJ_ROOT=${HOME}/myproj
$ cd ${PROJ_ROOT}
$ go mod init 192.168.0.0/myproj
```

## .proto作成
```
$ cd ${PROJ_ROOT}
$ vi my.proto
```


```go
syntax = "proto3";

option go_package = "192.168.0.0/myproj/grpc";

service Echo {
    rpc Echo (EchoRequest) returns (EchoReply) {}
}

message EchoRequest {
    string body = 1;
}

message EchoReply {
    string body = 1;
}
```

## Goコード生成
```
$ protoc --go_out=./internal/grpc \
  --go_opt=paths=source_relative \
  --go-grpc_out=./internal/grpc \
  --go-grpc_opt=paths=source_relative,require_unimplemented_servers=false my.proto
```

## サーバ実装
```
$ cd ${PROJ_ROOT}/cmd/server
$ vi main.go
```

```go
package main

import (
    "context"
    "log"
    "net"

    "google.golang.org/grpc"

    mygrpc "192.168.0.0/myproj/internal/grpc"
)

type server struct {
}

func (s *server) Echo(ctx context.Context, p *mygrpc.EchoRequest) (*mygrpc.EchoReply, error) {
    log.Println("request received")
    res := mygrpc.EchoReply{
        Body: p.Body,
    }
    return &res, nil
}

func main() {
    lis, err := net.Listen("tcp", "127.0.0.1:9999")
    if err != nil {
        log.Fatalf("failed to listen: %v", err)
    }
    
    grpcServer := grpc.NewServer()
    
    mygrpc.RegisterEchoServer(grpcServer, &server{})
    
    if err := grpcServer.Serve(lis); err != nil {
        log.Fatalf("failed to serve: %v", err)
    }
}
```

## クライアント実装
```
$ cd ${PROJ_ROOT}/cmd/client
$ vi main.go
```

```go
package main

import (
    "context"
    "log"
    "time"

    "google.golang.org/grpc"

    mygrpc "192.168.0.0/myproj/internal/grpc"
)

func main() {
    conn, err := grpc.Dial("127.0.0.1:9999", grpc.WithInsecure())
    if err != nil {
        log.Fatalf("connection failed: %v", err)
    }
    defer conn.Close()

    client := mygrpc.NewEchoClient(conn)

    ctx, cancel := context.WithTimeout(context.Background(), time.Second)
    defer cancel()

    r, err := client.Echo(ctx, &mygrpc.EchoRequest{Body:"hello"})
    log.Println(r)

    log.Println("done")
}
```

# 動作確認
- サーバ起動

```
$ cd ${PROJ_ROOT}/cmd/server
$ go run main.go
```

- クライアント実行

```
$ cd ${PROJ_ROOT}/cmd/client
$ go run main.go
2021/10/12 18:06:47 body:"hello"
2021/10/12 18:06:47 done
```
バリデーションメモ

初めてユニークネスを使ったのでメモ

<h1>uniqueness</h1>
必ず一意であること。
など、同じ情報を保存しないようにする
例)メールアドレスや電話番号など

今回使った状況としては、Userは投稿を追加することができ、さらにその中で投稿に紐づく商品の情報を追加することができるようにしてるが同じ商品は追加できないようにしていた。
Postに関連する商品としていたのでPostProductモデルとする
モデルでバリデーションを仕込む

```
class PostProduct < ApplicationRecord
  belongs_to :user
  belongs_to :post

  validates :title, presence: true, uniqueness: true
  validates :image, presence: true, uniqueness: true
  validates :product_url, presence: true, uniqueness: true
end
```

今かけているバリデーションは、
titleは空にはできず、同じ値も認めないこと
imageは空にはできず、同じ値も認めないこと
product_urlは空にはできず、同じ値も認めないこと
みたいなことを書いています。
同じ処理を書いているのでまとめちゃいましょう！

```
class PostProduct < ApplicationRecord
  belongs_to :user
  belongs_to :post

  with_options presence: true, uniqueness: true do
    validates :title
    validates :image
    validates :product_url
  end
end
```

これでスッキリしましたね！
実際に動くかやってみたところ、ちゃんとユニークネスは動いてくれたのですがここで問題が。

このコードだと、emailや電話番号くらいにしか使えません。
これは早いもの勝ちみたいな感じであるuserがこのemailを使用したら他のuserは使えねーよ？みたいな処理なんです。
emailや電話番号では正直問題にはなりません。
ですが他の機能だとちょっとめんどくさくなります。

たとえばtwitterでは１つの投稿に対していろんなuserが「いいね」や「リツイート」をします。
もしそのときに最初の書き方では、投稿には1いいねしかつけられません。

そこでuniquenessでは"scope"を使うことで期待通りの動きをしてくれます。

```
class PostProduct < ApplicationRecord
  belongs_to :user
  belongs_to :post

  with_options presence: true, uniqueness: {scope: :post_id} do #ここを追加
    validates :title
    validates :image
    validates :product_url
  end
end
```

こう書くことで、post_idがn番の中では重複した情報を入れることができませんよ！となります。
つまりpost_idが1番と2番では同じ商品を追加することができるということになりました！
gulp-dart-sass で glob したい

LibSass から Dart Sass への移行はもうお済みですか？

LibSass のサポートは2022年10月1日で終了予定とのこと。

> One year after this deprecation goes into effect (1 October 2022 at latest), we will drop support for @import and most global functions entirely. This will involve a major version release for all implementations.

https://sass-lang.com/blog/the-module-system-is-launched#future-plans

というわけで、やっと重い腰を上げ、Dart Sass への移行を済ませました。

その際、パーシャルファイルの glob でハマったので、解決方法を投稿しておきます。

## ディレクトリ構造

glob の確認用のサンプルのディレクトリ構造は以下となります。

`/src/sass/layout/` フォルダ内のパーシャルファイルを glob を利用して読み込ませます。

```
project
├ node_modules
├ src
│ ├ css
│ │ ├ hoge
│ │ │ └ style.css
│ │ └ style.css
│ └ sass
│   ├ layout
│   │ ├ _header.scss
│   │ └ _footer.scss
│   ├ hoge
│   │ └ style.scss
│   └ style.scss
├ gulpfile.js
├ package-lock.json
└ package.json
```

## npm パッケージのインストール

gulp を利用した Sass のコンパイルに必要な以下パッケージをインストールします。

* [gulp](https://www.npmjs.com/package/gulp)
* [gulp-dart-sass](https://www.npmjs.com/package/gulp-dart-sass)
* [gulp-sass-glob-use-forward](https://www.npmjs.com/package/gulp-sass-glob-use-forward)

glob を利用するためには [gulp-sass-glob-use-forward](https://www.npmjs.com/package/gulp-sass-glob-use-forward) が必要となります。

```
npm i --D gulp gulp-dart-sass gulp-sass-glob-use-forward
```

## package.json

```json:package.json
{
  "name": "sass-compile",
  "version": "0.0.0",
  "devDependencies": {
    "gulp": "^4.0.2",
    "gulp-dart-sass": "^1.0.2",
    "gulp-sass-glob-use-forward": "^0.1.3"
  }
}
```

## gulpfile.js

```js:gulpfile.js
const gulp = require('gulp')
const gulpDartSass = require('gulp-dart-sass')
const sassGlob = require('gulp-sass-glob-use-forward')

const sass = () => {
  return gulp
    .src('src/sass/**/*.scss')
    .pipe(sassGlob())
    .pipe(gulpDartSass())
    .pipe(gulp.dest('src/css'))
}
exports.sass = sass
```

## 問題点

sass ディレクトリ直下からは読み込めましたが、
子階層からの読み込みができず空の css ファイルが出力されてしまいました。

```scss:/src/sass/style.scss
// 読み込めた
@use "layout/*";
```

```scss:/src/sass/hoge/style.scss
// 読み込めない
@use "../layout/*";
```

## 解決方法

gulp-dart-sass の `includePaths` オプションに sass のルートディレクトリを指定することで子階層からも読み込むことができました！

```diff_javascript:gulpfile.js
const gulp = require('gulp')
const gulpDartSass = require('gulp-dart-sass')
const sassGlob = require('gulp-sass-glob-use-forward')

const sass = () => {
  return gulp
    .src('src/sass/**/*.scss')
    .pipe(sassGlob())
-   .pipe(gulpDartSass())
+   .pipe(gulpDartSass(
+      includePaths: ['src/sass'],
+   ))
    .pipe(gulp.dest('src/css'))
}
exports.sass = sass
```

```scss:/src/sass/style.scss
@use "layout/*";
```

```diff_scss:/src/sass/hoge/style.scss
- @use "../layout/*";
+ @use "layout/*";
```
トラブル事案｜wordpressでFatal error: Cannot redeclare retrieve_password() が出た場合

# エラーケース
* wordpress本体の更新を実施したところ、上手く更新できなかったもよう
* エラー`Fatal error: Cannot redeclare retrieve_password() 〜省略〜 wp-includes/user.php`が表示された

# 解決策
* 手動で更新ファイルを再アップしたら解決しました

## もうちょっと詳細
* [ココ](https://ja.wordpress.org/download/)から最新のwordpressを入手

https://ja.wordpress.org/download/

* ダウンロードしたファイルを解凍
* FTPでwordpressをインストールしているサーバーへアクセス
* ダウンロードしたファイル群の中から`wp-admin`と`wp-includes`を丸々上書き
* 同様に、ダウンロードしたファイル群の中から`〜.php`ファイルを丸々上書き（新しいバージョンの WordPress の root ディレクトリにある残りのファイルのこと）
* この際に `wp-content` `wp-config.php` は上書きしないこと！（通常、ダウンロードしたwordpressの中には`wp-config.php`は入っていません）
* あと`.htaccess` `.htpasswd` も上書きしないこと！（通常、ダウンロードしたwordpressの中には`.htaccess` `.htpasswd`は入っていません）
* 上書きできない場合は（上書きの際にエラーが出た場合は）、サーバー側のパーミッションを確認してみる（※ただし、元のパーミッションをメモしておくこと。更新後に戻せるように）

* 上書きが終わったら、ログイン画面にアクセスしてみる

* 参考サイト：[WordPress ファイルの置き換え](https://ja.wordpress.org/support/article/updating-wordpress/#%e3%82%b9%e3%83%86%e3%83%83%e3%83%971-wordpress-%e3%83%95%e3%82%a1%e3%82%a4%e3%83%ab%e3%81%ae%e7%bd%ae%e3%81%8d%e6%8f%9b%e3%81%88)

https://ja.wordpress.org/support/article/updating-wordpress/
Dockerを使ってGolangでHello,World!（超初心者向け）

Dockerでgolangを動かしてみます。
Dockerを触ったことがない人でもわかるように意識して書きました。


#事前準備
・Dockerのインストールが済んでいること
・Vimの基本的な操作（編集、保存、閉じる）ができること

#本題

下記のコマンドを実行します。
 docker run -it --name="任意の名前" -p 8080:80 golang:1.15 bash

_**コマンドオプションの意味**_
`-i`　：ホストの入力をコンテナの標準出力をつなげる
`-t`　：コンテナの標準出力とホストの出力をつなげる
>`-i,-t`オプションを付けないとコンテナの中で入力できない
`-i`オプションと合わせて`-it`と記述可能

`--name="　"`　：コンテナ名に任意の名前を付ける　#付けなくても動きます
`-p 8080:80`　：ポートマッピング
>　書き方：`-p [ホスト側のポート番号]:[コンテナのポート番号]`
　`-p 8080:80`で localhost:8080 への接続が、コンテナ内のポート 80 へ送られます。



`golang:1.15`　：構築するイメージを指定
`bash`　：コンテナ内で Bash シェルを起動


````:ローカルマシン
 ❯❯❯ docker run -it --name="first_app" -p 8080:80 golang:1.15 bash
````

dockerコンテナの中にはいる

````:Docker
＃Vimを使いたいのでupdate実行
root@51c29f39210b:/go# apt update
Get:1 http://deb.debian.org/debian buster InRelease [122 kB]
Get:2 http://security.debian.org/debian-security buster/updates InRelease [65.4 kB]
...

#Vimをインストール
root@51c29f39210b:/go#  apt install vim
Reading package lists... Done
...

#Vimでmain.goファイルを作成
root@51c29f39210b:/go# vim main.go

````

main.goファイル内に下記のような簡単なコードを書いてみる

````go:main.go
package main

import "fmt"

func main() {
    fmt.Println("Hello, World!")
}
````

Vimを閉じてmain.goを実行する。

````:Docker
root@51c29f39210b:/go# go run main.go
Hello, World!

````

Hello, World!を表示することができました。

#おまけ　
##Dockerから出てもう一度接続する
###Dockerから出る
````:Docker
root@51c29f39210b:/go# exit
````

###接続する
````:ローカルマシン
#コンテナの状態を確認する
❯❯❯ docker ps -a                                                                                                                                    
CONTAINER ID   IMAGE         COMMAND                  CREATED             STATUS                           PORTS                      NAMES
51c29f39210b   golang:1.15   "bash"                   About an hour ago   Exited (127) 3 seconds ago                                  first_app

#コンテナを起動する　docker start <CONTAINER IDまたはNAME>
❯❯❯ docker start 51c29f39210b

#コンテナに接続するdocker attach <CONTAINER IDまたはNAME>
❯❯❯ docker attach 51c29f39210b
````

>`docker exec <CONTAINER IDまたはNAME>`コマンドでも接続できる。
`attach`で接続した場合、exitコマンドで抜けるとコンテナが停止しますが、`exec`で接続した場合、exitコマンドで抜けるてもコンテナが停止しないという違いがあります。
詳しくは[こちら][exec]の記事に記載してあります。
[exec]:https://qiita.com/leomaro7/items/649732faf2f632419f11
GoogleSpreadSheetで買い物リストを作ってみた

わたしは食品を買い出しをする際に「買い物リスト」を作ります。今までは物理的なメモ用紙にリストを書いていたのですが、最近はGoogleのSpreadSheetを使うようになりました。スマホ片手にカートを押して買いものをするわけです。

何度かSheetで買い物リストを作成すると、いちいち文字を打つのがめんどくさくなってきました。そこで、チェックボックスをクリックするだけでよいように買い物リストを作るようにしました。

すると、再利用するときに以前のチェックを外さなければいけなくなって、めんどくさく思えました。そこで一気に以前のチェックを外す機能をつけてとりあえず満足のいくようなものになりました。

![list_sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127424/313761c5-818e-86a1-64e2-a67894b1950d.png)

作成した際に気づいた点などを忘れないうちにまとめておきます

## 全体像
SpreadSheetのデータをまとめて変更する機能は、GAS/Google App Scriptという言語を使ったスクリプトを作成する必要があるようです。GASはすごく多機能で、SpreadSheetにとどまらず様々なGoogleサービスと連携できるようです。

GASはJavaScriptとすごく良く似た言語仕様を持ちます。私は今でも言語仕様の詳細を知りませんが、JavaScriptだと思えば大体エラーはでません。ビルトインされた各種オブジェクトを呼び出すことで、Googleサービスのデータを操作することができます。例えば現在のシートのセルA5に`hello world`と書き込む関数は以下のような感じです:

```js
function sample () {
  var r = SpreadsheetApp.getActiveSheet().getRange("A5");
  r.setValue("hello world");
}
```

Googleサービスにアクセスするための `SpreadsheetApp` などのオブジェクトの一覧は、[Googleのリファレンス](https://developers.google.com/apps-script/reference) を参考にすればよいのですが、量が多いので適当にググったサンプルコードから始めるのがいいのかもしれません。[Googleのチュートリアル的なサンプルスクリプト](https://developers.google.com/apps-script/articles/tutorials) もまた、いきなり読み始めてもそこそこ理解ができます。

さて、GASで定義した関数をSpreadSheetから呼び出すわけですが、スマホアプリではできる機能とできない機能があるようです。例えば、「カスタマイズしたメニューを作成してそこをクリックさせることで関数呼び出しをする」のはブラウザ上からは可能ですが、アプリからは不可能のようです。

そこで、私は「トリガによって関数呼び出しをする」という方法を選びました。前述のスクリーンショットで赤く色づけされたチェックボックスをクリックした時に関数呼び出しをするようにするわけです。トリガに関するリファレンスは、[Simple Triggers](https://developers.google.com/apps-script/guides/triggers)に記載がありました。編集時にトリガされる関数 `onEdit`トリガは、引数としてイベントオブジェクトeを伴い、その `e.range` という属性によってどこが変更されたのかがわかります。なので以下のように関数定義をすることで、**セルB1のチェックボックスがクリックされたらclearing()を呼び出す**ことを実現できます:

```js
function onEdit(e) {
  var r = e.range;
  if (r.getA1Notation() != "B1"){
    return;
  }
  clearing();
}
```

clearingの実装はまあ、かなりナイーブに作りましたが私の用途ではこれで十分です:

```js
function clearing () {
  var dr = SpreadsheetApp.getActiveSheet().getDataRange();
  var d = dr.getValues();
  for (var i = 0; i < d.length; i++) {
    for (var j = 0; j < d[i].length; j++) {
      if (d[i][j] === true) {
        d[i][j] = false;
      }
    }
  }
  dr.setValues(d);
}
```

以上二つの関数 `onEdit, clearing` を実装することで、「特定の箇所のチェックボックスをクリックしたらシート全体のデータを修正する」ことができました。

## その他補記

- スクリプトエディタは結構便利でした。構文チェックや補完、デバッグ実行ができるのでWebブラウザ上での開発でも特に苦痛は感じませんでした
- リファレンスのページのHTTPレスポンスが遅すぎてかなりイライラしました
- スマホアプリとWebブラウザでの挙動の違いについて言及したGoogleのドキュメントは見つかりませんでした。適当にググったページで言及していたものの受け売りなので間違ってるかもしれません
- clearing() 実装のなかでトリガ対象であるB1を修正しているので再帰的にトリガが発火するのでは？と思いましたが、スクリプト経由による編集ではトリガは発火しないという仕様があるので大丈夫なようです。
何故俺のプロキシの環境変数の設定は反映されないんだ

# 何故俺のプロキシの環境変数の設定は反映されないんだ
### 理由
sudoをしたら君の環境変数の設定は通常引き継ぎません。


### 対処法
```bash
sudo -E hogehoge 
```

# そんなファイルないぞと怒られる

### 理由
rootの相対パスになってしまっているから。
~/hogehoge.conf
とか読めない

### 対処法
絶対パスで書く？？
ABC188 C - ABC Tournament を解いた

https://atcoder.jp/contests/abc188/tasks/abc188_c

![abc188_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/40230403-1b0f-9b3f-2810-511d0221538e.png)
![abc188_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/c9ea5a31-a57c-6324-950a-85397fdce24c.png)
![abc188_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/c0d76e23-610b-cf82-89a1-10ba21793c91.png)
![abc188_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/5b50d98e-5608-378f-5b93-0f215d218d3b.png)

文章の通りやってみた。

```abc188c.py
N = int(input())
A = list(map(int, input().split()))

dic = {}
for i in range(2**N):
    dic[A[i]] = i+1

lis = A[:]
if N == 1:
    print(dic[min(lis)])
    exit()
while True:
    nums = []
    for i in range(0,len(lis)-1, 2):
        nums.append(max(lis[i], lis[i+1]))
    lis = nums
    if len(lis) == 2:
        break

print(dic[min(lis)])
```

上記で通ると確証があったわけではない、計算量が不明だったから。。。
今回は数えてみた。
計算用に以下のコードを用意。

```cal_On.py
N = 2**16  #入力最大値
score = 0  #計算量カウント

for _ in range(1,2**16+1):
    score += N//2#for 文では2 飛ばしてカウントするので計算量は N//2
    N//=2        #N を 1/2 倍に更新
print(score)

#result
#score = 65535
```

O(65535) だったら計算量としては余裕。
だから問題ないわけだ、納得。
"FindPangolin.cmake" Ga Naiyo!!

# Mondai

```
By not providing "FindPangolin.cmake" in CMAKE_MODULE_PATH this project has asked CMake to find a package configuration file provided by "Pangolin", but CMake did not find one.
```

# Kaiketu
CMakeList.txt(in ORB_SLAM3)

``` 
set (Pangolin_DIR YOUR_Pangolin_PATH/Pangolin/build/src) 
```

# Saigoni
RasPi Nihongo Kakenai Yo!!
【初心者向け】VirtualBoxのインストール

## はじめに
これからLinuxの勉強を始めるという方がの役に立てたらうれしいです。
まずはLinux環境をローカルPCに仮想環境として動作環境を整備します。
仮想化ソフトウェアで代表されるOracle VM VirtualBoxのインストールを行います。
Windows、Linux、MacOSなどのコンピュータ上で仮想マシンを作成し、動作させることが可能な仮想化ソフトです。
インストール自体はGUIで行えるため、簡単にインストールまでを整理します。


## 前提条件
今回は下記条件のPC環境に対してインストール作業を実施します。

+ OS：Windows 10
+ CPU：intel CORE i7
+ メモリ：15.7GB

## インストールをはじめる
実際にインストール作業を進めてみましょう。
### [Step1] VirtualBoxのサイトにアクセス
下記URLへアクセスし左ナビの「Downloads」からダウンロード画面へ遷移します。
　URL→　[Oracle VM Virtualbox](https://www.virtualbox.org/)
![01.キャプチャ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2109986/efb88829-32d1-f4d6-a82a-b0a79c6ccf6d.png)

### [Step2] VirtualBoxのダウンロード
ダウンロード画面から最新版のVirtualboxを入手します。

今回の場合は「VirtualBox 6.1.26 platform packages」が最新の用ですので、その中からWindows向けの「Windows hosts」を選択します。

ダウンロードができるので、インストーラ（exeファイル）をデスクトップなどの適当な箇所へ保存します。
![02.キャプチャ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2109986/aa62204b-ec2b-c7b4-51ea-f0f5f1a7a322.png)

### [Step3] VirtualBoxのインストール
[Step2]で保存したインストーラ（exeファイル）をダブルクリックで実行し、VirtualBoxをインストールしていきます。

①Setup Wizard
　「Next >」で次へ進みます。

②Custom Setup
　1．インストールする内容のカスタマイズや、インストールフォルダの変更が可能です。
　　今回は初期設定のまま、「Next >」で次へ進みます。

　2．Intall Optionの設定を行います。
　　各チェックボックスをONにすると、対象の箇所にショートカットが作成されます。
　　□ Create start menu entries
　　　→ スタートメニューへショートカットを作成
　　□ Create a shortcut on the desktop
　　　→ デスクトップにショートカットを作成
　　□ Create a shortcut in the Quick Launch Bar
　　　→ クイックランチバーにショートカットを作成
　　□ Register file associtions
　　　→ 「.vbox」などの下層ファイルの関連付けを登録

　「Next >」で次へ進みます。

　3．「Install」でインストールを開始します。
　　※途中に一次的にネットワーク接続が切断される可能性があるという警告が出た場合、「Yes」で次へ進みます。

　4．インストール完了画面が表示されたら「Finish」を押下してインストール完了です。
　　完了画面にある「Start Oracle VM VirtualBox X.X.X after installation」をONにしておくとインストーラ終了時にVirtualBoxが起動します。

##　おわりに
VirtualBoxのインストール作業はここまでとなります。
小技シリーズ第4弾 100%積み上げ棒グラフ

このシリーズでは、Yellowfinのレポートやダッシュボードをより魅力的なものに作成するための小技集を紹介したいと思います。第4回は100%積み上げ棒グラフの作成手順を紹介します。

食料品販売会社の売上情報を使って下のような積み上げ棒グラフを作成します。支店ごとに、売上の構成をカテゴリ別に表示するグラフです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128512/7216006c-b8c5-f2e6-bb4e-980ede0da44a.png)

なお、以下の手順で使用したデータはCSV形式で[こちら](https://github.com/ChasingHH/ShareFiles/blob/Share/SalesAmount.csv)に共有しています。同じデータを使って手順を試したい場合は、CSVファイルの中身をDBにインポートし([CSVデータのインポート](https://wiki.yellowfin.co.jp/pages/viewpage.action?pageId=2294195))、Yellowfinでビューを作成してください([ビューの作成](https://wiki.yellowfin.co.jp/pages/viewpage.action?pageId=2294093))。
では、早速作成していきましょう。

新規でレポートを作成し、ビューを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128512/8075c071-6ef4-7a9e-4271-d4ce5b048119.png)&nbsp;&nbsp;&nbsp;&nbsp;![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128512/375ae1d0-139c-760f-b008-c8a87f17a453.png)

カラム(行)とロウ(行)に以下の項目を配置して、クロス集計表を作成します。
&nbsp;&nbsp;&nbsp;&nbsp;・カラム： カテゴリ、売上
&nbsp;&nbsp;&nbsp;&nbsp;・ロウ： 支店名
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128512/83f29dbf-7bc3-572c-a8e9-6e85fc2c0c2c.png)
デフォルト集約が設定されていない場合、ここで集約手段に合計(Sum)を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128512/1686853a-6efc-38d1-4288-cc9f8b1a9fee.png)
集計値 [Sum売上] のドロップダウンリストから [高度な関数] を開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128512/8b9430f7-8b64-3242-2552-23962e14c252.png)
関数の選択で [分析]、一覧から [合計値に対する百分率(%)] を選択した後、[保存] ボタンを押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128512/4bd89d63-d0f9-ba6b-5d1a-7d85bd04afd2.png)
[カラム(列)の書式] 編集画面から、[売り上げの合計値に対する百分率(%)] の書式を以下のように編集します。
&nbsp;&nbsp;&nbsp;&nbsp;・小数点以下桁数：1
&nbsp;&nbsp;&nbsp;&nbsp;・接尾辞：%
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128512/463c669f-0683-da97-ae4f-5a47255f35a1.png)

グラフ作成のステップに推移し、グラフの種類に [積み上げ縦棒] を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128512/3e194d40-353d-712b-7f2c-4f1cb8d35290.png)

以下の通りに軸と集計値を配置します。
&nbsp;&nbsp;&nbsp;&nbsp;・横軸：支店名
&nbsp;&nbsp;&nbsp;&nbsp;・縦軸：売り上げの合計値に対する百分率(%)
&nbsp;&nbsp;&nbsp;&nbsp;・色：カテゴリ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128512/b91552e2-1ad3-5af0-8934-8186f42d0834.png)

[グラフの軸] > [縦軸] > [目盛] から以下を設定します。
&nbsp;&nbsp;&nbsp;&nbsp;・下限範囲：0
&nbsp;&nbsp;&nbsp;&nbsp;・上限範囲：100
&nbsp;&nbsp;&nbsp;&nbsp;・目盛単位：50
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128512/6348ebe8-8623-bfb5-5736-ffee248e1a89.png)


支店ごとに、売上の構成をカテゴリ別に表示するグラフが作成できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128512/68c4393d-dec6-cf9c-2c30-2ea850654829.png)

あとは、任意の名前でレポートを公開します。

様々な場面での用途が考えられる積み上げ棒グラフです。是非、作成方法を覚えておいてください。
See you then! Cheers!!
【SQL】2つのテーブルの重複したレコードを結合し、それぞれ独立したカラムのテーブルを作成

```SQL
    SELECT 
      F1.apple,COALESCE(F2.apple,F1.apple) as great_apple
    FROM Fruits_table F1
    left join Fruits_table F2 on F1.Fruits_id = F2.Fruits_id and F2.Fruits_rank = 1
    where  F1.Fruits_rank = 0
    ORDER BY F1.Fruits_id

```
Rider 2021.3 EAP3 でファイル保存時のコード整形が標準機能になったらしい

## 概要
Rider 2021.3 EAP3 からファイル保存時にコード整形を行う設定が追加されました。
従来はマクロを使用して `⌘S` のショートカットを上書きするなどしてファイル保存時のコード整形を行なっていましたが、今回のアップデートで簡単に設定できるようになったようです。

## 設定方法
`File | Settings | Tools | Actions on Save` で `Reformat and Cleanup Code` を有効にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60752/afe2855c-3388-9112-22c4-5e05fa9c258b.png)
【MySQL】取得したデータが空文字またはNULLだった場合に代わりの文字列に変換したい

# やりたいこと

SELECT文でデータを取得した際に、そのデータが空文字、もしくはNULLだった場合に代わりの文字列を出したい。

# NULLのデータの変換は簡単

NULLの場合はifnull関数を使えば簡単に変換できる。

```sql
-- nameがNULLだった場合に'名無しさん'に変換
select ifnull(name, '名無しさん') from users;
```

このようにifnull関数を使うと、取得したデータがNULLだった場合に第2引数に変換される。

【参考記事】

https://www.dbonline.jp/sqlite/function/index23.html

しかし、今回は空文字とNULLを両方変換したいので、ifnullを使って実現するのは難しい。

# case式を使って条件分岐

case式で空文字とNULLの場合に別の文字列に変換する。

```sql
-- nameがNULL、もしくは空文字だった場合は'名無しさん'に変換
-- それ以外の場合はそのままnameを取得
select 
	case 
		when name is null or name = '' then '名無しさん' 
        else name 
	end as name 
from users;
```

```sql:１行で書く
select case when name is null or name = '' then '名無しさん' else name end as name from users;
```

これで本題の目的どおりに取得できる。

【参考記事】

https://www.sejuku.net/blog/82743

case式を使う場合、次の点に気を付ける。(というか僕がひっかかった点)

- name = nullでは変換できないため、name **is** nullとする。
- endのあとに**asでカラム名を設定する。**(設定しないと「case when name is null or name = '' then '名無しさん' else name end」がカラム名になる)

# まとめ

case式はすごく便利。
SPRESENSE で Sigfox 通信

# SPRESENSE
SPRESENSE は、SONY さんが提供している IoT用途のマイコンボードです。
[SPRESENSE公式ページ](https://www.sony-semicon.co.jp/products/smart-sensing/spresense/)

Main ボードのサイズは、Raspberry Pi PICO とほぼ同じ大きさです。

# Sigfox モジュール
結論から言うと、Arduino Uno 用の Sigfox モジュールを使って Sigfox の通信が可能です。

## UnaShield の使用
マイコンボードから Sigfox 通信を試す方法としては、UnaBiz社が提供している、Sigfox UnaShield を使った情報がたくさんあります。
KCCSさんのこちらのブログが一番取り掛かりやすいと思います。[KCCS - Sigfox Shield for Arduino - UnaShield -](https://www.kccs-iot.jp/20191212-technical/)

# Extension Board
最初、SPRESENSE と Una Shield を UART で通信させれば、とりあえずの動作確認は可能かなと思っていたのですが、SPRESENSE の I/O 電圧が 1.8V で、Una Shield は、Arduino Uno 用に作られているため I/O 電圧が5Vですので、レベルシフト（電圧変換）が必要になります。
そうなると、一気にめんどくさいなぁと思ったのですが、別売りの Extension ボードを取り付けると、サイズもI/O電圧も Arduino Uno 相当になります。
![w_extention.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/716263/9853fd13-bf89-c2c0-1324-503be4013e90.png)

# Sigfox 通信
Extension Board を使用すると、後は、通常の Arduino での Sigfox 通信と同じになりますので、前述の KCCS さんのブログで紹介されている サンプルコードを使用すれば、そのまま通信可能です。

Qiita にも、SPRESENSE を Arduino 互換で動かす記事がたくさんあるので参考にしてください。

- [Spresenseで遊んでみる（その１）](https://qiita.com/ryo_naka/items/6e36aeae6a0e720ea912)
- [Sony SPRESENSEを使ってみよう(1) Arduino編](https://qiita.com/usashirou/items/42782444dcbc27dc71c4)

# GPS/GNSS
Arduino Uno で Sigfox + GPS をやろうとすると、別途 GPS モジュールを購入し、UART で NMEA を取得することになるのですが、SPRESENSE の場合、GPS/GNSS がメインボード上にあるため、SPRESENSE + UnaShield だけでも、Sigfox 位置ロガーになります。

SPRESENSE の GPS/GNSS については、Github にサンプルがあります。
[SPRESENSE Arduino Sample GNSS](https://github.com/sonydevworld/spresense-arduino-compatible/blob/master/Arduino15/packages/SPRESENSE/hardware/spresense/1.0.0/libraries/GNSS/examples/gnss_tracker/gnss_tracker.ino)

ちなみに、オフィス内で試した限りでは、位置情報が FIX するまでかなり時間がかかる・もしくは FIX しないという事がありました。
ただし、車のダッシュボード上に置いた場合では、時間がかかりますが（3～4分）、問題無く動作し、一度 FIX した後は継続的に制度の高い位置情報が取れていました。

今回は、メインボード上のオンボードのアンテナのみ使用しました。外部アンテナを利用することも可能なため、こちらを使用すれば使えるようになるかもしれません。知らんけど。


# その他
## Una Shield の 加速度センサー
Una Shield には、「Adafruit MMA8451」の加速度センサーが搭載されていて、Arduino Uno では I2C で通信できていたのですが、SPRESENSE では、そのままでは動作せず、I2C のスキャンをしても何も見つからない状態でした。これは、追々調べることにします。
VSのマクロが動かなくなった時の対応


##やりたいこと
VSのマクロを実行したい
もう何回もはまってるのでorz

##やり方

####編集するファイル
C:\Program Files (x86)\Common Files\Microsoft Shared\VSA\9.0\VsaEnv\vsmsvr10.exe.config

####編集内容

```config
<runtime>
　～デフォルトの内容は触らない～
  <AllowDComReflection enabled="true"/> ★これを追加
</runtime>
```
OOFの予測値でConfident Learning (cleanlab) を使おう！

# はじめに

Confident Learningという手法を使うことで、分類タスクにおける、データセットの中の間違ったラベル(noisy label)のサンプルを検出することができる。[詳しい解説](https://aotamasaki.hatenablog.com/entry/confident_learning)が既にあり、Confident Learningを実行するライブラリに[cleanlab](https://github.com/cleanlab/cleanlab)というのものあるので、ここでは機械学習で後付でcleanlabを使う小技の紹介をする。

## cleanlab

cleanlabはConfident Learningを実行できるライブラリで、scikit-learn like APIのモデルクラスをラップして使うことができる。

```python
from sklearn.base import BaseEstimator

class YourFavoriteModel(BaseEstimator): # Inherits sklearn base classifier
    def __init__(self, ):
        pass
    def fit(self, X, y, sample_weight=None):
        pass
    def predict(self, X):
        pass
    def predict_proba(self, X):
        pass
    def score(self, X, y, sample_weight=None):
        pass

# Now you can use your model with `cleanlab`. Here's one example:
from cleanlab.classification import LearningWithNoisyLabels

lnl = LearningWithNoisyLabels(clf=YourFavoriteModel())
lnl.fit(train_data, train_labels_with_errors)
```

ただ、これをPyTorchで実装するのはメンドクサイ。。。[こちら](https://github.com/cleanlab/cleanlab/blob/master/cleanlab/models/mnist_pytorch.py)にサンプルコードがあるが、既に学習を回している人が後からサンプルのようにcleanlab用に書き換えるのはツライ。

しかし！ cross validationをしている方ならOOF(Out Of Fold)でtrainデータの予測値（正確には各ラベルの確率）を出力していると思われる。このOOFの値`y_oof`さえあれば、cleanlabのデータクリーニング部分は実行できるので、小技として紹介しよう。


train data に対するラベルのOOF予測確率`y_oof`は得られているとする。まず次のクラスを作る。

```python
from sklearn.base import BaseEstimator

class CleanModel(BaseEstimator): # Inherits sklearn base classifier
    def __init__(self):
        pass
    def fit(self, X, y, sample_weight = None):
        pass
    def predict(self, X):
        pass
    def predict_proba(self, X):
        pass
    def score(self, X, y, sample_weight = None):
        pass
```

上で作ったクラスをラップして、`fit`を実行する。

```python
# 確率に規格化できてない場合は規格化する
psx = softmax(y_oof, axis=1)

# モデルをラップする
clf = LearningWithNoisyLabels(
    clf=CleanModel(),
    prune_method='prune_by_class' # ここは自由に選ぶ
)
clf.fit(
    X=np.arange(len(train_df)),  # データのid
    s=train_df[y].values,  # クラスラベルの ndarray, shape (n_samples, )
    psx=psx,
    noise_matrix=None,
    inverse_noise_matrix=None,
)
```

`noise_mask`変数にノイズラベルと推測されるサンプルのインデックスが格納されています。

```python
cleaned_train_df = train_df.iloc[~clf.noise_mask]
```

あとはこの新しいデータで再学習を実行すればOKです。再学習は自身の既存コードで実行すればよいです。
HTMLのラジオボタンをいい感じに自作する。

#経緯
偉い人「CSSで調整できるラジオボタンが欲しい」
蝦「はい」
#作るもの
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425022/fbd2d749-73a9-464e-1b48-e0926664738a.png)
#HTML
```radio.html
<!DOCTYPE html>
<html lang="ja">
  <body>
    <h1>CSSでスタイルを設定できるラジオボタン</h1>
    <div>
      <label class="radio-label" for="radio-1"
        ><input
          type="radio"
          name="choice-1"
          class="radio-none-dsplay"
          id="radio-1"
        /><span class="dummy-radio"
          ><span class="dummy-radio-check"></span></span
        >選択肢1</label
      >
      <label class="radio-label" for="radio-2">
        <input
          type="radio"
          name="choice-1"
          class="radio-none-dsplay"
          id="radio-2"
        /><span class="dummy-radio"
          ><span class="dummy-radio-check"></span></span
        >選択肢2</label
      >
      <label class="radio-label" for="radio-3">
        <input
          type="radio"
          name="choice-1"
          class="radio-none-dsplay"
          id="radio-3"
        /><span class="dummy-radio"
          ><span class="dummy-radio-check"></span></span
        >選択肢3</label
      >
    </div>
  </body>
</html>
```
以下、重要な点
##labelのクリックでinputを選択できるようにする。
input要素のid属性とlabel要素のfor属性を同じにすると、label要素とinput要素を関連付けできる。この場合はlabelをクリックするとinput要素を選択できるようになる。

MDN曰く
> label要素 を input要素に関連付けるには、 input要素に id 属性を設定しなければなりません。そして label要素 に for 属性を設定して、値を input要素 の id と同じにします。
> 他の方法として、 input を直接 label の内側に入れることができますが、この場合は関連付けが明確なので、 for および id 属性は> > 必要ありません。

単に関連付けするだけならどちらかでいい。

##ダミーのラジオボタンを作るためのspan要素を作る。
input要素の直後に配置してセレクタで選べるようにする。input要素が外にある場合でもセレクタが変わるだけで同じ。


#CSS
```style.css
/* HTMLでラジオボタン部分を自作するため隠す。 */
.radio-none-dsplay {
  display: none;
}

/* ラベル本体 */
.radio-label {
  /* 縦に並べてなおかつ中の要素をきれいに中央に配置する */
  display: flex;
  vertical-align: middle;
  align-items: center;
}

/* 代わりに表示するラジオボタン部分 */
.dummy-radio {
  display: inline-block;
  margin-right: 5px;
  height: 18px;
  width: 18px;
  border: solid 1px black;
  position: relative;
  vertical-align: middle;
}

/* ラジオボタンの中に表示するチェック部分 */
/* 非選択時は非表示 */
.dummy-radio-check {
  display: none;
}

/* チェック部分のCSS */
/* 選択時のみチェックを表示する。 */
.radio-none-dsplay:checked + .dummy-radio > .dummy-radio-check {
  bottom: 3px;
  left: 3px;
  display: block;
  position: absolute;
  height: 18px;
  width: 10px;
  border-bottom: solid 5px black;
  border-right: solid 5px black;
  transform: rotate(30deg);
}
```
以下、重要な点
##疑似クラスセレクター
クラスや要素の後ろに:hogeの形で書くあれ。今回はinput要素が選択されているかどうかの判別に使う。

```style.css
.radio-none-dsplay:checked{/*ここにスタイル*/}
```

##結合子
今回は+(隣接兄弟結合子)と>(子結合子)を使う
input選択時のみチェック部分を表示したいので
「選択されたinput.radio-none-dsplayの直後（隣接兄弟結合子）にある.dummy-radioの中の(子結合子).dummy-radio-check」
というセレクターを書けばOK

```style.css
.radio-none-dsplay:checked+ .dummy-radio > .dummy-radio-check {/*ここにスタイル*/}
```

#おわり
なんかあったらコメントください
【Python】 開始終了、pipインストールメモ


####バージョン確認  

```bat:バージョン確認  
python --version
```
こんなのが出てくる（バージョンによって変わる）

```bat:結果
Microsoft Windows [Version 10.0.19042.1237]
(c) Microsoft Corporation. All rights reserved.

C:\XXXX\XXXX>python --version
Python 3.8.10

C:\XXXX\XXXX>python --version
Python 3.8.1>

```


####pipからのインストール

```bat:pipからのインストール
py -m -3.9 pip install BeautifulSoup
py -m pip install BeautifulSoup
```

####pipのアップグレード

```bat:pipのアップグレード
py -m pip install --upgrade pip
```

####開始   

```bat:
python
```

####コマンド終了 
```python:コマンド終了 
>>>exit()
>>>quit()
```
Sequel AceをDockerのMySQLにクイック接続する方法

# 目的

- Sequel AceをDockerのMySQLに接続する方法をまとめる

# ご注意

- Sequel Aceの導入方法は説明しない。

# 方法

1. ダウンロード後にSequel Aceを起動すると下記のような画面が開く。

    ![Sequel_Ace.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/532877cd-064c-30d4-85b3-b89cd5df9639.png)

1. 下記の内容を入力する。

    | 項目 | 情報 |
    | --- | --- |
    | Name | 任意の内容を入力 |
    | Host | ホスト名 |
    | Username | MySQLのユーザー名 |
    | Password | MySQLのユーザー名に紐づくパスワード |
    | Database | 接続する先のDBの名前 |
    | Port | DBの接続ポート |
    | Time Zone | Use Server Time Zoneを選択 |

1. MySQLで接続ポート番号が`4306`の場合下記の様になる。

    | 項目 | 情報 |
    | --- | --- |
    | Name | 任意の内容を入力 |
    | Host | 127.0.0.1 |
    | Username | MySQLのユーザー名 |
    | Password | MySQLのユーザー名に紐づくパスワード |
    | Database | 接続する先のDBの名前 |
    | Port | 4306 |
    | Time Zone | Use Server Time Zoneを選択 |

1. 入力すると下記のようになる。

    ![Sequel_Ace.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/61174a46-79f4-a9c4-9989-923f73999d7e.png)

1. 「Test connection」をクリックする。

    ![Sequel_Ace.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/c324ef1e-3a2a-7406-4d6a-b1e308604a2c.png)

1. 「接続が成功しました」と表示されていることを確認する。

    ![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3330363431372f61653764346466352d636237312d356139332d343061392d6334663263326565656539392e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/d1baf5ee-9f8a-fc6e-609e-4ae7513af35a.png)

1. 「接続」をクリックする。
1. 接続に成功し当該DBのテーブルがサイドバーに表示されている。

    ![111.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/0a3e156e-eb4b-69b7-6577-790812d83354.png)
自然言語処理ＡＰＩ

簡単な自然言語処理のＡＰＩを考えている。

構成としては二つある。

１）類義語ＡＰＩ
　これはテキスト分析の入り口の部分で、単語の類義語をインデックスに置き換えて、機械学習のベクトル次元を削減する前処理用のＡＰＩ

　入力　→　単語
　出力　→　インデックス

　現在のところは意味ベースで曖昧性の高い日本語を、英単語に置き換えることでインデックス化させる

２）機械学習用ＡＰＩ
　これはユーザーベースでトークンを入れてコールすることで、機械学習を自動処理させるもの
　イメージ的にはAUTO　MLのように、教師データを流すごとに成長していくもの
　今のところはインデックスのベクトルを与えて、ラベルを返すものを想定している。

# 活用事例

 ユースケースから仕様を決めるというのも、なんとなく変な話であるが、このＡＰＩを使って何が出来るのかを考える。

１）スパムメール削除
　メール本文から頻出単語のインデックスベクトルを作り、このメールが削除対象かどうかを判断して、フォルダに移動させる。
　利用形態はOUTLOOKにVBAマクロで仕込む

２）ブックマーク整理
　お気に入りフォルダのファイル名から、キーワードごとに仕分けして整理する
　親子関係を学習し、フォルダが自動的に階層構造になるようなもの
　コマンドラインから実行する


#関連情報

　これから着手していく

https://github.com/mcleavey/identify_author/blob/master/Identify%20the%20Author.ipynb

https://qiita.com/jw-automation/items/0fc9c1b9764233975ab9
PHPなしでお問い合わせフォーム作成

先日自分のポートフォリオを業務委託先に渡す前に作り直そうと思いました。
しかし、PHPでお問い合わせフォームを実装するのがめんどくさい、、。
PHPファイルにして、MAMP起動して、、って、
今のPFにしてから一時期googleフォームを埋め込むスタイルにしてたのですが、コーダー、エンジニアのPFにするにはダメかしら、、と。

そして調べてみるとhtmlだけでも実装できる方法が。

##Simple HTML from your websiteを使ってみる

https://www.staticforms.xyz/

[Simple HTML form for your website](https://www.staticforms.xyz/)
必要なのは上記のサイトのCreate Access Keyでアクセスキーを取得して、フォームに入れ込むだけです。
![スクリーンショット 2021-10-12 15.27.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139887/dafd0f91-ba3a-141a-b44e-4d8160efc5c4.png)

チートです。むしろgoogle formよりチートかもしれない。
見た目だけでも、、って人ならひとまずこの方法でもいいんじゃ無いか、、と思います。（でも一度はphpで作ってみた方が良いとは思いますが）

```
<form action="https://api.staticforms.xyz/submit" method="post">
        <input type="text" name="name" placeholder="Your Name">
        <input type="text" name="email" placeholder="Your Email" />
        <textarea name="message"></textarea>
        <input type="hidden" name="accessKey" value="取得したアクセスキー">
        <input type="hidden" name="redirectTo" value="リダイレクトしたい画面のurl">
        <input type="submit" value="Submit" />
</form>
```
気をつけなければいけないのが、
リダイレクト先を相対パスで書いてしまうと上手くいきません。
https~から書いてあげましょう。

リダイレクト先は私は別でファイルを用意しました。
同じフォルダの中にsuccess.htmlを作り、リダイレクト先のvalueに入れます。
同じホームに戻ってきてJSでアラートなり表示させても良いかと思います。
cssはよしなに書いてみてください。

![form.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139887/fd705b97-3fe2-8be8-0482-82a54e5ff9bf.png)

ご参考までに、、
index.html

```
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="style.css" />
    <title>Document</title>
  </head>
  <body>
    <h1>お問合せ</h1>
    <form action="https://api.staticforms.xyz/submit" method="post">
      <input type="text" name="name" placeholder="Your Name" />
      <input type="text" name="email" placeholder="Your Email" />
      <textarea name="message"></textarea>
      <input type="hidden" name="accessKey" value="取得したアクセスキー" />
      <input
        type="hidden"
        name="redirectTo"
        value="リダイレクトしたい画面のurl"
      />
      <input type="submit" value="Submit" />
    </form>
  </body>
</html>
```

style.css

```
h1 {
  text-align: center;
}
form {
  display: flex;
  flex-direction: column;
  width: 300px;
  margin: 0 auto;
}

input,
textarea {
  margin-top: 10px;
}
```

success.html

```
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>送信完了</title>
  </head>
  <body>
    <p>送信が完了しました</p>
    <button class="back__btn">
      <a href="ホームのurl">戻る</a>
    </button>
  </body>
</html>
```

時間がないんだ〜！って時は試してみてください。
ReactNativeで開発してた時にFCMの設定でつまずいた(Androidのみ)

## 1、FCM（Firebase Cloud Messaging）とは
Firebaseが提供しているアプリにプッシュ通知を送る機能です。
機能自体無料で使えて、アプリ側ではfirebaseから取得したfcmトークンをfcmに設定するだけでプッシュ通知を受け取れるためかなり便利です。
本格的なアプリを作るとなるとプッシュ通知は必要不可欠です。
https://firebase.google.com/docs/cloud-messaging?hl=ja

## ２、FCMの簡単な仕組み・設定方法
https://firebase.google.com/?hl=ja
↑Firebaseでプロジェクトを作成し、左のメニュー欄からCloud Messagingを選択します
開始方法からiOS、Android両方の設定をします。
iOSの方はAPNs認証キーの設定も必要なため、Apple Developerの登録も必要です。
今回はAndroidのみですのでそこは割愛します。
　
https://rnfirebase.io/messaging/usage
次にアプリ側でFCMトークンを取得し、そのFCMごとに識別して通知が送られてきます。

## 本題
プロジェクトでFCMを使うことになり、アプリの管理画面から通知文を作成し、APIからFCMにリクエストを出してFCMを経由してアプリに通知が届くような仕様でした。

今回FCMの実装をしている時ににつまずいたことは
・FCMの画面から直接トークンを指定して、送った場合→通知が届き、タップするとアプリが起動する
・アプリの管理画面から通知を送信し、APIからリクエストを出してFCMを経由して送った場合→通知は届くがタップしてもアプリが起動しない
という件でした。
なぜか管理画面から送る通知はタップしても起動することなく、そのまま通知メッセージが消えるだけでした。

## 原因
FCMから直接送った通知のデータと管理画面でAPIを使って送った通知のデータを見比べてみたところ原因が判明しました。

FCMから返ってくるデータを取得するには`setBackgroundMessageHandler`を使います。
アプリがバックグラウンドにある状態もしくはキルしている状態の時、プッシュ通知が送られてきた時にFCMからのレスポンスを取得することができます。
以下のコードをindex.jsに追記するとremoteMessageにデータが入っています。

```javascript
import messaging from '@react-native-firebase/messaging';

messaging().setBackgroundMessageHandler(async remoteMessage => {
  console.log('Message handled in the background!', remoteMessage);
});
```
ちなみにフォアグラウンド状態でも通知のデータを受け取れますが今回は割愛します。

### データを比べてみる
１、firebaseでタイトルとテキストを入力、fcm通知を選んで送信

```
{
　"notification": {
　"android": {},
　"body": "通知本文",
　"title": "通知タイトル"
　},
　"from": number,
　"ttl":number,
　"sentTime": 1633065375430,
　"data": {},
   "messageId": "${messageId}",
    "collapseKey": "バンドルID"
}
```
２、管理画面（API）から通知を送信

```
{
　"notification": {
　"android": {
　　"clickAction": "attention"
　},
　"body": "通知本文"
},
　"sentTime": 1633065600374,
　"data": {},
　"from": "501097458848",
　"messageId": "${messageId}",
　"ttl": 2419200,
　"collapseKey": "バンドルID"
}
```
管理画面から送った方にはandroidオブジェクト内にclickActionが入っています。
これが原因でした。

https://firebase.google.com/docs/cloud-messaging/http-server-ref?hl=ja
ここのclick_actionのところに記載されているとおり、
`ユーザーが通知をクリックしたときに実行されるアクション。
これが指定されている場合、ユーザーが通知をクリックすると、一致するインテント フィルタを持つアクティビティが起動します。`

clickActionを指定するとfcmトークンに紐ずくアプリを起動するのではなく、一致するインテントフィルタ（アプリで別途設定する値）に紐ずくアプリを起動させる挙動になります。
今回このインテントフィルタを設定していなかったので一致するインテントフィルタがなく、アプリが起動しませんでした。

ちなみにこのclickActionの使い道ですが、
例えば
１、LINEアプリからプロフィール欄のBGMを設定しませんか？と通知がくる
２、ユーザーがタップするとLINEアプリではなく、LINE MUSICアプリが起動し、すぐ設定が行える

こんな挙動をしたい時は便利かもしれません。
ただ別のアプリを起動させる必要もないため、今回はclickActionは削除する方針にしました。

####clickActionを削除すると問題なくアプリが起動しました！

# 補足
アプリ起動後、通知があるページ（お知らせ画面）に遷移させたいときは
１、アプリがバックグラウンド状態の時：`onNotificationOpenedApp`
２、アプリを閉じている状態の時：`getInitialNotification`
この二つを初期マウント時（useEffect）に走らせればデータを取得できます。
そのデータから通知のidを受け取りそれに紐ずく画面に遷移すれば意図した挙動になるかと思います。
なぜ誤差は正規分布になるのか

# はじめに
センサー系のデータ分析でしばしば値が正規分布することを仮定して外れ値検知を行ったりする。しかし、なぜ値が正規分布するのかについて理解している人は少ない。なんとなく自然界ってそういうのものだと思っていそうである。そこで、誤差がなぜ正規分布になるのか解説したい。

## 解説
と思ったが、[解説](https://www.jstage.jst.go.jp/article/bunkou1951/24/1/24_1_39/_article/-char/ja)があったので、紹介に留める。


森村 正直, 飯塚 幸三, 分光データ処理のための数学的手法, 分光研究, 1975, 24 巻, 1 号, p. 39-54, 公開日 2010/06/28, Online ISSN 1884-6785, Print ISSN 0038-7002, https://doi.org/10.5111/bunkou.24.39, https://www.jstage.jst.go.jp/article/bunkou1951/24/1/24_1_39/_article/-char/ja

こちらの3章,4章を参照してください。
DevOps+git+ssh 環境の作り方

DevOpsをssh接続でgitクローンする方法を毎回忘れるので、その備忘録。

環境
・windows10
（gitクライアントソフトはsourcetreeを使った）

## sshkeyの作り方
SourceTreeからターミナルを起動する。（任意のディレクトリで構わない）

```Bash
$ ssh-keygen -t rsa -C "(登録のメールアドレス)"
```

ターミナルは起動したままにする。

下は次回試してみる。

```Bash
$ ssh-keygen -t rsa -C "(登録のメールアドレス)" -f (任意のrsaファイル名)
```

## DevOpsでKey登録
DevOpsで「_usersSettings/keys」ページから、NewKeyボタンで作成したrsa.pubの中身をコピーする。
（改行コードを含まない様にする）

## ssh-add でrsaファイルを登録する
起動したままのターミナルから下記コマンドを実行する。

```Bash
$ eval `ssh-agent`
Agent pid 716　　#成功

$ ssh-add C:\\Users\\(LoginUser)\\.ssh\\id_rsa
Enter passphrase for C:\Users\(LoginUser)\.ssh\id_rsa:
Identity added: C:\Users\(LoginUser)\.ssh\id_rsa (メールアドレスが表示)　　#成功
```

## git clone してみる
```Bash
Permission denied, please try again.
```
上記が出たら、どこかが失敗している。
（作り直した方が早い）
英語圏


英語に関する情報や技術サイトをまとめる。

# 英語の方が有利な根拠
https://qiita.com/AlohaTech/items/f3e12a95c5f0dc757664

https://qiita.com/sukebeeeeei/items/76ce249ed264b8acc5f8

# 具体的なサイト
https://qiita.com/monsoonTropicalBird/items/a5a89cc689a81e6ba71e

# AI
https://www.coursera.org/learn/machine-learning
スタンフォード大学の先生であり、courseraを立ち上げたAndrew Ng氏による動画講座。

# Massive open online course(MOOCs)

https://ja.coursera.org/

https://qiita.com/satomshr/items/986c4b77f04080f901df

https://karino2.livejournal.com/246001.html

# エンジニア向け英語学習
https://enneer.com/
Java Silver アウトプット5

前回の続きです

https://qiita.com/0W5E8fPq1EOm4yE/items/6598894dd762f96d734c

chapter5のクラス定義とオブジェクトの生成・使用のアウトプットをします。練習問題を解きましたが中々処理の流れを把握できず難しいところでした。

・デフォルトコンストラクタは明示的なコンストラクタ定義がない場合のみ追加される(例:{Test(String s){}})

・宣言時に初期化しなくてもコンストラクタを用いて初期化するのは可

・引数の型と順番が同じだとオーバーロードされない

・オーバーロードは1つのクラスに同じ名前のメソッドを複数定義すること

・Stringの配列をString型で受け取れない

・メンバ間のアクセスルールは下記の通り

●クラス内で定義したインスタンスメンバ同士、staticメンバ同士は直接アクセスできる

●クラス内で定義したインスタンスメンバは、クラス内で定義したstaticメンバに直接アクセスできる

●クラス内で定義したstaticメンバは、クラス内で定義したインスタンスメンバに直接アクセスできない。インスタンスしてからアクセスする

●staticメソッドは「クラス名.メソッド名」という呼び出しは可

・ガべレージコレクタはプログラムが使用しなくなったメモリ領域を検出し解放すること

・ガべレージコレクタの対象は下記の通り

Nama e1 = new Nama();
Nama e2 =e1;
e1=null;
e2=null;

下記の例は対象外
Nama e1 = new Nama();
Nama e2 =e1;
e1=null;
e1は参照されなくなったがe2が参照されているので対象外

・カプセル化の目的は外部から属性への直接的なアクセスを阻止すること、インスタンス化されても値を変更することなく使用できるようにすること

・インスタンス変数はprivateを指定、メソッドはpublic

・アクセス修飾子はprotected修飾子とprivate修飾子はクラス宣言時には使用できないまた、ローカル変数には使用できない
MVCについてとブラウザからのリクエスト→サーバーへのレスポンスまでの流れ

##MVCについて
webでは、ブラウザ(Safari,Chomeなど)とサーバーの間で
ブラウザ→サーバへのリクエストと、それに対しての
サーバー→ブラウザへのレスポンスのやりとりが行われています。

その内部ではMVCが大きな役割を果たしています。

###MVCとは
ソフトウェアの設計モデルの一つで、機能をモデル・ビュー・コントローラーの３つの役割に分けて実装するという方法のことです。

実際に図で理解するのが一番わかりやすいと感じたのでぜひこちらを参考にしてみてください。

https://qiita.com/s_emoto/items/975cc38a3e0de462966a

###モデル・ビュー・コントローラーとは？
ではモデル・ビュー・コントローラーとはどのような役割を果たすものなのでしょうか？
それぞれの役割について説明します。

####モデル
コントローラーとデータベースとのやりとりを介している。ビジネスロジックの実装に関わっています。

####ビュー
DBから取得したデータなどを元にHTMLを作成する。ブラウザへの反映に大きく関与する。
####コントローラー
モデルの内容についての指揮をおこうなう。この中に実行したいアクションの内容が含まれている。
また、コントローラーの部分が肥大化してしまう傾向がある

##ブラウザからのリクエストからサーバーへのレスポンスまでの流れ
では実際にブラウザからリクエスト→サーバーへのレスポンス、その情報がブラウザに表示されるまでの流れについて説明して行きたいと思います。
①URIとしてリクエストを送る
例えばAmazonのログインを行いたいとします
その場合、
②初期処理
ここではLaravelやRailsなどのフレームワークで必要な機能の読み込みが行われます。

③URLからのルーティング
リクエストされたURIの情報をもとにルーティングを行います。
ルーティングとはどのコントローラからどのアクションを実行すればいいの？を判断すること。
このURIの中にはポート番号や、プロトコル（ネットワークの規約のようなもの）、ドメイン名の情報が含まれています。

④コントローラとモデル、データベースのやりとり
コントローラーには様々なアクションがあり、ルーティングにより特定のアクションが呼び出されます。コントローラーは呼び出されたアクションを元にモデルを介してデータベースとのやりとりを行います。具体的にはデータの保存や取得を行なったりします。

⑤ビューに取得したデータを渡す
コントローラーは取得したデータをビューに渡し、そのデータを元にビューはHTMLの生成を行います

⑥コントローラーに作成したHTMLの情報を渡す
ビューはコントローラーに作成したHTMLの情報を渡します。

⑦HTMLの情報をブラウザに返す
コントローラーはそのHTMLの情報をブラウザに返します。

⑧ブラウザに表示


このようにしてリクエストされたURIのデータはブラウザに表示されます。

##MVC以外のアーキテクチャについて
### Pythonのフレームワークの一つであるDjangoを使用したMVTモデルについて