OmniAICreator/Qiita-1.07M huggingface dataset:
ナビゲーションバーのドロップダウン実装 　

###ナビゲーションメニューのドロップダウンの実装　
今回は、水平の横長のナビゲーションバーのメニューをhtm、jQueryでドロップダウンにしていく
他にもhtmlとcssだけでも出来ます、、
（今回cssは動きに関係無いので省略)

```html
<ul class="header-Nav">
　　　　<li class="navigation__trigger">
　　　　　　　　<a>メニュー項目A</a>　　　　//今回の実装はメニュー名にリンク設定する想定
　　　　　　　　<ul class="navigation__dropdown">
　　　　　　　　　　　　<li></li>
　　　　　　　　　　　　<li></li>                            
      <li></li>
　　　　　　　　</ul>
  </li>
  <li class="navigation__trigger">
　　　　　　　　<a>メニュー項目B</a>
　　　　　　　　<ul class="navigation__dropdown">
　　　　　　　　　　　　<li></li>
　　　　　　　　　　　　<li></li>                            
      <li></li>
　　　　　　　　</ul>
  </li>
</ul>
```

```js
//ナビゲーション　ドロップダウン
$(function() {
    'use strict';

    $('.navigation__dropdown').hide();
    $('.navigation__trigger').hover(
        function () {
            $(this).addClass('is-hover');
            $('.navigation__dropdown', this).fadeIn('fast');
        },
        function () {
            $(this).removeClass('is-hover');
            $('.navigation__dropdown', this).fadeOut('fast');
        }
    );
});
```
`class="navigation__trigger"`の要素に、マウスホバーすることで
そのメニュー項目の中の`class="navigation__dropdown"`がフェイドインで表示されます。
マウスカーソルを外すとフェイドアウトで非表示になります。

さらに、この例ではhoverでメニュー項目に
`$(this).addClass('is-hover');`で追加
`$(this).removeClass('is-hover');`で削除が行われます。


**toggleClass** や **fadeToggle** を使えばもっと簡潔にかくこともできます。

```js
$('.navigation__dropdown').hide();
$('.navigation__trigger').hover(
    function () {
        $(this).toggleClass('is-hover');
        $('.navigation__dropdown', this).fadeToggle('fast');
    }
}
```
【Laravel8】Laravel-Mixでjavascriptファイルを取り込む方法

###【Laravel8】Laravel-Mixでjavascriptファイルを取り込む方法

##前提
Laravel 8.4
webpack-cli 4.9
Laravel-mix 5.1

・bladeにjsを取り込みたい
・bladeにscript直書きしたくない
・他にも方法があるけど、今回はMixを使って軽量化します。

#手順
### 1.VS codeでCtrl + P ⇒ webpack.mix.jsと入力し、ファイルを開く

```javascript:webpack.mix.js
const mix = require('laravel-mix');

mix.js('resources/js/app.js', 'public/js')
    .vue()
    .sass('resources/sass/app.scss', 'public/css');
```
↑こちらデフォルト
mix.js('resources/js/app.js', 'public/js')
  ⇒ resources/js/app.js を軽量化して、public/jsに配置するということです。

### 2. 一行書き足します。
```javascript:webpack.mix.js
const mix = require('laravel-mix');

mix.js('resources/js/app.js', 'public/js')
    .js('resources/js/assets/function.js', 'public/js') // ここ
    .vue()
    .sass('resources/sass/app.scss', 'public/css');
```
function.jsの部分は各自jsファイルの名前で置き換えてください。

### 3.resources/js/assetsフォルダを作成 ⇒ その中にjsファイルを入れる
![Code_jbjOs6L3ZM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1159729/9ae05730-ee94-e1c9-8950-62c855560844.png)


### 4.bladeでjavascriptを読み込む
```php:app.blade.php
    <script defer src="{{ mix('js/function.js') }}"></script>
</head>
```

### 5.ビルドする
```:Terminal
    npm run dev
```
成功するとこのように表示される

```:Terminal
    ✔ Compiled Successfully in 5232ms
```

こちらの場合、コマンド実行時・それ以降にCtrl + S(保存)すると自動でビルドされます。

```:Terminal
    npm run watch
```

### 6.javascriptの動作を確認
わたしの環境ではうまくいきました。
うまくいかない場合、package.jsonのscriptsを確認してみてください。

## 番外編

### app.js一つにまとめる方法
```javascript:app.js
import './assets/function.js'
import './assets/param.js'
import './assets/button.js'

```

```php:app.blade.php
    <script defer src="{{ mix('js/app.js') }}"></script>
</head>
```

### 自動ロードを設定

```javascript:webpack.mix.js
const mix = require('laravel-mix');

mix.js('resources/js/app.js', 'public/js')
    .js('resources/js/assets/function.js', 'public/js')
    .vue()
    .sass('resources/sass/app.scss', 'public/css');

mix.browserSync('http://localhost:8000''); // ここ
```
URLの部分は各自置き換えてください

##Doc
[Laravel 8.x アセットのコンパイル（Mix）](https://readouble.com/laravel/8.x/ja/mix.html)
【JavaScript】JavaScriptでTodoリストを作成する

## はじめに
　本記事は、プログラミング初学者が、学習を進めていて疑問に思った点について調べた結果を備忘録も兼ねてまとめたものです。
　そのため、記事の内容に誤りが含まれている可能性があります。ご容赦ください。
　間違いを見つけた方は、お手数ですが、ご指摘いただけますと幸いです。

##JavaScriptでTodoリスト

```index.html
<!DOCTYPE html>
<html>

<head>
	<title>JSTodoList</title>
	<meta charset="UTF-8" />
</head>

<body>
  <!-- 追加フォーム -->
  <div class="input-area">
    <input id="add-text"  placeholder="TODOを入力" />
    <button id="add-button">追加</button>
  </div>
  <!-- 未完了一覧 -->
  <div class="incomplete-area">
    <p class="title">未完了のTODO</p>
    <ul id="incomplete-list">
      <li>
        <div class="list-row">
          <p>タスク</p>
          <button>完了</button>
          <button>削除</button>
        </div>
      </li>
      <li>
        <div class="list-row">
          <p>タスク</p>
          <button>完了</button>
          <button>削除</button>
        </div>
      </li>
    </ul>
  </div>
  <!-- 完了済み一覧 -->
  <div class="complete-area">
    <p class="title">完了したTODO</p>
    <ul>
      <li>
        <div class="list-row">
          <p>完了タスク</p>
          <button>戻す</button>
        </div>
      </li>
    </ul>
  </div>
	<script src="src/index.js">
	</script>
</body>

</html>
```

```index.js
import "./styles.css";

const onClickAdd = () => {
  // 入力値を取得する
  const inputText = document.getElementById("add-text").value;
  // フォームを空にする
  document.getElementById("add-text").value = "";

  // divを生成
  const div = document.createElement("div");
  console.log(div);
  // <div></div>

  // クラス名を追加
  div.className = "list-row";
  console.log(div);
  // <div class="list-row"></div>

  // liタグ生成
  const li = document.createElement("li");
  console.log(li);
  // <li></li>
  // liの中にinputTextの内容を取得
  li.innerText = inputText;
  // <li>テスト</li>

  // divの子要素に各要素を設定する
  div.appendChild(li);
  /*
    <div class="list-row">
      <li>テスト</li>
    </div>
  */

  // 未完了リストにタスクを追加
  document.getElementById("incomplete-list").appendChild(div);
  // 未完了リストの一番下にフォームに入力した内容が表示される
};

// 追加ボタンをクリックした際にonClickAddを実行
document.getElementById("add-button").addEventListener("click", () => onClickAdd());

```
Burpのcookie jarが行うこと

Burpに最初から入っているcookie jarが何を行っているのか調べた

## cookie jarとは

Burp proxy経由でアクセスしたwebサイトは発行したcookieを全て保持する。

また、自動でcookieを引き渡しもしてくれる。

デフォルトではProxyとSpiderでのみ有効になっている。
Burpのflow extension

Burpのflow extesionを導入すると以下のようなメリットが有る

## ログの保存

burp標準のloggerは全てのログを保存するわけではないようだ。
flowを用いると全てのログを保存してくれる。

## 検索フィルター

標準のロガーよりも充実したフィルター機能や履歴ビューが利用できる。

## alternatives

logger++も同じような機能を提供する。
Burpのscannerとは

burpのscannerが何を行っているのか調べた

## scannerがやること

- webサイトの自動スキャン
  - コンテンツ探索
    - リンクを探索
    - inputの入力
  - 脆弱性診断
    - パッシブフェーズ
    - アクティブフェーズ
    - javascript分析フェーズ

## passive scan

リクエストとレスポンスの調査で検査できる脆弱性の調査

## active scan

CORSやインジェクション等のリクエストを改ざんして攻撃を行う

## javascript分析フェーズ

javascriptを分析してXSS等を検出する。
マージ済みのブランチを対話式で削除するgitサブコマンド(dansyari)を作ってみた

# こんなもの作った

- マージ済みのブランチを対話式で削除するgitサブコマンド `git dansyari`

![git-dansyari.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50690/854b8aa0-c048-021b-390a-a422ebb549a8.gif)

https://github.com/kuredev/git-dansyari

# 動機

- 前はこちらの[git curate](https://github.com/matt-harvey/git_curate)を使わせてもらっていたのだが、Ruby/Native Extensionで動いており、環境を変えたときにコンパイルがさくっと通らずに入れるのが面倒になってしまったのでもっと簡単に動作するものが欲しかった
  - 今回はシェルスクリプトのみで動くものを作った
- 機能的にもブランチを消すだけでよかったので、削除の確認だけの対話式のスクリプトとした

# インストール、使い方

- [このリポジトリ](https://github.com/kuredev/git-dansyari)をcloneして中の `git-dansyari` ファイルをパスの通った場所に配置、実行権限を付与
- 管理したいリポジトリで `git dansyari` コマンドを実行する（実行イメージは冒頭のgifを参照）

# 参考

https://qiita.com/b4b4r07/items/6b76a5f969231e5e9748
ネットワーク入門　VPCとセキュリティ

# この記事について
私自身の専門業務が機械学習やデータ分析を用いたになるのですが、ネットワークの構築を行うことになり基本を復習したので備忘録として記しておきます。

## 実行環境
AWS利用を想定して記述します。

## VPC
VPCとはVertual Private Networkの略になります。
要はプライベートにルールなどを色々決められる自作のネットワークになります。
AWSなどのクラウドサービスを利用してサーバーを構築する際にはVPCという環境を作成して、そこにサーバーを置く形になります。


### VPCのルール
VPCは主に２つ設定しなければいけないルールがあります。

1. IPアドレスを使用する範囲をどうするか
2. インターネットに繋ぐかどうか
3. VPCを更に小さい単位（サブネット）を複数設けるか

#### 1.IPアドレスを使用する範囲の決定
インターネットはIPアドレスという4桁（6桁もあります）の番号で宛先を指定して通信を行います。
このIPアドレスを指定しないと宛先していない郵便と一緒でどこに送れば良いか分からないため通信が出来ません。
IPアドレスには「ネットワーク部」と「ホスト部」があります。
この「ネットワーク部」は同じネットワーク内だと同一の値となり、「ホスト部」にてネットワーク内の固有の機器を識別する形になります。
もっと詳しく知りたいよって人は以下の記事で綺麗にまとめてくれているので参考にしてみてください。

https://qiita.com/mogulla3/items/efb4c9328d82d24d98e6


#### 2.インターネットに繋ぐ場合
インターネットに繋ぐ場合インターネットゲートウェイ（以下IGWと記述）を設定する必要があります。
IGWとは、VPCが外部のインターネットと通信を行う際の出入り口になります。
このIGWを設定しないとVPCは外部のネットワークと通信が出来ない形となります。


#### 3.VPC内にサブネットを設ける場合
サブネットを設けるか否かの判断はインターネットに一部の機能は繋げたいけど、一部は繋げたくないなどの要望がある時に複数のサブネットを設けます。
サブネットというのは、ネットワークを更に細かく区切るものになり、サブネットごとにルールを設けられます。
よって、あるサブネット内にあるサーバーは外部と通信を可能にし、他のサーバは外部との通信を出来ないようにすることでセキュリティをより頑強にすることができます。


## IGW（インターネットゲートウェイ）
先ほどインターネットに繋ぐ場合で少し説明をしたIGWについてもう少し詳しく書きたいと思います。IGWはVPCにアタッチ（紐付ける）ものになるのですが、そのままだとインターネットに接続が出来ません。
以下の手順でIGWの設定を行う必要があります。

1. IGWを作成する
2. IGWをVPCにアタッチする
3. ルートテーブルを作成し、名前タグに任意の名前を設定し作成をする。送信先は 
4. 作成したルートテーブルをIGWを用いて外部と通信を行いたいEC2の属しているサブネットに関連付け
5. 作成したルートテーブルの「ルートの編集」から送信先に「0.0,0,0/0」を追加し、ターゲットに作成したIGWを選択する

以上の流れでIGWを作成することで外部との通信が可能になります。
逆に外部との通信を避けたい場合は別のサブネット内に他のサーバを配置し、IGWに接続する設定を行わないようにします。



#終わり
文字ばっかで見づらいと思いますが、メモ的に使ってもらえればと思います。
以上になります！
Word VBA Show Data Form

#表の入力用のフォームがある
[Word の表でできること (2/3)](http://hp.vector.co.jp/authors/VA014071/tips/wd_tbl_2.html)
昔々、Word2000のころ、データフォームというのがあり、それで入力できたそうです。
しかもデータベースタブがありました。
これで入力できたそうですが、こんなタブは隠れてもいません。
今はどうすればいいのでしょうか。

#おなじみQAT
[ HOME > 即効テクニック > Word 一般 > 表とグラフ > データフォームを利用して表を作成する](https://www.moug.net/tech/woopr/0100021.html)

>初期設定では、[データフォーム]ボタンが表示されていないため、クイックアクセスツールバーに追加してから操作します。

# 自動記録ではできない
これをじどうきろくしようとしましたが。。。

```vb
Sub Macro1()
'
' Macro1 Macro
'
'
End Sub

```

空振り。
# 組み込みマクロ
Show とか Dataformもなし

# 答えは

[Word VBA 書式の詳細設定ウィンドウの表示](https://qiita.com/Q11Q/items/bd32bae2322c4aa64fe4)
前回はApplicationと、Taskpanesを使いました。

今回はDocumentを使います。

```vb
Sub データフォームを開く()
' Word VBA
 ActiveDocument.DataForm
End Sub
```

[Document.DataForm メソッド (Word)](https://docs.microsoft.com/ja-jp/office/vba/api/word.document.dataform)

>データ レコードを追加、削除、または変更できる [データ フォーム] ダイアログ ボックスを表示します。
#####構文
Expression.DataForm
expression 必須です。 Document オブジェクトを表す変数を指定します。
#####解説
このメソッドは、<Font color = "Red">差し込み印刷のメイン文書</font>、<Font color = "Blue">差し込み印刷用のデータ ファイル、</font>あるいは<b>表のセル</b>または<font color = "Green">区切り記号で区切られるデータを含む文書</font>に対して使用できます。

通常は差し込み文書(MailMerge)で見るのだが、実は標準で表に使うことができる。
ダイアログボックスの割にダイアログボックスは使わない。
もっとも開いても入力ができたりすることはない。
次にデータフォームはデータと見られる表と区切り文字が存在するときは表を優先した。

###区切り文字
文書にこれだけなら、データフォームが効いている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126919/37cc470e-d9c1-f008-4402-97b5b82a4694.png)

つまり、データベースが作れてしまうということになる。
しかもこんな簡単に入力フォームを作る方法はAccess、Excelにもない。
さらにコンマ区切りだけでなく、タブ区切り、セミコロン区切りもできる。
1人でアジャイル開発やってみる（インセプションデッキ編）

実務でアジャイル開発を始めてから1年以上たちますが、アジャイル開発いいですね。特に以下のような点を気に入っています。

+ 動くソフトウェアを重視する
+ 短い期間で（小さくても）リリースできるものを作り上げる
+ 心理的安全性などマインド面

特に１，２点目は学習する上でも大事だなーと思います。動くソフトウェアができる喜びを知ったからこそ自分はエンジニアになったわけで、学習においても調査が目的になってしまうと身につかない！ちゃんとリリースまで行って友達だけでもいいから使ってもらうことで、習得できる経験が全然違うと思います。

最近はフロントエンドのフレームワークを使ってみたいと思っているので、Nuxt.jsの学習のためにNuxt.jsを使ってアジャイル開発やってみようと思います。1人で！！！

## 使うもの
とりあえず以下の技術を使って始めようと思います。ほかにも使いたいものが出てきそうだけどそこは柔軟に。

+ Vue.js/Nuxt.js
+ Vuetify
+ firebase

## まずはスクラムボードの作成
今回はオンラインホワイトボードのMiroを使ってボードを作りました。
MiroはTemplateを使って開発に必要なドキュメントを作成することができるので1人で手軽にやるにはMiroがベストかと。
まずは開発までに必要なタスクを洗いだしました。
![スクリーンショット 2022-02-07 233539.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2518616/674db8a7-3f96-0cae-89c2-d1289fee9731.gif)

## スプリントについて
１スプリント３時間で行きます。学習に割く時間のだいたい２日分です。
ただ毎日やると疲れちゃうので休み休み更新しようと思います。

## 開発するプロダクトのテーマ
テーマは「アイスブレイク」にしました。
昨今リモートワークが増えてることもあり、アイスブレイクに悩んでいる人も多いのではないでしょうか。
かくいう私もその一人ですし、周りもそうなので知人にも興味を持ってもらえそうかと思いました。

# インセプションデッキ作成
## 我々はなぜここにいるのか
こんな感じです。プロダクトの目的は「コミュニケーション活性化」、手段は「アイスブレイクの提供」です。
![スクリーンショット 2022-02-07 234419.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2518616/739ca72a-cf1a-2c6a-15b1-067b2044bab7.gif)

## エレベータピッチ
コミュニケーション活性化が目的なので、みんなで楽しめるアイスブレイクにしたいですね。
個人的には”程よい”というのもポイントです。すごい印象に残るクリティカルなアイスブレイクじゃなくて、毎日使えるようなものにしたい。
![2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2518616/48fd97e2-529a-7725-438e-95d56e2f4c76.gif)
こうしてみるとエレベータピッチって情報量が多いですね。

## やらないことリスト
アウトプットはしたいので記事の公開は必須で。スプリントごとのリリースも頑張りたい！
開発するプロダクトはUIはさほどこだわらないけどUXはこだわりたい。
![3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2518616/510e4d6b-f374-5c47-4ccd-857cf9e1b670.gif)

## トレードオフスライダー
スコープと予算はこだわらない。期日は開発全体の期間は決めないのですが、だらだらやって放置するのも嫌なので、スプリントで決めたことは厳守！なるべく進める中で中期的な目標も立てれたらと思います。
あとは学習目的で始めたはずなのにいいもの作りたいって気持ちが意外と強いことに気づきました。
![4.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2518616/ff25072b-cb23-6373-9d47-d0a0e3154cba.gif)

## お隣さんを探せ
娘(7歳)くらいが楽しめるアイスブレイクを目指すのもありか・・・。その方が全体の発言量が増える可能性もあるかも
![5.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2518616/4aeb08de-91f3-b831-86ce-425d08f52b73.gif)


## 終わりに
今日はインセプションデッキの作成を行いました。
次回はユーザーストーリーマッピングとペーパープロトタイピングを行います。
![スクリーンショット 2022-02-08 000212.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2518616/29f0235e-836e-435a-6003-76216b3a28e8.gif)
【Scala】MongoScalaDriverを用いたupdateで複数フィールドを更新する

## 概要
MongoScalaDriverでは[こちら](https://mongodb.github.io/mongo-scala-driver/2.6/scaladoc/org/mongodb/scala/model/Updates$.html)のドキュメントに用意されているような、updateのメソッドが用意されています。updateのメソッドでは第一引数に更新documentの抽出条件、第二引数に更新fieldと値が設定されていますが、更新fieldを複数設定する場合にどうするかというのをいつも忘れるので、メモ書きします。

## 対応
[こちら](https://mongodb.github.io/mongo-java-driver/4.2/driver-scala/tutorials/perform-write-operations/#update-a-single-document)のチュートリアルにある通り、`combine`メソッドの中に設定する更新フィールドを設定します。

## 実装サンプル
チュートリアルの内容ほぼそのままですが、実装サンプルを記載します。
collectionの取得部分については、[【mongoDB】【Scala】mongoDB のインストール → Scala で CRUD する](https://www.msawady.com/entry/2017/10/01/220602)の記事を参照ください。


```scala
collection.updateOne(equal("_id", id), combine(
  set("title", title),
  set("detail", detail),
))
```
PaloaltoVM on AWS(10.0.4) 脆弱性保護プロファイル/セキュリティポリシー

今回は脆弱性保護機能のテストをしたいと思います。VMトライアルラインセスでは動作しなかったため、AWS環境で実施しています。構成は下記の通りです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/1e13a17c-08bf-d27a-6835-3030dd8d2c43.png)

## 1. 前提
Publicセグメント内にあるLinuxのみ外部からの接続を許可する形にして、セキュリティグループは10.0.0.0/16で許可。SSHポートフォワードを設定してPalo向けのHTTPSおよびWindows2016へのRDP接続をしています。

Internal-ZoneのWindows2016とDMZ-ZoneのAmazonLinuxはそれぞれのセグメント向けにスタティックルートを設定しています。一時的にインターネットからパッケージを引っ張ってきたりChromeをインストールするために、NATGatewayも設定しました。また、Paloaltoに後から追加したDMZとInternal用NICのセキュリティグループは下記の通り設定しています。

|Sourceアドレス | プロトコル | タイプ |
|--|--|--|
|10.0.0.0/16| TCP | すべてのTCP|
|10.0.0.0/16| UDP | すべてのUDP|
|10.0.0.0/16| ICMP | すべてのICMP|

## 2. 脆弱性保護プロファイル作成

では、脆弱性保護プロファイルを作成していきます。管理画面にログイン後、画面上の「OBJECTS」タブから画面左の「脆弱性防御」をクリックして、画面下の「追加」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/b53a94df-52f0-f701-ae9c-1e4a6f66526b.png)

名前を入力して、画面したの「追加」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/5d4c2ec1-a493-397f-a1a7-3765760aaa37.png)

ルール名を入力し、脅威名を「any」、アクションを「両方のリセット」として「OK」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/7ba1f7f1-1d85-f656-8222-5163e78782a6.png)

「OK」ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/a32c719b-8193-bd0a-83f8-b428d3d72ba3.png)


## 3. セキュリティポリシーへの適用

次は、事前作成済み（Internal->DMZ向けTCP80番ポート許可）のルールに脆弱性保護プロファイルを適用します。対象のセキュリティポリシーの名前をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/a5f93d09-4125-10b4-b292-3811c076ac02.png)

アクションタブをクリックして、プロファイル設定の脅威防御のプルダウンから先ほど作成したプロファイルを選択し「OK」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/cd5f76ed-2133-2820-dbd8-3311cac97ee7.png)

適用されるとプロファイル欄に！マークがつきます。ではコミットしましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/21e89eb3-fa18-ca73-bfb8-62061f6c7259.png)


## 4. 動作確認
まずは、Windows2016にRDP接続してブラウザからアクセスしてみます。（DMZのLinuxにはapacheをインストールだけしている状態です）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/016ac0b5-447f-d200-d027-2f605a70b852.png)

次にURLの最後に?hoge=../../etc/passwdと追加した状態でアクセスさせます。リセットされた旨の画面が表示されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/0d2ba22b-649c-db44-fd30-5c2976b80de6.png)

ではログを確認してみましょう。画面上の「MONITOR」タブから画面左の「トラフィック」をクリックするとブラウザアクセス成功時のログが確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/5dd2532b-8ee3-d343-1fcf-439430dff258.png)

次に同じ画面の「脅威」をクリックすると、下記の通りリセットされているのがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/5453655a-ab1f-c421-14b6-71b0187d8332.png)

## 5. その他
今回は脅威防御プロファイルの簡単な動作について検証してみました。QiitaでのPaloAlto取り扱いは今回が最後の記事となります。今まで5回ほどPaloaltoの内容について取り上げてきましたが、実際の導入では状況に応じた構成の検討やチューニング、その他考慮しなければいけない事など多岐にわたります。また今回のようにAWS上で構成する場合license絡みの作業や、ちょっとしたお作法があったりします。リクエストがあれば別の機会で取り扱ってみたいと思います。
mayaの環境を構築していく　3日目

pythonPath 通してuserSetup.py食わせるようにしたわけですが。
mayaの基本的な部分の環境は整ってきたので、あとはデフォルト値が気に入らないの忘れてた事に舌打ちしながら作業しつつ調整していく感じですね。

例）bindSkinのデフォルトオプション
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1484234/2d8b3e80-d0f1-6f32-f195-09c629cbc38c.png)
mayaのver上げるたびにコレ忘れてて、舌打ちしてる。
好みの設定はこっち
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1484234/771e1d12-59eb-e6da-ea3a-fcd0ad25bffe.png)

さてここからリグ開発の為の環境構築をしていくのですが、その為に色々準備をします。

tool開発の為の準備
--
tool開発(主にpython)はついついScript Editorでやりがちなのですが、

- 予期せぬmayaの強制終了
- うっかり複数起動して、終了する順番間違える

などによって編集内容が消えてしまう事が割と多く、その度にやる気が削がれていくので、
なるべく外部ファイルで編集してmayaで実行するという風にしています。

pythonPathを通してるので、例えばtestTool.pyをpythonフォルダに追加し、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1484234/78c98c27-8c81-ec9e-5af2-a1f9a09f3f6c.png)
中身を適当に記述して、

    import maya.cmds as cmds
    def main():
        cmds.createNode("joint")

これをmayaで実行
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1484234/a8743042-23e8-7884-dd31-6cd63df9bbdf.png)
問題なく testTool.pyの中身が実行されることが確認できました。
これで、whileミスって無限ループ起こししてmayaが応答しなくなっても躊躇なく強制終了できるようになりました。

※VSCodeのプラグインなどを使えば直接maya側に命令を送れるらしいですね。

tool類のリスト
--

リグを開発する為に必要（と思われる）ツールを作っていきます。

- 骨打ち用ツール
- リグビルドツール

とりあえずこの2つですね。
スキニングとかそういうのはリグの開発中盤くらいから欲しくなるだろうけど・・・・
まぁ欲しくなったら作りましょうかね。

キリがいいので続きは次回。
FindTimeの使い方

# はじめに
Outlookの隠れた(?)便利機能「FindTime」について、
とても簡単に利用できるにもかかわらず、
操作手順書があまり出回っていないので、簡単にまとめてみた。

# FindTimeとは
いわゆる「日程調整ツール」。
日程調整を効率化してくれるアプリ。

# 会議主催者が、投票を作成する手順
1. メール作成画面を開き、日程調整の対象者を宛先に追加する(画像省略)

2. 「New Meeting Poll」をクリックする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684495/901c1107-5daf-6cbd-877f-acaf67474ded.png)

3. 全員が緑色の時間帯を任意で複数選択し、「次へ」をクリックする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684495/cf06892e-91f3-3a0a-f097-a30864eff4d5.png)


4. 内容確認後、「メールに追加」をクリックする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684495/1ce56aec-b5fb-1b72-acd6-0b51634d61d5.png)


5. いつもどおり、メールを送信する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684495/592d8444-50f3-884c-aaf7-9a7c18a30625.png)


# 会議参加者が、投票する手順
受け取ったメールに添付されたリンクを開き、以下画面で投票を行う。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684495/98f0d50d-5367-bb04-5d06-bf96e1040600.png)


# 参考にしたページ

https://support.microsoft.com/ja-jp/topic/findtime-%E6%8A%95%E7%A5%A8%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95-4dc806ed-fde3-4ea7-8c5e-b5d1fddab4a6

https://art-break.net/tech/?p=5436

# おわりに
書いている途中で見つけたこっちのほうが便利かもしれない。比較してみる。

https://www.youtube.com/watch?v=_hvbmCFT1Dw
Ubuntu Server 20.04.3 LTS 構築#11 セキュリティ設定5-4

実施日:2022/01/30～

<<今回の内容>>
ウイルスを検出した際にメールで通知を受ける方法(ローカルユーザーのみ)

今回はウイルスを検出した際にメールで通知を受ける方法を設定します。
※今回の作業はローカルユーザーのみとします。Gmailなどにメールが届くように設定するには今回の作業以外にも設定が必要なので割愛。

調べてみると、まずはMTA(メール転送エージェント)とMTU(メールユーザーエージェント)の機能が必要なので導入します。

[コマンド]
dpkg -l 
⇒MTAとMTUが導入済みか確認しました。
　実行してから、大量のパッケージが表示されているので、やり直し。

dpkg -l bsd-mailx
dpkg -l posfix

検索結果の先頭行にunと表示されていましたので、未導入。

[コマンド]
sudo apt install postfix
⇒インストール中にメールサーバー形式を選択する画面が表示されます。
･設定なし
･インターネット
･サテライトシステム
･ローカルのみ
⇒ローカルのみを選択しました。
次にドメイン名を作成する画面が表示されました。
⇒表示されたもにのままで次に進めました。
⇒導入完了です。

[コマンド]
sudo apt install bsd-mailx
⇒インストール中にアーカイブを取得する必要があると表示されましたので、「Y」を選択。
⇒導入完了です。
こちらを選択したのは、シンプルなコマンドラインモードのメールユーザーエージェントで
今回の目的に沿うものと判断しました。

ウイルスを検知した際にメールで通知するために以前、作成したスクリプトにメール通知機能を追記します。

```
if [ $?=0 ];then
{
echo 'virus undetected'
    cat '/home/ユーザー名/Documents/scanlog.log' | mail -s 'Clamav scan OK' ユーザー名@localhost
}
else
{
echo 'virus infected'
    cat '/home/ユーザー名/Documents/scanlog.log' | mail -s 'Clamav scan NG' ユーザー名@localhost
}
fi
```

上記のスクリプトをスキャンスクリプトに追記しました。
最初はスキャンはするが、メールが届かないという状態になり、解決するのにかなり時間を消費しました。

修正した箇所は
echoとcat以下の箇所はそれぞれコマンドとして扱うため、if構文の中で複数コマンドを使用するときは{}で囲う必要があることが判りました。

次回はウイルススキャンのまとめをします。
スクリプト内にて①ウイルス定義更新をする。②定義更新後にウイルススキャンを行う。③その結果をメールで送信する。

本日はここまで。
Amazon SESを使うことで通常のGmailで独自ドメインを利用する -送信編-

# この記事について

準備編、受信編の続き
準備編
https://qiita.com/Sand-River/items/4c0dbb16b70e11ec594a
受信編
https://qiita.com/Sand-River/items/4b22f3d0369ab68cfb3f

# 送信定義
https://docs.aws.amazon.com/ja_jp/ses/latest/dg/send-email-smtp.html

SES Dashboardの「Simple Mail Transfer Protocol (SMTP) settings」から「Create SMTP credentials」を選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554633/40926a59-8718-5852-4a36-7aaa118097a0.png)

IAM User Nameだけ入力して「作成」
（必要なIAM Policyは自動でアタッチされる。ses:SendRawEmailのみ許可）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554633/66e003f8-bc86-06c0-fb0f-933e90565e93.png)

ユーザ作成の完了と共にSMTPの認証情報がダウンロードできる。
注意書きにもあるが、SMTP認証情報を取得できるのはSESからユーザを作成した__このタイミングのみ__で、失った場合はユーザを作り直す必要がある。
他のIAM Userのようにグループを作成してそれにSendRawEmailをAllowして……という手も使えない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554633/921771e8-0064-7535-aa79-28becc386b20.png)


# Gmailの設定

## 新規にGoogleアカウントを作成する

### Googleアカウントを作成する。
「代わりに現在のメールアドレスを使用」からSESで登録したドメインのメールアドレスを登録。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554633/3853dd41-fac8-76c4-0ee7-42e13f4931be.png)

S3からメールアドレス検証のメールを探し出して確認コードを入力すればOK。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554633/30acbfbf-8ce5-eb72-48a3-7fbe9edc5ae6.png)


### Gmailの設定
Gmailの設定（右上の歯車マーク）→「すべての設定を表示」
「アカウント」タブの「名前:」にある「他のメールアドレスを追加」を選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554633/8b0f77bf-ace6-5d21-1c8e-c454234c1ff8.png)

Fromの表示名とメールアドレスを指定する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554633/efa4b1d0-4333-5ab2-3a5d-6c2942f9342f.png)

Amazon SESのSMTPサーバは email-smtp._\<region\>_.amazonaws.com となる。
例）`email-smtp.us-east-1.amazonaws.com`
ポートはデフォルトの587でOK。
ユーザ名とパスワードはIAM Userを作成した際の認証情報に記述された情報を転記する。
「TLSを使用したセキュリティで保護された接続（推奨）」を選択（デフォルト）。
「認証情報を確認しています」と表示された後、画面遷移する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554633/cb19a486-60e2-a759-e4ed-22ea30f0e67e.png)

指定したメールアドレスに確認コードが配信される。
受信編で正しく設定されていればS3にメールが溜まっているはずなのでそこから受信したメールのオブジェクトをダウンロードしてきて確認コードを入力する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554633/b6f977d8-d2ac-4471-f2b1-f13a7cd5564d.png)

言語に日本語を指定してるとbase64でエンコードされていてテキストエディタで開いても読めない……コマンドラインでデコードを書くならこんな感じだろうか。\<mailfile\>の指定が2回入るのが美しくない。

`grep -n -E "^\r" <mailfile> | awk -F ':' '{print $1}' | xargs -I{} sed 1,{}d <mailfile>  | base64 -d`

正しく確認コードが認証されればウィンドウが閉じ、名前の一覧に今追加したアドレスが追加されているはず。


## 補遺

なお、勘の良い方ならお気付きだろうが、Gmailに登録したメールアドレスは登録ドメインのものであれば任意である。ドメインを自分一人で使う場合であればそこまで気にする必要はないが、グループで使う場合などはSMTP用のIAM Userに制限を掛けて置く必要がある。サンプルとして以下を参照のこと。
（この例であればFromとして利用できるアドレスがfoo@example.comに限られる）

```
{
  "Version":"2012-10-17",
  "Statement":[
    {
      "Effect":"Allow",
      "Action":[
        "ses:SendRawEmail"
      ],
      "Resource":"*",
      "Condition":{
        "StringEquals":{
          "ses:FromAddress":"foo@example.com"
        }
      }
    }
  ]
}
```


# 続き
SESで受信したメールを転送する処理を後回しにしていたので、そこをうまいこと作る。

……ちょいちょいとメールを別に送る処理をLambdaで作ればええだけやろ、と思ってた時代がありました。


https://qiita.com/Sand-River/items/36854e90c7f209b8a0dc
[師匠の教え]良い質の仕事を行うには？？

#前書き
どうも！絶賛就活中のグッピーです！今回は私の敬愛するエンジニアの師匠から教えていただいたことがだいぶ勉強になったので、備忘録的に今回の表題のことについて書いていこうと思います。






##そもそもなぜこういう話になったのか
私は今ひよっこエンジニアとしてインターン先で勉強していて、そのお題の一つとしてREADMEを書いてくれと頼まれていたのですが、事前に提示されていた仕様をうっかり忘れてしまい、その件で注意されました。

そして、その一環でどのように仕事をしているかと聞かれ、色々と仕事術に関しての講義が始まったのです。

##私が実践していた仕事術
私はもともと目上の人に気に入られることが多く、それを武器に世の中を生きてきました。
そうした処世術からか、仕事も上司に気に入られることに特化したものとなっていました。

私の仕事術は
①とにかく依頼された仕事は早くこなす。
②提出後、フィードバックをもらい、それを修正する。
③②を繰り返して、質を高めていき、上司のOKが出て、その仕事は終了

という仕事のやり方をしていました。
正直今までの経験上、報告連絡相談をいかに短時間でこなすかが自分の評価の向上につながるものだとばかり考えていました。

**しかし**、このやり方ではダメだったようです。

このやり方だと上司依存になりやすく、優秀な上司だったらまだしも、無能な上司だった場合には成長できなくなるのでやめておいた方がいい。という話でした。

###この話を聞いた私
「なん・・・だと・・・」

一種の思考停止に陥りました。そう、コペルニクス的転回です。今まで一番正しいと思っていたものが正しくなかったのです。

あまりの衝撃に思考は止まったのですが、自然と言葉が出てきました。
ならどのような仕事術ならいいのかと
そして私の師匠ないし上司は徐に優しく教えてくれました


##良い仕事の仕方

まずは例として大学のレポートが提示されました。

皆さんは大学のレポートはどのようにやっていましたか？？

そこそこ賢い方なら、まずレポートの採点基準や高得点を取るためにはどのような内容にすべきかなどを調べ、その後にその質に達するまで自分のレポートを研磨させたはずです。
そう。察しのいい人ならお分かりでしょうが、これを仕事にも適用するのです。


①頼まれた仕事に関して、インターネットなどで事前調査。質の良い仕事の基準を知る。
②質の良い仕事の基準に達するように仕事を行う。
③最終確認し、質が本当に達しているか、相手が求めたもの以上のものになっているかを確認。
④提出。

抽象化すると、調査→実行→確認→提出
ってことですね。

仕事のできる人にとっては当たり前かもしれませんが、最低限の質を担保するプロ意識が欠けていたことがわかったので、以後はこれを肝に銘じて気をつけています。

##まとめ
はい。ということで質の良い仕事の仕方を今回はまとめました。
Qittaっぽくない記事ですが、プロ意識はどの職種でも必要になってくるのだろうなとぼんやりと感じているので、肝に銘じる意味でもまとめました。
前は簡単に提出していたのですが、この教えがあってからは入念にチェックするようになりましたね。
いやー、やはりインターン先の上司には頭が上がらないです。

もし最後までご覧になった方がいらっしゃれば、LGTMボタンを押していただけますと嬉しいです、、、！！！

ありがとうございました！
はてなブログでソースコードの行番号をCSSだけで表示する

[はてなブログ上のソースコード表示](https://help.hatenablog.com/entry/markup/syntaxhighlight)ですが、行番号はつけられません。

そこで、CSSだけを使って行番号を表示させてみます。ただし、横スクロールを表示してソースコードは改行させないやり方です。

Markdown記法で、次のCSSを貼り付けてください。`<style>`だけだと有効にならないので、`<span>`で囲うのが良いそうです。

```html
<span><style>
pre.code {
  /* 行番号の基準をpreの左上にする */
  position: relative;
  /* コードの左側を空ける */
  padding: .25em 0 0 3em;
  /* 横スクロールバーを出して、コードが改行しないようにする */
  white-space: pre;
  overflow-x: scroll;
}
pre.code::before {
  /* 行番号。\aで改行している */
  content: "1\a 2\a 3\a 4\a 5\a 6\a 7\a 8\a 9\a 10\a 11\a 12\a 13\a 14\a 15\a 16\a 17\a 18\a 19\a 20\a 21\a 22\a 23\a 24\a 25\a 26\a 27\a 28\a 29\a 30\a 31\a 32\a 33\a 34\a 35\a 36\a 37\a 38\a 39\a 40\a 41\a 42\a 43\a 44\a 45\a 46\a 47\a 48\a 49\a 50\a";
  /* 行番号の基準をpreの左上にする */
  position: absolute;
  left: 0;
  /* widthを設定するためにblock表示 */
  display: block;
  width: 1.75em;
  /* 行番号の調整 */
  padding-left: .25em;
  color: #c0c0c0;
  text-align: center;
  /* 行番号とコードの間に線を引く */
  border-right: 1px solid #c0c0c0;
}
</style></span>
```

`overflow: hidden;`が予め設定されていたので、コードよりも行番号が多い場合は勝手に隠れてくれます。

## 参考にした記事

ベースにしたのは次の記事です。CSSの説明が詳しくて助かりました。

https://totora0155.hatenablog.jp/entry/line-number-with-css

さらに、`content:`で行番号を改行するアイデアは次の記事で教えてもらいました。

https://www.studiomic.net/pre-line-numbers/

また、はてなブログのMarkdown記法で`<style>`が有効にならないことと、その対処はこちらの記事を参考にしました。

https://blog.uchiten.info/entry/2017/01/30/174500

記事を書いてくださった皆さん、どうもありがとうございました！
Saleaforceの専用予約管理システムSalesforce Scheduler 

Saleaforceの専用予約管理システムSalesforce Scheduler 
１．Salesforce Scheduler は何ですか。
Salesforce Scheduler (旧称 Lightning Scheduler) では、Salesforce での予定のスケジュールを簡略化するために必要なツールが提供されます。適切な担当者が割り当てられた顧客の予定 (対面、電話、または動画) を適切な場所と時間にスケジュールすることで、パーソナライズした環境を作成します。

参照；
https://help.salesforce.com/s/articleView?id=sf.ls_overview.htm&type=5

ここでは、一点注意します。元もLightning Schedulerと呼ばれましたが、大体2021年の時Lightning Schedulerも呼ばれました。



２．Salesforce Schedulerの起源、およびField Serviceの関係

データベースから見ると、実際にField Serviceから一部分を取得してSalesforce Schedulerとする。
Salesforce Schedulerのオブジェクトとか、項目定義とかほとんどField Serviceの中で見つけますが、
それにSalesforce SchedulerよりField Serviceのほうは提供された機能が多いです。
Tkinterのmenuで選択されたradiobuttonに設定されたvalueを取得する方法

## 概要

**Tkinter**で作成した**menu**の**radiobutton**が選択されたとき、選択されたほうの**value**を取得する方法を記載します。

画像でいえば、1に設定された**value**を取得したいということになります。

![tkinter-menu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302006/8fef284c-0535-b3e0-526c-3dcf6d529e94.png)

## 動機

**radiobutton**と紐付ける関数は同じものにして、引数で処理を変更したい。
引数としては**radiobutton**の**value**を使いたい。

## 方法

**add_radiobutton**メソッドの**variable**引数に、**StringVar**を渡します。
_文字列ではなく数値型が欲しい場合は**IntVar**を渡す。_

## サンプルコード

```python:example.py
import tkinter as tk


class Menu(tk.Menu):
    def __init__(self, master=None):
        tk.Menu.__init__(self, master)
        master.bind("<Button-3>", self.create_menu)

        self.string_var: tk.StringVar = tk.StringVar()
        self.string_var.set("")

    def create_menu(self, event=None):
        self.post(event.x_root, event.y_root)

    def set_value_for_menu(self):

        self.add_radiobutton(label="1", value="hogehoge-1", variable=self.string_var, command=self.print_select_menu_item)
        self.add_radiobutton(label="2", value="hogehoge-2", variable=self.string_var, command=self.print_select_menu_item)

    def print_select_menu_item(self, event=None):
        print(self.string_var.get())


if __name__ == "__main__":
    root: tk.Tk = tk.Tk()
    menu: Menu = Menu(root)
    menu.set_value_for_menu()
    root.mainloop()
```

```text:出力結果
1を押した場合：
    hogehoge-1

2を押した場合
    hogehoge-2
```
AWSロードマップ(IAM)

#目次
[1.はじめに](#1-はじめに)
[2.用語](#2-用語)
[3.ドローンでクラウドを利用](#3-ドローンでクラウドを利用)

#1. はじめに
ドローン✖︎クラウドの記事をよく見るけど、どうゆう仕組みで連携してるのか分からなかったので
[AWSロードマップ](https://qiita.com/KurokawaKouhei/items/4e9aa3b526f3f233bf85 "Qiita Home")で勉強をしたいと思います！
(まずはざっくり覚えて徐々に深堀していく、仕事でAWS少し触ったぐらい)

#2. 用語
![スクリーンショット 2022-02-07 20.40.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2181084/8a7effb9-3dd7-00be-56e0-661a13582991.png)

###ポリシーについて理解する
####AWS管理ポリシー
- 予めAWSによって用意されてる管理ポリシー(大まかに各AWSサービスごとにフル権限と読み取り権限が用意されている)
- ポリシー
    - jsonフォーマットでアクセス権限をリスト化したもの
 
####カスタマー管理ポリシー
- 利用者が独自に作成する管理ポリシー

####管理ポリシーとインラインポリシー
- 管理ポリシー
    - ポリシー単体で存在でき、複数のプリンシパルエンティティ(IAMユーザー/グループ/ロール)につけたり外したりできる
- インラインポリシー
    - ポリシー単体では存在できず、プリンシパルエンティティと一対一

####リソースベースポリシー
- S3などのリソースにアタッチ
- 誰がリソースにアクセスでき、彼らがリソースでどのようなアクションを実行できるかを指定できる

###IAM基本概念の理解
####ルートユーザー
- AWSアカウントを作成した時に用意したアドレスとパスワードを使用してサインインできるアカウント
- 請求情報など支払い情報を含めたAWS全てのサービスとリソースに対して無制限のアクセスが可能

####IAMユーザー
- AWSを利用するアカウント

####IAM Group
- IAMユーザーの集合体
- 複数のユーザーに対してアクセス許可を指定でき、それらのユーザーのアクセス許可を容易に管理出来る

####IAM Role
- AWSのリソースに付与するもので、実態はIAMポリシーをグルーピングしたもの
- EC2には一つだけIAM Roleを付与できるがそのRoleに様々なポリシーを付与する事で様々なAWSリソースにアクセスできる

####AWSのアクセスキー
- アクセスキーIDとシークレットアクセスキーの2つで構成される認証情報
- S3やEC2といったAWSの各サービスに対してプログラムにおけるアクセスを認証するために作成される認証キー

####MFA設定
- ユーザーがログインする時に、アカウントとパスワードに加えユーザーが所有してるデバイスから発行されるワンタイムパスワードを入力することで、セキュリティーを強固にできる

#3. ドローンでクラウドを利用
####ドローンがLTE通信
- ドローンがLTE通信をできる様になれば、リアルタイムでカメラやセンサーの情報をクラウドにアップして解析などが可能
    - 災害時に遠隔地から離陸してデータをリアルタイムでクラウドにアップして確認など
- 飛行時間に影響を与えるAIの処理をクラウドで実施する事でより高度な事も可能

####ドローンショーでのドローン制御
[オリンピックのドローンショー解説動画](https://www.youtube.com/watch?v=T9DrALGftaw "オリンピックのドローンショー解説動画")
位置情報を使って、この位置に来たらLEDを何色に光らせろみたいなプログラムで制御してるらしい。
- GPSでは数メートル誤差が生じるのでRTKで補正
- AIも搭載していて風などで位置がずれたら自分で修正。 
・AIは機体のコンパニオンコンピューティングで処理してるんやと思うけど、クラウドでAIの処理を実施できたらどっちが電力消費少ないんやろ。

(こうゆうのを作る仕事をしてみたい、まだまだ知識たらんけど)
【悩めるpsql初心者へ...】ubuntu18→CentOS7でpostgresql13のヒント句を使った(泣)

# 概要
ubuntuだとrpmが使えないため、うまくpg_hint_planが使えなかった。
そこでcentOS7を入れてrpm使ってインストールした。

記事ごとに割と言っていることがバラバラで本当に４日間ほどこのアンサーにたどり着くのに時間がかかった。就職以来一番時間をかけたエラーだと思う。

なんとか早く対象者にこの記事が見つかればと思う。

# 環境
```bash
(PostgreSQL) 13.5
centOS 7
```

# OS切り替え(CentOS7をvagrantで立ち上げる場合)
```bash
$ vagrant init
```
vagrantファイルを変更し、CentOS7を仮想環境に入れる設定

```Vagrantfile
Vagrant.configure("2") do |config|
  config.vm.box = "centos/7"
end
```

```bash
# 仮想環境立ち上げ。時間かかる
$ vagrant up
# 仮想環境接続できる
$ vagrant ssh
```
# rpmをvagrantに転送
[ここ](https://ja.osdn.net/projects/pghintplan/downloads/73862/pg_hint_plan13-1.3.7-1.el7.x86_64.rpm/)からインストールしたrpmをvagrant環境にコピーする

ゲストOSから下記を実行

```bash
# ホストOSからゲストOSにコピーするためにvagrant-scpプラグインをインストール
$ vagrant plugin install vagrant-scp
# コピー
$ vagrant scp pg_hint_plan13-1.3.7-1.el7.x86_64.rpm :/home/vagrant
```
# postgres13をインストール
仮想環境のvagrantユーザーで

```bash
$ sudo yum -y install epel-release yum-utils
$ sudo yum-config-manager --enable pgdg13
$ sudo yum -y install postgresql13 postgresql13-server
$ sudo /usr/pgsql-13/bin/postgresql-13-setup initdb
$ sudo systemctl enable --now postgresql-13
# postgresが正常に動いているか確認
$ systemctl status postgresql-13
# postgresユーザーになる
$ sudo -i -u postgres
# DB操作できる
$ psql
```
## rpmインストーラーを使ってpg_hint_planをインストール
```$ exit```でvagrantユーザーになって、sudo権限で下記を実行

```bash
$ sudo rpm --install pg_hint_plan13-1.3.7-1.el7.x86_64.rpm
# 確認のためにもう一度
$ sudo rpm --install pg_hint_plan13-1.3.7-1.el7.x86_64.rpm
	package pg_hint_plan13-1.3.7-1.el7.x86_64 is already installed
```
## postgresqlに入って設定
```bash
$ psql
# db作成
postgres= create database test
# testデータベースを選択
postgres= \c test
postgres= LOAD 'pg_hint_plan';
LOAD
```
# 設定の更新
```bash
# だいぶ下の方にある。(Shift+gで一番下までひとっ飛び!!)
$ sudo vi /var/lib/pgsql/13/data/postgresql.conf
shared_preload_libraries = 'pg_hint_plan'
# 更新
$ sudo service postgresql-13 restart
```

# 確認
```bash
$ psql
postgres= \c test

postgres= 
/*+ SeqScan(users) */ 
EXPLAIN(ANALYZE,BUFFERS)
SELECT
count(*)
FROM
users;
```

# tips
ヒント句は、

- 統計情報を定期的に更新しない
- データ分布が変わらない
- 想定外の実行計画が選択された場合のコスト増大がすさまじい

の条件が揃った時は使うことを検討してもいいかもしれない
# 参考
[How To Install PostgreSQL 12 on CentOS 7 / CentOS 8](https://computingforgeeks.com/how-to-install-postgresql-12-on-centos-7/)

[pg_hint_planで実行計画を制御する](https://www.fujitsu.com/jp/products/software/resources/feature-stories/postgres/article-index/pg-hint-plan/)
djangoでアプリを作成するまで（herokuへデプロイする）

##概要
PythonのフレームワークであるDjangoでアプリを作ってherokuに更改するまでをまとめてみた。
今回は「heroku」へのデプロイ編
※前回のdjangoでアプリを作成するまでの手順は以下を参考
https://qiita.com/tky529/items/e340ab404a89c359ecd3

##前提
仮想環境で構築しておりますが、仮想環境以外でも同様の事が可能です。
Python 3.7.12

##手順
まずはherokuでアプリを動かすために必要なパッケージをインストールします

```
% pip install dj-database-url gunicorn whitenoise
```

次に必要な「django-heroku」もインストールしたいのだが、私の環境（pythonのバージョン等の関係？）だとpsycopg2のエラーが出てしまうため、以下のサイトを参考にインストールした
参考
https://e-tec-memo.herokuapp.com/article/197/

まずは依存関係のパッケージをインストールせずにdjango-herokuのみをインストール

```
% pip install --no-deps django-heroku
```

その後psycopg2をインストールするとエラーとなるためわかりに以下をインストール

```
% pip install psycopg2-binary
```


インストールが終わったらrequirements.txtファイルへ書き込みます。
requirements.txtはサーバーにアプリで使用するパッケージをHerokuに教えるためのファイルです。

```
% pip freeze > requirements.txt
```

####Procfileファイル
次にProcfileを作成します。
これは、Heroku起動時に実行するコマンドを伝えます。
ルートフォルダ直下にProcfileというファイルを作成し、以下の内容を記載します。
※gunicornはpython manage.py runserverの凄いバージョンらしい

```Procfile
web: gunicorn mysite.wsgi
```


####runtime.txtファイル
runtime.txtファイルはHerokuに使用するpythonのバージョンを知らせるためのファイルです。ルートフォルダ直下にruntime.txtを作成します。

```runtime.txt
python-3.6.4
```

####アプリケーションディレクトリ/local_settings.py

アプリケーションディレクトリ直下にlocal_settings.pyファイルを作成しましょう。
同じ階層のアプリケーションディレクトリ/settings.pyからDATABASE設定をコピーしていきます。
SECRET_KEYもこちらに設定します。

```config/local_settings.py
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))

SECRET_KEY = 'django-*******'

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

DEBUG = True
```

####アプリケーションディレクトリ/settings.py
先程の設定を受けてsettings.pyも修正します。
SECRET_KEYは削除してください

```config//settings.py
import dj_database_url

...

DEBUG = False

ALLOWED_HOSTS = ['127.0.0.1', '.herokuapp.com']

...

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'name',
        'USER': 'user',
        'PASSWORD': '',
        'HOST': 'host',
        'PORT': '',
    }
}


...
# 最後の行に追加
# ローカルではlocal_settingsを使用する設定
try:
    from .local_settings import *
except ImportError:
    pass

# SECRET_KEYを環境変数として使用する設定
if not DEBUG:
    SECRET_KEY = os.environ['SECRET_KEY']
    import django_heroku #追加
    django_heroku.settings(locals())


db_from_env = dj_database_url.config(conn_max_age=500)
DATABASES['default'].update(db_from_env)


```


####Herokuへデプロイ
まずはherokuにログインする
```
% heroku login
```

herokuアプリを作成する
※testappは好きな名前（他人と重複しない名前）
※アプリ名は忘れないようにする

```
% heroku create testapp
```


Gitコマンドを打っていく

```
% git status
% git add -A .
% git commit -m "first commit"
% git push heroku master
```

次にherokuにコマンド

```
% heroku ps:scale web=1
% heroku run python manage.py migrate
% heroku run python manage.py createsuperuser
・・・ユーザー名、メールアドレス、パスワードは任意のもので設定する
% heroku open
```

これでheroku常にアプリが公開（デプロイ）された

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/633008/e2d9db06-da62-9610-32d8-6affc80dd8c5.png)


お疲れ様でした！！


参考
https://tutorial.djangogirls.org/ja/
postgresqlでjsonbを使って検索してみたメモ

## 概要
JSONBでの検索メモ

```
CREATE TABLE test (dummy_id serial NOT NULL, group_id int,  data jsonb);
select * from test;
insert into test(dummy_id, group_id, data) values (1,1, '{"a":[{"group_id":1},{"group_id":2}]}');
insert into test(dummy_id, group_id, data) values (2,1, '{"a":[{"group_id":3},{"group_id":4}]}');
insert into test(dummy_id, group_id, data) values (3,2, '{"a":[{"group_id":1},{"group_id":2}]}');


SELECT dummy_id, test.group_id as test_group_id, groups.group_id,data
FROM test, jsonb_to_recordset(data#>'{a}') as groups(group_id int) 
WHERE groups.group_id in (1,2)
  AND dummy_id != 1
;
```

|dummy_id|test_group_id|group_id|data|
|---:|---:|---:|:---|
|3|2|1|{"a": [{"group_id": 1}, {"group_id": 2}]}|
|3|2|2|{"a": [{"group_id": 1}, {"group_id": 2}]}|


## 参考

[【PostgreSQL】 jsonb型カラムをSQLで検索・集計したい](https://blog.serverworks.co.jp/postgres_jsonb_search)

[PostgreSQL 11.5文書 第8章 データ型 8.14. JSONデータ型](https://www.postgresql.jp/document/11/html/datatype-json.html)
[PostgreSQL 11.5文書 第9章 関数と演算子 9.15. JSON関数と演算子](https://www.postgresql.jp/document/11/html/functions-json.html)
SpreadSheetで作った勤務スケジュールをLINEで通知し確認出来るようにしてみた

#１．SpreadSheetのスケジュールを開かずにスケジュールを確認したい#

こんにちは。小売業で人事をやっているKAZUと言います。
私の所属する部署にはメンバーが6名いて、土日関係ないシフト制のため、平日に出勤しないメンバーがいます。「○○さん今日休みだったかな」といった会話が2日に1回程度発生します。各メンバーのシフトはSpreadSheetで保管されていますが、月が新しくなる場合やシートが増えるとSpreadSheetの保管場所が分からなくなり、探すのも手間になっています。すばやく簡単に全員へ通知できればと思いました。

#２．実現したいこと#
SpreadSheetにアクセスせずにスケジュールを確認したい。
スケジュールはSpreadSheetの内容をLINEでメンバーに通知したい。

#３．完成したもの#
SpreadSheetの内容をIntegromatを使用してLINEに通知する簡単な仕組みです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2476779/77eff91f-59fa-9980-2508-96fd122b5476.png)

#４．使用したツール#
・SpreadSheet
・LINE Notify
・Integromat

#５．作成の工程#
Integromatを使用して以下の２つのフローを作成します。
①Google Sheet（Watch Rows)⇒②LINE(Send a Notification)

##Integromatのフロー全体像##
![フロー.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2476779/31ca4712-b4c6-d192-3dbe-98b174f65799.png)

##①SpreadSheetの設定##
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2476779/1740826c-deba-6c60-b873-d02869711085.png)

##②LINEの設定##
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2476779/8a674e63-3eab-9815-9347-9d8fc31ea5ad.png)

#６．同じ部署内の反応#
実際に実行したLINE通知画面をメンバー3名に見てもらい意見を聞いてみました。
・SpreadSheetsを見に行かずシフトが確認できるのは楽だと思う。
・スケジュールは文字形式ではなく、SpreadSheetの表のままのほうがい見やすい。
・プロセスを逆にして、LINE側に急に休む場合に入力して、メンバーに通知、SpreadSheetが書き換わるほうがよい。
・仕組みはよいが、自分が休みの日にLINE通知が来ない設定にしてほしい。
・リマインくんというLINEのbotがあるので、それを活用してみては。

#７．反省点、今後のために#
部署内の反応であった通り、急に休む場合など変更点をLINEに書き込んで、それをSpreadSheetsに反映し、変更点が赤色などで表示されるほうが、今回作成したものより実用性、ニーズがあることがわかりました。また『リマインくん』というLINE botが存在しており、スケジュールを管理する機能があるので、リマインくんとスケジュール表を組み合わせるとより簡単で実用性の高いものが作れることがわかりました。ニーズの把握不足、課題認識のずれ、現時点であるサービスの下調べができていなかったことは反省点です。
"git fetch origin"と "git fetch origin master" の違い

知っている人も多いだろうが、新卒の備忘録として残しておく。

- <b>git pull origin master (Aブランチで実行)
    - リモートのmasterブランチをローカルのAブランチにマージする
    - 言い換えると、最新のリモートのmasterブランチを持ってくる
    - その際に、リモートの他のブランチの情報は持ってこない


- <b>git fetch origin master && git merge origin/master (Aブランチで実行) 
    - git fetch origin master 
        - リモートのmasterブランチの変更だけをローカルにダウンロード（マージはされていない）
    - git merge origin/master
        - リモートのorigin/masterをローカルのAブランチにマージ
        - ここで初めてリモートの最新情報を持ってこれる


- <b>git fetch origin && git merge origin/master (Aブランチで実行) 
    - git fetch origin
        - リモートの変更を全てローカルにダウンロード
    - git merge origin/master 
        - リモートのmasterブランチをローカルのAブランチにマージ
        - ここで初めてリモートの最新情報を持ってこれる
【C#】List型変数に指定条件のデータが格納されているかの確認方法

#結論
`Any()`を使います。

```C#
List<int> dataList = new();

//変数内に2146435071個データを格納する。
dataList.AddRange(Enumerable.Repeat(0, 2146435071));

//リスト内に値が0のデータがあるか調べる
if (dataList.Any(x => x == 0))
{
    Console.WriteLine("値が0のデータあったよ！！");
}
```

#注意すること
下記のソースコードのように実装すると処理速度が大幅に低下します。

```C#:やらかしソースコード
List<int> dataList = new();

//変数内に2146435071個データを格納する。
dataList.AddRange(Enumerable.Repeat(0, 2146435071));

//リスト内に値が0のデータがあるか調べる
if (dataList.Count(x => x == 0) != 0)
{
    Console.WriteLine("値が0のデータあったよ！！");
}
```

###Count()とAny()で何が違うのか
`Any()`の場合は条件に合ったデータが1つでも存在した場合は途中で処理を中断するのに対して、`Count()`の場合はまず条件に合ったデータをすべて探して、探した結果の数が0個ではないかを確認しています。

###処理速度(Any() VS Count())
実際に処理速度がどれくらい違うのかを確認しました。
結果は

| 種類| 実行時間[ms] |   格納データ数|
|:-:|:-:|:-:|
|  Any() |   0|   1|
|  Count() |   5|   1|
|  Any() |   0|   10000|
|  Count() |   4|   10000|
|  Any() |   0|   2146435071|
|  Count() |   15484|   2146435071|

```C#:検証ソースコード
using System.Diagnostics;

List<int> dataList = new();

//変数内に2146435071個データを格納する。
dataList.AddRange(Enumerable.Repeat(0, 10000));

var sw = new Stopwatch();

sw.Start();

//リスト内に値が0のデータがあるか調べる
if (dataList.Count(x => x == 0) != 0)
{
    sw.Stop();

    Console.WriteLine($"Count()→{sw.ElapsedMilliseconds}[ms]");
}

sw.Restart();

//リスト内に値が0のデータがあるか調べる
if (dataList.Any(x => x == 0))
{
    sw.Stop();

    Console.WriteLine($"Any()→{sw.ElapsedMilliseconds}[ms]");
}
```

...(´ε｀ )ﾌﾑﾌﾑ
やっぱり処理的に考えてもそりゃ`Any()`の方が早いっすよねー。
じゃあ、Listの最後に0が格納されていてそれ以外が1だった場合はどうなんの？ということで検証してみました。
結果は

| 種類| 実行時間[ms] |   格納データ数|
|:-:|:-:|:-:|
|  Any() |   0|   1|
|  Count() |   0|   1|
|  Any() |   0|   10000|
|  Count() |   4|   10000|
|  Any() |   14942|   2146435071|
|  Count() |   15356|   2146435071|

まあ、想像通りでしたね。`Any()`も結局はList内の要素を順番に取り出して条件に合っているかを確認しているので要素の最後のみ条件に一致した場合は、`Count()`のやらかしソースコードとほぼ同じ時間がかかるみたいです。

```C#:検証ソースコード
using System.Diagnostics;

List<int> dataList = new();

//変数内に2146435070個データを格納する。
dataList.AddRange(Enumerable.Repeat(1, 2146435070));

//最後に0を追加する！
dataList.Add(0);

var sw = new Stopwatch();

sw.Start();

//リスト内に値が0のデータがあるか調べる
if (dataList.Count(x => x == 0) != 0)
{
    sw.Stop();

    Console.WriteLine($"Count()→{sw.ElapsedMilliseconds}[ms]");
}

sw.Restart();

//リスト内に値が0のデータがあるか調べる
if (dataList.Any(x => x == 0))
{
    sw.Stop();

    Console.WriteLine($"Any()→{sw.ElapsedMilliseconds}[ms]");
}
```
↓結果↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2519245/c9ddd33d-5966-4955-1618-bc7f747503c4.png)

####ちなみに
インテリセンス君が`Any()`使えや！と怒ってくれるのでｳｨｯｽって従っておけばいいと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2519245/48d97855-6f30-982c-5447-2de4d3c830b8.png)

以上！！！
【AWS】Application Load Balancerにhttpsアクセスできるようにする

前提

- Application Load Balancerに独自ドメインを割り当てている

# SSL証明書を取得する

サービスからCertificate Manegerを選択

![cm1.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596144/c454c372-9fdb-029d-2294-e27b1c804031.jpeg)

証明書をリクエスト

![cm2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596144/57aa1479-3516-17c7-478c-fbfc1bf2f91a.jpeg)

パブリック証明書をリクエスト

![cm3.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596144/2993c606-d060-d45c-cc53-313087c98d9b.jpeg)

- 完全修飾ドメイン名にhttps化したいドメインを入力する
- DNS検証

![cm4.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596144/c2e458fa-55c7-c0ec-81c2-8a41c3082e8f.jpeg)

リクエストをクリック

![cm5.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596144/165ecb85-d260-f6e1-7fc4-296208d610d8.jpeg)

証明書IDをクリック

Route53でレコードを作成をクリック

![cm6.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596144/03885427-2bd7-8c46-72ad-b1d278b3dea5.jpeg)

レコードを作成をクリック

![cm7.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596144/97018c5e-b05c-faf5-a7a0-45f01542fc31.jpeg)

検証ステータスが発行済みになるまで待つ。10分くらい?

# ロードバランサーのリスナーを設定する

### httpリクエスト用のリスナーを編集する

既に存在するhttpリクエスト用のリスナーを選択し、編集をクリック

![lb1.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596144/81b0af34-1309-3bc3-ebfa-bb4a725fb738.jpeg)

httpリクエストされたとき、そのままターゲットグループにhttpリクエストするよう設定されていたので、これを削除する。

![lb2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596144/8f79be85-3349-f677-36e5-5d7ac57c02b4.jpeg)


代わりにhttpsにリダイレクトするよう設定をする。

![lb3.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596144/6f9fd526-4904-a11d-8910-27c08441b2de.jpeg)


### httpsリクエスト用のリスナーを追加する

httpsリクエストされたら、ターゲットグループにhttpリクエストするよう設定する(`Forward to`)

![lb4.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596144/8a72f0fd-3ba6-c428-98bf-0b73f7be5c46.jpeg)


`Default SSL certificate`の項目では、`From ACM`とドメインを選択する

![lb5.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596144/dcf266a3-ef66-d7d9-453a-24f66b6d2480.jpeg)



# セキュリティグループを編集する

追加したリスナーの箇所で『ロードバランサーようのセキュリティグループでは、このリスナーポートでのトラフィックは許可されません』と言われたので、ロードバランサーに割り当てているセキュリティグループのインバウンドルールにhttps接続を許可するルールを追加する。

![lb6.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596144/caee2b75-f800-2148-5e4a-218a6ce8d462.jpeg)

インバウンドルールについては割愛。これでhttpsアクセスできるようになった。

# 参考

[Application Load Balancer を使用して HTTP リクエストを HTTPS にリダイレクトするにはどうすればよいですか?](https://aws.amazon.com/jp/premiumsupport/knowledge-center/elb-redirect-http-to-https-using-alb/)

[AWS運用には無料のSSL証明書を活用しよう！（取得も簡単、難易度低です)](https://aws.taf-jp.com/blog/37623)

[Qiita AWSでSSL証明書を作ってELBに設定する](https://qiita.com/kosuge/items/3c51ff4bb59d94a57d2e)
MacBookにadbをインストール・使えるようにする方法

[yamaday0u](https://twitter.com/yamaday0u)です。
仕事でadb（Android Debug Bridge）を利用する機会があったので、整理します。

ちなみに未経験からのエンジニア転職後初のQiitaへの投稿になります。転職活動を振り返った記事も投稿していますのでぜひ読んでみてください。
[【未経験からのエンジニア転職応援】実務未経験からのエンジニア転職活動の振り返りの共有](https://qiita.com/yamaday0u/items/65d6bf2589c46312f0d2)

※2022年から技術系の記事は[個人ブログ](https://yamaday0u.net/category/programmer/)に投稿しております。ぜひこちらもご覧ください→[yamaday0u Blog](https://yamaday0u.net/category/programmer/)
## adbとは
Android Debug Bridgeの略で、Android SDKに標準で付属するデバッグツールです。
adbコマンドを用いて、開発中のAndroidアプリのデバッグを行うことができます。

## 前提
Android Studioがインストールされていること。

Android Studioがインストールされていれば、Android SDKが使えるようになっています。

## Android SDK Locationの確認
adbを使えるようにするために、まずAndroid StudioでAndroid SDK Locationを確認します。

Android Studioを開き、`Tools` > `SDK Manager`をクリックします。
![スクリーンショット 2022-02-05 11.01.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/849306/3edb93c9-ddbb-571a-4de3-e60cbc8a9181.png)

Android SDK Locationにパスの位置が表示されています。これをターミナルでパスを通します。
SDK Platformsに何かしらのSDK Platformのパッケージがインストールされていれば、パスを通した後にadbコマンドが使えるようになります。
![スクリーンショット 2022-02-07 22.11.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/849306/27076e16-ec3a-22ab-c525-e7fa5583c015.png)


## ターミナルでSDK Platformsのパスを通す
SDK Managerで確認したロケーションにパスを通します。

### bashの場合
ルートディレクトリ直下の.bash_profileファイルにパスを記述します。

```bash:ターミナル
vim ~/.bash_profile
```

```:~/.bash_profile
export PATH=$PATH:/Users/ユーザー名/Library/Android/sdk/platform-tools
```

最後にパスを読み込ませます。

```bash:ターミナル
source ~/.bash_profile
```

### zshの場合
ルートディレクトリ直下の.zshrcファイルにパスを記述します。

```zsh:ターミナル
vim ~/.zshrc
```

```:~/.zshrc
export PATH=$PATH:/Users/ユーザー名/Library/Android/sdk/platform-tools
```

最後にパスを読み込ませます。

```zsh:ターミナル
source ~/.zshrc
```

## adbが使えるか確認
ターミナルにadbと入力して以下のような表示が出たらadbを使う準備完了です！

```zsh:ターミナル
$ adb
Android Debug Bridge version 1.0.41
Version 31.0.3-7562133
Installed as /Users/ユーザー名/Library/Android/sdk/platform-tools/adb
.
.
.
```


## 参考資料
[Android Debug Bridge（adb）（Android デベロッパー）](https://developer.android.com/studio/command-line/adb?hl=ja)
[IT用語辞典 e-Words](https://e-words.jp/w/adb.html)
[Android Debug Bridgeとは？Android開発のデバッグツールのインストールと初期設定（Qiita）](https://qiita.com/TanakanoAnchan/items/676e1e9c15028fd6cb91)
[MacのPCからADBコマンドを利用できるようにする(すでにJavaがPCに入っている人向け)（Qiita）](https://qiita.com/miriwo/items/cb0fa4c2def859bc2641)
TypeScriptでfs, pathモジュールがインポートできなかった (Next.js Tutorial)

# はじめに
Next.jsのチュートリアルをTypeScriptでやっていた際に、モジュールが見つからないとVSCodeに言われました。
悲しい。

# 問題
**モジュールfsとpathがインポートできません。**
公式チュートリアルのプリレンダリング(SSG vs SSR)の部分で、`posts.js`なるものを作るのですが、自分はTypeScriptでやりたかったため、`posts.ts`としました。
しかし、JSファイルだとインポートできていたモジュールが、TSファイルにするとできなくなってしまいました。困った。

```posts.js:
// 公式のチュートリアルコード
import fs from 'fs'
import path from 'path'
```

# 解決策
**`@types/node`をインストールすればよいらしい。**
TS用のモジュールパッケージが入っていない感じなのかな？
理屈はわかりませんが、とりあえず参考ページにあったコマンドを叩く。

```
npm install --save-dev @types/node


# 自分はDockerを使っていたので、以下のコマンド。
# 1.コンテナをバックグラウンドで立ち上げ
# 2.コンテナを指定して命令を与える

docker-compose up -d
docker exec {your container name} npm install --save-dev @types/node

# 念のためアップデートを実行しておく
npm update
```

試してみたところ、無事にモジュールがインポートできるようになっていました！

# おわりに
調べれば解決法が落ちてる現代の情報社会、ありがたい。

# 参考

https://stackoverflow.com/questions/41553291/can-you-import-nodes-path-module-using-import-path-from-path/45218692
[0] Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: Module: /Users/....../webpack.config.js [0] require() of ES modules is not supported.と出た時の対処法

## 解決法
拡張子を変更すると解決しました！！
before

```
webpack.config.js
```
after

```
webpack.config.cjs
```

そして、package.jsonも変更

```
{
  ...略
  "scripts": {
    "build": "webpack --config webpack.config.cjs",
    "start": "webpack serve --config webpack.config.cjs"
  },
  ...略
}

```