OmniAICreator/Qiita-1.07M huggingface dataset:
JS~オブジェクトと配列~


#オブジェクトの構成

```
title: JavaScript
```
title ▶　プロパティ名
JavaScript ▶　データ（値）
この組み合わせをプロパティとなります。

では、実際にJSで、オブジェクトを作って行きたいと思います。

# ①　document.write
変数を宣言し、オブジェクトを作成していきます。

```index.html
<script>
    'use strict'

    let team = {name:'花子', age: 22, gender:'女'};
    document.write(team.name);
    document.write(team.age);
    document.write(team.gender);
  </script>
```
このように、document.writeにてブラウザ上に出力する方法もありますが、一つ一つ取り出すことができます。

# for ... in

```index.html
<script>
for(let p in team) {
    document.write(p + '=' + team[p]);
    }
</script>
```
この方法で取り出すこともできますが、ランダムに出力されてしまいます。

# ③ id属性で出力

```index.html
<body>
<section>
    <table>
      <tr>
        <td id="name"></td>
        <td id="age"></td>
        <td id="gender"></td>
      </tr>
    </table>
  </section>
</body>
<script>
document.getElementById('name').textContent = team.name;
document.getElementById('age').textContent = team.age;
document.getElementById('gender').textContent = team.gender;
</script>
```
こうすることで、順番に出力することができました。
![スクリーンショット 2021-04-08 11.21.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1033397/2763951c-780e-fdf9-b591-e207bb10fc87.png)

#配列　VS　オブジェクト

配列とオブジェクトどっちを使えばいいの？？ってなりますよね。

配列は同じ種類のデータを管理します。
それに対して、オブジェクトは違う種類のデータを管理します。

そこで考えるのは、表として考えましょう。

縦に並べたほうがわかりやすい　▶　配列
横に並べたほうがわかりやすい　▶　オブジェクト

しかし、実際は、配列とオブジェクト両方使っていくことが多いので、一概には言えません。
【HTML5】 簡単レスポンシブ対応：HTMLのみで画面幅に合わせて表示する画像を変更する方法（picture, sourceタグの使い方）

HTML5から追加されたpictureタグを使うと、画面サイズによって表示する画像を簡単に切り替えることができる。

CSSやJSが不要でHTMLのみで実現できる。


##使い方

```html:.html
<picture>
    <source media="(メディア属性の値)" srcset="画像パス">
    <img src="画像パス" alt="" />
</picture>
```

- 使うタグは`picture`、`source`、`img`の３つ。
- メディア属性の条件に適合する場合は`srcset`で指定した画像が表示される。
- どの条件にも当てはまらない場合はimgが適用される。


**▼ポイント**

1. viewportの記述必須。
1. `source`属性は複数記述可能。
1. `source`属性を記述する順番は重要。上から順にメディア属性の条件が照らし合わされる。
1. どの条件にも当てはまらない場合はimgタグが適用。

```html:viewport
<meta name="viewport" content="width=device-width, initial-scale=1.0">
```


<br>
##メディア属性の使い方
メディアクエリを属性に適用したもの。メディア属性が使えるのは次の５つのタグ：`a`, `area`, `link`, `style`, `source`。

```html:
media="screen and (適用条件:画面幅)"
```

**▼適用条件**

| 適用条件 | 概要  | 意味 |
|:--|:-:|:--|
| max-width | 以下 | 画面幅の最大値。小さい幅から、この値まで適用。  |
| min-width | 以上 | 画面幅の最少値。大きい幅から、この値まで適用。  |

maxは以下、minは以上。〜以上、〜以下としたい場合はそれぞれを組み合わせる。

`(min-width: 360px) and (max-width: 680px)`なら、360px~680pxの時に適用となる。



<br>
##実例

```html:
<picture>
  <source srcset="public/image/pic-pc.png" media="(min-width: 1080px)"/>
  <source srcset="public/image/pic-tablet.png" media="(min-width: 680px)"/>
  <source srcset="public/image/pic-sp.png" media="(min-width: 360px)"/>
  <img src="public/image/pic.png" alt="" />
<picture>
```

- 1080px以上はpic-pc.pngを表示。
- 680px以上（~1079px）はpic-tablet.pngを表示。
- 360px以上（~659px）はpic-sp.pngを表示。
- 上記のどれにも当てはまらない場合（~359px）はpic.pngを表示。


<br>
以上。
【Python】購買データから購買サイクルを計算する

# ID別に購買サイクルを計算する

下記のようなID別に購買日を縦持ちで持っているデータに対して、ID別に購買間隔をPythonで計算する方法です。

データ（id_date.csvとする）
![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/580417/1c5350bf-32d2-dd61-b78f-8345dd7ada83.png)

## コード

```python
#ライブラリの読み込み
import pandas as pd
import numpy as np

#データの読み込み 文字コードはファイルに合わせて指定
df = pd.read_csv('id_date.csv',encoding='shift-jis',dtype={'ID':'str','DATE':'str'})

#並び替える（日付昇順）
df_arg = df.sort_values(['ID','DATE'],ascending=[True, True])
#購入日を日付型に変換（元々日付型であれば不要）
df_arg['DATE_dt'] = df_arg['DATE'].apply(lambda x : dt.strptime(x,'%Y%m%d'))

#日付の差分を計算する＆一つ前のレコードの会員を取得する
df_arg['cycle'] = df_arg['DATE_dt'].diff()
df_arg['ID_diff'] = df_arg['ID'].shift()

#不要なレコードを消す（IDとID_diffが一致するレコードのみ取得）
df_diff = df_arg[df_arg['ID']==df_arg['ID_diff']]

#cycleを日付型から数値型に変換する
df_diff['cycle_int']=df_diff['cycle'].apply(lambda x : x.days)
#必要なカラムだけ残す
df_out = df_diff[['ID','cycle_int']]

#IDごとに購買サイクルを中央値で取得
df_cycle = df_out.groupby('ID',as_index=False).median()[['ID','cycle_int']]
```

## 解説

処理の流れとしては

①IDと日付でデータをソートする（日付昇順）
②日付はひとつ上の日付との差を取得（→cycle）
③IDはひとつ上のIDを取得（→ID_diff）
④IDが各レコードで一致しているもののみ取得（→各IDの先頭のレコードを削除する）
【Nuxt.js】mode option is deprecated. You can safely remove it from nuxt.config が出たときの対処法

Nuxt.jsのv2.15.4にアップデートしたときに出たエラーです。

versionアップして`yarn dev`したら次のようなメッセージーが出てきました。

```
WARN mode option is deprecated. You can safely remove it from nuxt.config
```

調べてみるとNuxtの公式に書かれていました。

https://ja.nuxtjs.org/docs/2.x/configuration-glossary/configuration-mode/

v2.14.5から変更されたようですね。

https://github.com/nuxt/nuxt.js/pull/8044

`nuxt.config.json`から`mode`オプションを記述するのが**非推奨**になったようです。

```nuxt.config.js
mode: 'universal'
```

今後は変わりに`ssr`を使用してくださいとのことです。

## **SSR**の場合はこのように変更

```diff_javascript
- mode: 'universal'
+ ssr: 'true'
```

## **SPA**の場合はこのように変更

```diff_javascript
- mode: 'spa'
+ ssr: 'false'
```

## **SSG**にする場合はこのようにします。

```nuxt.config.js
ssr: 'true',
target: 'static
```

以上、古いバージョンからアップデートするときの注意点でした。
IMPORTRANGEの関数が便利すぎておちいったワナ

#■ とりあえず始めに。

#####ImportRangeの使い方はスルーします。
この辺は検索すればいくらでもでてくると思いますので。


#■ ImportRangeを使って何がおこったか。

スプレッドシートAに、スプレッドシートBの一部を引用しようとImportRangeを使ったんです。

それまでは **アクセス許可** を押せば、ポンポコと指定した範囲の値をとってくれてました。

![アクセス許可ー-Google-スプレッドシート.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/710015/9692d0bc-534b-97f1-0968-9e33658c68f2.png)

しかし今回は、**アクセス許可**を押しても値をとってこない！！
どころか、ずっとクルクルとローディンみたいなのしてますけど…
![クルクル-Google-スプレッドシート.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/710015/6da3511d-87ed-c0e8-8482-645176cb84f7.png)

ちょっと待つ…

![クルクル-Google-スプレッドシート.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/710015/6da3511d-87ed-c0e8-8482-645176cb84f7.png)

まだ待つ

![クルクル-Google-スプレッドシート.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/710015/6da3511d-87ed-c0e8-8482-645176cb84f7.png)

あれ？時間かかり過ぎじゃない？

![クルクル-Google-スプレッドシート.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/710015/6da3511d-87ed-c0e8-8482-645176cb84f7.png)

**絶対何かおかいしい！！！**

#■ 原因

とっても単純でした。
Google Driveにアップした際に
**一部がエクセルの形式になっていた!!!!!!!!!!!!!!!!**

スプレッドシートに変換してあげなおして、解決しました。


EXCEL形式じゃだめだよ！って教えてよ！

って話でした。

<br>
# We are recruiting !
株式会社GENZでは現在キャリア採用を行っております。
ご興味がある方は以下をご確認ください！
[株式会社GENZ - 採用情報]
 (https://www.genz.jp/recruit/?qirecruit=20210412)
[株式会社GENZ - ブログ]
 (https://www.vamp.jp/?qi=20210412)
【メモ】【Git】ローカル上の変更を取り消したい

Gitをいじっていたらエラーから抜けられなくなってしまいました。
そんなときにとても便利だったコマンドをメモとして残しておきます。

##ローカル上の変更の取り消し
```git checkout```でローカル上の変更を取り消すことができます。

```
% git checkout .
```

```git clean -df .```で新規ファイル等も削除できます。

```
% git clean -df .
```


###参考文献
[Gitでいろいろ取り消したい](https://qiita.com/matsugaknight/items/c0526812e89249b93239)
Webデザインの勉強

ツイートして3分でアカウントが作成できる素晴らしい時代

という訳で、Webデザインの傍ら、ディープラーニングの勉強しつつQiita始めました
コーディングのハイライト機能がちゃんと付いてるのQiitaくらいしか無いしね
本当はPatreonのポスト機能で一括管理したいけど、仕方ないね

Laravelの勉強終わったら、そもそも自分のWebサイト作るかもしれない
Django のtemplateで少し便利なカウンター

Djangoのtemplateを扱う際にcounterを自分で記載せずとも勝手にカウントしてくれてたので、そのコードを備忘録で残しておきます。


## コード
```Python
{% for value in values %}
    count:{{ forloop.counter }}
    value:{{ value }}
{% endfor %}
```


## まとめ
forloop.counterで今が何回目のループかカウントしています。

便利ですね。

短いけど、以上
【2021年4月版】Git で Stash、その前に !? 

# Git で Stash よく使うなら

自分の作業ブランチに他のバグ対応を取り込みたい、けど、絶賛作業中でコミットできない。。。
そんなときは `git stash` ご活用かと思います。特に VS Code では UI から Stash の追加と pop が目視で確認しながら行えるので比較的安全に作業を退避して、ブランチ切り替えて、マージして、ブランチ戻して、stashも戻して、などごちゃごちゃやりつつ、commit の綱渡りをしておられるかと思います。

小さな修正ならいいかもしれませんが、そこそこのボリュームのマージして動作確認した後で自分の stash もマージしてさらに調整しないと・・・という作業では commit ミスが起きやすく、作業中にブランチを行ったり来たり、もしくはマージ用の一時ブランチ作ってそっちで集中的にマージと動作確認、さらにバグが見つかって破綻、などの歴史を繰り返しているかと思います。

そう、ブランチの切り替え作業はけっこうリスクを伴う作業もあるので、できれば並行して作業を進めたい…
そんなある日、以下の記事を目にしました。

https://opensource.com/article/21/4/git-worktree

# Git worktree を使え！

**Git worktree でコードを自由にいじろう** ということですが、`git worktree` コマンドってなんだ？ということで公式のヘルプを見てみると・・・

https://git-scm.com/docs/git-worktree

`Manage multiple working trees` ってことで、複数のワーキングツリーを管理するコマンドだそうです。・・・っていうかワーキングツリー、複数にできたんだ・・・？

ワーキングツリーとはローカルの作業フォルダのことですが、1つのリポジトリから個別にCloneしてくればもちろん複数になりますがそれぞれ`別のリポジトリ`となってしまうので、ファイルの比較とか取るのは面倒だったりしました。
それが一つのリポジトリに対してちゃんと複数のワーキングツリーとして管理できると、複数ブランチを別のワーキングツリーとして並列に管理でき、diff を取ったりmergeしたりが現在の作業ファイルをそのまま維持してできるので飛躍的に安全に作業できるのです。

`git worktree`コマンドはVS Code の UIではサポートされていないので以下のようなコマンドを打ちます。

```
$ git worktree add パス ブランチ名
```
で、ローカルからワークツリーを削除するには

```
$ git worktree remove パス
```
でOKです。

ただしVS Code のコード管理機能ではメインのワーキングツリーしか認識してくれないのでそちらの操作はコマンドベースになります。まぁ、メインのワークツリーのコミットに邪魔されないので十分かと思います。
まぁVS CodeのUIでサポートされればより使いやすくなると思いますが、**git worktree アリ！** というお話でした。

`git worktree` の詳しい使い方については、以下の優秀な記事をご覧いただきたいです。

https://qiita.com/yoichi22/items/8f92110f24690ca8966f

以上です。
[bash] 関数を1行で書く

## はじめに
bash等のシェルにおいて、長いコマンドを毎回打つのが面倒なとき、`alias` を設定しておくと便利です。

また、引数を交えて`alias` を設定したい場合、関数を定義することにより実現可能です。

## 関数定義の例
例えば、以下のコマンドを`dbash hoge` に省略したいとします。

```bash
docker exec -it hoge /bin/bash
```

このとき、状況により変化する引数(`hoge`)が引数の間にあるため、`alias`では対応できません。

その場合、以下のように関数を定義します。

```bash:.bashrc
function dbash(){
  docker exec -it "$1" /bin/bash
}
```

すると、以下のコマンドで実行可能になります。

```bash
dbash hoge
```

## 1行で定義したいとき
先程の関数は便利ですが、いくつも定義しようとすると行数が多くなり、見通しが悪くなる場合があります。

かといって、単に以下のように定義するとエラーとなります。

```bash:.barhrc
function dbash(){ docker exec -it "$1" /bin/bash }
```

エラー

```bash
source ~/.bash_profile
-bash: ~/.bashrc: line 1: syntax error: unexpected end of file (EOF)
```

そのため、ワンライナーで書く場合、コマンドの終了を書いてあげる必要があります。

```bash:.bashrc
function dbash(){ docker exec -it "$1" /bin/bash; }
```

上記はコマンドの最後に`;` が加わっています。

これで、`.bashrc` が見辛くなる心配もありません。

ただ、無理矢理1行にするのもよくないので、適宜使い分けましょう。

## その他Tips
関数定義に置いいて、`function` または`()` のいづれかは省略可能です。
※ `()` を省略した場合、`{` 前のスペースに注意

```bash
function dbash { docker exec -it "$1" /bin/bash; }
```

```bash
dockrun(){ dbash exec -it "$1" /bin/bash; }
```
【Dr.Sum Datalizer】明細で、ExcelやCSVに出力する最大件数を指定する



#目標
Dr.Sum Datalizerの明細で、超デカい件数のダウンロード（特にExcelで）を行おうとすると、最悪の場合DatalizerサーバのCPU100%→Datalizerほぼ停止、使えなくなる。
明細でExcelやCSVに出力するときの最大件数を指定しておこう。

#経緯
つい先日100万件EXCELダウンロード事案が発生、本番Datalizerサーバが瀕死で冷や汗！
開発初期に作られた集計定義で考慮が足りておらず、年月で最大20年分のデータ抽出が可能。
現場の方はしっかり20年分指定してEXCELダウンロードしようとしてました。

#手順･･･その前に考えてみよう
大量にデータがあるテーブル/ビューを参照している明細型のDatalizer集計定義作成時は、超デカい検索結果にならぬよう、抽出条件に留意すべし。

例）抽出条件「年月」のみ＝やろうとすれば過去データ全てを出せる
　　→検索結果はものすごい件数になる
　　→でも、画面上は普通に表示される
　　（1ページ表示件数が50～100件程度だから。悲劇はこのあと起きる）
　　→EXCELダウンロードする
　　→サーバのCPU100%に、瀕死状態
　　→抽出画面側でブラウザ閉じてもだめ、走り出したら止まらないぜ

回避案）
　★「年度」を必須条件に追加することで最大でも一年単位になり、サーバ停止リスク減
　★でも現場は一度で沢山出したいものなので、利便性とのバランスが大事
#手順
設定は２種類ある。

(1)各集計定義で（=その定義だけで有効）
(2)システム設定で（＝Datalizer全体的に有効）

　※どちらも設定した場合は、(1)各集計定義が優先
　※(2)は全体に影響がでるので、設定値を何にするか決めるのは結構難しい

(1)各集計定義
集計定義の　[属性] → [明細データに関する設定] → [通常表示以外の出力最大行数]
※以下の画面はVer.4.2
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278265/a9570cb8-f46e-4e2d-74ff-1a7e395670c4.png)

(2)システム設定
<font color="OrangeRed">Ver.4.2</font>
　[テナント管理] → [テナント管理者ページへログイン ボタン] → [集計表共通設定] → [共通システム設定] → [明細データに関する設定] → [通常表示以外の出力最大行数]
<font color="OrangeRed">Ver.5.0以降</font>
　[管理ページ] → [集計表共通設定] → [設定] → [共通システム設定] → [明細データに関する設定] → [通常表示以外の出力最大行数]

※以下の画面はVer.4.2
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278265/71988cf5-50d9-b831-112b-564f251e54ff.png)

#その他
大塚商会でこのような情報を見つけました。ご参考までに。

https://faq.mypage.otsuka-shokai.co.jp/app/answers/detail/a_id/285399/~/%5Bdr.sum-ea-dw-4.x%5D%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%81%AB%E9%AB%98%E8%B2%A0%E8%8D%B7%E3%81%8C%E6%8E%9B%E3%81%8B%E3%82%8B%E9%9B%86%E8%A8%88%E3%82%92%E7%A6%81%E6%AD%A2%E3%81%99%E3%82%8B%E5%88%B6%E9%99%90%E3%81%AF%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%99%E3%81%8B%EF%BC%9F

#つぶやき
この事象が私の環境で起きたときは、悩んだ末にサーバ再起動しました。
Datalizerサービス停止、しばらく待ってからのサービス再起動でもいけるのかもしれませんが。

事件発生～再起動完了までの間に現場からの問合せTELが次々かかってきて、慌てる中で「Dr.Sum使って貰えてるんだな」という嬉しさもあり。。

#ウイングアークのユーザコミュニティ「nest」
私も参加しています。多くの有益な情報があり、交流があります。
世の中が変わり、社外活動の重要性がより増していると考えております。
社外で自分の価値を計れるものさしを持とう。

https://www.wingarc.com/wug-nest/
無料静的サイトホスティングサービスの比較

#無料で個人のサイトを運営できるという衝撃
大学生時代から、レンタルサーバーを借りてWPブログを立ち上げてちょこちょこブログを書いてはお小遣い稼ぎをしていたのですが、正直当時学生だった私にはレンタルサーバーの契約料金がかなり痛く、運営維持ができませんでした。(というか気付いたらサーバーの契約終わって勝手に閉鎖されてた..笑)

ずっと昔から興味だけはあったプログラミングの勉強を始めて、「無料のサーバーがある」というのは驚愕の事実を知りました。githubにpushさえできれば無料で個人のサイトを始められるってめちゃくちゃいいですよね。


PFはとりあえずNetlifyにて公開しました。
が、Netlify以外にも色々と選択肢があるようなので、記録に残しておきます。

#静的ホスティングサービスの選択肢
・Netlify
・GitHub Pages
・Vercel
・Azure Blob Storage
・AWS Amplify Console
・Amazon S3
・Firebase
・Heroku
・Static Web Apps
	

| service | price | スループット | RTT| 独自ドメイン |
|:-:|:-:|:-:|:-:|:-:|
|  Netlify | 200GBまで無料で以降従量制 | 約 100KB/s | 約50ms | ◎|
| GitHub pages | 100GB まで無料で超えたら追い出される | 数MB/s |  約5ms |◎ |
| Firebase hosting | 10GB まで無料で以降従量制 | 数MB/s| 約5ms  | ○|
| Vercel| 個人アカウントは無料だが非営利目的に限る | 2.8 MB/s| 2.3 ms | ? |

広告を貼る際はVercelのhobby planは無料で使えない様子。

#GitHub Pages vs Netlify
>現時点で Jekyll のバージョンは 3.9.0 に固定されており、 使用できるプラグインが限定的。 
一方 Netlify では各サイトのビルドを独立した環境で行うため、 このような制約がありません。
>また Netlify ではデプロイ時のログを見ることができるため、 トラブルシューティングがしやすいです。
>GitHub Pages はローカルに静的サイト構築フレームワークをインストールしなくても使えるため手軽ですが、 ある程度使い込むとなると Netlify の方が良い。(引用: https://bit.ly/3wMwySS)

らしい。


>※Jekyllとは・・・個人、プロジェクト又は組織のサイト向けの、簡単で、ブログのような静的サイトジェネレーターである。 GitHubの共同創業者であるトム・プレストン・ワーナーによって開発が開始され、Rubyで記述されており、自由ソフトウェアライセンスのMIT Licenseの条件に基づいて配布されている。 ([Wikipediaより引用](https://bityl.co/6IkP))


#Netlify vs Vercel
>Netlify の無料プランの場合、CDN は世界で 8 箇所しかなく、日本は含まれていない
[Netlifyは遅い](https://bit.ly/3mpZJq0)らしい。


・[NetlifyからVercelへの移行を検討した話](https://bityl.co/6IkZ)


#結論
調べたけど、とりあえずNetlifyで、PV数取れてきたらレンタルサーバーに移行でいい気がするなぁ。

#参考サイト様
企業規模で運用した場合の比較が書いてありとても参考になります↓
[静的 Web サイトホスティングサービス比較](https://qiita.com/changeworld/items/27bc292ec96da53fbc47)
after_createとafter_updateを共存させるとオーバーライドするからafter_commitでまとめちゃう！の時に立ち止まって考えること

# この記事で伝えたいこと

単純にafter_createとafter_updateがまとまったのがafter_commitというわけではないよ、ということ

# 経緯

実装でafter_create_commitが宣言されていて、
「あ、これと同じようなことをupdateでもやりたいから、下にafter_updateしちゃえ」
ってやろうとしたら、どうやらrailsガイドに注意書きが

https://railsguides.jp/active_record_callbacks.html

どうやらオーバーライドされてしまうらしい。
ということでじゃあ、after_commitでまとめるかーって単純な発想になったのだけど、そもそもこれら、実行されるタイミングが違うのです。


# DBに保存（commit）される前か後という大きな違い

使えるメソッドがまず変わってきます。
DB保存後はattrbutes_wasみたいなのが使えないです。

この記事のような。
https://qiita.com/htz/items/56798d53ec5988733fc6

commit内で条件分岐するときや判定が必要な時は気をつけましょう。
createとupdateをまとめるときはafter_commitにまとめるのはいいと思うのですが
まとめた後のことも考えた方が良さそうです。。。。
【Vue.js】【i18n】vueファイルごとにメッセージを設定【4つの手順で簡単実装】

# なぜ、vueファイルごとにメッセージを設定する？
Vueファイルは単一ファイルコンポーネントとして実装することができ、一つのファイルでコンポーネントを完結させることができます。
一つのファイルで一つのコンポーネントを作ることが一般的なVueでは、「Vueで管理するi18nメッセージを外部ファイルとして設定」より「vueファイルに設定」の方が、Vueとして自然な構成でありメンテしやすいと思います。

公式: https://kazupon.github.io/vue-i18n/guide/sfc.html#basic-usage

# 4つの手順
4つの手順でvueファイルごとにメッセージを設定することができるようになります。

## moduleをinstall
まず、vue-i18n関連のmoduleをインストールします。

必要なモジュールは以下です。

- vue-i18n : 翻訳機能を提供するmodule
- vue-i18n-loader : vueファイルにi18nメッセージを設定するためのmodule

以下のコマンドでvue-i18n本体をインストールします。

```bash
npm install vue-i18n
```

続いて、以下のコマンドでvue-i18n-loaderをインストールします。

```bash
npm install --save-dev @kazupon/vue-i18n-loader
```

## vue-i18n-loaderを設定
vue.config.jsにvue-i18n-loaderを設定します。

```vue.config.js
module.exports = {
  chainWebpack: config => {
    config.module
      .rule('i18n')
      .resourceQuery(/blockType=i18n/)
      .type('javascript/auto')
      .use('i18n')
        .loader('@kazupon/vue-i18n-loader')
        .end();
  }
}
```

この設定でi18nタグを利用できるようになります。

## Vueにvue-i18nプラグインをインストール
Vueにvue-18nプラグインをインストールします。

```src/main.js
import Vue from 'vue'
import VueI18n from 'vue-i18n'
import App from './App.vue'

Vue.use(VueI18n)
Vue.config.productionTip = false

const i18n = new VueI18n({
  locale: 'ja',
  messages: {
    ja: {},
    en: {}
  }
})

new Vue({
  i18n,
  render: h => h(App),
}).$mount('#app')
```

Vue.useメソッドでvue-i18nをインストールします。
VueI18nのオブジェクトを生成してVueのコンストラクタに設定することで、言語のデフォルト設定や共通のメッセージを設定することができます。

## vueファイルにメッセージを適用
vueファイルにメッセージを適用します。

```src/App.vue
<i18n>
{
  "en": {
    "helloWorld": "Welcome to Your Vue.js App"
  },
  "ja": {
    "helloWorld": "ようこそ、あなたのVue.jsアプリへ"
  }
}
</i18n>

<template>
  <div id="app">
    <img alt="Vue logo" src="./assets/logo.png">
    <HelloWorld :msg="$t('helloWorld')"/>
  </div>
</template>
```

メッセージはi18nタグで設定します。
$tメソッドでメッセージを出力することができます。

# 【おまけ】動作確認用に言語切替機能を実装
ここからはおまけです。
動作確認用に言語を切り替えるサンプルを公開します。

```src/App.vue
<i18n>
{
  "en": {
    "helloWorld": "Welcome to Your Vue.js App"
  },
  "ja": {
    "helloWorld": "ようこそ、あなたのVue.jsアプリへ"
  }
}
</i18n>

<template>
  <div id="app">
    <select v-model="locale" class="locale">
      <option value="en">English</option>
      <option value="ja">日本語</option>
    </select>
    <img alt="Vue logo" src="./assets/logo.png">
    <HelloWorld :msg="$t('helloWorld')"/>
  </div>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
  name: 'App',
  components: {
    HelloWorld
  },
  computed: {
    locale: {
      get() {
        return this.$i18n.locale
      },
      set(locale) {
        this.$i18n.locale = locale
      }
    }
  }
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
.locale {
  position: fixed;
  top: 16px;
  right: 20px;
}
</style>
```
GIt タグの一覧を出力する

# 目的

- 現在のタグの一覧を出力する方法をメモ的にまとめる

# 方法

1. ローカルリポジトリ内部で下記コマンドを実行する。

    ```terminal
    $ git fetch
    $ git tag
    ```

1. タグの一覧が出力される。
OpenCVのOCR(tesseract-ocr)をWindows(64bit)、C++で使う(vcpkgで簡単インストール)

vckpgのみで可能だと思ったので記載。
以下を参考にさせていただきました。
https://qiita.com/lilac0011/items/9fe6e061c3a036689a36

# 使うもの(バージョン)
* [Visual Studio Community](https://visualstudio.microsoft.com/ja/downloads/)(2019)
* [vcpkg](https://github.com/microsoft/vcpkg)
    * [tesseract-ocr](https://github.com/tesseract-ocr/tesseract/)(4.1.1)
    * [opencv4](https://github.com/opencv/opencv)(4.5.1)

# vcpkgインストール
vcpkgのGitHubにある通り、以下でvcpkgをインストール
※実行したフォルダがインストール場所になる

```
> git clone https://github.com/microsoft/vcpkg
> .\vcpkg\bootstrap-vcpkg.bat
```

# opencv + contrib(text)とtesseract-ocrインストール
### contrib(text)インストールのための設定
以下のファイルにtextをインストールするための設定を追加

* profile.cmake
    * vcpkg_check_featuresにtextオプションを追加
* vcpkg.json
    * textオプションの追加と依存関係を記載
    * 前後関係から`,`の付け忘れに注意

```cmake:.\vcpkg\ports\opencv4\portfile.cmake
vcpkg_check_features(OUT_FEATURE_OPTIONS FEATURE_OPTIONS
 "ade"      WITH_ADE
 "contrib"  WITH_CONTRIB
 "cuda"     WITH_CUBLAS
 "cuda"     WITH_CUDA
 "eigen"    WITH_EIGEN
 "ffmpeg"   WITH_FFMPEG
 "gdcm"     WITH_GDCM
 "halide"   WITH_HALIDE
 "jasper"   WITH_JASPER
 "jpeg"     WITH_JPEG
 "lapack"   WITH_LAPACK
 "nonfree"  OPENCV_ENABLE_NONFREE
 "openexr"  WITH_OPENEXR
 "opengl"   WITH_OPENGL
 "png"      WITH_PNG
 "qt"       WITH_QT
 "quirc"    WITH_QUIRC
 "sfm"      BUILD_opencv_sfm
 "tiff"     WITH_TIFF
 "vtk"      WITH_VTK
 "webp"     WITH_WEBP
 "world"    BUILD_opencv_world
 "text"     BUILD_opencv_text
)
```

```json:.\vcpkg\ports\opencv4\vcpkg.json
    "text": {
      "description": "Scene Text Detection and Recognition in Natural Scene Images",
      "dependencies": [
        {
          "name": "opencv4",
          "features": [
            "contrib"
          ]
        }
      ]
    }
```

### インストール

```
vcpkg install opencv4[text]:x64-windows
```

Visual Studioで利用するように以下で構築

```
vcpkg integrate install
```

### おわりに
あとは、学習済みデータを[tessdataリポジトリ](https://github.com/tesseract-ocr/tessdata)やtesseract-ocrの[Windows用インストーラ](https://github.com/UB-Mannheim/tesseract/wiki)から取得すれば使用できます。

以前はやたらと苦戦して構築したopencvでのocr環境がパッケージマネージャで簡単に構築できるようになりました。
これなら次に利用する際にも簡単にできそう。
AWSアカウントについて

先日AWSの登録をしたのですがその際にルートユーザーとIAMユーザーの２種類があり、その違いが分からなかったのでざっくりと纏めて見ました。これから登録される方の助けになれば幸いです。

##AWSのユーザーについて

AWSでは新規登録をするとルートユーザーが作成されます。このルートユーザーは普段は使用はせずに作業用としてIAMユーザーを使用することが推奨されています。

では、この２種類のユーザーの違いは何があるのか？

●ルートユーザー
アカウントすべてのAWSサービスとAWSリソースに完全なアクセス権を持つ特権ユーザー。
アカウントの変更・解約・サポートプランの変更等をする時のみ使用する。

●IAMユーザー（作業用ユーザー）
AWSで基本的に作業するユーザー
認証情報とアクセス許可の権限を個別に変更できる
作業者ごとに個別に作成する
通常の作業はIAMユーザーで行う。

##IAMの登録方法

IAMの設定画面の左側のメニューバーにあるユーザーにとぶ。そこでユーザーを追加でユーザー詳細の設定をしていきます。
ユーザー名は任意の名前で大丈夫です。AWSのアクセスの種類はコマンドラインなどのプログラムによるアクセスとマネージメントコンソール（AWSのサービス画面）から操作する方法の２種類があります。お好みのアクセス方法を選択して下さい。

次に進むを押すとユーザーのアクセス許可の設定を出来ます。
最初は既存のポリシーを直接アタッチ（AWS側である程度の設定を用意してくれています）でよいかと思います。なるべく無駄な権限は付与しない方がベストみたいです。

次の画面のタグの追加は、該当ユーザーがどのような役割なのかを付与できます。
必要に応じて設定してください。

以上でIAMユーザーの登録は完了ですが、登録完了後に出るサインイン用のURLが表示されるのでどこにコピーすることをお勧めします。


##最後に
AWSはサービスがたくさんあって覚えることが多いですが、楽しんで覚えられるように頑張りたいと思います。

参考サイト
※解説を詳しくして下さっているのでとてもお勧めです。

https://www.udemy.com/course/aws-and-infra/
Outlook予定表からTeams会議を作成すると「オンラインで参加」ボタンが表示されない予定になってしまう

##ある日
Teams会議をOutlook予定表から作成したところ、「オンラインで参加する」ボタンが表示されない、ただの予定になっていることが分かった。


##実際にTeams会議を作成してみる
１．「新しいTeams会議」を押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482157/a5c8b9e1-329d-0ede-cf17-a51929cef14d.png)

２．タイトルなど必要項目を入力し、「送信」を押下する
※「新しいTeams会議」から作成したため、「場所」と会議のリンクがデフォルトで入力されている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482157/cad5c113-5acc-04b8-042c-bf38dfbb17b1.png)

３．会議の予定が作成されたので再度詳細を見てみる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482157/66ae8dd1-c52f-0bac-102f-f91e53f613f0.png)
**「場所」が消えている！！
会議のリンクもなくなっている！！**

→このため、「オンラインで参加する」ボタンが表示されないただのスケジュールが出来上がる。

##原因
メールがテキスト形式になっているため
(前はテキスト形式でも問題なかった気がするのだが。。。)


##対策
* Teams会議を作成するときだけHTML形式(リッチテキストでもよい)にする
* 作成後、再度詳細を開いて、「場所」に「Microsoft Teams 会議」を入力する

※HTMLのリボンかアクセスツールバーを作成しておくとショートカットが使えて便利かもしれません。

##まとめ
Microsoftさん。。テキスト形式でも会議作成できるようにできませんか。。



以上です。
【Pandas】最新のCSVファイルを読み込む方法 .no.33

![見出しを追加 (82).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/e8492438-19da-9dc4-155b-0772e8e19972.png)

こんにちは、まゆみです。

Pandasについての記事をシリーズで書いています。

今回は第33回目になります。

今までの記事では、<font color="Red">自分のパソコンにダウンロード済みのcsv</font>を読み込んでPandasでそのデータに計算を施したり、順番を並べ替えたりする方法を書いてきました。


![見出しを追加 (81).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/b6874424-2afa-1973-81aa-2b6c9f9a3b44.png)

ということで、今回の記事では最新のCSVファイルを読み込む方法について書いていきます。

ではさっそく始めていきます

#今回の記事で使うデータ

今回は、たくさんのデータを提供してくれるサイトを紹介します
![スクリーンショット 2021-04-08 085340.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/21731bca-7d24-be87-6341-c4608da3c5c7.jpeg)
[NYC Open Dataへのアクセスはこちらから](https://opendata.cityofnewyork.us/data/)

データがカテゴリー別に分かれているので、興味のある分野を選んで、調べてみたいデータを使ってくださいね。

##csvデータのURLを使う

使いたいデータが決まりましたら、

「Export」➡　「CSV」 ➡　「リンクをコピー」の順に進みます

![スクリーンショット 2021-04-08 091637.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/9d9b9936-d0ae-585b-130f-847c98da49b2.jpeg)

コピーしたリンクは下記のようになりますが、「?accessType...」以下は要らないので

![スクリーンショット 2021-04-08 091705.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/896b6761-8863-53ee-7d38-82e6c2444d49.jpeg)

下記のスクショのように、要らない部分を削除したURLのみコピーします。

![スクリーンショット 2021-04-08 091723.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/1bd3bb1f-a1c5-0bdf-c478-89520bff226c.jpeg)

##.read_csv()で読み込む

今までの記事で紹介したように、Pandasの.read_csv()メソッドを使ってcsvを読み込むのですが、

>今回はすでにダウンロードされたcsvではなく

>常にアップロードしているweb上のcsvを読み込むので

先ほどコピーしたcsvのURLを、url=　という変数に代入して、.read_csv()の引数として渡します。

![スクリーンショット 2021-04-08 093128.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/8e8c159d-c788-b037-99a5-ee9a92654a59.jpeg)

最新のデータを読み込むことができました。

#まとめ

今回の記事はこれで終わりにします。

次回の記事では、今回と同じデータを使って、特定のコラムをPythonのリストにしたり、辞書にする方法をお伝えしていきますね。
ComposeをFragmentの上で動かすときちょっとハマったこと

# 内容

`Activity`に `FragmentContainerView`をおいて、 `fragmentManager`使って `Fragment`を設置したとします。

 `Fragment`はというと

```kotlin
class MainFragment : Fragment() {
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        return ComposeView(requireContext()).apply {
            setContent {
                ComposenavigationsampleTheme {
                    Surface(color = Color.Green) {
                        Text(text = "This is Compose on MainFragment")
                    }
                }
            }
        }
    }
}
```

一見うまくいきそうですが、実行するとこんなエラーが

```kotlin
java.lang.IllegalStateException: ViewTreeLifecycleOwner not found from DecorView@ef08ca9[MainActivity]
```

調べてみると、Compose UIコンテンツを `Fragment`や既存のViewレイアウトに組み込む場合は、 `ComposeView` を使用して、その `setContent()`メソッドを呼び出すのですが、 `ComposeView`

を `ViewTreeLifecycleOwner`にアタッチする必要があるようです。

なので具体的には `Activity`の `onCreate()`で `ViewTreeLifecycleOwner.set(window.decorView, this)`を追加してあげる必要があります。

結果的に `Activity`はというと

```kotlin
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        ViewTreeLifecycleOwner.set(window.decorView, this)

        if (savedInstanceState == null) {
            val fragmentManager = supportFragmentManager
            val fragmentTransaction = fragmentManager.beginTransaction()
            fragmentTransaction.replace(R.id.container, MainFragment())
            fragmentTransaction.commit()
        }
    }
}
```

これで、 `MainActivity`→ `MainFragment`→ `ComposeView`というような感じでComposeでのUI構築ができるようになりました。

これを使えば既存のプロジェクトに画面ごとにCompose移行ができそうな感じがします。

## 追記2021/05/29
`MainActivity`で `ComponentActivity`を継承すれば `ViewTreeLifecycleOwner.set`する必要はないみたいです。
では、既存のプロジェクトでComposeをFragment1つずつに徐々に入れていきたいとき、そうすればいいんじゃ？と思ったのですが、いきなり大元のActivityを `ComponentActivity`を継承するものにしてしまうと `supportFragmentManager`が使えなくなってしまってちょっときつそうです。


# 参考

- [https://satoshun.github.io/2020/02/jetpack-find-view-tree-lifecycle-owner/](https://satoshun.github.io/2020/02/jetpack-find-view-tree-lifecycle-owner/)
- [https://qiita.com/takahirom/items/ced09e3cd9d5a984c3b2](https://qiita.com/takahirom/items/ced09e3cd9d5a984c3b2)
- [https://developer.android.com/jetpack/compose/interop](https://developer.android.com/jetpack/compose/interop)
【21.03.31-0401】Luxy.jsを導入する


#にゅわっとスクロールするやつの正体

一つ一つの要素にいちいちアニメーションをつけているのかなと思っていたが、
メンターさんに聴いた所、「慣性スクロール」「パララックス」というエフェクト？で、
Luxy.jsを導入するのがおすすめだと聞いたので導入してみたいと思う

#まずは公式ドキュメントをみてみる

https://min30327.github.io/luxy.js/

#手順

###①npmもしくはgithubから、luxy.jsをDLしてプロジェクトファイルに入れ込む

1. npmでインストールの場合

ターミナルで

```terminal.terminal
$ npm install luxy.js --save
```
を叩く(もちろんプロジェクトファイルの中に移動してから）

↓npmコマンドについての補足

```
//インストール
% npm install (パッケージ名) --save
//アンインストール
% npm uninstall (パッケージ名) --save


//--save
//package.jsonファイルにパッケージ情報がdependencyとして追記される

//-dev
//Sassなど、開発やテストのみで必要な場合、ローカルインストール(devDependencies)
//※jqueryなど実行に必要なパッケージの場合はつけなくてOK(dependencies)

```

###②HTMLのhead内にパスを通す

```index.html
<head>
   <script src="node_modules/luxy.js/dist/js/luxy.min.js"></script>
</head>
```

※パスは適宜変えてください。npmでインストールした場合はこれでokなはず。

###③bodyの最後に以下を追加

```index.html

    //ここから
    <script charset="utf-8">
        luxy.init();
    </script>
　　//ここまでを記述

    //これより下は任意です。イメージのために入れてます・
    <script src="//code.jquery.com/jquery-3.3.1.js"></script>
    <script src="https://unpkg.com/swiper/swiper-bundle.min.js"></script>
    <script src="script.js"></script>
</body>
```


###④適用させたい要素を#luxyで包む

大体mainにid="luxy"付ければok

```index.html

<header>ヘッダー</head>
<main id="luxy">
　メインコンテンツ
</main>
```

ここまでで慣性スクロールは適用されているはずです。

###⑤スマホ・iPadの慣性スクロールをオフにする

##パララックスを適用させるには

| 1 | 2 |
|:-:|:-:|
| data-offset  | ピクセル単位のオフセット（座標、表示位置）を指定できます  |
| data-speed-y  | 垂直方向のパララックススクロール効果の速度を指定できます  |
| data-horizontal  |  ‘1’ に設定すると、水平視差スクロールを有効にできます |
|  data-speed-x |  水平方向のパララックススクロール効果の速度を指定できます |
【Javascript】5秒後にページ遷移する方法

ドメインの変更などで新しいサイトに遷移する方法のメモ

.htaccessでリダイレクトするのが一般的なのですが、
この方法をつかえばページ単位で使うこともできるのと.htaccessの細かい設定をせずに実装できます。


``` javascript
setTimeout(function(){
  window.location.href = 'https://xxxxxx.com';
}, 5*1000);
```

`setTimeout`で秒数を指定。
`window.location.href`で遷移するサイトを指定します。

デメリットはアナリティクスの流入元がすべて前のドメインになることぐらいでしょうか。
KarateをProxy環境下で実行する

# はじめに

Karateは、Cucumberと同様のBDD（ビヘイビア駆動開発）を行うためのフレームワークであり、Gherkinの文法を自然言語に近い形で記述できるユニットテストツールです。
Karateについては、以下を参照してください。

- [APIテスト自動化ツール「Karate」のまとめ](https://qiita.com/takanorig/items/46098b066f1216e3ca89)

# Proxy 環境下での実行

Karateは、HTTP／HTTPS経由でテストを行うため、Proxyの影響を受けます。
Proxy環境下で実行したい場合は、```karate-config.js``` で、以下の★印部分のように指定します。

```js:karate-config.js
function() {    
  var env = karate.env; // get system property 'karate.env'
  karate.log('karate.env system property was:', env);
  if (!env) {
    env = 'dev';
  }
  var config = {
    env: env,
    myBaseUrl: 'http://localhost:8089',
    myVarName: karate.properties['MY_VAR_NAME']
  }
  if (env == 'dev') {
    // customize
    // e.g. config.foo = 'bar';
  } else if (env == 'e2e') {
    // customize
  }

  // ★Proxy指定
  karate.configure('proxy', { uri: 'http://my.proxy.host:8080' });
  // 認証ありの場合
  // karate.configure('proxy', { uri: 'http://my.proxy.host:8080', username: 'myuser', password: 'mypass' });


  return config;
}
```
【Vue.js】v-bindの省略記法メモ

v-bindの省略記法について

```html
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.7/dist/vue.js"></script>

<div id="app">
  <h1 :class="{red : isActive, 'bg-blue' : !isActive}">Hello</h1>
  <button @click="isActive = !isActive">切り替え</button>
</div>
```

```js
new Vue ({
	el: '#app',
  data: {
  	isActive: true
  }
})
```

```css
.red {
  color: red;
}

.bg-blue {
  background-color: blue;
}
```

``:class``これはv-bindの省略記法。
MySQLで日本語が???と表示されてしまう時の対処法

## こう表示されていました

```sql
mysql> select * from tags;

+----+-----------+----------------------------+----------------------------+
| id | name      | created_at                 | updated_at                 |
+----+-----------+----------------------------+----------------------------+
|  1 | ???       | 2021-04-07 23:52:14.766919 | 2021-04-07 23:52:14.766919 |
|  2 | ??        | 2021-04-07 23:52:14.811726 | 2021-04-07 23:52:14.811726 |
|  3 | ??        | 2021-04-07 23:52:14.831898 | 2021-04-07 23:52:14.831898 |
|  4 | ???       | 2021-04-07 23:52:14.848186 | 2021-04-07 23:52:14.848186 |
|  5 | ??        | 2021-04-07 23:52:15.171303 | 2021-04-07 23:52:15.171303 |
|  6 | ????????? | 2021-04-07 23:52:15.537739 | 2021-04-07 23:52:15.537739 |
|  7 | ??        | 2021-04-07 23:52:15.653962 | 2021-04-07 23:52:15.653962 |
|  8 | ??        | 2021-04-07 23:52:15.787906 | 2021-04-07 23:52:15.787906 |
|  9 | ??        | 2021-04-07 23:52:15.900384 | 2021-04-07 23:52:15.900384 |
| 10 | ??        | 2021-04-07 23:52:15.917328 | 2021-04-07 23:52:15.917328 |
| 11 | ???       | 2021-04-07 23:52:15.929639 | 2021-04-07 23:52:15.929639 |
| 12 | ????      | 2021-04-07 23:52:15.941627 | 2021-04-07 23:52:15.941627 |
| 13 | ??        | 2021-04-07 23:52:15.954311 | 2021-04-07 23:52:15.954311 |
+----+-----------+----------------------------+----------------------------+
```

## 解決方法

このコマンドで、日本語表示を可能にする。

```sql
mysql> set names utf8;
```


```sql
mysql> select * from tags;

+----+-----------------------------+----------------------------+----------------------------+
| id | name                        | created_at                 | updated_at                 |
+----+-----------------------------+----------------------------+----------------------------+
|  1 | 食べ物                   | 2021-04-07 23:52:14.766919 | 2021-04-07 23:52:14.766919 |
|  2 | 転職                      | 2021-04-07 23:52:14.811726 | 2021-04-07 23:52:14.811726 |
|  3 | 生活                      | 2021-04-07 23:52:14.831898 | 2021-04-07 23:52:14.831898 |
|  4 | 街並み                   | 2021-04-07 23:52:14.848186 | 2021-04-07 23:52:14.848186 |
|  5 | 仕事                      | 2021-04-07 23:52:15.171303 | 2021-04-07 23:52:15.171303 |
|  6 | ワーキングホリデー | 2021-04-07 23:52:15.537739 | 2021-04-07 23:52:15.537739 |
|  7 | 観光                      | 2021-04-07 23:52:15.653962 | 2021-04-07 23:52:15.653962 |
|  8 | 移住                      | 2021-04-07 23:52:15.787906 | 2021-04-07 23:52:15.787906 |
|  9 | 散歩                      | 2021-04-07 23:52:15.900384 | 2021-04-07 23:52:15.900384 |
| 10 | 留学                      | 2021-04-07 23:52:15.917328 | 2021-04-07 23:52:15.917328 |
| 11 | カフェ                   | 2021-04-07 23:52:15.929639 | 2021-04-07 23:52:15.929639 |
| 12 | ドイツ語                | 2021-04-07 23:52:15.941627 | 2021-04-07 23:52:15.941627 |
| 13 | 天候                      | 2021-04-07 23:52:15.954311 | 2021-04-07 23:52:15.954311 |
+----+-----------------------------+----------------------------+----------------------------+
```


参考;
https://dev.mysql.com/
[AWS] aws cliで、EC2のスナップショットIDの一覧を取得する

![EC2ヘッダ画像.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34875/16f77c88-e5b1-4872-23d5-0d35213aca2f.png)

aws cliを利用して、EC2のスナップショットIDの一覧を取得する方法を紹介します。

## aws cliのバージョン

```zsh
% aws --version
aws-cli/2.1.28 Python/3.8.8 Darwin/20.3.0 exe/x86_64 prompt/off
```

## リージョンとプロファイルの設定

```zsh
% export AWS_DEFAULT_REGION=ap-northeast-1
% export AWS_PROFILE=xxxx
```

## スナップショットIDの一覧を取得

```zsh
% aws ec2 describe-snapshots \
--query "Snapshots[*].[SnapshotId]" \
--owner-ids self \
--output text \
--no-cli-pager
```

## 実行結果

```zsh
snap-XXb21e34857fXXXXX
snap-XX6b9ae9820aXXXXX
snap-XX42a5e4f320XXXXX
snap-XX89dd6d4a27XXXXX
snap-XXe5d373fc47XXXXX
```
[AWS] aws cliで、EC2スナップショットを一括で削除する

![EC2ヘッダ画像.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34875/bb393ecc-94e9-c03c-78e8-4989ffd38edc.png)

aws cliを利用して、EC2のスナップショットを一括で削除する方法を紹介します。

## aws cliのバージョン

```zsh
% aws --version
aws-cli/2.1.28 Python/3.8.8 Darwin/20.3.0 exe/x86_64 prompt/off
```

## リージョンとプロファイルの設定

```zsh
% export AWS_DEFAULT_REGION=ap-northeast-1
% export AWS_PROFILE=xxxxx
```

## スナップショットを一括で削除する

describe-snapshots でスナップショットのリストを取得し、xargsコマンドでdelete-snapshotの引数として設定します。

```zsh
aws ec2 describe-snapshots \
--query "Snapshots[*].[SnapshotId]" \
--owner-ids self \
--output text \
--no-cli-pager | \
xargs -I{} aws ec2 delete-snapshot \
--snapshot-id {}
```
【Youtube】APIキーの取得手順（2021/04/08時点のキャプチャ）

# はじめに
YoutubeのAPIがあれば動画情報の取得が出来ます。
YoutubeはWEBスクレイピングを規約違反としているのでAPI経由で情報を取得する必要があります。

私は↓のPythonライブラリと組み合わせて自動動画取得ツールを作成予定です。

https://qiita.com/shinkai_/items/7175215d7433b4cf150c

普段使うサービスなので新人プログラマがAPIの勉強をするのにもピッタリだと思います。

# Google Cloud Platformにアクセス

※Googleアカウントを取得していることが前提です。

Google Cloud Platformのコンソールにアクセスします。

https://console.cloud.google.com/

こんな画面です。

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1203022/228c5d97-cb82-fd6b-a5a2-60bc0b3c44d1.png)

# プロジェクトの新規作成
画面左上の**「プロジェクトの選択」**をクリックし、メニューを開いてください。

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1203022/86912068-803b-7978-fe59-34e4fe887412.png)

**「新しいプロジェクト」**をクリックします。
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1203022/a8dfd8cf-4e6e-52f8-e5fd-ab704ebc0aac.png)

任意のプロジェクト名を入力し、**「作成」**をクリックします。

![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1203022/8cdb1b92-8b83-ca13-0c1b-8630885a277f.png)

作成に少し時間がかかります。
完了すると通知がきます。

![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1203022/d7e3b40b-f7d4-e76f-5ad8-eb96e99df1a0.png)

# APIライブラリの有効化
次にAPIライブラリを有効にします。

画面左上の**メニュー** ＞ **APIとサービス** ＞ **ライブラリ**　の順で選択します。

![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1203022/8c1aa21b-cf79-0d38-9f0d-4761ad2b49dc.png)

先程作成したプロジェクトを選択します。

![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1203022/de46b0df-52cf-52cc-7658-bc033b154dbe.png)

**APIとサービスを検索**の入力欄に**「YouTube Data API v3」**と入力します。

![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1203022/ac69a20b-b34d-01d4-9eae-acc2a61089c1.png)

**「YouTube Data API v3」**をクリックします。

![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1203022/21f39553-e534-3fda-4d65-1c62d6e56000.png)

**「有効にする」**をクリックします。

![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1203022/eadecc8e-4376-706c-620d-5e394a9a5d5f.png)

有効化まで少し時間がかかります。
有効化後の画面で次の認証情報の作成を行います。

# 認証情報の作成（APIキーの作成）
**「認証情報」**をクリックします。

![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1203022/08614cb2-a6f8-e3e7-cd67-1f6b99e73b64.png)

**「認証情報を作成」**をクリックし、**「APIキー」**をクリックします。

![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1203022/ddff7b77-1f3f-eb4a-7dfb-7cb270c3e4f6.png)

APIキーが作成されます。

![13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1203022/cc7aea47-061a-837d-44f8-2864019b4e4a.png)

続けて**「キー制限」**をクリックします。
APIの制限のラジオボタン**「キーを制限」**を選択し、**「YouTube Data API v3」**を選択、**「保存」**をクリックします。

![14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1203022/dbfdf8c1-fea9-dede-b67e-01b4c1828c14.png)

以上です。快適なYoutubeライフを！
【Windowsユーザー必見】エイリアスを永続的に登録して開発効率を爆上げしよう！！（複数コマンド、引数偏）

皆さんこんにちは！

前回書いた[【Windowsユーザー必見】エイリアスを永続的に登録して開発効率を爆上げしよう！！](https://qiita.com/akki-memo/items/6c8d8ec1f649f874a225)この記事。

エイリアスと言うものを登録して開発速度を上げる話をしました。

詳しく知りたいという方はぜひ記事をご覧ください！

今回は前回とは違う内容をお届けします。

どういうことかと言うと、タイトルにも書いてる通り複数コマンドを行えるようにしたり、``npm install firebase``のように毎回違う値を引き取る場合のエイリアスをご紹介します。

それでは早速説明を見ていきましょう！

#複数コマンドの登録#

複数コマンドを登録するには、マクロ登録時にコマンドとコマンドの間に``$t``を記述します。

以下はGitで新しくリポジトリを作成するときの一例です。

```powershell
doskey gcauto=git init $t git add . $t git commit -m "first commit" $t git branch -M main $t git remote add origin $* $t git push -u origin main
```

コマンドとコマンドの間に``$t``がありますよね。

これで普段の``git init && git add .``と同じ機能になります。

#引数を受け取る#

ここで、先ほどのコマンド一部分``git remote add origin $*``の``$*``は何なのか。。。

これが引数を受け取る記号となります。

つまりどういうことか。。。

例えば``npm install firebase``を実行したい場合は以下のようにエイリアスを登録します。


```powershell
doskey ni=npm install $*
```

こうすることで``npm install firebase``や``npm install jquery``など毎回違う値でもしっかりとその値を受け取てくれます！！！

このようにして複数コマンドと引数を受けとることが可能です！

どんどん開発速度上げていきましょう！

以上、「【Windowsユーザー必見】エイリアスを永続的に登録して開発効率を爆上げしよう！！（複数コマンド、引数偏）」でした！

Thank you for reading
【Rails】acts-as-taggable-onの区切り文字の変更

- タグ機能を実装時にてまどったので備忘録として、残しておきます

# 環境

- Rails 6.1.3
- acts-as-taggable-on 7.0.0

# デフォルト

デフォルトでは`,`が区切りとなり、複数のタグに分割してくれる。

```ruby:例)デフォルト
class User < ActiveRecord::Base
  acts_as_taggable_on :tags
end
tag = ['ruby,javascript,react']
@user = User.create(tag_list: tag)
@user.tag_list = ['ruby','javascript','react']
```

# カスタマイズ

区切り文字を変更するのに前までは、メソッドを書いて処理していましたが github の README に変更方法を書いてありました。

```ruby
ActsAsTaggableOn.delimiter = ','
# ','を変更することで区切り文字を変更できる
# [',' , '|']のように配列で区切り文字を渡すことができます
```

config/initializers/tag.rb を作成し、その中に書く

```ruby:config/initializers/tag.rb
ActsAsTaggableOn.delimiter = ' '
# これにより半角の空白で文字が区切られます
```

ちなみに、タグを追加するメソッド tag_list.add('文字列')　のときは分割はしてくれません

```ruby
tag_str = 'html css'
@user.tag_list.add(add_tag, parse: true)
@user.tag_list = ['ruby','javascript','react','html','css']
# parse: trueをつけることで区切り文字で分割してくれます
```

# まとめ

公式を確認することで解決できることがあるので、まずは公式を確認しましょう。
LeetCodeでブートキャンプ①

##この記事について
**考える力を付けたい。**
そのために最近知った[LeetCode](https://leetcode.com/)でコーディングの練習を始めました。
自分が辿った思考方法を文章化していきたいと思います。

ついでに英語の勉強もしたい！！！！


[LeetCodeについて説明されている記事](https://qiita.com/ktsujino/items/9cfa31dced5a68720485)


## 補足
僕は業務経験は半年もない、ペーペーのエンジニアです。
**優しくて、暖かすぎて熱くなるくらいの目**でこの記事を読んでください。


##問題（Two Sum）
```
Given an array of integers nums and an integer target, 
return indices of the two numbers such that they add up to target.

You may assume that each input would have exactly one solution, 
and you may not use the same element twice.

You can return the answer in any order.

Example 1:
Input: nums = [2,7,11,15], target = 9
Output: [0,1]
Output: Because nums[0] + nums[1] == 9, we return [0, 1].
```

###和訳（なんとなく）
```
整数が入った配列と、整数のtargetが与えるで。
足された合計がtargetになるindexを返してな。

同じ要素を２回使ったらダメよ！！
答えはどんな順番になっても大丈夫やで。
```

##最終的な僕の回答
```ruby
Input: nums = [2,7,11,15], target = 9


def two_sum(nums, target)
    output = []
    nums.each_with_index do |num1, i1|
        nums.each_with_index do |num2, i2|
            next if i1 == i2 || i1 > i2
            if num1 + num2 == target
                output << i1
                output << i2
            end
        end
    end
    
    output
end

Output: [0,1]
```

##思考軌跡

###其の１ each使う
配列を２回、回してそれぞれの要素足すようにしたらいいか。


```ruby
Input: nums = [2,7,11,15], target = 9


def two_sum(nums, target)
    output = []
    nums.each do |num1|
        nums.each do |num2|
        end
        end
    end
    
    output
end
```

これやと、どのindex同士が足されたか分からんなぁ。。。



###其の2　each_with_index使う
`each_with_index`で要素番号分かるようになったし、これでoutputに値を入れていけるわ！！！


```ruby
Input: nums = [2,7,11,15], target = 9

def two_sum(nums, target)
    output = []
    nums.each_with_index do |num1, i1|
        nums.each_with_index do |num2, i2|
            next if i1 == i2
            if num1 + num2 == target
                output << i1
                output << i2
            end
        end
    end
    
    output
end


Output: [0,1,1,0]
```


返ってきた値が`[0,1,1,0]`になってる。
１度足された同士の要素は計算しいひんようにせなあかんな。



###其の3 next ifの条件を変える（完成！！！！）


`i1 > i2`、で最初のeachのindexが、２つ目のeachのindexよりも大きい場合はnextで次の繰り返しに行くようにした。



```ruby
Input: nums = [2,7,11,15], target = 9


def two_sum(nums, target)
    output = []
    nums.each_with_index do |num1, i1|
        nums.each_with_index do |num2, i2|
            next if i1 == i2 || i1 > i2
            if num1 + num2 == target
                output << i1
                output << i2
            end
        end
    end
    
    output
end


Output: [0,1]　　#できた！！！！
```


## 感想
バリバリのエンジニアの方やったらもっとシンプルに記述できるんでしょうな。。。
簡単とは言え、ヒントも見ずに問題を解けるのは嬉しい。
画像閲覧＆Basic認証付き簡易HTTPサーバー

### Summary

PCのフォルダにある画像を、同じネットワーク上のスマホやタブレットから簡単に見たくなったので、Pythonの勉強がてら作成。

Python3 の http.server.SimpleHTTPRequestHandler にある list_directory を利用して、少し改造。必要に応じて、Basic認証も利用可能。

- 画像のあるディレクトリのルートで、サクッとスクリプトを起動して利用可能。インターネット上での使用ではなく、家の中での使用を想定。
- 画像が複数のディレクトリに整理されている場合でも、リンクをクリックして、それぞれのサブディレクトリに移動して画像を閲覧可能。
- 画像ファイルは、リンクではなく、スマホやタブレットの画面にちょうどいいサイズで表示。
- 画像以外のファイルやディレクトリは、元々の list_directory の機能のまま、リンクとして表示。

### Code

https://github.com/skwsk/authImgServer
Reactの基礎の基礎 #01Reactとは、JSXとは

## Reactとは
Facebook社が開発したJavaScriptのライブラリです。
比較対象にされることが多いVue.jsはフレームワークとなります。
フレームワークのほうが大きい枠となるんですが、ライブラリのReactが比較対象になっているのがすごいっぽい。
既存のWEBページにReactの一部を組み込むことが可能です。
VirtualDOMでDOM操作を行うことができる。変更された差分だけを再描画するのでパフォーマンスがあがります。

## JSX とは
こちらもFacebook社が開発したJavaScript内でHTMLを簡単に記述するための言語となります。
可読性の高い言語なのがうれしい。ただブラウザでは解釈できないので変換する必要があります。
それをトランスパイルと呼んでおり、有名なのがBabelやTypeScriptなどがある。

```jsx
return(
 <>
  <h1 className="title">Reactの勉強中</h1>
 <>
)
```

トランスパイルを使わずにReactを記述すると下記のように非常に可読性の低い文章となる。
（JSXで記述したコードをトランスパイルを使って変換すると、下記のコードになっている）

```jsx
React.creatElement(
 "h1",
 { className: 'title'},
 "Reactの勉強中です"
);
```


### jsxの文法
①Reactパッケージのインストール

```jsx
import React from "react"
```

②class, for, onclickの記述方法

```jsx
//クラス
NG:class
OK: className
//for
NG:for
OK: htmlFor
//クリック
NG:<button onclick="activate()">アクティブ</button>
OK:<button onClick={activate}>アクティブ</button>
```

③{}内に変数や関数を埋め込むことができる

```jsx
const foo = "<h1 className="title">Reactの勉強中</h1>"
const App = () => {
 return (
  <div id="hoge" className="fuga">
   {foo}
 </div>
);
};
```

④空要素は閉じタグをつける

```jsx
const App = () => {
 return (
  <div id="hoge">
   <input type="text" />
   <img src="assets/foo.png" />
  </div>
);
};
```

## まとめ
こちらの動画を見ながらまとめた記事となります。
Reactの学習をしていて、かなりつまづいているのですがひとつずつ理解を深めていくしかないですね。

https://www.youtube.com/channel/UC-bOAxx-YOsviSmqh8COR0w
【Firebase】デプロイのやり方


作成したアプリケーションをFirebaseにデプロイして、公開しましょう。

#Firebaseの設定
firebaseのコンソール画面のサイドバーから、**「Hosting」**を選択し、「始める」をクリックしてください。

![Something went wrong](https://img-host.wemotion.co.jp/uploads/afiuas.png)

以下のような画面になると思うので指示にある通りにコマンドを実行してください。

```
$ npm install -g firebase-tools
```

![Something went wrong](https://img-host.wemotion.co.jp/uploads/zsdf-iJ1.png)

続行をクリックすると以下のようになります。

![Something went wrong](https://img-host.wemotion.co.jp/uploads/ky79w4z.png)

指示通り、**$firebase login**を実行し、googleアカウントでログインしてください。

続いて、**$firebase init**を実行し、プロジェクトの作成をします。

以下のような画面になるので、**Hosting**をスペースキーで選択し、エンターを押してください。

![Something went wrong](https://img-host.wemotion.co.jp/uploads/rWjAK.png)

続いて、**Use an existing project**を選択し、エンターを押してください。

![Something went wrong](https://img-host.wemotion.co.jp/uploads/y2isXy.png)

続いて、**dist**と入力し、エンターを押してください。

![Something went wrong](https://img-host.wemotion.co.jp/uploads/dphsy.png)

続いて、**y**を入力し、エンターを押してください。

![Something went wrong](https://img-host.wemotion.co.jp/uploads/xF9BT.png)

次は、**N**を入力し、エンターを押してください。

![Something went wrong](https://img-host.wemotion.co.jp/uploads/RRmka.png)

以上でプロジェクトの設定は完了しました。

##デプロイの準備

続いて、アプリケーションをbuildしていきましょう。buildとは、vue.jsをブラウザ上で表示できるように変換することです。

以下のコマンドを実行しましょう

```
$ npm run build
```

実行が完了したら、distというディレクトリが作成されているかと思います。

この中に、vueファイルが、htmlファイルや、jsファイルに変換されて入っています。

##デプロイの実行

```
$ firebase deploy
```

を実行しましょう。

コマンドを実行したら、以下のような出力になります。

![Something went wrong](https://img-host.wemotion.co.jp/uploads/deploy.png)

Hosting URL:とあるところ、のURLにアクセスしてください。

正常にできていれば、アプリケーションをローカルで立ち上げていた時と同じように操作できるかと思います。
[Unity]シンプルなUniRxコードを練習で作ってみた

# 概要
UniRxを学ぶための短いサンプルコードを作ってみました。
# 導入
Package ManagerからUniRxをインポートします。
![スクリーンショット 2022-12-21 7.23.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/cdabcb0d-7f0e-827e-de2e-b322a5d1e753.png)


# 本文
C#ファイルを２つ作成します
KeySensorクラスはスペースキーが押されるタイミングでbool変数【button】の値を変更します

```cs
using UnityEngine;
using UniRx;

public class KeySensor : MonoBehaviour {
    public ReactiveProperty<bool> button = new ReactiveProperty<bool>(false);

    void Update() {
        if (Input.GetKeyDown(KeyCode.Space)) {
            button.Value = !button.Value;
        }
    }
}
```

PrinterクラスはKeySensorクラスが持つ【button】の値が**更新される**とCheckButtonTypeメソッドが実行されます。

```cs
using UnityEngine;
using UniRx;

public class Printer : MonoBehaviour {
    public KeySensor keySensor;

    void Start() {
        keySensor.button
            .SkipLatestValueOnSubscribe()
            .Subscribe(buttonType => CheckButtonType(buttonType));
    }

    public void CheckButtonType(bool buttonType) {
        if (buttonType) {
            Debug.Log("ON");
        } else {
            Debug.Log("OFF");
        }
    }
}
```

空のオブジェクト（今回は名前をKeySensorAndPrinterにしました）を作成してKeySensorとPrinterをAddComponentします。PrinterにはKeySensorをアタッチします。
![スクリーンショット 2022-12-21 7.57.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/e2ca9fae-3ec6-f351-a6b1-0fea26f25879.png)


実行するとスペースキーを押すたびにConsoleへメッセージが表示されるのが確認できます
![スクリーンショット 2022-12-21 7.50.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/1fd9700f-8b41-7f05-5f12-77ba3c10bf58.png)

# 補足

```cs
.SkipLatestValueOnSubscribe()
```

の部分を省略すると【button】の初期値にfalseを設定したタイミングも更新が行われたものとして扱われてしまいます。
Dockerからboto3を使ってEC2を停止する

boto3を動かす環境はDocker上に構築します。

# Dockerfile
AWSCLI v2もいっしょに入れておきます。

```dockerfile
FROM python:3
USER root

RUN apt-get update && apt-get install -y --no-install-recommends \
    curl \
    unzip \
    jq \
    less \
    vim \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
RUN unzip awscliv2.zip
RUN ./aws/install

RUN pip install --upgrade pip
RUN pip install --upgrade setuptools
RUN pip install boto3

```

# docker-compose.yml
boto3でAWSに接続するための認証はAWSCLIのクレデンシャルを使います。
PCローカルのホームディレクトリ`$HOME/.aws/credentials`にすでにアクセスキーの情報を書いてあるので、ボリュームでアタッチして共有します。Dockerの中に入ってから`aws configure`で設定したり、環境変数を設定する方法もありますが、使い捨てを考えるとこの方法が楽かと思います。

```yml
version: '3'
services:
  python3:
    build: .
    container_name: 'python3'
    working_dir: '/root/'
    tty: true
    volumes:
      - ./:/root
      - $HOME/.aws/:/root/.aws/
```

# コンテナを起動して接続
```bash
# ビルドと起動
docker-compose up -d --build

# 確認
docker-compose ps
 Name     Command   State   Ports
---------------------------------
python3   python3   Up

# 接続
docker-compose exec python3 bash
root@bbb321efbfea:~# 
```

# EC2停止のスクリプトを実行

EC2はAmazonLinux2のインスタンスを実行させていて、`AmazonLinux01`というNameタグをつけています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402286/b4bb1772-4c8b-65fc-20ee-6d1f11f64dff.png)

通常は`client.stop_instances()`にインスタンスIDを直接書いてあげればOKなのですが、今回はNameタグをもとにインスタンスIDを取得して変数に格納し、その変数を渡す方式にしてみました。

```py:main.py
import boto3

# variables
instance_name = "AmazonLinux01"

# get instance id
client = boto3.client("ec2")
instance_id = client.describe_instances(
  Filters=[{"Name": "tag:Name","Values": [instance_name]}]
)["Reservations"][0]["Instances"][0]["InstanceId"]

# stop ec2
response = client.stop_instances(
  InstanceIds=[
    instance_id
  ]
)

print(response)
```

実行してみると、以下のようなレスポンスが返ってきます（printされます）

```bash
# EC2停止
python main.py 
{'StoppingInstances': [{'CurrentState': {'Code': 64, 'Name': 'stopping'}, 'InstanceId': 'i-00e79808cbf3f76a8', 'PreviousState': {'Code': 16, 'Name': 'running'}}], 'ResponseMetadata': {'RequestId': 'dccb6bc8-35e7-45a0-8cc4-ce8c14df7a65', 'HTTPStatusCode': 200, 'HTTPHeaders': {'x-amzn-requestid': 'dccb6bc8-35e7-45a0-8cc4-ce8c14df7a65', 'cache-control': 'no-cache, no-store', 'strict-transport-security': 'max-age=31536000; includeSubDomains', 'content-type': 'text/xml;charset=UTF-8', 'content-length': '579', 'date': 'Wed, 07 Apr 2021 22:14:40 GMT', 'server': 'AmazonEC2'}, 'RetryAttempts': 0}}
```

コンソール画面で見ると「停止済み」に変わりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402286/89fba06e-f32a-c26c-f489-fc0dc16cd31c.png)

ちなみに、`client.stop_instances()`の`stop`を`start`に変えてあげればEC2を起動させることができます。

# 参考リンク
[Dockerコンテナで上で動くAWS SDKにローカルの認証情報(~/.aws/credentials)を読み込ませる](https://zenn.dev/faycute/articles/e72d62db84084c)

[Boto3 Docs - client.stop_instances()](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ec2.html#EC2.Client.stop_instances)