OmniAICreator/Qiita-1.07M huggingface dataset:
real-time-Personal-estimation（カテゴリ外の画像を推定させない為にはどうしたらいいか）※失敗です.

## 前回までの記事
前回は,yolov5をローカルマシンを使ってGPU利用の学習を行った.
https://qiita.com/asmg07/items/0abad3e16886cb60ecef
ここでテストとして,epochs 1000で学習をさせ結果は以下のようになった.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567360/384b0903-ce33-bbc9-fe12-b83516bc5cba.png)
このモデルをもとにテストをしてみた結果以下のように全くうまく学習できていないことが判明する.
カテゴリ外の画像
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567360/d9392774-6777-f26e-07b3-a71506aef45d.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567360/3e5689b3-9ce3-9d31-c38a-934f2c725ace.png)
カテゴリ内の画像
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567360/83b1245a-54c8-a7af-c1a6-c8a87c94c051.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567360/7703ab87-7a48-8f11-4e5a-dbb70f53dcc1.png)
この結果からわかる問題点はカテゴリ外の画像を推定させない為には,どうしたらいいかを考える必要がある.
## 今回の記事の概要
とりあえず学習させる画像を約100枚から数百枚もしくは数千枚に増やしたらどうなるのかを実際にやってみたいと思う.
## アノテーション
画像収拾については前記事で示しているので今回は割愛する.当該記事を下記に示す.
記事内search.py　https://qiita.com/asmg07/items/8502fe59b65f92d1e379
アノテーションについては Vottを使っている.
画像データは
・斎藤飛鳥 350枚
・与田祐希 350枚
でいこうと考えている.
なお,search.pyで吸い上げた画像から使えそうな画像だけを残してそこからアノテーション
を行うからここをまず根気よくやる必要がある.
## 学習について
epochs50回
![results.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567360/39c524d0-c32d-9f09-c7e7-050dc4f538e6.png)

epochs100回
![results.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567360/1702331f-c7fd-751f-3779-46bbf394fa56.png)
## 結論
yoloを使った乃木坂認識自体は失敗に終わった.
理由としては,人という認識においては優れているけど,人個人を認識するのは難しい.
理由はまだわかってません.
ってことでyoloを使った開発は続けていきますが,乃木坂認識プロジェクトはとりあえず保留です.
ありがとうございました.
GKEのMaster/NodeのUpgrade方法とリリースチャネル周りの整理

#はじめに
GKEのMaster/NodeのUpgrade方法とリリースチャネル周りの整理してみます。

#まとめると以下の様なイメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78184/760a91b2-4ae2-015f-07f4-a36f8ba54e64.png)


基本的に、MasterとNodeどちらも自動/手動Upgradeできます。
ただし、Masterは自動Upgradeを無効化できません。Nodeは、自動Upgradeを無効化できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78184/0d708dea-7dc5-e1b0-a566-ddc77cc120f0.png)

#リリースチャネル
https://cloud.google.com/kubernetes-engine/docs/concepts/release-channels

リリースチャネルは、自動Upgradeする際のUpgrade対象のバージョンを3つのタイプを指定することが可能です。3つのタイプは、 Rapid、Regular、Stable チャンネルが指定可能です。

チャネルで指定したUpgradeサイクルを定義する対象は、MasterとNodeになります。
リリースチャネルを使うと、ノードの自動アップグレードは無効にできません。
リリースチャネルで指定した、Upgradeが実施される前に手動でUpgradeすることはできます。
Windows10にVSCodeインストール

何番煎じだと言われそうですが個人的備忘録として。
また資料まとめの練習を兼ねてQiitaに投稿していきます。

今回はWindows10環境にVSCodeをインストールしていきます。
様々な開発環境構築の手順を今後Qiitaにまとめる為にもVSCodeインストールだけ書いたページを用意しておきます

## 環境

|項目|バージョン|
|:---:|:---:|
|OS|Windows 10 Home Edition x64 [10.0.18363.1082]|
|Visual Studio Code|1.50.0（[https://visualstudio.microsoft.com/ja/downloads/](https://visualstudio.microsoft.com/ja/downloads/)）|

※取り敢えず構築当時の最新。

## 1. Visual Studio Codeをインストールする

Visual Studio Code(以後、長いのでVSCode)をインストールしていきます。
上記表にある通り、[ダウンロードページ](https://visualstudio.microsoft.com/ja/downloads/)からインストーラをダウンロードします。

「Visual Studio 2019」<font color="Red">**ではなく**</font>下の青いアイコンの方から
「Visual Studio Code」→「無料ダウンロード」→「Windows x64 ユーザーインストーラー」を選びましょう。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/782968/091d3a7b-d6e6-a798-4b79-091bf66d895c.png)

クリックするとインストーラ「VSCodeSetup-x64-*.exe」がダウンロードされます。（\*部分はバージョン。その時の最新でOK）
ダウンロードしたインストーラを実行しましょう。

「使用許諾に同意」→「追加タスクの選択」→「インストール内容の確認」の順で進んでいきます。
![2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/782968/56ff62f6-0759-28df-4b4b-13d074dc1d19.png)
追加タスクでは"その他"の項目４つは**全てにチェックを入れて**おきましょう。
（個人的に右クリックのコンテキストメニューに出てきた方が楽なので）
![3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/782968/7ba1248d-c625-6792-d0a8-b07ca17e2c2d.png)
![4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/782968/89c45ac4-46c9-f44a-739d-5035bbf7822e.png)

これでVSCodeをインストールすることができました。
試しにVSCodeを起動してみてツールバーの[Help]→[About]を選択し、バージョンを確認しましょう
![5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/782968/f6c79f45-2429-cdec-ff59-7e8110dce8cc.png)

細かなバージョンは違っていても問題ありません。
あとはデスクトップにショートカットを作ったり、タスクバーに固定したりは個人のお好みで。

では今回はここまで。
Pythonで二分探索

二分探索のコードは以下です。

```python 
def binary_search(src, target_value):
    result = False
    lower_index = 0
    higher_index = len(src)-1
    while True:
        dst = src[lower_index:higher_index+1]
        medium_index = (lower_index + higher_index) // 2

        if src[medium_index] == target_value:
            result = True
            break

        if (higher_index - lower_index) == 1:
            break

        if target_value >= dst[medium_index]:
            lower_index = medium_index
        else:
            higher_index = medium_index
    return result


def main():
    src = [1, 2, 3, 4, 5, 6]  # すでにソート済み
    target_value = 4

    if binary_search(src, target_value):
        print('Found!')
    else:
        print('Not Found')


if __name__ == '__main__':
    main()
```

実行結果は以下になります。

```console
Found!
```


最後まで読んでいただきありがとうございました。
またお会いしましょう。
[Fortran] H行W列からなる文字列をいい感じに受け取る [AtCoder]

# はじめに

AtCoderの問題では、縦$H$行、横$W$列からなるマス目の状態を文字列で与えられます。これを受け取るプログラムをワンライナーで書こうとしましたが僕の力では出来ませんでした。

## 入力の仕様(例)

整数$W$,$H$と、$H$個の長さ$W$の文字列$S_i　(1 \le i \le H)$が与えられます。$S_i$の$j$文字目の文字は上から$i$行目、左から$j$列目を表しています。


```
W H
S_1
S_2
:
S_h
```

入力例
---
```
5 3
abcde
fghij
klmno
```

## 自然な実装

まずは自然な受け取り方を考えます。**入力の仕様**から考えても、「長さ$W$の文字列要素を$H$個持つ配列」を用意すれば良さそうです。

```fortran
program main
    use,intrinsic :: iso_fortran_env
    implicit none
    integer(int32):: w,h,i
    character(:),allocatable:: s(:)

    read*, w,h
    allocate(character(w):: s(h))
    read*, (s(i), i=1,h)

end program main
```

出来ました。これで十分な気がします。readしてる行の`(..., i=1,h)`というのはimplied doと言うやつです。`[(i, i=1,10)]`で、要素が`1 2 3 4 5 6 7 8 9 10`の配列を返します。Pythonの内包表記のような感じです。

欠点
---
$i$行$j$列目の要素にアクセスするときにちょっと面倒です。

```fortran
    print*, s(i)(j:j) ! i行j列目の文字を表示
```

あと行と列でデータの持ち方が違う(文字列と文字配列)というのも気持ちが悪いですし、Row-majorなのも腹が立ちます。

## いい感じにデータをもたせる
```fortran
program main
    use,intrinsic :: iso_fortran_env
    implicit none
    integer(int32):: w,h,i
    character(1),allocatable:: s(:,:)
    character(:),allocatable:: lines(:)

    read*, w,h
    allocate(character(w):: lines(h))
    allocate(s(w,h))
    read*, (lines(i), i=1,h)
    s(:,:) = reshape([(transfer(lines(i),s(:,i)), i=1,h)], [w,h])
end program main
```

このように受け取るといい感じです。先程のデータの持ち方は`lines`にやらせており、implied doとtransferとreshapeを使った前衛的なコードによって、1文字を2次元の配列で持つ`s`にわたしています。

$i$行$j$列目の要素にアクセスするときはこのように書けます。

```fortran
    print*, s(j,i) ! i行j列目の文字を表示
``` 
Column-majorでいい感じです。

欠点
---
先程より複雑になってしまいました。いっそのことライブラリにしてしまうのはどうでしょうか。

```fortran
function read_grid(w,h) result(s)
    integer(int32),intent(in):: w,h
    character(1):: s(w,h)
    character(w):: lines(h)
    integer(int32):: i

        read*, (lines(i), i=1,h)
        s = reshape([(transfer(lines(i),s(:,i)), i=1,h)], [w,h])
end function
```
allocateしなくて良い分やや楽

使い方
---

```fortran
program main
    use,intrinsic :: iso_fortran_env
    implicit none
    integer(int32):: w,h
    character(1),allocatable:: s(:,:)

    read*, w,h
    s = read_grid(w,h)
end program main
```

なかなか便利なライブラリじゃないでしょうか。

# まとめ

いい感じの受け取り方を紹介+ライブラリ化をしました
[GoLand]コメントの先頭にスペースを設定する﻿

# 1.はじめに
ググっても解決策(GoLandの公式ヘルプ)がなかなかヒットしなかったので書きました。
個人的にはGoLandを別のPCにインストールしたときという、たまにの機会に忘れていて結構困るためです。

## 1-1.この記事を読んだらどうなるのか
フォーマット時にコメントの先頭にスペースが自動的に入るようになって、楽になれる。

## 1-2.対象読者
GoLandでコメントの先頭にスペースを自動でいれられずに苦しんでいる人。

#  2.GoLandの設定
[こちら](https://pleiades.io/help/go/reformat-and-rearrange-code.html#configure-leading-spaces-in-comments)が公式のヘルプ
公式を引用させてもらいます。

> 1.設定ウィンドウ（ファイル | 設定）を開きます。
> 2.エディター | コード・スタイル | Goをクリックします。
> 3.その他タブをクリックします。
> 4.コメントに先行スペースを追加するチェックボックスを選択します。
> 5.コメントのスペースを除いてフィールドで、追加アイコン（the Add button）をクリックします。
> 6.例外として追加する接頭辞の名前を入力します（たとえば、easyjson）。
> 7.OKをクリックします。
![code_style_add_leading_space_to_comments.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309702/ce892ce3-9b1b-54f9-9a62-94b1e3654d80.png)

これでフォーマット時にコメントの先頭に空行が入るようになります。


# 参考
[公式ヘルプ](https://pleiades.io/help/go/reformat-and-rearrange-code.html#configure-leading-spaces-in-comments)
Laravelルーティングから起動まで

【概要】
----------------------------------------
<b>1.プロジェクトの作成</b>

<b>2.ルーティング</b>

<b>3.起動方法</b>


1.プロジェクトの作成
----------------------------------------


```terminal
$ composer create-project laravel/laravel 名前 --prefer-dist
```
名前に作成したいファイル名を記載するとその名前でファイルが生成されます。任意のファイルの中にで作成してください。
<br>
2.ルーティング
----------------------------------------

```php:routes/web.php
<?php
Route::get('/' , function(){
   return view('****');
});
```
１.で作成した際にテンプレートで上記は記載されています。'/'はhttp://localhost:8000/へアクセスするようになっており、"welcom"はviews/welcome.blade.phpのプログラムが反映されます。3.で起動した際にLaravelが出てきます。

公式ではなく直にちゃんとルーティングが反映されているかを確認する方法としてweb.phpに直接viewを反映する方法があります。

```php:routes/web.php
Route::get('hoge' , function(){
  return '<html><body>HOGE<p>HELLO,HOGE
          </body></html>';
```
上記のようにコーディングすると、
http://localhost:8000/HOGEにアクセスした際に、
”HOGE”と”HELLO,HOGE”が記載されているページを表示できます。
<br>

3.起動方法
----------------------------------------

```terminal
$ php artisan serve
```
これで起動ができます。
phpの場合は何も設定していなければ、"localhost:8000"でブラウザに表示できます。
<br>
Ruby on Rails ログイン機能のバリデーション設定

####Userモデルのname,emailカラムにバリデーションを設定

Railsガイドなどを参考にしています。
https://railsguides.jp/active_record_validations.html

【やりたいこと】
・名前やメールアドレスは空欄で登録できないようにする
・名前とメールアドレスの文字数制限

ポイントは
①"presence: true"→空欄での登録を禁止する
②"length: { maximum:  }" → ":"の後ろに設定した数字以上の長さを禁止する

app/models/user.rb ファイルでの作業になります。
作成したのは下記のコード。

```Ruby
class User < ApplicationRecord
  validates :name,  presence: true, length: { maximum: 20 }
  validates :email, presence: true, length: { maximum: 300 },
end
```
うまくいっているか、Rails consoleで確認してみる。まずは空欄で登録しようとすると。。。

```
> User.create(name: "", email: "")
   (0.3ms)  BEGIN
   (0.4ms)  ROLLBACK
 => #<User id: nil, name: "", email: "", created_at: nil, updated_at: nil>
```
ROLLBACKして登録されていません。

そして長い名前やメールアドレスを登録しようとしてみると、これもROLLBACKしていることが分かります（email欄の...となっている部分はあまりに長いので記事での表示を省略しています）。

```
> user = User.create(name: "a"*25 , email: "b"*３5０ + "@test.com")
>  (0.3ms)  BEGIN
>  (0.4ms)  ROLLBACK
=> #<User:
     id: nil,
     name: "aaaaaaaaaaaaaaaaaaaaaaaaa",
     email:"aaaaaaaaaaaaaaaaaaaaaaaaa...@test.com",
     created_at: nil,
     updated_at: nil>
```
エラーの理由を表示すると。。。

```
> user.errors.messages
> {:name=>["is too long (maximum is 20 characters)"],
 :email=>["is too long (maximum is 300 characters)"]}
```
"length: { maximum: }"がちゃんと機能していることが確認できました。

ちなみにmaximumとなっている部分は、いろいろ応用して使えるようです。
（下記Railsガイドより）

```
class Person < ApplicationRecord
  validates :name, length: { minimum: 2 }
  validates :bio, length: { maximum: 500 }
  validates :password, length: { in: 6..20 }
  validates :registration_number, length: { is: 6 }
end

:minimum: 属性はこの値より小さな値を取れません。
:maximum: 属性はこの値より大きな値を取れません。
:inまたは:within: 属性の長さは、与えられた区間以内でなければなりません。このオプションの値は範囲でなければなりません。
:is: 属性の長さは与えられた値と等しくなければなりません。
```
certbot(LetsEncrypt)でエラー/Invalid response from

# エラー症状

LetsEncryptの証明書更新でエラーが発生。

エラー内容を確認すると認証用ページにリクエストとしても応答がないと。
動作しているWebアプリケーションには動的にページを追加することはできないので失敗して当然。

```bash
Domain: mydomain.com
Type:   unauthorized
Detail: Invalid response from
http://mydomain.com/.well-known/acme-challenge/rwH-dBrZhXrgii7uiGmccp8GFMOdv1RRRHrBSVfkWuU
[2606:2800:220:1:248:1893:25c8:1946]: "...

To fix these errors, please make sure that your domain name was
entered correctly and the DNS A/AAAA record(s) for that domain
contain(s) the right IP address.
```

LetsEncryptの当該ドメインの設定ファイル(`/etc/letsencrypt/renewal/<ドメイン名>.conf`)を確認したところ
認証方法が`webroot`でディレクトリが`var/www/xxx`になっていた。たぶん、Webアプリ導入前に証明書を取得したのだと思う。

# 環境

- Amazon Linux 2
- Certbot 1.9.0
- Apache 2.4
- 複数のバーチャルホスト
- それぞれがリバースプロキシを利用
- リバース先のWebアプリにはアプリ外から動的にページを配置することはできない

# 対策

`--webroot`でなく`--apache`オプションを付与して証明書を再取得するだけ。これだけでOKだった。

```
# certbot certonly --apache -d mydomain.com -d mydomain2.com
```

# 備考/更新時の指定

更新(certbot renew)する際は--apache オプションの指定は不要。

なぜ省略できるかといえば設定ファイルにapacheを使うことが明示されているから。
この指定をすると更新パラメタ(renewalparams)で、認証処理・インストール処理がapacheに設定されている。

```conf:/etc/letsencrypt/renewal/<ドメイン名>.conf

証明書や鍵ファイルのパス

[renewalparams]
authenticator = apache
account = 68964f20a9151fxxxxxxxxxxxxxxxxxxxxx
server = https://acme-v02.api.letsencrypt.org/directory
installer = apache
```

# 備考/バーチャルホストが1つしかない場合は`webroot`でいける模様

今回は複数のサーバで発生していたのですが、バーチャルホストを1つしか使っていない場合は、
Apache Webサーバ設定で、Aliasを使って`/.well-known/acme-challenge`をファイルシステムに実在するディレクトリを紐付ければいけるようです。
(このディレクトリはアプリでは使ってない)

```conf:httpd.conf
Alias /.well-known/acme-challenge /var/www/letsencrypt
<Directory /var/www/letsencrypt>
  Order allow,deny
  Allow from all
</Directory>
```

certbotコマンド

```bash
# certbot certonly --webroot -w /var/www/letsencrypt -d ドメイン
```
PIDファイルがないからMySQLが起動しない

# 前提条件
自分の環境は以下の通りです。

* MacOS Catalina　バージョン10.15.6
* MySQL5.7

# 起動しなくなった原因
MySQLのサーバーが立ち上がっている状態でPCが再起動してしまった...

つまり、下のような状態で再起動しました。

```
$ mysql.server start
Starting MySQL
.. SUCCESS!
```

# エラーの内容
```mysql.server start```を叩いて
MySQLを起動しようとしたら以下のエラーが発生しました。

```
ERROR! MySQL server PID file could not be found!
```

# 解決方法
以下のコマンドを叩くと解消しました。
[user] [^1]の部分は適宜読み替えてください。

[^1]: ターミナルのこの部分で確認できます ```[user]@[machine]~ $ ```

```
$ sudo chown -R [user]:_mysql /usr/local/var/mysql
```

# さいごに
ネットで検索しても解決方法がバラバラで、片っ端から試してみたものの解決しませんでした。
なので、自分と同じ方法で解消する方がいたら良いなと思い、備忘録ついでに投稿しました。
SwiftUIでNavigationBarのBackgroundColorなどを変更する方法

## やりたいこと
SwiftUIでNavigationBarの背景色を変える
`UIAppearance`は使いたくない(強い意志)
## 結論
- `UINavigationBar.appearance()`を使わずにNavigationBarのBackgroundColorを変更
- `UIViewControllerRepresentable`でNavigationBarのStyleを変えたいViewを生成
- NavigationBarを使うViewの`.background()`に上記のViewを設定

### 準備
```swift
import SwiftUI
import UIKit

struct NavigationConfigurator: UIViewControllerRepresentable {
    var configure: (UINavigationController) -> Void = { _ in }

    func makeUIViewController(context: UIViewControllerRepresentableContext<NavigationConfigurator>) -> UIViewController {
        UIViewController()
    }
    func updateUIViewController(_ uiViewController: UIViewController, context: UIViewControllerRepresentableContext<NavigationConfigurator>) {
        if let nc = uiViewController.navigationController {
            self.configure(nc)
        }
    }

}
```
### 実際の使用例
```swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        NavigationView {
            Text("Don't use .appearance()!")
            .navigationBarTitle("Try it!", displayMode: .inline)
            .background(NavigationConfigurator { nc in
                // UIKitでNavigationBarのスタイルを変更するのと同じ方法でOK
                nc.navigationBar.barTintColor = .blue
                nc.navigationBar.titleTextAttributes = [.foregroundColor : UIColor.white]
            })
        }
    }
}
```
### プレビュー
<img width="250" alt="ss20201011" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166705/08fcba9d-45f5-63dc-c8a1-103165d065dd.png">


## 環境
2020年10月11日時点
Xcode 12.0.1
Swift 5.3
これ以外の環境については特に検証してないのでわからないですが、
SwiftUIが動く環境であれば可能だと思い込んでます

## NavigationBarの背景色を変えたい
とりあえず、さくっとググってみるといくつかの記事で、コンストラクタとかの初期化処理の際に`UINavigationBar.appearance()`でしかできないとかかんとか、、、:sob:
  
たしかに、`UINavigationBar.appearance()`でも変えれることは変えれるが、
画面ごとに色を変えるのが困難(ってかこれだけなら無理なのでは、、、)

## Stack Overflowありがとう！
[SwiftUI update navigation bar title color](https://stackoverflow.com/questions/56505528/swiftui-update-navigation-bar-title-color)
ちゃんと、いい感じに変更する方法を教えてくださってる方がいらっしゃりました:smile:

## この方法のデメリット
プレビューをライブモードにしないとスタイルが反映されないです
ライブモードにすればいいだけなので、どうでもよいですね

ってことで、 `UIViewControllerRepresentable` を使っていい感じに背景色を変更できました
まだまだ、SwiftUIは成長途中なので、この子を使いこなさないといけなさそう
swap導入（Cloud9）

##はじめに
Cloud9でアプリを作成中、メモリ不足が発生したのでswapについてメモしておきます。

間違い等ございましたら、是非ご指摘いただけたらと思います！

##swapとは
メモリが足りないときにメモリの中身をハードディスクに移す機能のこと。あるいは、2つのものを交換すること。

英単語のswapの意味は「交換する」

<a href="https://wa3.i-3-i.info/word1718.html">【swapの詳しい解説】</a>
##swap領域とは
ハードディスク内に設置される領域。メモリー容量が足りなくなった時、メモリの中で不要な部分をSWAP領域に移動させる(スワップアウト)。

ハードディスクへのアクセスは遅いので、スワップアウトが多発するとパフォーマンスの低下に繋がる。どうしてもメモリが足りない場合、SWAP領域を利用。

##swap領域を確認

```:ターミナル
$ free -m
             total       used       free     shared    buffers     cached
Mem:          3955        293       3662         80         11        214
-/+ buffers/cache:         68       3887
Swap:            0          0          0

```

##swap領域用ファイルを作成

```:ターミナル
$ sudo /bin/dd if=/dev/zero of=/var/swap.1 bs=1M count=2048

```

##swap領域作成(mkswapコマンド)

```:ターミナル
$ sudo /sbin/mkswap /var/swap.1
```

##swap領域を有効化(swaponコマンド)

```:ターミナル
$ sudo /sbin/swapon /var/swap.1
```

もう一度freeコマンドでswap領域を確認すると...

```:ターミナル
$ free -m
             total       used       free     shared    buffers     cached
Mem:          3955       1343       2612         80         11       1239
-/+ buffers/cache:         92       3863
Swap:         1023          0       1023
```


##参考記事
><a href="https://wa3.i-3-i.info/word1718.html">swapの解説</a>
><a href="https://www.wakuwakubank.com/posts/685-linux-swap/">SWAP領域の確認と作成</a>
Railsでいいね順に投稿を並べる（ランキング）

##概要
ネットでrailsのいいねランキングを探すとjoinを使った内部結合でいいねが１つ以上ある投稿をランキングする記事は見つかったがいいねが０のものを含めたランキングの記事が見つからず、
頑張って実装したので理解度を深める意味で殴り書きします。

##前提
Questionモデル（投稿）
Likeモデル（いいね）

##実装
※長くてごめんなさい

```rb
@questions= Question.left_outer_joins(:likes).group('questions.id').select('questions.*, COUNT(likes.*) AS likes_count').distinct.reorder(likes_count: :desc).limit(100)
```

##解説…？
1. Questionモデルにleft_outer_joins(:likes)でlikesテーブルを外部結合する
　joinsメソッドを使った内部結合だといいねされていないQuestionが除外されるため外部結合を使う。

2. 1で結合したテーブルをquestions.idでグループ化する
　　いいねされている対象のQuestionが同じ同士でグループ化する

3. select文で返すデータを指定（questionテーブルの全てとlikes_count)

4. distinctで重複したデータを取り除く。

5. <b>ここ重要!<b> reorderメソッドでlikes_countが多い順に並べ替える
   orderメソッドだとQuestionsテーブルのデフォルトの並び順(新規登録順）が適用されてしまうため
   reorderメソッドで並び順を書き換える

6.（ここはお好みで）limitメソッドでデータの取得件数を１００件に絞る 

##最後に
正直曖昧な理解が多くなんとかこぎつけた実装なので間違っていたり効率が悪いかもしれません。。
それとなく教えてくださると幸いです。。

この辺りのActiveRecordのクエリインターフェースに関してはRailsガイドがとてもわかりやすく載っているので
是非参考に
オブジェクト指向を自分なりにまとめてみた。

#はじめに
はじめまして。大学生エンジニアのMackeyです。
今回は、今までよくわかんなかったオブジェクト指向について自分なりにクソ簡潔にまとめてみました。
また、今回題材となる言語はRubyです。
初Qiitaの記事なので、変なところなどはあると思いますが、そこはあしからず。

#記事を読んでいただく上での前提
・rubyでは、全ての値がオブジェクトである
・オブジェクトはクラスから生成することができる
・オブジェクトは何らかのクラスに所属している
・変数の概念を理解している

#参考URL
・キノコード / プログラミング学習動画のYouTuber さんの
【Ruby超入門コース】13.クラス｜クラスとは、「データ」と「処理」をまとめたもの！【プログラミング初心者向け入門講座】
https://www.youtube.com/watch?v=E5IX_WLuvcs&list=PLavQwENTsEBUAgSok7Ww4-Q-ZHissbMOv&index=14

この方の説明はとてもわかりやすいので是非チャンネル登録してください。

#そもそもオブジェクト指向とは何ぞや。
プログラミング初心者の方がプログラミングをやっていてぶつかる壁の一つとしてオブジェクトやクラスやインスタンス、メソッドなどといったことが挙げられると思います。なので初心者の方向けにそれぞれのワードを専門用語なしで説明していきたいと思います。

#そもそもオブジェクト指向とは

#クラスとは
クラスとは設計図や骨組みのイメージ。

#インスタンスとは
インスタンスはオブジェクトの中でもクラスから生成された物を強調したいときに使う言葉。

#メソッドとは

```csharp:Class.rb

//studentクラスの生成
class Student

  //initializeメソッドはオブジェクトを生成したときに自動的に実行されるメソッド
  def initialize(student_name)
    @name = student_name
  end

  //数学と英語の平均点を表示するメソッド
  def average(math,english)
    result = (math + english) / 2
    p @name,result
  end

end

//オブジェクトを生成
a = Student.new("tanaka")

//studentクラスのインスタンスaでaverageメソッドを実行
a.average(50,30)

```
Pythonとpipの素性を知りたい

MacやLinuxでPythonを触る時はバージョンが混在していることが多く結構困る。触っているPythonやpipがどこのフォルダにあるものかを調べるためのコマンド

## Pythonの場所

```python:terminal
which python
which python3
which python2
```
で確認する

出力結果

```python:output
/usr/local/bin/python
```

### 他の方法

```python:terminal他の方法
type python
where python
```
でも行けました。@shiracamus様、コメントありがとうございます!

## pipの場所

```python:terminal
pip -V
pip3 -V
```
で確認する

出力結果

```python:output
pip 20.2.3 from /home/myName/.linuxbrew/opt/python@3.8/lib/python3.8/site-packages/pip (python 3.8)
```

Windowsだと困ったことない。
TBB の clang-cl クロスコンパイルビルドはハードゲームである

# 背景

* TBB を clang-cl で Linux(WSL)でビルドしたい

=> 現状 MASM アセンブラとか TRX 命令とかあって諦め. Windows プレビルトを使うのがよいでしょう.

## 原因

MSVC ビルドだと masm な asm を使っている(頑張れば yasm 文法とかに書き換えできるかもだが)

_xbegin などの TRX(transactional memory?)命令を使っている

https://github.com/conan-community/community/issues/43

clang(clang-cl)だと一応定義はあるが, どうもコンパイルがうまくいかない.
ベアメタルでAllwinner A10 の UART出力

Allwinner A10のUART出力をベアメタルで動かしてみました。

QEMUで動かしてみました。
QEMUの場合は初期化しなくとも、とりあえずデータ出力が確認できるので簡単です。

# コード

```c
#include <stddef.h>
#include <stdint.h>

extern void io_halt(void);

#define UART0_THR   ((volatile uint32_t *)(0x01C28000))

void uart_putc(unsigned char c)
{
    *UART0_THR = c;
}

void uart_puts(const char* str)
{
    for (size_t i = 0; str[i] != '\0'; i ++)
        uart_putc((unsigned char)str[i]);
}

void kernel_main(void)
{
    uart_puts("uart01: uart tx\n");
    uart_puts("exit : Ctrl-A x ,monitor : Ctrl-A c\n\n");

    while (1)
        io_halt();
}

```

UART0_THRに一文字分のデータを書き込めばUART0にデータを出力します。

# 実行例

QEMUにはAllwinner A10を搭載したcubueboardのエミュレーション機能があります。
オプションでUART0 を 標準出力に割り当てます。

```
qemu-system-arm -M cubieboard -m 512 -serial mon:stdio -kernel kernel.elf -nographic
uart01: uart tx
exit : Ctrl-A x ,monitor : Ctrl-A c
```

# 参考
* [AllwinnerA64(SOPINE)でGPIOとUARTをBaremetalで使ってみた](https://qiita.com/msoft444/items/45afabc9b475fef0d9cc)
 * こちらの記事では、初期化をちゃんと行って実機で動くコードになっているみたいです。 
* https://linux-sunxi.org/A10
 * レジスタ仕様が載っているUsers manualがダウンロードできます。
VoxCeleb データセットのメモ

音声と顔のデータセット

http://www.robots.ox.ac.uk/~vgg/data/voxceleb/

URL リストなどがあるだけのため, 自前でダウンロードが必要です.

https://github.com/cyrta/voxceleb

にダウンロードのまとまったスクリプトがあるようですので使うとよいでしょう.

tiffmpeg は libmp3lame 機能があるものが必要です.
エラーが出たら ffmpeg のサイトから static build あたりを使うといいでしょう.

`youtibe-dl --ffmpeg-location <path/to/ffmpeg>` で明示的に ffmpeg のパスを指定できます.


動画データ保存する場合それなりにディスク容量が必要になります(数テラバイト?). 著者は 4000 個くらいでディスク空き容量がなくなったのでそこで諦めました.
Rails でTimezoneを動的 に保存、表示する実装方針


# 背景と要件
Meetingなどのイベントの時間をあらゆるタイムゾーンを考慮して保存したいという要求がありました。

たとえば、
Meeting1 は Tokyo で 11:00 〜開催される。
Meeting2 は  UTC で 10:00〜開催される。

のようなことを表現したい。



# 実装手順
- RailsのAPIサーバーのdefaultのTimezoneを固定する。
- DBにTimezoneを保存する
- Timezoneを動的に変更するロジックをどこに挿入するかを決める。
- timzoneを考慮して、DBにtime型が保存されるか確認
- 保存する際に、timezone情報が無いstringが渡されないようにvalidation


# RailsのAPIサーバーのdefaultのTimezoneを固定する。

まずRailsは考慮するタイムゾーンが複数存在します。

https://qiita.com/joker1007/items/2c277cca5bd50e4cce5e

今回は、混乱をさけるため一旦以下すべてのTimezoneをUTCにしました。

- database
- activereocord
- system

# DBにTimezoneを保存する

timezoneを変更する基準となる変数を保存します。
timezoneは ActiveSupport経由で変更するので、validな値が保存されるように以下のようなvalidationを書けます。

```rb
# tz :string
class Meeting < ApplicationRecord 

validates :tz, inclusion: { in: ActiveSupport::TimeZone::MAPPING.values }, presence: true

end

```

# APIでGET時に、timezoneをdynamicに変更するロジックをどこに挿入するかを決める。
APIで値を返すときに、動的にTimezoneを変更して時間を返すロジックをいれます。
今回の場合はSerialzerにくみこみました。このロジックは表示に関わるロジックなので、結果的にViewに近いLayerでいれることになりました。


```rb

#  tz :string
class Meeting < ApplicationRecord 
  ~ 省略 ~

  def timezone
    ActiveSupport::TimeZone.new(tz)
  end

  def use_timezone
    Time.use_zone(timezone) do
      yield
    end
  end
end
```

```rb

class MeetingSerializer

  attribute :start_time do |record|
    record.use_timezone do
      record.start_time
    end
  end

end
```


# timzoneを考慮して、DBにtime型が保存されるか確認
保存はtimezone情報がついている、stringを渡せば、ActiveRecordがいい感じにやってくれます。

```rb
# actieve_record のtimezone は UTC

[47] pry(main)> meeting
=> #<Meeting:0x00007ff2c7ad4618
 id: "162b1ed7-5502-42f8-8bed-592d2dae7db1",
 start_at: Mon, 05 Oct 2020 16:00:00 UTC +00:00,
 created_at: Tue, 06 Oct 2020 06:28:39 UTC +00:00,
 updated_at: Thu, 08 Oct 2020 02:11:54 UTC +00:00>
[48] pry(main)> meeting.start_at="2020-10-06T01:00:00+0900"
=> "2020-10-06T01:00:00+0900"
[49] pry(main)> meeting.start_at
=> Mon, 05 Oct 2020 16:00:00 UTC +00:00
```

# 保存する際に、timezone情報が無いstringが渡されないようにvalidation

以下のような、controllerのconcern moduleを作成し、before_action でvalidationをかませるようにしました。

```rb

module ValidateTimeFormat
  class TimeFormatError < StandardError
  end

  extend ActiveSupport::Concern

  included do
    rescue_from ValidateTimeFormat::TimeFormatError, with: :render_time_format_error
  end

  TIME_FORMAT = '%FT%T%z'

  def render_time_format_error(msg)
    render json: { message: msg }, status: :bad_request
  end

  def validate_time_format(time_str)
    DateTime.strptime(time_str, TIME_FORMAT).zone
  rescue Date::Error
    raise ValidateTimeFormat::TimeFormatError, :time_format_is_invalid
  end
end
```

# まとめ
RailsはTime系は考慮するポイントが多いイメージがありました。
今回実装したことで、完璧に理解しました()

### twitterもフォローよろしくおねがいします。 ！
https://twitter.com/yoshixj
【Java】Calendarクラスで10日後の日付を取得



```java:TenDaysCalendar.java
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class TenDaysCalendar {

	public static void main(String[] args) {
		// 現在の日付情報を取得
		Date now = new Date();
		// Calendarにセット
		Calendar c = Calendar.getInstance(); // Calendarはnewを使わない
		c.setTime(now); // 引数にはDate型
		
		// 日付を表示してみる
		System.out.println("***********現在日時***********");
		System.out.println("Calendar.DATE: " + Calendar.DATE); // 5
		System.out.println("c.get(Calendar.DATE): " + c.get(Calendar.DATE)); // 今日の日付
		
		// 表示形式を指定して出力
		SimpleDateFormat f = new SimpleDateFormat("yyyy年MM月dd日"); // 表示形式を指定
		
		// 日付に10加算して10日後の日付を取得したい
		c.add(Calendar.DATE, 10);
		System.out.println();
		System.out.println("***********10日後***********");
		System.out.println("10日後の年月日: " + f.format(c.getTime()));
		System.out.println("Calendar.DATE: " + Calendar.DATE); // 5
		System.out.println("c.get(Calendar.DATE): " + c.get(Calendar.DATE));
		
		// さらに10日後の日付をセットして取得してみる
		System.out.println();
		System.out.println("***********さらに10日後***********");
		System.out.println("c.set(Calendar.DATE, (Calendar.DATE + 10))として10日後の日付にしようと試みる");
		c.set(Calendar.DATE, (Calendar.DATE + 10));
		System.out.println("10日後の年月日: " + f.format(c.getTime()));
		System.out.println("Calendar.DATEは定数で5なので、10加算すると15日になる");
		
		System.out.println();
		System.out.println("c.set(Calendar.DATE, (c.get(Calendar.DATE) + 10))として10日後の日付にしようと試みる");
		c.set(Calendar.DATE, (c.get(5) + 10));
		System.out.println("10日後の年月日: " + f.format(c.getTime()));
		System.out.println("上でDATEが15日にセットされたので10を加算して25日になる");
	}
}
```

```:実行結果
***********現在日時***********
Calendar.DATE: 5
c.get(Calendar.DATE): 11

***********10日後***********
10日後の年月日: 2020年10月21日
Calendar.DATE: 5
c.get(Calendar.DATE): 21

***********さらに10日後***********
c.set(Calendar.DATE, (Calendar.DATE + 10))として10日後の日付にしようと試みる
10日後の年月日: 2020年10月15日
Calendar.DATEは定数で5なので、10加算すると15日になる

c.set(Calendar.DATE, (c.get(Calendar.DATE) + 10))として10日後の日付にしようと試みる
10日後の年月日: 2020年10月13日
上でDATEが15日にセットされたので10を加算して25日になる
```


#Calendar.DATEはfinal定数だから変更できない

finalなのになんでsetとかできるの？

これが全然理解できませんでした。というか今もよく理解できていません。とりあえずいろいろ検証してみた結果、定数フィールド値というものがあって
`Calendar.DATEは定数5`が格納されているよう。


#getをすると日付が取得できる
```java

c.get(Calendar.DATE);
```
とすると日付がちゃんと取得できる。どういうこと？って感じでした。

とりあえず、Calendar.DATEは定数5なので、

```java
c.get(5);
```
として日付が取得できました。

#日付情報はDATEじゃなくて他のところに格納されている？！
ちょっと調べてみましたが私にはわかりませんでしたが、getの引数に5を渡すと、
`DATEの定数値が来たぞ！日付を返さなきゃ！`ということで、別のところに入っている日付を取ってきてくれるというイメージで良いかと。

基礎でやるような

```java
int name = "tanaka";
getName(){
  return name;
}
```
のイメージとは違うのかな。


またわかり次第記事を更新しますが、とりあえず上記のような理解ですっきりしましたし、扱いとして問題ありませんでした。
【Next.js】Next プロジェクトを Dockernize する

k8s 環境に Next.js プロジェクトをデプロイすることになったので、いろいろ書いてみた。
今回は npm ではなく、yarn を使用している。


## 環境

- ubuntu 20.04.1
- Docker 19.03.13
- Next.js 9.5.4

また、npm スクリプトはこんな感じ。

```json
{
  "scripts": {
    "dev": "next",
    "build": "next build",
    "start": "next start"
  }
}
```

## Docker 上で開発を行う

Docker 内の Node で開発を行う場合。ローカルの Node のバージョンを気にせず開発は行えるが、ローカルのエディタでは型定義などを読み込めず面倒ではある。

- Dockerfile  
  開発用なので、ベースイメージは通常のものにした。

```dockerfile
FROM node:12.18.4

WORKDIR /app
# npmパッケージのインストールに必要なファイルをコピー
COPY package.json yarn.lock ./
# npmを使用している場合は、以下のようにする
# COPY package*.json ./
RUN yarn install
EXPOSE 3000
CMD ["yarn", "dev"]
```

- Docker build

```
docker build --rm -t next_dev:latest -f path/to/Dockerfile
```

- Docker run  
  プロジェクトのフォルダで実行する。(-v の引数にプロジェクトフォルダを絶対パスで指定すれば OK)

```
docker run -p 3000:3000 -v $PWD:/app -it next_dev:latest
```

## Production 向けにビルドする

ここからは、本番向けにイメージを作成する。

### とりあえず作ってみる

いつも通り作ってみる。本番向けなので alpine イメージを使う。
ビルドコンテキスト(Docker build 時に Docker デーモンへ送信されるファイルの場所)はプロジェクトフォルダ。

```dockerfile
FROM node:12.18.4-alpine

WORKDIR /app
# ローカルのソースを全てコピー
COPY . /app
# npmパッケージのインストール、production向けにビルド
RUN yarn install && NODE_ENV=production yarn build
EXPOSE 3000

CMD ["yarn", "start"]
```

- ビルド&実行

ビルドにはプロジェクトフォルダで以下のコマンドを実行。

```
$ docker build --rm -t next_prod:latest -f path/to/Dockerfile
```

デーモンとして動かすには以下のコマンドを実行。

```
$ docker run -d -p 3000:3000 next_prod:latest
```

これでサーバー自体は動くが、このままでは Docker イメージのサイズが 900MB あるので、もう少しスリムにしたいところ。
(もちろん、イメージのサイズは Next.js プロジェクトの中身による)

```
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
next_prod         latest              d211c6246173        6 minutes ago       899MB
```

### multi stage build する

multi stage build により、Docker イメージの容量を削減する。

- Dockerfile

```dockerfile
FROM node:12.18.4-alpine AS base

# パッケージのインストールを行う
WORKDIR /base
COPY . .
RUN yarn install

# Production向けビルドを行う
FROM base AS build
WORKDIR /build
COPY --from=base /base ./
RUN NODE_ENV=production yarn build

# ビルド成果物をコピーし、サーバーを起動
FROM node:12.18.4-alpine AS production
ENV NODE_ENV=production
WORKDIR /app
# ビルド成果物のみをコピーしてやる
COPY --from=build /build/package.json /build/yarn.lock ./
COPY --from=build /build/.next ./.next
COPY --from=build /build/public ./public
# node_modules以下がこのイメージにないので、next.jsのサーバーを動かすために必要
RUN yarn add next

EXPOSE 3000
CMD ["yarn", "start"]
```

- ビルド&実行

```
$ docker build --rm -t next_prod:msb -f path/to/Dockerfile
$ docker run -d -p 3000:3000 next_prod:mdb
```

これにより、イメージはかなりスリムになった。各イメージの容量はこんな感じ。

```
$ docker images
REPOSITORY          TAG           SIZE
next_prod           msb           574MB    # production multi stage build
next_prod           latest        899MB    # production build
next_dev            latest        1.44GB   # dev
```

## おわりに

DockernizeなのかDockerizeなのかよくわからない。
[App groups] UserDefaults データにアクセスできないときに確認したこと

App groupsを使用した、UserDefaultsの使用で、データにアクセスできない問題が発生した。
私の場合は、Build Settings の Signing 設定のCode Signing Entitlement 設定がなかったことが問題だった。
通常、app groupsを有効にしgroupを指定したら自動的にできあがる？とおもうのだが
私の環境では（Xcode 12.0.1） では、自動的に設定されなかったので、他の正常に動いているTargetを参考にこの問題を確認し解決できた。
メモまでに。

## Code Signing Entitlementを設定

まず、XXXXXX.entitlementsファイルを作成する。
XXXXXX.entitlements （XXXXXXは任意のファイル名） ファイルを作成。
内容は以下のplistデータで、**group.my.appgroup.id** の部分は、使用するapp group名を記述する。

```
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>com.apple.security.application-groups</key>
	<array>
		<string>group.my.appgroup.id</string>
	</array>
</dict>
</plist>
```

作成したentitlementsファイルを、プロジェクトに追加する。

次に、設定を行う。

app groupが使用できない問題となっているTARGETを選択し、
Build Settings の Signing の Code Signing Entitlement に、ファイル名を設定する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6327/ac2f9d03-e235-cbf3-0fed-3027be0fe182.png)
JavaScript ミリ秒を秒、分、時間、日にちに変換する方法


まず、定数nowにDate()オブジェクトをインスタンス化（初期化）したものを代入。
now.getTimeメソッドで求められるのは、１９７０年1月１日０時０分から現在までの時間をミリ秒（1/1000秒）で表した数字。

```
const now=new Date();
const time=now.getTime();
```


まずは、秒を求める。

```
const sec = Math.floor(time/1000)%60;
```

もし、now.getTime()で得られた数値が1655555555000(ミリ秒）だとしたら、
定数time/1000で秒数になる。
60（1分＝60秒）で割った余りがまだ１分に満たない秒数つまり、秒となる。

次に、分を求める。

```
const min=Math.floor(time/1000/60)%60;
```
Math.floor(分数)を60分（1時間)で割った余り。つまり、まだ1時間に満たない分数。

次に、時間を求める。

```
const hours=Math.floor(time/1000/60/60)%24;
```
Math.floor(時間)を24時間で割った余り。つまり、まだ24時間(１日)に満たない時間。

```
const days=Math.floor(time/1000/60/60/24);
```
Math.floor(日数）。つまり、24時間で割った数。
bitnami redmine4.1環境で、redmica1.1を動作させる。

##■インストール( ..)φメモメモ
　bitnami redmine環境で、redmicaを動作させたのでメモを残しておく。
　手順は以下の通りに進める。
　windwos版のみ検証し、その他の環境は確認しておりませんが他の方の参考になるかもしれないので公開します。
　※`bitnami-redmine`のインストールや、`redmica`の解凍作業は割愛しております。

##■環境：
　`bitnami-redmine-4.1.1-3-windows-x64-installer.exe`
　`redmica-1.1.0`
　`Windows10 Home 64bit x64`
　`インターネット接続環境`


##■手順
####・Bitnami Redmine Stack Manager Toolを起動して、以下のサービスを停止する。
　`  redmineApache、redmineMySQL、redmineThin1、redmineThin2`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651745/d7769f10-f1c9-fc0d-a348-67b783d8ccf7.png)

####・インストールしたbitnami redmineのhtdocsをredminacaに差し替える
　※ただし、元のbitnami redmineのhtdocsは一部使うので、消さずに残しておく。
　例)
　`C:\Bitnami\redmine-4.1.1-3\apps\redmine\htdocs`

####・差し替えたhtdocs(redminaca)に、元のbitnami redmineの側htdocs（以下ファイル）を上書き（追加）する
　`--htdocs\bin`
　`|-about`
　`|-bundle`
　`|-changelog.rb`
　`|-nokogiri`
　`|-rackup`
　`|-rails`
　`|-rake`
　`|-redcarpet`
　`|-rougify`
　`|-sprockets`
　`|-thin`
　`|-thor`
　
　`--htdocs\config`
　`|-additional_environment.rb`
　`|-boot.rb`
　`|-database.yml`
　`|-thin_service_envvars.rb`
※ご注意：`routes.rb、settings.yml、locales`は必ず、redminaca側を使ってください表示がおかしくなります。

####・元のbitnami redmineの側htdocsにある、`Gemfile`ファイルをベースに以下の3行を追加する。（Gemfileの編集）
独自の依存関係の設定 (Gemfile）
※htdocs(redminaca)側のGemfileファイルは使わない。
　`gem 'eventmachine', github: 'eventmachine/eventmachine', branch: :master, ref: '10fb0c4'`
　`gem 'addressable'`
　`gem 'rubyzip', (RUBY_VERSION < '2.4' ? '~> 1.3.0' : '~> 2.3.0')`

####・Bitnami Redmine Stack Manager Toolを起動して、以下のサービスを開始する。
　`redmineApache、redmineMySQL`

####・コマンドプロンプト（`use_redmine.bat`）を起動して以下のコマンドを動作させる。
　依存するソフトウェアのインストール、セッションストア秘密鍵の生成
　`cd apps\redmine\htdocs`
　`bundle install`
　`bundle exec rake generate_secret_token`

####・コマンドプロンプトのコマンド補足（データベースのテーブル作成が必要な場合）
　`set RAILS_ENV=production`
　`bundle exec rake db:migrate`
　※データベースのテーブル等の作成は今回(redmine4.1→redmica1.1)は必要なかったが、
　　ＤＢ変更がある場合はこのコマンドがないと正常に動作しないので注意する。
　　例えばredmine3.*系→redmine4.*系等を行う場合や、redmine4.1→redmica1.2を実施する場合　　　

####・プラグインについて（必要に応じて実施、以下は参考例）
　プラグインを格納して以下のコマンドによりインストールする。
　`bundle install`
　`bundle exec rake redmine:plugins RAILS_ENV=production`
・プラグインの格納場所
　`C:\Bitnami\redmine-4.1.1-2\apps\redmine\htdocs\plugins`
　`C:\Bitnami\redmine-4.1.1-2\apps\redmine\htdocs\vendor\cache`
　※詳しくはそれぞれのプラグインのインストールを参考にしてください。


####・mysqlで、bitnamiアカウントのパスワードを修正（合っていれば不要）
　※database.ymlのパスワードに合わせておく、合っていないと起動時にけられるため（以下は例）
　`mysql -u root -p`
　`set password for bitnami@localhost = '92cc5383ad';`


####・Bitnami Redmine Stack Manager Toolを起動して、以下のサービスを開始する。
　`redmineThin1、redmineThin2`
Chainerによる機械学習のためのPython学習メモ　４章 ~ 6章 数学編

# What

Chainerを利用して機械学習を学ぶにあたり、私自身が、気がついた点、リサーチした内容をまとめる記事になります。今回は、機械学習に必要な数学を抜粋して勉強します。

私の理解に基づいて記述しているため、間違っている場合があります。間違いは都度修正するつもりです、ご容赦ください。

#Content

### 微分

**線形性**
 関数、定数a, b, 変数xに対し
　　　　f(ax + b) = a * f(x) + b
と分離できる場合、線形であるという

**連鎖律**
合成関数の微分の公式のことをいうらしい（・・・忘れた）

機械学習で取り扱う入力は多変数となる場合が多いので、個々の変数との出力の関係は多変数解析（要は偏微分）が必要になる。

### 線形代数

**テンソル**
ちょっと理解ができていないところがあるのでテキスト抜粋
>テンソル (tensor) はベクトルや行列を一般化した概念です。 例えば、ベクトルは 1 方向に、行列は 2 方向にスカラが並んでいます。これは「ベクトルは 1 階のテンソルで、行列は 2 階のテンソルである」であることを意味します。 この考え方をさらに進めて、下図のように行列を奥行き方向にさらに並べたものを3階のテンソルと呼びます。例えば、カラー画像をデジタル表現する場合、1 枚の画像は RGB (Red Green Blue) の3枚のレイヤー（チャンネルと呼びます）を持つのが一般的です。 各チャンネルは行列として表され、その行列がチャンネル方向に複数積み重なっているため、画像は 3 階テンソルとみなすことができます。 3 階のテンソルは、特定の要素を指定するのに「上から 3 番目、左から 2 番目、手前から 5 番目」のように整数（インデックス）を3個必要とします。

恥ずかしながら今更しりました。定義自体はシンプルですね。

### 確率・統計
機械学習では良質なデータが大量にあるほど良い、つまり大量のデータを扱う分野であるという認識は持っていたのでやはり確率・統計も出てくるよな〜と思いました。ここがミソなんでしょうね。では、中身を見ていきます。
人間がパッと気が付かないような法則や特徴どうやって見つけ出すか？考えた時に、科学的根拠に基づいた方法として確率、統計が出てくるというのも納得がいきます。
>ある結果が観測されたというとき、ある事象が原因である確率を考えるにはどうしたら良いでしょうか。

サイコロで例えるなら、①2つのサイコロを投げた時、その積が12でした。組み合わせが6,2である確率は？といった感じ？
②サイコロを２回投げて6, 2が出る確率と違いはある？
②なら2 / 36 = 1 /18 ①なら2 / 4 = 1/ 2[(2, 6), (3, 4)]で①と②で結果が異なるってことを言いたいのかな。これをベイズの定理というらしい。
数式は後で、じっくり読み込むとして、ベイズの定理は何を解決できる定理かが抑えられればいいかな。

### 尤度(ゆうど)
初見の言葉です。犬みたいな感じを書いてゆうどと読むみたいです。
カリキュラムだけではちょっと理解が難しかったので、下記サイトを参考にしました。
https://qiita.com/kenmatsu4/items/b28d1b3b3d291d0cc698
>尤度関数の基本概念は、「サンプリングしてデータが観測された後、そのデータは元々どういうパラメーターを持つ確率分布から生まれたものだったか？」と言う問いに答えるためのものです。なので、逆確率的なベイズの定理っぽさがあると自分は思っています。（実際、尤度はベイズの定理を構成する１要素となっています）

この説明はわかりやすいですね。尤度が最大になる時が尤もらしい推定モデルになるというのも理解しやすいです。

>複数データに対する尤度は、 1 より小さな値の積となるため、結果は非常に小さな数になり、コンピュータでこの計算を行う際にはアンダーフローという問題が発生しやすくなります。

デジタルとアナログの変換で生じる問題ですね。どのくらい問題になるか、現時点でイメージは持てないですが。

### 事後確率最大化推定（MAP推定）

与ええられたデータ群から尤もらしい確率分布を推定するのが、尤度ですが、**尤もらしいモデルではない**モデルから生じた確率モデルを予測する手段がMAP推定。例えば、ベルヌーイ分布から生じた,[表、表、表、表、表]というデータ群から、データ群から得られる以外の情報（例：裏が出ることもある等)を与えてできるだけ元のベルヌーイ分布を推定するにはどうすれば良いかを考える理論。実際には、データを扱う人の推測を確率モデルに組み込めるよって話。ある意味センス？？？笑
###分散
久しぶりに復讐したので忘れてる部分もありました。母分散、標本分散、不変分散の関係は以下のサイトが参考になりました。分散の平方根が標準偏差
https://staff.aist.go.jp/t.ihara/dispersion.html

###相関係数
2 種類のデータ間の相関が強いほど 𝑟 の絶対値は大きくなります。
rの値で、相関があるかを判断する指標はない。せいぜい大小で議論するか、判断基準を任意に設定するか。大学の時に買った統計の本いつでも見れるようにしておこう。

# Comment 
なんとか準備編読了です。Pythonの学習と思い出し作業が大半でした。早くコードを書きたいのですが、、、入り口が長いですね。
最近何かとAWSが話題ですが、AWSのコンテンツの中にも機械学習があるみたいなんですよね。
今の学習が終わったら、ちょっと調べてみたいと思ってるんですが、何ができるんでしょう？？？というよりも、AWSをきちんと理解したい。。。わかりにくくていまいち掴めないんです:cry:
[ Ruby ]クラスのネストや、継承、selfの基礎

# はじめに
作業しながらも、継承の影響範囲ってどこまでだっけ。。とか
この場合のselfは何を指しているんだっけ。。とか
基礎部分をフワッとしか理解できていなかったので今回は

- クラス
    - 継承
    - self
    - ネスト

といった内容を、実際に書きながら学んでいったのでその記録として書きます。
メソッドや変数のことも書きたいのですが、長くなりそうなので別で書きたいと思います。


## クラスの継承
クラスを定義する際にスーパークラスを1つ指定することができ、
この時に指定しない場合は、自動的にobjectクラスを継承します。
そのため、クラスを新しく定義する時は常に何かのクラスを継承する形になり
必ず継承ツリーのどこかに入ることになります。

#### 継承する対象
- スーパークラスのクラスメソッド
- インスタンスメソッド
- メソッド内に記述されているインスタンス変数

また、継承ではありませんが、スーパークラスの定数、クラス変数も参照できます。

```ruby
class Klass
  VALUE = "I'm VALUE"
  @@class_val = "I'm class_val"
end

class A < Klass
end

class B < A
  def self.display_bal
    puts @@class_val
  end
end

# スーパークラスの定数の参照
puts B::VALUE
# => I'm VALUE

# クラス変数の継承
B.display_val
# => I'm class_val
```

## self
`self`はオブジェクトそのものを指すので、使用する場所によって中身が変わります。

以下の例では、インスタンスメソッド内で使用した場合のみ、`インスタンスオブジェクト`を指しました。
また、クラスメソッドを定義する際に用いる`self`は、クラスオブジェクトを指しているため
`self.メソッド名`の`self`を直接クラス名で指定することもできます。

```ruby
class Klass
  # Klass
  p self
  
  # Klass
  def (p self).class_method
      puts "inner_class_method"  
      # Klass
      p self
  end

  def instance_method
    puts "inner_instance_method"
    # <Klass:0x00007fa07e1a47c8>
    p self
  end
end

Klass.class_method
klass_instanse =  Klass.new
klass_instanse.instance_method
```

## クラスのネストなど
クラスを定義する際に、他のクラスにネストさせることができます。
定義の仕方として以下の２パターンがありますが、一部挙動が変わってきます。

```ruby
# 直接中に記述する
class TopKlass
  class Klass
  end
end

## ------ ##

# ”::”を用いる
class TopKlass
end

class TopKlass::Klass
end
```

### 定義の仕方による挙動の違い
#### 定数の参照

・直接中に記述
自身からトップレベル方向へ順に定数を参照していきます。
自身から近い順にから順に参照していき、最後にトップレベルを参照するという流れになります。

```ruby
VALUE = "Top level"

class TopKlass
  VALUE = "in TopKlass"

  class InnerKlass
    def self.put_value
      puts VALUE
    end
  end

end

TopKlass::InnerKlass.put_value
# => in TopKlass
```

・ネームスペースを用いて記述
自身に定数がなければ、次にトップレベルを参照すし、そこから順に自身のクラス方向へ参照していきます。

```ruby
VALUE = "Top level"

class TopKlass
  VALUE = "in TopKlass"
end

class TopKlass::InnerKlass
  def self.put_value
    puts VALUE
  end
end

TopKlass::InnerKlass.put_value
# => Top level
```

#### class,module のどちらにネストさせるのかを明確にする
・中に記述
各階層でclassかmoduleかを指定するため、別で定義したmoduleをclassとして指定するとエラーになります。

```ruby
module TopKlass
end

class TopKlass
  class InnerKlass
  end
end

# => TopKlass is not a class (TypeError)
```

・ネームスペースを用いて記述
classかどうかを指定するのは、最後（一番右）に記述したもののみであるため、
それ以外はclassやmoduleの判断を柔軟に行ってくれます。

```ruby
module TopKlass
end

class TopKlass::InnerKlass
end

# エラーにならない
```

#### ネスト元のオブジェクトがなかった時に例外を出すかどうか
・中に記述
以下の例の場合、TopKlassを別で定義していなかった場合、
新たにTopKlassを定義してくれるため例外は発生しません。

```ruby
class TopKlass
  class InnerKlass
  end
end
```

・ネームスペースを用いて記述

以下の場合は、別でTopKlassを定義していなかった場合例外を出します。
新たにTopKlassを定義はしてくれません。

```ruby
class TopKlass::InnerKlass
end

# => uninitialized constant TopKlass (NameError)
```
# おわり
Go To トラベルの宿泊施設をスクレイピング

[Go To トラベル](https://goto.jata-net.or.jp/stay/)の宿泊施設のリストは

https://goto.jata-net.or.jp/assets/data/stay.csv

にcsvデータがあるのでスクレイピングしなくても取得できます

# 開発ツール

https://developer.mozilla.org/ja/docs/Tools

ネットワークモニターでリクエスト内容を確認できます

![stay_csv.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36151/32e9da7b-4d3a-457f-6c62-8f774c31fb0a.png)

```python
import pandas as pd

df = pd.read_csv("https://goto.jata-net.or.jp/assets/data/stay.csv")

df["都道府県"].value_counts()
```

|          |   都道府県 |
|:---------|-----------:|
| 東京都   |       2551 |
| 長野県   |       2328 |
| 京都府   |       2235 |
| 北海道   |       1965 |
| 沖縄県   |       1886 |
| 静岡県   |       1629 |
| 大阪府   |       1494 |
| 神奈川県 |       1018 |
| 山梨県   |        956 |
| 兵庫県   |        904 |
| 千葉県   |        864 |
| 新潟県   |        855 |
| 愛知県   |        833 |
| 群馬県   |        806 |
| 福岡県   |        783 |
| 栃木県   |        715 |
| 岐阜県   |        661 |
| 大分県   |        647 |
| 福島県   |        631 |
| 鹿児島県 |        549 |
| 熊本県   |        537 |
| 三重県   |        525 |
| 石川県   |        521 |
| 和歌山県 |        484 |
| 広島県   |        444 |
| 山形県   |        409 |
| 宮城県   |        407 |
| 長崎県   |        385 |
| 茨城県   |        364 |
| 福井県   |        352 |
| 岩手県   |        335 |
| 香川県   |        328 |
| 岡山県   |        327 |
| 埼玉県   |        312 |
| 奈良県   |        298 |
| 愛媛県   |        295 |
| 滋賀県   |        287 |
| 富山県   |        259 |
| 島根県   |        240 |
| 高知県   |        225 |
| 鳥取県   |        221 |
| 宮崎県   |        221 |
| 青森県   |        220 |
| 秋田県   |        204 |
| 山口県   |        201 |
| 徳島県   |        184 |
| 佐賀県   |        168 |
【物体検出】TridentNet : Receptive Fieldを広げFPNを超える






![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/ac702f23-5c11-9f3d-64cd-39742de0d1ce.png)

 Trident Networkについてまとめて行く。

<h1>Investigation of Receptive Field</h1>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/67180c06-9168-1563-c2ea-87c4465cefe5.png)

Dialationの実験でDialationの幅を大きくするとLarge Objectの精度が上がってる。広いReceptive Fieldによる恩恵。

これにより最適なReceptive FieldがDetectionの精度を上げる事が分かる。




<h2>Multi-branch Block</h2>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/f574a2a0-fac3-fd4b-6e30-ed41286b470e.png)

Dialation以外同じ構造で同じweightを使ったNetworkを設計する。




<h2>Weight sharing among branches</h2>

parameteの数を減らせる。
違ったScaleの物体も同じように表現される。
parameterが違うScaleでTrainingされる事によって、Sample数が増える。


<h2> Scale-aware Training Scheme</h2>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/249fc133-2218-d7fa-66e1-1d009da51382.png)

SNIPのように、li~uiの間のサイズの物体のみを検出する。

<h2>Fast Inference Approximation</h2>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/9e063e1e-7efa-a265-41f0-cec66905b1a4.png)

TridentNetは構造上遅い。INference時に真ん中のみを使うと元の、Faster-RCNNと同じスピードで処理出来る。さらに精度は少ししか落ちなかった。これはweight sharingをしたことによって、様々なScaleの物体を入力するData Augmentaionと同じ効果を得られたのではないかと推測出来る。

<h1>結論</h1>
Receptive Field大事！

<h1>参考文献</h1>
Scale-Aware Trident Networks for Object Detection
https://arxiv.org/pdf/1901.01892v2.pdf
git revert を git revertした

#git revert とは

一言で言えば「**既存のコミットを取り消す**」コマンドです。

似たコマンドで**git reset**がありますが、
・git reset：　そのまま過去に戻す
・git revert：　「コミットを打ち消したよ」というコミットを新たに追加して、状況を戻す
という違いがあります。

両方とも、できればあまり使いたくないですね。

# revertをrevertの経緯

では、なんでrevertをrevertしたのか、ですが、

①**最新コミットが不要だったので、revertした**
②**やっぱりそのコミットは必要だった**
③**revertしたことをrevertしたい**

という経緯です。

一から書き直してもいいですが、
やっぱりまるまる一気に元に戻したい。。。

#revertをrevertする

それでは実際にどんな感じだったか、可能な範囲で晒していきます。

※ ブランチ名を仮に`fix_user_images`とします。

###１、最初のrevert

```
# "git revert [コミット番号]"で、そのコミットを無かったことにする
$ git revert fb286b771

[fix_user_images 2c93f2815] Revert "画像サイズ修正"
 3 files changed, 1 insertion(+), 8 deletions(-)
 create mode 100644 〜〜/〜〜
```

###２、revertをrevert
１でなくなくrevertしたあとに、同じブランチで既に新たな開発を始めていたので、
その開発内容はサラにします（泣

```
# ログ確認
$ git log --oneline

2829851e0 (HEAD -> fix_user_images) Revert "画像サイズ修正"
2c93f2815 Revert "ユーザー画像追加"
7b1b3b230 (origin/fix_user_images) Merge branch 'develop' of gitlab.〜〜〜:〜〜〜 into fix_user_images
...


# 最新コミットに戻す
$ git reset --hard HEAD

HEAD is now at 2829851e0 Revert "画像サイズ修正"


# revertして作られたコミット「"Revert "画像サイズ修正"」をrevert
$ git revert 2c93f2815

Removing 〜〜/〜〜
[fix_user_images 619bf7743] Revert "Revert "画像サイズ修正""
 3 files changed, 8 insertions(+), 1 deletion(-)
 delete mode 100644 〜〜/〜〜
```

###３、無事反映を確認

```
$ git log --oneline

619bf7743 (HEAD -> fix_user_images ) Revert "Revert "画像サイズ修正""
2c93f2815 Revert "画像サイズ修正"
7b1b3b230 (origin/fix_user_images) Merge branch 'develop' of gitlab.〜〜〜:〜〜〜 into fix_user_images
fb286b771 画像サイズ修正
...
```

#終わりに

・git revert
・git reset
・git rebase
は「3大叩いてはいけないgitコマンド」としてインプットしていましたが、
実際はまだまだこんなもんじゃないんだろうなと思います。

今後頻繁に叩く必要が出ないことを祈ります。。。。
Vue.js - ディレクティブ

ディレクティブの備忘録
※今後も更新予定

# ディレクティブ
条件分岐やループ処理など、複雑な処理をViewに組み込むVueの命令のこと。

* `v-xxx`の形式でViewに埋め込んで処理を書く

# ディレクティブ一覧
## v-text
文字列をテンプレートに埋め込む。

```html
<p v-text="name"></p> <!-- データオブジェクトの name を pタグ内に埋め込む -->
```
※下記と同じ出力がされるためどちらの記法でもよいが、アプリ内ではどちらかに統一すること。

```html
<p>{{ name }}</p> <!-- 通常のマスタッシュ構文 -->
```

## v-pre
構文を無効にする。
デリミタをそのまま出力したい時などに使用する。

```html
<p v-pre>{{ name }}</p> <!-- 画面では {{ name }} がそのまま出力される -->
```

## v-bind
属性値にJavascript式を埋め込む。

```html
<a v-bind:href="url">リンク</a> <!-- データオブジェクト下のurlを埋め込む -->
```

頻繁に利用されるため、省略構文も用意されている。
本来の属性名の頭に `:` を付与して表現する。

```html
<a :href="url"></a>
```

## v-on
イベントとそのイベントが発生した際に実行する処理を定義する(イベントリスナーの設定)
イベントを設定したいタグに `v-on:イベント名="イベント発生時に呼び出す処理"` の形で属性を付与する。

```html
<!-- pタグクリック時にVueインスタンスのmethodsオブジェクト内に定義されたonclickmethodが呼ばれる -->
<p v-on:click="onclickmethod">クリック</p>
```

`v-on` も頻繁に使用されるため省略形が存在する。
`v-on:` を `@` に置き換えても同様の結果が得られる。

```html
<p @click="onclickmethod">クリック</p>
```

また、イベントとして設定できるのはJavascriptで定められている下記リファレンス内のイベントのみ。
https://developer.mozilla.org/en-US/docs/Web/Events

## v-model
指定したdataオプションのオブジェクトを監視し、同期を行う。
例えば、次のようなHTMLとVueオブジェクトがあるとする。

```html
<testInput v-model="name" />
<p>{{ name }}</p>
```

```js
Vue.component('testInput', {
// 省略
});

new Vue({
  el: "#app",
  data: {
    name: "Alice"
  }
});
```

この状態でHTMLを描画し、inputのテキストを更新することでdata.nameの値も更新される。
更新がかかるとpタグ内のnameについても値が変更される。
このようにして監視を行い、更新があった場合にそれを参照している箇所についても同期をとることができる。
上記のように、テンプレート(HTML)とdataオプションのオブジェクト間でデータの同期をとることを`双方向バインディング`と言う。

また、v-modelはv-onとv-bindの組み合わせのシンタックスシュガーであり、次の二つのinputタグの記述方法は同義となる。

```js
<testInput v-model="name" />
<testInput v-bind:value="name" v-on="name=$event">
```

# 参考
・API(ディレクティブ) 日本語ドキュメント ※バージョンが2系より前
https://jp.vuejs.org/v2/api/#%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%86%E3%82%A3%E3%83%96

・API(ディレクティブ) 英語ドキュメント ※3系にも対応
https://v3.vuejs.org/api/directives.html

・Javascript イベント一覧
https://developer.mozilla.org/en-US/docs/Web/Events

・これからはじめる Vue.js 実践入門 (山田祥寛 著)
https://amazon.co.jp/dp/4815601828
2段階エディット法ー共通バグの発見率から全体の総エラー数を推定する手法

AP試験学習記録27年秋 午前48

二つの独立したテストグループA，Bが，あるシステムについて一定期間並行してテストを行い，それぞれNA個及びNB個のエラーを検出した。このうち，共通のエラーはNAB個であった。このシステムの総エラー数Nを予測する式はどれか。ここで，NA＞0，NB＞0，NAB＞0とし，グループA，Bのエラーを検出する能力及び効率は等しいものとする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/9f74db1b-c8c1-9684-777e-45a1bb50d40e.png)

１、2段階エディット法
共通バグの発見率から全体の総エラー数を推定する手法を2段階エディット法といいます。

総エラー数のうちグループA，Bのバグ検出確率"P(A)"，"P(B)"は、

　P(A)＝NA／N　…(1)
　P(B)＝NB／N　…(2)

と定義することができ、そこからP(A)，P(B)が共に発生する"P(AB)"を、

　P(AB)＝　P(A)×P(B)＝NAB／N　…(3)

と導くことができます。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/7cd70166-cc00-b230-c604-ad7917dfa141.png)


NAの検出率＝NA／N
NBの検出率＝NB／N
NABの検出率＝NAB／N

(3)の式に(1)と(2)を代入すると、

　(NA／N)×(NB／N)＝NAB／N

→　N＝NA×NB／NAB



参照：
https://www.ap-siken.com/kakomon/27_aki/q48.html
[Go]「...（ピリオド３つ）」の使い方（基本編）

# 1.はじめに
これからGoを始める人のためになればと思って記事を書きました。
ソースコードで「...」を初めて見たときに、ググっても日本語で情報がまとまっているものがあまり無いので、私が業務でよく使っている「...」の使い方をまとめようとおもいました。

## 1-1.この記事を読んだらどうなるのか
「...」の使い方とポイントを理解できる

## 1-2.対象読者
Goの「...」がわからない人

#  2.「...」の使い方（基本編）

## 2-1.関数の引数を可変長にしたいとき
関数の引数を可変長にすることができます。
たとえば、関数で複数のintを可変で受け取りたいときがあるとしたら、以下のように書くことができます。
ポイントは **...int** のように型の前に...を書くことです。

関数内でも可変長引数はSliceとして扱われます。
気をつけたいのは、関数を呼び出すとき可変長引数に値を渡さないと、可変長引数はnilとして扱われます。（もちろんコンパイル通ります）

```go
// WriteInt はintを可変で受け取って出力する関数
func WriteInt(nums ...int) {
	for _, v := range nums {
		fmt.Println(v)
	}
}
```

実行すると、以下の結果になります

```go
func main() {
	WriteInt(1, 2, 3)
}

// 実行結果
1
2
3
```


[Go Playgroud](https://play.golang.org/p/F9zRiUTi1ny "Go Playgroud")
## 2-2.可変長引数の関数に値を全て渡す
前の章で説明した可変長引数の関数に対して、「...」を使うことで一気に渡すことができます。
ポイントは **s...** のように渡したい値の後に...を書くことです。

```go
func main() {
	s := []int{1, 2, 3}
	
	// sが持つ値を...を使って、全てWriteIntに渡している
	WriteInt(s...)
}

func WriteInt(nums ...int) {
	for _, v := range nums {
		fmt.Println(v)
	}
}
```

[Go Playgroud](https://play.golang.org/p/zIoO3fXyiHM "Go Playgroud")

私が業務で一番よくつかうのは、Sliceをappendするときです。

```go
func main() {
	s1 := []int{1, 2, 3}
	s2 := []int{4, 5, 6}
	s3 := append(s1, s2...)
	fmt.Println(s3)
}

// 実行結果
[1 2 3 4 5 6]
```

# まとめ
これらの例を通して、可変長引数 ... の強力な用途とその応用方法を紹介しました。Go言語におけるこの機能は、コードの柔軟性と再利用性を大いに高めることができます。ぜひあなたのコードで活用してみてください！
応用編の記事も書いたのでよかったらご参考にしてください。

https://qiita.com/Yashy/items/3f15ea8f60224c8f95c2

# 参考
[公式ドキュメント Passing_arguments_to_..._parameters](https://golang.org/ref/spec#Passing_arguments_to_..._parameters)
[公式ドキュメント append](https://golang.org/pkg/builtin/#append)
[3 dots in 4 places](https://yourbasic.org/golang/three-dots-ellipsis/)
[Goで可変引数の関数にスライスを展開して渡す](https://qiita.com/hnakamur/items/c3560a4b780487ef6065)
[★ Ultimate Guide to Go Variadic Functions](https://blog.learngoprogramming.com/golang-variadic-funcs-how-to-patterns-369408f19085)