OmniAICreator/Qiita-1.07M huggingface dataset:
Laravelでメールを送信する

[参考：Laravelのmailableクラスでメール送信を行う[導入/入門編]
](https://www.ritolab.com/entry/38)

### mailableクラス
```terminal
$ php artisan make:mail sampleMailClass.php
```

を実行後、以下のように記述

```laravel-project/app/Mail/sampleMailClass.php
<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use App\Encyclopedia;

class sampleMailClass extends Mailable
{
    use Queueable, SerializesModels;

    protected $name; // メンバ変数
    protected $content;

    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct($mailData) // コンストラクタ
    {
        $this->name = $mailData['name'];
        $this->content = $mailData['content'];
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
         $this->text('view.page') // メール本文のイメージを記述したview 後ほど記述
                ->subject('お問い合わせが届きました')// メールタイトル
                ->with([
                    'name'    => $this->name,
                    'content' => $this->content
                ]); // viewに渡す引数
    }
}

```

### 簡単なビューページ

```page.blade.php
<form action="controller">
 <label for="name">名前:</label>
 <input type="text" name="name" value="">
 <br>
<label for="content">内容</label> 
<textarea name="content" value=""></textarea>
 <br>
<button type="submit"  class="btn btn-primary">
 送信
 </button>


メールを送りました！！

名前：{{$name ?? ''}} {{-- 空チェック --}}
<br>
本文{{$content ?? ''}}　{{-- 空チェック --}}

```

### ルーティング
ルーティングは以下のように設定

```web.php
Route::get('controller', 'Controller@notification'); 
```

## コントローラー

```terminal
$ php artisan make:controller Controller
```

実行後、以下のように記述

```laravel-project/app/Mail/Controller.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
use App\Mail\SendContact;

class Controller extends Controller
{
    public function notification(Request $request)
    {
        $contactData = [
            'name' => $request->name,
            'content' => $request->content                   
        ];
        $name = $request->name;
        $content = $request->content;
        $to = 'utsupedia@gmail.com';
        Mail::to($to)->send(new SendContact($contactData));

        return view('contact.result', ['contactData' => $contactData]);
    }
}
```
railsでdeviceをカスタマイズしてたら「I18n::InvalidLocale in　〜〜」というエラーが出た

## ■解決したいこと
RailsでWebアプリ作成で
device（ユーザー管理機能）のGemを追加したところ
サインイン画面、ログアウト画面で
「InvalidLocale in〜〜」というエラーが表示されて解決できず困った！


■経緯
deviceの
・ログアウト機能
・フラッシュメッセージ機能
の実装を進めていたらエラーが発生した。

## ■結論
ja.yml
devise.ja.yml
を配置しているディレクトリが間違っていた、、

誤：プロジェクト名/app/assets/stylesheets/config/
正：プロジェクト名/config/

↑上記２つのファイルはフラッシュメッセージを日本語化するためのファイル。
configディレクトリの直下に配置するものだが、
違うほうのconfigファイルに配置していた。

### ■自力で調べた内容
検索ワード　「InvalidLocale in　」
フラッシュメッセージの日本語化の設定に関する記事がいくつか出た。
（参照記事）
・rails sしたら[deprecated] I18n.enforce_available_locales・・・・って出てくる
https://qiita.com/katsuyuki/items/9f9f202047cdef7f11a6
マテリアルデザイン導入直後にやること

# 概要
Androidプロジェクトにマテリアルデザインを導入後にやることを書きます。
Androidプロジェクト作成した後のHello worldに対して行います。

# ライブラリ導入
マテリアルデザインを導入するために、`build.gradle`を以下のように記載します。

``` build.gradle
    // material design
    api 'com.google.android.material:material:1.2.0-alpha06'
```

# styles.xmlの変更
`res/values/styles.xml`を以下のように記載します。

``` xml
    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.MaterialComponents.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>
```

# activity_main.xmlの変更
`res/layout/activity_main.xml`を変更して表示を確認します。

``` xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"

    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.google.android.material.button.MaterialButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="確認"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        />

</androidx.constraintlayout.widget.ConstraintLayout>
```

# 結果
以下の表示になることを確認
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417396/b0091b11-5265-3b8c-05b0-87c5c227fb5d.jpeg" width=50%>


# 余談
`res/values/styles.xml`を初期値の状態のままだと以下のエラーが表示されます。

``` log
Error inflating class com.google.android.material.button.MaterialButton
```

# 参考
* Developer tutorials
    * https://material.io/collections/developer-tutorials/#
* Getting started with Material Components for Android
    * https://material.io/develop/android/docs/getting-started/
ts-node と ts-node-dev の違い

# どちらも
typescriptでの開発には持って来いなパッケージ達ですが、初めて調べた時、似たような名前でどっちを使えばいいのか結構悩んだので、違いをまとめておきます。

# ts-node

ts-nodeパッケージを追加します。

```
npm install typescript ts-node
```

typescriptも追加しないと、tsファイルが動かないので、これも追加します。
※グローバルにインストール済みの場合は必要ないです。

tsファイルを作成

```typescript:src/index.ts
console.log("Hello World");
```

package.jsonに下記を追加

```json:pacage.json
  "scripts": {
    "ts-node": "ts-node src/index.ts"
  },
```

実行してみます。

```:実行結果
npm run ts-node       

> ts-node_t@1.0.0 ts-node C:\Users\ne240\Desktop\work\module_learning\ts-node_t
> ts-node src/index.ts

Hello World
```
コンパイルなしで結果が出力されました。

### オプション
一部オプションを紹介しておきます。

```
-T, --transpile-only    // 型チェックを行わず、トランスパイル(ts->js)のみ行う
                        // 高速な起動が可能

-P, --project <path>    // tsconfig.ts のパスを指定できる
                        // 1つのプロジェクト内で複数の tsconfig.ts を使用したい時に便利
```


# ts-node-dev

続いて、ts-node-dev
ts-nodeとnode-devの合体版だそうな

ts-nodeと同様にts-node-devを追加します。

```
npm install typescript ts-node-dev
```

tsファイルを作成

```typescript:src/index.ts
console.log("Hello World");
```

package.jsonに下記を追加
※オプションについては後述

```json:pacage.json
  "scripts": {
    "ts-node-dev": "ts-node-dev --respawn src/index.ts"
  },
```

実行してみます。

```実行結果
npm run ts-node-dev

> ts-node-dev_t@1.0.0 ts-node-dev <PATH>
> ts-node-dev --respawn src/index.ts

Using ts-node version 8.10.1, typescript version 3.9.3
Hello World
```

適当にtsファイルの出力文言を変えて保存してみます。

```typescript:src/index.ts
console.log("Goodbye World");
```

ソースコードの変更を検知して、自動で変更後のメッセージを出力してくれました。

```
[INFO] 13:13:44 Restarting: <PATH>\src\index.ts has been modified
Using ts-node version 8.10.1, typescript version 3.9.3
Goodbye World
```

### オプション
こちらもオプションを一部紹介しておきます。

```
--respawn               // 今回のサンプルのように本来実行して即終了のプログラムも、
                        // 終了せず監視状態になってくれる
                        // 常時起動の待ち受けサーバとかならいらない

--ignore-watch <path>   // 監視対象から除外するファイルを指定
                        // 公式には正規表現が使えるっぽいことが書いてあり試してみたが動作せず…
                        // できた方いれば教えてください。
```

オプションの指定順は

```
ts-node-dev [node-dev|ts-node flags] [ts-node-dev flags] [node cli flags] [--] [script] [script arguments]
```

ちなみに、`ts-node-dev`って長いですよね。
`tsnd`って省略もできるので、こちらも試してみてください。

### 通知抑制

それから意外と重要なのがこれ

```json:.node-dev.json
{
  "notify": false
}
```
こいつがないと変更を検知するたびに、こんな感じででかい音と共に通知が飛んできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638864/3e5abf6c-96e7-287d-f890-e32ff0d4829e.png)

# まとめ
### ts-node
tsファイルをjsファイルにコンパイルすることなく、起動することができる

### ts-node-dev
tsファイルをjsファイルにコンパイルすることなく、起動することができ、
さらに監視モードで素早く再起動が使用できる

ちなみに、現状nodemonのほうが結構有名かなと思ってるんですけど、nodemonよりts-node-devのほうが**大幅に**再起動の速度が早いらしい！
（試したわけじゃないですけど、公式に明記してあります。）


# 参考
[npm公式 : ts-node](https://www.npmjs.com/package/ts-node)
[npm公式 : ts-node-dev](https://www.npmjs.com/package/ts-node-dev)
日本語キーボードのバックスラッシュは「ろ」

# 概要
Mac 上の Virtual Box に日本語化した Kali Linux(2020.2) を入れて遊んでいたところ、バックスラッシュ `\` が入力できなくて困った。
結果、`ろ` に割り当てられているのを発見した。
便利そうなので Mac でも同じ方法で入力できるように設定した。
Windows 10 は `¥` と `ろ` が両方 `¥` （にみえる `\`）に割りあたっていた。

これはもしかして常識…？

# on (Kali) Linux

以下の方法で日本語化した。キーボードレイアウトは 日本語 (OADG 109A) とした。
[Kali Linux 2020.1 導入と日本語化 | セキュリティ | DoRuby](https://doruby.jp/users/r357_on_rails/entries/Kali-Linux-2020)

ターミナルで作業していたところ `\` を含むコマンドが必要になった。
Mac の作法に倣って `Alt + ¥` と押すと謎の文字 `�` が入力された。これはさすがに違う。
Windows のノリで `¥` キーを押したら、`¥` が出てきた。気にせずコマンド実行したらエラー。あかんか。
で、いろいろ触っていたら `ろ` （右 Shift の左隣）で `\` が入力できることを発見した。

# on Mac OSX

アンダーバー・アンダースコア `_` は `Shift + ろ` と指が覚えてしまっているが、 Mac では `Shift` なしの `ろ` だけで `_` を入力できる。
ならば Linux に合わせてしまおう。[Karabiner-Elements](https://karabiner-elements.pqrs.org/) を使ったキーバインドの変更方法は、以下を参照。
[Macでバックスラッシュを入力しやすくする設定 by Karabiner-Elements - モノラルログ](https://matsuoshi.hatenablog.com/entry/2018/12/19/000000)

追記：そのまま適用すると VirtualBox でも入力が置換されてしまい本末転倒だった。 `frontmost_application_unless` で VirtualBox を除外すると良い。
<details><summary>設定例</summary><div>

```json
{
  "title": "backslash",
  "rules": [
    {
      "description": "underscore to backslash",
      "manipulators": [
        {
          "from": {
            "key_code": "international1"
          },
          "to": [
            {
              "key_code": "international3",
              "modifiers": [
                "option"
              ]
            }
          ],
          "type": "basic",
          "conditions": [
            {
              "type": "frontmost_application_unless",
              "bundle_identifiers": [
                "^org\\.virtualbox\\.app\\.VirtualBoxVM"
              ]
            }
          ]
        }
      ]
    }
  ]
}
```
</div></details>
参考）[Karabiner-Elementsの設定項目をまとめました - Qiita](https://qiita.com/s-show/items/a1fd228b04801477729c#conditionsbundle_identifiers)

# on Windows 10

ところで Windows はどうだったか、と確認したところ、 `¥` と `ろ` は同じ入力、つまり `¥` にみえる `\` に割りあたっていた。どちらに見えるかはアプリケーションに依存する。

いったい、なぜ今まで気づかなかったのか…
三項演算子の構文比較

Python の学習をしていて、三項演算子の構文が独特で気持ち悪かったので、他の言語がどうなっているのか、主要な言語についてざっと調べてみました。

## 三項演算子がある言語

### Python
まずは気持ち悪く感じたPython

```
trueのときの処理 if 条件式 else falseのときの処理
```

### C / C++ / C#  
王道のC系

```
条件式 ？ trueのときの処理 ： falseのときの処理;
```

### java
```
条件式 ？ trueのときの処理 ： falseのときの処理;
```

### Objective-C
```
条件式 ？ trueのときの処理 ： falseのときの処理;
```

### Swift
```
条件式 ？ trueのときの処理 ： falseのときの処理
```

### javascript
```
条件式 ？ trueのときの処理 ： falseのときの処理
```

### PHP
```
条件式 ？ trueのときの処理 ： falseのときの処理
```

### Ruby
```
条件式 ？ trueのときの処理 ： falseのときの処理;
```

### Perl
```
条件式 ？ trueのときの処理 ： falseのときの処理
```

## 三項演算子がないが代替関数がある言語
### VBA
```
IIf(条件式 ？ trueのときの処理 ： falseのときの処理)
```

### R
```
ifelse(条件式, trueのときの処理, falseのときの処理)
```

## 三項演算子がない言語
- Kotlin
- Go
- fortran


# まとめ
主要な言語について調べてみましたが、やはりPython の並びは独特ということがわかりました。
どういう思想でこの並びなんだろうか？
ほかにもPython と同じ並びの言語ってあるのだろうか？

個人的には、大多数の

```
条件式 ？ trueのときの処理 ： falseのときの処理
```

が、わかりやすくて好きです。
staticの使い方

#背景
これから鬼教官より自分の面倒を見ていただけることになった。
課題を今後出されるので、そこで習ったことを記す。

#課題
消費税クラスを作成し、継承。
消費税の変数はstaticにし、消費税込みの値段を出力せよ。

#プログラム
前回からの派生版。
消費税クラスを作成・継承し、消費税込みの値段を出力するかというプログラム。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642378/55ce4ef8-439d-9920-5325-7797cbdfa94b.png)
余裕をかました結果。。。。

#学び
staticを使うときは、クラス名.フィールド名で参照することができる
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642378/1d933abb-3be0-6e5c-5246-bf0f69dddbe2.png)
rails s で  Renderedから動かなくなった。原因と解決までについて (grid-template)

##エラーの原因
初めに、今回のエラーの原因と、どうやって解決したかについて書きます。
原因は cssファイルの grid-templateの記述ミスでした。
NGなcss
<img width="301" alt="d3acc8a81392e422606a5e5337afa2b0.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/616852/83b00ece-bedc-4356-32e9-cff67f25d894.png">
ここでgrid-templateの「;」の位置が最後の記述の下に来ているのが原因でした。

正しくは、
<img width="307" alt="67796e390fb12e755bf217acc3a5aee2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/616852/59509db4-d194-2646-9905-d9e7563e22c7.png">
のように、 grid-templateの記述を"footer";　と変更してアクセスできるようになりました。

grid-templateでエラーが出ているような記事などなかったためこれだけのエラーに半日使ってしまったので、
同じようなエラーで困った人の参考になれば幸いです

##エラーの内容
rails sでサーバーを起動後 localhost:3000 にアクセスすると読み込み状態のままになった。
renderd ~~/~.html.erb within layouts/application
から動かず、ctrl+cも効かない状態になった。

##どこが原因と考えたか
htmlファイルやコントローラーにエラーがある状態なら、エラー画面が表示された。
->rubyなどの環境が原因ではない。pcの環境ではない。と考えました。
->変更したファイルの中身が原因になる。

##何を行ったのか
githubで新しくブランチを作成して、commitを一つずつファイルを確認した。
（git cherry-pick commit_id　でcommitを参照）
cssファイルをコメントアウトした際、画面が表示されたのでcssの中身が原因だと判明。
順にコメントアウトを消して、grid-templateでエラーが出ていることが判明。
；の位置を変えて画面の表示を確認。

##迷走の記録
初めのうちは、エラーの原因究明の方法がわからず迷走してました。
ちなみに、以下の記事を試しましたので記録として
https://qiita.com/sakuraniumarete/items/ac07d9d56c876601748c
https://teratail.com/questions/77742
https://teratail.com/questions/97670
https://b0npu.hatenablog.com/entry/2016/04/11/032826

また、今回よく使ったコマンドとしてkillコマンドを使いましたがその参考記事も
lsof -wni tcp:3000　から　kill -9 killしたいPID
https://qiita.com/motty93/items/d22c1eb8f5128f8cd7f8

##まとめ
grid-templateの「;」は誤った位置にあってもエラーが出ない時がある。
MacOSをCatalinaにしてphpが動作しなくなったら

# MacOSのバージョンアップ時の定期事故である、phpenvの再インストール

## phpが動かなくなった時の対応

よくmacosのバージョンをあげたらいきなりphpが動かなくなることが多いです。
今まで毎回そうだったのでもう定期事故として考えています。面倒だけど、仕方なく新しいの使いたいから今回もバージョンアップ！

```
$ php -v
dyld: Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.64.dylib
  Referenced from: /Users/syokatsu/.phpenv/versions/7.3.13/bin/php
  Reason: image not found
zsh: abort      php -v
```

やはりこれか〜！
icu4cの問題は以前もあったので、気軽に次のステップへ

まずはphp-buildのバージョンアップから！

### php-buildのバージョンアップ

```
$ cd ~/.phpenv/plugins/php-build
$ git pull
```
今まではphp7.3系を利用していたが、php7.4が落ちてきたのでそろそろphp7.4系をinstallすることに！

### php7.4のinstall

関連libraryインストール。必要なのは色々あるはずなので、必要な物をinstall

```
$ brew install bzip2 icu4c krb5 libedit libzip oniguruma openssl@1.1 pkg-config tidy-html5
$ vi ~/.phpenv/plugins/php-build/share/php-build/default_configure_options
~~
この内容を追加
--with-zlib-dir=/usr/local/opt/zlib
--with-bz2=/usr/local/opt/bzip2
--with-libedit=/usr/local/opt/libedit
~~

$ vi ~/.zshrc
export PKG_CONFIG_PATH="/usr/local/opt/krb5/lib/pkgconfig:/usr/local/opt/icu4c/lib/pkgconfig:/usr/local/opt/libedit/lib/pkgconfig:/usr/local/opt/libjpeg/lib/pkgconfig:/usr/local/opt/libpng/lib/pkgconfig:/usr/local/opt/libxml2/lib/pkgconfig:/usr/local/opt/libzip/lib/pkgconfig:/usr/local/opt/oniguruma/lib/pkgconfig:/usr/local/opt/openssl@1.1/lib/pkgconfig:/usr/local/opt/tidy-html5/lib/pkgconfig" 
```

phpのinstall

```
$ phpenv install 7.4.6
...
[Success]: Built 7.4.6 successfully.

$ phpenv global 7.4.6
$ php -v
PHP 7.4.6 (cli) (built: May 23 2020 01:07:57) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Zend OPcache v7.4.6, Copyright (c), by Zend Technologies
    with Xdebug v2.9.5, Copyright (c) 2002-2020, by Derick Rethans
```
github -issueについて

#issueとは？
「議論すべき重要な話題・論点・争点」 / 「関心事」あたりになる。

リポジトリごとにissueを作成、管理を行える。
issue ではその repository が見られれば誰でも発言でき、議論・報告・連絡・提案などもろもろが可能。 
仕事で使う際は単純にタスク単位に issue を切って管理していくためのツールとして使われることも多い。タスク管理ツールとしての使い方だと Todo ツールなどに近い。 issue 単位で Todo = やることを書いていく。

##issue の作成方法

issuesタブからNew issueを押すと入力ページへつながる
<img width="1792" alt="スクリーンショット 2020-05-23 0.02.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599304/f84e007c-7089-a436-799c-a681e638f773.png">

<img width="1792" alt="スクリーンショット 2020-05-23 0.07.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599304/7dde86f1-56ed-68c6-d13f-de446d8cb9e8.png">

内容を記載し、[Submit new Issue]をクリックするとIssueの登録が完了。あとはこのリポジトリにアクセス権限のある人なら、誰でもIssueに対してコメントができる。

##Title
タイトルだけでIssueの内容が把握できるようにする。

Issueがバグの場合は、設計要素の名称を書く。

【xx画面】xxボタン押下時にエラー など...


##問題の内容
複数の問題をひとつのIssueに含めない。面倒だけど問題の数だけIssueを発行する。

###書くべき内容

```
実行環境
自分が行った内容
期待する結果
実際の結果
```


###実行環境
そのツール自体のバージョンや、依存していそうなソフトウェアとそれらのバージョン(OS、依存パッケージ、ホスト言語など)を記載する。
開発者がなるべく同じ環境を再現できるように具体的に書くのが望ましい。

###自分が行った内容
具体的に何をやろうとしたのかを記載。
入力として与えた値や問題が起こる直前に行ったことなどの解決に繋がりそうな情報も一緒に記載する。実際に仕様したコードや、その状況が発生するサンプルコード、スクリーンショットや動画などを貼る。

###期待する結果
自分がどのような結果になることを想定していたのかを記述する。自明な場合は省略しても可。場合によっては、自分が期待していた結果がそもそも仕様上正しくないということもあり得る。

###実際の結果
「正しくない計算結果が出た」、「予期しないエラーが発生した」、といった結果を記載。実際の値などを用いて極力詳細な結果を提供する。長いエラーメッセージを全てそのまま貼り付けるのは可読性を損なうので、そのような場合は必要な部分のみを切り取って記載。



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599304/674dd222-6ca2-e691-8e1d-c6b88d2c96a7.png)



Issueが解決したら[Close issue]ボタンをクリックしてクローズする。クローズしたIssueも、完全に消える訳ではなく、Issueの一覧から確認できる。

#担当者を明確にする「Assignee」機能
プロジェクト管理には必須のAssignee（アサイニー）。Issueに担当者を割り当てる機能ある。Issue画面のサイドバーにある[Assignee]という文字をクリックする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599304/387e35a3-7d9d-6577-f7bc-18861cd1e54a.png)


Assigneeは途中で付け替えることもできる。そしてIssueの一覧画面ではアイコンが並ぶので、誰がどのくらいのタスクを抱えているかが一目で分かる。

Assigneeに指定することで、通知も逃さず受け取ることができます。1つのIssueに対して1人しかアサインできない。

#スケジュールを管理する「Milestone」機能
Issueに締め切りをつける機能。GitHubでは、Issueごとに期日を切るのではなく、マイルストンを先に置いて、それにIssueを紐付ける。

Issueの一覧画面からマイルストンの一覧画面に遷移します。そこから[New milestone]で新しいマイルストンを作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599304/f2d28985-4a51-0a44-b900-bc18bbaf491d.png)


マイルストンの設定画面ではタイトル、概要、期日を入力。タイトルの付け方はチームごとに分かりやすいようにつける。[Create milestone]をクリックすると作成完了です。

マイルストンもAssigneeと同様、Issue画面のサイドバーから設定できる。Milestoneの一覧画面では、紐付けられたIssueの内、何%がクローズされたかという進捗が確認できる。マイルストンを先に設定し、そこに必要なIssueを紐付けていく、という仕組みになっていることが分かる。

#増えたIssueを整理する「Label」機能
Issueにラベルを付けて分類できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599304/49b0248f-532a-1d97-a13e-acbf4ab06182.png)
Vue.js　親・子　コンポーネント間　データ　受け渡し　

#やりたいこと

Vue.js (Vue CLI)で、親・子コンポーネント間でデータを受け渡したい。

今回は以下のような流れでデータを受け渡します。
child1.vue(子1)　→　pearent.vue（親）　→　child2.vue（子2）

#child1.vue(子1)　→　pearent.vue（親）、子から親へデータを移動

今回は、ボタンを押すと```input```に記載された文字列を親コンポーネントに渡す処理を実装します。

まずchild1.vue(子1)


```
<template>
    <div id="target-input">
        <p>以下input内に入力されたデータを親に渡します</p>
        <input type="text" @input="example = $event.target.value">
        <button @click="sendToParent">親へデータを渡す</button>
    </div>
</template>

<script>
export default {
    data(){
        return {
            example : "",
        }
    },
    methods: {
        sendToParent() {
             this.$emit("textForParent",this.example);
        }
    },
};
</script>
```
**ポイント**
・```methods```内、```this.$emit```は引数を２つとります。１つ目は好きに名前を付けてください。
　（後ほど親コンポーネント内で使用します）
・２つ目は、親コンポーネントへ渡したいデータを指定します。今回は```data```内の```example```です。

上記で「送り口」の実装は完成です。

しかしこのままでは「受け取り口」が用意されていない為、データが親コンポーネントへ渡りません。
受け取り側であるpearent.vue（親）に、「受け取り口」を実装していきます。
pearent.vue（親）

```
<template>
  <div id="app">
    <child1 v-on:textForParent="text = $event"></child1>
    <child2></child2>
  </div>
</template>

<script>
import child1 from './child1.vue'
import child2 from './child2.vue'

export default {
  name: 'App',
  components: {
    child1,
    child2,
  },
  data(){
    return {
      text : "",
    }
  },
};
</script>
```
**ポイント**
・```v-on```ディレクティブの後に、子コンポーネント内で設定した```this.$emit```の第１引数をとります。
・```$event```には、子コンポーネント内の```this.$emit```の第２引数である、データが入ります。

これで、親コンポーネント ```data```内の```text```へ、子コンポーネントからデータを渡すことが出来ました。

#pearent.vue（親）　→　child2.vue(子2)　、親から子へデータを移動

では今度は親コンポーネントから子コンポーネントへデータを移動してみましょう。
先ほどの```text```を、child2.vueへ渡してみます。

pearent.vue（親）

```
<template>
  <div id="app">
    <child1 v-on:textForParent="text = $event"></child1>
    <child2 v-bind:textForChild2="text"></child2>
  </div>
</template>

<script>
import child1 from './child1.vue'
import child2 from './child2.vue'

export default {
  name: 'App',
  components: {
    child1,
    child2,
  },
  data(){
    return {
      text : "",  //実際には、child1からのデータが入っています
    }
  },
};
</script>
```

**ポイント**
・```<child2></child2>```に```v-bind```を付けてあげます。```text```のデータを子に送ります。
上記で「送り口」はできました。

今度はchild2.vue(子2)に「受け取り口」を作ります。
child2.vue(子2)

```
<template>
    <div>
        <p>以下に親コンポーネントから渡されたtextデータを表示します。</p>
        <p>{{textForChild2}}</p>
    </div>
</template>>

<script>
export default {
    props:["textForChild2"],
};
</script>
```
**ポイント**
・```props```を設定して親コンポーネントからデータを受け取ります。これを```template```内で呼び出します。


以上です！
今回の例ではchild1.vue(子1)内で作られたデータがpearent.vue（親）へ渡り、そこからchild2.vue(子2)へ渡りました。

子から親へ、親から子へデータを受け渡しすることが出来ました！
Route53 で管理するドメインを CloudDNS に権限移譲する

## はじめに

いきなりですが、ドメイン委譲をしたい、そんな事ありませんか？私はあります。

例えばあるプラットフォームのDNSサーバで管理するドメインのサブドメインを、別プラットフォームのDSNサーバで管理できるようにしたいとかです。もちろん別プラットフォームでなくとも、別ゾーンで管理したいとかもケースとしてありますね。

今回でいうと

- AWSのRoute53でメインドメイン（`example.com`）を管理している。
- そのメインドメインのサブドメイン（`sub.exapmle.com`）をGCPのCloud DNSで管理できるようにしたい。

という感じです。`example.com`はご自身がお持ちのドメインで置き換えて考えてください。

もちろんRoute53側でサブドメインを作成して運用するパターンもありますが、GCPでLBや各種ネットワーク系のサービスを利用すると考えるとGCP側にあったほうがいいと考えました。`hoge.sub.exapmle.com`や`fuga.sub.exapmle.com`を発行するたびにRoute53で作って…みたいなことも面倒です。

また`example.com`とは別に`example2.com`のように別ドメインを取得してそれをCloudDNSに登録するパターンもあります。これもこれでいいのですが、一定コストが掛かるのと、今回紹介する権限委譲が大変ではなかったのでこのパターンも取りませんでした。


## やってみる

手順は意外と簡単です。

1. Cloud DNSでサブドメインを作成する
2. NSレコードを取得
3. Route53にNSレコードを登録


### 1. Cloud DNSでサブドメインを作成する

ネットワークサービス => Cloud DNS => ゾーンの作成

<img width="800" alt="スクリーンショット 2020-05-22 21.54.50.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164543/03e41811-e902-bf5a-76b6-bfa8f9de9666.png">

上記のように、**example.comがある前提で**、`sub.example.com`を作成してしまいます。
「sub.example.comという実態がないのにここで作成していいの？」と思いますが、まずは作成で大丈夫です。


### 2. NSレコードを取得

そのまま作成すると以下のようにNSレコードが複数発行されます。

<img width="800" alt="スクリーンショット 2020-05-22 21.55.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164543/ea287711-8966-528d-5408-2ca6ec7236f5.png">


図でいうと4つ分をコピーします。


### 3. Route53にNSレコードを登録


Route53 => ホストゾーン => ドメイン名`exmple.com`=> レコードセットの作成 に移動します。

もちろん`exmple.com`はご自身がお持ちのドメイン名です。`sub.exmple.com`はRoute53には存在しないのでここで登録します。入力するのは赤枠で囲っている2箇所です。

<img width="800" alt="スクリーンショット 2020-05-22 22.01.31.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164543/cbfc2266-63df-c7c6-e73b-f0a36d52c8c6.png">


上の赤枠には`sub.exmple.com`の`sub`を入力します。
下の赤枠にはステップ2で取得したNSレコードを入力します。
そのまま作成を押すと利用できるようになります。





## 参考

https://knowledge.sakura.ad.jp/10547/

https://dev.classmethod.jp/articles/route53-transfer-hostedzones/
【GoogleAppsScript】スクリプトでフォーム作成時にページ指定で遷移させたい

## 概要
GoogleAppsScript（GAS）には[GASでGoogleフォームを作成する最も簡単なスクリプト](https://tonari-it.com/gas-create-form/)にある通り、スクリプトからフォームを作成する機能があります。フォームは入力内容に応じて遷移させるページを変えることができますが、これをスクリプトで実現した場合にどう実装するかというのを紹介します。

## やりたいこと
1ページ目で、2ページ目か3ページ目に遷移させるか選択します。
<img width="655" alt="スクリーンショット 2020-05-22 23.53.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32098/5fb2ecf4-e72a-2f44-5e4b-a2e9c8caaddb.png">
2ページ目ではテキストを入力します。次へを押すと4ページ目に遷移します。
<img width="665" alt="スクリーンショット 2020-05-22 23.53.19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32098/74b56ef4-7bb4-98a0-849e-cff53c14ddb9.png">
3ページ目ではテキストを入力します。次へを押すと4ページ目に遷移します。
<img width="658" alt="スクリーンショット 2020-05-22 23.53.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32098/a9d95087-d103-0f2f-79ac-d457cfb7f754.png">
4ページ目でテキストを入力して送信します。
<img width="667" alt="スクリーンショット 2020-05-22 23.53.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32098/7604210c-d351-2f57-0f83-d1ee49191c23.png">

## 実装方針や注意点など
* 今回はページを指定して遷移させるようにします。遷移先のページを指定するには、後のページのオブジェクトを先に作成していく必要があるので、実装では4ページ目から作成するようにします。なお、ページ分けについては[PageBreakItem](https://developers.google.com/apps-script/reference/forms/page-break-item)を使用します。
* 後ろからページのオブジェクトを作成していくと、当然そのままだとページの順番が逆になります。ので、前にしたいページは都度移動させていきます。ページの入れ替えについては[moveItem](https://developers.google.com/apps-script/reference/forms/form#moveitemfrom,-to)メソッドを使います。
* 1ページ目の選択ではcreateChoiceに遷移先ページを指定することで、遷移先を変えることができます。[GASで既存のフォームの選択肢に「回答に応じてセクション移動」を設置するには](https://teratail.com/questions/228175)の記事が参考になります。
* 2ページ目で4ページ目に遷移させる設定は[setGoToPage](https://developers.google.com/apps-script/reference/forms/page-break-item#setGoToPage(PageBreakItem))メソッドを使用します。注意点としてはsetGoToPageは設定対象オブジェクトの直前に設定されるので、3番目のページのオブジェクトで呼び出しを行います。

## 実装サンプル
ソースを[こちら](https://github.com/someone7140/javascript/blob/master/SampleFormGas/formCreate.js)にアップしています。
今日のことりん: Regexが文字列に含まれているかをかっこよく書く。

ある文字列に特定のパターンが書かれているか以下のように書くことができる。

```kotlin

Regex("abc").containsMatchIn("abcd") // true

Regex("abc").containsMatchIn("abb") // false
```

もっとかっこよく以下のように書くことができる。

```kotlin
Regex("abc") in "abcd" // true
```

### なぜできるか?
`in`を使うためにはクラスにcontainsがoperatorとして定義されていれば良い

Stringsに以下が定義されているため`in`でRegexを評価できる。

```
@kotlin.internal.InlineOnly
public inline operator fun CharSequence.contains(regex: Regex): Boolean = regex.containsMatchIn(this)
```
文字列内の変数展開的な処理の簡易実装


#例

```vb:実行コード
'※「Microsoft Scripting Runtime」への参照設定が必要
Dim Source As String
Dim Values As New Scripting.Dictionary

'変数を含む文字列
Source = "name='${name}', age=${age}, birthday=${birthday}"

'変数の値
Call Values.Add("name", "山田　太郎")
Call Values.Add("age", 20)
Call Values.Add("birthday", DateValue("2000/4/1"))

'文字列内の変数展開の実行
Debug.Print SubstituteVariables(Source, Values)
```

```console:出力結果
name='山田 太郎', age=20, birthday=2000/04/01
```



#ソースコード

```vb:SubstituteVariables.bas

'※「Microsoft Scripting Runtime」への参照設定が必要
Function SubstituteVariables(Source As String, Values As Scripting.Dictionary) As String

    Static VariableParser As Object

    Dim Matches As Object
    Dim Match As Object
    Dim StringArray() As String
    Dim ArrayIndex As Long
    Dim PrevStringIndex As Long
    Dim VariableName As String

    If Values Is Nothing Then
        SubstituteVariables = Source
        Exit Function
    End If

    If Values.Count = 0 Then
        SubstituteVariables = Source
        Exit Function
    End If

    If VariableParser Is Nothing Then
        Set VariableParser = CreateObject("VBScript.RegExp")
        With VariableParser
            .Global = True
            .IgnoreCase = False
            .MultiLine = False
            .Pattern = "(\$+)\{([^}]+)\}"
        End With
    End If

    Set Matches = VariableParser.Execute(Source)

    If Matches.Count = 0 Then
        SubstituteVariables = Source
        Exit Function
    End If

    ReDim StringArray(1 To Matches.Count * 2 + 1) As String
    ArrayIndex = 1
    PrevStringIndex = 1

    For Each Match In Matches

        If Match.FirstIndex - PrevStringIndex + 1 > 0 Then
            StringArray(ArrayIndex) = Mid(Source, PrevStringIndex, Match.FirstIndex - PrevStringIndex + 1)
            ArrayIndex = ArrayIndex + 1
        End If

        If Match.SubMatches(0) = "$" Then

            VariableName = Match.SubMatches(1)
            Debug.Assert VariableName <> ""

            If Values.Exists(VariableName) Then
                StringArray(ArrayIndex) = Values(VariableName)
                ArrayIndex = ArrayIndex + 1
            Else
                StringArray(ArrayIndex) = Match.Value
                ArrayIndex = ArrayIndex + 1
            End If
        Else
            StringArray(ArrayIndex) = Mid(Match.Value, 2)
            ArrayIndex = ArrayIndex + 1
        End If

        PrevStringIndex = Match.FirstIndex + Match.Length + 1
    Next

    If PrevStringIndex <= Len(Source) Then
        StringArray(ArrayIndex) = Mid(Source, PrevStringIndex, Len(Source) - PrevStringIndex + 1)
    End If

    SubstituteVariables = Join(StringArray, "")

End Function

```
[Azure IoT Edge] Jetson Nano でリアルタイム物体検出

![streaming.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575879/dfa3c960-575e-104b-5a11-99c15ccabb0e.gif)

Jetson Nano 上でリアルタイム物体検出を行います。

* Jetson Nano を [Azure IoT Edge](https://docs.microsoft.com/ja-jp/azure/iot-edge/about-iot-edge) デバイスとして使用し、その上で [Custom Vision](https://docs.microsoft.com/ja-jp/azure/cognitive-services/custom-vision-service/home) の物体検出モデルを使用
* 結果を [Azure IoT Central](https://docs.microsoft.com/ja-jp/azure/iot-central/core/overview-iot-central) で可視化

手順の詳細は以下の github にまとめています。（英語）
https://github.com/yahanda/decode20-demos
CloudFunctionsのトリガーのファイルを規約化する

## CloudFunctionのトリガーのファイルを規約化する

下記にてCloudFunctionsのトリガーのディレクトリ設計についてまとめていました。

- [CloudFunctionsのトリガーに対するディレクトリ・フォルダ・ファイルの設計](https://snamiki1212.com/firebase-trigger-for-directory-architecture)

上記の記事の案２）のケースを元に、規約化するやり方をこの記事ではまとめます。

## はじめに

[先程の記事の案２）](https://snamiki1212.com/firebase-trigger-for-directory-architecture#%EF%BC%92%EF%BC%89%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E5%90%8D%E3%81%A7%E8%A1%A8%E7%8F%BE)は、こんな感じでファイル名でストレージパスを表現します。

<img width="312" alt="file.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186228/fc7aa592-92c3-07e8-bc16-25c54f114d53.png">

つまり、下記のようにマッピングしています

- Firestoreのストレージパス: version/v1/users/{user_id}
- TypeScriptのディレクトリ設計: `~/version.v1.users.{user_id}.ts`

ここで、TypeScript側のファイルはこの命名に従えば規約化されるようなロジックを書きたいです。

では、みていきます。

### コード：ファイル名から規約化する

まず、`conventer.ts`にてファイル名を元にストレージのpathへ変換するメソッドを定義しておきます

```ts:conventer.ts
import path from 'path'

export const getStoragePath = (filename: string) =>
  path.basename(filename, '.ts').replace(/\./g, "/");
```



### コード：ファイル名からストレージパスにつなげる



トリガーファンクションで、自分のファイル名を元にFirestoreのファイルパスを導き出すことで規約化します。

こんな感じです。

```ts:version.v1.users.{user_id}.ts
import * as functions from "firebase-functions";

import {getStoragePath} from './conventer'

const storagePath = getStoragePath(__filename)
// => version/v1/users/{user_id}

const ref = functions
  .region("asia-northeast1")
  .database.ref(storagePath);

export const onCreate = ref.onCreate((snapshot, context) => {
  // ...
});

```


シンプルですね。
これで、規約化されました。
vscodeで関数名と（）の間のスペースがなくなる問題．

# 前提
### 利用したエディタ
``Visual Stdio Code``
みんな大好き．

### 利用したコーディングスタイル
[JavaScript Standard Style](https://standardjs.com/)

理由は簡単で，けっこうルールが細かく決められていて，個人的に好みだったからです．
（逆にゆるいのが嫌い）

# 問題となったルール
上記コーディングスタイルの中に，[このような](https://eslint.org/docs/rules/space-before-function-paren)ルールがあります．
簡単に言うと，関数宣言の括弧の前にはスペースを入れましょうということです．

```javascript
function name (arg) { ... }   // ✓ ok
function name(arg) { ... }    // ✗ avoid
 
run(function () { ... })      // ✓ ok
run(function() { ... })       // ✗ avoid
```

# どのような問題が発生したか
ソースを保存したときに，勝手に関数名と（）の間の空白が消されました．
つまり，上記の例の``aviod``状態になったということです．

手で空白を追記して，保存したら消えて．．．
という無限ループに陥っていました．

# 解決方法
``Visual Studio Code``の``setting.json``を開いて，
``javascript.format.insertSpaceBeforeFunctionParenthesis``
にチェックを入れただけです．

これだけです．
Gitでリモートに新規作成したbranchがgit fetchしてもローカルで追跡出来ずハマった話

#はじめに
私が午前中を溶かした、`git fetch`でハマった話を忘備録を兼ねて記載する。

#発生した事象
`git fetch`しても新規作成したブランチ名が表示されない事象に遭遇した。

具体的には、以下のように作業を進めていた。
①リモートリポジトリをローカルにクローン
②リモートリポジトリで新規ブランチを作成
③クローン済みのローカルリポジトリに②で作成したブランチをチェックアウト

この際、③にてブランチのチェックアウトをしようと、
`git fetch`でリモートブランチの情報取得後、
`git branch -a`でリモートブランチを確認したが、新規作成したリモートブランチ名が表示されない。
そのため、チェックアウトも出来ずハマってしまった。


#原因
`./git/config`内のfetch対象の指定が、以下のようにブランチ毎になっていた。

```
[remote "origin"]
	url = https://hogehohehoge
	fetch = +refs/heads/hoge:refs/remotes/origin/hoge
	fetch = +refs/heads/hoge2:refs/remotes/origin/hoge2
```


#解決方法
以下のように、fetch対象のbranchをリモート全体に指定する事で、
クローン後に新規作成した時にも情報を取得してくれるようになった。


```
[remote "origin"]
	url = https://hogehohehoge
	fetch = +refs/heads/*:refs/remotes/origin/*
```

#参考文献
こちらのページに大変助けられました。ありがとうございます…！

『Git』10.5 Gitの内側 - Refspec
https://git-scm.com/book/ja/v2/Git%E3%81%AE%E5%86%85%E5%81%B4-Refspec
Deno で "node".split("").sort().join("")

Deno 公式の Twitter アカウントが投稿していたコード。

[Deno on Twitter: ""node"\.split\(""\)\.sort\(\)\.join\(""\)" / Twitter](https://twitter.com/deno_land/status/1262517004159913985)

> "node".split("").sort().join("")

結果を出力してみる。

```deno.ts
console.log("node".split("").sort().join(""))
```

node が deno になった。

```
$ deno -q run deno.ts
deno
```

これが Deno という名前の由来かどうかは探してみたが見つからなかった。

[Deno \- Wikipedia](https://ja.wikipedia.org/wiki/Deno)

> DenoはJSConf EU 2018でのライアン・ダールによる講演「Node.jsに関する10の反省点」で発表された。ライアン・ダールはこの講演において、後悔しているNode.jsの初期設計での決定について言及し、APIの設計でpromiseを使用しないという選択をしたこと、古いGYPビルドシステムを使用するようにしたこと、node_modulesとpackage.jsonの採用、拡張子を除外したこと、index.jsによる魔法のようなモジュールの依存関係の解決、V8のサンドボックス環境の破壊を挙げている。最終的に、彼はDenoのプロトタイプ版を発表し、Protocol Buffersのようなシリアライズツールを使用したメッセージの受け渡しを通じてシステムコールバインディングを実現し、アクセス制御用のコマンドラインフラグを提供することを目指した。
Pythonのスライス記法で大混乱した時用の例集

#最初の定義

```python
x=[1,2,3,4,5,6]
```

#一般

前から

```python
x[1:]
#[2,3,4,5,6]
```
後ろから

```python
x[:1]
#[1]
```

#マイナス
前から

```python
x[-1:]
#[6]
```

後ろから

```python
x[:-1]
#[1,2,3,4,5]
```

#ゼロ
前から

```python
x[0:]
#[1,2,3,4,5,6]
```

後ろから

```python
x[:0]
#[]
```


#オーバー
前から

```python
x[9:]
#[]
```

後ろから

```python
x[:9]
#[1,2,3,4,5,6]
```
S3+Cloudfront+Route53でSPAを公開したときにハマったこと

## tl;dr
- やはりまだACMの証明書はバージニア北部にリージョン設定しておかないとCloudFrontに設定できない
- S3のバケット名はドメイン名完全一致じゃないとだめ
- S3の`Static website hosting`を設定したときに出てくるエンドポイントをCloudFrontの`Origin Domain Name`に設定しないと`Static website hosting` の設定を素通りする、何も効かない

## やってたこと
- S3 + CloudFront + Route53 で静的ホスティングサイトを作成する
- アップするものはReact(create-react-app)で作成したSPAのbuildファイル
- CIで自動的に〜とかちょっとすっ飛ばしたかったので手動でS3のバケットに挙げる

## ハマったこと
### やはりまだACMの証明書はバージニア北部にリージョン設定しておかないとCloudFrontに設定できない

お名前.comでドメイン取得したので、互いにサイトを行ったり来たりで取得した。
最初は四苦八苦あって証明書は取れたもののCloudFrontで設定ができない。

いろいろ調べてみると`米国東部 (バージニア北部)us-east-1`にリージョンを設定して証明書を取得しないといけないそう。ここでメインドメイン(example.com)の証明書を取得できていないことにも気づいたので、ワイルドカードを使ったドメイン(*.example.com)と一緒にドメインを追加して証明書を取得。

あとはCloudFrontとRoute53の設定をして完了。

### S3のバケット名はドメイン名完全一致じゃないとだめ

まあこれは色んなサイトにも書いてあるし公式も説明してる感じなので調べてみてください

まあそんなこんなでルートにアクセスしたらビルド内容の表示ができました。

### S3の`Static website hosting`を設定したときに出てくるエンドポイントをCloudFrontの`Origin Domain Name`に設定しないと`Static website hosting` の設定を素通りする、何も効かない

こいつが一番わからなかった。
前提として、SPAなので用意したバケット直下のindex.htmlを全てのアクセスに関してレスポンスしたい。
その設定がS3の`Static website hosting`でできるそう。
でもいくら設定してもできなかった。

なんでかなと思ってCloudFrontとかいろいろ確認してみてやっと理解。

CloudFrontの`Origin Domain Name`に設定していたものが、`example.com.s3.amazonaws.com`だった。S3の`Static website hosting`設定画面に表示されているエンドポイントは`example.com.s3-hoge-ap-northeast-1.amazonaws.com`のようにリージョン名がついているものだった。

S3のエンドポイントをCloudFront側に設定して完了。
これで一旦`Static website hosting`の設定は反映されるように。

## 最後に
ただここからまだredirect設定(ドメインのあとのパスは残しつつレスポンスはバケット直下のindex.htmlみたいなやつ)をしないといけなくて、そこがちょっとうまく行かず。一旦ここまでをメモとして残しておく。
Jupyter Notebook 指定したディレクトリを起動する

この記事は、勉強で自分が忘れないようにするアウトプットで
書いたもの
参考程度に考えていただければと思います。
間違ってる、こうした方が良いよという意見がございましたら是非教えてくださいｍ(＿)ｍ

anaconda Promptで初期ディレクトリから、別のディレクトリを
起動する。

まず、Anaconda Promptで以下の内容を入力![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/629920/3a002f70-2875-4b3a-702d-46e4d0577fb9.png)

そしたら、以下の設定ファイルになる![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/629920/ab47ec12-e18d-7036-fc75-981e1fb60fe9.png)
上記の内容だと既にconfigファイルが存在しているので「N」と
入力する。「ｙ」を入力すると上書きされてしまうので注意。
本来は、C:/Useres/ユーザー名/.jupyter/jupyter_notebook_config.pyとなるはず。
(参考リンク：https://kazusa-pg.com/jupyter-notebook-use-virtual-env-kernel/)

以下の入力でディレクトリの起動が出来ました。
$　jupyter notebook 起動したいディレクトリ名

(参考リンク：https://qiita.com/ponponpopon/items/2c7fff94c7ec32ace230)
XAMPPでLaravel開発環境構築

XAMPPを使って、Laravel開発環境を構築します。 

以下のサイトから、Windows向けのXAMPPをダウンロードします。
<https://www.apachefriends.org/jp/download.html>
私の環境では、[PHP 7.3.18]を使用しました。
ダブルクリックしてインストールを行います。
このとき、<c:\xampp>からパスを変更しないほうが良いです。

インストールが完了したら、
<c:\xampp\xampp-control.exe>
を起動しましょう。

XAMPP Control Panelが立ち上がったら、さっそくApacheを起動してみます。
Apacheの[Start]ボタンをクリックしてみましょう。
次に、[Admin]ボタンをクリックすると、ブラウザが立ち上がります。
Skypeを入れていると、エラーが発生し、立ち上がらないことがあります。
Skypeが80、443ポートを使用しているために、既に使われているとエラーが発生し立ち上がらないことがあります。
この解決策は、Apacheの[Config]ボタンをクリックして、[Apache(httpd.conf)]の修正が必要です。

エディターで起動してみましょう。
修正箇所は２か所です。
①Listen 80
②ServerName localhost:80
ポートを80以外に変更します。
今回は8081に変更しました。

では、再度[Start]して[Admin]から、起動を確認しましょう。
ブラウザが立ち上がり、エラーとなりました。
URLを<http://localhost/>　→　<http://localhost:8081/>に変更して確認したところ
正常に立ち上がっていることを確認しました。

では、Laravelでプロジェクトを構築します。
コマンドプロンプトを開いてください。
[cd \]と入力し、ルートに移動します。
次に[cd xampp\htdocs]に移動します。

composerを使用して、プロジェクトを作成します。
composer create-project laravel/laravel --prefer-dist {作成するプロジェクト名}
と入力してEnterしてください。
５分程度かかりますので、そのままお待ちください。
Successと表示されたら、成功です。

次に、エクスプローラから<c:\xampp\apache\conf\httpd.conf>をエディターで開きます。
DocumentRootとDirectoryを設定します。

DocumentRoot "/xampp/htdocs/｛作成済プロジェクト名｝/public"
<Directory "/xampp/htdocs/｛作成済プロジェクト名｝/public">

保存して、同様にxampp Control Panelから[Admin]を起動してみましょう。
Laravelの画面が表示されたらOKです。

次は、XAMPP Control PANELからMySQLのAdminボタンをクリックして、MySQLを起動します。
ポートを変更していますので、エラーが出るようでしたら、
<http://localhost:8081/phpmyadmin/>
と入力しなおしてください。（ポートはご自身の環境に合わせて）

左側のツリーから新規作成ボタンをクリックしてデータベースを作成します。
DB名称は作成済のプロジェクトに合わせて名称を入力します。
文字コードは[utf8-general-ci]を選択しました。
最後に作成ボタンをクリックして終了です。

.envファイルの設定も必要です。
エクスプローラから<c:\xampp\htdocs\{作成したプロジェクト名}>に移動します。
その下に保存されている<.env>ファイルをエディターで開きます。
そして、以下の設定を変更します。
    DB_CONNECTION=mysql
    DB_HOST=127.0.0.1
    DB_PORT=3306　←MySQLのデフォルト
    DB_DATABASE=作成したデータベース名
    DB_USERNAME=root　←デフォルト
    DB_PASSWORD=　←デフォルト

次に1行目のAPP_NAMEも設定してください。

デフォルトの表示言語を変更します。
初期は英語で表示されていますので、日本語に設定する際は、
<c:\xampp\htdocs\{作成したプロジェクト名}\config\app.php>
をエディターで開き、以下の２か所を修正します。
　①　'locale' => 'en',　→　 'locale' => 'ja',
　② 'timezone' => 'Asia/Tokyo',

では、起動を確認してみましょう。
Apacheを一度[Stop]してから[Start]して[Admin]から確認をしてください。
Laravelが表示されれば、成功です。
Swiftの文について見ていきます

##概要
新たにSwiftを学び始めたので、アウトプットも兼ねて、Xcodeの文を見ていきます。

```viewController.swift
class ViewController: UIViewController {
    @IBOutlet weak var countLabel: UILabel!
    var count = 0 
    override func viewDidLoad() {
        super.viewDidLoad()
        countLabel.text = "0" 
    }
    @IBAction func plus(_ sender: Any) {
        count = count + 1     
        countLabel.text = String(count)
        if(count >= 10){
            changeTextColor()
        }
    }
    @IBAction func minus(_ sender: Any) {
        count = count - 1
        countLabel.text = String(count)
        if(count <= 0){
            resetColor()
        }
    }
    func changeTextColor(){
        countLabel.textColor = .yellow
    }
    func resetColor(){
        countLabel.textColor = .white
    }
}
```

class ViewController: UIViewController {

```
    @IBOutlet weak var countLabel: UILabel!
    var count = 0 
```
この部分は変数の宣言になります。varとつけて宣言を表明し、その後にcountLabelという変数名をつけています。その後のcount変数を宣言して 0 を代入しています。

```
    override func viewDidLoad() {
        super.viewDidLoad()
        countLabel.text = "0" 
    }
```
この部分はアプリを開いた時に自動的に読み込まれる箇所です。
countLabelにオブジェクト.textをつけてそれに文字型の0を代入して表示しています。


```
    @IBAction func plus(_ sender: Any) {
        count = count + 1     
        countLabel.text = String(count)
        if(count >= 10){
            changeTextColor()
        }
    }
```
この部分はボタンがタッチされた時該当する　plusメソッドが動きますが、その処理を記述しています。
countに1を足す処理です。そしてさらに足したcountを文字型に変えて表示しています。
その後のif文はcountが10超えたらchageTextColorというメソッドを読み込むという記述です。

```
    @IBAction func minus(_ sender: Any) {
        count = count - 1
        countLabel.text = String(count)
        if(count <= 0){
            resetColor()
        }
    }
```
ここはさっきと逆でcountから1引く処理をしています。そしてそれを文字型に変えて表示。if文で0以下になったらresetColorというメソッドが読み込まれるという記述です。


```
    func changeTextColor(){
        countLabel.textColor = .yellow
    }
    func resetColor(){
        countLabel.textColor = .white
    }
```

最後にこの箇所はメソッドを定義する箇所です。
changeTextColorメソッドでは.textColorオブジェクトを使って文字を黄色に変えています。
resetColorメソッドは同じように文字を白色に変えています。
AzureでWeb appからKeyvalutを使う時のパーミッション設定

AzureでWeb appからKeyvalutを使う方法は、
[本家のドキュメント](https://docs.microsoft.com/en-us/python/api/azure-keyvault-secrets/azure.keyvault.secrets.secretclient?view=azure-python)
に記載されてますが、これだけではアクセスできませんでした。

Keyvalutへのアクセス許可を設定する必要があります。

1．AzureのPortalからアクセスしたいApp ServiceのIdentityを開き、StatusをOnにする。変更すると、Object IDが割り当てられて表示される。

2．Azureのshellからgetのパーミッションを追加する（xxxxxxxxxxxxxxxxxxxxxxは1.で得たObject ID）

```console
$ az keyvault set-policy --name "keyvalutの名前" --object-id xxxxxxxxxxxxxxxxxxxxxx --secret-permissions get
```
Flutter/Dartで数値を3桁ごとにカンマで区切る


## 方法
`Intl` パッケージ `NumberFormat` を使う。

```dart
import 'package:intl/intl.dart';
final formatter = NumberFormat('#,##0', 'ja_JP');
void main () {
  print(formatter.format(1000000));
  // 1,000,000
}
```

## 参照情報
[formatting - Currency format in dart - Stack Overflow](https://stackoverflow.com/questions/14865568/currency-format-in-dart)
[intl | Dart Package](https://pub.dev/packages/intl)
コードレビューに関する指針

# はじめに

私のチームで行っているコードレビューを行う際に、どのように進めていくかの指針を定めているのですが、普遍的に活用できる内容であるため、この取り組みを紹介します。

# コードレビューの指針

## 目的

- 　良いコード、クソコードについての共通認識を持った上でコードレビューを行うことで、チーム全体のプログラミングレベルを引き上げる

## 心構えについて

- 双方
    - 良いコードについて共通認識を持つこと
- レビュイー
    - コードの変更目的(Why)、具体的な変更内容(What)を明確にする
    - 指摘は人格否定ではないことを理解し、素直な気持ちで受け入れる
- レビュアー
    - 不明な点は素直に質問する
    - 感じた点は、我が身に返ることを恐れず指摘する
    - なぜ悪いのか論理的に説明する
    - 良かったら褒める

## レビュー観点

- 設計
    - システムに対して適切な設計になっているか
- 機能
    - 仕様に沿った or 開発者が意図した実装になっているか
- 複雑さ
    -できるだけシンプルになっているか
        - 第三者が再利用、修正しやすい形式になっているか
        - 現時点で必要以上の機能が実装されていないか([YAGNI])
        - 冗長な条件文で記述されていないか
- テスト
    - 実装内容に対して、適切なテストを実施しているか / テストコードが実装されているか
- 命名
    - 変数やクラス、メソッドなどに明確な名前が付けられているか
        - 関数の役割や変数の内容が理解でき、適度な長さになっているか
- コメント
    - コメントは明確で分かりやすいか
        - コード自体から読み取れない、何故その処理が必要なのか背景を説明するのに活用する
        - 処理内容についてのコメントは極力避け、コードをシンプルにすることで対応する
- スタイル
    - コードはスタイルガイドに従っているか
- ドキュメント
    - 関連するドキュメントは更新されているか

## 具体的な進め方

- レビュイー
    - 細かくフィードバックを得るため、レビュー依頼を小さい単位でできるように心掛ける
    - レビュー前に、上記の観点に沿った実装ができているかを確認する
    - コードの変更内容をまとめて、レビュワーに伝える
        - 後述のテンプレート
- レビュワー
    - 変更されたコードについて、行っている処理を全て理解する
    - 不明な点については、どういう処理なのか、どういう意図なのかを質問する
    - 指摘点について、論理的に理由を説明し、具体的にどのように修正すべきかのフィードバックする
    - 指摘点だけでなく良いところもフィードバックする


## 決めておくべき事柄

### レビューに関する前提条件

開発フローの中で、どのタイミングでレビューをするか、また事前に満たしておくべき基準といった標準的な決め事を定めておきます。

例えば、GitFlowスタイルの開発フローにおけるreleaseブランチへのマージ時に、事前に自動テストの通過を確認しておくなど。

### コードレビューテンプレート

GitのPull Requestのテンプレートとして記載しています。
可能であれば、タスク管理ツール等と連携するのが良いと思います。

- 概要
    - 実装した機能についてまとめる
    - 対応する課題チケットのリンクを添付する
- 主要変更箇所
    - 修正に伴う影響範囲をチェックリストで記載する
- 留意事項
    - 必要であれば、レビュワーに特に確認をお願いしたい部分や伝えておくべき情報を書く

### Linter

コードレビューに直接的に関係ありませんが、チーム内で共通のLinterを設定してフォーマットを統一することで、手軽にコーディングスタイルが統一でき、それに伴い可読性が上がります。

# 参考

- [デキるプログラマだけが知っているコードレビュー7つの秘訣](https://www.virtual-surfer.com/entry/how-to-review-for-web-engineers)
- [Google エンジニアリング・プラクティス ドキュメント](https://shuuji3.xyz/eng-practices/)
- [コードの健全性: 礼儀正しいレビュー == 役立つレビュー](https://developers-jp.googleblog.com/2019/12/respectful-reviews.html)
 - [トレタのコードレビューへの取組 - トレタ開発者ブログ](https://tech.toreta.in/entry/2020/02/10/163000)
- [リファクタリングチームに入ってから学んだ理解しやすいコードを書くための基本的なこと](https://engineer.crowdworks.jp/entry/2020/03/10/180847)
Githubコマンド　一覧

# githubコマンド一覧
Qiitaの練習と、自分用メモを兼ねてgithubコマンド一覧を作成

- `git init` 　カレントディレクトリをGitで管理できるようになる
- `git status`　ワークツリーとインデックスの現在の状態を確認
- `git add`　ファイルをインデックスに追加
- `git commit`　インデックスに登録されたのをローカルリポジトリにコミット。`-m`をつけることで一文のメッセージを付けれる。何もなしだと文章
- `git diff`　現在のインデックスとワークツリーの差分確認
- `git log`　コミットの履歴確認
- `git reset [識別番号]`　前に戻す　`git reset HEAD^`で1つ前に。
- `git push origin [branchname]` リモートリポジトリへ反映
- `git branch [name]`　[name]にブランチの名前を指定してブランチを作成（何も指定しないとブランチの一覧を表示できる。*←これが左についているところが現在のブランチ
- `git checkout [name]`　　[name]にブランチの名前を指定することでブランチを切り替えられる。


### ブランチ
履歴を分岐して記録できるようになる。そうすることで他のブランチの影響を受けないので、同時に複数の変更を進められる。
vue.jsとmoment.jsを使って、TODOに日付を表示する

# vue.jsとmoment.jsを使って、TODOに日付を表示する

TODOリストに日付を追加する方法が分からなかったので、メモ。

## moment.js導入手順
```bash

$ yarn add moment
```
で、vuecliのプロジェクトにmoment.jsをインストールします。

```javascript

import moment from 'moment';
```
で、インストールしたmoment.jsを読み込みます。

## TODOに日付を表示する
下記のように、TODOを追加するシンプルなコードを書きます。


```vuejs

<template>
  <div id="app">
    <h2>todos</h2>
    <p>
      <input v-model="newtodo" v-on:keyup.enter="addtodo" />
    </p>
    <div v-for="todo in todos" :key="todo.id">
      <p>
        <span class="todo">{{ todo }}</span>
      </p>
    </div>
  </div>
</template>

<script>
import moment from 'moment';
export default {

  data() {
    return {
      todos: [],
      newtodo: '',
    };
  },
  methods: {
    addtodo() {
      if (!this.newtodo) {
        return;
      }
      this.todos.push(this.newtodo);
      this.newtodo = '';
    },
  },
};
</script>

```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499375/a63acc10-53e2-efd7-6f73-939853074f8b.png)


addtodoメソッドで、TODOと現在の時刻を取得して、todos[]にpushします。

```javascript

    addtodo() {
      if (!this.newtodo) {
        return;
      }
      const params = {
        text: this.newtodo,
        created_at: new Date(),
      };
      this.todos.push(params);
      this.newtodo = '';
    },
```
`parmas`に、入力したtodoと、created_atには、new Date()で、現在の日付を代入したもの を代入します。
`this.todos.push`で、配列todos[]に`params`の値をpushします。

とすることにより、テンプレート側で{{todo}}で参照できます。

```vuejs

 <div v-for="todo in todos" :key="todo.id">
      <p>
        <span class="todo">{{ todo }}</span>
      </p>
    </div>
```
参照した結果がこちらです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499375/01a1522a-d8d8-9dd9-f6e8-3a68f3139ce3.png)

{{todo.text}}とすれば todosの中のtextが取れるし、{{todo.created_at}}とすれば日付が取れます。

これだけだと、moment.jsの出番がないので、活用します。

```javascript

export default {
  filters: {
    moment: function(date) {
      console.log(date);
      return moment(date).format('YYYY/MM/DD HH:mm');
    },
  },
```
で、momentというフィルターを作成します。文字列をDate関数よりも簡単に扱えるmoment関数に変換するものです。

テンプレート上で、`{{ todo.created_at | moment }}`とすることによって、momentのフィルターを通しました。
`moment(date).format('YYYY/MM/DD HH:mm');`の部分で、YYYY/MM/DD HH:mmの形式に変換することができました。
変換した結果が下記になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499375/781cd105-91f3-db7a-a77f-f9949d3423db.png)

使い方忘れそうなのでメモしました。
MinGWを変更する方法

###きっかけ
MinGWでは対応できないプログラムがでてきた
###プログラム
```C++
void sleep(double sec)
{
    int msec=sec*1000;
    std::this_thread::sleep_for(std::chrono::milliseconds(msec));
}
```
###エラー
```
sleep.cpp: In function 'void sleep(double)':
sleep.cpp:28:10: error: 'std::this_thread' has not been declared
     std::this_thread::sleep_for(std::chrono::milliseconds(msec));
          ^~~~~~~~~~~
```
###原因
なんでこれが出てくるのか迷ったのでエラー内容をググってみた。
すると、原因は使っているコンパイラにあるみたいだった。
http://www.mingw.org/
このMinGWというもの。
このコンパイラでは対応できないみたいだそう。。。
###よし、変更しよう
どうやら、TDM-GCCならできるそう。
https://jmeubank.github.io/tdm-gcc/
インストールしてみた。
###さて、実行
それでまた実行するとまた同じエラーがでてしまった。
心折れそう、、、(´;ω;｀)
それでまたググりました！
###またまた、原因
環境変数をいじらなきゃいけないみたいです。
①エクスプローラーを開く
![エクスプローラー 2020_05_22 22_47_39_LI.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642188/df8113c5-c95c-f938-4a0b-c9eea4cbe970.png)
②PCを右クリック→プロパティ
③システムの詳細設定をクリック

![システム 2020_05_22 22_52_49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642188/d1d5fd6e-e1f4-e2a1-5e2b-794ac8bce48e.png)
④下の方にある環境変数...をクリック
![システムのプロパティ 2020_05_22 22_54_35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642188/4d2bd415-8aa8-2311-084a-87400252951b.png)
⑤システム環境変数のところにあるPATHをダブルクリック
上の欄じゃなくて下です。
![システムのプロパティ 2020_05_22 22_56_19_LI.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642188/1fc51125-3f31-e5de-b3b2-f8d083079fa6.png)
⑥**C:TDM-GCC-64\bin**が下の方にあったので一番上まで上へボタンを押しまくってあげました。
![システムのプロパティ 2020_05_22 23_02_36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642188/d51f454b-cf4a-5a01-28e5-4bdbb334bafb.png)
**これで設定は完了！**あとはパソコンを再起動します。
###解決！
私の場合これで解決しました。まだまだ勉強不足ですからこれからもがんばっていきます。
###最後までお読みいただきありがとうございました。
ボタンを押した時に処理を実行させたい時

今回は投稿内容を編集し、編集完了ボタンを押したらdbの投稿内容を書き換える（更新する）というもの

if文で条件を指定してからデータベースへアクセスし書き換えるという流れ

<?php
/**　post_rewriteはinputタグのname属性**/

if(isset($_POST['post_rewrite'])){
  $statement = $db->prepare('UPDATE posts SET message=? WHERE id=?');
  $statement->execute(array($_SESSION['message'],$_SESSION['posts_id']));
?>

HTML文（ボタンの部分のみ）
<input class="buton submit" type="submit" name="post_rewrite" value="修正完了する">


これで修正完了するボタンを押すとphpが処理される
Azure AppServiceにSSHでログインてvenvを有効にする方法

これが最適なやり方かわかりませんが、うまくいきました。

```console
# PYTHON_VERSION=$(python -c "import sys; print(str(sys.version_info.major) + '.'+ str(sys.version_info.minor))")
# export PYTHONPATH=$PYTHONPATH:"/antenv/lib/python$PYTHON_VERSION/site-packages"
```

これではうまくいかなかった。

```console
# source /antenv/bin/activate
```
初心者の単語No4（Javaコマンド、JVM）

**フィールド**
・クラスで宣言した変数名
・レコードを抗セする単位。
（その他の意味 分野・領域など）

#javaコマンド
Javaアプリを起動するコマンド。
（Javaプログラムを実行する）
##コマンドのオプション
| オプション | 概要 |
|---------|-----|
| -classpath | 関連するclassファイルの検索先 |
| --module-path | モジュールの検索先 |
| -jar | jarファイルを実行 |
| -version | Javaバージョンを表示 |

**例：Test.jarを実行する例。パラメーターとして「太郎」を設定。**
> ＞ java -jar Test.jar **"太郎"**

※その他コマンド系は、またそのうち纏めて記述します。

##JVM(Java Vitual Machine)
Javaのプログラムを動かすためのソフトウエア。
その他の言い方として、「Java仮想マシン」「JavaVM」

Ｊａｖａは、どのマシンでもJavaが動作することを思想として作られた言語。

###JVMの仕組み
①Javaプログラム⇒②JVM⇒③OS
①を解釈し、③のＯＳで実行可能な形式のコードに変換して動作させる。
②のJVMはJavaで作ったプログラムをプラットフォームに依存しないで動かすために必須ということ。

①から②の際にテキストコードをバイナリコード(マシン語)に変換
②から③の際にバイナリコードを読み込んでネイティブコードに変換

###JVMの構成
大まかに３つに分けた領域が存在する。
1.Ｎew領域
2.Old領域
3.Permanent領域
がある。
1から2の領域ではヒープ。
３の領域では非ヒープ領域。

####ヒープ
OSやアプリケーションなどのシステムが利用するメモリ領域のこと。
※JVMのヒープ領域はオプションで自由に設定を変更可能。

１．New領域
⇒更に３つの領域に分類される。
⇒オブジェクトがインスタンス化された際にEden領域に配置
⇒Edenのメモリがいっぱいになると、オブジェクト退避のためにFrom領域とTo領域に格納。
２．Old領域
⇒New領域に格納されているオブジェクトで使用期間が長い情報が管理されている。
⇒OldがいっぱいになるとFullGCと呼ばれる処理が頻繁に起こる。
※FullGCは重い処理の為実行されている間はシステムが止まる。
３．Permanent領域
⇒クラスやメソッドなどの情報が格納。
【補足】
GCはガーベージコレクションの略。
⇒メモリ領域中の使用済みのメモリ領域を整理し、空き領域を作ること