OmniAICreator/Qiita-1.07M huggingface dataset:
【Ruby】クラス内のselfがつくメソッドとつかないメソッドの違い。クラスメソッドとインスタンスメソッドについて。

クラスの中の関数定義時にselfがつくメソッドとselfがつかなメソッドが混在している場合がある。

それぞれに名称があり用途、呼び出し方が異なる。

##目次

1. [それぞれの要点まとめ](#それぞれの要点まとめ)
2. [確認用の実例](#確認用の実例)
3. [クラスメソッドとインスタンスメソッドの用途の違い](#クラスメソッドとインスタンスメソッドの用途の違い)
4. [実用的な実例（シンプルなの）](#実用的な実例シンプルなの)



<br>
##それぞれの要点まとめ
それぞれの関係をまとめると以下のようになる。

| 項目 | selfあり | selfなし |
|:-:|:--|:--|
| メソッドの名称  | クラスメソッド  | インスタンスメソッド  |
| 対象  | クラス全体  | インスタンスのみ  |
| メソッド名の例  | self.hello1  | hello2  |
| 呼び出し方の例  | クラス名.hello1  | クラス名.new.hello2  |


<br>
##確認用の実例
実用性を無視してそれぞれの関数を定義し確認してみる。

```ruby:
class TestClass
  #selfありのメソッド
  def self.hello1
    p "self hello 1"
  end

  #selfなしのメソッド
  def hello2
    p "hello 2"
  end
end
```


クラス`TestClass`の中に、以下２つのメソッドがある。

- `self.hello1`　：クラスメソッド
- `hello2`　：インスタンスメソッド


それぞれの呼び出し方は以下のようになる。

####クラスメソッドの呼び出し
selfありメソッドを呼び出す方法

```ruby:selfありメソッドを呼び出す
TestClass.hello1
=> "self hello 1"

#または
::TestClass.hello1
=> "self hello 1"
```

クラス名をオブジェクトとして直接メソッドを実行すればOK。


####インスタンスメソッドの呼び出し
selfなしメソッドを呼び出すためには、**インスタンスを作成し、作成したインスタンスに対してメソッドを実行する**必要がある。


```ruby:selfなしメソッドを呼び出す
#インスタンスを生成し代入
inst = TestClass.new

inst.hello2
=> "hello 2"

#or
#インスタンスを生成し直接実行
TestClass.new.hello2
=> "hello 2"
```


<br>
##クラスメソッドとインスタンスメソッドの用途の違い
**クラスメソッドはすべてのインスタンスで有効**なため、商品点数や人数の総合計を算出するメソッドとして用いられることが多い。

**インスタンスメソッドはそのインスタンスのみで有効**なため、商品の生成や人の生成などで使われることが多い。


<br>
###実用的な実例（シンプルなの）
商品カテゴリ毎に商品を登録するインスタンスと、すべてのカテゴリの商品数を足し合わせた商品点数を出力するクラスメソッドを定義したコード例。


```ruby:クラス定義
class Product
  ######クラス全体
  #クラス変数（初期値０で初期化）
  @@product_ttl_num = 0

  #クラスメソッド
  def self.ttl_num
    p "商品点数：　#{@@product_ttl_num}"
  end

  #####インスタンス毎
  #インスタンス生成時に自動で実行するメソッド
  def initialize(category)
    @product_category= category
    @product_list = []
  end

  #インスタンスメソッド（追加用）
  def add(name)
    @product_list.push name

    #クラス変数に１を追加
    @@product_ttl_num += 1
  end
end
```

クラスの定義は以上。次にインスタンスを生成する。
<br>

```ruby:インスタンスの作成
##インスタンスの生成（phoneカテゴリ）
phone = Product.new(phone)

#インスタンスメソッド実行
phone.add("iphone6s")
phone.add("iphone12pro")


##インスタンスの生成(codesカテゴリ)
codes = Product.new(codes)

#インスタンスメソッド実行
phone.add("USB typeC")
phone.add("USB3.0")
```

phoneとcodesの２つのインスタンスを作成し、それぞれに商品を２つづつの計４つ登録。


<br>

```ruby:クラスメソッドの実行
#クラスメソッド実行
Product.ttl_num

=> "商品点数：　4"
```

クラスメソッドを実行すると、すべてのインスタンスの商品の合計点数を得られる。
Logrotate の使い方

Web サーバーでサブドメインなどを作成し、標準以外の場所にログを吐き出した場合、Logrotate の設定を追加しないと、ログがどんどん大きくなります。


Logrotate の使い方を示します。

テスト用データの作成

/var/log/test_dir にテスト用の log ファイルを作成します。

```text
# tree test_dir/
test_dir/
├── access.log
├── error.log
└── sample.log
```

設定ファイルの作成

```text:/etc/logrotate.d/test-service
#
#	test-service
#
/var/log/test_dir/*.log {
    ifempty
    dateformat .%Y%m%d
    missingok
    compress
    daily
    rotate 3
}
#
```

Logrotate を実行します。

```bash
sudo logrotate -fv /etc/logrotate.d/test-service
```

実行後のログの様子

```text
# tree test_dir/
test_dir/
├── access.log.1.gz
├── error.log.1.gz
└── sample.log.1.gz
```
YouTubeのPython解説を覚え書き。

Learn Python - Full Course for Beginners [Tutorial]
https://www.youtube.com/watch?v=rfscVS0vtbw
(英語字幕は ところどころ間違っているので 注意が必要。)

***
2:14 -
python download
https://www.python.org/downloads/
Python 3 or Python 2?
Python 3 は 今後も利用されていくバージョンで、サポートもされているため、このコースではこちらを利用します。
Python 3 は 初心者が学ぶのに適しています。
(2020-12-18 現在、Python 3.9.1 のみ ダウンロードリンクがあった。)

次のインストール中のオプション ２つ:
Add Python 3.9 to PATH
Disable path length limit
これらは どちらも設定せずに インストールを完了するといいらしいです。(参考: https://gammasoft.jp/python/python-install-on-windows/)

***
4:53 -
Choose text editor
IDE - integrated development environment
PyCharm Community Edition を ダウンロードする。(現在 最新バージョンは 2020.3)
https://www.jetbrains.com/ja-jp/pycharm/download/#section=windows

installation Options
通常は何もチェックしなくて構いませんが、必要な場合は適宜チェックしてください。(参考: https://gammasoft.jp/python/pycharm-install-on-windows/)

***
6:42 -
Setup & Hello World

7:07 -
動画内の旧バージョンのPyCharmでは 右下にConfigureのメニューがあるが、最新版の2020.3では 画面左 Customizeタブの "All settings..." から 設定ができるみたい。
また、動画ではAppearanceのThemeをDarculaに変更していたが、最新版ではデフォルトからDarculaだった。

7:49 -
動画内では"Interpreter: "というオプションだけだが、最新版の初回起動時では New enviroment using: Virtualev と なっており、Base interpreterが"...Python39\python.exe"になっていれば良いようだ。
オフショア開発におけるリモートチームの管理方法

オフショア開発では、リモートチームの管理がよく問題になってきます。

開発者チームが現場にいない場合、仕事の品質はちゃんとコントロールできるのでしょうか？また、リモートチームとはどのようにコミュニケーションを取り、どのようにタスクを割り当てれば良いでしょうか？

「日本企業対オフショアリング。オフショアリングがうまくいかない日本企業はなぜ多いのか?」Mobilunityオンラインウェビナーでは、Tokyo Digital Music Syndicates社のCTO / Technical Directorの小松純氏がリモート開発チームとの日々の関わりの課題についてご講演いただき、それぞれの質問について説明しました。

リモートチームを管理するには、
・経験の長いシニアのオフショアエンジニアにチームリードの役割を担当してもらう。なぜなら、他のオフショアメンバーとのコミュニケーションのハブになってもらい、困りごとの解決などをサポートしてもらうことができるからだ。
・タスクで何を期待するかを伝えることに重点的に時間とパワーを割く
最初からタスクごとの説明を書ききったり資料をまとめたりするのは難しくても、最低限ラフな箇条書きやサマリーのメモだけでも書いて伝えて、不明点を質問してもらえるようにする
・日常的にCallで顔を合わせて話をするリズムを作る
何かストレスを抱えていたりしないかなどを確認し、問題があればしっかり話をして早めに対処する
・日常のコミュニケーションの中心はSlackでのテキストチャット
Callだと聞き取れなくて誤解が発生しやすいので、大事な話はテキストベースで

より具体的に下記のリンクより小松氏のプレゼンテーション全体を確認できます。
https://www.youtube.com/watch?v=-at6QEAdqpo
【備忘録】GCEでのLaravelの環境構築

GCEでLaravelの環境構築をよく行うので備忘録です。
間違い等ございましたら、ご指摘いただけますと幸いです。

## 目次
- 構築する環境
- PHPの導入
- Gitの導入
- Composerの導入
- Apacheの導入
- Laravelの導入
- LaravelとApacheの設定

## 構築する環境
- debian 10
- PHP 7.3
- Composer
- Laravel 6.0
- git
- Apache2

## PHPの導入
パッケージ一覧を更新

```
sudo apt update && sudo apt -y upgrade
```

PHP7.3 と 必要なPHPモジュールのインストール

```bash
sudo apt-get install php7.3 php-pear
sudo apt-get install libapache2-mod-php7.3 php7.3-xml php7.3-gd php7.3-opcache php7.3-mbstring php7.3-curl zip unzip php7.3-zip php7.3-mysql
```

PHPが導入されたか確認

```bash
php -v
```
バージョンが表示されればOK!

## Gitの導入
```bash
sudo apt-get install git
```

## Composerの導入
composer-setup.phpのダウンロード

```bash
curl -sS https://getcomposer.org/installer -o composer-setup.php
```

[公式サイト](https://getcomposer.org/download/)にてHash値を確認し、変数に格納

```bash
HASH=公式サイトで確認したHash値
# (v2.0.8の場合は756890a4488ce9024fc62c56153228907f1545c228516cbf63f885e036d37e9a59d27d63f46af1d4d07ee0f76181c7d3)

php -r "if (hash_file('SHA384', 'composer-setup.php') === '$HASH') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
# 実行結果: Installer verified

sudo php composer-setup.php --install-dir=/bin --filename=composer
# 実行結果
# All settings correct for using Composer
# Downloading...

# Composer (version 2.0.8) successfully installed to: /bin/composer
# Use it: php /bin/composer
```

Composerが導入されたか確認

```bash
composer

# 実行結果
#    ______
#   / ____/___  ____ ___  ____  ____  ________  _____
#  / /   / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
# / /___/ /_/ / / / / / / /_/ / /_/ (__  )  __/ /
# \____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
#                     /_/
# Composer version 2.0.8 2020-12-03 17:20:38
```

Composerの文字がデカデカと出力されればOK!!

## Apacheの導入
Apacheと必要なモジュールのインストール

```bash
sudo apt-get install apache2
sudo a2dismod mpm_event
sudo a2enmod mpm_prefork
sudo systemctl restart apache2
```

## Laravelの導入
Laravelの導入場所に移動

```bash
cd /var/www/html
```

/var/www/html内のユーザーの権限を変更

```bash
sudo chown -R ユーザー名 /var/www/html
```

既存のプロジェクトを使用する場合は、gitでcloneする
新規でプロジェクトを作成する場合は、

```bash
sudo composer create-project --prefer-dist laravel/laravel プロジェクト名 "6.*"
```

権限の変更

```bash
sudo chgrp -R www-data /var/www/html/プロジェクト名
sudo chmod -R 775 /var/www/html/プロジェクト名/storage
```

## LaravelとApacheの設定

```bash
cd /etc/apache2/sites-available
sudo nano プロジェクト名.conf
```

プロジェクト名.confの記述は、

```conf:プロジェクト名.conf
<VirtualHost *:80>
    ServerName 使用するサーバー名(なければプロジェクト名).com

    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/html/プロジェクト名/public

    <Directory /var/www/html/プロジェクト名>
        AllowOverride All
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
```

次にsites-availableディレクトリからsites-enabledディレクトリへのシンボリックリンクの変更,
apacheの再起動を行います。

```bash
sudo a2dissite 000-default.conf
sudo a2ensite プロジェクト名.conf
sudo a2enmod rewrite
sudo service apache2 restart
```

以上で設定は終了です！
Laravelの設定やDBはその都度で！！
Amazon Transcribeで日本語会話を文字起こししてみた

インタビュー動画の記事作成をする機会があり、動画を再生して、少し戻って。。。というのが面倒だったので、音声をなんとか一発で文字起こしできないかを調べていたところ、いくつかツールが存在していることを知りました。

その中でも普段から馴染みのあるAWSの「Amazon Transcribe」を試しに使ってみたので、その感想をメモとして残します。

## Amazon Transcribeとは

音声ファイルの文字起こしをしてくれるAWSのサービスです。

>Amazon Transcribe は、自動音声認識 (ASR、automatic speech recognition) と呼ばれる深層学習プロセスを使って迅速かつ高精度に音声をテキストに変換します。
引用：https://aws.amazon.com/jp/transcribe/

料金も15秒の音声の文字起こしで0.006 USDで、1時間でも1.44 USDととてもリーズナブルです。他の文字起こしサービスでは1時間で2000円を超えることも多いので、値段設定はさすがAWSですね。登録後12ヶ月は1ヶ月あたり60分の無料利用枠もあるので、気になる方は是非試してみてください。


## 使ってみた

使い方もとても簡単です。

- s3にファイルをアップロードする

- Amazon Transcribeでjobを作成する

以上です。

操作手順等は以下の記事を参考にさせていただきました。ありがとうございます。
https://qiita.com/shimizu-nowhere/items/2508f2e87daee8cb1083
https://qiita.com/kooohei/items/2580addd6c1bbc8f1c34


以下が出力結果のサンプルです。内容は編集しています。
単語ごとに出力されて、それぞれの精度まで数値で出力されます。

```json
{
    "jobName": "amazon_transcribe",
    "accountId": "hogehogehoge",
    "results": {
        "transcripts": [
            {
                "transcript": "hoge fuga piyp"
            }
        ],
        "items": [
            {
                "start_time": "0.04",
                "end_time": "0.41",
                "alternatives": [
                    {
                        "confidence": "0.9699",
                        "content": "hoge"
                    }
                ],
                "type": "pronunciation"
            },
            {
                "start_time": "0.42",
                "end_time": "0.79",
                "alternatives": [
                    {
                        "confidence": "0.5512",
                        "content": "fuga"
                    }
                ],
                "type": "pronunciation"
            },
            {
                "start_time": "0.79",
                "end_time": "1.45",
                "alternatives": [
                    {
                        "confidence": "0.9987",
                        "content": "piyo"
                    }
                ],
                "type": "pronunciation"
            }
        ]
    },
    "status": "COMPLETED"
}
```

## 感想

以下使ってみての感想です。

### 精度に関しては予想よりもよかった

英語ならまだしも日本語の文字起こしは難しいんじゃないかと思っていて、正直あまり期待していませんでした。ところが、実際に使ってみると単語単位では予想以上に高精度で文字起こしができており、文章単位でもところによっては精度が高かったです。

### 文字起こしまでの操作が簡単

AWSを少しでも触ったことのある人ならば、文字起こし完了までのハードルはとても低いと思います。

### 対話の音声データでは利用ハードルがグッと上がる

今回使用したデータはインタビューの音声データで、登場人物が二人いました。そのため、文章や単語の文字起こしができても、どちらが発言したのかはインタビューの流れから確認する必要があります。また、同時に発言しているシーンでは精度が極端に低下していました。利用シーンは考える必要がありそうです。

## 終わりに

実際にAmazon Transcribeを使ってみると、想像以上に精度は高かったです。ただ、所々でミスがあったりするので、あくまでサポート的な役割でこのサービスは使ってみるのがいいと思いました。AWSのアップデート速度は凄まじいので、日本語の識別精度もどんどん良くなっていくと思います。


### 参考
https://aws.amazon.com/jp/transcribe/
https://qiita.com/shimizu-nowhere/items/2508f2e87daee8cb1083
https://qiita.com/kooohei/items/2580addd6c1bbc8f1c34
ざっくりとしたWebサーバーの仕組み

# はじめに
DMM WebCampでメンターをしている白瀬(@juvenile-develop)です。
Webサーバー自体の仕組みを大雑把に説明しようと思います。

# Webの概要
インターネットにおいてWebページをクライアントのリクエストに対してレスポンスを返してくれるのがWebサーバーのお仕事です。
![WebRequestResponse.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/852615/2055fc9e-384d-abc3-1e7b-bb7be63ed780.png)

リクエストの中身を作ってWebサーバーに送りレスポンスの中身を解析してユーザに表示するのがブラウザのお仕事です。
実際にリクエストの中身とレスポンスの中身を見てみましょう。

cURLというツール(及びライブラリ)を使うと通信内容を見れます。

```bash:curl
$ curl -v -X GET http://example.com
```
curlが作成したHTTPのリクエストデータが出力されます。

```bash:Request
> GET / HTTP/1.1
> Host: example.com
> User-Agent: curl/7.68.0
> Accept: */*
>
```

そして接続と自己紹介がうまくいくとレスポンスが返ってきます。

```bash:Response
< HTTP/1.1 200 OK
< Age: 463948
< Cache-Control: max-age=604800
< Content-Type: text/html; charset=UTF-8
< Date: Sun, 29 Nov 2020 23:58:35 GMT
< Etag: "3147526947+ident"
< Expires: Sun, 06 Dec 2020 23:58:35 GMT
< Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT
< Server: ECS (sjc/16DD)
< Vary: Accept-Encoding
< X-Cache: HIT
< Content-Length: 1256
<
```

これはレスポンスヘッダといわれる部分です。
１行目と最後の行以外は割愛します。
１行目はステータスが返ってきます。EC2でサーバーにDeployした方はよく見たかもしれませんが500エラーや404エラーはここに入っています。
最後の行はBodyの大きさが入っています。

```html:
<!doctype html>
<html>
<head>
    <title>Example Domain</title>

    <meta charset="utf-8" />
    <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <style type="text/css">
    body {
        background-color: #f0f0f2;
        margin: 0;
        padding: 0;
        font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;

    }
    div {
        width: 600px;
        margin: 5em auto;
        padding: 2em;
        background-color: #fdfdff;
        border-radius: 0.5em;
        box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02);
    }
    a:link, a:visited {
        color: #38488f;
        text-decoration: none;
    }
    @media (max-width: 700px) {
        div {
            margin: 0 auto;
            width: auto;
        }
    }
    </style>
</head>

<body>
<div>
    <h1>Example Domain</h1>
    <p>This domain is for use in illustrative examples in documents. You may use this
    domain in literature without prior coordination or asking for permission.</p>
    <p><a href="https://www.iana.org/domains/example">More information...</a></p>
</div>
</body>
</html>
```

レスポンスボディ(HTML)が返ってきます。
ブラウザはこのHTMLを解析して画面に出力します。
![Example Domain - Google Chrome 2020_11_10 15_11_17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/852615/3b7e6332-71e9-c209-6e86-7a386c8dca62.png)

#まとめ
これがWebサーバーのざっくりとした仕組みです。
これだけ？と思うかもしれませんが基本はこれだけです。

注意すべき点は、RubyやPHP, Perlなどのサーバーサイドプログラムのコードはサーバー内で完結しているため、クライアント側から見ることができないということです。
クライアント(ブラウザ)が見ることができるデータはHTML, CSS, JavaScriptに限ります。

![WebSystem.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/852615/cce37244-c049-ca7c-7f2a-8d4ba2c82591.png)

データの流れ、データを持っている人を意識することによってアプリを作る際に迷わずバグも少なく作れます。また他の人が作っているモノ(プログラム以外でも)をそれがどのようにできているのかを考えるクセを付けることによって論理的な思考や理解がしやすくなります。
[Swift] ByteArrayとHexStringを相互変換する

# 実装

```String+.swift
extension String {
    func toBytes() -> [UInt8]? {
        let length = count
        if length & 1 != 0 {
            return nil
        }
        var bytes = [UInt8]()
        bytes.reserveCapacity(length / 2)
        var index = startIndex
        for _ in 0..<length / 2 {
            let nextIndex = self.index(index, offsetBy: 2)
            if let b = UInt8(self[index..<nextIndex], radix: 16) {
                bytes.append(b)
            } else {
                return nil
            }
            index = nextIndex
        }
        return bytes
    }
}
```

```Data+.swift
extension Data {
    func toHexString() -> String {
        var hexString = ""
        for index in 0..<count {
            hexString += String(format: "%02X", self[index])
        }
        return hexString
    }
}
```

# 動作確認

```Test.swift
func testBytesHexConversion() {
    let bytes: [UInt8] = [0, 1, 254, 255]
    XCTAssertEqual("0001FEFF", Data(bytes).toHexString())
    XCTAssertEqual(bytes, "0001FEFF".toBytes())
}
```

# 参考

https://stackoverflow.com/a/42731691/6570300
TypeScriptにModuleから入門してみた話［TS×Express］

## はじめに

普段サーバーサイドはJacaScript×Expressで書いている私ですが、
ロジックが複雑になってくると、さすがに型なしでは辛いなーと感じてきました。
また、補完などの面からもTypeScriptを導入してみたいとは常々思っていました。

ただ、Expressを使ったアプリを全部TSに移行するとなると、
express-tsとか諸々を入れることになって、
正直めんどくさいし、トラブりそうだなーと思ってました。

そこで、複雑な場所だけをModuleとして切り出して、
そこだけをTSで書いて、それ以外の部分はJSで書いていけば、
気軽にTSを導入しつつ、トラブルも減らせそうだなーと考えました。

それで、部分的にTSを導入する方法を調べたら
意外と簡単に出来そうな雰囲気だったので、
実際にTSを使ってHelloWorldをしてみました！

## まずはいつも通りJSで作成
最初にターミナルで諸々を作成

```sh:Terminal
# プロジェクトフォルダを作成
$ mkdir express-ts
$ cd express-ts

# プロジェクトの作成
$ yarn init
> （いろいろ入力）

# Expressをローカルインストール
$ yarn add express

# 必要なファイルを作成
$ touch app.js
$ touch utils/utils-js.js
```

次にapp.jsにHelloWorldを記述

```js:app.js
const express = require('express')
const app = express()
const port = 8000

// 自作モジュールの読み込み
const utilsJs = require('./utils-js')

app.get('/', (req, res) => {
  res.send(utilsJs.joinText('HelloWorld!', 'From Module!'))
})

app.listen(port, () => {
  console.log("App listening at http://localhost:" + port)
})
```

あと、使用するモジュールも記述

```js:utils-js.js
// 文字を足し算する関数
const joinText = (text1, text2) => text1 + " " + text2

// 関数をモジュールとして出力
module.exports = { joinText }
```

最後に、起動用のコマンドをpackage.jsonに追記して

```jsonc:package.json
{
  "scripts": {
    "start": "node app.js"
  }
}
```

これで``yarn start``でアプリを起動し、
[localhost:8000](http://localhost:8000)にアクセスすると、HelloWorld FromModule! と問題なく表示されました。


## TSを導入
いよいよTSを導入してみます。
どうもtypescriptとts-nodeを入れればいいみたいです。

```sh:Terminal
# 必要なものをインストール
$ yarn add -D typescript ts-node

# TSの設定ファイルを作成
$ touch tsconfig.json

# TSでのモジュールを記述するファイルを作成
$ touch utils-ts.ts
```
そして、いい感じにTSの設定を記述

```jsonc:tsconfig.json
{
  "compilerOptions": {
      "target": "es2018",
      "module": "commonjs",

      // jsファイルもコンパイルが通るように設定
      "allowJs": true,
      
      // ストリックモードは有効に
      "strict": true,  

      // 入出力先を設定
      "rootDir": ".",
      "outDir": "./dist",

      // デフォルトで書かれているもの
      "esModuleInterop": true,
      "skipLibCheck": true,
      "forceConsistentCasingInFileNames": true
  },
  "include": [
    "app.js"
  ],
}
```

次に、さっそくTSでモジュールを記述

```ts:utils-ts.ts
// 文字を足し算する関数
const joinText = (text1: string, text2: string): string => {
  return text1 + " " + text2
}

// 関数をモジュールとして出力
export { joinText }
```

そして、TSでのモジュールを組み込むためapp.jsを追加・修正

```js:app.js
// 自作モジュールの読み込み
const utilsJs = require('./utilsJs')
const utilsTs = require('./utilsTs') //ここ追記

app.get('/', (req, res) => {
  res.send(utilsTs.joinText('HelloWorld!', 'From Module!')) //ここ修正
})
```

最後にpackage.jsonにある起動用コマンドを修正して

```jsonc:package.json
{
  "scripts": {
    "start": "ts-node app.js",
    "build": "tsc"
  }
}
```

これで`yarn start`してみると、内部でTSをコンパイルしつつアプリを起動できました。
いつも使用している`node app.js`と同じように使えていい感じ！

また``yarn build``すると、/dist にJSにコンパイルされたファイルが出力できる模様。
実際に稼働させるときは、このファイルをデプロイすればいいみたい。

## おわりに

TypeScriptって敷居が高いイメージだったけど、思ってたより簡単に導入できました。
（特にトラブルもなく、逆にあっけなかった気もします・・ｗ

アプリを全部TSにするのは大変でも、部分的なモジュールから導入して、
TSの恩恵（安全性や補完など）を受けれるのはとてもいい感じ。
しかし、安全性という意味では全部TSのアプリにはとてもかなわないというのも事実。

やっぱり、全部TSでアプリを作るってよりは敷居は圧倒的に低いので、
全部TSではなく、メインはJSで部分的にTSってのも選択肢に入る印象！
MySQL パスワードが入力できない　表示されない

超初心者向けですが…
この記事に辿り着いたという事は
パスワードを入力しても「＊＊＊＊＊」もカーソル移動しない、何も表示されない、私は小一時間苦しみました。コマンドプロンプトだとちゃんと「＊＊＊＊＊」が表示されると思いますが、中には非表示な仕様のもあるだけでキーボードになんの問題もありません。


```sql:pass
Enter password>
```

カーソルが微動だにしなくてもめげずにパスワードを入力して、`Enter`してください。
ログインできます。
[メモ]discord.jsとDiscordでPCログインアラートを作る。

# はじめに

これはPCがログインされる度に、Discordで警告を発せられるマシーンです。

# ソースコード

startup.js

```js
const Discord = require('discord.js');
const client = new Discord.Client();
const time = new Date();
var os = require("os");
var ip = require('ip');

client.on('ready', () => {
    const Channel = client.channels.cache.get("DISCORD_CHANNEL_ID");
    Channel.send(`<@DISCORD_USER_ID>\nTIME : ${time}\nHSOT NAME : ${os.hostname()}\nIP : ${ip.address()}\nDescription : PC is just started up.`);
    console.log(`\nTIME : ${time}\nHSOT NAME : ${os.hostname()}\nIP : ${ip.address()}\nDescription : PC is just started up.`);
});

client.login('DISCORD_BOT_ID');

/*
    ip.address() が使えない場合は、cmdでnpm i ipを入力してください。
    https://www.npmjs.com/package/ip
*/

```

run.bat

```bat
node X:\ファイルパス\startup.js

```

# セットアップ

1.win + R
2.shell:startupを入力します。
3.run.batを`スタートアップ`に置きます。
4.startup.jsを`X:\ファイルパス\`に置きます。

# 実行結果

cmd.exe
![003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/571953/d3644920-25ac-bfe5-3eff-bd22bbbd9559.png)

Discord
![002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/571953/f0b9a54d-255e-40ef-8fbe-6f11f35cab0a.png)


# まとめ

このマシーンはいくつかのデメリットがあります:
1.cmd.exeが起動されたら、自動的に閉じることはできません。
2.PCがログインされる度に警告を発せられますが、PCが起動されてログインされていない場合は警告を発せられません。
3.cmd.exeが起動されてすぐ閉じられたら、警告を発せられません（プログラムはまだ実行されていませんから）。
AngularのPDF表示ライブラリの調査結果

PDFを表示する機能の調査概要を記載します。
時間があれば、gitのレポジトリ作成してさらしますが、メモがわりとお考えください。

#### 要件

1. 柔軟にUIの付け替えが可能
2. 同一ページ内部で複数のPDFが表示できる
3. pdfの文字内検索ができる
4. 指定したページに遷移または、移動することができる


### 考慮にいれたライブラリ

1. ng2-pdf-viewer [npm](https://www.npmjs.com/package/ng2-pdf-viewer) / [git](https://github.com/VadimDez/ng2-pdf-viewer#readme)
2. ng2-pdfjs-viewer [npm](https://www.npmjs.com/package/ng2-pdfjs-viewer) / [git](https://github.com/intbot/ng2-pdfjs-viewer#readme)
3. ngx-extended-pdf-viewer [npm](https://www.npmjs.com/package/ngx-extended-pdf-viewer) / [git](https://github.com/stephanrauh/ngx-extended-pdf-viewer)

### GitHub / npm trendsから

#### 考察

ng2-pdf-viewerは安定して、利用率.Contribute数は高い。
ngx-extended-pdf-viewerについては直近数値を伸ばしており、多機能。

#### Table

| library | used by | Contributes |
|:---|:----:| :---: |
| ng2-pdf-viewer | 3.9k | 24 |
| ng2-pdfjs-viewer | 209 | 4 |
| ngx-extended-pdf-viewer | 449 | 14 |

_2020/12/16現在_

#### 比較表

![ng2-pdfjs-viewer-vs-ng2-pdf-viewer-vs-ngx-extended-pdf-viewer-npm-trends.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144543/5b98b074-2f5f-dae2-6b2d-56f8a12f4860.png)

> [npm trends](https://www.npmtrends.com/ng2-pdfjs-viewer-vs-ng2-pdf-viewer-vs-ngx-extended-pdf-viewer)より引用

### 機能比較

#### 必要機能の確認

1. 柔軟にUIの付け替えが可能
2. 同一ページ内部で複数のPDFが表示できる
3. pdfの文字内検索ができる
4. 指定したページに遷移または、移動することができる

#### 必要機能の正誤表

| library | UIの付け替えが可能 | 複数のPDFが表示できる | pdfの文字内部検索ができる | 指定したページに遷移または、移動することができる |
|:---|:----:| :---: | :---: | :---: |
| ng2-pdf-viewer | △*1 | ○ | ○ | △*2 |
| ng2-pdfjs-viewer | × | × | ○ | ○ |
| ngx-extended-pdf-viewer | △*3 | △*4 | ○ | ○ |

```
*1 : thumbnailについては、本体の全てのページがレンダリングした時でないと全てのPDFは表示されない
*2 : 機能の提供はされておらず、自力で実装する必要がある
*3 : 機能の提供はあるが、一瞬表示されるバグが存在しているためあまりUXがよいとは言えなかった
*4 : 同一のページ内部で表示することができず、1つのページに一つのPDFしか表示することができない
```

### 基本機能

#### [ng-pdf-viewer](https://www.npmjs.com/package/ng2-pdf-viewer)

##### ページ情報の取得

- current pageの取得
- total pageの取得

##### その他機能

- 回転
- 拡大/縮小
- PDFのサイズ調整

##### Rending Condtion
- テキストとしてレンダリング
- rendering conditionの取得

##### 検索
- 検索
- 検索のヒット数取得
- 検索該当のハイライト

#### [ng-pdfjs-viewer](https://www.npmjs.com/package/ng2-pdfjs-viewer)

##### ページ情報の取得

- current pageの取得
- total pageの取得

##### その他機能

- 回転
- 拡大/縮小
- PDFのサイズ調整
- ダウンロード
- 指定ページへのスクロール
- ブックマーク

##### Rending Condtion

- テキストとしてレンダリング
- rendering conditionの取得

##### 検索

- 検索
- 検索のヒット数取得
- 検索該当のハイライト


#### [ngx-extended-pdf-viewer](https://www.npmjs.com/package/ngx-extended-pdf-viewer)

##### ページ情報の取得

- current pageの取得
- total pageの取得

##### その他機能

- 回転
- 拡大/縮小
- PDFのサイズ調整
- ダウンロード
- 指定ページへのスクロール
- ブックマーク
- 認証機能
- メニューのカスタマイズ
- 言語指定
- パスワード解除
- PDF情報の表示

##### Rending Condtion

- テキストとしてレンダリング
- rendering conditionの取得

##### 検索

- 検索
- 検索のヒット数取得
- 検索該当のハイライト
Too many open files になったとき

# 概要
- Jenkinsサーバで、 `Caused by: java.io.IOException: error=24, Too many open files
` のようなエラーが発生
- FD(File Descriptor)が枯渇しているっぽいのでulimitを上げる
- OSはUbuntu 14.04

# /etc/security/limits.conf

以下の記述を追加

```
* soft nproc 65535
* hard nproc 65535
* hard nofile 65535
* soft nofile 65535
```

rebootして `ulimit -n` すると...

```
$ ulimit -n
65535
```
良さそう。

# ところがJenkinsは自分で勝手に上書きをしていた...

[Jenkinsから見えるulimitの結果がおかしい場合](https://qiita.com/kumagi/items/f65690508a48e346df5b)

まさにこれ。

`/etc/default/jenkins` を書き換えて、 service restartして、真の対応完了。

（Systemd化されている最近のやつは別の箇所を編集する必要があるのであしからず）
【gRPC】.protoファイル更新後の再起動処理。（prototool利用時）

個人メモです。

.protoファイルを更新後以下処理を行う。

```:
#(1)ディレクトリを移動
cd grpcの設定ファイルがあるディレクトリ

#(2)aliasの読み込み
source aliases.sh

#(3)bashでコンテナを起動（本番はaliasで代用）
docker-compose run --rm prototool bash


#(4)Protbufファイルのコンパイルとスタブの作成
bash-5.0# prototool generate
bash-5.0# eixt

#(5)イメージ再構築とコンテナ起動
docker-compose build イメージ名 && docker-compose up イメージ名
```

<br>
##主要な処理
###(3) `docker-compose run --rm prototool bash`

`docker-compose run`コマンドで、イメージからコンテナを作成し実行する。

```:docker-compose.yml
version: "3.7"
services:
  prototool:
    image: uber/prototool:1.8.1
    volumes:
      - .:/work
```

`image: uber/prototool:1.8.1`
prototoolはuberが開発したツール。

・`--rm`
このオプションはコンテナ起動後に、そのコンテナを削除する。
bashをexit後に`docker ps -a`で確認してもprototoolのコンテナは存在しない状態になる。


<br>
###(4)`prototool generate`
.protoファイルをベースに、スタブを生成する。
rubyに変換する場合は、

`.protoのファイル名.pb.rb`というファイルが生成される。

`pb`はProtocol Buffersの略。



<br>
###(5) `docker-compose build イメージ名 && docker-compose up イメージ名`

最終的にやりたいことは`docker-compose up イメージ名`による、指定したイメージの作成とコンテナの起動。

このイメージは別のイメージに依存しているため、`docker-compose build イメージ名`でコンテナを起動するために必要なイメージを再ビルドしておく。



<br>
###参考リンク
https://github.com/uber/prototool#prototool-generate
Functional Optionのネスト

初めてAdvent Calendarに投稿します!!
何かあればコメントいだだけるとありがたいですm(。。m）


次のコードを実行するとどうなるでしょうか？

```
package main

import (
	"fmt"
)

func main() {
	Step1("hello")
}

func Step1(v ...interface{}) {
	Step2(v, "world")
}

func Step2(v ...interface{}) {
	for _, obj := range v {
		for _, obj2 := range obj {
			fmt.Println(obj2)
		}
	}
}
```

A. 
hello
world

B.
world
hello

C.
コンパイルエラー

D.
panic（実行時エラー）


<details><summary>正解はこちら</summary>
正解はCです。
`Cannot range over 'obj' (type interface{})` でコンパイルエラーとなります。
</details>
Ubuntu Server 20.04.1 LTS と Windows10のデュアルブート環境作成

#0.Intro
基本この方の手順でいけます。
[Dual Boot Ubuntu Server 20.04 LTS and Windows 10 - A Step by Step Install Guide - (UEFI Tutorial)]
https://www.youtube.com/watch?v=yJeDV34GzqI
しかし、GPTという発想がないところからスタートしたのでこの動画のようになるまでが大変でした。
色々調べてPowershellのコマンドであるMBR2GPTにも行き着きましたが、それも上手くいかず。
結局、新しいPCだったのでWindowsは再インストールするところから始めています。

作業前の注意点としては、他のUbuntuとWindowsのデュアルブートについての記事でも指摘されていますが、
1.Windowsの高速スタートアップは切る
2.対象のストレージ以外は外しておいた方が良い。
3.CSMは切っておいたほうがいいかもしれない。
4.Secure Bootも切っておいたほうがいいかもしれない。
です。

[対象のマシンの構成]
【モデル名】GALLERIA ZZ
【グラフィック】NVIDIA GeForce RTX 2080 Ti
【CPU】Intel Core i9-9900K 3.60GHz
【メモリ】128GB
【ストレージ】SSD 1TB + HDD 4TB
【MB】Asrock z390 phantom gaming 4
【光学ドライブ】BD-RE
【LAN】Gigabit LAN

#1.本論
[Windows10]
まずストレージのGPT変換を行います。
1.インストールメディアで立ち上げる。(僕はDVDでした)
2.「コンピューターを修復する」を選択。
3.「トラブルシューティング」を選択。
4.「コマンドプロンプト」を選択。
5.diskpartで以下を作業
(ディスク一覧を表示)
list disk
(インストールしたいディスクを選択)
select disk 0
(全部クリア)
clean
(GPTフォーマットを行う)
convert gpt

6.diskpartを抜けて再起動。
7.インストールメディアから通常にインストール。
8.セットアップし起動。
9.ディスクの管理で「GUIDパーティションテーブル(GPT)」となっていることを確認。
![コメント 2020-12-18 063355.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66198/30ad7b4c-e9b3-ee6b-d3f6-60855395699f.png)

100MのEFIシステムパーティションも存在してるかと思います。
10.Windowsの領域をUbuntuに割り当てたい領域分だけ縮小。
11.生成された未割り当ての領域で「新しいシンプルボリューム」を作成する。
この際ドライブレターは割り当てない。フォーマットも必要ない。
![コメント 2020-12-18 06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66198/8cb462d3-d7c9-1357-1a97-a2f953e80a5d.png)
12.Windowsを終了。

[Ubuntu Server 20.04.1 LTS]
こちらもDVDからインストールしました。
手順としては[Guided storage configuration]の手前までは普通にインストールして下さい。
[Guided storage configuration]にたどり着いたら
[Custom storage layout]を選択
先ほど「新しいシンプルボリューム」で作成したボリュームを選択。Editでformatをext4を選択。マウントは自動で選択されると思いますが、「/」を選択。
選択すると自動で今選択したものと同時にWindowsのUEFIのブート領域も選択され、二つ並ぶと思います。

あとは普通のインストールの手順です。

以上でデュアルブート出来る用になっていると思います。起動順序はUEFIでお好みに。

#2.付記
デュアルブート出来るようになったのですがUbuntuの画面表示がsafe graphicでないと乱れるようになりました。これはなんでなんでしょうね。。。
大した問題ではないので適当に対応します。そもそもUbuntu Serverなので画面表示はどうでもよいですしw

なにぶん何回もできる作業でないのでキャプチャ少なくてすみません。
何かしらの参考になれば幸いです。
Jetpack ComposeのLaunchedEffectについて

Jetpack Compose で開発する上できっと使うことになるであろう `LaunchedEffect` についてみていこうと思います。

※この記事は Jetpack Compose 1.0.0-alpha09 時点の内容のため、stable までに大きく変わる可能性があります

## `LaunchedEffect` とは

- Composable がコンポジションに入る時に実行される関数
- コンポジションを離れる時に実行している処理をキャンセル
- 引数の subject が変更された時にも実行している処理をキャンセルして再度実行
- 実行する処理は `CoroutinesScope` で行われる

箇条書きすると上記のことを行う関数で、Composable が表示されるタイミングに何か処理を実行したい時に使用します。

## `LaunchedEffect` の使い方

ただ Composable が表示されるタイミングだけ処理をしたい場合は以下のように subject に Unit を指定します。

```kotlin
@Composable
fun SplashScreen(
    onTimeOut: () -> Unit
) {
    LaunchedEffect(Unit) { 
        delay(SplashWaitTime)
        onTimeOut()
    }
    ...
}
```

subject に値を渡す場合だと、例えば検索時のサジェストの処理に使えたりします。

```kotlin
@Composable
fun SearchScreen() {
    ...
    var searchQuery by remember { mutableStateOf("") }
    LaunchedEffect(searchQuery) {
        // execute search and receive result
    }
    ...
}
```

## `LaunchedEffect` の実装を覗いてみる

`LaunchedEffect` のコードをみると subject を remember で保存し、変更があれば処理を再実行するようになっています。

```kotlin
@Composable
@ComposableContract(restartable = false)
fun LaunchedEffect(
    subject: Any?,
    block: suspend CoroutineScope.() -> Unit
) {
    val applyContext = currentComposer.applyCoroutineContext
    remember(subject) { LaunchedEffectImpl(applyContext, block) }
}
```

`LaunchedEffectImpl` の方では Composable のライフサイクルを扱う `CompositionLifecycleObserver` でコンポジションに入った時に処理の実行、離れた時で `Job` のキャンセルを行っています。

```kotlin
internal class LaunchedEffectImpl(
    parentCoroutineContext: CoroutineContext,
    private val task: suspend CoroutineScope.() -> Unit
) : CompositionLifecycleObserver {

    private val scope = CoroutineScope(parentCoroutineContext)
    private var job: Job? = null

    override fun onEnter() {
        job?.cancel("Old job was still running!")
        job = scope.launch(block = task)
    }

    override fun onLeave() {
        job?.cancel()
        job = null
    }
}
```

## 参考
- https://developer.android.com/reference/kotlin/androidx/compose/runtime/package-summary#launchedeffect_1
- https://github.com/android/compose-samples
1年間人生の軌跡を記録してみた話

# はじめに
1年前ぐらいに書いた[人生を可視化しよう](https://qiita.com/kaku10/items/07fedca0110eae4123d6)という個人的に作ったものを１年間続けてみた所感記事です。

# やったこと
Google フォームに下表にある項目を1年間通して逐次入力していきました。元の記事から項目は少しアップデートしてかけた時間も記録するようにしました。また最終的には縦軸が幸福度、横軸が時間の人生グラフを作りたいと思ったので影響度だった項目は幸福度に変えました。
また重要なことですが、記録する対象はあくまで自分が残しておきたいものだけです。一挙一動すべて記録し続けるのは現実的ではないし疲れてしまうので。記録のために時間を掛けるのは生産的ではないとも思いました。

項目名 | 項目説明 | 必須項目
--- | --- | ---
Title | やったことが分かるタイトル | ○
Done at | やった日付 | ○
Happiness | 人生においてどれぐらい幸せだったか（-10〜10で表す） | ○
Spending hours | やったことにかけた大体の時間（0.25h単位） | 
Category | カテゴリ分類 | ○
Description | やったことの詳細説明 | 
Link | 関連リンク | 

## 概要図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445743/45c5ee85-ff84-107c-1ccf-62bb226b4edb.png)

## カテゴリについて
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445743/d9ec89c9-f9ab-27c1-84af-21b57915a879.png)
カテゴリ分けについてはざっくりこんな感じで分けています。フォーマットとして、「大分類名（小分類名）」という形にしていて、Google データポータルで見たときに下記のような計算フィールドを使えば大分類名の項目のみを抽出できるからです。

```
REGEXP_REPLACE(Category, '（.+$', '')
```

# 結果
Google フォームで入力したデータはスプレッドシートにDBライクな構造で記録されているのでGoogle データポータルでグラフ化することができます。今年の結果は下図のようになりました。また見た目のテンションを上げるためにところどころ英語にしてます。ぱっと見かっこいいしね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445743/f58935b4-48f5-f4a1-c2cd-38a45d00b170.png)
グラフを見ると11月が一番幸福な月でしたとか、コロナなのに遊んでばっかなのがバレて恥ずかしいとか、1年間振り返っていろいろな気付きを得ることができると思います。来年はインプット・アウトプット増やしてもっと生産的な活動ができるようになるといいですね。前年比で増えてるかどうかも分かるので来年の目標を数値に落とし込めるのは大きな利点かなと思います。

# 1年間続けての感想
運用コストが低いことは非常に良かったです。フォームのメンテも気軽にできますし、入力したあとやっぱりもっと幸福度高いなーと思ったときでも Spreadsheet なので変更が容易でした。
運用としては徐々に入力するのが気持ち面倒になっていき、週末まとめて一週間の出来事を入力するというかたちになりました。ただ、当初の想定通り記録をし続ける手間が小さかったのでそこまで苦ではなかったです。
当初は1週間間隔でレポートを見てやることを改善していければいいと思ったのですが、1週間だと出来事が少なく、あまり身振りを改善することができませんでした。1ヶ月、１年の間隔で見る分にはふりかえるには充分な示唆があるので、長期的な数値を見るツールとして活用していければいいと思います。
将来的に10年、20年続けて行って人に話せられる人生グラフを気長に作っていきたいと思います！
AssumeRoleをECS&Digdag環境で利用する

# やりたいこと

- AWS アカウント A

  - S3 に日次でファイルが置かれる

- AWS アカウント B

  - アカウント A の S3 のファイルを取得したい
  - 実行環境は ECS 上で動いている Digdag サーバー

AssumeRole は一時的なクレデンシャルを生成して、他の AWS アカウントからのアクセスを許可できるので、以下のようなセキュリティ的に避けたい設定を行わなくて済みます

- IAM ユーザーを作成し、AWS アクセスキー発行
- S3 の公開設定

# AWS アカウント A - 参照先

## ロールを作成

1. AWS コンソールからロールを作成
1. 信頼されたエンティティの種類を「別の AWS アカウント」にして、アカウント B のアカウント ID を設定
   - この段階では、アカウント B の root に権限が付与される（ここは後で変えます）
1. アカウント B 用のポリシーを作成して、ロールにアタッチ  
   以下は今回のやりたいことを実現する最低限のポリシーです

   ```json
   {
     "Version": "2012-10-17",
     "Statement": [
       {
         "Sid": "VisualEditor0",
         "Effect": "Allow",
         "Action": "s3:GetObject",
         "Resource": ["arn:aws:s3:::[バケット名]/*"]
       }
     ]
   }
   ```

# AWS アカウント B - 参照元

## AssumeRole のポリシーを作成

1. AWS コンソールからポリシーを作成

   ```json
   {
     "Version": "2012-10-17",
     "Statement": [
       {
         "Sid": "VisualEditor0",
         "Effect": "Allow",
         "Action": "sts:AssumeRole",
         "Resource": "arn:aws:iam::[アカウントAのID]:role/[さっき作ったロール名]"
       }
     ]
   }
   ```

1. ECS タスクのロールにこのポリシーをアタッチ  
   ECS タスクで使われているロールは、コンソールの ECS タスク定義から、「タスク実行ロール」で確認できます

# AWS アカウント A - 参照先

作成したロールの信頼関係タブから、以下のように編集

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::[アカウントBのID]:role/ECSタスクロール名"
      },
      "Action": "sts:AssumeRole",
      "Condition": {}
    }
  ]
}
```

さきほどは、アカウント B の root に権限を与えていましたが、ECS タスクロールに権限を与えるように変更しました

# 動作確認

## AWS CLI

Digdag のタスクが sh で、AWS CLI を使う場合

ECS タスクで使う Docker などで以下を用意する

`~/.aws/config`を作成

```sh
[profile assume]
role_arn = arn:aws:iam::[アカウントAのID]:role/[ロール名]
credential_source = EcsContainer

または

echo "[profile assume]" > ~/.aws/config
echo "role_arn = arn:aws:iam::[アカウントAのID]:role/[ロール名]" >> ~/.aws/config
echo "credential_source = EcsContainer" >> ~/.aws/config
```

```sh
aws s3 cp [コピー元] [コピー先] --recursive --profile assume
```

## Python

Digdag のタスクが Python の場合

```python
from sts import STS

# role_arn: arn:aws:iam::[アカウントAのID]:role/[ロール名]
# bucket: 参照先のバケット名
# key: 参照先のオブジェクトキー
# save_file_path: 保存先（Digdagコンテナー内）
class S3(object):
    def get_by_sts(self, role_arn, bucket, key, save_file_path):
        resource = STS().get_resource(role_arn, "s3")

        resource.Bucket(bucket).download_file(
            key,
            save_file_path,
        )
```

```python
import boto3


class STS(object):
    sts_client = boto3.client("sts")

    def get_resource(self, role_arn, resource_name):
        role_obj = self.sts_client.assume_role(
            RoleArn=role_arn,
            RoleSessionName="AssumeRoleSession",
        )

        resource = boto3.resource(
            resource_name,
            aws_access_key_id=role_obj["Credentials"]["AccessKeyId"],
            aws_secret_access_key=role_obj["Credentials"]["SecretAccessKey"],
            aws_session_token=role_obj["Credentials"]["SessionToken"],
        )

        return resource
```

`boto3.client("sts").assume_role`に RoleArn と任意のセッション名を渡して、一時的なクレデンシャルを発行しています
リスト・関数・for・while・with(open)・classと前回までの学習補足（Ruby学習後のPython初学）

#リスト
```python:test.py
list = ["0", "1", "2"]
# Rubyの配列の扱いに近い

list[0]
# 0番目の"0"が取り出される。
```

#関数
```python:test.py
def test(arg):
    return arg + 1

print(test(0))

#関数となるのがtest、引数となるのがargになる。
#関数の場合はreturnによる戻り値が必要である。
```
上記の場合、*test(0)*の*0*を引数として関数*test*の*arg*に入って、
戻り値として*+1*されて*return*されて出力されている

#for文
```python:test.py
for index in range(100)
    print index

#0回から99回まで数字を出力する

for i in range(1,101)
    print index

#1回から100回の範囲指定
#forとinの間はindexやiとされるのが通例。

#リストによるfor文
num = 0
list = ["0", "1", "2"]
for item in list:
    print list[num]
    num += 1

#リストの中身に対して全て実行される。リストの場合はforとinの間はitemが通例。
```

#while文
```python:test.py
num = 1 #カウンタ変数を初期化
while num <= 10:
    print(num)
    num += 1 #カウンタ変数を更新
```
*while*前の*num*の部分がカウンタ変数といい、*while*後の条件式で扱う。
なお、while文内でnumを更新し条件式に当てはまらないものを定めないとループするようになる。

#with(open)
```python:test.py
# with open('参照するfile', 'モードと呼ばれる実行処理') as file:
#     実行する処理の記述
```
例えばtest.pyの直上のディレクトリの中にtest.txtのfileがあった場合　**./test.txt** と
書くことで参照先をパス指定できる。
なお、モードと呼ばれる実行処理の中にはread（読み取り）の頭文字に当たる**r**や
write（書き込み）の頭文字に当たる**w**などがモードと飛ばれる実行処理になる。
（詳しい内容は次回以降の学習）

#class
```python:test.py
# class クラス名（頭文字は大文字）:
#    def __init__(self, プロパティ1, プロパティ2, ...,):
#        self.プロパティ1 = プロパティ1
#    def メソッド名(self):
#        return 実行する処理 

#例 
class Card: #Cardというクラス
    def __init__(self, date, user_name): 
        self.date = date
        self.user_name = user_name
    def message(self): #クラス内の関数をメソッドという、今回はmessageというメソッド
        return self.user_name + self.date #メソッドの戻り値

date_a = '2020-01-01'　
user_name_a = 'Test'

card_a = Card(date_a, user_name_a) #Cardクラスにcard_aというインスタンスを生成

print(card_a.message())　#card_aに対してmessageメソッドを実行してprint出力している
```

#前回までの補足
①VScodeでコードを書いてターミナルで実行できる環境を整えた所、実行するとエラーが出たので備忘録。#coding:utf-8の記述をしておかないと日本語を使用していることによるエラーが出る。
②予約語がPythonにもある
③print(type(調べたいもの))でstr型かint型かわかる。
④strでもintでもないブーリアン型がある。　例：T = True , N = False
⑤importできるモジュールに関してpypiで検索すると外部からのモジュールを探すことができる
有名なところでいうとNumPy、Pandas、Flask、Django等
よく忘れるstring.Format() メソッドの書式設定

VisualStudio デコーディングしている時、よく使うけれど忘れてしまう書式設定についてメモレベルで記録しておく

# 数値

### カンマ区切り、小数点以下固定

``` sample.cs
// 123,567.111
string numFormat = string.Format("{0:#,0.000}", 123456.111111);
```

``` sample.cs
// 0.000
string numFormat = string.Format("{0:#,0.000}", 0);
```

### 0の場合、「0」だけ表示

``` sample.cs
// 0
string numFormat = string.Format("{0:#,0.###}", 0);
```

### 0の場合、空白

``` sample.cs
// stringl.Empty
string numFormat = string.Format("{0:#,#.###}", 0);
```

### 先頭0埋め（コード化等に使用）

``` sample.cs
// 0123
string numFormat = string.Format("{0:0000}", 123);

```

# 日付

### 年4桁、月日2桁、24時間2桁、分秒2桁、ミリ秒表示

``` sample.cs
// 2021/01/01 13:01:01.123 
string dateFormat = string.Format(@"{0:yyyy/MM/dd HH:mm:ss.fff}", DateTime.Now);

```
【Python】欠損率(欠測率)一定割合以上の列を削除（Pandas）

# 背景
特徴量に欠損値(NaNとか)がある場合、平均や0で埋めたりする。しかし、欠損値の割合が増すにつれて平均や0で埋める割合が増えるわけだけど、それは同時に「その特徴量の大部分が同じ値なる」ことがある。パッと思いつく問題点は以下。

- 全て欠損値の場合、全てが同じ値で埋められて、分散が0に。(標準化ができない。)
- 全てが欠損値じゃない場合でも、交差検証で分割次第で値が全て同じに。

# 一定割合以上の欠損値を含む特徴量をモデルから削除
ということで、手っ取り早く一定の割合以上の欠損値を含む特徴量を削除してしまうことで、上記の問題を避けてしまうことにする。データはpd.DataFrameで与えられるとして手順は以下。

1. 各列の欠損値の合計を示す配列を取得
2. 1.をデータ数で割って割合にする
3. 一定の割合（rate）よりも欠損値を含む列番号をリストに追加していく
4. 3.のリストをpd.DataFrame.drop()に入れてまとめて削除

```python:main_in
import pandas as pd

def drop_manyNuNcolumns(df,rate):
    NaN_sum = df.isnull().sum() # 1.
    rate_NaN = NaN_sum / df.shape[0] # 2.
    drop_list = list() # 3.
    for i in range(rate_NaN.shape[0]-1):
        if rate_NaN[i] > rate:
            drop_list.append(i)
        else:
            pass
    return df.drop(data.columns[drop_list],  axis=1) # 4.
```
Herokuへデプロイする方法 ＆ アプリ名変えたい場合


前回投稿した記事「[git init から git pushまでの流れ](https://qiita.com/shiho0322/items/5a77e259ea2feeeb48c3)」の後、そのままHerokuへデプロイすることが多いので、その手順を自分用にまとめておきます。

間違っている箇所がありましたら、ご指摘いただけると助かります！！



## Gitでコマンドを打つ

```Git:Git
$ heroku create 〇〇(アプリ名)
```
〇〇(アプリ名)　のところは、入力せずに打つと、自動でHerokuがアプリ名生成してくれます。
後で変更も可能です。（後述）

ちなみにアプリ名は、すでに他の人が使っている名前だと、
`Name is already taken`と怒られます。

次に、下記のコマンドを打ちます。

```Git:Git
$ git push heroku main
```
main のところは master の場合もあります。
おそらくどっちかです。


## herokuのアプリ名を変えたい場合

リポジトリのディレクトリ内で変更する場合は

```Git:Git
$ heroku rename 〇〇(新アプリ名)
```

　
リポジトリのディレクトリ外で変更する場合は

```Git:Git
$ heroku rename 〇〇(新アプリ名) --app 〇〇(旧アプリ名)
```

こちらで可能です！



## 最後に
Herokuだと無料版は5つまで？しかアプリが作れないみたいなので
代わりのツールを探したいところです◎
何かオススメあったら教えてください～！
【Laravel(多対多)】php artisan migrateエラー(SQLSTATE[42S01]: Base table or view already exists:)が出た時

Laravelで多対多のデータベース接続を行っている際、php artisan migrateコマンドを入力すると、下記のエラーが出ました。
すでにデータベースにテーブルが存在すると言われて困惑しましたが、
一度データベースから直接テーブルを削除して、再度php artisan migrateを行うと問題なく解決しました。

何も変更を加えず、やり直すだけで解決する場合もあるので、一度試してみてください。
railsでパラメータを付けてredirect_toする一つの方法


いろいろかっこいいやり方はあるみたい
https://blog.kozakana.net/2015/10/redirect_to-with-parameter/

ですが、今回自分の状況的に(パラメータも一つだったので)

```ruby
redirect_url = ENV["HOST"] + "/hoge?h=" + hash値
redirect_to redirect_url
```

って感じでstringで生成して事足りてしまった。
似たようなことで悩んでる人いればご参考までに。
Macを新調したらやるべきセッティングリスト

個人的に入れるべきアプリ、セッティングなどをまとめました


#日本語・英数字の入力切替を簡易化
karabiner-elementsというアプリをDLすればUSキーボードでもcommandボタン一つで英数字・日本語入力の切替をすることができます。
詳しいやり方は以下記事を参照してください
[Mac USキーボードの日本語・英数字切替を左右のcommandキーのみで行う方法【karabiner】](https://qiita.com/Oyuki123/items/8fa3bfe804ec6d27e0c5)




#クリック時の速度・トラックパッドの設定

####タップで左クリック、二本指でタップで右クリック、三本指でドラックを割り当てる。
・[Mac トラックパッドで「3 本指のドラッグ」を有効にする
](https://support.apple.com/ja-jp/HT204609)

####四隅(ホットコーナー)に希望動作をセッティング

私は左下にログイン画面、

システム環境設定>Mission Control>ホットコーナー で好きな動作が割り当てられます。
詳しくは以下記事を参照
[【Mac】トラックパッドの四隅に操作を割り当てる！「ホットコーナー」が意外に知られていない便利機能](https://indoorheart.com/mac-hotcorner)


#ShiftItでタブ分割を効率化
[DLはこちら](https://github.com/fikovnik/ShiftIt/releases)
[詳しいDL方法などはこちら](https://pikawaka.com/tips/shiftIt)

#開発用

###XcodeのDL
完璧に忘れていたのですが、Xcodeがないとコマンドが使えないっぽい。
以下記事を参考にDL。
[2020年度版第4弾】新しい Mac を手に入れたらやること一式【ターミナル編・主に Homebrew の巻】
](https://bityl.co/4uz3)

・Gitの最初の設定

```
$ git config --global user.name 'Makito Katsube'
$ git config --global user.email 'katsubemakito@gmail.com'
```
参考記事: [Gitを使い始めたら一番最初にやりたい `git config`設定メモ](https://bityl.co/4v1i)


###HomeBrewのインストール
brewコマンドを叩けるようにする。

https://brew.sh/index_ja

ここからリンクをターミナルにコピペ。
PCのパスワードの入力が求められたり、returnキー押してねとか言われたりするので、その通りにする。
Dockerについて

#Dockerとは
「コンテナ技術」を用いた`仮想環境`を構築するツール。
Docker社が開発した、オープンソースの人気 No.１ソフトウェア
1つのコンテナとして確立させる為の手間をまとめてるので簡単にコンテナが作れちゃう。

　<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/836751/2cce53c6-541a-2fad-cfbf-ae3c2e11ded0.png" width="260">

##Dockerの仕組み
- <b>DockerHub</b>　　　　　　に保存してある
- <b>Dockerイメージ</b>　　　（コンテナ作る為のレシピ）を使い
- <b>Dockerコンテナ</b>　　　　を作って
- <b>Dockerエンジン</b>　　　　で動かします。
　

###DockerHub ( レジストリ )
Dockerの為のコンテナ共有サービス。ほぼ GitHub 。
① Dockerのイメージがたくさん転がっているので、そこから`Pull`してコンテナを作ります。( Pullしたイメージを元にrunコマンドでコンテナを作成 )
② 作ったコンテナで開発や作業をし、それをイメージに`commit`する。　
③ コミットしたイメージをDockerHubに`Push`する事で自分のリポジトリにアップロード。
④ 開発作業などで違うPCでもイメージを使いたいときに、そのアップロードしたイメージを`Pull`するだけでOK！
　
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/836751/185bf1c2-8068-b6e9-d023-df295b2f9b88.png)

###Dockerイメージ
コンテナの元となるもの、ひな型、パッケージ。
イメージはいくつかのレイヤと呼ばれるファイルを重ねることで出来ています。
もし欲しいイメージが無かった場合は<b>Dockerfile</b>を使い自分でイメージを作ることが出来ます。

```

FROM  ubuntu:18.10　　　　　 　#ベースとなるOSの指定    

LABEL version="1.0"　　　     #Dockerfileのメタ情報（こう言うFileだよと言う情報）
LABEL description="Dockerfileのテスト、Apacheサーバー"
 
RUN   apt-get update
RUN   apt-get install -y apache2　　 #このFileに入るレイヤのインストール

CMD   ["apachectl", "-D", "FOREGROUND"]　　#コマンドで上のRUNを起動させている
```
  
　

|コマンド　|実行内容　|
|:------|:------|
|FROM	|ベース（親）画像を指定します。|
|LABEL	|メタデータを提供します。 メンテナ情報を含めるのに良い場所です。|
|ENV	|永続的な環境変数を設定します。|
|RUN	|コマンドを実行してイメージレイヤを作成します。 パッケージをコンテナにインストールするために使用されます。|
|COPY	|ファイルとディレクトリをコンテナにコピーします。|
|ADD	|ファイルとディレクトリをコンテナにコピーします。 ローカルの.tarファイルをアンパックできます。|
|CMD	|実行中のコンテナにコマンドと引数を提供します。 パラメータは上書きできます。 CMDは1つだけです。|
|WORKDIR	|あとに続く説明の作業ディレクトリを設定します。|
|ARG	|ビルド時にDockerに渡す変数を定義します。|
|ENTRYPOINT	|実行中のコンテナにコマンドと引数を提供します。 引数は存続します。|
|EXPOSE	|ポートを公開します。|
|VOLUME	|永続データにアクセスして保存するためのディレクトリマウントポイントを作成します。|


###Dockerコンテナ
Dockerイメージの情報を元に起動された仮想環境

###Dockerエンジン
Dockerの心臓、ここがあってのDockerであり、Dockerそのものになります。
コンテナやイメージからくるコマンドをホストOSに伝えて動かす為のもの。

３つの要素からなりたっており

• 　コマンド命令を受け付ける部分 
• 　REST API（ステートレスなデータのやり取り）
• 　Dockerデーモン（ホストOSとやり取りするところ）
　　　　　　　　　　　　　　　　　　　　　　　　　　　と分かれています。

　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/836751/ccc31027-642a-7176-438c-3efdb86ca419.png)

##まとめ
これだけ簡単に環境設定が出来て軽くて使い勝手が良いなんて三拍子揃ってるなんて素敵！！
デメリットも色々あるようですが、気軽に使えるから便利！！！
　

##参考
http://docs.docker.jp/v1.12/engine/understanding-docker.html
https://qiita.com/shubatto/items/105f5b90e1cd91ba7c4c
https://blog.codecamp.jp/docker-file-how-to
https://tech-lab.sios.jp/archives/19073
https://knowledge.sakura.ad.jp/13265/
https://www.youtube.com/watch?v=VIzLh4BgKck
Unityでの開発において、車を扱うアプリで指定したルート上でイベント処理を行う-Vol.2

プログラマーの大角です。Unityで車を扱ったOculus Rift用のVRアプリ開発を行った際の実装の一部をご説明させて頂きます。

下記記事の続きとなります
https://qiita.com/NestVisual/items/dbb54a920ecf2e5707a7
#概要
今回は決められたルートを走る車が指定したポイントに来た時に、STATEを変化させて次のSTATEで処理を行う部分についての実装方法を説明させて頂きます。

前回の記事でWayPointProgressTrackerAuxiliaryForMainCar.csで定義したProgressNumForMainCarという変数を使用します。

#実装工程（１）
指定したルートのポイントにProgressNumForMainCarが到達した時にSTATEに連動させるメソッドが下記になります。
UniRxで実装しています。

```csharp
        /// <summary>
        /// 指定したWayPoint以上で指定したStateに変更
        /// </summary>
        /// <param name="state">変更したいState</param>
        /// <param name="progressNum">WaypointProgressTrackerのprogressNum</param>
        protected void StateChangeInSpecifiedWaypoint (STATE state, int progressNum) {
            this.UpdateAsObservable ()
                .Select (x => WayPointProgressTrackerAuxiliaryForMainCar.ProgressNumForMainCar)
                .DistinctUntilChanged ()
                .Subscribe (_ => {
                    if (CurrentStateAndDifferenceExists (state) &&
                        WayPointProgressTrackerAuxiliaryForMainCar.ProgressNumForMainCar >= progressNum) {
                            State = state;
                    }
                });
        }

        /// <summary>
        /// 変更したいSteteと現在のStateとの差分確認
        /// </summary>
        /// <param name="setState">変更したいState</param>
        /// <returns></returns>
        bool CurrentStateAndDifferenceExists (STATE setState) {
            int setStateIntType = (int)setState;
            int currentStateIntType = (int)State;
            return setStateIntType > currentStateIntType;
        }
```

#実装工程（２）
メソッドを使う側は下記のように記述します。
STATE.ONEなど今回は数字で定義してますが、実際にはそのSTATEで行う内容で定義しています。

```csharp
switch (State) {
                case STATE.ONE:

                    // MEMO:場合によっては何らかの処理の後に下記メソッドを呼び出す等組み合わせていく
                    StateChangeInSpecifiedWaypoint (STATE.TWO, 63);
                    break;

                case STATE.TWO:

                    // TODO:ここに指定したルートのポイントで行いたい処理を記述する
                    break;

                default:
                    break;
}
```
#あとがき
UniRxは便利なので良く使わせて頂いてます。
最後まで見て頂き有難う御座いました。
Pythonをはじめたばかりの人に送る過去15回分のABCのA問題分析

#はじめに
この記事ではABCのA問題の分析をし、「if文と演算しか使えない」などの初心者のための記事です。複数のジャンルにまたがっている回もあります(例:[AtCoder Beginner Contest 182](https://atcoder.jp/contests/abc182/tasks/abc182_a))。「典型的な問題」と書かれている問題から解くと良いでしょう。

#使う文の種類

##演算(+,-,*,/,//,%)
[AtCoder Beginner Contest 184 A.Determinant](https://atcoder.jp/contests/abc184/tasks/abc184_a)
[AtCoder Beginner Contest 182 A.twiblr](https://atcoder.jp/contests/abc182/tasks/abc182_a)
[AtCoder Beginner Contest 181 A.Heavy Rotation](https://atcoder.jp/contests/abc181/tasks/abc181_a)
[AtCoder Beginner Contest 180 A.box](https://atcoder.jp/contests/abc180/tasks/abc180_a)
[AtCoder Beginner Contest 178 A.Not](https://atcoder.jp/contests/abc178/tasks/abc178_a)
[AtCoder Beginner Contest 177 A.Don't be late](https://atcoder.jp/contests/abc177/tasks/abc177_a)
[AtCoder Beginner Contest 173 A.Payment](https://atcoder.jp/contests/abc173/tasks/abc173_a)
[AtCoder Beginner Contest 172 A.Calc](https://atcoder.jp/contests/abc172/tasks/abc172_a)(典型的な問題)


##min,max
[AtCoder Beginner Contest 185 A.ABC Preparation](https://atcoder.jp/contests/abc185/tasks/abc185_a)






##if,else文
[AtCoder Beginner Contest 183 A.ReLU](https://atcoder.jp/contests/abc183/tasks/abc183_a)
[AtCoder Beginner Contest 182 A.twiblr](https://atcoder.jp/contests/abc182/tasks/abc182_a)
[AtCoder Beginner Contest 179 A.Plural Form](https://atcoder.jp/contests/abc179/tasks/abc179_a)
[AtCoder Beginner Contest 178 A.Not](https://atcoder.jp/contests/abc178/tasks/abc178_a)
[AtCoder Beginner Contest 177 A.Don't be late](https://atcoder.jp/contests/abc177/tasks/abc177_a)
[AtCoder Beginner Contest 174 A.Air Conditioner](https://atcoder.jp/contests/abc174/tasks/abc174_a)(典型的な問題)
[AtCoder Beginner Contest 173 A.Payment](https://atcoder.jp/contests/abc173/tasks/abc173_a)

##切り上げ、切り下げ
math.ceilとint(//1でも可)を用いた切り上げ、切り下げの問題
[AtCoder Beginner Contest 176 A.Takoyaki](https://atcoder.jp/contests/abc176/tasks/abc176_a)

##count
countを扱った問題はtryとwhile Trueの組み合わせやifとforの組み合わせでも解ける(A問題の制約ではTLEしない)。ここでは、countを使うと簡単に解ける問題はcountのところのみに書いてある。
[AtCoder Beginner Contest 175 A.Rainy Season](https://atcoder.jp/contests/abc175/tasks/abc175_a)

##in
リストにある要素が入っているか確認する時などに使います。(ここではfor i in rangeのinは含めないこととする。
[AtCoder Beginner Contest 171 A.αlphabet](https://atcoder.jp/contests/abc171/tasks/abc171_a)

##chr
アルファベットのリストなどを作ることができる組込み関数。
[[python] いろいろな文字種のリストを作成](https://qiita.com/okkn/items/3aef4458ed2269a59d63)を使うことができる。
[AtCoder Beginner Contest 171 A.αlphabet](https://atcoder.jp/contests/abc171/tasks/abc171_a)

##感想
if,else文と演算の組み合わせが多い(例:[AtCoder Beginner Contest 177 A.Don't be late](https://atcoder.jp/contests/abc177/tasks/abc177_a))。また、多くのmin, max,countを使う問題はif文を使ってもACできる。意外とfor,whileを扱う問題が少なかった。また、言われた通りに実行すればACがもらえる問題が多い。[AtCoder Beginner Contest 022 A.Best Body](https://atcoder.jp/contests/abc022/tasks/abc022_a)など、昔のコンテストは難易度が300を超えているものがあるが、最近のコンテストは難易度が1桁のものが多い。([AtCoder Problems](https://kenkoooo.com/atcoder/#/table)を参考にした。)


#参考文献
- [AtCoder Problems](https://kenkoooo.com/atcoder/#/table)