OmniAICreator/Qiita-1.07M huggingface dataset:
M5Atomのアナログ入力を使う

Atom Matrixのアナログ入力についてテストします。
arduinoでやっていることを、小型＆低価格でできるかの確認作業です。
USBで接続されている状況で、センサの値をパソコンで受け取ります。
これが動けば、抵抗値のセンサならなんでもいけます。
可変抵抗、曲げセンサ、圧力センサ、光センサなど。
また、serial.write()を使うことで、processingに値を渡せます。
そして、分圧抵抗回路で、ボタンを10個ぐらいは認識できます。
（ただし同時押しは非対応）

#環境
M1 Mac
M5ATOM Matrix
KUMAN K5センサセットに入っていた、CdS光センサキット（たまたま手元にありました）
（なければ10Kぐらいの抵抗とCdSセンサを使います。回路は単純です）

#書き込み準備
下記参照
https://qiita.com/hextomino/items/69f9804038041618b243

#配線
偶然ですが、配線の必要がありません。刺すだけでした。
ATOMの穴が下からGND,5V,G25となっており、光センサキットが「-,+,S」となっていて、同じ並びであったためです。

| 配線 |光センサキット |ATOM端子アップ|
|:-:|:-:|:-:|
|![IMG_0297.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/579633e5-d35a-d44f-8f1a-743fe292a44b.jpeg)|![IMG_0298.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/ef03530d-c5da-b675-106c-f2a5b8ed4f79.jpeg)|![IMG_0302.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/3983a23f-73c6-9e24-f90d-1d9f16bab61c.jpeg)|


#ソースコード
```c:atomAnalog.ino
void setup() {
  Serial.begin(115200);
}

void loop() {
  int a = analogRead(25);//32(G33)
  Serial.println(a);
  delay(50);
}
```

#結果
測定は曇り空です。手で覆うと4095になるので、2^12=4096、12bit解像度です(esp32の仕様)。
![スクリーンショット 2021-02-10 15.07.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/eb9a8127-b494-34dd-8edb-d3f5bb33c30a.png)
シェルスクリプト上でgnuplotを動かす

#目的
シェルスクリプト上でgnuplotのスクリプトにパスを与えて繰り返し処理をしたい

描画プログラムをgnuplotで書いたが、繰り返し処理やファイル操作をgnuplotのスクリプト上で行うのは面倒なので、シェルスクリプトを用いて、描画部だけgnuplotを用いたい

#参考
大筋はこちらのページを参考にした
http://auewe.hatenablog.com/entry/2013/06/03/012031



#実行
今回はターミナル上で引数として入力データとタイトル名を与える。


```shell:Visualization.sh
#!/usr/bin/bash -f
# Visualization.sh
# 第一引数データ
# 第二引数タイトル

dataPath=$1
title=$2
echo "plot ${dataPath} Spectral. title is ${title} ."
echo ${dataPath} | sed -e  "s#/#\\\\#g"
gnuplot << EOF
  set terminal png
  set output '${title}.png'
  set nokey
  plot '${dataPath}' with lines
EOF
```

追加で加えた処理が以下
cygwin上で動かすため、入力パスは”/”区切りだが、gnuplot上では"\"で処理されるため、その置換を行った
(参考:https://qiita.com/miriwo/items/8bf37eedf92fc6ea8b77)

```shell

echo ${dataPath} | sed -e  "s#/#\\\\#g"

```

#出力

![test.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1098682/025ddb46-9659-1081-50a4-ec810873e5c2.png)
【Shopify】liquidのオブジェクトについてまとめてみた (country_option_tags, currency, current_page)

#はじめに
この記事では、Liquidオブジェクトについて日本語訳したものです。

`country_option_tags`、`currency`、`current_page`のオブジェクトをまとめていきます。

[こちら](https://shopify-dev.shopifycloud.com/docs/themes/liquid/reference/objects)を参考にしました。

#country_option_tags オブジェクト
country_option_tagsオブジェクトの概要について[ドキュメント](https://shopify-dev.shopifycloud.com/docs/themes/liquid/reference/objects/country-option-tags)からの引用です。

>管理画面の配送ページに配送ゾーンとして含まれる国ごとの`<option>`を生成します。

各`<option>`には、`data-provinces`という属性が認定され、その国のサブリージョンのJSONエンコードされた配列が含まれます。

サブリージョンを持たない国の場合、`data-provinces`属性には空の配列が設定されます。

```.liquid
<!-- Store ships only to Canada and the United Kingdom -->
<select name="country">
  {{ country_option_tags }}
</select>
```
>\<!-- Store ships only to Canada and the United Kingdom -->
\<select name="country">
　　\<option value="---" data-provinces="[]">---</option>
　　\<option value="Canada" data-provinces="[['Alberta','Alberta'],['British Columbia','British Columbia'],　　　　　　['Manitoba','Manitoba'],['New Brunswick','New Brunswick'],['Newfoundland','Newfoundland'],['Northwest Territories','Northwest Territories'],['Nova Scotia','Nova Scotia'],['Nunavut','Nunavut'],['Ontario','Ontario'],['Prince Edward Island','Prince Edward Island'],['Quebec','Quebec'],['Saskatchewan','Saskatchewan'],['Yukon','Yukon']]">
　　　　Canada
　　\</option>
　　\<option value="United Kingdom" data-provinces="[]">United Kingdom\</option>
\</select>


#currency オブジェクト
currencyオブジェクトの概要について[ドキュメント](https://shopify-dev.shopifycloud.com/docs/themes/liquid/reference/objects/currency)からの引用です。

>currencyオブジェクトは、ISOコードや通貨のシンボルなどの情報を返します。

グローバルオブジェクトである、`shop`や`cart`を使用することで、ストアやカートで使用されている通貨の情報にアクセス出来ます。

```.liquid
ISO Code: {{ currency.iso_code }}
Name: {{ currency.name }}
Symbol: {{ currency.symbol }}
```
>ISO Code: USD
Name: United States Dollar
Symbol: $

##currency.name
通貨の名前（例：`United States dollars`や`Euro`）を返します。

##currency.iso_code
通貨のISOコード（例：`USD`や`EUR`）を返します。


##currency.symbol
通貨のシンボル（例：`$`、`€`）を返します。




#current_page オブジェクト
current_pageオブジェクトの概要について[ドキュメント](https://shopify-dev.shopifycloud.com/docs/themes/liquid/reference/objects/current-page)からの引用です。

>`current_page`はページ分割されたコンテンツを閲覧しているときのページ番号を返します。

これは、`pagenate`ブロックの外でも使用できます。

```.liquid
{{ page_title }} - Page: {{ current_page }}
```
>Summer Collection - Page: 1



#終わりに
今回の記事はここまでになります。

お疲れさまでした。

# Shopify アプリのご紹介

Shopify アプリである、「商品ページ発売予告アプリ | リテリア Coming Soon」は、商品ページを買えない状態のまま、発売日時の予告をすることができるアプリです。Shopify で Coming Soon 機能を実現することができます。

https://coming-soon.reterior.jp/

https://apps.shopify.com/shopify-application-314?locale=ja&surface_detail=%E3%83%AA%E3%83%86%E3%83%AA%E3%82%A2&surface_inter_position=1&surface_intra_position=1&surface_type=search
GoogleAppsScriptでメールの個別自動送信プログラムを作る

# はじめに
プログラム言語を用いて、メールの一括送信がしたい。
pythonなどの言語を用いれば、自動送信は可能だが「自身のパソコンをシャットダウン」した状態で、メールを送信するためには自身のパソコン上で実行するのではなくGoogleAppsScript（以降GAS）というサーバーレスで実行する言語を選んだ。
プログラミング言語を初めてみたが、自身で実行環境を作るのが難しいという方向けに記事を書いた。

主な使い方はメールを一括で送りたいが、メールを送る人によって文面を変更したい場合に有効である。

# 目次
<!-- タイトルとアンカー名を編集 -->
1. [GoogleAppsScriptとは](#Chapter1)
1. [GoogleAppsScriptでメールを送る](#Chapter2)
1. [GASでスプレッドシートを読み込む](#Chapter3)
1. [for文を使ってメールを一括で送る](#Chapter4)
1. [GASの上限を知る](#Chapter5)
1. [参考文献](#reference)

<!-- 各チャプター -->
<a id="#Chapter1"></a>
# GoogleAppsScriptとは？
Googleが提供しているサーバーレスで各種Googleサービスをサーバー上から各種Googleサービスを実行できるスクリプトのことである。

”GoogleAppsScript”
https://script.google.com/home

にアクセスして、コードを書くことができる。
プログラミング言語は開発環境を作ることに一定以上のスキルが必要であるが、GoogleAppsScriptは開発環境のこうちくが不要のため上記アドレスにアクセスするだけで誰でもコードを書き始めることができる。

# GoogleAppsScriptでメールを送る
    /* 各データを準備 */
    var strTo= 自分のメールアドレス"; //To　
    var strName="VPN利用者様"; //苗字
    var strFrom="admin@gmail.com"; //From
    var strSender="admin@gmail.com"; //差出人
 
    /* メール本文を準備 */
    var strSubject = "【要回答】メールタイトル（回答期限：2019/4/30）【△△△より】";
    var strBody = "メール本文";

    /* メールを送信 */
    GmailApp.sendEmail(
      strTo,
      strSubject,
      strBody,
      {
        from: strFrom,
        name: strSender
      }
    ); //MailAppではfromが設定できないとのこと

<a id="#Chapter3"></a>
# GoogleAppsScriptでメールを送る
GoogleAppsScriptでスプレッドシートから送信先を取得しつつメールを送るには、

- [GASでのメールの送り方](https://qiita.com/matsuhandy/items/bbfa357db4e3e1e5c92a)
- [GASでのスプレッドシートの読み取り方](https://qiita.com/negito6/items/c64a7a8589faaffcfdcf)

を組み合わせることで実装した。
上記コードを貼り付けたら、

https://script.google.com/home

![キャプチャ2.GIF](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28591/fe0bdcca-b1d0-7129-dfc9-51bf7429a552.gif)

にアクセスをして、実行ボタン「▶」を押す。
そうするとGoogleAppsScript経由でメールが送られる。

<a id="#Chapter4"></a>
 //スプレッドシートのkeyを指定して取得
  var spreadsheet = SpreadsheetApp.openById('1SRQIPPzVV2vwTeSsIpQrMt4DSuiO1P3eqGUcjrHc');
  Logger.log(spreadsheet+"の読み込みを開始しました")//Spreadsheet
  
    //これからGoogleAppsScriptでloopを開始します
    //Number(i)が整数化しています
    //iの変数がスプレッドシートの何行目までを読み込むかを設定します
    for(var i  = 447 ; i <= 596; i++){
    
      //ログに出力(整数ループができているか？)
      Logger.log(Math.round(i));
      Logger.log(Number(i));
       
      //セル(A,i)を表示します。
      var range = spreadsheet.getRange("A"+Number(i));
      //4. 値を取得する
      var value = range.getValue();
      //セル(B,i)を表示します。
      var range2 = spreadsheet.getRange("B"+Number(i));
      //4. 値を取得する
      var value2 = range2.getValue();
     //セル(B,i)を表示します。
      var range3 = spreadsheet.getRange("C"+Number(i));
     //4. 値を取得する
      var value3 = range3.getValue();
      Logger.log(value);
      Logger.log(value2);
      Logger.log(value3);
      Logger.log(value+"@gmail.comにメールを送ります（本番アドレスに送信します）");

<a id="#Chapter5"></a>
# GoogleAppsScriptには実行上限が存在するので、大規模アプリを開発する人は要確認
”【GAS】Google Apps Scriptの制限・上限まとめ【実行回数・時間・容量】”
https://monoblog.jp/archives/2349

<a id="#reference"></a>
# 参考文献
- [GoogleAppsScript屋さん](http://googleappsscript.hatenablog.com/)
- [【保存版】Google Apps Scriptリファレンス～キーワード別インデックス](https://tonari-it.com/google-apps-script-reference/)
Railsチュートリアル3章でテストがうまくいかない(Rubyのバージョンに注意)


タイトルの通りのエラーが発生し、ググってもなかなか解決しなかったので、他の人も同様の問題を抱えた際に参考にできればいいなと思ったので備忘として記事に残します。

##困ったこと
railsチュートリアル3章で``$ rails generate controller StaticPages home help``
実行後、testの中身を変えずにtestしたところ　以下のエラーが表示されテスト自体ができない

```
$rails t
/Users/kiyomasa/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/capybara-3.23.0/lib/capybara/selector/filters/node_filter.rb:9:in 
`initialize': wrong number of arguments (given 4, expected 3) (ArgumentError)
      #以下略
      
```

##結論　
Rubyのバージョンが3.0.0で行ってましたが、**Capybaraはバージョン3.31.0ではruby3.0.0では動かなくなる**（記事執筆時点）
なので　
+ capybaraのバージョンを対応したものに上げるか
+ Rubyのバージョンを下げるか　
で対応する

自分の場合、capybara公式　で最新のgemをインストールしてやってみたが現状変わらなかったため、
以下記事を参考に**Rubyのバージョンを2.7.2へ下げた**ところ、うまくいった
（他のgemfileのバージョンコンフリクトも発生しなくなった）


※質問したサイト
https://teratail.com/questions/321440　

###以降　自分で調査した内容　（見る必要はありませんが、参考に）

##wrong number of argumentsでエラーを調査

エラー内容から、推測
capybara gemで使う``node_filter.rb``
で``wrong number of arguments (given 4, expected 3)``=引数エラーが出ているらしい
と判明

???だったので調べる
https://qiita.com/TOSHIMITSU_MIYACHI/items/82417ab6126d816af4e4
どうやら

wrong number of arguments (a for b)
a＝呼び出し側の引数の数
b＝メソッド側の引数の数
があっていないということらしい。

あっていないと言われても、自分で作ったメソッドでもないし、もしかしてgemのバージョンがおかしいのか？と調査

##capybaraについて調査

元々gemfileはrailsチュートリアルから丸々コピーして使っていた（一部エラー出てバージョンを変えたりはしてみた）
https://qiita.com/morrr/items/0e24251c049180218db4

Capybara = UIテストのためのrubyフレームワーク
らしい

理解はしたけど、エラーには関係ないよな。と振り出しに戻る

###teratailから回答が...!!
terateilで質問する→回答なし→一晩考える→朝回答きていて確認

→結論の通り、

Rubyのバージョンが3.0.0、
一方**Capybaraはバージョン3.31.0ではruby3.0.0では動かなくなる**（記事執筆時点）
なので　
+ capybaraのバージョンを対応したものに上げるか
+ Rubyのバージョンを下げるか　
で対応する

ということでした。
全く考えもつかなかったので、今後は気をつけるようにしたいと思います。

###Ruby のバージョンを落とすやり方
https://qiita.com/_am_/items/c1dbeb11f40bbbac8fd9
[Unity3D]  SceneCameraに映っている位置をGameSceneに映す

SceneCameraに映っている位置をGameSceneに映す
---
1, Sceneに映っている状態でGameObject → AlignWithViewを選択する
![91067E73-F76D-468F-BED4-872799BBD245_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/3047d197-ce69-70ed-4483-9c91b44f22d4.jpeg)
![73C20DE4-B442-4A8A-B827-F3F06B766568_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/50da1cd1-ec89-fea6-58f0-23436f50ddc9.jpeg)

↓


反映される
![E655294F-4909-4613-A349-7788CDC3EFFE_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/9290f6cd-5ec5-f4c0-5be5-7164088452d2.jpeg)
○rudyとrudy on rails(rails)の違いについて○


#1. rudyとrailsとは

まず、最初にrudyとrailsについて大まかに説明すると

__・rudy : proguramming 言語__


__・rails : フレームワーク　__
（4章でお伝えしますが、アクションで変数を定義するのが一般的です）

という違いになります。
＊railsはproguramming言語ではないので注意してください。

#2. 具体的な違い

1章（1.rudyとrails）だけではあまりピンとこないと
思われる方のほうが多いと思うのでこの章では具体的な説明をしていきたいと思います。

__○rudyとは__
rudy on railsやwedアプリケーションフレームワークを
使うことができるpuroguramming言語のことを指します。
__○railsのフレームワークとは__
railsのフレームワークとはrudyで作られたシステムの事です。
rudyで作られてるならrailsの役割必要なの？って思いますよね。
答えから述べるとかなり必要です。
例えば、手で餅をついた後にパッケージしたりするのと機械で餅をついた後にパッケージしたりするのでは効率がかなり違いますよね？
これと同じようにrailsは機械と同じ役割をになっています。
__・rails=機械で効率よく行う__
と覚えておくといいかもしれません。

#3. railsについて

機械で効率よく行うと述べましたが、どういうシステムになっているのか詳しく説明していきます。
__: rails figure :__
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1093177/ded16eb7-ea61-ec28-858e-4bde576f55c2.png)


図のような流れとなっており、順番を追って説明していきます。
（クライアントからリクエストが送られてきた状態からです）
1.HTTPサーバーからリクエストを元に送る
2.リクエストを元にcontroller＆actionに誘導します
3.controllerにて要件を伝えて、modelへと伝達します（この場合、許可が降りると考えていただいても構いません）
4.5.modelからdata baseのレコードを引き出します
6.引き出したレコードはcontroller&action内にあるインスタンス変数に渡されます
7.レコードだけではブラウザーに表示できないため、viewを元にHTMLファイルを作成します
8.レコードの情報が埋め込まれたHTMLファイルを渡します
9.HTMLファイルを渡してクライアントにレスポンスします
急に単語が色々と出てきたと思うので、順番に説明していきます

__・rouding : urlのどのconttollerのどのactionで処理するか適切に判断する（対応表みたいなもの）__
__・controller : viewの中のcontrollerとactionと同じフォルダーから
同じフォルダーを探して、ブラウザーに返します__
__・view : 見た目のHTMLファイルを指します__
__・data baseとはデータを保存できる場所のことを指します__
また、databaseは下の図のような表のようになっており、このようにしてデータを管理しています。このような表のことを「テーブル」といいます。



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1093177/2d664567-de97-d10e-d34d-97d314bb1379.png)

__カラム：縦の列のこと__
__レコード：１行ずつのデータのこと（色のついてる部分を指します）__
＊豆知識として、マイグレーションファイルでテーブルの内容を変えることができるので覚えておいた方がいいです。
:example:
rails generate post column:data と書き込むとpostsテーブルのカラムとdataの変更が可能です。このときpostsを単数形にして記入する必要があります。
#4.actionで変数で定義することについて
actionを変数で定義する必要性については、HTMLのままではdata baseに接続できないためです。
__○ viewファイル内に変数を定義している場合__
<_div class="~~">　　　　　　    　　
　　＝＝＝　　　　　　　　　→   post1="===" ,post2="==="
<_/div> 
のような形となります。
erd(embedded rudy)埋め込みrudyの場合
<_% post1="===">
となり、表示の仕方は
<_%=post1%>
という形になります。
__○actionに変数を定義する場合__
変数名の後に＠をつけることでactionで定義したviewを使うことができます。
ソフトウェアの品質について

# はじめに
引き続き、研修で学んだことをアウトプットしていきます。
今回は「ソフトウェアの品質」についてです。

# 学んだこと
### 品質とは？
製品やサービスの良し・悪しのこと

求められる品質は`製品`であったり`ユーザーの期待値`によって異なる
例）製品：スポーツウェアとおしゃれ着

求められる品質はさまざまであるため、一定の基準を設けるために以下を規定

### 評価するための指標
#### 外部品質
エンドユーザーが最初に触れる部分の品質
対象：ソフトウェアのふるまい

#### 内部品質
エンドユーザーに直接影響しないが、外部品質には影響する
対象：ソースコード、仕様書、設計書など

### ソフトウェアの品質特性
#### 機能性
要求されている機能が満たせているか

`合目的性`　：機能は目的に対して適切か
`正確性`　　：期待に対して正確か
`相互運用性`：ほかのシステムとやり取りできるか
`機密性`　　：セキュリティはどうか
`標準適合性`：標準（ISOやJISなどの規格）と合っているか

#### 信頼性
障害が起こりにくいか、正しく動作し続けられるか

`成熟性`　　：障害で機能が停止しないか
`障害許容性`：障害が起きても機能を提供し続けられるか
`回復性`　　：障害が起きても戻れるか
`標準適合性`

#### 使用性
使い勝手や使いやすさ、操作性はどうか

`理解性`　　：理解しやすいか
`習得性`　　：学習しやすいか
`運用性`　　：運用しやすいか
`魅力性`　　：使ってみたくなるか
`標準適合性`

#### 効率性
与えられたリソースに対して、適切な性能を発揮しているか

`時間効率性`：適切な時間で応答するか
`資源効率性`：資源（メモリ・ハードディスクなど）適切に使用しているか
`標準適合性`


#### 保守性
できたソフトウェアの修正のしやすさはどうか

`解析性`　　：障害が発生したときに原因解析しやすいか（ログがちゃんと出ているかなど）
`変更性`　　：変更しやすいか
`安定性`　　：影響範囲が安定しているか（変更が予定外のとこに及ばないか）
`試験性`　　：テストしやすいか
`標準適合性`

#### 移植性
別の環境へ移すことになったときのやりやすさはどうか

`環境適応性`：他の環境に移しやすいか
`設置性`　　：インストールしやすいか
`共存性`　　：他のソフトウェアと共存できるか
`置換性`　　：他のソフトから置き換えられるか
`標準適合性`

### 品質特性はどこで使う？
非機能要求を見つけるために使う

##### 非機能要求とは？
機能として顧客から明確に求められてはいないが、システムとして必要そうなもの
例）機能　：OKボタンを押したら、ダイアログを開く
　　非機能：レスポンスは3秒以内でおこなう

### V字モデルとは？
開発工程とテスト工程の関係を表したもの
見比べることで「実施されるテストがどのレベルの開発内容を検証するためのテストなのか」がイメージしやすくなる

- 要求分析　⇔　受け入れテスト
- 要件定義　⇔　システムテスト
- 基本設計　⇔　結合テスト
- 詳細設計　⇔　単体テスト
- コーディング　⇔　コードレビュー

#### なぜテストをするのか
開発されたシステムが案件、仕様書通りに作成されているか、品質に問題ないかなどの確認を行うため

#### 受け入れテストとは
システム全体をユーザー視点で問題ないか検証

#### システムテストとは
システム全体を開発者視点ですべてのプログラムとハードウェアを組み合わせて検証

#### 結合テストとは
単体テストで検証したものを組み合わせて不具合がないか検証

#### 単体テストとは
メソッドなどの小さな単位で要件・機能を満たしているか検証

# まとめ
ソフトウェアの品質について細かく考えたことがなかったので、これらの知識が頭にあるのと無いのとでは開発していく際に影響してくるだろうなと感じました。意識することで、高品質なシステムにつながっていくと思うので、定期的に確認して自分の中に落とし込んでいきたいと思います。
VSCodeのRemote - Containersを使ってdocker-composeしてRailsのサーバーを立ち上げた時、なぜかサーバーが起動していない現象

## はじめに

Railsの初学者が書いています。
間違ってたり、こうした方がいいなどがあれば教えてください

僕はこれで1日を無駄にしました。
皆さんはちゃんと英語を読むようにしましょう（戒め）

## 結論

以下のように変更しましょう

```diff:/.devcontainer/docker-compose.yml
...

# Overrides default command so things don't shut down after the process ends.
- command: /bin/sh -c "while sleep 1000; do :; done"
+ command: /bin/sh -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'; while sleep 1000; do :; done"
```

## 原因

上のコメントにあるように<font color='red'>**Overrides**</font>されます。
そのため元のdocker-composeのCOMMANDが実行されません。


## 参考

[【Rails】Rails 6.0 x Docker x MySQLで環境構築](https://qiita.com/nsy_13/items/9fbc929f173984c30b5d)
[VSCode Remote Containerが良い](https://qiita.com/d0ne1s/items/d2649801c6f804019db7)
Windows初心者がPath通すのに戸惑った話　※超初心者向け

<strong>初心者向けの記事です。ご了承ください。</strong>

<h1>背景</h1>
今回初めてWindowsのパソコンを買ったので、PythonのディストリビューションであるAnacondaのインストールおよび環境構築をしました。インストールしたのはいいものの、jupyter labやnotebook、またpythonのインタプリタまでがコマンドプロンプトで起動しなかったので、どうにかして解決しましたが、初心者にこれはきついと感じたので、発信してみます。

# jupyter labが起動しない
こちらはすぐに解決したものになります。
環境構築およびインストールに際して、参考にしたサイトを示しておきます。
[ANACONDAのPATHをWINDOWSで通す話](https://sukitokuportfolio.wordpress.com/2018/11/20/anaconda%E3%81%AEpath%E3%82%92windows%E3%81%A7%E9%80%9A%E3%81%99%E8%A9%B1/)
こちらのサイトでは、環境変数のpathに、以下を追加しろとありました。

```
C:\Users\XXXX(ユーザ名)\Anaconda3\
C:\Users\XXXX(ユーザ名)\Anaconda3\Scripts\
```
とりあえずこれを追加したのはいいものの、コマンドプロンプトでjupyter labと入力しても何も起きなかったので？？？となって、確認したところ、自分でインストールしたAnaconda3のディレクトリの名前がanaconda3となっていたので、そもそも存在しないディレクトリにpathを通していました。なので、追加するべきpathはこちらでした。

```
C:\Users\XXXX(ユーザ名)\anaconda3\
C:\Users\XXXX(ユーザ名)\anaconda3\Scripts\
```
なんて初歩的...まあ気を取り直して次々と思っていたら...
# pythonどこ行った
まあとりあえずpythonのバージョンでも確認するかといって、以下のコマンドをたたいたところ、

```
$ python -V
Python
```
肝心なバージョン名が出てきません。
え？と思った私はとりあえずインタプリタを起動しようとして、pythonコマンド打ち込んだところ...
![python.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660318/f802e291-832a-3ff7-58c1-3b798a222b2f.png)
なぜかマイクロソフトのストアに飛んでpythonのインストールを促されました。MacOSしかさわってこなかったので何が何だか...
ということでpathを確認してみると...
<strong>※関係のあるpathをピックアップして抜き出しています。</strong>

```
C:\Users\XXXX(ユーザ名)\AppData\Local\Microsoft\WindowsApps
C:\Users\XXXX(ユーザ名)\anaconda3\
C:\Users\XXXX(ユーザ名)\anaconda3\Scripts\
```
それっぽいものを見つけました。どうやら打ち込んだコマンドをストア内に検索して、引っかかったらこれに飛ぶ仕組みになっているようです。
前提としてpathは上から反映されるので、機能するべきanacondaのほうのpathに行く前にストアのpathに引っかかってしまったんだと思われます。
ので、ストアのpathを一番下にもっていくとちゃんと動作しました。
改善後↓

```
C:\Users\XXXX(ユーザ名)\anaconda3\
C:\Users\XXXX(ユーザ名)\anaconda3\Scripts\
C:\Users\XXXX(ユーザ名)\AppData\Local\Microsoft\WindowsApps
```
# 感想
MacOSばかり触っていたので、Windowsでの環境構築はこれが初めてでした。初歩的なことではありますが、考えさせられました。悔しいです。これからも頑張っていこうと思います。
【blender】アニメーションの基本操作の導入(タイムライン)

# この記事でできること
- まずはblenderでanimationを操作する場所を知ることができます。

![ダウンロード (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/194721f4-ef52-07e0-a6ac-6c0d9e971898.gif)

# やり方
- 下図のように、起動直後のCubeを使用していきます。

![a01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/806a5253-b314-8419-f456-308fbaa126f6.png)

- 下図のように、「タイムライン」を表示したり、今回のアニメーションの時間を設定します。

![a02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/7ae32202-e390-a025-1dea-9b2be5d2790a.png)

- 下図のように、「オブジェクト」→「アニメーション」→「キーフレームを挿入」を選択します。

![a03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/c561d1ac-291e-7eb1-4589-7f62f4050ff1.png)

- 下図のように、「キーフレーム挿入メニュー」が表示されるので、今回は「位置」を選択します。

![a04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/78918d07-ab31-8bd5-ee8e-2366e12f259a.png)

- 下図のように、一秒の時点にキーフレームが挿入されたことがわかりました。

![a05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/e85727b0-ed7c-2dc5-3380-02bc56316e8c.png)

- 下図のように、「→│」のアイコンを選択して、タイムラインの末端へ移動します。
- ブルーレイやDVDなどのリモコン操作をしていると、同じようなアイコンがあると思います。見てみましょう。

![a06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/0b140560-2018-6496-af5d-22d2bab94f71.png)

- 下図のように、オブジェクトCubeを移動します。(移動方向は自由です)

![a07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/ec8d0487-da6b-6c11-42f6-a8a86c8f33b9.png)

- 下図のように、「」アイコンを選択すると、アニメーションが再生されます。

![a08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/7f3fb7d7-98ce-41c7-c42b-8d3089c283da.png)

![ダウンロード (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/e2aea7cf-6535-0c3a-7eeb-2ab6d2a61f3e.gif)
RaspberryPi4でUbuntu20.10を使う

#開発環境
・Raspberry Pi 4
・ノートPC (OS Imageのインストールに使用)

#準備
マイクロSDカードにOSイメージを書き出します。
私は今回、Raspberry Pi OS Imagerを使用しました。
https://www.raspberrypi.org/software/　
↑こちらのサイトからダウンロードできます。

Ubuntu Server 20.10の64bit版を選択し、ダウンロードします。
Desktop版でも良いとは思いますが、作業の際に
- モニター
- 有線マウス
- 有線キーボード
が必要になりますので、これらをお持ちでなければ、Server版をおすすめします。
ダウンロードができたら、ファイルをRaspberry Pi OS ImagerでマイクロSDカードに書き出しましょう。

#初期設定
ここでは詳しくは書きませんが、お使いの環境に合わせて、設定を進めていきます。
(ユーザー名、ログインパス、Wi-Fi等)

下記コマンドで、パッケージの更新を行います。

```
$ sudo apt update && sudo apt upgrade
```
ここでの作業は時々行うことで、OSを最新の状態に保つことができます。

```
$ sudo cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=20.10
DISTRIB_CODENAME=groovy
DISTRIB_DESCRIPTION="Ubuntu 20.10"
```
OSのバージョンを確認しておきます。
###ssh接続
作業をクライアントPCで行うために、22番ポートが開放されているか見てみます。

```
$ sudo ufw status
```
```
Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere                  
Postfix                    ALLOW       Anywhere                  
25                         ALLOW       Anywhere                  
143                        ALLOW       Anywhere                  
110                        ALLOW       Anywhere                  
OpenSSH (v6)               ALLOW       Anywhere (v6)             
Postfix (v6)               ALLOW       Anywhere (v6)             
25 (v6)                    ALLOW       Anywhere (v6)             
143 (v6)                   ALLOW       Anywhere (v6)             
110 (v6)                   ALLOW       Anywhere (v6)   
```

これは私の環境下でのufwステータスです。
OpenSSH項目がALLOWとなっていれば大丈夫です。

新たにポートを開放したい時は

```
$ sudo ufw allow '任意のポート番号'
$ sudo ufw reload
$ sudo ufw status
```
この操作を行います。

実際にクライアントPCからssh接続する時は

```
$ ssh 'ユーザー名'@'IPアドレス'
```
とします

#まとめ
今回はマイクロSDカードにUbuntu20.10をインストールしするところから、
ssh接続を通すところまでを行いました。
使い慣れたPCで快適なコーディングライフを過ごしましょう。
PythonでTypoglycemiaを作る

PythonでTypoglycemiaを作ってみた。

#Typoglycemiaとは
Typoglycemiaとは文章中の単語で、最初と最後の文字以外が入れ替わっていても文章が読めてしまう現象です。多分、例を見たらわかるので、以下を読んでみてください。

```
こんちには みさなん おんげき ですか？　わしたは げんき です。
この ぶんょしう は いりぎす の ケブンッリジ だがいく の けゅきんう の けっか
にんんげ は もじ を にしんき する とき その さしいょ と さいご の もさじえ あいてっれば
じばんゅん は めくちちゃゃ でも ちんゃと よめる という けゅきんう に もづいとて
わざと もじの じんばゅん を いかれえて あまりす。
どでうす？　ちんゃと よゃちめう でしょ？
ちんゃと よためら はのんう よしろく
```
どうですか？ちゃんと読めてしまいますよね。
2ちゃんねるに投稿されたコピペで、実際にケンブリッジ大学で研究が行われた訳ではないみたいです。

#Pythonで文字を入れ替えてみる
前後の文字だけを残して中身の文字順を変えるのは簡単にできます。
例えば、Helloという単語の場合、先頭と後方の単語をそれぞれ、HeaderとFooterとして固定します。
さらに内側のellをBodyとして、このBodyの語順を入れ替えればTypoglycemiaになります。
![Group.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1083406/1da6d767-9f2c-06cb-c386-d13b4b2bf49f.png)

プログラムでは文字に先頭から番号をふり、文字と番号を結び付けその番号の順番をランダムに変えることで文字順を入れ替えています。この場合、入れ替えが起こるのは1,2,3番の文字だけで、先頭の0番と後方の4番は入れ替えが起こらないように固定するようにします。
![Group 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1083406/71f2bf93-298b-c413-576d-07203e0b018d.png)

Pythonで以上の仕組みを再現します。

```python:shuffle.py
import random

def shuffle(input_word):

    input_word_length = len(input_word)
    body = ""

    header = str(input_word[0])
    footer = str(input_word[input_word_length-1])

    body_num = list(range(1,input_word_length-1))
    random.shuffle(body_num)

    old_word = ""

    if input_word_length == 1:
        return input_word

    if input_word_length == 4:
        body = input_word[2] + input_word[1]
        shuffled_word = header + body + footer
        return shuffled_word

    for num_selector in range(0,input_word_length-2):
        body = old_word + input_word[body_num[num_selector]]
        old_word = body

    shuffled_word = header + body + footer

    return shuffled_word

input = input()

print("---> " + shuffle(input))
```

Helloと入力すると意図した動作をしてくれます。

```
Hello
---> Hlelo
```

これだと1単語しか変換できないので、スペースで区切られた文章を変換できるようにします。
PythonではString型の変数にsplit関数が用意されており、スペースで区切られた文章を単語に区切り、listにしてくれます。便利ですね！
![Group 4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1083406/148f405a-a238-4fa1-326e-e77bc875ca9d.png)
以下のようにlistを作り1単語ごとshuffle関数に入れることで入れ替えた文章を作ります。

```python:make_typoglycemia.py

def make_typoglycemia(input_sentence):

    if input_sentence == "":
        typoglycemia = ""
        return typoglycemia

    word_split_list = input_sentence.split()
    old_word = ""

    for word_selector in range(len(word_split_list)):
            word_split_list[word_selector] = shuffle(word_split_list[word_selector])

            typoglycemia = old_word + word_split_list[word_selector]
            old_word = typoglycemia + " "

    return typoglycemia
```

#GUIアプリケーションにする

これを元にGUIアプリケーションを作りました。日本語入力モードだと挙動が不安定な部分もありますが良かったら見てください！(漢字ひらがな変換にpykakasi、GUI構築にtkinterを使ったので実行する際はインストールしてください。)
<a href="https://github.com/rennn2002/typoglycemia"><img src="https://github-link-card.s3.ap-northeast-1.amazonaws.com/rennn2002/typoglycemia.png" width="460px"></a>
![Screen-Recording-2021-02-10-at-1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1083406/e6e96a19-c864-bd7b-3a03-a21943c11f13.gif)

PythonでGUIを作るのに意外とハマったところが多かったので記事にするかもです。
openCVとKotlinを使った塗り絵アプリ#2

#はじめに
[前回の記事](https://qiita.com/syma_joho/items/d16abacdf34866552f56)
前回は環境の導入方法とデザインの表示について書きました。
今回は実際にopenCVを使ってみて苦労した点を書いていこうと思います。
画像はペイントで適当に作ったもので大丈夫です。

必要になる引数の型はリファレンスで確認しながら作業しました。
[openCVリファレンス](https://docs.opencv.org/4.5.0/pages.html)

#塗りつぶし
openCVではfloodFillという関数で色を塗ることができます。
はじめはfindcontoursという関数を使って線の輪郭を抽出してその輪郭の範囲内を
floodFillで色を塗るという考えでした。

```kotlin:MainActivity.kt

//drawableに格納した画像を変数に入れる
var bitmap: Bitmap= BitmapFactory.decodeResource(resources, R.drawable.画像ファイル名)
//画像を行列の状態に変換(詳しい仕組みは理解できていません。)
var mat: Mat = Mat.zeros(bitmap.height,bitmap.widht, CV_8UC1)
var list: MutableList<MatOfPoint> = ArrayList()

//輪郭抽出
findContours(mat, list, mat(), 0, 0)

//指定した座標から抽出された輪郭までを指定の色で塗りつぶす
floodFill(mat, mat, Point(x,y), Color(R,G,B))
```

これだけだとエラーが起きました。

画像処理するにはまず２値化という処理をしないといけないらしい。
（２値化というのは画像を白か黒でしか表現できない形にすること。）
２値化処理はcvtColorというものが使えるので追記します。

```kotlin:MainActivity.kt

//drawableに格納した画像を変数に入れる
var bitmap: Bitmap = BitmapFactory.decodeResource(resources, R.drawable.画像ファイル名)

//画像を行列の状態に変換(詳しい仕組みは理解できていません。)
var mat: Mat = Mat.zeros(bitmap.height,bitmap.widht, CV_8UC1)

//輪郭抽出した階層を保存しているらしい
var list: MutableList<MatOfPoint> = ArrayList()

//Mat型でしか変換できない為型変換処理
bitmapToMat(bitmap, mat)

//２値化処理（グレースケール変換）
cvtColor(mat, mat, COLOR_BGR2GRAY)

//輪郭抽出
findContours(mat, list, mat(), 0, 0)

//指定した座標から抽出された輪郭までを指定の色で塗りつぶす
floodFill(mat, mat, Point(x,y), Color(R,G,B))
```

これで2値化の状態で塗りつぶすことができます。
これでは塗り絵にならないので色情報を追加しなければいけないのでこれも追記します。

```kotlin:MainActivity.kt

//drawableに格納した画像を変数に入れる
var bitmap: Bitmap = BitmapFactory.decodeResource(resources, R.drawable.画像ファイル名)

//画像を行列の状態に変換(詳しい仕組みは理解できていません。)
var mat: Mat = Mat.zeros(bitmap.height,bitmap.widht, CV_8UC1)

//輪郭抽出した階層を保存しているらしい
var list: MutableList<MatOfPoint> = ArrayList()

//Mat型でしか変換できない為型変換処理
bitmapToMat(bitmap, mat)

//２値化処理（グレースケール変換）
cvtColor(mat, mat, COLOR_BGR2GRAY)

//色情報を戻す
cvtColor(mat, mat, COLOR_GRAY2BGR)

//輪郭抽出
findContours(mat, list, mat(), 0, 0)

//指定した座標から抽出された輪郭までを指定の色で塗りつぶす
floodFill(mat, mat, Point(x,y), Color(R,G,B))
```

これでRGB指定で色を塗れるようになりました。

これでは一か所にしか色を塗ることができません。
次回は複数個所に塗れるようにしていこうと思います。

#さいごに
開発してる際に便利だと思ったものを紹介しようと思います。
xmlで定義したIDを使おうとすると必要になる「findViewById」
こいつが省略できるみたいです。

1.Gradle Scripts 内の bulid.gradle(拡張子が.app)に一番下の行に下記のコードをコピペ
[apply plugin: 'kotlin-android-extensions']
2.プロジェクトと同期が必要になるので画面上側に出てくる[Sync Now]をクリック
3.使いたいソースファイルに下記コードをコピペ
[import kotlinx.android.synthetic.main.activity_main.*]
【Java】オブジェクトリスト (Collection) のプロパティ存在チェック

# オブジェクトリストのプロパティの値をチェックしたい
・毎回 For とかで回すのがめんどい
・汎用的に使えるようにジェネリクスを利用
・static にして jstl (jsp) でも手軽に使えるように

## チェック用関数
なんちゃらUtilsなどのクラスに作成（下記では ThisUtils）
・T1: リストに入ってるオブジェクトのクラス
・methodName: オブジェクトの値を取り出すためのメソッド名（例: getValue）
・T2 val: リストに入ってるオブジェクトの値をチェックするためのオブジェクト （例：getValue と比較する値）

```java
	@SuppressWarnings("unchecked")
	public static <T1,T2> boolean isCollectionPropertyContains(Collection<T1> list,
			String methodName, T2 val) {

		Logger logger = LoggerFactory.getLogger(ThisUtils.class);
		if (list == null || list.isEmpty()) { return false; }
		for (T1 t: list) {
			Method method = null;
			try {
				method = t.getClass().getMethod(methodName);
				T2 prop = (T2) method.invoke(t);
				if (val == null) {
					if (prop == null) { return true; }
				}
				else if (val.equals(prop)) {
					return true;
				}
			}
			catch (Exception e) {
				StringWriter sw = new StringWriter();
				e.printStackTrace(new PrintWriter(sw));
				logger.error(sw.toString());
				return false;
			}
		}
		return false;
	}
```

## 使用例
##### 宝くじのリストがあり、番号が合っているかのチェックがしたい
・List&lt;Lottery&gt; kujiList    ： くじのリスト
・public String Lottery.getNumber()   : Lottery の番号取得メソッド
・String winNumber          : 当選番号 

```java
boolean result = ThisUtils.isCollectionPropertyContains(kujiList, "getNumber", winNumber);
```


以上、お疲れさまでした！
herokuにデプロイしたコードの修復

###アプリ開発の際、gitに保存するのを忘れて上書きしてしまったコードの修復方法
herokuを用いたアプリ開発の時の対処法

####herokuの過去バージョンへの戻し方
herokuアプリにて現在のバージョン、そして戻したいバージョンをメモっておく
(v〇〇)表記

ターミナル操作

```
heroku rollback v〇〇
```

これを行うことでherokuのバージョンを前のものに戻すことができます。

取得したいバージョンにしたのち、

```
heroku git:clone -a アプリ名
```

にてローカル上にcloneしましょう。

これにて上書きしてしまいなくなってしまったコードが復元できます。嬉

#gitコミットは定期的に!!
mac book proのキーボード、トラックパッドセットアップのログ(Big Sur)

新しくMacをセットアップするときに、キーボード、トラックパッドの細かいところをいつも忘れてしまうのでメモ。

### キーボードが絡むソフトウェアインストール
- [homebrewの導入](https://brew.sh/)
- homebrewから一連のソフトウェア導入（キーボードの設定が絡むもの）

```
$ brew install iterm2 google-japanese-ime karabiner-elements alfred usb-overdrive
```

※ usb-overdriveはBig Surのベータ版がとれる前は[サイト](https://www.usboverdrive.com/)から直接DL

### キーボード関連の設定
Caps lockを殺して、ここにCommandボタンを持ってくると腱鞘炎になりにくいのでKarabiner Elementsを使う。ところが日本語<->英語の入力切り替えやiTerm2でのコピペなどの起動で問題が出てくるので、そこも調整していく

- Karabiner Elements
    - CapsLock <-> Commandの交換
- [入力ソースをCommand+Spaceで切り替えられるようにする](https://saketorock.com/mac-command-space/)
- [iTerm2だけでCommandをCtrlに変更する設定](https://apple.stackexchange.com/questions/388692/in-iterm2-map-the-left-command-key-to-the-left-control-key-map-commandtab)
- [usb-overdriveのミドルボタンスクロールの設定](https://superuser.com/questions/189122/middle-click-using-ibm-lenovo-keyboard-with-trackpoint-to-scroll-on-mac-os-x)
    - USB接続でThinkpadのキーボードを使うため、Middle Buttonでホールドした状態でスクロールをenableしたい
    - Middle Button -> Move To Scrollに設定

ついでに[Google日本語入力も設定](https://qiita.com/normalsalt/items/017031713f6577e488aa)

### TrackPad関係の設定
- [ダブルタップでドラッグする](https://www.radia.jp/archives/810)
- システム環境設定 -> トラックパッドからの設定
    - 「スクロールの方向：ナチュラル」のチェックをオフ
    - 「ページ間をスワイプ」を３本指に設定
Lightsail｜WordPress｜テーマがアップできない削除できない

AWS-Lightsail-WordPress（bitnami）のトラブルシューティングです。

# ケース
* LightsailでWordPressを１つ立ち上げました
* 同じインスタンス内の`apps`ディレクトリへ新規ディレクトリを作成し、その中に別のWordPressを手動で入れました（以下、別のWordPressを「WP-β」と表します）
* データベースへの接続も完了し、WP-βへは正常にログインできる状態です

# トラブル：テーマがアップロードできない

テーマをアップしようとした際に、下記の表示がされました（FTPの認証情報の入力がもとめられる表示。たぶん、画像・メディアなどのファイルもアップロードできない状態）

> **接続情報**
> 要求されたアクションを実行するには、WordPress が Web サーバーにアクセスする必要があります。 次に進むには FTP の認証情報を入力してください。 認証情報が思い出せない場合は、ホスティング担当者に問い合わせてください。

ググると、下記の記事を発見

[WordPressでアップデートやインポートをしようとしたらFTPパスワードを聞かれちゃう件の対処](https://dacelo.space/wordpress/entry-1242.html)
[【CentOS】wordpressでFTPを聞かれないようにする](https://hacknote.jp/archives/37775/)

他にも同様の記事がありましたが、共通事項は`wp-config.php`へ一行を追加すること

```php:wp-config.php
define('FS_METHOD', 'direct');  // ←追加

/** Absolute path to the WordPress directory. */
if ( ! defined( 'ABSPATH' ) ) {
	define( 'ABSPATH', __DIR__ . '/' );
}
```

※`/** Absolute path to the WordPress directory. */`より上に追加する必要があります

※更新後は、一度WordPressからログアウト／再ログインしてください（ブラウザのリフレッシュもした方がいいかも）

これでFTP情報の入力は求められないかと。

なお、Lightsail-WordPress（bitnami）の`wp-config.php`にも同じ記述がありますので、この対応は妥当かと思います。

【/opt/bitnami/apps/wordpress/htdocs/wp-config.php】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283603/519d980b-d201-31e2-b5f7-27b8f92b7fa5.png)

---

しかし、これだけでは解決せず...

# トラブル：パーミッション問題

> この親ディレクトリのアクセス権はサーバーによる書き込みを許可していますか ?

次に、この表示がされました。パーミッションの問題ですね。
そこで、パーミッションを**Lightsail-WordPress（bitnami）のもの**（`/opt/bitnami/apps/wordpress/htdocs`）を参考にし、同じ状態にしました。

## 理想形：Lightsail-WordPress（bitnami）のパーミッション

【↓理想形】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283603/2e23f300-863c-0a1b-6346-2ebc7226e09e.png)

* 所有者：グループは`bitnami:daemon`
* ディレクトリは`775`
* ファイルは`664`
* ただし、`wp-config.php`だけは`640`

## 現状（変更前）の確認

【↓現状・変更前】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283603/6d03c7c8-e476-32a5-8142-4be66f35cf94.png)

* ユーザー名`bitnami`でWordPressを手動アップ＆解答した状態
* 所有者：グループが`bitnami:bitnami`になっている
* ディレクトリは`755`になっている
* ファイルは`644`になっている

## すること

* グループを総じて`daemon`へ変更
* ディレクトリおよびファイルへグループの書き込み権限を付与する
* ただし、`wp-config.php`だけは`640`にする

## 手順

インスタンスへSSH接続し、ターミナルからパーミッションを変更します。

なお下記は、WP-βのファイル一式がディレクトリ`WordPress`に入っているとして、記載します。ディレクトリ`WordPress`は、各環境に応じて書き換えてください。

### 1）グループの変更
```terminal:terminal
$ sudo chown -R bitnami:daemon wordpress
```

ディレクトリ`wordpress`に対して、オプション`-R`で再帰的に（つまり`wordpress`内の全てのディレクトリとファイルに対して）`chown`を実行

`bitnami:daemon`は`所有者：グループ`

### 2)ディレクトリのパーミッション変更
```terminal:terminal
＄ sudo find wordpress -type d -exec chmod 0775 \{\} \;
```

ディレクトリ`wordpress`から、`find -type d`コマンドでディレクトリを探し出して、パーミッション変更を実行

`find`コマンドの使い方やオプションについては【参考サイト：[find コマンド](https://hydrocul.github.io/wiki/commands/find.html)】をご参照ください

### 3)ファイルのパーミッション変更
```terminal:terminal
＄ sudo find wordpress -type f -exec chmod 0664 \{\} \;
```

同じく`find`コマンド。`-type f`でファイルを指定して実行

### 4)wp-config.phpだけ640
```terminal:terminal
$ sudo chmod 0640 wordpress/wp-config.php
```

※この後で、一度WordPressからログアウト／再ログインしてください（ブラウザのリフレッシュもした方がいいかも）

これで私は「この親ディレクトリのアクセス権はサーバーによる書き込みを許可していますか?」の表示がでなくなりました（問題なくテーマのアップロードもできています）
ポリモーフィズムって何？


# はじめに
現在、Rubyと並行してJavaの学習を行っています。
その中で、ポリモーフィズムという言葉がでてきたので学んだことを備忘録として残したいと思います。

# ポリモーフィズムとは

日本語では「多様性」という意味です。
１つの名前の複数のメソッドを対象に応じて定義できることなのです。

現状の私の知識では、「オーバーロード」「オーバーライド」の２点を学びましたので、
説明していきます。


## オーバーロードとは
同一のクラス内で同一名の複数のメソッドを定義すること。
区別の仕方は、メソッドの引数や、戻り値の型の違いで区別する。

下記のコードですが、同じクラス内に同名のメソッドがありますよね？
しかし、メソッドに引数があるかないかで呼び出すメソッドを区別しています。

```java
class Parent{
//メソッド
 void sample(){
     System.out.println("parent");
 }
// オーバーロードされたメソッド
 void sample(String s){
     System.out.println("sample:" + s);
 }
}
```

## オーバーライド
子クラスに親クラスと同一のメソッドを定義することです。
挙動として、子クラス内に王手同一のメソッドがオーバーライドされたメソッドによって処理が置き換えられる。

```java
//親クラス
class Parent{
//メソッド
 void sample(){
     System.out.println("parent");
 }
// オーバーロードされたメソッド
 void sample(String s){
     System.out.println("sample:" + s);
 }
}

//子クラス
class Child extends Prarent {
  //オーバーライドされたメソッド
  void method(){
    System.out.println("child");
  }
}
```

# さいごに
コードを書く時に、何気に行っている作業にも名前がついていて、それを理解することでより理解が深まることを実感しました。
ここまで読んでいただきありがとうございました！
vue.jsやNuxt.jsでcsvダウンロード機能を実装する方法

バックエンド側から取得しておいたデータをフロントの管理画面で表示していて、そのデータをcsvにして吐き出す機能を実装したいときがあります。
こんなときはわざわざバックエンドにまたリクエストかけるのではなく、vue.js上で受け取ったjsonデータをいじってcsvにしたほうが効率的です。

# vue.jsやNuxt.jsでcsvダウンロード機能を実装する方法


とりあえずライブラリに頼ります。
https://www.npmjs.com/package/vue-json-to-csv

```:npm
npm i vue-json-to-csv
```

```:yarn
yarn add vue-json-to-csv
```

```vue:vue.js
<template>
  <VueJsonToCsv :json-data="csvData" :csv-title="csvファイルのタイトル" :labels="labels">
    <v-btn @click="download">
      csvダウンロード
    </v-btn>
  </VueJsonToCsv>
</template>

<script>
import Vue from 'vue';
import VueJsonToCsv from "vue-json-to-csv";

export default {
  components: {
    VueJsonToCsv,
  },

  data() {
    return {
      csvData: [],
　　　 //labelsはcsvの各データのラベルを決められます。
      labels: {
        id: { title: "ID" },
        url: { title: "URL" },
        name: { title: "購入者" },
        purchaseDate: { title: "申込購入日" },
      },
    }
  },

  methods: {
    download() {
      // date型とか変換したいときはこのタイミングで変換
      this.jsonData.forEach((data) => {
        this.csvData.push({
          id: data.id,
          url: data.url,
          purchaseDate: data.purchaseDate,
        });
      });
    }
  }
}

```

たったこれだけです。

こんな感じでaxiosとかで取得したデータを整えてcsvダウンロード可能です。
初めてのRuby on rails 開発: Scaffold編 [Memo for neko]

まだ慣れていないと、作っている途中で開発の流れが分からなくてなってしまうこともあるかと思います。
そのためのメモです。

開発環境：
・Mac book Pro (Retina, 13-inch)
・mac OS Big Sur バージョン11.2
・Ruby: ruby 2.6.3p62
・RubyGems: ---
・Rails: Rails 6.1.2

まとめ：
1.2.3. Rails 新規作成ー＞ rails new 名前　
4.Scaffoldの作成ー＞ rails g scaffold モデル名　カラム名：データ型
5.ルート確認 ー＞ rails routes
6.サーバー起動 ー＞ rails s
7.確認
* [補足](#補足) (エラー関係と対処)


<h4>1.PC内にディレクトリ（フォルダ）を新規作成</h4>
```terminal.rails_lesson例
mkdir rails_lesson
cd rails_lesson
```

<h4>2.Railsのアプリ新規作成</h4>

例えばBlogアプリなら、

```terminal.blog_app例
rails new blog_app
```

<h4>3.作成したRailsアプリのディレクトリへの移動</h4>

```terminal.Blog例
cd blog_app
```
<h4>4.Scaffold作成</h4>
例）rails g scaffold モデル名　カラム名１：データ型１　カラム名２：データ型２

```terminal.blog_app例
rails g scaffold Blog title:string body:text
rails db:migrate
```

モデルに, titleというstirng型のカラムとbodyというtext型のカラムを作成．
（db:migrateは、データ反映のため，しなくても良いかもだけど・・・念のため）

参考画面：
![rails_scaffold.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69607/2a4f9c96-0cce-0737-7d88-da3109648558.png)


<h4>5.ルートを確認</h4>

```terminal.Blog例
rails routes
```
参考画面：
![rails_routes.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69607/1a9144bc-e5a4-6725-adde-ac4dd6e1f1db.png)


<h4>6.サーバー起動！</h4>

```terminal.Blog例
rails s
```

<h4>7.ローカルサーバーで動いているか確認</h4>
<p>7-1 パソコンのお好きなブラウザ（Chromeなど）でRuby on rails が動作しているか確認．</p>

```
localhost:3000
```

参考画面：
![done.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69607/0c944caf-9327-a938-3624-fbb0596f7ab2.png)

<p>7-2 Ruby on rails で先ほど作ったBlogが動作しているか確認．</p>

```PC
localhost:3000/blogs
```

参考画面 1：
![blogs.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69607/93f46dae-34b8-2827-cb88-03bd7545a7f4.png)

参考画面 2：
![Screen Shot 2021-02-10 at 14.07.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69607/23fcc1ee-eb27-1016-58b1-411a530f7b36.png)

完成（パチパチ，　お疲れ様でした．）

## 補足　
（エラー関係の対処）

- 「Yarn not installed.」と出た際は，以下のコマンドでインストールしましょう！

```terminal
npm install --global yarn
```

- 「webpacker:install Error...」と出た際は，以下のコマンドでインストールしましょう！

```terminal
rails webpacker:install
```
競馬AI〜タイムと着差をスクレイピング〜


### タイムと着差がスクレイピング出来てない。。。
前回、競馬AIを作りたくてnetkeiba.com様からスクレイピングさせてもらいました。その時のデータがこんな感じです。
![スクリーンショット 2021-02-10 11.03.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/978166/a0b69bce-451b-b938-18c3-0b291c0e03de.png)

**タイムがない。。。！！！**
順位であるrankを予測したいので一応これでも予測出来るのですが、やはり競馬において走破タイムは大事になってきます。有名なものだと走破タイムから計算した**西田式スピード指数**というものがあります。これは以下の式で表されます。

```math
西田式スピード指数=( 基準タイム － 走破タイム ) × 距離指数 ＋ 馬場指数 ＋ （斤量－５５) × ２ ＋ ８０
```

詳しい解説は[こちら]が参考になりました。
[こちら]:https://team-d.club/about-speed-index/
計算は置いておいて、とにかく走破タイムをスクレイピングしないと始まらない。
### 環境
Google Colab
### 走破タイムをスクレイピング
netkeiba.com様からスクレイピングします。
![スクリーンショット 2021-02-10 11.24.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/978166/8dbaeecf-e841-090c-050a-6b866cfabbf7.png)
こちらの**タイム**と**着差**の列をスクレイピングしていきます。
スクレイピングの流れは
**1 requestsでhtmlを取得**
**2 BeautifulSoupでほしい要素を（タイムと着差）取得**
これをレースIDごとにfor文を回して取得するだけです。レースIDは前回スクレイピングしてきたcsvファイルのUnnamed:0の下２桁を除いた番号です。

requestsを使って、URLにアクセスするのですが上記のような結果ページのURLは
https://race.netkeiba.com/race/result.html?race_id=レースID&rf=race_list
となっています。レースIDの部分をfor文で回しながらタイムと着差を取得していきます。
ほしい要素は右クリック→検証で見ることが出来ます。
![スクリーンショット 2021-02-10 14.01.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/978166/719ba7fb-ebc9-30e3-f4ad-a14ad2107eda.png)
するとspanタグのRaceTimeクラスに格納されていることが分かります。
全体のコードは以下のとおりです。

```python
import requests
from bs4 import BeautifulSoup
import time

df_time_tyakusa = pd.DataFrame()
id=keiba_data["race_num"].unique().astype("str")
for h in id:
  time.sleep(1)
  url = "https://race.netkeiba.com/race/result.html?race_id=" + h + "&rf=race_list"
  urls = requests.get(url) #URLを取得
  soup = BeautifulSoup(urls.content, "html.parser") #htmlを解析する
  racetime = soup.find_all("span",class_="RaceTime") #spanタグのRaceTimeクラスにタイムと着差がある。
  for i in racetime:
    texts = i.text #テキストにする。
    s = pd.Series(texts)#Seriesにする。
    df_time_tyakusa=df_time_tyakusa.append(s,ignore_index=True) #DataFrameに追加する。
```

結果は以下のとおりです。(コードが非効率なせいか2015~2018年のデータだけでも３時間くらいかかりました。)
<img width="200" alt="スクリーンショット 2021-02-10 13.56.38.png" src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/978166/f8b8b572-81a4-8c88-4116-f5a3ad7acd72.png>

偶数行にタイム、奇数行に着差が入ったSeriesが取得できるので、それらを分けてもともとのkeiba_dataに結合します。

```python
df_time_tyakusa.columns=["time","tyakusa"] #カラム名を命名

tyakusa=df_time_tyakusa[1::2].reset_index(drop=True) #奇数行を取得

time=df_time_tyakusa[::2].reset_index(drop=True) #偶数行を取得

time_tyakusa=pd.concat([time,tyakusa],axis=1) #タイムと着差を結合

keiba_data = pd.concat([keiba_data,time_tyakusa],axis=1)#もとのデータに結合
```

結合後はこんな感じです。
<img width="700" alt="スクリーンショット 2021-02-10 13.53.46.png" src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/978166/b0329d7b-a497-e9f5-f7e5-2d81389fe58a.png>
ちゃんと結合できてますね。
着差についてはクビとか鼻を何秒とかに直したほうが良さそうですね。クビの着差ってコンマ何秒とかだと思いますが、秒に直してタイムと足すことで本当の走破タイムを計算できます。
タイムについてもそのまま使うとリークを起こすので、時系列でソートして過去のデータを使うなどの工夫が必要です。
これらを使って、競馬AIをグレードアップしてみます。
最後までご覧いただきありがとうございました。
React Native + expoでチェックボックスを実装してみた

##React Nativeでチェックボックスを実装してみた
現在、React Natie + expoでiOSでもAndroidでも動作するチェックボックスを実装したいと考えています。

そこで情報収集をしたので、まとめておこうと思います。

##expoのCheckBoxは利用できない
検索した結果、まずはじめにExpoのCheckBoxがヒットしたので、調べて見ると、どうもiOSで動作しないとのこと。

[参考：Expo Docs](https://docs.expo.io/versions/latest/sdk/checkbox/)

##他のUIライブラリを検討することに
expoを利用できなかったので、他のUIライブラリを利用することとしました。

調査したUIライブラリ
・React Native Paper
・React Native Elements

####React Native Paperのチェックボックス

[公式Doc](https://callstack.github.io/react-native-paper/checkbox.html)

####React Native Elementsのチェックボックス
[公式Doc](https://reactnativeelements.com/docs/checkbox/)

各サイト等を確認した結果、UI・利用用途として今回はReact Native Elementsの方が合っていましたので、React Native Elementsで実装していこうと思います。

##React Native Elementsの実装
####STEP1:インストール

```
npm install react-native-elements
```

####STEP2:チェックボックスを利用するjsxでimport

```react:〇〇.jsx
import { CheckBox } from 'react-native-elements'
```

####STEP3:CheckBoxを実装

```react:〇〇.jsx
import { CheckBox } from 'react-native-elements'

export default function App() {
  return (
    <CheckBox
      title='Click Here'
    />
  )
}
```

####STEP4:CheckBoxの状態をセットする変数を宣言、その変数を元に状態を表示

```react:〇〇.jsx
import { CheckBox } from 'react-native-elements'

export default function App() {
  const [checked, setCheck] = useState(false);

  return (
    <CheckBox
      title='Click Here'
      checked={state.checked}
    />
  )
}
```

ここで確認!
シュミレーターでiOS、Android共にチェックがついた(true)の状態でチェックボックスが表示されているはずです!

※タップ動作の設定はしていないので、タップしても動作はしません

####STEP5:動作を設定する
onPressを用いて動作を設定します

```react:〇〇.jsx
import { CheckBox } from 'react-native-elements'

export default function App() {
  const [checked, setCheck] = useState(false);

  return (
    <CheckBox
      title='Click Here'
      checked={state.checked}
      onPress={() => setCheck(!checked)}
    />
  )
}
```

完成!
これで動作するはずです!
checkdにtrue or falseが代入されていますので、それを利用します。
deviceを導入する順序

#deviseとは？
deviseとはユーザー登録が簡単に実装できるGemです。こちらをインストールすることでよくアプリなどで見る【ログイン、ログアウト】の画面を簡単に作ることができます。また、新規登録に必要な要素も名前やメールアドレス、ニックネーム、会社名など自分が設定したい要素を付け加えることもあっという間にできます。
今回はそのdeviseを自身のアプリケーションへ導入する方法について書きたいと思います！

##導入の順序
1,Gemを導入する
　　Gemfileに記述し、bundle installを実行します。

```ruby:Gemfile
#1番下に記述
.
.
.
.
.
gem 'devise'
```
```terminal:ターミナル
Gemをインストールする
%　bundle install
```
2,deviseをインストール
　　bundle installを実行するだけでは、まだdeviseを使うことができません。
　　ターミナルを使い、deviseをインストールし、
　　アプリケーション内で使用できるようにしましょう。

```terminal:ターミナル
deviseをインストール
% rails g devise:install
```
3,モデルを作成する
　　rails g devise:モデル名 という特別なコマンドを実行します。
　　deviseを紐ずけたモデルの生成には特別なコマンドを実行する必要があり、
　　この時、「マイグレーションファイル」と「ルーティング」も自動に作られます。
　　そのため、rails db:createなどのファイルを作るためのコマンドは必要ありません。
　　要注意ですね！

```terminal:ターミナル
deviseのモデルを作る(モデル名はTitleとします)
% rails g devise title
```
4,テーブルを作成する
　　モデルを作った際に自動で作られたマイグレーションファイルへ
　　必要なテーブルやカラム名を追加します。
   　　カラムの追加や削除については[こちら](https://qiita.com/ITmanbow/items/2bf4dfa4d9ca705b97df)の記事で詳しく紹介されています。
　　記述が終わったら、rails db:migrateでテーブルにマイグレーションしていきましょう。

```terminal:ターミナル
必要なカラムやテーブルの作成が終わったら、マイグレーションする
% rails db:migrate
```
5,ビューを作成する
　　モデルの作成同様、rails g devise:veiws という特別なコマンドで作成します。
　　devise機能を使うためのビューが複数自動に作成されるのでとてもありがたいです！
　　新規登録をregistrations、ログインをsessionsと表記してビューが作成されます。

```terminal:ターミナル
deviseのビューを作る
% rails g devise:views
```
#最後に
これで自分のアプリケーション内にdeviseを導入することができました。
まだまだ初心者の私の記事ですが、誰かの役に立てたら嬉しいです。
他にいいコマンドなどありましたら教えてください。

#参考させていただいた記事
[マークダウン記法について](https://qiita.com/Qiita/items/c686397e4a0f4f11683d)
[マークダウンのメリット、デメリット](https://tech-camp.in/note/technology/84353/)
JSONパースするのにKotshiを使ってみた

##何故今回Kotshiを使うのか
KotlinでJsonパースするのにGSONを以外のライブラリを検索してみると
JacksonとMoshiを見つけました。
その上で[ベンチマーク](https://www.ericdecanini.com/2020/10/13/benchmarking-gson-vs-jackson-vs-moshi-2020/)を見るとJackson or Moshiが良さそうでした。
さらにMoshiについて調べているとMoshiよりも早い(らしい？)Kotshiを見つけたため
JackSonと同じぐらいのMoshiよりも早いならより良いだろうとKotshiを使うことにしました。

##環境
Android Studio 4.1.1
kotlin 1.4.21
kotshi 2.2.3
moshi 1.9.3

##Gradleを使って必要なものを準備
 gradle(:app)に以下を追加

    plugins {
            (略)
       // 以下追記
       id ‘kotlin-kapt’
    }

    android {
            (略)
       // 以下追記
       kapt {
           generateStubs = true
       }
    }

    dependencies{
            (略)
       // 以下追記
      // Moshi
      implementation(“com.squareup.moshi:moshi:1.9.3”)
      implementation(“com.squareup.moshi:moshi-kotlin:1.9.3")

      //Kotshi
      implementation “se.ansman.kotshi:api:2.2.3”
      kapt “se.ansman.kotshi:compiler:2.2.3"
    }
上記を追加したらSync Now　or File>Sync Projects...をクリック

## DataClassの作成
クラスにアノテーション「JsonSerializable」を付ける。
Jsonの項目名と違う変数名を実装するときは
アノテーション「Json( name =“”)」
を付けることで紐つけができる

    import se.ansman.kotshi.JsonSerializable

    @JsonSerializable
    data class HogeData(
        val hoge: Long,
        @Json( name =“fugeId”)
        val fuge: Int
    )


##KotshiJsonAdapterFactoryを作成
JsonAapterFactory生成クラスを作成

HogeAdapterFactory.kt *名前はなんでも良い

    import com.squareup.moshi.JsonAdapter
    import se.ansman.kotshi.KotshiJsonAdapterFactory

    @KotshiJsonAdapterFactory
    abstract class HogeAdapterFactory :JsonAdapter.Factory {
    }
上の状態まで記述したら一度ビルドをする

    import com.squareup.moshi.JsonAdapter
    import se.ansman.kotshi.KotshiJsonAdapterFactory

    @KotshiJsonAdapterFactory
    abstract class HogeAdapterFactory :JsonAdapter.Factory {
        companion object{
            val INSTNCE : HogeAdapterFactory = KotshiHogeAdapterFactory
        }
    }
上記の記述をした状態でビルドが通ればOK

##使い方
    val builder =Moshi.Builder().add(HogeAdapterFactory.INSTANCE).build()

    // not List
    val adaper = builder.adapter<HogeData>(dataType)

    //Jsonからデータクラスに変換 Strig or JsonReader　or BufferedSourceをfromJsonに渡す
    val hoge = adapter.fromJson(JSON)

    //データからJsonに変換
    val Jsonlist = adapter.toJson(HogeData())


    // List
    val dataType = Types.newParameterizedType(List::class.java,HogeData::class.java)
    val adaper = builder.adapter<List<HogeData>>(dataType)

    //Jsonからデータクラスに変換 Strig or JsonReader　or BufferedSourceをfromJsonに渡す
    val hogelist = adapter.fromJson(JSON)

    //ListデータからJsonに変換
    val Jsonlist = adapter.toJson(ListOf(HogeData(),HogeData()))

*実際に使うときはデータクラスの変数と違う物があると例外が発生するので例外処理を入れる必要がある

---
###引用・参考元
[Benchmarking Gson vs Jackson vs Moshi 2020 | Eric Decanini](https://www.ericdecanini.com/2020/10/13/benchmarking-gson-vs-jackson-vs-moshi-2020/)
[kotlinでjsonパースはkotshiがいいかも](https://blog.kaelae.la/entry/2018/01/29/203000)
[Kotlinにも対応したJSONライブラリーMoshiの基本的な使い方](https://qiita.com/naoi/items/0b333a03f1496bf6dec2)
Digdag の Ruby scripts でメソッドに引数を渡す方法

# はじめに

Digdag の [Ruby scripts](https://docs.digdag.io/operators/rb.html) では `rb>: Task::MyWorkflow.my_task` というような感じで Ruby のメソッドを実行することができますが、
この `my_task` メソッドに対して引数を渡したい場合の解決方法を記載します。

# 結論

引数が必要なメソッドを実装し、Digdag のパラメータで同名のパラメータを渡してやると Digdag がよしなにやってくれます。

```ruby
def my_task(hoge:)
  puts hoge
end
```

```
+task1
  _export:
    hoge: 'Hello, world!'
  rb>: Task::MyWorkflow.my_task
  require: tasks/my_workflow
```

# 詳細

[Digdag のこのあたり](https://github.com/treasure-data/digdag/blob/v0.9.42/digdag-standards/src/main/resources/digdag/standards/rb/runner.rb#L164-L247)の実装を読むとパラメータから引数を取得していることがわかります。

また、以下のように `rb>:` の記述で引数を指定することでは解決できません。

```
rb>: "Task::MyWorkflow.my_task(hoge: ${hoge})"
```