OmniAICreator/Qiita-1.07M huggingface dataset:
[AtCoder]AtCoder Beginner Contest 195

# はじめに
* AtCoder Beginner Contestの過去問の解法及び提出したソースコードをまとめています。
* 基本的に自分が振り返ることを目的としておりますが、誤りや気になった点、その他質問等もお待ちしておりますので遠慮なくお願いします。

# コンテストページ
https://atcoder.jp/contests/abc195

# A問題
HがMの倍数であるか判定したいので、HをWで割った余りが０かどうかを確認してあげればよいです。

```c++
#include <bits/stdc++.h>
using namespace std;

int main()
{
    int m,h;
    cin >> m >> h;
    if(h%m==0) cout << "Yes" << endl;
    else cout << "No" << endl;
    return 0;
}
```
# B問題
まず最初にWをグラムに直すことを忘れず。
Wを１からWまでの整数Xで割ったときの値をYとすると、「YグラムのみかんをX個選ぶ」と言い換えられます。
Yが[A,B]の範囲に含まれるかを判定し、含まれる場合のXの最大最小を求めてあげればよいです。

```c++
#include <bits/stdc++.h>
using namespace std;

int main()
{
    double a,b,w;
    cin >> a >> b >> w;
    w*=1000;

    int mn = INT32_MAX;
    int mx = 0;
    for(int i = 1; i <= w; i++){
        if(w/i >= a && w/i <= b){
            mn = min(mn, i);
            mx = max(mx, i);
        }
    }

    if(mn == INT32_MAX) cout << "UNSATISFIABLE" << endl;
    else cout << mn << " " << mx << endl;
    return 0;
}
```
# C問題
1000のi乗から1000のi+1乗引く1の各数に含まれるコンマの数はi個です。
上記を考慮しnの範囲で足していけばよいです。

```c++
#include <bits/stdc++.h>
using namespace std;
#define ll unsigned long long

ll powll(ll x, ll n){
    ll ret = x;
    for(ll i = 0; i < n; i++) ret *= x;
    return ret;
}

int main()
{
    ll n;
    cin >> n;
    ll ans = 0;
    for(ll i = 0; i < 6; ++i){
        ll p = powll(1000, i) - 1;
        if(n > p) ans += n - p;
    }
    
    cout << ans << endl;
    return 0;
}
```
# D問題
荷物を価値の高いものから順にソート(同じ価値の場合は重さが軽い方が前方)して空いている箱のうちその荷物を入れられる最小の容量の箱に詰めていけばよいです。

```c++
#include <bits/stdc++.h>
using namespace std;

int main()
{
    int n,m,q;
    cin >> n >> m >> q;
    vector<pair<int,int>> wv(n);
    vector<int> x(m);
    for(int i = 0; i < n; i++) cin >> wv[i].first >> wv[i].second;
    for(int i = 0; i < m; i++) cin >> x[i];

    sort(wv.begin(), wv.end(), [](auto l, auto r){
        if(l.second > r.second) return true;
        else if(l.second < r.second) return false;
        else  return (l.first < r.first);
    });
    
    for(int i = 0; i < q; i++){
        int l,r;
        cin >> l >> r;
        l--;r--;
        vector<int> tmp_x;
        for(int i = 0; i < m;i++){
            if(l <= i && i <= r) continue;
            tmp_x.push_back(x[i]);
        }
        vector<bool> done((int)tmp_x.size(), false);
        sort(tmp_x.begin(), tmp_x.end());
        int ans = 0;
        for(int i = 0; i < n; i++){
            for(int j = 0; j < (int)tmp_x.size(); j++){
                if(done[j]) continue;
                if(tmp_x[j] >= wv[i].first){
                    ans += wv[i].second;
                    done[j] = true;
                    break;
                }
            }
        }
        cout << ans << endl;
    }

    return 0;
}
```
# E問題(未AC)
まだ解いておりません。

# F問題(未AC)
まだ解いておりません。
Rubyにおけるオブジェクト、クラス、インスタンス、メソッド、インスタンス変数とは

##本記事の目的
タイトル通り、Rubyにおけるオブジェクト、クラス、インスタンス、メソッド、インスタンス変数という言葉がどのような意味を持つのかを記述していきます。プログラミングにおいては何かが何かを包含してピラミッド構造のようなものを構成している点が特徴的だと感じたので、それに着目し、より高次の概念を表す用語が上に来るように書きました。
##オブジェクト
Rubyではあらゆる「データ」がオブジェクトです。Rubyのなかでオブジェクトではないものはないと思い込んでいたのですがそれは誤りで、「データ」でないメソッドなどはオブジェクトではありません。
##クラス
クラスはオブジェクトを生み出し、オブジェクトの振る舞いを規定するものです。
##インスタンス
全てのオブジェクトは何らかのクラスに属します。その際に「所属先」のクラスに対し「所属するオブジェクト」がインスタンスと呼ばれます。
##メソッド
メソッドとはオブジェクトについての一連の処理を定義したものです。例として文字列オブジェクトの文字数を返すlengthメソッドなどがあります。メソッドはデータではないため、必然的にオブジェクトではないということになります。
また、メソッドが呼び出されたオブジェクトをそのメソッドのレシーバといいます。
##インスタンス変数
メソッド内で定義された変数は通常メソッドの外では機能しませんが、@から始まるインスタンス変数なら、クラス内のインスタンスの中でならどこでも使えます。
##では結局オブジェクトとは何なのか？
オブジェクトとは何かを理解するには、理屈だけでなく感覚的にオブジェクトを理解することが必要だそうです。自分がその域に達するのはまだ先のように思えますが、今のところオブジェクトとは、自然言語における主語と述語のような相互補完関係をメソッドと築いているものなのかなと思います。（メソッドは繋げられるが自然言語で述語が連続したら文法的におかしいという違いはありますが）
pythonファイルの先頭に数字を使うとSyntaxErrorになる

参考書の勉強で章ごとに5_7_3.pyとか使っていて、あるとき他のファイルからモジュールをインポートしようとしたらエラーになった。

```python

from 5_7_2 import TwoLayerNet
==> from 5_7_2 import TwoLayerNet
         ^
SyntaxError: invalid syntax
```
ファイル名を変えたりしてみると先頭に数字を使っていることがどうやら問題になっているっぽい

```python
from twolayer572 import TwoLayerNet
#こっちは実行できた
```
また先頭数字でもそれ単体で実行はできるけどimportしようとするとエラーになります。
ggplotでのAes関数の説明の備忘。

　
ggplotでつかうaes関数であったり、直接書き込む描画パラメータであったりについて
`ggplot2-specs` をヘルプで調べると色々と具体例を示しながらへｌ教えてくれる。

もしRStudio使ってないなら、以下のリンクでも、同じ情報がみれる。

https://ggplot2.tidyverse.org/articles/ggplot2-specs.html
DynamoDBでインクリメンタルなIDを管理する場合の実装

# 概要

状況としては以下の様な場合を想定

- 各グループ毎にインクリメンタルなIDを管理する
- グループの設定を管理するテーブルに最新のIDを保存

## 結論

1. 更新式でADDを使ってインクリメントしてIDを生成する
※ただしIDの間が抜ける可能性がある

2. IDの抜けが許容できない場合はトランザクションでUpdateとPutする
※Lockを考慮する必要がある

### 1. インクリメントするやり方

サンプルはGoと[guregu/dynamo](https://github.com/guregu/dynamo)を使用したコードとなります

```go
var domainConfig DomainConfig
err := configTable.Update(hashkey, target).
    Add("CurrentID", 1).
    Value(&domainConfig)
if err != nil {
    // error処理
}

data.ID = domainConfig.CurrentID
err = dataTable.Put(data).Run()
if err != nil {
    // error処理
}
```

上記の書き方で現在のIDに+1した値が確実に取得できるので、このIDをデータにセットすればグループ毎にインクリメンタルなIDを使うことができる
ただし、取得した後のPut処理が失敗した場合、取得したIDが使われないケースがある

### 2. トランザクションを使って確実にIDをセットするやり方

DynamoDBのトランザクションはGet系と更新系でしかまとめられないので、Getしてから設定をUpdate、データをPutするところまで全てを同一のトランザクションに入れることはできない
なので条件付きのUpdate処理を使うことでデータが既に更新されている場合は更新しないようにする
以下の様にトランザクションを使ってUpdateとPutを実行し、かつ設定をUpdateする条件にCurrentIDが変更されていない時のみとすればIDが先に更新されてしまった場合はエラーとなるのでIDがずれることはなくなる
ただし、先に他の処理に更新されてしまった場合や、トランザクション処理中にDBアクセスした時はエラーとなるため、リトライ処理を検討する
大量のバッチ処理時にはロックをかけて複数の処理が同時に実行されないような工夫をしないと、大量にエラーとなってしまうので注意する

```go
err := configTable.Get(hashkey, domainID).One(&domainConfig)
if err != nil {
    // error処理
}
data.ID = domainConfig.CurrentKey + 1

tx := db.WriteTx() // dbは *dynamo.DB
tx.Update(configTable.Update(hashkey, domainID).
    Set(currentID, key).
    If("$ = ?", "CurrentID", domainConfig.CurrentID)) // CurrentIDが変更されていない時のみ更新する
tx.Put(dataTable.Put(data))
err = tx.Run()
if err != nil {
    // error処理
}
```
aws-sdkを使用して、sesでメールを送信する

lambda内で処理した結果をsesを使用してメールで送信する。

## 環境
```
serverless -v
```
>Framework Core: 2.1.1
Plugin: 4.0.4
SDK: 2.3.2
Components: 3.1.3

```
node -v
```
>v14.7.0

## 目次
1. メールアドレス登録
2. serverless create
3. コード追加

## メールアドレス登録
awsマネジメントコンソールにアクセス、sesのコンソール画面に移動。
![スクリーンショット 2021-03-14 19.06.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022774/b2cbc0fa-2a27-243f-2a5e-ac9498bb9442.png)

画面上部のVerify a New Email Addressをクリックする。
![スクリーンショット 2021-03-14 19.07.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022774/cb019435-bbfb-efe9-2c64-c9176164b63c.png)
クリックしたらモーダルウィンドウが出てくるので、登録したいメールアドレスをクリック。
登録したら、awsから認証のメールが届くので、届いたメールのリンクをクリックし、認証を完了させる。

### sandboxから外す
このままでは、認証を得たメールアドレスに対してしかメールを送信することができません。
登録したメールアドレスをsandboxから外しましょう。
> [公式ドキュメント](https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/request-production-access.html)

やることは簡単で、
Email Sending > Sending Statisticsより、Edit your account detailsをクリック
![スクリーンショット 2021-03-14 19.16.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022774/d477df63-2d10-8c16-74a7-bb05af19e8be.png)

Enable Production AccessをYesに変更するだけです。
他の項目は記入しなくても承認されるかと思われます。
一応他項目の詳細を記入しておきます。

* Mail Typeは送信する予定のメールの種類を選択します。特に理由がなければ、Transactionalのままでokです。
* Website Urlは所属している企業の会社説明のurlがベターかと思います。これの用途はAWSが、これから送信する予定のコンテンツの種類を理解するためです。なので、個人開発をしている方はtwitterなどのリンクでもいいかと思います。
* Use case descriptionは、Amazon SES を使用してメールを送信する方法を記入します。
* Preferred contact languageは母国語を選択してください。

![スクリーンショット 2021-03-14 19.18.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022774/a6118e0c-b873-750a-c7cc-b9f363c735ac.png)

Submit for reviewをクリック後、10分ほどで、Production AccessがSandboxからEnabledに変更されると思います。変更されたら承認されたということです！🎉

## serverless create
今回はTypeScriptを使用します。

```
serverless create -t aws-nodejs-typescript -n sample -p ./sample
```

```
npm install
```

```
npm install aws-sdk
```

## コードを追加
今回は、受け取ったevent変数の文字列を送信してみたいと思います。

```typescript:handler.ts
export const index = async (event: string) => {
  const params = {
    Destination: {
      ToAddresses: "送信先のメールアドレス",
    },
    Message: {
      Body: {
        Text: {
          Data: `event`,
          Charset: "utf-8",
        },
      },

      Subject: {
        Data: "テスト",
        Charset: "utf-8",
      },
    },
    Source: "sesに登録したメールアドレス",
  };
  return ses.sendEmail(params).promise();
};
```

デプロイ

```
sls deploy -v
```

AWSコンソールのlambdaの画面から今回デプロイした関数に対してテストを実行すると、引数に入れた文字列が本文となって、メールが送信されていることが確認できるかと思います。

参考url
https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/request-production-access.html
https://dev.classmethod.jp/articles/lambda-to-ses/
ActiveRecord を googleauth の TokenStore として使う方法 

Google API を Ruby から操作するための Google 製 gem が [googleauth](https://rubygems.org/gems/googleauth?locale=ja) で、これは当然 OAuth2 のトークンをファイルや DB に保存しておくように作られているが、中に含まれているトークン保存のためのクラス (TokenStore) は以下の2種類しかなくて、つまり ActiveRecord 用の TokenStore は用意されていない。

* FileTokenStore (https://github.com/googleapis/google-auth-library-ruby/blob/master/lib/googleauth/stores/file_token_store.rb)
* RedisTokenStore (https://github.com/googleapis/google-auth-library-ruby/blob/master/lib/googleauth/stores/redis_token_store.rb)

だけど、上記 2 クラスは Google::Auth::TokenStore https://github.com/googleapis/google-auth-library-ruby/blob/master/lib/googleauth/stores/redis_token_store.rb を継承しているようだったので、雑に継承して通せたのでメモ。

これから作るのは、

* GoogleAuthToken ( token_key と client_id の組をもつ Model )
* ActiveRecordTokenStore ( Google::Auth::TokenStore のサブクラスで、 ActiveRecord 用 )

```bash
$ rails generate model google_auth_token token_key:string client_id:string 
```



```ruby
class GoogleAuthToken < ApplicationRecord
  belongs_to :user #これは任意だけど、ふつうこういう形になるんじゃないかな 
  validates :token_key, presence: true, uniqueness: true
  validates :client_id, presence: true
end
```

`app/models/active_record_token_store.rb` に、

```ruby

 class ActiveRecordTokenStore < Google::Auth::TokenStore
  def initialize user_id
    @user_id = user_id
  end

  def load id
    record = GoogleAuthTokenStore.find_by! user_id: @user_id, token_key: id
    record.to_json
  end

  def store id, token
    json = JSON.parse(token)
    client_id = json["client_id"]
    access_token = json["access_token"]
    refresh_token = json["refresh_token"]
    expiration_time_millis = json["expiration_time_millis"]
    record = GoogleAuthToken.find_or_initialize_by user_id: @user_id, token_key: id, client_id: client_id, access_token: access_token, refresh_token: refresh_token, expiration_time_millis: expiration_time_millis
    record.save
  end

  def delete id
    record = GoogleAuthToken.find_by! user_id: @user_id, token_key: id
    record.destroy
  end
end
``` 




こんな感じにしておけば、例えば

```ruby 
def authorize client_id, token_store
  Google::Auth::UserAuthorizer.new client_id, [
    Google::Apis::DriveV3::AUTH_DRIVE,
  ], token_store
end
```

とすると、 API アクセスしやすい。
[Vue]パスの変更を監視する

#概要
Vue.jsでパスの変更を監視したかったので、手法をメモします。

#環境
Vue.js 2.5.17

#実装
```.vue
<script>
export default {
  watch: {
    $route(to, from) {

    },
  },
}
</script>

```

$routeをwatchで監視すればパスの変更によって処理することができます。
ポートフォリオサイト【MySweetSauna】を公開しました

# MySweetSauna
![スクリーンショット 2021-03-10 20 50 18](https://user-images.githubusercontent.com/43335573/110625007-40854580-81e2-11eb-878b-d9358440db52.png)

サウナ施設の情報を共有したり、地図から登録済みサウナ施設を探せたり、様々な機能を取り揃えたサウナ好きのためのWebアプリケーションです。

https://github.com/Wataru9029/mySauna/

# URL
https://www.mysauna.tk/

* トップページ右上にあるログインボタンをクリックしログイン画面に遷移します。
* 「簡単ログイン」のボタンをクリックすると、フォーム入力することなくログイン可能です。

# 制作の背景
* サウナ施設の共有と備忘録のために作成しました。
* 施設によっては感染対策が施されていないことがあり、このご時世サウナに行きづらいと感じていたので、おすすめ度と感染対策度の星評価を登録できるようにしました。
* また現在地から1番近いサウナを探せるように、"マップから探す機能"を作成しました。

# 機能一覧
## ユーザー機能
![mysauna_login.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/414649/b210a4fd-5eff-937a-ba46-0b8ce220c6e6.gif)

* ユーザー登録・編集・削除(deviseのgemを使用)
* ゲストログイン
* プロフィール画像の登録・編集(carrierwaveのgemを使用)
* 管理者権限のあるユーザーのみ、ユーザー管理可能(rails_adminのgemを使用)

## サウナ施設の投稿機能
![mysauna_post.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/414649/8d863d1e-aecf-3aaa-6dae-0771aa3bb452.gif)

* お気に入りのサウナ施設(施設の写真、名前、住所等)を投稿
* 一覧表示、詳細表示
* 地図表示(Google Maps API)
* タグ付け機能(acts-as-taggable-onのgemを使用)
* 投稿へのいいね機能(非同期通信)
* 投稿へのコメント機能
* サウナ施設の検索機能(施設名、説明文、住所のOR検索)

## フォロー機能
![mysauna_follow.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/414649/e5f94b1a-5ea8-754b-8d0a-fbd158cefea2.gif)

* ユーザーのフォロー・フォロー解除(非同期)
* フォロー中のユーザーとフォロワーの一覧表示

## メッセージ機能
![mysauna_message.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/414649/fc04a11c-3465-e2bb-54df-6733afc85294.gif)

* ユーザー同士のメッセージ機能(作成、削除)

## 通知機能
![mysauna_notification.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/414649/21831e3e-caad-6246-e612-6e2cecb1bf6a.gif)

* 以下のタイミングでユーザーに通知を送信(自分の投稿がいいねされた時、自分の投稿にコメントされた時、他ユーザーからフォローされた時)
* 通知の一覧表示
* 未確認の通知がある場合はマークを表示

## その他の機能
![mysauna_mapindex.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/414649/c6759d8f-3d2e-8a28-cc4e-ae8403088222.gif)

* ランキング機能(いいね順、高評価順、感染対策順)
* 登録済みサウナ施設をマップから探す機能(Google Maps API)
* ページネーション機能(kaminariのgemを使用)
* HTTPS通信(AWS Certificate Manager)
* レスポンシブ対応

# 環境・使用技術
## フロントエンド
* HTML/CSS
* JavaScript, jQuery
* Bootstrap 4.3.1

## バックエンド
* Ruby 2.5.3
* Ruby on Rails 5.2.2

## 開発環境
* MySQL
* Docker/docker-compose

## 本番環境
* AWS(EC2, RDS, VPC, ALB, S3, Route53, ACM)
* Nginx
* Puma
* CircleCIにてdocker-composeよりコンテナを構築し、Capistranoを使って自動デプロイ
* MariaDB

## テスト
* Rspec(単体・統合)
* CircleCIにてdocker-composeよりコンテナを構築し、自動テスト

## その他使用技術
* Google Maps API
* 非同期通信(投稿へのいいね、ユーザーのフォロー)
* コードの自動修正(Rubocop)
* Githubの活用(プルリクエスト、マージ等)

# インフラ構成図
<img style="max-width:100%;" alt="readme_infrastructure" src="https://user-images.githubusercontent.com/43335573/107848024-cc01f580-6e33-11eb-916a-62991825b94f.png">
【Rails】CSSにbackground-imageで設定した背景画像が表示されない

![bgimage.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1182947/57d685ee-9499-b7bd-0024-cc2108dd01c8.jpeg)
現在作成している自作のアプリケーションで、
上のように背景に画像を設定したく、
CSSでbackground-image プロパティを使えば良いことが分かり、
以下のように記述しました。

```css
.sample-contents {
  width: 100vw;
  height: 350px;
  background-image: image-url('sample-top.JPG');
  background-repeat: no-repeat;
  background-size: cover;
  background-position: center;
}
```

これで画像が出るはず！だったんですが、画像が表示されなかったので、
解決するために試したこと等を記録します。

## 解決したかったこと
CSSでbackground-image プロパティを使ったが、画像が表示されない
## 今回の解決方法
記述していた.css ファイルの拡張子を.scss に変更したら表示できた。

というわけで本当にただのケアレスミスでした。
ただまだcssとscssがどう違うのかや、何故cssだと表示できなくてscssだとできたのかはちゃんと理解できていないのでこれから勉強します。

### 解決するまでにチェックしたポイント
#### background-color は表示できるか
クラス名のスペルミスが無いかの確認も兼ねて一旦background-color を指定すると、
きちんと表示できました。
じゃあ画像に何か問題があるのかと考えて次へ。
#### 画像パスの指定は合っているか
app/assets/images にちゃんと保存してあるかどうかを確認。

VSCodeの場合、ファイルを右クリックで画像のようにパスがコピーできたので、パスは確かだろうと確認できました。
![スクリーンショット 2021-03-14 19.01.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1182947/c6450987-30f3-3767-493e-32df697d5c8b.png)

以上です。
【Vue.js】vue-cliでのVueインスタンスの記述について

# vue-cliでのVueインスタンスの記述について

## 背景
Vue-cliを使うと、Vueと違ってVueインスタンス部分のdataやmethodsなど、

- ```data:```→```data()```

のように書き方が少し違う（自分はググって出てきた記事等を参照して書いていた）が、こちらは公式のガイド等はないのだろうか

## 結論
>同じ種類のコンポーネントの異なるインスタンス間で、独立した data を扱うために、data はオブジェクトではなく、オブジェクトを返す関数でなくてはならない

>コンポーネントの全てのインスタンスが同じデータオブジェクトを参照しているので、1つのリストのタイトルを変えることは、他の全てのリストのタイトルを変えることになる。

よって、CLIの場合は関数にしていないとやはりだめなよう
また、CDNの場合もオブジェクトを返す関数にした方がよいよう

## 参考

CDNを使用した際は、```data: {}``` でも　```data: function() {  return {}  }```のどちらでもエラーは出ない

https://jp.vuejs.org/v2/guide/components.html#data-%E3%81%AF%E9%96%A2%E6%95%B0%E3%81%A7%E3%81%AA%E3%81%91%E3%82%8C%E3%81%B0%E3%81%AA%E3%82%8A%E3%81%BE%E3%81%9B%E3%82%93

この記事は上記の公式をもう少し噛み砕いてマス

https://github.com/cidermitaina/til/issues/17
【Vue.js】.vueファイル


# .vueファイル

HTMLのテンプレートとスクリプト・スタイルを一緒にかいておける

いわゆるコンポーネント化ができているということ

```App.vue
<template>
  <div id="app">
    <img alt="Vue logo" src="./assets/logo.png">
    <HelloWorld msg="Welcome to Your Vue.js App"/>
  </div>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'

export default {
  name: 'App',
  components: {
    HelloWorld
  }
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

```
Aruduino UNOで脈拍センサー,AE-NJL5501Rので脈拍を見る


1.センサーの接続
2.下記のソースコードを書き込む
3.コンパイル実行で表示されたら終了
4.Arduinoプロッターで開く
5.おわり

秋月のセンサー
ＮＪＬ５５０１Ｒ搭載　パルスオキシメータ用・反射型センサ　ＤＩＰ化モジュールキット
[AE-NJL5501R]
通販コード　K-09433
発売日　2015/07/01
メーカーカテゴリ　株式会社秋月電子通商

delay(1); -> delay(10);へ変更した。

秋月の脈拍センサー,AE-NJL5501Rで脈拍を見る NJL5501R
https://qiita.com/caa45040/items/f3a5674e825c9ac542fb

```c++

/*
  AnalogReadSerial

  Reads an analog input on pin 0, prints the result to the Serial Monitor.
  Graphical representation is available using Serial Plotter (Tools > Serial Plotter menu).
  Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground.

  This example code is in the public domain.

  http://www.arduino.cc/en/Tutorial/AnalogReadSerial
*/

// the setup routine runs once when you press reset:
void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
}

// the loop routine runs over and over again forever:
void loop() {
  // read the input on analog pin 0:
  int sensorValue = analogRead(A0);
  // print out the value you read:
  Serial.println(sensorValue);
  //delay(1);        // delay in between reads for stability
  delay(10);

}


```

![pm_an_dd_5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/03559e2d-3bc6-0850-cc5c-51a9dd31c55d.jpeg)

![pm_an_dd_6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/31d27f83-022d-b9d9-7ef2-0d1195725001.jpeg)
【npm】npmとは

# npmとは？【フロントエンド？パッケージ管理】
### Node.js のパッケージ（Package）を管理するツール
パッケージとは、Node.jsで利用できるJavaScriptの「ライブラリ」や「フレームワーク」などのこと

  - 例えば
    - CSSフレームワークのbootstrap
    - jsフレームワークのvue.js
  - あとはよくあるちょっとしたjsモジュールの
    - シャドーボックス
    - スライダーとか

- Node Package Managerの略

- ```package.json```に必要なパッケージ、バージョンを記述して管理する
- ```node_modules```ディレクトリ配下に、インストールしたパッケージのソースが配置されていく


# 参考
https://qiita.com/minato-naka/items/fc74f6c9439ab59cec63

とりあえずこれだけでOK
フロントエンド開発の３ステップ（npmことはじめ）

https://qiita.com/hashrock/items/15f4a4961183cfbb2658
【Vue.js】Vuexを使用したmapState使い方

# mapState使い方

## 目的

Vuexで値を表示する際、```$store.state```を省略して記述したい

## 実装

vuexからmapStateを抽出する

- ```import { mapState } from 'vuex'```

computedにmapStateを設定

```vue
computed: {
    ...mapState({ //他の算出プロパティと共有する（...）（表示を省略して記述するための設定）
      gender: 'gender',
      year: 'year',
      month: 'month',
      day: 'day',
      q1: 'q1',
      q2: 'q2',
      q3: 'q3',
      consultation: 'consultation',
    })
}
```

## 全体

```vue
<template>
<div>
  <div class="form">
    <div class="header">
      <p id="step">STEP4</p>
      <p id="inst">以下の内容をご確認ください</p>
    </div>
    <div class="body">
      <div>
        <p class="genre">-性別-</p>
        <p class="answer">{{ gender }}</p>
      </div>
      <div>
        <p class="genre">-生年月日-</p>
        <p class="answer">{{ year }}{{ month }}{{ day }}</p>
      </div>
      <div>
        <p class="genre">-現在、生命保険に加入されていますか？-</p>
        <p class="answer">{{ q1 }}</p>
      </div>
      <div>
        <p class="genre">-現在入院中ですか。または、最近3ヶ月以内に医師の診断・検査の結果、入院・手術をすすめられたことはありますか？-</p>
        <p class="answer">{{ q2 }}</p>
      </div>
      <div>
        <p class="genre">-過去5年以内に、病気やけがで、手術を受けたことまたは継続して7日以上の入院をしたことはありますか？-</p>
        <p class="answer">{{ q3 }}</p>
      </div>
      <div>
        <p class="genre">-ご相談内容-</p>
        <p class="answer">{{ consultation }}</p>
      </div>
    </div>
  </div>
  <div class="button-group">
    <router-link to="/consultation" class="button">前へ戻る ＞</router-link>
    <router-link to="/confirmation" class="button">送信 ＞</router-link>
  </div>
</div>
</template>

<script>
import { mapState } from 'vuex' //vuexからmapStateを抽出する

export default {
  computed: {
    ...mapState({ //他の算出プロパティと共有する（...）（表示を省略して記述するための設定）
      gender: 'gender',
      year: 'year',
      month: 'month',
      day: 'day',
      q1: 'q1',
      q2: 'q2',
      q3: 'q3',
      consultation: 'consultation',
    })
  }
}
</script>

<style scoped lang="scss">
* {
  // outline: auto;
	margin:0; padding:0; 		/*全要素のマージン・パディングをリセット*/
  max-width: 100%;
}

#step{
  background: #1e90ff;
  color: #fff;
  font-size: 2px;
  margin: 0;
  max-width: 40px;
  padding: 2px;
  text-align: center;
}

#inst {
  font-size: 12px;
  color: #696969;
  text-align: center;
  padding-bottom: 10px;
}

.header {
  background: #afeeee;
  margin: 0%;
  padding: 0%;
  line-height: 10px;
  border-bottom: solid 1px #48d1cc;
}

.body {
  font-size: 9px;
  margin: 10px;
  padding-bottom: 10px;
  line-height: 30px;
  text-align: left;
}

.genre {
  color: #1e90ff;
  text-align: left;
  line-height:200%
}

.answer {
  margin: 0 0 0 10px;
}

textarea {
  border: 1px solid #dcdcdc;
}

.form{
  max-width: 80%;
  margin-top: 80px;
  margin-left: auto;
  margin-right: auto;
  border: 1px solid #48d1cc;
  border-bottom: 0.5px solid #000;
}

.button-group{
  text-align: center;
}

.button {
  background-color: #40e0d0;
  color: #fff;
  border: solid 1px #48d1cc;
  margin-top: 1rem;
  padding: 5px 10px;
  border-radius: 0.5rem 0.5rem;
  text-decoration: none;
  display:inline-block;
  margin: 10px;
}
</style>

```
PHP 関数スコープ　ローカル、グローバル

#PHPの関数スコープについての基本

例）

```php

<?php

$a =10;
$n = 100;


<?php
$a = 10;
$n = 100;

function change()
{
    print $GLOBALS['a'] . "\n";
    $GLOBALS['a'] = 25;
}
change(); //10
print $a . "\n"; //25

function change2()
{
    $n = 10;
}
change2();
print $n . "\n"; //100

function change3()
{
    global $n;
    $n = 15;
}
change3();
print $n . "\n";//15


```

###グローバル関数の指定には２種類ある
①```$GLOBALS['a']；```
②``` global $n;```

####①について
```$GLOBALS['a']; ```は関数内からグローバルスコープへのアクセスが可能になる。
```'a'```の部分に変数の```$```を除いた値を入れると使用可能（今回は```$a```の為```'a'```)
$GLOBALS['a'] = 'hoge';
のように値を変更できる

####②について
global $n
$n = 'hoge';
とすることで変更可能に
Promise.allとPromise.allsettledの違いを教えて

これまで自分は、Promise.allを使ったことがなくPromise.allsettledに関しては名前すら聞いたことがありませんでした・・・そこで、自分と同じような人が少しでも早く理解を深められたらいいなと思いPromise.allとPromise.allsettledについての記事を書いてみました！
#Promiseについて簡単に
JavaScriptの特性として、「非同期処理」というものがあります。同期処理は書かれたコードが上から順番に必ず実行されるのに対し、非同期処理は上から順番に実行されない時もあります。例えば、外部連携などの実行に時間がかかる処理の場合、実行が完全に完了する前に次の処理に走ってしまうことがあります。そのため、

```
let res = dynamodb.get(params)
console.log(res)
```
上記のような流れの場合に、非同期処理だと1行目の処理が最後まで終わり変数に代入される前に2行目の処理が実行されエラーになるというパターンが発生することがあります。
ただ、Promiseを使うことで実行する順番を指定することが可能です。
そのため、Promiseにより先ほど説明したようなエラーを防ぐことができます。
# Promise.allを使用するメリット
Promise.allを使うメリットとして、時間のかかる非同期処理をたくさん行わないといけない場合に、「無駄なく効率よく並列で実行できる」ことが挙げられます。

例えば、下記のように時間のかかる処理を複数行うとします。

```
let res_1 = await dynamodb.get(params_1) // 実行を完了するのに1秒
let res_2 = await dynamodb.get(params_2) // 実行を完了するのに2秒
let res_3 = await dynamodb.get(params_3) // 実行を完了するのに3秒
```
この場合だと、全て実行し終えるのに6秒もかかります。

一方で実装したい機能の関係上、毎回6秒も待ってられない場合を考えてみます。
その場合、下記のようにします。

```
let  [ res_1 , res_2,  res_3] = await Promise.all(
dynamodb.get(params_1), dynamodb.get(params_2), dynamodb.get(params_3)
)
```
そうすると、3つの処理が順番に行われるのではなく、並行で実行されます。
よって、全て実行し終えるのに3秒しかかからないのです。
Promise.all()を使うことで、複数の非同期処理を最速で終わらせることができます。
#Promise.allとPromise.allsettledの違いとは
両者の違いに触れる前に、Promiseは成功した際にはresolveが、失敗した際にはrejectが返されます。(正確にはPromiseのステータスをpendingからfullfilledに変更するために、resolve()を呼び出しrejectedに変更するためにreject()を呼び出します)

では、違いについて見ていきましょう。
 Promise.allは、配列内の複数あるPromiseがたった1つでも「reject」を返すと、即終了します。たとえ、それ以外のPromiseが全て順調にうまくいっており、それらの実行が最後まで完了していなかったとしても、途中で終了します。初めはなんで？？？って感じでした(笑)
それに比べて、Promise.allsettledは配列内のPromiseが「resolve」でも「reject」でも関係なく、全ての処理が終わって初めて完了します。
そのため、「とりあえず、成功・不成功気にせず全てのPromiseを実行したいんだ！」(あ、自分はこれでした笑)と考える方は、Promise.allsettledでその悩みは解決できると思います。
#最後に
あまりQiitaなどを書いたことがないため、拙い文章ではあったと思いますが最後まで読んでくださりありがとうございました！これからも月に2回ほど学んだことをアウトプットしていきます。もう少し文章が上手くなれるように頑張ります笑
セル内に改行があるCSVをPHPで処理する方法

fopen でファイルを読み込んで、CSV処理を書いていると、
CSVのセル内に改行があり、ハマったのでメモ

# fopen で書いていたがセル内の改行がうまく取得できない

```php5
$file = "test.csv";
$fp = fopen($file, "r");
while($line = fgets($fp)) {
    $data = explode(",", $line);

    //DB保存など

}
fclose($fp);
```

このような感じでコードを書いていたが、
CSVのセル内に改行があると、うまくデータが取得できない

# 解決方法
SplFileObject　クラスを書けば、うまいこと取得してくれた

```php
$file = new SplFileObject($file);
$file->setFlags(
    \SplFileObject::READ_CSV |           
    \SplFileObject::READ_AHEAD |       
    \SplFileObject::SKIP_EMPTY |       
    \SplFileObject::DROP_NEW_LINE 
);


foreach ($file as $data) {
    error_log(print_r($data, true));
    //１行ずつ配列として取得できる
}
```

超ラク
自作コマンドを作る方法

# shellscriptで独自のコマンドを作って楽したい。
繰り返される作業をスクリプトで作成できたら楽しそうだなと思い、shellscriptを学んでみました！
簡単なコマンドを作成してみたので備忘録的に残すことにしました。

## 作成手順
まず好きな場所に作成したいコマンドの名前のファイルを作成します。
※拡張子はつけません！！ .shとつけてshellscriptのファイルとして実行することもできます

```zsh
touch mycmd/mytest
```


#### 処理を記述
中身（行いたい処理）を書きます
readで入力を受け取ったり、 $1,$2のように引数を受け取ることもできますが、
今回は簡単に今日の日付を YYYY-MM-DDの形で出力するだけとします。

```zsh
#!/bin/zsh
today=$(date "+%Y-%m%-d")
echo $today
```


#### 権限の変更
このままだと実行権限がないと思われるので、権限を変更します。

```zsh
// ユーザーが実行できればいいので u+xとします。
// 777とかしちゃってもいいと思います！
chmod u+x mycmd/mytest
```

#### パスを通す
PATHを通します。
.zshrcに記述します

```zsh
PATH="/Users/hogename/mycmd:${PATH}"
export PATH
```

sourceコマンドで編集した.zshrcを実行します。
ターミナルを一度閉じてもかまいません

```zsh
source .zshrc
```


これで mytest と入力すればどこからでも実行できるはずです！！
【RaspberryPi4】aplayとpigpioライブラリの同時使用で起きる問題の対処法

# はじめに
こんにちは、だるおです。

今回はラズパイ関連の記事です。

先日Raspberry Pi4でOpen Jtalk関連をいじっていた際、**リモコンモジュールが動作しなくなる事象**が発生しました。
また、リモコンモジュールを動作させるとRaspberry Pi4の**オーディオ関連全般が動作しなくなるという逆の事象**も発生しました。

これについて、解決法を調査し、最終的に解決することができたので記事にすることにしました。

# 動作不良の原因
いろいろ試してみた結果、わかったことは以下の通りです。

- オーディオ関連の操作(aplayコマンドなど) → pigpioライブラリが動作しなくなる (再起動したら動作する)
- pigpioライブラリの使用 → オーディオ関連全般が動作不良 (エラーは出ない) (再起動したら動作する)

オーディオ関連の操作では他にもvlcやpygameを試しました。
どちらか一方を使用すると一方が動作しなくなることから、二つが何らかの処理を取り合っていると考えられます。
調べてみると、pigpioライブラリとオーディオ関連は**PWM**・**PCM**といった名前の制御を行っていることがわかりました。

pigpioライブラリはデフォルトで**PCM制御**を行う設定になっています。
また、aplayコマンドなどは基本的に**PCM制御**で音源を扱っているみたいです。
つまり、**両者がPCM制御を取り合っている状態**なわけです。

# 解決法
PCM制御を取り合うのであれば、**pigpioライブラリをPWM制御で扱うよう変更すれば問題がなくなるはずです。**

gpio libraryのページから引用すると、
>
You can change the default with a configuration option.  For C use gpioCfgClock, for the pigpio daemon use the -t option.

と、-tオプションで設定できるみたいです。

また、コマンドオプションのページに以下の記述もありました。どうやら正解だったようです。

>
Default PCM. pigpio uses one or both of PCM and PWM. If PCM is used then PWM is available for audio. If PWM is used then PCM is available for audio. If waves or hardware PWM are used neither PWM nor PCM will be available for audio.

では設定していきます。

**/lib/systemd/system/pigpiod.service**を編集。

```ini
[Unit]
Description=Daemon required to control GPIO pins via pigpio
[Service]
ExecStart=/usr/bin/pigpiod -l -t 0
ExecStop=/bin/systemctl kill pigpiod
Type=forking
[Install]
WantedBy=multi-user.target
```

ExecStartの部分に`-t 0`を設定しました。
これで、pigpioライブラリはPWM制御で扱うことになります。

あとは、サービスを再起して完了です。

```bash
$ systemctl restart pigpiod.service
```

エラーを吐かれたらデーモンをリロードしてください。

```bash
$ systemctl daemon-reload
```

あとは音楽を流したり、リモコン操作したりして、問題がなければ解決です。

# 結論
- ラズパイ関連に限らず、英語で調べれば大体解決方法が載っている。
- **結局公式サイトが最強。**

# 参考
- [Raspberry Pi3のpigpio＋音の再生は、そのままではできないっぽい - リベルさんの戯言室](https://lib.hatenablog.com/entry/2019/03/10/Raspberry_Pi3のpigpio＋音の再生は、そのままではできないっぽ)
- [pigpio library](http://abyz.me.uk/rpi/pigpio/faq.html#Sound_isnt_working)
Nuxt.jsで作成した静的サイトをGitHub Pagesにデプロイする方法

#この記事について
Nuxt.jsで作った静的サイトを、GitHub Pagesで公開する方法を調べたので自分なりに後で、見返せるようにまとめてみました。

**参考記事はページ下部にリンクを添付させて頂きます。より詳しい内容は、そちらをご確認お願い致します。**

##前置き①（今回やる内容）
Nuxt.jsで作った静的サイトをGitHub Pagesで公開する。

##前置き②（前提条件）
今回の、記事を通してサイトを公開するにあたって前提の条件があります。

**1. Nuxt.jsを用いて静的サイトを作成したことがある。**
**2. 上記で作成したサイトをGitHub上で開発管理している。**

#サイト公開までの流れ
前提条件を満たした上で、下記より公開までの手順を解説します。

##手順①push-dirのインストール
作成したNuxtプロジェクトにターミナルで**push-dir**をインストールします。

```
npm install push-dir --D
```

##手順②デプロイコマンドの設定
インストールが完了した後、package.json内でdeployコマンドを追記します。

```json:package.json
"scripts": {
    "dev": "nuxt-ts",
    "build": "nuxt-ts build",
    "start": "nuxt-ts start",
    "generate": "nuxt-ts generate",
    "deploy": "push-dir --dir=dist --branch=gh-pages --cleanup"//記述追加部分
},
```

`--branch=gh-pages`の部分で、デプロイ先のブランチを指定しています。

今回は、Nuxtで生成したdistファイルのみをデプロイしたいので、masterブランチではなく**gh-pages**[^1]という名前のブランチを指定しております。指定したブランチが現在無くても、コマンド実行時に自動的に作成されますので事前に用意しなくても大丈夫です。

[^1]: ブランチ名は任意。

##手順③ファイルパスの修正

デプロイ先でもパスを正しく反映させるため、nuxt.config.jsのfaviconとbaseのパスを修正します。

```js:nuxt.config.js
head: {
        title: 'Nuxt-sample',
        
        〜〜〜〜〜中略〜〜〜〜〜

        link: [
            { rel: 'icon', type: 'image/x-icon', href: '/<リポジトリ名>/favicon.ico' },//fabiconはここ
        ]
},

〜〜〜〜〜中略〜〜〜〜〜

router: {
        base: '/<リポジトリ名>/'//baseはここ
}
```
上記２箇所の、`<リポジトリ名>`の所に自分が開発管理しているGitHubのリポジトリの名前を入れます。
ここまで作業を終えたら、変更をmasterブランチにコミットプッシュします。

##手順④静的ファイルを作成し、GitHubにデプロイする。
Nuxtで静的ファイルを生成するため、ターミナルにて下記コマンドを入力します。

```
npm run generate
```

generateが完了したら、プロジェクトファイルにdistファイルが生成されます。
続けて、生成されたdistファイルをデプロイするため下記コマンドを実行します。

```
npm run deploy
```

上記コマンドを実行後、package.json内のdeployコマンドで指定したブランチが自動で作成されて、そこにdistファイルのみがコミットプッシュされます。

**これにより、いちいちブランチを切り替えて作業する必要がないので、非常に作業が楽になります。**

最後に、`https://<ユーザー名>.github.io/<リポジトリ名>/`でURLを叩いて、無事表示されれば公開完了です。

ここまで、お付き合い頂き有難うございました。
Nuxtで静的サイトの公開を検討されている方は、是非、GitHub Pagesを利用してみてください。
無料で比較的簡単に出来ますので、オススメです！

#参考サイト
https://upd.world/nuxtjs-deploy-gh-pages/#%E6%89%8B%E9%A0%861-push-dir-package-%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB
Django の非同期 View について調べてみました！

# はじめに
Django 3.1 より[非同期 View](https://docs.djangoproject.com/en/3.1/topics/async/)がサポートされるようになりました。
非同期で描画することによって、Webアプリケーションのページ速度の向上が見込めます。Python標準に入っているasyncやthread,multiprocessingとは違う技術が使われているので、Webアプリケーション+Djangoの構成においては非同期 Viewを使った方が良いかもしれません。

# 環境
| モジュール | バージョン |
| --- | --- |
| Python | 3.8.3 |
| Django | 3.1.3 |
| httpx | 0.16.1 |
| uvicorn | 0.11.8 |

# 使い方
## App の作成
```
$ django-admin.py startproject project .
$ python manage.py startapp app
```

## ソースコードを修正
```python:view.py
import asyncio
import httpx
from django.http import HttpResponse


async def http_call_async():
    for num in range(1, 6):
        await asyncio.sleep(0.5)
        print(num)

    async with httpx.AsyncClient() as client:
        r = await client.get("https://www.yahoo.co.jp/")
        print(r)

async def index(request):
    loop = asyncio.get_event_loop()
    loop.create_task(http_call_async())
    return HttpResponse('Hello, async world!')
```

```python:urls.py
from django.contrib import admin
from django.urls import path
from app.views import index

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', index)
]
```

## 実行
```
$ uvicorn project.asgi:application
```

## アクセスすると・・・
ブラウザから http://127.0.0.1:8000 にアクセスすると、

```
$ uvicorn project.asgi:application
INFO:     Started server process [89162]
INFO:     Waiting for application startup.
INFO:     ASGI 'lifespan' protocol appears unsupported.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     127.0.0.1:52036 - "GET / HTTP/1.1" 200 OK
Not Found: /favicon.ico
INFO:     127.0.0.1:52036 - "GET /favicon.ico HTTP/1.1" 404 Not Found
1
2
3
4
5
<Response [200 OK]>
```
のように出力され、先に 200 OK が返っている事が分かるかと思います。

# おわりに
いかがでしたでしょうか？試すだけであれば、比較的簡単に試せたかと思います。
複数のAPIにリクエストを投げてviewを返す時など非同期でリクエストしてあげる事でボトルネックとなりがちなネットワーク関連の処理を
軽減させる事ができます。
また、Django を実行する際は、runserver ではなく、ASGI（Asynchronous Server Gateway Interface）を使う必要がありますのでご注意ください。

# 参考
https://testdriven.io/blog/django-async-views/
https://docs.djangoproject.com/en/3.1/topics/async/
ある日突然vscodeでRemote-wslができなくなったときの対処

# はじめに

突然ある日[Remote-wsl](https://qiita.com/nj_ryoo0/items/a42c47436b77310f5430)がエラーとなりできなくなったときのための対処方法をメモ代わりに残します

# 対処

wsl上で直接vscode実行をしようとすると、`segmentation fault`と返ってきたのでそれについて調べて見ると以下のものが見つかりました。

[How can I fix the “segmentation fault” error in Visual Studio Code's terminal?](https://stackoverflow.com/questions/56972740/how-can-i-fix-the-segmentation-fault-error-in-visual-studio-codes-terminal)

その内容を参考に以下のコマンド実行で治りました

```bash
rm -rf ~/.vscode-server
```

# さいごに

あとがきするほどの内容ではないですが、昔同じことが発生して解決方法もわからずに泣く泣くwslをインストールし直した経験もあったので、今回でその解決方法もわかったので良かったです。
【備忘録】Git ・ GitHubの基礎

<h1>Git・GitHubとは
<p>わかりやすかった写真で説明すると
・Git→開発環境（ローカル環境）で
「ここを編集・追加・削除したよ～」とわかりやすくメッセージを残すために用いる


・GitHub→みんな見れるとこ。作品がいっぱいある美術館的な感じ。


![FireShot Capture 094 - 【GitHub超初心者入門】この前初めてGitHubを使い始めたエンジニア見習いが書くGitHubの使い方と実践～とりあえず一緒に動かして_ - qiita.com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1144247/2c27343c-9041-f581-e24a-0a3b771480ec.png)


<h1>主な流れ
<p>1.個人のファイルの変更
↓（git add）
2.ステージングエリア（控室）
↓（git commit）
3.ローカルリポジトリに登録OK
↓（git push）
4.リモートリポジトリ（GitHub）に登録

<h1>新規プロジェクトでの細かな流れ
<h2>git init　~これを編集するよ！~
<p>名前の登録をして
cdコマンドで編集したいファイルへ移動して

```
 git init
```

とすることでgitの隠しファイルが作られる
<h2>～githubにあげる準備するよ！～
<p>

```
git add ファイル名
git commit
```
とここまでするとなんか別のエディターに切り替わる。

```
///ここに変更した内容の記載///
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# On branch main
# Your branch is up to date with 'origin/main'.
#
# Changes to be committed:
#	modified:   first.txt
#
```
そして閉じる。
<h2>～githubにpushするよ！～
<p>・GitHubでレポジトリを作成
or push an existing repository from the command lineをコピペすることにより登録
そしてpushコマンドでどんどん更新することができるようになる。

<h1>その他コマンド
<p>
<ul>
<li>【git status】・・・状況の確認（よく使う）
<li>【git log】・・・変更履歴の確認
<li>【git log --oneline】・・・1行で変更履歴の確認
<li>【git diff】・・・ステージとの差分。add,commitする前に確認する
</ul>

<h1>基礎的なLinuxコマンド
<p>【cdコマンド】
ディレクトリを移動。

【lsコマンド】
ディレクトリの内容を表示します。
ls -a コマンドで、隠しファイルを含めたディレクトリ全内容を表示します。

【mkdirコマンド】
ディレクトリを新規作成。

【rmコマンド】
ファイルを削除。

【cpコマンド】
ファイルをコピー。

【mvコマンド】
ファイルの移動とファイル名の変更。
【gulp】gypとかnode-pre-gypとかのエラーに悩まされ続けた話

とある案件で、gulpの制作環境が必要だったので環境を構築したのだが、
ものすごく詰まってしまったのでメモ。

node：v8.9.4
npm：5.6.0

nodebrewで切り替えてバージョンを合わせる。
`npm i`でインストール。

すると、gypやらnode-pre-gypやらのよく分からないエラーが出てインストールができない。

## エラー内容

```
gyp: No Xcode or CLT version detected!
gyp ERR! configure error 
...
```

```
node-pre-gyp ERR! build error 
...
```

```
npm ERR! code ELIFECYCLE
npm ERR! errno 1
...
```

## やってみたこと

いろんな記事をみて、以下いろいろやってみた。

- `npm cache clean`
- `xcode-select --install`
- `npm install --unsafe-perm`

…が、特に変化なし。
どうやらこのエラーは曲者らしい。

ちなみにXcodeのCLTは、元々あったので、削除して再インストールした。
でもダメだった。

## 解決方法

よく見るとこんな文があった。

```
xcode-select: error: tool 'xcodebuild' requires Xcode, but active developer directory '/Library/Developer/CommandLineTools' is a command line tools instance
```

それと、助けられたのはこの記事。

https://qiita.com/eytyet/items/59c5bad1c167d5addc68

### 手順

1. Xcode自体は入れてなかったので、Xcodeをインストール
2. 環境設定を開き、「Locations」タブより→「Command line Tools」を設定

（元記事と同じく、「Command line Tools」が空欄になっていた）
![error-gyp-node-pre-gyp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232821/4d0b995e-fd01-5ca8-e30e-cbb9a89c890d.png)

動いた！
CLTだけで良かったと思っていたが、まさかXcode入れる必要あったとは…

謎過ぎて、解決までにかなり時間を使ってしまったので、
同じように時間を使ってしまう人が、少しでも減りますように。
MacのDBeaverからXserverのMysqlに接続する

#0. DBveaverをインストールする
こちらです。

https://dbeaver.io

#1. XserverでSSH認証鍵をゲットする
XserverはSSHでのトンネル接続にしか対応してません。
Xserverのサーバーパネルから「SSH設定」からSSH認証鍵を手に入れてください。
詳細は[公式マニュアル](https://www.xserver.ne.jp/manual/man_server_ssh.php)
もしくはググってください。僕よりカスほど日本語うまいプロたちが超良質なチュートリアルをあげてくれてると思います。
**一つ注意としてはパスフレーズは設定したほうが良いです**
なんでかは僕もわかりません。

#2.DBeaverでSSHの設定をする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181362/24e897a0-a93c-6793-8059-f16526e44ca1.png)
DBeaverを立ち上げたらこんなの出てくるので、MySQLをえらんでもらって次へ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181362/3d2e01e3-02df-383d-5519-2255fb09ace4.png)
次の画面でまず上のSSHタブを押してこの画面にしてください。
そして以下の設定を行ってください。

- SSH Tunnelを使用するにチェックを入れる
- Host/IP: サーバーID.xsrv.jp(例えばtest.xsrv.jp)
- Port: 10022(Xserver用の設定です。ほかのサーバーは知らん)
- User Name: サーバーID(例えばtest)
- Authentication Method/認証方法: Public Key/公開鍵認証
- Private Key: 右のフォルダボタンから1で作った秘密鍵を選択
- Passphrase: 1で入力したパスフレーズを入力。

そしてTest tunnel configurationを押す。
普通にセットアップできてたらここでつながったよ！的なのが出てきます。

#3.DBeaverでDBの設定をする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181362/2bb164eb-f40c-60cd-7ba7-de37eef68741.png)
SSHの設定が終わったら次にDBの設定をします。
まず、XserverのサーバーパネルでMySQL設定を開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181362/9d05a32b-2b17-e903-a73d-8e57cbfbf0a7.png)
ここのホスト名をコピーしてください。
そして以下のように入力します。

- Server Host: コピーしたホスト名を書きます。(mysqlxxxxx.xserver.jp)
- Database Name: 接続したいDBの名前(サーバーパネル、MySQL一覧で確認できます)
- ユーザー名: DBのユーザー名(サーバーパネル、MySQLユーザー一覧で確認できます)
- パスワード: DBユーザーのパスワード(どこでも確認できません。わからなければMySQLユーザー一覧で変更できます)

最後にテスト接続を押します。
正しく接続できていたらつながったよ！的なメッセージが出てきます。

#4.終了
終了ボタンを押します。お疲れさまでした。

#5.私が詰まったところ
DBのホスト名とSSHのホスト名が違うことに一生気が付かなくて一生「つながらないよ！」って怒られてました。しんどかった。
学んだこと: MySQL専用のホスト名があるんだね。ありがとうXserver。
[GAS] Maps.ElevationSamplerで自他称日本一低い山の標高を調べてみた

## はじめに
以前にMaps関連のクラスを利用した小ネタを２つ紹介しましたが、`ElevationSampler`というクラスが残っていました[^1] ので、自他称日本一低い山の標高を調べてみました。もちろん小ネタです。

[^1]: 執筆時点のMapsの主要４クラス`Geocoder`、`DirectionFinder`、`StaticMap`、`ElevationSampler`

https://qiita.com/STSHISHO/items/c2a68989d74db4725112

https://qiita.com/STSHISHO/items/3c2028223b052a70f6fa

## 目的
まず、何をもって山なのか、日本一低いの根拠は、などツッコミどころはありますが、[Wikipedia](https://ja.wikipedia.org/wiki/%E6%9C%80%E3%82%82%E4%BD%8E%E3%81%84%E5%B1%B1)や[こちらの記事](https://tabi-mag.jp/lowhill/)を参考に５山をリストアップしました。

1. **日和山** 宮城県仙台市（3m）
2. **天保山** 大阪府大阪市（4.5m）※二等三角点のある山としては日本一低い
3. **蘇鉄山** 大阪府堺市（7m）※一等三角点のある山としては日本一低い
4. **大潟富士** 秋田県南秋田郡大潟村（0m）※周囲がマイナス標高
5. **弁天山** 徳島県徳島市（6.1m）※自然の山としては日本一低い

`ElevationSampler`を使って上記５山の標高を取得します。

## ロジック
標高を取得するためには、まず、地名や施設名から緯度と経度を取得する必要があります。直接標高を取得することができないため、一度`Maps.Gecoder`を経由して緯度経度リストを生成します。（念の為住所も取得しています）

```Javascript
const Sh     = SpreadsheetApp.getActiveSheet()
const Rng    = Sh.getRange('B2:D6') //サンプルのため既定値として設定
const Mts    = Rng.getValues()
const latlng = [] //緯度経度格納用配列

Mts.forEach((Mt, i) => {
  let res = Maps.newGeocoder().setLanguage('ja').geocode(Mt[0])
  latlng.push([res.results[0].geometry.location.lat, res.results[0].geometry.location.lng])
  Mts[i][2] = res.results[0].formatted_address
})
```

次に順次`sampleLocation()`にてレスポンス[^2] を受け取り、標高を取得します。

[^2]: 詳細は[公式ドキュメント](https://developers.google.com/maps/documentation/elevation/overview#ElevationResponses)を参照してください。

```JSON
// JSONサンプル
{
  "results" : [
    {
      "elevation" : 1608.637939453125,
        "location" : {
          "lat" : 39.73915360,
          "lng" : -104.98470340
        },
      "resolution" : 4.771975994110107
    }
  ],
  "status" : "OK"
}
```
```Javascript
latlng.forEach((p, i) => {
  let res = Maps.newElevationSampler().sampleLocation(p[0], p[1])
  Mts[i][1] = res.results[0].elevation
})

Rng.setValues(Mts)
```

`Mts`をスプレッドシートに上書きして終了です。

## 最後に
以下、動作デモになります。

![demo.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1111613/5c1c55f9-207e-c82d-29b5-13ebcb25348d.gif)

サンプルのため、`status="OK"`が前提ですのでエラー処理はしていません。同様に地名も特定できるもの前提ですので、複数候補がある場合の処理は実装していません。

なお、取得結果は日和山 3m→2.2m、天保山 4.5m→3.8m、蘇鉄山 7m→7m、大潟富士 0m→-4.2m、弁天山 6.1m→1.8mとなり、事前に調査した公開データと異なります。多少の誤差はあるとしても、この辺りは何を基準にした公開データ、計測データなのかよくわかりませんね。おそらく純粋な標高データと大潟富士のような比高ということでしょうかね。この場で深堀りすることでもないので詳しい方がいらっしゃいましたらコメント頂けますと幸いです。

### [参考]
+ [Class ElevationSampler  |  Apps Script  |  Google Developers](https://developers.google.com/apps-script/reference/maps/elevation-sampler)
+ [Overview  |  Elevation API  |  Google Developers](https://developers.google.com/maps/documentation/elevation/overview#ElevationResponses)
+ [最も低い山 - Wikipedia](https://ja.wikipedia.org/wiki/%E6%9C%80%E3%82%82%E4%BD%8E%E3%81%84%E5%B1%B1)
+ [日本の低山 TOP5](https://tabi-mag.jp/lowhill/)
+ [標高と海抜は何を表している？知ることが防災に - ウェザーニュース](https://weathernews.jp/s/topics/201710/240065/)
ActionController::UnknownFormat in ○○Controller#show

<font color="red">○○Controller#show is missing a template for this request format and variant. request.formats: ["text/html"] request.variant: [] NOTE! For XHR/Ajax or API requests, this action would normally respond with 204 No Content: an empty white screen. Since you're loading it in a web browser, we assume that you expected to actually render a template, not nothing, so we're showing an error to be extra-clear. If you expect 204 No Content, carry on. That's what you'll get from an XHR or API request. Give it a shot.</font>


うわあああああ～！！！！！！
難しそうなエラーだけど、対応するViewが無い時に起こるエラー
Viewがどうなっているか確認すれば治ることが多い！

いかなる時も落ち着いて！私っ！！
Python: 適宜ファイルを差し替えながら大量のデータを書き込む

# 概要

大きなデータを書き込むときに、1つのファイルに書き込んでしまうと、読み込みのときに処理時間が膨大になったり、あるいはメモリのエラーで実行がそもそも不能になる可能性があります。

そこで、書き出し量がある一定量を超えたときに、出力ファイルを切り替えて、1ファイルが大きくならないようにするロジックを書くことがあるかもしれません。普通は主要処理の中に直接ロジックを書き込んだりすることも多いと思いますが、クラス化して使いやすくしました。

# ファイル複数書き出しのクラス

## コード

```python
class FileWriter:

    def __init__(self, output_directory, path_format, threshold):
        self.output_directory = output_directory
        self.path_format = path_format
        self.threshold = threshold
        self.count = 0
        self.total_count = 0
        self.file_count = 0
        self.file_object = None

    def write(self, string, count = 1):
        if self.file_object is None:
            self.file_count += 1
            self.file_object = open(f"{self.output_directory}/{self.path_format.format(self.file_count)}", "w")

        self.file_object.write(string)
        self.count += count
        self.total_count += count

        if self.count >= self.threshold:
            self.file_object.close()
            self.file_object = None
            self.count = 0

    def finish(self):
        if self.file_object is not None:
            self.file_object.close()
            self.file_object = None

    def __enter__(self):
        return self

    def __exit__(self, ex_type, ex_value, trace):
        self.finish()
```

## 使い方

with の中で使います。書き込み用のディレクトリ (output_directory) を指定して、あとはひたすら write を実行していくだけです。 path_format に従ったファイル名で出力がされます。 write するたびに数値を与え、その合計が threshold を超えたら、ファイルの番号を1増やして新たに書き込みを始めていきます。

# 使ってみる

0 ~ 1023 までの数字を1行ずつ書いていきます。write に count の値を与えていないため、デフォルト値の1がカウント加算されます。カウントが threshold に指定している 100を超えたところで新しいファイルに移行し、書き込みを続けます。

```python
with FileWriter("out", "single_{:04d}.txt", 100) as fw:
    for i in range(1024):
        fw.write(str(i) + "\n")
```

これにより、 out/single_0001.txt ~ out/single_0011.txt というファイルに、数字が連番で書き出されます。


さて、1つの文章であるため、ファイルが分割されないように出力したいが、複数行の文字列であるため、行数分だけカウントは増やしたいということがあるかもしれません。そういう場合は len などを駆使しつつ、 write の引数 count に値を指定すればオーケーです。

```python
with FileWriter("out", "multiple_{:04d}.txt", 100) as fw:
    values = [str(i) for i in range(40)]
    string = "\n".join(values) + "\n"
    for i in range(10):
        fw.write(string, len(values))
```

0 ~ 39 までの数字を40行でまとめて書き出すため、100を超えるタイミング、つまり 40 * 3 = 120 のときにファイルが切り替わります。 out/multiple_0001.txt ~ out/multiple_0004.txt が出来上がります。
【自分用】Next.jsの始め方

Next.jsプロジェクトの始め方

```
$ npx create-next-app my-app
$ cd my-app
$ yarn dev
```
これで`http://localhost:3000`上で動き始める

##typescriptで始めたい
`--example`オプションを使うと良い。
これはテンプレートを指定するためのオプションで、typescriptテンプレートの場合はこんな指定になる。

```
$ npx create-next-app --example with-typescript my-app-ts
$ cd my-app-ts
$ yarn dev
```

ちなみに他にもかなりの数のテンプレートが存在しているので、
試してみるのもかなり勉強になりそう。
[テンプレート一覧はこちら](https://github.com/vercel/next.js/tree/master/examples)


##随時更新
他に最初にやっておけばいい設定なんかあれば随時更新してく。
【RxSwift】KickstarterのViewModelインターフェースをスマートにするラッパー

##はじめに
RxSwiftを使ってViewModelを設計する時、
特にKickstarterのViewModelインターフェースでは
プロパティの再定義が冗長で可読性を落としてしまう。

```Swift
var hoge:PublishRelay<Hoge>

init() {
    let _hoge = PublishRelay<Hoge>()
    self.hoge = _hoge.asObservable()
}
```
これをプロパティ1つ1つ再定義していてはかなり無駄であるため、
これを解決するラッパーを使用する。

##ラッパー
以下の記事を参考にした。
https://qiita.com/yokirin/items/a8df2bc9080ccf853724

これを使うと、上記の冗長な再定義がこうなる
いやあ神すぎる。。。個人的な1番の負債が一発で解消できた。

```Swift
@PublishRelayWrapper var hoge:PublishRelay<Hoge>

init() {
}
```

再定義がいらない。
使用するときは、self.$hogeで使用する。(リンク先を参考に。)

##終わりに
KickstarterのViewModelインターフェースは使いやすいが、
冗長な再定義でずっと悩んでいた。それをラッパーで解決できたので
これから気持ちよく使っていけそう。
自分でラッパーを用意できるようになりたいところ。
WSL2でsystemctlが動かない時の対処法

#◆WSL2でsystemctlが動かない

発生したエラー

```
$ systemctl
System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to connect to bus: Host is down
```

以下の状態になった際、systemctlが正常に動いていません。

```
$ ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0    896   528 ?        Sl   15:51   0:00 /init
```

PID1のcommandがsystemdではなく/initになっている状態です。

#◆解決方法

```
$sudo apt install git dotnet-runtime-3.1 daemonize
$git clone https://github.com/arkane-systems/genie.git
 
$cd genie
$make install
$genie -s
```

#◆確認

```
$ ps aux
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           1  0.5  0.1 106868 11864 ?        Ss   17:30   0:01 systemd
```

#◆起動時に解決する

以下を参考にしました。

https://snowsystem.net/other/windows/wsl2-ubuntu-systemctl/

```
if [ "`ps -eo pid,cmd | grep systemd | grep -v grep | sort -n -k 1 | awk 'NR==1 { print $1 }'`" != "1" ]; then
  genie -s
fi
```
Vue.jsのSPAでVuetifyのパンくずリストを実装する

SPAで画面毎urlが変わる場合のパンくずリストをVuetifyのBreadcrumbsコンポーネントを使用して表示させます。

Vue.jsではパンくずを表示するプラグインで[vue-breadcrumbs](https://github.com/samturrell/vue-breadcrumbs)、[vue-2-breadcrumbs](https://github.com/Scrum/vue-2-breadcrumbs)などがあるようです。今回は_vue-2-breadcrumbs_を選択します。
_vue-2-breadcrumbs_を選択した理由は、vue-routerで画面の親子関係を設定しやすかったからです。

# 環境

- Vue.js 2.5.17
- Vuetify 2.4.3
- vue-router 3.5.1
- vue-2-breadcrumbs 0.7.12

# 実装方法

SPAでurlを変更させるためvue-routerを使用しますが、meta属性のbreadcrumbプロパティを設定します。
オブジェクトを設定した場合labelが表示名で、parentが親画面名です。parentには親のname属性を設定します。String型をセットした場合、labelに適用されます。
この設定で「ラビットハウス / 香風智乃」「ラビットハウス / 香風タカヒロ」という関係になります。

```javascript:router.js
import Vue from 'vue';
import VueRouter from 'vue-router';

Vue.use(VueRouter);

const router = {
    mode: 'history',
    routes: [
        {
            path: '/',
            name: 'Rabbithouse',
            component: RabbithouseComponent,
            meta: {
                breadcrumb: 'ラビットハウス',
            },
        },
        {
            path: '/charactor/chino',
            name: 'chino',
            component: KafuChinoComponent,
            meta: {
                breadcrumb:
                {
                    label: '香風智乃',
                    parent: 'Rabbithouse'
                }
            },
        },
        {
            path: '/charactor/takahiro',
            name: 'takahiro',
            component: KafuTakahiroComponent,
            meta: {
                breadcrumb:
                {
                    label: '香風タカヒロ',
                    parent: 'Rabbithouse'
                }
            },
        },
    ]
};

export default new VueRouter(router);
```

私の場合、App.jsとファイルを分けています。分けない場合は、App.jsに記述してください。vue-2-breadcrumbsをuseする時に、templateとcomputedをオプションで追加します。
Vuetifyではv-breadcrumbタグのitemsに画面情報のオブジェクトの配列をセットします。パンくずのデータは`this.$breadcrumbs`に入っているのでv-breadcrumbタグの仕様に合わせた配列に作り直してセットします。

```javascript:breadcrumb.js
import Vue from 'vue';
import VueBreadcrumbs from 'vue-2-breadcrumbs'

Vue.use(VueBreadcrumbs, {
    template:
        `<div>
          <v-breadcrumbs class='breadcrumb-item active' :items="items" />
        </div>`,
    computed: {
        items() {
            return this.$breadcrumbs.map((crumb, i) => {
                return {
                    text: this.getBreadcrumb(crumb.meta.breadcrumb),
                    disabled: this.$breadcrumbs.length - 1 === i,
                    to: this.getPath(crumb)
                };
            });
        }
    }
});

export default VueBreadcrumbs;
```
```javascript:App.js
import breadcrumb from "./breadcrumb";

const app = new Vue({
    el: '#app',
    router: router,
    vuetify: vuetify,
    breadcrumb: breadcrumb,
});
```
JavaScriptの配列のループ処理(for/map/reduce)の計測

JavaScriptの配列のループ処理を計測する。

今回計測したのは以下。
- `for`
- `for of`
- `for in`
- `forEach`
- `reduce`
- `map`

## 測定方法

ループ処理内では何も実行しない。
1度の実行だとはじめに実行されるループ処理が最も遅くなっため、計測対象のループ処理自体を数回実行し実行時間の平均を算出する。

```
const { performance } = require("perf_hooks");

// 1回の実行だと実行順序によって結果にブレがあったため何回か実行した結果の平均を取る
function measure(f, t) {
  const n = 100000;
  const s = performance.now();
  for (let i = 0; i < n; i++) {
    f(a);
  }
  // 少数第五位まで表示
  const d = 100000;
  console.log(t, " avg: ", Math.floor(((ms = performance.now() - s) / n) * d) / d);
}

// 配列の長さ - 測定に応じて数値を変える
const l = 10;
const a = [...Array(l)];

// 各loop処理の実行
measure(function (a) {for (let i = 0; i < a.length; i++) {}}, "for\t");
measure(function (a) {for (const i of a) {}}, "for of\t");
measure(function (a) {for (const i in a) {}}, "for in\t");
measure(function (a) {a.forEach(() => {});}, "forEach\t");
measure(function (a) {a.reduce(() => {});}, "reduce\t");
measure(function (a) {a.map(() => {});}, "map\t");
```

```
$ node loop.js
for       avg:  0.00005
for of    avg:  0.0001
for in    avg:  0.00048
forEach   avg:  0.00007
reduce    avg:  0.00006
map       avg:  0.0001
```

## 結果

数値はミリ秒。

| 処理\配列の長さ | 10 | 100 | 1000 | 10000 |
|--------------|----|-----|------|-------|
| for          | 0.00005| 0.00009 | 0.00047| 0.00417|
| for of       | 0.0001| 0.00027 | 0.00146| 0.01424|
| for in       | 0.00048| 0.00286 | 0.02671| 0.27616|
| forEach      | 0.00007| 0.00025 | 0.00148| 0.02653|
| reduce       | 0.00006| 0.00031 | 0.00149| 0.02717|
| map          | 0.0001| 0.00057 | 0.00401| 0.06101|


パフォーマンスが良い順番は以下。

1. `for`
2. `for of`
3. `forEach` `reduce`
4. `map`
5. `for in`