OmniAICreator/Qiita-1.07M huggingface dataset:
python で linebot を 作る

# したいこと

・LINEBOTを作る
・メッセージを送るだけ

参考
https://chuna.tech/blog/web-service/LINE/how-to-use-line-messaging-api/



LINE Developer に ログイン
https://developers.line.biz/console/


インスコ

```
pip install line-bot-sdk
```


# トークンとIDの確認

トークン
Messaging API設定 > チャンネルアクセストークン

自分のユーザーID
チャネル基本設定の一番最下部にある

```test.py
from linebot import LineBotApi
from linebot.models import TextSendMessage
from linebot.exceptions import LineBotApiError

CHANNEL_ACCESS_TOKEN = 'your=' #自分のトークンを入れい
USER_ID = 'your' #自分のユーザーIDを入れて下さい

def send_message(text):
  line_bot_api = LineBotApi(CHANNEL_ACCESS_TOKEN)

  try:
      line_bot_api.push_message(USER_ID, TextSendMessage(text=text))
  except LineBotApiError as e:
    print(e.message)

if __name__ == "__main__":
  text = "テストメッセージ" #好きな文章でOKです
  send_message(text)

```

これで `test.py` を動かせばメッセージが送られる

`OK`
【MySQL】ERROR 1045 (28000)が出たときの対処法

`MySQL 8.0.32`にログインしようとしたところ、 __「ERROR 1045 (28000)」__ が出ました。

状況は以下の2通りです。

# `mysql -u root`でエラーが出る場合
```
$ mysql -u root
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
```

`-p`をつけてそのあとにそのままパスワードを入れるとログインできました

```
$ mysql -u root -pパスワード
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 27
Server version: 8.0.32 Homebrew

Copyright (c) 2000, 2023, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> 
```
`-p`のあとは空白不要です。


# MySQLをインストールしたばかりで、`mysql -u root -p`でエラーが出る場合
```
$ mysql -u root -p
Enter password: 
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
```

この場合はおそらくのrootユーザーのパスワードが設定されていないことが原因であるため、一旦`mysql -u root`でログインし、以下を実行すると上手くいくかと思います
`set password for root@localhost = 'パスワード';`

:::note info
`update mysql.user set password=password('パスワード') where user = 'root';`はMySQL5系まで有効なコマンドで、8系ではエラーが出るため使えません
:::
```
$ mysql -u root
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 11
Server version: 8.0.32 Homebrew

Copyright (c) 2000, 2023, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> set password for root@localhost = 'パスワード';
Query OK, 0 rows affected (0.09 sec)
```

一旦ログアウトし再度`mysql -u root -p`でログインしてみます
```
mysql> \q
Bye
$ mysql -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 12
Server version: 8.0.32 Homebrew

Copyright (c) 2000, 2023, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> 
```

これでログインできました！

### 参考
- [ERROR 1045 (28000):でMySQLにrootログインできない場合の対策 | 己で解決！泣かぬなら己で鳴こうホトトギス](https://onoredekaiketsu.com/can-not-root-login-to-mysql-with-error-1045-28000/)
- [MySQL8でユーザーのパスワードの変更 / リセット方法](https://www-creators.com/archives/5574)
git へ　プッシュ　ターミナルにて

<h1>ターミナルにて、プッシュする方法</h1>

    $git push origin add-comments
origin は、プッシュ先
add-commets　は、ブランチ名


<h1>ブランチ変更</h1>

    $git checkout main

<h1>pull</h1>

    $git pull
Powershell実行ポリシーの私的ベストプラクティス

# この記事で伝えたいこと
「**むやみにコンピューター全体へ実行ポリシーを設定すべきではない**」とうことです。
一時的な作業でps1スクリプトを実行する、定期ジョブでps1スクリプトを実行することが要件であれば、セキュリティ観点からコンピューター全体のポリシーを緩和するのではなく、実行時のみポリシーを緩和すべきです。
```powershell:非推奨な使い方
Set-Executionpolicy -ExecutionPolicy Unrestricted -Force
```

# 私的ベストプラクティス

#### 1. 一時的にスクリプトを実行する場合
以下の様にScopeを現在起動しているPowerShellのProcessに限定し、一時的なポリシー設定をすべきです。サブプロセスにも適用されるため、ps1スクリプトから呼び出すスクリプトにも適用されます。
```powershell:一時的にスクリプトを実行する場合
Set-Executionpolicy -ExecutionPolicy RemoteSigned -Scope Process -Force
```
| Scope | 説明 |
| ---------------- | ------------------------------------------------------ |
| Process | 現在のPowerShellプロセス内でのみ実行ポリシーが適用されます。 |
| CurrentUser | 現在のユーザーアカウントに対して実行ポリシーが適用されます。 |
| LocalMachine | コンピュータ全体に対して実行ポリシーが適用されます(デフォルト値)。 |

#### 2. 定期ジョブでスクリプトを実行する場合
以下のpowershellコマンドにExecutionPolicyオプションを指定して、一時的にポリシーを緩和すべきです。
```powershell:定期ジョブでスクリプトを実行する場合
powershell -ExecutionPolicy RemoteSigned -File "D:\script\test.ps1"
```
SIEM

# SIEM（シーム)
```各種ログを総動員して解析し、セキュリティ上の脅威となる事象を検知```する仕組み

```SIM```、```SEM```の別々の仕組みが合わせてSIEMという仕組みになる。

### 効果
情報の収集・管理を効率的に行うと、```不正行為を早期発見により不正行為の抑止```につながる。
それにより驚異の検知支援で```インシデントの予兆を知る```ために役立つ

### 注意
SIEMは効果が出るか出ないかは```日常運用にかかっている```。

## SIM
複数の種類のログを収集して一元的に管理する。
```情報の収集・管理```を行う。

## SEM
事前に設定した監視・確認ルールに従って、複数ログの記録を組み合わせて分析し、管理者に通知する。
```脅威となる事象の検知支援```を行う。

## ログを保存する
収集・管理対象となるログを残すのは、SIEMではなく、```導入済みの機器```
### ログを残す機器（例）
* ルーター
* ファイアウォール
* インターネット接続用のプロキシサーバー

# 出典
https://www.sbcr.jp/product/4797388800/

# 感想
SIEMは悪意ある通信に対して早期にそれに対して処置をすることができるから。日頃から気にかけなくてはならない。
【アプリ作り：Step1】Monaca+Vue+Sassの開発環境構築

# 前置き
息抜きと勉強を兼ねて、自分がほしいなと思うアプリを作ろうと思います。
今回はStep1として、Monaca+Vue+SCSSの開発環境構築方法についてメモです。
前提としてMonacaにログインしているとします。

# 手順１:Monaca+Vue導入

1\.新しいプロジェクトを作成し、テンプレートの種類を選択
![スクリーンショット 2023-03-05 16.13.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224077/a1b642ed-eec7-35a7-c55c-f57941e26851.png)

2\.フレームワークを選択
![スクリーンショット 2023-03-05 16.13.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224077/723fe562-ed05-b109-5292-2b4e214a4a0e.png)

３\.お好きなテンプレートを選択
![スクリーンショット 2023-03-05 16.13.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224077/4144d0b7-10b6-32bd-5a5a-3b9e670b3993.png)


4\.プロジェクト情報を記入
![スクリーンショット 2023-03-05 16.13.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224077/eebe5da6-b250-443f-c47e-b50f41dbbcd4.png)

5.作成を確認
![スクリーンショット 2023-03-05 16.18.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224077/bed65bdc-2596-8d78-0336-3c97d5b30b42.png)

6.ローカルの開発環境構築
```terminal
cd [プロジェクトを作りたい場所]
npm i -g monaca
monaca login //←コマンド押下後、monacaのログイン情報を入力
monaca import
monaca preview
```

![スクリーンショット 2023-03-05 16.22.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224077/154df671-76e8-2ed4-989c-8a3b8eb7bb18.png)

# 手順2:Sassのインストール

以下のコマンドを押下し、Sassをインストール
```terminal
npm install node-sass nodemon --save-dev
```

src配下に、scssディレクトリを追加。
（※src配下の全体構成は以下キャプチャ参照）
![スクリーンショット 2023-03-05 18.36.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224077/f768e1b5-b16f-4d8a-9993-ca0158b193e7.png)


package.jsonを修正
```package.json
"scripts": {
    "monaca:preview": "npm run dev & npm run watch",
    "monaca:transpile": "npm run build",
    "monaca:debug": "npm run watch",
    "dev": "cross-env NODE_ENV=development vite",
    "watch": "cross-env NODE_ENV=development vite build --watch", //←★修正対象
    "build": "cross-env NODE_ENV=production vite build", //←★修正対象
    "postinstall": "cpy ./node_modules/framework7-icons/fonts/*.* ./src/fonts/ && cpy ./node_modules/material-icons/iconfont/*.* ./src/fonts/",
    "compile": "node-sass src/scss/style.scss src/css/style.css" //←★修正対象
},
```

# 手順3:ビルド
```
npm run compile
npm run build
monaca preview
```
記事にコメント機能⑤

<h1>コメント一覧を表示</h1>

MVCのコントローラーとビューの役割
app/controllers/articles_controller.rb

      def show
        @comments = @article.comments
      end

@commentsを定義したので、viewで表示していきます。

    .article
      %h2 コメント一覧
      - @comments.each do |comment|
        .article_comment
          %p= comment.content

app/assets/stylesheets/article.scss
調整

    h2{
        font-size: 16px;
      }
    &_comment {
        padding: 12px 0;
      }

app/controllers/articles_controller.rb
いまここに@commentsと定義しました。
app/views/articles/show.html.haml
その後、showで@comments.eachで表示しました。

railsの思想として、あくまで、viewというものは表示するためのもの。コントローラーで色々と定義して、それをviewで表示しましょう。
こうすることで、railsぽくなる！！

    .article
      %h2 コメント一覧
      - @article.comments.each do |comment|
        .article_comment
          %p= comment.content
と書く人もいる。
Googleデジタルマーケティング＆Eコマース：認知ステージの基礎

# はじめに

”Googleデジタルマーケティング＆Eコマース プロフェッショナル認定証"　の受講が完了しました(2022/3/3)。私がこのコースから得られた素晴らしい体験を、テーマごとに分割して、わかりやすくご紹介しています。興味を持たれた方は、是非下記を受講してみてください。

https://jp.coursera.org/professional-certificates/google-digital-marketing-ecommerce

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/77505f22-0d8f-b3af-4f9c-ed148bcefd65.png" width="800">

[以前、マーケティングファネル][funnel]を紹介しました。今回、認知ステージ（トップ・オブ・ザ・ファネル）について、もう少し詳しく説明します。

[funnel]: https://qiita.com/mapami/items/56f851127a0880d3c97e

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/4c241597-897d-6e8e-5205-efdb4cfa4b76.png" width="300">


# 認知ステージの最初のステップ

認知とは、潜在顧客が初めてあなたのブランドと出会うことです。

これは簡単なことのように思えるかもしれませんが、どうすればあなたのブランドを適切なオーディエンスの目に留まらせることができるのでしょうか？

最初のステップは、リサーチです。あなたの顧客が誰で、オンライン上のどこにいるのかを知ることで、マーケティング活動を適切な場所に集中させることができます。

***<font color="MediumBlue">特定のオーディエンスを知る</font>*** ことで、彼らに到達する可能性が最も高いチャネルを選ぶことができます。

# 認知度を高める戦術

ビジネスが顧客にリーチするために使用できる戦術の1つが、ランキングや検索エンジンの結果を向上させる方法です。

- 特定の検索キーワードを中心に、ウェブサイトのコンテンツを最適化する。
- ウェブサイト・ソーシャルメディア・Eメール・ビデオプラットフォームにデジタル広告を掲載するために費用を支払う。
- 他のブランドやインフルエンサーとプロモーションのパートナーシップを結ぶ。

強力な戦略は、***<font color="MediumBlue">複数のチャネルを活用し、すべてのチャネルで一貫した体験</font>*** を生み出すものであることを覚えておいてください。

また、認知は ***<font color="MediumBlue">一過性のものではない</font>*** ということも覚えておいてください。誰かがあなたのビジネスを知ったとしても、それが次の検討ステージに進むまでには、数日、数週間、あるいはそれ以上の時間がかかることがあります。

潜在顧客にリーチしたら、その人にあなたのことを思い出してもらうことが目標です。例えば、あなたの会社が冷蔵庫を販売しているとします。それは大きな買い物で、毎日するものではありません。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/42d00236-e46b-7193-7fbe-cba66b928b52.png" width="700">

しかしながら、オンラインプレゼンスを一貫して維持することで、いざというときにあなたの存在を思い出してもらうことができます。そうすれば、あなたのサービスが必要になったとき、あなたのビジネスを思い浮かべるでしょう。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/ea4eae24-0f41-fd24-c264-03a80ea12142.png" width="700">


認知ステージは、認知度と顧客エンゲージメントを向上させます。マーケティング担当者はさまざまなツールやチャネルを使用して潜在顧客とつながり、彼らの記憶に残るようにします。

# 認知の測定

ターゲットにリーチするために適切なチャネルを選択することは、企業がオンラインで製品を販売する上で重要なことです。しかし、最も重要なことは、選択した戦術がうまくいっているかどうかをどのように確認するかということです。

- すでに行っていることを改善する方法はあるのか?
- それともまったく新しい計画でやり直す必要があるのか?

これらの質問にすべて答えるのが、測定です。

測定基準とは、目標に対する進捗を追跡・評価するために使用される定量化可能な測定値のことです。

例えば、デジタル広告の認知度を測定するために、マーケティング担当者はインプレッション、リーチ、フリークエンシーなどを追跡するツールを使用します。数値が企業の目標である認知度を下回っている場合、広告戦略を見直すことになるかもしれません。

| 測定基準  | 内容  | 
| :--- | :--- | 
| インプレッション | デジタル広告が人々の画面上に表示された回数の合計です。この数には、広告に2回以上接触したユーザーも含まれます。100人が200回広告に接触した場合、200回表示されたことになるので、インプレッション数は200となります。 | 
| リーチ | 異なるデバイスで広告に遭遇したユニークな個人の総数を指します。何度広告に出会っても、カウントされるのは1回だけです。100人が200回遭遇した広告のリーチは100となります。 | 
| フリークエンシー| ある時間枠の中で、各個人がその広告に何回遭遇したかを示すものです。なので、100人のそれぞれが1週間に2回広告を取得した場合、そのフリークエンシーは2です。 | 

:::note warn
これらは、認知度を測定するために使用することができるメトリックのほんの一部です。
:::

企業は、Webサイトのあるページに一定量の訪問者を獲得するなど、より具体的な認知度目標を設定することも可能です。何を測定するかは、何を達成しようとするかによって異なります。そのため、ファネルの各段階に応じた目標を設定することが重要です。
台風通過前後の風雨の様子を地図とグラフで整理する

## はじめに

過去の台風上陸前後に、どのくらい雨や風が強かったのか気になりました。そこで、特定の都市において、台風通過・上陸前後の風雨の様子を一覧できるようなウェブサイトを作成してみました。

:::note alert
注意：データ等は精査しておりませんので、間違いが含まれるかもしれません。**ご利用の際は自己責任で**お願いいたします（当方は責任は負いません）。
:::

とりあえず、以下の３つの台風を作成しています。

* [令和元年台風第19号](https://mghs15.github.io/typhoonSummary/?data=2019T19&style=mono2)@東京
* [令和２年台風第10号](https://mghs15.github.io/typhoonSummary/?data=2020T10&style=mono2)@鹿児島
* [令和４年台風第14号](https://mghs15.github.io/typhoonSummary/?data=2022T14&style=mono2)@鹿児島

※令和元年台風第19号@東京の例
![Screenshot 2023-03-05 at 15-21-54 T-Summary.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2842832/c910ee56-0f89-46ba-42be-ffd549a78a08.png)

レポジトリはこちら

https://github.com/mghs15/typhoonSummary

## データの収集と加工

台風や当時の気象の状況は気象庁のウェブサイトから取得できます。台風の経路は、GeoJSON へ変換し、地図上に掲載します。地図の表示には、ウェブ地図ライブラリとして [Mapbox GL JS](https://github.com/mapbox/mapbox-gl-js)を、背景地図として、[国土地理院 最適化ベクトルタイル](https://github.com/gsi-cyberjapan/optimal_bvmap)を利用しています。

各気象状況はグラフにして、時系列が揃うように縦に並べたいと思います。グラフの表示には、[Chart.js](https://www.chartjs.org/) を利用することにしましたので、各気象データは、Chart.js が読み込めるようなデータ形式に変換しています。

また、各台風の情報やフォーカスするべき期間については、別途メタデータを作成しています。

最後に各データを統合して一つの JSON ファイルにまとめて、Web サイト用のデータとします。

### 台風の経路

気象庁の「[台風位置表](https://www.data.jma.go.jp/yoho/typhoon/position_table/index.html)」で得られるデータから作成する。

1. 上記ページで、目的の台風の位置表 PDF ファイルを開く。
2. ファイル全体をコピーして、テキストファイルにペースト。
3. テキストファイルを GeoJSON へ変換。

参考：変換には[以前の記事](https://qiita.com/mg_kudo/items/d490f7b47f44e74e8b8e)の成果を利用しています。

### 降水量・風速

気象庁の「[過去の気象データ検索](https://www.data.jma.go.jp/obd/stats/etrn/index.php)」で得られるデータから作成する。

1. 上記ページで、表示地点、年、月、日を指定。
2. 「YYYY年MM月DD日の１時間ごとの値を表示」をクリック。
3. 表示された表をヘッダを除いてコピーして、テキストファイルにペースト（タブ区切りでペーストできる）。
4. 年、月、日、場所の4カラムを手動で列の先頭に追加。
5. 必要な日付分繰り返して一つのファイルにまとめる。
6. Chart.js に渡せるようなデータ構造の JSON へ変換。

### 潮位

気象庁の「[潮汐観測資料](https://www.data.jma.go.jp/gmd/kaiyou/db/tide/genbo/index.php)」で得られるデータから作成する。

1. 上記ページで、表示地点、表示年月を指定。
2. 毎時潮位にチェックを入れて、「各項目を入力してクリック」を押す。
3. 表示された表をヘッダを除いてコピペして、テキストファイルにペースト（タブ区切りでペーストできる）。
4. 場所、年、月の3カラムを手動で列の先頭に追加。
5. Chart.js に渡せるようなデータ構造の JSON へ変換。

## ハマったところ

グラフを並べる関係上、各グラフの描画範囲（軸の目盛りの数値や軸の名称を除いた領域）の大きさを揃えたかったのですが、Chart.js では、y 軸領域の大きさ（目盛りの桁数等で変化）によって、グラフ描画範囲が変わってしまうという問題に当たりました。解決のためのスマートな方法が見つからず、適当な文字（"=" 等）で埋めて、目盛りの桁数をそろえることでお茶を濁しています。

また、Chart.js の v3 以降の場合、[時系列データを扱うには別途 adaptor が必要](https://www.chartjs.org/docs/latest/migration/v3-migration.html#setup-and-installation)となっております。今回は [chartjs-adapter-moment](https://github.com/chartjs/chartjs-adapter-moment) を利用しました。

## 参考文献
* 気象庁
	* [台風位置表](https://www.data.jma.go.jp/yoho/typhoon/position_table/index.html)
	* [過去の気象データ検索](https://www.data.jma.go.jp/obd/stats/etrn/index.php)
	* [潮汐観測資料](https://www.data.jma.go.jp/gmd/kaiyou/db/tide/genbo/index.php)
* [国土地理院 最適化ベクトルタイル](https://github.com/gsi-cyberjapan/optimal_bvmap)
* [Mapbox GL JS](https://github.com/mapbox/mapbox-gl-js)
* [Chart.js](https://www.chartjs.org/)
	* [chartjs-adapter-moment](https://github.com/chartjs/chartjs-adapter-moment)
* [【Chart.js】時系列(タイムライン)のグラフを表示させる方法](https://mat0401.info/blog/chartjs-timeline/)
Elastic IPの関連付け解除と解放を行ったのに使用量が増える時の解決法

## はじめに
AWS超初心者です。EC2インスタンスの使用量が増え続けていたので解決法をメモします

## この記事の対象者
この記事は下記のような人を対象にしています。

- AWS初心者
- EIPの関連付け解除と解放を行ったのに使用量が増えて困ってる人
- インスタンスは消したくないけど使用時間が増えるのはイヤな人

## 結論
**EBSボリュームがアタッチされたままでした！！**
AWS EC2のインスタンスを停止してEIPの関連付け解除・解放を行っても、EBSボリュームがアタッチされたままだと、データを保存するために使用時間が増え続けているみたいです。
このため、インスタンスを停止した後は、EBSボリュームもデタッチする必要があります。

## デタッチする手順
1. EC2コンソールのサイドバーからElastic Block Storeの**ボリューム**を選択する
2. デタッチしたいインスタンスのEBSにチェックを入れる
3. アクションタブからボリュームのデタッチを選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2871384/7a264edc-490b-b9f6-27eb-3dc9bd6bea0c.png)
以上の手順でボリュームの状態が使用中から使用可能になれば成功です。

## おわりに
こちらから各サービスの使用状況を確認できるので、Elastic Compute Cloud→Asia Pacific (Tokyo)の使用量が増えてないか確認してみてください。

https://us-east-1.console.aws.amazon.com/billing/home#/bills
sliceメソッドのイメージ

<p>めちゃくちゃ小ネタです。</p>
<p>sliceメソッドの引数が一瞬わからなくなることがまれによく（？）あったのですが、自分の中で覚えやすかった方法のメモ。</p>
<h2>sliceメソッドとは</h2>
<p>文字列や配列に対して使用し、所定の位置でそれらを切り抜くメソッド。</p>
<p>例えば以下のように使う。</p>

```javascript: test.js
const str = "小ネタ記事です"
const result1 = str.slice(3);
const result2 = str.slice(3,5);

// 結果
// result1 : 記事です
// result2 : 記事
```
<h2>個人的な混乱ポイント</h2>
<p>個人的には２つの引数を取るときが若干わかりづらいときがある。</p>
<p>例えばresult1の方は割とわかりやすくて、この文字列を先頭からインデックス番号０を順に振っていくとして、「記」がインデックス番号３になるので、それ以降を切り取るイメージで良い。</p> 
<p>しかし、２つの引数を取るときは、第二引数のインデックス番号の文字が含まれるのか含まれないのか、どっちやったっけ、となることがたまにあった。</p>

<h2>個人的な整理方法</h2>
<p>個人的には以下の様に頭の中を整理すると間違えなくなった。</p>

```javascript: test.js
"小ネタ記事です" 
 0 1 2 3 4 5
// この様に文字にインデックス番号を振られていると考えるとわかりにくいので、、、

"/ 小 / ネ / タ / 記 / 事 / で / す /"
 0    1   2   3    4    5    6   7  
// このように文字間に仕切りがあり、そこに番号が振られていて
// 仕切りの位置で切り取られるのだと考えるとスッキリした
```
<p>仕切り番号でスライスされているのだ、と考えるとなんだかスッキリしたのでした。</p>

<p>以上、5分で書いた小ネタ記事でした。</p>
BYOD

# BYOD
```私物のパソコンやスマートホンなどを、業務に使用したり社内ネットワークに接続すること```。
この行為によって持ち込まれたウイルスに社内のシステムが感染したり、許可されていないソフトウェアの使用などのリスクがあり、禁止する企業が多い。

# 出典
https://gihyo.jp/book/2022/978-4-297-12375-8

## メリット
BYODの具体的なメリットには次のようなものがあります。

### 業務効率の向上とサポート工数削減
使い慣れている端末なのでスタッフが```操作方法などを熟知しているために迷いなく操作```でき、社用端末使用時よりも社内ヘルプデスクなどに```問い合わせすることも少なくなります```。
### 端末を複数台持つ必要がなくなる
社用とプライベート用の```2台のスマートフォンを持つ必要がなくなる```ことで、バッテリーなどの端末の管理が楽になり、紛失リスクも減少します。
### 情報端末に関わるコストが削減できる
社員が所有する端末を使用するので、```情報端末に関わる初期投資および運用コストが削減```できます。今までコスト等の問題で一部の外出が多いスタッフのみモバイル端末を導入していた場合でも、全スタッフに広げることができます。
### シャドーIT対策になる
次章で詳しく述べますが、スタッフが勝手にプライベート端末を社用に使用する「シャドーIT」対策として有効です。

## デメリット
もちろんBYODにはデメリットも存在し、次のようなものが挙げられます。

### 情報セキュリティリスクが増加する
BYOD導入時に最も懸念されるのが情報セキュリティリスクです。プライベートでさまざまなアプリケーションをインストールしたりWebサイトを訪問したりすることで、不正なアプリケーションのインストールやウィルス感染などの恐れがあります。そしてそれらを利用した不正アクセスによって、```機密情報が漏えいしたり重要な情報が改ざんされたりするリスクも増加```。端末を他人に貸与したり紛失したりすると、社員以外の人物が社内システムなどにアクセスできる危険性が高まります。
### 社員の公私の切り替えが難しくなる
プライベート端末で業務を行うことが可能になるため、```プライベートと仕事の切り替えが難しくなり、社員のストレスが増加する恐れがあります```。
### 社員のプライバシー保護の問題が生じる
BYODを導入する場合、情報セキュリティリスク対策のために、会社が端末の管理ができるアプリケーションをインストールする場合があります。そのアプリケーションを通じて```端末利用状況をはじめとする社員のプライベート情報が会社に知られる危険性```があります。

## BYODが気づかないうちに進んでいる「シャドーIT」
仕事中にこっそりスマートフォンを使っている男の人
聞きなれない言葉かもしれませんが、「シャドーIT」とは```正式な許可や手続きを経ずに社員の勝手な判断で個人所有のスマートフォンなどを業務で使用する行為やその状態を指す言葉```です。
スマートフォンだけでなく、個人所有のPCなどを業務に使用することもシャドーITの一種。「個人のスマートフォンで会社のメールを確認した」、「ちょっと提案に間に合わないので休日に自宅のPCで作業をした」というのもシャドーITです。

先ほどBYODの課題として情報セキュリティを挙げましたが、このシャドーITはどのようにその端末が使われているかが会社側からはまったく認知できないので、情報セキュリティリスクは「最大」と言えます。
すでに```その端末にバックドアが仕込まれていたりウィルスに感染していたりする場合、情報が筒抜けになってしまう可能性がある```からです。またそこまでの事態に至っていなくても、ウィルス対策を含むセキュリティが万全である保証はまったくありません。

社員自身は「少しでも業務を効率的に進めるため」と考えて行っているのですが、しっかりとした```セキュリティ対策を講じた上で個人所有の端末を業務利用することがBYODの大前提```。シャドーITで発生するリスクの大きさを考えれば、とても許容することはできません。

# 出典
https://www.optimalbiz.jp/blog/byod-merits-and-demerits/#:~:text=%E3%81%8C%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82-,%E3%83%A1%E3%83%AA%E3%83%83%E3%83%88,%E8%80%83%E3%81%88%E3%82%8C%E3%81%B0%E3%80%81%E3%81%A8%E3%81%A6%E3%82%82%E8%A8%B1%E5%AE%B9%E3%81%99%E3%82%8B%E3%81%93%E3%81%A8%E3%81%AF%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%9B%E3%82%93%E3%80%82,-BYOD%E3%81%AE%E5%B0%8E%E5%85%A5
gomockを使ってio.Readerを引数に取るメソッドをモックする

# 概要
`gomock`を使用して`io.Reader`を引数に取るメソッドをモックするテストを書きました。
公式ライブラリでは`io.Reader`を使用するメソッドが多く存在し、利用する場面でもそれらをそのまま受け渡したいケースも時には存在すると思います。検索をすると自作の`matcher`を使用するなど複雑なやり方が載っていますが`strings.NewReader()`を使用して`io.Reader`型の引数を作成することで通常の引数の確認と同様にテストを作成できました。備忘録を兼ねて投稿します。

# 方法

下記のようなメソッドがあったとします。`mockgen`を使用することでモックを作成しています。

```go:sample_repository.go
package usecase

import "io"

// go:generate mockgen -source=$GOFILE -package=$GOPACKAGE -destination=mock_$GOFILE
type SampleRepository interface {
	Read(r io.Reader) error
}
```

上記のメソッドを以下のように使用しているとします。
```go:sample_interactor.go
package usecase

import "strings"

type sampleService struct {
	sampleRepository SampleRepository
}

func NewSampleService(sr SampleRepository) sampleService {
	return sampleService{sampleRepository: sr}
}

func (ss *sampleService) Exec(text string) {
	r := strings.NewReader(text)
	ss.sampleRepository.Read(r)
}
```

テストはこのように書けます。`strings.NewReader()`は`io.Reader`型を返却するので、テストを記載することが可能です。
```go:sample_interactor_test.go
package usecase

import (
	"strings"
	"testing"

	"github.com/golang/mock/gomock"
)

const testString = "hoge"

func TestExec(t *testing.T) {
	tests := []struct {
		name  string
		setup func(m *MockSampleRepository)
	}{
		{
			name: "Test the argument",
			setup: func(m *MockSampleRepository) {
                // 引数を指定してモックが使用されることを宣言
				m.EXPECT().Read(strings.NewReader(testString))
			},
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			// gomockのコントローラーを作成
			ctrl := gomock.NewController(t)

			//　SampleRepositoryのモックを作成
			mock := NewMockSampleRepository(ctrl)

			// モックをセットアップ
			tt.setup(mock)

			// SampleRepositoryを使用してSampleServiceを作成
			sampleService := NewSampleService(mock)

			// テスト対象の関数を実行
			sampleService.Exec(testString)
		})
	}
}

```

# まとめ
`io.Reader`を検証するのに少し身構えてしまっていましたが、通常のモックのテストと同様に書けることがわかりました。
SwiftのUIPanGestureRecognizerで移動制限をつける

## はじめに

今回はUIPanGestureRecognizerを使って、Viewをドラッグすると動くようにします。その際に、決めた範囲からViewが出ないように制限をつけてみました。

## やり方

まずは、UIPanGestureRecognizerを使ってViewがドラッグした位置に動くように実装します。
100×100の背景色赤の正方形をViewに追加し、UIPanGestureRecognizerを設定します。

※今回は分かりやすくするためにy軸方向にしか動かない形で実装します
```swift:qiita.swift
class ViewController: UIViewController {
    let squareView = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
    override func viewDidLoad() {
        super.viewDidLoad()
        squareView.backgroundColor = UIColor.red
        let panGesture = UIPanGestureRecognizer(
            target: self,
            action: #selector(didPan(_:))
        )
        squareView.addGestureRecognizer(panGesture)
        view.addSubview(squareView)
    }

```

次に上記コードで指定したdidPan関数を作って、ドラッグ動作に応じてsquareViewが移動するように記述します。

```swift:qiita.swift
  @objc
    func didPan(_ recognizer: UIPanGestureRecognizer) {
        let translation = recognizer.translation(in: self.view)
        squareView.frame.origin.y += translation.y
        recognizer.setTranslation(CGPoint.zero, in: self.view)
    }
```

これでsquareViewをドラッグで縦方向に動かせるようになりました。

![gesture.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2182598/2ba45495-d9d0-cf91-4824-ce85476969ea.gif)


次にこのsquareViewが画面の半分より下にいかないように範囲制限をしたいと思います。didPan関数を以下のように変更します。

```swift:qiita.swift
@objc
    func didPan(_ recognizer: UIPanGestureRecognizer) {
        let translation = recognizer.translation(in: self.view)
        //ルートビューの高さの半分(画面の高さの半分)の値を取得
        //※フレームの位置は左上が起点になるので、正方形の高さを引いておく
        let halfPostion = view.frame.height / 2 - squareView.frame.height
        //現在のsquareViewの位置を取得
        let currentPostion = squareView.frame.origin.y
        //ドラッグした移動量を足した時予測される位置を取得
        let predictedPosition = currentPostion + translation.y
        
        //予測される位置が、halfPostionの範囲内か、範囲外かで処理を分岐
        if predictedPosition <= halfPostion {
            //予測される位置が、halfPostionの範囲内なら移動量を足す
            squareView.frame.origin.y += translation.y
        } else {
            //予測される位置が、halfPostionの範囲外になるならhalfPostionの位置に指定
            squareView.frame.origin.y = halfPostion
        }
        recognizer.setTranslation(CGPoint.zero, in: self.view)
    }

```

![gesture2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2182598/215bf615-0369-855c-939d-3d5ea056b573.gif)

これで画面の中央から下にViewが移動できなくなりました！
Viewの移動に制限をつける方法は色々あると思いますが、
今回はこのような方法で実装してみました。

## 最後に
swift初学者のため、誤っている点やもっと良い方法があれば是非コメントで教えていただけたら嬉しいです。
見ていただいてありがとうございます！
楕円曲線暗号

# 楕円曲線暗号
公開鍵暗号方式の一種。

楕円曲線で定義された問題を解くときに計算量が多いことから、高い安全性を実現しています。

```RSA暗号と比べて暗号化を高速```で行えるほか、```短い鍵長で同レベルの安全性```を得ることができます。

# 出典
https://gihyo.jp/book/2022/978-4-297-13178-4

## 公開暗号方式とは
データの暗号化と復号で異なる鍵を使います。
暗号化で使う鍵は```公開鍵```
復号化で使う鍵は```秘密鍵```

### メリット
* 鍵の管理の容易さ
データを送ってくれる人全員に同じ鍵を渡すことになります。
鍵を使ってデータを暗号化してもらえば、安全にデータを受け取ることができます。

#### 気づき
2つに鍵を分けることで```送る先分の鍵を分けなくてよくなった```のか。
復号鍵を持っておくことで```中身を見られることがない```のか。

### RSA暗号
```大きな2つの素数の積の素因数分解```が難しいと言う性質に安全性の根拠があります。

# 出典
https://www.sbcr.jp/product/4797388800/
Miroでファイルをエクスポートする方法

## はじめに

オンラインホワイトボードツール「Miro」で作成した成果物を添付資料として提出したい場面は多くあるかと思います。
「Miro」は画像（JPG）、PDF、CSV 形式でエクスポートすることが可能ですが、今回は添付資料として提出する際に適している画像（JPG）、PDF 形式のエクスポート方法をご紹介します。

## エクスポート方法の概要

エクスポート方法は対象範囲とファイル形式によって、大きく下図の 3 つに分類できます。

| 対象             | 形式        | 手順                                         |
| ---------------- | ----------- | -------------------------------------------- |
| ボード全体       | 画像（JPG） | 対象範囲の選択                               |
| ボード全体       | PDF         | 1. フレーム作成<br>2. フレームの順番入れ替え |
| 個別オブジェクト | 共通        | 1. フレーム作成<br>2. ファイル形式の選択     |

次項目から個別に詳しく説明していきます。

## 対象：ボード全体、形式：画像（JPG）

1. 左上のメニューバーから「このボードをエクスポートする」をクリック
2. 「画像として保存」をクリック
   ![miroExportFile_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2962887/cb80561d-73f7-4982-fc74-aa9008d84e32.png)

3. エクスポートする範囲を選択
4. エクスポート画質を選択後に「エクスポート」をクリック
   ![miroExportFile_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2962887/4e83db57-97fa-7209-43d1-07422847a8f7.png)


## 対象：ボード全体、形式：PDF

1. 出力するページごとにフレームを作成
   このとき A4 のフレームを使用すると、エクスポートした際に意図せず図が縮小することが防げます。
   ![miroExportFile_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2962887/e2f4de5e-89f3-27d5-f903-9dddf9bfac01.png)

2. 左下の「サイドバーを開く」をクリック
   ![miroExportFile_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2962887/aea34487-2693-33d2-ea85-94996a1d8bd5.png)

3. フレームの順番を、PDF にエクスポートした際のページ順に入れ替える
   ![miroExportFile_05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2962887/edf72592-5566-5ba8-2603-3a9d90ca71e8.png)

4. 左上のメニューバーから「このボードをエクスポートする」をクリック
5. 「PDF として保存」をクリック
6. エクスポート画質を選択後に「エクスポート」をクリック

## 対象：個別オブジェクト、形式：共通

1. 対象のオブジェクトを選択し、「・・・」をクリック
2. 「フレームを作成」をクリック
   ![miroExportFile_06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2962887/54393ca7-d8f9-3add-7f2e-12dea4d741f5.png)

3. 作成されたフレームを選択、「・・・」をクリック →「画像としてエクスポート」をクリック
   ![miroExportFile_07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2962887/3eed2e58-19bb-9d1d-2252-5204c4a80046.png)

4. 画像（JPG）か PDF かを選択後に「エクスポート」をクリック
   ![miroExportFile_08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2962887/2be22408-2964-2d0a-2776-e38044568ddd.png)


## 注意点

フレームの名称はエクスポートしたファイルに表示されません。
![miroExportFile_09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2962887/feac4dfd-48d2-3ef1-83fb-158866e9432e.png)

そのため、もしフレームの名称も表示したい場合は、テキストに書き写す等の作業が必要になります。
![miroExportFile_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2962887/5d249432-4e37-446d-c5f7-0d5569c62961.png)


## 公式サイト

Miro[（公式サイト）](https://miro.com/ja/)

ご参考になれば幸いです。最後までお読み頂きありがとうございます。
Next.jsでフォント導入する時に困ったこと

## とあるプロジェクトを進めていたときに...
フォントがデフォルトだと味気なかったためgoogle fontsからフォントを導入しようとした。
検索結果などから`_document.ts`を作ればいいことがわかった。
それを元に作ってみたところ
### フォントが適用されない

## 原因はMaterialUI
プロジェクトにおいて文字列を使用する要素の多くにMaterialUIの`Typography`コンポーネントを使用していた
どうやらMaterialUIの`Typography`コンポーネントでフォントを利用するにはそれ用の設定が必要であった。
試しに`Typography`を使わずに文字列を試すとフォントが適用されていた。
結果として`_document.ts`に問題はなかった

## 解決策:createTheme
MaterialUIには`createTheme`というプロジェクト内で適用される色やスタイルをカスタムできる関数が用意されている
それを用いてthemeを定義すればよかった
```tsx
const theme = createTheme({
        typography: {
            fontFamily: '"Yusei Magic"',
        },
    });
```
スタイルの適用法などは公式ドキュメントを参考
https://mui.com/material-ui/customization/typography/

`_document.ts`の参考記事
https://qiita.com/dosukoi_man/items/4624de0275a53ba648d3
ターミナルで 「>」の入力モードになったときは


備忘録です。
以下の状態になったときは
 **`ctrl`と`C`を同時に押す** と脱出できます。

ターミナルでコマンド実行中、

```
$ GRANT ALL ON *.* TO 'user';
```

とするところを、最後のシングルクォーテーションの入力ミスで
```
$ GRANT ALL ON *.* TO 'dev-user¶1~
```
としてEnterキーを押してしまいました。すると
```
>
```
という入力モードになり
`exit`や`quit`を実行しても戻りませんでした↓。
```
> quit
> exit
> 
```
試しに`ctrl`と`C`を同時に押すと抜け出せました。
Pythonで別のディレクトリ内のファイルを参照する

このようなディレクトリ構成です
```
myapp/
├ config
│ ├ asgi.py
│ ├ settings.py
│ └ urls.py ← ここから
└ src
  └ views.py ← ここをimportしたらエラー発生した
```

config/urls.pyからsrc/views.pyをimportしたところ...
```python:urls.py
from ..src import views
```

エラー発生
```
attempted relative import beyond top-level package
```
(訳：トップレベル パッケージを超えた相対インポートを試みました)

下記を参考にして解決できました
・[pythonで上のディレクトリ内ファイルをimportする方法](https://qiita.com/ysuzuki19/items/55e2907a7c8f06889581)

# 原因
実行ディレクトリをルートディレクトリとするPythonの仕様があるようです。

# 解決策
```python:urls.py
import sys
sys.path.append('../')
from src import views
```
sysでプロジェクト内のルートディレクトリに移動し
そこからsrcディレクトリ内にあるviews.pyを参照するようにimportすることで解決できました。
【完全初心者】AWSのアカウント登録からEC2サーバーのインスタンス作成

# 概要
3/5 9:00~12:00までの勉強会で、
AWSのアカウント登録からEC2サーバーのインスタンス作成まで行いました。
内容を共有します。
#### 動作環境
macOS Monterey バージョン 12.6
MacBook Air (Retina,13-inch,2020)
プロフェッサ 8GB 3733 MHz LPDDR4X
グラフィックス　Intel Iris Plus Graphics 1536 MB

# そもそもAWSとは？
参考サイトです。
- [AWS初心者のための勉強会資料【入門編】〜結局AWSって何なの？〜](https://qiita.com/koizumittn/items/77923a8f71d47d895b34)
- [初学者のためのAWS入門(1)](https://qiita.com/mshinoda88/items/e7557227f7060b52d8ae)
- [【AWS初心者向け】AWS学習方法まとめ【15時間で達成できる】](https://qiita.com/toma_shohei/items/b7a001d26bd988d52021)
- [クラウドエンジニア(AWS)ロードマップ2021](https://qiita.com/KurokawaKouhei/items/4e9aa3b526f3f233bf85)
- [【2022年版】Amazon EC2 まとめ](https://qiita.com/c60evaporator/items/06aa523c470d52782c7b)
- [コードで学ぶAWS入門](https://tomomano.github.io/learn-aws-by-coding/#fig:vocareum_console)

# AWSのアカウント作成
まずはアカウント作成。初期設定も行なった。
- https://aws.amazon.com/jp/
- [AWSアカウントを取得したら速攻でやっておくべき初期設定まとめ](https://qiita.com/tmknom/items/303db2d1d928db720888#%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3%E3%82%B9%E3%83%86%E3%83%BC%E3%82%BF%E3%82%B9%E3%81%AE%E7%A2%BA%E8%AA%8D)
- [AWSアカウントを作成したら最初にやるべきこと -セキュリティ編-](https://qiita.com/yanyansk/items/3a989b70d2d3d49eff16)

## EC2サーバーのインスタンス作成
- ssh接続まで行なった。
[知識0から、AWSのEC2でウェブサーバーを構築するまで](https://qiita.com/shunsuke227ono/items/23dbf4f3bc663a2875f0)
[【EC2入門-2022年】無料枠で始めるインスタンスの作成手順](https://qiita.com/y_kato_eng/items/7f7878a40a23412e5fc2)
## キーペアの作成
- 作成したキーペアを.sshにコピー。権限エラー出た際はググってください。
```
ssh -i "キーペアファイル名" ec2-user@"パブリックIPアドレス"
```
[AWS EC2インスタンスへSSH接続する方法 ( Mac )](https://utubou-tech.com/mac-ec2-ssh/)

# 次回(3/19)までのタスク
- AWSとは？のサイトを確認し、AWSの概要について理解する
VSCode React拡張機能の snippets まとめ

# 説明
ES7+ React/Redux/React-Native snippets
![スクリーンショット 2023-03-05 14.24.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2841732/b3797782-c662-3c5e-3652-0228915530ce.png)

VScode で React を利用する際 snippets を用いて開発スピードを向上させることが目的


#### 補足情報
Name: ES7+ React/Redux/React-Native snippets
Id: dsznajder.es7-react-js-snippets
Description: Extensions for React, React-Native and Redux in JS/TS with ES7+ syntax. Customizable. Built-in integration with prettier.
Version: 4.4.3
Publisher: dsznajder
VS Marketplace Link: https://marketplace.visualstudio.com/items?itemName=dsznajder.es7-react-js-snippets


# snippets 一覧

### アロー関数

##### rafc
```jsx
import React from 'react'

export const aaaa = () => {
  return (
    <div>aaaa</div>
  )
}
```


##### rafce

```jsx
import React from 'react'

const aaaa = () => {
  return (
    <div>aaaa</div>
  )
}

export default aaaa
```


##### rafcp

```jsx
import React from 'react'
import PropTypes from 'prop-types'

const aaaa = props => {
  return (
    <div>aaaa</div>
  )
}

aaaa.propTypes = {}

export default aaaa
```

### function 関数

- rfc
- rfcp
- rfce

::: note info
基本アロー関数推奨なので実行結果は割愛
:::
Lua入門体験記 Part(1/n)

# はじめに

[Vim駅伝](https://vim-jp.org/ekiden/)への参加をきっかけとして、既存のNeovim設定(Vim scriptで書かれた`init.vim`)をLuaで書き換える義務が発生しました。

そもそも使ったことのない言語で、Vim界隈外では名前を聞いたことすらありませんでした。

せっかくの機会なので、入門してみたいと思います。

(本記事は単なるLuaの入門体験記であり、Neovimの記事ではありません。)

# 著者について

matoruruといいます。ちなみにmatoruruは猫😺です。

matoruruとは、私の[Twitter](https://twitter.com/_matoruru)や[GitHub](https://github.com/matoruru/)のアイコンにもなっている黄色いやつのことです。

[matoruruは全てフィボナッチ数列に従ったサイズの真円で構成されています](https://twitter.com/_matoruru/status/1544821381774585857)。

VimからNeovimへ移り住んできたVimmerです。最近は諸事情によりVS Codeを使っていますが、Vim拡張でしのいでいます。

---

・・・失礼しました、ここから本編です🐈

# 環境

Ubuntu 20.04.5 LTS

# インストール

```
> sudo apt install lua

Reading package lists... Done
Building dependency tree
Reading state information... Done
Package lua is a virtual package provided by:
  lua5.3:i386 5.3.3-1.1ubuntu2
  lua5.2:i386 5.2.4-1.1build3
  lua5.1:i386 5.1.5-8.1build4
  lua50 5.0.3-8build1
  lua5.3 5.3.3-1.1ubuntu2
  lua5.2 5.2.4-1.1build3
  lua5.1 5.1.5-8.1build4
You should explicitly select one to install.

E: Package 'lua' has no installation candidate
```

怒られてしまいました。バージョンを指定する必要があるそうです。

以下のようにしたらインストールできました。

```
sudo apt install lua5.3
```

インストールできているかどうか確認します。

```
> lua -v
Lua 5.3.3  Copyright (C) 1994-2016 Lua.org, PUC-Rio
```

大丈夫そうですね。

# ファイルの拡張子は`.lua`

大切です。

# 実行方法

```
> lua ファイル名
```

# コメント

```lua
-- コメントは「--」で書く

--[[
複数行
コメント
は
こんな感じ
]]--
```

# エントリーポイントはない

CやJavaのようにmain関数のような入り口はないらしい。

聞いていたとおりスクリプト言語ですね。上から順に実行される。

# 変数

宣言せずに使える。Bashとかと同じですね。

# データ型

宣言をしないので、変数自体に型はない。

でも値にはデータ型がある。JavaScriptとかと同じ動的型言語です。

```lua
x = "Hello, world!"
print(x)
-- Hello, world!
```

念願のハローワールドをしました。標準出力は`print`関数です。

数字や文字列、bool型も使えるみたい。

```lua
x = 1
print(x)
-- 1

x = 10
print(x)
-- 10

x = true
print(x)
-- true
```

関数も変数に入れられるらしい。（関数型プログラミングもいけそうだ・・・）

少し試してみる。

```lua:変数myprintにprint関数を代入してみる
myprint = print
myprint("worked!")
-- worked!
```

お！動いた😺

関数の引数としても関数を渡せるらしいので、関数型プログラミングができちゃいますね。

とりあえず入門記事の第1章はここまでにします。

# 最後に

記事を読んでくださってありがとうございます！

Twitterフォローしていただけると記事を書き続けるモチベーションになります😺
https://twitter.com/_matoruru

# 参考

http://starcode.web.fc2.com/
LightGBMError: The number of features in data (75) is not the same as it was in training data (74).

LightGBMError: The number of features in data (75) is not the same as it was in training data (74).
You can set ``predict_disable_shape_check=true`` to discard this error, but please be aware what you are doing.

モデルに渡すデータの特徴量数が異なる場合に表示されるエラー
`predict_disable_shape_check=True`を引数に渡すと、
エラー回避できるが誤った予測を得る可能性がある

```py
pred = model.predict(df, predict_disable_shape_check=True)
```

そもそもカラム数が異なる場合、必要な処理が抜けているのかも

```py
df_origin = df.drop('y', axis=1)
pred = model.predict(df_origin)
```

## Reference
- [predict_disable_shape_check](https://lightgbm.readthedocs.io/en/latest/Parameters.html#predict_disable_shape_check)
【データ基盤構築/dbt】FROM句でソースデータを指定する場合はsource関数を使うと便利

# 今回の課題
dbtについて勉強をしていて、`source`関数というものを見つけ、
詳細を理解してみることにした。

# sources機能とは
dbtの「DWHにロードされているローデータを」`sources`として定義することができる機能。
基本的にFROM句にDWH内のローデータを記述する場合は、source関数を使用した方が良さそう。
#### **※source機能を使用すると下記のような利点がある**
* リネージにソースデータの情報も追加される。
`source`関数でモデルからソースを参照すると、リネージやドキュメントにも、どれがソースデータなのか反映されるようになる。
* メンテナンス性が上がる。
モデルが`source`を使わずにFROM句にテーブル名が書いてしまっていると、開発中にデータの問題が発生した場合に、どこから来たデータか分からず、デバッグの難易度が上ってしまう。

## sourcesの定義方法
modelディレクトリ下のYAMLファイルを下記のように定義する。
これによって、dbt内でsourcesを定義することができる。
```yaml
sources:
  - name: [データセット名]
    databases: [BigQueryで言うところのプロジェクト名, Snowflakeで言うところのDatabase名]
    tables:
      - name: [テーブル名1]
      - name: [テーブル名2]
```
## 定義したsourcesの使い方
modelディレクトリ下の`.sql`ファイルに下記のように記述する。
```sql
select * from {{ source('[データセット名]', '[テーブル名]') }}
```
上記の`.sql`ファイルを`dbt run`などで実行すると、下記のようにコンパイルされる。
```sql
select * from `[BigQueryのプロジェクト名]`.`[データセット名]`.`[テーブル名]`
```
以上のようなかたちで、source機能を使用することができた。

ちなみに、modelと同様にsourcesでもテストを実施したり、ドキュメントの自動生成を実施することができるようだった。

# まとめ
dbtでFROM句でソースデータを指定する場合は、
source関数を使えばdbtのデータリネージにソースデータが反映されるのでデータのデバッグなどの時に便利。


#### 参考記事

https://zenn.dev/foursue/books/31456a86de5bb4/viewer/ed0bb9

https://dev.classmethod.jp/articles/dbt-sources/
One Tech で次元モデリングについて解説してみた！

### はじめに
Softbankのテックブログで記事を書いたので紹介します！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1044781/dcf06f64-8332-a1f1-5b75-51e478b96010.png)


【[One Tech](https://www.softbank.jp/biz/blog/cloud-technology/category/?tags=blog-cloud-technology__keyword__one-tech)】とは、さまざまな部署・職種のエンジニアが世の中にあるさまざまなIT関連のキーワードや流行の１つに着目し、独自あるいはその職種ならではの視点からIT関連の技術用語やトレンドについて執筆していく連載企画です。


なぜ**次元モデリング**をテーマにしたかというと、以前あるデータサイエンスミートアップに参加した際に、登壇者の方が「**日本の企業は次元モデリングがまだまだ実装できていないし、日本語の記事も少ない、、**」という事を話していたので、「じゃあ私が書いてみるか！」と思い立ちこのテーマで執筆して見ることにしました

### この記事について
- データに基づいて意思決定を行うビジネス層やアナリティストが効率的かつ的確にデータ分析をする為の次元モデリング（Dimensional Modeling）というデータウェアハウス上のデータモデリング手法を紹介します
- RDB（リレーショナルデータベース）の基礎知識がある方、ビジネスデータの分析に興味のある方、SQLの基礎知識がある方向けに書いています
- この記事を読むことで、スタースキーマの基礎知識、スタースキーマ構造のデータベースの処理例を得ることが出来ます。

ぜひ読んでみてください！！

https://www.softbank.jp/biz/blog/cloud-technology/articles/202302/dimensional-modeling/
Googleデジタルマーケティング＆Eコマース：カスタマージャーニーとタッチポイント

# はじめに

”Googleデジタルマーケティング＆Eコマース プロフェッショナル認定証"　の受講が完了しました(2022/3/3)。私がこのコースから得られた素晴らしい体験を、テーマごとに分割して、わかりやすくご紹介しています。興味を持たれた方は、是非下記を受講してみてください。

https://jp.coursera.org/professional-certificates/google-digital-marketing-ecommerce

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/77505f22-0d8f-b3af-4f9c-ed148bcefd65.png" width="800">

# ビジネスの秘訣

企業のマーケティング活動は、顧客を獲得し、利益を上げ、オンラインプレゼンスを拡大するための方法であり、すべて自分たちのためにあると考えがちです。しかし、本当に効果的なマーケティング戦略は、

***<font color="MediumVioletRed">『顧客のニーズとペインポイントを知る』</font>***

ことから始まります。

ペインポイントとは、顧客や潜在顧客が解決したいと思っている具体的な問題のことです。『"どうすればもっと売れるか"ではなく

***<font color="MediumVioletRed">『どうすれば顧客のペインポイントに対処し、目標を達成できるか』</font>***

を知ることが、最も成功するビジネスの秘訣なのです。

# カスタマージャーニーを理解する

カスタマージャーニーは、

***<font color="MediumVioletRed">『顧客がその商品について知り、購入するまでの道のり』</font>***

のことです。

例えば、新しい天気予報のアプリが欲しいと思っているとします。

- 今使っているアプリは信頼性が低く、傘を持たずに雨に降られることが多いので、最高の天気予報アプリをオンラインで検索し、いくつかの選択肢を見つけたとします。
- その中で、名前に見覚えがあるものがありました。友人が最近教えてくれたのか、それともオンライン広告だったのか。いくつかの候補に絞り、レビューを読み始めます。
- 2つはあなたが望むすべての機能を持っていますが、あなたはおなじみの名前のものを選びます。いくつかのベスト・オブ・リストでトップになっており、トライアルサブスクリプションがあります。
- アプリをダウンロードするも、うまく動作しません。
- レビューに戻り、これは既知の問題であることを知りました。あなたは、ライブチャットを通じてサポートに連絡します。彼らはあなたがすぐに問題を解決するのを助け、あなたは会社について良い気分になりました。
- あなたはトライアルを開始し、1ヵ月後、あなたは雨が降ったときに常に傘を持っていました。
- トライアルがもうすぐ終了することを知らせるEメールが届き、アプリにとても満足したあなたは、定期購入しました。これで、あなたはロイヤルカスタマーです。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/69f58ad4-45cb-ed14-b3bc-c85cb4e1ea81.png" width="800">

### タッチポイント

この購入の旅におけるブランドとのやりとりの一つひとつをタッチポイントと呼びます。検索からカスタマーレビュー、オンライン広告、試用版、ライブチャット、フォローアップの電子メールまで、すべてのタッチポイントは、ブランドとその製品に対するあなたの印象を良くも悪くもする可能性を持っていました。

どのような場面でも悪い体験があれば離脱される可能性があるため、途中で必要な情報や回答が得られるようにすることが企業にとって最善の利益となるのです。十分な顧客調査があれば、マーケティング担当者はこれらのタッチポイントを利用してカスタマージャーニーマップを作成することができます。

### カスタマージャーニーマップ

カスタマージャーニーマップとは、一般的な顧客が購入までの過程で遭遇するタッチポイントを視覚化したものです。異なるタイプの顧客のパターンと行動に基づいて、複数のジャーニーマップを作成することも可能です。もちろん、一人ひとりがどのような経路をたどるかを正確に把握することは不可能であり、ジャーニーマップは未来を予測するためのものではありません。


カスタマージャーニーマップは、お客様がどのように、そしてなぜあなたのビジネスと関わっているのかを理解するためのものです。

お客様が
- どのように貴社を見つけ、
- どのように貴社について知り、
- どのような問題を解決したいのか

が分かれば、お客様の体験をより良いものにすることができます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/0ce31c7c-305c-29b8-567e-78ddefc2a17b.png" width="800">

カスタマージャーニーを理解することで、より良い、よりユーザーフレンドリーな体験を生み出すことができるのです。つまり、より良い顧客体験は、最終的にあなたのビジネスの成功を意味します。

# タッチポイントを洞察する

タッチポイントを特定する際、ソーシャルメディアやディスプレイ広告を挙げたくなるかもしれません。これらのチャネルはタッチポイントを発生させる媒体かもしれませんが、実際のタッチポイントはもっと多くの情報を提供します。タッチポイントを特定する際には、そのインタラクションがどのように顧客のニーズを満たすかを考えてください。

- 例えば、ソーシャルメディアをタッチポイントに分類するのではなく、Twitterでフラッシュセールの告知をしたときの顧客の反応をタッチポイントに分類します。リンクをクリックしたとき、彼らは割引価格で購入できるものを知りたがっているのです。

この例から、ソーシャルメディア上のすべてのインタラクションをソーシャルメディアという単一のタッチポイントで単純に括ってしまうと、どれだけ文脈的な情報が失われてしまうかに気づきます。

タッチポイントには
- 文脈
- 顧客のニーズ

が反映されています。

この例では、

***<font color="MediumBlue"">『文脈は好奇心であり、ニーズは節約でした』</font>***
[Python] 備忘録　元のファイルの日付を出力するファイル名に入れる・・

Pythonで出力するときに、元のファイルの日付・時間を使いたい場合がありますが
けっこう複雑ですぐに思い出せないので、備忘録として残すようにしました。

```Python
from datetime import date
import datetime
import os

###  filename='' 
filedate = datetime.datetime.fromtimestamp(os.path.getmtime(filename))

filedate.strftime("%Y-%m-%d %H:%M:%S")  # '2023-02-25 20:05:37'
filedate.strftime("%Y%m%d-%H%M")  # '20230225-2005'
```

2023/6/10 追記
ついでに、本日の日付をフォルダやファイル名にするのは

```Python
from datetime import date
import datetime

today=datetime.datetime.now()

today.strftime("%Y%m%d-%H%M")  # '20230610-1435'

```
Django(Python)でマイグレーションを行う手順

久しぶりにDjangoを触ってみてマイグレーションの実行に手間がかかったので
私用メモ的にまとめてみました。
DBはSQLiteをしようしています。

各バージョンは下記の通りです
```
Python:3.9.6
Django:4.1.7
SQLite:3.37.0
```

ディレクトリ構成は下記を例に進めていきます
```
myapp/
├ config
│ ├ asgi.py
│ ├ settings.py
│ └ urls.py
├ src
│ └ models.py
manage.py
db.sqlite3
```

# モデル作成
ルートディレクトリでsrcディレクトリを作成し、その中にmodels.pyを作成します
コードはDjango公式チュートリアルを引用いただきます

```python:models.py
class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')


class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)
```

# マイグレーション用スクリプト作成
前の手順で作成したmodels.pyを使ってマイグレーション用のスクリプトを作成します
ターミナルでコマンドを実行します

```shell
python manage.py makemigrations src
```

コマンドを実行するとsrc配下にmigrationsディレクトリが作成され
その中に__init__.pyと0001_initial.pyが作成されます。
```
myapp/
├ config
│ ├ （省略）
├ src
│ ├ models.py
│ └ migrations
│   ├ __init__.py
│   └ 0001_initial.py
manage.py
db.sqlite3
```

SQLのコマンドを確認してみます
```shell
$　python manage.py sqlmigrate src 0001
BEGIN;
--
-- Create model Question
--
CREATE TABLE "src_question" ...
...
CREATE INDEX ...
COMMIT;
```
テーブル作成とインデックス作成のコマンドが確認できます。

models.pyを変更した時は
```shell
python manage.py makemigrations src
```
SQLを確認します
```shell
python manage.py sqlmigrate src 0002
```

# データベースに反映
```shell
python manage.py migrate
```

db.sqlite3を確認してみます。
models.pyで定義したテーブルが作成されていると思います。
・src_question
・src_choice

# 参考資料
https://python.keicode.com/django/models-basics.php
Cloud Functions バックグラウンド関数でFirestoreのサブコレクションが更新されたことを検知し、同階層にログを作成する

Firestoreでドキュメントの作成時にや削除時にトリガーして使用することを想定しています。
ログデータ作成はアプリ側ではなくバックグラウンドで安全に処理したいですね。

```javascript
exports.myFunction = functions.firestore
  .document('collection/{docId}/subcollection/{subId}')
  .onCreate((snap, context) => {
    const data = snap.data();

    // ログ用のデータを作成する
    const logData = {
      subcollectionId: context.params.subId,
      createdAt: admin.firestore.FieldValue.serverTimestamp()
    };

    // ログ用のドキュメントを作成する
    const docRef = admin.firestore().collection('collection').doc(context.params.docId).collection('logs').doc();
    
    // ログ用のドキュメントにデータを書き込む
    return docRef.set(logData)
      .then(() => {
        console.log('Log document created');
        return null;
      })
      .catch((error) => {
        console.error('Error creating log document:', error);
        return null;
      });
  });
```

ドキュメントIDの取得方法は以下です。
```javascript
exports.myFunction = functions.firestore
  .document('collection/{docId}/subcollection/{subId}')
  .onCreate((snap, context) => {
    // これ
    const docId = context.params.docId;
    const subId = context.params.subId;
    console.log(`New subcollection created with ID: ${subId} in document with ID: ${docId}`);
  });
```
Velocloudを用いたネットワーク設計の考え方について

## はじめに ##
VeloCloudのネットワーク構成について記入しています。
Cloud-Gatewayを用いた、Public Cloudとの接続とCloud-Gatewayを利用しない、Public Cloudの接続などをまとめています。
こちらの資料は、少しずつアップデートしていきます。（自身のメモなども兼ねています）

:::note info
Velocloudは非常に多くの機能を持っていますが、ここではシンプルに1つプロファイルでSD-WANを構成する場合としています。
:::

### 構成図を見ながら整理する。 ###
イメージがないとわかりにくいのでサンプルのネットワークで説明します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/775358/f0b3bee8-bb5c-a852-ef86-75ff327350c2.png)
こちらが、サンプルのネットワーク図です。ブランチには、VelocloudのEdgeが置いてあります。
Profileで全体でCloud-VPNを利用しているため、拠点間は自動的にフルメッシュになります。
Profileとは、Edgeに設定する共通のポリシーです。
共通の設定はProfileで行い、個別の設定はEdge単体に実施するという流れになります。
なお、Profile内だけでメッシュを切るなどの設定も可能です。（ここでは割愛）
黄緑色の線は、VeloCloudのDMPOを表したものです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/775358/002d6d5e-815b-a966-8d57-77edd3b071d5.png)
VelocloudのProfileはすべてこのProfileを適用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/775358/35effdb1-fe1d-051f-4caa-f7997340b170.png)

AWSとVPNを接続する場合は、各拠点からNVS（Non Velocloud Site）で接続を行います。
拠点が多いほどVPNを追加する必要がありますし。AWSのVPN-GWにも接続先上限があるので限界があります。
NVSはIPSecで接続の行います。現時点ではStatic Routingとなります。赤い線はIPSecの接続イメージです。
図上AWSと書いていますが、VPN-GWとEdgeとでIPSecで接続を行っています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/775358/10a7cb60-2860-a639-99f5-cb4ea8f9f2ec.png)

VeloCloudの画面からはこのような設定です。
プロファイル上はこちらの設定を行い、各Edge側でどのWANを用いて、Secretは何を使うかなど個別の設定を行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/775358/95063792-c786-5d90-8df4-57c132f76080.png)

サービスの中身はこちらです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/775358/72f878cf-e632-8246-1865-0ddebb7b71a2.png)

:::note warn
AWSの場合、接続先毎にEndpointが変更となるため、各Edge毎にNVSを作成する必要があります。
Azureの場合、接続先毎にEndpointが共通のため、一つの設定で済ませることが可能です。
各プロバイダ毎に接続要件がことなりますので、組み合わせて利用してください。
:::

Cloud Gatewayで構成する場合はこのような感じになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/775358/c79a51eb-4f8c-c804-6fc9-bdbd5a32c197.png)

Cloud Gatewayは、Internet上に稼働するクラウドと接続するためのGatewayです。
EdgeとPublic Cloudの接続を中継するため、各ブランチ側でVPN接続が不要です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/775358/64927268-66cf-5a10-4531-cb1387fca031.png)
AWS via VCGと書いてある設定が、Cloud Gateway経由での接続となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/775358/c3f9853b-6ec2-e700-51af-e39180d8bca9.png)
こちらは、1つのVCGから2つの接続先に接続する設定です。
画面下部の冗長VeloCloud クラウドVPNのチェックをいれると、もう一つVCGがアサインされます。
接続先のIPアドレスで、VCGの場所が変わるので設定を作成する場合に注意が必要です。
この画面上では、オーストラリアのVCGが選定されています。


### 今回はここまで
次回は、実際に接続している画面を用いての説明などを書いて行きたいと思います。
ご覧頂きありがとうございました。
Splunk: エイリアスの使い方


###### 実施環境： Splunk Free 8.2.2

 Splunk での検索において、あるフィールドを別のフィールド名で扱いたい場合があります。
 rename コマンド等を使用してもフィールド名の変更はできますが、実はコマンドを使用しなくとも別のフィールド名を適用できる機能があります。
それが今回紹介する、エイリアスという機能です。

### 1. 概要

例えば、ログ A においてホスト名を表すフィールド名が「 host 」、ログ B において同じくホスト名を表すフィールド名が「 server 」であるとします。

![WS000542.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/482499c6-e5fa-b7d2-7dbf-8bc20176581c.jpeg "イメージ1")

この2つのログを組み合わせる場合、「 server 」というフィールド名が「 host 」というフィールド名になってくれればホスト名の比較がしやすくなります。

![WS000543.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/78f497a0-fd3c-499b-a249-a05afdd308d4.jpeg "イメージ2")

 rename コマンドや eval コマンドでもこのような操作はできますが、これをコマンドなしで実現するのがエイリアスという機能です。

### 2. 設定方法

「設定」⇒「フィールド」を選択します。

![WS000536.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/e9d7e7e0-cae2-2d06-30b0-c60c68a65a88.jpeg "設定")

「フィールドのエイリアス」を選択します。

![WS000537.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/6716f422-441f-2412-5d34-454660d707fa.jpeg "フィールド")

エイリアスの一覧画面が開くので、右上の「新しいフィールドのエイリアス」を選択します。

![WS000538.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/3c8d9867-b1e2-967f-5c83-b0801d3c42f0.jpeg "エイリアス一覧1")

エイリアスの設定を入力します。

![WS000539.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/ca334fe5-b9fe-d078-dd93-e9b7764fd211.jpeg "エイリアス作成")

ここでは以下の設定を入力します。

|項目名|値|
|:-|:-|
|宛先 App | search |
|名前| `test_alias` |
|適用先|ソースタイプ|
|名前付き| `splunkd` |
|フィールドのエイリアス| `log_level` = `level_alias` |
|フィールド値を上書き|チェックしない|

「フィールドのエイリアス」では、=の左に元のフィールド名、右に新しいフィールド名を入力します。
新しいフィールド名が既に存在する場合、「フィールド値を上書き」にチェックが入っていればエイリアス後のフィールド名で上書き、チェックが入っていなければ既に存在するフィールド名がそのまま維持されます。

「適用先」には今回はソースタイプを使用していますが、ソースやホストに設定を紐づけることも可能です。

これでエイリアスが作成できました。

![WS000540.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/6461958b-9288-fe86-a381-90738216fc72.jpeg "エイリアス一覧2")

### 3. 使用方法

試しに、以下の SPL でエイリアスを使用してみましょう。

```Splunk:Splunk
index="_internal"
| fillnull value="(NULL)" level_alias
| stats count BY log_level, level_alias, sourcetype
```

![WS000541.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/dc1cca71-cfab-e2ea-ca1d-bff1f6bc8ecb.jpeg "エイリアス使用")

指定したソースタイプにおいて新しいフィールド名`level_alias`が存在していることがわかります。
Files.move

test.txtをtest dirに移動するプログラム
移動先は...testではなく...test\test.txtを指定する

```java
public class SampleProject {
    public static void main(String[] args) throws Exception{
        Path p1 = Paths.get("c:\\dirtest");
        File f = p1.toFile();
        method2(f);
        Path p2 = Paths.get("c:\\dirtest\\test.txt");
        Path p3 = Paths.get("c:\\dirtest\\test\\test.txt");
        Files.move(p2,p3);
        method2(f);
    }
    static void method2(File pf) {
        System.out.println("----------------");
        method(pf,"",null);
    }
    static void method(File pf, String indent, FileFilter ff) {
        class SampleClass {
            File[]  method() {
                if(ff == null) return pf.listFiles();
                else  return pf.listFiles(ff);
            }
        }
        File[] fs = new SampleClass().method();
        for(File f:fs) {
            System.out.print(indent + f.getName());
            if(f.isDirectory())  System.out.println("   is directory.");
            else  System.out.println("    is file");
            if(f.isDirectory())  method(f, indent + " ",ff);
        }
    }
}
```
```
----------------
sample.ser    is file
showa.txt    is file
test   is directory.
test.java    is file
test.txt    is file
testfile.txt    is file
testmakefile.txt    is file
testwritefile.txt    is file
----------------
sample.ser    is file
showa.txt    is file
test   is directory.
 test.txt    is file
test.java    is file
testfile.txt    is file
testmakefile.txt    is file
testwritefile.txt    is file
```