OmniAICreator/Qiita-1.07M huggingface dataset:
GitHub CLI extension 作ってみた

## 始めに
タイトルの通りです。

最近 GitHub CLI にはまってて、

```shell
gh pr create --draft
```

で簡単にドラフト PR 作れるので、それでサクッと作ったり

```shell
gh repo view --web
```

でリポジトリのページにアクセスしたり、

マウスアクションに頼る機会がどんどん減っていって、気持ちが良いです。

僕も全部を使い倒せてるわけではないですが、まだまだたくさんあるので、ぜひ皆さんも使ってみてください。

さて、そんな便利な GitHub CLI ですが、
なんと gh コマンドを自作することができるのです。

## GitHub CLI extension とは
その名の通り
GitHub CLI の拡張機能です。

https://docs.github.com/ja/github-cli/github-cli/creating-github-cli-extensions

で、拡張機能を自分で作って、それを公開することができるので
すごい簡単に OSS 開発っぽいことに挑戦できるので、なんだか「あ〜俺めちゃくちゃエンジニアしてる〜〜〜〜」って気持ちになれます。

基本的に公式と Bash の書き方のページだけ見ればなんでもできるっぽいです。


## やったこと

とりあえずサクッと、
自分の GitHub のページにアクセスできる拡張機能を作ってみました

```
gh extension create gh-my-page
```

```bash:gh-my-page
#!/bin/bash
set -e

url=$(gh api user --jq .html_url)

open $url
```

```shell
gh extension install .
gh my-page
```

とすると GitHub の自分のページがブラウザで表示されます

面白え！！！！！

## 進化させてみた

自分のだけ表示できてどうするんだ、ということで、
他の人の名前も見れるようにしてみました

用件は
- 引数があると、その名前のページを表示する
- 引数がない時は、自分のページを表示する
- それっぽくするためにヘルプコマンドを用意する

```
gh extension create gh-page
```

```bash:gh-page
#!/bin/bash
set -e

name=""

while [ $# -gt 0 ]; do
  case "$1" in
  -h | --help)
    echo "First argument is want to display account or organization name."
    echo "default, your github account name."
    echo "e.g."
    echo '$ gh page yasudanaoya'
    exit 0
    ;;
  -* | --*)
    echo "$1 is not found"
    exit 0
    ;;
  *)
    name="$1"
    ;;
  esac
  shift
done

if [ -z "$name" ]; then
  name=$(gh api user -q .login)
fi

open https://github.com/$name
```

```shell
gh extension install .

# 以下の二つは同じ結果
gh page
gh page yasudanaoya
```

## 終わりに

普段フロントエンジニアとして、画面のあるものしか作っていないので、こう言った画面を持たない機能の開発は新鮮で楽しかったです。

心残りがあるとすれば、最後に作った gh extension では
`-` や `--` から始まる GitHub のページにはアクセスができないことです。
バリデーション的に存在するかどうかわかんないですが
musl を clang で使う (Debian・Ubuntu)

[musl](http://musl.libc.org/about.html) は glibc の代わりに使える標準Cライブラリで、Alpine Linuxのデフォルトになっています。muslは[clang](http://clang.llvm.org) と組み合わせて使えますが、Debian・Ubuntuではgcc用のラッパー `musl-gcc` はあるのに [musl-clang](https://git.musl-libc.org/cgit/musl/tree/tools/musl-clang.in) は無いので、自分で書いたラッパーを以下に貼ります。何か問題が見つかればコメントでご連絡お願いします。muslがgccでコンパイルされているため　libgcc.a が必要になります。`libgcc-10-dev` などのパッケージにlibgcc.aが入っています。

```shell
#!/bin/sh

ARCH=aarch64
# or ARCH=x86_64 etc.
GCCVERSION=11

# Scrt1.o for dynamic PIE
# rcrt1.o for static PIE
# crt1.o for no PIE
LIBPREFIX=/usr/lib/${ARCH}-linux-musl
GNULIBPREFIX=/usr/lib/gcc/${ARCH}-linux-gnu/$GCCVERSION

if echo " $@" | fgrep -q -- ' -static'; then
  DYNLINKER=''
  if echo " $@" | fgrep -q -- ' -static-pie'; then
    CRT=${LIBPREFIX}/rcrt1.o
  else
    CRT=${LIBPREFIX}/crt1.o
  fi
else
  DYNLINKER="-Wl,-dynamic-linker,/lib/ld-musl-${ARCH}.so.1"
  if echo " $@" | fgrep -q -- ' -pie'; then
    CRT=${LIBPREFIX}/Scrt1.o
  else
    CRT=${LIBPREFIX}/crt1.o
  fi
fi
exec clang $DYNLINKER -nostdinc -isystem /usr/include/${ARCH}-linux-musl -nostdlib -nostdlib++ -nodefaultlibs -nostartfiles -L${LIBPREFIX} $CRT ${LIBPREFIX}/crti.o "$@" -lc ${GNULIBPREFIX}/libgcc.a ${LIBPREFIX}/crtn.o

```
JavaScriptのクロージャーについて

#クロージャー
クロージャーとはレキシカルスコープの変数を関数が使用している状態のことを指します。イラストで確認してみましょう

```JS:JS
function fn1() {
  let b =1;
  function fn2() {
    console.log(b);
  }
  fn2();
}
fn1();
```
![スクリーンショット 2021-10-17 13.38.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1265227/0baaa3f1-0941-d13b-8459-d8c6c37fda90.png)

このように関数が多階層で定義されている時に、関数fn2がそのレキシカルスコープである変数bを参照しています。このこの状態をクロージャーと表現します。このクロージャーを用いた実装ケースも確認しましょう。

###プライベート変数の定義
まずinvrement関数というものを用意し、この関数が呼ばれた際にカウントを１つずつ加算する仕組みを作ってみましょう。

```JS:JS
let num = 0;

increment();
increment();
increment();

function increment() {
  num = num +1;
  console.log(num);
}
```
これで1,2,3と出力できます。ただこのままではnumがソースコードのどこからでも書き換えることができてしまします。例えば以下のようにどこかでnumの値を初期化してしまった(書き換えた)場合出力される値が被ってしまい期待した挙動が取れないケースがあります。

```JS:JS
let num = 0;

increment();
increment();
increment();

function increment() {
  num = num +1;
  console.log(num);
}

num = 0;
increment();
```

![スクリーンショット 2021-10-17 13.53.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1265227/4d7cdf70-155e-b20b-c138-eba48e0ed15b.png)

そこで、クロージャーを用いて関数の内部には変数をもちながらも外部からはアクセスできないようにしましょう。

まず、incrementという関数をincrementFactoryと書き換えます。このincrementFactory内にnumの初期化、及びincrement関数を記述し、incrementFactoryの戻り値としてincrement関数を設定します。このようにJavaScriptでは関数も戻り値として設定することができます。

```JS:JS
function incrementFactory() {
  let num = 0;

  function increment() {
    num = num +1;
    console.log(num);
  }
  return increment
}

const increment = incrementFactory();
increment();
```

最後に戻り値をincrementという変数に格納し実行します。この時incrementFactoryの中で関数incrementの中で使用していることになるので、関数incrementはnumへの参照を保持している状態でincrementFactoryから返却することになります。ちなみに関数の実行は関数名のあとに()をつけます。

###動的な関数生成
静的な関数との違いは関数を生成する関数に引数を設定し、呼び出し時に参照する値を設定できる点になります。

```JS:JS
function addNumberFactory(num) {
  function addNumber(val) {
    return num + val;
  }
  return addNumber;
}

const add5 = addNumberFactory(5);
const result = add5(10);
console.log(result);
```

addNumberFactory(num)の引数であるnumへの参照を呼び出し時点で保持します。

##参考
Udemy： 【JS】ガチで学びたい人のためのJavaScriptメカニズム
Chatworkにメッセージを送るGASスクリプト

![20211017-01.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145508/36ad8891-b785-45e6-2786-5ab19452ca7d.jpeg)
![20211017-02.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145508/3f4e8d89-529e-5600-0fbc-a010b42a8858.jpeg)


```
function myFunction() {
  var WK_ROOM_ID = "(ROOMID)";
  var WK_TOKEN = "(TOKEN)";
  var WK_TEXT = "Chatworkにメッセージを送るGASスクリプト";
  // 送信データ
  var params = {
     headers : {"X-ChatWorkToken" : WK_TOKEN},
     method : "post",
     payload : {
       body : WK_TEXT
     }
   };
  var url = `https://api.chatwork.com/v2/rooms/${WK_ROOM_ID}/messages`;
  UrlFetchApp.fetch(url, params);
} 
```
Custom View で自身のサイズを元にサイズ変更を行う方法

# ◆はじめに
Android の custom view にて、自身のサイズ変更を元に自身のサイズが変わる処理を行い、計算をすべて親クラスに丸投げするケースのメモです。

# ◆ダメな例その１

```kotlin
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
    // super.onMeasure() が呼ばれてないので、サイズ計算ができておらず、目的の処理が行えない。
    doSomethingWithSizeModification()

    super.onMeasure(widthMeasureSpec, heightMeasureSpec)
}
```

# ◆ダメな例その２

```kotlin
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
    // super.onMeasure() により、現状のサイズが計算される。
    super.onMeasure(widthMeasureSpec, heightMeasureSpec)

    // 計算されたサイズを元に View の内部を変更するが、上記の計算と合わない内容になってしまい、表示がおかしくなってしまう。
    doSomethingWithSizeModification()
}
```

# ◆現状の解決策

なんか美しくないのですが、一度の再計算にて計算結果が安定するケースに限り、対応可能だと思われます。
※無限に連鎖するケースとかそもそも対応できるとは思えないが、、、。

```kotlin
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
    // super.onMeasure() により、現状のサイズが計算される。
    super.onMeasure(widthMeasureSpec, heightMeasureSpec)

    // 計算されたサイズを元に View の内部を変更する。
    doSomethingWithSizeModification()

    // super.onMeasure() により、サイズを再計算する。
    super.onMeasure(widthMeasureSpec, heightMeasureSpec)
}
```

# ◆おわりに
とっても微妙な方法なので、もっといい方法があれば教えてくださいmm
React+Material UIにおける、ボタン押下時の@keyframesアニメーション①

# 初めに
ボタン押したときにkeyframeで設定しているアニメーションを発動
そしてタイトルが長いな、、
※初回にアニメーションが走るのは何とかしたいが、、、

# こんな感じのもの
ボタンを押すと、領域が拡大or縮小します

# コード
```react
import { useState } from "react";
import { Box, Button } from "@material-ui/core";
import { makeStyles } from "@material-ui/core/styles";
import clsx from "clsx";

// classオブジェクト定義
const useStyles = makeStyles(() => ({
  // 開閉共通のclass(jsx側に設定)
  commonItem: {
    backgroundColor: "#ff0000",
    width: "200px",
  },
  // 開くときのclassオブジェクト(jsx側に設定)
  openedItem: {
    animation: `$openEffect 1000ms`,
    height: "100px",
  },
  // 閉じるときのclassオブジェクト(jsx側に設定)
  closedItem: {
    animation: `$closeEffect 1000ms`,
    height: "30px",
  },
  // 開いた時の動作
  "@keyframes openEffect": {
    "0%": {
      height: "30px",
    },
    "100%": {
      height: "100px",
    },
  },
  // 閉じたときの動作
  "@keyframes closeEffect": {
    "0%": {
      height: "100px",
    },
    "100%": {
      height: "30px",
    },
  },
}));

// コンポーネント
const TestComponet = () => {
  // classオブジェクト生成
  const classes = useStyles();
  // 開閉のフラグ
  const [isOpen, setIsOpen] = useState(true);

  return (
    <>
      {/* 開閉、共通のclassをBoxに設定 */}
      <Box
        className={[
          clsx(
            classes.openedItem,
            {
              [classes.closedItem]: !isOpen,
            },
            classes.commonItem
          ),
        ]}
      >
        {/* 開閉ボタン(設定値と逆のフラグを設定) */}
        <Button onClick={() => setIsOpen(!isOpen)}>開閉</Button>
      </Box>
    </>
  );
};

export default TestComponet;
```

# 最後に
初のReact関連記事！
yarn add 関連はうまくやって下さい、、
ユーザーのURLをmyapp.com/usernameとかmyapp.com/settingsみたいなナウい感じにしたい（Rails）

## やりたいこと
ユーザーのマイページやアカウント設定ページのルーティングをしたいです。
普通にRailsの`resources`メソッドに任せてしまうと、`my_app.com/users/:id`てな具合になってしまいます。

でも、ナウいQiitaとかnoteとかだとこんな感じになっています。

```
https://qiita.com/kakudaisuke
https://qiita.com/settings/account

https://note.com/kakudaisuke
https://note.com/settings/account
```

シンプルでかっこいいじゃないですか！
僕のアプリもこうしたい！

実装してみて、簡単にできたものの、細かいところの調整がやや面倒だったのでメモを。

### 環境
ruby 2.7.2
Rails 6.1.4.1

## 実装！
### routes

```ruby:config/routes.rb
Rails.application.routes.draw do
  root 'posts#index'
  #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  # users
  devise_for :users,
             only: %i[session password registration],
             controllers: { sessions: 'users/sessions',
                            password: 'users/passwords',
                            registrations: 'users/registrations' }

  get '/users', to: 'users#index'
  get '/settings', to: 'users#edit'
  resources :users, param: :account_name, only: %i[show new create update destroy], path: '/'
end

```

（ユーザーに関わる部分なので、なんとなくdeviseのルーティングも併せて載せておきましたが、今回の実装とは全く関係ないので無視で。）

`resources`メソッドの`param`や`path`というオプションを駆使すると簡単にやりたいことは大体できてしまいます。

https://railsdoc.com/page/resources

いくつか注意点があります。

- `index`を`resouces`に含めてしまうと、ルート`myapp.com/`がユーザー一覧になってしまうんですよね。ルートpathは別に設定したいので分けました。

- **これ、順番が大事で、resources :usersを一番最後に書かないと、`/posts`、`/users`なども`account_name`だと判断されてしまいます**。予期していないルーティングがされ「postsなんてユーザーいないぞ」とエラーに。

- それでも例えば`posts`なんていうアカウント名のユーザーがいたら、やはり、マイページではなく、posts一覧にルーティングしてしまいます。そこで、今回はモデルのバリデーションで使われたくない名前を定義してブロックしました↓。

```ruby:app/models/user.rb
reserved_words = %w(posts users my_app)
validates :account_name, exclusion: { in: reserved_words }
```

### Model

`param: :account_name`を有効にするには、モデル側でパラメーターにidじゃないのを使うよーと宣言してあげないといけません。

```ruby:user/rb
def to_param
  account_name
end
```

ドキュメント→https://railsdoc.com/page/to_param

### Views

こんな感じで設定してあげます。

```erb
<%= link_to User.model_name.human, '/users' %>

<%= link_to 'アカウント設定', '/settings' %>

<%= link_to 'マイページ', user_path(current_user) %>

<%#= postのユーザー名からユーザーページへのリンク %>
<%= link_to(post.user.account_name, "/#{post.user.account_name}") %>
```
## 最後に
これでとりま自分がやりたいことは実現できました！
ただ、もっとなんかスマートな方法がある気もしています。。

何かご指摘などあればバシバシよろしくお願いします。
vistaのセキュリティのいい話

#概要

vistaのセキュリティのいい話

#参考にしたページ。

https://security.macnica.co.jp/blog/2021/04/USBMalware.html

#何が起きた。

記事をメモ帳にコピペして、usb.txtで、名前を付けて保存した、その時、デフェンダーに隔離された。

#どうして

記事の内容が、デフェンダーの、yaraルールに、ヒットしたのだろう。ウィルスと判断して隔離した。

以上。
ラビットチャレンジレポート #0

# E資格取得を目指してラビットチャレンジを開始
* 2月にE資格を取得するためにラビットチャレンジをスタート
* 提出用のレポートをまとめるためにqiitaに登録
* 講座を通して学んだ内容をここにまとめていく

# ラビットチャレンジのスタートテストについて
* 57/60で合格となり講座を開始できる
* テストの挑戦は5回まで。5回でクリアできない場合、追加課金する必要あり
* テストは何回受けても同じ問題がでる
* テストの難易度が高いと感じる場合は超AI入門講座から受講するのがおすすめ
* 筆者は3回目で合格
Concourse CIと他のCIツールをざっくりと比較してみた

Concouse CIについて、調査する機会がありましたので、調査結果をまとめようと思います。
[Concouse CI](https://concourse-ci.org/)と他のCIツール（CircleCI、Jenkins）との比較を行いました。

# 比較対象CIツール概要

### concourse
1. 比較的新しいCIツール（2014年リリース）。モダンであるが、日本語のドキュメントは少ない。
2. 実行の際に可能な限りconcourseに依存することをなくし、外部要因を「resource」というものに抽象化するという哲学を持っている。それにより、どのconsourceサーバーでも、同じプロセスで実行できるようにする。
「resource」は、具体的には、実行のためのDockerイメージ、時間をトリガーとしてビルドする際の時間（タイムリソース）、データを保存してあるs3バケットなど様々。

### Circle CI
1. SaaSである。
2. 有料になる可能性があるが、構築の手間は少ない。
3. 障害発生時、原因解析や復旧をすることが困難。 

### Jenkins
1. 最も一般的なCIツール。日本語のドキュメントが豊富
2. Jenkins自体は、主に自動化フレームワークとして機能し、重要なロジックの多くはプラグインのライブラリによって実装されてる。そのため、柔軟性はあるが、多数のサードパーティ製プラグインに依存するようになる可能性がある。


# Consource vs CircleCI vs Jenkins

|  | Concourse | CircleCI | Jenkins |
|:-:|:-:|:-:|:-:|
| 提供方法  | オープンソース  | SaaS  | オープンソース  |
| パイプラインの記述方法  | yaml  | yaml  | groovy  |
| パイプライン以外の設定方法  | fly cli  | 画面から実施  | 画面から実施  |
| パイプラインの可視化 | ステップのリスト<br>ジョブの依存関係 | ステップのリスト<br>ジョブの依存関係 | ステップのリスト |
| ビルドの実行環境  | コンテナ  | コンテナとVM（複数OSを選択可能）  | 物理マシン、VM、コンテナ（構築次第）|
| 構築難度 | Dockerの知識があれば、容易 | github,bitbucketの連携のみ、容易 | サーバー構築の必要性あり、やや難 |
| リポジトリへのプッシュなしでビルドの実行 | fly executeコマンドで実行 | 不可 | 不可 |
|  拡張 | リソースカタログ  | Orbs  | プラグイン  |
|  エラー調査 | 実行状況の表示<br>コンテナへのアクセスをサポート  | 実行状況の表示<br>コンテナへのアクセスをサポート  | 実行状況の表示  |

# 特に気になったこと
### fly cliによる操作
concourseはすべての操作はfly cliというコマンドラインツールから行います。
これにより、処理の自動化や共有が行いやすいです。

### ローカルでの実行
CircleCI、Jenkinsは、ローカルでの変更をプッシュしないでビルドするということができません。
しかし、concourseにおいては、自身の変更のみをビルドすることができます。
これにより、リモートのコミットを汚染したり、テスト前の変更をプッシュすることを防ぐことができます。

# 現状での個人的見解
1. Dockerの知識がある程度あった方がいいことやローカルでの構築作業が必要になるため、CircleCIとの選択では、プロジェクトの状況に応じて、一長一短あると思いました。
2. Jenkinsと選択する際は、すでに進んでいるプロジェクトではないなら、Concourseを選択することが望ましいと思います。

# 今後の調査
Concourseの実際の設定方法や特定のユースケースを想定した調査ではないので、今後の調査では、
1. ローカルでの自分の変更のみのビルド方法
2. テストの実施方法
3. エラーの通知方法
4. デプロイ方法
などのユースケースを想定して、構築してみようと思います。


# 参考文献
Justin Ellingwood."CI/CD Tools Comparison: Jenkins, GitLab CI, Buildbot, Drone, and Concourse".THE DIGITALOCEAN COMMUNITY.2017-7-24.https://www.digitalocean.com/community/tutorials/ci-cd-tools-comparison-jenkins-gitlab-ci-buildbot-drone-and-concourse ,(参照2021-10-17)
Pythonを使ってブラウザでWebページを開く方法

#もっと便利に使いたい

仕事で使ういつものたくさんのサイト、クリックひとつで開けたら便利だと思いませんか？
Pythonを使えばブラウザでWebページを開くのを自動化することができます。

#動作環境
* Windows / Mac / Linux どれでも可
* Python 3.7.9

#webbrowser.open関数を使う
webbrowserモジュールは標準ライブラリに含まれいるので、インストールは不要。
スクリプトの最初でインポートすればOK。

```python
import webbrowser
```

次に、特定のWebページを開くには、webbrowser.open関数を使います。

```python
webbrowser.open(url)
```
めっちゃ簡単！
変数urlには開きたいページのURLを指定します。

具体的なサンプルコードはこちら。

```python
import webbrowser
url = 'https://google.com'
webbrowser.open(url, new=0, autoraise=True)
```

* 第1引数 url： WebサイトのURLを設定します。
* 第2引数 new： 表示モードを設定。下表参照

|new  |動作  |
|---|---|
|0  |同じウインドウで開く  |
|1  |新しいウインドウで開く  |
|2  |新しいタブで開く  |

* 第3引数 autoraise: Trueなら、可能であればウィンドウが前面に表示されます。


#まとめ

今回はPythonを使ってブラウザでWebページを開く方法をご紹介しました。
これを使うことでいつも行っている動作を効率化できます。
例えば、エクセルに指定したいつも開くURLをまとめて開いたりできます。
お試しあれ。
Custom View にデフォルトの属性群を指定する方法

# ◆はじめに

特定の custom view すべてに適用されるデフォルトの属性値を指定する方法のメモです。

# ◆具体的なケース

例えば `MyTextView` という custom view を作った際に、以下のようにデフォルトのスタイルを毎回差し込む必要があるとします。

```xml
<MyTextView
    android:id="@+id/artist_name_text_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    style="@style/myTextView"
/>
```

この場合、custom view の恩恵が薄くなってしまうし、style の設定し忘れをコンパイル時に検出できなかったりして、とっても残念な感じです。

ということで、デフォルト属性を指定したいよねという話です。

※ちなみに、カスタムの属性を指定する方法は簡単で、attrs.xml に属性を定義して、custom view 側のコンストラクタで渡ってくる attrs から値を取得すればOKです。興味のある方は [過去記事](https://qiita.com/beyondseeker/items/119873801b4bb07d4d5c) 参照のこと。

# ◆実装例

## ☆Custom View
デフォルトの属性を指定したい custom view です。

引数を2つ持つコンストラクタにて、親クラスのコンストラクタの第3引数に、デフォルト属性用の attr を渡します。
※ *R.attr.myTextViewStyle* は後述。

```kotlin:MyTextView.kt
class MyTextView : AppCompatTextView {
    constructor(context: Context) : super(context)
    constructor(context: Context, attrs: AttributeSet) : super(context, attrs, R.attr.myTextViewStyle)
    constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
}
```

## ☆attrs.xml
Custom view から参照される attr です。
※この attr とデフォルト属性群の関連付けは後述。

```xml:attrs.xml
<resources>
    <attr name="myTextViewStyle" type="reference" />
</resources>
```

## ☆styles.xml
myTextViewStyle とデフォルト属性群を関連付けます。

```xml:styles.xml
<resources>
    <!-- アプリの Theme 設定 -->
    <style name="AppTheme" parent="Theme.MaterialComponents.Light">
        <!-- myTextViewStyle とデフォルト属性群の関連付け  -->
        <item name="myTextViewStyle">@style/MyTextView</item>
    </style>

    <!-- MyTextView 全てに適用されるデフォルト属性 -->
    <style name="MyTextView">
        <item name="android:ellipsize">end</item>
        <item name="android:maxLines">1</item>
        <item name="android:textSize">12dp</item>
    </style>
</resources>
```

# ◆おわりに
らくちんですね～
ReactNative > nodenvでnode管理しているときに、NODE_BINARYエラー



ReactNativeをXCodeでビルドしたところエラーが出たので解決メモ

環境:

- react-native: 0.66.1


## 事象

以下のコマンドでReactNativeを作成したほやほやの状態で、

```
npx react-native init MyTestApp
```


Xcodeでビルドしたところ以下のエラーがでました。

```
Showing Recent Messages Error: Could not find node. Make sure it is in bash PATH or set the NODE_BINARY environment variable.
```


## 原因と解決

私の環境ではbashにnodeのPATHが通っていなかった事が原因でした。


↓[このへんのbash設定](https://qiita.com/sugasaki/items/8cb12c06d2a44515194a#2-path%E3%81%AE%E8%A8%AD%E5%AE%9A)をひととおり設定し、
[Mac > anyenv,nodenvをMacに設定 - Qiita](https://qiita.com/sugasaki/items/8cb12c06d2a44515194a#2-path%E3%81%AE%E8%A8%AD%E5%AE%9A)

    
```
echo 'export PATH="$HOME/.anyenv/bin:$PATH"' >> ~/.bash_profile
```

bashでもnodenvが動作するように設定を完了後、Xcodeでビルドしたら、無事にビルド成功しました。

![Simulator Screen Shot - iPhone 13 mini - 2021-10-17 at 15.06.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49910/a0d557bd-15fb-5bae-a147-1947b3cbb3de.png "Simulator Screen Shot - iPhone 13 mini - 2021-10-17 at 15.06.09.png")



## 実機での動作確認


これで、シミュレーターでは動作確認ができるようになったのですが、実機で動かすときにエラーが出ました。


```
Can't find the 'node' binary to build the React Native bundle.  If you have a non-standard Node.js installation, select your project in Xcode, find  'Build Phases' - 'Bundle React Native code and images' and change NODE_BINARY to an  absolute path to your node executable. You can find it by invoking 'which node' in the terminal.
```
![スクリーンショット 2021-10-17 15.08.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49910/0c84d210-4fef-383b-4b58-42147520a04f.png "スクリーンショット 2021-10-17 15.08.05.png")


以下のコマンドでnodeの実行パスを調べます

```
which node
```

私の環境では以下のように表示されたので、

```
/Users/xxx/.anyenv/envs/nodenv/shims/node
```



Projectファイルを選択 -> TARGETS -> APP Name -> Build Phases -> Bundle React Native code and image




![スクリーンショット 2021-10-17 14.45.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49910/294690f8-0369-cc1f-4197-d8d069a55164.png "スクリーンショット 2021-10-17 14.45.30.png")

以下のように設定しました。


![スクリーンショット 2021-10-17 15.12.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49910/4bce2c42-9a97-e00d-6a96-6a04fbc4ebf3.png "スクリーンショット 2021-10-17 15.12.17.png")

```
export NODE_BINARY=$HOME/.anyenv/envs/nodenv/shims/node
```


これで無事に実機でアプリが起動しました。


![IMG_0761.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49910/73bd7d88-bc5e-c642-e6f5-ec4221bd5db6.png "IMG_0761.PNG")



参考

[React-NativeをiOS実機でビルドしたら，node binaryが見つからないとエラーが出た件 - Qiita](https://qiita.com/_mkazutaka/items/eca26d441461985d8397)
【Laravel】トランザクションの書き方

#はじめに#
　トランザクションとは、お互いに関連のある複数の処理をまとめて一つの処理として扱うということを表します。
例えば、銀行口座の振り込み処理などでは、AさんがBさんに1万円振り込んだとすると、Aさんの口座からは1万円出金し、Bさんの口座には1万円入金するという処理が必要になります。この時、Bさんの入金処理が何らかのエラーにより実行されなかった時、Aさんの処理が実行されてしまっては整合性が取れなくなります。このように、関連する処理をひとまとめにして、全ての処理が正常に実行された時に処理を反映させるのがトランザクションというものです。

#Laravelでトランザクションを実装#
　今回はLaravelでトランザクションを実装します。トランザクションは、DBファサードが提供する機能なので、まずはDBファサードを有効にします。

```transaction.php
use Illuminate\Support\Facades\DB;
```

次に、実際にトランザクションを張っていきます。
まずはクロージャを使用する場合は、このように書きます。

```HomeController.php
use Illuminate\Support\Facades\DB;

class HomeController extends Controller{

    public function transaction(){

        DB::transaction(function(){
           DB:: 〜何かの処理;
           DB:: 〜何かの処理;
        });

    }

}
```

　このように、クロージャ内で二つ以上の処理を実行し、正常に動作した場合はコミットされ、例外がスローされた場合は自動でロールバックされます。
引数を指定したい場合はこのように書きます。

```HomeController.php
use Illuminate\Support\Facades\DB;

class HomeController extends Controller{

    public function transaction(Request $request){

        DB::transaction(function()use($request){
           DB:: 〜何かの処理;
           DB:: 〜何かの処理;
        });

    }

}
```


　次に、手動でトランザクションを貼る場合です。

```HomeController.php
use Illuminate\Support\Facades\DB;

class HomeController extends Controller{
    public function transaction(){
          try{   
               DB::beginTransaction();

               DB:: 〜何かの処理;
               DB:: 〜何かの処理;

               DB::commit();
           }catch(Throwable $e){
               DB::rollBack(); 
           }
    }
}
```


正常に動作すればコミット、例外がスローされればロールバックして処理が終了します。

#終わりに#

未経験から転職を目指して勉強中です。
誤り等ありましたらご指摘いただけますと幸いです。
放送大学 入門微分積分 演習問題1メモ

### A2(1)
lim n→∞ (1+(1/n))^nになるよう、mを設定する
ex. 3n=m, n=2m


### B1(1)
|bn|<ε/2 ...①
N1>2K/εと定義する ...②

|An-α|= A + B の箇所において、

##### A
```math
A = |\frac{b_1+b_2...b_N}{n}|<|\frac{K}{N1}|
```
分子はKと定義、分母はnより小さいと定義したN1にすることで、左辺より大きくなる
②より、

```math 
|\frac{K}{N1}|<\frac{K}{\frac{2K}{ε}}=\frac{ε}{2}
```

##### B

```math
B = |\frac{b_{N+1} + b_{N+2} ...b_n}{n}|
```



②より、n|<ε/2, つまり(bN+1 + bN+2 ...bn)はε/2*数(n - N)より小さくなる

```math
|\frac{b_{N+1} + b_{N+2} ...b_n}{n}| \times \frac{1}{n} < (n-N) \times \frac{ε}{2} \times \frac{1}{n}
```
a=(n-N)nは0<a<1であるため、B<ε/2
【学習記録③】Vue CLIを使ってみる！

#はじめに
Vue.jsを最近勉強し始めたので学んだ文法などを備忘録としてメモしていこうと思います。
過去の学習記録の記事を書く際は[JSFiddle](https://jsfiddle.net/boilerplate/vue)を用いていましたが、実際に開発を行う場合は基本的にVue CLIを用いるということを知ったので今回の記事ではVue CLIについて書いていこうと思います。

##Vue CLIとは
Vue CLIとはVue.jsの開発をより効率的に行うように手助けしてくれるツールです。

https://cli.vuejs.org/

公式のページには以下のメリットが書かれています。

**・Feature Rich**
特定のESバージョンへ変更するbabelやUnitテスト・E2Eテストなどが利用しやすい！（サポートしている）

**・Extensible**
プラグインの取り込みが容易

**・No Need to Eject**
ejectせずともプロジェクトを最新に保つことができる
（これはこの記事を書いている時にはピンと来てないのですがejectすると元に戻せないからそのリスクがなくなるとかそういうことでしょうか...？まあ分かったらまた記事にしようかな？）

**・Graphical User Interface**
Vue CLIというツールなのにGUI！？という感じですが、調査した感じだとどうやらGUIもあるようで、以下の記事がとても分かりやすかったです！

https://qiita.com/isihigameKoudai/items/eee3eb6a435675fdfd73

**・Instant Prototyping**
一つのVueファイルでサクッと簡単なアプリが作れてしまう！

**・Future Ready**
ES2015にネイティブに対応しているブラウザ向けのビルドなどが行える！
（ちょっと今の知識だとbabelでいいんじゃない？とも思ってしまったので使っているうちにこれの意味等がちゃんと分かったら記事にします）

##Vue CLIのインストール
まずはNode.jsをインストールします。

https://nodejs.org/ja/

インストール完了後、nodeのバージョンをターミナル等で確認すると以下のようにバージョンが表示されることが分かります。

```console
C:>node -v
v14.18.1
```

nodeをインストール後、以下のコマンドを実行してVue CLIをインストールします。

```console
C:>npm install -g @vue/cli
```

無事にインストールが完了したら以下のようにvue cliのバージョンを確認することができます。

```console
C:>vue --version
@vue/cli 4.5.14
```

##Vueプロジェクトの作成
それではVueプロジェクトを作成してみます。
任意のフォルダで以下のコマンドを実行し、プロジェクトを作成します。

```console
C:\Work\VuePractice>vue create vuePractice
Invalid project name: "vuePractice"
Warning: name can no longer contain capital letters
```

あれ？プロジェクトの名前はキャメルケースにするのはダメなんですね(;^_^A

ということでケバブケースにしてみました。

```console
C:\Work\VuePractice>vue create vue-practice
?  Your connection to the default npm registry seems to be slow.
   Use https://registry.npm.taobao.org for faster installation?
```

「中国版npmみたいなものを使うと速いよ！」と出ますが、まあ、本家のnpmを使うことにします。
ここは`No`とします。

```console
Vue CLI v4.5.14
? Please pick a preset:
  Default (Vue 3) ([Vue 3] babel, eslint)
  Default (Vue 2) (babel, eslint)
  Manually select features
```

今回は`Default (Vue 3) ([Vue 3] babel, eslint)`を選んでいきます。
インストールが終わると以下のように複数のフォルダやファイルが作られていることが分かります。
![pic1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538249/e583af08-94b1-9c47-bd12-3cd5517129ac.png)

以下のコマンドで起動してみましょう。

```
C:\Work\VuePractice\vue-practice>npm run serve
> vue-practice@0.1.0 serve
> vue-cli-service serve

 INFO  Starting development server...
98% after emitting CopyPlugin

 DONE  Compiled successfully in 3538ms

  App running at:
  - Local:   http://localhost:8080/
  - Network: http://192.168.3.75:8080/

  Note that the development build is not optimized.
  To create a production build, run npm run build.
```

`localhost:8080`へアクセスしてみると以下のようにアプリが立ち上がっていることが分かります。
![pic2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538249/99a9a9c0-f0e4-6829-59b9-27f03c92a865.png)

#おわりに
今までは簡単なVueの文法等の勉強でしたがいよいよ本格化してきた感じがします。
フォルダ構成やVueファイルの内容等をしっかり理解していきたいと思います。
【php】連想配列中の重複したレコードを削除

```sample.php
    /**
     * 配列の重複を削除
     *
     * @param [type] $arr
     * @param [type] $column
     * @return void
     */
    private function getUniqueArr($arr, $column)
    {
        $tmp = [];
        $uniqueArray = [];
        foreach ($arr as $value){
            if (!in_array($value[$column], $tmp)) {
                $tmp[] = $value[$column];
                $uniqueArray[] = $value;
            }
        }
        return $uniqueArray;
    }
```

```sample.php
$project = $this->getUniqueArr($mergedArr, 'project_id');
```

https://qiita.com/YusukeHigaki/items/dbcb726592aa2fa2ff42
MQTTを使ってInfluxDBで記録とダッシュボード表示しつつ、他のデバイスにも送るメモ

#はじめに
前のはMQTTの本来の持ち味が生かせておらず、通信経路としてだけだったので、同報通知するパータンをメモする。

#InfluxDB(時系列DB)

https://qiita.com/NWLab/items/736ffe812757edc187f1

を参考に設定と実行を

InfluxDB側でMQTTを使うわけではないのでTelegrafは不要

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97061/f6774dad-eb67-1bba-907c-8606408623c0.png)

#M5Stack(送信側）
こんな感じでJson形式で送信
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97061/8fcf1bcb-9326-e1f4-c920-c0efc170f469.png)


#Node-RED
##1つ目のフロー（MQTT Broker）
こんな感じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97061/29a7b470-f54f-9464-6ab5-ddfad208a6ff.png)

参考

https://qiita.com/NWLab/items/cb3f434705708c40755b

##2つ目のフロー

###準備
パレットで、node-red-contrib-influxdbをインストールします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97061/1550a194-88da-aaa7-eb6a-b2179b661973.png)

ストレージにInfluxDB関係がインストールされました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97061/10bffff5-a40d-3785-7419-32e61ebd5be8.png)
###MQTT IN
MQTT　IN はこんな感じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97061/6550ef74-8921-5628-666b-9295d2121f9d.png)
###InfluxDB
influxdbは”influxdb out”でも"influxdb batch"でも出来そう。ここでは"influxdn out"を使ってみる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97061/f8290bc2-2dde-6693-5e56-c0afa8f435fa.png)
名前はInfluxDBにして、Serverは右の鉛筆をクリックするとノード編集になるから各値を入れる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97061/0f318ec0-93f8-168d-6f48-4a43738621a5.png)
追加して、Influxdb outのプロパティが（サーバのVerifyが終わったら？）少し項目が変わるので、続けて入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97061/ddd1b466-4d6e-2fe7-0cda-3ba01a3f5691.png)
###Functionノード
Functionノードをおいて
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97061/d09e1bcd-cc71-c2db-fc92-bd8f1b8ea52e.png)

###結合
あとは結んで
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97061/3966c9a0-78cf-0752-1f5f-6cf2a4e58f2d.png)

###確認
InfluxDBのデータExplorerで確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97061/b41113d4-47c9-7471-bba1-122a47301a47.png)

##2つ目のM5Stack(受信側）
こんな感じでJson形式で受信したものの温度だけ表示
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97061/496a54f1-c757-67ff-3d70-486f3f96079b.png)

#結果
M5StickC＋の方を警報灯にしたりできるから、実運用はこの形もありだと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97061/bd985369-f5d1-b617-f43e-ec0cb5a49fe2.png)
【Vue.js】コンポーネント内で実行するメソッドを親コンポーネントから渡す

#はじめに
例えば、ボタンのコンポーネントを作成して様々な場所で使用したいとき。
ボタン押下時の実行メソッドは全てのページで同じとは限らないので、なにを実行するのかを親で渡してあげる方法の紹介です。

たまに忘れてしまうので頭に叩き込むため＆忘れた時用のメモで残します。
何か間違いや、もっといい方法などありましたらコメントで教えていただけると幸いです。

#emitで書いた場合
##子コンポーネントの書き方

```.vue
<template>
  <button
    class="Button"
    @click="clickButton">
    <slot />
  </button>
</template>

<script>
export default {
    name: 'Button',
    methods: {
        clickButton() {
            this.$emit("click-event");
        }
    }
}
</script>

<style scoped>
.Button {
  width: auto;
  padding: 5px;
  text-align: center;
  color: #fff;
  border-radius: 11px;
  background: rgb(80, 156, 80);
}

.Button:hover {
    background: rgba(80, 156, 80,0.3);
}
</style>

```

クリック時に`clickButton`メソッドを呼んでいます。
しかし実際になにを実行するかは親が決めたいので`this.$emit("clickEvent")`と書きました。
　
ボタン押下時は`clickButton`メソッドを呼んで、内容は親でこの`clickEvent`に渡されたメソッドを実行するということですね。

##親コンポーネントの書き方

```.vue
<template>
  <Button
   @click-event="buttonConsole">
    ボタン
  </Button>
</template>

<script>
import Button from '@/components/Button.vue'
export default {
  components: { Button },
  methods: {
    buttonConsole() {
      console.log("親コンポーネントでボタン押下")
    }
  }
}
</script>
```

`@click-event`で`buttonConsole`を渡しました。
ボタンを押下するとconsoleが出力されます。

![757E227D-A698-4003-8B49-C2F28F1FBE4F_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550109/e4132b48-57a8-89e5-da7d-47500d508b7c.jpeg)


#propsで渡した場合
##子コンポーネントの書き方

```.vue
<template>
  <button
    class="Button"
    @click="clickEvent">
    <slot />
  </button>
</template>

<script>
export default {
    name: 'Button',
    props: {
        clickEvent: {
            type: Function,
            required: true
        }
    }
}
</script>
```

クリック時にメソッドを呼びます。
なんのメソッドを実行するかは親から渡せるように`props`に定義しました。
　

##親コンポーネントの書き方

```.vue 
<template>
  <Button
   :click-event="buttonConsole">
    ボタン
  </Button>
</template>

<script>
import Button from '@/components/Button.vue'
export default {
  components: { Button },
  methods: {
    buttonConsole() {
      console.log("親コンポーネントでボタン押下")
    }
  }
}
</script>
```

v-onで子コンポーネントにメソッドを渡しています。
この書き方だとrequirdなどの成約をつけることができます。
rails本番環境（EC2）でWe're sorry, but something went wrong.

#はじめに
現在プログラミング学習を始めて３ヶ月目の初学者です。
学んだことをqiitaに投稿という形でアウトプットするため、また備忘録として記事を作成しました。

開発環境では何も問題なく動いていたのですが、本番環境では
We're sorry, but something went wrong.
と出てしまいました。なのでエラーログの確認からして行きます

##エラーログの確認
参考記事
https://qiita.com/ug23/items/308182bf4e60bc81f04e
https://qiita.com/nkekisasa222/items/d4ef64a5e6b539ed3c37

AWS EC2を使いデプロイしていて、そもそもエラーログの見方から分からなかったので上記の記事を参考にしました。

1.EC2サーバにログイン後、対象アプリのリポジトリに移動。

```
[ec2-user@******]$ cd 対象のリポジトリ
```

2.直下のlogに移動

```
[ec2-user@****** 対象のリポジトリ]$ cd log
```


3.logまで移動したらlsコマンドで直下のファイルを検索。すると以下のように表示される

```
[ec2-user@****** log]$ ls
development.log  production.log  puma-error.log  puma.log
```
4.下記コードを実行し、エラーログを確認

```
[ec2-user@****** log]$ tail -f production.log
```

##エラー内容
ActionView::Template::Error(undefined local variable or method `users_path'
と出ていました。場所は
 app/views/layouts/application.html.erb:31
です。なので試しにviコマンドで31行目をコメントアウトしブラウザのリロードをかけてみました

```
$ vi app/views/layouts/application.html.erb
```

ですが、またもやWe're sorry, but something went wrong.の表示が出てきたので。変更が反映されていないと思い下記のコマンドでプロセス番号を確認し

```
$　ps aux|grep puma
```
キルコマンドで削除

```
$ kill 4405
```
コメントアウトを外しrailsを再起動

```
rails s -e production
```

無事にアプリケーションを立ち上げることが出来ました！


##最後に
qiitaへの投稿に慣れていないので、分かりづらい上に情報が少ないですが、これから欠かさず投稿していこうと思います。
【Vue.js】v-for について

#はじめに
こんにちは！　松本　佑大（まつもと　ゆうだい）と申します！
今回はv-forについてアウトプットしていきます！


#v-forとは
v-forとはvueで配列に基づいて、リストレンダリングする為に使用するディレクティブです。

#書き方
```HTML:HTML
<div id ="app">
  <ol>
    <li v-for="color in colors">{{ color }}</li>
  </ol>
</div>
```
```Vue.js
var app = new Vue({
    el:'#app',
    data:{
       colors:['Red','Green','Blue'],
    }
})
```

![スクリーンショット 2021-10-10 18.07.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2114750/ba2388fc-d07a-58f9-b4ca-ed6483811cda.png)


今回は番号付きでの表示のため`ol`タグを使用しました。
配列名`colors`を設置し、配列の値を定義します。`['Red','Green','Blue']`
HTNL側でolタグで囲み`<li v-for="color in colors">{{ color }}　</li>`というふうに書いてください。

このようにすると上記の画像のように出力されます。




#まとめ
今回のポイントとしては、下記のように、配列名はエイリアス名の複数形にしておくとわかりやすいのでそのように書くことを推奨します。

```HTML:HTML
<div id ="app">
  <ol>
    <li v-for="① in ①s">{{ ① }}</li>
  </ol>
</div>
```

```Vue.js
var app = new Vue({
    el:'#app',
    data:{
       ①s:['Red','Green','Blue'],
    }
})
```


#最後に
今回はv-forについてアウトプットしました。
今回の記事を読んで気になったこと、質問等あればコメント等頂けると幸いです。

今後ともQiitaにてアウトプットしていきます！

最後までご愛読ありがとうございました！
Heroku Railsアプリデプロイ時にrake assets:precompileでNoMethodError: undefined method `[]' for nil:NilClass

久しぶりに `rails new` して Herokuにデプロイした時にエラー

```bash
-----> Preparing app for Rails asset pipeline
       Running: rake assets:precompile
       rake aborted!
       NoMethodError: undefined method `[]' for nil:NilClass
```

# master.keyをHeroku環境変数に設定する

master.keyが登録されていないことが原因でした。
以下のコマンドで解決

```bash
$ heroku config:set RAILS_MASTER_KEY=`cat config/master.key`
```
[Swift]メルカリみたいな手数料を自動計算するプログラムを実装する

メルカリで商品を出品したことがある人ならご存知かと思いますが、販売価格を設定する際に任意の金額を入力すると、自動的(リアルタイム)に手数料と販売利益が算出されて、テキストに反映されるみたいなやつを見たことあるのではないかと思います。

なので今回はそれのやり方を書いていきたいと思います。

ではいきましょう！

<h1>はじめに</h1>

まず、storyBoardでこんな感じのを用意してください

![スクリーンショット 2021-10-17 13.20.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1106647/5f8cfcc3-61e3-d5db-9128-2095f98b104d.png)

本質的には、①ユーザーが実際に金額を入力する部分のTextField、②計算された手数料を反映させるUILabel、③計算された販売利益を反映させるUILabel　の三つが存在してるだけです。

まああとは、見栄えをよくするためにこの三つ全てのtextAlignを右寄せにすると良いと思います。

ではコードに移ります。

<h1>コード</h1>

まずは全体像からです。

```php
import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var settingFeeTextField: UITextField! //入力する部分
    @IBOutlet weak var commissionLabel: UILabel! //手数料を算出する部分
    @IBOutlet weak var finalFeeLabel: UILabel! //最終的な収益を算出する部分
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        settingFeeTextField.keyboardType = .numberPad//数字のみ入力可にする
        
        NotificationCenter.default.addObserver(self, selector: ♯selector(textFieldDidChange(notification:)), name: UITextField.textDidChangeNotification, object: settingFeeTextField)
    }
    
    deinit {
        NotificationCenter.default.removeObserver(self)
    }
    
    @objc private func textFieldDidChange(notification:NSNotification){
        
        let textField = notification.object as! UITextField
       
        let toIntFeeTextField = Int(textField.text!)
        
        let ToZero = toIntFeeTextField ?? 0 

        let calculateCommission = ToZero / 10//10%の手数料
        
        commissionLabel.text = String(calculateCommission)
        
        finalFeeLabel.text = String(ToZero - calculateCommission)
        
        
    }

}
```

では簡単に解説していきます。

まずは、数字しか入力したくないので、キーボードタイプを数字のみに変更してます。

そして、TextFieldのイベントが発火したときの通知を受け取るために、NotificationCenterを設置しましょう。(※UITextFieldが独自に持つメソッドを用いても良いとおもいます。)

そしてそのメソッドの中で、計算をするためにString型をInt型に変更しましょう。

そしてまあ、後はそれらの計算結果をString型に再キャストして、反映するという感じです。

以上です！

(※ちなみに、テキストフィールドの値をnil結合で０を入れておかないと、値が1以下になった時エラーが出るので注意してください。あ、あと手数料はご自身で自由に設定されると良いと思います。)


完成品がこちら

![Qiita動画２.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1106647/d3564619-d802-673b-61b7-860218f8a498.gif)



<h1>最後に</h1>

お疲れ様でした
Nuxt.js×TypeScriptでURL末尾に"/"を追加する(Trailing Slash)

## 背景
本番環境の関係でURLの末尾に"/"を追加したかった。
そのため、vue-routerで遷移したpage全てを/付きでリダイレクトさせたい。

## 手順
middlewareにredirectをする処理を追加

```middleware/redirect.ts
import { Middleware } from '@nuxt/types'

const routing: Middleware = ({ route, redirect }) => {
  if (route.path.slice(-1) !== "/") {
    redirect(301, route.path + "/");
  }
}

export default routing
```

nuxt.config.tsに上記ファイルをセットしてあげる
trailingSlashをtrueにする

```nuxt.config.ts
...
router: {
  middleware: 'redirect',
  trailingSlash: true,
},
...
```

## 参考
https://knote.dev/post/2020-03-19/nuxt-trailing-slash/
https://designsupply-web.com/media/programming/6864/
Nginxとdocker-composeにおける, client_max_body_sizeのエラーに関する対処

<h1>エラーに対する対処</h1>
<p>エラー対処方法のメモ書きです。</p>
<p>Nginxはアップロードできるファイルサイズがデフォルトで定められているので、その変更方法とdocker-composeを使っているが故にありがちなミスを書き記しておきたいと思います。
</p>

<h2>client_max_body_size</h2>
まず、Nginxのアップロード可能なファイルサイズ上限は**client_max_body_size**で指定することができます。（デフォルト上限は1MB）

デフォルト上限を超えるとエラーになるので、アップロード上限を指定しておくと後が楽になるでしょう。


```sh:default.conf
server { #またはhttp{}

  #5MBにアップロード上限を指定
  client_max_body_size 5M 

}
```

<h2>docker-composeでよくあるエラー</h2>

前述した**client_max_body_size**を.confファイルに指定したのにもかかわらず、
コンテナ内に反映されず、ファイルアップロード上限のままになっていることがあります。

この場合、.confファイルをコンテナ内に永続化できていないので、docker-compose.ymlでvolumeしましょう。
また、後で.confファイルを追加する際にいちいちファイルを指定するのも面倒くさいので、conf.dを作成して.confファイルの管理を容易にしておきましょう。

```sh

#Nginxのコンテナにconf.dを作成(.confファイルはconf.dに入れておく)
mkdir nginx-container/conf.d

# --- docker-compose.yml ---

nginx:
  
  volumes:
    - nginx-container/conf.d:/etc/nginx/conf.d

# --- ---

```
VS Code 1.61 の新機能 - 同一エディタ内でのエディタ分割機能

https://code.visualstudio.com/updates/v1_61#_split-an-editor-without-creating-a-new-group

１つのエディタを分割する機能は以前から存在した(`Ctrl`+`￥` や `Ctrl`+`K` `Ctrl`+`￥`)が、その場合はエディタグループが分割する形だった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181011/674054d6-fe26-47f9-b9ea-9727d612a0a8.png)

今回、同じエディタ内でエディタを分割する機能が追加された。

`Ctrl`+`K` `Ctrl`+`Shift`+`￥`を押すとエディタが分割し、もう一度押すと分割が解除される。3分割以上はできないっぽい。

分割された状態でエディタ右上の`レイアウトの切り替え`ボタンを押すと、分割方向の縦横が切り替わる。

![inside_split.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181011/e75909a7-63ed-86b8-6539-b6b4e2f29aa3.gif)

今回新設されたコマンドは以下の通り

- **workbench.action.splitEditorInGroup**
    - コマンド日本語名: `表示: グループ内のエディターの分割`
    - ショートカットキー: `Ctrl`+`K` `Ctrl`+`Shift`+`￥`
- **workbench.action.toggleSplitEditorInGroup**
    - コマンド日本語名: `表示: グループでエディターの分割を切り替え`
    - (補足) トグル操作での切り替え
- **workbench.action.joinEditorInGroup**
    - コマンド日本語名: `表示: グループ内のエディターに参加する`
    - ショートカットキー: `Ctrl`+`K` `Ctrl`+`Shift`+`￥`
    - (補足) 分割を元に戻す
- **workbench.action.toggleSplitEditorInGroupLayout**
    - `表示: グループレイアウトでエディターの分割を切り替え`
- **workbench.action.focusFirstSideEditor**
    - コマンド日本語名: `表示: アクティブエディターで表側にフォーカス`
    - (補足) 分割された側をフォーカスする
- **workbench.action.focusSecondSideEditor**
    - コマンド日本語名: `表示: アクティブエディターで裏面にフォーカス`
    - (補足) 分割した側をフォーカスする
- **workbench.action.focusOtherSideEditor**
    - コマンド日本語名: `表示: アクティブエディターで裏側にフォーカス`
    - (補足) トグル操作でのフォーカス移動

今現在の機能仕様だとコマンド構成にかなり無駄があるように見えるが、いずれ3分割以上できるようになることを見越してのコマンド構成か？

あと、デフォルトのショートカットキーが押しにくい＆ショートカットキー定義がされていないコマンドがあるので、よく使用する場合はカスタムでショートカットキー定義を行ったほうが良さそう。
MELSEC-Q GX Works2のコンパイラの動作を調べる(その2)

前回の続きです。

[MELSEC-Q GX Works2のコンパイラの動作を調べる(その1)](https://qiita.com/fa_yoshinobu/items/02ac2c95937a13695716)

# 配列を使ったST文はどのようにコンパイルされるか
自動割り付けデバイスは次のようになっている場合です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2146151/413e7cd2-c35d-e3d9-f98a-a97c27c82ef1.png)

### Sample1
配列の要素数16個のビット配列を作りL1の内容を転送するロジックです。

```plaintext
(*Sample1*)
index:=1;
array_bit[index]:=L1;
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2146151/2d7181d4-8ab6-3f26-eea4-cb7478c7ef5d.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2146151/749e949f-fe1a-274c-fe76-268cbc6cfa47.png)

### Sample2
配列の要素数128個のビット配列を作ります。ここでは意地悪をして先頭をD0.0のワードデバイスにします。
128/16=8なので配列の大きさは8Wordです。g_array_bit_D0にはD0-D7が割り当てられます(BITとして)
そしてindexの場所にL2の内容を転送するロジックです。
BSET/BRSTを使いちゃんと動きようになってますね。

```plaintext
(*Sample2*)
index:=2;
g_array_bit_D0[index]:=L2;
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2146151/14b9752a-d391-5d95-b26d-d3c6271052f8.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2146151/57d36871-b55e-685e-0b73-521d3d78c28f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2146151/3f013540-795d-c386-7af3-287887d2afc5.png)

### Sample3
配列の要素数16個のワードデータの配列を作りW3の内容を転送するロジックです。

```plaintext
(*Sample3*)
index:=3;
array_word[index]:=W3;
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2146151/8ec641bc-50d3-96a8-a6bc-4f8abfde6e8c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2146151/cbe6eedb-1567-29d9-5072-a1f31bb2456d.png)

### Sample4
配列の要素数128個のワードデータの配列を作ります。ここでは意地悪をして先頭をK4M0のビットの桁指定にします。
4*4*128=2048 なので配列の大きさは2048BITです。
g_array_word_M0にはM0-M2047が割り当てられます(WORDとして)
そしてindexの場所にW4の内容を転送するロジックです。

```plaintext
(*Sample4*)
index:=4;
g_array_word_M0[index]:=W4;
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2146151/14b9752a-d391-5d95-b26d-d3c6271052f8.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2146151/705557d1-b9fb-e3e9-6d55-2da4e62de3f3.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2146151/83fdf645-b0c2-3525-626e-05b59f7665d3.png)
検索結果の加工

今回はSELECT文で取得したデータの加工方法をまとめます！

|   加工内容    　　　　　　　| キーワード|
|-----------------|---------|
| 重複行を除外する    |DISTINCT |
| 結果を並び替える    |ORDER BY|
| 行を限定して取得する |OFFSET FETCH |
| 結果を集合演算する  | UNION,EXCEPT,INTERSECT|

例
・SELECT DISTINCT 〇〇　FROM 〇〇
・SELECT * FROM 〇〇 ORDER BY DESC

のように、DISTINCTのみSELECT文の最初の方に記述するので気をつけてください！
ちなみに、DESCとは検索結果を降順に並び替えるために使用します。
Splunk: テスト用データを用意せずにダミーイベントを作りたい

Splunk のサーチコマンドの動作確認で時々使うのでメモ。

###### 実施環境： Splunk Free 8.2.2

Splunk のサーチコマンドの動作確認を行う際に、テスト用のデータを用意せずサーチ内だけでさくっとダミーイベントを作成したい時があります。
そのような時は、 makeresults コマンドを使用します。

```Splunk:Splunk
| makeresults
```

上記を実行すると、コマンドを実行したサーバ日時を値に持つ _time フィールドのみのイベントが1つだけ生成されます。

![スクリーンショット 2021-09-26 13.30.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/dca3e3fc-acf7-15bb-daec-8b146d7822d2.png "テストサーチ1")

複数のイベントを生成したい場合は、 count オプションに作成したいイベント数を指定します。

```Splunk:Splunk
| makeresults count=5
```

![スクリーンショット 2021-09-26 13.30.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/b0ed5d50-4b90-1286-6974-6b504e3a3a08.png "テストサーチ2")

複数作成しても、 _time フィールドの値は全て同じです。
現在時刻を起点として一定間隔のデータを作成したい場合は、  streamstats コマンドを利用して生成した数列を _time に加算 / 減算することで作成できます。

```Splunk:Splunk
| makeresults count=5 
| streamstats count AS Serial
| eval _time = _time - Serial * 60 * 5 
| fields - Serial
```

![スクリーンショット 2021-09-26 13.37.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/1cb30f2a-a20c-3b17-ea91-32c73e93eb5b.png "テストサーチ3")

起点時刻を指定したい場合は、 eval コマンドの strptime 関数を使用します。

```Splunk:Splunk
| makeresults count=5 
| streamstats count AS Serial
| eval Date = strptime("2021-09-20 12:30:45", "%Y-%m-%d %H:%M:%S")
| eval _time = Date + ( Serial - 1 ) * 60 * 60 * 24 
| fields - Serial, Date
```

![スクリーンショット 2021-09-26 13.48.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/36ab65f3-81e8-7015-ba66-aab21bea879f.png "テストサーチ4")

_time 以外のフィールドを追加する場合は、 eval コマンドを使用します。

```Splunk:Splunk
| makeresults count=5 
| eval Field = "test"
```

![スクリーンショット 2021-09-26 13.49.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/2d295942-99bc-6d52-be8a-37947f754401.png "テストサーチ5")

ランダムな値が必要な場合は、 eval コマンドの random 関数を使用します。
なお、 random 関数は「0から2の31乗-1の間の任意の整数を返す」関数の為、数値の範囲を指定したい場合は%で割り算の余りを取ります。

```Splunk:Splunk
| makeresults count=5 
| eval Number = random() % 100
| fields - _time
```

![スクリーンショット 2021-09-26 13.56.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/a37dee36-0e94-0abe-741d-1adb2da8c05a.png "テストサーチ6")

文字列等数値以外の値にしたい場合は、 if 関数や case 関数を併用もできます。

```Splunk:Splunk
| makeresults count=5 
| eval Judge = if( random() % 2 > 0, "OK", "NG")
| fields - _time
```

![スクリーンショット 2021-09-26 13.58.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/2cbcee8c-a23b-0a74-1902-095c2d9a6254.png "テストサーチ7")

```Splunk:Splunk
| makeresults count=5 
| eval Rand = random() % 3
| eval Judge = case( Rand == 0, "Red", Rand == 1, "Yellow", Rand == 2, "Green")
| fields - _time, Rand
```

![スクリーンショット 2021-09-26 14.07.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/e5463960-ea98-6734-4f4c-ed4dd60fa6fc.png "テストサーチ8")
anyenv + nodenvでNode.jsのバージョンを上げる

個人の忘備録ですが、`anyenv`と`nodenv`でNode.jsのバージョンを管理してる方の役にも立てばと思います。

## 手順

### [STEP1] anyenvアップデート用のプラグインをインストールする

**既に、`anyenv-update`をインストールしてる方は不要**ですが、`anyenv`上に構築してる`nodenv`をアップデートするために、`anyenv-update`というプラグインが必要になるので、まずはインストール。

これを使うと、`nodenv`以外にも、`anyenv`が管理してる`*env(rbenv等)`を一括でアップロードすることができます。

https://github.com/znz/anyenv-update


```terminal
$ mkdir -p $(anyenv root)/plugins
$ git clone https://github.com/znz/anyenv-update.git $(anyenv root)
```

### [STEP2] nodenvを最新にする
上記がインストールされたら以下コマンドを実行。

```terminal
$ anyenv update
```


## [STEP3] Node.jsの必要なバージョンをインストールする

インストール可能なリストを出力

```terminal
$ nodenv install -l
```

例えば `14.18.1` をインストールしたい場合

```
$ nodenv install 14.18.1
```

### [STEP4]Node.js を新しいバージョンに切り替える

対象のバージョンがインストールされてるか確認

```terminal
nodenv versions
```

ローカル(カレントディレクトリ配下で利用するバージョン)を設定する場合

```terminal
nodenv local 14.18.1
```

グローバル(システム全体で利用するバージョン)を設定する場合

```terminal
$ nodenv global 14.18.1
```

以上。
S3の静的ウェブサイトで複数のサブフォルダーをホストする

# やりたいこと
S3バケットに複数のサブフォルダーを追加して、`https://domain_name/folder_name`でそれぞれのフォルダーにアクセスできるようにする

# 目次
<!-- タイトルとアンカー名を編集 -->
1. [設定](#1-設定)
1. [エラー](#2-エラー)
1. [参考文献](#3-参考文献)

#1. 設定

#### S3バケットにサブフォルダーを追加する
例

```
BUCKET_NAME/portfolio
BUCKET_NAME/website_1
BUCKET_NAME/website_2
```

#### それぞれのサブフォルダーにドキュメントルートとしてindex.htmlを設置
例

```
BUCKET_NAME/portfolio/index.html
BUCKET_NAME/website_1/index.html
BUCKET_NAME/website_2/index.html
```

#### CloudFrontディストリビューションの設定を変更

##### 対象のディストリビューションを選択して、Error pagesタブへ移動
##### カスタムエラーレスポンスを作成
1. エラーコード403を選択
2. `response page path`を`index.html`に設定
3. 作成
![Screen Shot 2021-10-17 at 10.33.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2106354/5335ba97-0808-3659-056b-203b7141dca6.png)
![Screen Shot 2021-10-17 at 10.30.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2106354/facc3ec0-3349-8521-aa2b-4d37f11c7d6f.png)

##### 動作確認
ディストリビューションがデプロイされたら、`https://domain_name/folder_name`でアクセスをしてエラーが出なければ完了

#2. エラー
上記の設定をしても、403エラーのリダイレクトがされない場合に確認すること
CloudFrontディストリビューションのorigin nameはS3静的ウェブサイトのエンドポイントを設定する
例
⭕️`BUCKET_NAME.s3-website-ap-southeast-1.amazonaws.com`

origin nameがS3バケットそのもののエンドポイントだとリダイレクトがうまくいかない
❌`BUCKET_NAME.s3.ap-southeast-1.amazonaws.com`

<a id="#Chapter2"></a>
# コメント
ベストプラクティスではないかもしれないけれど、個人や社内のトレーニング用で複数のウェブサイトを一つのバケットで管理したいときに便利だと思った

<a id="#reference"></a>
#3. 参考文献
- [AWS S3で静的ウェブサイトをホスティングする](https://qiita.com/suuungwoo/items/2e49c3008a04e48581ed)
OAuth とは？ 概要を確認

## 勉強前イメージ

認証の仕組みだけど
特徴とかは言えない覚えてない・・・

## 調査

### OAuth とは

オーオースと読み、webサーバのリソースへのアクセス権限を代理で行うことを許可するためのプロトコルになります。
OAuthを使用することで、クライアントにユーザ名やパスワードを知らせることなく、
サーバのリソースを第三者へアクセスさせることができます。
現在はOAuth 2.0が標準化されています。

OAuthではシステム間でアクセストークンを使用し、受け渡すことで権限の認可を行っております。
利用者の認証情報そのもののやり取りはありません。
認証情報のやり取りを行わず、サービス同士を連携させることができます。

### 登場人物

OAuthには3つの登場人物が主にいます。

- OAuth Service Provider

ユーザの認可情報を第三者に渡すサービス

- OAuth Consumer

Service Provider から認可情報を受け取って、
情報へアクセスしたり追加など行うサービス

- User

使用者側で、
Service ProviderがConsumerにアクセスすることを許可したりなど行う

### ユースケース

よくあるのが以下のような流れです。

例えばアルバムサービスに画像を投稿すると、
同じような投稿や、投稿した旨をSNSサービスに自動で投稿する というようなことでOAuthが使われています。

![1# OAuth とは？ 概要を確認 - diagrams.net - Google Chrome 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/1760c75e-9765-c97b-9972-7bb58214f5fe.png)


## 勉強後イメージ

ログインとかにも使われる・・・
あれ？なんかいろいろ勘違いしてたことあったかも。。
まだ概要だけだから詳細は今度。

## 参考

- [第1回　OAuthとは？―OAuthの概念とOAuthでできること](https://gihyo.jp/dev/feature/01/oauth/0001)
- [OAuthとは？その仕組みを徹底解説〜便利と危険は裏返し〜](https://www.tdk.com/ja/tech-mag/knowledge/147)
【勉強記録】ソート (paizaランク C 相当)

## 目次

- 問題文
- 私の解答
- 解答例
- 私の解答（２回目）
- 学んだこと
- 振り返り
- 一言

## 問題文 
[詳細はコチラ](https://paiza.jp/works/mondai/c_rank_level_up_problems/c_rank_sort_boss)

###問題文の要約
[x, y]の組み合わせでデータをn個渡すので、yの値でソートせよ。

>入力例2
4
2 3
0 4
5 0
3 3

>出力例2
0 4
3 3
2 3
5 0

## 私の解答(1回目：誤りです。)

``` main.py
num = int(input())
lis = []

for i in range(num):
    a =list(map(int, input().split()))
    lis.append(a)

lis.sort(reverse=True)

for i in range(num):
    for x,j in enumerate(lis[i]):
        if x == 0:
            print(j, end = " ")
        else:
            print(j)
```
[x,y]の組み合わせが複数入る二次元配列の中で、どういう形でソートされてるのかよく分からないまま作成。
reverse=Trueは単純にxを起点として昇順、降順が入れ替わるだけで、yはあくまでソートの順としては2番手。
頭が混乱してenumerateを使ってしまったのですが全く不要。


## 解答例（コメントアウト部分を追記）

``` main.py
N = int(input())
kingin = [0] * N

for i in range(N):
    [a, b] = [int(j) for j in input().split()]
    kingin[i] = [b, a] # 2文字目でソートするため入れ替えている

# print(kingin) # [[3, 2], [4, 0], [0, 5], [3, 3]]
kingin.sort(reverse=True)
# print(kingin) # [[4, 0], [3, 3], [3, 2], [0, 5]]

# 表示は1文字目を前に戻す
for i in range(N):
    [a, b] = kingin[i]
    print(b, a)
```
値を格納する際に1,2文字目を入れ替えてからソートする。出力する際には戻すということがポイントですね。
ソートの仕様の理解が深まりました。


## 私の解答（2回目）
``` main.py
num = int(input())
squere = []

for i in range(num):
    [kin, gin] = map(int, input().split())
    a = [gin, kin]
    squere.append(a)

squere.sort(reverse=True)

for i in range(num):
    [gin, kin] = squere[i]
    print(str(kin)+ " " + str(gin))
```
時間をおいて再挑戦しました。
文字の入れ替えがやや強引です。
が、変数名の名づけなどは問題文に沿った形にしたのでパッと意味が分かる命名が出来たと思います。

## 学んだこと
1. ソートの仕様
1. 値の受け取り方、ばらし方

## 一言
問題文の読み込みのスピードアップ、使い方のバリエーションを増やすことを目指します！