OmniAICreator/Qiita-1.07M huggingface dataset:
CakePHPで正しくEmailTransportを設定する

###はじめに

CakePHP４でEmailをローカルで送るよう`config/app.php`に設定していて、Emailがどうも送られないので解決法を記事にしました。

###この記事の対象
- `config/app.php`と`config/app_local.php`の違いがわからない方
- `config/app.php`でEmailTransportの設定を行なったのにメールが来ない方

###Emailの設定方法

以下の記事の通りにEmail設定を行います。
https://qiita.com/hajime_shoji/items/22cd78dc51932963233c

```php:config/app.php
    'EmailTransport' => [
        'default' => [
            'className' => 'Smtp',
            'host' => 'smtp.gmail.com',
            'port' => 587,
            'timeout' => 30,
            'username' => 'myGmailAccount@gmail.com',//ここに自分のGmailアカウントを設定
            'password' => 'myPassword',//ここに自分のGmailアカウントのパスワードを設定
            'client' => null,
            'tls' => true,
//            'url' => env('EMAIL_TRANSPORT_DEFAULT_URL', null),//ここはコメントアウト
        ],
    ],

```

この設定をして、Controller等でEmailを送る機能を実装します。
受信先もGmailアカウントを使用する場合、必ず`安全性の低いアプリからのアカウントへのアクセスを許可する`設定を行いましょう。詳しくは上の参考記事を見てください。

###問題点

この設定をしているのにも関わらず、メールが送られない場合があります。
ここで見てほしいのは、`config/app_local.php`です。というのも、CakePHPでは、`config/app.php`を読み込んだ後、すぐに`config/app_local.php`が読み込まれます。慣れていないとうっかり見落とす場合があります。自分は`config/app_local.php`がデフォルトのままでした。

参考：https://book.cakephp.org/3/en/development/configuration.html#configuring-your-application

###解決案

ローカルでは`config/app.php`ではなく`config/app_local.php`にEmailTransportの設定を書きましょう。

```php:config/app_local.php`
    'EmailTransport' => [
        'default' => [
            'className' => 'Smtp',
            'host' => 'smtp.gmail.com',
            'port' => 587,
            'timeout' => 30,
            'username' => 'myGmailAccount@gmail.com',//ここに自分のGmailアカウントを設定
            'password' => 'myPassword',//ここに自分のGmailアカウントのパスワードを設定
            'client' => null,
            'tls' => true,
//            'url' => env('EMAIL_TRANSPORT_DEFAULT_URL', null),//ここはコメントアウト
        ],
    ],

```

###補足

ちなみに、メールを送る時はエラーが起こりうるので、SendしたらしっかりTry＆Catchでエラーをログに書き込んでおきましょう。

```php:
            try {
                $this->getMailer('Mailerの名前')->send($Mailerのメゾット, [$entity]);
            } catch (\Exception $e) {
                Log::error($e->getMessage());
            }
```
RAID10とRAID01の違い


## RAID10 とは

- RAID10 とは以下の2つを合わせたもの
	- RAID0 : ストライピング
	- RAID1 : ミラーリング

下記の図のように、
RAID0でRAID1グループに分散させ、
その分散させたデータをRAID1でミラーリングしているのがRAID1+0になります。

![RAID1+0.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/939f8a16-f613-f674-349f-1771192bacec.jpeg)



## RAID01 とは

- RAID10 とは以下の2つを合わせたもの
	- RAID1 : ミラーリング
	- RAID0 : ストライピング

下記の図のように、
RAID1でミラーリングしたデータを
RAID0で各HDDに分散しています。

![raid0+1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/899243bc-8d92-68dd-c1ff-d1806e10b462.jpeg)


##　違い

同じHDD構成であれば、
読み込み速度・書き込み速度、使用できるデータの容量に違いはありませんが、
耐障害性に関して違いがあります。

- RAID1+0の耐障害性

この構成であれば、ディスクが最大4本まで障害になってもデータの損失はありません。
グループをまたがった障害に強いが、グループ内でのディスク障害はデータ損失になります。

![RAID1+0 障害.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/fda4997e-e765-c7e7-4d02-74fd8e51d4a3.jpeg)


- RAID0+1の耐障害性

しかし、RAID0+1であれば耐障害性はさがります。
1+0とはちがい、グループをまたがった耐障害性がありません。
データをまたがった障害が発生するとデータ損失になります。


![RAID0+1 障害.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/c1e5ea17-7004-78e6-3c0f-f5432aa21ae2.jpeg)
windows端末上でのssh鍵のパーミッションを変更するバッチファイル

# windows端末上でssh鍵のパーミッション変更する

特に何も考えずにsshをしようとするとssh鍵のパーミッションで以下のようなエラーが起きた

```
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions for 'id_rsa.pem' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
Load key "id_rsa.pem": bad permissions
username@servername: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
```

windows端末にはchmodに相当するssh鍵のパーミッション変更のためのコマンドはない
git bashなどでchmodをしても上手くいかない

調べてみるとGUIで権限設定はできるらしい
https://qiita.com/reatoretch/items/4cc88097338145aa94ba
がコマンドラインでいろいろと完結したいのでバッチファイルを書いてみた。

## 作成したバッチファイル
※ 管理者権限が必要です

```bat
@echo off

if NOT %ERRORLEVEL% EQU 0 goto NotAdmin
if "%1"=="" goto NoArg
icacls %1 /inheritance:r
takeown /F %1

for /f "usebackq" %%t in (`whoami`) do set myName=%%t
echo %myName%
icacls %1 /grant "%myName%:F"
goto End

:NotAdmin
echo 管理者権限で実行してください
goto End

:NoArg
echo ファイル名を引数として与えて下さい

:End 
```

## 実行方法
1. 上記内容を `change_permission.cmd` などとして保存
1. 管理者権限でPowershellを開き上記ファイルの場所へ `cd` で移動
1. `./change_permission.cmd <鍵ファイルのパス>` として実行


ファイルの権限をすでにいじっているとうまくいかない可能性があると思うが基本的にはうまくいくとおもいます。
自分の環境では問題ありませんでした。

具体的には継承された権限をicaclsで無効化し

```
icacls %1 /inheritance:r
```
takeownで所有権を獲得

```
takeown /F %1
```
icaclsを使って自分にフルコントロールを与えている

```
icacls %1 /grant "%myName%:F"
```

ここ間違ってるよ、もっと簡単な方法知ってるよという方、是非ご教授お願い致します。
ありがとうございました
PHP ~Cookie~

# Cookie
Cookie はブラウザにちょっとした情報を保存するための仕組みで、いったん値をセットしてしまえば、それ以降のリクエストではこの値を自動的に合わせて送ってくれるという仕組みになっています。

# setcookie() 関数
下記の画像は、colorという名前にcolorの値を保存してくれます。
そうするとブラウザにcolorの値をセットしてくれます。
![スクリーンショット 2020-10-06 17.41.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663122/c0c7b551-8f74-8757-5296-afc9b67bde05.png)
※setcookieの前に何も出力してはいけないというルールがあります。

# Session
Sessionを使う事によってサーバー側で情報を保持できる様になる為デベロッパーツールなどで値を確認したり編集できなくなりますので安全性が高まります。
#CookieとSessionの違い。
### Cookie
ブラウザ保存
サイズ制限あり
文字列のみ
安全性が低い
簡単な設定項目など
### Session
サーバー側に保存
サイズ制限なし
オブジェクトなどもOK
安全性が高い
認証情報など。。

## session_start();
session_start();とする事で使える様になります
そうすると下記の画像の様に、＄_SESSIONが使えます。
![スクリーンショット 2020-10-06 18.25.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663122/576e9b07-5c0e-98ca-b79f-5c6bccecb85a.png)
BigQueryでワンライナーでDDLを生成する

# 概要
BigQueryに存在するテーブルのDDLが欲しいときってありませんか？僕はあります。
`bq`コマンドでスキーマ情報を取得できますが、JSON形式だったりで微妙に欲しい物と違う。
そんなときに使えるワンライナーです

# 実行環境
Mac

# 必要なもの
- [bqコマンドラインツール](https://cloud.google.com/bigquery/docs/bq-command-line-tool?hl=ja)
- [jqコマンド](https://stedolan.github.io/jq/)
- [gnu-sed](http://www.gnu.org/software/sed/)
    - 下記コマンドでは`alias sed='gsed'`してます

# コマンド
```bash
TABLE_NAME=fh-bigquery:wikipedia_v3.pageviews_2018; \
bq show --schema --format=prettyjson ${TABLE_NAME} \
 | jq -c -r '.[] | [.name, .type]' \
 | sed -r 's/(\[|\]|")//g' \
 | sed -e 's/,/ /g' \
 | sed -e 's/INTEGER/INT64/g' \
 | sed -e '2,$s/^/,/g' \
 | sed -e 's/^/  /g' \
 | sed -z "s/\(.*\)/CREATE TABLE \`${TABLE_NAME}\` (\n \1)\n/g" \
 | sed -e 's/:/\./g'
```

# 結果
```sql
CREATE TABLE `fh-bigquery.wikipedia_v3.pageviews_2018` (
   datehour TIMESTAMP
  ,wiki STRING
  ,title STRING
  ,views INT64
)
```

# 備考
- カラム名とかによっては使えないかもしれないけど許してください
- あとパーティションとかディスクリプションには対応してません。カラムディスクリプションは１コマンド足せばできるかもしれないです（未検証）

# 最後に
- `jq`をもっと使いこなせるようになりたい
lambda_handlerの引数eventの中身を知る方法

何かのイベントにフックしてlambdaを実行する際、eventの中身がわからくて困ったとき用メモ

```
import json
import urllib.request
def post_slack(message):
    send_data = {
        "text": message,
    }
    send_text = json.dumps(send_data)
    request = urllib.request.Request(
        'slackのwebhookURL',
        data = send_text.encode('utf-8'), 
        method = "POST"
    )
    with urllib.request.urlopen(request) as response:
        response_body = response.read().decode('utf-8')

def lambda_handler(event, context):
    message = json.dumps(event)
    post_slack(message)
```
読書会「プログラマが知るべき97のこと」 #6

# 1．今回の読んだ記事
No.85　[冗長なログは眠りを妨げる](https://xn--97-273ae6a4irb6e2hsoiozc2g4b8082p.com/%E3%82%A8%E3%83%83%E3%82%BB%E3%82%A4/%E5%86%97%E9%95%B7%E3%81%AA%E3%83%AD%E3%82%B0%E3%81%AF%E7%9C%A0%E3%82%8A%E3%82%92%E5%A6%A8%E3%81%92%E3%82%8B/)　
著者: Johannes Brodwall

# 2．記事の概要
**重大な問題が起きているか、いないかを判断できるようなログの出し方をするとよい**

+ ログの情報が多すぎることは、ログを出力しないのと同じこと
+ 「情報ログ」と「エラーログ」の出力場所を分け、記載があるかで判断
+ 分散システムの場合、依存関係で発生する異常もあるので考慮が必要

# 3．この記事を選んだ理由・感想
**理由**
自分が担当するシステム以外のログの出力基準などを聞いてみたかったから。
アプリが正常に動くことだけでなく、サービス稼働後の運用面も加味してシステムを構築していかなければならないということを皆で再確認するため。

**感想**

- エラーログファイルを分けることについて
 - 検知をする面でいえば、監視ツールが「ERROR」文字列を出力すれば検知して通知するなどの仕組みがあれば、やる必要無いように思った。
 - 半面、単純にエラー調査する場合において、エラーログファイルだけを見るだけでよくなるという点では、ログファイルを分けることに価値があるかもしれない。

# 4．議論
**各開発チームごとのログの出し方方針を語る**

- **Aチーム**

    - ログが少なくて、「もう少し多く出力した方がよかった」と思ったことがあった。
        - スタートとエンドの記載しかなくて、遅延が発生した際にどこが遅くなっているのか判別がつかなかった
    - ただ、ログを出しすぎるとサイズが大きくなる

- **Bチーム**

    - 分散システムなので連携システムの遅延を検知するのに、外部連携時のスタート・エンドの記載は重要
        - エラーになるほどではないが、「通常より処理が遅いかもしれない」・・・という小さい異常などが起きた場合に気づくことができるから

- **Cチーム**
    - 24時間動くようなシステムではなく、アクセスもそれほど多くないので細かいことまで意識していない
    - ログをたくさん出すとディスクを圧迫することもあり、お客様からも嫌がられる可能性があるので極力少なめに出力する


**ログに関する設計書についての議論**

- 運用業務が専任の人に対して重要なのでしっかり作りたいが、記載レベルや運用などが難しい面もある
    - 人が書いたログを見ることが多いので感じることは、運用の観点で適切なログの記載レベルをを開発時にメンバーに共有するのが難しい
        - 運用してみて追加していくなどで対応している
        - 重要ななログを出すタイミングは設計書に定義して書くことはある程度認識があって実現できているが、メンバーの裁量によって不足がある。
        - （自分のシステムに関して言うと）運用に慣れていない人が設計した場合、全体的にログが少なめになってしまう傾向がある。
    - ログ専用の詳細設計書を作るのもいいが、ログを追加したり減らしたりしたときのメンテナンスが結構大変でうまく運用しきれていない
    - 自分で開発・運用しているので、試験を実施するときに追加していくようにしている
    

**その他：組み込み系でのログ**

- 1トランザクションでの操作をすべてログをメモリにためて、障害が発生したときだけすべて出力しておく方法だった
    - 機械の中で動くものなのでログファイルを貯められないから
    - へー、なるほど


# まとめ
ログに関してはそれぞれに意見があって面白い。
そして、ログの話は結構盛り上がるということがわかった。議論時間が過ぎてもまだ話せそうな雰囲気。
ここら辺は、皆それぞれ言いたいことがあるのだと思う。
次回に続く。
renderとredirect_toの違い


#renderとredirect_toの違い
progateのrails講座をやっていて、renderとredirect_toの違いに迷ったのでその違いについて、自分用にまとめます。

##違い
・render       :  直接viewのファイルを指定　他のアクションを経由しなくてよい
　　　　　　　　　　renderを指定したアクション内の変数を他のviewでも使用することができる
・redirect_to  :  URLを指定　他のURLに転送

##書き方
render(フォルダ／ファイル）　フォルダ名のため最初の／はいらない

```

render("users/edit")
```
redirect_to("/URL/~/~") 最初／いる

```

redirect_to("/users/#{@user.id}")
```

##動きの違い
・render　　　　　：　controller　→　view
・redirect_to　　　：　controller　→　URL　→　route　→　controller　→　view

renderがviewファイルを指定して、それを表示させる処理
redirect_toはブラウザ上でHTTPリクエストを受けたのと同じ処理


##使い分け
・render      :  更新せず前のデータを引き継ぎたいときなど使用
・redirect_to :  データの削除や更新など　controllerの処理が必要
GoogleAppEngineでIPアドレスを取得する方法

## $_SEVERからアクセス元のIPアドレスは取得できない

例えばLaravelで`request()->ip()`として得られるのは、`169.254.1.1`という、リンクローカルアドレスになる。
参考：[ループバックアドレスとリンクローカルアドレス](https://www.itbook.info/study/p62.html)

## IPアドレスはヘッダーから取得できる

以下のようにすればIPアドレスが取得できる。
`request()->header('X-Forwarded-For')`

プロキシサーバーを経由している場合はカンマ区切りのデータになる。
先頭がアクセス元のIPアドレス、2番目以降はプロキシサーバーのIP。

参考：[Request Headers](https://cloud.google.com/appengine/docs/flexible/python/reference/request-headers)
「もっとプログラム脳を鍛える数学パズル」_Q18 (code:Ruby) -> Rust

[「もっとプログラマ脳を鍛える数学パズル」](https://www.shoeisha.co.jp/book/detail/9784798153612)をRustで書き直すのは、ボケ防止にちょうど良いかもしれない、と思った。

# Q18:非常階段での脱出パターン

## Ruby

```ruby:q18_2.rb
N = 16

@memo = {0 => 0, 1 => 1}

def steps(n)
    return @memo[n] if @memo[n]

    none = (~n)
    movable = (none << 1) + 1
    moved = (n & (~movable)) | ((n >> 1) & none)

    @memo[n] = 1 + steps(moved)
end

sum = 0
(1..((1 << N) - 1)).each do |i|
    sum += steps(i)
end

puts sum
```

## Rust

```rust:main.rs
use std::collections::HashMap;
fn main() {
    let mut q18 = Q18::new();
    println!("{}", q18.sum(16));
}

struct Q18 {
    memo: HashMap<u64, u64>,
}

impl Q18 {
    fn new() -> Q18 {
        let mut q18 = Q18 {
            memo: HashMap::new(),
        };
        q18.memo.insert(0, 0);
        q18.memo.insert(1, 1);
        q18
    }

    fn steps(&mut self, n: u64) -> u64 {
        match self.memo.get(&n) {
            Some(v) => return *v,
            _ => {
                let none = !n;
                let movable = (none << 1) + 1;
                let moved = (n & !movable) | ((n >> 1) & none);

                let result = 1 + self.steps(moved);
                self.memo.insert(n, result);
                result
            }
        }
    }

    fn sum(&mut self, number_of_steps: u64) -> u64 {
        (1..=((1 << number_of_steps) - 1)).fold(0, |acc, i| acc + self.steps(i))
    }
}

```

もとのRubyコードの`@memo[n] = 1 + steps(moved)`の箇所は、2行に分けないとBorrowingのエラーが発生する("cannot borrow `*self` as mutable more than once at a time")ので、一旦resultとして変数に結果を格納する。
必然的に、見通しの良いコードになる。
エクセルからPythonスクリプトを実行する(xlwingsを使用)

# はじめに
エクセルに実行ボタンを配置して、それを押すと、Pythonのコードを実行するスクリプトの雛形作成についてまとめたいと思います。
ここではxlwings quickstartを使用します。

# 前提環境
OS: macOS Catalina 10.15.3
python: Python 3.7.9 (Anaconda 4.8.3)
-> Anacondaを[公式サイト](https://www.anaconda.com/products/individual#linuxos)からinstallした状態で、"test-env"という仮想環境を1つ作成済み


# 準備
1.以下のコマンドを実行をし、xlwingsのアドインをインストールする。  
*xlwingsはエクセルからPythonを実行するためのモジュールのことです。

```
$ xlwings addin install
```

成功すると以下が表示されます。

```
xlwings version: 0.20.7
Successfully installed the xlwings add-in! Please restart Excel.
Successfully enabled RunPython!
```

2.アドインを適応させるために、ツール > Excel アドイン を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227613/d447617c-bb57-349b-cc49-762fc6e95fb6.png)
出てきたポップアップの「参照」を押し、***xlwings.xlam*** を検索して選択 ->
ファイルを開くを押す。有効なアドインでXlwingsが選択されていればOKです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227613/b16d7e3d-dea1-1340-bcdb-83380d3f8795.png)


3.全てのエクセルを閉じ、再度対象のエクセルを開く。
エクセルのメニューにxlwingsが増えていることを確認ください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227613/9ce78241-0007-7275-63f3-8e8698fc7616.png)

4.プロジェクトを作成したいディレクトリに移動する
5.コマンドラインで以下を実行。プロジェクト名には作成したいプロジェクトの名前を指定すること。

```
$ xlwings quickstart {{プロジェクト名}}
```
6.プロジェクトが作成されその中にプロジェクト名.pyとプロジェクト名.xlsmが作成されていることを確認する。今回はわかりやすいように"test_project"という名前のプロジェクトを作成しました。
(余談ですが、プロジェクト名を"test"にするとなぜか実行ボタンを押下の際にうまくスクリプトが実行されませんでした。[こちら](https://github.com/xlwings/xlwings/issues/657)にもそのような記載がありました。)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227613/343dae80-7a93-892a-cb4e-c11c75593618.png)


# エクセルに実行ボタンをつくってpythonスクリプトを実行する
1.VBE(Visual Basic Editor)を開く。ショートカットキーは「Alt+F11」
以下のような画面が開くことを確認する。
![スクリーンショット 2020-10-07 17.52.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227613/99e8ce98-d243-a01a-d39c-21fb2544acb6.png)

2.エクセルに戻って実行ボタンを追加する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227613/d7c0cc23-d70c-9d5a-8089-7deb1a5b2178.png)

その際、ポップアップが出てくるので、そのポップアップで、紐づけたいVBA関数を選択する。
ここで***SampleCall***を選択し、マクロ名の欄にも反映されることを確認しOKを押す。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227613/9a5060fa-a3bd-6e89-743b-61f9e13a70ed.png)

これによってボタンを押したら、SampleCallが実行されることになります。

3.次に、pythonを実行するためのAnaconda環境を設定します。
エクセルのメニューのxlwingsを開きInterpreterの欄に

***/Users/ユーザー名/opt/anaconda3/{Anacondaの環境名}/bin/python***を記入します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227613/6c47da8b-89d1-0105-d387-85b0ae4bd7ff.png)

PYTHONPATHは実行した際に自動的に入るので空のままで大丈夫です。

4.ここまでで準備は完了です。ボタンをタップしてください。
A1に***Hello xlwings!***という文字が表示されればpythonのコードが実行できたことになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227613/1d4308ef-dbe0-f8eb-3518-0dad3418db9c.png)

これで、エクセルからPythonコードを実行する雛形作成されました！
Ember.jsでFirebase Authを使う

[Ember.js](https://emberjs.com/)で、FirebaseのAuth機能を使います。

# ソースコード

https://github.com/mk2/ember-firebase-auth-demo

# 流れ

## セットアップ

```sh
# Ember.jsの新規プロジェクト生成
ember new ...
cd ...

# 必要なライブラリをインストール
ember install emberfire@next
ember install ember-simple-auth

# firebaseのセッションストアを作成
ember generate firebase-session-store application
```

## Firebaseプロジェクトの作成

コンソール（ https://console.firebase.google.com/ ）から新規プロジェクトを作成します。そして、ウェブアプリを追加し、その認証情報を https://github.com/firebase/emberfire/blob/master/docs/guide/installation.md#2-configure-firebase を参考に設定します。また、FirebaseコンソールのAuthenticationからGoogleアカウントによる認証を有効化します。

## テンプレートの修正

ログイン出来るかどうかだけみたいので、下記のようなシンプルなテンプレートにします。

https://github.com/mk2/ember-firebase-auth-demo/blob/master/app/templates/application.hbs

```hbs
{{#if session.isAuthenticated}}
  {{ session.data.authenticated.user.displayName }} さん
  <button {{action "logout"}}>Sign out</button>
  {{outlet}}
{{else}}
  <button {{action "login"}}>Google経由でログインしてください</button>
{{/if}}
```

## コントローラーの作成

[emberfireの公式例](https://github.com/firebase/emberfire/blob/master/docs/guide/authentication.md#ember-simple-auth)を見るとRouteでやっているのですが、同じようにやると上手く出来ませんでした。代わりにコントローラーを作成します。

https://github.com/mk2/ember-firebase-auth-demo/blob/master/app/controllers/application.js

```js
import Controller from '@ember/controller';
import { inject as service } from '@ember/service';
import firebase from 'firebase/app';
import { action } from '@ember/object';

export default class ApplicationController extends Controller {
  @service
  session;

  @service
  firebaseApp;

  @action
  logout() {
    return this.session.invalidate();
  }

  @action
  async login() {
    const auth = await this.firebaseApp.auth();
    const provider = new firebase.auth.GoogleAuthProvider();
    const result = await auth.signInWithPopup(provider);
    return result;
  }
}
```

## 実行

```sh
npm run start
```

で開始し、localhost:4200を開きます。

![スクリーンショット 2020-10-07 18.58.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213719/9cccedc5-8ce2-0c52-1d2e-1611d7c8a8de.png)

ボタンが出るので押すと、Googleのログイン画面がポップアップウィンドウで出てきます。そこで許可すると、下記のようにログインすることが出来ます。

![スクリーンショット 2020-10-07 18.59.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213719/0f9aca32-ef2b-f218-7789-7520e741f0b7.png)
HTMLの基本

#概要
HTMLの基本の書き方です。すごく初心者向けです。
タグの使い方、基本的な構造を記述しています。

#HTMLの基本の構造　

```html
<!doctype html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>タイトル</title>
  </head>

  <body>
    <h1>見出し1</h1>
    <p>段落１</p>
  </body>
</html>

```

- < !doctype html >
ドクタイプ宣言といい、そのページがHTMLで、その使用に合わせて作られているのかを示す。



- < HTML > ~ < /HTML >
Doctype宣言のすぐ後に記述する。これはHTMLの文章だということを表している。



- < head > ~ < /head >
ページのタイトルや使用する外部ファイルのリンク(cssやリセットcssなど)、ページの情報を表している。※実際にページには表示されない。



- < meta charset="UTF-8" >
文字のコードを表している。これを正しく記述することによって文字化けを防ぐことができるので、必ず記載する。


- < body > ~ < /body >
HTMLの本体部分。この部分に記述したコードが実際にWebページに表示される。


- < title > ~ < /title >
Webページのタイトルとして表示される部分。


ここまでをテキストエディタに記述してファイルを保存し、開くと真っ白なページが出来上がっています。


#HTMLの基本の記述方法

上記で説明し、作成したページに文字や画像を表示する方法をこちらで詳しく解説します。
実際にWebページに反映されるのは< body >の中なので、< body > ~ < /body >の間に記述します。

- タグ
HTMLでは基本的にこのタグ<>で文字列を囲んで記述する。
開始タグ<>と終了タグ</>で囲う、そのひとつのかたまりを要素と呼ぶ。
※タグには全角文字を使うことはできませんので注意してください。


```html
 <body>
    <h1>見出しをここにインプット</h1>
    <p>ここに文章をインプット</p>
  </body>
```

- < h1 >
ページの見出しを表すタグ。hはHeadingを表しており、< h1 > ~ < h6 >まである。
h1が一番大きな見出し、h6が一番小さな見出しとなる。h1から順番に使う決まりがある。

- < p >
文章の段落を表すタグ。pはParagraphを表している。< p >タグを使うと囲まれた文章がひとつの段落として表示される。

- < img >
画像を表示するタグ。通常のように終了タブがない。文字列を囲まずに使う。
例：　< img src="image.jpg" alt="画像">
src属性は画像の場所を示す。alt属性は画像が何らかの原因で表示されない場合に代わりに表示される文字列を表す。

その他にも様々なタグがありますが、基本的な記述方法がわかると他のタグも使いやすくなると思います。
vueのバージョンアップに躓いた話

## 環境

`macOS Catalina 10.15.7`
`Homebrew 2.5.3`
`npm: 6.14.8`
`yarn: 1.22.10`
`@vue/cli: 3.10.0`


## 経緯

vue3.0 使おうとしたらバージョンあげてくださいと怒られたので
とりあえず

```
$ npm install -g @vue/cli
```

やってみたら以下のwarningが出てバージョンをあげることができなかった ( yarnも同様 )

```
@vue/compiler-sfc@3.0.0 requires a peer of vue@3.0.0 but none is installed. You must install peer dependencies yourself
```

一度uninstallして再度installするとできました。的な記事をみたので試してみても結果変わらず...

## 解決

```
$ rm -rf ~/.npm-global/bin/vue
```

を削除した後に再度

```
$ npm install -g @vue/cli
```

を行ったらバージョンをあげることができた

## まとめ

とりあえずそれっぽいところ消して入れ直すってのは自分が直せる範囲では有効だと思っています

ただ、今回は結局原因がなんだったのかわからず、なんなら正しくバージョンを上げられているのかもわかっていない状態なので
今後は、`npm install`したらどういう処理が動くのか、どこに影響するか、など少しでも理解できれば原因追求できるのかなって感じでした

## p.s.

vue3.0 使ってみたの記事も投稿予定です
ブロックチェーンを一度 生で見る話(2020年12月時点)


一度、生でブロックチェーンを見たらわかることがあります。
ぜひ体験してみましょう。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ブロックチェーンは一度 生で見た方が良い話 <a href="https://t.co/DSVt4f8Vth">pic.twitter.com/DSVt4f8Vth</a></p>&mdash; 山田しいた💦👏😷 (@yamada_theta) <a href="https://twitter.com/yamada_theta/status/1234058849503473670?ref_src=twsrc%5Etfw">March 1, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

Symbol from NEMのブロック生成を監視するスクリプトです。
NEMはREST APIによるWebSocket通信に対応していて、生成されたブロックをリアルタイムで表示させることができます。（一般的にエクスプローラーなどで見るブロックチェーンは第三者サービスがキャッシュしたデータで生のデータではありません）
chromeなどのブラウザでF12キーを押してコンソールを開き、以下のスクリプトをコピペしてみてください。

追記：現在Googleトップページのセキュリティが厳しくなったためscriptの埋め込みが制限されています。適当にノードにアクセスしてそのページでF12コンソールを開いてください。
例：http://api-01.ap-northeast-1.0.10.0.x.symboldev.network:3000/node/info


### script埋め込み
```js
(script = document.createElement('script')).src = 'https://xembook.github.io/nem2-browserify/symbol-sdk-0.22.0.js';
document.getElementsByTagName('head')[0].appendChild(script);
```

### ブロック生成監視
```js
NODE = 'http://api-01.ap-northeast-1.0.10.0.x.symboldev.network:3000';
nem = require("/node_modules/symbol-sdk");
wsEndpoint = NODE.replace('http', 'ws') + "/ws";
nsHttp = new nem.NamespaceHttp(NODE);
listener = new nem.Listener(wsEndpoint,nsHttp,WebSocket);
listener.open().then(() => {
   listener.newBlock().subscribe(x=>console.log(x))
});
```

> Promise {\<pending>}

と表示されたら成功です。

これで30秒に1度ぐらいのペースで新しく生成されたブロックが表示されるようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29187/29aa876b-02f5-37e0-32d5-670c470d2987.png)
python 標準搭載 仮想環境 venv

# 前提環境

* Windows10 64bit
* python3.8.2

# venv

* [python公式サイト](https://docs.python.org/ja/dev/tutorial/venv.html)

python3.5から標準搭載になった仮想環境。他の入れなくていいので純正嬉しい。
残念ながらpythonのバージョン指定はできず、インストールされているpythonのバージョンが利用される。
ライブラリの切り替えに使える。

#### コンソール

Windows向けとしてはcmd用のbatとpowershell用のps1があり、cmdで試した。
**pipでライブラリ追加時に管理者権限必要なのでcmdは管理者権限で開くこと**

### 仮想環境作成

python -m venv [環境名]

```console
D:\work> python -m venv mytestenv
```

```:仮想環境のフォルダ構成(※一部省略)
mytestenv・・・環境名のフォルダができる
+ Scripts
  + activate
  + activate.bat・・・Windows向け
  + Activate.ps1・・・Windows向け
  + django-admin.exe
  + django-admin.py
  + pip.exe
  + python.exe
+ Lib
  + site-packages・・・ライブラリ追加したらここに入る
+ Include
```

### 仮想環境に切り替え

[環境名]\Scripts\activate.bat

```console
D:\work> mytestenv\Scripts\activate.bat
```

```console:切り替わった状態
(mytestenv) D:\work>
```

```console:試しにライブラリ追加
(mytestenv) D:\work>pip list
Package    Version
---------- -------
pip        19.2.3
setuptools 41.2.0

(mytestenv) D:\work>pip install numpy
Collecting numpy
  Using cached https://files.pythonhosted.org/packages/69/89/d8fc61a51ded540bd4b8859510b4ae44a0762c8b61dd81eb2c36f5e853ef/numpy-1.19.2-cp38-cp38-win_amd64.whl
Installing collected packages: numpy
Successfully installed numpy-1.19.2

(mytestenv) D:\work>pip list
Package    Version
---------- -------
numpy      1.19.2
pip        19.2.3
setuptools 41.2.0
```

# その他仮想環境

いろいろあるけど、使いそうなものだけ。

|仮想環境|サイト|
|---|---|
|venv|https://docs.python.org/ja/dev/tutorial/venv.html|
|virtualenv|https://github.com/pypa/virtualenv|
|pipenv|https://github.com/pypa/pipenv|

# おわりに

pythonバージョンを複数管理したいので
pipenvにチャレンジしてみる。

# おまけ

ps1はスクリプト実行に関するセキュリティエラーが出た。(これは別途試してみる)

```console:powershell
D:\work> mytestenv\Scripts\Activate.ps1
mytestenv\Scripts\Activate.ps1 :このシステムではスクリプトの実行が無効になっているため、ファイル D:\work\mytestenv\Scr
ipts\Activate.ps1 を読み込むことができません。詳細については、「about_Execution_Policies」(https://go.microsoft.com/fwl
ink/?LinkID=135170) を参照してください。
発生場所 行:1 文字:1
+ mytestenv\Scripts\Activate.ps1
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : セキュリティ エラー: (: ) []、PSSecurityException
    + FullyQualifiedErrorId : UnauthorizedAccess
```
PyTorch で conv2d + padding='same' 相当を行うメモ

pytorch で, numpy や tensorflow などでの padding='same'(名前がややこしいが, 畳み込んだ結果が入力画像と同じサイズになる)で畳み込み処理したい.

https://discuss.pytorch.org/t/same-convolution-in-pytorch/19937

https://discuss.pytorch.org/t/same-padding-equivalent-in-pytorch/85121


PyTorch 自体には, padding='same' 自体はないため, それ相当を自前で行うか, 上下左右の padding 幅が変わらないのであれば, 最近(少なくとも v1.6.0)では, Conv2d に padding 引数と, padding_mode を指定で対応できます. e.g.


```
conv = torch.nn.Conv2d(1, 1, kernel_size, padding=[kernel_size[1]//2, kernel_size[0] // 2], bias=False, padding_mode='replicate')
```

padding の幅は, kernel width size や stride などから自前で計算する必要があります.
discuss にあるように, 奇数の kernel 幅であれば `kernel_width//2` で求まります.
 
`padding_mode` は, デフォルトの `"zeros"` だと, 端っこの結果が暗くなるので注意ください.
`replicate` or `reflection` あたりを指定がよいかと思います.
【Metal】Metalを使ってレンダリングするまでの流れを図にしてみた

Metalでシェーダーからレンダリングしようとすると、たくさんの処理を書く必要があります。

たいていは同じような処理だったりするのでそのままコピーすれば動きますが、１つ１つの処理が何をしているのか忘れてしまうことも多いです。

そこで、処理の流れを思い出しやすいように図に描いてみました。
大きな図になってしまったので見辛いかもしれませんが、拡大するなどして参照してみて下さい。
Metalを習得するときなども、この図が傍らにあると理解しやすいかもしれません。

**＜Metalでシェーダーを使った場合のレンダリングの流れ＞**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116010/0c49ddc1-d153-aa14-146a-948910691fca.png)

参考資料：
[Metal入門](https://booth.pm/ja/items/826318)
<img width="200px" src="https://booth.pximg.net/74c0c65b-cd71-4b0d-9263-f3095f3e17a0/i/826318/381e8253-f80e-44a4-bf13-254e1af1fdf4_base_resized.jpg">
github 検索 ブランチ指定 タグ指定

#githubの左上の検索の話
以下の赤枠でタグを指定して、検索したいと思い、オプションを調べたところ、公式に、、、
![スクリーンショット 2020-10-07 18.06.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624073/92f6bd83-29a5-c7dc-b232-bc059e81babd.png)

「「「<a href="https://docs.github.com/ja/free-pro-team@latest/github/searching-for-information-on-github/searching-code#%E3%82%B3%E3%83%BC%E3%83%89%E6%A4%9C%E7%B4%A2%E3%81%A7%E3%81%AE%E7%95%99%E6%84%8F%E7%82%B9">コード検索では、デフォルトブランチのみインデックスされます。</a>」」」

との記述があり、できないそうです、、(タグ指定の方法知ってる方いらしたら教えてください)

#解決策
少し面倒ですが、、、
調べたいリポジトリのタグをclone
ローカルで`grep "調べたい文字" -rl .`
プログラミング講師が最低限取っておくといい資格試験一覧　


コロナウイルスの影響もあり、プログラマになりたいという人が多く現れ、必然的にプログラミング講師の需要は高まりました。

そこで今回は今からプログラミング講師になろうとしている方、既にプログラミング講師をされている方向けに、プログラミング講師が最低限取っておくといい資格試験を紹介します。

#国家資格
##ITパスポート

ITパスポートは「備えておくべきITに関する基礎的な知識が証明できる国家試験」をスローガンに実施されている試験です。

大学の授業などでよく取得することを推奨されています。

基本的にITに関する基礎知識を出題しており、経営全般・IT管理・IT技術と比較的幅広い範囲が試験内容になっています。

試験自体は毎月各都道府県で実施されており、すぐに受験することができます。

<a href="https://www.jitec.ipa.go.jp/1_11seido/ip.html" target="_blank">ITパスポート詳細</a>

##基本情報技術者

基本情報技術者試験はこれこそエンジニアの基礎と言われる試験です。

対象者像として「高度IT人材となるために必要な基本的知識・技能を持ち、実践的な活用能力を身に付けた者」とされており、ITパスポートよりも難易度が上がる試験です。

ITパスポートは簡単にいえばエンジニアになる為の準備、基本情報技術者はエンジニアの基礎に立つといったイメージでしょうか。

試験ではアルゴリズムやプログラミング、ネットワークやセキュリティなど、より専門的な知識が幅広く必要になります。

生半可で合格することは中々難しい為、そこそこの勉強が必要になります。

<a href="https://www.jitec.ipa.go.jp/1_11seido/fe.html" target="_blank">基本情報技術者試験詳細</a>

##応用情報技術者

応用情報技術者試験はその名の通り、基本情報技術者試験より上位の応用的な内容が問われる試験です。

対象者像として「高度IT人材となるために必要な応用的知識・技能をもち、高度IT人材としての方向性を確立した者」とされており、もちろん応用なので基本情報技術者試験よりも難易度が上がります。

これまでのテクノロジ系に加えてマネジメント系・ストラテジ系分野が追加されている為、より広範囲の知識が問われます。

しかし、応用情報技術者試験は基本情報技術者試験を受けずとも、いきなり受験することが可能です。

基本は抑えているから応用受ける！ということが可能なのです。

自身がある方はいきなり受けてみるのも一つかもしれません。

<a href="https://www.jitec.ipa.go.jp/1_11seido/ap.html" target="_blank">応用情報技術者試験詳細</a>

#民間資格

##オラクルマスター

オラクルマスター試験は日本オラクル社が公式に運営するデータベースに関する技術力を認定する資格です。

試験ではデータベースの管理・運用、SQLを問う問題が出題されます。

オラクルマスターにはグレードが存在し、ブロンズ・シルバー・ゴールド・プラチナと難しくなっていきます。

シルバー以上を持っていると、日頃から運用・管理をしているのだなと思われるイメージです。

基礎はすでにわかっているという方はシルバーから受けるのがいいかもしれません。

<a href="https://www.oracle.com/jp/education/certification/examlist-172597-ja.html" target="_blank">オラクルマスター詳細</a>

##情報処理技術者能力認定試験

情報処理技術者能力認定試験は株式会社サーティファイが実施している「システム・エンジニアやプログラマに求められるコンピュータシステムの基礎知識と、プログラミング能力を測定する認定試験」です。

試験はレベル別に分けられており、1級・2級・３級と分かれています。

３級が学生向けで、２級が基礎、３級が中級者を主な対象としています。

上記で挙げた試験ほどメジャーではありませんが、スキルの証明にはいい試験です。

<a href="https://www.sikaku.gr.jp/js/jss/" target="_blank">情報処理技術者能力認定試験詳細</a>

#宣伝

##プログラミング講師検定

弊社はプログラミング講師向けの試験を開設しました。

プログラミング講師のレベルを証明する為の検定試験です。

プログラミング講師だけでなく、企業の研修担当者やプログラミング教育を指導する教育機関関係の方々にも受験していただけます。

一次試験では、基礎知識問題としてIT知識と講師知識問題、専門知識問題が出題されます。

二次試験では、面談を行い講師としての適性があるか、知識があることと教えることは別であることを理解しているかをみます。

プログラミング講師検定では本試験申し込みを開始していますので、是非ご利用ください。

<a href="https://pro-ken.jp/" target="_blank">プログラミング講師検定</a>

#まとめ

以上、プログラミング講師が最低限取っておくといい資格試験を紹介しました。

最後に宣伝も挟みましたが、プログラミング講師には最適の試験ですので是非ご検討ください。

最低限の試験の紹介なので基本メジャーで基礎的な試験を紹介しましたが、エンジニアの試験は他にもたくさんあります。

さらに上を目指したい方などは調べてみてください。
【Rubocop】Use 2 (not 1) spaces for indentation.を解決する

Rubocopを導入しエラーを解決していく中で、下記のエラーが結構な数出てました。
「Use 2 (not 1) spaces for indentation.」

調べても日本語の解説記事がほとんどなかったので、備忘録として残してみます。
間違っている点等あれば、ご指摘いただければと思います。

ちなみに、Rubocopの自動修正は効かなかった＼(^o^)／

## 環境
MacOS Catalina
Rails 6.0.3.2
Ruby 2.6.3

## Use 2 (not 1) spaces for indentation.とは
Google翻訳にかけてみると、下記のような感じ。
「インデントには2つ（1つではなく）のスペースを使用します。」
つまり、インデントを２つ空けろってことかな？

## 該当のエラー行
```ruby　
app/controllers/messages_controller.rb:2:1: C: Use 2 (not 1) spaces for indentation.
	before_action :set_room, only: [:create, :destroy]
^
app/controllers/messages_controller.rb:6:2: C: Use 2 (not 1) spaces for indentation.
		if Entry.where(user_id: current_user.id, room_id: @room.id)
 ^
app/controllers/messages_controller.rb:7:3: C: Use 2 (not 1) spaces for indentation.
			@message = Message.create(message_params)
  ^
```

パッと見問題なさそうに見えるんだけど、スペースが1つ空いていると言えば空いてるなぁ。
もっと他にも同じような行あるんだけどなぁ。。。

例えば、下記の行では何故か上の行だけ怒られてる。

```ruby　
	before_action :set_room, only: [:create, :destroy]
	before_action :set_message, only: [:destroy]
```

謎 of 謎。

## 修正してみる
before

```ruby　
	before_action :set_room, only: [:create, :destroy]
```

after

```ruby　
	before_action :set_room, only: [:create,  :destroy]
```

直してみるとエラーの数が減った・・・違和感あるけどこれ何かおかしくね？？
元に戻してみた結果→エラーが更に減る（笑）

でもエラーが減ったのは該当行ではなく別のエラーみたい。
うーんなぜ減ったのかも分からんし何が正解なんだ。。。

よくよく見るとエラーが出ているのが全て同じファイル内なので、
このファイル特有の問題がなにかあると予想。

# 解決できた
結論は、「エラーが出ているファイルだけタブでインデントしていた」です。
VSCODEでスペースインデントに変更することで、エラーが消えました。
![スクリーンショット 2020-10-07 18.01.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682425/96084fe4-c114-a53b-9a60-31efb6bdda6b.png)
なぜこのファイルだけ違ったのかは分からんが・・・。

# 終わりに
凡ミスでしたが、エラーメッセージに惑わされてなかなか生活にたどり着けませんでした。
同じように悩んでいる方の役に立てば幸いです！
heroku デプロイ後のアプリ更新反映

1 変更をステージングする

```
> git add -A  #-A は変更を加えた全ての変更をステージングさせる
もしくは、
> git add 特定のファイル名  
```

2ステージングした変更をコミットする

```
> git commit -m "コメント"
```

3 コミットした変更をHeroku上のアプリにPushする

```
> git push heroku master
```

4 migrate 

```
$ heroku run rake db:migrate
#seedも更新する場合は
$ heroku run rake db:seed
```
【LINE】数MB画像を約600KBまで簡単に圧縮する方法

# 目標
短時間かつ安全に数MB画像を約600KBまで圧縮を行う。

# 流れ
1 LINEのグループを作成する（誰も招待しなくてOK）
2 画像をそのまま送信
3 送信した画像を選択しカメラロールに保存
4 共有（下記のような方法であれば圧縮されないかと思います）
　iphone Mac であればairdrop
　android であれば周辺ユーザーとの共有
　windows であればBluetoothによるワイヤレスファイル転送
　クラウドストレージを活用（GoogleDrive、DropBoxなど）


# まとめ
昨今様々なオンラインでの画像圧縮がありますが、
初めて使うサイトのため、セキュリチィ面での不安がある方もいらっしゃるかと思います。
しかしlineであれば皆さんよく使っているので安心して使用できるかと思い記事にしました。
また撮った写真を相手に普通に送れば、
同様に画像が圧縮され、多少なりとも画質が落ちるため、
iphoneユーザーであればairdropをおすすめします。

またtwitterではQiitaにはアップしていない技術や考え方もアップしていますので、
よければフォローして頂けると嬉しいです。
詳しくはこちら　https://twitter.com/japwork
【Swift】SwiftUIでColorをUserDefaultsに保存(メモ) 

SwiftUI使用時ColorをUserDefaultsに保存する実装メモ

#環境
- Xcode: 12.0
- Swift5

#実装例
Color→cgColor→RGB値にして保存

```Swift
        let userDefaults = UserDefaults.standard
        let color = Color.orange
        if let components = color.cgColor?.components {
            userDefaults.setValue(components[0], forKey: "RColor")
            userDefaults.setValue(components[1], forKey: "GColor")
            userDefaults.setValue(components[2], forKey: "BColor")
        }
```

使用時はUserDefaultsからDouble型で値を取り出し、
以下のようにRGBからColorを生成するだけ

```Swift
let color = Color(.sRGB, red: RColor, green: GColor, blue: BColor, opacity: 1.0)
```
AWS S3から画像をダウンロードする方法（rails,carrierwave）

環境
ruby2.6.5
rails5.2.4
gem 'carrierwave'
gem 'fog-aws'
##ステップ1　日本語のファイル名をやめよう
投稿されたファイル名に日本語が含まれている場合、その後の処理が難しくなります。gem 'carrierwave'では、公式にもある通り、ファイル名を変更することができますので、まずそこから始めましょう。
私の場合は、ファイル名をランダム英数字で保存することにしました。保存する時に現在時刻を使用するのはやめましょう。リサイズする時に時刻がずれてしまい、エラーがおきます。

```ruby:image_uploader.rb

  def filename
    "#{secure_token}.#{file.extension}" if original_filename.present?
  end

  def secure_token
    var = :"@#{mounted_as}_secure_token"
    model.instance_variable_get(var) or model.instance_variable_set(var, SecureRandom.uuid)
  end
```
このように記述することで投稿されたファイル名はランダム英数字で保存されます。filenameのみでは、ファイル名は変更されるものの、S3へのアクセスがうまくいきませんでしたが、def secure_tokenを追加で記述することにより解決されました。

##ステップ２　ルーティングを設定

```ruby:routes.rb
  resources :posts do
    member do
      get :download
    end
  end
```
##ステップ3　controllerにダウンロードメソッドを記述しよう
  ```ruby:posts_controller.rb

  def download
    url = URI.encode(@post.image.url)
    data_path = open(url)
    send_data data_path.read, disposition: 'attachment',
    type: @post.image_type
  end
```
私のレベルは初学者レベルなので記述に無駄はあると思いますがご容赦ください。

## 遭遇したエラーと解決まで
最初にファイル名に日本語名が含まれていた時には、アップロードする分には何も問題はありませんでした。しかし、いざダウンロードメソッドを記述してダウンロードしようとすると、502 access deniedが表示されました。この502が厄介で、最初はAWSへのアクセス権限がないのかと思いましたが、アップロードできているのならば、アクセス権限はあるはずです。さらに調べていくと、URLが見つからない場合も502が表示されることがわかり,
さらに日本語表記が原因であることがわかりました。画像投稿サイトでもダウンロードする際には、ランダム英数字のファイルになっていることが多かったのは、このような理由だったのでしょう。
モギモギ解説 その１

## 2 番目に大きい整数 (The Second Largest Integer)

if文でかくと鬼のように難しいです。

```cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int a,b,c;
  cin >> a >> b >> c;
  if(a <= b && b <= c) {
    cout << b << endl;
  } else if(c <= b && b <= a) {
    cout << b << endl;
  } else if(b <= a && a <= c) {
    cout << a << endl;
  } else if(c <= a && a <= b) {
    cout << a << endl;
  } else if(a <= c && c <= b) {
    cout << c << endl;
  } else if(b <= c && c <= a) {
    cout << c << endl;
  }
}
```

配列を使ってソートするのが一番スムーズなやり方ですね。

```cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  vector<int> a(3);
  cin >> a.at(0) >> a.at(1) >> a.at(2);
  sort(a.begin(), a.end());
  cout << a.at(1) << endl;
}
```

## Number of Multiples

for文でもシミュレーションしてもできますが、以下のように『R以下のdの倍数の数』から『L未満のdの倍数の数』を引くことで簡単に求められます。

```cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int L, R, d;
  cin >> L >> R >> d;
  cout << R/d - (L-1)/d << endl;
}
```

## Buying Sweets

こちらも2番目同様にfor文でシミュレーションせずとも、以下のように『XからAを引いた値をBで割ったあまり』を求めることで答えになります。

```cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int X, A, B;
  cin >> X >> A >> B;
  cout << (X-A) % B << endl;
}
```

## 母音を数える (Counting Vowels)

条件に合致したものを数えるのみです。

```cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int n;
  string s;
  cin >> n >> s;
  
  // 答えを格納する変数
  int ans = 0;

  for(char c: s) {
    if(c == 'a' ||c == 'i' ||c == 'u' ||c == 'e' ||c == 'o') {
      // 当てはまる度にインクリメント
      ans++;
    }
  }

  cout << ans << endl;
}
```

## JOI ソート (JOI Sort)

ちょっと難しいです。
Jの出た回数、Iの出た回数、Oの出た回数をカウントして、その後、それぞれの回数分だけそれぞれの文字を出力しましょう！

```cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int n;
  string s;
  cin >> n >> s;
  int ansJ = 0; // Jの出た回数
  int ansO = 0; // Oの出た回数
  int ansI = 0; // Iの出た回数
  for(char c: s) {
    if(c == 'J') ansJ++;
    if(c == 'O') ansO++;
    if(c == 'I') ansI++;
  }

  // Jの出た回数だけJを表示
  for(int i=0; i<ansJ; i++) {
    cout << 'J';
  }

  // Oの出た回数だけOを表示
  for(int i=0; i<ansO; i++) {
    cout << 'O';
  }

  // Iの出た回数だけIを表示
  for(int i=0; i<ansI; i++) {
    cout << 'I';
  }
  cout << endl;
}
```

## 共通要素 (Common Elements)

これはbool型のvectorを使うことで二重for文を使わず実装可能です。

```cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int n, m;
  cin >> n >> m;
  
  // bool型のvewctorを用意(初期値を指定していないので全てfalse)
  vector<bool> a(101);
  vector<bool> b(101);

  for(int i=0; i<n; i++) {
    int x;
    cin >> x;
    // 長さnの配列にxが存在することを示すためaのx番目をtrueにする。
    a.at(x) = true;
  }
  for(int i=0; i<m; i++) {
    int x;
    cin >> x;
    // 長さnの配列と長さmの配列とxが存在することを示すためaのx番目にaの中身をいれる
    b.at(x) = a.at(x);
  }

  // 長さnの配列と長さmの配列のいずれにも存在する値を小さい順に探して、見つけたら表示。
  for(int i=0; i<=100; i++) {
    if(b.at(i)) cout << i << endl;
  }
}
```
インスペクション(Inspection)


応用情報技術者平成28年春期 午前49


作業成果物の作成者以外の参加者がモデレータとして主導すること，並びに公式な記録及び分析を行うことが特徴のレビュー技法はどれか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/c5895647-8850-54d3-14c1-6e7d9f443a5b.png)

１、インスペクション(Inspection)は、
事前に役割を決められた参加者が責任のある第三者(モデレータ)の下で成果物を確認する、最も公式なレビュー技法です。通常3人から6人が参加して実施します。

他のレビュー法との違いは、参加者の役割が明確になっていること、チェックリストなど形式的な文書に基づいて実施すること、正式な記録を強調することです。

インスペクションの参加者に割り振られる役割には以下の5種類があります。

・モデレータ(Moderator)
　議長・司会としてインスペクション全体を運営する

・オーナー(Owner)
　レビュー対象となる成果物の作成者で、発見された問題に応じて成果物の修正を行う

・インスペクタ(Inspector)
　評価者としてレビュー対象となる成果物の問題発見を行う

・プレゼンタ(Presenter)
　ミーティングにて参加者に資料の説明を行う

・スクライブ(Scribe)
　書記としてレビューで発見された問題などを記録する


２、
・ウォークスルー
　→×。ウォークスルーは、開発者が主体となりエラーの早期発見を目的としてプログラムのステップごとにシミュレーションを行いながら確認をしていくレビュー技法です。

※シミュレーション：予測・設計・計画策定などのために、現実のモデルを作り、それを使って観測または実験すること。

・パスアラウンド　pass around
　→×。パスアラウンドは、電子メールなどを使って、対象の成果物を複数のレビュアに配布・回覧し、フィードバックを求めるレビュー技法です。

・ペアプログラミング
　→×。ペアプログラミングは、二人一組で実装を行い、一人が実際のコードをコンピュータに打ち込み、もう一人はそれをチェックしながら補佐するという役割を随時交代しながら開発作業を進める手法です。


参照：
https://www.ap-siken.com/kakomon/28_haru/q49.html
スマホコーディングにおいて、vwとvhをデザイン幅に沿ってピクセルから自動換算するためのscss


デザインファイルが
横幅750px縦は1334pxだという想定で、
縦横のマージンをvh
横のマージンをvw
でピクセルから換算するscssです。

サイズに関してはデザインファイルをみて値を調整してね。

unitというのはピクセル単位のことで定義は
-100から100を５ピクセル毎で、定義しているよ☆

```_variable.scss
$units  : -100,-95,-90,-85,-80,-75,-70,-65,-60,-55,-50,-45,-40,-35,-30,-25,-20,-15,-10,-5,0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100;
```

それを召喚してvhとvwに変換

```_margin.scss
@each $unit in $units {
    .sp-mt#{$unit}{
      margin-top: #{decimal-round(($unit / 13.34),3)}vh!important;
    }
    .sp-mb#{$unit}{
      margin-bottom: #{decimal-round(($unit / 13.34),3)}vh!important;
    }
    .sp-mr#{$unit}{
      margin-right: #{decimal-round(($unit / 7.5),3)}vw!important;
    }
    .sp-ml#{$unit}{
      margin-left: #{decimal-round(($unit / 7.5),3)}vw!important;
    }
}
```

小数点以下3桁で切るのに関数も使っている、引用元忘れました。。。すみません

```_fuctions.scss
@function decimal-round($number, $digits: 0, $mode: round) {
  $n: 1;
  @if type-of($number) != number {
    @warn '#{ $number } is not a number.';
    @return $number;
  }
  @if type-of($digits) != number {
    @warn '#{ $digits } is not a number.';
    @return $number;
  } @else if not unitless($digits) {
    @warn '#{ $digits } has a unit.';
    @return $number;
  }
  @if $digits > 0 {
    @for $i from 1 through $digits {
      $n: $n * 10;
    }
  }
  @if $mode == round {
    @return round($number * $n) / $n;
  } @else if $mode == ceil {
    @return ceil($number * $n) / $n;
  } @else if $mode == floor {
    @return floor($number * $n) / $n;
  } @else {
    @warn '#{ $mode } is undefined keyword.';
    @return $number;
  }
}

@function decimal-ceil($number, $digits: 0) {
  @return decimal-round($number, $digits, ceil);
}

@function decimal-floor($number, $digits: 0) {
  @return decimal-round($number, $digits, floor);
}
```



これでデザインファイル通りに
.sp-mt30
とすれば総体的な空きができるのことです。

ネガティブマージンの場合は
.sp-mt-30
とかって表現できる。

vwはわりと見かけるけどvhはあんまりなかったので投稿してみました。
自作サービスを動かしてみたら失敗したのでタスクスケジューラにねじ込んだ話

Oracle HTTP Server 12cをサーバの再起動にあわせて毎度手動で起動するのが面倒だったので、自動実行できないかと考えたのが始まりです。

# ねじ込んだ理由
・「Oracle HTTP Server 12c」が乗っているサーバを利用している
・サーバが再起動するたびに、HTTPを起動させるのが面倒臭い…
　→サーバ起動時に自動でHTTPを立ち上げるようにしよう！
・サービスを作成して自動実行に設定できた…！
　→サービスの状態「　」。
・タスクスケジューラでいけるのでは？

# 作成したサービス
・Oracle HTTP Server 12c を起動する際に必要なNodeManagerを起動するサービス
・Oracle HTTP Server 12c 本体を起動するサービス

# 全体の流れ
1. サービスの作成と自動設定
本来HTTPを起動するためには、NodeManagerの起動→HttpServerの起動という手順を踏みます。
これらを実行するサービスを作成します。

2. 1.が失敗したのでサーバ起動時にサービスを実行するようタスクスケジューラを設定

## サービスの作成
作ったはいいですが、実行に失敗したのでざっくりと。
基本は、
「javaのクラスファイルを作成→→exeファイルを作成→サービス登録」
という流れになります。

#### ファイルの作成
（javaのクラスファイルとexeファイル作成は割愛します。）
サービスの登録にあたり、exeファイルと同じ場所にxmlファイルが必要になります。
xmlの詳細は以下の通りです。
```
<service>
  <id>OracleHttpStartBat</id>
  <name>OracleHttpStartBat</name>
  <description>This service start OHS.</description>
  <executable>java</executable>
  <arguments>-jar "OracleHttpStartBat.jar"</arguments>
  <logmode>rotate</logmode>
</service> 
```
上からサービスのID、サービス名、概要、実行言語、引数、ログ形式、となります。

xml作成後、同じパス上でコマンドプロンプトを開き、以下を実行してください。
```(OracleHttpStartBat.exe) install```
簡単ですが、これでサービスの登録は完了です。
これで自動起動に設定しておけば、サービスは自動実行されます。
たぶん。

参考URL
https://qiita.com/moni-hide/items/fd26fb223f2d4736cf55

## スケジュールアシスタント設定
上のサービスの件がうまくいかなかったので、こっちで実行しました。
こちらはかなり操作が簡単です。
サーバ内のスケジュールアシスタントを起動します。
以下のものを指定してほぼ完了です。（詳細はプロパティで編集できます。）
1.タスクの名称
2.トリガー（実行タイミング、間隔、開始日時の設定）
　今回はユーザーのログオン時を指定。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605483/e6a24727-41bd-41d2-be6e-50dadf7c654c.png)

3.操作（実行するプログラムの設定）
　今回は対象バッチファイルの実行。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605483/cbd871e7-d8d5-109b-85c9-fed231e094bc.png)

プログラムを実行する際は、バッチファイルを作っておきましょう。
こっちの方法だと正常にHTTPが起動できました…
ThingWorx REST API クイックメモ

#はじめに

この記事では、ThingWorx へ REST API を用いてアクセスし、Thing の持つプロパティの値を読み書きしたり、サービスを呼び出したりする方法を説明します。

##対象読者

この記事は、ThingWorx を用いた開発の基礎知識を有していることを前提として書かれています。また、REST API の基本的な知識も必要です。

##対象バージョン

この記事は、ThingWorx 8.x および 9.x を対象に書かれています。

# REST API 基礎

##対応しているメソッド

Thing の持つプロパティの値を読み出すには、GET メソッドを使います。プロパティに値をセットするには、PUT を使用します。ただし、リモート・バインドやローカル・バインドされているプロパティに値を書き込むことはできません。

##必要なリクエスト・ヘッダ

RET API 発行時、下記のヘッダを積んでおく必要があります。

**Content-type**
Content-type ヘッダには `application/json` をセットします。

**Accept**

Accept ヘッダには受け取りたいデータのメディアタイプを指定します。8.x 以降、下記が使用可能です。

- text/xml
- application/json

また、9.x 以降は下記も可能です。

- text/html
- text/csv

##認証

ThingWorx へ REST でアクセスする際には、Application Key と呼ばれるセキュリティ・トークンを使うと便利です。通常の BASIC 認証も対応していますし、SSO が構成されている場合にはその他の認証方法も選択可能ですが、パスワードをプログラムでどのように扱うかなどの問題を避けるために Application key を使うことをお勧めします。

Application Key を使うには、リクエストヘッダに `appKey` を追加します。appKey の値は、ThingWorx コンポーザーで作成した Application Key の値です。

全体として、下記のようなリクエストヘッダになっていれば十分です。

**認証関連ヘッダ**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119047/e89ddd62-596c-87b3-7aa1-f206cf8d8a8d.png)

**その他ヘッダ**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119047/634b634f-abbd-5456-8d1f-250d83d4e374.png)


# REST API エンドポイント

ThingWorx の REST API については、完全なガイドがヘルプセンターにあります。
ThingWorx 9 のヘルプセンターは[こちら](http://support.ptc.com/help/thingworx/platform/r9/en/#page/ThingWorx%2FHelp%2FREST_API%2FThingWorxRESTAPI.html%23)からアクセスできます。

## Things

よく使うのは、やはり Thing の持つプロパティの値へのアクセスでしょう。

**`Thingworx/Things`**
すべての Thing の一覧が得られます。注意すべきことは、指定した Application Key が紐付けられているユーザーの権限において、閲覧可能な Thing に限られる、ということです。Application Key の権限では見えない Thing は応答に含まれません。

**`Thingworx/Things/{Thing名}/Properties/{プロパティ名}`**
個別の Thing の、個別のプロパティの値を読み書きします。読み出す場合は GET メソッドを、書き込む場合は PUT メソッドを使用します。PUT メソッドでは、プロパティ名とその値を JSON 形式で、リクエストボディに記載します。

下記はブラウザから `ThingWorx/Things/{Thing名}/Properties` へアクセスして、Thing の持つプロパティを一覧させたところです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119047/b798bba1-b72e-47b7-6c6b-c35eb2a85940.png)

つづいて、プロパティ `PumpBPower` の値を読み取るべく、`ThingWorx/Things/{Thing名}/Properties/PumpBPower` を GET してみます。ブラウザに次のように表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119047/4f141e25-02a4-2796-ad69-1ecb67480f35.png)

Postman での実行では、次のようにレスポンスを確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119047/865707a1-335a-f5c9-7e4a-63c9760140fe.png) 

**`Thingworx/Things/{Thing名}/Services/{サービス名}`**
Thing名に指定した Thing のサービスを起動します。サービスに入力パラメータがある場合には、POST のボディに JSON 形式で記述します。

下記は、`SayHello` という名前のカスタムサービスを Postman で呼び出しているところです。`SayHello` サービスは "Hello, things!" という文字列を返すだけの単純なサービスです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119047/35d4e35d-10db-bcae-601f-313a06ac377d.png)


#その他

上記に簡単に説明した Thing のプロパティ値の読み書きやサービス起動の他にも、ログを読み出したりユーザーやグループの情報をリストしたりなど、REST API を使うと ThingWorx を外部から便利に使えます。詳細の情報は上記に紹介した ThingWorx のヘルプセンターを参照してください。
WPFハイパーリンクからWEBブラウザに遷移する

Hyperlinkタグに「RequestNavigate = "Hyperlink_RequestNavigate"」を入れる




```xaml:hyperlink.xaml
<TextBlock>           
    <Hyperlink NavigateUri = "https://www.yahoo.co.jp/"
               RequestNavigate = "Hyperlink_RequestNavigate">
        こちら
    </Hyperlink>
</TextBlock>
```



参考:
https://www.366service.com/jp/qa/be8bff473a3a9f570c9a7021e8a00922
【Mac】AppStoreでSlackをアップデートしたら「A JavaScript error occurred in ...」エラーが出て起動出来なくなった 

## 2020/10/7午後 追記
再度調べてみると[slack status](https://status.slack.com/2020-10/85b15afeaf6954f8)でアナウンスが行われていました。
現在調査中で[WEBサイト](https://slack.com/downloads/mac)から直接ダウンロードを行って欲しいとの事なので、できる限り公式を参照ください。

## なにが起こったか
AppStoreを覗くとSlackのアップデート通知が来ていた為、アップデートを行うと添付のエラーが出て起動が出来なくなった。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323216/0ea3dabb-0875-4f49-2dcc-58106b39f772.png" width=50%>

## 筆者の環境
マシン：MacBook Pro
OS：macOS Mojave バージョン 10.14.6

## やってみたて無駄だったこと
・Mac内のアプリケーションフォルダから削除し、AppStoreからSlack再インストール

## 解決方法
[App Cleaner](https://freemacsoft.net/appcleaner/)を使用し、添付ファイルのような関連ファイルも削除後、AppStoreからSlack再インストール
<font color="Red">※ 再インストール後はログアウトされ環境設定も削除される為、アカウント情報などは事前に保持する事をお勧めします。</font>

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323216/b413117e-06ec-d1b0-80c2-7c6624b984e4.png" width=50%>

### 削除した関連ファイル
 - Slack.app
 - com.tinyspeak.slackmacgap
 - com.tinyspeak.slackmacgap
 - com.tinyspeak.slackmacgap.bom
 - com.tinyspeak.slackmacgap.plist

## 終わりに
OSやパッケージのバージョンだけではなくソフトウェアのアップデートも場合によっては、開発作業などに被害が出ることを実感しました。
今回はSlackだったので、appが使えなくてもブラウザから操作が出来たのでまだマシですね。
アップデートタイミングには気をつけます。
Node.js: stream.Readableを全部読み込む方法

この投稿では、Node.jsの`stream.Readable`の内容を全部読み込む方法を紹介します。

## stream.Readableを全部読み込む方法

`for await`を使う方法がシンプルです。

```js
const { Readable } = require('stream')
const stream = Readable.from(['hello', 'world'])

async function readAll(stream) {
  let data = ''
  for await (const chunk of stream) {
    data += chunk
  }
  return data
}

readAll(stream).then(console.log)
//=> "helloworld"
```

## イベント駆動なコード

よく見かける方法として、`Readable`の`"data"`イベントを使うコードがあります:

```js
const { Readable } = require('stream')
const stream = Readable.from(['hello', 'world'])

function readAll(stream) {
  return new Promise(resolve => {
    let data = ''
    stream.on('data', chunk => {
      data += chunk
    })
    stream.on('end', () => resolve(data))
  })
}

readAll(stream).then(console.log)
//=> "helloworld"
```

これでも同じ結果が得られますが、`for await`を使ったほうが個人的に読みやすいと思います。

## 関連記事

* [Node.js: stream.Readableを作るシンプルな方法 - Qiita](https://qiita.com/suin/items/b606ff841f5b82189cd3)
Unityで作ったAndroidアプリが覚えのないネットワークアクセス権限を要求してくる

# 前提
- Unity 2019.4.11f1 (LTS)

# 課題
- ネットワークにアクセスするような処理を書いたつもりがないのに、関係の権限が要求されます。
    - `WWW`、`UnityWebRequest`、`HttpWebRequest`とかは使用していません。

# 要求された権限
- `android.permission.ACCESS_NETWORK_STATE`
- `android.permission.CHANGE_WIFI_MULTICAST_STATE`
- `android.permission.INTERNET`

※必要な権限として表示されるだけで、ユーザの許可が求められるわけではありません。

# 対処
- Package Manager で、不要なパッケージを削除したところ、要求されなくなりました。
    - `Advertisement` ～ [Unity Ads](https://docs.unity3d.com/ja/current/Manual/UnityAds.html) (マニュアル)
    - `Analytics Library` ～ [Unity Analytics](https://docs.unity3d.com/ja/current/Manual/UnityAnalytics.html) (マニュアル)
    - `In App Purchasing` ～ [Unity IAP](https://docs.unity3d.com/ja/current/Manual/UnityIAP.html) (マニュアル)

# 解ったこと
- パッケージを使用していなくても、プロジェクトに導入されているだけで、権限の要求が付いてしまうようです。
Ubuntu18.04でMAVProxyのインストール

Ubuntu18.04にMAVProxyをインストールします。

# 環境
- Ubuntu 18.04.5
- Python 2.7.17
- MAVProxy Version: 1.8.22

# インストール

```
$ sudo usermod -a -G dialout <username>
$ sudo apt-get install python-dev python-opencv python-wxgtk4.0 python-pip python-matplotlib python-lxml python-pygame
$ pip install PyYAML mavproxy --user
$ echo "export PATH=$PATH:$HOME/.local/bin" >> ~/.bashrc
```

# MAVProxyの起動

- USB経由で接続

```
$ mavproxy.py --master=/dev/ttyACM0
WARNING: You should uninstall ModemManager as it conflicts with APM and Pixhawk
Connect /dev/ttyACM0 source_system=255
Log Directory: 
Telemetry log: mav.tlog
Waiting for heartbeat from /dev/ttyACM0
 MAV> online system 1
MANUAL> Mode MANUAL
fence breach
Received 722 parameters
Saved 723 parameters to mav.parm
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386259/37880773-727b-2182-8fb1-deec7ba6fa84.png)

- Network経由で接続

```
$ mavproxy.py --master=udp:127.0.0.1:14550
WARNING: You should uninstall ModemManager as it conflicts with APM and Pixhawk
Connect udp:127.0.0.1:14550 source_system=255
Log Directory: 
Telemetry log: mav.tlog
Waiting for heartbeat from 127.0.0.1:14550
MAV> link 1 down
```

```
$ mavproxy.py --master=tcp:0.0.0.0:14550
WARNING: You should uninstall ModemManager as it conflicts with APM and Pixhawk
Connect tcp:0.0.0.0:14550 source_system=255
[Errno 111] Connection refused sleeping
[Errno 111] Connection refused sleeping
[Errno 111] Connection refused sleeping
[Errno 111] Connection refused sleeping
Failed to connect to tcp:0.0.0.0:14550 : [Errno 111] Connection refused

```
macOS  JetBrainsでダウンロードしたGoLandで改行「\」が打てない場合

JetBrainsで GoLandをダウンロードしプログラムを書いていたところ、改行を表す「\」が打てなかった。
色々調べてMacのキーボード配列をいじったりしたが変化せず、、、

optionキーとfnキーと同時に¥を押すと\が打てました。
どういうバグなんだろう、、、