OmniAICreator/Qiita-1.07M huggingface dataset:
Systemdを使ったRaspberry Piのプログラムの自動起動

# はじめに

本記事の内容は、やってみてとりあえず上手くいった手順のみです。

# 対象アプリケーション

https://qiita.com/takmot/items/987b493afeeada75925f
上記記事のUDP受信プログラムを.NET Coreで作成し、ラズパイ向けにpublishしたものです。

このアプリケーションをラズパイ上の`/home/pi/work/udp/publish/udp_receiver`に配置しました。`udp_receiver`は実行ファイル名です。

# SystemD Unit ファイル

PCでSystemD Unit ファイルを作成します。
ファイル名は`udp_receiver.service`（`[実行ファイル名].service`）にします。
内容は以下です。

```
[Unit]
Description=UdpRecv
After=network.target

[Service]
User=root
Type=simple
ExecStart=/home/pi/work/udp/publish/udp_receiver

[Install]
WantedBy=multi-user.target
```

`Description`は名前なので任意です。
`ExecStart`に実行するプログラムのパスを指定します。
あとはそのままで良いはずです。

# 自動起動設定

作成したSystemD Unit ファイルをFTPでRaspberry Piに転送。
SystemD Unit ファイルの格納パスは、`/etc/systemd/system/`になります。
`sudo mv udp_receiver.service /etc/systemd/system/`等で移動します。

あとは以下コマンドを実行していきます。※`udp_receiver`は実行ファイル名です。

1. サービスを再読み込みする

```
sudo systemctl daemon-reload
```

2．サービスの自動起動を有効化する

```
sudo systemctl enable udp_receiver
```
以下、実行結果です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695430/904b1c96-321f-b1bf-712d-2ad462913378.png)

3．サービスを開始する

```
sudo systemctl start udp_receiver
```

4．サービスの動作状況を確認する

```
sudo systemctl status udp_receiver
```

以下、`sudo systemctl status udp_receiver`実行結果です。

```
● udp_receiver.service - UdpRecv
   Loaded: loaded (/etc/systemd/system/udp_receiver.service; enabled; vendor preset: enabled)
   Active: active (running) since Wed 2020-09-23 16:33:39 JST; 5s ago
 Main PID: 1240 (udp_receiver)
    Tasks: 8 (limit: 4915)
   Memory: 5.1M
   CGroup: /system.slice/udp_receiver.service
           mq1240 /home/pi/work/udp/publish/udp_receiver

 9月 23 16:33:39 raspberrypi systemd[1]: Started UdpRecv.
 9月 23 16:33:40 raspberrypi udp_receiver[1240]: Receive wait
```

5．Raspberry Piを再起動する

```
sudo reboot
```

6．再起動後プロセスが自動起動しているか確認する

```
sudo ps -x
```

以下のように起動していました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695430/e9dc07eb-2747-c7cd-2e5e-c1f3d891799a.png)

また、今回はUDPポート8888を開いているのでそれも確認します。

```
sudo lsof -i:8888
```
以下、結果です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695430/5cef63ce-e45f-606a-6573-fc25a2c287f5.png)


7．プログラムを停止する

```
sudo systemctl stop udp_receiver
```

8．自動起動を無効化する

```
sudo systemctl disable udp_receiver
```

# Webアプリを自動起動した際の問題

上記のSystemD Unit ファイルの場合、
プログラムの実行位置は"/"になります。

Webアプリの場合、htmlに紐づいたjsファイル、cssファイルがあり、
それらを相対パスで指定している場合、
プログラムは"/"からの相対パスを見に行くためファイルがなくエラーになります。
この辺りのエラーは、ブラウザのデベロッパーツールで確認できます。

この問題を解消するためにSystemD Unit ファイルを以下のように変更します。

```
[Unit]
Description=UdpRecv
After=network.target

[Service]
User=root
Type=simple
WorkingDirectory=/home/pi/work/udp/publish		# 追加
ExecStart=/home/pi/work/udp/publish/udp_receiver

[Install]
WantedBy=multi-user.target
```


# 参考記事
https://qiita.com/KEINOS/items/f3e6b3064b0cbe35fd03
https://tomosoft.jp/design/?p=11697
[Android/Kotlin]コードから背景色を変更する

## 結論
```kotlin
val view: View = findViewById(R.id.constraint) // idを指定（synthetic使えば要らない）
view.background = getDrawable(R.color.colorAccent) // 背景色をcolorAccentに変更
```


## 全体
```kotlin:MainActivity
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        constraint.background = getDrawable(R.color.colorAccent) // constraintの背景色をcolorAccentに変更

    }
}
```

```xml:activity_main
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout  xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/constraint"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

```
【処理時間】ログ出力設定

slow_queryだと指定秒数の閾値を超えてるSQLしか取れないと思われますが、postgresqlのauto_explainを使ってログを出すと各SQLの処理時間が確認できます。

##postgresql.logへの出力例
```
Sep 24 11:59:37 dev postgres[12692]: [21-1] LOG:  duration: 0.518 ms  plan:
Sep 24 11:59:37 dev postgres[12692]: [21-2] #011Query Text: UPDATE dtb_session SET sess_data= $1, update_date= CURRENT_TIMESTAMP WHERE sess_id = $2
Sep 24 11:59:37 dev postgres[12692]: [21-3] #011Update on dtb_session  (cost=0.00..6.07 rows=1 width=47)
Sep 24 11:59:37 dev postgres[12692]: [21-4] #011  ->  Seq Scan on dtb_session  (cost=0.00..6.07 rows=1 width=47)
Sep 24 11:59:37 dev postgres[12692]: [21-5] #011        Filter: (sess_id = $2)
```
設定にはpostgresqlのモジュールコンパイルが必要です。
以下設定手順です。
バージョンは適宜読み替えてください。

```
$ cd /usr/local/src
$ tar zxvf postgresql-9.1.9.tar.gz
$ cd postgresql-9.1.9
$ cp -i ../config.nice-postgresql-9.1.9 .
$ ./config.nice-postgresql-9.1.9
$ make
```
※ make installはしないこと！

```
$ cd contrib/auto_explain
$ make
$ make install
```
※こっちはmake installする。

##postgresql.confへの追記
```
$ vi /var/lib/pgsql/data/postgresql.conf
```
で、以下の行がコメントアウトされている。

```
#shared_preload_libraries = ''             # (change requires restart)
shared_preload_libraries = ‘auto_explain'  # (change requires restart)
#custom_variable_classes = ''              # list of custom variable class names
custom_variable_classes = 'auto_explain'   # list of custom variable class names
```
postgresqlをリスタートする。

```
$ /etc/init.d/pgsql restart
```
WPF と Prism.Unity で DI する

WPF アプリ開発で使われる MVVM フレームワークに Prism がありますが、 Prism は DI フレームワーク提供しています。
今回は Prism が提供する DI フレームワークの一つである Unity を使った DI のやり方を紹介していきます。

# NuGet パッケージの取得
Prism.Unity を取得します。

# コンテナへの登録

```
// DI コンテナの生成
IUnityContainer container = new UnityContainer();

// インターフェイスとクラスを紐づけて登録
container.RegisterType<IAnimal, Dog>();

// インスタンスを登録
container.RegisterInstance<IAnimal>(new Dog());

// シングルトンとして登録
container.RegisterSingleton<IAnimal, Dog>();
```
IUnityContainer クラスの Register...メソッドを使ってクラスを登録します。
RegisterType メソッドは常に登録したクラスのインスタンスを新しく生成してインジェクションしてくれます。
RegisterInstance メソッドは登録したインスタンスをインジェクションしてくれます。
RegisterSingleton メソッドは登録したクラスのインスタンスを一度だけ生成して以降は同じインスタンスをインジェクションしてくれます。

# コンテナからの取得
```
var animal = container.Resolve<IAnimal>();
var viewModel = container.Resolve<MainViewModel>();
```
DI ではありませんが、登録したクラスをコンテナから直接取り出すこともできます。
インターフェースではなくクラスであればコンテナが自動で登録してくれているので、登録することなく取り出すことができます。

# インジェクション
# コンストラクタインジェクション
```
// コンストラクタ
public MainViewModel(IAnimal dog) {
}
```
コンストラクタの引数に DI してほしいクラスを宣言しておけば自動的にインジェクションしてくれます。

# プロパティインジェクション

```
[Dependency]
public Person { get; set;}
```
プロパティに DI するためには Dependency アトリビュートを対象プロパティにつけます。
この際、get と set の両方を用意してやること、自動実装プロパティにしておくことが必要です。

# 使ってみる
```c#:App.xaml.cs
public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);
        IUnityContainer container = new UnityContainer();
        container.RegisterType<IAnimal, Dog>();
        container.RegisterType<IPerson, John>();
        var vm = container.Resolve<MainViewModel>();
        }
    }
```
```c#:MainViewModel
public class MainViewModel 
{
    [Dependency]
    public IPerson Person {get; set;}

    public MainWindow(IAnimal animal) {}
}
```
これで Person と animal インスタンスをインジェクションすることができます。
DI を受ける MainWindow クラスもコンテナに生成してもらう必要があります。
MySQLのデータベース、テーブルの作成と削除、行の追加

###データベース作成
````sql
create database shop;
````

### データベース一覧
````sql
show databases;
````

###データベース削除

````sql
 drop database shop;
````
###テーブル作成

````sql
create table Shohin (
    shohin_id varchar(4) not null primary key,
    shohin_mei varchar(100) not null,
    shohin_bunrui varchar(32) not null,
    hanbai_tanka int,
    shiire_tanka int,
    torokubi DATE
    );
````

###テーブル一覧

````sql
show tables;
````

###テーブル削除

````sql
drop table Shohin;
````

###データ追加
insertの後のintoは省略可能。
また、全てのカラムに対してデータを登録する場合、カラム名の指定を省略可能。

````sql
-- into,カラム名を省略したバージョン
insert Shohin values ('0001', 'Tシャツ', '衣服', 1000, 500, '2009-09-20');

-- 特定のカラムのみデータを登録する場合、valuesの前に対象のカラムを記述する
-- 指定されていないカラムについてはnullが入る
insert Shohin (shohin_id, shohin_mei, shohin_bunrui) values ('9999', '技術書', '経験値');
````
###データ削除
````sql
delete from Shohin where shohin_id = 9999;
````
select_tag　選択値設定（include_blank => true）

select_tag　空白行設定（include_blank => true）時、
DBから検索された値をVALに設定しても、空白テキストが表示されている
対策：$("#selectbox").val(DBから検索値).trigger('change')


include_blank => falseなら、
$("#selectbox").val(DBから検索値)
V-forでsliceを 使ってlist array を制限する

```vuejs:comment.vue
上に
<v-for="comment in comments" :key"comment.id">
{{id}} {{name}}
</div>
<button :disabled="currentPage == 1" @click="prevPage">少なく表示する</button>
      <button :disabled="currentPage == totalPages" @click="nextPage">
        もっと見る
      </button>
```

Scriptのところに下記を入れる

```vuejs:comment.vue
 currentPage: number = 1
//コメントをsliceを使ってページごとに５個ずつ出す
  get comments() {
    return this.visaCommentResponse.slice(0, this.currentPage * 5)
  }
//ページの数をわかる
  get totalPages() {
    return Math.ceil(this.commentCount / 5)
  }
//もっと見るボタン
  nextPage() {
    if (this.currentPage < this.totalPages) this.currentPage++
  }
//少なく表示するボタン
  prevPage() {
    this.currentPage = this.currentPage - 1 || 1
  }
```

結果はこれです。
![Screen Shot 2020-09-23 at 16.15.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/645432/5fcf82df-7e75-10f9-8deb-960054ea3af1.png)

EDIT* もう少し簡単にできた。

script のところに

```vuejs:comment.vue
commentsShown?: number = 10

get comments() {
    return this.visaCommentResponse?.slice(0, this.commentsShown)
  }

  loadMore() {
    this.commentsShown += 10
  }

  loadLess() {
    this.commentsShown -= 10
  }
```
ボタンは

```vuejs:comment.vue
<button
        v-if="
          visaCommentResponse.length > 10 &&
            commentsShown < visaCommentResponse.length
        "
        @click="loadMore"
      >
        Load More
      </button>
      <button v-if="commentsShown > 10" @click="loadLess">
        Load less
      </button>
```
package.jsonのdependenciesにコメントを残す(yarn限定)

# 前提
- yarn 1.x でしか動かず、npm installは失敗する
- yarn 2.x は未調査

# 概要
package.jsonのdependencies, devDependenciesなど何らかの事情で依存ライブラリを固定したときにその事情を残す場所に困って解決したのでメモ

# 方法
```
"stylelint": "13.3.0 because of https://github.com/stylelint/stylelint/issues/4732",
```

みたいに書く
このときyarn.lockはちゃんと

```
"stylelint@13.3.0 because of https://github.com/stylelint/stylelint/issues/4732":
  version "13.3.0"
```

のようになる

# 利点
1つ上の行にパッケージ風のコメントを書く方法もあるが、これなら一番近くに事情を残せるし、package.jsonを自動ソートしていてもどこかに行かない

# 他の方法
https://dev.to/napolux/how-to-add-comments-to-packagejson-5doi
しまぶーさんのモダンJavaScript講座の要約

# しまぶーさんJavaScript講座　要約
## なにこれ
[モダンJavaScript講座](https://www.youtube.com/watch?v=1TIK03WFAxM&list=PLwM1-TnN_NN4SV6DEs4OtfA51Up6XzTfB&index=6)
しまぶーさんがyoutubeに投稿している動画が非常にわかりやすかったので、思い返せるために自分なりにまとめました。

# JavaScript

JavaScriptさん　1995年に生まれる

ECMAScriptは、netscapeがJavaScriptを国際的な標準化団体（Ecma innternational）に提出した時に生まれた。
（豆知識：ES4以下はリリース順。ES5以上は年号表記。ES2015が正解）

# ECMASCriptとは？
➡️JavaScriptの中核になる言語仕様。どの実行環境でも共通な動作のみが定義
実際はコンパイルする必要がある

ブラウザでモジュールを使うために模索した結果、コードを事前に変換が主流に

## モジュールとは
ただの1つのファイル（モジュール）。相互に読み込んだりexportとimportを使用して機能をやり取りしたり、あるモジュールの関数を別のモジュールから呼び出せる。
スコープの概念あり。

Node.jsが2009年に開発。CommonJSのモジュールAPIに準拠

JavaScriptにはモジュールの仕様が複数存在してる。

## パッケージとパッケージ管理システムとは
・パッケージとは
「package.json」で記述されたファイルやディレクトリ
➡️メリット
機能の細分化ができて、名前空間問題が解決できる
➡️共有したい！
・改めてパッケージとは
共有したい機能の単位

・パッケージ管理システムとは

・パッケージ管理システムがやってくれること
1．リポジトリの購読
2．パッケージのインストール・削除
3．依存関係の解決
パッケージに必要な別のパッケージを自動的にインストールできる
「package-lock.json」のこと。「node_modules」に依存関係が入ってる。
expressをインストールする時に必要な依存関係のものを一瞬でDLできる
例）jQueryUIを使うにはjQueryが必要で、先にjQueryを読まないとエラーを吐く
4．設定管理
設定書いたら1，2，3を自動で行える。手動の手間が省けてチームで環境を揃えられる

## Bunbleとは
1．開発時はCommonJSモジュールで開発
2．モジュールの依存関係を解決して1ファイルに変換（これがバンドル）
3．いつも通りscriptタグで読み込む

## Browserifyとは
CommonJSで書かれたものをブラウザ向けにバンドルするツール。require文を使える。そのおかげでNode.jsのパッケージが使えるようになった➡️npmが主流へ
CJS形式モジュールをバンドルするよ。

## webpackが2012年に降臨爆誕
そして覇権を取る。環境最強ですね。
cjsとかブラウザで使えないファイルを何でもバンドルできるのがwebpack。
codesplittingを使ってチャンク分割している（難しいからスルー）

## ESmodule降臨爆誕。
独自仕様だったので、共通の仕様が欲しかった。
んで、ES2015からJavaScriptの言語仕様としてモジュールの仕組みが導入される。
簡単に言うと、requireからimportになる。

## wepack誕生までの流れまとめ
モジュールバンドラーが流行る（特にwebpack）➡️CJSやESM形式でモジュールを使ってコード掛けるから
CJS主流だったnpmクライアント開発で使える＝パッケージ管理システムも使える

## コンパイルとは

## コンパイルを使うと
1．開発時にはブラウザで動かないけど、便利な機能を使ってコードを書ける
2．書いたコードをブラウザで動くように変換➡️いつもどおり読み込む

## Babel(6to5)の誕生（元々は6to5だったけど、Babelに改名された）
wepackとbabelを一緒に使える。
元々はES2015の新機能（letとか）が使えなかったけど、babelのおかげで使えるようになった？

## コンパイルの可能性
コンパイルが当たり前になって、便利なパッケージが流行りだす
React(.jsx)・Vue(.vue)・TypeScript(.ts)

## モダンなJS環境になるために
コードを事前に変換が主流になった。モジュールを使えたり依存関係を解決でき、ES2015仕様が使える。パラダイムシフト

## 覚えるべきもの
Node.js パッケージ管理システム npm(package.json) 事前変換（Bundle, Compile)
webpack babel ES module ES2015 React Vue TypeScript
【JavaScript】基礎的な文法編

# 編集中です！

・typeof
文字列の型を表示できる
#
```
console.log(typeof 11); # number
```

・NaN
Not a Number（ナンと呼ぶ）。数値が表せないよ〜ってこと。

・文字列の評価
- false（falseと表示されるもの）
    - 0
    - null
    - undifined
    -  「’’」（空文字）
    - false
- true
    - 上記以外全てtrue

・論理演算子「!a」
NOT演算のこと。〜ではない。「a以外なら何でもおk」。rubyのunlessに似てる。
何か前にも躓いた気がする。

#
```
      a = 1;
      console.log(!(a === 0));
	# true

      a = 1;
      console.log(!(a === 1));
	# false
```

・switch
まんまrubyのwhenですね。
#
```test.js
      a = 1;
      switch (a) {
        case 0:
          console.log(0);
        case 1:
          console.log(1);
        default:
          console.log("aaa");
      }
// 出力結果: 1
```

・テンプレートリテラル
ES6から使えるようになったやつ。
バッククオート「`」で範囲を囲む！
変数や計算式を入れられる。
#
```
`aaa`
${1+1 + a}
```

・デフォルト引数
メソッドのデフォルトで表示する引数を決められる。値ありなしでもエラー起きないよ。
#
```
      function showAd(message = "Ad") {
        console.log(`--- ${message} ---`);
      }
      showAd("Ad");
      showAd();

// 出力結果
—- Ad ---
—- Ad ---
```

・ブロックで囲うとエラーが出ない（ブロックスコープ）
⬇️下記はエラーが出る（定数がすでに宣言されてる！エラー）
#
```index.html
  <script src="js/main.js"></script>
  <script>
      const x = 300;
      console.log(x);
  </script>
```

#
```main.js
  const x = 100;
  console.log(x);
```

⬇️下記はエラーが出ません（定数が別々で定義されているから）
#
```index.html
  <script src="js/main.js"></script>
  <script>
    {
      const x = 300;
      console.log(x);
    }
  </script>
```

#
```main.js
{
  const x = 100;
  console.log(x);
}
```
TypeScriptの基礎的なこと（用語編）

## TypeScriptとは
JavaScriptにコンパイルされる、静的型システムがついた、JavaScriptの上位集合

## なぜTypeScriptか？（なぜTypeScriptしか勝たんのか？）
・ドキュメントとしての側面を利用するため
変数の型とか引数の情報を教えるため、書けなくてもドキュメントを読めて開発効率上がる
・Linterとしての側面を利用するため
ESlintはコロンとかチェックできるけど変数の型は無理。TSはそれができる。強みが違うから共存して生きていくっ！
・ES5へのコンパイラとしての側面を利用するため

## any型は使うな！TypeScriptはもうお手上げって思っちゃうから。

## void型：何も返さない

## watchモード
tsファイルを自動的にjsファイルへコンパイルする。「tsc index.ts —watch(-w)」

## tsc —initとtscコマンド
tsc —initでコンパイル設定用tsconfig.jsonが生まれる。その後にtsc叩くと一括コンパイルできる

## constructor
予約語？初期化、最初の処理　

## publicとprotectedとprivate（こいつらはES6じゃなくてTypeScript。要は、よそ者）
・public
誰でもどこからでもおk。何でも良い。ガバガバ。ガバマン
（readonlyはどこでも使える）　

・protected
継承先からなら良いよ〜。ちょっとお硬いけど実は柔軟なやつ。

・private
絶対このクラスからしか通さん。このクラスしか勝たん。

## abstract
継承用クラスだよ！って宣言するTypeScriptのメソッド。ES6はゆるいから厳格に決める。ちなabstractにするとインスタンスが作成できない（staticはおk）

## interfaceとは
オブジェクトのみのタイプエイリアス

## Nullish Coalescing（三項演算子のTypeScriptバージョンみたいな）
#
```
const userData = downloadedData.user ?? "no-user"; // undifとnullだけ右側が反応する
```

## オプショナルプロパティとは
語尾に「？」をつけることで、あってもなくてもokになる。

## デコレーター
クラスを受け取ってデコレーションする。ただの関数。「@」から始まるよ。クラスの定義時に発火する。
PHP Laravel 6 おすすめ映画投稿サイト作成過程 3:詳細ページ作成編

#showページの追加

recommendsディレクトリにshow.blade.phpを作成します。
![Screen Shot 2020-09-23 at 15.22.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/736153/dd60367c-97b8-4192-3231-fe6db7f04c82.png)

#コントローラー追加
ルーティングは以下の通りです。

```
|        | GET|HEAD  | recommends/{recommend}      | recommends.show    | App\Http\Controllers\RecommendController@show                          | web 
```

showメソッドで{recommend}を受け取り、show.blade.phpへ投げます。
なお、recommends/{recommend}の{recommend}にはDBのid番号が入ります。

```recommend/app/Http/Controllers/RecommendController.php
 public function show(Recommend $recommend)
    {
        return view('recommends.show', compact('recommend'));
    }
```

#showで受け取ったデータの出力方法
{{$recommend-> カラム名}}で各データを表示できます。

```recommend/resources/views/recommends/show.blade.php
<table>
    <tr>
       <th>{{$recommend->title}}</th>
       <th>{{$recommend->image_file_name}}</th>
       <th>{{$recommend->url}}</th>
       <th>{{$recommend->description}}</th>
       <th>{{$recommend->Impressions}}</th>
      </tr>
</table>

```

#リンクの作成
showページへのリンクは、以下の方法で設定できます。
なお、今回はindexページのタイトルにリンク設定しました。

```recommend/resources/views/recommends/index.blade.php
<a href="{{route('recommends.show', $recommend->id)}}">{{$recommend->title}}</a>
```

ちなみに、以下でも同じ動作を実現できます。
この表記では、該当するデータを{recommend}としてコントローラー側で受け取っていることが分かり易い反面、ルーティングを変更した場合に機能しなくなってしまうので注意が必要です。

```recommend/resources/views/recommends/index.blade.php
<a href="recommends/{$recommend->id}">{{$recommend->title}}</a>
```
【解説】ポートフォリオ(NotePro)

# URL
[NotePro](https://notepro.work/)

# 概要
デバイス内に散らばった情報を一つにまとめることできるWEBアプリケーション

# 制作背景
日頃から私自身で困っていたことを解決したいという考えから作成いたしました。

```
1.以前Twitterでいいねした投稿がいいねしすぎてすぐに見つからない
2.YouTubeでためになったことをスクショしたはいいものの、フォルダのどこにあるのかすぐに見つからない
3.参照リンクもまとめたい
4.某投稿サイトなどはあるが何かによりすぎて気軽な投稿はできそうにない雰囲気がある
5.まとめたものにいいねをもらいたい！！！！
```
### 1.以前Twitterでいいねした投稿がいいねしすぎてすぐに見つからない
Twitterでは気軽にいいねができすぎて、本当に必要な時、***いいねした投稿が見つからない***ことが皆さんも結構あるのではないでしょうか。
また、Twitterアカウント自体複数持っている方も結構いるのではないでしょうか。そうなると尚更、見つかりずらくなります。
noteとしてまとめる時間はかかるものの、
各アカウントのいいね欄を探しに行く時間を考えたら***圧倒的に時間削減できる***と考えたので作ろうと考えました。

### 2.YouTubeでためになったことをスクショしたはいいものの、フォルダのどこにあるのかすぐに見つからない
私自身結構な頻度でスクショを撮ります。
動画を見ている際、コメントで出てくるところを撮ったりするのですがフォルダには日常生活で撮影した写真などもあり***「あの時スクショした画像どこかな？」***と探すことが結構な頻度であります。
なのでこういったことも解決できたらいいなと考えておりました。

### 3.参照リンクもまとめたい
いいねしたツイート、スクリーンショットなどで、
参照元のリンクやページ内にある別サイトのリンクなども***「まとめて管理できないかなあ」***と考えておりました。

### 4.某投稿サイトなどはあるが何かによりすぎて気軽な投稿はできそうにない雰囲気がある
某緑（これ）のやつだったりなどいろいろありますが、
***私生活の豆知識なども一緒に投稿できる雰囲気ではない***ので、
もう少しラフで気軽に投稿できるWEBサービスが欲しかったのです。

### 5.まとめたものにいいねをもらいたい！！！！
単にnoteの作成であれば[everonte](https://evernote.com/intl/jp/)やiPhoneのメモなどで事足ります。
ですが、投稿するなら***まとめたものにいいねとかもらいたい***と考えておりました。
しかし、SNSぽくしてしまうと、最近では悲しい事件が起きたりしているで
SNSの使い方、モラルなどが強く必要となり、noteツールにそういうことまではもたせたくないと考えていたりしてました。
なのでSNSのいいところだけを取り、***誹謗中傷などはないけど、程よく承認欲求も満たされる***ものを作ろうじゃないか！

という上記の理由から今回の[NotePro](https://notepro.work/)を作成いたしました。


# 機能

```
リッチテキストによる投稿
idのtoken化
タグ機能
Twitterログイン機能
CSVのエクスポート機能
投稿に対するいいね
ゴミ箱機能
プロフィールの画像設定
```

### リッチテキストによる投稿
・[summernote](https://summernote.org/)を使用し制作
※日本語の解説などがあまりなく結構時間とられました。

### idのtoken化
・user_idやpost_idを乱数保存
皆さんが良く利用するサービスでも

```
user/12(id)/edit
```
上記みたいな簡単なIDで表示されているのはあまりないですよね。
簡単なIDにしてしまうと簡単に推測できてしまい悪用されかねないので
乱数（いろいろ種類がある）でトークン化して保守化しました。

### タグ機能
・投稿にタグを紐づけることができる

### Twitterログイン機能
・Twitterからのログインをすることができる

### CSVのエクスポート機能
・自分の投稿のみSCVで吐き出すことが可能

### 投稿に対するいいね
・他ユーザーのいいと思った投稿にいいねができる

### ゴミ箱機能
・不要投稿はゴミ箱に入れることができる

### プロフィールの画像設定
・アイコンの設定ができる

# 使用技術
・言語：Ruby2.5.7
・フレームワーク：Ruby on Rails5.2.4.3
・テスト：RSpec
・フロント：slim(BEM)、Sass、JavaScript(jQuery)、Bootstrap4
・インフラ：AWS(VPC | ELB | EC2 | SES | Route53 ）
・ソースコード管理：GitHub
・その他：Capistranoによる自動デプロイ

# 環境
### 開発環境
Vagrant 2.2.4
SQLite 3.7.17

### 本番環境
MySQL2 5.5.62
Nginx 1.16.1
Puma

# 使用したgem

```
gem 'faker'
gem 'pry-byebug'
gem 'rubocop-airbnb'
gem 'slim-rails'
gem 'devise'
gem 'summernote-rails', '~> 0.8.10.0'
gem 'omniauth'
gem 'omniauth-twitter'
gem 'google-analytics-rails'
gem 'meta-tags'
gem 'aws-ses'
gem "refile"
gem 'rails-i18n'
gem 'kaminari', '~> 1.2.1'
```

なるべく少なくとは思いつつ想定より多くなってしまいました、、

# NotePro作成するにあたり定義したものたち
・[ワイヤーフレーム](https://app.diagrams.net/#G1-Dw7_LS9NtYRiXQkgoc5ZwCSvMTDTHqo)
・[ER図](https://drive.google.com/file/d/1bEzzQWfZOvfq2R3U7MmzOUyKqpQUQ6VO/view?usp=sharing)
・[テーブル定義書](https://docs.google.com/spreadsheets/d/1Cb_EDgsR39UTWW4zN6D1xyNNcTKD48v4/edit#gid=1356632829)
【Laravel】GuzzleでEUC-JPのページを受信すると文字化け→cURLの受信結果を適切にエンコードして解決

## 現象
1. LaravelでHTTP通信するならGuzzleらしい
3. 試す。受信結果が文字化けする
4. cURLベースで書き直す
5. やっぱり文字化けする
6. EUC-JPのページで発生している

## 解決
以下のエントリを参考に、cURLでの受信結果を適切に変換することで文字化けを防ぐことができた。

- [PHPのcurlでeuc\-jpのページを取得したときに文字化けするのを防ぐ \| 俺日記](https://blog.shinji.asia/curl-php/)
- [unicode \- PHP: Convert curl\_exec output to UTF8 \- Stack Overflow](https://stackoverflow.com/questions/2510868/php-convert-curl-exec-output-to-utf8)


## コード
```php
function curl_get_contents($url, $timeout = 60) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
    curl_setopt($ch, CURLOPT_ENCODING, 'gzip');
    $result = $this->curl_exec_utf8($ch);
    curl_close($ch);
    return $result;
  }

  function curl_exec_utf8($ch) {
    $data = curl_exec($ch);
    if (!is_string($data))
        return $data;

    unset($charset);
    $content_type = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);

    /* 1: HTTP Content-Type: header */
    preg_match('@([\w/+]+)(;\s*charset=(\S+))?@i', $content_type, $matches);
    if (isset($matches[3]))
        $charset = $matches[3];

     /* 2: <meta> element in the page */
     if (!isset($charset)) {
      preg_match( '@<meta\s+http-equiv="Content-Type"\s+content="([\w/]+)(;\s*charset=([^\s"]+))?@i', $data, $matches );
      if ( isset( $matches[3] ) ) {
          $charset = $matches[3];
          /* In case we want do do further processing downstream: */
          $data = preg_replace('@(<meta\s+http-equiv="Content-Type"\s+content="[\w/]+\s*;\s*charset=)([^\s"]+)@i', '$1utf-8', $data, 1);
      }
    }

    /* 3: <xml> element in the page */
    if (!isset($charset)) {
        preg_match( '@<\?xml.+encoding="([^\s"]+)@si', $data, $matches );
        if ( isset( $matches[1] ) ) {
            $charset = $matches[1];
            /* In case we want do do further processing downstream: */
            $data = preg_replace('@(<\?xml.+encoding=")([^\s"]+)@si', '$1utf-8', $data, 1);
        }
    }

    /* 4: PHP's heuristic detection */
    if (!isset($charset)) {
        $encoding = mb_detect_encoding($data);
        if ($encoding)
            $charset = $encoding;
    }

    /* 5: Default for HTML */
    if (!isset($charset)) {
        if (strstr($content_type, "text/html") === 0)
            $charset = "ISO 8859-1";
    }

    /* Convert it if it is anything but UTF-8 */
    /* You can change "UTF-8"  to "UTF-8//IGNORE" to
      ignore conversion errors and still output something reasonable */
    if (isset($charset) && strtoupper($charset) != "UTF-8")
        $data = iconv($charset, 'UTF-8', $data);

    return $data;
  }
```

### gzipオプションについて
`curl_setopt($ch, CURLOPT_ENCODING, 'gzip');`はサーバー依存です。

筆者の環境では、gzipで圧縮されたレスポンスが返ってくるため必要でした。
（参考：[PHPのcurl\(\)でレスポンスが文字化けしたら確認すること２つ \- PHP \| ゆるりの足あと](https://yululy.com/php%e3%81%aecurl%e3%81%a7%e3%83%ac%e3%82%b9%e3%83%9d%e3%83%b3%e3%82%b9%e3%81%8c%e6%96%87%e5%ad%97%e5%8c%96%e3%81%91%e3%81%97%e3%81%9f%e3%82%89%e7%a2%ba%e8%aa%8d%e3%81%99%e3%82%8b%e3%81%93%e3%81%a8/)）
htmlのrequiredのバリデーション+jQuery submit+bootbox

```html
<input type="text" class="form-control" name="input-param1" id="input-param1" value="{{ input-param1 }}" maxlength="6" required>
<input type="text" class="form-control" name="input-param2" id="input-param2" value="{{ input-param2 }}" maxlength="6" required>
<button type="submit" class="btn btn-success btn-md btn-submit">登録</button>
```

```javascript
    $('.btn-submit').on('click', function(e) {
        // submitをキャンセル
        e.preventDefault();
        // htmlでのrequiredのバリデーションを判定
        if (! $('form')[0].reportValidity()) {
            return false;
        }
        // requiredを満たしていたらbootboxを出す
        bootbox.confirm({
            title: '記事編集',
            message: '更新しますか？',
            closeButton: false,
            callback: function(res) {
                if (res) {
                    bootbox.alert({
                        title: '記事編集',
                        message: '記事の更新後、画像が反映されるまで数分かかる場合があります',
                        closeButton: false,
                        callback: function() {
                            $('form').submit();
                        }
                    });
                }
            }
        });
    });
```

参考：https://qiita.com/pappikko/items/117efc8bcf5e9c3be9e1
LibTorch(PyTorch C++)APIメモ

ほぼ自分用です。随時更新します。
LibTorch環境構築は[この記事](https://qiita.com/kai_ware/items/f7ac015b330f10564ab3)を参照。

[公式資料](https://pytorch.org/cppdocs/notes/tensor_creation.html)が有能なので、まずはそこをチェック。

## float型vectorから1次元torch::Tensorへの変換
```.cpp
torch::Tensor tsr = torch::tensor(torch::ArrayRef<float>(vec));
```

## torch::Tensor型vectorからtorch::Tensorへの変換
```.cpp
torch::Tensor tsr = torch::stack(tsr_vec);
```

## 1次元torch::Tensorからstd::vectorへの変換
```.cpp
torch::Tensor tsr = torch::randn({ 3 });
tsr= tsr.contiguous();
std::vector<float> v(tsr.data_ptr<float>(), tsr.data_ptr<float>() + tsr.numel());
```

## 1次元torch::Tensorのスライス
参考：https://pytorch.org/cppdocs/notes/tensor_indexing.html

```.cpp
namespace ti = torch::indexing;
torch::Tensor tsr2 = tsr.index({ ti::Slice(i, i + slice_size) });
```

## 1次元生配列からtorch::Tensorへの変換
```.cpp
// おそらく生配列でなくとも変換可能
// 先頭ポインタ、サイズ、型が分かっており、メモリ上に連続に配置されていればOK?
float raw_arr[] = {1.f, 2.f, 3.f};
torch::Tensor tsr = torch::from_blob(raw_arr/*先頭ポインタ*/, 3/*size*/, torch::TensorOptions().dtype(torch::kFloat32));
```

## GPU使用可能かチェック
```.cpp
torch::DeviceType device_type;
if (torch::cuda::is_available()) {
	std::cout << "CUDA available! Running on GPU.\n";
	device_type = torch::kCUDA;
}
else {
	std::cout << "Running on CPU.\n";
	device_type = torch::kCPU;
}
```

## CPU/GPUへ送る & 型変換
```.cpp
auto model = std::make_shared<Model>();
model->to(torch::kCUDA); // torch::Device型でなくても良い。
model->to(torch::kCPU);

tsr.to(torch::kFloat64);
tsr.to(torch::kCUDA);
```

## tensorサイズ取得
```.cpp
size_t tsr_size = tsr.size(0 /*dim*/);
c10::IntArrayRef tsr_sizes = tsr.sizes();
```

## torch::Tensorから組み込み型の値を取得
```.cpp
// tsrがスカラーでないとエラーを吐くので注意。
// 配列を変換したい場合、tsr.index({i})やtsr[i]で要素にアクセスしてから変換。
double d = tsr.item().toDouble();
```

## その他
- `torch::Tensor`は微分可能、`at::Tensor`は微分不可(らしい)
    - 両者に速度の違いはほとんどないため、基本的に`torch::Tensor`を使う
- `torch_cuda.dll`が見つからないエラー
    - 作成したexeと同じ場所に、cudaとtorch関連のDLLをコピーしてきたか？
- カスタムデータローダーをインスタンス化できないエラー
    - get()だけでなく、size()も実装しなくてはいけない
    - 参考：https://github.com/pytorch/pytorch/blob/master/torch/csrc/api/include/torch/data/datasets/base.h#L53
Konyアプリで読み込み時にオリジナルのアイコンを表示してみた

##目次
1. はじめに
2. 実装方法
3. まとめ


##はじめに
Webやモバイル等のアプリを使っていると、データの読み込み中等に
よく以下のようなローディングアイコンが表示されるかと思います。
![スクリーンショット 2020-09-23 15.38.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/9eb9153a-f926-8265-f65b-26afdafedc5a.png)

今回は、Konyで読み込み中のアイコンを表示する方法について、
ご紹介していきたいと思います！

##実装方法
早速実装方法をご紹介していきたいと思います:ok_hand:

###①ローディングアイコンを表示
ローディングアイコンを表示するためには、
アイコンを表示したいフォーム内でアクションを設定し、
左メニューから`Loading Indicator`を選択します。

今回は、ログインボタンクリック後にローディングアイコンを表示したいため、
ログインクリック時にアクションを設定しました。

ローディングを表示する場合は、
Loading Indicatorで`Show`を選択します。
![show.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/c92c7fd7-2482-558c-0570-31f91b5b6332.png)
その他、アイコンの下に文字を表示したい場合などはTextに文字を入力すると、
文字の表示も可能になります。

###②読み込み終了後にアイコンを非表示
画面遷移後に、ローディングのアイコンが表示されたままだと困るので、
フォームが表示されたら、再度アクションを設定しアイコンが非表示になるよう設定します。

今回は、ログイン後に表示されるfrmMainのpreShowにアクションを設定しました。

ローディングを非表示にする場合は、アクションメニューでLoading Indicatorを選択し、
以下のように`Dismiss`を選択すれば完了です。
![dissmiss.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/22faff2c-bf54-f679-ca49-3f8fcea4f951.png)

ここまでの手順で、一旦ローディングが表示されるようになりました！

次にオリジナルのアイコンを表示したい場合の手順も紹介します:ok_woman_tone1:

###③アイコンデザインを変更
デフォルトのアイコンは、以下のようになっているかと思いますが、
![スクリーンショット 2020-09-23 14.38.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/79b4d8eb-7563-2d18-2ca6-2c8724035d68.png)

アプリのテーマカラーや企業カラーに合わせて、
アイコンのデザイン自体を変更したい場合があるかと思います:thinking:

その場合は、変更したいアイコンのファイル名を`loading.gif`という名前で保存し、
Assetタブから、該当のgifファイルをimportしてください。

そうすると、既存のデフォルトのローディングアイコンが上書きされ、
変更したファイルが適用されます。

ローディングアイコンについては、ご自身で作成しても良いですが、
「ローディングアイコン」と検索すると、無料でダウンロードできるサイトが沢山出てきますので、
お好みのものを探してダウンロードしてみてくださいね！

今回は、こちらを利用しました。
![loading.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/b8d66aef-22bc-801c-3f48-234a7ba50702.gif)

では、実際に動きをみてみましょう！
<blockquote class="twitter-tweet"><p lang="und" dir="ltr"><a href="https://t.co/n6QsirKNOZ">pic.twitter.com/n6QsirKNOZ</a></p>&mdash; Kony (@Kony12763790) <a href="https://twitter.com/Kony12763790/status/1308651679135404034?ref_src=twsrc%5Etfw">September 23, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

ログインボタンクリック後、上記のアイコンが表示され、
画面遷移後にアイコンが消えていることがわかりますね！

**〜補足〜**
loading.gifファイルは、Assetsタブの画像ファイルには表示されませんが、
フォルダを見るとプロジェクトフォルダのimagesの下に画像ファイルが保存されています。

変更したいgifファイルと、このファイルを同じ名前で保存することにより、
アイコンが上書きされ、ローディング表示時のアイコンの挿し替えが可能になります。
![スクリーンショット 2020-09-23 14.55.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/8b32d8f2-232c-dd04-de8d-0c92eab80c03.png)


##まとめ
今回は、読み込みの際に表示するアイコン表示の方法について説明しました。

細かい機能ではありますが、アイコンがないとアプリが動いているのかそれとも止まっているだけなのか、
わかりにくい場合があるので、読み込み中はアイコンを表示してあげて、
更に、アイコンに自社のキャラクターを使えば、ユーザーが使っていてより楽しいものになるかと思います！

Konyでは、ローディングアイコンを表示するために特に長いコードを書く必要なく
アクションメニューで簡単に設定できるので、是非今回の手順を参考にしてみてくださいね！:hand_splayed_tone1:

##参考
[Kony公式ドキュメント（showLoadingScreen）](https://docs.kony.com/konylibrary/visualizer/viz_api_dev_guide/content/kony.application_functions.htm#kony.app3)
小技：Teamsの新機能Listのアイコンを変える

#そもそも
MicrosoftのTeamsに新機能として追加された「List」ですが、コレまであったPlannerよりもシステム開発に向いたタスク管理ができます。

# Listsの選択肢列を編集しよう！
実際、ListってスプレッドシートをExcelみたく細かく設定できます。
表示される列も自由に編集できてとっても使い易いのですが、
実は`選択肢`の書式設定の詳細を編集すると`アイコン`が変更できます。
　→　というか書式用のJSONファイルをエディタで弄る必要ありますが

# 列の書式JSONについて
詳細モードに切り替えるとJSONが取得出来ます。
このなかに`iconName`っていう要素があるのでこの中を弄りましょう。
→　既存のテンプレートだと`Mail`とかが割当たっています

# 肝心のアイコンを調べる
以下のURLから文字列をコピペしましょう。 
https://developer.microsoft.com/en-us/fluentui#/styles/web/icons
Vue.jsでSassを使用する方法

Vue.jsでScssを使用したらエラーが出たので解決方法をまとめておきます。

複数の方法があるらしいですが、以下が簡単と感じました。
参考：[プロジェクト作成時に設定する方法](https://qiita.com/terufumi1122/items/6747cfed10b60e3c7fa1)、[プロジェクト作成後に反映する方法(今回)](https://deep-space.blue/web/695)

以下のようにstyleへScssの指定を追加して下さい。

```
<style lang="scss"> //この部分に追記
</style>
```

これだけだと次のようなエラーが出ますので、
`Failed to resolve loader: sass-loader You may need to install it.`
ターミナルで以下を実行します。

```
npm install sass-loader node-sass --save-dev
```

あとはいつものようにScssを記述していけば、自動でコンパイルしてくれます。

```
<style lang="scss">
  .nav {
    ul {
      li {
          list-style-type: none;
      }
    }
  }
</style>
```
簡単ですね！
matlabでMODBUS②WAGOのPLC 750シリーズ

　WAGOのPLCを取り上げます。多くのマニュアルが日本語になっています。MODBUS/TCPを使うために、TCPインターフェース750-342、アナログ入力のモジュール750-479、終端の750-600を組み合わせました。
![IMG_4739.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/4110e50a-ec09-599e-6dd3-6e177e126fc3.png)
　アナログ入力モジュールは2チャネルです。13ビット＋符号（左詰め、下2ビットはエラー・コード。通常'00'）の、2の補数形式で保持レジスタから読み取れます。アナログ・モジュールのアドレスは、つないだ順番に振られるようで、'1'と思われます。
　TCPインターフェース750-342の外側にはMACアドレスが書かれています。これをもとに、TCP/IPアドレスを振ります。750-842のマニュアルを読んで設定しました。具体的な説明は、[こちらの記事](https://www.denshi.club/pc/modbus/modbus-10-wago-750-8421ip.html)を参照してください。
###まずは、Modbus Explorer
　Modbus Explorerを起動します。
![2020-08-29_12h41_07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/caa49d95-75fc-411c-5540-1985f702db51.png)

　Deviceをクリックして、出てきたModbus TCP/IPのアイコンをクリックします。
![コメント 2020-08-29 124628.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/410e2120-fe47-63b0-d10b-003c79e1951c.png)

　Device Addressに、設定した192.168.111.24を入れ、Register TypeはHolding...を選択します。Register Addressは'1'、Readアイコンをクリックすると、8195が読み出されました。
![2020-09-23_10h12_48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/04bfa949-d33f-1bd6-af72-8018d4c10423.png)


　Confirm Parametersをクリックします。次の画面が立ち上がって、連続してreadが実行されてグラフが描かれます。
![2020-09-23_10h16_20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/f50fa8d6-9304-367b-61de-0316e8dc2f78.png)
　Reg_1の横にチェックをし、Generate Scripts CODEをクリックします。
　ライブエディタが立ち上がります。
###プログラム
　自動で生成された、

```matlab
% Holding Registers
% Read 1 Holding Register of type 'int16' starting from address 1.
modbusData.Reg_1 = read(m, 'holdingregs', 1, 1, serverId, 'int16');
```

の記述でデータを読み出して、値はmodbusData.Reg_1 に入ります。これを電圧に変えます。
　16ビット長 2の補数形式なので、一度dec2bin()でバイナリの文字列に変換します。この文字列の前に接頭語'0b'をくっつけ、後ろに桁数？を表す's16'をつなげます。その文字列をbin2dec()で10進数に変換すると、先頭が'1'であればマイナスの符号の処理が行われます（R2020a以降）。
　アナログ・データのフォーマットは±10Vなので、2^15で割って10をかけると電圧に変換されます。

　プログラムです。

```matlab
% Create a Modbus Object.
m = modbus('tcpip', '192.168.111.24');
m.Timeout = 3;

% Save the Server ID specified.
serverId = 1;

% Holding Registers
% Read 1 Holding Register of type 'int16' starting from address 1.
modbusData.Reg_1 = read(m, 'holdingregs', 1, 1, serverId, 'int16');

binStr = dec2bin(modbusData.Reg_1,16);
Vin = bin2dec(append('0b',binStr,'s16')) / 32768 * 10;
fprintf('Vin0 = %.5fV\n', Vin);

% Clear the Modbus Object created.
clear m

% Clear the Server ID.
clear serverId
```
Teamsに新機能「Lists」が追加されたんでExcelファイルから卒業

#そもそも
MicrosoftのTeamsに新機能として追加された「List」ですが、コレまであったPlannerよりもシステム開発に向いたタスク管理ができます。

#Plannerとの使い分け
元々あったplannerと出来る事は大きな違いはありません。
じゃどう使い分けるのか？

## Planner
外部とのやり取りや大きなタスクについて使うとよさげです。

## Lists
開発の細かいタスク・・・WBSやToDoやTaskの管理に便利です。
つまりExcelファイルを卒業できます！
是非！
Mac起動音のOn(Off)に切り替える方法

電源ONや再起動したときに鳴る「ジャーーン」というやつです。
過去にも備忘録として書きましたが、新しいコマンドが見つかったので再び備忘録として書きます。

過去の記事: [【備忘録】Macの起動音を消す方法 - Qiita](https://qiita.com/ymmmtym/items/f58ab2195f7dd67e1e48)

使用しているもの

- macOS Catalina
- 2016年より古いモデル(デフォルトで起動音がなる仕様)

# Macの起動音をOn/Offに切り替える方法

ターミナルで以下のコマンドを実行してください。

**Onにするコマンド**

```bash
sudo nvram StartupMute=%00
```

**Offにするコマンド**

```bash
sudo nvram StartupMute=%01
```

**現在のOn/Offを確認するコマンド**

```bash
nvram -p | grep StartupMute
```

Offの場合の出力例

```console
$ nvram -p | grep StartupMute
StartupMute	    %01
```

私は起動音をOffにする派ですが、
macOSをCatalinaにアップグレードしたタイミングでOnになっていたようです。

## Reference

[Bring back your Mac's startup chime with this simple terminal command - 9to5Mac](https://9to5mac.com/2020/02/21/bring-back-mac-startup-chime-command/)
機械学習概論　メモ書き

[Aidemy](https://aidemy.net/)　2020/9/30
#はじめに
　こんにちは、んがょぺです！文系大学生ですが、AI分野に興味が湧いたのでAI特化型スクール「Aidemy」に通い、勉強しています。ここで得られた知識を皆さんと共有したいと思い、Qiitaでまとめています。以前のまとめ記事も多くの方に読んでいただけてとても嬉しいです。ありがとうございます！
　今回は機械学習概論について、重要なところのメモ書きを行なって行こうと思います。


#機械学習概論1　要点
・機械学習には__「教師あり学習」「教師なし学習」「強化学習」__がある。
・教師あり学習は学習データと正解（教師）データを与えて正解するまで思考する方法。最頻。
・教師なし学習は学習データのみを与え、コンピュータ自身が規則性を見つける方法。
・強化学習は、行動主体が得られる利益（報酬）を最大化するよう思考し続ける方法。

#機械学習概論2　要点
・__教師あり学習の手順__：データ収集→データクレンジング→学習→テストデータでチェック→実装

・__教師あり学習の実践1__：ホールドアウト法：データを学習データとテストデータに分けて使用。train_test_split()関数を使う。
__X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=テストデータの割合,random_state=0)__
＊Xは正解ラベル以外、yは正解ラベル。trainが学習データ、testがテストデータ。random_stateはテストデータを選ぶseed。

・__教師あり学習の実践2__：k-分割交差検証：データをk分割しそのうち１つをテストデータとして使用。テストデータを毎回変えて計k回検証してその平均性能を算出する。（ex 20個のデータなら、19個を学習データ、1個をテストデータとし、計20回検証する）

・__過学習__：学習の精度が高すぎて適切に抽象化できず、未知のデータに対応できない状態。
・__ドロップアウト__：過学習回避の手段。明らかな例外を無視する。
・__アンサンブル学習__：複数のモデルに学習させ、結果の平均を取ることで精度を高める。

#機械学習概論3　要点
・__混同行列__：モデルの精度を評価する際に使われる表。結果を__「真陽性」「偽陽性」「真陰性」「偽陰性」__に分類する。「真偽」は正解したかどうか、「陽陰」はモデルの解答を示す。（つまり「偽陽性」なら、モデルはTrueと解答したが、答えはFalseだったということ）

・混同行列の実装：以下のように記述（「y_true」には[正解のリスト]を、「y_pred」には[モデルの解答のリスト]を与える。）

```python
from sklearn.metrics import confusion_matrix
#「正解」と「解答」をリストで定義(0が陽性、1が陰性)
y_true=[1,1,1,1,1,1]
y_pred=[1,1,1,0,0,0]

confmat = confusion_matrix(y_true, y_pred)
#[[0 0]   #[[真陽性　偽陰性]
# [3 3]]  # [偽陽性　真陰性]]
```

・__正解率__：全解答のなかで、「真」だった割合。（真陽性＋真陰性/全体）
・__適合率/精度__：「陽」と解答したもののうち、「真」だった割合。（真陽性/真陽性＋偽陽性）
・__再現率__：「実際の陽」のうち、「真」だった割合。（真陽性/真陽性＋偽陰性）
・__F値__：適合率と再現率の調和平均（2＊適合率＊再現率/適合率＋再現率）
*これらは全て０〜1で表され、1に近い方が性能が良いと言える。

・上記評価指標を実装：関数をインポートして、それぞれ「y_true」と「y_pred」を引数として与えることで計算してくれる。

```python
#precision_score：適合率, recall_score：再現率, f1_score：F値　のインポート
from sklearn.metrics import precision_score,recall_score,f1_score

y_true=[0,0,1,1]
y_pred=[0,1,1,1]
#F値の出力
print("F1".format(f1_score(y_true,y_pred)))
# 0.666666
```

・__PR曲線__：縦軸に適合率（Precision）、横軸に再現率（Recall）をとったグラフ。
・__適合率と再現率はトレードオフの関係__であり、場合によってどちらに重きを置くかを考える必要がある。特にこだわりがない時は、F値や、PR曲線においてPとRが一致する点（__ブレークイーブンポイント（BEP）__）を用いると良い。
Webpacker::Manifest::MissingEntryError in  モデル名　のエラーを解決

# Webpacker::Manifest::MissingEntryError in が出た時の対処
Rails アプリを作った。Rails s でサーバー起動後に出た。

## 自分の環境
Rails 6.0.3.3
ruby 2.6.5

## エラー

Webpacker can't find application in /Users/user/acne/public/packs/manifest.json. Possible causes:
1. You want to set webpacker.yml value of compile to true for your environment
   unless you are using the `webpack -w` or the webpack-dev-server.
2. webpack has not yet re-run to reflect updates.
3. You have misconfigured Webpacker's config/webpacker.yml file.
4. Your webpack configuration is not creating a manifest.
Your manifest contains:
{
}

##　対処
Webpacker can't find application in /Users/user/acne/public/packs/manifest.json. Possible causes:

って書いているので探してみたら、対象のフォルダ/ファイルがない。
packs/manifest.json.

したがって自分で作ったら起動完了した。

##　根本解決になっていませんでした。
上記の方法だとないフォルダを無理やり作っただけで、なぜ生成されないのかは解決されていませんでした。

私の場合はwebpacker インストール時にnode のバージョンの範囲が違うと出ていたのを無視して進めていました。

記事執筆時はnodeのバージョンは１２までの範囲、私の場合は1３系が入っていました。

これを１２に落とすことにより無事解決しました。nodeのバージョン管理も適当だったので、変更するのもやれやれでした。
SQLの基本について

Railsを使ってたこともあり,active_recordsに頼りきだったため、SQLについて学んで来なかった。今回はスッキリわかるSQL入門を読み、SQLの基礎について学んだため備忘録としてまとめる。

##基本的な文法
まず、基本的な文法についてまとめます。
###SELECT文（データを取り出す）
```:SELECT文
SELECT カラム名
FROM   テーブル名
WHERE  制限

例:
SELECT 口座番号, 名義, 残高
FROM   口座
WHERE  残高 > 0
```
###INTSERT文（データ追加）
```:INSERT文
INSERT INTO テーブル名
VALUES      (データ追加カラム1, データ追加カラム2, データ追加カラム3） 

例:
INSERT INTO 口座
VALUES      ('00000202', 'GOTO TARO', 20000）

```
###UPDATE文（データ更新）
```:UPDATE
UPDATE テーブル名
SET    カラム1 = 内容１, カラム2 = 内容2, カラム3 = 内容3
WHERE  制限

例:
UPDATE 口座
SET    名義 = 'ARATA OSORU'
WHERE  口座番号 = '00002222'
```
###DELETE文（削除）
```:DELETE文
DELETE FROM テーブル名
WHERE       制限

例:
DELETE FROM 口座
WHERE       名義 = 'ARATA OSORU'
```

##応用（よく使う）
SQLのよく使う文法をまとめます。
###テーブル結合
```:テーブル結合
SELECT 選択別リスト
FROM   テーブルA
JOIN   テーブルB
ON     両テーブルの結合条件

例:
SELECT 取引番号, 日付, 取引事由名
FROM   取引
JOIN   取引事由
ON     取引.取引事由id = 取引事由.取引事由.id
```
###複数のテーブル関連
☆UNION（検索結果を足し合わせた結果を返す）

```
SELECT  選択別リスト　
FROM    テーブル1
UNION
SELECT  選択別リスト
FROM    テーブル1

例:
SELECT  口座番号, 名義　
FROM    口座
UNION
SELECT  口座番号, 名義
FROM    廃止口座
```
他にも
・EXCEPT（ある集合と別の集合の差をとる）
・INTERSECT（2つのSELECT文に共通する行を集めた集合）
などがある。

##大切なこと
息を吸うようにSQL文を打てるようにするためには、毎日SQLを書くことが一番だと思う。
他にもたくさん、修飾句があるので常に学び続ける必要がある。

参考文献
スッキリわかるSQL入門
ML5で超簡単PoseNet(姿勢認識）

ML5で簡単PoseNet(姿勢認識）

PoseNetという姿勢を検知する定番のAIがある。

まともにプログラミングするとかなり大変だ。

しかしML5というTensorFlow系のAI啓蒙慈善組織が、親切にもこれを簡単にするライブラリを作成し公表してくれている。

このライブラリを用いて作成されたPoseNetが、サンプルで載せられていたので、今回BlogSpot版にしてみた。

ML5はYoloとMobileNetで利用した。ただ、コールバックのスタイルが制御をML5に渡している形式なのでしばらく敬遠していたが、この簡単さは制御を渡して余りあるだろう。

https://randomwalkjapan.blogspot.com/2020/09/ml5poseneteasy-posenet-by-ml5.html

![POSENET.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373401/cf1ec838-cca7-cc85-32f9-430700ec6ef5.jpeg)
Quip APIを作成してみた

## はじめに
Quip上のスプレットシートに保存されたテキストを解析するために、Quip APIでQuipの特定のドキュメントにアクセスした。その際のアクセス方法を個人用にメモしておく。
※個人メモなので省略しまくってます。

### Access Tokenの取得

POSTMANでTokenを取得する。
詳しくは、[Quip API Documentation](https://quip.com/dev/automation/documentation)を参照

```

GET https://platform.quip.com/1/users/current
```

### 実際にアクセスする
[Github](https://github.com/quip/quip-api)上のスプレットシートを取得する関数を用いてフォルダとドキュメントを取得する。


```quip_analysis.py

import quip

# access to the quip
client = quip.QuipClient(access_token=<access_token>)

# Get your thread_id from the URL of your document
user = client.get_authenticated_user()
starred = client.get_folder(user["starred_folder_id"])

# get the spreadsheet
spreadsheet = client.get_second_spreadsheet(thread_id=<thread_id>)
parsedSpreadsheet = client.parse_spreadsheet_contents(spreadsheet)
```

スプレット形式のデータを取得できるのでデータフレームに落とし込む

```quip_analysis.py
# create the dataframe
    counter = 0
    spreadsheetData = []
    colNames = []

    for rows in parsedSpreadsheet["rows"]:
        cells = rows["cells"]
        rowData = []
        for key, value in cells.items():
            if counter == 0:
                colNames.append(key)
            rowData.append(value['content'])
        spreadsheetData.append(rowData)
        counter += 1   
    l = pd.DataFrame(spreadsheetData, columns=colNames)
```
このあと形態素解析でドキュメント上の頻出ワードを抽出した。
Utf8JsonでDictionaryのキーにCustom Formatterを利用する

# はじめに

.NETでJSONを扱うにあたり、Utf8Jsonというライブラリがあります。

- [Utf8Json](https://github.com/neuecc/Utf8Json)

UTF-8ネイティブな.NET用のJSONライブラリには[System.Text.Json](https://docs.microsoft.com/ja-jp/dotnet/api/system.text.json?view=netcore-3.1)もありますが、参照型を扱う場合にデフォルトコンストラクタが必要なことから、私はUtf8Jsonを使うことがあります。

ここではUtf8Json使う場合に、Dictionaryオブジェクトのキーに組み込み型ではない、自作のクラスや構造体を使う方法を紹介したいと思います。

# 対象の自作クラス

こんなImmutableなデフォルトコンストラクタを持たないクラスや構造体を、Dictionaryのキーに利用します。

```csharp
    public readonly struct EmployeeId
    {
        public EmployeeId(int intValue)
        {
            IntValue = intValue;
        }

        public int IntValue { get; }
    }
```

# Custom Formatterを実装する

Utf8Jsonでは独自クラスでJSONのシリアライズを明示的に指定したい場合、IJsonFormatterを実装する必要がありますが、Dictionaryのキーに利用する場合は、IJsonFormatterに追加してIObjectPropertyNameFormatterを実装する必要があります。
EmployeeIdの例では、intのプロパティのみをシリアライズ・デシリアライズしたいので、Formatterを次のように実装します。

このとき、JSONの仕様上、連想配列（Dictionary）のキーは文字列である必要があるため（ @ktz_alias さんに指摘いただきました。ありがとうございました！）、異なるインターフェースIObjectPropertyNameFormatterで変換を実装します。

```csharp
public sealed class EmployeeIdFormatter : IJsonFormatter<EmployeeId>, IObjectPropertyNameFormatter<EmployeeId>
{
    public void Serialize(ref JsonWriter writer, EmployeeId value, IJsonFormatterResolver formatterResolver)
    {
        writer.WriteInt32(value.IntValue);
    }

    public EmployeeId Deserialize(ref JsonReader reader, IJsonFormatterResolver formatterResolver)
    {
        return new EmployeeId(reader.ReadInt32());
    }

    public void SerializeToPropertyName(ref JsonWriter writer, EmployeeId value, IJsonFormatterResolver formatterResolver)
    {
        writer.WriteInt32(value.IntValue);
    }

    public EmployeeId DeserializeFromPropertyName(ref JsonReader reader, IJsonFormatterResolver formatterResolver)
    {
        return new EmployeeId(reader.ReadString());
    }
}
```

# Custom Formatterを利用する
標準のFormatterに追加して、上記のFormatterを利用したい場合、つぎのように実装しましょう。

```csharp
CompositeResolver.RegisterAndSetAsDefault(
    new IJsonFormatter[] {new EmployeeIdFormatter()},
    new[] {StandardResolver.Default});

var employeeNames = new Dictionary<EmployeeId, string>
{
    [new EmployeeId(0)] = "Steve Jobs", 
    [new EmployeeId(1)] = "Bill Gates"
};
var jsonBytes = Utf8Json.JsonSerializer.Serialize(employeeNames);
```

これで次のようなJSONが得られます。

```json
{"0":"Steve Jobs","1":"Bill Gates"}
```

以上です。
numpy で画像データの lookup 処理をするメモ

* インデックスの画像データ(e.g. 物体の ID とか)から, 数値や色を lookup して画像データを作りたい
* np.digitize の逆操作をしたい

Is there a convenient way to apply a lookup table to a large array in numpy?

https://stackoverflow.com/questions/14448763/is-there-a-convenient-way-to-apply-a-lookup-table-to-a-large-array-in-numpy

ありがとうございます.

`lut[img]`, `np.take` や `cv2.LUT` でやる方法があります.
PHP Laravel 6 おすすめ映画投稿サイト作成過程 2:一覧ページ作成編

#viewファイルの追加
一覧を表示するため、今回は新たに作成したrecommensディレクトリにindex.blade.phpを作成しました。
![Screen Shot 2020-09-23 at 13.18.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/736153/cb148420-862f-ee5f-7fb9-287f738d8900.png)

#コントローラーの設定
コントローラー側では$recommendsをviewに渡します。

```recommend/app/Http/Controllers/RecommendController.php
  public function index()
    {
      $recommends = Recommend::all();
        return view('recommends.index', ['recommend' => $recommends]);
    }
```

#ダミーデータの入力
５件のダミーデータを入力します。
今回は、未入力が許されないタイトルとURLのみ指定します。

####useにコントローラーモデルを追加

```recommend/database/seeds/RecommendSeeder.php
 use Illuminate\Database\Seeder;//元から記載されている。
 use App\Models\Recommend; //追加。
```

####for文で５件のダミーデータを作成
```recommend/database/seeds/RecommendSeeder.php
 public function run()
    {
      for($i = 1; $i < 6; $i++){
        Recommend::create([
          'title' => 'test{$i}',
          'url' => 'url{$i}'
        ]);
      };
    }
```


####上記をデータベースシーダーに流し込む
```recommend/database/seeds/DatabaseSeeder.php
 public function run()
    public function run()
    {
        $this->call(RecommendSeeder::class);
    }
```

####シーダーを実行
```console
 $php artisan db:seed
```

####以上でダミーデータ作成完了です。



#index.blade.phpでDB一覧の表示
今回は、タイトルとタイトル画像を一覧で表示することにします。
手段はforEachでの展開です。

```recommend/resources/views/recommends/index.blade.php
@foreach($recommends as $recommend)
   <tr>
      <th>{{$recommend->title}}</th>
      <th>{{$recommend->url}}</th>
   </tr>
@endforeach

```

#ページネーション
表示数が多くなった場合には、以下の方法でページを分割することができます。
（加筆予定）
[JavaScript] includesメソッドの使い方

JavaScriptのIncludesメソッドについて簡単まとめたので、備忘録もかねて記事を書きます。

# includesメソッドの概要

includesメソッドを使うと、配列式や文字列の中から特定の要素、文字列が含まれているかチェックをすることができます。
以下、実際の例です。

# 配列

特定の要素が配列内に含まれるかチェックし、true or falseを返します

```js:例１
const test = ["foo", "bar"];

console.log(test.includes("foo")); // true
console.log(test.includes("baz")); // false
```

　　
第２引数を指定することで、検索を開始する位置を指定することができます。

```js:例２
const test = ["foo", "bar", "baz"];

console.log(test.includes("foo", 0)); // true
console.log(test.includes("foo", 1)); // false
```

# 文字列

文字列に対してもincludesメソッドは利用できます。

```js:例3
const test = "includesメソッド";

console.log(test.includes("メソッド")); // true
console.log(test.includes("関数")); // false
```


大文字小文字は区別されます。

```js:例4
const test = "includesメソッド";

console.log(test.includes("includes")); // true
console.log(test.includes("INCLUDES")); // false
```


大文字小文字の判定で困ったときは、toLowerCase or toUpperCaseが使えます。

```js:例５
const test = "includesメソッド";

console.log(test.includes("INCLUDES")); // false
console.log(test.toUpperCase().includes("INCLUDES")); // true
```

# indexOfメソッドとの違い

indexOfメソッドが、指定した要素が含まれている場合はその位置（インデックス）を、含まれない場合は-1を返します。
取得した要素に対し、何か処理を加えたい場合は、こちらを使うのが良いでしょう。

```js:例６
const test = ["foo", "bar", "baz"];

console.log(test.indexOf("baz")); // 2
console.log(test.includes("faa")); // -1
```

　

最後まで読んでいただきありがとうございますm(__)m
備忘録（構想設計とプログラムの分割）

**pythonで自動化とかできるんでしょ～？よろしく～、って言われたので頑張る記録　その4**

2020/9/25 改定
内容全く別物に変わりました問題が発生し、頭を抱える。
とりあえず変更後の仕様を改めて書く

**～～結論だけ先に書いておく～～**
特にpython実装上の何かは無い

<details><summary>**～～どうでもいい日記～～**</summary> 制作しているの大半がファイルが非リスト形式で頭を抱える。
ひとまず、「こういう入力データがあればこんな感じで自動化できます」、と言うところまで纏まれば協力してくれるらしいが・・・本当かな・・・嘘くさいな・・・。
仕方ないのでひとまず設計仕様を纏めることにした
**～～ここまで日記～～**</details>

やるべきことを取りまとめると、下記のようになる。
①から順に取り組むこととする。

①図1の生データに対し、「社員名と作業時間以外が同じ値ならば作業時間を統合する」処理をかける（社員名は不要なデータなので省く）

②表1の対照表を使って各行に設定1/設定2を付ける

③設定1ごとの合算時間を算出し、カレンダー形式にして表2のように出力
　また、日付ごとの最頻出の国名を見出しにすること。

④一ヶ月分のデータから設定2ごとに合算時間を算出し、図3に示すようなグラフと表を生成する。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/721074/2e6e2677-4b1c-1e61-8064-96500f821978.png)
　　　　　　　　　　　　　　　　図1　元データ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/721074/2999f76b-f21d-9b8b-36d0-b7503ba90459.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/721074/7df89b1f-2ce9-3845-b665-b0b606b67825.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/721074/3c85ee8f-74f7-c3bf-022c-f3ba7aa9b860.png)
　　　　　　　                 図３　グラフと表
【自分用メモ】BufferedReaderを使用したファイルの読み込み

FileReaderは一文字ずつ読み込むメソッド。
これをBufferingFilterを使用して、処理効率を上げよう！

```java

package practice1;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class Read {

	public static void main(String[] args) {

		//FileReader=1文字ずつ読み込む動き
		//BufferedReader=一定数読んでため込んで、たまったら放出（普通は一行ずつ）
		
		FileReader fr=null;
		BufferedReader br=null;
		
		//finallyメソッドでclose処理ができるように、tryメソッドの外側で宣言。
		//もしtryメソッド内で宣言してfinallyメソッドでclose()しようとするとローカル変数重複になる。

		try {
			fr=new FileReader("c:\\work\\filetest.txt");
			//あらかじめc:に作っておいたworkフォルダにfiletestファイルを作って以下の処理で使用
			br=new BufferedReader(fr);
			//読み込み と ためこみ放出 の機能を組み合わせ！

			String brLine=br.readLine(); //brLineに代入することで、1文読んだ後に正しく出力できる。
			while(brLine!=null) {
				System.out.println(brLine);
				brLine=br.readLine();
			}


		}catch(IOException e) {
			e.printStackTrace(); // //エラーの詳細を、コンソールに赤文字で表示させるクラス
			//System.out.println("読み書きのエラーが発生しました");

		}finally { //try-catchブロックがどう動いたとしても最後に必ず実行するfinallyメソッド
			if(br!=null) {
				try {
					br.close();
				}catch(IOException e) {}//中身はカラでもいいし、エラーメッセージを出力してもいい
				
			}
			if(fr!=null) {
				try {
					fr.close();
				}catch(IOException e) {}//中身はカラでもいいし、エラーメッセージを出力してもいい
			}
		}
	}
}


```