OmniAICreator/Qiita-1.07M huggingface dataset:
【初心者必見！】DSでExcelのdd/MM/yyyyの日付をyyyy/MM/ddに変換する

#はじめに
今回はExcelに「dd/MM/yyyy」の形式で書かれた日付を「yyyy/MM/dd」に変換する方法を皆様に知って頂ければと思います。
必要となればぜひ使って頂けると幸いです。

#設定方法
では順に説明していきます。

例えば下記のような日付があったとします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1902544/bd649ea2-62fe-8bc6-fa54-92981eadc7e7.png)

①まず、抽出したい日付の変数は「Short Text」にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1902544/30591912-fee5-6d0f-ad17-fd99c16c9cd0.png)

②抽出したい日付を先ほど作成した変数に格納します。（今回は「日付」という名前の変数です）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1902544/f411d31e-e4cf-fe71-921c-3ac67e55ede1.png)

③このままでは「dd/MM/yyyy」の形式で変数に格納されますので、これを変換していきます。
先ほど抽出したステップのコンバータを設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1902544/571fd878-99f0-d21e-22df-dd75ba7dad88.png)

④コンバータの＋ > 日付処理 > 日付抽出の順に選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1902544/4217116a-e99c-4134-3184-f6558c5c408c.png)

⑤下記の画面が表示されたら、フォーマットを編集します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1902544/60459e1b-9b30-c846-b739-5de7d9ab286a.png)

⑥フォーマットの ＋ > フォーマットパターンを選択します。
すると下記のように自動で設定されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1902544/d9130d4c-817a-5a67-ec09-77cc5fa0b7bf.png)

⑦下記画像の赤枠で囲まれている箇所のパターンに「dd/MM/yyyy」と入力しOKボタンを押します。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1902544/d209e196-19d1-3131-5e7f-8ae746e68abe.png)
テスト入力値の日付の形式とパターンの形式を合わせることによって、テスト出力に「yyyy/MM/dd」と入力されます。
![A.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1902544/5c7b9cc3-6837-f225-6b47-ee2e7a370ef6.png)

⑧コンバータの＋ > 日付処理 > 日付の書式設定の順に進みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1902544/ef719cce-96b6-8b77-3030-374984511917.png)

⑨そして下記画像の赤枠の箇所を「yyyy/MM/dd」と入力すると、下記画像の青枠のところに「yyyy/MM/dd」の形式で日付が入ります。
これで完了となります。
![B.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1902544/1354464b-afd1-8ea6-71c5-516fce6ea56f.png)

#最後に
少しめんどくさい手間を踏みましたが、一番正確に処理が出来ると思っておりますのでぜひとも参考にしていただければ幸いです。
最後までご覧いただき誠にありがとうございました。
RustでWebAssembly: web_sysでasyncなsleepをする

はじめに
========
RustでWebAssemblyを作っていて、async な `sleep()` をするコードです。

コード
=======
以下のような関数を定義して、

```rust
use futures::Future;
use js_sys::Promise;
use wasm_bindgen::prelude::*;
use wasm_bindgen_futures::JsFuture;

pub fn sleep(ms: i32) -> impl Future {
    let p = Promise::new(&mut |resolve, _| {
        web_sys::window()
            .unwrap()
            .set_timeout_with_callback_and_timeout_and_arguments_0(&resolve, ms)
            .unwrap();
    });
    JsFuture::from(p)
}
```

こんな感じで使います。

```rust
async fn hogehoge() {
    sleep(1).await;  // sleep 1ms
}

```
Rails CSRF対策について

# CSRFとは
Cross Site Request Forgeryのことで、
Webアプリに知らない間にリクエストが送られる不正攻撃のことです

例えばインスタで知らない間に自分の投稿を消されていたりしたら
CSRFです。



# CSRF対策の設定
application_controller.rbに下のような記述をすると、

```
Can't verify CSRF token authenticity
```
というエラーが出てきます。このエラーが出たらCSRFのエラーで
Railsがちゃんとしたリクエストがいっているかどうかを　CSRF Tokenというもので
確認するのですがそれが確認できないというエラーです。


```application_controller.rb

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
 
end

```
# 解決策

application_controller.rbに下のような記述をします。

```application_controller.rb
class ApplicationController < ActionController::Base
  protect_from_forgery with: null_session
 
end
```
これは公開する時にはあまり役に立たないです。```CSRF対策をOFFにしてしまう```からです。

他にも

```rb
class ApplicationController < ActionController::Base
   skip_before_action :verify_authenticity_token

end

```
このような方法もあるみたいです。　CSRF 対策を放棄する時に使います。


# 最後に
上のやり方はあくまでエラーを解決するための方法です。
アプリを公開したりする場合は、CSRF　Tokenの設定が必要になります。
下の参考資料に載っているので調べてみてください。


# 参考資料
https://midorimici.com/posts/rails-api-csrf
[Flutter]Dartで出てくる用語を五文字以内で要約してみた

Widget：
パーツ

Stateful：
不変

Stateless：
可変

build：
作る
補足説明：初期化ではないのがポイント

Element：
パーツ保持

BuildContext：
エレメント

ListView：
リスト

EdgeInsets：
外余白

padding：
内余白

itemBuilder：
子

isOdd：
奇数

~/：
切り捨て

Container：
容器

Row：
行

Column：
列

パッケージ：
人のやつ

MaterialApp：
アプリ(全体)

Scaffold：
(UI)構造

Mixin：
メンバ達

with：
増員

extention：
拡張

on：
追加

get：
中身取る
【JavaScript】変数と参照の振り返り①　let,var,constの違いとデータ型


#はじめに

Udemyの[【JS】ガチで学びたい人のためのJavaScriptメカニズム](https://www.udemy.com/course/javascript-essence/)の講座の振り返りです。

前回の記事

https://qiita.com/nao0725/items/3ed1b5a2e6f08aaed5e0

#目的

* 変数についての理解を深める


#本題
###1.let, var, constの違い

|  | version | 再宣言 | 再代入 | スコープ | 初期化 |
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|  let |  ES6~ | ✗  |  ◎ | ブロック  | ✗  |
|  var |    |  ◎ |  ◎ | ブロック  |undifined|
|  const | ES6~  | ✗  | ✗  |  関数 |  ✗ |


再宣言：もう一度変数として宣言する
再代入：一度設定した値を変更できるか
スコープ：varだけ関数スコープが生成
初期化：ホスティングのこと(varはundified)と表示される

以下VSコードで確認していきます。

````javascript
// 再宣言
// letやconstは再宣言不可（エラーになる）
let a = 0;
let a = 0;
// varは可能（b=1と表示される）
var b = 0;
var b = 1;

// 再代入
// 以下０ではなくcに１を入れ直す
let c = 0;
c = 1;
// constは再代入できない（定数？）
const d = 0;
d = 1;

// スコープ
// constやletの場合はブロックスコープが有効
{
  // 出力できない
  let e = 0;
  // varはブロックスコープが無視される
  var f = 0;
}
// ブロックスコープ外で書いても一緒
var f = 0;

// 初期化
// 宣言をする前に値を取得しようとすると
console.log(h);
// letはエラーになる
let g = 0;
// varは初期値がundifinedなのでそのまま出力される（エラー発生しない）
var h = 0;

// varは非推奨
// ごちゃまぜにすると混乱する
``````

###2．変数とデータ型

JavaScriptのデータ型

| 型 | 英名 | 例 |
|:-:|:-:|:-:|
|  真偽値 | Boolean  |  true/false |
|  数値 | Number  |  1,2,3,,,, |
| 文字列  | String  |  "HelloWorld" |
|  undifined | Undifined  |   |
|  null | null  |   |
| シンボル  | Symbol  | 一意の値  |
|  BigInt |  BigInt |  12n |
|  オブジェクト | Object  | {a:'value'}  |

数値がNumberなの注意（intじゃない）



今日はここまで！

#参考にさせて頂いた記事

* [【JS】ガチで学びたい人のためのJavaScriptメカニズム](https://www.udemy.com/course/javascript-essence/)
ROS2でurdfを書く最初の一歩

![SS 192.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/a41cd967-f549-8677-1efa-2e99bf69518d.png) 何事もとっかかりが大事

# やること
ROS2でヒューマノイドを動かしたいのですが、urdfというロボットの記述方法についてROS2環境でどうすればよいのかわかりません。
ROS1に対応した情報なら書籍もサイトもすぐに見つかりますが、ROS2でゼロからとなるとなかなか情報が見つかりません。
そこでROS2でurdfを始める場合の最初の一歩のところをメモに残しておきます。
まずは**最小限のurdfファイル**を書いて、それが**rviz2で表示できるか**を確かめます。

# 必要なもの
- ROS2が使える環境（Ubuntu 20.02 + ROS2/foxy）
- ROS2の基礎知識（topicの送受信デモを試した程度でよい）
- rviz2が導入済み

# 参考
[Using URDF with robot_state_publisher](
https://docs.ros.org/en/foxy/Tutorials/URDF/Using-URDF-with-Robot-State-Publisher.html)
[ROS講座13 URDFを記述する1](https://qiita.com/srs/items/35bbaadd6c4be1e39bb9)
大変参考になりました。ありがとうございます。

# ROS2のパッケージを作る

まず適当なワークスペースに移動して、urdfテスト用のパッケージを作ります。


```shell
$ ~/dev_ws/src #ビルド済みで使える状態の適当なワークスペース
$ ros2 pkg create urdf_test --build-type ament_python --dependencies rclpy
```
新たにワークスペースを作ったという場合は、一応アクティベートもしておきます。
<details><summary>（アクティベートする場合はこちらをクリック）</summary><div>

```shell
$ CD ~/dev_ws/
$ source install/local_setup.bash
$ CD ~/dev_ws/src
```
</div></details>

urdfの空ファイルと格納する場所を準備します

```shell
$ cd urdf_test/
$ mkdir urdf
$ cd urdf_test
$ touch test.urdf
```

# urdfを書く

urdfの中身を書いていきます。urdfはxml形式のファイルとなります。

```
$ nano test.urdf
```
nanoのところはもちろん vim でも codeでも使いなれたエディタでOKです。

```xml:test.urdf
<robot name="test_robot">
  <link name="base_link"/> #基準となる空のリンク

  <joint name="body_joint" type="fixed"> #ジョイントの設定
    <parent link="base_link"/> #ジョイントの親を指定
    <child  link="body_link"/> #ジョイントの子を指定
  </joint>
  <link name="body_link"> #リンクの設定
    <visual>
      <geometry>
        <box size="0.1 0.2 0.4"/> #見た目を長方形に設定
      </geometry>
    </visual>
  </link>
</robot>
```

urdfはリンク（腕のような部品）とジョイント（関節のような部品）のペアで書き連ねていきます。
上記はおそらくurdfの最小の構成で、ここから何か要素を削除するとRviz2で表示できなくなります。

# rviz2でurdfを表示する


#### rviz2を起動する
```
$ rviz2
```

空っぽのrviz2が立ち上がったら左側に「Displays」のウィンドウがあるか確認します。
ない場合は、上のメニューの「Panels」から「Displays」をチェックします。

#### udrfを適用する
「Displays」のウィンドウの下にある「Add」を押し、「RobotModel」を選択します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/3603673d-5288-5654-c715-c4bff0f02a15.png" width=400>

「RobotModel」が追加されたら、
Description Sourceの右側の空欄を選択して「File」を選択します。
さらにDescription Fileの右側の空欄を選択して該当ファイルを指定します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/fc7c8035-a1ac-c7f7-76df-cba83e7e592b.png" width=300>

以下のように画面に白い直方体が表示されたら成功です。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/0d7731aa-8466-6f7f-8607-0f5ee9339b5e.png" width=400>

ちなみにRviz2のビュー画面の操作は、

- 左クリック＋移動：回転
- ホイール押下＋移動：移動
- 右クリック＋上下：拡大縮小

となっています。

# 補足
今回はxmlファイルをrviz2から開いているだけなので、パッケージのビルドは必要ありません。
ワークスペースのアクティベートももちろん必要ありませんでした。
でも今後の実験に必要になってくるのでその準備だけはしておきました。

# つづき
このモノリスを次はgazeboに表示させたいと思います。

次回記事：

https://qiita.com/Ninagawa_Izumi/items/522bc711b77fd1d0e48d


https://qiita.com/Ninagawa_Izumi/items/d65e92877246e649cca6
【Android】WebViewをJetpack Composeで使った場合の、バックキーで前ページに戻る方法

WebViewでは、バックキー（戻るボタン）を押した場合に前のページに戻る（ブラウザバック）のが一般的な動作かと思います。
本記事では、WebViewをJetpack Composeで使った場合の、バックキーで前ページに戻る方法をメモとして投稿します。

# コード
```kotlin
@Composable
fun MyWebView() {
    // 1
    val backPressed = remember { mutableStateOf(false) }

    // 2
    AndroidView(
        factory = { context ->
            WebView(context).apply {
                webViewClient = object : WebViewClient() {}
            }.also {
                it.loadUrl("https://qiita.com")
            }
        },
        // 4
        update = { webView ->
            if (backPressed.value) {
                backPressed.value = false
                if (webView.canGoBack()) {
                    webView.goBack()
                } else {
                    // 前のページがない場合の処理（画面を閉じるなど）
                }
            }
        },
    )

    // 3
    BackHandler(
        enabled = true,
        onBack = {
            backPressed.value = true
        },
    )
}
```

# コードのポイント:bulb:
ポイントとなる箇所1〜4を説明します。

1. バックキーを押したかどうかの状態 `backPressed` を定義します。

1. `AndroidView` を使って `WebView` を表示させます。
1. 一番のポイントです。`BackHandler` を使って、バックキーのハンドリングを行います。バックキーが押されたタイミングで `onBack` のラムダが呼ばれるので、バックキーの押下状態を変更します。
1. 状態を変化させると再コンポーズされ、 `AndroidView` の `update` が呼ばれるので、そこで `backPressed` をチェックし、押された状態であれば `WebView` の `goBack()` を呼び出し前のページに戻ります。
プロセスビルダーの時の数式

+ [Record type name in process builder formula](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000C5UZw)


[Account].RecordType.DeveloperNameのようにオブジェクト名が必要そう。

```
(
ISNEW() 
|| 
ISCHANGED(  [Account].SBI_code_text__c ) 
)
&& 
NOT( ISBLANK(  [Account].SBI_code_text__c ))
&& 
[Account].RecordType.DeveloperName = "Account"    
```

+ [Process Builder Formula Criteria](https://salesforce.stackexchange.com/questions/208526/process-builder-formula-criteria)
TypeScriptハンズオン 学習メモ 1.TypeScriptを始めよう

# TypeScriptを準備しよう

## JavaScriptの限界

- 型のタイプが自由すぎる
- 関数も自由すぎる
    - 引数にどんな値も入れられる
- オブジェクトも自由すぎる
    - あとでいくらでも中身を書き換えることができる

## TypeScriptとは？

- 静的型付け言語
    - 型が異なるとトランスコンパイル時にエラーが出る
- クラスベースオブジェクト指向
    - 基本クラス。インタフェースもある。
- 上位互換の文法
    - JavaScriptもそのまま使える
    - JavaScriptの進化系

## TypeScriptに必要なもの

- Node.js(npm)
- TypeScript本体
    - npmにより必要なツールをダウンロードする
- Webpack
    - 多数のリソース類を一つにまとめる

## Node.jsのインストール

- 公式サイトから

## 開発ツールについて

- Visual Studio Codeを利用する


# TypeScriptによるアプリケーション作成

## トランスコンパイルについて

- TypeScriptをグローバル環境にインストールする

```sh
npm install typescript -g

# バージョン確認
tsc --V

# トランスコンパイルする
tsc sample.ts

# 作成されたjsファイルを実行する
node sample.js
```

# Node.jsプロジェクトで開発する

```sh
# プロジェクトを新規作成
mkdir typescript_app
cd typescript_app
# package.jsonの作成
npm init -y
# プロジェクトにTypeScriptを追加する
npm install typescript @types/node --save-dev
# TypeScriptの設定ファイルの追加
tsc --init
# Webpack本体とTS Loaderのインストール
npm install webpack ts-loader @webpack-cli/generators --save-dev
# Webpack-CLIで初期化（TypeScriptを選択、他はそのままEnter、Overwriteする）
npx webpack-cli init
```

## アプリケーションをビルドする

```sh
npm run build
```

- 作成されたdistフォルダ内のファイルをサーバーにアップロードすれば、Webアプリとして公開できる。

## 開発サーバで実行する

```sh
npm run serve
```

- http://localhost:8080/ を開く
- これらのコマンドは package.json の scriptsに書いてある

```json:package.json（一部）
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack --mode=production --node-env=production",
    "build:dev": "webpack --mode=development",
    "build:prod": "webpack --mode=production --node-env=production",
    "watch": "webpack --watch",
    "serve": "webpack serve"
  },
```

## Web上のTypeScript情報

### Playground

https://www.typescriptlang.org/play

### サバイバルTypeScript

https://typescriptbook.jp/
【Rails + Vue】変更が反映されない！？と思ったら bin/webpack-dev-server 忘れだった人の記事（foremanで一元管理する）

久々に開発を再開しようとしたら、変更したコードがビューに反映されなくて、てんやわんやしました。
Rails6 + Vue3で、webpackerを使って環境構築しており、`rails s`と `bin/webpack-dev-server`を、それぞれ手動で立ち上げていたことをすっかり忘れていただけだったのですが、いっそまとめて管理しようと心に誓いましたので、まとめます。

# gem foreman を使ってみる
## インストールする
gem [foreman](https://github.com/ddollar/foreman) を使って一元管理を試みます。アプリケーション実行の際のコマンドをまとめて管理できるという、ありがたgemです。

`Gemfile`に書いて `bundle install` しようとしましたが、この方法は非推奨とのこと。なので、以下を実行しましょう。

```
$ gem install foreman
```

## Procfileを新たに作成する

foremanは、Procfile の内容を継承するようになっているので、ここにコマンドを書いていきます。アプリケーション直下にProcfileという名前のファイルを作成します。拡張子はいりません。

```Procfile
rails: rails s
webpack: bin/webpack-dev-server
```

左側の名前は自由に変えてOK、右側が立ち上げる時に打っているコマンドですね。
Procfileの準備ができたら、あとは以下を打つだけで２つ同時に立ち上がります！

```
$ foreman start

```

ログも、１つのターミナルに２つまとめて表示されます。

```
02:48:15 rails.1   | started with pid 74544
02:48:15 webpack.1 | started with pid 74545
02:48:16 rails.1   | => Booting Puma
02:48:16 rails.1   | => Rails 6.0.4 application starting in development 
02:48:16 rails.1   | => Run `rails server --help` for more startup options
02:48:17 webpack.1 | ℹ ｢wds｣: Project is running at http://localhost:3035/
```

以上。ちょっと平和になったかもしれない記事でした。

少しでも役に立つことがあればうれしいです。
RailsのN+1問題をincludesメソッドで解決する

## アプリの概要（前提）
[![Image from Gyazo](https://i.gyazo.com/e4e30c01447d6af3ec95ce71221af4a9.gif)](https://gyazo.com/e4e30c01447d6af3ec95ce71221af4a9)

・こんな感じで、ユーザーaaaの投稿に対してコメントが６件ついていて、そのコメントと共に、コメントした人のユーザー情報（名前とプロフ画像）が載っている

・`/posts/8`にGETリクエストを送ると`views/posts/show.html.slim`が返される  

・ユーザーaaaの`id`は`16`  
・ユーザーoooの`id`は`17`

・Commentはbodyカラムを、Userはnameカラムとimageカラムを持つ

## N+1問題とは
N+1問題とは、データベースからデータを取り出す際に、必要以上にSQLが発行されることで、パフォーマンスが悪くなる（処理速度が遅くなる）問題のこと
## 具体例

先程のアプリのpostsコントローラー

```ruby:posts_controller.rb
def show
    @post = Post.find(params[:id])
    @comments = @post.comments.all.order(created_at: :desc)
end
```  
```erb:view
/ 投稿一覧

/ コメント一覧
<% @comments.each do |comment| %>
  <%= comment.user.name %>
<% end %>
```
`<% @comments.each do |comment| %>`のところで`post_id: 8`の全てのComment情報(body)及びコメントしたUserの情報(nameとimage)のSQLが発行される（`allメソッド`実行時ではないから注意）

その時に発行されたSQL(`rails s`の画面で確認できる)
[![Image from Gyazo](https://i.gyazo.com/8c8b779cf0db61debd4cbc2dcfce150e.jpg)](https://gyazo.com/8c8b779cf0db61debd4cbc2dcfce150e)

まず、オレンジ色の線が    
`post_id: 8`の`Comment`を全件取得（今回は６件）  
次に、赤色の線が  
1番目のcommentに紐づいているuserを1人取得(id: 17)  
2番目のcommentに紐づいているuserを1人取得(id: 17)   
3番目のcommentに紐づいているuserを1人取得(id: 17)  
4番目のcommentに紐づいているuserを1人取得(id: 16)  
5番目のcommentに紐づいているuserを1人取得(id: 16)  
6番目のcommentに紐づいているuserを1人取得(id: 16)

を表している。

このように、`post_id: 8`にされたコメントの数（６件）＋`Comment`を全件取得の１回で、合計７回SQLが発行されてしまう(usersテーブルに対してcommentの数(6回) + commentsテーブルに対して全件取得(1回))  。   
これがN+1問題と呼ばれている。   
このままでは、もし`post_id: 8`にされたコメントの数が10000件になれば10001回SQLが発行されることになってしまい、アプリのパフォーマンスの低下につながる。

## 解決方法
`post_id: 8`の`Comment`を全件取得し、その段階でそれに紐づいているuserを取得すれば、テーブルを参照する回数は２回で済み、コメントが何件になろうともSQLの発行回数は２回で済む。

具体的には、`allメソッド`を`includesメソッド`に変えるだけである。   

```ruby:posts_controller.rb
def show
    @post = Post.find(params[:id])
    @comments = @post.comments.includes.order(created_at: :desc)
end
```
※ `includesメソッド`とは、関連している複数のテーブルからデータを取得してくるときのアクセス回数を大きく減らすことができるメソッド。また、事前に検索やフィルタリング、ソートなどをしたデータを取得することもできるため、アプリケーション側でそれらの処理を行う必要がなくなる

※ 書き方は、`モデル名.includes(:関連名)`  
includesメソッドに渡す引数は、テーブル名ではなくアソシエーションで定義した関連名を指定する(テーブル名でないから注意)

<br/>

`includesメソッド`を使った場合に発行されるSQL
[![Image from Gyazo](https://i.gyazo.com/f3f2fad02782a0a688ea1ced6cc2c8ad.png)](https://gyazo.com/f3f2fad02782a0a688ea1ced6cc2c8ad)

※ オレンジ色の線で、`post_id: 8`の`Comment`を全件取得し、赤色の線でcommentに紐付くuserのデータを取得している。これなら、コメントが10000件になってもSQLの発行回数は２回で済む。

<br/>

（参考：[Railsガイド](https://railsguides.jp/active_record_querying.html#%E9%96%A2%E9%80%A3%E4%BB%98%E3%81%91%E3%82%92%E4%B8%80%E6%8B%AC%E8%AA%AD%E3%81%BF%E8%BE%BC%E3%81%BF%E3%81%99%E3%82%8B)）
イケてないswitch-case文からおさらばするPHP生活の知恵2 -PHP8編-

# はじめに

以前こんな記事を書いたんですよね。

https://qiita.com/layzy_glp/items/ea8fba02a1eba24a3123

でも最近PHP8を使うようになってもっとイケてる感じにかけるやん？ってわかったわけで、続編みたいな感じです。

# match式を使おう

ゆるゆる判定のswitch文を憎んでいるちょっとだけ意識高い目のぺちぱー諸氏は色んな方法でswitch文使わないで書こうと考えてると思うんですが、とうとうPHP8で我々の前に救世主が降り立ちました。 **match式**　です。

https://www.php.net/manual/ja/control-structures.match.php

構文はこんな感じです。

```php
$return_value = match (制約式) {
    単一の条件式 => 返却式,
    条件式1, 条件式2 => 返却式,
};
```

公式ドキュメントに書いてある大事なポイントを抜き出してきます。

> match 式は、 switch 文と似ていますが、いくつかの違いがあります:
* match 式の比較は、 switch 文が行う弱い比較ではなく、 厳密に値を比較(===) します。
* match 式は値を返します。
* match 式の分岐は、 switch 文のように後の分岐に抜けたりはしません。
* match 式は、全ての場合を網羅していなければいけません。

最後のところがめんどくさそうな雰囲気を醸し出してますが、心配はいりません。 `default` を使えばいいだけです。

# 書き換えてみよう

では前回でも使ったイケてない例を書き換えてみましょう。

```php
class HogeController {

    public function fuga($method){
        $title = '';

        switch($method){
            case 'new':
                $title = '新規作成';
                break;
            case 'update':
                $title = '更新';
                break;
        }

        return view('fuga', compact('title'));
    }

}
```

これを……

```php
class HogeController {

    public function fuga($method){
        $title = match($method){
            'new' => '新規作成',
            'update' => '更新',
            default => ''
        };

        return view('fuga', compact('title'));
    }

}
```

こうじゃ！

これはね、シビレますね！！(*´Д`)ﾊｧﾊｧ

## 関連記事

https://qiita.com/miriwo/items/f9ecdbc6b9346c8b0fed
スクルールしたら動かす

##スクルールしたら動かすやり方

```jquery:javascript
$(function() {
    $(window).scroll(function () {
	if ($(this).scrollTop() > 0) {
     ここに動かすコード書く
	} else {

	}
     });
})(jQuery);

```



```javascript:javascript
window.addEventListener('DOMContentLoaded', function(){
	window.addEventListener('scroll', function(){
		ここに動かすコード書く
	});
});


```




---------------------



参考

https://gray-code.com/javascript/execute-processing-when-scroll/
Gitlab 操作メモ

##間違ってコミットしたファイルを削除する。

```
git rm <file-name>
```

## ローカルにブランチを作って、リモートブランチを作る

`git checkout -b newBranch コピー元ブランチ`

```
git checkout -b feature/rooting develop ←developブランチからfeature/rootingブランチを作成
git push -u origin feature/rooting  ←ここでリモートブランチが作られる
```

## 直前のコミットメッセージを修正する

```
git commit --amend -m "修正後のメッセージ"
```

## マージ済のブランチを確認する

```
git branch --merged
```

## 不要になったローカルブランチを削除する。もしくは間違えて作ったローカルブランチを削除する

```
git branch -d localBranch
```

## 間違えてローカルブランチからリモートリポジトリに登録したリモートブランチを削除する

```
git push --delete origin remoteBranchName
```

## マージコミット（枝分かれ）を残してマージする

```
git checkout マージ先のブランチ名
git merge --no-ff マージ元のブランチ名
```

## カレントブランチをリモートブランチにpushする。

```
git push origin HEAD
A handy way to push the current branch to the same name on the remote.
```
PHPで\nを改行させる方法

PHPだと文字列に\nが入っていても改行されない。

ただの空白として出力される。

## 解決方法

```php
$summary = "abc\ndef\nghi";

//改行されない通常のコード
echo($summary);

//改行されるコード
echo(nl2br($summary));

```
nl2br関数を使うと、stringに含まれるすべての改行文字(`\r\n`,`\n\r`,`\n`,`\r`) の前に`<br />`あるいは`<br>`を挿入して返してくれる。

## 参考
https://www.php.net/manual/ja/function.nl2br.php

## PHPのお役立ち情報

https://wagtechblog.com/programing/php-school

https://wagtechblog.com/programing/php-book
Flutter doctor cmdline-tools componentエラー対処

# cmdline-tools component is missing
Flutterを[公式ドキュメント](https://flutter.dev/docs/get-started/install/windows)を読みながらインストールしているとdoctor実行時に以下のエラーが出ました．Android Studioで該当パッケージをインストールして解消したのでその備忘録です．
ちなみにAndroid Studioは以下のバージョン＆スタンダード構成でインストール済み
Verison：Android Studio Arctic Fox | 2020.3.1 Patch 2

```エラー文.
Running "flutter pub get" in flutter_tools...                     402.8s
Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel stable, 2.5.2, on Microsoft Windows [Version 10.0.19042.1237], locale ja-JP)
[!] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
    X cmdline-tools component is missing
      Run `path/to/sdkmanager --install "cmdline-tools;latest"`
      See https://developer.android.com/studio/command-line for more details.
    X Android license status unknown.
      Run `flutter doctor --android-licenses` to accept the SDK licenses.
      See https://flutter.dev/docs/get-started/install/windows#android-setup for more details.
[√] Chrome - develop for the web
[√] Android Studio (version 2020.3)
[√] VS Code (version 1.59.1)
[√] Connected device (2 available)
```
## 解決
まあエラーの通りCommand-line Toolsが入っていないのでインストールします．

- Android Studio　→　Settings →　Appearance & Behavior → System Settings → Android SDK →　SDK Toolsタブを選択
- Android SDK Command-line Tools(latest) Status - Not Installedのはず
- のでそれにチェックを入れてApplyするとインストールされるけど良いか？的メッセージが出ますので全部OK
- 完了！No issues found!

## ひとこと
エラーメッセージ通りの方法だとSDK Managerの場所でコマンドライン実行しなきゃらしいのですがそもそもなんのSDK？？って事態に最初悩みました．この領域はド素人なのでつらいですね～がんばろう．

ちなみにライセンスエラーはメッセージ通りに実行して全部YesすればOK.
(何個もAccept?って聞かれるけど全部読んでる人はいるのだろうか．．．”口を他人の臀部と接合すること”に同意してしまっているかもしれない．[サウスパークseason15episode01](https://w.atwiki.jp/aniwotawiki/pages/35215.html)より抜粋)
duplicityで--s3-region-nameや--s3-endpoint-urlが使えない場合の対処法

# 経緯

バックアップツールであるduplicityはS3やS3互換のバケットにバックアップを転送することができるとても便利なツールです。ところが、環境によっては、現在のduplicityはS3互換のバケット（IBM Cloud Object Storage等）をバックアップ先として利用できなくなっています。理由ですが、S3互換バケットを宛先指定するために必要なオプションである``--s3-region-name``や``--s3-endpoint-url``が、環境によっては使えないためです。例えば私の環境では、EPELで配布しているduplicityでこの事象にあたりました。

具体的に言うと、duplicityのオプションを表示すると、``--s3-region-name``や``--s3-endpoint-url``が表示されません。

```
$ duplicity --help | grep s3
  boto3+s3://bucket_name[/prefix]
  s3+http://bucket_name[/prefix]
  s3://other.host[:port]/bucket_name[/prefix]
  --s3-european-buckets
  --s3-use-rrs
  --s3-use-ia
  --s3-use-glacier
  --s3-use-deep-archive
  --s3-use-onezone-ia
  --s3-use-new-style
  --s3-unencrypted-connection
  --s3-multipart-chunk-size=number
  --s3-multipart-max-procs=number
  --s3-multipart-max-timeout=number
  --s3-use-multiprocessing
  --s3-use-server-side-encryption
  --s3-use-server-side-kms-encryption
  --s3-kms-key-id=S3_KMS_KEY_ID
  --s3-kms-grant=S3_KMS_GRANT
```

実行時に指定してもエラーになります。

```
$ duplicity full --s3-region-name ap --s3-endpoint-url s3.jp-tok.cloud-object-storage.appdomain.cloud ./src/ boto3+s3://my-icos-bucket/
duplicity: error: no such option: --s3-region-name
```

# 原因

開発元とIssueでやりとりしましたが、結論としては、duplicityを実行する環境のライブラリの問題ということになりました。

# 確実な対応方法

いくつか試しましたが、もっとも確実な方法は次の方法でした。

## tarballのダウンロードと展開

```
$ wget https://launchpad.net/duplicity/0.8-series/0.8.20/+download/duplicity-0.8.20.tar.gz
$ tar zxvf duplicity-0.8.20.tar.gz
$ cd duplicity-0.8.20
```

## 関連ライブラリのダウンロード

```
$ ./setup.py build_ext
```

## ライブラリを指定してduplicityを実行

```
$ PYTHONPATH=. ./bin/duplicity --help | grep s3 | grep -E "region|endpoint"
  --s3-region-name=S3_REGION_NAME
  --s3-endpoint-url=S3_ENDPOINT_URL
```
CSSの新しい単位qwとqh コンテナベースの相対単位って？

## qwとqhってどんな単位？
コンテナ単位と言われている「qw」と「qh」は、コンテナのサイズをベースにする相対単位です。
下記の図のようにコンテナの幅を起点としたサイズで`font`や`margin`などを指定することができます。
![スクリーンショット 2021-10-07 23.58.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146612/80f4874f-0679-faeb-88d4-59a161857941.png)

[CSS Container Query Unitsより](https://ishadeed.com/article/container-query-units/)

vwやvhは非常に便利でしたが、ビューポートサイズに相対するため意図しない表示になってしまうこともあったと思います。
現在のReactやVueなどコンポーネント単位で実装する言語とは相性が良いのではないかと思います。

## 対応状況は？
結論、今は設定をしないと使えません。
デモとしてなら良いですが、一般公開するサイトには利用できないでしょう。

試したい場合は以下のステップで設定をしてください。
1. [chrome://flags/](chrome://flags/)にアクセス
2. 「container queries」で検索
3. 「Default」になっているのを「Enabled」に変更する
![スクリーンショット 2021-10-07 23.53.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146612/ca384275-d697-9114-e7b4-c908ae575828.png)


## 1qwはいくつ？
公式ドキュメントによると1の単位はコンテナ幅の1％に当たるようです。

|単位|説明|
| ---- | ---- |
|qw|コンテナ幅の1％。10qwならコンテナの幅の10％|
|qh|コンテナの高さの1％。10qwならコンテナの高さの10％|

[公式ドキュメント](https://drafts.csswg.org/css-contain-3/#container-lengths)

## おまけコンテナークエリ（Container Query）って？
これまでは`media query`window幅に応じてCSSで表示を切り替えてきたけど、
コンテンツクエリは親要素の幅に応じてCSSを適応していくというものです。

```css
@container (min-width: 500px) {
  .child {
    display: flex;
    align-item: center;
  }
}
```

と書くことで親要素の幅が500より大きいときに横並びにする。
という記述をすることができます。

めっちゃ便利。


## 参考URL一覧
- [CSSの新しい単位がすごく便利！コンテナベースの相対単位「コンテナ単位（qw, qh）」の基礎知識と使い方](https://coliss.com/articles/build-websites/operation/css/css-container-query-units.html)
- [CSS コンテナクエリの基礎知識と便利な使い方を解説](https://coliss.com/articles/build-websites/operation/css/about-css-container-queries.html)
- [CSS Container Query Units](https://ishadeed.com/article/container-query-units/)
- [CSS仕様](https://drafts.csswg.org/css-contain-3/#container-queries)
【SQL】各条件に該当するレコード数の取得

WHERE句で絞り込まず、SELECT句で各条件に該当するレコード数を集計する。
この時、書き方がいくつかあるので紹介。

※GROUP BYで集計できない（不足がある）ケースを想定してね！

## サンプル
以下のデータ（witnesses）を想定して記述していきます。

| 名前 | 號数 |
|:----:|:----:|
| 夜行A  | 0 |
| きゃどくら  | 2  |
| チャンミダ  | 28 |
| 課長 | 29 |
| 銅寺 | 10 |

このデータにおいて以下のそれぞれの集計していきます。

* 號数が10以上
* 號数が10未満

## 1. CASEの利用
昔からある書き方です。
各レコードに対してCASEで条件判定し、該当する場合は1、そうでなければ0とします。
その結果をSUMすることで該当数を出しています。

後述の別手法も同様ですが、WHERE句による絞り込みと比較し、
対象となるレコード全体は減らさずに集約関数の対象となるレコードを絞り込むことができるので、
一文で様々な条件で集計などをかける場合に使用します。

```sql:
SELECT
    SUM(CASE 號数 >= 10 THEN 1 ELSE 0 END) AS 二桁立会人
    , SUM(CASE 號数 < 10 THEN 1 ELSE 0 END) AS 一桁立会人
FROM
    witnesses
```

下記のSELECT文の結果にある各フラグをSUMしていると捉えるとわかりやすいと思います。

```sql:
SELECT
    名前
    , 號数
    , CASE 號数 >= 10 THEN 1 ELSE 0 END AS 二桁立会人フラグ -- 0 or 1
    , CASE 號数 < 10 THEN 1 ELSE 0 END AS 一桁立会人フラグ -- 0 or 1
FROM
    witnesses
```

## 2. FILTER句の利用
SQL:2003で追加された機能です。

```sql:
SELECT
    count(名前) FILTER(WHERE 號数 >= 10) AS 二桁立会人
    , count(名前) FILTER(WHERE 號数 < 0) AS 一桁立会人
FROM
    witnesses
```
COUNTなどの集約関数の末尾にWHERE句同様の記述することで対象の絞り込み可能です。
CASEの利用と比較して直感的に、かつ慣れ親しんだ記述が可能です。
僕はこっちが好きです。

## その他
下記リンクのような書き方もあります。
https://qiita.com/zb185423/items/f20b21ca041989410b5f

万が一疑問が残った方は、下記SELECT文で確かめてみるとわかりやすいかも。

```sql:
SELECT
    名前
    , 號数
    , 號数 >= 10 AS 二桁立会人フラグ -- TRUE or FALSE
    , 號数 < 10 AS 一桁立会人フラグ -- TRUE or FALSE
FROM
    witnesses
```

元記事にもある通り、両フラグともTRUE/FALSEとなるはずです。
非NULLはCOUNTの対象なのでそのままだと全レコードが対象となってしまいます。
その対応のために「条件判定 OR NULL」とするわけですね。

勉強になります。
詳しくは元記事の方が丁寧に書いてくれてますのでそちらをご参照ください！

## まとめ
同じ結果を求めるために様々な書き方があることがわかりますね。
もちろん、どんな時でも今回の書き方を使えばいいわけではないですね。

WHERE句で対象レコードを絞りこめたほうがパフォーマンス的にはよいので、
まずはWHERE句でレコードそのものを絞り込めないか、から検討したほうがいいと思います。
[CakePHP] 型情報付きでエンティティを取得する

前回の[型情報付きでテーブルオブジェクトを取得する](https://qiita.com/hoogee/items/f476031427a270acc2cd)の続き

### 課題
通常CakePHPではエンティティオブジェクトをQuery/ResultSetからfirst()等で取得する。
ResultSetからforeachで取るような場合は```@var```書くしかないして、fisrt()のときくらいはEntityInterfaceではなく具体的な型情報がほしい。

###解決策
ジェネリクスを使用した回避策がこれ。
例としてByIdにしてあるけど条件は好みで適当に調整。

```
use Cake\Utility\Inflector;

/**
 * @template T
 * @param class-string<T> $fullEntityName 完全修飾エンティティ名
 * @param int $id
 * @return T of \Cake\ORM\Entity
 */
public static function getEntityById(string $fullEntityName, int $id, array $contain = [])
{
    if (!preg_match('#(\w+)$#', $fullEntityName, $matches)) {
        throw new \DomainException();
    }
    $tableName = Inflector::pluralize($matches[1]);

    return TableRegistry::getTableLocator()->get($tableName)->findById($id)->contain($contain)->first();
}
```

使用例

```
$article = getEntityById('\App\Model\Entity\Article', 3);

または

$article = getEntityById(\App\Model\Entity\Article::class, 3);

または

use \App\Model\Entity\Article;
$article = getEntityById(Article::class, 3);

いずれも\App\Model\Entity\Article型としてIDEに認識される
```

### 留意事項
テーブルモデルと同様、ジェネリクスを使う都合上、単にgetEntityById('Articles', ~~)と書くことはできず、完全修飾名で指定する必要がある。
使用例の真ん中の書き方であればIDE補完付きで書くことができるのでそれほど手間ではない。

また配列形式であれば以下のように書けるはずだが、現時点ではPhpStormは対応しておらず、今後対応予定とのこと。([公式ブログ](https://blog.jetbrains.com/phpstorm/2021/07/phpstorm-2021-2-release/#generics)のWI-60894 Support parameter wrapping)

```
use Cake\Utility\Inflector;

/**
 * @template T
 * @param class-string<T> $fullEntityName 完全修飾エンティティ名
 * @param string $named
 * @return array<int, T>
 */
public static function getEntitiesByName(string $fullEntityName, string $name, array $contain = [])
{
    if (!preg_match('#(\w+)$#', $fullEntityName, $matches)) {
        throw new \DomainException();
    }
    $tableName = Inflector::pluralize($matches[1]);

    return TableRegistry::getTableLocator()->get($tableName)->findByName($name)->contain($contain)->toArray();
}
```
雑談でリモートワークでの生産性を上げる取り組み

リモートワークが始まってから随分と時間が立ちました。
以前より働きやすくなった方もそうでない方もいらっしゃるのではないかと思います。

今回は、**slackを利用したリモートワークでの雑談のきっかけづくりの取り組み** について書いてみました。

# なにをやったか
ご存じの方もいらっしゃるかと思いますが、Colla（Slackアプリ）を導入してみました。
https://colla.jp/

# なにをやってくれるのか
* 定時にbotがメンバーに質問をしてきます
* メンバーが答えた内容をまとめてチャンネルに流してくれます

# なにがいいのか
雑談をすることで生産性が上がるみたいな話を聞いたことあるかと思います（個人的には、雑談が心理的安全性を高めるのに一つの要因にでもなっているのかなとか思っています）。

とはいえ、いきなり時間を設けて雑談しましょう！ としたとしても、定着まではなかなか難しいのかなと思います。
Collaの良いところは、そんな問題を解決するために、**"雑談を生むためのきっかけ"** を毎日与えてくれることで、**"雑談の定着を促す"** 点にあるのかなと思っています。

また新しくチームに配属される方がいる場合、対面で一度も会ったことが無いケースでも、チームに馴染みやすくするための手助けになることも期待できる点もあると思います。

# 個人的に気に入っている点
**"質問が秀逸な点"** これに尽きます。
予想の遥か上をいくような内容を質問してきますし、その甲斐もあってか、ちょっと**大喜利のような気分**になる時もあります（自分は全く笑いが取れませんが...）

ただ考えてみると、この辺りはプロダクトとしてよく考えられているなと思います。
ありきたりな質問だけだと、飽きが来ますし、そうなると定着にはつながらないので。

# Collaの質問例
**ネタっぽい質問のパターン**
![colla_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1780140/fe8e8f9b-9450-e561-e159-c4ab3e22940d.png)

**真面目な質問のパターン**
![colla_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1780140/f44898ef-1f90-4f4d-59b9-c03de609fa9d.png)

**大喜利を誘うパターン（<del>回答は私がスベったもの</del>）**
![colla_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1780140/d4f57537-0ee9-34d9-cd66-35ea5a70f019.png)


# 導入後はどうなったか
Collaの回答からスレッドで雑談が発生することもありますし、**Collaと関連がないところでも雑談が発生するようになった** かとは思います。
家で栽培している植物の話とか、料理したお昼ご飯の写真をアップしたりなんかが実際にありました。
（もちろん全てがCollaによるものだとは思わないですが、雑談定着の要因の一つにはなっていると思っています）

# さいごに
リモートワーク中でSlack導入をしているところは多いかと思います。無料で使えるアプリですし、一度試して見る価値はあるかと思います。
**"雑談が減ってきたなと感じている方"** や **"これから新しくチームに配属する方に早く馴染んでほしいと考えている方"** は、導入を検討しても良いかと思います。
AngularアプリでBootStrapを使ってみる

# BootStrapとは
BootStrapはCSSのフレームワークです。BootStrapを使うとデザイナーでなくても簡単にそれっぽい見た目の画面を作成することができます。
また、Sassが採用されているため変数を使う・CSSクラスを継承して新しいCSSクラスを作るなど、プログラミング言語っぽくCSSを記載することができます。
Angularを使用していない場合でももちろんBootStrapは使えますが、jQuery等の関連ライブラリを読み込む必要があります。
また、Sassは直接ブラウザで読み込むことができないためCSSファイルにコンパイルする必要があります。
Angularを使っている場合はそれらの面倒をすべてAngularが補ってくれるため、比較的簡単にBootStrapの恩恵を受けることができるみたいです。
見た目には特にこだわりはないけどそれなりに見やすい画面を作成したいといった場合に使えそうですね。
# bootstrap(ng-bootstrap)を使ってみる
こちらを参考にしました。
[bootstrapの変数の書き換え方](https://qiita.com/pikanji/items/111cfb353bd6ec1eabb5)
[bootstrapの主な変数](https://higuma.github.io/bootstrap-4-css-customization/ja/variables.html)
[SCSSの記法](https://anteku.jp/blog/develop/scss1/)

インストールは以下のコマンドで行う（Angular9.x以降の場合）


```
ng add @ng-bootstrap/ng-bootstrap 
```

node_modulesフォルダ下にbootstrapがインストールされて、Angularアプリ内での利用が可能になる。（node_modules\bootstrap）
app.module.tsのimports配列にNgbModuleが追加される。

```app.module.ts
...
import { ParamComponent } from './param/param.component';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';

@NgModule({
  declarations: [
    AppComponent,
    EventComponent,
    ...
  ],
  imports: [
  ...
    NgbModule
  ],
  ...
})
export class AppModule { }
```

また、angular.jsonではAngularアプリ全体の設定（ビルドの設定）が記載されている。
以下のようにアプリで共通のCSSファイル（src/styles.scss）がAngularではデフォルトで用意されているが、bootstrapをインストールすると共通のCSSファイルにbootstrapがimportされる。

```angular.json
            "styles": [
              "src/styles.scss"
            ],
```

```styles.scss
/* You can add global styles to this file, and also import other style files */

/* Importing Bootstrap SCSS file. */
@import '~bootstrap/scss/bootstrap';  //bootstrapがimportされている
```
この時点でAngularアプリにはbootstrapが適用されていて、見た目が変わっている。
bootstrapの設定を書き換えたい場合は、SCSSの変数を書き換えればいい。
bootstrap全体で使われている変数は`node_modules\bootstrap\scss\_variables.scss`に記載されており、
変数の後ろに`!default;`が記載されている。
styles.scssでbootstrapを読み込む前に変数を定義することで、上書きすることができる。


```_variables.scss
$font-size-base:              1rem !default; // Assumes the browser default, typically `16px`
$font-size-lg:                $font-size-base * 1.25 !default;
$font-size-sm:                $font-size-base * .875 !default;
```

↓変数を上書きして独自の見た目に書き換える

```styles.scss
/* You can add global styles to this file, and also import other style files */
$theme-colors: (    //テーマの色を変えている
  primary: rgb(49, 190, 148)
);
$font-size-base: 2rem;    //文字のサイズをデフォルトの1remから2remに変更
/* Importing Bootstrap SCSS file. */
@import '~bootstrap/scss/bootstrap';

```

結果
文字のサイズが2倍になり、リンク文字の色が変わっている
![AngularアプリでBootStrapを使ってみる_sample1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2130321/5e6fd4fc-2de2-2f1a-a48d-5616cc0c39f1.png)
Chromeのオススメな初期設定10選(Mac)

Chromeのオススメな初期設定10選(Mac)

今回はMacのChromeのオススメな拡張機能や設定を紹介します。
Chromeの設定をおこうことでより便利にブラウザを使用することができます。特に拡張機能とキーボードの設定を変更することをオススメします。

##☆リンク

・[Macのオススメな初期設定15選(メールアプリ設定編)](https://qiita.com/x5dwimpejx/items/724adb7bc75701906e68)

・[Macのオススメな初期設定30選　(システム環境設定編)](https://qiita.com/x5dwimpejx/items/2917b2f4c710bceab24f)

・[Macのオススメな初期設定20選(Finder設定編)](https://qiita.com/x5dwimpejx/items/d1cafbfcf1ca4a31e578)

・[Chromeのオススメな初期設定10選(Mac)](https://qiita.com/x5dwimpejx/items/86008a0b4beeb22ff5e1)

・[Macのオススメなアプリ40選](https://qiita.com/x5dwimpejx/items/98bad7b354887647b4ca)

・[【未経験】【資格】AWS ソリューションアーキテクト（SAA） 合格までの勉強方法(約50時間)](https://qiita.com/x5dwimpejx/items/0b9b7e7b502d8bd255e9)

##Chrome拡張機能
####Google翻訳
必須の拡張機能です。英語サイトは全て翻訳できるようになります。めちゃくちゃ便利で英語が不要になります。

####Google検索キーボードカット
こちらも必須です。検索にまつわる操作をキーボードのみで行えるようになります。

####Notion Slides by Wunderpresentation
Notionに書いた内容を元に素早くプレゼンテーションを作ります。

####OneTab
複数開いているタブを一括に整理します。

####Black Menu for Google
小窓の検索窓を表示して検索ができるようになります。

####grt Memo
メモをすぐに呼び出せるようになります。Clipyと同じような機能ですが、Clipyはアプリ間で利用できるのに対して、こちらはChromeのみです。

####Save To Pocket
Pocketを使用していれば、Pocketにすぐに登録できるようになります。

##Chrome設定

####デフォルトブラウザへ設定
　Chomeで設定してもいいし、システム環境設定で設定してもいいです。

####ブックマーク
ブックマークの使い方としては、フォルダを作り、その中にSaaSやWebアプリを登録しておきます。Alfred 4でブックマークを検索できるようにしておくと、めちゃくちゃ便利です。

####キーボードのショートカット
システム環境設定から以下のショートカットキーを設定しました。これは完全に好みなので参考にして見てください。
 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406910/745b56f3-9fe2-90d7-ba33-318b7ccec1aa.png)

####拡張機能のショートカット
こちらも好みなので参考までに見てください。

拡張機能のアイコンを選択します。
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406910/42d8b0f9-f0d1-a501-c3a8-619b84206a49.png)

拡張機能の左のアイコンをクリックします。
 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406910/8c63b569-d16a-2931-8ca9-e9e6e6020d37.png)
 


キーボードショットカットをクリックします。
 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406910/d5bdc85e-bdff-452d-c6af-93e75ff7f624.png)

各キーボードのショートカットを設定します。
 
  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406910/35249664-efeb-8dd0-41db-f20683e73e85.png)
 
  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406910/9496dfec-5b2c-82e4-78cb-46dd2c092477.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406910/417b196e-5026-5086-38c6-9b6f5c962a74.png)
setodaNoteCTF - stay_in_touch 150 

#問題

https://ctf.setodanote.net/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/1bf19ca9-1a93-d0d3-61f1-178fe629cc62.png)

#解いてみた

ファイルを見ます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/46f49ca7-6bc0-6c55-3407-cc5543cdc774.png)

IMAPなどがあるところを見るとメール関連の問題のようです。

[ファイル]⇒[オブジェクトをエクスポート]⇒[IMF]

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/a379e1b0-3353-d720-6134-33aff04c7f63.png)

たくさんメールがあるので全部エクスポート。

全部見てみましたが、本文が見れるのは雑談系のメールだけで以下のような重要そうなメールは本文が表示されませんでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/789d2ad9-c28c-034d-c558-cf4f57ae39af.png)

右クリック⇒[追跡]⇒[TCPストリーム]を見てみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/a339db28-ff98-a310-6a35-8bc8c17437ab.png)

なんかよくわかりませんが、パスワードが手に入りました。

その少し前のTCPパケットを見るとファイルを送付したであろうメールを見つけました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/4f6f2e41-c037-0239-4e8d-b11f25e4305d.png)

この中からメールのプロトコルっぽいところを無視してコピペして保存。

具体的には
Subject: =?UTF-8?B?UmU6IOOAkOOBlOebuOirh+OAkeiqsumVt+S7o+eQhuOBruW4sOekvg==?=
から
--------------E3A9083942D9027C4375FEE4--
までをコピペ。
x.emlで保存。
outlookで開く。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/e3c20dbd-741c-f11d-bbdc-03668bf9408f.png)

添付ファイルをダウンロードしてさっきのパスワードを入力します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/27d924ca-4cdd-6c8b-a377-38e8256e5b03.png)

できました。
Rspec バリデーションをエラーメッセージのキーでテストする

RSpecを勉強していてモデルのバリデーションのテストを検証する際、以下のようにエラーメッセージを含んでいるかどうかでテストを行なっていた。

```ruby
it 'is invalid without a title' do
    post = create(:post, title: nil)
    post.valid?
    expect(post.errors[:title]).to include("can't be blank")
end
```

しかし、国際化に対応した時、英語だけではなく日本語や他の言語の時もテストしたい場合どうなんだろうと思った。
そこで調べていたところ、このエラーメッセージに対応するキーが存在するかどうかのマッチャーがRails6から導入されていたらしい！　
[どのフィールドにどの検証エラーが追加されたのかを、「表示言語やエラーメッセージに依存しない形で」テストする方法](https://qiita.com/jnchito/items/6cf94a82e719c1dca5f1#%E8%BF%BD%E8%A8%98rails-6%E3%81%A7%E3%81%AF-errorsof_kind-%E3%81%8C%E4%BE%BF%E5%88%A9)

これによって、次のようなテストを書くことができる。

```ruby
it 'is invalid without a title' do
    post = create(:post, title: nil)
    post.valid?
    expect(post.errors).to be_of_kind(:title, :blank)
end
```

こっちの方が個人的には好み〜
また、バリデーションエラーメッセージに対応するキーについてはこちらにリストアップされていた。
[Railsガイド](https://railsguides.jp/i18n.html#%E3%82%A8%E3%83%A9%E3%83%BC%E3%83%A1%E3%83%83%E3%82%BB%E3%83%BC%E3%82%B8%E5%86%85%E3%81%A7%E3%81%AE%E5%BC%8F%E5%B1%95%E9%96%8B)

ちなみに、`#of_kind?`メソッドについて調べてみたところ第２匹数にはキーだけでなくエラーメッセージを渡すこともできる。
[API doc](https://apidock.com/rails/ActiveModel/Errors/of_kind%3F)
Swift - #colorLiteral使ってカスタマイズのUIColorを定義

#はじめに
UI部品に色を指定したい場合、↓のようにstoryboardでいじる以外、
![截圖 2021-10-07 22.10.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1326861/7a3cd733-d929-7a28-1faa-5739c1bfd2db.png)
コードで指定することもできます。例えば、

```サンプル.swift
self.view.backgroundColor = UIColor.black
```
`.black`黒色は内蔵の色なので、`UIColor.`を入力して、自動的にリストが出てくると思います。↓の感じ
![截圖 2021-10-07 21.32.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1326861/15d97c1c-2127-d126-6608-9f84127bfa6a.png)

でも、もし欲しい色は内蔵にない場合はどうすればいいですか？storyboardでなら、「custom...」が選べるのだが、コードの場合は？？
#まず
UIColorをextensionし、欲しい色の名前を宣言しましょう。
#次
**#colorLiteral(red: 1, green: 0.8, blue: 0, alpha: 1)**をreturnします。
↓のように

```sample.swift
extension UIColor {
    static var cusLightYellow: UIColor { return #colorLiteral(red: 1, green: 0.8, blue: 0, alpha: 1) }
}
```
#欲しい色の数値わからない？？
大丈夫です！↑のコードを入力したら、↓のように出てきます（色の枠）。
![截圖 2021-10-07 22.39.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1326861/078e41b5-3b42-e37e-b5d4-0c5c7f99faad.png)
この枠をクリックすると、storyboardみたいなカラーパネルが出てきます。
![截圖 2021-10-07 22.41.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1326861/1a085f41-0c9a-e47e-746d-c463a3a6dbd1.png)
#それでも欲しい色がない？？
下の「Other...」をクリックすると、storyboardの「custom...」のようなものが出てきました！ここで自由に選べます！めでたしめでたし
![截圖 2021-10-07 22.46.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1326861/4dcc30d1-e939-d348-e5c6-82270ae725f7.png)
#最後に
普通にコードのカラーリストを確認してみたら、先ほど宣言した「cusLightYellow」が出てきました。

```サンプル.swift
self.view.backgroundColor = .cusLightYellow
```
![截圖 2021-10-07 23.03.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1326861/c01e1679-ec95-c026-4a90-41ef22c1169c.png)
setodaNoteCTF - echo_request 120 

#問題

https://ctf.setodanote.net/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/5211c88f-6d04-017e-b124-61aa45a93291.png)

#解いてみた

ファイルを見てみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/ca3f36d1-fd9f-2bd5-3c78-0678abbc11f8.png)

パケットがたくさんあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/df08670a-322a-62cb-be50-fa8177057d87.png)

途中からpingがたくさん投げられていてちょっと気になります。タイトルもecho_requestですし。
1つずつどういった違いがあるか見ていると29番パケットから1文字ずつフラグが書かれていることに気づきました。

数が多いので最初の二つだけ画像とります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/42fb9500-265a-36eb-2bd1-ab3193721c54.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/e472d2b5-8c9a-6856-373a-526371a7827c.png)

これをそのまま入力すると正解でした。
初めてのオリジナルアプリ公開までの道のり

# 公開までの道のり

月 | やってたこと
--- | ----------------------
５月 | tech camp（教養コース入学）
７月 | tech camp（転職コース入学、夜間休日タイプ）
８月 | カリキュラム終了
９月 | オリアプ作成開始
１０月 | オリアプ完成

卒業予定は１月、笑

# 公開したアプリの概

## アプリ名
**FX-Traders**
https://fxtraders.jp

## どんなアプリ？
fx取引の記録を公開できるアプリになります。そしてその記録をもとにグラフを作り結果を解析できるアプリです。
それを公開することで

* 自身が決めた取引ルールの厳守
* 取引ルールのブラッシュアップ
* 第三者からのフィードバック
* 他者取引への理解

などを狙っています。

## なんで作ったの？
まずは自分で欲しかったから。一番大きな理由でもありますね。学生の頃にfxの記録を紙のノートに書いていて、画像を残せないのが残念で書くだけで満足していて、笑笑
こんなことを思っている人がたくさんいるんじゃないか？って思ったのも作った理由のひとつです。
あとはコロナ禍で投資を始める人も増えていることが想定されますから需要もあるかと思ってもいます。

なので、

* 自分が使いたい
* あるといいなと思っている人もいるのでは？
* コロナ禍で投資人口も増えているのでは？

と言うところでこのアプリを作りました！

## アプリ実装項目

### 取引記録
* 投稿
* 編集
* 削除
* 検索（gem, ransack）
* 画像投稿（gem, active storage）
* いいね機能（ajax, font awesome）

### 取引手法
* 投稿
* 編集
* 削除
* 検索（gem, ansack）
* 画像投稿（gem, active storage）
* いいね機能（ajax, font awesome）

### コメント
* 投稿（ajax）
* 削除（ajax）

### ユーザー関連
* フォロー機能
* グラフ表示（gem, chartkick）
* メール認証機能
* 管理者機能

### seo対策
* メタtag（gem, meta_tags）
* ぱんクズリスト（gem, gretel）
* サイトマップ（gem, sitemap_generator）
* サイトマップの自動更新（gem, whenever）

### デプロイ
* aws（ec2, s3, route53）
* mysql（maria DB）
* Unicorn
* Nginx
* 自動デプロイ（gem, Capistrano）
* ssl証明（AWS, ACM）

### その他
* ページネーション
* 日本語対応（gem, rails-i18n）
* 広告のランダム表示
* 問い合わせ（ライン公式, font awesome）
* ハンバーガーメニュー
* PV数(閲覧数)取得（gem, impressionist）
* OGPの設定（gem, meta-tags）

# アプリを作った感想
勉強期間は約3ヶ月ですが自分的には満足できるものができました。が、まだ実装したいことがたくさんあるので追加実装を続けていく予定です。
さらにreact, react nativeを勉強していきたいなと思っています。
m1でbrew installができない

## 環境
macOS Big Sur 11.6
## 問題
`brew install` を実行したら以下のエラーが出た。

```:ターミナル
Error: Cannot install under Rosetta 2 in ARM default prefix (/opt/homebrew)!
To rerun under ARM use:
    arch -arm64 brew install ...
To install under x86_64, install Homebrew into /usr/local.
```

## 解決法
以下を実行する

```:ターミナル
arch -x86_64 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
```
その後に

```:ターミナル
arch -arm64 brew　〇〇
```
これでインストールできました！
AutoMLを使って30分でSignate-Intermediateへ昇格

# まえがき

Signateではコンペティションの成績で7段階で称号が割り当てられていますが、１つ上げるだけでもかなりハードルが高いものだと思っていました。レベルが高いのはもちろんのこと、コンペが数多くあるわけではないので昇格するのに時間がかかるものだと決めつけていましたが、意外とそうではありませんでした。
称号付きコンペやSOTA Challengeなど、昇格する機会を設けてくれており、運営の方々には感謝です。
試しに称号付きコンペに参加をし、初手でAutoMLを使ってみた所、案外すんなり閾値を超えることができ、Intermediateに昇格しました。
30分かからずにできたのでせっかくと思い、記事を作成しました。

↓SignateHPから引用（https://signate.jp/users/rankings/help）
![img-tier-pyramid@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1903093/7a43380b-983b-f0c3-d277-fb1ed3e4aecf.png)


# 参加コンペティション
2021年10月のみ開催されているコンペです。

https://signate.jp/competitions/552


# コード

## ライブラリのインポート
```py
import pandas as pd
```

```py
!pip install pycaret
from pycaret.classification import *
```

## データの読み込み

```py
train_data = pd.read_csv("train.csv")
train_data
```

![スクリーンショット 2021-10-07 21.27.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1903093/076648e9-22e3-2e61-032c-827c95d4040e.png)



```py
test_data = pd.read_csv("test.csv")
test_data
```



![スクリーンショット 2021-10-07 21.28.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1903093/f9c6a355-dee1-dc3d-c231-27f87bfa93d4.png)



**学習データの正解ラベルの割合**

```py
len(train_data[train_data["loan_status"]==1])/len(train_data)
```
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1903093/36ffeddb-6741-5a01-2120-729f32e18a9a.jpeg" width=80%>

## Pycaret

```py
model = setup(data=train_data, target="loan_status")
```
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1903093/66bbda2a-e6ef-2a52-f8f9-8444fa7dabc9.jpeg" width=50%>

```py
compare_models()
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1903093/e1c4430c-1904-f0a7-0c77-570a2474eab0.png" width=90%>



**個人的にLightGBMが好きなので、とりあえず使っています。**

```py
model = create_model("lightgbm")
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1903093/93b215e2-30c3-b4fa-10e9-cc5e9834e62f.png" width=60%>


## F1スコアが最適になるようにパラメーターをチューニング
```py
tuned_model = tune_model(model, optimize="F1")
```
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1903093/6c884620-f0b3-a927-6c99-551132d4e6b5.png" width=60%>

※Accuracy Ver.
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1903093/eddb9f5c-9358-5914-5043-0ada1b291a49.png" width=60%>



```py
evaluate_model(tuned_model)
```

![スクリーンショット 2021-10-07 21.38.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1903093/e0eaa8fa-2f8a-6e47-30d4-7e341af640a5.png)



**とりあえず、学習データの正解ラベルの割合を閾値として採用**

```py
test_pred = predict_model(tuned_model, probability_threshold= 0.2148, data=test_data)
test_pred
```

![スクリーンショット 2021-10-07 21.39.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1903093/710580d7-ec1d-7bc8-c601-760446579b01.png)



## 提出

```py
sample = pd.read_csv("submit.csv", header=None)
submission = sample.drop(columns=[1])

submission[0] = test_pred["Label"]
submission.to_csv("submission.csv", header=None)
```

# あとがき
Intermediateに昇格したことによって自己アピールにつながればいいなと思っています。
次は、AdvancedやExpertに昇格できるようにSOTA Challengeに参加してメダル獲得できるように頑張りたいと思います。
【超初心者向け】belongs_toとhas_many、アソシエーションってなに？

# belongs_toとhas_many アソシエーションについて


belongs_toとhas_manyが「あれ？どっちがどっちだっけ？」となっていたので、備忘録として記載。

####そもそも関連付け（アソシエーション）とは？
テーブル同士に関係があることを表現すること。

例えば、茶川さんという著者（author）　がいて、羅生マンという本（book）を書いていたとする。（※架空の著者・本です。）

茶川さんはauthorテーブル、羅生マンはbook テーブルにそれぞれ保存されます。この状態は、一人の作者に対して一冊の本なので、「1対1」です。

ここで、茶川さんが「蜘蛛と糸」という本（book）を書いたとする。
すると、bookテーブルには新たに「蜘蛛と糸」という本が追加されるので、
一人の著者に対して複数の本が関連付いていることになります。
これが「1対多」の関係になるということになります。この際に、model　記載するのが「belongs_to」と「has_many」ということになります。
今回の例でいうと、一人の著者が複数の本を書いている（ここでは都合よく本が著者に従属していると考える）ため、

belongs_to・・・book
has_many・・・author

ということになります。

つまり、それぞれのmodel 記載する場合は、このように記載しましょう。

```
class Autor < ApplicationRecord
     has_many :books
#bookモデルだが、1対多の「多」に該当するため、ここではbooksになる。has_oneを用いる場合は「book」
end
```

```
class Book < ApplocationRecord
     belongs_to :autor
end
```


以上簡単ではありますが、自分が忘れがちなポイントに関して書き留めておきました。
自分と同じ初学者の方のとっかかりとして使用していただければ幸いです。また、個人的にはQiitaだけではなくしっかりと公式のドキュメントを読んでいく癖もつけていきたいです！

https://railsguides.jp/association_basics.html
React Study(1)

# React勉強はじめます
　これまでバックエンド側のゴリゴリのJavaとかOracle PL/SQLしかやってこなかったので、ユーザーサイドの画面側の技術についてめちゃくちゃ疎い。しかもここ5年くらいは本当に管理職の仕事しかしていないからすべての技術知識が化石級に…。
　しかしながらこれからの時代、バックエンドからフロントエンド、何ならクラウド含めたインフラ環境まで知識としてつけておかないとエンジニアのマネジメントもままならない。
　ってことで、フロントエンドの技術中心に勉強始めようと思います。
　世のため人のためになる、っていうよりは、自分学習メモなのでさらっと書いていきます。

# とりあえずHello React的なところから
ありきたりなことやっていきます。
## 環境回り
　まずはReact環境の作り方。って言ってもWindowsでnode.jsインストーラーで入れるだけです。

```console:nodeバージョン
c:\projects>node -v
v14.18.0

c:\projects>npm -v
6.14.15
```
## Hello React
　create-react-appしてプロジェクト作ります。

```console:プロジェクト作成
c:\projects>npx create-react-app react_practice
（省略）
Happy hacking!
```

　出来上がったらnpm startするとブラウザが勝手に開きます。

```console:起動・動作確認
c:\projects\react_practice>npm start
```

http://localhost:3000/ がデフォルトのポートになっているのでそのアドレスが勝手に開きます。
![react-start.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/833719/801c0add-a400-9124-0638-4914e1786035.jpeg)
　初歩の初歩はまずここから。
　これから画面の通り、src/App.jsをいじって勉強していきます。