OmniAICreator/Qiita-1.07M huggingface dataset:
Rails resourcesとは(実務に向けた解説)

# resoucesとは
Railsで定義されている7つのアクションのルーティングを自動で作成するメソッドです。
resoucesを使うことで簡単にルーティングを作成できる.


```routes.rb
Rails.application.routes.draw do
  resources :コントローラー名
end

```
・Railsで定義されている7つのアクション
|アクション名|役割|
|--|--|
|index|リソースの一覧を表示させる|
|show|リソースの詳細を表示させる|
|new|投稿フォームを表示させる|
|create|リソースを追加させる|
|edit|更新フォームを表示させる|
|update|リソースを更新させる|
|destroy|リソースを削除する|

例えば```users```なら
```routes.rb
Rails.application.routes.draw do
  resources :users
  root 'users#index'
end
```
***usersリソースに対する以下のような7つの標準的なアクションに対するルーティングが生成***されます。
idは今回は１ということにします。

|HTTPリクエストメソッド|URL|アクション|用途|
|---|----|----|----|
|GET|/users|index|すべてのユーザーを一覧するページ|
|GET|/users/1|show|id=1のユーザーを表示するページ|
|GET|/users/new|new|新規ユーザーを作成するページ|
|POST|/users|create|ユーザーを作成するアクション|
|GET|/users/1/edit|edit|id=1のユーザーを編集するページ|
|PATCH|/users/1|update|id=1のユーザーを更新するアクション|
|DELETE|/users/1|destroy|id=1のユーザーを削除するアクション|

> 引用　　https://railstutorial.jp/chapters/toy_app?version=7.0#table-demo_RESTful_users
			
# 複数のコントローラーなら
複数のコントローラーのルーティングを下のように一行で定義することができます。

```routes.rb
Rails.application.routes.draw do
  resources :コントローラー名, :コントローラー名
end

# (例)officesコントローラーとusersコントローラーの7つのアクションのルーティングが作られる
  resources :offices, :users
```
# 現場ではonlyもよく使われる
***resourcesでonlyオプションを使用***すると、***生成されるルートが特定のアクションに制限***されます。```only```は、***不要なルートを生成せずに、特定のアクションだけを含むルートを生成する時***に使います。

```
resources :users, only: [:index, :show]
```
みたいな感じです。具体的なコードで見ていきます。コードはChatGPT参照。
resourcesメソッドを使用したルーティングの具体例で、
この例では、articlesというリソースに対するRESTfulなルーティングを考えです。
```routes.rb
Rails.application.routes.draw do
  # "articles" リソースに対する全てのRESTfulなルートを生成
  resources :articles

  # "comments" リソースに対する特定のルートだけを生成
  resources :comments, only: [:index, :show, :new, :create]

  # "authors" リソースに対するルートを "destroy" を除いて生成
  resources :authors, except: [:destroy]

  # "reviews" リソースに対するカスタムな名前のルートを生成
  resources :reviews, path: 'opinions', controller: 'feedback'

  # "posts" と "comments" のネストされたルートを生成
  resources :posts do
    resources :comments
  end

  # "profiles" リソースに対するルートをカスタムコントローラーで生成
  resources :profiles, controller: 'users_profiles'

  # "tags" リソースに対する特定のフォーマットの制約を追加
  resources :tags, format: true

  # その他のカスタムなルート
  get 'dashboard', to: 'dashboard#index'
end
```
アルゴリズムクイックリファレンス

# サマリ

グラフや木構造に少し親しみが持てました(^^)

# アルゴリズムの数学

- 単一の最適アルゴリズムは存在しない
    - 最良時、平均時、最悪時を考える
- 性能比較（高い順）
    - 定数 O(n)
    - 対数 O(log(n))
    - 下位線形
    - 線形
    - nlog(n)
    - 2乗
    - 指数

# パターンとドメイン

- アルゴリズムパターン
    - 名前
    - 概要
    - 文脈
    - 効力
    - 解
    - 結果
    - 分析
    - 関連アルゴリズム
- 性能は、最良と最悪を捨て、k-2の平均と分散で評価
- メモリリークの話

# 整列アルゴリズム

- 挿入ソート
    - ７並べみたい
    - 要素数が少ないときに強い
- 中央値ソート
- クイックソート
    - 軸要素を選び大小の交換
    - 平均的に速い
- 選択ソート
    - 遅い
- ヒープソート
    - クイックソートがだめなら
    - 二分木
    - 最悪時でも速め
- 数え上げソート
    - 並べ替えのユニークな数字が少なければ、最速
- バケットソート
    - データがとりうる値がわかっていれば、超高速
    - 整列済みのバケツにハッシュでデータを投入していく

# 探索

- 逐次探索
- 二分探索
    - 整列済みのdataに強い
- ハッシュに基づいた探索
    - オンメモリで最強
- 二分木探索
    - 2次記憶にある状態でも性能が出る
    - dataの変更が多く行われる場合によい
    - 赤黒木がいい

# グラフアルゴリズム

- 探索
    - 幅優先探索
    - 深さ優先探索
- 最短経路問題
    - ダイクストラアルゴリズム
        - 正の重み付きグラフ
    - ベルマンフォード法
        - 正負対応
- 全対最短経路
    - フロイドワーシャル法
- 最小被覆木アルゴリズム
    - プリム法

# AIにおける経路発見

- ゲーム木
- 探索木
- A*探索

# ネットワークフローアルゴリズム

グラフに容量が与えられる問題

- 割当問題
    - コスト最小化
- 二部マッチング問題
    - マッチング最大化
- 輸送問題
    - コスト最小化
- 積替え問題
- 最大フロー問題
- フォード・ファルカーソン法で大体解ける
- 線形プログラミングでも大体解ける
    - 等式不等式で与えられた制約下で線形目標関数を最適化する技法


# 計算機何学

- 点、線、多角形といった幾何学的対象を扱う
- 凸包
    - 点集合のすべてを含む最小の凸形状
- 線分交差
- 凸包走査
    - 凸包を計算するアルゴリズム
- 最近傍質問
    - 区画方式
    - ボロノイ図法
    - KD木
        - O(logn)
- 範囲質問

# その他

- B-tree
- B+tree
MoveIt!についてざっくりと説明

Unity公式のRoboticsHUBではロボットのモーションプランニングにMoveItが使用されていたので、ざっくりとできることを調べてみました。

https://github.com/Unity-Technologies/Unity-Robotics-Hub

#概要
ROS通信用オープンソース産業用ロボティックスプランニングフレームワーク
グリッパーを指定した姿勢への経路を計算し、移動させるマニュピレーターの制御に向いている。
ライセンスはBSD

# モーションプランニング（動作計画）
衝突を回避した軌道予測を行うことができる。
稼働域の制限を考慮した動作になる。
計画に利用できるアルゴリズムは複数から選択することができる。

# ロボットの操作
ロボットでワークを掴んだり、離したりする制御が用意に実現できる。

# 3D環境知覚
センサ等を使用し、周囲の環境を取り込むことができる。

# 逆運動学(IK)
特定の座標にアームを動かすための姿勢を推定することができる。

# 順運動学
アームの位置から座標を取得することができる。

# 衝突チェック
周囲の環境衝突が発生しないパスを計画することができる。
自己の衝突も検知できる。
URDFに定義されたメッシュを使用して判定を行う。

# GUIシミュレーター
RVizを用いたGUIシミュレーションができる。

# 物理シミュレーター
Gazeboを用いたシミュレーションができる。

# 簡単なロボットのセットアップ
URDF,SRDFファイルからRobotModelを構築できる。

#### URDF（Unified Robot Description Format）
ROSおよびROS2でロボットを記述するためのフォーマット
各ロボットメーカーから入手できる。
サンプルは以下の通り。

https://wiki.ros.org/urdf/Examples

# MoveIt Commander
PythonまたはC++用のユーザ向けライブラリで、ロボットの動作計画の基本APIをROSの知識なく利用できる。RoboticsHUBではRVizを使用していないので、こちらを利用しているはず。
git pull でコンフリクト？だかなんだかが出る

今回は自分のための記事です．

gitコマンドで最新のソースコードを常に保持していたい．
ただ，実験PCは複数台あるから，だれかが少し書き換えたら，pullでエラー吐く．

そのエラーは下記．

```
error: Your local changes to the following files would be overwritten by checkout:
    test.txt
Please commit your changes or stash them before you switch branches.
Aborting
```

gitは調べればたくさん出てきます．
私はそこまで詳しくないので，解説できません．

git pullをした際に，マージする？スタッシュする？みたいに聞いてきます．
独自に編集したものが消えちゃうけど大丈夫？ってgit側が親切に聞いてくれてます．
git pushを強制的に行うコマンドは存在するが，git pullを強制的に行うコマンドは存在しないらしい．

じゃあ，どうすれってんだよ
１番クリーンなのは，全て消して，クローンし直すこと．
ソースコード群が重いと，クローン自体の時間がかかりすぎる．

便利なリセットコマンドを発見．

git reset --hard origin/○○○

○○○はブランチ名を入れてください．

解釈としては，
ブランチの状態をリセットして，○○○○ブランチの最新の状態に合わせるものだと解釈．
【react-router-dom】現在のページのURLのparamsを参照できるuseParamsをざっくり紹介【React】

<h2>useParams</h2>
URLからparamsを受け取って、値を取得することは多々あると思います。

今回はそんな場面で使えるuseParamsをご紹介します。

いくつか方法があるかと思いますが、一番シンプルに値を取得できるやり方なのではないでしょうか。

<h2>実装方法</h2>
こちらがuseParamsの実装例です。<a href="https://reactrouter.com/web/api/Hooks/uselocation">公式ドキュメント</a>よりお借りしました。

useParamsをインポートし、ファクション内で、変数に代入して、そのparamsの値を文字列に入れて表示させるといったものになっています。


```react
import React from "react";
import ReactDOM from "react-dom";
import {
  BrowserRouter as Router,
  Switch,
  Route,
  useParams
} from "react-router-dom";

function BlogPost() {
  let { slug } = useParams();
  return <div>Now showing post {slug}</div>;
}

ReactDOM.render(
  <Router>
    <Switch>
      <Route exact path="/">
        <HomePage />
      </Route>
      <Route path="/blog/:slug">
        <BlogPost />
      </Route>
    </Switch>
  </Router>,
  node
);
```
<h2>参考</h2>

https://reactrouter.com/web/api/Hooks/uselocation
特定ユーザーのQiita記事一覧を得る(1)

#Qiitaは人のためならず

自分は誰のためでもない、未来の自分のためにQiitaの記事を書いています（つまりすぐ忘れる）。
最初のうちは結構いい感じに機能していましたが、記事が増えるにつれ、マイページから自分の記事を探すのがつらくなってきました。
で、自分の記事一覧を表示するスクリプトを用意しました。
ローカル環境でも動作します。
[動作デモ](https://elix.jp/app/tools/qiita_index.html?uuid=ELIXIR)

#やっぱ自分のためなり

実際に使ってみて感じたのですが、自分の記事の一覧を得るためというより、他の人の記事一覧を得るのにとても有用でした。
やっぱり良い記事を書いている人は良い記事を量産していることが多いですね。
タイムラインから「いい記事だな」と思った記事を書いたユーザーIDをコピペして、その人が書いた記事一覧を眺めるのにとても役に立っています。

[qiita_index.html?uuid=baby-degu
](https://elix.jp/app/tools/qiita_index.html?uuid=baby-degu
)とか。

#ソースコード
myindex.htmlという空のファイルを作成し、下記の内容をコピペしたらダブルクリックで動作します。

追記：最新ソースコードは[こちら](https://qiita.com/ELIXIR/items/417275e4c751c1fb59a0)です

```[myindex.html]
<!DOCTYPE html>
<html>
<head><title>user</title>
  <script>
    const USER_ID='ELIXIR'; // 自分のuser_idに変えてください
    var resArr = [];
    function onload(){
      document.title=USER_ID;
      getUser();
    }

    function getUserCB(){
      getData(Math.floor((this.response["items_count"]+99)/100));
    }
    function getUser(){
      resArr = [];
      var req = new XMLHttpRequest();
      req.responseType="json";
      req.addEventListener("load", getUserCB);
      req.open('GET', 'https://qiita.com/api/v2/users/'+USER_ID, true);
      req.send();
    }

    function getDataCB(){
      resArr=resArr.concat(this.response);
      if(this.page>1){
        getData(this.page-1);
      }else{
        dispData(resArr);
      }
    }
    function getData(_page=1){
      var req = new XMLHttpRequest();
      req.responseType="json";
      req.page=_page;
      req.addEventListener("load", getDataCB);
      req.open('GET', 'https://qiita.com/api/v2/users/'+USER_ID+'/items?per_page=100&page='+_page, true);
      req.send();
    }

    function dispData(_resArr){
      var result = document.getElementById('iResult');
      var str="";
      for(i=0;i<_resArr.length;++i){
        str += '<a href="'+_resArr[i]['url']+'" target="_blank">'+ _resArr[i]['title']+'</a><br/>';
      }
      result.innerHTML += str;
    }
  </script>
</head>
<body onload="onload()">
  <div id="iResult">
  </div>
</body>
</html>
```
#結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/dc5f31c8-95d0-8955-217a-46676ffe96b6.png)

今回はとりあえず記事一覧を表示しています。
[次回以降](https://qiita.com/ELIXIR/items/dcdab71d6c81ea5a82f2)で、タグでフィルタリングしたりできるようにしたいと思います。
複数ホストから一斉にファイルを回収する

[前回はこちら](https://qiita.com/mashi0923/items/169ca40f53b2cd9392de)
前回のおまけのような内容です．

前回は一斉にプログラムを動作させる方法を記載しました．
今回は複数ホストから一斉にファイルを回収する方法を載せておきます．

使い方はなんら変わりません．

```paramiko_copy.py
#!/usr/bin/python3
 
import paramiko
import os
import datetime as dt
import scp
 
user = "username"
passwd = "PASSWD"
 
with open("host.txt") as f:
    s = f.readlines()
 
host_name = []
for i in range(len(s)):
    if s[i].startswith('#'): 
        pass
    else:
        host_name.append(s[i].replace("\n",''))
print(host_name)
 
path = "/home/user/paramiko/result/"
for i in range(len(host_name)):
    target_host = host_name[i]
    file_name = path + "*.txt"
    with paramiko.SSHClient() as ssh:
        # 初回ログイン時
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        # ssh接続する
        ssh.connect(target_host, username=user, password=passwd)
 
        print('[SCP転送開始]')
        # scp clientオブジェクト生成
        with scp.SCPClient(ssh.get_transport(), sanitize=lambda x: x) as scp:
            # scp送信する場合はput
            #scp.put('test.csv', '/home/user/paramiko/result/')
 
            # scp受信する場合はget
            scp.get(file_name)
```

プログラム下部のscp.SCPClient(ssh.get_transport(), sanitize=lambda x: x)の <font color="Red">sanitize=lambda x: x</font>は非常に重要である．
今回私は\*.txtでファイルを回収しようと考えていたが，サニタイズをしなければ，*(アスタリスク)も通常の文字として判定されてしまう．
ワイルドカードを使わない場合は必要ないかと思うが，実験の結果などは，同一拡張子で保存することが多いので，私はワイルドカードをたくさん使います．
躓いたので参考までに．

[サニタイズについて](http://ja.uwenku.com/question/p-zjyyvlic-gx.html)

[サニタイズをもっとわかりやすく](https://wa3.i-3-i.info/word16265.html)
YouTubeの動画を2.5倍速や4倍速で再生するブックマークレット

## V1

https://chrome.google.com/webstore/detail/smasurf-for-web-browser-e/kbilhcaegfmcpmlnpcogdgfchpodhcih

最初は拡張を使っていましたが、この程度のことに拡張を使うのには抵抗がありますし、6倍速にしたかったのに出来なかったのでやめました。

## V2

とりあえず知ってる関数だけで書きました。たまに動きませんでした。

```js
javascript:document.querySelector('video').playbackRate = 6
```

## V3

たまに動かないのは複数のvideoタグがあるためだと考え、`Array.from`で対応してみました。第二引数に関数を渡すと`map`相当のことができます。

```js
javascript:Array.from(document.querySelectorAll('video'), e => e.playbackRate = 16)
```

## V4

しばらくV3の実装で動いていましたが、後で見るリストを使っていると動画の切り替え時に再生速度がリセットされてしまうという事象に見舞われました。videoタグの仕様を研究・観察してV4を完成させました。動画の切り替え時に`loadedmetadata`イベントが発火するのでその度に`playbackRate`を変更するという実装にしました。`addEventListener`を使用していないのは、他の再生速度への切り替えをページを更新することなく行うためです。

```js
javascript:((v,h)=>{h({target:v});v.onloadedmetadata=h})(document.querySelector('video'),e=>e.target.playbackRate=2.5)
```

```js
(
  (videoElement, handler) => {
    handler({ target: videoElement })
    videoElement.onloadedmetadata = handler
  }
)(
  document.querySelector('video'),
  e => e.target.playbackRate = 2.5
)
```

## おまけ

後で見るリストから再生済みの動画を削除するコードです。1クリックで全消しできればいいのに、なぜか3回クリックしないと消せない仕様になっていてイライラしたので作りました。

```js
javascript:(h=>{h('ytd-playlist-sidebar-renderer yt-icon-button',()=>{h('ytd-menu-service-item-renderer',()=>{h('tp-yt-paper-button',()=>location.reload(),1000)})})})((n,f,t=100)=>{Array.from(document.querySelectorAll(n)).pop().click();setTimeout(f,t)})
```

ブックマークレットで安全に変数宣言する最短の方法が即時関数なので、同じ関数を何度も使うために関数の引数に関数を渡しています。`setTimeout`をPromiseで包めばネストを減らせますが、`new Promise`と書く文字数がもったいなかったのでコールバック形式にしました。`Array.from(...).pop()`は最後の要素を取り出すためにやっています。

```js
(
  handler => {
    handler(
      'ytd-playlist-sidebar-renderer yt-icon-button',
      () => {
        handler(
          'ytd-menu-service-item-renderer',
          () => {
            handler(
              'tp-yt-paper-button', 
              () => location.reload(),
              1000
            )
          }
        )
      }
    )
  }
)(
  (name, func, time = 100) => {
    Array.from(
      document.querySelectorAll(name)
    ).pop().click()
    setTimeout(func, time)
  }
)
```
PHPで配列の要素を部分一致で検索する方法 ( preg_grep )

# PHPで配列の要素を検索する方法
学べること
- preg_grepの使い方
- 変数を検索する場合の正規表現
## preg_grep

検索してマッチする配列の要素を返します。
- 使い方


``` php 
$array = ['hoge','huga'];
$result = preg_grep('/ho/',$array);
var_dump($result);

//出力結果
// array(1) {
//   [0] =>
//   string(4) "hoge"
// }
```

- 解説

preg_grepの第一引数には検索する文字列、第二引数には配列を入れます。
ここでは配列の要素で"ho"が含まれるものを検索しています。$resultには検索にマッチした要素が配列として入っています。


ちなみに、第一引数の検索する文字列を囲ってるスラッシュはデリミタ（区切り文字）と呼ばれ、スラッシュじゃなくてもかまいません。例えば`'{ho}'`でもOK.

## 検索文字列が変数の時


それでは、検索する文字列が変数だった場合はどうしましょう。
上記に従うと、以下のパターン1のようになるはずです。

```php
$array = ['hoge','huga'];
$search = 'ho';
//パターン1
$result = preg_grep('/$search/',$array);
```

しかし、これでは$searchそのものが検索ワードとして扱われてしまうのでダメ。
ちなみに`preg_grep($search,$array);`もだめ。これはデリミタがないですね。
ではどうするかというと、以下のように書きます。

```php
//パターン2
$result = preg_grep('/'.$result.'/',$array);

//パターン3
$result = preg_grep("/$result/",$array);
```
上記のパターンだとそれぞれ変数展開されます。

クォーテーションの違いは下記記事が参考になるかと！
[PHPのダブルクォーテーションとシングルクォーテーションの違いを理解する](https://qiita.com/bitcoinjpnnet/items/64458299eaeefbacab44)

もちろん
`preg_grep('{'.$result.'}',$array);`
とか、
`preg_grep("/{$result}/",$array);`
でもOK。

こちらもご参考に。
[文字列の中の変数展開についてまとめました](https://eng-entrance.com/php-string-variable)

今回は部分一致で検索する場合を紹介しましたが、完全一致で検索する場合は`in_array()`を使いましょう！

でわでわ。
同一ネットワーク上の複数ホストに対して，一斉実行命令を出す(on python3 paramiko)

私が普段学校で実験を行う際に，複数のホストで一斉にプログラムを動かしたいときが有ります．
人手があれば，1人1台張り付いて実行すれば良いですが，深夜に実験を回すこともあるので，1人で複数ホストに対して一斉に実行命令を出すことができれば効率が上がると考え，実装しました．
同様の環境を構築したい方は，参考にしていただけると幸いです．

#実行環境と使用ツールのインストールなど
命令を送るPC：Debian11(test)
命令を受け取るホスト：ラズパイ(Debian)
今回はラズパイに向けて実行してますが，PCでも問題ないです．

命令を送るPCのPythonのバージョン
Python 3.9.2

環境構築に向けて，インストールしなければいけないものがあります．
それはparamikoというパッケージ？モジュール？です．

```
$ aptitude search paramiko
i   python3-paramiko      - Make ssh v2 connections (Python 3) 

もしくは

$ sudo apt-get install python3-paramiko -y

もしくは

$ pip3 search paramiko
# - - - - - - - - - - - - - - - - - - #
# pip3 search はうまく実行されないという記事が
# 投稿されているので，
# 素直にapt　or aptitude で入れるのが
# スマートでしょう．
# - - - - - - - - - - - - - - - - - - #
```

#プログラムを動かす前の準備

今回私が作成したプログラムは，同一ディレクトリ内に，host.txtというテキストファイルをおいておきます．
その内容は，記載してあるホスト名を読み込み，通信を行います．
host.txtは以下のようになっています．(一例)

``` host.txt
host1
host2
#host3
#host4
host5
#host6
```

上記のようにホスト名を記載します．
先頭に#が付いているホストはプログラム内部では通信対象ホストから外れます．
いちいち消して，通信するときに書いてもいいですが，めんどいのでコメントアウト的な感じにしておきました．
リモートホストの場合は不具合などで通信対象から外れることもあるかと思いますので，そのような仕様にしています．

host.txtに記載してあるホスト名は，/etc/hostsに記載しておいてください．
そうしないと，ホスト名がわかりませんというエラー吐きます．

体感速度ですが，動作時間は非常に短いので，host.txtに記載する順番は大きく影響しませんが，順番通りに書いたほうがわかりやすいと思います．


#使用方法

host.txtに書いてあるホストに対して，forループで順番にコマンドを送りつけます．

```paramiko_sample.py
#!/usr/bin/python3

import paramiko
import os
import time

user = "username"        # sshログイン時のユーザー名
passwd = "PASSWD"    # sshログイン時のパスワード
command = "python3 /home/username/paramiko/sample.py"
#commandには "ls" や "pwd" などターミナル上で打ち込むコマンドも使えます．
host_name = []     #

with open("host.txt") as f:
    s = f.readlines()

for i in range(len(s)):
    if s[i].startswith('#'):
        pass # startswithは先頭が#で始まるかどうかを判定しています．
    else:
        host_name.append(s[i].replace("\n",''))

for i in range(len(host_name)):
    target_host = host_name[i]
    with paramiko.SSHClient() as ssh:
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        # 初回ログイン時の(yes/no)?ってやつを飛ばしてくれます．非常に便利
        ssh.connect(target_host,username=user,password=passwd)
        # ここでリモートホストに対して接続を行います．
        stdin,stdout,stderr = ssh.exec_command(command)
        # ここで，コマンドを送りつけます．
        # stdin  -> 標準入力
        # stdout -> 標準出力
        # stderr -> エラー表示
```

これであらかたの説明は終わりました．
最後にちょこっと諸注意を述べておきます．

#諸注意

勘の良い方は気づいたかと思いますが，commandのファイル名を絶対パスにしています．
それはなぜかといいますと，paramikoでログインした際の自分の居場所?(pwdコマンド)は/home/usernameにいます．
ホームディレクトリでプログラム量産している方は少数派だと思います．
必ず，どこかのディレクトリ内部にプログラムなどなどが配置されていると思います．
なので，絶対パスで記載してください．
確実にエラー吐きます．
file not found系のエラー出てきますよ．

## 更に感のいい人は気づいたかな？
リモートホストPCで実行する以下のプログラム
command = "python3 /home/username/paramiko/sample.py"
sample.pyの内部で，ファイルを読み書きするなど，ファイルパスを記載している方は更に注意が必要です．

仮にsample.pyの内部が以下のような内容だったとしましょう．

```sample.py
FILE="./dir1/hogehoge.txt"
with open(FILE) as f:
    s = f.readlines()
```

通常のsshログインで動かす場合は，以下のようにcdコマンドでディレクトリを移動するので問題ありません

```
$ cd paramiko
$ pwd
/home/username/paramiko
$python3 sample.py
```

ですが，これがparamikoを使っての遠隔だと，cdコマンドを入力してないので，
自分の居場所はホームディレクトリです．
そこで，sample.pyを実行したところで，ホームディレクトリ下にdir1というディレクトリが存在しないのです．
もちろん実行できません．
なので，ファイルのパスを記載する場合は，必ず，絶対パスで記載したほうが，読み書き関係でエラーはなくなると思います．
Apache 2.2系とApache2.4系での海外IPのアクセス制限方法 ( AH01797: client denied by server configurationとエラーが出る場合)

### 実行環境
Apache/2.2.15 (Unix)
→ Apache/2.4.37 (centos)


### 概要
`.htaccess` ファイルで国外IP制限をしていたところ、サーバーのリプレイスで書き換えが発生しました。
以下は同じ内容をApacheのバージョンが `2.2系` から `2.4系` に書き換えた場合と、そうしなかった場合に起こりうるエラーの説明です。

Apache 2.2系

```
### 検索エンジンをまとめて許可
SetEnvIf User-Agent "Googlebot" allowbot
SetEnvIf User-Agent "msnbot" allowbot
SetEnvIf User-Agent "bingbot" allowbot
SetEnvIf User-Agent "Slurp" allowbot
## 一旦すべて拒否して
order deny,allow
deny from all
## 改めて、検索エンジンからのアクセスを許可
allow from env=allowbot

## SearchConsoleのプロパティ確認用の対策
allow from googlebot.com
allow from google.com
## 国外IPからのアクセスを拒否 
allow from 1.0.16.0/20
allow from 1.0.64.0/18
~
```

Apache 2.4系

```
## 検索エンジンをまとめて許可
SetEnvIf User-Agent "Googlebot" allowbot
SetEnvIf User-Agent "msnbot" allowbot
SetEnvIf User-Agent "bingbot" allowbot
SetEnvIf User-Agent "Slurp" allowbot

## 一旦すべて拒否

<RequireAny>
    Require all denied
    ### 検索エンジンからのアクセスを許可
    Require env allowbot
    ## SearchConsoleのプロパティ確認用の対策
    Require host googlebot.com
    Require host google.com

    ### 日本国内のIPを許可(国外IPからのアクセスを拒否)
    Require ip 1.0.16.0/20
    Require ip 1.0.64.0/18
    ~
</RequireAny>
```

#### 書き換えた`.htaccess`ファイルのデバグ方法<br>
[こちらのサイト](https://www.webpagetest.org/)を開き、検証したいURLを入力。適当な国を選び「Start Test」をクリックでテスト開始です。
結果ページで「Screenshot」か「View Test Log」をみて、無事403エラーとなっていれば国外IP制限できていると確認できます。
ちなみに、結果ページのURLは個別に発行されるため容易にシェアも可能、かなりお気に入りです。
#### 書き換えをしてなかった場合
Apache 2.4系の環境にて、上記の書き換えを行わない場合は以下のサーバーエラーがログ出力されると思います。

```
Error    12.345.678.9012        AH01797: client denied by server configuration: /var/www/vhosts/qwerty.com/httpdocs/            Apache エラー
```

### 参考
検索エンジンbot一覧
https://www.casis-iss.org/ex1911/
検索エンジンのプロパティ
https://support.google.com/webmasters/answer/80553?hl=ja
日本国内IPの一覧
http://www.cgis.biz/tools/access/
SQLのクセにfor文が使えるとは・・

# はじめに
長らくプログラムで飯を食ってますが、SQLでfor文のような繰り返しができることを初めて知って衝撃を受けたので投稿します。
入れ子for文のサンプルとして九九を例に実際に使ってみましょう。

# プログラミング言語で九九を出力

とりあえずjavascriptだとこんな感じのことをSQLでやってみます。

```javascript
for (let x = 1; x <= 9; x++) {
    for (let y = 1; y <= 9; y++) {
        console.log(`${x} x ${y} = ${x * y}`);
    }
}
```

結果

```text
1 x 1 = 1
1 x 2 = 2
...
9 x 9 = 81
```

# SQLで九九を出力

for文的繰り返しは、`WITH RECURSIVE`を使って実現できます。
PostgreSQLで実行しました。

```sql
WITH RECURSIVE wx(x) AS (
    VALUES (1)
    UNION
    SELECT x + 1 FROM wx WHERE x < 9
), wy(y) AS (
    VALUES (1)
    UNION
    SELECT y + 1 FROM wy WHERE y < 9
)
SELECT x, y, x * y AS z FROM wx, wy;
```

結果

| x | y | z |
| :--- | :--- | :--- |
| 1 | 1 | 1 |
| 1 | 2 | 2 |
| ... | ... | ... |
| 9 | 9 | 81 |

# おわりに
すっかり生SQLを書くことも少なくなってきましたが、SQLもちゃんと進化しているんですね。
まあ癖が強い？からこんな簡単な例でも書かないと、初見だとなんじゃこりゃ？？ってなりますね。。
PHP　基礎 Part1

#PHPとは

HTMLは決まった画像しか表示できませんが、
PHPは見る人や状況に応じてテキストを変えることができます。

PHPはHTMLに組み込んで使うことができます。
<?php ?>の中に命令を書いていきます。
文末にはセミコロンを使うようにして下さい。

出力する時はechoを使うようにしましょう。

##変数

変数はPHPでは$を使って書いていきます。

##文字列の連結

PHPでは文字列を連結する時は.を使います。

##変数展開

文字列の中に変数を入れる時は変数展開をしますが、
{変数}を使いましょう。

##配列

配列の時は$配列名 = array(値1,値2...)を使います。
配列の末に値を追加する時は$配列名[]= '値'を記述しましょう。

##foreach

foreachは()の最初に配列名を入れて、asの後に変数を入れる。
連想配列の時は(配列名 as キー変数 => 値変数)

##関数

関数はまとまった処理を行い、値を返すモノです。
組み込み関数と言って、予め関数が入っています。

いくつかの組み込み関数を紹介します。
echo strlen(引数)　これで値の字数を数えます。
echo count(引数)  これは引数の配列の値の数を数えます。
echo rand(引数)   これは1つ目の引数から2つ目の引数までの数字をランダムで表示します。

#formを作る

formを作るにはformタグを作ります。
属性でactionを使い、属性値にURLを置きます。
method属性ではgetかpostを使います。

inputタグでtype属性をtextにします。
nameで受け取る値に名前を付けましょう。
文章のためにはtextareaタグを使いましょう。

送信ボタンを作る時はtypeをsubmitにします。
フォームに送った値を受け取るためには$_POSTで受け取ります。
$_POSTの後に['']で送ったnameの値を入れます。

#セレクトボックス

selectタグの中にoptionタグを使います。
optionタグにvalue属性を使い、実際に送信される値を決めます。
全然プログラムやったことないアラフィフがいまさらGitHubを学んでみた　〜プッシュ編〜

# 前回のおさらい
こんにちは、GIRONの粟津です。

前回は、[GitHub](https://github.co.jp/)の初期設定をしました。

☆実施したこと☆ 
1. GitHubのアカウントを作成する
2. リポジトリを作る
3. ローカルリポジトリを作成する

まずGitHubアカウント作成から始まり、ローカルリポジトリの作成までしました。
これでGitHibが利用できるようになっていると思います。

## ファイルをプッシュする
今回はファイルを作成して、そのファイルをプッシュまでしてみたいと思います。GitHubとえいばコミットから始まり、プッシュを行うことで一連の流れが完成します。
ではさっそく、プッシュまでやってみましょう！

###1. ファイルを作成する
まずは、ファイルをローカルリポジトリに作成します。今回はマークダウン形式のファイルを作成し、前回作成した”giron_school”のフォルダに格納します。
ファイル名は、大文字小文字は区別されて判別されるので、どちらかに統一してファイル名を付けた方が良いです。

```
README.md
```

###2. コミットする
これから先ほど作成したファイルをコミットします。
コミットとは、ファイルの追加や更新したファイルをリポジトリに記録することを言いい、ゲームで言えばセーブすることと似ています。

それでは先ほど作成したファイルをコミットするための準備**(ステージといいます)**をします。

```
$ git add ［README.md］　←作成したファイル名を入力してください
```
ターミナルで実行すれば、ファイルのステージ完了です。

次にコミットします。

```
$ git commit -m "add text"
```

``-m``以降にコミットする時のコメント``"add a text"``を入力します。

これでファイルのコミットが完了しました。
ここまではローカルリポジトリでの作業になります。


###3. リモートリポジトリを追加する

先に作成していたリモートリポジトリを追加します

```
git remote add origin https://github.com/あなたのGitHubアカウント名/GIRON_SCHOOL.git
```


###4. ブランチをプッシュする
今回は**master**というブランチを作成します。

```
$ git branch -M master
```

ちなみにブランチとは、プロジェクトを分岐という意味なのですが、正直自分も完全に理解できているわけではありません。
いまは**master**にいますが、通常それぞれ開発するときに各ブランチを切って作業をおこなうようです。

###5. プッシュする
ここまできたらあとは、ローカルリポジトリの内容をリモートリポジトリに反映させるためのプッシュするだけです。

```
$ git push origin master
```


###6. ブランチを確認する
GitHub上に作成したファイルがアップされているか確認します


これで一通り終了となります。
まずは動かしてみたという程度ですので、まだまだGitHubを使いこなしているかといえばそうではないですね。
まずは実際に何かの作業をやってみるというのが一番理解できるのかなと思います。

それでは今回はこの辺で！
C#の基本イディオムについてその2~条件文・判定編~

C#で条件分岐や判定をしたい場合の基本的なイディオムについてまとめた。

## 変数の値を比較するだけの場合
(例)valという数値型の変数が5以上かどうかを判定したい時、

~~~csharp
if(val >= 5)
~~~

変数を左にして書く。

~~~csharp
if(5　<= val)
~~~
でも間違いではないが、基本的に文字は右から左に読むので、読みづらい。

## 変数の値が特定の範囲内にあるかどうかを判定する場合
(例)valという数値型の変数が5より大きく、10未満かどうかを判定したい時、

~~~csharp
if(5 < val　&& val < 10)
~~~

判定したい値が指定した数値の中にあるかどうかが分かるように書く。
数学の5<x<10をイメージするといい。

## 複数の条件があり、その全ての条件を満たすときだけ処理をしたいとき
(例)nameがジョルノ・ジョバーナ、partが5、ageが15のときのみ何か処理をしたい時、

~~~csharp
if(name != "ジョルノ・ジョバーナ") return;
if(part != 5) return;
if(age != 15) return;
(実行したい処理を書く)
~~~

1つのifで1つの条件を判定するようにする。
「return;」とだけ書くと、実行をその場でやめる。


~~~csharp
if(name != "ジョルノ・ジョバーナ"　&& part != 5 && age != 15) return;
~~~
まとめて書くと条件が多ければ多いほど見にくくなってしまうので、分けて書く場合がベター。

## ただbool値を返したい
(例)nameがジョルノ・ジョバーナかどうかだけを判定したい場合、

~~~csharp
return name == "ジョルノ・ジョバーナ";
~~~

returnの後に条件分を書けばいいだけ。
「==」や「!=」は比較演算子なので、変数や値を比較演算子つなげて書くと、trueかfalseのbool値を返すので、

~~~csharp
if(name == "ジョルノ・ジョバーナ") {
  return true;
} else {
  return false;
}
~~~
のように書くと冗長的な書き方になってしまうので、特にこだわりがなければ、上記の書き方はしない。
「name == "ジョルノ・ジョバーナ";」がtrueかfalseを返すことが分かっているので、余計に書く必要はない。


## 参考文献
https://www.amazon.co.jp/gp/product/4774187585/ref=ppx_yo_dt_b_asin_title_o01_s00?ie=UTF8&psc=1
Ruby on Railsにおけるajax処理について

アプリケーションで取り扱いデータの処理内容が多くなってきたり、大容量データをデータベースとやり取りする時にAjaxを使用してデータ通信をすることでパフォーマンスの改善につながります。
ajaxを使用しないと更新の際データ通信時間が長すぎて503エラーが出たりするのに対して、ajax処理を導入することでエラーを回避したりできるメリットなどもあるようです。

#環境情報
まず環境によってコードの書き方などが変わって来るらしいので私のrails環境を記入しときます。
ruby2.6.5
rails 6.0.4


#基本的なajaxの使い方
railsに限らずajaxの一般的な使い方は<a href="https://www.sejuku.net/blog/28967">こちら</a>のような内容になります。
一般的なアプリケーションだとボタンなどをクリックするアクションをしてから読み込み処理をしてそれからサーバー再度でどのような返答をすればいいかの処理を決めてという風なやり取りをスレうするのに対してajaxだとユーザーからのアクションをしなくてもJavaScript側から取得できるすべてのイベントからリアルタイムにイベントを発火させることができる。非同期通信でページ遷移なしで
スムーズにフロントエンド側に結果を反映できるのが特徴です。
データをすべて読み込んでから結果を返すやり方だとユーザー側もその間待たなくちゃいけないので、リアルタイムでやり取り出来て必要最低限のアプリケーションを動かすことになるのでユーザビリティーやアクセシビリティーの向上にもつながると思います。

#Railsでのajax処理の書き方
RubyOnRailsではView側のヘルパーメソッドに(form＿tag)などで:remote=>trueを指定してあげることでajax導入を導入することができます、特にGemを使用するなどのことはなく非常に簡単に導入できます。

```inbdex.html.erb
<%= form_tag({:controller => '<コントローラ名>', :action => 'index'}, :remote => true, :class => 'hoge') do -%>
<%= hidden_field_tag :sample_name1, 'sample_name1' -%>
<%= submit_tag('Start sample', :class => 'btn btn-primary btn-sm') -%>
<% end %>
```

Controller側でその アクションに対応する処理を行い、render でレスポンスを指定します。

デフォルトではレスポンスとしてフロントエンド側にJavaScriptの処理が戻ってきます。そのレスポンス用JavaScriptは View ファイルにJavaScriptテンプレートを記述して用意します。

とりあえずこれまでです、説明できるようになったら追記します
スタードメインで取得したドメインをVercelで設定する方法

## ドメインの取得
* どこでも良かったのですが、前に使ったことのあるスタードメインで取得しました。
* レジストラ？は一番安いネットオウルにしました。
* スタードメインとネットオウルの関係、というかそれぞれが何なのか、どんだけ調べてもよくわからない。知らなくても生きていけるからとりあえずそこはもう考えるのやめました😂
* 料金は1年で900円ちょっとでした。更新料がいくら掛かるかは不明…どこかで見れるんでしょうか。よくわからないので自動更新にするのはやめました。

## 設定してみる
### 1. DNSレコード編集
* とりあえず設定方法は知らないので、[こちら](https://zuma-lab.com/posts/vercel-onamae-domain-settings)を参考に進めてみます。
* ネットオウルにログインして、``スタードメイン管理`` > ``管理ドメイン一覧``を開くと、取得したドメインが出てきました。
![スクリーンショット 2021-07-20 21.41.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1309306/20653abf-2ee3-3286-a64b-ddc02d0b9529.png)
* 参考にしたサイトに倣って、DNSの設定をするのか？と思い、``ドメイン管理ツール`` > ``DNSレコード編集``を開いたら、Vercel側の情報が必要っぽい。
* 別タブでVercelにログインし、``Settings`` > ``Domains`` を開きます。するとドメイン名を入力するところが出てきたので、取得したドメイン名を入力します。
![スクリーンショット 2021-07-20 21.45.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1309306/50cafcec-88be-cdbb-b1be-2e995a5d76e3.png)
* Addを押すと、なにやらポップアップが表示されます😳　が、とりあえずReccomendのものを選択しました。
* すると、``Invalid Configuration``と表示されますが、気にせず、そこに表示されたものをネットオウルの管理画面に入力すると参考にしたサイトには書いてあります。
* ``レコード追加``を開いてみると、当たり前ですがお名前ドットコムとは設定項目が違います。とりあえず、2つレコードを追加し、以下のように入力しました。
![スクリーンショット 2021-07-20 21.49.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1309306/486512b0-3636-29f4-3ddb-5374fa90edd2.png)
* これでできた！？と思いましたが、これでは名前解決されていませんでした。

### 2. ネームサーバー変更
* とりあえず、よくわからないけど、ネームサーバーの設定をしてみることにしました。
* ``ドメイン管理`` > ``ネームサーバーの確認・変更``を開き、Vercelで先程開いた``Domains``の``NameServer``ってところに表示されている値を入れてみました。（スクショ取ってませんでした…）
![スクリーンショット 2021-07-20 22.18.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1309306/f9dbe8c5-4ea2-b3ce-2cb7-dd3c7e763e76.png)
* ``確認画面`` > ``確定する``を押します。（ここちょっと時間かかりました）
* ``ドメイン管理``に戻ると、**「スタードメイン専用」以外のネームサーバーが設定されています**と表示されているので、Vercelが設定できてる？と思い、再度確認してみることに。
![スクリーンショット 2021-07-20 22.15.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1309306/03457d9b-6195-d23a-d588-c4dddfcc41b0.png)
* が、名前解決されていませんでした。

### 3. Git pushでビルドする
* そこで、Vercelのドキュメントを読んでみたところ、一度ビルドをしないといけないっぽい？と思い、ちょうど変更箇所があったので、それをadd > pushしてビルドを走らせます。
* すると、できました！

https://www.erikoono.com/

## 結局
* DNSレコード編集とネームサーバーの変更とVercelのビルドをして設定ができたのですが、DNSレコード編集とネームサーバーの変更の両方が必要なのかどうかは不明です😂
* 最後まで読んでいただき、ありがとうございました！
C#の基本イディオムについてその1~変数の初期化編~

C#でコードを書く際の基本的なイディオムについて、まとめてみた。

## 変数の初期化
変数名と値は一緒に定義する。

~~~csharp
var name = "aiueo";
~~~

もちろん、

~~~csharp
var name;
name = "aiueo";
~~~
と書くこともできるが、2行で各理由が特になければ、1行で済ませる。

## 配列の変数の初期化
変数名と同様に、変数名と値を一緒に定義する。

~~~csharp
var arrayData1 = new string[] {"あいうえお", "かきくけこ", "さしすせそ"};
var arrayData2 = new int[] {0, 1, 2};
var arrayData3 = new List<int>() {3, 4, 5, 6, 7, 8, 9};
~~~

以下の書き方も間違ってはいないが、コードが増えてしまうので、基本的に1つでまとめられる場合は1行でまとめてしまうのがベター。

~~~csharp
var arrayData1 = new string[] {};
arrayData1[0] = "あいうえお";
arrayData1[1] = "かきくけこ";
~~~

~~~csharp
var arrayData3 = new List<int>() {};
arrayData3.Add(1);
arrayData3.Add(2);
~~~

## オブジェクトの初期化

~~~csharp
public class Person {
     public string FirstName { get; set; }
     public string LastName { get; set; }
     public int Age { get; set; }
}
~~~
というPersonクラスが定義されていたとする。(コンストラクタはない。)

新しいオブジェクトを作成する際は、

~~~csharp
var person1 = new Person {
   FirstName = "太郎",
   LastName = "山田",
   Age = 22,
}
~~~
のようにまとめて定義してしまう。

## クラスの中にコンストラクタがあった場合

~~~csharp
public class Person {
      public string FirstName { get; set; }
      public string LastName { get; set; }
      public int Age { get; set; }

      public Person(string fn, string ln, int age)
      {
         FirstName = fn;
         LastName = ln;
         Age = age;
      }
}
~~~
上記のように、Personクラスの中にコンストラクタがある場合、person1を作ったときのように初期化しようとすると、構文エラーになるので、注意。

この場合は、

~~~csharp
var person1 = new Person("太郎", "山田", 12); 
~~~

コンストラクタの引数順に値をセットすること。


## 参考文献

https://www.amazon.co.jp/gp/product/4774187585/ref=ppx_yo_dt_b_asin_title_o01_s00?ie=UTF8&psc=1
移動平均を使って測定値の時系列遷移を確認する

```
ykishi@dezembro moving-average % cat mytest.py 
#!/usr/bin/env python3

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import os
import sys

df = pd.DataFrame(columns=["ymd", "value"])
print(df)
print()

# --------------------------------------------------------------------------
# 連続した日付のリストを作る
# --------------------------------------------------------------------------
size = 90
date_index = pd.date_range("2021-04-25", periods=size, freq="D")
print(date_index)
print()

# --------------------------------------------------------------------------
# ymd列に上記を代入する
# --------------------------------------------------------------------------
df["ymd"] = date_index
print(df)
print(df.dtypes)
print()

# --------------------------------------------------------------------------
# valueにランダムな数値をセット
# --------------------------------------------------------------------------
values = np.random.choice([100, 200, 400, 800, 1600, 3200, 6400], size=size)
df["value"] = values
print(df)
print()

# --------------------------------------------------------------------------
# valueの移動平均(weekly)を求めて新しい列として追加する
# --------------------------------------------------------------------------
window = 7
df["moving_average"] = df["value"].rolling(window).mean()
print(df)
print()

# --------------------------------------------------------------------------
# チャート描画
# --------------------------------------------------------------------------
df["ymd"] = df["ymd"].dt.strftime("%Y-%m-%d")  # X軸に表示する文字を設定

df.plot(x="ymd", kind="line")

plt.title("Moving Average")
plt.xticks(rotation=90)
plt.grid(True)
plt.subplots_adjust(bottom=0.2, top=0.9)

plt.savefig("test.png")

# --------------------------------------------------------------------------
# DataFrameをEXCELに出力する
# --------------------------------------------------------------------------
df.to_excel("test.xlsx")
ykishi@dezembro moving-average % 
```
![test.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1182287/ae5f2d13-73ea-803c-1a01-fc715ce49c73.png)
Mac購入後の初期設定一覧

随時更新

# Homebrewのインストール
https://qiita.com/zaburo/items/29fe23c1ceb6056109fd

PATHが通らないので以下を参照。

https://chicog.me/articles/1/

# gitのインストール

https://tracpath.com/bootcamp/git-install-to-mac.html

brew install git

ただこれだけやっても、gitを実行しても元々macに入っている古いgitが起動するので、PATHを通す必要あり。

homebrewでインストールした場合自分は/opt/homebrew/Cellar/gitにインストールされた。


# PATH設定でやらかした

https://qiita.com/noraworld/items/4556f91bc31f641d187d

# zshがなんかしょぼい

pwdの内容をプロンプトに表示させる。デフォルトだとカレントディレクトリしか表示されない。以下の記事は古いので注意。

https://qiita.com/ktr_type23/items/3eb782f98c7a5f4c60b0

上記のやり方だとカスタマイズ内容に限界がある気がする。なんかプラグイン的なの使った方がいい。

以下の記事の手順に従ったら、結構カスタマイズできた。iterm2っていうターミナルソフトを使わされることになるけど、
そっちの方が色々恩恵があるらしい？
https://opensource.com/article/20/8/iterm2-zsh
記事の中で

```
brew cask install iterm2
```
というのがあるけど、これは動かなかった。
正しくは？

```
brew install iterm2 --cask
```

らしい。
https://www.mathkuro.com/mac/brew-cask-command-error/#toc2

# Finder上でHomeディレクトリにアクセスできるようにする

https://dtmmethod.com/mac-finder-home

Linuxですらデフォルトでアクセスできるんで、こんくらいデフォルトでできるようにしといてほしい。

# dockerのインストール

パッケージマネージャ使わず普通にここから。

https://docs.docker.com/docker-for-mac/install/

# super userの設定

https://izumii19.hatenablog.com/entry/2018/11/27/171545

```
su
```

と打つとsorryと出てきたが、これはデフォルトではルートユーザーの設定がされていないかららしい。
VSCode で前回開いていたフォルダを開かせないようにする

# VSCode で前回開いていたフォルダを開かせないようにする

今回の目的は「**VSCode をまっさらな状態** で起動できるようにする」です。

この設定は好みが別れると思いますが、
個人的には前回開いていたフォルダを開きたいとは限らないケースの方が多いのでOFFにしたいと思います。

## 前回開いていたフォルダを開かせないように設定を変更する

以下の設定を `settings.json` に追加する。

```json
{
    "window.openWithoutArgumentsInNewWindow": "on",
    "window.restoreWindows": "none"
}
```

### window.restoreWindows

VSCode 再起動時の挙動に関する設定で `none` にすることで何も開かないように制御できます。

#### 公式ガイドから引用

>The `window.restoreWindows` setting tells VS Code how to restore the opened windows of your previous session. By default, VS Code will restore all windows you worked on during your previous session (setting: `all`). Change this setting to `none` to never reopen any windows and always start with an empty VS Code instance. Change it to `one` to reopen the last opened window you worked on or `folders` to only restore windows that had folders opened.
>
>[Window management　-　Visual Studio Code](https://code.visualstudio.com/docs/getstarted/userinterface#_window-management)

### window.openWithoutArgumentsInNewWindow

すでに VSCode が起動している時に VSCode を起動した場合の挙動に関する設定のようです。

こちらの記事がとても分かりやすかったです。

[VS Code 1.22 の新機能のリリースノートをしずしずと眺めてみる](https://qiita.com/12345/items/8253a1eee38b6741905e)
linuxショートカットキー一覧


####コマンド入力系
```
コマンド履歴を検索する
Ctrl + r

コマンド履歴を中止する
Ctrl + g

行頭に移動する
Ctrl + a

行末に移動する
Ctrl + e

カーソル左の全てを削除する
Ctrl + u

カーソル右の全てを削除する
Ctrl + k

カーソル左の一単語を削除する
Ctrl + w
```

####vi
```
一番下にいく
Shift + g

一番上にいく
gg

一番下から検索する
?hoge

一番上から検索する
/hoge

上から大文字小文字区別せず検索する
/hoge\c

下から大文字小文字区別せず検索する
?hoge\c

検索を止める
ESC 2回

一括置換する
:%s/hoge/fuga/g

一つ戻る
u

やり直す
Ctrl + r

右にある一単語を削除する
dw

一行削除する
dd

一行コピーする
yy

コピーした行を一行下に挿入する
p
```

vi ショートカットキー参考サイト
https://uguisu.skr.jp/Windows/vi.html
業務で使う最低限のSSH接続設定

# はじめに

新しい案件に参画する際に、SSH関連の設定を行うが、よく忘れるため自身のメモとして以下内容を記載する。

* SSH接続とは
* 公開鍵と秘密鍵の作成
* SSH接続に利用するコマンド
* ~/.ssh/配下のファイルの内容

## SSH接続とは

* リモートコンピュータと通信を行うためのプロトコル
* ネットワーク中でやり取りするデータが暗号化されるため安全
* パスワード認証と公開鍵認証がある

## 公開鍵と秘密鍵の作成

```
$ ssh-keygen
# パスワードを未設定にすると、以降の接続でパスワードの入力が不要

# もし~/.ssh/が存在しない場合は以下で作成しておく
$ mkdir ~/.ssh/
$ chmod ~/.ssh/ 700
$ touch ~/.ssh/config
```

## SSH接続に利用するコマンド

基本は以下オプションを含めたsshコマンドを利用することが多い。
※ `~/.ssh/id_rsa`のパーミッションは600にする必要がある。
※ `chmod 600 ~/.ssh/id_rsa`

```
$ ssh -i ~/.ssh/id_rsa apache@11.111.111.11 -p 22
＃ -i：秘密鍵の指定
＃ ~/.ssh/id_rsa：秘密鍵
＃ apache：ユーザ名
＃ 11.111.111.11：接続先のホスト名
＃ -p：ポート番号を指定
＃ 22：利用するポート番号
```

しかし、ssh接続をする機会が1日に複数回あるため、正直面倒である。そこで、後述する`~/.ssh/config`に接続情報などの情報を記述することで、上記sshコマンドの内容を省略することが出来る。

```config:~/.ssh/config
Host dev
    HostName 11.111.111.11
    Port 22
    User apache
    IdentityFile ~/.ssh/id_rsa
```

`~/.ssh/config`を記述した場合のsshコマンドは以下の通り。

```
$ ssh dev
```


## ~/.ssh/配下のファイルの内容

* id_rsa
  - `ssh-keygen`で生成された秘密鍵
* id_rsa.pub
  - `ssh-keygen`で生成された公開鍵
* config
  - SSH接続の情報を記述するためのファイル
* known_host
  - 今まで接続したサーバの情報が書き込まれる
自粛生活期間に家のスマートホーム化をやってみた (4か月目)

自粛生活で家にいる時間が長いので、昔からやってみたかったスマートホーム化をやってみています。
2021年3月頃にはじめて4か月ほどで色々できたので、まとめてみます。

#### できたこと
* 家の中の色んな情報をポータルで表示できるようになりました

![portal3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/849198/16a93072-cb78-962c-a2ac-09af95a8eac8.png)

0: 

https://qiita.com/tosshie/items/bc43114d42e05bc3afcb

1: 

https://qiita.com/tosshie/items/19f87cc86919a0349c0b

2: 

https://qiita.com/tosshie/private/34d348b31df4306db898


3: 

https://qiita.com/tosshie/private/e844c4cfc2eac126dfd2

4: 

https://qiita.com/tosshie/private/a94a109dae282cc939ca

5: 

https://qiita.com/tosshie/private/6e9ee9e291b2f63330a2

6: 

https://qiita.com/tosshie/items/6ec2b118ac016811a24a

7: 

https://qiita.com/tosshie/private/3ec7d3efc61c2dddd6ec

8: 

https://qiita.com/tosshie/private/ed1bf4ab51e0c0e43fb8

#### 構成

* システムの構成とデータの流れは以下の絵のような感じです

![構成図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/849198/4dfb806b-4cee-b179-a766-1ce9c1131780.png)


A:

https://qiita.com/tosshie/items/eee733de2540d1bf49a2

B:

https://qiita.com/tosshie/items/0b6a93a8e351cd801321

C:

https://qiita.com/tosshie/private/34d348b31df4306db898

D:

https://qiita.com/tosshie/items/08a2c740e19c4154daf7

E:

https://qiita.com/tosshie/private/6e9ee9e291b2f63330a2

F:

https://qiita.com/tosshie/items/fe79368c6ef75df3736c

G:

https://qiita.com/tosshie/items/19f87cc86919a0349c0b

H:

https://qiita.com/tosshie/items/3ec7d3efc61c2dddd6ec

I:

https://qiita.com/tosshie/items/0e4a7cb3f8171984dc39

J:

https://qiita.com/tosshie/items/e844c4cfc2eac126dfd2

K:

https://qiita.com/tosshie/items/0b5856d06d6bfc228d41

L:

https://qiita.com/tosshie/items/6ec2b118ac016811a24a


#### かかった費用
- 買ったときの値段と後から調べた値段が混ざっています

| No. | item | 単価 | 個数 | 費用 |
|:-:|:-:|:-:|:-:|:-:|
| 1  |  switchbotの温湿度計 | 1,680円  | 5個  |  8,400円 | 
| 2  | raspberry pi 4 model B(4台分ケース代、SDカード代とかも含む)  | 10,021円  | 4個  |  40,084円 |
| 3  | raspberry pi zero WH(2台分ケース代、SDカード代とかも含む)  | 5,000円  | 2個 |  10,000円  |
| 4  | MHZ19C(二酸化炭素濃度計)  | 3,331円  |  2個 | 6,662円  |
| 5  | 窓の開閉センサー  | 1,700円  | 3個  |  5,100円 |
| 6  | ラズベリーパイ用カメラとケース | 5,930円  | 1個  | 5,930円  |
| 合計  |   |   |   | 76,176円 |


-------
参考：

- 自粛生活期間に家のスマートホーム化をやってみる(2か月目)

https://qiita.com/tosshie/items/738a85184d6cdaf20b3e
How can speed up a video by 2X in ffmpeg?


```shell
# 1.25x speed
ffmpeg -i origin.mp4 -filter_complex "[0:v]setpts=0.8*PTS[v];[0:a]atempo=1.25[a]" -map "[v]" -map "[a]" fast.mp4

# 2x speed
ffmpeg -i input.mkv -filter_complex "[0:v]setpts=0.5*PTS[v];[0:a]atempo=2.0[a]" -map "[v]" -map "[a]" output.mkv

# 2x speed
# chatgpt generate the cli
ffmpeg -i input.mp4 -filter:v "setpts=0.5*PTS" -filter:a "atempo=2.0" output.mp4
```

`ffmpeg -i input.mp4 -filter:v "setpts=PTS/2" fast.mp4` only speed up video


## shell script

**Thank ChatGPT**

```shell
#!/bin/bash

# Ask the user for the input video file
read -p "Enter the path to the input video file: " input_file

# Ask the user for the speed multiplier
read -p "Enter the speed multiplier (e.g. 2 for 2x speed): " speed_multiplier

# Build the ffmpeg command with the input file and speed multiplier
ffmpeg_command="ffmpeg -i $input_file -filter:v \"setpts=$(bc -l <<< "1/$speed_multiplier")*PTS\" -filter:a \"atempo=$speed_multiplier\" output.mp4"

# Run the ffmpeg command
eval $ffmpeg_command

echo "Done!"
```

---

Ref:

https://stackoverflow.com/a/56164569

https://superuser.com/questions/1261678/how-do-i-speed-up-a-video-by-60x-in-ffmpeg

https://trac.ffmpeg.org/wiki/How%20to%20speed%20up%20/%20slow%20down%20a%20video

http://ffmpeg.org/ffmpeg-all.html#atempo
【Rails】特定のroutesのみを表示する方法

####My Profile
プログラミング学習歴②ヶ月目のアカウントです！
プログラミングスクールで学んだ内容や自分が躓いた箇所等のアウトプットの為に発信しています。
また、プログラミング初学者の方にわかりやすく、簡潔にまとめて情報共有できればと考えています。
もし、投稿した記事の中に誤り等ございましたら、コメント欄でご教授いただけると幸いです。　



#対象者

* rails routesをよく使用する方


#目的

* grepを使って特定のroutesのみを表示して探す手間を省く

#実際の手順と実例
###1.特定のroutesのみ取得

```terminal.
rails routes | grep hoge
```

* チームで開発する際にroutesが多すぎて探すのに時間がかかっている方にかなりおすすめです！
* **hoge**部分にはroutes上に存在する文字列であれば表示できます！

活用してスムーズな開発につなげてください！！



#参照

>[bundle exec rails routesで特定のroutesのみ表示する](https://qiita.com/motty93/items/c9d3ec5adcf23369245c)
データの前処理ですることリスト

重回帰分析を実装する前に、少しでも精度を上げるために、データの前処理をする必要があります。
1.機械学習のアルゴリズムに適用できる形に変換する前処理
2.モデルの精度を向上させるために行う前処理
の2つのフェーズに分けることができますので、それぞれ書いておきます。

# 1.機械学習のアルゴリズムに適用できる形に変換する前処理 
1-1.データの確認
1-2.重複行の確認
1-3.欠損値処理
1-4.カテゴリカル変数処理
1-5.重回帰分析の実装
以上のような流れで機械学習のアルゴリズムに適用できる形に変換していきます。

## 重複行の確認
重複の確認には、`df.duplicated()`を使用します。
`()`の中を`keep=False`にすることで、重複データをすべてTrue, それ以外をFalseと返します。

```python
# 重複行の数の確認
df.duplicated(keep=False).value_counts()

# 重複行の削除
df.drop_duplicates()
```

## 欠損値処理
欠損値とは、`NaN`と表記されているもののことです。csvの中でいう空白のセルです。
欠損値の確認は、`df.isnull()`で確認できます。
`df.isnull().sum()`で各列ごとの欠損値の数の合計を確認できます。

### 欠損値の除去
`df.dropna()`で欠損値が含まれる全ての行が削除されます。
`df.dropna(subset=['列名'], axis=0)`とすると、`'列名'`の列に欠損値が含まれている行を削除できます。

列の中身のほとんどが欠損値の場合は、列ごと削ってしまってもいいかもしれません。
その場合は、`df.drop(labels='列名', axis=1)`で列を削除できます。

### 欠損値の補完
欠損値を平均値や中央値で補完する時もあります。
どちらを使うかはケースバイケースです。
正規分布に近いような分布をしている時は、平均値を当てはめるといいかもしれません。
`df.describe()`でデータ統計量の確認ができます。
`plt.hist(df['列名']`で列の中のデータがどのような分布をしているか可視化できます。

補完する時は`.fillna()`を使います。

```python
# 欠損値を平均値で補完
df.fillna({'列名':df['列名'].mean()})

# 欠損値を中央値で補完
df.fillna({'列名':df['列名'].median()})
```

## カテゴリカル変数処理
文字列データ含め、カテゴリを表すデータをカテゴリカル変数といいます。質的変数とも呼ばれます。
例えば「男性, 女性」というような文字列データはカテゴリカル変数です。
また、男性を 0, 女性を 1 と置き換えた「0,1」のデータも、値としては文字列ではなく数値ですが、カテゴリカル変数です。

補完する時は、最頻値を使用するケースが多いです。
最頻値は`.mode()`で取得できます。
どのような文字が入っているかを調べるときは`.unique()`で見ることができます。

```python
# 最頻値(abc)を使用して欠損値を補完
df.fillna({'abc':df['列名'].mode()[0]})
```

### Label Encodeing
Label Encodingは各カテゴリに 0, 1, 2, ... と数値を割り振る変換です。
scikit-learnの中でも前処理系のものを取り扱うには`preprocessing`を使用します。

```python
# モデルの宣言
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
le.fit(df['列名'])
#　モデルの適用
le.transform(df['列名'])
```
どのカテゴリがどのラベルに変換されたかは`le.classes_`で確認できます。

### One-Hot Encoding
One-Hot Encodingはダミー変数化とも言われ、各カテゴリの値ごとに0, 1の列を作成します。
カテゴリの値の種類の数だけ列が増えます。
`pd.get_dummies()`でできます。

# 2.モデルの精度を向上させるために行う前処理
2-1.特徴量エンジニアリング
2-2.外れ値除去

## 特徴量エンジニアリング
特徴量エンジニアリングとは現在あるデータを用い、より有用なデータを作成することです。
例えば、「カツオ、リンゴ、レモン、イワシ、ブタ、ウシ」という文字列が含まれる列の場合、
カツオとイワシは魚なので、1
リンゴとレモンは果物なので、2
ブタとウシは肉なので、3
のようにグルーピングしてみると、分析結果が良くなるかもしれません。

```python
# クラス分けのリストの定義
class_1 = ['カツオ', 'イワシ']
class_2 = ['リンゴ', 'レモン']
class_3 = ['ブタ', 'ウシ']

# それぞれを置換するリストの作成
food = []
for i in df['列名']:
    if i in class_1:
        food.append(1)
    elif i in class_2:
        food.append(2)
    elif i in class_3:
        food.append(3)

# データフレームに列を追加
df['food'] = food
```

このように、多いカテゴリをより有用な少ないカテゴリに分け直すような方法以外にも、

- a複数変数をかけ合わせて、交互作用特徴量を得る
- ある変数の累乗をとって、多項式特徴量を得る
- ある変数の対数をとる
- 連続値を離散値に変換する（ビニング）

など、さまざまな方法があります。

## 外れ値除去
外れ値を除去する時は、「3σ法（平均値ベース）」と「ハンベル判別法（中央値ベース）」の2つの手法が主です。
基本的には3σ法を採用し、それでうまく外れ値を検知出来ない場合はハンペル判別法を使うといいです。
ハンペル判別法は外れ値の数が多く、平均が引っ張られている場合などに有用な手法です。

### 3σ法

```python
# 3σ法
mu = df['列名'].mean() # 平均値
sigma = df['列名'].std() # 標準偏差
df = df[(mu - 3 * sigma <= df['列名']) & (df['列名'] <= mu + 3 * sigma)]
```

### ハンペル判別法
3σ法における平均値が中央値に、標準偏差が中央絶対偏差（MAD）に変わります。

```python
# ハンペル判別法
median = df['列名'].median() #中央値
MAD = 1.4826 * np.median(abs(df['列名']-median))
df = df[(median - 3 * MAD <= df['列名']) & (df['列名'] <= median + 3 * MAD)]
```
[HTML/CSS]justify-contentの種類について

# はじめに
本記事では、justify-contentの種類を記述していきます。
間違えまくり&覚えきれない箇所でしたので備忘録です。

# justify-contentとは
display: flex;と併せて使用します。
主軸方向(初期値は水平方向)の配置の詳細を決めます。

# 種類(学習したもの)
・justify-content: flex-start;    左寄せ
![flex-start.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1768158/bfd0124d-33a9-7be3-5647-b05fecdf9eaf.png)


・justify-content: flex-end;    右寄せ
![flex-end.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1768158/796c869e-f230-79c3-69c7-74b76b292444.png)



・justify-content: center;    中央寄せ
![center.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1768158/38843884-e3be-ce34-5983-55a749133b62.png)

・justify-content: space-between;    両端が左右に寄り、等間隔
![spece-between.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1768158/ccdb5640-f19b-92a9-c25c-3881940854c5.png)


・justify-content: space-around;    両端が左右に寄り、等間隔。両端の余白と要素間の余白が1:2
![spece-around.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1768158/e19f422a-3a04-e800-a550-3d38869836ab.png)

# 終わり
CSSのコードを書いていて「楽しいな」と感じるときが多いです。
「space-between」と「space-around」は少し似ているとは感じますが、
実際にデザインを考える上で、
細かいところも重要になるだろうと思いました！！

どんどんCSSも書けるよう、がんばります！！
【Golang】ベンチマークで "no test files" と出てしまう。テストはあるのに。

> Golang では、ベンチマークが簡単にできるというので `go test -bench ./subpackage/...` と打ったら "no test files" と言われてしまう。しかし `go test ./subpackage/...` でテストは走るし、ベンチ用テスト関数もある。

[「"golang" test bench "no test files"」とググって](https://www.google.com/search?q=%22golang%22+test+bench+%22no+test+files%22)も「テストがないから」とか、`go help test` を見ても、なんかゴチャゴチャしてわからなかったので、自分のググラビリティとして。

## TL; DR <sub><sup><sub><sup>（今北産業）</sup></sub></sup></sub>

1. ベンチを走らせる時の構文が間違っています。おそらく正規表現の「`.`」が抜けています。

    ```
    go test -bench <正規表現> <テストのパス> <その他のオプション>
    ```
1. ベンチを走らせるには `-bench` オプションが必要ですが、**実は引数も必要**。
    - 引数は正規表現でマッチした関数のみを走らせるために必要です。すべてのベンチを走らせたい場合は `.` と指定します。
1. `./subpackage/` ディレクトリ以下にある、テストとベンチを走らせたい場合は以下の通り。

    ```bash:1000回のループを10回繰り返してメモリ使用量も測定する
    go test -bench . ./subpackage/... -benchtime=1000x -count 10 -benchmem
    ```
    - `-benchtime=1000x` と `x` を付けると時間ではなく回数扱いになり、ベンチの関数の `b.N` に渡される。
    - [他の `test -bench` のオプション一覧](https://pkg.go.dev/cmd/go#hdr-Testing_flags) @ pkg.go.dev

## TS; DR

シンプルなテストとベンチマークから始めずに、いきなりサブディレクトリにパッケージをわけたものだから、<ruby>ふいんき<rt>・・・・</rt></ruby>でコピペピピックするからわけわかめになるので、毎回ドキュメント嫁に叱られるのです。

```text
-bench regexp
  Run only those benchmarks matching a regular expression.
  By default, no benchmarks are run.
  To run all benchmarks, use '-bench .' or '-bench=.'.
  The regular expression is split by unbracketed slash (/)
  characters into a sequence of regular expressions, and each
  part of a benchmark's identifier must match the corresponding
  element in the sequence, if any. Possible parents of matches
  are run with b.N=1 to identify sub-benchmarks. For example,
  given -bench=X/Y, top-level benchmarks matching X are run
  with b.N=1 to find any sub-benchmarks matching Y, which are
  then run in full.
```
- [Testing flags](https://pkg.go.dev/cmd/go#hdr-Testing_flags) | [Documentation](https://pkg.go.dev/cmd/go) @ pkg.go.dev

> 【筆者訳】
> **-bench regexp**
>
> 正規表現にマッチするベンチマークのみを実行します。デフォルトでは、ベンチマークは実行されません。
> すべてのベンチマークを実行するには、'`-bench .`' または '`-bench=.`' を使用します。
>
> 正規表現は、括られていないスラッシュ（/）文字で正規表現を分割することができます。
> シーケンス中（一連の処理を実行中）に、ベンチマークの識別子（関数名）の各部分で対応する要素にマッチすると、一致する可能性のある親を `b.N=1` で実行し、サブベンチマークを特定します。
>
> 例えば、'`-bench=X/Y`' と指定した場合、まず '`X`' にマッチするトップレベルのベンチマークが '`b.N=1`' で実行され、'`Y`' にマッチするサブベンチマークがないか探します。その後、マッチしたものを全て実行します。
Rails 投稿機能

# 投稿機能（newアクション）
railsを利用した基本的な投稿機能について、学習内容をメモ的に記載しています。

####ルーティング
```ruby
Rails.application.routes.draw do
  get "posts/new", to: "posts#new" 
end
```

まずは、newアクションに対応するルーティングを記載し、新規投稿画面に遷移させます。
HTTPメソッドは、新規投稿画面を表示させたいので、サーバに対して「新規投稿画面を下さいよ」という意味で`get`を使用します。

```html:投稿フォームの作り方
<form action="/posts" method="post">
  <type="text" name="content">
  <type="submit" value="投稿する">
</form>
```

# ヘルパーメソッド(form_with)

前述のhtmlを使用した投稿フォールの作成方法とは別に、ヘルパーメソッドという便利なメソッドが存在します。
ヘルパーメソッドを使用した投稿フォームの記載

```html.erb
<%=form_with url: "/posts", method: :post local: true do |form|%>
  <%=form.text_field :content%>
  <%=form.submit "投稿する"%>
<%end%>
```
#####ヘルパーメソッドを使用するメリット
- コードの記述を簡略的・分かりやすく記述できる
- セキュリティ面が向上する

#####パラメーター
formからリクエストでサーバに対して値を送る時に外部から渡されるデータのこと。
railsのコントローラーに渡されるパラメーターは`params`というはハッシュ形式に格納されています。

```
<%=form.text_field :content%>
```
の`:`の後に記載したキー名で、値を送信することで、リクエストのparams内に`｛"キー名"=>"投稿内容"｝`と言った形式で値をコントローラーに渡すことができます。
コントローラーにおいて、`params[:キー名]`で値を取得することができます。

# 投稿機能（createアクション）

####ルーティング
```ruby
Rails.application.routes.draw do
  get "posts/new", to: "posts#new"
  post "posts", to: "posts#create"  
end
```
createアクションの場合は、URIパターンは、`posts`のみの記載、HTTPメソッドが`post`になっている点に注意が必要です。
サーバに対して、何か値を送信するので、`post`メソッドが必要になります。
投稿完了とともに、投稿完了画面を返してやると、わかりやすいです。

#####createメソッド
ActiveRecordメソッドの一つで、値をテーブルに保存するには、new→情報入力→saveの流れが必要でしたが、このメソッドを使えば一発でテーブルに保存することができます。

```ruby
def create
  Post.create(params[:content])
end
#Postテーブルにformから送られてきたキー名contentの値を保存する記載
```
Content Builder の基本 ⇒ Content Builder のカスタマイズと強化

１．Content Builder をどのようにカスタマイズできますか?
２．エディターの特定のタブへのアクセスを制限するメリットは何ですか?
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/b5e2cea9-af21-9d88-9744-28d3102c3f76.png)
[Rails] ActiveStrageの画像の保存先をAmazon S3にする②~バケット作成~

##はじめに
前回の続きです。AmazonS3に画像を保存するために、保存先であるバケットを作成します。

##バケットの作成
AWSにルートユーザーでログインします。
検索フォームにS３と入力して、S3をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1552346/e38deb09-db31-6c3f-8996-6d9c74da49d0.png)


バケットを作成と書かれたボタンをクリックします。
バケット名を入力します。名前は自由に決めて大丈夫です。

リージョンというところは「アジアパシフィック（東京） ap-northeast-1」を選択してください。

ブロックパブリックアクセスのバケット設定というところですが、
まず、**「パブリックアクセスを全てブロック」**のチェックを外し、
**「新しいパブリックバケットポリシーまたはアクセスポイントポリシーを介して付与されたバケットとオブジェクトへのパブリックアクセスをブロックする」**
と
**「任意のパブリックバケットポリシーまたはアクセスポイントポリシーを介したバケットとオブジェクトへのパブリックアクセスとクロスアカウントアクセスをブロックする」**
と最後の警告のところの三つにチェックを入れます。↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1552346/c839610e-3196-953d-d2c1-af1afbbeab27.png)


その後は何も入力せずに「バケットを作成」をクリック
これでバケットの作成が完了したはずです。

##セキュリティー対策 バケットポリシーを設定

バケットポリシーというものを使用してアクセス制限の設定をします。
前回作成したIAMユーザーのみがこのバケットにアクセスできるように設定します。

まずはIAMを検索から探し、クリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1552346/03bfac2a-f515-61ef-49c6-bedeebd54b36.png)

それから「ユーザー」という項目をクリックすると、前回作成したユーザーが出てくるので名前をクリックします。

「ユーザーのARN」と書かれた情報が出てくるはずです。コピーができるようになっているはずなのでコピーして、一時メモアプリなどに保存しておいてください。

続いてS3の方に戻ります。同じように検索でS3と入力してバケットのページへ移動してください。
作成したバケット名をクリックして画面中央の「アクセス許可」というところをクリックしてください。

スクロールすると、バケットポリシーという項目が出てくるので編集をクリックし下記を貼り付けてください。

```:バケットポリシー
{
   "Version": "2012-10-17",
   "Id": "Policy1544152951996",
   "Statement": [
       {
           "Sid": "Stmt1544152948221",
           "Effect": "Allow",
           "Principal": {
               "AWS": "①"
           },
           "Action": "s3:*",
           "Resource": "arn:aws:s3:::②"
       }
   ]
}
```

貼り付けたら、「①」のところに先ほどコピーした「ユーザーARN」を入力します。
「②」に作成したバケット名を入力します。

しっかり確認し間違えがなかったら、変更を保存をクリックして完了です。

もし不明なエラーが出たら下記のことを確認してください
・「①」の箇所に「ユーザーARN」を記述できているか
・「②」の箇所に「作成したバケット名」を記述できているか
・ダブルクォーテーション（""）を消してしまっていないか
・全角スペースを入れてしまっていないか


これでバケット作成完了です。