OmniAICreator/Qiita-1.07M huggingface dataset:
【AndroidStudio】作成したアプリ（APK）をデバイスにデプロイするには？

開発に使用しているマシンが仮想デバイスに対応していないため、
自分の実機（スマホ）にデプロイしてテストするためのメモ。

---

1.  AndroidStudioメニュー ＞ ビルド ＞ 署名済みバンドル / APKの生成… をクリックする。

1.  「APK」を選択して「次へ」。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682053/c838c139-8488-9184-3ff3-c85362510007.png)

1.  キー保管パスを「新規作成」する。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682053/c13afd54-5e84-ad5f-7fe8-3dd3a6053baf.png)

1.  「新規キー・ストア」ダイアログにて、キー保管パスとキーそのものの2つを設定する。[^1]
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682053/0d92ba2d-494f-f11a-397a-26ea2536bbed.png)
    *  キー保管パス
        *  キー保管パス：デフォルトで %USERPROFILE% 配下にjksファイルを作るようになっている。任意のパスとjksファイル名を指定する。
        *  パスワード：キー保管パスのパスワードを指定する。
    *  キー
        *  エイリアス：キーを識別するための名前。
        *  パスワード：キーそのもののパスワードを指定する。
        *  有効期間（年）：デフォルトで25年。変更可能。
        *  証明書：必要に応じて情報を入力する。省略可能。デプロイするアプリに表示されるものではないが、APKの一部として証明書に含まれる。

    「OK」をクリックすると何やらエラーが出るが、
    今回は自分のデバイスにテストのためにデプロイすることが目的なのであまり深く考えない。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682053/68e3f4d1-9d0a-febf-3ed0-dcaba928b870.png)

1.  元のダイアログに戻って「次へ」。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682053/bb750c77-9df2-b0d5-14f8-37bbb3b2adb6.png)

1.  ビルド・バリアントは「release」を選択し、署名バージョンは（とりあえず）「V1」「V2」を両方選択して「完了」。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682053/9c752131-f37d-02de-6772-74c97c25d339.png)

1.  ビルドが完了したら、イベントログから locate をクリックする。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682053/804ef652-1876-bdeb-0f69-8143426cff55.png)

1.  ビルドしたAPKファイルの格納フォルダが展開するので、
    そのAPKファイルをGoogleドライブを介す等の方法で任意のデバイスにデプロイする。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682053/2ec32f37-da16-898e-f269-fde24e2494e6.png)

    ▼実際にAndroidスマホにデプロイ→インストールして起動した画面のスクリーンショット
    <img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682053/b55f11ee-5ef0-8832-0219-f8752abe31fa.png">

以上

---

[^1]: [アプリへの署名 | Androidデベロッパー](https://developer.android.com/studio/publish/app-signing?hl=ja#generate-key)
EC2インスタンスのストレージのボリュームサイズを変更する

社内でRedashのAMIを運用していたのですが、急に動かなくなってしまい、ボリュームサイズの変更が必要になりました。

![スクリーンショット_2020-09-02_10_00_29.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47882/173bd48f-f91d-f5ff-46ac-487f1d3f2f47.jpeg)

**/ is using 99.8% of 7.69GB**

げげ〜。

# ボリュームサイズの変更
ボリュームサイズの変更の手順は以下です。

- EBSボリュームのサイズを変更する
- EC2内のパーティションを物理のボリュームのサイズに合わせて再設定する

# EBSボリュームのサイズを変更する
EC2ダッシュボード > Elastic Block Store > ボリュームに移動し、サイズを変更したいEBSボリュームを選択してボリュームの変更をします。

今回は8GBを倍の16GBに変更します。

![スクリーンショット_2020-09-02_10_08_06.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47882/7f9dff18-0c17-4450-7397-b68ae61baee9.jpeg)


# EC2内のパーティションを物理のボリュームのサイズに合わせて再設定する

パーティションの変更の仕方は以下のドキュメントの「パーティションの拡張 (必要な場合)」に従います。実際これのとおりにやっただけです。

https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/recognize-expanded-volume-linux.html

ディスクとパーティショニングを`lsblk`コマンドで確認します。

```console
root@ip-XXX-XXX-XXX-XXX:~# lsblk
NAME        MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
nvme0n1     259:0    0   16G  0 disk 
└─nvme0n1p1 259:1    0    8G  0 part /
```

この状態ではディスクは16Gあるのに、8Gしか割り当てられておらず、8G余っています。

これを`growport`コマンドでパーティションに割り当てます。

```console
root@ip-XXX-XXX-XXX-XXX:~# growpart /dev/nvme0n1 1
CHANGED: partition=1 start=2048 old: size=16775135 end=16777183 new: size=33552351,end=33554399
```

`/dev/nvme0n1`がデバイス名で`1`がパーティション番号です。

これでボリュームサイズの変更を反映することが出来ます。

# トラブルシューティング
実際には`growpart`コマンドを実行した際に

```
root@ip-XXX-XXX-XXX-XXX:~# growpart /dev/nvme0n1 1
mkdir: cannot create directory ‘/tmp/growpart.1729’: No space left on device
FAILED: failed to make temp dir
```

というエラーが出ました。あまりにも容量が足りなすぎてコマンドの実行が出来ないようです。
なんとかしてコマンドを実行するのに必要な最低限のスペースを空けないといけないので、`/var/log`以下のファイルを削除して、なんとかなりました。
enumerate関数について（python）

#１.はじめに
こんにちは！！今回はpythonのenumerate関数について記事を書きたいと思います。
enumerate関数を使用すると、forループの中でリストやタプルの要素と順番を取得できます。要するにリストやタプルの中身とその順番の番号を返してくれるという関数になっています。
enumerate関数を使用するとコードを簡略化でき、直感的に理解できるかと思います。
それでは、簡単な問題をenumerate関数を扱う場合と扱わない場合で解いてみようと思います。
#２.問題
研究室で定期発表会があります。発表の順番はこの用意されている名簿（配列）の順に行きたいと思います。ですがこの名簿には順番が書かれていないので直感的にわかりません。なので名前と発表の順番を出力してください。

このような問題を解いてみましょう。
#3.enumerate関数を扱わない場合
enumerate関数を扱わない場合はこのようなコードになります。

```enumerate.py
publicator = ["haruto","sota","minato","yuto","riku","mei"]
num = len(publicator)

for i in range(num):
    print(i+1,publicator[i])
```
```out
1 haruto
2 sota
3 minato
4 yuto
5 riku
6 mei
```
len関数を扱い配列の数を取得して、forループをしています。
#4.enumerate関数を扱う場合
では続いて本題のenumerate関数を扱う場合、このようなコードになります。

```enumerate.py
publicator = ["haruto","sota","minato","yuto","riku","mei"]

for i,pub in enumerate(publicator,1):
    print(i,pub)
```
```
1 haruto
2 sota
3 minato
4 yuto
5 riku
6 mei
```
変数を二つ使用しなくてよくて、enumerate関数を扱った場合のほうがコードの簡易的なのではないかなと思います。
ちなみにenumerate(publicator,1)の部分は配列publicatorの順番の番号を１からスタートという意味なので、i+1などにしなくて済むので便利な関数です。
#5最後に
enumerate関数はforループの中で扱い、リストやタプルの要素と順番の番号を返してくれる関数でした。
コードを書いていると意外と便利に扱えます。

Qiita二回目の投稿で、今までブログなどの情報発信をしたことがないためわかりにくい文章になっているかもしれません。
これから、情報発信をしていき文章力をつけていきたいと思います、また技術で遊べる人間になるのが僕の夢なので温かい目で見守っててください。
これから、よろしくお願いします。
それでは！
JSONとは(JavaScriptとJSONの違い)

JSONって結局なんなんだ？っと思っていろいろ調べたのでまとめる

#JSONとは
* JSONはJavaScriptオブジェクトの表記法をベースにした"**データフォーマット**"
* JSON自体は文字列でもオブジェクトでもなく、ただの”データフォーマット”
* JavaScript言語の元に、JS形式のオブジェクト(JSオブジェクト)、JS形式の文字列(JS文字列)などが存在するのと同様に、
JSONというデータ定義言語の元に、JSON形式のオブジェクト(**JSONオブジェクト**)、JSON形式の文字列(**JSON文字列**)が存在する

以下でJSONオブジェクト、JSON文字列、それらへの変換方法を記述する。

##JSONオブジェクト
* キー(プロパティ名)はダブルクォートで囲んだ文字列でないといけない
* オブジェクトの末尾にカンマ置いてはいけない

```javascript
// ***JSONオブジェクト***
let JSON_Object = {
    "place": "Osaka",
    "number": 2
}
console.log(JSON_Object.place); //JSオブジェクト同様キーを指定して値を参照できる

// ***JSオブジェクト***
let JS_Object = {
    place: "Osaka",
    number: 2, //←末尾カンマはつけてもOK
}
```
##JSON文字列
* 定義的にはJS文字列と同じ
* 一般的にJSONオブジェクトを文字列にしたものを指すことが多い
* 文字列なのでキーを指定して値を参照できない

```javascript
// ***JSON文字列***
let JSON_Str = '{"place": "Osaka","number": 2}'
console.log(JSON_Str.place); //errになる　→　キーを指定して値を参照できない
```

##JSON.stringify()
JavaScript のオブジェクトや値をJSON文字列に変換するメソッド
JSオブジェクトに関してはJSONオブジェクトの文字列に変換される

```javascript
// ***JSオブジェクトを変換**
let JS_Object = {
    place: "Osaka",
    number: 2,
}
console.log(JSON.stringify(JSON_Object));
//出力  :  {"place":"Osaka","number":2}


// *** JSリスト,JS数値を変換
console.log(JSON.stringify([1, 2, 3]));
// 出力  :  "[1,2,3]"
console.log(JSON.stringify(1000));
// 出力  :  "1000"

```






##JSON.parse()
文字列をJSONとして解析してJavaScriptのオブジェクトや値に変換するメソッド
JSON.stringify()の逆

```javascript
console.log(JSON.parse('{"place": "Osaka","number": 2}'));
//出力　{ place: 'Osaka', number: 2 }
console.log(JSON.parse("[1,2,3]"));
// 出力　[ 1, 2, 3 ]
console.log(JSON.parse("1"));
// 出力　1
```

###参考リンク
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/JSON
Nuxt.jsの動的ルーティングでQiitaっぽい構成を作ってみるメモ


Qiitaと同様の構成を作ってみたメモです。

## 通常のNuxt.jsの動的ルーティング

こんな構成にすると

```
pages/
--| users/
-----| _id.vue
--| index.vue
```

`https://ドメイン/users/<ユーザー名>` みたいな構成を作ることが出来ます。

> https://ja.nuxtjs.org/guide/routing#%E5%8B%95%E7%9A%84%E3%81%AA%E3%83%AB%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0


このユーザー名の部分がURLにアクセスした際の値で動的に変わります。

## Qiitaっぽい構成って?

(2020年9月時点)Qiitaの記事は以下のような構成です。

```
https://ドメイン/<ユーザー名>/items/<記事ID>
```

例: `https://qiita.com/n0bisuke/items/ceaa09ef8898bee8369d`

先ほどの`ユーザー名`だけが動的な場合と違って、ネストされて`記事ID`も動的になっています。

これをNuxtで再現したいなという話です。

## こんなディレクトリ構成

参考記事などを見ながら触ってたらこんな構成でうまく行きました。

```
pages/
--| _userid/
-----| items
--------| _itemid.vue
-----| index.vue
--| index.vue
```

末端となる記事ページは`/pages/_userid/items/_itemid.vue`になります。

> ![スクリーンショット 2020-09-02 9.42.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/439d45e0-0b9b-cbe1-c556-d4e67df2fc69.png "スクリーンショット 2020-09-02 9.42.33.png")

出来てみるとそんなもんかという感じですね。

### 記事ページのコード

メモ程度です。

```_itemid.vue
<template>
  <section class="section">
    {{userid}}のitem:{{itemid}}
  </section>
</template>

<script>

export default {
  name: 'item',

  data(){
    return{}
  },

  computed: {},
  mounted(){},
  methods: {},
  
  async asyncData({ $content, params }) {
    const userid = params.userid;
    const itemid = params.itemid;
    return {userid, itemid};
  },
}
</script>
```

## 参考

> https://qiita.com/notsunohito/items/46bc9c6ad88fed46ea14
自社開発のWebエンジニアに伝え続ける3箇条

# 概要

Webエンジニアの業務では、SEの業務領域である要件定義や設計、時にはマーケティングや予算管理等のスキルが求められることもあります。
特に自社開発となると、営業やマーケターといった非エンジニアとコミュニケーションを取りながら、システムの設計や実装を進めるケースが多いでしょう。

その際、新米Webエンジニアへ繰り返し伝えることが特に多い3つの紹介です。
組織や社風にもよるので一概にどんな環境でも共通するものではありませんが、参考までに。
（どちらかというと社内向けの備忘の側面が強いです）

# 1. 言われた通り作らない

結果的に、言われた通りのものを作ることはもちろんあります。
が、最初から言われるがままに実装するのは避けるべきです。

システムはあくまでも目的を果たすための手段に過ぎません。
依頼者が考える目的と解決策が、エンジニア視点だと異なることも多くあります。
そもそものやり方を変えたり既存ツールで解決できたり、全く別のアプローチを取ることで、提案された解決策以上の効果を生むこともあります。

エンジニアはシステムを作るプロフェッショナルですので、システム設計や技術領域を知っていないと出てこない解決策を考えついてこそプロフェッショナル足り得ます。

もしこれを考えず、言われたものだけ作っていた場合、思考停止に陥りクリエイティブな発想力が身に付きませんし、当初の想定以上の価値は生まれません。
つまり期待未満か期待通りのアウトプットしか期待できなくなります。

# 2. これってできますか？にYes/Noだけで答えない

これってできますか？
は単純にcan?cannot?の質問ではなく、「できるならその対応をお願いします」の前フリ質問であることが多いです。
そのため、簡単に「できる」と答えると代替案を考えるまでもなく、本来手段であるはずのシステムが固定化されて、実行に移る可能性があります。

1の「言われた通りに作らない」に通ずるところがあるのですが、必ず「なぜその質問をするのか？何を成し遂げたいのか？」目的を確認した上で、目的を達成するためのアプローチを選択するステップを踏みましょう。

エンジニアと非エンジニアにおける言葉のすれ違いはよく起きるので、以下togetterが結構面白いです。

[「技術者の表現 と 非技術者の解釈」言葉のすれ違い問題](https://togetter.com/li/1362165)

# 3. 期日と要件の決まっている案件に対し、思考停止で無茶をしてでも間に合わせようとしない

「いつまでにこれを作る」というissueに対して、責任感が強いがゆえに、残業してでも間に合わせようと限界以上の働きをしてしまうことがあります。
こういう事態は往々にしてQCDSのバランスが崩壊していることが多いです。
そういった事態は関係者内でQCDSという概念が知られていない、あるいは意識できていないために起きます。

* Quality(品質)
* Cost(コスト)
* Delivery(納期)
* Scope(範囲)
    * ※ SはServiceだったりFだったりもする

QCDSはトレードオフの関係にあります。
「最高品質のものをコストを全くかけず、最速で全部やる」＝QCDS全てMax
というのは夢物語です。
高品質と短納期であればその分コストは増します。

例えば

* 郵便で速達を頼むとQualityは維持したままDeliveryを短くするので、Cost(速達料金)が増します。
* ファストフードはCostを抑えて提供スピード(Delivery)も抑えるので、時間をかけてゆっくり作る高級レストランよりQualityは落ちます。

つまり

* 不具合を軽微に抑える「高いQuality」
* 期日をしっかり切った「厳密なDelivery」
* 要件を全て満たす、「広範囲のScope」

と、最初からQCDSのうち3つが固定された案件は必然的にCostしか可変要素がなく、結果として人員追加投下や残業でカバーせざるを得なくなります。
あるいはそのCostをMax投下したとしても間に合わず、

* 重大な不具合を起こすQualityの低下
* 期日が守れないDeliveryの未達
* 必要な機能が揃わないScopeの未達
にも繋がることがあります。

そのためにはQCDSの概念をエンジニアだけでなく関係者全員が理解しておくこと、理解した上で無闇にDeliveryを固定しないことを浸透させていく必要があります。
【AndroidStudio】ボタンのキャプション設定方法その1

ボタンを配置するとキャプションの初期値として「Button」がセットされるが、
「ハードコーディングはよくないから、@stringリソース＝strings.xmlを使いなさい（意訳）」と促される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682053/bab02fb5-ca98-72c9-9bf1-a605e1985844.png)

activity_main.xmlコード上で該当箇所にカーソルをあてると黄色い :bulb: が表示される。
その黄色い :bulb: をクリックして、「文字列リソースの抽出」をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682053/55e14aa4-44f3-6b3a-d070-f7e96933d94b.png)

すると「リソースの抽出」ダイアログが出るので、任意の値を記述する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682053/85f12956-2240-409f-a7ff-f926c1ddbef9.png)

*  リソース名：strings.xmlの中で、画面に配置したコントロールを識別するための文字列。サンプルではidと合わせている。
*  リソース値：キャプションとして表示する文字列。
*  ソース・セット：「main」「debug」「releace」から選択する。とりあえず「main」のまま。
*  ファイル名：「colors.xml」「strings.xml」「styles.xml」から選択する。キャプションは文字列なので「strings.xml」のまま。
*  ディレクトリーにリソースを作成：とりあえずそのまま。

「OK」をクリックするとactivity_main.xmlの :point_left: 箇所が `"Button"` から `"@string/myButton"` に変更される。

```activity_main.xml
    <Button
        android:id="@+id/myButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="onClickMyButton"
        android:text="@string/myButton" 👈
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
```

strings.xmlは app ＞ res ＞ values 配下にある。
ここまでで設定した内容が :point_left: 箇所に記述されている。

```strings.xml
<resources>
    <string name="app_name">sandbox</string>
    <string name="myButton">テスト</string> 👈
</resources>
```

ボタンのキャプションが「テスト」になる。
<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682053/d80fc1f4-a3c5-b5fa-3bd5-b67c9bf95bae.png">

:arrow_right: [設定方法その2](https://qiita.com/Yuko809/items/daa61d70d3001417bc54)

以上
CodeSandboxでnuxtとvuetifyを使いたい時の間違いと解決策

# CodeSandbox使ってますか？

みなさんはCodeSandboxを利用したことがありますか？

Nuxt.jsやVue.jsを学習していて、軽く試してみたいと考えてる方には、超おすすめです。

環境構築から動作確認までをブラウザ上で簡単に実施できます。

今回はそんなCodeSandboxでVuetifyを使いたい時のよくある間違いを紹介いたします。

# vuetifyではなく@nuxtjs/vuetifyです

nuxt.jsにvuetifyの機能を追加する場合には、Dependenciesの項目にあるAdd dependencyを利用します。

このAdd dependencyで検索するときに要注意です。

皆さんが普段のプロジェクトで利用しているVuetifyは、『@nuxt.js/vuetify』です。

vuetifyと検索してしまうと、普段使い慣れていない『vuetify』が出てきます。

そちらをインストールしましょう。

# moduleに追加していますか？

インストールが完了しましたら、nuxt.config.jsのmodulesに

    "@nuxt.js/vuetify"

を追加しましょう。

@nuxt.js/vuetifyをインストールしたのにエラーが出てしまうのはこちらが原因です。

# v-app忘れていませんか？

v-appはVeutifyを使うために必須の要素です。

v-appで囲まないでVuetifyのコンポーネントを使うと予期しない動作や表示になってしまいます。

エラーは出ないけど上手く動かないというのは、こちらが原因の可能性があります。

# Forkしていただければすぐに使えます。

https://codesandbox.io/s/nuxt-default-project-ee5xr?file=/pages/index.vue

上記CodeSandboxへのリンクです。

フォークしていただければ、自分のプロジェクトとして進められます。

# ※WPに記事移行しています。

Nuxt.jsに興味がある方はぜひ覗いていってください。

https://moneyhack.tech/codesandbox-01/
iOS 14 の問題と対策

iOS 14 でアプリを動かした時の問題と対策

#問題
1.Navigation Bar の色が変わる

#対策
###1.Navigation Bar の色が変わる
通常、Navigation Bar の背景色を変えるには、Bar Tint を指定します。
しかし、iOS14 beta6 ではなぜか透過色になってしまうようです。

対策としては、Backgroud に背景色を指定することで回避できるようです。

iOS14 beta 6 での現象で、beta4 の時点では正しく表示されてました。
よくある一時的なバグで、次のバージョンでは何事もなかったように直っていれば良いのですが・・・
>iOS13.0でも似たような問題があり、iOS13.1でなおっていたようで・・・
>https://developer.apple.com/forums/thread/121753
JavaScript学習ロードマップ


JavaScript苦手・・という状況からJavaScript好きになれるロードマップ（多分）

全編ほぼ動画なので、とっても見やすい。挫折しづらい。

全体的な流れとしては、動画見る ▶︎ コードを書いて学習の流れです

個人的に好きなエンジニア系Youtuberのお二人の動画がメインになります

- [Yahoo!出身のエンジニア しまぶーのIT大学さん](https://www.youtube.com/channel/UCti6dG0zSAetLGGYcgNML4Q)

- [Web万屋エンジニアチャンネルさん](https://www.youtube.com/channel/UCHxqQ8bUg5F2GW79D_DvSjQ)

## LEVEL ☆ JavaScriptってなに？

そもそもJavaScriptって何？フロントエンドって何してるの？ってレベルを解消

![eb3d67a527485b507775ddfba139d4c0.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335670/0646bbcf-7114-7a2e-ea4a-7e0e036ae29b.jpeg)


- [フロントエンド基礎編](https://www.youtube.com/playlist?list=PLpYVzO5BZomp-4e2LYTDePd3fzXs9CQhU) / 約40分

## LEVEL ★ JavaScript入門編

> JavaScriptをマスターするならHTMLを知っておかないかん by 弊社マネージャー

![cc44a8739dd85da75bdedc971d9dba02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335670/53c0a471-431c-eaad-3d32-8734d91e065d.jpeg)

HTMLの基礎から、JavaScriptの全体像を学習できます。

- [HTML入門編](https://www.youtube.com/playlist?list=PLpYVzO5BZomr5xMUR9LJ2oo82yIQAy695) / 約43分

- [JavaScript入門編](https://www.youtube.com/playlist?list=PLpYVzO5BZomqbLjRiHo7VvVYotX9QoQ0N) / 約3時間8分

## LEVEL ★★ モダンなJavaScriptってなに？

JavaScriptは定期的にアップデートされ、新しい機能が追加されています

特に2015年に大幅なアップデートがあり、2015年以降（ES2015〜）がモダンなJavaScriptと言われています（多分）

基礎を学習してからモダンなJavaScriptを学習すると「なぜそうなったのか」が分かるので、より理解が深まると思います。

- [モダンJavaScript入門編](https://www.youtube.com/playlist?list=PLpYVzO5BZomrLfNDHVPi-oFcdDikWjq7u)  / 約2時間47分

## LEVEL ★★★ もっとJavaScript

JavaScriptの全体像を掴んだところで、みんな大好きJavaScript Primerにトライしましょう

RailsチュートリアルのJavaScriptバージョンと思って頂いてOKです。

結構ボリューミーな内容なので、しっかり腰を据えて取り組みましょう

- [JavaScript Primer](https://jsprimer.net/intro/)

コールバック関数、非同期処理、Promise、async/awaitに詰まったら以下の再生リストがオススメです（絶対詰まる）

- [JavaScript中級編](https://www.youtube.com/playlist?list=PLpYVzO5BZomrLVHyyxzhWfFMojrWesMy3)

## LEVEL ★★★★ もっともっとJavaScript

ここまできたら、モダンなJavaScriptライブラリである[React](https://ja.reactjs.org/)や[Vue.js](https://jp.vuejs.org/index.html)を触ってみるのも面白いかもしれません

Reactを学ぶならオライリーの新書ハンズオンラーニングがおすすめです。


https://www.amazon.co.jp/React%E3%83%8F%E3%83%B3%E3%82%BA%E3%82%AA%E3%83%B3%E3%83%A9%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0-%E7%AC%AC2%E7%89%88-%E2%80%95Web%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E9%96%8B%E7%99%BA%E3%81%AE%E3%83%99%E3%82%B9%E3%83%88%E3%83%97%E3%83%A9%E3%82%AF%E3%83%86%E3%82%A3%E3%82%B9-Alex-Banks/dp/4873119383/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=3TJDSUA1VI4CH&keywords=React+%E3%83%8F%E3%83%B3%E3%82%BA%E3%82%AA%E3%83%B3&qid=1644967710&sprefix=react+%E3%83%8F%E3%83%B3%E3%82%BA%E3%82%AA%E3%83%B3%2Caps%2C182&sr=8-1

https://qiita.com/yukiji/items/c72445e760ee9e59788f

フロントエンドでトレンドな[TypeScript](https://www.typescriptlang.org/)を学習するなら[TypeScript学習ロードマップ](https://qiita.com/irico/items/33744e15a4e0ca52d6bc)がオススメです

## おまけ

JavaScriptの最新情報はJser.infoで追っていきましょう

- [Jser.info](https://jser.info/)

JavaScriptの豆知識をまとめた再生リスト

- [JavaScript Tips](https://www.youtube.com/playlist?list=PLpYVzO5BZomrQ01XInJUoulv5CXGx_7AV)
[rails devise]ログインしていないユーザーをログインページへ遷移する方法

前提　今回はitemsコントローラーでの操作にする。

```
class ItemsController < ApplicationController
  before_action :move_to_signed_in, except: [:index]
  def index
    # トップページ生成
  end

private
  def move_to_signed_in
    unless user_signed_in?
      #サインインしていないユーザーはログインページが表示される
      redirect_to  '/users/sign_in'
    end
  end
```

#before_actionの使い方
```
before_action :move_to_signed_in, except: [:index]
```
before_action→コントローラで定義されたアクションが実行される前に、指定した共通の処理を行うことができるメソッドのこと。
except: [:index]→indexアクションは除く
・indexアクションを除き他のアクションが実行された時move_to_signed_inの処理を行う。つまりトップページが表示されているときはmove_to_signed_inの処理は実行されない

#move_to_signed_inの実行内容
```
def move_to_signed_in
    unless user_signed_in?
      #サインインしていないユーザーはログインページが表示される
      redirect_to  '/users/sign_in'
    end
```
user_signed_in?→ユーザーがログインしているかどうか判別する
unless→「もし～でないならば」
unless user_signed_in?→もしユーザーがログインしていないのなら
redirect_to  '/users/sign_in'→ログインページに画面遷移する

#まとめ
indexアクション以外のアクション（createなど）をユーザーが実行しようとしたら
ログインしているユーザーかどうか判別する。
ユーザーがログインしていなかったらログインページ（/users/sign_in）に画面遷移する
ログインできていたらユーザーが指定したアクションが実行できる
急に sublime text 3 の SFTP が効かなくなった

sublime text 3 ではプラグインを入れることで SFTP/FTP 接続ができるようになります。
参考→https://hyp.llc/tips/sublimetext-3-sftp/

ところが先日突然これが動かなくなりました。
エラーが出るわけでもなく、ただただ動きません。
アップデートかなとも思いましたがどうやら最新の状態らしいです。

どうしたものかと思い、一度ウィンドウを閉じ、いろいろ調べてから再度開きなおしたらなんと普通に動きました。

エンジニアとして仕事を進めているうちに、何か不具合がでたらエラーを見るということに慣れすぎていて、再起動するという超初歩的な解決方法を忘れていました。
Pythonのデフォルト引数の挙動

Pythonのデフォルト引数は<b>メソッド実行時ではなくプログラム起動時に評価される</b>
これまで使っていたRubyやScalaでの挙動が普通だと思っていたので、何がおかしいのかわからずにかなりハマった


### Ruby

```ruby
def test(t=Time.now)
  puts(t)
end

test
sleep(10)
test
```

実行結果

```
2020-09-02 09:05:42 +0900
2020-09-02 09:05:52 +0900
```

### Scala

```scala
object Test {
  def test(t: DateTime = DateTime.now()): Unit = {
    println(t)
  }
  
  def run(): Unit = {
    test()
    Thread.sleep(10000)
    test()
  }
}
```

```
2020-09-02T09:14:08.681+09:00
2020-09-02T09:14:18.732+09:00
```

### Python

```python
import datetime
import time

def test(t=datetime.datetime.now()):
    print(t)

test()
time.sleep(10)
test()
```

```
2020-09-02 09:20:40.970098
2020-09-02 09:20:40.970098
```

他の言語はどうなんだろう
Blender 2.90でモディファイアの適用ボタンが見つからない件

blender2.9にバージョンアップしてみたらモディファイアタブの適用ボタンがみつからない。
![モディファイア2.9.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682050/117ceb0c-b422-00c5-356a-7fa8f6871884.png)


2.83ではここにあったのが↓
![モディファイア2.8.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682050/f187b4be-5096-8ebb-de62-13da77cf48d7.png)

2.90ではなくなってる↓
![モディファイア2.91.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682050/2405abde-4a43-ad73-58a5-f25f92b576a1.png)



探した結果、ココにありました↓カメラマークなどがある横の小さい矢印を押すと出てきます。
![モディファイア2.92.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682050/7af1adf8-6e2a-3a33-5eb5-9d692b5d1ec3.png)
MapKitで指定の場所を表示する

mapViewで好きな場所を指定できるようにします。

<img width="380px" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276894/a2d7f21b-d4e1-96d7-163c-acdf0d5253b9.png">

表示させたいロケーションを指定する。

```swift
// latitude 緯度 / longitude 経度
let initialLocation = CLLocation(latitude: 21.282778, longitude: -157.829444)//
```
Google Mapにピンを打てば緯度経度は取得できます。

<img width="380px" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276894/0eb662f1-9b9d-fa11-5e19-e199928dcb05.png">

ロケーションを中心とした、表示領域を設定します。
extensionを使うと便利です。


```swift
private extension MKMapView {
    // ロケーションの中心から東西南北1000メートルの領域を表示。
    func centerToLocation(
        _ location: CLLocation,
        regionRadius: CLLocationDistance = 1000
    ) {
        let coordinateRegion = MKCoordinateRegion(
            center: location.coordinate,
            latitudinalMeters: regionRadius,
            longitudinalMeters: regionRadius)
        setRegion(coordinateRegion, animated: true)
    }
}
// Region 領域
```

```swift:呼び出し元
override func viewDidLoad() {
    mapView.centerToLocation(initialLocation)
}
```

## 参考
[MKCoordinateRegion | Apple Developer Documentation](https://developer.apple.com/documentation/mapkit/mkcoordinateregion)

[init(center:latitudinalMeters:longitudinalMeters:) | Apple Developer Documentation](https://developer.apple.com/documentation/mapkit/mkcoordinateregion/1452245-init)
【GCP・AWS】データ分析がささりそうな顧客へのセールスシナリオを考えてみた

ターゲット
・データ分析に興味がある。
・BigQueryはつかってみたい。
・でもやり方がわからない。

1.データ分析をやってみよう
・データ分析をやってみたいけど、専門家もいないし、何から始めていいかわからない。
・まずはどんな結果がほしいかを考えましょう。
・過去のデータを利用して分析しみましょう。
・まずはじめるときの構成図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/3d5350a5-5bf9-b28b-2ce5-031f6b5ef1f3.png)
※「データを格納→BigQuery→Looker」が最も簡単な流れになります。
・Lookerにだすと視覚化が簡単にできます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/7a8e3118-a5ef-8d70-a442-c83086c504a1.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/0e9a4e76-388a-07b1-cf16-4224fb74d124.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/e2c44b78-328d-3524-567d-34470ebcbae8.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/979ddf9f-c2f9-c4bd-0b35-a7062d0e1f06.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/025f8bd0-fff2-e464-614a-3bbd5c2a7fc5.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/4781fec7-89af-2fa4-c43b-749aaf6e7125.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/a73a8784-111d-1de7-fd97-3cec9ec29c93.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/7aa88fd3-b51a-ffe9-769d-c362d6ec4c5c.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/c21788a6-98ed-b537-f4e5-fd75dbee1471.png)


2.データ分析のループを作ろう
・データ分析はループさせる必要があります。
・分析結果がビジネスに活かせるかは常にチェックが必要です。
・ループのやり方はこんな感じです
・でも、データ分析を定着させるといってもいろいろ大変。
（データの取得とか大変そう、データがいろんなところにあるなど）
・GCPではそれらを解決する手段もあります
 - サイロ化したデータを集約できる
 - 分析基盤を作ることでデータの自動収集も可能

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/403ebf29-6aa0-981f-2321-4145a698a9e1.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/72c628f1-2429-7e3a-303a-f63f0e596d09.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/d539374a-1366-9d1e-eccc-63cfddbe2a00.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/bb32de90-c568-413d-1fcc-d249ff5f5c92.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/e36074b4-29ff-cf36-ca87-77974031354c.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/3d4963a8-c9d5-520e-5a3c-f95151c837b8.png)

・ほかにも便利な機能があります。
（BigQuery MLなど）

3.データ分析をする風土づくり
・Google主催のイベントは多数開催されています
・勉強会
・大画面にLookerをうつす
・みんながさわってみる
・データ分析の認定資格
※※※こういうことをやってもまだまだデータ活用されない。それにかんする記事は以下に記載。
・「2020年のデータと〜」というガートナーの記事に「クラウドは必然、CDOが必要」とある。


4.事例紹介
・CloudNextDayなどの事例
・GoogleCloudの最新ポストの事例
・データ集約・可視化
・ログ解析
・オープンハウスの事例　https://cloud.google.com/blog/ja/topics/customers/openhouse-using-ai-platform-and-bigquery


5.まとめ？
・Lookerをつかうとだれでもデータをみやすくなります
　みんながデータに触る→データ分析の意識が高まる→データ分析によりDXを推進する
・業務効率化、データ分析事業の立ち上げのきっかけに。
forthで数9を4個つかって1から15までの数を表す式をつくる。

#概要

forthで練習問題やってみた。

#数9を4個つかって1から15までの数を表す式をつくる。


```
9 9 - 9 9 / . 1  ok

9 9 / 9 9 / + . 2  ok

9 9 + 9 + 9 / . 3  ok

9 9 9 + 9 / dup + . 4  ok

9 9 9 + 9 / dup + - . 5  ok

9 dup 9 + 9 + 9 / - . 6  ok

9 9 9 + 9 / - . 7  ok

9 9 9 drop 9 / - . 8  ok

9 9 - 9 * 9 . 9  ok

9 9 / 9 dup 9 / +  . 10  ok

9 9 9 + 9 / + . 11  ok

9 dup 9 9 + + 9 / + . 12  ok

9 9 9 + 9 / dup + + . 13  ok

9 dup 9 9 + 9 / dup + - + . 14  ok

9 dup dup 9 + 9 + 9 / - + . 15  ok

```

#こちらで実行確認


https://embed.plnkr.co/plunk/nWe24XGyjEHUUiVG


以上。
Vue.jsの学び方 (案)

# vue.jsの学び方

1. 公式ドキュメントで基本を学ぶ
2. 実際の物作る系の教材

まずは、ひたすら公式ドキュメントを追っていく。

- [はじめに — Vue.js](https://jp.vuejs.org/v2/guide/index.html)

公式ドキュメントと平行して、動画教材を使って動きを確認していく。

- [The Vue Instance - Intro to Vue.js | Vue Mastery](https://www.vuemastery.com/courses/intro-to-vue-js/vue-instance/)
- [Vue.js Tutorial: Hello world in Vue 👋 - Scrimba Tutorial](https://scrimba.com/p/pXKqta/cQ3QVcr)

**Vue Mastery**で流れをざっくり概要を把握してから、**Scrimba**で復習するような流れでやっていく。


JSの基本は以下がおすすめらしい。
[JavaScript Primer - 迷わないための入門書 #jsprimer](https://jsprimer.net/)

## 基礎が終わったら

適切な難易度の課題を自分で考えて、作ってみるか、以下のような教材を使ってみる。

- [Vue js 2 Completo ¡De 0 a Experto! + Firebase + Node [MEVN] | Udemy](https://www.udemy.com/course/curso-vue/)
- [Nuxt.js & Contentfulでハイスペックなポートフォリオサイトを超簡単に公開しよう！【JAMstack】 | Techpit](https://www.techpit.jp/courses/28)
- [【Vue.js/Firebase】標準的バス情報フォーマットに対応したPWA形式の時刻表アプリを作ろう！ | Techpit](https://www.techpit.jp/courses/49)
- [freeCodeCamp.org](https://www.freecodecamp.org/news/)


laracastsのvue講座も良いかもしれない。

- [Laracasts Topic: Vue](https://laracasts.com/topics/vue)
AWSChatbotをShared かつ PrivateなSlack Channelに設定する

詰まったので備忘録

## 要点
- AWSChatbotのSlackのauthorizeおよびchannelsIDの設定は、Shared channelのOwnerに属しているユーザーにやってもらう必要があるかも
- Slack appをchannelに導入する際もOwnerに属しているユーザーにやってもらう必要がある

## 経緯
- 顧客のメンバーが弊社の開発メンバーとして参画することになったので、もともと弊社のSlack Channelに流していたCodePipelineの通知を、顧客がOwnerのShared Private Channelに変更する作業をやっていた。
- 自分は対象のchannelにも属していて、AWSChatbotのSlackAppもinviteできたので、いけるだろと思ってた

## ハマリポイント1
- 自分でAWSChatbotの設定をする際に、channelID部分でエラーが出て設定が完了できなかった
- authorizeはShareされた側(not Owner)でやってたので、Ownerじゃないからだめなのかなと思って顧客に依頼した。
- ただし、Ownerじゃないからだめってドキュメントも見つけられなかったので、もしかしたら私の設定ミスの可能性もあり。要検証

## ハマリポイント2
- 前述したがAWSChatbotのSlackAppはOwnerじゃないWorkspaceのユーザーが入れた。
- 何度かCodePipeline動かして通知を発砲してみたけどウンともスンともしない
- 既存の弊社のWorkspaceに設定してた方は動いてたので、なんかキューがそっちにもってかれてだめなのかなと思い、AWS側を疑い出す
- 弊社WorkspaceのAWSChatbotClientを削除して見る=>変わらない
- エラー出てるのかなと思ったけど、CloudWatchLogsに吐き出す設定してなくて調査できない。
- これでできなきゃ諦めようと思って、自分で追加したSlackAppを削除して顧客にやってもらったらできた。

## 感想
- SlackIntegration系のSharedかつPrivateなchannelの設定について情報少なすぎ問題
- 基本的にOwner側が設定することを前提してる気がするが、システム開発会社とユーザー企業みたいな感じでOwenerがリテラシー低かったりするとくっそめんどくさそう。今回は割とできる人が担当だったの助かった。
- なお、Githubの通知も設定してたのだが、そっちは絶賛できてない。それっぽいIssueは見つけたがOpenのまま、絶望。
- だれか教えて
FontAwesome

![スクリーンショット 2020-09-01 16.14.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595730/4f38944d-b9f0-aa31-b85b-7934c1716910.png)
***
ドットインストールの学習メモです
***

###FontAwesomeのサイトへ行ってkitのscriptタグをコピペしてくる。

###headに埋め込み

```html
<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="UST-8">
	<title>MyFontAwesome</title>
	<link rel="stylesheet" href="css/styles.css">
	<script src="https://kit.fontawesome.com/496f164843.js" crossorigin="anonymous"></script>
</head>
```

###bodyに埋め込み

iタグ、クラスはfas fa-ad my-icon
内容はアイコンのページに書いてある↓
タグをクリックすればそのままコピーできる

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595730/1270e9c6-ad70-bbda-d357-ddb5e1e5d61a.png" width="500">


```html
<body>
	<i class="fas fa-ad my-icon"></i>
</body>
```

**- fas 塗り潰し solid
- far 白抜き  regular
- fal 細い線  light**
**- fab ツイッターなど　brand**

**- fa-ad
   - fa-flag
   など**

my-iconクラスは足しておく


スタイルシート

```css
.my-icon {
	font-size: 32px;
	color: orange;
}
```
結果こうなる
![スクリーンショット 2020-09-01 16.14.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595730/49cf603e-3f3f-4b34-8447-e2f3046cb03d.png)

#アイコンのサイズ変更
- fa-xs
- fs-sm
- fa-lg
- fa-2x...10x
 
```html
<body>
	<i class="far fa-flag my-icon fa-xs"></i>
	<i class="far fa-flag my-icon fa-sm"></i>
	<i class="far fa-flag my-icon fa-lg"></i>
	<i class="far fa-flag my-icon fa-5x"></i>
</body>
```
![スクリーンショット 2020-09-01 16.33.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595730/db398144-de63-122c-a980-47b63466c68d.png)

#リストにアイコンを使う
- fa-fw　幅をそろえる。

```html
<body>
	<div><i class="fas fa-home fa-fw"></i>Home</div>
	<div><i class="fas fa-info fa-fw" ></i>about</div>
	<div><i class="fas 	fa-question fa-fw"></i>help</div>

	<ul class="fa-ul">
		<li><span class="fa-li"></span><i class="fas fa-home fa-fw"></i></span>Home</li>
		<li><span class="fa-li"></span><i class="fas fa-info fa-fw" ></i></span>about</li>
		<li><span class="fa-li"></span><i class="fas fa-question fa-fw"></i></span>help</li>
	</ul>

</body>
```

![スクリーンショット 2020-09-02 8.05.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595730/1ebed30c-f0aa-5bc5-716b-5bb70b56eb03.png)


#回転ローディングアイコン　ほぼコピペでおk

```html
<body>
	<i class="fas fa-spinner fa-spin fa-3x"></i>
	<i class="fas fa-spinner fa-pulse fa-3x"></i>
</body>
```
#以下FontAwesome5と６で仕様が違うみたいなので割愛。
周回遅れの zsh + zinit

# 周回遅れの zsh + zinit
macOS 10.15 Catalina は、標準シェルが zsh になった。  
しばらく、 bash の設定を踏襲して使っていた。
と言っても、便利にしてしまうとリモートサーバ上での作業時に 「あれって」 ならないように最小限に留めていた。
少し使いやすくしようと思い直して、調べた結果 [Zinit](https://github.com/zdharma/zinit) を使ってみることにした。

## zinit のインストール
通常、追加の色々は、 [Homebrew](https://brew.sh) を使っているのだが Zinit は用意されていないので
おすすめの 'Option 1 - Automatic Installation' を行った。

## テーマの選定＆インストール
テーマは [Powerlevel10k](https://github.com/romkatv/powerlevel10k) を選択した。
こちらは Homebrew でインストールできる。
Powerlevel10k のインストールに先立って、おすすめのフォントをインストールする。

### フォントのインストール(Homebrew)
まずは、

```shell
$ brew tap homebrew/cask-fonts
```

そして目的のフォントのインストール、

```shell
$ brew cask install font-meslo-lg-nerd-font
```

### ターミナルのフォント変更
Terminal → Preferences → Profiles で Font "Change..." より
"Meslo LG M Regular Nerd Font Complete" を選択した。

![フォントの変更](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261790/3aaa8c6c-3def-3bc5-b161-261f676e1ab5.png)

### [Powerlevel10k](https://github.com/romkatv/powerlevel10k) インストール
こちらは Homebrew に登録されているので

```shell
brew install romkatv/powerlevel10k/powerlevel10k
echo 'source /usr/local/opt/powerlevel10k/powerlevel10k.zsh-theme' >>! ~/.zshrc
```

続いて設定を行う。

```shell
$ p10k configure
```

設定後の `~/.pk10.zsh` を [ターミナルをいい感じにして楽しむ](https://qiita.com/szk07/items/b15c38ec73e547a23439) を参考に微調整した。

![設定後](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261790/64a8d116-679c-f4ec-047c-a983b0c54dd3.png)

# おまけ
[合字(ligature リガチャ)](https://ja.wikipedia.org/wiki/合字) フォントの [`Fira Code`](https://github.com/tonsky/FiraCode) をインストールし、
[Atom](https://atom.io) のフォントの変更を行った。

![Atom Fira Code](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261790/f0995d68-102d-b63f-ec09-16384759d563.png)

等幅フォントにおける「全角と半角」は、通用しなくなったのね。  
[エディタで等幅日本語フォントを最適に表示させるには、フォントサイズを2か3か5の倍数にするといいよ！](https://qiita.com/suin/items/559d02ea32bd4a6ef08b)
rails[createアクションによってデーター送信に失敗した時、エラー文を表示するときの手順]

1.エラー文を表示したいビューファイルに記述する。
今回はnew.html.erbに記述する。〇〇は自分で命名する。

```
<%= render '〇〇/error_messages', model: f.object   %> 
```
2.〇〇/_error_messages.html.erb
ファイルを作り記述する。

```
#〇〇/_error_messages.html.erbの内容
<% if 変数A.errors.any? %>
  <div id="error_explanation">
    <ul>
      <% 変数A.errors.full_messages.each do |message| %>
      <li class="error-alert"><%= message %></li>
      <% end %>
    </ul>
  </div>
<% end %>
```


3.もしデーターが保存できたら、同じコントローラー(今回はitemsコントローラー)のindexアクションに画面遷移して、保存できなかったらitems#newアクションを表示する。

```
def create
    @item= Item.new(item_params)
     if @item.save
      redirect_to action: 'index'
    else
      render :new
    end
  end
```
4.これでデーター送信に失敗したら
new.html.erb
<%= render '〇〇/error_messages', model: f.object   %> 
を記述した箇所にエラー文が表示されるようになる
BootcampでCPUの仮想化を有効にする

BootcampでDockerを利用としたときに「Cannot enable Hyper-V service」というエラーがでて起動できなかったり、Hyper-Vが起動できないといったことが起こることがあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99262/51c7a243-b48f-ef2e-7e7d-ce27f65a474b.png)

WindowsでHyper-Vをインストールして有効化しているのにこの事象が発生する場合、CPUの仮想化が無効になっていることがあります。

これはタスクマネージャーの「パフォーマンス」タブから簡単に確認することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99262/be37da45-08ba-d201-cc53-bd1d631926c7.png)

これを解消するためには、つぎのような手順を踏む必要があります。

1. optionボタンを押しながらPCを再起動する
2. **mac OSを起動する**
3. 「システムの環境設定」 -> 「起動ディスク」からBootcampを選択し「再起動」する

これでCPUの仮想化が有効になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99262/af00c901-09d1-4198-b685-bf1c2a58ac86.png)

なお悲しいことにPCを再起動すると元に戻ってしまうので、再起動するときは必ず一度macを起動して、そこからBootcampを再起動しなおす必要があります。日常的にはシャットダウン運用ではなく、スリープか休止運用することになるでしょうか？

これは、おそらくBootcampの不具合だと思いますが、mac OSがARMに移行していくことが目に見えている今、根本解決してもらえることは期待薄そうですね・・・
【rails】ストロングパラメータの仕組みを理解しよう

#ストロングパラメータとは？
フォームから入力された情報を指定して、安全に受け取るための仕組み。これによって不正な情報を受け取らないことができる。

```:コントローラー
def tweet_params
  params.permit(:title, :text)
end
```

ここで使っているpermitはparamsで取得したキーのうち、データベースに保存していいものを許可するメソッドです。
検索機能の実装

備忘録です！！

##ransackをインストール

```
gem 'ransack'
```

bundle installしてください。


##コントローラーの設定

今回は、掲示板の投稿一覧、ブックマーク一覧の検索機能を実装していきます。

```ruby:board_controller.rb
def index
  @search = Board.ransack(params[:q])
  @board = @search.result(distinct: true).includes(:user).order(created_at: :desc).page(params[:page])
end

def bookmarks
  @saerch = current_user.bookmark_boards.ransack(params[:q])
  @bookmark_board = @search.result(distinct: true).includes(:user).order(created_at: :desc).page(params[:page])
end

```

検索のパラメーターは、デフォルトでparams[:q]となっています。
ransackメソッドに検索のparamsを渡してあげて、インスタンスを生成。
生成されたインスタンスをresultメソッドで呼び出して、検索結果を表示させています。

distinct: trueは、今回なくても大丈夫です。

distinct: trueというのは、「関連する子テーブルの情報を条件に絞り込んで、親テーブルの検索結果を表示するとき」に使用します。

例えば、掲示板１という投稿に、

「rails楽しい」

「rails勉強中」

という二つのコメントがあったとします。

railsと検索した時に、distinct: trueがないとr、掲示板１が2回取得されて検索結果が2件になってしまいます。

それを、防ぐ為に、distinct: trueを用います。

##viewの追加

検索用のviewは、パーシャルで作成してきます。

```ruby:boards/_search.html.erb
<%= search_form_for search, url: url do |f| %>
<div class='input-group mb-3'>
  <%= f.search_field :title_or_body_cont, placeholder: "検索ワード", class: 'form-control' %>
  <div class='input-group-append'>
    <%= f.submit value: "検索", class: 'btn btn-primary' %>
  </div>
</div>
<% end %>
```

search_form_forには、先ほどコントローラーで設定した、検索オブジェクト（search)、urlを渡してあげます。

urlを指定しない場合、ブックマーク一覧の検索フォームでリクエストするurlが、/boardsになってしまいます。

これは、BoardsController#indexにルーティングされます。

本来は、bookmarkアクションを呼び出して欲しいので、urlを指定する必要があります。

title_or_body_contは、タイトルと本文が部分一致を示しています。
（_contが部分一致を表す）

```ruby:board/index.html.erb

<%= render 'search', url: boards_path, search: @search %>

これで完成です。
パソコンに保存されているファイルをpythonで読み込む

コンペに参加した際、pythonでcsvデータ(私の場合はExcelデータ)を読み込み、ファイルを開くのに苦労したのでメモを残しておきます。

環境：windows10, anaconda, jupyternotebook

まずは読み込みたいをデータのパスをPC上で確認します。
＊パスとは"データがある場所"を示す文字列です。パソコン内における住所的なもの。

１．読み込みたいデータが入っているフォルダを開く

２．読み込みたいデータにカーソルを合わせ、右クリック

３．プロパティをクリック

４．左上の全般を押し、場所を確認。私の場合だと　場所：C:\Users\ユーザー名\Desktop\ファイル名１\ファイル名２\ファイル名３\ファイル名４\ファイル名５
注： \は￥という風に記述されている場合もあります。C:も、人によっては異なるアルファベットでしょう。またファイル名１，２，３...の数は人によって異なります。

５．パスを、C:は無視して、\Users\ユーザー名\Desktop\ファイル名１\ファイル名２\ファイル名３\ファイル名４\ファイル名５\読み込みたいデータのファイル名　とします。
注：　￥は\に書き換えてください。読み込みたいデータのファイル名は全般の一番上の段にも記述してあります。

以下に読み込むためのコードを記述します。

```
#まずはpandasをインポート
import pandas as pd

#データの名前をdfとし、読み込みます。
#\を文字として使用する場合は、\がエスケープ文字として処理されないように、raw文字列指定にします、すなわちr"パス名"としています。
df = pd.read_csv(r"\Users\ユーザー名\Desktop\ファイル名１\ファイル名２\ファイル名３\ファイル名４\ファイル名５\読み込みたいデータのファイル名")

#データの先頭5行をを表示してみる
df.head()
```

データの形式がExcel（csv）の場合、パスの読み込みたいデータのファイル名は、読み込みたいデータのファイル名.csv　としましょう。
以上です。

”\を文字として使用する場合は、\がエスケープ文字として処理されないように、raw文字列指定にします、すなわちr"パス名"としています。”
→こちらに関しましては、2020/9/2に@shiracamus様からご指摘頂きました、ありがとうございます。

何かご指摘ございましたら、よろしくお願いいたします。
Nginx + Flask + uwsgi (python3) 環境を Amazon Linux2 で動かす

よく使うので起稿。
EC2でお手軽python httpサーバー。

インストールの順番によってはpython2になってしまってハマるので
EC2インスタンスの新規作成直後を想定しています。

# 準備

いつもの
uwsgi入れるためにpython3-develが必要。

```
sudo timedatectl set-timezone Asia/Tokyo
sudo amazon-linux-extras install epel
sudo amazon-linux-extras install nginx1
sudo yum groupinstall "Development Tools"
sudo yum install python3
sudo yum install python3-devel
sudo pip3 install flask
sudo pip3 install uwsgi
sudo yum update

cd
mkdir app logs

```

# nginx

下記のようなのを追記。（tmp.sockにすると動かないっぽい・・）

```/etc/nginx/nginx.conf
location / {
        include uwsgi_params;
        uwsgi_pass unix:///run/uwsgi.sock;
}

```

# flask

いつもの

```/home/ec2-user/app/app.py
from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World!"

if __name__ == "__main__":
    app.run()

```


# uwsgi

chdirしないと動かない。

```/home/ec2-user/app/app.ini
[uwsgi]
chdir = /home/ec2-user/app
module = app
callable = app
master = true
processes = 1
socket = /run/uwsgi.sock
chmod-socket = 666
vacuum = true
die-on-term = true

logto = /home/ec2-user/logs/uwsgi.log
```

#uwsgi service化

↓のファイルを作る。

```/etc/systemd/system/uwsgi.service
[Unit]
Description = uWSGI
After = syslog.target

[Service]
ExecStart = /usr/local/bin/uwsgi --ini /home/ec2-user/app/app.ini
Restart=always
KillSignal=SIGQUIT
Type=notify
StandardError=syslog
NotifyAccess=all

[Install]
WantedBy=multi-user.target
```
※たまにuwsgiのPathが違う時がある。which見て修正。

# サービス起動、nginx再起動

```
sudo systemctl enable uwsgi
sudo systemctl start uwsgi
sudo systemctl restart nginx
```

#その他

デバッグ時は下記のあたりを見る。

```
/var/log/nginx/error.log
/home/ec2-user/logs/uwsgi.log
```

途中で困ったときのコマンド

```
uwsgi --wsgi-file app.py --http :5000
↑app.pyを手動で起動してみる

sudo /usr/local/bin/uwsgi app.ini
↑app.iniから起動してみる

```
[CentOS7]aws cliのインストール

## aws cliのインストール

- pipのウェブサイトからインストールスクリプトをダウンロード

```sh
# 移動
cd /var/tmp

# インストールスクリプロトをダウンロード
curl "https://bootstrap.pypa.io/get-pip.py" -o "get-pip.py"
sudo python get-pip.py
```

- pipを使用してawscliをインストール

```sh
sudo pip install awscli
```

- バージョン確認

```sh
# バージョン確認
aws --version
aws-cli/1.18.128 Python/2.7.5 Linux/3.10.0-1127.19.1.el7.x86_64 botocore/1.17.51
```

- awsコマンドの設定

```
aws configure
==========
AWS Access Key ID [None]: XXXXXXXXXXXXX
AWS Secret Access Key [None] : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Default region name [None] : xxxxxxxx
Default output format [None]: json
==========
AWS Access Key ID : アクセスキー
AWS Secret Access Key : シークレットキー
Default region name : デフォルトのリージョン (参考 : https://docs.aws.amazon.com/ja_jp/general/latest/gr/rande.html)
Default output format : デフォルトのフォーマット
```
Rails6系で、herokuにデプロイしようとしたら手間取った件について

## この記事で書くこと
久しぶりにHerokuでRailsアプリケーションを作成して公開しようとしたら、いくつかの躓きがあったのでその備忘録。
具体的にいうと、credentialsの扱いについて。
https://railsguides.jp/6_0_release_notes.html#railties-%E4%B8%BB%E3%81%AA%E5%A4%89%E6%9B%B4

## 環境
Rails 6.0.3.2
ruby 2.7.0p0 (2019-12-25 revision 647ee6f091) [x86_64-linux]

## 起きたこと
①`Rails.application.credentials` を読み込もうとしてる箇所でデプロイ中に参照エラーが発生してデプロイが失敗する。
② [herokuの公式ドキュメント](https://devcenter.heroku.com/articles/getting-started-with-rails6)を見ても、情報が見当たらなかったので、調べていると [HerokuにRailsアプリをデプロイする](https://qiita.com/daigou26/items/64d87d987652c4108ae6) という記事を見つけたので、読んでみる。この環境変数が何を指してるのか解らなかったので、理解するために、もう少し調べると、 [Rails5.2から追加された credentials.yml.enc のキホン](https://qiita.com/NaokiIshimura/items/2a179f2ab910992c4d39) という記事を見つけ、 **`config/master.key` が共有されない環境では、この環境変数を設定することで、暗号化されたファイルを解読することができる**ことがわかりました。参考にさせていただいた記事の皆さんありがとうございます！ :bow: 
というわけで、
③ `config/master.key` の内容をherokuの環境変数に設定する。

```zsh
heroku config:set RAILS_MASTER_KEY=`cat config/master.key`
```
を実行しました。
③再度デプロイするも、失敗。今度は、 `ActiveSupport::MessageEncryptor::InvalidMessage` が発生していることが原因。
④自分の環境を見直すと、 以下の内容でした。

```
config/master.key
config/credentials/production.key
config/credentials/development.key

config/credentials.yml.enc
config/credentials/production.yml.enc
config/credentials/development.yml.enc
```

自分が環境変数でセットした `master.key` で開錠できるのは、 `config/credentials.yml.enc` です。
でも、自分は `config/credentials/production.yml.enc` を作成していたので、そちらが読み込まれて、 `master.key` で解錠できずにエラーが発生しているのではないかと気付きました。

④正しい鍵の内容をherokuの環境変数に設定し直す。

```zsh
heroku config:set RAILS_MASTER_KEY=`cat config/credentials/production.key`
```

⑤設定し直すと、無事デプロイできました。
Githubでのリモートリポジトリの復元方法


#　間違えて消してしまった
先日、いらないリモートリポジトリを消そうとしたら、間違えて必要なリモートリポジトリを代わりに消してしまいました。

#復元方法
まずは、自分のプロフィール写真を選択し、settingsをクリックします
![スクリーンショット 2020-09-02 2.23.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669290/d8dda408-2ab9-f8b2-317c-43d360554763.png)
そして、Repositoriesをクリックします。
![スクリーンショット 2020-09-02 2.25.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669290/f207c137-f387-2f08-b72e-88e59131267b.png)
Repositoriesの中からDeleted repositoriesに復元したいファイルを発見し、Restoreを選択する
![スクリーンショット 2020-09-02 2.26.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669290/47ea20ef-95a3-ddc9-32d4-ef38c7e482b1.png)

#最後に
消したリモートリポジトリがDeleted repositoriesに反映されるまでは１時間くらいかかるらしいです
JavaScriptのarrayのmap関数でアロー関数を使う

##arrayのmap関数とは？
「配列内のすべての要素に対して、同じ処理を加えた新しい配列を返す」関数。

サンプル

```javascript
array1 = [0,1,2,3,4,5]
```

という配列に対して、すべての要素を２倍にした新しい配列

```javascript
array2 = [0,2,4,6,8,10]
```

を簡単に作れる

###map関数の基本的な使い方の例

サンプル

```javascript
var func = function nibai(value){return value * 2};

var baseArray = [1,2,3,4,5];
var newArray = baseArray.map(func);
console.log(newArray); // =>[2,4,6,8,10]
```

1. 引数を一つ取り、引数を二倍にして返すnibai関数を作り、変数funcに代入する
2. baseArrayを作る
3. baseArrayのmapメソッドを使い、引数として1で作った関数（を代入した変数func）を渡す
4. mapメソッドが、配列の中身を一つづつnibai関数に渡して結果を受け取る
5. すべての値が二倍になった配列が得られる

###無名関数を使う
サンプル

```javascript
var baseArray = [1,2,3,4,5];
var newArray = baseArray.map(function(value){return value * 2});
console.log(newArray); // =>[2,4,6,8,10]
```

###アロー関数を使う

1 : 通常の書き方

```javascript
var baseArray = [1,2,3,4,5];
var newArray = baseArray.map(function(value){return value * 2});
console.log(newArray); // =>[2,4,6,8,10]
```

2 : アローを使って「function」を省略

```javascript
var baseArray = [1,2,3,4,5];
var newArray = baseArray.map((value) => {return value * 2});
console.log(newArray); // =>[2,4,6,8,10]
```

3 : 1行ならreturnと{}を省略可能

```javascript
var baseArray = [1,2,3,4,5];
var newArray = baseArray.map((value) => value * 2);
console.log(newArray); // =>[2,4,6,8,10]
```

4 : 引数1個なら()も省略可能

```javascript
var baseArray = [1,2,3,4,5];
var newArray = baseArray.map(value => value * 2);
console.log(newArray); // =>[2,4,6,8,10]
```
ffmpegで複数のmp3ファイルを結合

ディレクトリ配下にある全てのmp3ファイルを一つのmp3ファイルに結合します。
調べたり試した中で、これが一番簡単だと思いました。
コマンド2つでできます。

###環境
- mac OS : Catalina version 10.15.6
- ffmpeg : stable 4.3.1 (bottled)

## 手順1
結合したい全てのmp3ファイルのリスト(mylist.txt)を作成します。
まとめたいファイルがあるディレクトリで以下を実行します。

```
$ for f in *.mp3; do echo "file '$f'" >> mylist.txt; done
```

mp3ファイルのリスト(mylist.txt)の中身

```
file 'file1.mp3'
file 'file2.mp3'
...
```

## 手順2
作成したmp3ファイルのリストを使って1つのmp3ファイルに結合します。
まとめたいファイルがあるディレクトリで以下を実行します。

```
$ ffmpeg -f concat -safe 0 -i mylist.txt -c copy output.mp3
```
※output.mp3は出力するmp3ファイル名


なお、`-safe 0` を入れなくてもできるかもしれませんが、
私の環境では`[concat @ 0x7fcb00008200] Unsafe file name 'input.mp3' mylist.txt: Operation not permitted`というエラーが出てできませんでした。

.
.
.


##参考
* [ffmpegでファイルをリストにして、動画を連結させる方法](https://yatta47.hateblo.jp/entry/2016/07/19/200000)
Cloud Front + Lambda@Edgeでドメイン名でrewriteする

WebアプリケーションのCD(継続的デリバリー）で、パスベースのURLを採用したSPAの場合、

`${SHA_HASH}.domain.name -> origin/index.${SHA_HASH}.html`

のようなrewriteをしたいことが良くあります。

`/${SHA_HASH}/**/* -> /${SHA_HASH}/index.html`

にrewriteする方法もありますが、本番とパスの階層が変わってしまって、ステージングテストで苦労することになるので、ドメインベースにしたいわけです。

これは、nginxやApacheでもできますが、このためだけにnginxやApacheを立ち上げるのもばからしいので、Lambda@Edgeでできないかと思うわけです。結論から言うと問題なくできます。

1. Cloud Frontでのワイルドカードドメインの利用
2. デプロイ前に、index.html -> index.${SHA_HASH}.htmlにリネーム。

など、面倒なことがいろいろありますが、ソースコードだけで言うと以下のようにすればとりあえず動きます。


```js
exports.handler = async (event, context) => {
    const request = event.Records[0].cf.request;
    if(!request.uri.match(/^\/(?:js\/|css\/|img\/|favicon.ico)/)) {
        const host = request.headers.host[0].value;
        const hostMatch = host.match(/^([0-9a-f]{40}|[a-z]{3,}-?[0-9]*)\./);
        const versionId = hostMatch ? hostMatch[1] : "production";
        request.uri = `/index.${versionId}.html`;
        console.log(request.uri);
    }
    return request;
};
```

あまり汎用性のないコードですが、ドメイン名やuriの取得・変更する部分は共通だと思うので、参考になると幸いです。

ちなみに、本来、request.uri.matchの部分は、Cloud Front側でやってしまった方がパフォーマンス面でもコスト面でも良いでしょう。
React Native Expoでフォームのバリデーションができる「React Hook Form」

React Native + ExpoでTextInputにバリデーションをかけたくてググったところ、React-Hook-FormというReactのライブラリを発見しました。ライブラリの説明では、類似ライブラリであるFormikやRedux Formよりもシンプルに書けるとアピールされています。ドキュメントに日本語版があるのも嬉しいですね。使ってみました。

React Hook Form
高性能で柔軟かつ拡張可能な使いやすいフォームバリデーションライブラリ。
https://react-hook-form.com/jp/

# インストール
```
$ yarn add react-hook-form
```

# 下準備
以下のようにインポートし、useFormフックで必要なAPI・オブジェクトを引っ張ってきます。FormDataにはフォームが保持する値を定義します。

`import { useForm, Controller } from 'react-hook-form'`

`const { control, handleSubmit, errors } = useForm<FormData>()`

```
type FormData = {
  firstName: string
}
```

# 入力コントロールにバリデーションをかける

フォームの入力コントロールをControllerタグでJSX内に定義します。

```
      <Controller
        control={control}
        render={({ onChange, onBlur, value }) => (
          <TextInput
            style={styles.input}
            onBlur={onBlur}
            onChangeText={value => onChange(value)}
            value={value}
          />
        )}
        name="firstName"
        rules={{ required: true }}
        defaultValue=""
      />
      {errors.firstName && <Text>This is required.</Text>}
```

renderには、画面に表示される入力コントロールのコンポーネントを指定します。propsに渡ってくるonChange, onBlur, valueを適宜処理します。

バリデーションエラーは、nameに指定した名前でerrorsオブジェクトの中に入ってきます。errors.firstNameを条件にすることで、バリデーションに失敗したときに項目ごとのエラーメッセージを表示できます。

rulesはバリデーションの内容で、required, min, max, minLength, maxLength, pattern(正規表現)などを指定できます。

defaultValueは文字通りデフォルト値です。

# サブミット処理に関数をかませる
ボタン押下でhandleSubmit関数が動いて、エラーがあればerrorsオブジェクトが更新されてonSubmitは実行されない、エラーがなければonSubmitが更新される、という振る舞いになります。
`<Button onPress={handleSubmit(onSubmit)} label="SAVE"></Button>`
git push origin master が出来ない

# Git Hubに上げられない
新しくアプリを作りGit Hubに上げられず、エラーでかなり困りました。
なんとか解決をしたので、忘れないように備忘録として書きます。

新しくrailsでアプリを作り、リモートリポジトリにあげよう下記のコマンド打ち

```
$ git remote add origin 新しく作ったリポジトリのコピーしたURL

$ git remote
origin
```
ここでoriginと出力され

それでは紐づけが完了したので、ローカルリポジトリの現状の情報を、リモートリポジトリに反映

### git push

ローカルリポジトリでのコミットをリモートリポジトリ（origin）に反映させる

```
$ git push origin master #リモートリポジトリ（origin）に情報を反映
```
ここでエラー

```
error: src refspec master does not match any
error: failed to push some refs to 'https://〜'
```
解決した方法は git secrets をインストールする

```
brew install git-secrets
```

これだ解決がして無事にGit Hubに上げられました。
【Vue.js】Firebase Cloud Storage にファイルをアップロードする方法

#前提条件
・Vue.jsのプロジェクトファイルを作成している
・Vuetify.jsの導入ができている
・Firebaseとの接続ができている

#実装方法
1、file形式で画像をアップロードする
2、変更があった場合は、@changeで感知して、onFilePickedを実行
3、Cloud Storageにアップロードする
4、アップロードしたファイルのURLをFirestoreに保存する

## template
```vuejs

<template>
  <div>
    <img :src="imageUrl" height="150" v-if="imageUrl" />
    <v-file-input
      type="file"
      show-size
      ref="fileupload"
      accept="image/png, image/jpeg, image/bmp"
      prepend-icon="mdi-camera"
      label="UPLOAD IMAGE"
      @change="onFilePicked"
    ></v-file-input>

    <v-btn @click="upload">アップロード</v-btn>
  </div>
</template>
```

##script
```js
<script>
import firebase from 'firebase'

export default {
  data () {
    return {
      imageName: "",
      imageUrl: "",
      imageFile: "",
    };
  },
  methods: {
    onFilePicked (file) {
      if (file !== undefined) {
        this.imageName = file.name;
        if (this.imageName.lastIndexOf(".") <= 0) {
          return;
        }
        const fr = new FileReader();
        fr.readAsDataURL(file);
        fr.addEventListener("load", () => {
          this.imageUrl = fr.result;
          this.imageFile = file;
        });
      } else {
        this.imageName = "";
        this.imageFile = "";
        this.imageUrl = "";
        this.$refs.fileupload.value = null;
      }
    },

    // 画像アップロード処理
    upload: function () {
     firebase.storage().ref().child(`images/${this.imageName}`).put(this.imageFile).then(snapshot => {
        snapshot.ref.getDownloadURL().then(downloadURL => {
          firebase.firestore().collection("images").add({
            downloadURL,
          });
        });
      });

      this.imageName = "";
      this.imageFile = "";
      this.imageUrl = "";
      this.$refs.fileupload.value = null;
    }
  },
};
</script>
```

#Thanks
[【Nuxt.js × Vuetify】ファイル入力情報を受け取る](https://blog.proglearn.com/2019/10/22/%E3%80%90nuxt-js-x-vuetify%E3%80%91%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E5%85%A5%E5%8A%9B%E6%83%85%E5%A0%B1%E3%82%92%E5%8F%97%E3%81%91%E5%8F%96%E3%82%8B/)
[How to reset/clear file Input](https://stackoverflow.com/questions/59658463/how-to-reset-clear-file-input)