OmniAICreator/Qiita-1.07M huggingface dataset:
React progate 備忘録 JSXとJSの違い

1 renderメソッドのreturn内のみ、JSXで記述する必要があります。JSXで記述された要素はブラウザに表示されます。

2 renderメソッドのreturnの外にはJavascriptを記述できる。

3 return内にもJSXにJavascriptを埋め込むことができる。やり方はJSXのJavascriptの部分を中かっこ{}囲む。
HTMLとJavascriptが一体化してるイメージ。
４　renderメソッドのreturnの外であるjavascriptのコメントは通常通り{/**/}ではなく、//と書く

```jsx:App.js
import React from 'react';

class App extends React.Component {
  render() {
  
   
    const imgUrl = "https://s3-ap-northeast-1.amazonaws.com/progate/shared/images/lesson/react/ninjawanko.png";
    
    return (
      <div>
      
        <h1>{name}</h1>
        
     
        <img src ={imgUrl}/>
        
      </div>
    );
  }
}

export default App;

```
ridk use が機能しないので自力で rubies.yml を編集した話

# 概要
RubyInstaller でインストールした Ruby のバージョンが `ridk use` で切り替えられないという問題を，インストールしてある Ruby の情報を手動で `rubies.yml` に書いて解決した．

# 詳細
私の端末には [RubyInstaller](https://rubyinstaller.org/) によって Ruby 2.5.5 と Ruby 2.6.3 がインストールしてある．`ridk use` は，RubyInstaller 2.6.0-1 から実装されたバージョン切り替えのためのコマンドである．しかし，`ridk use` を実行しても

```
C:\Users\ユーザー名>ridk use
Select ruby version to enable:
```
となってしまう．本来ならば次のように表示されるはずである．

```
C:\Users\ユーザー名>ridk use
1 - C:/Ruby25-x64       ruby 2.5.5p157 (2019-03-15 revision 67260) [x64-mingw32]
2 - C:/Ruby26-x64       ruby 2.6.3p62 (2019-04-16 revision 67580) [x64-mingw32]
Select ruby version to enable:
```
また，`ridk use list` を実行しても何も表示されない．

```
C:\Users\ユーザー名>ridk use list

C:\Users\ユーザー名>
```
この問題の解決方法を模索した結果，[RubyInstallerのridk useコマンドメモ (for Windows)](https://gist.github.com/icm7216/66681d1b08994e563d5de33083943697) によれば

>`ridk use`コマンドは切り替え対象の Ruby のリストをレジストリから取得しますが、`rubies.yml`があればこのファイルを優先します。

とのことなので，`rubies.yml` を手動で編集することで解決を試みた．以下，その手順を述べる．

## rubies.yml を作成する
`ridk use update` を実行して `rubies.yml` を作成する．いま，Ruby のバージョンは 2.6.3 になっているので `C:/Ruby26-x64/ridk_use` に作成される．

```
C:\Users\ユーザー名>ruby -v
ruby 2.6.3p62 (2019-04-16 revision 67580) [x64-mingw32]

C:\Users\ユーザー名>ridk use update
Update C:/Ruby26-x64/ridk_use/rubies.yml
```

## rubies.yml を編集する
適当なエディタで `rubies.yml` を開くと次のようになっている．Ruby のバージョンはひとつも認識されていない．

```yml:編集前のrubies.yml
--- []
```
これを次のように書き換える．もちろん，他のバージョンがインストールされている場合はそれも加える．

```yml:編集後のrubies.yml
---
- C:\Ruby25-x64
- C:\Ruby26-x64
```

## ridk use を実行してみる
`rubies.yml` が編集できたので，再び `ridk use` を使ってみる．

```
C:\Users\ユーザー名>ridk use list
1 - C:/Ruby25-x64       ruby 2.5.5p157 (2019-03-15 revision 67260) [x64-mingw32]
2 - C:/Ruby26-x64       ruby 2.6.3p62 (2019-04-16 revision 67580) [x64-mingw32]

C:\Users\ユーザー名>ruby -v
ruby 2.6.3p62 (2019-04-16 revision 67580) [x64-mingw32]

C:\Users\ユーザー名>ridk use
1 - C:/Ruby25-x64       ruby 2.5.5p157 (2019-03-15 revision 67260) [x64-mingw32]
2 - C:/Ruby26-x64       ruby 2.6.3p62 (2019-04-16 revision 67580) [x64-mingw32]
Select ruby version to enable: 1
Disable C:/Ruby26-x64
Enable C:/Ruby25-x64

C:\Users\ユーザー名>ruby -v
ruby 2.5.5p157 (2019-03-15 revision 67260) [x64-mingw32]
```
無事に Ruby のバージョンを切り替えることができた．

# 最後に
結局，`ridk use` がなぜ機能しなかったのかはわかっていない．レジストリには RubyInstaller の情報がちゃんと書き込まれているので，レジストリの情報を取りにいく段階で何かしらのエラーが起こっているのかもしれない．

# 参考
- [RubyInstaller](https://rubyinstaller.org/)
- [RubyInstallerのridk useコマンドメモ (for Windows)](https://gist.github.com/icm7216/66681d1b08994e563d5de33083943697) 
- [The ridk tool](https://github.com/oneclick/rubyinstaller2/wiki/The-ridk-tool)
SFSafariViewControllerをmodalで出す

いつからかSFSafariViewControllerは
`present(safafiVC, animated: true)`
としてもpush遷移の挙動をするようになりました。

modalで表示させたい時は

```swift:modal.swift
let safariVC = SFSafariViewController(url: targetURL)
safariVC.modalPresentationStyle = .overFullScreen
present(safariVC, animated: true)
```

とすればモーダル表示になってくれます。

そうなった経緯とか探れたら良い記事になりそうですが、とりあえず方法だけ。
React progate 備忘録 JSX


#JSXについて
1 JSXは、HTMLとほとんど同じように記述することができます。
2 JSXの注意点
JSXはほとんどHTMLと同じですが、いくつか違いがあります。
左の図のように、return内に複数の要素があるとエラーになります。
複数の要素がある場合は、右の図のように<div>タグで囲んで、1つの要素にまとめてあげましょう。
3 コメントのやりかた　
     {/*コメント部分*/}

```jsx:src/App.js
import React from 'react';//Recatをimport
class App extends React.Component{{/*React.Componentを継承するクラスの定義*/}
 render() {
{/*JSXを戻り値とするrenderメソッドを定義*/}
    return (
      <div>
        {/* <h1>タグを用いて、「Hello World」と表示してください */}
        <h1>Hello World</h1>
        
        {/* <p>タグを用いて、「一緒にReactを学びましょう！」と表示してください */}
        <p>一緒にReactを学びましょう！</p>
        
      </div>
    );
  } 
}
export default  App;//クラスをexport
```
4 JSXでは閉じタグが必要になります。img src='画像のURL' /のように、タグの終わりにスラッシュ「/」を記述します。
Hide .DS_Store file from Emacs

`.DS_Store` ファイルをMacから削除する…というTipsは山ほどあるのですが、いづれも一時的でいつの間にかまた復活してしまいます。なので私の場合は、Emacsの各シーンで `.DS_Store` が非表示になるように設定しています。


## counsel-find-file
```emacs-lisp
(setq counsel-find-file-ignore-regexp (regexp-opt '(".DS_Store")))
```

## dired
```emacs-lisp
;; omit .DS_Store
(require 'dired-x)
(setq-default dired-omit-files-p t)
(setq dired-omit-files "^\\.DS_Store")
```

## neotree
```emacs-lisp
;; Patched to allow everything but .DS_Store
;; Tips from https://github.com/syl20bnr/spacemacs/issues/2751
(with-eval-after-load 'neotree
  (defun neo-util--walk-dir (path)
    "Return the subdirectories and subfiles of the PATH."
    (let* ((full-path (neo-path--file-truename path)))
      (condition-case nil
	  (directory-files
	   path 'full "^\\([^.]\\|\\.[^D.][^S]\\).*")
	('file-error
	 (message "Walk directory %S failed." path)
	 nil)))))
```
RailsでCSPに引っかかった話

#結論
`config/initializers/content_security_policy.rb`にwebのconsoleに表示されてるリンクを追加すればいい。

#ことの発端
Railsで開発
↓
CapybaraでSeleniumのChrome Headless Driverでテスト
↓
serverをrunしていれば通るテストが通らなくなった

#環境
- Ruby 2.5.3
- Rails 5.2.3

関係ない環境

- Capybara 2.18.0

あとテストはminitestで書いてます
#バグを見る
Headlessじゃなくても通らないかチェックする。

```ruby:*_test.rb
setup do
  Capybara.server_port = 3000
  Capybara.server_host = "localhost"
  Capybara.app_host = "http://localhost:3000"
  Capybara.current_driver = :selenium_chrome
end
```

```:実行結果
F

Failure:
Test#test
[test/integration/*_test.rb:*]:
Expected false to be truthy.
```

通らない。
通らないテストに`sleep 3000`とか入れて、検証画面を開ける時間を稼ぐ。
テストを実行→sleepしたら右クリックから検証を選択→コンソールを開く

```:コンソール
Refused to connect to 'http://localhost:3000/***`
because it violates the following Content Security Policy directive: 
"connect-src https://s3-us-west-2.amazonaws.com/rubygems-dumps/ 
https://*.fastly-insights.com https://api.github.com".
```

**？？？？？？**

全然わからないのでググりまくる。

#解決へ
https://qiita.com/sola-msr/items/1f3106cb4a097c883880
こちらのページがヒット。
>web.configを開いて以下Content-Security-Policyの部分、script-srcとimg-srcとframe-srcにポリシー違反として出てきたURLを追加（＝こいつらは読み込んでいいというリスト）をすればちゃんと表示されるようになりました。

なるほど、Content-Security-Policyのviolateに表示されてるのを追加すればいいと……
Railsはこういのは多分configでいじってると予想。またググってると
https://bauland42.com/ruby-on-rails-content-security-policy-csp/

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/380303/c38158f6-6662-3811-69dd-d3f8078ec941.png"  width=80%>

お〜〜これですね。

#ということで解決
`conifg/initializers`から似たようなファイルを見つける。

```ruby:config/initializers/content_security_policy.rb
Rails.application.config.content_security_policy do |policy|
  unless Rails.env.development?
    ...
    policy.connect_src :self ,...
    ...
  end
end
```

適当に`:self`を追加する。(localhost:3000に入れなかったため)
これでテストを走らせると……

```ruby:実行結果
Finished in 8.905670s, 0.5614 runs/s, 0.8983 assertions/s.
5 runs, 8 assertions, 0 failures, 0 errors, 0 skips
```

よーし！！！！

#今回の教訓
多分CSPなんてRailsの基礎なので、基礎をやらずにコーディングすると痛い目にあう。終わり。
50日目 PHP入門を復習してフォームを作りました。

Progate PHP入門を復習しました。
簡単かとおもったけど意外と手こずったかな・・・


###1 章：PHPとは？
PHPの書き方

```
<?php なにがし; ?>
```

こんな感じ。はてなPHPではじめてセミコロンで閉じる。
画面に出力するときは、echoではじめる。

```
<?php echo なにがし; ?>
```

###2 章：PHPの基礎を学ぼう
データは主に、文字列と数値。
””や’’でくくると文字列あつかいになる。

###3 章：条件分岐
 if,else,elseif,switchがある。

```
 if (条件){
 正しかったらここを実行;
 }
```

###4 章：配列を使ってみよう
配列はarrayではじめる。
キーをつける時は、こんな感じ。

```
array( 
	'key1' => 'value1',
 	'key2' => 'value2',
  	'key3' => 'value3',
  	);
```

###5 章：繰り返し処理
for,foreach,whileがある。
breakで切り上げ
continueで次へとばす。
ifの分岐で使うとべんり。


###6 章：関数を使ってみよう
機能はおまとめするとなにかと便利。

```
function(){
	
};

function();
```

###7 章：お問い合わせフォームを作ろう
フォームを作るには<form ></form>でくくる。
送信先のHTMLに表示するには、`$_POST['key']`

（Progateの復習 88分)

###フォームを作る！
１章〜７章を参考にしてフォームを作りました。
これを作業フォルダに`index.php`という名前で保存します。

そしてmacのコンソールからphpを起動します。

```
php -S localhost:8080 -t ~/Desktop/workspace
```

ブラウザで、`http://localhost:8080/`を開きます。

うごいたぞー！！！
（簡単なフォームを作って動かすまで 60分）

###道場コースPHP１
問題集みたいな。
`()`とか`;`とか忘れて動かないのに見つからない！みたいな凡ミスで時間を食いました。
（所用時間 42分）
個人的メモ Docker rails開発でエラーが出た時にDockerのコンテナにアクセスしてエラー個所を特定する方法

#rails開発でエラーが出た時にDokerのコンテナにアクセスしてエラー個所を特定する方法

概要
本日不運にもバグを踏んでしまい、binding.pryでエラー個所を特定後Doker内のログを確認する必要があったので、忘備録的にメモ。
各々環境が違うと思うので、他のかたは参考程度にしてください。


### 以下の方法で特定します。


まず、エラーメッセージ的に怪しい部分のコードの直前に

```
binding.pry
```
という行を追加。

そして開発環境で目的のdockerコンテナが立ち上がっているか、以下のコマンドで確認

```
doker ps
```
もし立ち上がっていなければ

```
docker-compose restart
で、全部のコンテナをリスタートさせるか、あるいは
docker-compose restart コンテナ名
で特定のコンテナをリスタートさせる
```

docker ps を確認して無事にコンテナが立ち上がったら、

```
docker attach コンテナ名
```

でコンテナ内にアクセスして、

ブラウザでlocalhostにアクセス。
そうするとbinding.pryを書いた行で止まるので

```
binding.pry
```

でbinding.pry内にアクセスすると、コンソールで色々DBなどを確認できたりするので、そこで確認したり、attachのログで確認する
php:7.3-apache に zipとimagickを追加

## zip

- `libzip-dev` `zlib1g-dev` の2つが必要
- docker-php-ext-`install`

```
FROM php:7.3-apache
RUN apt-get update && \
    apt-get install -y libzip-dev zlib1g-dev && \
    docker-php-ext-install zip
```

## imagick

- `libmagickwand-dev` が必要
- peclでinstallする
- docker-php-ext-`enable`

```
FROM php:7.3-apache
RUN apt-get update && \
    apt-get install -y libmagickwand-dev && \
    pecl install imagick && \
    docker-php-ext-enable imagick
```

## 参考
- [How to install Imagick in PHP Docker?](https://webapplicationconsultant.com/docker/how-to-install-imagick-in-php-docker/)

- [zip extension #748](https://github.com/docker-library/php/issues/748) の for php7.3
【Vuetify2.0に】Vuetify で outlined が反映されない時【なったよ】


# 結論

- Version 2.* 系にアップグレードすればいいよ
- ただし、大幅にデザインが変わっているからレイアウトは絶対崩れるよ

# 詳細のお話

Vuetifyを使って v-card を Outlined (shadowを0にして、薄く枠線をつけてくれる)表示にしたいと思っていた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241647/62efea98-0ab6-52d5-3aa3-017b8fb1291c.png)

なので、コードにOutlinedオプションを追加したのだが、うまくいかない。

```vue

<v-card outlined>
  ...省略
</v-card>
```

デバッグで確認すると、outlinedが変換されていないことがわかる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241647/f6d04ec3-8872-0821-298b-c0eec9fc69c2.png)

なので、無理やりclassを追加してみたが、やはり反映されない

```vue

<v-card class="v-card--outlined">
  ...省略
</v-card>
```

こういう時は一次情報、ということでVuetifyのリリースノートを見ました。
https://github.com/vuetifyjs/vuetify/releases

すると...

どうやら、`oulined`が追加されたのは **v2 系以降**のようです。

outline から outlined に名前を変えたよ、というお知らせと（）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241647/0a7d110e-cd0f-2a17-6adc-3aa5dae51679.png)

v-card　でも outlinedが使えるようになるよ！というお知らせが。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241647/f285d0b1-d473-5392-e4d9-1a3159512488.png)

ということは... `yarn.lock` (or `package.json`)を恐る恐る確認すると...

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241647/c01f4c80-1249-e0b8-f9e5-12b978453d9e.png)

燦然と輝く 1.5の文字が！！！

ということでアップデートしていきます。 

各種方法についてhここら辺が参考になるのではないでしょうか。
[Vuetifyを1.5.5→2.0.0にアップグレードしたおはなし。](https://qiita.com/filunK/items/e71999d5abef404744b3)
[Vuetify 2.0の注目機能とNuxt.jsでの試し方](https://qiita.com/reireias/items/3688ff593185a79d521b)

私の場合はNuxt.js上で動かしているので、 `@nuxtjs/vuetify` でアップデートを試みます。

`@nuxtjs/vuetify` のバージョンは現行の最新バージョンである `1.2.1` を指定します。
そこらへんは下記ページで必要に応じて確認してください
https://www.npmjs.com/package/@nuxtjs/vuetify

```
$ yarn upgrade @nuxtjs/vuetify@1.2.1

yarn upgrade v1.17.3
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
warning " > sass-loader@7.1.0" has unmet peer dependency "webpack@^3.0.0 || ^4.0.0".
warning "@nuxtjs/vuetify > vuetify-loader@1.3.0" has unmet peer dependency "webpack@^4.0.0".
[4/4] 🔨  Rebuilding all packages...
success Saved lockfile.
success Saved 5 new dependencies.
info Direct dependencies
└─ @nuxtjs/vuetify@1.2.1
info All dependencies
├─ @nuxtjs/vuetify@1.2.1
├─ deepmerge@4.0.0
├─ fibers@4.0.1
├─ vuetify-loader@1.3.0
└─ vuetify@2.0.5
✨  Done in 8.59s.
```

すると

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241647/33e5b691-61fd-293b-9df7-5779a19b7444.png)

反映された！

しかし、リリースノートでも

> Updated every component to the new Material Design 2 specification

と謳っている通り、
v1系と比較して大幅にレイアウトの修正が入っているようなので**あちこちレイアウトが崩壊します。**

既存のプロジェクトのバージョンをあげる際には検証が必要です。

# ちなみに

いつv2.0になったのかというと
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241647/46bccace-b81f-2279-a333-74e73d401121.png)
...
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241647/a4f89032-26ea-ff10-7c5f-acabee48c0fe.png)
超最近の話じゃないか...
(↑のスクショを撮ったのは2019.08.08です)

何が変わったのか、ちゃんとリリースノートを読んでおこうと思います。
Laradockでローカルサーバを立ち上げてブラウザ表示する方法

MacやWindowsのローカル環境で、LaravelやRubyonRailsを使う場合、`php artisan serve`や`rails s`を起動すればすぐにブラウザで表示できるのですが、docker環境にプロジェクトを作成した場合、コマンドだけではブラウザに表示されません。

dockerで立ち上げたローカルサーバがどのような仕組みでブラウザ表示されるのかをまとめていきたいと思います。

## localhostで立ち上げたら基本的にうまくいかない

docker環境で`rails s`をすると、`http://localhost:3000`の表示が出るかと思います。

（Laravelなら`http://localhost:8000`だったかな）

そのままlocalhostをブラウザに入力しても表示はされません。

なぜなら、localhostは`127.0.0.1`だと判断されるからです。

dockerコンテナにはIPが設定されていて、`172.22.0.x`のようなIPが確か動的に設定されます。

これらを指定しなければなりません。

各フレームワークごとに設定の仕方は異なるのですが、Railsなら、`rails s -B 0.0.0.0`でdocker環境のIPで立ち上げることができると思います。

コンテナを再起動しないのであれば、`172.22.0.x`を指定しても良いのですが、起動するたびに動的にIPが割り振られるので、`0.0.0.0`を指定することで、その時のdockerコンテナのIPを指定すると良いです。

## ポート接続

laradockの場合、workspaceというコンテナでプロジェクトを作成するのですが、（通常のdockerだとwebコンテナでしょうか。）22ポート→22ポートへの接続しかされていません。

なので、`0.0.0.0:22`で立ち上げたサーバを`localhost:22`で表示することができる状態です。

railsは3000、laravelは8000で立ち上げるので、ポート接続の設定もしないといけません。

laradockのdocker-compose.ymlファイルの以下のように設定します。

```
### Workspace Utilities ##################################
    workspace:
      ports:
        - "${WORKSPACE_SSH_PORT}:22"
        - "3000:3000"
        - "8000:8000"

```
これで、3000ポートと8000ポートも接続することができます。

この状態で`rails s -B 0.0.0.0`でサーバを立ち上げれば、`localhost:3000`でRailsの画面を表示することができます。

## NginxかApacheを使うのがおすすめです

毎回`rails s -B 0.0.0.0`を打つのも大変ですし、プロジェクトが増えてくると同時に立ち上げることができなくなってきてしまいますので、nginxやapacheを使うのがおすすめです。

こちらの設定方法は今回は割愛しますが、IPとポートの考え方は基本的には同じです。

nginxやapacheを使えば、Railsなら3000ポートと決まっているわけではなく、このディレクトリに接続した時は8001番ポートで接続する、というようにポートの振り分けを柔軟に行うことができます。
NavigationLinkのLabelで指定したImageが青く表示される問題対応

# この記事について

NavigationLinkのLabelにImageを指定した場合青く表示されてしまう問題の解決方法です。
そうなるのかの深堀はまだしておりません:pray:
解決したよーって内容だけ先に記載します！

```swift
struct FreeView: View {
    var body: some View {
        NavigationView {
            ScrollView(.vertical) {
                NavigationLink(destination: ProfileView())  {
                    Image("icon")
                }
            }
        }
    }
}
```

<img width="298" alt="スクリーンショット 2019-08-08 13.06.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75593/13c43b0c-4e16-7c51-819d-035cde298edb.png">

# renderingModeをoriginalにする

```swift
struct FreeView: View {
    var body: some View {
        NavigationView {
            ScrollView(.vertical) {
                NavigationLink(destination: ProfileView())  {
                    Image("icon")
                        .renderingMode(.original)
                }
            }
        }
    }
}

# buttonStyleをplainにする

```swift
struct FreeView: View {
    var body: some View {
        NavigationView {
            ScrollView(.vertical) {
                NavigationLink(destination: ProfileView())  {
                    Image("icon")
                }
                .buttonStyle(PlainButtonStyle())
            }
        }
    }
}
```


<img width="289" alt="スクリーンショット 2019-08-08 13.10.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75593/fd06ac9d-72da-1f83-d58c-f281527f8437.png">


# 参考にしたサイト
[Apple Developer Forums](https://forums.developer.apple.com/thread/119809)
書籍『たのしいRuby』の練習問題を解いてみた Part.5

# 本題
今回は第16章の練習問題を解いていく。正規表現の内容だ。それでは早速解いてみる。
**(1)**　電子メールアドレスは「ローカルパート@ドメイン名」という形になっている。このような文字列から、ローカルパートとドメイン名を取得する正規表現を作れ。

```ruby:1_1.rb
def local_domain(str)
  str =~ /^(.*)@(.*)/
  local = $1
  domain = $2
  return [local, domain]
end

p local_domain("abcde@fghijk.com")
p local_domain("hellow@gmail.com")
#実行結果：["abcde", "fghijk.com"]
#実行結果：["hellow", "gmail.com"]
```

ちょっとこれだと、全てのメールアドレスを正しく分けるのは難しそう…問題文ではそこまで厳しくは指定されていないので、今回は上の様にした。

**(2)**　「"正規表現は難しい！なんて難しいんだ！"」という文字列を,gsubメソッドを利用し「"正規表現は簡単だ！なんて簡単なんだ！"」という文字列に直してください。

``` ruby:2_1.rb
str = "正規表現は難しい！ なんて難しいんだ！"

str.gsub!(/難しい！/, "簡単だ！")
str.gsub!(/難しいん/, "簡単なん")
#確認のため出力してみる
p str
#実行結果："正規表現は簡単だ！ なんて簡単なんだ！"
```

考えてみたが、それぞれで変えないといけそうなのでそうした。

**(3)**　アルファベットとハイフンからなる文字列を与えられると、ハイフンで区切られた部分をCapitalizeするようなメソッドword_capitalizeを定義せよ。
問題：p word_capitalize("in-reply-to")
　　　p word_capitalize("X-MALIER")

```ruby:3_1.rb
def word_capitalize(str)
	x = str.split('-')
	x.each do |i|
		i.capitalize!
	end
	return x.join("-")
end

p word_capitalize("in-reply-to")
p word_capitalize("X-MALIER")
#実行結果："In-Reply-To"
#実行結果："X-Malier"
```

受け取った文字列を('-')で分けて、それぞれに#capitalize!を使い文字列先頭の文字を大文字に、残りを小文字に破壊的変更をした。最後に分けられていた文字を('-')でつなげ直した。
# 最後に
今回は正規表現について復習した。前、解いた漢数字➡整数の時に調べていたので理解しやすかった。
現在は、railsについて勉強している。友人と協力してwebアプリを作る計画が動き出したので上手く、年末までには形にしていきたい。
ZF coPILOTとは

# ZF coPILOTとは
* L2+システムの総称
    * ZF ProAI（システムのコア）
    * NVIDIA DRIVE Xavier(プラットフォーム）
    * AI
    * 360度センサーセット
* 車線変更、追い越し、合流を提供
* ドライバー監視機能
* 2021年量産
curlからaws Wowza APIを叩きストリーミングの統計情報を取得する。

ストリーミングサービスの開発に携わっているのですが、その監視用にAPIからCPU使用率やコネクション状況などの情報が取れないかと調べたのでまとめておきます。

## Applicationの情報が欲しい場合
```sh

$ curl -X GET \
-H 'Accept:application/json; charset=utf-8' \
-H 'Content-Type:application/json; charset=utf-8' \
--digest -u "{username}:{password}" \
http://{server_IP}:8087/v2/servers/_defaultServer_/vhosts/_defaultVHost_/applications/{app_name}/monitoring/current
```
## Severのメトリクスが欲しい場合
```sh

$ curl -X GET \
-H 'Accept:application/json; charset=utf-8' \
-H 'Content-Type:application/json; charset=utf-8' \
--digest -u "{username}:{password}" \
http://{server_IP}:8087/v2/machine/monitoring/current
```

## 参考
- https://www.wowza.com/docs/statistics-query-examples
- http://www.wowza.com/resources/WowzaStreamingEngine_ConfigurationReference-4.7.4.pdf
[メモ] 私の環境におけるシェル設定スクリプトの設定関係メモ

# 概要
シェル設定スクリプトについての(今のところ)個人用のメモです。
ZshとmacOSを使用する私の環境向けになっています。

# 私がシェルの起動スクリプトに求める要件

1. 起動する`ssh-agent`プロセスはユーザのログインごとに1つのみでなくてはなりません。
2. `PATH`環境変数がどんどん長くなってはなりません。
  - シェルの中でシェルを起動した場合
  - sshした時?
3. rbenv, pyenv等が正常に動作しなければなりません。
  - `PATH`環境変数において、(`rbenv`, `anyenv`, `pyenv` などの)shimsの優先度は、システムにデフォルトでインストールされている実行可能ファイルのそれよりも高くなければなりません。
  - `PATH`環境変数において、(`rbenv`, `anyenv`, `pyenv` などの)shimsの優先度は、Homebrewでインストールされた実行可能ファイルのそれより高くなければなりません。
4. Homebrew によってインストールされたソフトウェアが正常に動作しなければなりません。
  - `PATH`環境変数において、Homebrewでインストールされた実行可能ファイルの優先度は、システムにデフォルトでインストールされている実行可能ファイルの優先度より高くなければなりません。
5. 他のユーザに影響を及ぼしてはいけません。

# 私のmacにおける .zshrc .zprofile .zshenv .zlogin の実際の使い分け

1. `PATH`環境変数の設定は `.zprofile` で行います。
  - `.zshrc` は、インタラクティブシェル用の設定を行うところで、CUI広範に広く影響を及ぼしたい`PATH`環境変数の設定は `.zshrc` で行うのに向いていません。
  - `.zshenv` も `.zshrc` も、Zsh中でZshを実行するごとに実行されるため、ここで`PATH`環境変数に追記すると`PATH`環境変数がどんどん成長してしまいます。
  - `.zshenv` については、macOS の `/etc/zprofile` が (`eval $(path_helper -s)`によって)`PATH`環境変数に優先度の高いパスを追加するため、ここで優先度の高い`PATH`環境変数の設定は行ってはいけません。
  - `.zlogin` は、 `.zshrc` での設定に依存しログイン時に一回だけ行うといいような処理(おそらく`fortune` の実行や新着メールの表示など。TODO: 要出典)に向いています。
  - どこで`PATH`環境変数を設定しても、その`PATH`環境変数は当該のログインシェルの外には影響を及ぼせないと言う問題があります。
  - `/etc/zshenv` `/etc/zprofile` `/etc/zlogin` `/etc/zshrc` を編集すると、他のユーザに影響を及ぼしてしまいます。

2. ssh-agentは起動も終了もしません。
  `ssh-agent`は勝手に起動する[^1]ため、シェル設定スクリプトで起動する必要がありません。
  同時に実行される`ssh-agent`はたかだか1プロセスであるため、`ssh-agent`を終了する必要もありません。
[^1]: [acevif, macOSのシェル設定スクリプトにおける固有の特徴と注意点](https://qiita.com/acevif/items/a24f551e3913435d3750#ssh-agent%E3%81%AF%E5%8B%9D%E6%89%8B%E3%81%AB%E3%82%AA%E3%83%B3%E3%83%87%E3%83%9E%E3%83%B3%E3%83%89%E3%81%A7%E8%B5%B7%E5%8B%95%E3%81%99%E3%82%8B)

# Z shell の起動フロー

## ログインシェルの時: 

1. `/etc/zshenv`
2. `~/.zshenv`
3. `/etc/zprofile`
4. `~/.zprofile`
5. `/etc/zshrc`
6. `~/.zshrc`
7. `/etc/zlogin`
8. `~/.zlogin`

## インタラクティブシェルの時:
1. `/etc/zshenv`
2. `~/.zshenv`
3. `/etc/zshrc`
4. `~/.zshrc`

※TODO: ソースを追記してください (cf. 脚注記法)
※TODO: インタラクティブシェルとは何か追記してください
THETA VのIPアドレス静的設定(IPv4)

#はじめに
THETA V以降ではクライアントモードで接続が可能。
しかし、通常の方法で設定するとDHCPでIPアドレスが動的に決まってしまう。
そこでIPアドレスを静的に設定する方法を記録しておく。

#前提知識

[Theta V の Client Mode設定を間違えてしまってハマった話]
(https://qiita.com/watakandhi/items/5e287823e007b3e369dd)

[C#でUSB接続したTHETA Sを操作できるライブラリを作成してみた]
(https://qiita.com/soundkonchan/items/d392794d57dc849720f3)

[Github:WpdMtp]
(https://github.com/kon0524/WpdMtp)

先人に感謝。

#IPアドレス(v4)の設定方法

USB接続してWpdMtpを使用して解決した。
基本はAccessPointInfoで受信したbyteを参考にして送信用byteを作成すればOK。

[THETA公式:0x99A5 SetAccessPoint]
(https://developers.theta360.com/ja/docs/v2/usb_reference/operation/set_access_point.html)
上記を読んでも意味がわからなかったので、IPのbyte規約は総当たりで見つけた。
IPはsizeが4のUINT32と書いてあるが、有効なbyte配列と比較してもどう解釈するべきか不明のまま。

AccessPointInfoでIPを受けると下記のような配列になる。
byte配列:[4,0,0,0,0,0,0,0]

SetAccessPointで設定するIP部分は下記のように渡してやる。（ex 192.168.1.1）
先頭に"4"、下4つにIPv4を入れてやればOK。
byte配列:[4,0,0,0,192,168,1,1]

#疑問

クライアントモード接続中にOscApiでもIP設定を試してみたが、
"Command executed is currently disabled."とエラーが出て、変更はできなかった。
おそらく、動的設定されたIPアドレスを使っている最中だからだと思う。
しかし、IPアドレス使用中に変更APIが使えないなら、どのタイミングで使えるのだろうか？
（追記）→ダイレクトモードなら、OcsApiで登録ができた。

bit配列の先頭の4はIPv4の4であり、データ定義はIPv6にも備えているからこんな形になっている？
SwiftUIでCollectionViewのようなレイアウトを整えてみる

# この記事について

SwiftUIでUIKitでいうところのCollectionViewのような見た目のレイアウトを
[QGrid](https://github.com/Q-Mobile/QGrid)というライブラリを使用するとさくっと作れるよって話です。

最後の方はおまけのようなものなのですが、PR投げてみたって話です。


# SwiftUIでCollectionViewのデザインを作るにはList?
Listで良しなにって感じなんですかね？

<img width="689" alt="スクリーンショット 2019-08-06 19.01.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75593/5e0bf21d-9d31-75ae-98f6-15cad70d8be2.png">
[SwiftUI-Cheat-Sheet](https://github.com/SimpleBoilerplates/SwiftUI-Cheat-Sheet)

# QGridというOSS

![QGridDemo.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75593/086cadea-1ccd-5a87-8f45-06747ed5e9a7.gif)


*QGrid is the missing SwiftUI collection view. It uses the same approach as SwiftUI's List view, by computing its cells on demand from an underlying collection of identified data.*

どうやら、SwiftUIのListのようにうまくやってるっぽい
[QGrid](https://github.com/Q-Mobile/QGrid)

# 動かしてみる

```swift
import SwiftUI
import QGrid

struct CollectionView: View {
    var body: some View {
        QGrid(landmarkData,
              columns: 2,
              columnsInLandscape: 4,
              vSpacing: 50,
              hSpacing: 20,
              vPadding: 100,
              hPadding: 20) { landmark in
                Cell(content: landmark)
        }
    }
}

struct Cell: View {
    var content: Landmark
    var body: some View {
        HStack {
            VStack(alignment: .center) {
                self.content.image
                    .resizable()
                    .frame(width: 150, height: 150)
                    .clipShape(Circle())
                    .overlay(Circle().stroke(Color.orange, lineWidth: 2.0))
                Text(self.content.name)
            }
        }
    }
}

#if DEBUG
struct CollectionView_Previews: PreviewProvider {
    static var previews: some View {
        CollectionView()
    }
}
#endif
```

<img width="372" alt="スクリーンショット 2019-08-06 19.14.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75593/975bbb7a-482e-3fb5-957e-a92c754285a8.png">

# 気になった箇所に対してPR投げてみた

```swift
// Dirty little hack to handle layouting of the last row gracefully :
.opacity(!isLastRow || column.id < self.data.count % self.cols ? 1.0 : 0.0)
```
どうやら、最終行にCellを表示させる際
(data.count % col > 0)余りがある場合、必要に応じて表示/非表示にしている感じでした。

以下の図の場合
15個のCellが画面上には描画されており3つ非表示にしているためUserからは見えてない状態になります。


<img width="648" alt="スクリーンショット 2019-08-08 12.16.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75593/d371de55-83e2-77de-a169-1e49461ad93b.png">

`(data.count % col > 0)`であれば`data.count % col`だけ最終行にCellを追加するようなPRを送らせてもらいました。

## 結果
**Mergeされました:raised_hands:**

<img width="775" alt="スクリーンショット 2019-08-08 12.22.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75593/c96879d1-93e5-cd26-5f6d-77ea2cb0ebef.png">

PR内のコメントでいくつかアドバイスを頂きつつ修正を重ねたのですが、
確かにこっちほうが良い！という納得感もありながら改善していけたのはすごく貴重な経験でした:pray:
Python で文字列に変数を埋め込む方法あれこれ

## 概要

- Python で文字列に変数を埋め込む方法 (変数展開) が複数あるのでサンプルコードを書く

## f-string

[2\. 字句解析 — Python 3\.7\.4 ドキュメント](https://docs.python.org/ja/3.7/reference/lexical_analysis.html#f-strings)

> バージョン 3.6 で追加.
> 
> フォーマット済み文字列リテラル（ formatted string literal ）または f-string は、接頭辞 'f' または 'F' の付いた文字列リテラルです。これらの文字列には、波括弧 {} で区切られた式である置換フィールドを含めることができます。他の文字列リテラルの場合は内容が常に一定で変わることが無いのに対して、フォーマット済み文字列リテラルは実行時に式として評価されます。

サンプルコード。

```py
foo = 'Hello'
bar = 'world'
print(f'Message: {foo}, {bar}')
```

## string.Template

[string \-\-\- 一般的な文字列操作 — Python 3\.7\.4 ドキュメント](https://docs.python.org/ja/3.7/library/string.html#template-strings)

> テンプレート文字列は $ に基づいた置換をサポート

サンプルコード。

```py
from string import Template
foo = 'Hello'
bar = 'world'
t = Template('Message: ${first}, ${second}')
print(t.substitute(first=foo, second=bar))
```

## str.format

[組み込み型 — Python 3\.7\.4 ドキュメント](https://docs.python.org/ja/3.7/library/stdtypes.html#str.format)

> 文字列の書式化操作を行います。このメソッドを呼び出す文字列は通常の文字、または、 {} で区切られた置換フィールドを含みます。それぞれの置換フィールドは位置引数のインデックスナンバー、または、キーワード引数の名前を含みます。返り値は、それぞれの置換フィールドが対応する引数の文字列値で置換された文字列のコピーです。

サンプルコード。

```py
foo = 'Hello'
bar = 'world'
print('Message: {}, {}'.format(foo, bar))
```

## % 演算子

[組み込み型 — Python 3\.7\.4 ドキュメント](https://docs.python.org/ja/3.7/library/stdtypes.html#printf-style-string-formatting)

> 文字列オブジェクトには固有の操作: % 演算子 (モジュロ) があります。この演算子は文字列 書式化 または 補間 演算子とも呼ばれます。format % values (format は文字列) とすると、format 中の % 変換指定は values 中のゼロ個またはそれ以上の要素で置換されます。この動作は C 言語における sprintf() に似ています。

サンプルコード。

```py
foo = 'Hello'
bar = 'world'
print('Message: %s, %s' % (foo, bar))
```
iCaldendar RFC-5545: RRULEで毎月の最後の平日を求める

本稿では、RFC-5545のRRULEで毎月の最後の平日を求める方法を紹介する。ここでの平日とは、土日以外の曜日を指す。国民の休日や会社カレンダーの営業日ではないので注意。

### 毎月の最後の平日を求めるRRULE

```js
RRULE:FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=-1;BYMONTHDAY=-1,-2,-3
```

このルールで抽出される日付の一覧は[rrule.jsのデモ](https://jakubroztocil.github.io/rrule/#/rfc/RRULE:FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=-1;BYMONTHDAY=-1,-2,-3)で確認できる。

### 解説

このルールは下記の4つのパートに分けられる:

```js
FREQ=MONTHLY
BYDAY=MO,TU,WE,TH,FR
BYSETPOS=-1
BYMONTHDAY=-1,-2,-3
```

`FREQ=MONTHLY`は月次で繰り返す指定。

次に条件設定。

`BYDAY=MO,TU,WE,TH,FR`は、曜日を月〜金に限定するための条件指定。これで土日が入ることはなくなる。

`BYMONTHDAY=-1,-2,-3`は末日、末日の1日前、末日の2日前に限定する条件指定。月によって日数が異なるので、負の整数を使うことで、後ろからn日目といったふうに相対的な指定になっている。

ここまでで、月〜金の日で、かつ、月末の3日間を満たす日に絞り込まれる。

このままだと、毎月多くて3日間の日付がピックアップされてしまうので、`BYSETPOS=-1`で最後の1日だけを抽出するように制限をかける。

### 給料日を求める

例えば25日が給料日。ただし、25日が土曜日なら24日が支給日になる。24日、25日が土日なら23日が支給日になるとったルールも、このRRULEを応用すると対応することができる。

```js
RRULE:FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=-1;BYMONTHDAY=23,24,25
```
macOSのシェル設定スクリプトにおける固有の特徴と注意点

# 概要

Zshなどのシェル設定スクリプト(`.zshrc`や`.zshenv`など)を書く上で、いくつか意識されるべきmacOS特有の注意点があります。
それをまとめました。
ssh, Homebrew, rbenv, pyenv, anyenv などを使用する私の環境むけになっています。

# tl;dr 短く言うと

1. path_helperの振る舞いに気をつけてください。 PATHは`.zprofile`で設定してください。
2. システム標準のSSHを使っているなら `ssh-agent` は起動する必要がありません。


# macOSのシェル設定スクリプトにおける固有の特徴と注意点

## `/etc/zprofile` で `PATH`環境変数 に優先度の高いパスが追加されます

macOS環境においては、`/etc/zprofile` で `path_helper` (厳密に言うと `path_helper -s` により生成されたコード)が実行され、色々なパスが`PATH`環境変数の左に追加されます。
そのため、`/etc/zprofile` の実行よりも前に`PATH`環境変数に設定したパスは優先度が下がります。

## ログインモードのシェルが複数起動する

macOS標準の "ターミナル" アプリで新しいウィンドウやタブを開くとシェルがLogin modeで実行され、ターミナルのタブ１つにつき1度 `.zprofile` や `.zlogin` が実行されます。
そのため、メンテナンス系などの重めの処理をそれらの中で実行する時は、多重起動しないよう配慮する必要があります。

## 環境変数が "ターミナル" アプリのタブごとに閉じている

macOSにおいては、`/etc/zshenv` `.zshenv` `/etc/zprofile` `.zprofile` `/etc/zlogin` `.zlogin` `/etc/zshrc` `.zshrc` のどこで環境変数を設定しても、その環境変数は"ターミナル"アプリの当該のタブに閉じていて、その外には影響を及ぼしません。

(これは他のOSのGUIでも概ね同じかも。 むかしSolarisやLinux触ってた時は、ログインシェルでの環境変数がそのまま子プロセスであるGUIにも引き継がれることを期待する環境があった気がする。)

## `ssh-agent`は勝手にオンデマンドで起動する

Mac OS X Leopard 10.5.2およびそれより新しいmacOSにおいては、`launchd` が `$SSH_AUTH_SOCK` で接続を待ち受けていて、sshを利用するプログラムが起動され `$SSH_AUTH_SOCK` へ接続されると、`launchd`はシステム標準のSSHの `ssh-agent` を起動します。 [^1] [^2]
そのため、シェル設定スクリプトで`ssh-agent`を起動する必要はありません。

[^1]: [rmontero, USING SSH AGENT WITH MAC OS X](http://roberto-montero.com/blog/using-ssh-agent-mac-os-x)
[^2]: [Joel Knight, SSH Agent on OS X](https://www.packetmischief.ca/2016/09/06/ssh-agent-on-os-x/)

# TODO

- 全体的にもっと出典が欲しい
PHP 初心者　foreach文

foreach..配列の内容をループ形式で取り出せる

コロン構文...配列分の波括弧をコロンで終わらせる。閉じる場合は"endforeach;"
メリット...HTML分を書く際スッキリして書くことが出来る。

HTML文を書く前提としてコロン構文は外せない。課題だったHTMLも含めたコードを書くことが出来たので既存のコードをもう少し要素を付け加えていきたい。

後一番先頭の配列は以前に連想配列と学んだけど、ドットインストールではその辺は触れなかったから気になる。調べておこう

```
<?php

//配列
$game = [

  "kamimaho" =>100,
  "suisouginka"=>90,
  "pararero"=>80,
];

//foreach...上記の配列を引っ張ってきてくれる

foreach ($game as $key =>$value){
  echo $key."は".$value."点です" ;
}

コロン構文
foreach ($game as $key =>$value):
  echo $key."は".$value."点です" ;
endforeach;
?>

//HTMLのリストで表示させる記述
<ul>
  <?php foreach ($game as $key =>$value): ?>
  <li><?php echo $key."は".$value."点です" ; ?></li>
<?php endforeach; ?>
</ul>
ストレージについて勉強する④


##オールフラッシュストレージについて
仮想化のIOミキサーにおいて
データがすべてのサーバから等距離にあるため低レイテンシーを維持。

##注目されているのがPurestorage
###Pure　Storage FlashArray
強み①：重複排除と圧縮のテクノロジー
→その強みをビルドインで実現できている。
強み②：どんなワークロードでも高速
→「そこそこいい値」をずっと維持できる。
強み③:ワークロードを選ばないアーキテクチャ
→可変長に最適化されている。データが多ければ多いほどスループットが低いことがわかる。これは実環境で検証したほうが分かりやすく、性能を実感しやすい。
強み④：モジュール型アーキテクチャ
→外付けが多く、いろんなものを組み合わせてカスタマイズできる。

###Pure1
クラウドベースのストレージ管理システム
ストレージの状態を30秒ごとにクラウドにUP
Dellの監視システムだと3ステップかかるところを1ステップで済ませることができる。

###PureBlade
バックアップに特化したストレージ

###evergreen
クラウドライクなシステム。
オンプレのストレージの一部をクラウドにデータ移行させたいときにも便利。
PythonでJSONの入出力(エンコーディングもしっかりと)

# なにこれ

備忘録

データ処理関係をJSONで保存したりするケースを考える。
JSONファイルをなんらかの方法で受け渡しし、そのファイルをいじる。
Windows環境とUNIX環境をいったりきたりするとコーディングがcp932とかになって死ぬ。

なんか毎回ググってる気がするので、Windows環境とUNIX環境で動く自分なりのJSONの入出力をまとめた。

# コード

入力

```python
import json

with open(FILE_PATH, "r", encoding="utf-8") as f:
    all_data = json.load(f)
```

出力

```python
import json
import codecs

with codecs.open(FILE_PATH, 'w','utf-8') as f:
    json.dump(all_data, f, ensure_ascii=False)
```

# おわりに

出力を以下のように書いてて同じJSONいじってて環境が変わるたび毎回死んでた。

```python
with open(FILE_PATH, "w", encoding="utf-8") as f:
    json.dump(all_data, f)
```

# おわり
~~おしり~~
iCaldendar RFC-5545: 毎月の末日をRRULEで求める

本稿では毎月の末日を抽出するRRULEの書き方を紹介する。

```js
RRULE:FREQ=MONTHLY;BYMONTHDAY=-1
```

このルールで抽出される日付の例は[rrule.js demo](https://jakubroztocil.github.io/rrule/#/rfc/RRULE:FREQ=MONTHLY;BYMONTHDAY=-1)で確認できる。

## 解説

`FREQ=MONTHLY`は月次で繰り返すの意味。

`BYMONTHDAY=-1`は、毎月の末日の後ろから1番目という意味。つまり末日になる。

## 参考文献

* [iCalendar spec: 4.8.5.4 Recurrence Rule](https://www.kanzaki.com/docs/ical/rrule.html)
* [RFC 5545 - Internet Calendaring and Scheduling Core Object Specification (iCalendar)](https://tools.ietf.org/html/rfc5545)
Autoware(1.9.1) Docker セットアップ

とりあえず既存動作を見たいためのセットアップ

## dockerインストール
[Autoware.AI - wiki : Docker Installation 参照](https://gitlab.com/autowarefoundation/autoware.ai/autoware/wikis/docker-installation)

## NVIDIA ドライバインストール

リポジトリ登録
<pre>
sudo add-apt-repository ppa:graphics-drivers/ppa
sudo apt-get update
</pre>

ドライバ一覧
※自分のグラボに対応したバージョンを確認
<pre>
apt-cache search 'nvidia-[0-9]+$'
</pre>

ドライバインストール
※*** → インストール対象のバージョン
<pre>
sudo apt-get install nvidia-***
</pre>

## nvidia-dockerインストール
※nvidia-docker2だとうまく動かなかったので1.0.1を使用

インストール ※以下のコマンド全実行後に再起動実施
<pre>
wget https://github.com/NVIDIA/nvidia-docker/releases/download/v1.0.1/nvidia-docker_1.0.1-1_amd64.deb
sudo dpkg -i nvidia-docker_1.0.1-1_amd64.deb
sudo apt-get install nvidia-modprobe
</pre>

動作確認(CUDAがlatestだとうまく動かなかったので9.0で確認した)
<pre>
nvidia-docker run --rm nvidia/cuda:9.0-runtime nvidia-smi
</pre>

## Autoware-docker(1.9.1)インストール

<pre>
docker pull autoware/autoware:1.9.1-kinetic
</pre>

## デモ実施
[Autoware.AI - Wiki : ROSBAG Demo](https://gitlab.com/autowarefoundation/autoware.ai/autoware/wikis/ROSBAG-Demo) に沿って、デモ実施
Ruby on Railsでアプリの雛形をつくる

===仕様
今回はscaffoldは使用しない。
・アプリケーション名は任意。
・データベースはMySQLを使用する。
・tweetsコントローラー内に、index, new, createアクションがある（メソッドの中身が記述してある必要はありません）。
・コントローラーに対応したビューファイルがある（表示される内容はデフォルトのままで構いません）。
・tweetモデル内に、title, contentカラムがある（いずれも文字列）。
・tweetsテーブルが作成されている。
・必要なルーティングが設定されている。

===模範解答
> rails _4.2.6_ new sample-app -d mysql
> rails g controller tweets index new create
> bundle exec rake db:create
> rails g model tweet title:string content string
> bundle exec rake db:migrate
> routes.rb に resources :tweets, only: [:index, :new, :create] を追加し、不要な記述を削除
arduinoとは全く違う、IoTツールobnizのしくみ


obnizとarduinoの違いって何？マイコンなの？という質問をよくされるので、
**技術的観点から**しくみの違いを書いてみたいと思います。


# 一言でいうと

arduinoはコンピューターですがobnizは<font color="red">**システム**</font>です。
しくみが全く違うので、使い所が変わってきます。


# arduino/ラズパイのしくみ

arduinoにはプログラムを書き込むことができ、その書き込んだプログラムに応じて様々な動きをさせることができます。
![スクリーンショット 2019-08-08 11.08.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227015/3d6c1e28-bbb7-bd80-17c1-74ebe7b0e05a.png)

あくまで<font color="red">プログラムを書き込んで使うボード</font>です

# obnizのしくみ

obnizはarduinoのように、プログラムをボードに書き込むわけではありません。
![スクリーンショット 2019-08-08 11.08.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227015/70aa6768-172e-7215-658c-b96b4ab7a48c.png)

obnizとは別の、クラウド越し（インターネット越し）にあるPCやスマートフォンにプログラムを入れます。
![スクリーンショット 2019-08-08 11.08.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227015/a2bcb00f-8ea7-29c3-4bad-d1fc39a9e79a.png)


これは、クラウドを通じてマイコンにプログラムを書き込むというわけでもありません。
![スクリーンショット 2019-08-08 11.08.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227015/98d7facd-3b48-f801-a50a-a0cf61e8c2cf.png)

あくまで、プログラムはボード上ではなく<font color="red">**PC上で実行されます**</font>。
プログラムを実行すると、そのPCはobniz boardを<font color="red">遠隔で操作する</font>ことができます。ここがarduinoやラズパイと違うところになります。
![スクリーンショット 2019-08-08 11.08.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227015/7ffd8101-5e53-5300-a55f-6bb20f888be2.png)

<font color="red">PCが遠隔にあるボードを操作する</font>というのがobnizです。


# obnizのメリットとデメリット
この**ボードを遠隔操作する**というところがarduinoとの違いになってきます。
これにより色々なメリットがあります。

全体的なメリットとしては**webサービスを作るときの常識をハードウエアを作る際にも持ち込める**というものになるかなと思います。

**obnizのメリット**

 * インターネット越しに操作ができる
 * プログラムの実行がPC上なのでPCソフト／webサービスのように開発ができる
    * 好きな言語が選べる(SDKがあるのでJavaScript推奨)
    * 好きなエディタで書ける
    * メモリ容量とか気にしなくて良い
    * コンパイルが必要がない
 * 色々なクラウドサービスと連携が簡単にできる
 * ライブラリ等、共有資産が使いやすい
 * GUI付きのハードウェアプログラムが書ける
 * 手元にないボードの挙動を変更できる
 * 違うハードウェアでも同じプログラムで操作できる

もちろんデメリットもあります。

**obnizのデメリット**

 * インターネットがないと動かない
 * ネットワークのディレイが発生する
 * 遠隔操作するPC(もしくはスマートフォンなど)が必要になる 

インターネットがないと動かないというのは、スマートスピーカーのデメリットと同じですね

# obnizの特徴がより活きるところ


上記のメリットをより具体的な例にしてみると、たとえば一つのプログラムでいくつものボードを動かすことができます。

![スクリーンショット 2019-08-08 11.09.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227015/9837f6c1-373c-1f7f-2ae2-3bbd5c19234c.png)

3つでも4つでも100個でも、ボードを１つのプログラムから同時に動かすことができます。
ボードAのセンサの値に応じてボードBの表示を変える　等も１つのプログラムでできるので簡単です。



また、インターネット越しで有ることを活用すると、家においたボードを会社から動かす　ということもできます。
![スクリーンショット 2019-08-08 11.15.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227015/79bb8b76-f7a9-8b41-4d61-72327ae8a9ba.png)
帰宅前にクーラーをONにしたり、ペット監視したりがはかどりますね。



# つまり

arduinoはコンピューターで、obnizはシステムです。
それぞれ使いみちが異なるので、やりたいことに合わせて選択したら良いと思います。

obnizについてのより詳細の情報は公式ドキュメントに行くのが手っ取り早いです。
・[obnizドキュメント(公式)](https://obniz.io/ja/doc/root)


性能的な比較はこちらの記事にまとめています
[IoTデバイス開発向け製品を徹底比較。Arduino、Raspberry Pi、M5Stackからobnizまで](https://blog.obniz.io/ja/blog/iot%e3%83%87%e3%83%90%e3%82%a4%e3%82%b9%e9%96%8b%e7%99%ba%e5%90%91%e3%81%91%e8%a3%bd%e5%93%81%e3%82%92%e5%be%b9%e5%ba%95%e6%af%94%e8%bc%83%e3%80%82arduino%e3%80%81raspberry-pi%e3%80%81m5stack%e3%81%8b/)
おれのLinuxは適当すぎる〜vi篇

viにようやく興味がでてきたので()、まずは一番使いそうな操作から。
調べて手を動かしておおってなって、の備忘録です。

環境はmac。

既存のテキストファイル（英数字と空白が含まれてるならなんでもいいと思います）を用意。

#カーソルの移動
##1単語ずつの移動
めっちゃ便利。なんでこれ知らなかったんでしょうね。
ただしwとeの使い分けがちょっとわからん。が、存在するってことは何からしら意味があると思うのでおいおい。
マークダウンで表の作成記法ってどうやるんかなw

次の単語の移動：w　#ハイフンは1単語としてカウントする
現在または前の単語の先頭に移動：b
現在または次の単語の末尾に移動：e

##行の中での移動
これが知りたかった、まずはここから手に馴染ませる。

行頭：0
行末：$

最終行への移動：G

#編集
##全行の削除
:%dでどーんと消える。ddで1行まるごと消えるのは知ってましたよ！

#参考文献
[viの基本操作](http://www.gi.ce.t.kyoto-u.ac.jp/user/susaki/command/vi.html)
CloudWatchの空になったロググループ削除

# 問題

ログはカスタムsyslogサーバで集めていた。EBはもちろん下位インスタントのログも無理やり転送していた。特に負荷問題はないし、カッコウわるいけど、まーいいかの状態だった。
それが・・・もやは、CloudWatchはシステム構成の必須サービスになっている。何にしろログサーバとしてEC2単体運用はよろしくないので徐々にCloudWatchに移動することに。

そこで・・・EBの場合、ログ設定項目の[保持期間]、[ライフサイクル]によって環境のリタイヤと同時に掃除されると思ったら・・・
CloudWatchのログファイルは消えるが、フォルダのような[ロググループ]や[ログストリーム]はそのまま残るのではないか。
EBはスワップで頻繁にリリースするので過去環境の[ロググループ]が大量に残っていた。
ググっても大した情報はなかった。いくぞ！Lambdaよ。

# 関数コード

```python:Python3.7
import json
import boto3
import time

def lambda_handler(event, context):
    curTime = int(time.time())

    client = boto3.client('logs')
    pagenator = client.get_paginator('describe_log_groups')
    page_iterator = pagenator.paginate()
    
    for grps in page_iterator:
        for grp in grps["logGroups"]:
            grpName = grp["logGroupName"]
            storedBytes = grp["storedBytes"]
            creationTime = grp['creationTime']

            #新規ログテーブルはまだデータがない場合もあるため作成日14日以上を対象とする        
            useDays = int((curTime - (creationTime / 1000)) / (24 * 3600))

            #print(grpName, curTime, creationTime, f"useDays:${useDays}", f"storedBytes:${storedBytes}")
        
            if useDays >= 14:
                if storedBytes < 1:
                    print("DEL " + grpName + ": " + str(storedBytes) + "byte")

                    res = client.delete_log_group(
                        logGroupName = grpName
                    )

    return {
        'statusCode': 200,
        'body': json.dumps("OK")
    }
```

* 設定
 * タイムアウト: デフォルト3秒ではタイムアウトになるので30秒程度に。
 * CloudWatch Events: cron(0 13 * * ? *)　一日１回で十分。


# 参考
 * https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/logs.html#CloudWatchLogs.Client.delete_log_group
 * http://liibercraft.com/archives/201

* ECSのコンテナーログ保存先をCloudWatchに設定した翌日、テスターからECS上のサービスが動いてないと連絡があった。環境構築後、作業は数日後になることもあるので、作成日14日以上の条件を追加。
RailsのActiveRecordなどを単体で動かしてpry-byebugでデバッグする

Railsのソースコード読んでても黒魔術がいっぱいで、どうやって動いてるのかよく分からんです。

`rails new`で素のサンプルアプリケーションを作って、 `pry-byebug` などのデバッカを差し込んでもよいんですけど、railsのバグ報告に使われてるissueテンプレート使うと1ファイルで書けるし、rubyはdockerで実行しちゃえばクリーンな環境でできそう。

元ネタは以下です。

https://github.com/rails/rails/blob/646dd8c51fc438bf935d4192ba0479e439c1ec54/guides/bug_report_templates/active_record_gem.rb

pry-byebugの設定を追加で差し込んでおきます。


```test.rb
# frozen_string_literal: true

require "bundler/inline"

gemfile(true) do
  source "https://rubygems.org"

  git_source(:github) { |repo| "https://github.com/#{repo}.git" }

  # Activate the gem you are reporting the issue against.
  gem "activerecord", "6.0.0.rc2"
  gem "sqlite3"
  gem 'pry-byebug'
end

require "active_record"
require "minitest/autorun"
require "logger"
require 'pry'

if defined?(PryByebug)
  Pry.commands.alias_command 'c', 'continue'
  Pry.commands.alias_command 's', 'step'
  Pry.commands.alias_command 'n', 'next'
  Pry.commands.alias_command 'f', 'finish'
end

binding.pry

# This connection will do for database-independent bug reports.
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
ActiveRecord::Base.logger = Logger.new(STDOUT)

ActiveRecord::Schema.define do
  create_table :posts, force: true do |t|
  end

  create_table :comments, force: true do |t|
    t.integer :post_id
  end
end

class Post < ActiveRecord::Base
  has_many :comments
end

class Comment < ActiveRecord::Base
  belongs_to :post
end

class BugTest < Minitest::Test
  def test_association_stuff
    post = Post.create!
    post.comments << Comment.create!

    assert_equal 1, post.comments.count
    assert_equal 1, Comment.count
    assert_equal post.id, Comment.first.post.id
  end
end

```

```console
$ docker run -it --rm -v $(pwd):/tmp/work ruby:2.6.3 /bin/bash
root@27dd893231b5:/# ruby /tmp/work/test.rb

From: /tmp/work/test.rb @ line 31 :

    26: end
    27:
    28: binding.pry
    29:
    30: # This connection will do for database-independent bug reports.
 => 31: ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
    32: ActiveRecord::Base.logger = Logger.new(STDOUT)
    33:
    34: ActiveRecord::Schema.define do
    35:   create_table :posts, force: true do |t|
    36:   end
```

あとはご自由に。
O365スケジューラーのCalendarViewが404エラーになる原因

★現象
　CalendarViewを実行したが404エラーになった。

★原因
　アクセス権の不足。
　CalendarViewでスケジュール情報にアクセスする場合、全詳細情報へのアクセス許可が必要。
　↓Outlookでの設定例
![O365アクセス権.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/467228/5823fb33-4f22-6cdd-8e0e-d907f6878b93.png)

★アクセス権を変更できない場合の回避方法
　getScheduleを利用する。
　これで全詳細情報の参照権限が無くても予定を取得することは可能。
　　※ただし、calendarViewと違い詳細情報は取得できない


★参考リンク
Graphエクスプローラー
https://developer.microsoft.com/ja-jp/graph/graph-explorer

calendarView
https://docs.microsoft.com/ja-jp/graph/api/user-list-calendarview?view=graph-rest-1.0&tabs=http

getSchedule
https://docs.microsoft.com/ja-jp/graph/api/calendar-getschedule?view=graph-rest-1.0&tabs=http
TCPレイヤーで「なんかパフォーマンスが低下してるな…」の手引き



## なんか遅いを解決する
開発環境やその他の環境と比べて特定の別環境で実行したら「なんか遅くなる…」という場合に陥る話です。

### 1.Nagleアルゴリズムを切る
大雑把に言えば、細かい粒度の書き込みデータをある程度遅延(バッファ)して送信するというTCPのオプション機能。
https://ja.wikipedia.org/wiki/Nagle%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0
`アプリケーションが繰り返し1バイトなど小さな粒度で送信する問題を取り上げている。IPv4 で 20バイト、TCP自体で20バイトのヘッダーがあり、合計40バイトになるため、1バイトを送信するのに合計41バイト送信しなくてはならなく、オーバーヘッドが大きい。`
Wikipediaの記載の通り、オーバーヘッドが大きいため細かい粒度はある程度まとめて送るほうが効率がいい場合があるため、デフォルトではこのオプションが有効になっていることが多い。
アプリケーション側で意味のあるバッファしている場合など、Nagleアルゴリズムが無駄な遅延となることがあるためオプションを無効にすると改善される場合[^1]がある。

java.net.Socketだと無効にする場合はこいつ→`Socket.setTcpNoDelay(boolean on)`


### 2.DNSの逆引きをしない
サーバー側で接続元の情報が欲しいとき、例えばログに接続元情報を出力したい場合など
接続されたSocketに対して`java.net.InetSocketAddress.getHostName()`を呼ぶとIPアドレスからホスト名の逆引きが行われます。
IPアドレスからホスト名の逆引きに失敗すると、DNSの応答までに数ミリ秒～数秒と結構時間がかかるため、その分遅くなります。
逆引きに失敗する環境でしか起こりえないので、この場合のパフォーマンス低下には気づきにくいですが接続元の情報をなにかしらする実装がある場合か、`getHostName()`などでgrepすることで原因特定ができる場合があります。


*****
もう少し色々あったきがするけど思いつく範囲だと２つしかなかった……。



[^1]: Nagleを無効にする場合はレイテンシは低下するけどスループットも低下する可能性もあるので、アプリケーションの特性と相談する必要があります。
Oracleのテーブル最適化の作業、メモ書き

Oracleで作業していて肥大化したテーブルの割り出しと、テーブルの最適化を行う方法をとりあえずメモ書き。

## 各テーブルサイズの取得

以下のSQLでテーブル名、テーブルサイズを取得してどのテーブルを最適化するか判断。


```sql
SELECT 
      a.table_name AS "テーブル名称"
      ,a.num_rows AS "レコード数"
      , b.MB AS "容量(MB)"
FROM user_tables a 
      , (Select Segment_Name,Sum(bytes)/1024/1024 MB From user_segments Group By Segment_Name) b 
WHERE a.table_name = b.Segment_Name
ORDER BY a.num_rows desc, b.MB desc;
```
[元のSQLはこちらを参考に](https://www.zanmai.net/blog/data/252.html)


## テーブルの行移動を有効にする

以下のSQLを使ってテーブルの行移動を有効にする。すでに行移動が有効になっている場合には必要ない。

```sql
ALTER TABLE "テーブル名" ENABLE ROW MOVEMENT;
```

## テーブルの縮小を行う

以下のSQLを使ってテーブルの縮小を行う。
CASCADEは関連するインデックスのサイズの縮小まで行う。COMPACTにも切り替えができるが、こちらはセグメントデータの再構成のみ行う。

```sal
ALTER TABLE "テーブル名" SHRINK SPACE CASCADE;
```

## 補足

一先ずメモ書き程度にまとめ。
追々記述を追加するかも。
Gitコマンド

個人的によくテンパるのでよく使うコマンドをまとめてます。

# ブランチ操作
#### 現在のブランチの状態確認
```
$ git status
```

#### ローカルブランチを全て表示
```
$ git branch
```

#### ローカル／リモートブランチを全て表示
```
$ git branch -a
```

#### ブランチ切替え
```
$ git checkout [ブランチ名]
```

#### ローカルブランチの削除
```:ローカル
$ git branch -d [ブランチ名]
```
```:リモート
$ git push origin :[ブランチ名]
```

#### ファイルの最新化
```
$ git pull origin [ブランチ名]
```

#### ローカルのソースをリモートのソースと同期
```
$ git checkout -- [対象ソースファイル]
```

#### ソースのコミット
```
$ git commit [オプション]

オプション
　-m "コメント文字列"　コメント入力モードを省略してコメントを挿入
```

#### ソースのプッシュ
```
$ git push
```


####
```
$ git remote prune origin
    - リモートにないブランチがローカルあれば削除する
```

#### リモートにあるブランチをローカルになければ追加する
```
$ git fetch
```


#### pruneとfetchを同時に行う  
```
$ git fetch --prune または $ git fetch -p
```

#### ローカルのmasterブランチをリモートのmasterブランチにpushする
```
$ git push origin master:master
```

```:省略形
$ git push origin master
```

#### ローカルのmasterブランチをリモートのreleaseブランチにpushする
```
$ git push origin master:release
```

#### リモートブランチをローカルに作成  
```
$ git checkout -b [ローカルブランチ名] origin/[リモートブランチ名]  
```
```:例）
$ git checkout -b development origin/development  
```

# ログ関連
#### コミット済みのログを確認
```
$ git log
```

#### ログIDに紐づくコミット内容を確認
```
$ git show [ログID]
```

## ブランチの取込み
```
$ git merge [ブランチ名]
```
```:例）branch_Aがbranch_Bを取り込む
$ git branch -a
*branch_A
 branch_B
$ git merge branch_B
```
## タグ操作
#### タグ一覧
```
$ git tag
```

#### タグ登録
```:ローカル
$ git tag [タグ名]
```
```:リモート
$ git push origin tag [タグ名]

一括登録
$ git push origin --tags
```

#### タグ削除
```:ローカル
$ git tag -d [タグ名]
```
```:リモート
$ git push origin :[タグ名]
```
*ローカルを削除してからリモート側を削除
Amazon linux2 にjava 1.8.0をインストールする

Amazon linux2 EC2インスタンスにjavaをインストールしたいと思います。


立ち上げて`sudo yum update`を実施後、javaが入っているか確認する



```
[ec2-user@ip-10-0-0-127 ~]$ java -version
-bash: java: command not found
```

入ってなさそうですね


javaを探す

```
[ec2-user@ip-10-0-0-127 ~]$ sudo yum search java
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
============================== N/S matched: java ===============================
aether-javadoc.noarch : Java API documentation for Aether
ant-antunit-javadoc.noarch : Javadoc for ant-antunit
ant-contrib-javadoc.noarch : Javadoc for ant-contrib
ant-javadoc.noarch : Javadoc for ant
ant-javamail.noarch : Optional javamail tasks for ant
antlr-javadoc.noarch : Javadoc for antlr
aopalliance-javadoc.noarch : API documentation for Java/J2EE AOP standards
apache-commons-beanutils-javadoc.noarch : Javadoc for apache-commons-beanutils
apache-commons-cli-javadoc.noarch : Javadoc for apache-commons-cli
apache-commons-collections-javadoc.noarch : Javadoc for
                                          : apache-commons-collections
apache-commons-collections-testframework-javadoc.noarch : Javadoc for
                                                        : apache-commons-collections-testframework
apache-commons-dbcp-javadoc.noarch : Javadoc for apache-commons-dbcp
apache-commons-exec-javadoc.noarch : Javadocs for apache-commons-exec
apache-commons-jexl-javadoc.noarch : Javadocs for apache-commons-jexl
apache-commons-pool-javadoc.noarch : Javadoc for apache-commons-pool
apache-commons-validator-javadoc.noarch : Javadoc for apache-commons-validator
apache-commons-vfs-javadoc.noarch : Javadoc for apache-commons-vfs
apache-rat-javadoc.noarch : Javadocs for apache-rat
aqute-bnd-javadoc.noarch : Javadoc for aqute-bnd
aqute-bndlib-javadoc.noarch : Javadoc for aqute-bndlib....
```


要件に合わせて、JREまたはJDK（=javacなど開発系コマンドを含む）を選んでインストール

```
# JDK1.8.0をインストール
$ sudo yum install -y java-1.8.0-openjdk-devel.x86_64
```

Java8を有効化する

```
[ec2-user@ip-10-0-0-127 ~]$ sudo alternatives --config java

There is 1 program that provides 'java'.

  Selection    Command
-----------------------------------------------
*+ 1           java-1.8.0-openjdk.x86_64 (/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.201.b09-0.amzn2.x86_64/jre/bin/java)

Enter to keep the current selection[+], or type selection number: 1
[ec2-user@ip-10-0-0-127 ~]$ java -version
openjdk version "1.8.0_201"
OpenJDK Runtime Environment (build 1.8.0_201-b09)
OpenJDK 64-Bit Server VM (build 25.201-b09, mixed mode)
```

おしまい

参考元
https://www.yoheim.net/blog.php?q=20180101
個人的メモ　rails エラーメッセージの表示が英語だった時にi18nファイルを弄って日本語化する方法

エラーメッセージが英文でそのまま「モデル名+エラー内容」で出力されてしまい、ユーザーにわかりやすいように日本語化する方法を教えていただき、公式ガイドを見つつ実装したので忘備録的にメモ。

i18n公式ガイド : https://railsguides.jp/i18n.html

# 元々のエラーメッセージ表示内容

```
transration missing ja.activereccord.errors.models.モデル名.カラム名
```

### 対処方法

i18nの設定が書かれたファイルがconfig/local/ja.ymlにあるので、ここのそのエラー内容に対応した場所に日本語表示を定義する。
例えば

```
 activerecord.errors.models.model_name.model_culumn_name

```

というエラー表示であれば、

```
 activerecord:
    errors:
      models:
        model_name:
          culumn_name: 「ここに新しく定義するメッセージを書く」
```


また、しっかり階層構造下に書かなくとも、

「activereccord-errors-messages直下に定義してもja.ymlさんはモデルカラム名」

に定義すると、モデル全体にエラーメッセージを適応してくれるため、その必要がある時はここに書いてもよいです。

以下は例です

```
  activerecord:
    errors:
      messages:
        culumn_name: 「ここに新しく定義するメッセージを書く」
```


※公式ガイド4.5.1 エラーメッセージのスコープ　より
https://railsguides.jp/i18n.html#%E3%82%A8%E3%83%A9%E3%83%BC%E3%83%A1%E3%83%83%E3%82%BB%E3%83%BC%E3%82%B8%E3%81%AE%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%97

```
公式ガイドによると、ymlファイルに書かれているメッセージ内容を以下の順番で探してくれるみたいです。

| activerecord.errors.models.[model_name].attributes.[attribute_name] |
| activerecord.errors.models.[model_name] |
| activerecord.errors.messages |
| errors.attributes.[attribute_name] |
| errors.messages |
```
Mac上で MySQLの起動に失敗する

# 現象
mac上でインストールしたMySQLを起動しようとするとエラー

```
Starting MySQL
.. ERROR! The server quit without updating PID file (/usr/local/var/mysql/XXXXXXXX.local.pid).
```

`brew services start mysql@5.7`で起動するとエラーが表示されないために気づけない
バックグラウンドでの起動でない
`/usr/local/opt/mysql@5.7/bin/mysql.server start`でやっと気づくという罠があります。

# 原因
MySQLはアンインストールしてもdataファイル（/usr/local/var/mysql）は削除しないため、起動時に生成されるPIDファイルなどが悪さをする。

# 対策
MySQLのアンインストール

```
brew uninstall mysql
brew uninstall mysql@5.7
```

Dataファイル削除

```
rm -rf /usr/local/var/mysql
```

ソケットファイルも削除
参考にさせていただいたサイトでは書かれていたので念の為

```
rm -rf /tmp/mysql.sock
```

# 参考
[MySQLをいれた際に遭遇したエラー](https://qiita.com/harukikaneko/items/f0b70fada8216c63e6d6)