OmniAICreator/Qiita-1.07M huggingface dataset:
Notionでブログを作る（Notion Blog）

#1. ログイン（Vercel）
https://vercel.com/new

#2. Import Git Repository
「Import Third-Party Git Repository →」を押下する。

#3. Import a Third-Party Git Repository
「https://github.com/ijjk/notion-blog.git 」と入力し，「Continue」を押下する。

#4. Select Vercel Scope
「PERSONAL ACCOUNT」>「Select」を押下する。

#5. Create Git Repository
「REPOSITORY NAME」を入力し，「Continue」を押下する。

#6. Import Project
① PROJECT NAME
　重複しなければ，ブログのURLに使用される。
　例: https://{{PROJECT NAME}}.vercel.app/blog

② Environment Variables（BLOG_INDEX_ID）
　a.「NAME」に，「BLOG_INDEX_ID」と入力する。
　b. Notionを開き，「Add a page」を押下し，「https://www.notion.so/ {{ページのタイトル}}-」以降のURLをコピーする。
　c. 画面右上の「Share」>「Share to web」を押下する。
　d. Vercelに戻り，VALUE (WILL BE ENCRYPTED) にペーストし，「Add」を押下する。

③ Environment Variables（NOTION_TOKEN）
　a.「NAME」に，「NOTION_TOKEN」と入力する。 
　b. Notionを開き，右クリックし，「検証」の右上に表示される「Application」>「Strage」>「Cookies」>「https://www.notion.so 」>「token_v2」の「Value」をコピーする。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/361909/e1f0571d-028a-d550-f6b0-8f75af992ffd.png)
　c. Vercelに戻り，VALUE (WILL BE ENCRYPTED) にペーストし，「Add」及び「Deploy」を押下する。

#7. Vercelに自動遷移
プロジェクトの「Visit」を押下し，上部の「Blog」からブログにアクセスできる。

#8. Notionで記事を作成
6 ②で追加したページを開き，表のPage列「Open」を押下し，記事を作成する。
※Publishedをチェックした記事のみブログで公開される。

#Reference
https://github.com/ijjk/notion-blog
STM32F303K8とOLED、OLED096UNO-AでHello Worldを表示2


x mbedが使える人が対象

1.mbedでstm32f303k8をコンパイル出来るようにする。
2.新規プログラムを開く
3.下記のソースを書く。
4.oledのライブラリをインストールする。
Dai YokotaさんのSSD1306_128x64_I2Cライブラリを使用した。
https://os.mbed.com/users/jk1lot/code/SSD1306_128x64_I2C/file/46dcbaa430f4/SSD1306.h/

ライブラリのインストール方法は、
mbedの画面のプロジェクトディレクトリー名の所で右クリックして
新しいライブラリー...を選択してOLED検索画面からDai Yokotaを選択
する。
5.コンパイルする。
6.何らかの方法で書き込む。
7.Hello Worldが表示されたら終わり。

```c++

#include "mbed.h"
#include "SSD1306.h"
 
#define ADDR     (0x3c<<1) //  address
//#define ADDR     (0x3d<<1) //  address
 
I2C i2c(I2C_SDA, I2C_SCL);
 
// Host PC Communication channels
Serial pc(USBTX, USBRX); // tx, rx
 
// Instantiate OLED
SSD1306 oled(i2c, ADDR);
 
int main() {       
    pc.baud(9600);    
 
    oled.writeString(0, 0, "Hello World !");  
    pc.printf("Printed something\r");    

    while(1){}
}

```

![oled8x8_ii.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/f2c9179a-d292-84ab-7c28-baa7a751d352.jpeg)


![oled8x8_ww.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/bc614ee8-60fa-10ed-4911-707c051e5f9d.jpeg)

![oled8x8_oo.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/fdbb6027-e05b-db86-aa1d-8b7f9df47b47.jpeg)
Herokuエラー　デプロイ　※日記

2021/01/29

Herokuのデプロイにて、エラー発生

![スクリーンショット 2021-01-29 19.52.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954637/1b14981a-f8b0-51d1-d965-7ec0e670e2c5.png)
![スクリーンショット 2021-01-29 19.52.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954637/986b88f7-bade-ab22-27e6-5a0eb61ea462.png)

なんだ？と思って翻訳もよく分からず、メンターに相談。。
そこからメンターさんと3時間くらいあれやこれや試したけど解決できなかった（ ｉ _ ｉ ）
（メンターさんありがとうございます）

いろんな人の記事とかみてたけどここでエラーなる人ほぼこのエラー文なんやね。。

でもみんな解決してるけど私何しても解決できない。。

明日またメンターさんに相談するとして、その次のRails新基礎シリーズ行きますか、、
並行してRailsチュートリアルもやってみる

また上記の件解決できたら編集する

今週もお疲れ様でした！！！！！

追記　
なんとこの記事書いたあと解決できた…！

詳しく理解できてないけど、コマンドはこんな感じ↓
→%　　自分が打つコマンド
→　　 返ってくるコマンド

①バンドルインストールを使う？時にやるコマンド　
→% bundler -v 
した後に
→Bundler version 2.2.4　表示される。これは今使ってるバージョン

②2.2.4バージョンを使用しており、確認後一旦アンインストール
→% gem uninstall bundler 
そしたら下の2行が表示される。今2.1.4バージョンと2.2.4バージョンがあるという意味
上の2.2.4になっていたのは最新の2.2.4が優先されていた
→Successfully uninstalled bundler-2.1.4
Successfully uninstalled bundler-2.2.4

③2.1.4に下げたい、2.1.4だけをインストールしたいので
→%gem install bundler -v 2.1.4

→Fetching bundler-2.1.4.gem
Successfully installed bundler-2.1.4
Parsing documentation for bundler-2.1.4
Installing ri documentation for bundler-2.1.4
Done installing documentation for bundler after 3 seconds
1 gem installed

④確認
→%bundler -v       
→Bundler version 2.1.4　　変わった！

⑤そして
→%bundle install     なんか２回やってる、、（記憶なし）
→長文コード

その後に再度Herokuのディレクトリであることを確認して、
GitHubにpushするのと同じコマンドをいれる

⑥ほんで最後、
→%git push heroku master  
→長文コード
でいけた〜〜！！

このあとは
→%heroku run rails db:migrate
などの処理を私は行って無事解決〜〜

手伝っていただいたメンターさんお二方、感謝です

あ、ただこの前にGimfile.lock消したり、master key消したりまたインストールしたりした、、した記憶。(曖昧)

自分用やけど、もし困っている人居ればこんなポンコツ記事やけどなんか参考なればいいな。笑
md-to-pdfを利用してmarkdown fileを一括でpdfにする

## md-to-pdfを利用してmarkdown fileを一括でpdfにする



**研究ノート**をmarkdownでとっているひとは多いのではないだろうか。研究ノートには画像を貼り付けておきたい。markdownに画像を貼り付けるためには、

```
![image](files/Users/suimye/Desktop/gazou.png)
```
このようにローカルに保存した画像へのパスを書いたり、Gyazo等を使って画像をwebへアップロードして、かつリンクを貼るという方法がありますが、画像のフォルダなどを変更すると当然ながらリンク切れをするので、mdに画像を加えたノートは普遍性に乏しく、提出したり共有したりするときに不便になります。

そこで、ノートの保管時にmarkdownをpdf化することで、画像を埋め込んだノートを保存するということを行うようになった。これであれば、一度書いたノートの書き換えなども行いにくいし、画像も含めてpdf化してくれるので研究ノートとして完結している。また、これまで書いたmarkdownノートを一括してpdf化してくれたら、後からさくっとpdfで保管できるので助かる。markdownを一括してpdf化するツールとして、[ここを参考にして](https://dev.classmethod.jp/articles/md-to-pdf/)、md-to-pdfをインストールした。

> 環境: Mac 10.15.7, Homebrew 2.7.7

```
brew install yarn 
yarn add md-to-pdf
```

フォルダ内のmarkdownを一括でpdf化してくれる

```
npx md-to-pdf ./*.md
```

確認したところ、画像がちゃんとPDFに挿入されていた。

P.S.   
スクリーンショットの画像フォルダを固定しておけば、markdownのノートにメモの画像をドラックアンドドロップで貼り付けることができる[**Typora**](https://typora.io/)をmarkdown editorとして利用し、常にそのフォルダから**Typora**へドラッグアンドドロップで貼り付けるようにすると、スクショのリンク切れが起こり難く、定期的にpdf化をすれば運用が簡単なのでおすすめです。
Ｈyper-Ｖ内部ネットワーク設定(固定IP)

# 初めに
・Hyper-Vにおける内部の仮想ネットワーク設定方法
・IPはcentos内のifcfg(インターフェース設定ファイル)で固定
・サンプルのOSはCentOS7とUbuntu(20.04 desktop)
・多分もっと良い方法はあるかと

# ざっくり
1. 内部の仮想スイッチを作成
2. 作成したスイッチをホストのネットワークと連携(内部からのネットワーク接続を可能とするため)
3. 仮想マシンにネットワークアダプターとして、スイッチを設定
4. インターフェース設定ファイルに記述し、設定再起動

# 詳細(ざっくりに沿って)
## 1.内部の仮想スイッチを作成
### 1.1. ツールバーの操作から「仮想スイッチ マネージャー」を選択
![image01_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541739/2ffba611-8a77-2bd7-5f9e-d6182902429a.png)
### 1.2. 左側で「新しい仮想ネットワークスイッチ」、右側で「内部」を選択し、「新しい仮想スイッチの作成」のボタンを押す
![image01_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541739/cf8e38d1-f3c0-c418-43f4-cdc823d18466.png)
### 1.3. 名前にスイッチの名称を設定(ここではvsw-internal)し、「適用」ボタン⇒「OK」ボタンを押す
![image01_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541739/9e6d4c6a-1ffe-d4e6-b913-fa0f4fc0ce6e.png)

## 2. 作成したスイッチをホストのネットワークと連携
### 2.1. インターネットに接続しているしているネットワークのプロパティを開き、共有タブから作成したスイッチの接続を許可する
![image02_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541739/e6ae3f81-6093-a270-6f18-7b8f2b9f5bb4.png)
※コンパネからの「ネットワーク接続」等から表示できるはず
<b>※ホスト再起動したら、毎回オンオフをやらないといけないっぽい</b>

## 3. 仮想マシンにネットワークアダプターとして、スイッチを設定
### 3.1. Hyper-VマネージャーのOSの設定を開き、ネットワークアダプターに作成したスイッチを設定し、「適用」⇒「OK」を押す
![image02_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541739/0bc08db4-c51b-f95e-4144-4860ee693875.png)
※仮想環境を右クリックすれば「設定」を選択し、ウィンドウを表示できる

## 4. インターフェース設定ファイルに記述し、設定再起動
### 4.1. ホスト側で「ipconfig」等を行い、作成したスイッチのIPv4とサブネットの設定を確認する
![image02_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541739/7e005a2f-26cc-4637-0c14-be5a5cb6dc51.png)
※こちらで試したサンプルではこのような感じ
### 4.2. ＯS内からインターフェースファイルを編集する
#### 4.2.1. CentOS

```
cd /etc/sysconfig/network-scripts
vi ifcfg-eth0
```

##### 編集内容

``` ifcfg-eth0
-ONBOOT=no
+ONBOOT=yes

-BOOTPROTO=dhcp
+BOOTPROTO=static

+IPADDR=[IPV4の先頭３つ].[任意で設定]
+DNS1=[IPV4]
+NETMASK=[サブネットのIP]
+GATEWAY=[IPV4]
``` 

##### 設定例（上記ipconfig時における例）

``` 
IPADDR=192.168.137.55
DNS1=192.168.137.1
NETMASK=255.255.255.0
GATEWAY=192.168.137.1
``` 

#### 4.2.2. Ubuntu
``` 
cd /etc/netplan
sudo vi 10-network-manager.yaml
``` 
※10-network-manager.yamlは新規作成

##### 設定例（上記ipconfig時における例）
``` yaml:10-network-manager.yaml
network:
  version: 2
  renderer: networkd
  ethernets:
    eth0:
      dhcp4: false
      dhcp6: false
      addresses: [192.168.137.55/24]
      gateway4: 192.168.137.1
      nameservers:
        addresses: [192.168.137.1]
``` 

### 4.3. ネットワークインターフェースの再起動

#### 4.3.1. centos
``` shell
ifdown ifcfg-eth0
ifup ifcfg-eth0
``` 

#### 4.3.2. ubuntu
``` shell
sudo netplan apply
``` 

## ネットの確認方法
1. pingでgoogle.comなどにつないで、ネット接続、名称解決ができているかの確認
2. TeraTerm 等でIPADDRの接続先にssh接続確認できるかを確認
とか、、

# 現在調査中
ホストを再起動した場合は、2.1 の画面で、一旦チェックを外して設定後、再度チェックを入れて設定しないと、接続できないみたい、、、なんか良い方法を模索中、、、
プログラミング日記

2021/01/29　day２４

Twitterクローン完了。Heroku突入

Twitterクローン３日半もかかってしまった。。　もう少し早く仕上げたかったな。
まぁ何はともあれとりあえずRails基礎編終わり（理解度はまだまだ）

![スクリーンショット 2021-01-29 19.24.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954637/0aa395f1-8550-1113-f9af-ca773d96f923.png)

こんな感じ！！！！！！　うん、質素。最低限の機能とデザイン。これで3日ヽ(；▽；)w

内容確認画面
![スクリーンショット 2021-01-29 19.30.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954637/0f5e60db-3802-78ac-8123-b694e0ff9a5e.png)

次は編集ボタンクリックするとこんな感じ、からの
![スクリーンショット 2021-01-29 19.31.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954637/feb2880f-4e45-325d-acfd-74909790aa0a.png)

編集しました！
全部リダイレクトでトップページに戻るようにした
![スクリーンショット 2021-01-29 19.32.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954637/cb549840-8756-0160-3872-d404e119a957.png)

削除（ボタン押すと　Tweetを削除しました！てでます）
![スクリーンショット 2021-01-29 19.35.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954637/18a4468c-0e20-5117-c8ae-9fdaf5dda752.png)

そして右上のtweetするを押して入力
![スクリーンショット 2021-01-29 19.37.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954637/8e86c11b-b4a2-9efb-162c-8ea3a832f16c.png)

そして確認画面→登録すると編集と同じでtweetしました！ってでる
![スクリーンショット 2021-01-29 19.38.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954637/33eec110-f784-fbab-460b-82eb9a6cce1e.png)


こんな感じヽ(；▽；)　初めてだし、これはこれでいいと自分に言い聞かす。

ほんでここの間隔開けるの忘れてた。。今気づいた。
![スクリーンショット 2021-01-29 19.24.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954637/d36598fb-b1f5-0042-071b-db8900ff0aa4.png)

今日復習できたCSSについて。
まだ曖昧な部分あり。
https://www.evernote.com/shard/s542/sh/f9665dc9-0566-591f-207b-aae970c220d9/89959a243e15e3e0197595a8b6298e24
勉強の息抜きに見たい、笑えるためになる動画　一選

最近、無料でもかなり質の高い情報が得られるようになったなーと思います。

基本的にはQiitaで調べることが多いですが、Youtubeでも本当にたくさんの方の動画が出ていて
ためになる＆面白いものが多く有るのでメモがてらに記載したいと思います。

タイトルの通り笑える内容だと思うので楽しんでみていただけたらと思います。

特に動画４分以降の畳み掛けがすごいです。


https://youtu.be/FJac317JqeI



こいこいさんの動画は　Excel、VBAやPython、AIの情報がメインです。
でも堅苦しい内容ではなくて
ポケモンとかコナンとかの話題が出てきたり、シュールなボケのツカミがあったりと
気難しい感じがしないのがとてもよかったりします。

今後はそれ以外にもいろいろ追加していけたら、と思っています。


お粗末さまでした。。。
Dockerのローカル環境をAWSに載せてみる


はい！こんにちは！
1月中にこの記事を出そうと思ってましたが、なかなかうまくいかないものですね。
2/1に、第3者チェックを通してから2月頭に公開になりそうだ！！！！　現在 1/26 定時ちょい過ぎ

今日はdockerについてAWSとの連携のイメージを簡単にご紹介しようと思います。

## はじめに
今やもうコンテナって言葉を知らない人はいないと思います！
知らない人はちょこっと調べて、ローカルで実装してみて、動いたタイミングで
「AWSサーバに乗っけたい！」って思ったら参考程度に読んでみてください〜:v:

## いつぞやのDockerfile（ちょっと復習）

```Dockerfile:Dockerfile
# 基盤のimageファイル選択
FROM php:7.3-fpm
# コンテナを立ち上げるときにライブラリ・パッケージのアップデートとインストール
RUN apt-get update && apt-get install -y \
...
>>>　省略
```

> ローカルでDockerfileやdocker-compose.ymlで
コンテナの設計書書いて構築もできて開発してまーす！

この状態でコンテナ化が完了したと思っているそこのあなた！
どうやってサービス展開するの？リリースするの？って疑問が出てくると思います。

サービス展開するなら本番環境の構築なども必要ですよね？

以下AWSの複数サービスを使って、ローカルコンテナ環境をクラウドに移行する1手法をご紹介します！

## 全体のイメージ（自己流）

ごちゃごちゃしていますが、これはどうしてもこうなる部分なんです、、あしからず、、、
![ 2021-01-29 15.44.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642236/7047a37c-8d45-2b6c-06b1-4e682de2eb3f.png)


## 使うAWSのサービス
1. ECR（コンテナイメージの保存）
2. EC2（ECSを乗っけるサーバー）　　※本記事では触れませんがALBの設定なども必要です。
3. ECS（クラスター 、サービス、タスク）

メインで関係してくるのはこの3つのサービスです！

3. CodeCommit
4. CodeBuild（CodeDeploy）

さらにCodeCommitとCodeDeployを使えば、CodeCommitへのPUSHを検知して、
コードのビルドができる仕組みも作ることができます。私は挫折しましたが、、、

今は運用の中で、ソースコードについては一部コンテナに直接SSH接続して、pullする方法を取っていますが、
AWS側でもdocker-composeファイルを導入して複数コンテナの操作を1ファイルで行ったりすることができるそうです:thumbsup:


## ソースをコンテナに乗っける方法
私が今回行った方法は以下です。

> 1. CodeCommitでソース管理をする
2. CodeDeployのラインでCodeBuildの部分をいい感じに設定してmasterブランチにPUSHされたタイミングをトリガーとしてCodeBuildのビルドが走るようにする
3. CodeBuildする時に、CodeCommitのソースをイメージの中に追加で配置した状態でBuildが走るように追加設定する

この方法だと、CodeBuildが通った時に出来上がっているコンテナには、
画像①で作成したコンテナ（インフラ部分）が構築されていて、頻繁に更新されているソースの部分は、
masterブランチにgit pushされた時に自動で乗っかるようになっています。
ただ、コンテナに配置したソースはコンテナ停止するとなくなるのが基本なので、データの永続化対応は別途必要です。

DBもコンテナだったら、EC2側に、ボリュームを設定してあげるとかで対応できるはずです。
ただEC2関連の理解がまだまだ浅いので、間違ってたら指摘待ってます！

そして、ソースをコンテナに乗っけるって部分も
おそらくもっとスマートな方法があると思うので、
その辺は次回構築時か、環境見直そうぜって時に調査実装したいなと思ってます！

## まとめ
今回AWSを初めてしっかり触って環境構築をしていきました。
時々先輩エンジニアの知恵をお借りしてセキュリティ部分を設定したり、
EC2のロードバランサーを設定したりしましたが、初学者にはサービスとサービスの連携が少し難しいと感じました。
（結果的に、かなり自己流の設定になってそうなので、工数が許されるのなら作り直したい、、w）
ある程度基本的なEC2の知識がある状態で、ECSに手を出すのがオススメです！

そして本記事で紹介している方法とは別で
より良いコンテナクラウド化の方法がわかる方は、こっそり教えてくださいませー！

本日も最後までお読みいただきありがとうございました！

また今度ネタができたら呟きます！
CentOS8でポートフォワード

# firewall-cmdでポートフォワードする場合
firewall-cmdでポートの行き先を指定する場合、今までルーティングテーブルの設定したり、ルーするサーバでポートを開けたりしていたが、ポートフォワードの場合は不要だったことに今更気づいたのでメモ。

クライアント(client)がルータ(rt)のport80にアクセスしたら、サーバ(sv)のport8080に転送させたい場合の設定。こんな感じ。

```
(client) --------------> (rt) -------------> (sv)
             ip:10.10.20.254        ip:10.10.10.20
             port:80                port:8080
```

### 設定前

```shell
[rt]# firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: eth0 eth1 eth2
  sources: 
  services: cockpit dhcpv6-client ssh
  ports: 
  protocols: 
  masquerade: no #マスカレード無効
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 
[rt]# cat /proc/sys/net/ipv4/ip_forward
0 # forward無効
```
### ポートフォワードを設定する

```shell
[rt]# firewall-cmd --add-forward-port=port=80:proto=tcp:toport=8080:toaddr=10.10.10.20 --permanent
[rt]# firewall-cmd --reload
```
### 設定後

```shell
[rt]# firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: eth0 eth1 eth2
  sources: 
  services: cockpit dhcpv6-client ssh
  ports: 
  protocols: 
  masquerade: no #マスカレードは無効のままで変更なし
  forward-ports: 
        port=80:proto=tcp:toport=8080:toaddr=10.10.10.20
  source-ports: 
  icmp-blocks: 
  rich rules: 
[rt]# cat /proc/sys/net/ipv4/ip_forward
1 #forwardが有効に変更
```

これだけでいけるらしい。

### 接続確認
クライアント(client)からルータ(rt)の80番ポートにアクセスし、サーバ(sv)の8080ポートにフォワードできていることを確認。

```shell
[client ]$ curl http://10.10.20.254:80　#ポート番号なしでもOK
# 10.10.10.20:8080の内容が表示される
```


今まで、ルーティングを設定したりマスカレードをいじったりしてたけど意味がなかった。。。
【LaTeX】でsubfilesを使ってファイル分割をしているとき、draftにして画像を枠で置き換える

最近私はLaTeXでsubfilesを使ってファイル分割をしています、というのもSandyBridgeおじさんなのでtexファイルのビルドが遅いからです。

その時、分割されたページをビルドする際は画像を枠だけにして、メインのtexファイルをビルドするときは画像をちゃんと埋め込むということをできないか考えました。
画像を埋め込むとビルドやレンダリングの時間が増加するので...

# ファイル構成
- main.tex
- imgs/test.png
- pages/4_aaaaaaa.tex

# ファイル
```tex:main.tex
\providecommand{\main}{..}
\documentclass[dvipdfmx]{jsarticle}
\usepackage[dvipdfmx]{graphicx}
\usepackage{subfiles}

\usepackage{graphicx}
\graphicspath{{\main/imgs/}{imgs/}}

\title{\vspace{-3cm} Problem set} 
\author{\vspace{-1cm} だれそれ\thanks{うんたらだいがく がくぶ2年}}
\date{最終更新:~\today~\currenttime~(JST)}

\begin{document}

    \maketitle

    \subfile{pages/4_aaaaaaa}

\end{document}
```


```tex:4_aaaaaaa.tex
\makeatletter
\def\@classoptionslist{draft}
\makeatother

\documentclass[../main]{subfiles}
\setcounter{section}{3}

    
\begin{document}
 \includegraphics[width=16cm]{test.png}\\
よって、企業の限界費用関数は
\end{document}
```

# 結果
## 4_aaaaaaa.texのほうをbuild
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245977/373ec286-6bec-99c4-6b06-a85a610982c3.png)

## main.texのほうをbuild
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245977/a001a08e-030a-cc9b-7aff-eb3ecad801e1.png)


# Ref
- https://tex.stackexchange.com/questions/262342/subfiles-not-detecting-draft-mode
railsで投稿日時を日本時間にする方法

# 開発環境
Mac OS Catalina 10.15.7
ruby 2.6系
rails 6.0系


# 前提
記事投稿機能は実装済みです。(postモデル)

# application.rbファイルを編集

config内のapplication.rbファイル内に以下の記述を追加します。

```
config.i18n.default_locale = :ja
config.time_zone = 'Tokyo'
```

```application.rb
module Anipho
  class Application < Rails::Application
    # Initialize configuration defaults for originally generated Rails version.
    config.load_defaults 6.0

    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration can go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded after loading
    # the framework and any gems in your application.
    # 以下2行を追加してください
    config.i18n.default_locale = :ja
    config.time_zone = 'Tokyo'
  end
```

# ja.ymlファイルを編集

config/localesディレクトリ内にja.ymlファイルを作り、その中に以下の記述を追加します。

```ja.yml
ja:
  time:
    formats:
      default: "%Y/%m/%d %H:%M"
```

自分の場合は既にコードがあったので、以下のような感じになります。

```ja.yml
ja:
  activerecord:
    models:
      post: 投稿
    attributes:
      post:
        images: ペットの写真
        title: 写真のタイトル
        category_id: ペットの種類
  time:
    formats:
      default: "%Y/%m/%d %H:%M"
```

ymlファイルはインデントが合わないだけで正常に作動しないので、繊細に作業する必要があります。

# ビューファイルに投稿日時を表示する

最後にビューファイルに投稿日時を表示する記述をします。

記述する際にはlメソッド を使います。

```show.html.erb
<div class ="time">投稿日時：<%= l @post.created_at %></div>
```

最終的に以下のようなビューになりました。

![スクリーンショット 2021-01-29 19.22.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1035658/872f7066-a1f6-1e56-bbb1-4f89e9a099f4.png)

以上です。参考になれば幸いです。
Ruby on Rails 6でFaceBook APIを本番環境でも使用する

# 初めまして
私は、現在オリアプ制作中で、FacebookのAPIを使用し、ログインできるようにしたいと思い実装しました。
ローカル環境で動作していたものの本番環境(heroku)ではうまく動作せず、ハマっていたので解決した方法を備忘録として残したいと思います！
APIの詳細設定や導入方法を割愛させていただきます。

# 開発環境
Ruby on rails6
heroku/7.47.11 darwin-x64 node-v-12.16.2

# 解決方法

https://developers.facebook.com/
↑にて
①ログインしていただき、Facebookで作成したアプリ名をクリックします。
②左側のサイドメニューの欄に「FaceBookログイン」→「設定」をクリックします。
③クライアントOAuth設定の画面に飛びますので、「有効なOAuthリダイレクトURL」の中に下記を記述をします。

```
https://ご自身のアプリ名/users/auth/facebook/callback
```
④変更を保存をクリックします。
これで本番環境でも正常に動作することが確認できました。

#最後に
まだまだ、知識不足ですので、説明足らずな箇所があると思いますがご容赦ください。
ここまで読んでいただきありがとうございました！
無料・10分でできる、BigQuery サンドボックス利用手順

■想定する読者
　・ローカルにあるデータをアップロードして、さくっとクエリを書いて分析したい方
　・Big Query等、クラウドSQLの分析環境構築が未経験で、構築手順を知りたい方
　・簡単、無料、クレジットカード登録不要でやりたい方

■要旨
　・BigQuery サンドボックスが便利
　・googleアカウント作成～クエリ回すところまで手順を画像で紹介

■注意
　・2021/1/29時点の情報です。
　・googleの利用条件変更、UI変更等が発生する可能性がありますので、説明内容と現在の環境が乖離している可能性があります。

■BigQuery サンドボックスとは
>BigQuery サンドボックスを使用すると、サンドボックスの制限範囲内で BigQuery の機能に自由にアクセスできます。このサンドボックスでは、クレジット カード情報を入力することなく、Cloud Console を使用できます。また、サンドボックスを使用する際に、プロジェクトで請求先アカウントの作成や課金の有効化を行う必要はありません。

<br>
<br>


☆☆☆☆☆利用手順☆☆☆☆☆

① Googleアカウントの作成（既にアカウントがあれば不要）
② BigQuery サンドボックスの使用


① Googleアカウントの作成
以下のページから、「自分用」（ビジネス管理用でも可）を選択し、アカウントを作成する。
https://support.google.com/accounts/answer/27441?hl=ja

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064424/32163c00-db5f-a275-dd07-1f60fef0709b.png)

>Google アカウントのログインページに移動します。
[アカウントを作成] をクリックします。
名前を入力します。
[ユーザー名] にユーザー名を入力します。
パスワードを入力して確認します。
[次へ] をクリックします。
（省略可）アカウントの電話番号を追加して確認します。
[次へ] をクリックします。

<br>
<br>

② BigQuery サンドボックスの使用

以下のページから、「Cloud Consoleに移動」をクリックし、手順に従う。
https://cloud.google.com/bigquery/docs/sandbox?hl=ja

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064424/54b7caf7-4c7a-7d3f-7a1e-337e21c74e0b.png)

>サンドボックスを開く手順は、次のとおりです。
Cloud Console を開きます。
ナビゲーション ペインで [BigQuery] をクリックします。また、ブラウザに次の URL を入力して、Cloud Console を直接開くこともできます。
利用規約に同意します。
BigQuery サンドボックスを使用する前に、プロジェクトを作成する必要があります。プロンプトに従って新しいプロジェクトを作成します。
プロジェクトを作成すると、Cloud Console に次のようなサンドボックス バナーが表示されます。

[GCP操作手順（画像）]

・GCP画面初期ポップアップ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064424/14661279-0654-6396-6856-dab0bfb30d65.png)

・BigQuery画面（https://console.cloud.google.com/bigquery）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064424/487fe372-2dce-2dbc-e8f0-446bdbb99373.png)

・プロジェクトを作成する（プロジェクト名は適当でOK）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064424/a142c2ae-1af6-a2aa-4b1e-d47a8edf2816.png)

・しばらくするとプロジェクトが作成される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064424/0da96bd3-e132-ccbe-b6b6-b47c0e28d68a.png)

・データセットを作成する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064424/4c94062d-4cd4-56cf-65dd-8d0a970b705d.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064424/fb0cb132-1517-cb78-3ab4-806940ee269c.png)

・テーブルを作成する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064424/1df1932c-77f8-e076-8750-120802d8fe60.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064424/565c564e-b346-85e1-fb44-c567b12788af.png)

・クエリを実行する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064424/f2bd60ce-e945-4776-57a8-c738e735d463.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064424/9d058cbf-3701-c2a3-46d8-43008a8e87d8.png)

<br>
Enjoy!
【Python】Excelシート見出しの色を変更する。

pythonを使用してExcelファイルの操作を勉強しています。
本日の気づき(復習)は、Excelシート見出しの色を変更です。
# 見出しの色変更
同じフォルダー内にあるExcelファイル「テスト」の見出しの色を変更させます。

```python:例
from openpyxl import load_workbook

wb = load_workbook('テスト.xlsx')

for i, ws in enumerate(wb.worksheets):
    ws.sheet_properties.tabColor = 'ff8c00'

wb.save('テスト_変更後.xlsx')
```
## 色の指定方法

```python:色を変更している記述
ws.sheet_properties.tabColor = 'ff8c00'
```

色の指定は正直迷いましたが、「cssの色指定と同じかも」と仮定してみたら
意外とすんなりいきました。
CSSとの違いは頭の「＃」をどける事でしょうか。
色見本はこちらのサイトを参考にさせて頂きました。
https://www.colordic.org/
表示されている記述の＃以外をコピーして貼り付けただけです。
ありがとうございます！

## 条件付け
上記の記述はシートの見出し全てに同じ色を付けるものでしたので
条件を付けて合致するシートだけ色を変更するようにしてみます。

```python:5シートおきに色を変更させる
for i, ws in enumerate(wb.worksheets):
    if (i + 1) % 5 == 0:
        ws.sheet_properties.tabColor = 'ff8c00'
```

ポイントは左から数えて何番目かということでしょうか。
if文を使えばいろんな指定が出来そうで楽しみです。
Rubyやcssと似た記述があってちょっとほっとしたのは内緒です。
DB上でTimestamp型のカラムはSqlResultSetMappingするとjava.util.Date型にマッピングされる件

# DB検索結果がオブジェクトにマッピングされない

SpringbootでNativeQueryでDBにアクセスする時、Entityと素直にマッピングされない結果が欲しかったため、以下の方法で独自クラスにマッピング定義をして結果を格納するようにしました。

- 結果セット格納用POJO

```ForMapping.java
@Data
@AllArgsConstructor
public class ForMapping {
	private Long id,
	private String name,
	private Timestamp created
}
```

※コンストラクタやsetter/getterはlombokでやってます。

- Entityクラス

```SomeEntity.java
@SqlResultSetMapping(name = "MappingDef", classes =
{
	@ConstructorResult(targetClass = ForMapping.class, columns =
	{
		@ColumnResult(name = "id", type = Long.class),
		@ColumnResult(name = "name", type = String.class),
		@ColumnResult(name = "created", type = Timestamp.class),
	})
})
```

テーブル上は、idはlong、nameはTEXT、createdはTIMESTAMP型だったので、それぞれ対応するJavaのクラスを型に指定してマッピングを試みます。

これでSQLを実行して結果を取得しようとした所、結果が1件も取得できませんでした。地道にデバッグしてみると、SQLの実行自体は成功していましたが、結果セットのPOJOへのマッピングのあたりで失敗しているようでした。こんなエラーメッセージが。

```
Could not locate appropriate constructor on class
```

エラーメッセージはHibernateの以下の部分で出ていることが分かりました。やはり、SQLの結果セットをPOJOにマッピングするところのようです。

```ConstructorResultColumnProcessor.java
private static Constructor resolveConstructor(Class targetClass, List<Type> types) {
	for ( Constructor constructor : targetClass.getConstructors() ) {
		final Class[] argumentTypes = constructor.getParameterTypes();
		if ( argumentTypes.length != types.size() ) {
			continue;
		}

		boolean allMatched = true;
		for ( int i = 0; i < argumentTypes.length; i++ ) {
			if ( ! areAssignmentCompatible( argumentTypes[i], types.get( i ).getReturnedClass() ) ) {
				allMatched = false;
				break;
			}
		}
		if ( !allMatched ) {
			continue;
		}

		return constructor;
	}

	throw new IllegalArgumentException( "Could not locate appropriate constructor on class : " + targetClass.getName() );
}
```

ソース
https://github.com/hibernate/hibernate-orm/blob/5881b88173d5d8727f8e4aec064751107f430da4/hibernate-core/src/main/java/org/hibernate/loader/custom/ConstructorResultColumnProcessor.java#L71


# 原因はマッピング定義の型誤り
デバッグで分かりましたが原因は単純で、createdという項目をjava.sql.Timestamp型で指定しているのがNGだったようです。これにより、マッピングしようとしてもマッチするコンストラクタが見つからん！ということで、先のエラーメッセージでした。

公式の情報が見つけられなかったのですが、ネイティブクエリの結果セットをマッピングする時にDB上のTIMESTAMP型をjava.util.Dateにマッピングする、という情報を以下URL内で見つけました。

（参考）
https://stackoverflow.com/questions/24160817/getting-error-could-not-locate-appropriate-constructor-on-class

マッピングの定義部分とPOJOの型をjava.util.Dateに変更したところ、無事結果を取得できるようになりました。
【ターミナル初心者よく使うコマンド（小学生でも分かる解説）】

#コマンドの実行
コマンド（命令）の実行の仕方はいたって簡単。

・＄（モノによっては％）の右側にコマンドを入力
・Enterを全力でタップ

そうすると、結果が勝手に出てくる。
ただ、モノによっては結果は出ないで、移動だけするとかもある。

#最低限覚えるコマンド

###「../」 → 一つ上のディレクトリ（カバン）を指定###

ごめんなさい、これだけコマンド（命令）ではない💦

例：フォルダ２（カバン２）の中にフォルダ３（カバン３）が入っていて、今カバン３を開いている

```
../フォルダ３（カバン３）
```

これで、フォルダ３（カバン３）の1つ上のフォルダ２（カバン２）を指定できる

###「pwd」 → カレントディレクトリ（今いる場所）を表示する###

```
＄ pwd
/Users/folder2
```
結果の一番右に書いてあるのが、今いる場所。
「folder2」に、今いるということがわかる。

###「ls」 → カレントディレクトリにあるファイル・フォルダを全部表示する###

```
$ ls
Application Music Desktop
```
カレントディレクトリの中身を全部見れる。カバンを開いて、取り出さずに中身だけ見る感じ。
この場合は、「Application」「Music」「Desktop」という３つのファイル/フォルダがあることがわかる。
※「ls」の「l」は、「アイ」じゃなくて、「エル」
※これは**見るだけ**だから、移動はしてないことにも注意

###「cd」 → ディレクトリを移動する###

```
$ cd （移動先）
```
例えば、（移動先）にDesktopと書けば、Desktopに移動する。
（移動先）は、さっきの「ls」コマンドをしてから、出てきた中から選ぶのが一般的。

###「mkdir」 → 新規のディレクトリを作成する###

```
$ mkdir （作るディレクトリ名）
```
「mk」は「make」つまり、作る
「dir」は「directory」つまり、ディレクトリ 
そのまんま。
例えば、（作るフォルダ名）にnew_folderと書けば、new_folderという新しいディレクトリが作られる。
※今いるところに作られるから、今どこにいるかを確認しておくこと

##「rm」 → ディレクトリを削除する##

```
$ rm （削除するファイル名）
```
「rm」は「remove」の略
例えば、（削除するファイル名）にnew.htmlと書けば、new.htmlが削除される。
カバンの中のノート１冊を捨てるような感じ。

```
$ rm -r （削除するディレクトリ名）
```
このように「-r」をつけると、ディレクトリごと削除できる。
例えば、（削除するファイル名）にnew_folderと書けば、さっき作ったnew_folderが中身ごと削除される。
ノートの入ったカバンごと捨てるような感じ。

##「mv」 → ファイルやディレクトリを移動する##

```
$ mv （移動元ファイル名） （移動先ディレクトリ名）
```
例えば、（移動元ファイル名）にnew.htmlを、（移動先ディレクトリ名）にnew_folderを書くと、new_folderの中にnew.htmlが入る。

その他コマンドはいっぱいあるけど、とりあえずこれらを覚えておけば使える。
わからなかったらその都度調べるべし。
Kubernetesでkubeadm initがCrashLoopBackOffのメッセージを出して失敗する。（企業イントラネット内環境等）

CNIにtigera-operatorを使って複数のCNIを持つKubernetes環境を構築しようとした際に、
kubeadm init が、pods tigera-operatorがエラーで終了し、
namespace:calico-systemのpodsが立ち上がらない現象が発生し、
なかなか他の似たような記事が見当たらなく、数日はまったので誰かの役にたてればと思い、残します。。
時間がない人は、一番↓に結論書いてあります。


kubeadm initまでは、下記記事参考
https://docs.projectcalico.org/getting-started/kubernetes/quickstart。
また、このエラーは恐らくOSやバージョンには非依存です。
が、念のため筆者の環境をのせておきます。

```
$ uname -a
Linux core5-ub-dk02 5.4.0-52-generic #57~18.04.1-Ubuntu SMP Thu Oct 15 14:04:49 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
```

kube init後
podsが起動するのを待ってると...

```
$ kubectl get pods -A
NAMESPACE         NAME                                      READY   
--------
snip
--------
tigera-operator   tigera-operator-cdc4b6478-rlrlz            0/1       CrashLoopBackOff   2          1m
```
CrashLoopBackOff?とはなんぞ。
失敗して、何度か再起動を繰り返している様子。
podsのログをのぞいてみる。

```
$ kubectl logs tigera-operator-cdc4b6478-rlrlz -n tigera-operator

....snip....
Dial tcp 10.96 0.1 443: getsockopt: no route to host
```
ほう。。

これは、何のIPアドレスだっけと思い調べると、

```
$ kubectl get services
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   24h
```

えええ
ここは、うまいことNATやらルーティングやらでつながるようにしてくれてるでしょ普通ー。
と思ったので、NATが上手くいってないのかと思い、もう一度作り直した。
以下、色々リセットするためのコマンド。公式には、上から3つぐらいしか書かれていない

```
sudo  kubeadm reset
sudo rm $HOME/.kube/config
sudo rm -rf /etc/cni/net.d/*
sudo sudo iptables -F && sudo iptables -t nat -F && sudo iptables -t mangle -F && sudo iptables -X
sudo systemctl stop kubelet
sudo systemctl stop docker
sudo iptables --flush
sudo iptables -tnat --flush
sudo systemctl start kubelet
sudo systemctl start docker
sudo iptables -P FORWARD ACCEPT
```
しかし、その後構築し直すも同じく失敗。

んー、なんかホストのネットワーク関連っぽいな。
試しにインターネット直接繋がる環境でやってみると、すんなり完了。
色々さ分見ながら切り分けすと、

```
# ip a
# ip r
```
上記コマンドで差分をみてみると、なんと、
Kubernetesホスト上のルーティングテーブルに、**デフォルトゲートウェイが設定されていなかった**のが問題だった。。

弊社のイントラネット内だと、デフォルトゲートウェイの設定とかいらないので、（外にでたい場合はHTTP-Proxyを指定する）デフォゲ設定してなかったのだ。。

こんなので数日はまるとは。。。
Docker関連の外にでれない環境内での構築ははまりますなあ。
VSCode: リモート開発環境のほうにローカル側のExtensionsを簡単に入れる方法

# 背景
- VSCodeを使って、リモート環境に接続して開発したいとき、
- 各リモート環境毎に拡張機能（Extensions）を追加する必要があります
- settins.jsonのほうに自動でインストールする拡張機能を記述しておく方法はありそうですが、記述するのが面倒に感じました
- VSCodeのUIを触っていたら簡単にできたので、備忘録として残しておきます

# 試した環境
- OS: Windows 10 + WSL (Ubuntu 18.04) and SSH (Ubuntu 18.04)
- VSCode: v1.52.1
- 必要だと思われるExtensions:
    - Remote-WSL: v0.52.0
    - Remote-SSH: v0.63.0
    - Remote Development: v0.20.0
- 分かりやすいように私のローカルでのVSCodeにはテーマを適用しておきます。
    - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143120/c43bd476-de49-426b-57d5-b80f610776a5.png)


# 手順
- Remoteに接続する（詳細は割愛）
    - やり方はいろいろありますが、例えば、左下の下記アイコンから接続します。
    - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143120/0bbe2ca0-733a-c215-fedf-cbfbcd780f9a.png)
    - 最初は何もインストールされていないシンプルな状態です。
    - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143120/ec39f0bd-11d0-128c-bf29-b352519363f8.png)
- 左側のアイコンで、拡張機能（Extentionsを選びます）
    - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143120/c4e82c9e-a8cd-42ad-78bc-d3634efa9831.png)

- 次のようなペインが出てきます
    - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143120/bacc2991-4561-d905-96dc-488752223585.png)
- `LOCAL-INSTALLED`の行にダウンロードっぽいアイコンがあるのでそれを押下します
    - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143120/7c74efee-e796-8eea-2def-746d6aba3b91.png)
- 次のようなメニューが出ます
    - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143120/047c1a39-4c95-3063-f617-a9860ae683f0.png)
- インストールしたい各拡張機能を選択するか、全選択をして、OKすると、インストールされます
    - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143120/544ead5c-fa28-486d-76bd-907eb85a311c.png)
- 以上でローカル環境と同じ状態になりました。最後まで読んでいただき、誠にありがとうございます。
    - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143120/daaaa5a2-7aa7-b488-0e19-aff113b1cda5.png)
「全て異なる」という条件をPythonで実験する

## はじめに

「a, b, cは全て異なる値かどうか」という条件に遭遇したので、いろいろ実験したメモです。


## やりたいこと
変数a, b, c 全ての数値が異なる場合は「全て異なる値です」と出力し、そうでない場合は「同じ値が含まれています」と出力するプログラムを考えます。


## 実験1: `a!=b!=c`と書く

``` python.py
a = 0
b = 1
c = 0 # a=cのため、同じ値が含まれている
if a != b != c:
    print("全て異なる値です")
else:
    print("同じ値が含まれています")

# 出力 -> "全て異なる値です"
```

「全て異なる→ `a==b==c`の逆なので`a≠b≠c`」と書いてしまうかもしれませんが、上記の通り、正しく判別することはできません。

Pythonの[公式ドキュメント](https://docs.python.org/3/reference/expressions.html#comparisons)を見てみましょう。

> Comparisons can be chained arbitrarily, e.g., x < y <= z is equivalent to x < y and y <= z, except that y is evaluated only once (but in both cases z is not evaluated at all when x < y is found to be false).

「 "x < y <= z" は "x < y and y <= z" と等しい」と書いてあります。

つまり、`a!=b!=c`は`a!=b and b!=c`の判定を行なっているだけでは (≠では推移律が成り立たないので) 、**`a!= c`が成り立っているかどうか** は保証されないということです。
<details><summary>(実際に試してみたメモ)</summary><div>

```python:python.py
a, b, c = 0, 0, 1

if a != b != c:
    print("Yes")
else:
    print("No")

# No
# 0 != 0 が偽になるため。

# 一方で、

a, b, c = 0, 1, 0

if a != b != c:
    print("Yes")
else:
    print("No")

# Yes
# 0 != 1 は真であり、かつ、1 != 0 も真であるため、論理式は真になる。
```
</div></details>

先程の`a = 1, b = 0, c = 1`を例にすると、$a≠b$ かつ $b≠c$であることは確認しているけれども、「$a≠c$であるかどうか」までは確認していないことになります。

そもそも、$a=b=c$, $a < b ≦ c$ はあっても、 $a≠b≠c$ という式の書き方は、数学や論理式の文脈でグローバルに定義されているものではありません。このような書き方は、たとえ他の言語で運良く意図通りに動いたとしても、可読性の観点から好ましくはないと考えられます。

## 実験2. `not (a==b==c)`

``` python.py
a = 0
b = 1
c = 0
if not (a == b == c):
    print("全て異なる値です")
else:
    print("同じ値が含まれています")

# 出力 -> "全て異なる値です"
```

論理式を把握されている方からすれば当然と思われるでしょうが、これも「全て異なる」の判定には使えません。
「全て等しい」の否定は「少なくとも1つ異なる」と等しいため、1つだけでも異なるものがあれば真と判定されるためです。

では、どう書けば「全て異なる」を正しく判定できるのでしょうか。


## 正しい書き方

```python.py
if a!=b and b!=c and c!=a:
    #省略
```

素直に「全て異なる」という条件の中身を展開して、端折らずに書くのが最善と考えられます。

```python.py
if a!=b!=c!=a:
    #省略
```

短く書きたいならば、先述したPythonにおける比較の定義を利用し、 `a!=b!=c!=a` と書くことで、上と同じ判定を行うこともできます(共有ありがとうございます)。
ちなみに、3個以上の比較でも同様に定義されていることは、[公式ドキュメント](https://docs.python.org/3/reference/expressions.html#comparisons)に記載されています。

>Formally, if a, b, c, …, y, z are expressions and op1, op2, …, opN are comparison operators, then a op1 b op2 c ... y opN z is equivalent to a op1 b and b op2 c and ... y opN z, except that each expression is evaluated at most once.
</div></details>

先述したように、数学や論理式として定義されたものではありませんが、可読性はそこまで損なわれないと思います。

ただ、これらの書き方は、4つ以上の要素がある場合には使えません。`a!=b and b!=c and c!=d and d!=a`だけでは、`a!=c`と`b!=d`を判定できないためです。

その場合には、以下のような方法が考えられます。

```python.py
s = [a,b,c]
if len(set(s)) == len(s):
```

`set`型 (集合) を利用して、「`set`型に`list`の`[a,b,c]`を入れ、重複がなければ`set`の要素数が`list`の要素数と等しい」という書き方です(共有ありがとうございます)。
これならば4つ以上でも簡潔に判定できます。

 set型については[こちら](https://note.nkmk.me/python-set/)に分かりやすく解説されています。
Cluster API: v0.3.13 変更内容

## はじめに

ここでは Cluster API v0.3.13 の変更内容についてまとめています。

- https://github.com/kubernetes-sigs/cluster-api/releases/tag/v0.3.13

Cluster API は複数の Kubernetes クラスタのプロビジョニングやアップグレード、オペレーションをするための宣言的な API とツールを提供する SIG Cluster Lifecycle のサブプロジェクトです。

## ✨ 新しい機能

- ApiServer、ControllerManager、Scheduler について KubeadmControlPlane (KCP) spec の変更を許可 ([#4080](https://github.com/kubernetes-sigs/cluster-api/pull/4080))
    - :memo: APIServer、ControllerManager、 Scheduler の設定が変更できなかったようです（どう考えてもそれは困る
    - :memo: そういえばこないだ設定変更しようとしてできないなと思っていたところでした🤘
- "delete" annotation によってスケールインで優先する KubeadmControlPlane マシンのマーキングをサポート ([#4019](https://github.com/kubernetes-sigs/cluster-api/pull/4019))
    - :memo: KCP の Machine オブジェクトに `cluster.x-k8s.io/delete-machine` annotation を付けておくとそのマシンが最優先で削除されるようになりました
- `clusterctl describe cluster` コマンドの追加 ([#4088](https://github.com/kubernetes-sigs/cluster-api/pull/4088))
    - :memo: Cluster オブジェクトに連なる Cluster API 関連のオブジェクトをツリー形式で出力するコマンドです

## 🐛 バグ修正

- kubeadm bootstrap スクリプトで、`error_exit` コード引数を設定 ([#4106](https://github.com/kubernetes-sigs/cluster-api/pull/4106))
    - :memo: エラー時に終了コードを出力するように変更されています（バグ修正ではない気がするが）
- IPv6 の APIEndpoint を修正 ([#4066](https://github.com/kubernetes-sigs/cluster-api/pull/4066))
    - :memo: IP アドレスとポートをジョインする部分のコードが IPv6 が入ってくることが考慮されていなかったようです
- KubeadmControlPlane は、v1alphav2 kubeconfig secrets を受け付けるようになりました ([#4050](https://github.com/kubernetes-sigs/cluster-api/pull/4050))
    - :memo: v1alphav2 で作成された kubeconfig を含む Secrets が v1alphav3 にアップグレードすると使われないという問題があったようです

## 📖 ドキュメンテーション

- 開発者ガイドに必須な情報として envsubst を追加 ([#4025](https://github.com/kubernetes-sigs/cluster-api/pull/4025))
    - :memo: Cluster API のプロバイダの開発者にとって envsubst について知っておくのは必須です！
    - :memo: ちなみにこの enbsubst は、gettext のものではなく Go で実装された別のコマンドなことに注意してください（[drone/envsubst](https://github.com/drone/envsubst))

## 🌱 そのほか

- repolist を使用するための任意のパラメータを追加 ([#4102](https://github.com/kubernetes-sigs/cluster-api/pull/4102))
「JavaScript」関数定義

# 関数とは
Rubyでいうところのメソッドを、JavaScriptでは関数と呼びます。

Rubyでメソッドを定義する際はdef メソッド名 ~ endと記述しました。一方で、JavaScriptではfunction 関数名(){ 処理 }と記述することで関数を定義することができます。

#### function
functionを用いることで関数を定義することができます

```
function 関数名( ) {
  // 処理
};
```
#　JavaScriptの戻り値
JavaScriptでは関数の戻り値をreturnを用いて明示する必要があります。

```
function calc(num1,num2){
  return num1*num2
};

const num1 = 3
const num2 = 4
console.log(calc(num1,num2))
```

上記のように最終的に返したい結果の部分にreturnをつけてあげてください。

# 関数宣言と関数式について
関数宣言については上記で紹介した

```
function 関数名( 引数 ){
  // 関数内の処理
};
```
特徴として下記で紹介する関数式とは違い関数宣言は先に読み込まれます。
順番に読み込まれるのではないので定義している文より先に呼び出す文があってもエラーにならず結果を返してくれます。
####関数宣言
一方で、関数式の場合は、function(){}という無名の関数を変数に定義または代入して関数を定義する、という記述になります。

```
変数 = function( 引数 ){
  // 関数内の処理
};
```
こちらは逆に順に読み込まれるので定義前に呼び出したりすると定義されていないよとエラーになること間違い無いでしょう。


# 関数式の種類
###無名関数
無名関数は、関数名なしで関数を定義することができます。より簡潔なコードが記述できるというメリットがあります。

```
// 関数宣言
function hello(){
  console.log('hello')
};

// 関数式（無名関数）
const hello = function(){
  console.log('hello')
};
```

###即時関数
即時関数とは、関数を定義すると同時に実行される構文です。関数を定義してから呼び出すという手間を省くことができます。
()の中にfunctionからはじまる関数定義そのものを配置することで、その関数を即実行するということができるようになります。その結果、関数を呼び出すという手間が省けます。

```
// 無名関数
const countNum = function(num) {
  console.log(num)
}
countNum(1);

// 即時関数
(function countNum(num) {
  console.log(num)
})(1);
```
###　アロー関数
アロー関数とは以下のようにfunctionの記述を省略し、その代わりに（）=>という記述によって関数を定義する構文です。より短い記述で関数定義をできるというメリットがあります
このように、アロー関数を用いることで短い記述で関数を定義することができます。

```
// 無名関数
const 変数名 = function(){
  処理
};

// アロー関数
const 変数名 = () => {
  処理
};
```
初心者必見！固定値（キー、URLなど）は.envファイルに書いて再利用しよう！！（Laravel偏）

皆さんこんにちは！

３日前くらいに書いた記事（[初心者必見！固定値（キー、URLなど）は.envファイルに書いて再利用しよう！！](https://qiita.com/akki-memo/items/c33348cfce315548ac6b)）が中々好評だったので、改めて``env``ファイルについて書いていこうと思いました。

前回書いた記事では、Vue.jsで``env``ファイルの使用方法を書きました。

今回はタイトルにも書いてる通り、「Laravel」偏です。

今一度、``env``ファイルについて説明しようと思います。

知っている方は、スルーで結構です。

Javascriptでバックエンドとやり取りを行うとき、恐らく多くの方が以下のように書かれると思います。

```
axios.get('http://127.0.0.1')
```

ここで問題なのが、これを実際にサーバーにアップロードする時って、``http://127.0.0.1``のようなローカルホストとは接続を行いませんよね？

また、その都度バックエンドのURLをコピーしてくるのもナンセンス。

そんなこんなで出てくるのが``env``ファイル！！

・一度値を設定してしまえば、使いまわしOK！

・シークレットキーなどのセキュリティ面でも活躍！（ファイルに直接キーを入力するのは、githubにあげるときに見られてしまうため）

・ローカルと本番環境の使い分けができる！（今回はここはやりません）

こんなに魅力的なんです！

まぁ話はこの辺にしておいて、当然の如くVue.jsとLaravelではやり方が違うので、使い方を一緒に見ていきましょう！

#envファイルに定数を設定#

プロジェクト直下に``.env``というファイル名があると思うので、それを開いてみてください。

そしたら、以下を例に値を設定して見て下さい。

```.env
RECAPTCHA_SECRET_KEY = 'ciascihsiachuhewurvuvurw'
```

定数名は、自分で分かりやすいように設定してください！

#configファイルで値の設定#

次に、``config``ディレクトリを開き、``app.php``を開いてください。

Vue.jsでは``.env``ファイルに記述して終わりだったのですが、Laravelでは``.env``ファイルを読み込まない設定なので、configで設定します。

```config/app.php
'RECAPTCHA_SECRET_KEY' => env('RECAPTCHA_SECRET_KEY')
```

先ほど``env``ファイルで設定した名前を``env(name)``で呼び出し、``'RECAPTCHA_SECRET_KEY'``のように適当に名前を付けて下さい！

#呼び出し#

最後に、ここで設定した値を呼び出します。

の前に、いったんキャッシュを消去します。

コマンドプロンプトにて、以下のコマンドをうちます

```
php artisan config:cache
```

最後に呼び出していきます。

```index.php
$secret = config('app.RECAPTCHA_SECRET_KEY');
```

この``app.``は何かというと、``config``ディレクトリの``app.php``の``RECAPTCHA_SECRET_KEY``を呼び出すという意味です。

このようにして、固定値を呼び出すことができます。

いかがだったでしょうか？

簡単かつ作業効率もあがるのでぜひこの機会にガンガン使ってください！！

以上、「初心者必見！固定値（キー、URLなど）は.envファイルに書いて再利用しよう！！（Laravel偏）」でした！

良ければ、LGTM、コメントお願いします。

また、何か間違っていることがあればご指摘頂けると幸いです。

他にも毎日初心者さん向けに記事を投稿しているので、時間があれば他の記事も見て下さい！！

Thank you for reading
抵抗R、電気容量C、インダクタンスLから時間の次元の３つの量を思い出す方法

# はじめに

電子回路でパッと時定数の関係が出てこない場合に思い出す方法を紹介する。これらを暗記してないと、LTspiceなどで回路シミュレーションしているときに、検算がパッとできないので、だいぶ個人的な備忘録です。

## インピーダンスから思い出す方法

インダクタとキャパシタのインピーダンスは、jωL, -j/ωC と書けることを覚えていると、周波数ωの次元は[1/s]であり、jは純虚数(無次元)、インピーダンスは抵抗Rの次元なので、

``` math:
j\omega L = R \rightarrow \frac{L}{R} \propto \frac{1}{\omega} ~~ [{\rm s}] 
```

``` math:
\frac{j}{\omega C} = R \rightarrow RC \propto \frac{1}{\omega} ~~ [{\rm s}] 
```

となるので、L/R, RC が秒[s]の次元を持つ。

次に、この２つを掛け合わせて、

``` math:
\frac{L}{R} \times RC = LC ~ [{\rm s}^2] \rightarrow \sqrt{LC} ~~ [{\rm s}]
```

となるので、$\sqrt{LC}$ も秒[s]の次元を持つことになる。

まとめると、

``` math:
\frac{L}{R},~~~RC,~~~\sqrt{LC}
```

の３つは時間の次元をもつ。この３つの中だと、Rだけが分母と分子にそれぞれ登場している。つまり、LとCは、大きくなると時間も長くなる。Rは、Cとカップルすると時間と正の相関をするが、Lとカップルすると負の相関になる。
(注) RCを２乗して、L/Rで割るとか、次元だけであれば３つ以外の作り方もできるので、あくまで上の３つの場合に限った話ではある)。


## ちゃんと次元解析する方法

ワットの単位は、単位時間あたりの仕事量で、電流と電圧をかけたら電力になるから、、とちゃんと計算すればもちろん時間の次元になる量をだすことができる。

- [電気と電子と光に関わる単位](http://www.ele.kochi-tech.ac.jp/tacibana/etc/analog-intro/ele-units.html)
- [RC並列回路の過渡現象](https://denki-no-shinzui.com/13776/)

など参照されたい。


## 共振回路の例

おまけとして、共振回路のQ値の例も考えてみる。

直列共振回路のQ値は、

``` math:
Q = \frac{\omega_0 L}{R} = \frac{1}{\omega_0 CR} = \frac{1}{R} \sqrt{\frac{L}{C}}

```

であり、並列共振回路のQ値は、

``` math:
Q = \omega_0 CR = \frac{R}{\omega_0 L} = R \sqrt{\frac{C}{L}}
```

である。詳細は、[Q値と周波数特性を学ぶ](https://www.aps-web.jp/academy/ec/191/) を参照ください。

ここでは、L/R と RC が同じ次元であることから、割り算すれば無次元になることを用いて、sqrt{L/C}が抵抗の次元であることを確認しよう。

``` math:
\frac{\frac{L}{R}}{RC} = \frac{\frac{L}{C}}{R^2} [{\rm no~dimension}] \rightarrow \sqrt{\frac{L}{C}} ~~ [{\rm \Omega}]
```
Python スクリプトを自動再起動するメモ

## 背景

numpy + C/C++ native module のある python コードでスクリプト自動リロードをやって開発効率を高めたい.
(native module の import はリロード対応していないため)

yarr で Python で numpy データをさくっと RPC 通信するメモ
https://qiita.com/syoyo/items/c393d1a6d596c7f7f30f

の続きです.

プロセスの自動起動は pm2 など使う手もありそうですが, いろいろセットアップがめんどいのでとりあえずは bash スクリプトで起動しなおしというふうにします.

## 方法

```py
# server.py
import sys
import yarr
import numpy

import socketserver

def proc_numpy(a):
    print(a)

def quit(retcode: int):
    sys.exit(retcode)

# server
socketserver.TCPServer.allow_reuse_address = True
yarr.yarr(('localhost', 8000), [proc_numpy, quit])
```

yarr は内部で socketserver を使っています. 
`allow_reuse_address` を有効にしておかないと, カーネル側でソケットの情報がしばらく(5~10 秒くらい?)残るため, 再起動すると socket address already used エラーになります. これを解決します(もしくは quit するときに socket の close() を明示的に行うか)

### プロセス自動起動

プロセス自動起動ツールとかはぱぱっと使えるいいのが探してもありません
(悪用しやすいからですかね)


とりあえず簡単な bash スクリプトで対応する場合.

```bash
#!/bin/bash

while true; do

  echo "start server..."

  python server.py

  echo "retcode " $?

  sleep 1

  echo "restart server..."

done
```

```python
# client.py
import yarr
import numpy

a = numpy.random.rand(256, 512, 512)

yarr.call(('localhost', 8000), 'proc_numpy', a)

# load() error in yarr will happen when exiting a server, so catch it as a work around.
try:
    yarr.call(('localhost', 8000), 'quit', int(1))
except Exception as e:
    pass
```

呼び出す側です. `yarr.call` では, RPC 発行のあといくつか後処理で相手と通信していますが, quit を呼ぶと相手はプロセス終了しておりエラーが発生してしまいます.
とりあえずは try/except で suppress します.


これで自動でプロセスが再起動するようになりました!


### python 自身で再起動

https://blog.petrzemek.net/2014/03/23/restarting-a-python-script-within-itself/

ありがとうございます. `os.execv` で行けました.
自己実行形式にしていない場合は, `

https://gist.github.com/plieningerweb/39e47584337a516f56da105365a2e4c6

にあるように  `os.execv(sys.executable, ['python'] + sys.argv)` にします.

自己再実行の場合の server は以下のようになります.

```py
import sys
import yarr
import numpy
import os

import socketserver

def proc_numpy(a):
    print(a)

def quit(retcode: int):
    print("restarting... ")
    # Restart python script itself
    os.execv(sys.executable, ['python'] + sys.argv)

# server
print("server start")
socketserver.TCPServer.allow_reuse_address = True
yarr.yarr(('localhost', 8000), [proc_numpy, quit])
```

これで server 側の起動は普通に

```
$ python server.py
```

で起動するだけです! あとは quit コマンドを受け取ったら自分でよろしく再起動してくれます!

特に RPC で分けるほどではないスクリプトの場合(e.g. データロードなど前処理の量が多くない, jupyter-lab など使わずにコマンドラインで実行している)は, `os.execv` であれば単体スクリプトのままで使えますね.

## watchdog と組み合わせ live reload っぽいことをする

ファイルの変更などを watch してくれる watchdog と組み合わせれば,
自前スクリプトをエディタなどで書き換えたときに `os.execv` 呼んで再起動し live reload 相当というのもできます!

ファイルの更新をきっかけにコマンド実行 (python編)
https://qiita.com/ksato9700/items/ea4b769d010e8cf1fb0c

ありがとうございます.



## まとめ

C/C++ native module 含んだ python コードの開発がはかどりますね!
Intel/Appleシリコン対応Universalバイナリーを作ってみた

# Universalバイナリーとは
Apple社がWWDC20で新しいmacOSのバージョンmacOS 11 Big Surの発表と共に自社設計のArmベースのチップ（Appleシリコン）をMacに搭載することも発表した。
今までのIntelのチップからAppleシリコンの移行をよりスムーズなものにするために、AppleはPowerPCからIntelへの移行の時と同様、二つのツールを発表した。一つはIntel用のバイナリーをARM用に動的に変換するプログラムRosetta2。そして、もう一つがIntel、ARM両方で実行できるUniversalバイナリー。
今回はXcode12でUniversalバイナリーをビルドする方法とバイナリーがどのアーキテクチャーに対応しているか確認する方法を紹介する。

# Universalバイナリーのビルド方法
AppleデベロッパーアカウントからXcode12をダウンロードして、既存のXCodeプロジェクトを開く。
プロジェクトの設定画面から、ビルドしたいアプリケーションのビルド設定を表示する。
“Architectures”という項目のオプションから”Standard Architectures (64-Bit Intel and ARM)”を選択する。
![ビルド設定](https://raw.githubusercontent.com/gmorimoto-spc/qiita-src/master/universal-build/xcode_build_setting.png)

ビルドターゲットを”Any Mac(Apple Silicon, Intel)”を選択してUniversalバイナリーをビルドする。
![ビルドターゲット選択](https://raw.githubusercontent.com/gmorimoto-spc/qiita-src/master/universal-build/xcode_change_build_target.png)

今回ビルドするのはプレプロセッサマクロでIntelMac、AppleSiliconMacで別の文字列が出力される簡単な分岐処理が実装されているコマンドラインツールだ。

```objective_c
#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
#if defined(__x86_64__)
    printf("Arch is x86_64\n");
#elif defined(__aarch64__)
    printf("Arch is Arm64\n");
#else
    printf("Unknown architecture\n");
#endif
    return 0;
}
```

ビルドターゲットを"My Mac"にしてビルドしたIntel用バイナリーと比べてみるとUniversalバイナリーの方が2倍ほど大きかった。
![バイナリーサイズ](https://raw.githubusercontent.com/gmorimoto-spc/qiita-src/master/universal-build/ls_checkArchitecture.png)
Intel用の実行コードとAppleSilicon用の実行コードがファイルに格納されているのでUniversalバイナリーは2倍のサイズになっている。

# バイナリーの対応アーキテクチャー確認方法
バイナリーがx86_64とARM両方で実行できるUniversalバイナリーかを確認するためにコマンドラインツールのlipoを使用する。
対応アーキテクチャーを調べるにはオプションの「-archs」を足して実行する。

```sh
lipo -archs バイナリーへのパス
```
コマンドは「lipo -archs バイナリーへのパス」。以下のような返事が表示される。
![対応アーキテクチャー](https://raw.githubusercontent.com/gmorimoto-spc/qiita-src/master/universal-build/lipo_archs.png)
Universalビルドしたバイナリーはx86とARMの両アーキテクチャに対応していることが分かる。

最後にツールがIntel、AppleSilicon環境で違う文字列を出力することを確認した。

**Intel環境**
![Intel環境ツール出力](https://raw.githubusercontent.com/gmorimoto-spc/qiita-src/master/universal-build/checkArchitecture_output_Intel.png)

**AppleSilicon環境**
![AppleSilicon環境ツール出力](https://raw.githubusercontent.com/gmorimoto-spc/qiita-src/master/universal-build/checkArchitecture_output_AppleSilicon.png)

環境に依存するコードはプレプロセッサマクロで分けることができるのは便利なので覚えておこう！
Ruby学習者がPHPを最新版(v8)にアップデートしてみた

プログラミングでRubyおよびRuby on Railsをメインに学習中ですが、**Rubyの復習も兼ねてPHPの基礎も学習**することにしました。

パッと見だと通じる部分も多いようなので、PHPを勉強することでRubyの復習にもなるかな…と考えたからです。

今回は、Macに標準でインストール済みのPHPをバージョンアップします。

# 対象＆前提
・Ruby学習者でPHPもかじってみたい人
・Macユーザー（私はMacOS Catalina(10.15.7)使ってます)
・シェルはzshを使用

# まずは現在のバージョンを確認

ターミナルを起動して、PHPのバージョンを確認するコマンドを叩きます。

```zsh
% php -v              
PHP 7.3.11
```
どうやら、私のPCにはPHP７.３.11というバージョンが入っているようです。

[PHP公式](https://www.php.net/) によると、2021年1月現在は「v8.0.1」が最新とのこと。
早速、バージョンアップしていきます。

# Homebrewを使ってインストール

Macのパッケージ管理ツールである**Homebrew**を使ってインストールしました。
※Homebrew導入済みの前提で書きます。Homebrewのインストール方法は一番下の補足を参照。

```zsh
% brew search php@8    # Homebrewに存在するPHPｖ8のパッケージを確認

==> Formulae
php@8.0 ✔
==> Casks
homebrew/cask/eclipse-php                          homebrew/cask/netbeans-php
```
Homebrewにv8があるようなので、インストールコマンド実行。

```zsh
% brew install php@8.0
```
インストールにはしばし時間がかかります。
インストール中にたびたび出てくるビールマークの誘惑。

インストールが完了したら、バージョンアップされているか確認します。

```zsh
% php -v              
PHP 7.3.11
```

…おや？バージョンアップされてない？？

```
% cd /usr/local/opt/    # いろいろ調べて辿りついたこのディレクトリにはv8いるっぽいが…
% ls
　：
ｐｈｐ
php@8.0
python@3.9    # 余談：あらMacにはデフォルトでPythonも入ってるのね！
　：
```

これまでの数少ない環境構築の経験から、PHPの古い方を参照し続けているのかと仮定。
設定ファイルにパスを追記することにしました。

ターミナルからｖｉエディタを起動して、以下の1行を書きこみ。

```vim
export PATH="/usr/local/opt/php@8.0/bin:$PATH"
```

escして:wq(書き込み保存してから終了)。
設定の再読み込みのため、以下のコマンドを実行。

```zsh
% source ~/.zshrc    # 設定再読み込み
```

再度、PHPのバージョン確認コマンドを打ってみる。

```zsh
% php -v              
PHP 8.0.1

% which php                                                        
/usr/local/opt/php@8.0/bin/php
```

PHP v8.0.1に変わっていることを確認できました！
以上で、PHPのアップデートは完了。

## Rubyの復習
そういや今回はRubyの復習がほぼない。
しいて言えば、バージョン確認コマンドくらい。
Rubyもバージョン3が出たようなのでアップデートしなきゃ。

```zsh
% ruby -v    # Rubyのバージョンを確認する
ruby 2.6.5
```

## 補足: Homebrewをインストール

そもそもHomebrewを導入しておらず、インストールする場合の方法を備忘録として残します。

インストールするためのコマンドは [Homebrew公式](https://brew.sh/) のトップページに明記されてます。
ページ見るたびビール飲みたくなる。 

```zsh
% cd       # ホームディレクトリに移動する
% pwd      # 本当にホームディレクトリにいるかどうか念のため確認

# Homebrew公式にも載ってるコマンドを叩く
% /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"  

% brew -v       # インストールできたか、バージョン確認コマンドを使って確認
Homebrew 2.5.1  # バージョンが表示されたのでインストール完了

% brew update  # 念のためアップデート

% sudo chown -R `whoami`:admin /usr/local/bin  # Homebrewの権限変更を実施
```
「JavaScript」基本1

# 記述を残そうと思った理由
はじめ苦手意識がありなかなか手を付けようとしなかったせいで、だいぶ内容が飛んでしまったのでさらっと復習がてらこちらに残そうと思い記述しています。
目標15分でまとめて行きたいので雑になります

# JavaScriptとは何か？
JavaScript（ジャバスクリプト）とはプログラミング言語の1つです。Rubyはサーバーサイドを担う言語でしたが、JavaScriptは主にクライアントサイドにおいて力を発揮します。すなわち、「ブラウザ上でのアプリケーションの使いやすさ」や「リクエストの送り方の工夫」をJavaScriptは担っています。

JavaScriptによって、より使い勝手の良いアプリケーションの作成ができます。Ruby on RailsのWebアプリケーションにJavaScriptを適用する方法はこのあとのLESSONで学びます。本LESSONではJavaScriptのみを学び、より使い勝手の良いアプリケーションを作成するための基礎を身に着けましょう。

JavaScriptは多くの開発現場でも用いられているプログラミング言語です。

JavaScriptは画面を更新せずとも、サーバーと通信ができるためページ遷移なしで、画面の表示を切り替えられる。
動的動きをつけることができる。

# つまり
かっこよくできるし、便利にできるし、いろいろなことができるよって解釈

# 特徴は？
**デベロッパーツール**
コンソールでデバック
コマンドは

```
⌘ + option + C
```

# 基礎構文
JavaScriptでは変数定義の様式は、var、const、letと３つ存在します。

#### var
古い書き方
もう使わない

#### const
再代入ができない書き方

#### let
再代入ができる書き方
再定義は不可
####要は
**let** は再代入する予定のある変数を定義する際に使用する
**const** は再定義する予定のない変数を定義する際に使用する

####テンプレートリテラル
テンプレートリテラルは、JavaScriptの構文
ダブルクォートやシングルクォートの代わりにバッククォートで囲むことで、文字列内に挿入することができる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797153/ccc42b0b-e565-af57-e35e-baa65a5bbd8f.png)

####要は
文字列の中に変数を埋め込むことができる
改行を入れることができる
HTMLの要素を作成することができる

```
const name = "Tom"
const age = 25

const introduction = `私の名前は${name}、${age}歳です`
console.log(introduction)
// => 私の名前はTom、25歳です と出力される
```


# 条件分岐
条件を満たしているかどうかで実行内容を分岐する処理

```
if (条件式1) {
  // 条件式1がtrueのときの処理
} else if (条件式2) {
  // 条件式1がfalseで条件式2がtrueのときの処理
} else {
  // 条件式1も条件式2もfalseのときの処理
}
```
# for文
繰り返し処理を行う

```
for ([①初期化式]; [②条件式]; [③加算式]) {
  // 繰り返す処理の内容
}
```
# forEach関数
配列に対する繰り返し処理

```
配列.forEach( function(value){
  // 処理の記述
})
```
SageMakerのライフサイクル設定(Mecab+neologdなど)

メモです。

SageMakerのライフサイクルにMecab+neologdの設定を作成

```.sh
#!/bin/bash
sudo -u ec2-user -i <<'EOF'

# python3の環境に適応
source activate python3

sudo yum install -y ca-certificates
sudo yum install -y python-devel
sudo yum install -y mysql-devel

pip install mysqlclient
pip install lightgbm
pip install mecab-python3
...

git clone https://github.com/taku910/mecab.git
git clone --depth 1 https://github.com/neologd/mecab-ipadic-neologd.git

sudo mkdir -p /opt/mecab

PATH=${PATH}:/usr/local/bin
cd ~/mecab/mecab && ./configure --enable-utf8-only && make
sudo make install
cd ~/mecab/mecab-ipadic && ./configure --with-charset=utf8 && make
sudo make install
cd ~/mecab-ipadic-neologd && ./bin/install-mecab-ipadic-neologd -n -y -p /opt/mecab/lib/mecab/dic/neologd

sudo ln -s /usr/libexec/gcc/x86_64-amazon-linux/4.8.5/cc1plus /usr/local/bin/

source deactivate

EOF
```

logはCloudWatchで確認が可能
/aws/sagemaker/NotebookInstances　→　notebook名/LifecycleConfigOnStart