OmniAICreator/Qiita-1.07M huggingface dataset:
Swift TextFieldに入力された文字がメールアドレスかどうか確認する方法

#TextFieldに入力された文字がメールアドレスかどうか確認する方法
今回、TextFieldに入力された文字がメールアドレスかどうかによって条件分岐する方法を実装していきたいと思います。

#まず初めにLabel,TextField,Buttonを設置
![スクリーンショット 2020-12-24 15.47.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933229/43dc3e32-4c14-3462-ea9b-e5a5b9cf19b4.png)

#次にitemとコードを接続
![スクリーンショット 2020-12-24 15.49.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933229/15ecf39f-3f3c-9782-47bd-9b2e3fbc78c7.png)

#下記のコードを追加する

```
//メールアドレスかどうかのクラス
class func isValidMailAddress(_ string: String) -> Bool {
        let mailAddressRegEx = "[A-Z0-9a-z._+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"
        let mailAddressTest = NSPredicate(format:"SELF MATCHES %@", mailAddressRegEx)
        let result = mailAddressTest.evaluate(with: string)
        return result
}
```

#ButtonをTouchUpInsideで接続
![スクリーンショット 2020-12-24 15.59.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933229/3a3dff8d-38a9-3539-c352-cd1135ae72ef.png)

ここにコードを書いていきます

#ラストスパート！

```
import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var Label: UILabel!
    @IBOutlet weak var TextField: UITextField!
    @IBOutlet weak var Button: UIButton!


    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }


    //メールアドレスかどうかのクラス
    class func isValidMailAddress(_ string: String) -> Bool {
            let mailAddressRegEx = "[A-Z0-9a-z._+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"
            let mailAddressTest = NSPredicate(format:"SELF MATCHES %@", mailAddressRegEx)
            let result = mailAddressTest.evaluate(with: string)
            return result
     }


    @IBAction func ButtonTouchUpInside(_ sender: Any) {
        //メールアドレスが正しい時
        if ViewController.isValidMailAddress(self.TextField.text!) {
            Label.text = "正しいメールアドレスです"
        //メールアドレスが正しくない時
        } else {
            Label.text = "正しいメールアドレスを入力してください"
        }
    }


}
```

#完成
![ezgif-6-b32a736c76c7.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933229/f4d8b281-6df7-2571-3ea4-af23d2f2e5fe.gif)
restclient-jqを使う


<2023年5月4日追記>
`restclient-jq`がpackage.elで入るようになっていました。(2022年4月に対応されたようです)
<追記ここまで>


emacs上のrest clientとして[restclient.el](https://github.com/pashky/restclient.el)という便利ツールがあります。

このREADMEの中に`jq-set-var`というものを使って、レスポンスの中身を`jq`で編集して変数に代入する機能の説明があります。
ところが、実際にサンプル通り記述すると

```
Unknown restclient hook type jq-set-var
```
というエラーが出て、動いてくれません。

よく見てみると`jq-set-var`は`restclient-jq.el`というスクリプトの中で定義されていて、`package.el`ではこいつは入らないようです。

仕方ないので、`restclient-jq.el`をelispのパスが通るところに置いて、

```
(require 'restclient-jq)
```
すれば無事動きました。
なお、別途`jq-mode`と`cl-lib`もインストール必要なようです。
Laravelのサービスコンテナのextendは抽象と実装両方とも反応する

[ReadDouble](https://readouble.com/laravel/7.x/ja/container.html)のサービスコンテナの章に、結合の拡張と書いてあるのが目に入り、実装を拡張するのかインターフェースをデコレートできるのかどっちだろうと気になったので調べてみたら両方反応しました。色々使えそう。

# コード

```PHP:Foo.php
interface Foo
{
    /**
     * 関数の説明
     */
    public function getString(): string;
}
```
```PHP:FooImpl.php
/**
 * クラスの説明
 */
class FooImpl implements Foo
{
    private $bar = 'default';

    /**
     * 関数の説明
     */
    public function setString(string $new): void
    {
        $this->bar = $new;
    }

    /** {@inheritdoc} */
    public function getString(): string
    {
        return $this->bar;
    }
}
```
```PHP:FooDecorator.php
/**
 * クラスの説明
 */
class FooDecorator implements Foo
{
    public function __construct(Foo $base)
    {
        $this->base = $base;
    }

    /** @var Foo */
    private $base;

    /** {@inheritdoc} */
    public function getString(): string
    {
        return 'decorated ' . $this->base->getString();
    }
}
```
```PHP:AppServiceProvider.php
class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        $this->app->extend(Foo::class, function (Foo $service, $app) {
            return new FooDecorator($service);
        });
        $this->app->extend(FooImpl::class, function (FooImpl $service, $app) {
            $service->setString('and changed');
            return $service;
        });
    }

    public $bindings = [
        Foo::class => FooImpl::class
    ];
}
```
```PHP:FooController.php
class FooController extends Controller
{
    public function __invoke(Foo $foo): array
    {
        return ['message' => $foo->getString()];
    }
}
```
```PHP:FooControllerTest.php
class FooControllerTest extends \Tests\TestCase
{
    use MockeryPHPUnitIntegration;

    /**
     * @test
     */
    public function fooTest(): void
    {
        $this->withoutExceptionHandling();

        $response = $this->get('/foo');

        $response->assertJson(['message' => 'decorated and changed']);
    }
}
```

#　実行結果

```shell
$ php artisan test --filter FooControllerTest

   PASS  Tests\Feature\App\Http\Controllers\FooControllerTest
  ✓ foo test

  Tests:  1 passed
  Time:   6.73s
```
NLPを実践。Googleペガサスプロジェクトによる中国語・英語・日本語のテキスト/文章要約のためのWebアプリデモ

NLP in practice: A Web App Demo for text summarization in Chinese, English and Japanese by Google Pegasus Project
# STRATEGYSUM Text Summarization /テキスト要約テキストのまとめ文本摘要システム
Google Pegasusプロジェクトモデル[1–2]をベースにしたオンラインテキスト要約推論サービスを、tesla V4 GPUを使用してGoogle Cloud上にデプロイし、試してみました。
オンラインデモでは、英語、中国語、日本語のテキストに対応しており、ユーザーは入力するだけで、システムが自動的に言語を検出して要約処理を行います。
ウェブデモ
http://35.196.244.158
ご質問がある場合やモデル展開計画を提供する必要がある場合は、私に連絡してください： steven.zhang@spacexdeepsace.com
[1] https://github.com/google-research/pegasus
[2] https://ai.googleblog.com/2020/06/pegasus-state-of-art-model-for.html
今日、オンラインユーザーは情報過多に悩まされており、ウェブ上には膨大な量のテキスト情報が急増しているため、ユーザーが必要とする全ての資料を読むことは困難である。
自動テキスト要約は、正式にはこの問題を解決するものであり、また、自動テキスト要約は高度な自然言語アプリケーションの一つでもあります。テキスト要約には、抽出的要約と抽象的要約の2種類があります。抽出的要約は、入力テキストのサブセットを選択して要約を作成することで、重要な内容を最大限にカバーし、冗長性を最小限に抑えることを目的としている。これに対して、抽象的要約は、入力テキストの抽象表現を作成し、自然言語生成技術を用いて要約を生成することを目的としている。抽出的抽象化と比較すると、抽象化抽象化は生成の難易度が高く、抽象化抽象化には原文には存在しない表現が含まれている可能性があるため、手作業で抽象化抽象化を作成するのに近いものとなります。StrategySumは、我々が提案する言語横断抽象化ソリューションであり、ペガサス[1]をベースとしたエンドツーエンドの深層学習モデルを用いて言語横断抽象化表現を抽出することで、多言語抽象化生成を支援するとともに、テキスト推論[2]などの様々な戦略を組み合わせて、生成された抽象化表現が原文に忠実であることを保証するという利点がある。
- 多言語要約タスクの処理において、学習コーパスは、ある言語では比較的豊富であるが、他の言語では非常に疎である。学習データが非常に疎な場合、モデルが学習する要約例が十分にないため、対象言語の要約タスクを処理することは非常に困難であり、モデルは重度のオーバーフィットやアンダーフィットを起こしやすい。我々は、モデルへのヒントとして言語タイプの埋め込みを使用して、単一のモデルに複数の言語を扱う能力を装備することを提案しています。
- クロスランゲージ言語モデルは、言語モデルとしてトランスフォーマーベースを用い、言語エンベッディングを導入しながら事前学習スキームとしてペガサスが提案したGSG(Gap Sentences Generation)を用いて学習する。
- 一般的な抽象化モデルで生成された抽象化文は、真実ではない内容や原文と矛盾する内容を構成することが多い。この問題に対処するために、GoogleもMicrosoftも独自の見識と抽象度忠実度の評価基準を提案している。原文に忠実でない場合は、で提案されている三元論的アプローチを用いて校正を行い、それでも失敗した場合は、抽出された抽象化モデルに置き換えることで、原文への抽象化の忠実度を最大限に確保しています。
- トランスモデルの空間複雑度はシーケンス長の2乗であり、一般的なトランスモデルの構造では非常に長いテキストを扱うことが難しいという問題に対して、パーティショニング抽出法を用いて、まず抽出抽象を用いてテキストの長さを短くし、ノイズが多く重要でない内容をフィルタリングしながら抽出抽象を生成し、長文テキストとの互換性を確保すると同時に、生成された抽象が現実的であることを保証することを提案している。
## 抽象化タスクのテスト
> Chang’e-5号は、中国の月探査プロジェクト第3期の月探査機で、中華人民共和国初の地球外サンプルリターンミッションを実施し、月探査プロジェクトの「軌道・着陸・帰還」の最後の「帰還」ミッションを完了した. Chang’e-5は2020年11月24日午前4時30分に海南の文昌宇宙発射場から打ち上げられ、月面で自動サンプリングを行い月面から離陸し、地球に帰還して12月17日に内モンゴルに着陸した。
>
> 約6000語
抄録：__
Chang’e-5は、2020年11月24日に海南の文昌宇宙発射場から打ち上げられました。これは中国の月探査プロジェクトの第三段階の一部である。中国が宇宙活動を開始して以来、月面での自動サンプリング、月面からの初の離陸という4つの “初 “を達成した。無人での月面サンプルリターンでミッションは終了した
JupyterのPDF出力の日本語対応法（2020年12月版）

2年以上も前に[日本語のJupyter NotebookをPDFとしてダウンロードする](https://qiita.com/masa-ita/items/8d5ebe8afe0d580af184)という記事を書きましたが、その後nbconvertなどの仕様変更があり、役に立たなくなっていたようです。
そこで、改訂版を記しておきます。
## TeXのインストール
### Ubuntuの場合
下記のモジュールをインストールすれば良いようです。

```bash
sudo apt install texlive-lang-japanese
sudo apt install texlive-xetex
sudo apt install pandoc
```
### Macの場合
[MacTex](http://www.tug.org/mactex/)をインストールするのがもっとも簡単と思います。
なお、私の場合にはMacPortsを使っていたので、ghostscriptはMacPortsでインストールしたものを使いました。

## テンプレートファイルの変更
nbconvertに付属するテンプレートでは日本語の文字が表示されないので、修正が必要です。
### テンプレートファイルの配置先
テンプレートファイルは以前はnbconvertのインストールディレクトリにありましたが、現在は環境によって配置されるディレクトリが変わるようです。`jupyter --path`コマンドを実行すると、jupyterがデータファイルを検索するディレクトリ一覧が表示されるので、これらの場所を探してみると良いでしょう。

```bash
# jupiter --path の実行例
$ jupyter --path
config:
    /home/basicuser/.jupyter
    /usr/local/etc/jupyter
    /etc/jupyter
data:
    /home/basicuser/.local/share/jupyter
    /usr/local/share/jupyter
    /usr/share/jupyter
runtime:
    /home/basicuser/.local/share/jupyter/runtime
```
上記の`data:`以下に列挙されているディレクトリのいずれかが配置先です。
この例では、
`/home/basicuser/.local/share/jupyter/nbconvert/templates/latex`
にTeXのテンプレートファイル（拡張子`.tex.j2`）が配置されていました。
### 変更内容
テンプレートファイル`index.tex.j2`ファイルの内容を、

```tex:index.tex.j2
((=- Default to the notebook output style -=))
((*- if not cell_style is defined -*))
    ((* set cell_style = 'style_jupyter.tex.j2' *))
((*- endif -*))

((=- Inherit from the specified cell style. -=))
((* extends cell_style *))


%===============================================================================
% Latex Article
%===============================================================================

((*- block docclass -*))
\documentclass[11pt]{article}
((*- endblock docclass -*))
```
から、下記のように変更します。

```tex:index.tex.j2
((=- Default to the notebook output style -=))
((*- if not cell_style is defined -*))
    ((* set cell_style = 'style_jupyter.tex.j2' *))
((*- endif -*))

((=- Inherit from the specified cell style. -=))
((* extends cell_style *))


%===============================================================================
% Latex Article
%===============================================================================

((*- block docclass -*))
\documentclass[xelatex,ja=standard]{bxjsarticle}
((*- endblock docclass -*))
```


## 注意すること
なお、venvなどの仮想環境の場合には、テンプレートファイルのインストール先も仮想環境ごとに異なります。例えばvenvの場合、
`venv/share/jupyter/nbconvert/templates/latex`
に配置されていました。

また、テンプレートファイルの場所は、`jupyter_nbconvert_config.json`で指定可能です。上記の`jupyter --path`の`config:`でリストアップされたディレクトリにこのファイルが生成されている場合があるようです。標準的な場所に見つからない場合には、このファイルがないかどうかを確認してみてください。

## 参考にしたサイト
[Jupyter Notebook をPDFで保存する方法（日本語対応）](http://pyopyopyo.hatenablog.com/entry/2020/10/02/002508)
Laravelでデータベースのcreated_atから日付だけ取り出す

#Laravelでデータベースのcreated_atから日付だけ取り出す

##背景
```created_at``` を使用し、いつから利用しているのかを表示したい。しかし、```created_at``` をそのまま使用すると日付だけでなく時間まで表示される。日付だけ表示したい。

##対処方法
Conposerで公開されているパッケージの中に存在するライブラリである**Carbon**を使用。
作成した```controller```ファイルを編集する。
まずは上の方に```use Carbon¥Carbon;```を記述する。
次にfunction中に以下のように記述する。

```
$date = Carbon::createFromFormat('Y-m-d H:i:s', $user->created_at)->format('Y-m-d');
```

```$user``` はそれぞれ使用したいデータベースのテーブル名などになるよ。

ちなみに**Carbon**については下記を参照するとわかりやすいかも。
[【Laravel】Carbonを初めて使ってみた](https://qiita.com/mackeyTA/items/e8b5e47a9f020a1902c0)
【VSCode】git管理外のファイルを検索対象にしたい

#初めに
私は普段VSCodeで開発を行っているんですが、唐突にこんなことを思いました。

「普段意識していないけど、フレームワークの中身ってどんな風に動いてるんだ…？」

そこで「Ctrl+PやCtrl+Shift+F(Windowsの場合)」でファイル検索をしようとしたところ、あることに気が付きました。
**フレームワークのファイルが引っかからん！**


#原因

VSCodeはデフォルトで.gitignoreファイルと.ignoreファイルを検索から除外する設定がオンだから！
※「Ctrl」+「,」(Windowsの場合)で設定画面を開くことができ、「機能-検索」に該当の設定が存在します。
![search0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310355/85092015-2d3c-58f5-7a80-24b1adf46fe1.png)



確かに検索のたびにフレームワーク等のGit管理外ファイルが引っかかったら鬱陶しいですよね。

#解決方法
今回の目的はフレームワークの処理を検索することだったので、こちらのチェックを外してしまいましょう！
![search1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310355/ac93edd8-de34-03b6-1706-557f2b2a7222.png)

すると、VSCodeの設定を司るsetting.jsonファイルが更新されました。
![search2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310355/19b872ea-c438-b8de-d995-2751b672aee1.png)

あとは実際に検索してみて…
![search3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310355/910aef09-2014-cc44-b183-e1cc92b82743.png)

**おっけーーーーーい！！**

#まとめ
今回のように検索の設定はもちろんですが、[編集したら自動でファイルを保存してくれる設定](http://beiyan-tool.info/?p=527)や、[特定のファイル編集の際行末尾の空白を自動で削除する設定](https://qiita.com/otera@github/items/d715f760aab2f6e88e67)(マークダウンのときだけ設定できるんだ…！となりました。)等、開発効率を上げる設定はたくさんあります。
こちらの記事を書きながら「自分ももっと調べなきゃ…！」と感じました。
Hololens無印でWebRTCをやってみた（未完成）

[HoloLens Advent Calendar 2020](https://qiita.com/advent-calendar/2020/hololens)の24日目のです。
本人がまだHololens2を入手できていないのでHololens無印の話です。~~（誰かHololens2くだちい）~~

# はじめに
Hololens2が出てきて、Hololens無印くんは性能的に結構お役御免な感じになっています。
まあもとが2016年発売のデバイスなので、逆に後継機が出るまで3年（日本だと4年弱）も良く戦ったと思います。
しかし、Hololens2は最初日本では入手性がわるく、また一般人には40万からのデバイスをポンポン買うのは難しい状況です。

そんな中、いろいろと別件でWebRTCを触るうちに、「これ、無印Hololensのスペック不足をある程度補えるのでは？」という夢が湧いてきたのでチャレンジしてみました。

# 最終構想
### 大枠の仕組み
1. Hololensのカメラの映像をWebRTCで他の機器（Androidスマホ）に流す
2. 受け取ったAndroidは映像からAI()などの方法でやりたいことをやる（例：文字列解析、ポーズ解析、表情解析その他）
3. 判定結果をWebRTCのDataChannelでHololensに流す（流すデータはそれぞれに必要なもの）
4. Hololensは受け取ったデータからMR的処理をかける

### この仕組の良さげなところ
- AndroidスマホをWifiホストにしてHololensつないだらP2PでWebRTCできるしレイテンシとかがかなり低くできるはず
- Hololens系に比べて、Androidスマホは価格比の性能が高めでしかも買い替えしやすい
- 特殊な組み込み系WindowsでかつUWPアプリ用のAI系ライブラリに比べてAndroid関係のほうがEdgeAI用のライブラリが多い（あくまで浅いところの話なので深いと色々とあるのかも・・・）

### この仕組のデメリット・不明点
- ある程度スペックのあるHololensのCPUを生かさずに追加の端末（コスト）がかかる
- Hololens + WebRTCのレイテンシ・画質が不明（P2Pとはいえ、実用的な品質でるの？）
- ~~そもそもHololens2出てるんだからそっち買え~~

# 今回やること
とりあえず、Hololens無印で、WebRTCを使ってみて、現実的なレイテンシ・画質が出るのかを確かめる

# 下準備
- Hololens無印
- Unity 2019.4.17f1
- MixedReality-WebRTC 2.0.2
- VisualStudio 2019

基本的には、[MixedReality-WebRTC](https://microsoft.github.io/MixedReality-WebRTC/index.html)の[Unity tutorial](https://microsoft.github.io/MixedReality-WebRTC/manual/unity/helloworld-unity.html)に沿ってやっていってみる

# 手順
## 1. Unityでプロジェクトを作る
Unity Hub -> 新規作成 と進み、適当に作ります。
テンプレートは3Dを選択します。
あと、保存先は多分全角文字とかスペースが入らないパスのほうがめんどくさい事象に当たりにくい気がします。

![sc01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45441/edfecc3d-6603-92df-1557-ee636b8aa37e.png)

## 2. MixedReality-WebRTCライブラリの追加
プロジェクトにMixedReality-WebRTCライブラリを追加します。
追加の仕方として
1. Githubからpackageをダウンロード・インポート
2. UPMを利用してインストール
がありますが、今回は2の方法を利用します。

### 2.1. manifest.jsonに記述の追加
プロジェクトを作ったフォルダ以下の **Packages** フォルダに **manifest.json** というファイルがあります。
![sc02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45441/4a6d8ac3-80ff-eed8-80a4-83271687c7bd.png)

これをテキストエディタ等で開き下記の設定を追加します。

```json
{
↓ここから
   "scopedRegistries": [
      {
        "name": "Microsoft Mixed Reality",
        "url": "https://pkgs.dev.azure.com/aipmr/MixedReality-Unity-Packages/_packaging/Unity-packages/npm/registry/",
        "scopes": ["com.microsoft.mixedreality"]
      }
   ],
↑ここまで追加
   "dependencies": {
     "com.microsoft.mixedreality.webrtc": "2.0.2",　←これを追加
     "com.microsoft.mixedreality.webrtc.samples": "2.0.2",　←これを追加
以下に元のファイルの記述が続く

```

追加できたらファイルを保存します。

### 2.2. Unity側で確認
2.1. が終わり、Unity側に戻ると、ローディングが走ります。
ローディングが結構長いので、気長に待ちます。
ローディングが終了すると下記のようなダイアログが出ます。
![sc03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45441/2d02765b-4cb8-5f09-213e-d9dfb692f5c3.png)
これが出たらインポート成功です。

一応、PackageManagerでもインポートされていることを確認しておきます。
![sc04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45441/486a14b1-021d-1b90-d903-cf40ecfc986d.png)

## 3. MRTKライブラリのインストール
2.　でやったのと同じように、MRTKライブラリをインストールします。

# まとめ中

ちょっとまとめきれないので一旦保存
後で追加する
#lesson 7 tableau public で100万行以上（エクセルでは無理）のオープンデータを公開 国別に棒グラフをつくる


# 税関別データから2019年の合計金額を抽出し国別に棒グラフをつくる**

**フィルターの上位を単純に使うと、輸出入でわけたときに不具合が生じます。**

## 使うデータ
[kaggle](https://www.kaggle.com/zanjibar/japantradestat) にあります。ダウンロードには、kaggle のアカウントが必要です。

- [custom_y_hs2_from_1998.csv](https://www.kaggle.com/zanjibar/japantradestat?select=custom_y_hs2_from_1998.csv)
- [hs2_jpn.csv](https://www.kaggle.com/zanjibar/japantradestat?select=hs2_jpn.csv)
- [country_jpn.csv](https://www.kaggle.com/zanjibar/japantradestat?select=country_jpn.csv)

## 説明動画は、[これ](https://youtu.be/EwlVETwDIXg)　

### 動画の解説

- 最初にシートをクリヤします。
- Value をシートにもってきます。
- フィルタつかって、Year 2019 のデータのみにする
- マーク（データのカテゴリ分け）で、Country(国コード)で分ける
- 表示形式を、棒グラフ
- 金額で降順にソートして棒グラフを見やすくする
- Country(国コード)に対応国名を表示するようにする
- フィルタをつかって輸出入金額上位１０位までの国にする。★輸出入合計でしかフィルタかけらないみたい
- フィルタで輸出入を分ける　上位１０位が輸出入合計のままなので、香港が輸入でのこってしまう。
【Ruby on Rails】deviseの導入について

Deviseの導入についてのアウトプットです。

Deviseは主にユーザーのログイン機能や新規登録を行う際に使用するツールです。

```ruby:Gemfile
# 中略
gem 'devise'
```

```
% bundle install
```

bundle install後にdeviseをインストールする。

```
% rails g devise:install
% rails g devise モデル名（複数形にしない）
```

マイグレーションファイルを作成後にdeviseのviewファイルを生成する。

```
% rails g devise views
```

生成後、いよいよ編集です。
スクリプトからSlackにスラッシュコマンドを送信する裏技(2020年12月最新版)

# 【概要】
Slack連携をしている勤怠管理システムにスクリプトから打刻したいと思い、Slackにスラッシュコマンドを送信する方法を調べた。

SlackにスラッシュコマンドをAPIから送信する場合、`chat.postMessage`などを使用するとスラッシュコマンドではなく単純なテキストとして認識されてしまう為、`chat.command`というAPIを使用する必要がある。

しかし、`chat.command`を使用する為にはPOSTのスコープが必要で、その為に必要なLegacyTokenが2020年5月5日をもって発行出来なくなってしまったので、今までのように`chat.command`を使用することは出来なくなってしまった。
https://api.slack.com/changelog/2020-02-legacy-test-token-creation-to-retire


そこで今回は、`chat.command`を使用する裏技について解説する。

# 【手順】
1.GoogleChromeなどから、Slackにアクセスし、スラッシュコマンドを送りたいチャンネルを開く

2.F12を押して通信の内容を表示し、送信したいスラッシュコマンドを一度手動で送信する

3.通信の一覧に`chat.command`が表示されるので、右クリックする
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601695/80c851c0-952e-57e5-d095-0e51eb1a11fd.png)

4.Copyから、様々な言語向けにHttpリクエストをコピー出来るので、使いたい言語でコピーする
![slack2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601695/7099adc5-dbc5-697d-94fe-4f7df6569f61.png)

5.コピーした内容をスクリプト化し実行すると、スラッシュコマンドが送信され
る


# 【おまけ】
今回自分はcURL(cmd)でコピーし、batファイルとして作成したが、書式の問題でそのままでは動かなかったので、動くようにする方法を記述しておく。

1.sec-ch-ua:という行があれば削除する
2.一番最後にある--compressedを削除する
3.compressedがあった手前の行の最後にある^を削除する
4.^%^を、全て%%に置き換える

これでbatからスラッシュコマンドを送ることが出来る。
FreeNASのjail環境へポートフォワードする

FreeNASを愛用の方も多いかと思いますが、FreeNASではポートフォワードなどの機能がGUI上からは行えません。
とは言え、jailでプラグインなどを利用するとどうしても欲しくなる時があります。
ここではipfwとnatdを使ったポートフォワードを行います。

※tcp80をフォワードする時は管理GUIのポート番号をあらかじめ変更しておいてください。

## 手順

### 1. JailのConfigurationで内部用ネットワークを作成

jail→Configuration　を選択
 →物理ネットワークと被らないようにする
例)172.30.111.0/24など
※Jail側のゲートウェイアドレスは172.30.111.254になる

### 2. Jailでコンテナ作成する
プラグインなどを使ってコンテナを作成しましょう。
※作成の際は、VIMAGEとNATにチェック入れる事を忘れずに

### 3. rc.confの修正
natさせるため、/etc/rc.conf(/conf/base/etc/rc.conf)を修正する
下記を最終行へ追記

```
# Enable natd
natd_program="/sbin/natd" # path to natd, if you want a different one.
natd_enable="YES" # Enable natd (if firewall_enable == YES).
natd_interface="vtnet0" # Public interface or IPaddress to use.
natd_flags="-f /etc/natd.conf" # Additional flags for natd.
gateway_enable="YES"
firewall_enable="YES"
firewall_type="open"
```

### 4. natの設定
/etc/natd.conf(/conf/base/etc/natd.conf)を作成する
下記のような感じで。example: natd(8)以下に実施したい項目を追加する。
この場合は192.168.111.130:80,443(ホストインターフェース)に来たパケットを172.30.111.10:80,443(Jailインターフェース)へフォワード

```
### 基本設定
use_sockets yes
same_ports yes
port 8668 # NAT ルーティングに使用するポート
unregistered_only yes
dynamic yes # ルーティングインターフェイスの動的監視．ppp では必須
### これ以降はポートフォワーディング設定
## redirect_port PROT TARGET_ADDR:TARGET_PORT[-TARGET_PORT] IN_PORT[-IN_PORT]
## example: natd(8)
redirect_port tcp 172.30.111.10:80 192.168.111.130:80
redirect_port tcp 172.30.111.10:443 192.168.111.130:443
```

### 5. initコマンド追加
コンパネ→Tasks→Init/Shutdown Scriptの追加

 - タイプ：コマンド
 - コマンド：/sbin/ipfw add 10 divert 8668 ip from any to any via vtnet0
　　※最右は対象のインターフェース名
 - When：Post Init
 - 有効化：チェック

### 6. 再起動
Freenasを再起動して、設定が反映されているか確認する。

## さいごに
FreeNASのバージョンによる差異がありますが、ipfwとnatdは使えますので問題ないと思います。
shellコマンド（自分用メモ）②

[shellコマンド（自分用）①](https://qiita.com/HANYA/items/2e53804f91baf385777b　)　の続き

####・　nkf
漢字コードの変換フィルタで「<b>N</b>etwork <b>K</b>anji <b>F</b>ilter」の略。
異なるOS間でテキストデータを交換する際に問題となる文字コードと改行コードを変換するためのコマンド

```
$ echo コマンド　| nkf -wMQ                      ←　-wMQはオプション
=E3=82=B3=E3=83=9E=E3=83=B3=E3=83=89
```

####・　tr コマンド
<b>使用例</b>
　　tr 文字列1 文字列2
<b>意味</b>
　　文字列1を文字列2に置き換える

```
$ echo コマンド | nkf  -wMQ | tr = %　　　　　　　←　＝ を ％ に置き換える
%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89
```

####・　curl コマンド
ファイルをサーバーに送ったり、逆にサーバーから手に入れたり出来るコマンド

```
$ curl -e http://〜〜〜.com 'http://〜〜〜.com'   　←　-e はオプション
```
####・　catコマンド
ファイルの中身を表示させるコマンド

```
$ cat ファイル名
```

####・　sedコマンド
文字を削除できるコマンド
置換前の文字に削除したい文字を入れ、置換後の文字のところを空文字にすればOK

```
＄ sed -e 's/置換前の文字/置換後の文字/g'　
$ "http://~~~.com"    ← " "を消したい
$ sed -e 's/"//g'　　　← " を指定
$ http://~~~.com
```
####・　tarコマンド
<b>使用例</b>
　　$ tar cfvz peace.tar.gz *txt
<b>意味</b>
　　ファイル名の最後にtxtがつく全てのファイルをtar形式アーカイブにし、gzipで圧縮する。
<b>使用例</b>
　　$ tar xfvz peace.tar.gz
<b>意味</b>
　　tar + gzipされたアーカイブを解答・展開する

複数のファイルを1つにまとめた『アーカイブファイル』を作成／展開するコマンド
＊ アーカイブ ・・・・ プログラムのソースコードなど、複数の関連するファイルをまとめた物

```
$ tar cvf アーカイブ [ファイル名|ディレクトリ名]　　　→　c v f はオプション
c　→　create の意味　　v　→　view (処理したファイルの一覧)　　f →　指定したアーカイブファイル名にアーカイブを作成する
ここには出てないけど　xオプション　→　アーカイブの展開　　　zオプション →　アーカイブをgzip形式で圧縮/解凍
```
####・　gzコマンド
<b>使用例</b>
　　$ gzip ファイル
<b>意味</b>
　　ファイルを圧縮する
<b>使用例</b>
　　$ gzip -d ファイル
<b>意味</b>
　　ファイルを解凍する（圧縮を元に戻す）

```
$ gzip ファイル名.tar
```
####・　zipコマンド（複数のファイルをまとめてzip形式に圧縮する）
<b>使用例</b>
　　$ zip peace.zip *txt
<b>意味</b>
　　ファイル名の最後にtxtとつくファイルをzip圧縮する。
<b>使用例</b>
　　$ zip -r peace.zip peace/
<b>意味</b>
　　ディレクトリを圧縮。

```
zip [オプション] アーカイブ ファイル名
$ zip archive file
$ ls
archive.zip  file
```
####・　unzipコマンド（zip形式のアーカイブを展開する）
<b>使用例</b>
　　$ unzip peace.zip
<b>意味</b>
　　peace.zipファイルを展開する。

```
$ unzip [オプション] [ファイル名]
$ unzip -d dir tmp.zip 
Archive:  tmp.zip
  inflating: dir/a.out               
   creating: dir/dir/
  inflating: dir/hello.c             
   creating: dir/isus/
```
####・　ejectコマンド
CDトレイを開けるコマンド

```
$ eject　　　　　 →  開く　
$ eject　-t　　　 →　閉める （機能しない可能性あり）
```
####・　haltコマンド
電源を切るコマンド　（root権限でないと出来ない）

```
# halt　　　　　または　　　　$ sudo halt
```
####・　rebootコマンド
再起動する為のコマンド　（root権限でないと出来ない）

```
# reboot　　　　または　　　　$ sudo reboot
```
####・　shutdownコマンド
オプションと合わせて電源を切ったり再起動したりするコマンド（root権限でないと出来ない）

```
# shutdown -h now　　　または　　　$ sudo shutdown -h now 　→　電源を切る
# shutdown -r now　　　または　　　$ sudo shutdown -r now 　→　再起動させる
（ shutdown -h +5 ）　now でなくても時間指定が出来る
```
####・　historyコマンド
打ったコマンドを履歴で出せる
＊ historyコマンド関係なく、↑ を押すと１つ前の履歴が表示される

```
$ history
```
　



##参考
https://www.atmarkit.co.jp/ait/articles/1609/29/news016.html
https://www.garunimo.com/program/linux/
https://webkaru.net/linux/zip-command/
【AR】Java版Minecraftの建築物をARで現実空間に表示してみた

#成果物
早速ですが、こちらが成果物になります。
ARにて設置した建築物の内装まで見ることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360820/51c0159e-0b17-8a8e-ba36-18015ff3798b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360820/a533c44a-ddbb-1bed-a7a8-ca10b73764c3.png)

実際動作させている動画はこちらです↓


#開発環境
Windows 10 Pro
Unity2019.4.17f
Visual Studio 2019 Community
AR Foundation
JMC2OBJ



#開発中のお話
まず、肝となるのがMinecraftの建築物をUnityにインポートするところだと思います。
とってもいいツールがあって、以下の画像のような[JMC2OBJ](https://www.jmc2obj.net/ "")というJava版Minecraftのセーブデータから、取り出したい建築物などを範囲選択して、それを.objファイルにエクスポートすることができます。
![スクリーンショット 2020-12-24 15.23.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360820/7ab2616d-76c8-30c2-f3ba-1c9f6fb535f5.png)
.objにしてしまえばもうこっちのものです。あとはUnityにて平面をタッチしたときにそのオブジェクトが出てくるようにスクリプトを書くだけで終わりです。

#背景
やってみようと思った理由としては、ただMinecraftで自分で作った建物とかを現実空間の広い所（グラウンドとか）でARで表示してその中を歩くということをしてみたかったからです。

#感想
なかなか面白いなと感じました。ARにて表示した建築物を実際の大きさにして、広いところで表示すればかなり面白いと思います。
PCの画面の中だけだと、サイズ感がよくわからなかったりします。ネットショッピングとかでも、商品を画像としてみただけでは大きさはよくわかりませんよね。寸法とか書かれてても、いちいち測るのが面倒です。ARはそれを解決してくれます。そうゆう意味でも、今回はいい体験が得られました。
これをARグラスでやったらさらに現実感があって面白いこと間違いなしです。
幸いJMC2OBJなどのいいツールを見つけることができたので簡単にできました。ありがとうございます。
オブジェクトの基礎

<h1>オブジェクトを定義する</h1>

```javascript
{プロパティ1:値1,プロパティ2:値2}
```
・{}（ブレース）で囲む。
・プロパティと値は：（コロン）で繋ぐ。
・要素と要素は,（コンマ）で区切る。

<h1>オブジェクトの値を取り出す</h1>
```javascript
オブジェクト.プロパティ名
```

```javascript:example.js
const item = {name:"ブラウス",price:2000};
console.log(item.price)
```

```console:console
2000
```

<h1>オブジェクトの値を更新</h1>
```javascript
オブジェクト.プロパティ名 = 新しい値
```

```javascript:example.js
const item = {name:"ブラウス",price:2000};
item.price = 1800;
console.log(item.price)
```

```console:console
1800
```


<h1>配列にオブジェクトを代入する</h1>
```javascript
[{プロパティ1:値1...},{プロパティ2:値2...}]
```

```javascript:example.js
const items = [
  {name:"ブラウス",price:2000}, //オブジェクト1。カンマで区切る
  {name:"デニム",price:5000}   //オブジェクト2
]
```

<h1>配列の中のオブジェクトを取り出す</h1>
```javascript:example.js
const items = [
  //配列の要素にはインデックス番号が振り分けられている。
  {name:"ブラウス",price:2000}, // インデックス番号⓪
  {name:"デニム",price:5000}   // インデックス番号①
]

//配列itemのインデックス番号1を取り出す
console.log(items[1]);

//配列の中のオブジェクトの値を取り出す
配列[インデックス番号].プロパティ名

console.log(items[1].price);
```

```console:console
{name:"デニム",price:5000}
5000
```

<h1>複雑なオブジェクトを扱う</h1>
オブジェクトの値の部分にさらにオブジェクトを用いる。

```javascript:example.js
const cafe = {
  name:スターバックスコーヒー,
  bussinessHours {
    opening:"10時00分",
    closing:"21時00分",
  },
  menu:["ブラックコーヒー","カフェラテ","ココア"]
};

console.log(cafe.name);
console.log(`営業時間:${cafe.bussinessHours.opening}から${cafe.bussinessHours.closing}`)
```

```console:console
スターバックスコーヒー
営業時間:10時00分から21時00分
```
【PHP】アスタリスクで様々な三角形を作る

```
アスタリスク(*)で以下の三角形を作成
*
**
***
****
*****
```

```PHP
<?php
for($i = 0 ; $i < 5 ; $i++){
    for($j = 0 ; $j < $i + 1 ; $j++){
    echo '*';
    }
    echo "\n";
}
?>
```


```
*****
****
***
**
*
```

```PHP
<?php
for($i = 0 ; $i < 5 ; $i++){
    for($j = 0 ; $j < 5 - $i ; $j++){
    echo '*';
    }
    echo "\n";
}
?>
```

```
*****
 ****
  ***
   **
    *
```

```PHP
<?php
for($i = 0 ; $i < 5 ; $i++){
    for($j = 0 ; $j < $i ; $j++){
    echo ' ';
    }
    for($k = 0 ; $k < 5 - $i ; $k++){
    echo '*';
    }
    echo "\n";
}
?>
```
octoberCMS phpinfo()見たい

備忘録です。

octoberCMS使っていて、確認のために、phpinfo()見たい時。

```php
title = "php"
url = "/phptest"
is_hidden = 0
==
<?php
function onStart(){
  phpinfo();
}
?>
==
```

分からないので、index.phpを一時的に書き換えてとかやってました。
GASでファイルアップロードリクエスト

[Fringe81 Advent Calendar 2020](https://qiita.com/advent-calendar/2020/fringe81)の24日目、本日はクリスマスイブですね！
GAS(Google Apps Script)でファイルアップロードリクエストの作成についてです。

# 結論
こんな感じです。

```javascript
const file = DriveApp.getFileById("<FileのID>");

const blob = Utilities.newBlob(
  file.getBlob().getBytes(),
  file.getMimeType(),
  file.getName()
);

const params = {
  method: "post",
  payload: {
    filename: blob,
  },
};

const response = UrlFetchApp.fetch("https://localhost/", params);
const content = response.getContentText();

console.log(content);
```

ググると`multipart/form-data`リクエストをガリガリ書くサンプルが多いんですが、なくてスッキリですね！
ポイントは[Utilities.newBlob](https://developers.google.com/apps-script/reference/utilities/utilities#newBlob(Byte,String,String))使うことですね。

# 確認
サーバサイドで確認は面倒なので、[UrlFetchApp#getRequest](https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app#getRequest(String,Object))で確認できます。
`params`は上と同じなんで省略しています。

```javascript
  const request = UrlFetchApp.getRequest("https://localhost/", params);
  console.log(JSON.stringify(request));
```

ログはこんな感じで出力されます。

```json
{
	"url": "https://localhost/",
	"method": "post",
	"useIntranet": false,
	"followRedirects": true,
	"validateHttpsCertificates": true,
	"contentType": "multipart/form-data; boundary=\"-----r2aYVguYIKQa5XjzMqZkKhCuh6OZ9VpnZ7zkFTW0x3ZKRKKXlQ\"",
	"payload": "-------r2aYVguYIKQa5XjzMqZkKhCuh6OZ9VpnZ7zkFTW0x3ZKRKKXlQ\r\nContent-Disposition: form-data; name=\"filename\"; filename=\"test.txt\"\r\nContent-type: text/plain\r\n\r\nabc\n\r\n-------r2aYVguYIKQa5XjzMqZkKhCuh6OZ9VpnZ7zkFTW0x3ZKRKKXlQ--\r\n",
	"headers": {
		"X-Forwarded-For": "XXXXXXXXXXXXXXX"
	}
}
```

contentTypeが`multipart/form-data`になっているし、boundaryよしなにやってくれていますね！
なおここでは、`test.txt`というファイルをアップロードしようとしていて、中身は`abc`となります。

`UrlFetchApp#getRequest`の使いみちがわかってなかったんですが、**リクエスト何が発行されているかをなんとなく知りたい時**に使えますね。

# 最後に
最近GAS結構触っているんですが、ハマる用途には便利だし、世の中の先人の知恵が多くあるので助かっております！
皆さんも2021年はGASを触ってみてはいかがでしょうか？

新しいIDEをまだ使えないので、使えるようになるクリスマスプレゼントを期待して今日は眠ります！
では良いクリスマスイブを！！
【PHP】Laravel bladeビューファイルの記述の注意点

個人メモです。
Laravelでbladeビューファイルの記述の注意点について。


##注意点

- PHPの処理は全て冒頭に`@`が必要
- PHP処理は1行ずつ（改行は使えない）
- ディレクティブがない行はHTMLとみなされる。
- PHPの処理のみを改行ありで記述する場合は`@php`を使う
- PHP処理の終わりは`@end処理の名前`を記述


<br>
##bladeビューとは？
拡張子`.blade.php`のファイル。
HTMLをそのまま記述することができる。冒頭に@をつけることでphpの処理も併せて記述できる。

```php:xxx.blade.php
<div>
 @if(条件式)
   <p> true </p>
 @endif
</div>
```

コンパイル時に@があればPHPと見なす。


<br>
##PHPの処理は全て冒頭に`@`が必要
if文の処理を使う場合は、`@if`と`@endif`だけではなく、`@else`など、PHPの行の冒頭には全て@が必要。


```php:OK
<div>
 @if(条件式)
   <p> true </p>
 @elseif(条件式２)
   <p> else if</p>
 @else
   <p> false </p>
 @endif
</div>
```

<br>
@がない行はHTMLとみなされる。

```php:NG（エラー）
<div>
 @if(条件式)
   <p> true </p>
 elseif(条件式２)
   <p> else if</p>
 else
   <p> false </p>
 @endif
</div>
```


<br>
##PHP処理は1行ずつ（改行は使えない）
@がない行はHTMLとみなされるため、`if(条件式){処理}`の`{ }`は使えない。

```php:不可
<div>
 @if(条件式) {
     処理
    }
 @endif
</div>
```


<br>
##PHPの処理のみを改行ありで記述する場合は`@php`を使う
普通のPHPの処理のように`{ }`も使って記述したい場合`@php`と`@endphp`の中に記述する。

```php:
@php
 if(条件式) {
     処理
    }
 endif
@endphp
```

`@php`の中のはphpの世界のため、@は不要（`@if`の@はいらない。）
stripeでc2cサービスの決済を行うには…

<h1>はじめに</h1>
今回C2Cの決済をstripeで行う機会があったのでまとめてみました。
私自身、初めてstripeを使用するため足りないところが多々ありますが、参考にしていただけると幸いです。
また間違っている点や修正点がございましたら、ご指摘お願いします。

<h1>stripeを使用するに当たっての注意事項</h1>
stripeでは特定の業種およびビジネス手法において stripeのサービス利用が禁止されています。
今回のC2Cの決済を行う上でもstripe connect を使用するとか、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/977422/d42a6f44-9a05-0c1f-36b5-b6f663dbed68.png)
引用元：https://stripe.com/jp/restricted-businesses

<h1>アカウント選び</h1>
今回は手早く決済機能を導入したいのでexpressアカウントを用いたconnectの利用を行っていきます。
expressの特徴は大きく分けて2つ
<h6>①素早く簡単にユーザー登録できる</h6>
売り手(client)を簡単に登録できます。clientは支払いを受けるのに必要な情報だけを登録するだけ。
平均 2 分以内に完了します。用意された UIを利用して迅速に立ち上げられます。また UI をカスタマイズできます。

<h6>②用意された売り手向けのダッシュボードが利用できる</h6>
用意された Express ダッシュボードを使用して、「売上金額」と「支払日」に関してclientに提示できます。
このダッシュボードはリアルタイムで自動的に更新され、最も重要な支払い関連のレポートを表示します。

<h6>③コンプラチェックが楽</h6>
カードネットワークのルール、資金移動、顧客確認、納税申告など支払い時に生じる面倒なコンプラ問題に対しても
connectを採用することで軽減してくれます。
具体的には、顧客確認・マネーロンダリングチェックなどを行い、不正リスクを未然に防ぐなど。

<h1>express demoを使ってみよう</h1>
expressを使うにあたってstripeが推奨する https://rocketrides.io/ を使ってみましょう
Rocket Ridesというサンプルマーケットにおいて、ユーザーごとのダッシュボードでの売上管理が実現。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/977422/28551bea-4946-3d81-a83a-8b0e115580ae.png)
YouTube Analyticsのトラフィックソースを時系列グラフで表示する方法

#YouTube Analyticsの流入経路を時系列グラフで表示する方法

##この記事の目的

国内のメディア企業でYouTubeチャンネルの制作とデータ分析を担当しているstNaoです。

弊社ではスプレッドシートを用いてYouTube動画の分析を管理しているのですが、
「トラフィックソース」別の再生回数の推移を時系列で確認したいことが時々起こります。

この記事では、下の画像のようにトラフィックソース別の再生回数をスプレッドシートで表示する方法を紹介いたします。



![Screen Shot 2020-12-24 at 14.34.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614701/ddc034a0-0fe8-a503-2946-e55e03d74ee6.png)

##YouTube Analyticsからcsvをダウンロード

画像を参考に、YouTubeアナリティクスからトラフィックソースのデータをダウンロードします。

この時、右上のダウンロード選択肢の「Google スプレッドシート (新しいタブ)」を洗濯します。

![Screen Shot 2020-12-24 at 14.37.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614701/9dd4c1aa-7fcd-d3d8-edfa-77c3e9ff6f09.png)


##Analyticsのデータをピボットテーブルで変更する

新しいタブにスプレッドシートが表示されます。
現在表示されている「表データ」のタブではなく、画面下のタブから「グラフデータ」をクリックしましょう。

ここで画像を参考に、「データ>ピボットテーブル」を選択します。
そのままOKを選択してください。

![Screen Shot 2020-12-24 at 14.33.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614701/ec0ca373-c68f-3b95-a67d-f7a2ba191d4d.png)

次に新しく作られたシートの右側のメニューから、画像を参考に操作していきます。

まず、「行」では「日付」を選択。

![Screen Shot 2020-12-24 at 14.33.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614701/9644d3a5-7098-9fac-8deb-70f34aa9c4d1.png)


次に「列」で「トラフィックソース」を選択

![Screen Shot 2020-12-24 at 14.33.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614701/af37db28-af58-96b6-a837-330186f2dc04.png)

最後に、「値」で「視聴回数」を選択。


![Screen Shot 2020-12-24 at 14.33.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614701/4ecd354d-831c-0771-5434-2a1b90b7175c.png)


これで新しいシートにデータが記入されました。
あとはグラフを作るだけです。グラフを表示したい範囲を選択した上で、
「挿入＞グラフ」を選択してグラフを表示させましょう。

![Screen Shot 2020-12-24 at 14.34.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614701/d7f2dfed-bfde-959f-86b0-f12fb6f92be4.png)

グラフの完成です。

![Screen Shot 2020-12-24 at 14.34.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614701/32083ee7-5284-9517-a458-013aa2e4e6e5.png)


YouTubeアナリティクス画面の標準でも、時系列でグラフは表示されますが、分析作業をしたい時には不便ですのでスプレッドシートを活用した方法もおすすめです。

以上でした。

シートにサムネイルを加えることで、より見やすくなります。
こちらの解説は下記のポストを参照してください。

[YouTubeのサムネ一覧をスプレッドシートで一括取得する方法](https://qiita.com/drafts/fd129c33297c5d7e1f26)

YouTubeの分析について、「こうしたい」「ああしたい」といった疑問がありましたらコメントにてリクエストお願いいたします。
MecabをLinux(CentOS)にbrewでインストール

前提：レンタルサーバー ロリポップマネージクラウドで行いました。他のでもできると思います。

#### 1.まずインストールするためにHomebrewをインストールします。
[公式サイト](https://brew.sh/index_ja)にある、インストールコードをターミナルに入力します。

```terminal
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```

#### 2.Homebrewのパスを通す
このままじゃコマンド「brew」は使えません。
使えるように、設定してあげないといけません。

これをターミナルに一気に入力したら、「brew」で、Homebrewを使えるようになります。

```
test -d ~/.linuxbrew && eval $(~/.linuxbrew/bin/brew shellenv)
test -d /home/linuxbrew/.linuxbrew && eval $(/home/linuxbrew/.linuxbrew/bin/brew shellenv)
test -r ~/.bash_profile && echo "eval \$($(brew --prefix)/bin/brew shellenv)" >>~/.bash_profile
echo "eval \$($(brew --prefix)/bin/brew shellenv)" >>~/.profile
```
情報源: https://fukatsu.tech/linuxbrew

#### 3.brewが使えるか確認

これだけ入力して「brew: command not found」にならなければ大丈夫です。いろんな解説とかがバーっと出てきたらokです。

```
brew
```

#### 4.Mecabをインストール

まずmecabをbrewでインストール。ただこれだけだと使えません。辞書データが必要です。

```
brew install mecab
```

辞書をインストール。完了！

```
brew install mecab-ipadic
```

#### 5.mecabが使えるか確認

mecabとターミナルに入力して、何も出てない状態で何か文章を打ち込んでみてください。

```
mecab
```

```
お腹減った。

お腹	名詞,一般,*,*,*,*,お腹,オナカ,オナカ
減っ	動詞,自立,*,*,五段・ラ行,連用タ接続,減る,ヘッ,ヘッ
た	助動詞,*,*,*,特殊・タ,基本形,た,タ,タ
。	記号,句点,*,*,*,*,。,。,。
EOS
```

お腹減ったと入れると、解析された結果が出てきます。以上です〜。お疲れ様でした。
Thymeleafでラジオボタンをreadonlyっぽくする


# ラジオボタン
th:disabledで選択してないボタンをdisabledにする。
これだけ。

```html
<input type="radio" name="gender" id="gender" value="男性" th:checked = "${gender == '男性'}"　th:disabled="${gender != '男性'}">
<input type="radio" name="gender" id="gender" value="女性" th:checked = "${gender == '女性'}"　th:disabled="${gender != '女性'}">
```

# セレクトボックス
セレクトボックスはth:textとvalueに値を突っ込んでしまえばOK。

```html
<select id="birthYear" name="birthYear">
	<option	th:text="${birthYear}" th:value="${birthYear}"></option>
</select>
```
【Laravel】bladeで検索結果を保持する

```
request()->hoge
```

request()->{保持したいフォームのname属性}で保持できる。
Getパラメータを取得しているのでGetメソッド使用時にしか使えないかも。


例

```
{{ Form::text('hoge', request()->hoge, ['class' => 'form-control']) }}
```
Konyで作成したアプリから電話をかける方法

#目次
1. はじめに
2. 実装方法
    3. 画面作成
    4. コーディング
    5. Actionの紐付け
3. まとめ
4. 参考

#はじめに
連絡帳アプリや、アプリ内の問い合わせ画面で、
電話番号を表示してそのまま電話をかけられるような開発を行う場合があるかと思います。

今回はKonyで作成したアプリから、
標準の電話アプリを呼び出し、特定の電話番号に電話をかける方法についてご紹介します！


完成イメージ
<blockquote class="twitter-tweet"><p lang="und" dir="ltr"><a href="https://t.co/CYim0siDOA">pic.twitter.com/CYim0siDOA</a></p>&mdash; Kony (@Kony12763790) <a href="https://twitter.com/Kony12763790/status/1341980362226855936?ref_src=twsrc%5Etfw">December 24, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


#実装方法
######1. 画面作成
まず画面を作成します。
電話番号が表示されているLabelと、タップするとコール確認のポップアップを表示させるButtonを配置します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/3f73326d-c91b-e0a5-41f5-64629d6ccd53.png" width=70%>
Buttonをアイコンに変更したい時は、SkinからBackGroundのTypeを`Image`にすると任意の画像ボタンにできます。

Imageの`Choose`をクリックするとポップアップが表示されるので変更したい`Value`を選択します。一覧で表示された画像から使いたい画像を選択してください。
使用したい画像が無い場合は`Import`をクリックするとPCにある画像を使用できます！
選択したらOKを押してポップアップを閉じてください。これでButtonのSkinを電話アイコンに設定できます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/af48b7b7-f715-ca3f-0b10-bc5db783877a.png" width=50%>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/d8e19c8f-6a5e-6bde-3425-b8a1f05445db.png" width=49%><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/5a3c551a-858c-dd3b-cd47-8e7e2a763ae1.png" width=50%>

######2. コーディング
電話ボタンを押したら表示されている電話番号に電話をかけるコードをForm1Controllerに書きます。

```Form1Controller.js
define({ 

  callToNumber :  function () { 
    var number = this.view.lblPhone.text; 
    kony.phone.dial(number); 
  }

});
```
`kony.Phone.dial(number)`で`number`に渡されたlblPhoneの電話番号にアプリ上から電話をかけることができます。
この時パラメーターである`number`には数字、+、-、スペースのみが有効な文字として扱われます。

######3. Actionの紐付け
関数の準備ができたらActionと紐づけていきます。
btnPhoneを選択し、ActionタブからonClickのEditをクリックしてActionの紐づけを行います。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/f4444fe6-7cb0-c3a2-e69a-60fc05227171.png" width=50%><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/2e73d53c-53d3-8c05-b71e-3d8dca8b6ebe.png" width=70%><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/fc4983bd-3c39-7760-2ba1-1b06feb8bf1d.png" width=70%>



実際に動作を見てみましょう
<blockquote class="twitter-tweet"><p lang="und" dir="ltr"><a href="https://t.co/CYim0siDOA">pic.twitter.com/CYim0siDOA</a></p>&mdash; Kony (@Kony12763790) <a href="https://twitter.com/Kony12763790/status/1341980362226855936?ref_src=twsrc%5Etfw">December 24, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

電話アイコンをタップした後、発信ボタンをタップすることで
アプリ上で電話をかけることができました！

#まとめ
アプリから電話をかける機能は、問い合わせページや予約ページなどでよく見かけると思います。
Konyの場合、今回ご紹介した通り
簡単に実装を行うことができるので、ぜひ使ってみてくださいね！

#参考
kony.phone.dialについて：
https://docs.kony.com/konylibrary/visualizer/viz_api_dev_guide/content/kony.phone_functions.htm#phone.di
GitHub EnterpriseとJenkinsでもupdate_dependenciesを諦めない

プロジェクトの依存関係 (Dependency) の更新は自動化しておきたいですよね

[Dependabot](https://dependabot.com/) 便利ですね、CocoaPodsなら[Renovate](https://www.whitesourcesoftware.com/free-developer-tools/renovate)とかも使えるかと思います

GitHub使えたりクラウドサービス使える場合はいいんですが、案件によって制約があったりする事もあるのでJenkins+fastlaneでなんとなくやってみました

```ruby:Fastfile

  desc "daily"
  lane :daily do
    bundle_update
    swiftlint_format
    pod_update
  end

  private_lane :bundle_update do
    output = sh('bundle update')
    create_pr(
      branch_name: "bundle-update",
      commit_message: "update: Gemfile.lock",
      pr_title: "[CI] bundle update",
      pr_body: output
    )
  end

  private_lane :swiftlint_format do
    swiftlint(
      mode: "autocorrect",
      format: true,
      ignore_exit_status: true
    )
    output = sh("git diff --name-only")
    create_pr(
      branch_name: "swiftlint-format",
      commit_message: "autocorrect: swiftlint-format",
      pr_title: "[CI] swiftlint format",
      pr_body: output
    )
  end

  private_lane :pod_update do
    output = sh('bundle exec pod update')
    Dir.chdir("#{ENV['PWD']}") do
      sh("./Scripts/license-plist.sh")
    end
    create_pr(
      branch_name: "pod-update",
      commit_message: "update: Podfile.lock",
      pr_title: "[CI] pod update",
      pr_body: output
    )
  end

  private_lane :create_pr do |options|
    next if system('git diff --quiet --exit-code')
    current_branch = git_branch
    date = Date.today.to_s
    branch_name = "ci/#{options[:branch_name]}-#{date}"
    sh("git checkout -b #{branch_name}")
    git_add
    git_commit(path: "./", message: options[:commit_message])
    push_to_git_remote
    create_pull_request(
      title: "#{options[:pr_title]} #{date}",
      body: options[:pr_body],
      base: options[:pr_base] || "develop"
    )
    sh("git checkout #{current_branch}")
  end

```

```:Jenkinsfile
pipeline {
    triggers {
        cron('H 1 * * 1-5')
    }
    stages {
        stage('daily') {
            environment {
                GITHUB_PULL_REQUEST_API_TOKEN = YOUR_GITHUB_API_TOKEN
            }
            when {
                triggeredBy "TimerTrigger"
            }
            steps {
                echo 'Daily..'
                sh 'bundle exec fastlane daily'
            }
        }
    }
}
```

コードをみて貰えばそれだけなんですが、一応解説を。

やっている事はツール(bundler)の更新、swiftlintのformat、ライブラリ(CocoaPods)の更新、PRの作成です

## ツール(bundler)の更新

`bundle update`をshで実行します

## swiftlintのformat

fastlaneからswiftlintのformatとautocorrectを実行します
formatやautocorrectはローカル(開発環境)で実行してもいいんですが
開発者によって環境依存があったり、編集中にコンパイルしちゃった時の動きが不安定だったりするので、CI実行に寄せました
各自で実行してもらっていれば、CIで差分は出ないですし、実行してなかった場合も拾えるのでいいかなと。

## ライブラリ(CocoaPods)の更新

pod updateとlicense-plistの更新をしています。

## PRの作成

`next if system('git diff --quiet --exit-code')`で差分がなければ終了
元ブランチを取っておいて、CI用のブランチをcheckout
変更をcommitして、PRを作成します。
api_tokenやrepo、api_urlなどは環境変数で渡しています
PR作成後、元のブランチをcheckoutして戻しています

## Jenkins pipeline

triggersにcronを指定、月〜金の1時に実行
whenにtriggeredByで"TimerTrigger"を指定する
VueJSの'Uncaught TypeError: Cannot read property 'apply' of undefined'を解決する。

## 背景
v-onでmethodを動作させる以下のようなmethodを書いていたら

```vuejs
<template>
<div>
  <button v-on:click="submitMethod">
</div>
</template>

<script>
export default {
    name: "Component",
    method: {
        submitMethod: function(){
           // 何かの動作を記述。
        }
    },
    // その他コード
}

</script>


```

以下のエラーでよく詰まったので解決法をメモする。

```shell
'Uncaught TypeError: Cannot read property 'apply' of undefined'
```


## 解決法
理由の多くは、「関数が定義されてない」ということが多い。
ただ、「いや、タイポもないはず！！」という人は以下のようになってることが多い。

```js
// ダメな方
method: {
  submitMethod: function(){
    ...
  }
}

// 動く方
methods: {
  submitMethod: function(){
    ...
  }
}

```

そう`methods`が正しいのに、`method`になってしまっている。
vueは、このエラーを実行時にしか教えてくれない。
しかもエラー文も`Uncaught TypeError: Cannot read property 'apply' of undefined`
と全く関係なさげなメッセージである。

他の人も気をつけてね。
Watson Studio(またはCloud Pak for Data)のNotebookのpythonのversionの変更方法

以前Python3.6で動かしてきたWatson StudioのNotebookですが、最近「Python3.6はもう非推奨だからPython3.7に環境を変更せよ」とメッセージが出るようになりました。
本記事では、Watson Studio(またはCloud Pak for Data)のNotebookのPython環境のversionを変更する方法について説明します。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/87c0fee4-1b5c-2572-03dd-9ff57d44f412.png)

#方法1: Notebookを編集モードで開いて変更
##1. Notebookを編集モードで開く
Pythonのversionを変更したいNotebookの鉛筆(編集)アイコンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/430b0262-9c4c-fd5f-1c4b-80bff1a95a06.png)

##2. 右上のiマーク(notebook情報の表示)アイコンをクリック
右上のiが丸で囲まれているアイコンをクリックをクリックします:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/e53ffbab-c564-43ce-a2eb-5017220212f9.png)

##3. 表示された情報エリアの「環境」タブをクリック
情報が右側に表示されるので、その中の「環境」タブをクリックします:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/9846fbcd-0039-c2db-d0f6-98660763f2b8.png)

##4. 「環境定義」のドロップダウンから変更したい環境をクリックして選択
今回はPython3.7に変更したいので、Python 3.7で現在と同じXSを選択します。
環境定義のドロップダウンをクリック:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/c0c01aef-5f66-15a4-14dc-2c76675725eb.png)

ドロップダウンリストから選択します:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/32b28cf5-c8f9-09eb-25cd-d093d45c2973.png)

##5. 「環境を変更しますか?」の確認が表示されたら、「環境の変更」をクリック
内容を確認し、「環境の変更」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/18ab559e-857e-2176-a7de-3c0b53d843d7.png)

その後しばし作業中の画面になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/c5c26176-6de3-781f-862c-000c5d0119cc.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/c9f9eeea-dca3-ca7b-c4aa-4fc423f11155.png)

無事Python3.7にできました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/9388ea46-76fd-ded0-ec5e-d1c507ca6c8c.png)

#方法2: 資産ページのアクションから変更
##1: プロジェクトを開いて、資産タブのNotebooksセクションにある、変更したいファイルのアクションメニュー（縦の・・・）をクリックし、
「環境の変更」をクリック。
>ロックされていたり、カーネルが稼働していると「環境の変更」メニューが出てこないので、ロックを解除して、ファイルのアクションメニュー（縦の・・・）から「カーネルの停止をクリックして、停止させてから行ってください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/0bb027b2-cddc-56d2-2247-b06d876facf0.png)

##2:Notebook を実行するランタイムを選択して、「関連付け」をクリック
ドロップダウンリストからNotebook を実行するランタイムを選択して、「関連付け」をクリックします:

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/0844b726-f0a9-7eee-c7b5-56339d202866.png)
 
とりあえず変更はされたと思うのですが、表示はPython3.6のままです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/92a6c0cf-3904-f9d5-fe16-a611335e4cec.png)

その後カーネルを起動する際に変更されるようです。鉛筆(編集)アイコンをクリックします。

無事変更されてました！:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/271f166c-5154-afee-bc12-e7ba721b02ad.png)

資産タブのNotebooksセクションをその後表示させるとPython3.7になっていました：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/df3c4b8c-5e0f-5710-d8b2-ff3f3268a9d2.png)

#まとめ

2つの方法を紹介しました。どちらでも簡単ですね。でもたくさん変更するものがあると面倒かも、、、、。
以上です。
【Go】Qiita 週間いいね数ランキング【自動更新】

# タグ別

[`Android`](https://qiita.com/items/8b3af051428d746f26c5) [`AWS`](https://qiita.com/items/e24b6279326a462d456c) [`初心者`](https://qiita.com/items/402899ec543aff109505) [`Docker`](https://qiita.com/items/ae11fca7d2eba445b037) [`Git`](https://qiita.com/items/74eacdbf363e260981c3) [`Go`](https://qiita.com/items/49d4537d95f878b3e91a) [`iOS`](https://qiita.com/items/e61a29a383d0403e92fc) [`Java`](https://qiita.com/items/4c3f84836bfdbb137226) [`JavaScript`](https://qiita.com/items/eaa7ac5b62a0a723edbb) [`Linux`](https://qiita.com/items/362e81e53c3f9dee22f1) [`Node.js`](https://qiita.com/items/66ed7ad8f7c9673e9d50) [`PHP`](https://qiita.com/items/3318cbdbc45c6ebd4014) [`Python`](https://qiita.com/items/9d7f2ffeafb36cf59a77) [`Rails`](https://qiita.com/items/93b9e7f7d143e9ce650e) [`React`](https://qiita.com/items/f9712f8acace22815b99) [`Ruby`](https://qiita.com/items/72c3d2e896bdc3e1a6b3) [`Swift`](https://qiita.com/items/e2b6f0645e29f0e2b761) [`TypeScript`](https://qiita.com/items/25b7c0870afa6d41d19b) [`Vim`](https://qiita.com/items/f5361177baef95e447d1) [`Vue.js`](https://qiita.com/items/2774e02c6eea5c830d99) 

# 集計について

- 集計期間: 2025-06-16 ~ 2025-06-23
- 条件: ストック数が **2** 以上の記事


# GitHub

https://github.com/koki-develop/qiita-ranking

スターをもらえるととっても励みになります :bow:

# いいね数ランキング

ランキングに入る記事が見つかりませんでした。
rbenvにOpenSSLを認識させる方法 on WSL

<h2>経緯</h2>
うるさいですね・・・。解決法だけ見せてくださいココアさん！という方は<a href="#solution">こちら。</a>

Ubuntu18.04 on WSL (Windows10)でrbenvをgitレポジトリからインストールしたが、SSL関連のエラーが散見された。例えばgem installができなかったり、open-uriでのhtml取得の際にrequire certifiedしないと証明書エラーになったり。（なぜか1度はnokogiriなどもインストールできて使っていたのだが、それは忘れておく。）

そこで、rubyが見ているOpenSSLのバージョンを調べてみる。

```
irb(main):001:0> require "openssl"
=> true
irb(main):002:0> OpenSSL::OPENSSL_VERSION
=> "OpenSSL 1.1.1  11 Sep 2018"
```
おそらくほとんどの状況であればこれで何の問題もないはずだろうが、私の場合は違った。というのも、以前Python3をローカルインストールした際にOpenSSL1.1.1hを手動インストールしており、システムで動いているのはそちらなのだが、rubyがそれを見ていないということを意味していたからである。

<h2>環境</h2>
Ubuntu18.04 on WSL (Windows10)
rbenv 1.1.2-40-g62d7798

<h2 id="solution">解決の流れ</h2>
<h3>OpenSSL::OPENSSL_VERSIONが正しく設定されるようにする</h3>
どのようにrubyが参照するOpenSSLが特定されているのか調べるために、それっぽいファイルを探してみる。

```~/.rbenv
$ grep -r OPENSSL ./*
```

とすると、まともでないものも含めかなりの数がヒットするが、その中で、

```
./plugins/ruby-build/bin/ruby-build:  OPENSSL_PREFIX_PATH="${PREFIX_PATH}/openssl"
./plugins/ruby-build/bin/ruby-build:  OPENSSLDIR="${OPENSSLDIR:-$OPENSSL_PREFIX_PATH/ssl}"
```

に注目。どうやらopensslディレクトリ\$PREFIX_PATH直下にないと認識されないようだ。そしてこのとき\$PREFIX_PATHは設定されていなかった。

（余談）
ちなみにmacの場合は同様にOpenSSLを認識させる方法も見つかった（<a href="https://qiita.com/kazutosato/items/9c4ff7711ca992dd67e5">記事</a>）のだが、参照する環境変数が違うのかこれでは上手くいかなかったためこんなことをする羽目になった。

そこで、\$PREFIX_PATHを設定。

```~/.bash_profile
$ export PREFIX_PATH=$PREFIX_PATH:/usr/local/bin
$ source ~/.bash_profile
```

この状態で

```
$ rbenv install 2.7.2
```

などすると上手くいくはず。

```
$ rbenv local 2.7.2
$ rbenv versions
  system
  2.6.5 (set by /home/rubyer/.ruby-version)
* 2.7.2
```

rubyのバージョンを変更するのを忘れずに、

```
irb(main):001:0> require "openssl"
=> true
irb(main):002:0> OpenSSL::OPENSSL_VERSION
=> "OpenSSL 1.1.1h  22 Sep 2020"
```

ちなみに、rbenvを経由しないsystemのrubyについてはこれでは解決しない。同じようなことをすれば解決するのだろうが、必要ないのでここでは扱わない。

<h3>SSL証明書を更新する</h3>
上記を経ても、open-uriでhtmlを取得する際にはrequire "certified"しないとエラーが出た。これはメッセージを読めば原因が証明書にあることは分かる。試しにrubyが参照する証明書の場所を確認し、内容を見てみよう。

```
irb(main):001:0> require "openssl"
=> true
irb(main):002:0> OpenSSL::X509::DEFAULT_CERT_FILE
=> "/usr/local/ssl/cert.pem"

$ cat /usr/local/ssl/cert.pem
-----BEGIN CERTIFICATE-----
MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4
GA1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbF
...
-----END CERTIFICATE-----
```

一応証明書は存在している。ということは、内容が不足していることが考えられる。したがって接続しようとするサイトとの通信に必要な証明書を置けばよいのだが、証明書もサイトごとにいくつか種類があるので、必要になるごとに<a href="https://jp.globalsign.com/support/rootcertificates/index.html">こういう所</a>からコピペやダウンロードをして追記することになるというのは避けたい。
ということで、私の場合はSSL通信が上手くいっている、Python3から網羅的な証明書群を拝借することにした。

```
$ find /usr/lib/python3 -name "*cert*"
/usr/lib/python3/dist-packages/certifi
/usr/lib/python3/dist-packages/certifi/cacert.pem
(以下略)
$ cp /usr/local/ssl/cert.pem /usr/local/ssl/cert.pem_copy 
$ cat /usr/lib/python3/dist-packages/certifi/cacert.pem > /usr/local/ssl/cert.pem 
```

検索は適当に。cacert.pemには複数の証明書が入っていた。念のため元の証明書はコピーして残しておき、置換。これで証明書エラーもなくなった。


（余談）
これまでこういったエラーには数々出会って解消してきたが、原因の特定からまともに「おまじない」もなく解決したのは初めてかもしれない。
reactの初期プロジェクト作成方法 


reactの初期プロジェクト作成方法について自分用に
まとまっているものが欲しく記事にしました

#1 react のプロジェクト作成
まずは初期プロジェクトの作成

```
create-react-app my-app --template typescript
```

#2 material-ui導入

現在使っているmaterial-uiの導入手順

```
yarn add @material-ui/core
yarn add @material-ui/icons
```
#3 AWS amplify導入

初期設定（aws-amplify/cli）などの設定を除いた設定
通しの設定が必要な場合は下記を参照

AWS amplify Docs
　https://docs.amplify.aws/start/getting-started/setup/q/integration/react#create-a-new-react-app

```
amplify init
yarn add aws-amplify @aws-amplify/ui-react
```

ソースコードへ下記を追加

```
import Amplify from "aws-amplify";
import awsExports from "./aws-exports";
Amplify.configure(awsExports);
```


#4 react router dom導入

ページ遷移に必要なreact router domの導入

https://reactrouter.com/web/guides/quick-start

```
yarn add react-router-dom
```