OmniAICreator/Qiita-1.07M huggingface dataset:
簡単すぎる！？Salesforceのデータ連携をノンプログラミングで出来る新サービス

### 概要

Salesforceのデータ連携について、
Amazon AppFlowを使えば簡単にできるよ（プログラムさえ必要ない）という話。

### Amazon AppFlowって何？

2020年4月22日に発表されたAWSの新サービス。
AWSサービスとの間で、数回クリックするだけで安全にデータを転送することができる
フルマネージドの統合サービス。

要はデータ連携が簡単にできるサービス。

Salesforce以外にもDataDogやMarketoやSlackなどにも対応している。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230829/b02ae8c3-df59-1044-bff7-c11dde789f9a.png)

### Salesforceとデータ連携

Salesforceでデータ連携するには？

#### Data Spider Cloud / Sky On Demand

SaaS型のETLツール。RPAのようにノンプログラミングでデータ連携可能。
Salesforce以外にもRDSやFTPやAPIなど様々なサービスに対応。

メリット：比較的実装しやすい。様々なサービスと連携可能。
デメリット：コスト（マネー的）がかかる。プログラム書ける人は、描写にイライラする。

#### DataLoader

Salesforceが表示で用意しているデータ連携ツール。
Jarファイルでバッチモードで起動も可能。

メリット：コスト（マネー的）がかからない。大量データもOK.
デメリット：CSVの単純連携以外に使えない。

#### 自前でバッチを用意

SalesforceのAPIを叩き、データ連携を行う。
Javaなどの一部の言語では、ライブラリを用意している。
一般的なSDKより使い勝手は悪いが、フルスクラッチなのでロジックを多数入れられる。

メリット：複雑なロジックにも柔軟に対応できる
デメリット：コスト（技術）が高い

### ここからAmazon AppFlowのハンズオン

S3にあるデータをSalesforceにデータ連携するツールを作成

### 補足説明

#### 料金っていくら？

実行するフロー数と処理されるデータ量の課金となる
詳しくはこの辺を見てほしい。

https://aws.amazon.com/jp/appflow/pricing/

#### 使えるリージョンは？

新しいサービスだが東京リージョン、使えるよ。

#### 大量データのパフォーマンスは？

お金が怖くて使っていないです。すいません。
【AWS】CloudFormation スタックを別アカウントで利用する方法

# CloudFormationのスタック共有
あるAWSアカウントで作成したスタックを別のアカウントに共有したくなった場合の手順です。
スタックセットで共有する事で、別アカウントにも自動でスタックが作成されます。
※親でスタックセットを作成したら、すぐに、子でスタックの作成が始まります。

## 設定の流れ
1. スタックセットの共有を行えるように設定
2. スタックセットの作成


# スタックセットを共有する側の設定
スタックを共有（提供）する側の設定を行います。
下記のyamlファイルを作成します。
ファイル名は`AWSCloudFormationStackSetAdministrationRole.yml`とします。

```yml:AWSCloudFormationStackSetAdministrationRole.yml
AWSTemplateFormatVersion: 2010-09-09
Description: Configure the AWSCloudFormationStackSetAdministrationRole to enable use of AWS CloudFormation StackSets.

Resources:
  AdministrationRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: AWSCloudFormationStackSetAdministrationRole
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service: cloudformation.amazonaws.com
            Action:
              - sts:AssumeRole
      Path: /
      Policies:
        - PolicyName: AssumeRole-AWSCloudFormationStackSetExecutionRole
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - sts:AssumeRole
                Resource:
                  - "arn:aws:iam::*:role/AWSCloudFormationStackSetExecutionRole"
```

上記のyamlを利用して、スタックの作成を行うと、IAMロールが作成されます。

# スタックを受け取る側の設定
スタックを受け取る側の設定のために、下記のymalファイルを作成します。
ファイル名は、`AWSCloudFormationStackSetExecutionRole.yml`

```yaml:AWSCloudFormationStackSetExecutionRole.yml
AWSTemplateFormatVersion: 2010-09-09
Description: Configure the AWSCloudFormationStackSetExecutionRole to enable use of your account as a target account in AWS CloudFormation StackSets.

Parameters:
  AdministratorAccountId:
    Type: String
    Description: AWS Account Id of the administrator account (the account in which StackSets will be created).
    MaxLength: 12
    MinLength: 12

Resources:
  ExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: AWSCloudFormationStackSetExecutionRole
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              AWS:
                - !Ref AdministratorAccountId
            Action:
              - sts:AssumeRole
      Path: /
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AdministratorAccess
```

スタックの作成を行うと、パラメータの欄で、AdministratorAccountIdを聞かれるので、先ほど、共有設定を行ったアカウントのIDを選択します。

# スタックセットを作成
CloudFormationの左のメニューから`StackSets`を選択します。

設定項目を進んでいくと、`デプロイのオプション`ページにたどり着きます。
そこで、「アカウント」の欄があるので、`スタックをアカウントにデプロイ`を選択します。
アカウントが大量にある場合は、`.csv`を選択する事が可能です。
また、リージョンを選択する事も可能です。
※複数リージョンでも利用できるようにテンプレートを作成する必要があります。

## 確認
スタックセットを作成したら、共有指定したアカウントで、スタックがすぐに作成されます。

# まとめ
スタックセットを利用する事で、複数アカウントで簡単に共有する事ができるので、複数アカウントがある場合は、積極的に利用していくべき機能だと思いました。
ますます、CloudFormationが好きになってしまいました！！
【今日のアブストラクト】Understanding Batch Normalization【論文 DeepL 翻訳】

この記事は自分用のメモみたいなものです.
ほぼ [DeepL](https://www.deepl.com/home) 翻訳でお送りします.
間違いがあれば指摘していだだけると嬉しいです.

翻訳元
[Understanding Batch Normalization](https://arxiv.org/abs/1806.02375)

# Abstract

### 訳文

バッチ正規化 (BN) は, ディープニューラルネットワークの中間層の活性化を正規化する手法である. 精度の向上や学習の高速化が可能であることから, ディープラーニングでは人気の手法となっている. しかし, 大きな成功を収めているにもかかわらず, その背景にある正確な理由やメカニズムについては, まだほとんどコンセンサスが得られていないのが現状である. 本論文では, 経験的なアプローチにより, BN の理解を深めるための一歩を踏み出す. 我々はいくつかの実験を行い, BN が主により大きな学習率での学習を可能にし, それがより速い収束とより良い一般化の原因であることを示した. BN を用いないネットワークでは, 大きな勾配更新を行うと, ネットワークの深さに応じて発散する損失と活性化が制御不能に増大し, 可能な学習率が制限されることを実証した. BN は常にゼロ平均で単位標準偏差の活性化を修正することでこの問題を回避し, より大きな勾配ステップを可能にし, より速い収束をもたらし, 鋭い局所最小値を回避するのに役立つかもしれない. さらに, 正規化されていない深層ネットワークの勾配や活性化がどのようにして不良な挙動を示すのか, 様々な方法を示す. 我々の結果をランダム行列理論における最近の知見と対比させ, 古典的な初期化スキームとその結果に新たな光を与える.



### 原文

Batch normalization (BN) is a technique to normalize activations in intermediate layers of deep neural networks. Its tendency to improve accuracy and speed up training have established BN as a favorite technique in deep learning. Yet, despite its enormous success, there remains little consensus on the exact reason and mechanism behind these improvements. In this paper we take a step towards a better understanding of BN, following an empirical approach. We conduct several experiments, and show that BN primarily enables training with larger learning rates, which is the cause for faster convergence and better generalization. For networks without BN we demonstrate how large gradient updates can result in diverging loss and activations growing uncontrollably with network depth, which limits possible learning rates. BN avoids this problem by constantly correcting activations to be zero-mean and of unit standard deviation, which enables larger gradient steps, yields faster convergence and may help bypass sharp local minima. We further show various ways in which gradients and activations of deep unnormalized networks are ill-behaved. We contrast our results against recent findings in random matrix theory, shedding new light on classical initialization schemes and their consequences.
【Java】IntelliJ IDEAでコンストラクタやGetterやSetterを一発で書く技。

Javaでオブジェクトのインスタンスを生成するクラスを作成する際に

- **コンストラクタ**
- **デフォルトコンストラクタ**
- **Getter(get()メソッド)**
- **Setter(set()メソッド)**

は大体記述すると思われますが、毎回毎回コード書くのめんどくさいですよね。

#解決法(Mac OS)

結論：手打ちせずに、**command+n**で自動生成しましょう！！

人の名前、年齢、IDをメンバ変数に持つPersonクラスを例に解説します。

**Personクラス**


```java
public class Person {
    private int PersonId;
    private String PersonName;
    private int PersonAge;

    public Person(int PersonId, String PersonName, int PersonAge) {
        this.PersonId = PersonId;
        this.PersonName = PersonName;
        this.PersonAge = PersonAge;
    }

    public Person() {
    }

    public int getPersonId() {
        return PersonId;
    }

    public String getPersonName() {
        return PersonName;
    }

    public int getPersonAge() {
        return PersonAge;
    }

    public void setPersonId(int PersonId) {
        this.PersonId = PersonId;
    }

    public void setPersonName(String PersonName) {
        this.PersonName = PersonName;
    }

    public void setPersonAge(int PersonAge) {
        this.PersonAge = PersonAge;
    }
}
```

#やり方

- **コンストラクタ、デフォルトコンストラクタの作成**



```java
    public Person(int PersonId, String PersonName, int PersonAge) {
        this.PersonId = PersonId;
        this.PersonName = PersonName;
        this.PersonAge = PersonAge;
    }

    public Person() {
    }

```
command+nでConstructorを選択

<img width="508" alt="スクリーンショット 2020-04-25 23.15.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296645/945798d5-874d-6bca-0e4e-70d3cf4c1ce8.png">

**メンバ変数を選択**し、OKでコンストラクタが自動生成されます。
**変数を指定しない**場合、デフォルトコンストラクタが自動生成されます。
<img width="744" alt="スクリーンショット 2020-04-25 23.14.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296645/366eb57f-b72c-d28c-183d-1a60b586364b.png">

- **Getter/Setterの作成**

```java
    public int getPersonId() {
        return PersonId;
    }

    public String getPersonName() {
        return PersonName;
    }

    public int getPersonAge() {
        return PersonAge;
    }

    public void setPersonId(int PersonId) {
        this.PersonId = PersonId;
    }

    public void setPersonName(String PersonName) {
        this.PersonName = PersonName;
    }

    public void setPersonAge(int PersonAge) {
        this.PersonAge = PersonAge;
    }
```
command+nでGetter/Setterを選択
<img width="576" alt="スクリーンショット 2020-04-25 23.18.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296645/49be4c68-41d5-99f9-2bb5-fd3f76dbaff1.png">
メンバ変数を選択しOKで、各変数のGetter/Setterが自動生成されます。
<img width="667" alt="スクリーンショット 2020-04-25 23.21.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296645/f05443a8-8a6a-a8a5-66ad-c24ce49651b0.png">

#おわりに
これでもうget(),set()とか何回も書かなくてよくなるので、最高に楽です。

ありがとうございました。
【AWS】CloudFormationの変更管理

# CloudFormationについて
AWSの構築をオートメーション化するサービスです。

使用する全てのAWSリソースを記述するテンプレートを作成すれば、AWS Cloud Formationがリソースのプロビジョニングや設定をしてくれます。
また、設計のテンプレートを作成するため、素早く複製する事もできます。

# CloudFormationの特徴
CloudFormationの特徴は以下の様な物があります。

- プロビジョニングされたリソースの変更・削除が可能
- JSON/YAMLで記述する
- クロスリージョンとクロスアカウントで管理
- 直接サポートされていないリソースや機能を利用する場合はカスタムリソースでスタックの作成の一部に独自ロジックを組み込む事が可能

今回の説明内容
1. 変更セットの作成
2. ドリフトの利用

# 変更セットについて
スタックの変更を追加していきます。
変更の管理が可能です。
下記の3つの方法を選択できます。

- 現在のテンプレートを利用
- 既存のテンプレートを置き換える
- デザイナーでテンプレートを編集する

## 現在のテンプレートを使用
yamlファイルの内容は変更されないため、テンプレート以外の設定（パラメータ、タグ等）を変更する事ができます。

## 既存のテンプレートを置き換える
yamlファイルを再度アップロードし、変更する事が可能です。

## デザイナーでテンプレートを編集する
デザイナーで編集する事もできます。

# ドラフトについて
CloudFormationで設定したものが変更されている場合、ドラフトの画面に表示されます。

例）
セキュリティグループAでEC2を立ち上げたが、EC2のインスタンス管理画面でセキュリティグループをCに変更した場合
RustでC++のcin >> aを実現する

# 概要
Rustの標準入力が面倒だったのでC++の```cin >> a```と似たような動作をするstructを作りました．

# 環境
Rust 1.42

# 実装
```rust
struct Input {
    data: Vec<String>,
}

impl Input {
    pub fn new() -> Input {
        Input{data: Vec::new()}
    }

    fn read(&mut self) {
        let mut line: String = String::new();
        std::io::stdin().read_line(&mut line).unwrap();
        self.data = line.split_whitespace().rev().map(|s| s.parse::<String>().unwrap()).collect::<Vec<_>>();
    }

    pub fn get<T: core::str::FromStr>(&mut self) -> T {
        if self.data.len() == 0 {
            self.read();
        }
        return self.data.pop().unwrap().parse::<T>().ok().unwrap();
    }
}

impl<T: core::str::FromStr> std::ops::Shr<&mut T> for Input {
    type Output = Input;

    fn shr(mut self, rhs: &mut T) -> Input {
        *rhs = self.get::<T>();
        return self;
    }
}
```

# 使い方
次のように使います．このコードは[この問題](https://atcoder.jp/contests/abs/tasks/practice_1)の入力を想定しています．

```rust
let mut cin = Input::new();

let mut a: usize = 0;
let mut b: usize = 0;
let mut c: usize = 0;
let mut s = String::new();
cin = cin >> &mut a >> &mut b >> &mut c >> &mut s;

println!("{} {}", a + b + c, s);
```

# 注意事項
~~このコードは現在```usize```と```String```のみに対応しています．他の型が必要なら適宜関数を追加する必要があります．~~
ジェネリクスを用いるように修正しました．```String::parse<type>```できる型で使えるようになりました．
C++でCSVファイルを読み書きする方法

#はじめに
　C++でcsvファイルの読み込み・書き込み方法を調べてみたので、
　本記事にまとめる。

#環境
 - 動作環境  
  Visual Studio 2019
 - 言語  
  C++

#インクルードするヘッダーファイル
 csvファイルを扱うために使用するヘッダーファイルは以下である。

 - string
 - fstream
 - sstream

#CSVファイル読み込み・書き込み方法
 
 ```php:ReadWriteCsv.cpp
#include <string>
#include <fstream>
#include <sstream>

int main () {
  std::string str_buf;
  std::string str_conma_buf;
  std::string input_csv_file_path  = "読み込むcsvファイルへのパス";
  std::string output_csv_file_path = "書き込むcsvファイルへのパス";

  // 読み込むcsvファイルを開く(std::ifstreamのコンストラクタで開く)
  std::ifstream ifs_csv_file(input_csv_file_path  );

  // 書き込むcsvファイルを開く(std::ofstreamのコンストラクタで開く)
  std::ofstream ofs_csv_file(output_csv_file_path );

  // getline関数で1行ずつ読み込む(読み込んだ内容はstr_bufに格納)
  while (getline(ifs, str_buf)) {    
    // 「,」区切りごとにデータを読み込むためにistringstream型にする
    std::istringstream i_stream(str_buf);
   
    // 「,」区切りごとにデータを読み込む
    while (getline(i_stream, str_conma_buf, ',')) {
       // csvファイルに書き込む
       ofs_csv_file << str_conma_buf << ',';
    }
    // 改行する
    ofs_csv_file << std::endl;
  }

  // クローズ処理は不要[理由]ifstream型・ofstream型ともにデストラクタにてファイルクローズしてくれるため
}
 ```

#参考
[ifstreamクラスの仕様](https://ja.cppreference.com/w/cpp/io/basic_ifstream)
[ofstreamクラスの仕様](https://ja.cppreference.com/w/cpp/io/basic_ofstream)
[getlineの関数仕様](https://cpprefjp.github.io/reference/string/basic_string/getline.html)
 
#気づいたこと

- 1つのcsvファイルに対して読み込み・書き込むを同時にすることはできないっぽい 
もし知っていたら展開してもらえると嬉しいです。

- ifstream・ofstream型はコンストラクタでファイルオープンしてくれるが、オープンするメソッドもある。 
例えば、オープンは別の関数でさせたい場合やインスタンスをメンバ変数にしたいときはオープンメソッドを使う。
WordPressでLet’s Encryptの設定＋自動更新設定

## 実現したいこと
centos(Wordpress)にてLet’s Encryptを入れてSSL証明書を発行、Let’s Encryptは有効期間が90日のため自動更新設定までを行います。

## 前提条件
- ドメインを取得していること (今回は仮にsample.comのドメインで実施) 
- Apacheがインストールされていること

## Lets'sEncryptの導入手順
Lets'sEncryptを入れるには、Certbotクライアントのインストールが必要

**Certbotクライアントのインストール**

```txt:
$ sudo yum install epel-release
```

```txt:
$ sudo yum install certbot python-certbot-apache
```
インストールが完了したら準備完了！！！
これでcertbotコマンドが実行可能になりました。

**証明書発行**

```txt:
$ sudo certbot certonly --agree-tos --webroot -w /var/www/html/ -d sample.com
```
※オプションの意味は下記のリファレンスを参照
[certbot公式リファレンス](https://free-ssl.jp/command/)

**証明書確認**

```txt:
$ ls -al /etc/letsencrypt/archive/sample.com/
```
下記のようなファイルがあればOK！

```txt:
cert.pem　サーバ証明書（公開鍵を含む）
chain.pem　中間証明書
privkey.pem　秘密鍵
fullchain.pem　サーバ証明書（公開鍵を含む）と中間証明書は一緒になっているファイル※今回は使用しません
```

**SSL証明書の設定**
下記部分を修正

```txt
$ sudo vim /etc/httpd/conf.d/sample_ssl.conf
SSLCertificateFile /etc/letsencrypt/archive/sample.com/cert.pem
SSLCertificateChainFile /etc/letsencrypt/archive/sample.com/chain.pem
SSLCertificateKeyFile /etc/letsencrypt/archive/sample.com/privkey.pem
```
**再起動**
再起動して変更を反映

```txt:
$ sudo systemctl restart httpd.service
```

## SSL証明書の自動更新設定
**テスト** ※これでは更新されません
まずはコマンドが正しいことを確認

```txt:
$ sudo certbot renew --force-renew --dry-run --webroot-path /var/www/html/ --post-hook "apachectl graceful"
```
--force-renew：残りの有効期限に関係なく強制更新
--dry-run：テスト実行オプション

**実行**
実際に更新されることを確認　※ブラウザの鍵マークをクリックして証明書の有効期限を確認

```txt:
$ sudo certbot renew --force-renew --webroot-path /var/www/html/ --post-hook "apachectl graceful"
```

**cron設定**
毎月1日の5:00に更新する設定
[Cronの詳しい設定方法はこちら](https://www.express.nec.co.jp/linux/distributions/knowledge/system/crond.html)

```txt:
$ sudo vim /etc/cron.d/letsencrypt
00 05 01 * * root certbot renew --force-renew --webroot-path /var/www/html/ --post-hook "apachectl graceful"
```
【AWS】CloudFormationのリソース参照を活用する

# CloudFormationについて
AWSの構築をオートメーション化するサービスです。

使用する全てのAWSリソースを記述するテンプレートを作成すれば、AWS Cloud Formationがリソースのプロビジョニングや設定をしてくれます。
また、設計のテンプレートを作成するため、素早く複製する事もできます。

# CloudFormationの特徴
CloudFormationの特徴は以下の様な物があります。

- プロビジョニングされたリソースの変更・削除が可能
- JSON/YAMLで記述する
- クロスリージョンとクロスアカウントで管理
- 直接サポートされていないリソースや機能を利用する場合はカスタムリソースでスタックの作成の一部に独自ロジックを組み込む事が可能

# リソースの参照について
既に作成されているスタックの出力の内容を利用して、別のスタックの作成時にリソースを参照できる様に設計する。

# EC2インスタンスを立ち上げる
以前、作成したスタックの出力内容を利用して、VPCの設定を行います。

設定するyamlにエクスポート名を指定することで参照する事ができます。

```yaml:EC2Setting.yaml
AWSTemplateFormatVersion: "2010-09-09"
Description: Create EC2 Instance
Parameters:
  InstanceType:
    Description: WebServer EC2 instance type
    Type: String
    Default: t2.micro
    AllowedValues:
    - t1.micro
    - t2.nano
    - t2.micro
    - t2.small
    - t2.medium
    - t2.large
    ConstraintDescription: must be a valid EC2 instance type
  KeyName: 
    Description : Name of an existing EC2 KeyPair.
    Type: AWS::EC2::KeyPair::KeyName
    ConstraintDescription : Can contain only ASCII characters.
  SSHLocation:
    Description: IP address range that can be used to SSH to the EC2 instances
    Type: String
    MinLength: '9'
    MaxLength: '18'
    Default: 0.0.0.0/0
    AllowedPattern: (\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})
    ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x.


Description: Create EC2 Instance
Resources:
  MyEC2Instance:
    Type: AWS::EC2::Instance
    Properties: 
      ImageId: "ami-XXXXXXXXXXXXXX"
      InstanceType: !Ref InstanceType
      SubnetId: !ImportValue MyVPC-PublicSubnet1A
      BlockDeviceMappings:
        -
          DeviceName: /dev/xvda
          Ebs:
            VolumeType: gp2
            VolumeSize: 8
      Tags:
      - Key: Name
        Value: myInstance
      KeyName: !Ref KeyName
      SecurityGroupIds:
         - !GetAtt "InstanceSecurityGroup.GroupId"

  InstanceSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: connect with ssh 
      VpcId: !ImportValue MyVPC-VPCID
      SecurityGroupIngress:
        -
          IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: !Ref SSHLocation
```

VpcId: !ImportValue `MyVPC-VPCID`
SubnetId: !ImportValue `MyVPC-PublicSubnet1A`
上記の網掛けの部分で別のスタックのエクスポート名を指定しています。

# まとめ
上記のように、VPCをCloudFormationで作成しておくと、E C2等の構築をする際にもリソースを参照できるので、構築の負担を軽減する事が可能だと思います。

全部、CloudFormationで管理したくなってきますね！
CompactCalendarViewのMinMonthとMaxMonthを無理やり実装した

## はじめに
CalendarViewにEventを自分で実装するのがだるかったので良さげなものがないか探して出会ったのがCompactCalendarViewでした。
導入や説明については、githubや他の方のブログにあったりするので探してみてください。
>CompactCalendarViewのgithub
>https://github.com/SundeepK/CompactCalendarView

## 問題
このCompactCalendarViewはEvent周りはAndroid初心者な自分でもすぐに使えるくらいには実装されているが、更新がストップしているのかsetMaxMonthやsetMinMonthが実装されてなかった。

## 解決作
Viewlistenerに月の移動で実行してくれるonMonthScrollがあったのでそこでループにすることで無理やりMinMonthとMaxMonthを実装した。

```
private var now_calendar:Date? = null

override fun onCreate(savedInstanceState: Bundle?) {
:
:
now_calendar= Date()#現在時刻の取得
val calendarView:CompactCalendarView=findViewById(R.id.compactCalendarView)
calendarView.setCurrentDate(now_calendar)# 現在の日付の設定
:
:
calendarView.setListener(object :CompactCalendarView.CompactCalendarViewListener{
            override fun onDayClick(dateClicked: Date?) {//ここでクリック処理ができます
                         :
                         :
            }
            override fun onMonthScroll(firstDayOfNewMonth: Date?) {
                val max_cal = Calendar.getInstance()
                max_cal.time = now_calendar
                max_cal.add(Calendar.YEAR,1)//その日から+1年後まで表示可能
                val min_cal=Calendar.getInstance()
                min_cal.time=now_calendar
                min_cal.add(Calendar.MONTH,-1)//その月の前の月以降は表示しない

                if(max_cal.time.after(firstDayOfNewMonth) && min_cal.time.before(firstDayOfNewMonth)) {
                   ~~処理~~
                }
                else if(max_cal.time.before(firstDayOfNewMonth) ){

                    calendarView.setCurrentDate(now_calendar)
                    ~~処理~~
                    //Toast.makeText(this@MainActivity,"Max_monthを超えました！",Toast.LENGTH_SHORT).show()

                }
                else if(min_cal.time.after(firstDayOfNewMonth) ){
                    calendarView.setCurrentDate(max_cal.time)
                     ~~処理~~
                    //Toast.makeText(this@MainActivity,"Min_monthを超えました！",Toast.LENGTH_SHORT).show()
                }
           
```


## 終わりに
初心者特有の無理やり実装なのでおかしい部分があるかもしれません。
もしもっといい方法やライブラリがあれば教えていただけると幸いです。
Google Cloud Runでバッチ処理をやらせよう

# まとめ

* バッチ処理用のスクリプトとwebサーバー用のスクリプトを分けておくと開発が捗る
* 所定のJSONをSTDOUTかSTDERRに流すとError Reportingにエラーを通知できる

# ソースコード

https://github.com/skuroki/merger

Githubでforkしたリポジトリで、上流の変更をマージしています。こちらの詳細は別記事の[Github上のリポジトリの操作を自動化するdockerコンテナ](https://qiita.com/skuroki@github/items/cef4c3dc5fdc701eb3e5)にて。

```webserver.rb
require 'webrick'
require 'json'
srv = WEBrick::HTTPServer.new({ :DocumentRoot => './',
                                :BindAddress => '0.0.0.0',
                                :Port => ENV['PORT'].to_i})
srv.mount_proc '/' do |req, res|
  res.body = `sh -e ./main.sh 2>&1`
  STDOUT.puts res.body
  STDOUT.flush
  if $? != 0
    res.status = 500
    STDERR.puts JSON.generate(
      "@type": 'type.googleapis.com/google.devtools.clouderrorreporting.v1beta1.ReportedErrorEvent',
      message: 'ジョブの実行に失敗しました'
    )
    STDERR.flush
  end
end
trap("INT"){ srv.shutdown }
srv.start
```

* `gem install` をしなくて良いように、Rubyに標準で入っている機能を使っています
* Google Cloud Runでは、コンテナの環境変数に、公開するポート番号がPORTで渡ってくるので、そのポート番号でサーバーを建てます
* STDOUT/STDERRへの出力はそのままだとバッファリングされたままHTTPリクエストの処理が終わって出力されない場合があるので、明示的にflushしてます（`STDOUT.sync = true` とかでも良い）
* Google Cloud Runには、ログをJSON形式で出力すると、自動的に構造化ログとしてStackdriver Loggingに送ってくれる機能があります
* ログのJSONが所定の形式に従っていればエラーとみなしてError Reportingに報告してくれます
    * ここでは `@type` の指定がそれに該当します
    * スタックトレースを `message` に含める方法もあるようですが、そちらは未検証です
    * Error ReportingにはアカウントのGMailアドレスに通知メールを送ってくれる機能があります
        * そこから、GMailのメールフィルタ機能とSlackの[転送用のメールアドレスを設定する](https://slack.com/intl/ja-jp/help/articles/206819278-Slack-%E3%81%AB%E3%83%A1%E3%83%BC%E3%83%AB%E3%82%92%E9%80%81%E4%BF%A1%E3%81%99%E3%82%8B#u36578u36865u20808u12513u12540u12523u12450u12489u12524u12473u12434u35373u23450u12377u12427)機能を使って、Slackで通知を受け取るようにしています
* Rubyの[シェル実行機能](https://docs.ruby-lang.org/ja/2.5.0/method/Kernel/m/=60.html)を使って、本体である `main.sh` の処理を起動しています
    * 終了ステータスを`$?`で取得しています
* 定時実行のトリガーは[Cloud Schedulerを使います](https://qiita.com/skuroki@github/items/339e404d19e39b21911d#cron%E3%81%BF%E3%81%9F%E3%81%84%E3%81%AA%E5%AE%9A%E6%9C%9F%E5%AE%9F%E8%A1%8C%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95)
    * Cloud Scheduler上ではHTTPステータスで成否を判断しているので、それにあわせてHTTPステータスを返すようにしています（エラー通知はログ経由で受け取っているので現状はあまり意味はありません）
Pythonで毎日AtCoder #47

### はじめに
[前回](https://qiita.com/taxfree_python/items/d6676bb018d3a22c8a89)

### #47
[問題](https://atcoder.jp/contests/abc128/tasks/abc128_c)

**考えたこと**
制約を見ると$N,M$が10以下と小さいので力ずくで解けると思い、実装しました。スイッチがon/offの二択なのでbit全探索します。計算量は$O(2^N)$になりますが、$N$が小さいのでTLEしません。要素がそれぞれのスイッチのon/offの状態を表したboolのlistを作り、それぞれの状態での電球の点灯状況を確認します。

```python
n, m = map(int,input().split())
ks = [list(map(int,input().split())) for _ in range(m)]
p = list(map(int,input().split()))

ans = 0
for i in range(2 ** n):
    on = [False] * n
    for j in range(n): #bit全探索
        if ((i>>j) & 1):
            on[n - j - 1] = True
    g = 0
    for j in range(m): #それぞれの電球の状況
        c = 0
        for s in range(1,len(ks[j])):
            if on[ks[j][s]-1]:
                c += 1
        if c % 2 == p[j]: #電球が点灯しているならg+=1する
            g += 1
    if g == m: #すべてのgが点灯しているならans+=1
        ans += 1
print(ans)
```

### まとめ
最近は、計算量が少ないからと甘えて雑な実装しているのでしっかり解説読んできれいに実装できるように精進します。ではまた、おやすみなさい。
REST API（$.ajax）でRedmineのチケットを更新するときは、レスポンスのdataTypeをJSONにしてはならない

## 概要
* jquery（3.5.0）の`$.ajax()`でRedmineのチケットを更新しようとしたら、上手くいかなくて困ったので共有

## 事象
### 書いたコード
```js
function updateTicketTitle( ticket_id, new_title ) {
    let url = `https://xxxxxx/redmine/issues/${ticket_id}.json?key=0123456789abcdef0123456789abcdef`;
    
    update_data = {
        "issue": {
            "subject": new_title
        }
    };
    
    $.ajax({
        url: url,
        type: "PUT",
        contentType: 'application/json',
        data: JSON.stringify(update_data),
        dataType: 'json'
    }).done(function(data, status, xhr) {
        console.log( "Success!!" );
    }).fail(function(xhr, status, error) {
        console.log( "Failed.." );
        console.log( {"xhr": xhr, "status": status, "error": error } );
    });
}

updateTicketTitle( "16", "New Title" );
```

### 実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468246/fffd59bf-68c9-61bc-bf4c-b911f0771483.png)

* parsererrorで失敗
    * JSON inputがおかしいとのこと
* 一方で、xhr.statusは200（成功）
    * チケットも期待通り更新されている
        * ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468246/75040adb-4602-e8b3-3b2b-ba9c2589627a.png)

## 原因
* `$.ajax()`に`dataType: 'json'`を渡していたのが原因
    * チケットの更新は、サーバからのレスポンスが存在しない
        * レスポンスが存在しないのにjsonでparseしようとして失敗していた

## 解決方法
* `dataType: 'text'`に変更する

```js
function updateTicketTitle( ticket_id, new_title ) {
    let url = `https://xxxxxx/redmine/issues/${ticket_id}.json?key=0123456789abcdef0123456789abcdef`;
    
    update_data = {
        "issue": {
            "subject": new_title
        }
    };
    
    $.ajax({
        url: url,
        type: "PUT",
        contentType: 'application/json',
        data: JSON.stringify(update_data),
        dataType: 'text'
    }).done(function(data, status, xhr) {
        console.log( "Success!!" );
    }).fail(function(xhr, status, error) {
        console.log( "Failed.." );
        console.log( {"xhr": xhr, "status": status, "error": error } );
    });
}

updateTicketTitle( "16", "New Title" );
```

* 今度は成功
    * ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468246/311504d5-7afd-660f-84fa-5d94199998a2.png)
自然言語処理（NLP）で注目を集めているHuggingFaceのTransformers

# HuggingFaceのTransformersとは？
米国の[Hugging Face社](https://huggingface.co/)が提供している、自然言語処理に特化したディープラーニングのフレームワーク。
ソースコードは全て[GitHub](https://github.com/huggingface/transformers)上で公開されており、誰でも無料で使うことができる。

[TensorFlow](https://www.tensorflow.org/)と[PyTorch](https://pytorch.org/)の両方に対応しており、テキスト分類や質問応答などの自然言語処理のタスクをディープラーニングを使って解くことができる。
[BERT](https://arxiv.org/abs/1810.04805)などの最先端のアルゴリズムに対応したアーキテクチャに加え、多言語、且つ、多様な事前学習モデルに対応しており、最先端のアルゴリズムを簡単に試すことができる。

# HuggingFaceのTransformersが提供しているもの
- BERTなどの最先端のアルゴリズムに対応したアーキテクチャ
詳細は下記のページ参照。
https://github.com/huggingface/transformers#model-architectures

- 多言語、且つ、多様な事前学習モデル
詳細は下記のページ参照。BERTでは日本語の事前学習モデルもある。
https://huggingface.co/transformers/pretrained_models.html

# HuggingFaceのTransformersで出来ること
自然言語処理の代表的なタスクはだいたい何でもできる。
公式ドキュメントのusageページ、もしくはGitHubのexamplesページに例が載っている。

https://huggingface.co/transformers/usage.html
https://github.com/huggingface/transformers/tree/master/examples

## テキスト分類
https://github.com/huggingface/transformers/tree/master/examples#glue-1

[GLUE(General Language Understanding Evaluation)](https://gluebenchmark.com/)のデータセットを使った場合の事例が載っている。
英語のベンチマーク用のデータセットであり、同じデータセットを扱うことで同じ土俵の上でアルゴリズムの精度を比較することができる。

GLUEには9つのタスクのデータセットが含まれており、基本的には全てテキスト分類のタスクである。
例えば、[SST-2(The Stanford Sentiment Treebank)](https://nlp.stanford.edu/sentiment/)は映画のレビュー文にポジティブ、ネガティブの2つのラベルを付与したものであり、テキスト分類によりポジティブ、ネガティブを推定するというタスクである。

ただ、examplesに載っている事例は全て英語のデータセットであり、日本語のオリジナルデータを試したい場合はソースコードとコマンドを変更する必要がある。詳細は下記のページ参照。

https://qiita.com/kenta1984/items/7f3a5d859a15b20657f3

## 質問応答
https://github.com/huggingface/transformers/tree/master/examples#squad

[SQuAD(Stanford Question Answering Dataset)](https://rajpurkar.github.io/SQuAD-explorer/)のデータセットを使った場合の事例が載っている。
GLUE同様、英語のベンチマーク用のデータセットであり、同じデータセットを扱うことで同じ土俵の上でアルゴリズムの精度を比較することができる。

データセットには、質問とそれに対応する応答、もしくは応答として相応しくないデータが収められている。
そして、未知の質問に対して適切な応答を推定するというタスクである。

```
質問: When did Beyonce start becoming popular?
応答: in the late 1990s
```

GLUE同様、examplesに載っている事例は全て英語のデータセットであり、日本語のオリジナルデータを試したい場合はソースコードとコマンドを変更する必要がある。

## 要約
https://github.com/huggingface/transformers/tree/master/examples/summarization/bertabs

[BertSum](https://arxiv.org/pdf/1908.08345.pdf)の著者の[リポジトリ](https://github.com/nlpyang/PreSumm)から最低限必要なソースコードを移植したもの。
BertSumはBERTを要約の分野に適用したもので、ニュース記事の要約では既存手法と比較して精度が大きく向上したと論文の中で述べられている。

英語のニュース記事の要約を試したいだけであればhuggingfaceのもので十分だが、

- データセットを換えて学習したい
- 英語ではなく日本語で試したい

などがあれば、オリジナルの[リポジトリ](https://github.com/nlpyang/PreSumm)をさわる必要がある。

## 固有表現抽出
https://github.com/huggingface/transformers/tree/master/examples/ner

## 翻訳
https://github.com/huggingface/transformers/tree/master/examples/translation/t5
yabaiが動かない時にする設定

#はじめに
私はMacを使っていますが、自分でウィンドウを動かしたり大きさ調整したりするのが面倒なので、タイル型のウィンドウマネージャyabaiを使っています。(やばい！
#たまにyabaiで管理してくれないアプリがある
少なくともデフォルトではGUIのEmacsとかはいい感じにウィンドウを調整してくれなかったんですけど、以下の設定を`.yabairc`に書くと動きました！

```
yabai -m rule --add app=Emacs manage=on
```
`app=xxx`の部分を動かないアプリに置き換えてみてください！
yabaiの再起動は、

```sh

brew services restart yabai
```
でできます!
[Unity初級]prefabしてあるUIパーツをInstantiateで登場させる

#概要
UIパーツはCanvas上に置かないと、存在はしてるのに表示はされない状態になります。
Instantiateで登場させた直後はCanvasに置かれてないのでCanvasへ移す手順が必要になります。
#本文
```cs

    public GameObject canvas;
    public GameObject InputButton;

    void Start()
    {
        GameObject prefab = (GameObject)Instantiate (InputButton);
        prefab.transform.SetParent (canvas.transform, false);
    }
```
![スクリーンショット_(150).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/75e769c2-a7ef-578d-335a-81b719801624.png)

SetParentによってUI(ここではInputButton)をCanvasへ移してます。
学生必見！オンライン授業動画を保存する方法

# はじめに
コロナウイルスが広がる中、塾や学校などでは授業のオンライン化が進んでいます。
毎週配信されていく動画を計画通り進...めばいいのですが、実際はだらけてしまってどんどん溜まっていってしまいますよね？笑
そして気づいた頃には、その動画の公開期限が目前まで迫ってきてしまいます。

そんな時、一番に思いつくのが
**「この動画、保存できたら後で見れるのに〜」**
でしょう。笑

でも、ネットで**「動画　保存」**で調べても、~~「5KPlayer」とかの~~ 怪しいアプリのダウンロードを勧めるサイトばかりです。動画を保存できる保証もなしにそんな変なアプリをいれて、ウイルスにかかったら溜まったもんじゃないですよね。
そこで、**アプリをダウンロードせずに動画を保存する**方法をご紹介します。

>
なお、この方法は**vimeo**で配信されている動画をダウンロードする方法です。
異なる場合でも同じような手順をふむとダウンロードできるかもしれないのでトライしてみてください。


#ダウンロードしよう
以下の手順にしたがって進んでください。

## 大まかな流れ
大まかな流れは以下の通りです。
記事の方法で途中に異なる点があったり、詰まったりした場合はこの流れに沿うように臨機応変に対応してみてください。

① 配信されているページへいく
② その動画のソースであるvimeoのページへいく
③ vimeoの動画のソースのリンクへいく
④ ダウンロード

## １　配信されているページへ行こう
ダウンロードしたい動画のあるページへ行きましょう。
![IMG_0736.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364760/36de3448-3049-db71-378d-f2ecc4c8be24.png)
再生バーが上の画像のような形をしていたら、vimeoが使われています。

それでは、ブラウザのメニューから**デベロッパーツール**を開いてください。
![IMG_0737.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364760/3ff8e218-5e72-c2fd-6f39-0efaae9eeee7.png)
すると、サイトのソースが表示されます。

その中から
「**https://player.vimeo.com/video/...**」
から始まるリンクを探してください。
（**...**の部分には９桁くらいの数字が入ります）
![IMG_F40E9AC50B4D-1.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364760/1375c515-38a9-e02f-acc9-71ddfc9142a0.jpeg)

> chromeを使用している場合は
「command + F」もしくは「control + F」
のショートカットキーで検索することができます。

.
> 数字の後に**?quality=540p**などがついている場合はその部分を取ってしまって構いません。
ちなみにこれは画質を表しています。
何も指定しない場合はautoで画質が設定されます。

## ２　vimeoのページへ行こう
先ほど探してきたリンクをコピペしてそのページへ移動してください。
![IMG_0739.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364760/1a1b1ec6-5f15-2c32-47a7-7170131427c2.png)
ここでも同様に**デベロッパーツール**を開いてください。
そして
「**https://...mp4...**」
のように、**mp4**が含まれるリンクを探してください。
とても長いリンクですが、**" "**（ダブルクオーテーション）で囲まれている部分が該当のリンクです。
（いくつか並んでいるのは画質が異なる動画です。どれを選んでも動画は同じです。）
![IMG_6B80B49345CF-1.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364760/7aff9b32-a01f-5f75-ec3a-4a2cca47d3f9.jpeg)

## ３　ソースのリンクへ行こう
先ほど探してきたリンクへ移動してください。
![IMG_0746.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364760/3fa48f50-0b47-8516-d157-3538a9cc47aa.png)
## ４　ダウンロードしよう
右下のボタンから、ダウンロードを選択してください。
（ブラウザによって異なります）
![IMG_0747.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364760/7c4494d1-3c52-d56a-3f3b-c77c51d953fb.png)
するとダウンロードが開始されます。

# おわりに
動画をダウンロードする方法を紹介しました。
ただ、一番の解決法はしっかり計画通りに動画を進めることでしょう。
Action Cableについて

# 背景
Railsでチャット機能の実装はどのようにするのかなと気になって調べてみると「Action Cable」というものを使うと簡単に実装できるとあったので簡単ではあるが、備忘録として自分なりに概要を書こうと思った。

##Action Cableとは
WebSocketとRailsのその他の部分をシームレスに統合するためのもの。Action Cable が導入されたことで、Rails アプリケーションの効率の良さとスケーラビリティを損なわずに、通常のRailsアプリケーションと同じスタイル・方法でリアルタイム機能をRubyで記述できます。

##実装手順
1.speakというアクションをもつ、ChatRoomチャンネルを作成する
※channels/chat_room.coffeeファイルはいらないので削除する

```
$ rails g channel chat_room speak
```

2.app/assets/javascripts/chat.coffeeをchat.jsにrenameし以下を記述する。

```chat.js

if(/chat/.test(window.location.pathname)) {
  var path = window.location.pathname.split('/');
  var room_id = path[path.length - 1];
  App.chat_room = App.cable.subscriptions.create({ channel: "ChatRoomChannel", room_id: room_id }, {
    connected: function() {},
    disconnected: function() {},
    received: function(data) {
      $('.messages').append(data['content']);
    },
    speak: function(message) {
      return this.perform('speak', {
        message: message,
        room_id: room_id,
        user_id: $('meta[name="current_user_id"]').attr('content')
      });
    }
  });
  $(document).on('keypress', '[data-behavior~=room_speaker]', function(event) {
    if (event.keyCode === 13) {
      App.chat_room.speak(event.target.value);
      event.target.value = '';
      return event.preventDefault();
    }
  });
}
```

3.書き込んだ内容をrenderするために、app/views/chat_messages/_chat_message.html.erb を追加します。

```_chat_message.html.erb
<div class="message">
  <span class="message__name">
    <%= chat_message.user.name %>:
  </span>
  <% if chat_message.user.id == current_user.id %>
    <div class="message__text message_current_user">
      <div><%= chat_message.message %></div>
    </div>
  <% else %>
    <div class="message__text">
      <div><%= chat_message.message %></div>
    </div>
  <% end %>
</div>
```

4.chat_room_channel.rbを以下のように編集する。
フロントから送信されたデータを受け取っているのでそれを加工して送信して、先ほど作ったテンプレートを使ってレンダリングするように実装する。

```chat_room_channel.rb

class ChatRoomChannel < ApplicationCable::Channel
  def subscribed
    stream_for "chat_room_#{params[:room_id]}"
  end

  def unsubscribed
    # Any clkanup needed when channel is unsubscribed
  end

  def speak(data)
    message = ChatMessage.create(chat_room_id: data['room_id'], user_id: data['user_id'], message: data['message'])
    ChatRoomChannel.broadcast_to "chat_room_#{data['room_id']}", content: render_message(message)
  end

  private
    def render_message(message)
      ApplicationController.renderer.render(partial: 'chat_messages/chat_message', locals: { chat_message: message, current_user: message.user })
    end
end

```

5.current_user_idはapp/views/layouts/application.html.erbのmetaタグとして設定してそれを読み出すことで取得できるようにする。

```application.html.erb


<head>
(中略)
<meta name="current_user_id" content="<%= current_user.id if current_user %>">
(中略)
</head>
```

※これで完成なのだが自分の場合はここでターボリンクスが悪さをしてエラーが発生したので同じエラーが起きた場合はターボリンクスを無効化してみてください。
[Rails]Hello ~ Enum ~

はじめに
===
Railsに触れ始め1ヶ月あまり、ふと`enum`に出会った。
その出会いについてまとめてみます

出会い
===
Aさん: 権限とか状態がこのサービスにはたくさんあるんだ
自分: へーそうなんですね。(覚えるの大変そうだな。。。)

しばらく一人で調べてみる。それっぽいのはあるけど、なんかよくわからん。なので聞いてみた

自分: 権限とかってどうやって判断してるんですか？
Aさん: enum 使ってる
自分: enum？何それおいしいの？

私は〜こうして〜enumと~出会ったので〜あったー。


enum is nani?
===
- 皆大好き`ActiveRecord`の追加されたモジュールです。(4.1以降)
- 特定のカラムの値と文字列(シンボル)をマッピングさせる

何が嬉しいの？
===
Userモデルに`state`カラムがあり、属性として`active`と`inactive`があると仮定します。おそらく下記のどちらかのパターンで設計する可能性があるかと思います。

| カラム名 | 型 | 値 | 作成方法 |
| ---- | ---- | ---- | ---- |
| state | string | active or inactive | rails g model User state:string |
| state | integer | 1 or 2 | rails g model User state:integer |

この時に、「とあるユーザが`active`かどうか？」をどう実現しますか？

```
user.state == 'active'
user.state == 1
```

テーブルや属性値が少なければこれで全然問題ないと思います。ただこれが増えていくと大変です。そこで enum の出番です。

enumでやってみる
===
まずはUserモデルを作成します。enumで操作するカラムの型は`integer`にします。
あとはmigrateしてあげましょう。

```
rails g model User state:integer
rails db:migrate
```

次に、enumでやるためにUserモデルにカラムに対するマッピングを定義します。

```
class User < ApplicationRecord
  enum status: { active: 1, inactive: 2 }
end
```

これで準備は整いました。`active`なユーザを作ってみましょう。

```
❯ rails c
Running via Spring preloader in process 8159
Loading development environment (Rails 5.1.7)

User.create(name: 'A', state: :active)
   (0.1ms)  begin transaction
  SQL (0.4ms)  INSERT INTO "users" ("name", "state", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["name", "A"], ["state", 1], ["created_at", "2020-04-25 12:42:27.161288"], ["updated_at", "2020-04-25 12:42:27.161288"]]
   (1.0ms)  commit transaction
=> #<User id: 1, name: "A", state: "active", created_at: "2020-04-25 12:42:27", updated_at: "2020-04-25 12:42:27">
```

ユーザが作成されましたね。integerで型定義したはずの`state`に**active**と入っていますね。
さてこのユーザが`active`なユーザかどうかをチェックしてみましょう。

```
User.first.active?
  User Load (0.3ms)  SELECT  "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ?  [["LIMIT", 1]]
=> true
```

逆に`inactive`かどうかをチェックしてみましょう。

```
User.first.inactive?
  User Load (0.2ms)  SELECT  "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ?  [["LIMIT", 1]]
=> false
```

次に`active`なuser一覧を取得してみましょう。

```
User.where(state: :active)
  User Load (0.3ms)  SELECT  "users".* FROM "users" WHERE "users"."state" = ? LIMIT ?  [["state", 1], ["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<User id: 1, name: "A", state: "active", created_at: "2020-04-25 12:42:27", updated_at: "2020-04-25 12:42:27">]>
```

上記のクエリを見ると、データベース上ではちゃんと値(integer)で保存されているのが確認できますね。enumを使うと、コードをより直感的かつわかりやすくすることができるようになります。

また定義した enum を複数形にしてあげることで定義済みのマッピングを取得することができます。

```
User.states
=> {"active"=>1, "inactive"=>2}
```

まとめ
==
enumを使うことでDBに保存されている値を気にする必要があまりなくなり、かつ直感的にすることができます。ぜひ活用していきたいなと思います。

素晴らしいものに出会えた。。。。。
Github上のリポジトリの操作を自動化するdockerコンテナ

# まとめ

* [Personal access token](https://github.com/settings/tokens)を使うと環境変数で与えやすくて便利ですよ
* gitの名前とメールアドレスの設定は、しないとエラーで怒られます

↑でわかる人はたぶん続き読まなくて大丈夫です。

# ソースコード

https://github.com/skuroki/merger

forkしてきたリポジトリに本体の更新をマージする処理をしています。

webサーバーになってるのはあとでGoogle Cloud Runで動かすためです。そちらについては別記事の[Google Cloud Runでバッチ処理をやらせよう](https://qiita.com/skuroki@github/items/317c1255eda939917774)にて。

`docker run` とかでmain.shを実行すれば直接実行も可能です。

内容は以下の感じ。

```main.sh
rm -rf work
git clone https://$TOKEN:x-oauth-basic@github.com/$USER/$REPOSITORY.git work
cd work
git config user.email $EMAIL
git config user.name $USER
git remote add upstream https://$TOKEN:x-oauth-basic@github.com/$UPSTREAM_USER/$REPOSITORY.git
git fetch upstream
git merge -m "Merge upstream" upstream/master
git push origin master
cd -
```

やってることはほとんどgitの基本操作なので説明は割愛します。ポイントはURLです。

gitの名前とメールアドレスの設定は、しないとエラーで怒られます。

# コンテナ上でgit cloneするのだるいよねって話

Githubからgit cloneしてくる場合、sshかhttpsを使う必要があって、

* sshだと公開鍵とかのファイルが必要
* httpsだと認証で名前とパスワード訊かれるのが自動化するときに面倒だし、パスワード渡したくない

というのがあります。

これを解決するために、

* [Personal Access Tokens](https://github.com/settings/tokens)を作る
  * repo権限が必要
* URLでtokenを渡す形式を使う

という手法を採用しました。URLは先述の内容の通りのフォーマットです。

# 余談：結果を受け取る

Githubのリポジトリには通知を受け取るメールアドレスを設定する機能（リポジトリのSetting→Notifications）があるので、Slackの[転送用のメールアドレスを設定する](https://slack.com/intl/ja-jp/help/articles/206819278-Slack-%E3%81%AB%E3%83%A1%E3%83%BC%E3%83%AB%E3%82%92%E9%80%81%E4%BF%A1%E3%81%99%E3%82%8B#u36578u36865u20808u12513u12540u12523u12450u12489u12524u12473u12434u35373u23450u12377u12427)機能を使って、Slackで通知を受け取るようにして、なんらかのマージが行われたときにはわかるようにしています。
Ubuntu MATE 20.04でFcitx Configurationが起動しないときの対処方法

# 概要

Ubuntu MATE 20.04をクリーンインストールした後，Fcitx Configurationを開こうとしたところ，これが正常に起動しなかった．これは，同OSの正式版リリース直後である2020年4月25日に確認されたことからバグかと考えられる．この対処法を示す．

# 結論

以下のコマンドで，`fcitx-config-gtk`をインストールする．

```shell-session:how_to_fix
sudo apt install -y fcitx-config-gtk 
```

# 環境

以下の環境で動作確認を行った．

```shell-session:environment
$ cat /etc/os-release
NAME="Ubuntu"
VERSION="20.04 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal

```


# 対処に至った経緯

## GUIの設定画面が開かない

以下のウィンドウが表示され，`OK`ボタンを押すと，テキストの設定ファイルが表示された．

![informatiopn.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232491/e5b7e984-ddfa-d780-f655-85e6a4219e61.png)


表示されたメッセージは，以下のとおりである．

>
You're currently running Fcitx with GUI, but fcitx-configtool couldn't be found, the package name is usually fcitx-config-gtk, fcitx-config-gtk3 or fcitx-configtool. Now it will open config file with default text editor.

## `the package`を探す

`the package name is usually fcitx-config-gtk, fcitx-config-gtk3 or fcitx-configtool`のパッケージに該当するものを，aptコマンドを用いて探した．この結果，`fcitx-config-gtk`がヒットした．

```shell-session:search_for_fcitx-config*
$ apt search fcitx-config
Sorting... Done
Full Text Search... Done
fcitx-config-common/focal,focal 0.4.10-3 all
  graphic Fcitx configuration tool - common files

fcitx-config-gtk/focal 0.4.10-3 amd64
  graphic Fcitx configuration tool

fcitx5-module-quickphrase-editor/focal 1.2.4-1build2 amd64
  Flexible Input Method Framework - Quick Phrase editor module

kde-config-fcitx/focal 0.5.5-2build1 amd64
  KDE configuration module for Fcitx

libfcitx-config4/focal,now 1:4.2.9.7-3 amd64 [installed,automatic]
  Flexible Input Method Framework - configuration support library
```

## 解決

以下のコマンドで，`fcitx-config-gtk`をインストールすると，正常に起動するようになった．

```shell-session:how_to_fix
sudo apt install -y fcitx-config-gtk 
```


# 最後に

`Ubuntu MATE in Launchpad`に，バグレポートをしておきました．もし，修正したほうが良い点があれば，ご教示ください．[GUI Fcitx Configuration cannot run on Ubuntu MATE 20.04](https://bugs.launchpad.net/ubuntu-mate/+bug/1875014)
【Linux】よく使う基本コマンドの復習

AWS構築でLinuxの知識の足りなさを痛感したので、改めて基本コマンドの復習をします。

#ディレクトリの操作
ディレクトリを操作したいときに使用する基本コマンドたち。

##cdコマンド
ディレクトリを移動するコマンド。


```
#ルートディクトリに移動
cd /
```

##pwdコマンド
カレントディレクトリ（自分がいるところ）を表示。

```
pwd
/Users/hukushima
```

##lsコマンド
ディレクトリ内を一覧表示するコマンド。

```
ls
Applications				Public
Creative Cloud Files		VirtualBox VMs
Desktop					    bash
```

###パス名展開
複数のファイルを一度に指定できる。

```
ls *.html
index.html                   home.html
```

###オプション
####-a
隠しファイルも表示する。

```
ls -a
.DS_Store			media-3-211-600x600.jpg
.localized			index.html
```
####-l
ファイルの詳細情報を表示する。

```
ls -l
drwxr-xr-x  10 hukushima  staff     320  3 29 19:59 javascript_practice
-rw-r--r--@  1 hukushima  staff   44368  4 20 01:03 media-3-211-600x600.jpg
-rw-r--r--@  1 hukushima  staff     296  3 28 21:09 index.htm
```

##mkdirコマンド
ディレクトリを作成するコマンド。

```
mkdir work
```

###オプション
####-p
深いディレクトリを作る。

```
mkdir -p work/test/2020
```

#ファイルの操作
ファイルを操作したいときに使用するコマンドたち。
##catコマンド
ファイルの中身を確認するコマンド。

```
cat test.txt
test
test
```

###オプション
####-n
行番号も表示する。

```
cat -n test.txt
1  test
2  test
```

##touchコマンド
ファイルを作成するコマンド。

```
touch index.html
```

##rmコマンド
ファイルを削除するコマンド。

```
rm index.html
```

###オプション
####-r
ディレクトリも合わせて削除。
中身もろとも完全削除される。

```
rm -r dir
```

####-f
削除する際、警告文を表示しない。
-rと合わせて使うことが多い。


```
rm -r dir
```
```
rm -rf dir
```

##mvコマンド
ファイルの移動、ファイル名の変更を行うコマンド。

```
# ファイル名の変更
# mv 変更前　変更後
mv index.html home.html
```

```
# ファイルの移動
# ファイル名　移動先ディレクトリ
mv home.html dir
```

##cpコマンド
ファイルやディレクトリをコピーする。

```
# ファイルをコピー
cp index.html new_index.html
```

```
# ファイルをディレクトリにコピー
cp index.html dir
```

###オプション
####-r
ディレクトリ をコピーする。

```
cp -r dir new_dir
```

##lnコマンド
リンクを貼るコマンド。
Windowsで言うショートカット的なやつ。

###ハードリンクとシンボリックリンク
####ハードリンク
1つのファイルの実態そのものに複数の名前をつける。
削除しても消えない。
でもあまり使わないイメージ。

```
ln file_a file_b
```
####シンボリックリンク
Windowsのショートカットと一緒。
リンク先のファイルにつながってる。

```
ln -s file_a file_c
```

##findコマンド
ファイルやディレクトリを探すコマンド。

```
# find 検索開始ディレクトリ　検索条件　検索アクション
find . -name index.html -print
```
ワイルドカードも使えます。


#まとめ
ひとまずこの辺りのコマンドはよく使うと思います。
基本中の基本ではありますが、飲水思源、深根固柢と言いますし、
何事も基礎は大事ですので自宅待機の間はコマンド操作を徹底させたいと思います。

ではでは。
フェイスシールド Prusa モデルをつくってみた


[前の記事](https://qiita.com/maco-san/items/67bf589a3aaa7c503c8e)でフェイスシールドについて調べてみましたが、この情報を書いていたら動き始めました。[Budman フェイスシールド](https://qiita.com/maco-san/items/67bf589a3aaa7c503c8e#budmen-%E3%83%95%E3%82%A7%E3%82%A4%E3%82%B9%E3%82%B7%E3%83%BC%E3%83%AB%E3%83%89)のマッチングサイトをみた方が連絡をくれて、フェイスシールドを量産(最初は100個を目標)することにしました。ここで、急遽作成することになり、Prusa のモデルを採用し量産体制に入りました（といってもずっとただ印刷するだけですけど）。そこで、Prusa が公開している情報をもとに必要なことをまとめておきたいと思います。

### 1. なぜ Prusa モデルを採用したのか

公開されているフェイスシールドは世界中にいろいろあります。今回は、あまり試行錯誤をしている時間がないので以下のことを優先しました。
- モデルのバージョンが安定している
- 印刷時間が短い
- 老若男女だれでも安全に快適に着用できる

### 2. Prusa のモデルバージョンと印刷時間

Prusaのモデルは大きく分かれてヨーロッパ版とアメリカ版、各々にRC1, RC2, RC3 と存在しています。

![alt](https://www.prusa3d.cz/wp-content/uploads/2020/04/FS_diagram_v3.png)

#### EU版とアメリカ版の違い

![alt](https://media.prusaprinters.org/thumbs/cover/640x480/media/prints/27950/images/279325_253e1b16-a093-49be-91fc-94f9d58f6cf5/3_pins.jpg)

一般的に入手できる部品で作ることを目指しているので、若干バージョンに違いが出ています。例えば、アメリカでは穴あけパンチは３つ穴、インチが一般的な単位であるに対して、EU版は二つ穴でセンチメートルがよくつかわれる単位です。日本で作成するのであれば、EU版を採用するのがよいでしょう。

![alt](https://blog.prusaprinters.org/wp-content/uploads/2020/03/rc1_vs_rc2-scaled.jpg)

#### RC1型
最初に開発されたモデルで、カチューシャのような円に近い形をしています。コンパクトですがフィットしやすいですが、ちょっと頭の大きな人に試したところ「痛い」と言っていました。小さく見えるので印刷時間は短そうですが、横からみると全面に穴が開いている凝ったデザインなので意外と時間がかかりました。

#### RC2型
頭の幅を大きくして「誰でも快適に装着できるように」改良されています。なかなかこの弧が絶妙な角度と長さでゴムバンドを付けたときに邪魔にならずぴったりフィットするデザインです。

#### RC3型
RC2の改良版で、よりはやく印刷できて複数枚印刷できるスタック対応用に改善されています。一枚印刷するのに標準であれば2時間40分程度で安定して印刷ができました。[スタック印刷](https://www.prusaprinters.org/prints/27267-prusa-protective-face-shield-rc31-stack-versions)を行うと一枚1時間20分程度まで時間が短縮できますが、私の環境では品質が安定するのが少し難しいので悩ましいところ（まだいろいろ混ぜながら試行錯誤中）。

各モデルのダウンロードサイト：
全ファイルのダウンロード
https://www.prusaprinters.org/social/16-prusa-research/collections/17041

ヨーロッパ版のダウンロード
https://www.prusaprinters.org/prints/25857-prusa-face-shield

#### 3Dプリンタで印刷すべき部品
- フェイスシールド部分（必須）
- ボトム部分（顎のところ。あった方がいい）
- バイザー部分（上からの飛沫をふぜぐ屋根部分。オプション）

#### 別途そろえる必要がある部品
- フロントパネル　プラ板。A4もしくはそれ以上でアルコール消毒につよい素材が望ましい。
- バンド　後ろのゴム。1.5 - 2.0 mmのものが望ましい。私は穴が開いてる「ボタンホールゴム」を使っています。例：[アマゾンのボタンホールゴム](https://www.amazon.co.jp/Clover-%E3%83%9C%E3%82%BF%E3%83%B3%E3%83%9B%E3%83%BC%E3%83%AB%E3%82%B4%E3%83%A0-20mm%E5%B9%85-1-2m%E5%B7%BB-26-034/dp/B0072MH0KC/)

#### その他あるとよい工具
- 3Dプリンタ(もちろん)
- 2つ穴あけパンチ
- [コーナーカッター](https://www.amazon.co.jp/MULTICRAFT-%E3%82%B3%E3%83%BC%E3%83%8A%E3%83%BC%E3%82%AB%E3%83%83%E3%82%BF%E3%83%BC-L%E3%82%B5%E3%82%A4%E3%82%BA-%E3%82%B0%E3%83%AA%E3%83%BC%E3%83%B3-SCC-10L/dp/B076M9SBQ9/)必須じゃないけどプロっぽくなる！
- はさみ

フロントパネルの穴をあけるときに穴の位置はこちらを参照のこと：https://prusa3d.com/downloads/others/COVID19_SHIELD_FOIL.pdf

そして大事なことは、3D プリンタのフィラメントはアルコール消毒に強いものを使いましょう。おすすめはPETGです。また、PETGで最適化された印刷用のファイルも数多く存在するのでその恩恵を受けられることは間違いありません。

### 3.実際に制作してみて
やればやるほど、さすがPrusaと感心することばかり。とても丈夫で海外で数多くの医療機関で使われ繰り返し改良されていただけのことがある！少し適当に作っても同着感はばっちり。外れてしまうことはありません。そして子供から大人まで装着可能です。命を守るためのシールドとして、実績と信頼が積み重ねられています。

### 4. おまけ
もし、ここを読んでから[プリントマニュアル](https://media.prusaprinters.org/media/prints/25857/pdfs/25857-prusa-face-shield-a2e7ac38-071f-4914-ba47-d2b75449fac1.pdf#_ga=2.145697716.1006542862.1587814383-310982073.1587178383)を読めばだいぶわかりやすいと思います。もし、プリントマニュアルの日本語化希望者がいればご連絡ください。（需要があれば日本語化してもいいかな、と思っています。が、どうなのかなあ....）
pgadmin4のテーブル構造

# はじめに
centos7で、pgadmin4 を利用してpostgresqlを参照しているが、毎回手動でサーバを登録するのが面倒なので、省力化する方法を考えてみました。

# 調べてみると
pgadmin4 のデータファイルは、centos7にインストールした場合、/var/lib/pgadmin/pgadmin4.db というファイルで管理されており、sqlite3 というRDBのようです。
※ pgadmin4 は yum でインストールしました

# テーブル構造
``` # sqlite3 /var/lib/pgadmin/pgadmin4.db ``` でDBにログインできます。
ログイン後は、
``` .schema ``` コマンドで、テーブルの内容が出力されます。

いくつかテーブルがあるようですが、関係するテーブルは、
1. server_group
2. user
3. server 
の3つのようです。

それぞれのテーブルは以下のような情報が格納されているようです。
　1. server_group

|カラム名  |内容  |
|---|---|
|id  |シーケンス値  |
|user_id |userテーブルのidカラムの値 |
|name |名称 |

　2. user

|カラム名  |内容  |
|---|---|
|id  |シーケンス値  |
|email |pgadminにログインするときのID |
|password | |
|active | |
|confirmed_at | |
|materpass_check | |

今回は、上記2テーブルについては、すでに登録されているものを使用しますので、最後のserverテーブルにinsertすべき値について考えてみます。

　3. server

|カラム名  |内容  |insertした値(空白の個所は無視) |
|---|---|---|
|id  |シーケンス値  |serverテーブルのidの最大値+1 |
|user_id |userテーブルのIDカラムの値 |userテーブルから取得した値 |
|servergroup_id |servergroupテーブルのIDカラムの値 |servergroupテーブルから取得した値 |
|name |表示される名称 |任意の値 |
|host |アクセス先DBのホスト名 |アクセス先DBのIPアドレス(xxx.yyy.zzz.aaa) |
|port |アクセス先DBのポート番号 |通常は5432 |
|maintenance_db| |postgrers |
|username|アクセス先DBのユーザ名|同左 |
|password|パスワード(暗号化方式等は不明)| |
|role| | |
|ssl_mode| |'prefer'|
|comment| | |
|discovery_id| | |
|hostaddr| | |
|db_res| | |
|passfile| | |
|sslcert| |'<STORAGE_DIR>/.postgresql/postgresql.crt' |
|sslkey| |'<STORAGE_DIR>/.postgresql/postgresql.key'|
|sslrootcert| | |
|sslcrl | |
|sslcompression| | |
|bgcolor| | |
|fgcolor| | |
|service| | |
|use_ssl_tunnel| | |
|tunnel_host| | |
|tunnel_port| |22 |
|tunnel_username| | |
|tunnel_authentication| | |
|tunnel_identity_file| | |
|connect_timeout| | |
|tunnel_password| | |

# アクセス方法
sqlを作成して、sqlite3コマンドで実行する方法もありますが、javaのプログラムからアクセスすることにしました。
jdbcドライバは、mavenの場合は以下のようになります。
```
<dependency>
    <groupId>org.xerial</groupId>
    <artifactId>sqlite-jdbc</artifactId>
    <version>3.30.1</version>
</dependency>
```

Connectionの取得は下記のようになります。DriverManager.registerDriver()は不要のようです。

```
DriverManager.getConnection("jdbc:sqlite:/var/lib/pgadmin/pgadmin4.db")
```
JSのモジュール機能とbabelとwebpackと

#CommonJSとECMAScript
JavaScriptにはサーバサイドのNodeJS(CommonJS)とブラウザのJavaScript(ECMAScript)の二つの言語仕様がある．

二つはモジュール機能（JavaScriptファイルを外部参照する機能）の記述に関して大きな違いがある．

##CommonJSのモジュール機能
CommonJSでモジュールを外部参照できるようにするためには，主にmodule.exportsを使う．

```Javascript:abc.js
module.exports = 変数１，　変数２，　．．．
```

CommonJSでモジュールを参照するためには，requireを使う．
requireで参照するモジュールのファイル名を指定することで，module.exportsした変数そのものを参照することができる．

```Javascript:
const abc = require('abc')
```

##ECMAScriptのモジュール機能
ECMAScriptでモジュールを外部参照できるようにするには，主にexportもしくはexport defaultを使う．

```Javascript:abc.js
export 変数
export default 変数
```

ECMAScriptでモジュール参照するためには，importを使う．
※import分はトッブレベルでないと使えない（ブロック中では使用不可）．

```Javascript:
import { 変数 } from 'abc' //export変数を参照する場合
import abc from 'abc' //export default を参照する場合
```

###CommonJSでもimport/exportが使用可能に
package.jsonに```"type":"module"```の設定を追加することでimport/exportが使用可能．

#babel
フロントエンドの実装には，ブラウザ間でHTML，CSS,JSの実装レベルが異なるという大きな問題がある．
この問題に関して新しいJS文法を古いJS文法に変換して古いブラウザでも使えるようにするためのツールがbabelである．
babelの役割は非常に多く，様々なことが実現可能である．

* 新しいJS文法から古いJS文法への変換
* NodeJSでECMAScriptのimport/exportの実装
* ReactなどのJSX文法の変換
* TSからJSへの変換

##babelの設定ファイル
.babelrc, babel.config.js,babel.config.cjs,babel.config.jsonのいずれかの設定ファイルに設定を書くか
webpackの場合，babel-loaderプラグインのoptionsに指定する方法が存在．

#webpack
webpackは，JavaScriptアプリケーション用の静的モジュールバンドルである．
webpackがアプリケーションを処理するとき，プロジェクトが必要とする全てのモジュールをマップし，１つ以上のバンドルを生成する依存関係グラフを内部で構築する