OmniAICreator/Qiita-1.07M huggingface dataset:
M1のMACでOpenCV導入に苦労した話

# はじめに
<!-- 発端や概要を記載 -->
M1のMacBookAirを購入して意気揚々とOpenCVで遊ぼうと思ったら色々苦労したのでメモします。
もっといい方法はあると思いますので、ご参考までに。
Qiitaも初心者なのであしからず

# 目次
<!-- タイトルとアンカー名を編集 -->
1. [環境](#Chapter1)
1. [導入方法](#Chapter2)
1. [参考文献](#reference)

<!-- 各チャプター -->
<a id="#Chapter1"></a>
# 環境
・マシン：MacBookAir 2020 M1
・Python：3.8.2（最初から入ってた）
<a id="#Chapter2"></a>
# 導入手順
①Xcodeをインストール（不要かも）

②Homebrewをインストール（不要かも）

※注意：bashからzshなるものが一般的になっていました。
      Pathを通す時は、.zshrcを書き換える必要があります。

④Cmakeをインストール（不要かも）
numpyインストール時にcmakeが〜とエラーが出たので念の為。。。

```
brew install cmake
```
③Anacondaをインストール　[ここを参照](https://sukkiri.jp/technologies/ides/anaconda-mac_install.html)

④OpenCVをインストール [ここを参照](https://hawk-tech-blog.com/python-opencv-setup/)
※注意1：Python3.8ではAnacondaのOpenCVを導入できないので3.7する必要あり
※注意2：GPUモジュールが入っていない奴じゃないと、実行時にエラーを吐きます。

```shell
pip install opencv-python-headless : main モジュールのみ
```

⑤実行！
テストコードはこんな感じで


```python
import cv2

img = cv2.imread('image.jpg')

cv2.imshow("image", img)
cv2.waitKey(0)
cv2.destroyAllWindows()

```

以上！
初学者の為のスクレイピング(Ruby)

始めてスクレイピングをやり、
うまくいったので、自分のメモとして残しておきます。


```ruby:yahoo_scrape.rb
require 'open-uri'
require 'nokogiri'

url = 'https://www.yahoo.co.jp/'
 

doc = Nokogiri::HTML(open(url))
 
puts 
doc.css('h1').each do |link|
  puts link.content
end
```
【Firebase Cloud Functions】CORS Errorに対応する


## 症状

こちらの動画：[【013】Cloud FunctionsとExpressでREST APIの型を作る【Firebase】](https://youtu.be/PmRUHEnsVQ8)でFirebaseのcloud functionsの学習を進めておりましたが、Postmanにて、以下の**CORS Error**が発生。


```
CORS Error: The request has been blocked because of the CORS policy
```

## 原因

異なるオリジンのリソースへのアクセスに制約がかけられていることが原因。

### CORSとは

**C**ross-**O**rigin **R**esource **S**haring の頭文字を取った略語で、
異なるオリジン間でリソースを共有するための仕組み。

オリジン（origin）はドメイン(domain)と似ていますが、ポート番号も含む形のことを言うそうです。

▼CORSについての詳細はこちら。
[なんとなく CORS がわかる...はもう終わりにする。](https://qiita.com/att55/items/2154a8aad8bf1409db2b)


## 対策

アクセスに制約がかからないように以下の対応を行います。

1. corsライブラリをインストール
2. `origin:true`に設定する

### 1.corsrライブラリをインストール
まずは cors と @types/cors をインストール。

```
npm install --save cors
npm install --save-dev @types/cors
```

### 2.`origin:true`に設定する

`const cors = require('cors');`と`app.use(cors({ origin: true }));
`を追加します。

```typescript:index.ts
import * as functions from 'firebase-functions';
import express from 'express';
import messagesRouter from "./routers/messages/route";
const cors = require('cors');
 
const app = express();
// Automatically allow cross-origin requests
app.use(cors({ origin: true }));
app.use('/', messagesRouter);

export const api = functions
  .region('asia-northeast1')
  .https
  .onRequest(app);
```

セキュリティ的には問題あるのかな？
Notes文書の添付ファイルを取得するLotusScript

Notesマイグレーションでは、Notes文書だけではなく、文書に添付されたファイルも移行する必要があります。Notes文書から添付ファイルを抽出する方法はヘルプに記載がありますが、こちらの記事にあるように正常に動作しません。（doc.EmbeddedObjectsの値がNullとなる）

- [NotesdocumentクラスのプロパティEmbeddedObjectsをForallでループする際にエラー](https://qiita.com/nomori/items/e10abdf5124392e202cb)

文書の添付ファイルを取得する処理は、文書に単一のリッチテキストフィールドが存在する場合と文書に複数のリッチテキストフィールドが存在する場合を考慮する必要があります。（それぞれのリッチテキストフィールドに、添付ファイルがある場合、ない場合、複数ある場合の組み合わせも考慮する必要があります。）

上記を踏まえて以下の関数を記載しました。

```
Sub Initialize
	Dim ss As New NotesSession
	Dim db As NotesDatabase
	Dim dc As NotesDocumentCollection
	Dim doc As NotesDocument
	
	'Set db = New NotesDatabase("Server","FilePath")
	Set db = ss.CurrentDatabase
	'--データベースの全てのNotes文書を取得
	Set dc = db.AllDocuments
	'--Notes文書を順次に取得
	Set doc = dc.GetFirstDocument
	While Not ( doc Is Nothing )
		'--Notes文書の全フィールド(Item)を順次に取得
		ForAll item In doc.Items
			'--フィールドがリッチテキストであれば
			If (item.Type = RICHTEXT ) Then
				'--リッチテキスト内の全てのオブジェクトを参照
				ForAll object In item.EmbeddedObjects
					If (object.Type = EMBED_ATTACHMENT) Then
						'c:¥Temp以下にオブジェクトを書き出す
						Call object.ExtractFile("c:¥Temp" & object.Source)
					End If
				End ForAll
			End If
		End ForAll
		Set doc = dc.GetNextDocument(doc)
	Wend
End Sub
```

※ 添付ファイルの出力先フォルダにはアクセス権限の付与が必要。
※ 同名のファイルが作成済の場合は、無条件で上書きされる。

（ここから、さらに添付ファイルの種類を判定することもあったりするのですが、それは別途で記載をする予定です。）
Excel 2019 for Mac Openステートメントについて

#Excel 2019 for Mac Openステートメントについて

[前回](https://qiita.com/EugenesWorks/items/f802a8680836de951ab8)、[前々回](https://qiita.com/EugenesWorks/items/ec63757761d80179b6c5)で少し触れていましたが、Openステートメントでテキストファイルの出力をする際、Excel 2019 for Macでは存在するパスであっても指定パスによってはエラーが発生し、処理が中断されます。今回はどのパスが問題が発生するのかを検証種類は少ないながらも書いていきたいと思います。

##検証パスの種類と検証コード

1. ライブラリーフォルダ(com.microsoft.Excelフォルダ)
2. 共有フォルダ
3. 日本語の入ったパス

1.のライブラリーフォルダはアクセスできれば[AppleScriptTask関数](https://qiita.com/EugenesWorks/items/f802a8680836de951ab8)の利用が容易になるのでできれば成功して欲しいところです。

2.はパスの直書きが可能なので予備として保存先として利用できます。

3.はフォルダに日本語で名前を付けるのは案外ありますが、経験上難しいかもしれません。

コードは実際に動かしたものと若干違いますが、ほぼ以下の通りです。

~~~
Dim root As String
Dim path1 As String
Dim appscript As String

root = ActiveCell.Value
path1 = root & Application.PathSeparator & "test.scpt"

applescript = "Hello"

Open path1 For Output As #2
    Print #2, applescript
Close #2

~~~

##結果

![pathresult.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/965663/bee48b19-fcb4-b7a2-d61d-7c5cd3dd7334.png)
1.ではアクセス権の付与ダイアログも表示されず、すぐに以下のエラーが表示されました。やはりセキュリティ上の観点でアクセスできないようです。
![librarypatherr.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/965663/f095ac7a-bc69-e6a2-37c3-a649d9a4baf9.png)

2.は問題なく保存できました。
![スクリーンショット 2020-12-28 12.06.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/965663/750a6768-b2c5-c24b-ca3d-0350e201b6bc.png)

3.はアクセス権の付与ダイアログが表示され、付与作業が終わった後に1.と同じエラーが発生しました。

やはり、予想通りでした。基本的にUsers/Sharedパスを利用した方が無難かもしれません。


私だけかもしれませんが、長くExcel for MacのVBAを触っている又は、海外製の工業向けプログラムを触っている方は自然とフォルダ名を英数字で記入する癖が付いているのではないでしょうか。Windows版のExcelのように扱える日がくるのはもう少し先のようです。
DockerコンテナにRailsの環境変数を適用させる方法(aws::Sigv4::Errorsの解決法)

# はじめに

Dockerを導入しコンテナを起動し、動作確認のために画像投稿したら以下のエラーが発生。
沼にハマったので解決法をメモします。

![aaaaa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/879778/0f24ed23-113b-39b4-fcc7-87e458ee75f6.png)

# 解決方法

結論から言うとS3導入後の**「環境変数がない」**というのが原因です。
自分は、ローカルで設定したし`source ~/.zshrc`も行って、うまくできているはずなのに...と沼にハマりました(笑)

なぜローカルで環境変数を設定して読み込んだのにエラーが起こるのか...

**理由はコンテナで環境変数を設定できていないから**です。
コンテナの概念は**「隔離された空間」**です。つまり、コンテナを作成・起動したら以前の`rails s`コマンドでサーバーを起動していた環境とは別の環境になっているということです。

もう解決方法は見えたと思いますが、コンテナ内にも環境変数を設定してあげれば解決できます。
そこで僕の場合は、コンテナ内でも、どの環境にも環境変数を１度設定するだけで適用できる方法を採用しました。
具体的には`dotenb-rails`というGemを導入しました。

# Gem dotenb-railsの導入

この`dotenv-rails`とは**環境変数を管理してくれるGem**です。
このGemを導入し、アプリディレクトリに`.env`ファイルを作成することで１つのファイルで環境変数を管理し、そのファイルに環境変数を設定するだけで全環境に環境変数を適用することができます。

## 1) Gemfileに記述

```ruby:Gemfile
gem 'dotenv-rails'
```

```ruby:ターミナル
bundle install
```

これで導入できました。
次に環境変数を設定していきましょう!

## 2).envを作成し環境変数を設定する

```ruby:ターミナル
touch .env
```

上記のコマンドを実行でも、エディタに直接作成していただいても構いません。
このファイルを作成し、設定したい環境変数を記述していきましょう。

環境ごとに環境変数を変えたい場合などは以下の記事がとても参考になるのでぜひ見てみてください。

[【Rails】dotenv-railsの導入方法と使い方を理解して環境変数を管理しよう！](https://pikawaka.com/rails/dotenv-rails)

ここでは.envの記述のみ解説します。

```ruby:.env
AWS_ACCESS_KEY_ID = '値'
AWS_SECRET_ACCESS_KEY = '値'
```

ターミナルで`rails c`を実行すると以下が出力されます。

```ruby:ターミナル
irb(main):002:0> ENV['AWS_ACCESS_KEY_ID']
=> '値'
irb(main):993:0> ENV['AWS_SECRET_ACCESS_KEY']
=> '値'
```

エラーの解決にはこの２つのみの設定で大丈夫ですが、他にも設定してある・したい方は記述を追加する必要があります。


## 3).gitignoreへの記述

環境変数の設定ができましたが、このままだとgitにpushしてしまった場合、環境変数の中身を**公開**することになってしまいます。

そのため.`gitignore`ファイルに`.env`を追記しcommit履歴に表示されないようにしpushを未然に防がないといけません。

```ruby:.gitignore
# １番下の行
.env
```

上記のように記述するだけでgitからは存在しないファイルとして扱ってもらうことができます。

## 4)環境変数の利用

これで環境変数の設定ができたので、後は使用したいところで呼び出すだけで利用できます。
非常に便利なGemなので、ぜひ使ってみてください

# 参考文献

[【Rails】dotenv-railsの導入方法と使い方を理解して環境変数を管理しよう！](https://pikawaka.com/rails/dotenv-rails)
評価指標をバッターで例える

バッティングセンターにて...

#Recall(再現率)
打てるボール（≒ストライク）をどれだけ見逃さず振っていくか

#Precision（適合率）
打てるボールだと判断して振った時にバットに当てたかどうか

#Specificity（特異率）
打てない球（≒ボール）にどれだけ反応しないか

#Accuracy（正解率）
打てる球/打てない球にそれぞれにどれだけふさわしい反応をしたか

---
といったところだろうか。。。？
.htacess の勉強メモ

## .htacessでできること
  - ベーシック認証
  - 301リダイレクト
  - URLの正規化
  - ファイル一覧表示の中止
  - 特定のIPアドレスやドメインからのアクセス制限

## 基本
・.htaccessでのリダイレクト処理は、Apacheで使用できるモジュールの１つ。
・mod_rewriteモジュールを使用する。

      <IfModule mod_rewrite.c>
          mod_rewriteが有効な場合だけ実行する処理をここに記述します
      </IfModule>


## mod_rewriteで使用するディレクティブ（命令文）
### RewriteEngine
  * mod_rewriteを有効にするか無効にするかを宣言できる。

### RewriteRule  
  * どのように書き換えるのかを指定できる。
RewriteRule {パターン} {置換内容}の形式をとり、{パターン}に一致したものを{置換内容}に書き換えます。[R]というフラグと併用（後述）し、リダイレクトを実行する。

### RewriteCond
  * どんな場合にリライトするかどうか、条件を指定できる 。
RewriteCond {条件}の形式をとります。RewriteRuleの前に記述。

### Options -Indexes
  * ファイル一覧を表示しないようにする

### フラグについて
  * RewriteRule の設定行に追加できるオプション
  * 基本的には、[R=301]、[R=302]のどちらかを設定します。( [R] と省略すれば [R=302] と同義です。)  
  * 301：恒久的なリダイレクト。検索エンジンが引っ越しと認識する
  * 302：一次的なリダイレクト。検索エンジンが（すぐには）引っ越しと認識しない

### ［L]
  * このフラグがあれば、この行でRewriteRule にマッチした場合、次の行に進むことまずに、その時点で処理を停止します。  
逆に、このフラグを忘れていて、次の行に別の RewriteRule 設定がまた記載されていれば、せっかくマッチしたリダイレクト先のURLが再度書き換えれてしまいます。  
また、上記の [R] フラグを利用するときは、必ず[L] を併記する必要があります（そうでない場合、エラーが発生していまいます）  
結果的に、RewriteRule を記載した行は、[R=301,L] と行末に記述することになるはずです。

## 例１ ：単純にドメインが変わるだけ（ディレクトリ構造そのまま）の引っ越し

例えば、example.com のドメインを、https://new-example.com へとリダイレクトしたいような場合。  
example.com直下の.htaccessファイルに以下を記述  


      <IfModule mod_rewrite.c>
      RewriteEngine On
      RewriteRule ^(.*) https://new-example.com/$1 [R=301,L]
      </IfModule>
[Linux]何となく使っていたシンボリックリンクでつまずいた時の話をしようか。

#内容

題名の通り、Laravelでシンボリックリンクを使用していたのですが、いざ本番環境にデプロイしたところ見事にローカル環境で設定していたシンボリックリンクがなくなっていました。
まず、ローカル時の段階であまりシンボリックリンクについて理解しないまま、使っていたため本番環境でつまずいてしまいました。
ちなみにローカル時のシンボリックリンクの指定方法については、下記の通りです。
参考:https://readouble.com/laravel/6.x/ja/filesystem.html

##環境

- Laravel6
- php(7.4.6)
- centos7(linux)
(pcはwindowsです。)

##シンボリックリンクとは

>シンボリックリンクとは、オペレーティングシステム（OS）のファイルシステムの機能の一つで、特定のファイルやディレクトリを指し示す別のファイルを作成し、それを通じて本体を参照できるようにする仕組み。
[引用](http://e-words.jp/w/%E3%82%B7%E3%83%B3%E3%83%9C%E3%83%AA%E3%83%83%E3%82%AF%E3%83%AA%E3%83%B3%E3%82%AF.html#:~:text=%E3%82%B7%E3%83%B3%E3%83%9C%E3%83%AA%E3%83%83%E3%82%AF%E3%83%AA%E3%83%B3%E3%82%AF%E3%81%A8%E3%81%AF%E3%80%81%E3%82%AA%E3%83%9A%E3%83%AC%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0,%E3%81%A7%E3%81%8D%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%E3%81%99%E3%82%8B%E4%BB%95%E7%B5%84%E3%81%BF%E3%80%82)

うん、確かにその通りだけど、わかりにくい。
自分なりに解釈したところ、
フォルダの中にフォルダを作成し、そのフォルダは自動的に指定したリンク先へ飛んでくれるってことです。
てことで概要がわかったので、実際に作成していきましょう。

##いざ実践

###やること
Laravelであれば、publicフォルダの中にそれぞれimg,css,jsのフォルダがあり、その中にそれぞれ画像やcssのファイル、jsのファイルを入れると思います。
そこから画像を取り出したいときは、階層を指定してとってきますよね。
そのため、publicフォルダの中にシンボリックリンクを指定しているフォルダを作成して、そのフォルダを指定すれば、自動的にリンク先に飛ぶので、リンク先の画像が取り出せるということです。

###コマンド操作

ちなみに私はローカル環境で

```
php artisan storage:link
```
と何も考えずに指定し、動かしていたので理解していませんでした。

そのため、今回はlinuxで直接指定する方法について記載します。

```
ln -s [リンク先] [フォルダの置き場]

//例
ln -s /var/www/test/storage/ /var/www/test/public
```

このようにコマンド指定すれば作成できました！


##まとめ

以上がシンボリックリンクに関しての内容になります。
やはり理解があまいままだとどこかでつまずきますね。笑
参考にさせていただいた記事は下記の通りです。

[参考](https://qiita.com/0084ken/items/6f39498c86fb592b2baf)
Raspberry Piでcronを使おうとしてスペースで詰まった話

#しようとしていたこと
ラズパイでcronを用いてpythonスクリプトを定期的に自動実行しようとする基本的な動作を行おうとした。具体的には、dht11温湿度センサによる温湿度の定期観測。csvファイルに書き込むプログラムをThonnyで直書きした。
#おち
cronを使うときは、スペースをチェック。特に/usr/・・・の前。
#環境
devices: Raspberry Pi3B+　センサー；dht11
OS: Rasbian NOOBS_ver_3_5_1
言語：Python 3
#問題
ターミナルで下記を実行した。

```
$ crontab -e
```
お好みのeditorでcron fileの最下部に下記のように記載（私はnanoを使用）
また、使用されているpython3がどこにあるかは、which python3とターミナルにきいた。

```
$ */1 * * * */usr/bin/python3 /home/pi/hoge/hoge1.py
```

動かいないので、ステータスを確認

```
$ sudo /etc/init.d/cron status
```

これがactiveである。
そして、cronの再起動

```
$ sudo /etc/init.d/cron restart
```

それでも動かいない。各種設定を施して、ログをみる

```
tail -f /var/log/cron.log
```

そしたら、1分おきに動いている。だが、csv fileには記録が残らない（書かれない）
なぞだ。

#解決策
すんごい初心者、ミスであった。

```
$ */1 * * * * /usr/bin/python3 /home/pi/hoge/hoge1.py
```

なんのその、/usrのまえに一つスペースがないときちんと動かいないようだった。
また、*のところにも、*/1はスペースなしでいけるが、* * * *のところは全部スペース１つずついれのだった。
cronの使い方の記事はたくさんあるが、スペースは当たり前なのかなかなか記事がなかったので、参考になればとここに残しておく。
AWSの勉強メモ

## ELB(Elastic Load Balancing)

        トラフィックを複数のインスタンスに分散する（オンプレでいうロードバランサー）
        ヘルスチェック機能を持っており、配下のインスタンスがヘルスチェックに失敗した場合、振り分けを停止する
        ヘルスチェックが回復した場合、振り分けを再開する
        暗号化・復号化（SSL）機能を利用できる

    3 種類のロードバランサー
     * Application Load Balancer
     * Network Load Balancer
     * クラシックロードバランサー 

## ELBのスティッキーセッション
ELBがサーバにリクエスト振り分ける際、特定のCookieを確認することで、
特定のクライアントからのリクエストを特定のサーバに紐付けることが出来る機能
  
###ELBのスティッキーセッションの設定は以下3つのパターン
    ・維持無し（スティッキーセッション無しの場合）
    ・ELBによって生成されたCookieの維持
    ・アプリケーションによって生成されたCookieの維持

  

### 維持無し（スティッキーセッション無しの場合）
リクエストはELBの負荷分散機能により、サーバに振り分けられます。
したがって、リクエストの度に異なるサーバに振り分けられる可能性があるため、
サーバでのセッション管理を前提としたシステムの場合は注意が必要です。

### ELBによって生成されたCookieの維持
ELBによって生成されるCookieによってリクエストの振り分けサーバが固定されます。
返信のリクエストがELBを経由する際にCookieが付加されます。

### アプリケーションによって生成されたCookieの維持
ELBでアプリケーションのCookie名を指定し、そのCookie情報をELBが確認して、
振り分けるサーバが固定されま


## CloudFront
・CDNの高速・高機能のアマゾンバージョン
・負荷を分散させ、大量のリクエストに対する対策を実施、通信にかかるレイテンシ（遅延）を改善する。

## 解決する問題
    ・サーバの付加軽減
    ・ネットワークのレイテンシの低減
php のちょっと難しい単語まとめ

## 参照渡しについて
     ・参照渡しは、変数で値を渡す際にコンピュータに変数の住所を渡す（メモリの領域の住所を渡す）。
     ・参照渡しされたものはどこかで値が変更された場合、元の変数の値も変化する。
     ・通常の参照渡しを行わない場合、関数内でreturnを行うが参照渡しの場合は必要なくなる。

## コンストラクタ
    ・クラスのインスタンス生成時に実行されるメソッド。
    ・主にそのクラスのメンバ変数を初期化するときに使用

## アロー関数　->  
    ・左辺にクラスのインスタンスを取る、右辺には左辺のクラスがもつプロパティやメソッドを指定し、
    プロパティへのアクセス・メソッドの呼び出しを実行する。

## 静的変数
    ・関数内に保存されるローカル変数
    ・通常、関数内のローカル変数は、関数の呼び出しが終了すると破棄される。
    そのため、呼び出すたびに値を増やしたい場合は対応できない。
    その場合、変数名に「static」キーワードを付けると、その変数は呼び出しが終了しても保存されるようになる。
    言い換えると、関数内で値を保存しておきたい場合は、静的変数(static)を使用する。
MySQLに変更してdb:migrateするとエラーになる。

#概要
RailsアプリでMySQLに変更してdb:createは無事完了。
続いてdb:migrateするとエラーになってしまう。

```
Mysql2::Error: Can't DROP 'uid'; check that column/key exists
```
```
ActiveRecord::StatementInvalid: Mysql2::Error: Can't DROP 'uid'; check that column/key exists
```


#原因
不要なマイグレーションファイルが原因。

```
bundle exec rake db:migrate:status　#マイグレーションファイルのステータスを確認。
```

```
   up     20201201080551  Devise create users
   up     20201204060220  Create microposts
   up     20201221072358  Add column microposts
  down    20201222055950  Remove from users
  down    20201222065441  Remove uid from users
  down    20201222065731  Remove provider from users
  down    20201222065821  Remove username from users
  down    20201222155423  Add column to users
```

#解決策
ステータスがdownになっているマイグレーションファイルを削除

```
rm -rf db/migrate/20201222055950_remove_from_users.rb 
rm -rf db/migrate/20201222065441_remove_uid_from_users.rb 
rm -rf db/migrate/20201222065731_remove_provider_from_users.rb 
rm -rf db/migrate/20201222065821_remove_username_from_users.rb 
rm -rf db/migrate/20201222155423_add_column_to_users.rb 
```
MySQLを再起動

```
sudo mysql.server restart
```
```
rails db:migrate
```
vue.jsについて勉強メモ

#### 単一ファイルコンポーネント
    画面の部品ごとにHTMLタグ・JavaScriptのコード・スタイルの3点セットで分割
    <template>
     <script>
      <style>
      
### Vue.jsとは
    Vue.js（ビュージェイエス）は，インタラクティブなUIを構築するためのJavaScriptライブラリです。
    Webサイト内のウィジェットや管理画面のダッシュボードといったビュー（view）層に特化しています。
    設計の特徴としてMVVMパターンに影響を受けています。


### Vue.jsのアーキテクチャ
#### リアクティブシステム
    フレームワークが備えている仕組み
    Vue.jsはDOMとJavaScriptのデータを同期するためにリアクティブなデータバインディングを提供します。
    HTMLテンプレート内でデータバインディングを指定することで，DOMとデータが同期され続けます。
    データを変更するたびにDOMが，DOMを変更するたびにデータがそれに応じて更新されます。
    このような双方向データバインディングにより，面倒なデータとDOMの同期から解放され，
    データ駆動的にアプリケーションを設計・実装することが可能になります。

#### コンポーネントシステム
    Vue.jsはUIをコンポーネント化する仕組みを持ちます。
    Webサイト/WebアプリケーションのUIをコンポーネントとして設計し実装すれば，高い再利用性やカプセル化で開発が楽になります。
    コンポーネントを組み合わせることで，大規模なWebサイト/Webアプリケーションの構築も容易になります。

#### レンダリングシステム
    Vue.jsは仮想DOM（Virtual-DOM）でDOMを高速にレンダリングします。
    他のライブラリ・フレームワークにも仮想DOMを採用しているものがありますが，Vue.jsではHTMLテンプレートでわかりやすく開発でき，
    かつ最適化された高速なレンダリングができるという優位性を持ちます。
    上述のリアクティブシステムと仮想DOMを組み合わせることで可能となりました。
    仮想DOMは特に意識せずに使えますが，より柔軟な動作を指定することも可能です。




### 基礎文法
#### ディレクティブ
    ディレクティブは，"v-"から始まるVue.jsで利用できる特別なHTMLの属性です。
    属性値の変化に応じたDOM操作や，DOMイベントのハンドリングを実現します。
    Vue.jsが標準で提供しているディレクティブの他に，自身でディレクティブを定義することも可能です。
    以降では，v-for, v-ifといったよく利用されるディレクティブについて取り上げます。
    
    #### リストレンダリング
    Vue.jsでは，v-forというディレクティブを利用して，配列のデータをリストレンダリングすることができます。

    var vm = new Vue({
    el: '#example',
    data: {
        items: [
        {
            name: 'みかん',
            price: 100
        },
        {
            name: 'もも',
            price: 300
        },
        {
            name: 'いちじく',
            price: 500
        },
        {
            name: 'メロン',
            price: 1000
        }
        ]
    }
    });

    <div id="example">
    <li v-for="item in items">
        <p>{{ item.name }} は {{ item.price }}円</p>
    </li>
    </div>


### Vue Routerの基礎
    ue.jsのプラグインとして公式に提供されているSPA構築のためのルーティングライブラリがVue Routerです。
    Vue Routerは，ページ遷移先URLに対応するViewのレンダリング管理機能の他にも，便利なフック関数や遅延ローディングなどの機能を持っています。
    インストールするにはスクリプトタグでVue.js本体に続けて読み込んでください。以下のようにjsdelivrなどのCDNサービスを使うと便利です


#### ルートの定義
    ルートとは，URLとViewの情報を保持する1つのレコードです。
    Vue Routerにおけるルートは，前回の記事で解説したVue.jsのコンポーネントを特定のURLにマッピングしたオブジェクトとして，
    ルーター初期化時のroutesオプションに設定されます。
    
    
    / ルートオプションを渡してルーターインスタンスを生成します
    var router = new VueRouter({
    // 各ルートにコンポーネントをマッピングします
    // コンポーネントはVue.extend() によって作られたコンポーネントコンストラクタでも
    // コンポーネントオプションのオブジェクトでも構いません
    routes: [
        {
        path: '/top',
        component: {
            template: '<div>トップページです。</div>'
        }
        },
        {
        path: '/users',
        component: {
            template: '<div>ユーザー一覧ページです。</div>'
        }
        }
    ]
    })

    // ルーターのインスタンスをrootとなるVueインスタンスに渡します
    var app = new Vue({
    router: router
    }).$mount('#app')


### SPAとは(シングルページアプリケーション)
    1つのHTMLをロードして，ユーザーインタラクションに応じて動的にページを更新するWebアプリケーション

### 参考
https://reffect.co.jp/vue/vue-js-basic
https://cr-vue.mio3io.com/guide/
https://router.vuejs.org/ja/guide/#html
ベーシック認証

## IP制限とダイジェスト認証のサーバ側の設定 
・Satisfy All　両方の認証必須
・Satisfy Any  片方のみでOK  

     例：hoge.conf
     <Directory "/var/www/vhosts/example.com/htdocs">
        Satisfy Any

        AuthType Basic
        AuthName "Abababa"
        AuthUserFile /var/www/vhosts/.htpasswd
        Require valid-user

        Order deny,allow
        Deny from all
        Allow from 192.168.1.0/24

        AllowOverride All
        Options Indexes FollowSymLinks
    </Directory>
    

## ベーシック認証
    MD5で暗号化する。
    認証をかけたいディレクトリに配置
    
    参考例
    https://test.com/entry/
    ID：3aGptestJeaje29
    PW：Lklsidonejhctest5
    
    .htaccess
    AuthType Basic
    AuthUserFile /www/test/html/entry/.htpasswd
    AuthName "auth"
    require valid-user
    
    .htpasswd
    3aGptestJeaje29:$apr1$eOdyc/hH$PBlbQsmy0IYm8UfTsHfSu/
    



###参考サイト
https://www.luft.co.jp/cgi/htpasswd.php
active-adminで管理者の新規登録をできなくする

ブログはこちらです．
https://wally-ngm.hatenablog.com/entry/2020/12/28/113312?_ga=2.221823768.120362624.1609122405-1426308614.1555332803


最近[active-admin](https://github.com/activeadmin/activeadmin)を使って管理画面を作ったりしてました．





ログイン画面を開くと管理者として新規登録ができてしまってとんでもないことになっていたので，できないようにする方法をメモっておきます．


## 管理者の新規登録をできなくする方法
active-adminではdeviseが使われていて，deviseの設定によってログイン画面の機能も変わってくるようです．

deviseの設定はmodelに書かれていますのでこれを変更します．

おそらく最初はこんな感じです．

```
class AdminUser < ApplicationRecord
  devise :database_authenticatable, :registerable, :recoverable, :validatable
end
```


`:registerable`を消すと，devise経由での新規登録ができなくなると同時に，active-adminの登録導線も消えます

```
class AdminUser < ApplicationRecord
  devise :database_authenticatable, :recoverable, :validatable
end
```


めっちゃかんたんでした．
toioがビジュアルプログラミングに接続できない場合

# この記事でできること
- toioがビジュアルプログラミングに接続できない場合、ESET Cyber Security のファイアウォールを解除することで接続できるようになります。

---

# 再現環境
- OS...Mac
- セキュリティソフト...ESET Cyber Security(ファイアウォールを有効)

---

# toioがビジュアルプログラミングに接続できない場合とは
- 下図のように、scratchLinkが推奨環境である1.3.66にも関わらず、ビジュアルプログラミングでtoioが接続できない状態が続きます。

![toioa02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/d48a2354-0d99-aed6-a8dd-bd9e127ba6d3.png)

![toioa01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/c5bbaf77-3493-1897-d633-ac11661b4cf8.png)

---

# 解決方法
- Macで、ESET Cyber Securityを使用している場合、下図のようにファイアウォールを一時的に解除することで、toioに接続することが可能となります。

![toioa03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/4c397e12-791d-380d-9b91-022f816a0c39.png)
![toioa04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/06d5679e-e712-5363-6c02-dc62ba932f91.png)

---

# それでも接続できない場合
- 下図のように、除外するプロキシに「*.scratch.mit.edu」を追記します。

![toioa05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/3a72639b-1e35-5dc6-406c-c1bd8389b9ec.png)

---

# toioの使用後は
- 忘れずに、ESET Cyber Securityのファイアウォールを有効に戻します。

---
Ruby　　if文について

この記事で説明すること
①if文とは
②if文の使い方
③elsifでさらに分岐


if文について上記の３点について簡単に説明していきたいと思います。


<h1>①if文とは</h1>

一言で言えば条件分岐を行うための文法です。

<strong>条件式を評価した結果が真である時、true以下の式を評価し、条件式が偽であれば elsifまたはelseの条件を評価します。</strong>

またifしか書かれていなければtrueの時しか処理は行われません。

if文では比較演算子をよく使われます。
「<」「<=」「>」「>=」「==」「!=」
一言で言えば比較するためのものですね！
比較演算子が気になる方は調べてください。

演算子の記事
http://www.tohoho-web.com/ruby/operators.html



<h1>②if文の使い方</h1>
ifの横に条件式を書きその下に処理を書きます。
さらに分岐をするときはelsifを使います（elsifはあとで説明します）。

```ruby
if 条件式1 then
    処理A　　条件式1がtrueのときに処理される
else
    処理B　全ての条件式がfalseのときに処理される
end

```

このif文の「then」は省略できます。以降省略形で記述します。


<h4>ifしか書かれていないパターン</h4>
```ruby
if 条件式1 
    処理A　　条件式1がtrueのときに処理され、falseなら何もしない
end

```

<h4>簡単な例</h4>

```ruby
if 0 < 10
    puts "trueです"
else
    puts "falseです"
end

#処理の結果はtrueなのでifの処理が実行される
```

```ruby
if 10 < 0
    puts "trueです"
else
    puts "falseです"
end

#処理の結果はfalseなのでelseの処理が実行される
```

<strong>条件式が「true」「false」ってどう言うこと...?</strong>

例えば
「if 10 < 0」と言う条件式は「0は10より大きくないので」falseになり
「if 0 < 10」と言う条件式は「10は0より大きいので」trueになります。


<h1>③elsifでさらに分岐</h1>

elsifとは...ifの条件式がfalseのとき、かつelsifのときの条件式がtrueのときに実行されます。

下の図で言えば
<strong>ifの条件式１がtrueなら処理Aを実行し、
条件式１がfalseかつelsifの条件式２がtrueのとき処理Bを実行し、
全ての条件式がfalseなら処理Cを実行することになります。</strong>



```ruby
if 条件式1 
    処理A　　条件式1がtrueのときに処理される

elsif 条件式2 
    処理B　　条件式1がfalseのとき、かつ条件式2がtrueのときに処理される

else
    処理C　全ての条件式がfalseのときに処理される
end

```

elsifを使えばさらに分岐ができるので条件を増やすこともできますね！


<h1>まとめ</h1>

①if文とは条件分岐を行うための文法
②ifの使い方...ifの横に条件式を書きその下に処理を書く
③elsifとはさらに分岐を増やすための記述


参考記事
https://docs.ruby-lang.org/ja/latest/doc/spec=2fcontrol.html#if


https://pikawaka.com/ruby/if
java 基本情報　勉強

## コンストラクタ
    ・インスタンスの初期化をおこなうためのもの
    ・名前とクラス名が同じで戻り値の型宣言もしない。
    

## 抽象クラス
    ・インスタンス化はできない
    ・クラス宣言でabstractキーワードを指定
    

## final

    ・修飾子の１つ
    ・その後の変更を不可にする
    ・クラスの場合、継承不可

## 継承
### extends(継承：インヘリタンス)
    ・基底となるクラスの性質を受け継いで、派生するクラスを生成する場合使用する。
    ・同じ記述は省略でき、違う部分だけを記述する
    ・上位クラス（スーパークラス、親クラス）のメソッドを使うときはsuperを記述する

### 継承のルール
    1.１つのスーパークラスから複数のサブクラスを作れますが、サブクラスから見ると、スーパークラスは１つしかありません。
    2.サブクラスはスーパークラスのフィールドやメソッドは引き継ぎますがコンストラクタやprivateなメンバは継承されません
Google Maps Javascript API で 複数のgeojsonファイルを描画する

この記事は [ちゅらデータアドベントカレンダーの23日目の記事](https://qiita.com/advent-calendar/2020/churadata) になります。

大大大遅刻してしまってすみません！年内に終わらせたい仕事があったんです（言い訳

# TL;DR

mapsのレイヤーを分けて作成してそれぞれにaddGeoJSON関数を適用させましょう。

```javascript
let map;
var area_layer1;
var area_layer2;

map = new google.maps.Map(document.getElementById('map'), {
        center: { lat: 26.27401341109744, lng: 127.72906195878593 },
        mapTypeId: google.maps.MapTypeId.ROADMAP
    });

area_layer1 = new google.maps.Data({map: map});
area_layer2 = new google.maps.Data({map: map});

area_layer1.addGeoJson(JSON.parse(geojson_string));
area_layer2.addGeoJson(JSON.parse(geojson_string));
```

# レイヤーごとにそれぞれ分ける理由

- addGeoJSONで読むことができるのは1つだけになってしまうため、1レイヤーに対して複数のgeojsonファイルを読み出すことができない
- 複数のgeojsonレイヤーにたいしてzIndexを用いた優先順位を付ける必要がある場合に、それぞれレイヤーごとに変数定義することで可能になる
- geojsonレイヤーの管理（map上への表示・削除)が簡単になる
質問の仕方

### ゴール
何を目的として実装やテストをしているのか、具体的に端的にまとめましょう。
ここがぶれていると問題は問題ではなくなることがあります。

### 現状

いま起きている現象について端的にまとめましょう。
エラーメッセージが出ている。いとした出力がないなどです。
### 実際に起きている不都合なこと

現状の何が不都合なのか説明できるようにしましょう。
ゴールとのギャップを正確に伝えられることは良い質問の第一歩です。

### 何をためしたか

実際になにか解決の手段を投じているならそれを伝えましょう。
もしかしたら解決策の方向性がまちがっているかもしれません。

検索段階でわからないなら実際に検索した言葉を伝えてみましょう。

### 質問にどう答えてほしいのか

何を答えとして望んでいるかを伝えましょう。
解決策を一緒に考えて欲しいのか、それとも方向性が間違っていないかみてほしいのか
答えをください。というのは最終手段ですが、どうしても解決できない時はそれも手段の一つです。


## 別パターン
###不具合が起きてるなーってとき
・本来はどうあるべきか？（希望）
・現状はどうなのか？

    例
    URLクエリパラメタに「XXXXXX」と「XXXXXX」を含めた場合、「XXXX」と「XXXX」にチェックが入るはずが、それ以外にチェックがついているようです。
    とか

    例２
URLクエリパラメタに「XXXXXX」と「XXXXXX」を含めた場合、「XXXX」と「XXXX」にチェックが入るはずが、そうなっていないようです

    見出しでわけて箇条書きでもいいかもです
    UIだったら、再現手順もかいたほうがいいかも
SVN　を利用するときのメモ

## SVN
### ファイルの状態
    ? はリポジトリ管理外
    M は、作業コピーを変更したを示す。（修正されたファイル）
    U 
    A は、追加されたファイル
    D は、削除されたファイル
    C は、競合しているファイル
    ! は、失われたファイル
    + は、コミット準備完了のファイル。
    
## SVNの流れ
    ・ファイル追加（元からあるファイルを更新した場合はファイル追加作業不要）
    ・ステータスの確認
    ・コミット
メモリまわりのメモ

### 概要
    PHPは、php.iniの中で設定されている。
    基本的に一連の処理を抜けると自動的に開放される。
    「memory_get_usage」は現在のメモリ使用量を出力。PHP スクリプトに割り当てられたメモリの量をバイト単位で返します。
    「memory_get_peak_usage」は最大メモリ使用量を出力。メモリの最大値をバイト数で返します。


### PHPプログラムのメモリの使用量を確認する
    $mem = memory_get_usage();
    $mem = number_format($mem);
    print("Memory:{$mem}");
    

### PHP.iniの設定
    memory_limit = 256M



    phpに直接書く
    <?php
    ini_set("memory_limit", "512M");


    
### メモリリーク
    確保したメモリを解放せずに、そもままにすると空きメモリが減っていく。
    この現象のことをメモリリークという。
ZFS poolのアップグレード

#動機
freebsd-updateを使ってバイナリアップグレードを続けていると、次第にシステムが対応するZFS featureが増えていき、既存のZFS poolが対応していないものが出てくる。これは簡単にアップグレードできるのだが、どうも巷の情報には穴がありそうなので自力でまとめておく。

#確認
システムでサポートされているがZFS poolで有効化されていないfeatureは、`zpool upgrade`で確認できる。[^1]

[^1]: 具体的なfeatureの情報はないけれど、`zpool status`実行時にもメッセージがでる。

```shell-session
>zpool upgrade
This system supports ZFS pool feature flags.

All pools are formatted using feature flags.


Some supported features are not enabled on the following pools. Once a
feature is enabled the pool may become incompatible with software
that does not support the feature. See zpool-features(7) for details.

POOL  FEATURE
---------------
zroot
      large_blocks
      sha512
      skein
      device_removal
      obsolete_counts
      zpool_checkpoint
      spacemap_v2

```

#有効化

無効のままのfeatureを有効化するのは簡単で、`zpool upgrade <ZFS pool>`とすれば良い。プール名の代わりに`-a`を指定すれば全てのプールがアップグレードされる。

```shell-session
>sudo zpool upgrade -a
This system supports ZFS pool feature flags.

Enabled the following features on 'zroot':
  large_blocks
  sha512
  skein
  device_removal
  obsolete_counts
  zpool_checkpoint
  spacemap_v2

If you boot from pool 'zroot', don't forget to update boot code.
Assuming you use GPT partitioning and da0 is your boot disk
the following command will do it:

        gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 da0

```

ここで末尾に「このプールから起動する場合はブートコードの更新を忘れないように」という注意書きが出ている。システムは更新されていてもディスク上のブートコードは古いままなので、新しいfeatureが使用された場合にそれを解釈できずに起動に失敗する可能性がある。

ただし表示されているコマンドをそのまま実行するのはかえって危険。この実行例の場合、da0p1を問答無用で書き換えてしまうので、本当にそれでいいのか確認する必要がある。ディスクのパーティションレイアウト次第では起動不能になる。

#ブートコード更新

レガシーBIOS経由で起動するGPTディスクの場合、ブートコードはfreebsd-boot (ada0p1)に存在し、実行例のda0をada0に変えればそのまま利用可能。[^2]

[^2]: /boot/pmbrはZFS featureとは関係ないが、トラブル防止のため/boot/gptzfsbootとセットで更新しておいた方が良い。

```shell-session
>gpart show ada0
=>        34  1953525101  ada0  GPT  (932G)
          34           6        - free -  (3.0K)
          40        1024     1  freebsd-boot  (512K)
        1064     4194304     2  freebsd-swap  (2.0G)
     4195368  1949329760     3  freebsd-zfs  (930G)
  1953525128           7        - free -  (3.5K)

>sudo gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada0
partcode written to ada0p1
bootcode written to ada0
```

UEFI+BIOS両用のGPTディスクの場合、freebsd-bootはada0p2になっている。もし実行例のとおり`-i 1`のままだと、EFIパーティションが破壊されてUEFIからブートできなくなる。またfreebsd-bootはレガシーBIOS経由のとき使われるブートコードなので、UEFIからブートする場合に使われるEFIパーティションも更新しなければいけない。現状でレガシーBIOS経由で起動していると気付かないまま放置してしまい、あとでUEFI経由で起動しようとしてハマる可能性がある。

```shell-session
>gpart show
=>        40  3907029088  ada0  GPT  (1.8T)
          40      409600     1  efi  (200M)
      409640        1024     2  freebsd-boot  (512K)
      410664         984        - free -  (492K)
      411648     4194304     3  freebsd-swap  (2.0G)
     4605952  3902423040     4  freebsd-zfs  (1.8T)
  3907028992         136        - free -  (68K)

>sudo gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 2 ada0
partcode written to ada0p2
bootcode written to ada0
>sudo mount -t msdosfs /dev/ada0p1 /mnt
>sudo cp -p /boot/loader.efi /mnt/EFI/BOOT/BOOTX64.efi
>sudo umount /mnt
```

#関連情報
*[FreeBSDのブートプロセス](https://qiita.com/mzaki/items/76acac14c16ac6789e68)
MySQL root アカウントでターミナルからログインしようとしたらエラーが出た

# 目的

- MySQLのrootアカウントのアカウント情報を用いてターミナルからログインしようとしたらエラーが発生したため筆者の場合の解決方法をまとめる

# 環境

- 下記の方法でMySQLの環境を構築した。
    - [Mac HomebrewでMySQLをインストールする](https://qiita.com/miriwo/items/ef6a064bc545fbea29d9)

# 情報

- Macに直接たてたMySQLにて発生したエラーの解決方法を記載する。

# エラーまでの経緯

1. Mac起動直後に下記コマンドを実行してMySQLにrootアカウントでログインを試みた。rootユーザのパスワードを入力しEnterを押下した。

    ```terminal
    $ mysql -u root -p
    ```

# エラー

1. 下記のエラーが発生した。

    ```terminal
    ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
    ```

# エラー解決までの経緯

1. MySQLが起動していないことがわかった。
1. 下記コマンドを実行してMySQLを起動した。

    ```terminal
    $ mysql.server start
    ```

1. 再度下記コマンドを実行してrootユーザでMySQLにログインしたところ正常にログインする事ができた。

    ```terminal
    $ mysql -u root -p
    ```

# 回避策

1. 下記コマンドを実行してMacの起動時にMySQLも起動するように設定した。

    ```terminal
    $ brew services start mysql
    ```

1. また自動起動設定を解除したいときは下記を実行する。

    ```terminal
    $ brew services stop mysql
    ```
シングルクォーテーション　と　ダブルクォーテーション

###説明
・ダブルクォーテーション　 ･･･ 文字列中の変数を変数値に置換する
・シングルクォーテーション ･･･ 文字列中の変数を変数値に置換しない  

###注意事項
ダブルクォーテーションの方が高機能な処理を行っているため、
シングルクォーテーションの方が処理が速い。  
変数の置換を行う必要が無い場合はシングルクォーテーションを使うようにした方がよさそうです。
デバッグの基本　メモ

### デバッグの基本
  * １つ１つ丁寧に、var_dump を繰り返してコードを読んでいく
  * grep検索を活用して関数の記載場所を確認
  * 記録を残しながらデバッグをすすめる。（どこまでやったかわかりやすい。）
  * プログラムは、exit;を利用して途中で止める（処理を追うことが目的なのです全ての動作を行う必要はない。）

### 上達への道
  * ソースコードをどれだけ多く書いて読んでいるかが大事。
python : ラーメンタイマーの作成（pyttsx3 , time）

# pythonでカップラーメンの音声タイマーを作成。
カップラーメンの時間経過をいつも感覚で判断していた。
問題なく食べれているが、せっかくなのでプログラミングの勉強を兼ねて作成。
## 目次
・コード
・結果
## コード
```python:コード
#必要なモジュールをimport,pyttsx3の呼び出し
#pyttsx3 : 読み上げ
#time    : 時間計測
import pyttsx3
import time
engine = pyttsx3.init()

#startは準備開始時間（蓋を開けるとか）
#startの20秒後にお湯を入れる設定
#20秒後にお湯を入れる音声アナウンス
start = time.time()
while True:
    oyu_in = time.time()
    if oyu_in-start >= 20:
        print("お湯を入れてください")
        engine.say('お湯を入れてください')
        engine.runAndWait()

        #お湯を入れた時間
        oyu_wait = time.time()

        break

#お湯を入れてからの待機時間
#ラーメンは180秒（3分）に出来上がると設定
#180秒後に食べられますと音声アナウンス
while True:

    #お湯を入れてから経過した時間
    oyu_end = time.time() 
                 
    if oyu_end-oyu_wait >= 180:
        print("食べられます")
        engine.say('食べられます')
        engine.runAndWait()
        break
        
#残り３０秒になったら音声アナウンス
    elif oyu_end-oyu_wait == 150:
        print(int(oyu_end-oyu_wait),"秒経過")
        engine.say('あと30秒です')
        engine.runAndWait()
        continue
        
#10秒刻みで経過時間を表示
    elif (oyu_wait-oyu_end)%10 == 0:
        print(int(oyu_end-oyu_wait),"秒経過")
```
## 結果
![スクリーンショット 2020-12-28 10.46.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698556/e2ba76e2-837f-b83d-85b3-7676b8937176.png)
PCの処理等の問題で残り３０秒や１０秒間隔の経過時間表示がないときがあった。
ただ、180秒経過は [ 180 >= ] としているため必ず音声アナウンスが出ます。
プロセッサ

## MIPS(milion instructions per second：ミップス)
1秒間の命令実行回数を百万単位で表すCPUの単位

50MIPSでは、1秒間に5,000万回の命令を実行できるので、1命令当たりの実行時間は、

　1秒÷5,000万回＝0.00000002＝20ナノ(秒)

になります。
eslintとprettierを設定する

## この記事について

「環境設定なにもわからないよ〜」という初心者が、新規プロジェクトにESLintとPrettierの設定を行った際の記録です。
ESLintとPrettierを競合せず導入して、`Cmd + S`で自動整形してもらうのがゴール

## 初期状態、実行環境

OS : macOS Catalina 10.15.6

VSCodeにESLintとPrettierはインストール済み

VSCode : 1.52.1
ESLint : 2.1.14
Prettier : 5.8.0

今回設定するプロジェクトはTypeScript + React(Next.js)環境、yarnを使用

## `yarn add` してみる

2020年12月時に推奨されているのは、`eslint-plugin-prettier`を使わない方法らしいので、それぞれの本体と`eslint-config-prettier`だけ入れてみる

```
# yarn add -D eslint prettier eslint-config-prettier
```

## `yarn eslint --init` してみる

```
# yarn eslint --init
```

色々質問されるので答えていく

```
✔ How would you like to use ESLint? · problems
✔ What type of modules does your project use? · esm
✔ Which framework does your project use? · react
✔ Does your project use TypeScript? · No / Yes
✔ Where does your code run? · browser
✔ What format do you want your config file to be in? · JavaScript
The config that you've selected requires the following dependencies:

eslint-plugin-react@latest @typescript-eslint/eslint-plugin@latest @typescript-eslint/parser@latest
✔ Would you like to install them now with npm? · No / Yes
```

最後に、npmでこのパッケージ入れますか？と聞かれるが、yarnで入れたかったため、パッケージ名だけコピーしてNoを選択

そのときは初期化に失敗したが、`yarn add -D`で上記パッケージを入れてからinitしたらNoでも初期化された

## `eslintrc.js`を修正

プロジェクトのルートに`eslintrc.js`が生成されたので、開いてみる

```js:eslintrc.js
module.exports = {
    "env": {
        "browser": true,
        "es2021": true
    },
    "extends": [
        "eslint:recommended",
        "plugin:react/recommended",
        "plugin:@typescript-eslint/recommended"
    ],
    "parser": "@typescript-eslint/parser",
    "parserOptions": {
        "ecmaFeatures": {
            "jsx": true
        },
        "ecmaVersion": 12,
        "sourceType": "module"
    },
    "plugins": [
        "react",
        "@typescript-eslint"
    ],
    "rules": {
    }
};
```

ここで、１行目の`module`に赤波線が付いていた

調べたところ、`exports`と`module.exports`の２種類あってどちらかしか使えないようなので、`exports`にしてみたら赤波線が消えた
ただ、`module.exports`のほうが推奨らしいので、ファイル名を`.eslintrc.json`に変更して`exports`自体を消した
[[ 参考(古い) ]](https://qiita.com/toshihirock/items/e98363a4c99950be5abc)

## Prettierの設定をする

Prettierはinitコマンドがなさそうだったため、手動で`.prettierrc.json`を生成して置く

```json:.prettierrc.json
{
  "printWidth": 120,
  "tabWidth": 4,
  "singleQuote": true,
  "trailingComma": "none",
  "semi": false,
  "parser": "typescript"
}
```

タブ幅はスペース４つ派

## 保存時に自動整形されない

ここで、あえてフォーマットを崩したファイルを保存して自動整形されるかを試してみたが、されなかった

```
# yarn prettier --write pages/users/\[id\].tsx
```

のように、ターミナルから実行したところ、整形された

VSCodeの`setting.json`に

```
"editor.formatOnSave": true,
```

を設定して、再起動後試してみるが、自動整形されない

```
"editor.defaultFormatter": "esbenp.prettier-vscode"
```

を追加して実行したところ、自動整形された

## プロジェクトの`settings.json`にも書いておく

```json:.vscode/settings.json
{
    "editor.formatOnSave": true,
    "editor.defaultFormatter": "esbenp.prettier-vscode"
}
```

とりあえず、目標は達成できたので一旦ここで終わるが、ほぼ初期設定のため、便利にできそうな所があれば随時改良していきたい。このプロジェクトの`pritter` `ESLint`周りをカスタマイズしたらここに追記する

## 参考文献

[Prettier と ESLint の組み合わせの公式推奨が変わり plugin が不要になった](https://blog.ojisan.io/prettier-eslint-cli)

[いつのまにかeslint-plugin-prettierが推奨されないものになってた](https://knote.dev/post/2020-08-29/duprecated-eslint-plugin-prettier/)
boolean による props の出し分けをシンプルに書く方法

ニコニコ生放送でフロントエンドエンジニアをやっている @misuken です。

今回は何気に便利な tips の紹介です

React で `props` を組み立てる際、 `boolean` の条件によってオブジェクトの出し分けを行いたくなることがあります。

`props` だけでなく、構造化されたオブジェクトを組み立てるときに同じ場面に遭遇することは多いと思います。

例えば以下の型があったとして。

```ts
interface Props {
  required: { children?: React.ReactNode };
  optional?: { children?: React.ReactNode };
}
```

## 典型的な書き方

通常は三項演算子を使用して書きます。

```ts
const enabled = true;
const props: Props = {
  required: {
    children: "〜",
  },

  optional: enabled
    ? {
        children: "〜",
      }
    : undefined,
};
```

これだといろいろ面倒なことがあります。

- ネストしている場合にインデントが深くなる
- ネストしている場合に何を返しているかが読みづらく可読性が悪くなく
- 条件の付け外し時に `enabled ?` と `: undefined` の修正が必要で面倒
- 条件の付け外し時にインデントが変化する
- 条件の付け外し時に差分が二箇所に分かれる
- 大きな `props` だと条件に一致しないときに返すものが把握しにくくなる

## シンプルな書き方

`(enabled || undefined) &&` を使うとシンプルに書けます。

```ts
const enabled = true;
const props: Props = {
  required: {
    children: "〜",
  },

  optional: (enabled || undefined) && {
    children: "〜",
  },
};
```

`enabled` が `false` なら `undefined` が、 `true` ならオブジェクトが返ります。

条件の付け外しで変化する場所がまとまっていて、インデントも変化せず、大きな `props` でも可読性が落ちることがありません。
Julia勉強中：Juliaでループ時の変数スコープでハマった話

Juliaが良さそうなので年末年始に少しでも知識を付けようと勉強中（1日目）。とりあえず書き方に慣れないと話にならないので、AtCoder過去問で練習していたら、初手で死亡したのでメモ。

## Julia Version

```bash
$ julia --version
julia version 1.4.1
```

## お題

https://atcoder.jp/contests/past201912-open/tasks/past201912_b

前の値と次の値を比較して `up` とか `down` とか判定しろという問題。こんなの1分で解かないといけない。

## え、その変数見えへんの？

とりあえず標準入力を1行1行取り出し、数値にして前の値と比較するという愚直なプログラム。**次の行を見る前に現在の値を前の値として記憶しておく。**問題の本質では無いので `break` 条件についてはとりあえず考慮しない。

```julia
using Printf

aprev = 0  # aprevを宣言

while true
    snext = readline()
    anext = parse(Int, snext)
    df = anext - aprev
    if df > 0
        @printf("up %d\n", df)
    elseif df < 0
        @printf("down %d\n", abs(df))
    else
        println("stay")
    end
    aprev = anext  # aprevに現在の値を記憶
end
```

別に変哲もないプログラムでしょう。でもこれコンパイルエラーになります。

```bash
$ julia 2019b.jl 
1
ERROR: LoadError: UndefVarError: aprev not defined
Stacktrace:
 [1] top-level scope at /home/morita/workspace/jlexp/2019b.jl:29
 [2] include(::Module, ::String) at ./Base.jl:377
 [3] exec_options(::Base.JLOptions) at ./client.jl:288
 [4] _start() at ./client.jl:484
in expression starting at /home/morita/workspace/jlexp/2019b.jl:26
```

は？`aprev not defined`て何でなの。

## localスコープからglobal変数は見えません

多分スコープの問題だろうと調べものをしたらこのような記事が。https://marui.hatenablog.com/entry/2019/08/09/115410

どうも問題はトップレベルで書かれた行はglobal変数として扱われ、それはlocal変数から見えない、という事が落ちな模様。気持ち悪いのは、`while`や`for`などのループは新しいlocalスコープを作るということ！公式サイトに具体例もちゃんと書かれていました。 https://docs.julialang.org/en/v1.1/manual/variables-and-scoping/#Local-Scope-1

公式の説明↓
https://docs.julialang.org/en/v1.4/manual/variables-and-scoping/#man-scope-table-1
>There are two main types of scopes in Julia, global scope and local scope. The latter can be nested. The constructs introducing scope blocks are ... (while, forなど)

つまり、`while`や`for`などは、localスコープのコンストラクタという事。また、localスコープはネストされるので、親forループ内で宣言されたlocal変数は、子forループ内でも参照できます。

## 解決方法

1つの方法は、forループの外の変数を `global` 宣言してあげる事です。

```julia
aprev = 0

while true
    global aprev # global宣言
    snext = readline()
    anext = parse(Int, snext)
    df = anext - aprev

    ...(snip)...
end
```

でも `global` 変数って何か気持ち悪いですよね。他の解決方法としては、ちゃんと関数として宣言してあげる事です。

```julia
using Printf

function f()
    aprev = 0
    
    while true
        snext = readline()
        anext = parse(Int, snext)
        df = anext - aprev
        if df > 0
            @printf("up %d\n", df)
        elseif df < 0
            @printf("down %d\n", abs(df))
        else
            println("stay")
        end
        aprev = anext
    end
end

f()
```

これで動きます。

## まとめ

関数くらいはちゃんと書くか。
CentOS8+Anaconda4.9.2+jupyterhub環境構築手順

# やりたいこと

* CentOS8にAnaconda4.9.2をインストールしてjupyterhubを立ち上げてログインできるようにする。

# 前提条件

* VirtualBox等で作成した仮想サーバにCentOS8が最小構成以上でインストール済みであること。
* root権限でSSH接続できること。

# Anacondaインストールシェルの入手先

https://www.anaconda.com/products/individual

から、シェルのパス

```
https://repo.anaconda.com/archive/Anaconda3-2020.11-Linux-x86_64.sh
```

をコピペする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75451/69cd0b93-c517-4ebd-88da-43d085ac429c.png)





# 準備

CentOSにSSH接続して、root権限で下記を実行する。

```
yum -y update
yum install -y wget
sysctl -w net.ipv6.conf.all.disable_ipv6=1
yum -y install vim-enhanced
```

# SELinux無効化

```
setenforce 0
vi /etc/selinux/config

下記を編集
SELINUX=disabled
```


# ポート開放

```
firewall-cmd --add-port=80/tcp --zone=public --permanent	
firewall-cmd --add-port=8000/tcp --zone=public --permanent
firewall-cmd --add-port=8081/tcp --zone=public --permanent
firewall-cmd --reload
```


# Anacondaインストール

### シェルをダウンロードする。

```
su yamato
cd /home/yamato
wget https://repo.anaconda.com/archive/Anaconda3-2020.11-Linux-x86_64.sh
```

### シェルをたたいてインストール開始。


```
sh Anaconda3-2020.11-Linux-x86_64.sh
```

ウィザードに従い yes を入力して進める。
終わったらパスを有効化する。

```
source .bashrc
```

# jupyterhubインストール

```
su yamato
conda install -c conda-forge jupyterhub
```

# jupyterhubの設定

```
cd /home/yamato/anaconda3/
jupyterhub --generate-config
vi jupyterhub_config.py
```

### 下記を編集する。

編集前

```
c.Spawner.default_url = ''
```

編集後

```
c.Spawner.default_url = '/lab'
```

### jupyterhub起動

コマンド

```
jupyterhub
```

でWebサーバが起動する。

http://192.168.1.11:8000

で、jupyterhubのログイン画面にアクセスできる。
192.168.1.11 の部分は、仮想サーバのIPアドレスなので、各自の環境に合わせて変更してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75451/1665fcc8-1c6f-6bc9-efce-395ae1439be6.png)


ログインのユーザ名とパスワードはCentOSのユーザと同じです。
たとえば、CentOSのアカウントが
Username: yamato
Password: 1234
ならば、yamato / 1234 で jupyterhub にログインできます。

ログインして下記画面が表示されたら成功です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75451/b072d193-cf70-196d-90ab-47928f1cdeee.png)

# graphvizのインストール

root権限で下記を実行する。

```
 yum install graphviz
```

# 各種パッケージ準備

実装で必要になるであろうパッケージをインストールしておく。

```
conda install anaconda
conda update --all
conda install pydotplus
conda install -c conda-forge opencv
```
SASEのアップデート

SD-WAN付きセキュリティクラウドの世界初のベンダーCato Networks社のインフォメーションで、侵入防止サービスにTeslaの名前のついたマルウェアが出てきた。
Teslaの車を狙ってるのか、それにひっかけてPCで繁殖するのか。
そしてアプリケーションでもFacebookが出てきてる。
偽Facebookアプリがあるのかもしれない。

•	IPS Signatures: 
o	Malware – Agent Tesla(New)
o	IOA – Wordpress Exploit (New)
o	CVE-2017-0199 (Enhancement)

•	Application Database: 
o	Facebook (Enhancement)

みんながやってそう、富裕層がもってそうなものがターゲットなのかもね。

SASEとは：
Secure Access Service Edgeの略。セキュリティ機器もクラウドにいってしまったサービス。セキュリティ機器自身の脆弱性があったりするのでそのパッチあてとかしなくて楽ちんになるやつ。VPNの脆弱性とかも気にしなくていいし、テレワーク社員の管理が楽になる。AWSとAzureもVPN延伸して一緒にくっつけてNWとセキュリティ管理できる。SD-WANもVPNも全部GUIで一元管理できる。Cato Networks社が世界初のSASEベンダー。旅行会社のエイチ・アイ・エスさんが採用している。
GAS: `Utilities.formatDate` バグってる？ 2020-12-28

# 概要

Google Apps Script（GAS）の話。
今日（2020-12-28）から？
2020年なのに2021年になる

**追記: ただのフォーマット指定ミスでした**

# 内容

## コード

```js
function myFunction() {
  const date = new Date()
  console.log(date)
  console.log(Utilities.formatDate(date, 'JST', 'YYYY-MM-dd'))
  console.log(Utilities.formatDate(date, 'UTC', 'YYYY-MM-dd'))
  console.log(Utilities.formatString("%d-%02d-%02d", date.getFullYear(), date.getMonth() + 1, date.getDate()))
}
```

## ログ

```
[20-12-28 10:26:16:935 JST] Mon Dec 28 2020 10:26:16 GMT+0900 (日本標準時)
[20-12-28 10:26:16:938 JST] 2021-12-28
[20-12-28 10:26:16:939 JST] 2021-12-28
[20-12-28 10:26:16:944 JST] 2020-12-28
```

* `date` の段階では2020年
* `Utilities.formatDate` の結果は2021年

# まとめ
2020-12-28 10:28現在。
この記事のような状態。

取り急ぎ

```js
Utilities.formatString("%d-%02d-%02d", date.getFullYear(), date.getMonth() + 1, date.getDate())
```

にして運用中

# 追記

formatの指定が悪かったみたい。
参考: [Utilities.formatDate　年末の日付がおかしい？？](https://qiita.com/haizuka/items/9aa68dfa0aed8a1113c4)

コード: 

```js
function myFunction() {
  const date = new Date()
  console.log(date)
  console.log(Utilities.formatDate(date, 'JST', 'YYYY-MM-dd'))
  console.log(Utilities.formatDate(date, 'UTC', 'YYYY-MM-dd'))
  console.log(Utilities.formatString("%d-%02d-%02d", date.getFullYear(), date.getMonth() + 1, date.getDate()))
  
  console.log(Utilities.formatDate(date, 'UTC', 'yyyy-MM-dd'))
}
```

ポイント: 年は `yyyy`

ログ:

```
[20-12-27 17:36:46:446 PST] Mon Dec 28 2020 10:36:46 GMT+0900 (日本標準時)
[20-12-27 17:36:46:451 PST] 2021-12-28
[20-12-27 17:36:46:453 PST] 2021-12-28
[20-12-27 17:36:46:457 PST] 2020-12-28
[20-12-27 17:36:46:458 PST] 2020-12-28
```
VSCodeからanaconda仮想環境を利用する

VSCodeからanacondaの仮想環境を利用する際にハマったのでメモ。

## 課題
まず、VSCodeでanacondaの仮想環境を利用するために、下記を行いました。
1. conda環境を作成  `conda create -n [環境名]`
2. vscodeのsettings.jsonに`python.pythonPath`を追加
3. pythonのインタプリターを指定(コマンドパレットからSelect Interpreter)

すると下記のようにconda環境のpythonを認識してくれました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501910/8528d2e1-2ba8-a6d8-e772-699385b137a2.png)

しかし、このままだとVSCode上のターミナルで`python`と打っても、デフォルトのpythonパスが指定されてしまいます。

## 解決策
[公式フォーラム](https://github.com/Microsoft/vscode-python/issues/4434#issuecomment-466600591)に回答されていました。
settings.jsonに下記のスクリプトを追加すればOKです。

```json:settings.json
"terminal.integrated.env.osx": {"PATH": ""}
```
`terminal.integrated.env.osx`の設定に変更がなされると、シェルの初期化が最初にされるため、設定した環境変数が使えるようです。
RailsのCurrentAttributesを使ってX-Request-IDでnginx(Webサーバ)とunicorn(アプリサーバ)のログを追えるようにする方法



# 動作確認したRailsのバージョン
6.0.3.4

# よくある話として
NginxなどのWebサーバのログとunicornやpumaなどのアプリサーバのログを同じIDで検索するため、X-Request-IDをアプリサーバのログに仕込んだりします。Railsに予め用意されているconfigの設定で行うのが手軽ですが、下記のような問題があります。

# TaggedLoggingの問題

TaggedLoggingを利用していれば、configファイルの以下の設定のコメントアウトを外せばX-Request-IDがログに付与されるようになっています。
`config.log_tags = [ :request_id ]`

X-Request-IDが123456789だとした時、↓のようなログになります。

```console
[2020-11-XXT09:37:34+09:00] [123456789] some message 
```

しかし、TaggedLoggingは例えば下記のような処理がある時、backtraceをログに出力してくれません。

```ruby
def XXX
rescue StandardError => e  
  logger.error e
end
```

そんな時はRails 5.2から実装されたCurrentAttributesを使うことで同じことを実現できます。
CurrentAttributesの
[ドキュメント](https://api.rubyonrails.org/classes/ActiveSupport/CurrentAttributes.html)にはrequest_idという単語があって、こういうユースケースを想定していることが想像できますね。

ドキュメントにあったコード例

```ruby
# app/models/current.rb
class Current < ActiveSupport::CurrentAttributes
  attribute :account, :user
  attribute :request_id, :user_agent, :ip_address

  resets { Time.zone = nil }

  def user=(user)
    super
    self.account = user.account
    Time.zone    = user.time_zone
  end
end
```

# 実装方法

流れとしてはmiddlewareでX-Request-IDをCurrentAttributesに設定して、formatterでそれを出力するだけです。

ActiveSupport::CurrentAttributesを継承したクラスを作成

app/models/current.rb

```ruby
# frozen_string_literal: true

class Current < ActiveSupport::CurrentAttributes
  attribute :x_request_id
end
```

middlewareを使って作成したクラスに値をセットします、

config/initializers/x_request_id.rb

```ruby

require 'current_x_request_id'

Rails.application.config.middleware.insert_after ActionDispatch::RequestId, CurrentXRequestId
```

ActionDispatch::RequestIdでX-Request-IDがenv['action_dispatch.request_id']にセットされます

lib/current_x_request_id.rb

```ruby

# frozen_string_literal: true

class CurrentXRequestId
  def initialize(app)
    @app = app
  end

  def call(env)
    Current.x_request_id = env['action_dispatch.request_id']
    @app.call(env)
  end
end
```

あとはformatterでそれを出力する

lib/formatter.rb

```ruby

    def call(severity, time, progname, msg)
        msg = msg2str(msg) # backtraceを出力するのに親クラス（Logger::Formatter）のメソッド（msg2str）を利用
        ~~~
        "request_id: #{Current.x_request_id} #{msg}"
        ~~~
    end
```

# 注意点として
CurrentAttributesはとても強力な仕組みですが、使う際はよく検討する必要がありそうです。注意書きの一例を載せておきます。

```console
A word of caution: It's easy to overdo a global singleton like Current and tangle your model as a result.
Current should only be used for a few, top-level globals, like account, user, and request details.
The attributes stuck in Current should be used by more or less all actions on all requests. If you start
sticking controller-specific attributes in there, you're going to create a mess.
```
deepl翻訳

```console
Currentのようなグローバルなシングルトンをやりすぎて、結果的にモデルが絡まってしまうことがあります。
Currentは、アカウント、ユーザー、リクエストの詳細などの少数のトップレベルのグローバルにのみ使用されるべきです。
Current に固定された属性は、多かれ少なかれすべてのリクエストのすべてのアクションで使用されるべきです。もし
コントローラー固有の属性を貼り付けてしまうと、混乱を招くことになります。
```
wsl2のdocker.credentials.errors.StoreErrorTracebackについて

# 背景
WSL2でdocker desktopを利用して`docker-compose build`等を実行すると下記のエラーが発生した。

```
docker.credentials.errors.StoreErrorTraceback (most recent call last):
  File "docker/credentials/store.py", line 80, in _execute
  File "subprocess.py", line 411, in check_output
  File "subprocess.py", line 512, in run
```

# 対処法
config.jsonを削除後、正常に動作した。

```
sudo rm ~/.docker/config.json
```
備忘録：お名前メールとroute53の連携で詰まったところ（送信できるが受信ができない）

## 構成
・お名前.comでドメイン取得
・お名前メールライト使用
・DNSはroute53を使用

## 詰まったところ
・メールを送信できるが、受信が全くできない
送信に関してはrailsでaction mailerで送ることができている。
ただ、ドメインに向けてメールを送信しても、以下の画像のようになり受信ができない。
![スクリーンショット 2020-12-28 8.46.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528450/1294b3ad-27df-1a88-4cdb-1b05cb90bb7d.png)

## 解決策
・route53でmxレコードの登録方法を変更して、mx〇〇.gmoserver.jpに転送する。

```
10 mail.example.com
　　　　　　↓
10 mx〇〇.gmoserver.jp
```
〇〇の中身はお名前メールにログインしてコントローラパネルを開き、「サービス設定」→「サーバー情報」を押してページ下部にサーバー情報があるのでそこを参照。


## 参考
[お名前メールライトとRoute53を連携する](https://qiita.com/YutaMoguaiMiura/items/af82ed7d4bc7e92fe16e)