OmniAICreator/Qiita-1.07M huggingface dataset:
【GoogleAppScript/SpreadSheet】R1C1方式でgetRange/getRangeListする方法

##動機
特定のSheetの条件に合うセルに背景色/文字色変更などの操作を行う場合、それぞれのセルについてgetRange()しないと行けないが、都度APIにアクセスしないといけないため動作が重くなる。
　⇒じゃあgetDataRange().getValues()で一旦データを拾った後、条件にあう範囲を配列で拾って、getRangeList().setFontColor()等を使ったら、軽いのでは？
　⇒リファレンス見たけどどうやってR1C1形式でgetRangeListしたらいいかわからん・・・・
ということで調べてみました。

＜公式リファレンス＞
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205043/367c47f8-4279-f633-29ac-33658661e0bc.png)


インターネット漁って見ても、**sheet.getRangeList(['A1', 'B1', 'C1'])**と、範囲ベタ打ちの物しかなく、変数を使ってR1C1方式で範囲を取得する方法がなかったので、下記忘備録として記載します。
また、getRangeには**getRange(｛行番号｝,｛列番号｝,｛行数｝,｛列数｝)**と記述すれば”ある連続した範囲”は取得出来るため、そんなに必要性は感じませんが、R1C1でrangeを取得する方法が乏しかったので、こちらも参考として記載します。



##R1C1方式でgetRangeList
```javascript:getRangeList.gs
　let ss =SpreadsheetApp.getActiveSpreadsheet();
　let sh =ss.getActiveSheet()//アクティブシート取得
 
//*セル番地のリストをベタ打ちで取得する場合
  let r1c1LocationList =["R1C1","R2C2","R3C3:R4:C4"]
  let range = sh.getRangeList(r1c1LocationList);
//=>getRangeListの返り値はRangeオブジェクトではないので、更にgetRanges()する必要がある
 
  let rangeList = range.getRanges();
//=>r1c1LocationListの配列のアドレスにあるrangeオブジェクトが配列で返ってくる



//*変数を使って複数セル範囲を取得する例
 r1c1LocationList =[]
for(let i=0;i<6;i++){
  r1c1Location.push(`R${i}C${i}`);
}
 
  range = sh.getRangeList(r1c1LocationList);
  rangeList = range.getRanges();
//=>A1,B2,C3,D4,E5のRangeオブジェクトが配列で返る
```

ポイントとしてはgetRangeListの返り値はRangeオブジェクトの配列ではなくRangeListオブジェクトなので、更にgetRanges()をして、Rangeオブジェクトの配列に戻さないとsetValueとかgetValueは出来ないよって事です。まぁあまりすることないと思うけど・・・



##R1C1方式でgetRange()
```javascript:getRange.gs
　let ss =SpreadsheetApp.getActiveSpreadsheet();
　let sh =ss.getActiveSheet()//アクティブシート取得


//*ベタ打ちでA1を取得する場合
  let range = sh.getRange('R1C1');


//*変数を使ってセル範囲を取得する場合
  let startRow=1;let startColumn=1
  let endRow=1;let endColumn=1
  let r1c1Location=`R${startRow}C${startColumn}:R${endRow}C${endColumn}` ;//=>　r1c1Location="R1C1:R1C1"と同じ
  range = sh.getRange(r1c1Location);//"R1C1:R1C1"="A1"のRangeオブジェクトを取得

```




ここまで書いて思ったけど、大体聡明な方なら、getDataRange().getValues()してから2次元配列をmapなりfilterするなりすると思うからそこまで需要ないよなと言う感じ！

まぁええわ、ほな！



##参考
＝後で記載します＝
Error response from daemon: login attempt to https://registry.heroku.com/v2/ failed with status: 401 Unauthorizedの解決法


環境
---
MacOS Big Sur 11.5.2
docker 20.10.6
heroku 7.59.1 

CircleCIでのテスト中起こったエラーです。
config.ymlの中の`Heroku login`でエラーになりました。

```circleci:config.yml
version: 2.1
orbs:
  ruby: circleci/ruby@1.1.2
  heroku: circleci/heroku@1.2.3

jobs:
  build:
    docker:
      - image: circleci/ruby:3.0.2
    working_directory: ~/minoirominori
    steps:
      - checkout:
          path: ~/minoirominori
      - ruby/install-deps
      - run:  wget -qO- https://cli-assets.heroku.com/install-ubuntu.sh | sh
      - run:  bash .circleci/setup-heroku.sh
      - add_ssh_keys:
          fingerprints: 
          - "SHA256:8whK7z7k7uhcgyvbVuKBmiRzJRMbxYTwK6pwTHG13Rs "

  test:
    docker:
      - image: circleci/ruby:3.0.2
      - image: circleci/mysql:8.0
        environment:
          MYSQL_ROOT_PASSWORD: password
          MYSQL_DATABASE: rails-front-demo-db
    environment:
      BUNDLE_JOBS: "3"
      BUNDLE_RETRY: "3"
      APP_DATABASE_HOST: "127.0.0.1"
      RAILS_ENV: test
    working_directory: ~/minoirominori
    steps:
      - checkout:
          path: ~/minoirominori
      - ruby/install-deps
      - run:
          name: Database setup
          command: bundle exec rails db:migrate
      - run:
          name: rspec
          command: |
            bundle exec rspec --format RspecJunitFormatter \
                              --out test_results/rspec.xml \
                              --format documentation
      - run:
          name: Rubocop
          command: bundle exec rubocop


  deploy:
    docker:
      - image: circleci/ruby:3.0.2
    steps:
      - checkout
      - setup_remote_docker:
          version: 20.10.6
      - heroku/install
      - run:
          name: heroku login #こちらでエラー発生
          command: heroku container:login
      - run:
          name: push docker image
          command: heroku container:push web -a $HEROKU_APP_NAME
      - run:
          name: release docker image
          command: heroku container:release web -a $HEROKU_APP_NAME
      - run:
          name: database setup
          command: heroku run bundle exec rake db:migrate RAILS_ENV=production -a $HEROKU_APP_NAME

workflows:
  version: 2
  build_test_and_deploy:
    jobs:
      - build
      - test:
          requires:
            - build
      - deploy:
          requires:
            - test
          filters:
            branches:
              only: main
```
エラー内容
---
```
Error response from daemon: login attempt to https://registry.heroku.com/v2/ failed with status: 401 Unauthorized
 ▸    Login failed with: 1


Exited with code exit status 1
CircleCI received exit code 1
```

DockerからHerokuにログインできませんとのこと。401 Unauthorizedとは認証がきちんとできていませんという意味みたいです。エラー通りhttps://registry.heroku.com/v2/ こちらのサイトにアクセスするとユーザー名とパスワードを入れる欄が出てきます。
何度もユーザー名にherokuの自分のアドレス、パスワードにherokuのパスワードを入れるもログインできず、、
複数の記事を参照し解決策が判りました！

解決策
---
ユーザー名は空のまま
パスワードには、cdで該当する自分のディレクトリに移動した後`heroku auth:token`で発行した数字を入れることで解決しました！

参考
---
https://neos21.net/blog/2019/02/14-01.html
ミスチルになりたかったので　判定機を作ってみた

## 心をミスチルにして　まずはクリックを
　注)　URL内のボタンを押した後　結果が流れてくるまでしばらくお待ちください

https://codepen.io/okinakamasayoshi/full/VwzzNdw

## ずっとHEROでありたい　いや　ミスチルになりたい

　昔職場の、「最近老眼がひどい」が口癖の　おばさまから

　「沖中君はミスチルの桜井君に似ているね」と言われて以来
　その後10年間誰も言ってくれないので、機械に無理強いしてみることにしました。

![キータ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1793443/bfbf129e-f1d0-7f31-5c49-b64aa649ba30.png)

　カメラから表情を読み取って、

:::note
　①爽やかでクール(ほぼ無表情)　　➡　20代のMr.Children桜井和寿
　②前めりで情熱的(画面に近づく)　➡　30代のMr.Children桜井和寿
　③はじける笑顔　　　　　　　  　➡　40代のMr.Children桜井和寿
:::

　と判定してくれる<font color="Red">**ミスチルチェッカー**</font>を作りました。


## 自分の欲望に　負けないように

　<font color="Red">**とにかく自分のテンションを上げるため**</font>だけに作りました。

　当初は「ミスチルのメンバーの誰に似てる？」の判定機を作成しましたが、
　ボーカルの桜井さんの時以外テンションがあまり、いや全然上がらず。
　いつでも<font color="Red">**「〇〇代の桜井さんに似てるよ」**</font>と言ってもらえるようにしました。
　(演奏もめちゃくちゃ大好きです！本当です！)

**①Teachable Machineで顔認識**
![かお.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1793443/ca4da009-0138-48d9-a9e4-67ce66dad08e.png)

　「メンバーの誰に似ている？」では、各メンバー画像を一括ダウンロードしたが、
　「〇〇代の桜井さん」の無駄な欲望を叶えたく、膨大な「桜井」から手作業で画像収集。

　クリアに判定結果が出るよう、自分のクール(?)、前のめり、笑顔の写真も少し追加。


**②疲れているときはミスチルじゃないよね**

　うつむいたり、ふさぎ込んだ表情を「ミスチル認定」してしまうと企画がブレるので、
　「自分の疲れ顔サンプル」を4候補目に入れたが、当然100%の笑顔も「疲れたあなた」と
　判定さるので、4つ目は<font color="Red">**「年老いて疲れた桜井和寿」という設定で「小泉元総理」**</font>を挿入。
　試しに「疲れた」のていで、うつむいてみてください。
![まとめ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1793443/2876e8a5-f5a1-3868-15af-9ac5de17f550.png)

:::note
　④疲れている(うつむいて顔が見えない)　➡　年老いたMr.Children桜井和寿
:::
　にしても失礼極まりない。小泉元総理。大ファンです。本当です。先日の選挙行きました。


**③やっぱり音楽も聴きたい**

　検索結果後、その年代のヒット曲を聴きたい！ということで、YouTube動画を埋め込み。

　参考①：　https://codepen.io/satoshtakitainu/pen/RgxmMQ
　参考②：　https://www.howtonote.jp/youtube/usage/index5.html

　YouTube共有URLの

```js
https://www.youtube.com/embed/******
```
　の部分「のみ」をHTMLに張り付けることで、きれいに埋め込めます。
![埋め込み.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1793443/6e979159-c4b2-b581-7340-c8eb5e846cbc.png)
　「結果が出ると自動的に音楽が流れる」にしたかったが、技術・著作権面で今回断念。
　
## 一応家族に使ってもらった

![使ってもらった.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1793443/7cc0a623-3546-454a-c5d4-b797241e63b2.png)

　娘(6歳)　：自分が動くことで、表示の文字が変わり嬉しそう。また何か作ってあげよう。
　妻(3〇歳)：<font color="Red">**どうすれば「20代」と判定されるかに必死。誇張なく引くくらい必死でした。**</font>

:::note warn
　毎朝これでテンション上げて、果てしない闇の向こうに(Oh.oh)手を伸ばそう　と思います。
:::


 **エディタはこちら**
　<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="VwzzNdw" data-user="okinakamasayoshi" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/okinakamasayoshi/pen/VwzzNdw">
  ミスチルチェッカー</a> by okinakamasayoshi (<a href="https://codepen.io/okinakamasayoshi">@okinakamasayoshi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
AMSAMOTIONの中華PLC(FX3U風)を使ってみよう その2

前回の続きです
FX3U互換なのでGX Works2使います

https://qiita.com/fa_yoshinobu/items/27babd3cdb0bb303b01a

# MiniDIN 8Pin(RS-422)での通信
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2146151/5bae4661-8e81-b483-2bf8-c60ad2b7895b.png)
付属ケーブルでの通信です。USB-RS422変換は中華おなじみのCH340です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2146151/f30095f5-6139-398b-deaf-750b07601baa.png)

それっぽく動きますが時刻設定しようとするとそんな機能はないと言われます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2146151/55def29b-759e-7189-0379-39fbf51f35a0.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2146151/143ce536-5878-8f53-a71c-b07e92b27edd.png)


# プログラム書き込み
適当にプログラム書いてみたけどちゃんと動きます。
ただ私は人生でFXは3回しか使ったことないので純正の挙動がよくわかんないですが。

説明書では16000ステップと書いてますが本当に16000までかけるのでしょうか？
16000ステップを書いて転送すると転送できますがENDがないらしく起動できません。
容量オーバーのようです。テストしてみると最大12191StepならRUNしました。

無駄に容量を食うプログラム例
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2146151/12acdcb3-25cc-c1f6-7176-522ee72c694f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2146151/4048e165-8e3d-7f19-dd8d-c2c815c7e279.png)

# RUN中書き込み
なんとRUN中書き込みも可能です。しかし失敗するとSTOPします。

##STOPしない例
A接点/B接点の変更
アドレスのみの変更
接点削除(NOPで代用可能な場合のみ)

## STOPする例
STEP数が増える挿入
削除

要するにステップ数が変わると即バグります
照合するとなんかぐちゃぐちゃです。
これは使えないというのが正しいです

# MCプロトコルでの通信(GX Works2)
デフォルトIPは192.168.1.18 Port 5551,6551
IPは特定のDレジスタに書けば変更可能なようですがうまくいかないのであきらめました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2146151/c1994d8f-8b11-0f33-b83e-ba0de5303ff3.png)

書き込みも読み出しもできる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2146151/fa91e5d4-f44d-a12a-ae43-5d5468bf1608.png)

# MCプロトコルでの通信(SoftGOT2000)
GOTは家にないのでSoftGOTで試してみます。

GT Designer設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2146151/b3c34d56-50e5-4165-02b7-29dae8fdabdc.png)

SoftGOT2000設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2146151/afc0abc5-fc7a-4248-f1a2-2982eb157d9b.png)

SoftGOT2000
おおーしゅごい＾＾
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2146151/674c025b-2c3e-ee0e-4123-0085c9cd5b60.png)

無線LAN経由なのでワイヤレスでGX Works2とSOftGOTが実行できます
中華PLCもワイヤレスの時代
![IMG_20211103_162814[1].jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2146151/a8ffb8dc-b817-af98-f66d-269528d7fd87.jpeg)

# 感想
一部使えない機能があったりいろいろいじってると挙動がおかしくなり電源を切るしかないことがたまにあります。
しかしLANまで付いて、8000円なのでなかなか優秀なのでは。
問題は一般のご家庭にはiQ Works2がないことですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2146151/5d12a0e7-5b71-c332-762a-a8b840adc55c.png)
PyMySQLを使って、Docker上のMySQLとローカルのPythonを繋げてみる

### やったこと
タイトルにある通り、PyMySQLを使って、ローカルのPythonとDocker上のMySQLでやりとりしてみた。
connectorはいくつもあるでしょうが、PyMySQLを使用した理由は、GitHubで
「MySQL Python」で検索して、最もstarがついていたから。

|  | version | 
|:-----------|------------:|
| Python     | 3.9       | 
| MySQL     | 8.0      |

> 引用元: PyMySQLのドキュメント
https://pymysql.readthedocs.io/en/latest/index.html

#### MySQLのコンテナ立ち上げ on Docker
```
docker run --name container_name -e MYSQL_ROOT_PASSWORD=root -p 3306:3306 -d mysql:latest
```
MYSQL_ROOT_PASSWORDは好きに設定する

#### ローカルでPyMySQLのインストール
```
python3 -m pip install PyMySQL
```

#### MySQLコンテナ内でデータベース、テーブルを作成
```
# MySQLコンテナ内に入る
docker exec -it countainer_name bash


# コンテナ内にて
mysql -u root -p設定したpassword
# データベース作成
mysql > CREATE DATABASE test;
mysql > use test;
# テーブル作成(nameとageカラム)
mysql > CREATE TABLE test (name varchar(10), age int);
```

#### PythonとMySQLを繋げる
```python:db.py
import pymysql.cursors
# Connect to the database
connection = pymysql.connect(host='localhost',
    user='root',
    password=設定したMYSQL_ROOT_PASSWORD,
    database='test',
    charset='utf8mb4',
    cursorclass=pymysql.cursors.DictCursor)
```
実行してみると↓のようなエラー発生
`'cryptography' package is required for sha256_password or caching_sha2_password auth methods`

#### cryptographyインストール
エラーにある通りcryptographyパッケージをインストール

```
pip install cryptography 
```

これでもう一度db.pyを実行してみるとつながりました。
これでDBとやりとりできます:clap:
ロールバックが出来ないパターン

カラムの型を変更した


その後ロールバックしたらなぜかできなかったので

## 開発環境
ruby 2.6.5
Ruby on Rails 5.2.5




## 本題
```
 t.string :name, null: false
```

上のようなカラムの型を変えようと思い


```:マイグレーションファイルを作成
 def change
    change_column :tasks, :name, :text, (←変更点)  null: false
 end
```
上記のようにマイグレーションファイルを作成
そして `rails db:migrate` 

その後 `rollback` してみるとエラーが発生

```
== 20210601072158 ChangeStyleNameColumn: reverting ============================
rails aborted!
StandardError: An error has occurred, this and all later migrations canceled:



This migration uses change_column, which is not automatically reversible.
To make the migration reversible you can either:
1. Define #up and #down methods in place of the #change method.
2. Use the #reversible method to define reversible behavior.


/Users/isamutatsuya/workspace/manyoTest/db/migrate/20210601072158_change_style_name_column.rb:3:in `change'
/Users/isamutatsuya/workspace/manyoTest/bin/rails:9:in `<top (required)>'
/Users/isamutatsuya/workspace/manyoTest/bin/spring:15:in `<top (required)>'
bin/rails:3:in `load'
bin/rails:3:in `<main>'

Caused by:
ActiveRecord::IrreversibleMigration: 

This migration uses change_column, which is not automatically reversible.
To make the migration reversible you can either:
1. Define #up and #down methods in place of the #change method.
2. Use the #reversible method to define reversible behavior.

```

今まで割と雰囲気でやっていたけど
`def change` で使えるメソッドには
ロールバックに対応しているものと
対応していないものがあるらしい


今回の `change_column` メソッドはまさに
ロールバックに対応していないものだった

以下の記事を参考にさせていただいくと

https://qiita.com/yukiyoshimura/items/887f2e689b4b6b9587e2

https://qiita.com/koni4k/items/294342048cb6d47bcc3f

対応してるしてないは
このようにいろいろとある

ちなみに

```
  def up
    change_column :tasks, :name, :text, null: false
  end

  def down
    change_column :tasks, :name, :string, null: false
  end
```

こうやって `up` メソッドや `down` メソッドを活用したら
ロールバックにも対応するマイグレーションファイルが作れる。

まあただロールバック対応のマイグレーションファイルを作っていいことがあるかどうかは
今の自分のレベルではわかりません
Rのpsychパッケージのalpha関数でエラーが出るとき


エラーメッセージの例
```R　
> alpha(set.data[,c(1,2,3)])
エラー: Unknown colour name: c(3, 4, 4, ..以下略
```

原因：psychの他にggplot2パッケージを読み込んでいると、psychではなくggplot2にあるalpha関数を呼び出してしまう。

対応1: ggplot2が以降のプログラムに必要ないときは、ggplo2をアンロードする。
```R
detach("package:ggplot2", unload=TRUE)
```
対応2: ggplot2が処理に必要でアンロードできないときは、明示的にpsychパッケージのalpha関数を呼び出す。
```R
psych::alpha(set.data[,c(1,2,3)])
```
PageSpeedInsights APIを使ってみたい（下調べ）

## はじめに
- 計測したいページごとに[PageSpeed Insights](https://developers.google.com/speed/pagespeed/insights/)の結果を確認するのは面倒くさいし記録を残したいってなると尚更なので何か解決策ないかなと思い調べたところAPIが公開されてるようなので備忘録的にまとめようかなと思います。
- 今回は、ウェブサイトの方の結果とCurlで叩いた結果を比較しながら、レスポンスの中身を見ていこうと思います。（実装はまた今度。）

## PageSpeed Insightsとは
- Webサイトのページ速度を計測する際に用いるツールです。
- Lighthouseとの大きな違いとしてLighthouseは手元のPCで動作するのに対して、PageSpeed InsightsはGoogleが用意したサーバ上で動作するようです。
- パッとみたところによるとフィールドデータ（とOrigin Summary）とラボデータというものがあります。（下画像参照）
- フィールドデータは、過去28日間に特定条件でアクセスしたユーザーのデータに基づく結果
- ラボデータは、今時点のシミュレーション結果
- ということはフィールドデータを確認したいならばLighthouseでもPageSpeed Insightsでもどちらでも良さそうですね。
- また、ラボデータを取るならば、Googleが用意したサーバ上で動作するPageSpeed Insightsの方が結果が安定しそうだなといった印象です。

![スクリーンショット 2021-11-03 15.05.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46053/b677bdbb-f4ad-9af6-de1c-9b2ec9a7e849.png)

|指標|表している結果|
|----|----|
|フィールドデータ|過去28日間に特定条件でアクセスしたユーザーのデータに基づく結果|
|Origin Summary|ドメイン全体におけるフィールドデータ|
|ラボデータ|今時点のシミュレーション結果|

## PageSpeed Insights APIを試す

- ご丁寧に使い方は[公式](https://developers.google.com/speed/docs/insights/v5/get-started?hl=ja)がしっかりと書いてくれています。
- 今回は結果のJsonが欲しいだけなのでAPIキーの取得はせずterminalから以下のようにCurlコマンドを実行し、結果をファイルに出力します。

```zsh
$ curl "https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url=https://developers.google.com" > result.json
```

## 出力されたJson

- 第一階層はこんな感じになってます。
- [リファレンス](https://developers.google.com/speed/docs/insights/v5/reference/pagespeedapi/runpagespeed?hl=ja#response)見たところ、以下の３つが「フィールドデータ」「Original Summary」「ラボデータ」に該当しそうですね。

```json
{
  "captchaResult": "CAPTCHA_NOT_NEEDED",
  "kind": "pagespeedonline#result",
  "id": "https://developers.google.com/",
  "loadingExperience": {...},
  "originLoadingExperience": {...},
  "lighthouseResult": {...},
  "analysisUTCTimestamp": "2021-11-03T05:48:54.232Z"
}
```


|プロパティ名|説明|
|----|----|
|loadingExperience|エンドユーザーのページ読み込みエクスペリエンスの指標。|
|originLoadingExperience|オリジンの集約されたページ読み込みエクスペリエンスのメトリック|
|lighthouseResult|オブジェクトとしての監査URLに対する灯台の応答。|

灯台？（笑）

## 結果の突合

### フィールドデータとloadingExperience

![スクリーンショット 2021-11-03 16.17.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46053/a54ef300-a169-ebcf-7712-5f989676e773.png)

### ラボデータとlighthouseResult

- ラボデータは上述のとおり、シミュレーション値なのでちょっと値ずれました。リクエストごとにちゃんとシミュレーションしてるんですね。（でも、大体結果としては一致）

![スクリーンショット 2021-11-03 16.25.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46053/bd44e990-f895-a636-8cd6-e68f775afa7a.png)

## 最後に

- なんかJsonの結果とサイト画面上の結果が合わないなと思ってたのですが、サイト画面上はデフォルトでモバイルの結果を表示しており、APIはデフォルトでデスクトップの結果を返すみたいです。クエリパラメータに `strategy=mobile` を付加してあげればモバイル版の結果を取得することができました。

```zsh
$ curl "https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url=https://developers.google.com&strategy=mobile" > result_mobile.json
```

- フィールドデータは定期的にラボデータはページの更新を行った際に計測すると良さそうですね。
- 次回はAPIキーを発行して、プログラム上から実行してみたいと思います。

## cf. 
- https://blog.ideamans.com/2019/05/lighthouse-and-pagespeed-insights.html
Windows 10でCtrl + Spaceでかな<=>ローマ字切り替えを行う方法

二段階手順があります。

## 1. MS-IMEプロパティを出す

Windows 10でMS-IMEのプロパティを出す必要がある。
だが、最新のMS-IMEだとそれが出せないことがあるので、こちらの記事を使ってバージョンを下げる。

https://windows-podcast.com/sundayprogrammer/archives/2228

## 2. キー割り当てを行う

Ctrl + spaceでMS-IMEをオンオフできるようにする。
手順は以下の記事に書いてある。

https://fshianasan.hateblo.jp/entry/2013/11/13/115852

普段はMacユーザーなので、この二つの手順の組み合わせを見つけるのにすごく時間がかかった、、、泣
(超小ネタ)あるぇ、VirtualboxでUSBのリダイレクトができないぞ？？？

最近メインマシンを変更して、ひっさびさに(3年ぶりぐらい)Ubuntuを入れ直したところ、「あるぇ？、なんかVirtualboxのゲストにホストのUSBデバイスをパススルーできねぇぞ？？」となったんですが、色々ググった結果：

```
sudo gpasswd [ユーザ名] vboxusers 
```

でグループ:vboxusersに自分のアカウントを入れてあげないといけないみたい。
ちょっとハマったのが、vboxusersをvboxuserと間違えて、あるぇグループがない？ってなったこと。ホーンと英語は複数形だの単数形だのめんどくせぇな。
Gitコマンドメモ

```text:Git設定一覧
$ git config -l
```
```text:ブランチ一覧
$ git branch
```
```text:直前のコミットを取り消す
$ git reset --soft HEAD^
Windowsで使う場合は"HEAD^"
```
```text:特定ファイルのみ元に戻す
$ git checkout [コミット番号] [ファイルパス]
```
```text:変更したファイルの差分一覧
$ git diff --name-only <コミットID1> <コミットID2>
```
```text:特定のファイルの差分
$ git diff <コミットID1> <コミットID2> <ファイル名>
```
```text:リモートのdevelopブランチをローカルのmainブランチにpull
$ git pull origin develop:main
```
```text:ローカルのdevelopブランチをリモートのmasterブランチにpush
$ git push origin develop:master
```
```text:特定のファイルを元に戻す
$ git checkout <filename>
```
```text:リモートoriginを変更
$ git remote rm origin
$ git remote add origin https://github.com/bar/hogehoge.git
```
```text:config変更
$ git config --global user.name hogehoge
$ git config --global user.email example@hogehoge.com
```
```text:gitignoreに反映されない場合
$ git rm -r --cached <ファイル名>
$ git ls-files --other --ignored --exclude-standard
無視しているファイルの一覧
```
+ origin: デフォルトのリポジトリの場所(URL)の別名
+ main: デフォルトのブランチの名前。メインのブランチ
まずNotionで何をするかをリストにする

# 何でもできると迷いがち

[Notion](http://notion.so/)は本当にいろいろなことができます。

しかし、目的を持って取り組まないと迷子になりがちです。というかなりました。

そこでオススメなのが、まず **何を記録したいか** をリストにすることです。

（この作業自体を *Notion* でやるとカッコいいですが、自分は *Joplin* でやりました）

# 自分的に「記録したいもの」をリストアップ

リストアップしてみると、自分が記録したいものは

- TODOリスト、やることリスト
- 今やっていることリスト、DOINGリスト
- 今日やったことリスト、ジャーナル
- 会社版のTODOリスト。プライベートと分けたい
- アイディアのメモ書き、これもリスト
- 日記。1日1回の長文
- 長文。Qiitaやブログなど不定期の文章
- 歌詞。誰もが歌詞は書くよね？　長文
- ~~干し芋の~~ 欲しい物リスト

こんな感じでした。

このリストをにらめっこしてどういう記録法がふさわしいか見ていきます。

- TODO, DOING, Journalは共通のタスクを移動する方式、つまりカンバンでなんとかなりそうです。
    - ですが個人的にカンバンが苦手なのでリストを複数作る形式にすることにしました。
        - 終わったタスクは打ち消し線で表すことにします。
    - リストのアイテムは基本的に短文です。
- アイディアのメモ書きは長文の場合も短文の場合もありそうです。
    - でもこの記録には一覧性が欲しいので、できればリストにしたい。
    - 長文は長文カテゴリに追いやって、短文限定にしよう。
- 欲しい物リストは基本的に短文のリストで良さそうです。
- 日記、歌詞、その他長文は一回の文が長いので、「長文のリスト」としてちょっと別扱いにしたい。

こうしてみると基本的に記録するものは全部リストでした。

今はどうか知りませんが、昔は「掲示板」がWeb技術の基本と言われていました。それを連想しました。

# 目的を持った上でNotionに戻る

そしてリストを管理するのにNotionはうってつけなのです。

以下のような構成にしました。

- 自分のNotion
    - TODO
        - やるべきことリスト
        - リストビュー
    - IDEA
        - 思いつきメモ
        - リストビュー
    - JOURNAL
        - やったこと
        - リストビュー
    - DOING
        - やってること。読書中の本など
        - リストビュー
    - WANT
        - 欲しい物リスト
        - リストビュー
    - DRAFT
        - 長文
        - ギャラリー
    - LYRIC
        - 長文
        - ギャラリー
- 会社用Notion
    - TODO
    - JOURNAL
    - DOING
- Obsidian
    - DIARY

日記だけは[Obsidian](https://obsidian.md/)にまかせてみました。

日記でキーワードによるネットワーク化ができたら面白いかもなあと思ったからです。

また、日記は基本的に夜書くので、自宅のローカルファイルでいいのです。

逆にTODOやIDEAはクラウド化していてもらえると助かります。

やろうと思えば日記もNotion上でできるので（ギャラリータイプ）、すべてをNotionに握られる生活が始まります。

今まで _Evernote_ や _SimpleNote_, _Joplin_ などノートテイキングアプリを渡り歩いてきました。

今思うとこれらのアプリが悪いわけではなく、 **頭の中がごちゃついてたから運用もごちゃついてしまった** のだと思います。

Notionとは長い付き合いになればいいなと思います。潰れなさそうだし…
Xcodeのシミュレータで録画する方法

よく紹介されている記事では、ターミナルを使用し、任意の名前を録画の都度つけないといけませんでしたが、シミュレータのみで録画する方法もあるので、今回は両方のやり方を書いていきたいと思います。

#環境
Xcode13.1
Swift5.5.1

#シミュレータで使用する方法

1.`⌘+⌥+スクショボタンをタップ`かシミュレータがフォアグラウンド時に`⌘+R`で録画開始。
2.スクショボタンで終了。

※録画が開始されるとこのような表示になります。
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409860/af318f35-662c-7fea-209d-dcbfa167cd1a.png)



#ターミナルを使用する方法
録画データはカレントディレクトリに保存されるので、事前に保存したいディレクトリに移動しておいてください。
1.`xcrun simctl io booted recordVideo 任意の名前.mov`で録画が開始
2. ⌃+cで録画終了

エラーが発生する方はXcodeで以下の設定を行ってください。
⌘+,>Locations>Command Line Toolsを設定してください。
An error occurred while installing ovirt-engine-sdk(Rails)　のエラーについて

久しぶりの投稿なので色々と見にくくなってしまったりしますが、ご容赦ください。

ただいまAWSにて自身のサイトを出すべく、サーバ環境の公開鍵の作成及びGitHubのクローンの最中で起きたエラーです。


#エラー内容
An error occurred while installing ovirt-engine-sdk (バージョン), and Bundler cannot continue.


#結論
こちらのエラーは、下記二つの原因がある可能性があります。

1. RailsにおけるGemfileのパッケージファイルが足りない
2. OS内のインストールするライブラリが足りない


#対処しよう

1. RailsにおけるGemfileのパッケージファイルが足りない

対処その1はRailsのGemfileのパッケージが足りない可能性があります。
下記コマンドを打ち込むことでRailsのGemfileにパッケージが入るので、エラーが解決する可能性があります。

```
gem install ovirt-engine-sdk -v （バージョン）
```

対処その2、OS内のインストールするライブラリが足りない

OS内にインストールするライブラリが足りない場合、同じようにエラーが出る可能性があります。こちらはAWSなどでRailsアプリケーションを起動しようとしている人に多い可能性があります。

そのため、AWSを使ってRailsアプリケーションを起動しようとしている人はこちらを疑ってみるといいと思います。

エラーの解決方法は下記コマンドを打ち込んで、AWS内にライブラリをインストールしましょう

```
sudo yum install libcurl-devel
```

#最後に
今回は2番目のコマンドでエラーを解消することができました。
AWSはまだまだ苦手な部分が多いので、こちらで備忘録として残していきたいと思います。
拙い文ではありますが、見て頂きありがとうござました。

参考サイトです。
https://tech-parrot.com/rails/an-error-occurred-while-installing-ovirt-engine-sdk/
Selenium Webdriverの指定方法（executable_path）が非推奨になったことへの対処法

# これまでの記述方法
これまでwebdriverは`executable_path`を指定して

``` Python
from selenium import webdriver

driver = webdriver.Chrome(executable_path='path/to/chrome')
```
または[Webdriver Manager](https://pypi.org/project/webdriver-manager/)を使って

``` Python
from webdriver_manager.chrome import ChromeDriverManager

driver = webdriver.Chrome(executable_path=ChromeDriverManager().install())
```
のように書いていました。

しかし、この記述方法が非推奨になったことで、

```
DeprecationWarning: executable_path has been deprecated, please pass in a Service object
```

という警告が出るようになりました。

# 新しい記述方法
警告にある通り、`Service`オブジェクトを使って

``` Python
from selenium.webdriver.chrome.service import Service

driver = webdriver.Chrome(service=Service('path/to/chrome'))
```
またはWebdriver Managerを使って

```
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
```
と記述すれば警告が出なくなります。

# その他
[こちらのStack Overflowの質問](https://stackoverflow.com/questions/64717302/deprecationwarning-executable-path-has-been-deprecated-selenium-python)を参考にしました。
Qiita初投稿なので読みにくい・一部間違いがあるかもしれませんがご容赦・ご指摘お願いします。
STM32L010でオーバークロックの為に48MHzにする。 MCO出力 HAL


xMbed2リビジョン143
x自己責任と言う意味が分かる人向け


![o_con77.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/69d5facb-a1fa-fd15-39e6-2675e69d3ccd.jpeg)



![o_con78.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/ca395e70-6afd-89b8-90a7-a2abecdb7369.jpeg)




目的
暇つぶし(全てで約30分程度の作業)(32MHz->48MHz)
クロック出力のテスト(STM32L010F4P6)


いろいろ
まず、オーバークロックで問題になるのは、フラッシュROMのリードが
ハマると予想した。高速な、CPUには、フラッシュROMのアクセスへの
様々なオプションがあるから?
だいたい、似たような製造プロセスで作られているので結構いけると予想した。
で、48Mhzで動いた。(わざわざ変えているとは、思えない)
魔法のスペルは、「RCC_PLLMUL_6」
みんなで叫ぶんだー
そもそもPLLてなんだ?周波数を倍にする物
X4をX6にしただけ。

高度に発展した科学は、魔法と区別が出来ない。とネットに書いてあった気がする。




```c++



/* STM32L010F6P6  -> Mbed NUCLEO-L011K4 program by caa45040 */

#include "mbed.h"

DigitalOut myled(PA_4);

//メインプログラム
int main()
{
    //クロックの初期化
    HAL_RCC_DeInit();

    // 32mz
    RCC_OscInitTypeDef RCC_OscInitStruct = {0};
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
    RCC_OscInitStruct.HSIState = RCC_HSI_ON;
    RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
    RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_6;
    RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_2;
    HAL_RCC_OscConfig(&RCC_OscInitStruct);
    RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                                  |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
    HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1);

    //PA9にSYSCLKを出力
    __HAL_RCC_GPIOA_CLK_ENABLE();
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    GPIO_InitStruct.Pin = GPIO_PIN_9;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF0_MCO;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    HAL_RCC_MCOConfig(RCC_MCO2, RCC_MCO1SOURCE_SYSCLK, RCC_MCODIV_1);

    //無限ループ
    while(1) {

        myled = 1;
        wait(0.2);
        myled = 0;
        wait(0.2);

    }//while

}//main



```
kaminari まとめ

## 開発環境
ruby 2.6.5
Ruby on Rails 5.2.5

https://github.com/kaminari/kaminari

## 使い方
・`gem 'kaminari' ` で `bundle install`

・`page(params[:page]).per(10)`  が使える
　`インスタンス = クラス.page(params[:page]).per(10)` とすると
　10件のデータがインスタンスに入る
　`params[:page]`については後述

・一覧表示の下に `<%= paginate @tasks %>` を入力して準備完了
　一覧表示の下に `First Previous 1 2 3 Next Last` というリンクが出現する

・それぞれがリンクになっている
　例えば２のリンクを押すとURLに `?page=2` というクエリパラメーターが送られる

・`params[:page]` はURLのクエリパラメーターの数字を引っ張るので
　リンクを押す度に `page(params[:page]).per(10)` の
　`params[:page]` が選択した数字に変わるので画面が遷移出来る


## 注意点
・`page(params[:page]).per(10)` は all メソッドと同時に使うものではない

・併せて order を使って表示順を変える際には
　`page(params[:page]).per(10).order(〜)` とする
　（原因不明だけど、order を先に持ってくるとテストが上手く行かなくなる）

・`params[:page]` は初期値でどうやら１が入るみたいなので
　 `if params[:page].present?` などで条件分岐しなくても大丈夫


参考にさせていただいた記事

https://qiita.com/you8/items/df68aaee3010e282d1ae
【初学者~中級者向け】JavaScriptのsplit 組み合わせ( join / trim / map / slice / reverse )


今回はJavaScriptのsplit()とその他のメソッドとの組み合わせを紹介していきたいと思います
join( ) / trim( ) / map( ) / slice( ) / reverse( )



##コードで解説
##**・join( )との組み合わせ**##
組み合わせることで**区切り文字の置換ができます(今回は「スペース」→「 , 」 に置換)**

[join( )](https://qiita.com/yasu-hoshi/items/f1189fd78e86dd402c6c)については以前こちらで解説してます


```javascript
const str = "朝 昼 夜";
const result = str.split(' ').join(',');
 
console.log(result);   // 朝,昼,夜
```

##**・trim( )との組み合わせ**##
**<font color="red">※trim()は前後の余計なスペースを削除するメソッドです</font>**
これと組み合わせて文字列の**前後と途中に出てくるスペースを一掃していきます**

```javascript
const s = '   abc,   efg,   hij ';
const arr = s.trim().split(/\s*,\s*/);  // => ["abc", "efg", "hij"]
```
**①ますはtirm( )によって前後のスペースが削除されます(途中のスペースはそのまま)**

```javascript
`abc,   efg,   hij`
```
**②その後split()と正規表現によって晴れて配列になります**

☆今回の区切り文字は**正規表現**と組み合わせて「**前後のスペースを含めたカンマ**」としてます

```javascript
["abc", "efg", "hij"]
```

##**・map( )との組み合わせ**##
[map( )](https://qiita.com/yasu-hoshi/items/dc15f42a4d1a42bada57)については以前こちらで解説してます
map(Number)と組み合わせることで**数字の入った文字列**を**数値型の配列**に変換できます

map(Number)が少しややこしく感じるかもですが、
処理としては**配列の要素を順番にNumber( )に入れる**というものです。
**<font color="red">※Number( )は数値に変換する関数です</font>**

```javascript
// 文字列を用意
const numberList = '100,200,300'

// 普通にsplitだけで配列にするとこちら
numberList.split(',')
// ["1", "2", "3"]

// map(Number)と組み合わせると
numberList.split(',').map(Number)
// [1, 2, 3]
```

##**・slice( )との組み合わせ**
**<font color="red">※slice( )は文字列または配列を部分的に取得できるメソッドです</font>**
すごくすごく、ややこしいとは思いますが(特に**第２引数注意**！！)
slice(1, 3)であれば **「indexの1 から <font color="red-orange">indexの3の手前</font>まで (つまり２まで！)」**
取得できます

split( )と組み合わせると

```JavaScript
const str = "1月 2月 3月 4月 5月";

// indexの1からindex3の手前まで 
const result = str.split(' ').slice(1, 3);

console.log(result);  // ['2月', '3月']
```
文字列から任意の箇所を取り出した配列にできます


##**・reverse( )との組み合わせ**##
**<font color="red">※reverse( )は最初から最後までの順番をひっくり返すメソッドです</font>**

```JavaScript
// 文字列を用意
const str = "大富豪 平民 大貧民";

// splitで配列にしてreverseでひっくり返す
result1 = str.split(' ').reverse();

// splitとreverseで革命的な配列を作った後に、joinで文字列に
result2 = str.split(' ').reverse().join(' ');

console.log( result1 ); // ['大貧民', '平民', '大富豪']
console.log( result2 ); // 大貧民 平民 大富豪
```
となります

##まとめ##
今回のようにメソッドを繋げて処理することは多いのでまた機会ありましたらご紹介します。
ありがとうございました。
複数人で共有するPCでパスワードのかかったSSH鍵を使いたい

ロボットの体内PCとかでよくある話なのですが

* 複数人で同じPCの同じアカウントを使用する
* gitのリモートレポジトリにアクセスする際に、だれか一人のSSH鍵で設定してしまうとセキュリティ的に問題がある(そのPCを使える人は全員、その人の全てのプライベートレポジトリを読み書きできてしまうので)

という場合があります。最近はGitHubが基本的にSSH認証だけしか対応しなくなってしまったので、HTTPS認証での「ユーザ名とパスワードを入力する」という方法も使えません。
そこで、それぞれ自分専用のSSH鍵を作成します。

```bash
ssh-keygen -C "[your email]" -f ~/.ssh/id_rsa_[your GitHub ID]

# 例えば
ssh-keygen -C "yasu313nori@gmail.com" -f ~/.ssh/id_rsa_yasu31
```
その際に`Enter passphrase`で秘密のパスワードを設定すれば、自分しか使えない鍵を`~/.ssh/id_rsa_[your GitHub ID]`に生成することができます。

あとはいつもと同じように、`~/.ssh/id_rsa_[your GitHub ID].pub`にある公開鍵をコピーして自分のGitHubのSSH public keyに加えれば、

```bash
cat ~/.ssh/id_rsa_[your GitHub ID].pub
```

`git clone`、`git push`系のリモートに接続するコマンドの前にSSH鍵を指定するようにすれば、自分の鍵でリモートにアクセスできます

```bash
GIT_SSH_COMMAND='ssh -i ~/.ssh/id_rsa_[your GitHub ID] -o IdentitiesOnly=yes' git clone [SSH URL of repository]
```

毎回このコマンドを打つのは長いので、`~/.bashrc`に以下のようなエイリアスを登録しておくと楽です。

```bash
alias git-[your GitHub ID]="GIT_SSH_COMMAND='ssh -i ~/.ssh/id_rsa_[your GitHub ID] -o IdentitiesOnly=yes' git"
# 例えば
alias git-yasu31="GIT_SSH_COMMAND='ssh -i ~/.ssh/id_rsa_yasu31 -o IdentitiesOnly=yes' git"
```
これで、リモートと通信するコマンドを打つ時はこのようにして自分の鍵を簡単に指定できます。

```bash
git-yasu31 pull origin master
```


# 参考
https://stackoverflow.com/questions/4565700/how-to-specify-the-private-ssh-key-to-use-when-executing-shell-command-on-git

https://stackoverflow.com/questions/51722110/the-best-way-to-manage-private-key-in-a-shared-computer
Qiita初投稿時にアップロードできる画像容量と、gif容量削減

#Qiita初投稿時にアップロードできる容量は2MBまで？
gifを記事内にアップロードしようとしたところ、
**”something went wrong”**というエラーメッセージが発生。。。

初投稿時はどうやら容量は2MBまで、ということのようなので、テスト投稿します。

だいぶ前の記事ですが、以下を参考にしました。↓↓↓
[初めてQiitaに投稿すると1ヶ月の画像アップロード制限が2MB→100MBにアップします](https://blog.qiita.com/75674629515-2/)


以降、一旦投稿後に追記↓↓↓


**しかし改善せず。。。**
**”something went wrong”**がまだ出る。。。
※アップロードしようとしたgifが大きすぎたのか、初投稿だから2MB上限で引っかかったのか不明です。

ですが、コメント欄のところにある、アップロードの上限は100MBになっているので、
そこはうまくいったようです。
**ちなみに、いろいろ試しまくったせいで、既に55MBも使ったことになってる。ぎゃ～。**
![アップロードできる容量.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599060/be3ff180-6fcf-83c6-07d1-c27c06e88296.png)




##**容量を減らすと改善した**
結果的に、
**アップロードするgifの容量が数MB以上だったので、できるだけ容量を小さくすると改善**しました。
容量の上限ははっきりわかりませんが、0.965MBはアップロードできました。

###容量を減らすためにしたこと

**・再生時間を短く編集する**
→最初と最後の方は必要ない時間が数秒くらい（録画ボタンのON、OFFする時間とか）あったりするので削除。

**・gifのフレームレートを落とす**
フレームレートは1秒間あたりの表示画像数なので、少なくなると容量が減ります。
一方で、理屈上は動きがカクカクしてきます。（パラパラ漫画をめくるスピードを落とすイメージ）
なので、カクカクして使い物にならないかもと思ったら、思ったよりもひどくなりませんでした。
（動きが多いものはカクカクしてしまうと思います。）

以下のサイトで動画をgifに変換しました。フレームレート（サイト上では、Frame Rate[FPS]と表記）など、容量を減らす設定も簡単にできました。
[Ezgif.com](https://ezgif.com/video-to-gif/ezgif-7-840fc4b1ac2d.mp4)

**・gifを圧縮する**
以下のサイトでgifの圧縮ができます。これも操作は簡単なので、やってみればたぶん分かります。
[あなたの画像エディター](https://www.iloveimg.com/ja/compress-image)

**→これらをすると、ざっくりですが、7,8割くらい容量が減りました**

以上です～(*^-^*)
WSL(Ubuntu 20.04.3 LTS) に、Rをインストールして、グラフ画像が出力できるまで

# 環境
Windows10 + WSL(Ubuntu 20.04.3 LTS)

```shell
$ cat /etc/os-release
NAME="Ubuntu"
VERSION="20.04.3 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.3 LTS"
VERSION_ID="20.04"
・・・
```

# はじめに
以下のものを作ることが目的
①R(4.1)をWSLに対してインストールして
②Rの実行ファイルを作成
③Rscriptでファイル実行して、グラフ画像を出力

# 手順

## R(4.1)をインストール
```shell
sudo apt update
# リポジトリの設定
sudo wget -qO- https://cloud.r-project.org/bin/linux/ubuntu/marutter_pubkey.asc | sudo tee -a /etc/apt/trusted.gpg.d/cran_ubuntu_key.asc
sudo add-apt-repository "deb https://cloud.r-project.org/bin/linux/ubuntu $(lsb_release -cs)-cran40/"

# 入れないとRのパッケージのインストールでコンパイルエラーが出る
sudo apt install build-essential
# Rのインストール
sudo apt install --no-install-recommends r-base
```
※2021/11/03 現在では、4.1.1がインストールされる

## Rの設定等

```shell
# Rのコマンドラインを起動
sudo R
```

```R
# ダウンロード先のミラーサイト設定(53のJapanを選択)
chooseCRANmirror()

# ggplot2のパッケージをインストール
install.packages("ggplot2")
```


## Rの実行ファイルを作成
```shell
vi test.R
```
以下のようなファイルを作成

```R:test.R
# インポート
library(ggplot2)

# グラフのプロットデータ作成(irisはプリセットされているデータフレーム)
p <- ggplot(data = iris,
       mapping = aes(x=Sepal.Width)) +
  geom_density(fill = "gold")

# 画像出力(サイズは dpi*width × dpi*height のピクセルサイズとなる)
ggsave(filename = "sample.png", 
       plot = p, 
       device = "png", 
       width = 6.4, height = 4.8,
       dpi = 100)
```

## 実行
```shell
Rscript test.R
```
※ただのubuntuのときは、chmodとかも必要、、、？

## 出力画像
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541739/2a870e0d-c239-dc7e-99b5-62644b6eaff2.png)


# 最後に
クライアントサイドでグラフAPIを使う代わりに、Restとかでサーバー実行してグラフの画像返すとかでも良いんじゃないかと思って調査してみました。

# 参考
https://cran.ism.ac.jp/bin/linux/ubuntu/
https://data-viz-lab.com/ggplot2
「議事録作成の自動化」で会議を大幅効率化！ 文字起こしアプリ Nottaの活用ポイント

元記事：[https://www.notta.ai/blog/notta-speech-to-text-tips](https://www.notta.ai/blog/notta-speech-to-text-tips)
![notta-speech-to-text-tips.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2226142/c822320e-2677-49fc-dc7c-ad674b429647.png)


「毎日毎日会議づくし・・・せめて議事録には余計な時間を使いたくない」

「会議のテンポが速すぎて議事録メモが追い付かない」

「日本語の議事録を、翻訳して海外オフィスに展開しないと・・」

‍

こんな会議の「議事録」にまつわるお悩みはありませんか？

実は、上記のお悩みを一挙に解決できるアプリがあるんです！

‍

それは、自動で文字起こしをしてくれるアプリ“Notta”。

文字起こしをNottaに任せておけば、会議中は会議内容に集中するだけ。さらに「翻訳機能」までついているので、海外オフィス展開前の「議事録英訳しなきゃ！」という要望にまで応えられるんです。

この記事では、議事録作成でNottaを最大限活用するためのポイントをお伝えしていきます。

‍

# Nottaの活用ポイント① | 議事録作成を任せる
一番ベーシックなNottaの活用方法は、文字起こし機能を使った議事録作成。

Nottaで会議中に音声を録音しておくだけで、自動で文字起こしが行われます。文字認識精度が非常に高く、誤字脱字が少ないので、後々の編集もラクラク。

また、アプリで録音していなくても、他の音声データを取り込んで文字起こしすることも可能。「リアルタイムで録音してなかった！」「過去の音声データから文字起こししたい」という時にも対応できます。

議事録編集の際、画像を挿入も可能なので、見やすく美しいビジュアルの議事録が作成できることもポイント。

議事録作成に費やす時間を最小化できる、嬉しい機能です。

‍

# Nottaの活用ポイント② | 共有機能で、簡単共有＆編集
Nottaで文字起こししたメモは、他の人と共有可能。

即時の展開が必要なときに、リンクを送るだけでメモ内容が共有でき、とても便利です。

また、共有した相手と同時に編集することで、編集作業の効率化も実現できます。例えば会議内容が非常に長い場合は、複数人で手分けして編集する、といったことも可能。

議事録作成だけでなく、時間をかけず共有まで行うことができます。

‍

# Nottaの活用ポイント③ | すぐに翻訳、すぐに展開
次に紹介するのは、Nottaの翻訳機能。

グローバル化が進む今、海外オフィスと会議内容を共有している人も多いのではないでしょうか。

「まずは日本語で議事録作成して、見直して、完成したら今後は英語に翻訳して・・・」

‍

こんなフローに時間を費やしている方は、実は少なくないのでは。

ただでさえ議事録作成に時間がかかるのに、さらに翻訳作業もしていると、肝心な本業に費やす時間がどんどん削られてしまいますよね。

‍

Nottaなら、文字起こしで作成した議事録を、さらに同アプリ内で翻訳することが可能。140言語に対応しているので、英語以外の言語でも活躍します。

議事録作成から翻訳作業まで、一括でNottaに任せて、大幅な効率アップが可能に。

‍

# Nottaの活用ポイント④ | アプリでも、Webでも
Nottaはスマートフォンのアプリでも、またウェブ版（PC）でも使用可能です。「スマートフォンを忘れてしまった」「PCが無い」という時でも対応可能。お持ちのデバイスで気軽に使用できます。

また、アカウント登録することで同期ができるので、デバイス毎にデータが分散してしまう、ということはありません。

忙しくてバタバタしていても、１つデバイスがあればその場で簡単に議事録の文字起こしが可能。どこでもいつでも効率化を実現できます。

‍

# まとめ
今回紹介したポイントを押さえてNottaを活用すれば、議事録作成プロセスが何段階も効率化すること間違いなしです。

ぜひ、次回の会議で試して、どのくらい作業効率がアップするのか、実感してみてくださいね。

---

Nottaは無料体験できますので、試してみましょう。
‍
‍**Web版**
‍‍Google ChromeやMicrosoft Edgeから[Web版](http://www.notta.ai/)をアクセスできます。（無料）
‍
‍**Chrome拡張機能**
‍Chrome web storeから[Notta拡張機能](https://chrome.google.com/webstore/detail/notta-speech-to-text-tran/kdelkaogljjcbjffjmahedaobfjineig?hl=ja)をインストールできます。（無料）
‍
‍**アプリ版‍**
iOSアプリは[App Store](https://apps.apple.com/jp/app/notta-%E9%9F%B3%E5%A3%B0%E3%81%AE%E9%8C%B2%E9%9F%B3%E3%81%A8%E6%96%87%E5%AD%97%E8%B5%B7%E3%81%93%E3%81%97-ai%E9%9F%B3%E5%A3%B0%E8%AA%8D%E8%AD%98%E3%82%A2%E3%83%97%E3%83%AA/id1480649572)からダウンロードできます。（無料）
Androidアプリは[Google Play](https://play.google.com/store/apps/details?id=com.langogo.transcribe&hl=ja&gl=US)からダウンロードできます。（無料）
pythonのlistで2要素間比較ソート

## 達成したいこと：2要素の情報を用いたソート
　pythonのリストでは、例えば`sorted()`を用いることで中身の要素をソートできます。また、`sorted(リスト名, key=ソート時のキー)`とすることで、ソートの優先度を指定することができます。
　ここでは、キーとして「2要素の情報」を使用する場合の書き方を取り上げます。
## 結論：cmp_to_keyの利用
`cmp_to_key()`内部にラムダ関数を記載すればOKです。
例えば、`[x,y]`(いずれも整数)を要素にもつリストに対して、`y/x`をキーとしてソートするには、以下の通り書けばよいです。

```Python
from functools import cmp_to_key
li=[[x,y] for x in range(10) for y in range(10)]
sorted_li = sorted(li,key=cmp_to_key(lambda a,b:a[1]*b[0]-a[0]*b[1]))
```

###蛇足
例に挙げた操作を素直に実装すると、次のようになります。

```Python
li=[[x,y] for x in range(10) for y in range(10)]
sorted_li = sorted(li,key=lambda a:a[1]/a[0])
```
しかし、この方法では`y/x`の計算において小数に由来する誤差が生じ、正しく要素間の比較演算ができない可能性があります。上記のように`cmp_to_key()`を用いて比較すると、整数同士の和(差)と積を計算するだけで良いので、誤差なくソートすることができます。
[初心者向け]Azure VMの作成方法から選び方まで

#はじめに
Azureをとりあえずサインアップしてみたけど、何のサービスから利用しようか迷ってる方におすすめの記事です。

今回はAzureの中でも取っ付きやすい、VMを作ってみましょうということで、作成方法から選び方まで解説していきます。
※個人利用向けです。

##Azure VMの作成方法
以下の記事で解説しています。※2021/9時点での内容です。
https://www.karikawa-blog.com/create-azure-virtual-machine/


##Azure VMの選び方
AzureのVMは大体10数種類あります。MS公式のDocsで各種類ごとの特徴が記載されてますが、イマイチピンとこないです。

以下の記事で個人利用向けにVMの選び方を紹介してるので、参考にしてみてください。
https://www.karikawa-blog.com/choose-azure-virtual-machines/
Python&HolePlateMakerでLEGOテクニックに互換する部品をコードから自作する

# はじめに
今回の記事は昨年公開したHolePlateMakerの改良についてまとめたものです。
↓前回の記事

https://qiita.com/Inoue_Minoru/items/2096d48401268c17929f

# 要は何が変わったの？

- 開けられる穴の種類にLEGOテクニックに互換しそうな穴が加わった。また、円形の穴の他に十字形(Axle)の穴も出力できるようになった。
- pythonパッケージについて非推奨だった項目を見直した。2021/10/31(日)確認では実行時のWarningがなくなっていたことを確認した。

# 事前準備

こちらの記事などを参考にvenvが使える状態にする。

https://qiita.com/fiftystorm36/items/b2fd47cf32c7694adc2e

なお、今回の検証にはmacOSをつかっているためvenvの実行コマンド等は適宜書き換えること。

#　入手先github

https://github.com/henjin0/HolePlateMaker

インストールなどの環境構築方法はgithubにあるため割愛します。
pip 21.3.1、Pythonは3.9.1を使用しました。


# 新機能のLEGOっぽい穴を確認してみる

まずはコードをcloneします。

```shell:git　clone
git clone https://github.com/henjin0/HolePlateMaker.git
```

Clone後のフォルダに移動し、仮想環境を作成する。


```shell:仮想環境
cd HolePlateMaker
python3 venv -m hpl
source ./bin/activate
```

pipを使ってパッケージをインストールします。もしpyqt5などのインストールでエラーが出力された際には`pip install -U pip` などでnpmのアップデートを実行してください。

```shell:パッケージ
pip install -r requirements.txt
```
インストールができたら、下記のプログラムを作成します。
実をいうと[同名のファイル](https://github.com/henjin0/HolePlateMaker/blob/main/sample_npArrayToHolePlate.py)でgithubにも入っていたり。

```python:　sample_npArrayToHolePlate.py
import numpy as np
from stl import mesh
import matplotlib
matplotlib.use('Qt5Agg')
from mpl_toolkits import mplot3d
from matplotlib import pyplot
from HolePlateMaker import NumpyArrayToHolePlate

# OS等の環境依存せずに文字が表示できるようにするためにフォント変更
pyplot.rcParams["font.family"] = "Arial" 

# 0:穴が生成されない 1:丸い穴が開く 2:十字形(Axle)の穴が開く(4.8mm穴のみ)
plateData = np.array([[1,0,2],
    [2,0,1],
    [1,1,1,],
    [0,0,2],
    [0,0,1],])

# 2番目の引数typeには穴の大きさの'3mm'と'4.8mm'が指定可能。
curMesh = NumpyArrayToHolePlate.NumpyArrayToPlate(plateData,'4.8mm')
curMesh.save('plate.stl')

figure = pyplot.figure()
axes = figure.add_subplot(111, projection='3d')
axes.add_collection3d(mplot3d.art3d.Poly3DCollection(curMesh.vectors))

# Auto scale to the mesh size
scale = curMesh.points.flatten()
axes.auto_scale_xyz(scale, scale, scale)

# Show the plot to the screen
pyplot.show()
```
LEGOテクニックに互換する4.8 mm穴に関するplateDataの対応はこちら。

| plateData | 4.8 mm穴 |
|:-:|:-:|
| 生成なし  | 0  |
| ○  |  1 |
|  ｘ |  2 |

実行コマンドはこちら

```shell:　exec
python sample_npArrayToHolePlate.py
```

出力される結果はこちら

<img width="600" alt="sample_npArrayToHolePlate.py出力結果" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271381/db465cc3-7d89-d92e-b837-79dcded20813.png">

積層型3Dプリンタで出力された結果はこちら
写真上側にある黒い部品はLEGOテクニック部品のリフトアームで、それぞれのAxleのピッチが一致していることが確認できます。　

<img width="400" alt="sample_npArrayToHolePlate.py出力結果" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271381/779b46cd-56ef-a579-af7e-f6ca357fdcb9.jpeg">

# まとめ

- HolePlateMakerに対してLEGOテクニック部品に互換する自作部品を新たに出力できるようにしました。
link_to メソッドで destroy アクションをルーティングする


## 開発環境
ruby 2.6.5
Ruby on Rails 5.2.5


## 方法

通常だと link_to メソッドは GET メソッドでルーティングしてまうので

```
<td><%= link_to "削除", "/blogs/#{blog.id}", method: "DELETE" %></td>
```
こんな感じで第３引数にメソッドを指定すればオッケー

また、 resources でルーティングした際に　
rails routes でルーティングを確認すると

```

      Prefix Verb   URI Pattern                                                                                       Controller#Action
                                   blogs GET    /blogs(.:format)                                                                                  blogs#index
                                         POST   /blogs(.:format)                                                                                  blogs#create
                                new_blog GET    /blogs/new(.:format)                                                                              blogs#new
                               edit_blog GET    /blogs/:id/edit(.:format)                                                                         blogs#edit
                                    blog GET    /blogs/:id(.:format)                                                                              blogs#show
                                         PATCH  /blogs/:id(.:format)                                                                              blogs#update
                                         PUT    /blogs/:id(.:format)                                                                              blogs#update
                                         DELETE /blogs/:id(.:format)                                                                              blogs#destroy
 
```

こんな感じで destroy アクションに対する prefix がない
これは


https://valuable.hatenablog.com/entry/ruby-on-rails-routing-init

省力されてるだけらしい
だから ~path っていう書き方もできる
Bootstrap5で動画を画面いっぱいに表示させる

Bootstrap5のみを使用した環境でvideoタグによる動画を画面いっぱいに表示する方法です。

# videoタグをdivで囲って幅と高さ、positionを設定

いきなり結論ですが、videoタグをdivで囲って、そのdiv
・幅：100%
・高さ：100vh
・position:relative
を設定します。
必要に応じてoverflow-hiddenを設定します。

子要素のvideoには
・positon:absolute
を設定し、追加のCSSで
・min-width:100%
・min-height:100vh
を設定します。

```html
<div class="w-100 vh-100 overflow-hidden position-relative video-wrapper">
    <video class="position-absolute top-0 left-0"  src="mov.mp4" muted autoplay loop></video>
</div>
```

```css
.video-wrapper video{
    min-width:100%;
    min-height:100vh;
}
```
Pythonで任意のP10・最頻値・P90を持つ三角分布を生成する

# やりたいこと
- P10、最頻値（モード）、P90が分かっているとき、その条件にフィットする三角分布を生成する

三角分布は、最小値a、最頻値b、最大値cの三つのパラメータで表現される連続分布の一種です。[^1]
モデルが単純で直感的に理解しやすいため、Oil&Gas業界のリスク評価などでよく用いられています。[^2]

![triangular.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1350685/419682ac-619b-33fe-e9a1-8df657807adb.png)

ここでは、P10、最頻値、P90が既知の標本データがあるとき、これにフィットする三角分布を計算する方法を紹介します。
SciPyのcurve_fitを用いて最小二乗法によるフィッティングを行います。

# コード
次のような三角分布のクラスtriangular_fitを定義します。

```Python:triangular_dist.py
import numpy as np
from scipy.stats import triang
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt

#三角分布のクラスを定義
class triangular_fit:
    def __init__(self,p10,mode,p90):
        #与えられたP10,最頻値、P90にフィットする三角分布を求める
        self.b = mode
        array_x = [p10,p90]
        array_y = [0.1,0.9]
        #curve_fitを用いて、累積分布関数がP10,P90にフィットする三角分布のパラメータa,cを計算
        param, cov = curve_fit(self.cdf_fit, array_x, array_y,bounds=[(-np.inf,p90),(p10,np.inf)])
        self.a = param[0]
        self.c = param[1]
    def cdf_fit(self,x,a,c):
        #累積分布関数を出力（フィッティング計算用）
        #scipyの三角分布の関数用にパラメータを変換
        c_tri=(self.b-a)/(c-a)
        loc_tri=a
        scale_tri=c-a
        return triang.cdf(x,c_tri,loc=loc_tri,scale=scale_tri)
    def cdf(self,x):
        #累積分布関数を出力
        #scipyの三角分布の関数用にパラメータを変換
        c_tri=(self.b-self.a)/(self.c-self.a)
        loc_tri=self.a
        scale_tri=self.c-self.a
        return triang.cdf(x,c_tri,loc=loc_tri,scale=scale_tri)
    def pdf(self,x):
        #確率密度関数を出力
        #scipyの三角分布の関数用にパラメータを変換
        c_tri=(self.b-self.a)/(self.c-self.a)
        loc_tri=self.a
        scale_tri=self.c-self.a
        return triang.pdf(x,c_tri,loc=loc_tri,scale=scale_tri)
    def ppf(self,q):
        #パーセントポイント関数（CDFの逆関数）を出力
        #scipyの三角分布の関数用にパラメータを変換
        c_tri=(self.b-self.a)/(self.c-self.a)
        loc_tri=self.a
        scale_tri=self.c-self.a
        return triang.ppf(q,c_tri,loc=loc_tri,scale=scale_tri) 

```
ここでは、P10=0、Mode=5、P90=15を満たす三角分布を計算してみます。

```Python:
p10 = 0
mode = 5
p90 = 15

#与えられたP10,mode,P90にフィットする三角形分布
test = triangular_fit(p10,mode,p90)

#チェック用：P10、P90の累積分布値がそれぞれ0.1,0.9に近い値になっているか確認。
print(test.cdf(p10),test.cdf(p90))

#チェック用作図：確率密度関数を出力
x = np.linspace(0-p90/2,p90*2,1000)
plt.plot(x,test.pdf(x))
plt.show()
```

# 出力
> 0.10000000062440002 0.8999999953027843
> ![tri_dist.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1350685/efc42027-fde5-2e32-4e12-b54aa91a728f.png)

# 参考にしたサイト
- [「三角分布」MathWorks](https://jp.mathworks.com/help/stats/triangular-distribution.html)
- [Pythonで非線形関数モデリング](https://qiita.com/hik0107/items/9bdc236600635a0e61e8)
- [triang:三角分布（triangular distribution）](https://mikiokubo.github.io/analytics//11scipy#triang:-%E4%B8%89%E8%A7%92%E5%88%86%E5%B8%83-(triangular-distribution))
- [SciPy.stats.triang](https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.triang.html)

[^1]: 最小値a、最大値b、最頻値cと定義されている場合もあります
[^2]: たとえば[「石油上流業界のポートフォリオ戦略」](https://oilgas-info.jogmec.go.jp/_res/projects/default_project/_project_/pdf/0/394/200107_057a.pdf)など
テスト52

```vb

Sub ReCheck()

Dim i As Long
Dim j As Long
Dim Last_Row As Long
Dim Last_Col As Integer
Dim tmp As Worksheet
Dim myShape As Variant

' ....〆('ω'*)<メモです

'シートを追加
Worksheets.Add After:=Worksheets(Worksheets.Count)

'シート名を「tmp」にする
ActiveSheet.Name = "tmp"
Set tmp = ActiveSheet

With ThisWorkbook.Sheets("修正")

    '[修正]シートが保護されていた場合、保護を外す
    If .ProtectContents = True Then
    
        .Unprotect
        
    End If

     '全てのセルにロックをかける
    .Cells.Locked = True
    
    '全てのセルを塗りつぶしなしにする
    .Cells.Interior.ColorIndex = 0
    
    '[修正]シートのデータを[tmp]シートへ全てコピー
    .Cells.Copy tmp.Cells
    
    Application.DisplayAlerts = False
    .Delete
    Application.DisplayAlerts = True
    
End With
    
tmp.Name = "修正"

With ThisWorkbook.Sheets("修正")
    
    '[修正]シートのデータを上から順番に各データのチェックをしていく
    '最終行を取得
    Last_Row = .Cells(.Rows.Count, 1).End(xlUp).Row
    
    For i = 2 To Last_Row       '行方向
    
        For j = 1 To 4     '列方向
        
            Select Case j
                Case 1      'A列
                
                    If .Cells(i, j).Value <> 3 Then
                        '黄色にする
                        .Cells(i, j).Interior.ColorIndex = 6
                        
                        'ロックをはずす
                        .Cells(i, j).Locked = False
                    
                    End If
                    
                Case 3     'C列
                
                    If .Cells(i, j).Value <> 100 Then
                        '黄色にする
                        .Cells(i, j).Interior.ColorIndex = 6
                        
                        'ロックをはずす
                        .Cells(i, j).Locked = False
                    
                    End If
                    
            End Select
        
        Next j
    
    Next i
    
'    'ボタンを作成(図形)
'    Set myShape = .Shapes.AddShape( _
'                            Type:=msoShapeRectangle, _
'                            Left:=.Range("F2").Left, _
'                            Top:=.Range("F2").Top, _
'                            Width:=50, _
'                            Height:=30)
'
'    myShape.Fill.ForeColor.RGB = RGB(250, 100, 50)
'
'
'    'ボタンにマクロを登録(ReCheck)
'    myShape.OnAction = "ReCheck"

    '[修正]シートに保護をかける(ボタンは使えるようにする)
    .Protect DrawingObjects:=True

End With


End Sub