OmniAICreator/Qiita-1.07M huggingface dataset:
viteのdefineConfigにプラグイン（GoogleTagManagerを差し込むやつ）を追加してみる

## GoogleTagManager を入れるためだけに、サードライブラリをインストールするのめんどい
てなわけで、Viteを使ってサイトを構築してるときにアクセス数とかの管理のために、GoogleTagManagerをhtmlに記述するってよくあるよね（多分

ベースのindex.htmlに直接書いてもいいんだけど、出来れば本番環境にのみタグを入れたいとかもあるはず。
そんなときにタグを入れるだけのライブラリとかも合ったりしてソレを入れればいいじゃんって感じですが、どうせなら勉強がてらに作ってみればいいじゃんということで作ってみた。

## やりたいこと
- 本番環境にGoogleTagManagerをいれる
- 開発・検証環境はrobotsのnoindexをいれる

```html:index.html
<!doctype html>
<html lang="ja">

<head>
  <!-- Google Tag Manager ここをリプレイスする予定-->
  <gtm></gtm>
  <!-- End Google Tag Manager -->
  <meta charset="UTF-8">
  <meta http-equiv="Pragma" content="no-cache">
  <meta http-equiv="Cache-Control" content="no-cache">
  <link rel="icon" href="/favicon.ico" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>何かサンプルサイト</title>
  <meta property="og:locale" content="ja_JP">
  <meta property="og:site_name" content="何かサンプルサイト">
</head>

<body>
  <div id="app"></div>
  <script type="module" src="./main.js"></script>
</body>

</html>
```
HTMLには変換用のタグを用意します

```javascript:vite.config.js
/** GoogleTagManager差し込み用プラグイン */
const gtmPlugin = () => {
  const isProduction = process.env.NODE_ENV === 'production';
  return {
    name: 'html-transform',
    transformIndexHtml(html) {
      return html.replace(
        /<gtm><\/gtm>/,
        (isProduction
          ? `<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','ここに何かIDを入れる');</script>`
          : `<meta name="robots" content="noindex">`)
      )
    },
  }
} 

export default defineConfig(() => ({
    // 省略
    plugins: [vue(), gtmPlugin()],
    // 省略
}));
```

transformIndexHtml　で　index.htmlが文字列として取得されるので、
ソレをprocess.env.NODE_ENVの値によって置換してるだけというシンプルなもの。

## まとめ
[公式](https://ja.vitejs.dev/guide/api-plugin.html)だと、規約だとかなんだとかあるみたいですが、即席のプラグインだし試しにやってみただけなので、わかるようになってから守るようにしようかと。
※命名とかよりもその機能が使えるかどうかが自分としては重要

robots.txtとかsitemap.xmlとか生成するとかも今後作れたらいいね（ネタを作って締める
画像の特徴点抽出

別の最近某探索の記事を書いていたけれど、書き終わらないので一部抜粋（2年前調べ）。

## 特徴点抽出（数量とバイナリ）
画像の[特徴点抽出](https://docs.opencv.org/master/db/d27/tutorial_py_table_of_contents_feature2d.html)には様々な種類(SIFT, SURF, FAST, CenSurE, ORB, KAZE, AKAZE...)がある。特徴のある点の座標を抽出するだけの特徴点抽出手法もあれば、多次元の特徴ベクトルを持つ特徴点抽出手法もある。

| 特徴量表現 | 主な特徴量 |
|:-:|:-:|
| バイナリ・多次元 | ORB, BRISK,  BRIEF, FREAK, AKAZE |
| 浮動小数・多次元 | HOG, SIFT, SURF, GLOH, CenSurE, KAZE |
| 浮動小数・１次元（位置決定） | Harris, Shi-Tomasi |

特徴量を浮動小数で表現すると情報量が非常に大きくなるため、大規模な探索用途では利用しにくいという欠点がある。例えばN次元の特徴量をfloat(4byte=32bit)で持った場合は32*N[bit]必要だが、バイナリであればN[bit]で一つの特徴を表現することができる。各次元の値の比較は、各ビットを比較して幾つのビットが異なるかを知ることで特徴量の違い（距離）を知ることができる。これをハミング距離と呼ぶ。利用する特徴量がバイナリかそうでないかで距離計算方法が異なるため気をつける必要がある。

[OpenCVで提供されているBoW](http://opencv.jp/opencv-2.2/cpp/features2d_object_categorization.html)がある(cv2. BOWTrainer, cv2.BOWKMeansTrainer, cv2.BOWImgDescriptorExtractor)が、いずれも浮動小数で表現する特徴量として取り扱う必要がある。近傍探索でcv2.BFMatcherを利用する際に、バイナリで表現する特徴量を利用する場合は引数normTypeとしてcv2.NORM_HAMMINGを指定する必要がある。
GPTScriptで遊ぶ

毎度、ググっても出てこない小ネタを取り扱っております。
本記事は個人的な見解であり、筆者の所属するいかなる団体にも関係ございません。

# 0. はじめに

- Darrenさんがまた変なものを作った
- Darrenさんは、CloudStack、Rancher、K3S、Kine等など「その発想はなかったわ」というプロダクトを次々に生み出すプログラミングハッカー。
- 現在は、Acorn Labs社に所属

彼が最近ご執心なのがChatGPTです。

catgptというchatgptにメッセージのプロンプトをパイプして操作をする変なものを作っていましたが、それを使っていてもっと便利なものが作れると思ったようで、gptとscriptを融合させて動かすgptscriptを発表しました。

これがなかなかぶっ飛んだ代物だったので、遊んでみました。

[gptscript\-ai/gptscript: Natural Language Programming](https://github.com/gptscript-ai/gptscript)

https://github.com/gptscript-ai/gptscript

# 1. インストール

gptscriptは、Linuxでも、macOSでも、Windowsでも動きます。
ここでは、Windows のWSL2で動かします。

下記のcurlスクリプトでインストールします。念のため中身は確認しておきましょう。
```
$ curl https://get.gptscript.ai/install.sh | sh
```

`gptscript -v`でバージョンが返ってくればインストールされています。

```
$ gptscript -v
gptscript version v0.1.4-701b9c8e-dirty
```

/usr/local/binにインストールされるみたいですね。
```
$ which gptscript
/usr/local/bin/gptscript
```

# 2. 動かしてみる

動かすためには~~.gptなるファイルが必要なので、簡単に以下のファイルを作ります。

```:example.gpt
# example.gpt

Tools: sys.download, sys.exec, sys.remove

Download https://www.sqlitetutorial.net/wp-content/uploads/2018/03/chinook.zip to a
random file. Then expand the archive to a temporary location as there is a sqlite
database in it.

First inspect the schema of the database to understand the table structure.

Form and run a SQL query to find the artist with the most number of albums and output
the result of that.

When done remove the database file and the downloaded content.
```

何これ？全然プログラムじゃないですよね。。
でも動くんです。衝撃です。

さらにこれを動かすためにOpenAIのAPIを使いますので、
https://platform.openai.com
へログインして、APIキーを発行してください。
APIキーが「sk-hogehogehoge」の場合、以下のように環境変数にAPIキーを入れてください。
.bashrcとかに書いておくとよいかもしれません。

```
export OPENAI_API_KEY="sk-hogehogehoge"
```

では、動かしてみます。

以下のようなログが出力されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/95093e75-8269-3682-eea5-56f4c8f1f074.png)

一番重要なのは最後のOUTPUT部分

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/7af018a6-0285-3ebe-dac9-d89188858f92.png)

これは、SQLiteチュートリアルのchinook.zipに入っているアーティストのアルバムのデータベースから最もリリースされたアルバムの多いアーティストとして、アイアンメイデンが21アルバムを出しているという結果を出力しています。

# 3. なぜこんな事ができるか？

これは、ChatGPTのOpenAIのAPIを使って、example.gptの中身をスクリプトとして実行できる形式に変換し、gptscriptを実行したマシン上で実行しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/29504239-b1ae-b57d-e031-b70bce264f90.png)

この図の3番と4番が重要で一般的なプログラミング言語ではこの部分はありませんが、gptscriptではOpenAIのGPT-4を挟むことにより、自然言語からプログラミング言語への変換を行っています。

# 4. 日本語でもやってみる

英語でできるのなら、日本語でもできるはず。

上記のexample.gptと同じ事を日本語でも試してみました。

```:example-ja.gpt
tools: sys.download, sys.exec, sys.remove

https://www.sqlitetutorial.net/wp-content/uploads/2018/03/chinook.zip のファイルを
ランダムなファイル名でダウンロードしてください。 次に、アーカイブを一時的な場所に展開する。

まず、データベースのスキーマを調べ、テーブル構造を理解してください。

フォームを作成し、SQLクエリを実行して、アルバム数の多いアーティストを見つけ、
その結果を出力してください。

完了したら、データベースファイルとダウンロードしたコンテンツを削除してください。
```

# 5. 実行結果

実行結果は以下のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/2020bf36-f419-28ef-bf0d-81a541fff84b.png)
何の問題もなく実行できました。

# 6. まとめ

gptscriptは自然言語を使ってプログラミングできる画期的なインタプリターです。
[Go,CircleCI]カバレッジ計測結果ファイルのデータサイズ抑制

# 問題
CircleCI で codecov の Orb([codecov/codecov](https://circleci.com/developer/ja/orbs/orb/codecov/codecov))を使い、go testでデフォルトのフォーマットで出力したカバレッジ計測結果のファイルをアップロードする際に、以下のようなエラーが発生していた。

**CircleCIのログ**
```
[yyyy-mm-ddTHH:MM:SS.SSSZ] ['info'] Could not read coverage file (<カバレッジ計測結果のファイルパス>): Error: There was an error reading the coverage file: Error: Cannot create a string longer than 0x1fffffe8 characters
```

調査した結果、codecov の Orb は nodejs をベースにしているのだが、入力ファイル(=カバレッジ計測結果のファイル)を読み込んだ段階で [nodejs の文字列サイズ上限に引っかかってしまっている](https://stackoverflow.com/questions/75681460/npm-publish-throws-error-err-string-too-long-cannot-create-a-string-longer-than)らしいことがわかった。
となると、Orbの設定を調整してもどうにもならなそうなので、Orb の入力ファイルに含まれる文字数自体を減らす方向で解決策を考えることにした。

# 解決策
カバレッジファイル内を観察すると、以下のように(あくまでイメージですが)同じブロックが繰り返し出現していた。

```
mode: atomic
xxx/xxx.go:25.13,26.27 1 1
xxx/xxx.go:26.27,28.3 1 1
yyy/yyy.go:9.45,12.17 3 9
yyy/yyy.go:12.17,14.3 1 9
xxx/xxx.go:25.13,26.27 1 2
xxx/xxx.go:26.27,28.3 1 0
yyy/yyy.go:9.45,12.17 3 3
yyy/yyy.go:12.17,14.3 1 0
```

これらの行を統合(重複削除 + 末尾の通過回数は加算)できれば、かなりファイルサイズを圧縮できそう。

色々調べつつ試していたところ、

[gcov2lcov](https://github.com/jandelgado/gcov2lcov)

というコマンドを使ってフォーマットをlcovへ変換すると、副次的に望む結果を得られることが確認できたため、これをCircleCIに組み込むことにした。


```
  jobs:
    ...
      - run:
          name: convert format of coverage profile file for data compression
          command: |
            go install github.com/jandelgado/gcov2lcov@latest
            gcov2lcov -infile=<デフォルトフォーマットのカバレッジ計測結果ファイルパス> -outfile=<lcovフォーマットのカバレッジ計測結果ファイルパス>
```



# 参考
https://songmu.jp/riji/entry/2019-11-14-go-github-actions.html

https://sue445.hatenablog.com/entry/2020/11/08/192113

https://gihyo.jp/article/2023/03/tukinami-go-05

https://github.com/jandelgado/gcov2lcov

https://github.com/pingcap/tidb/pull/32201/files

↑は、atomicで出力した結果に対して、set相当に変換するロジックをプロジェクト独自に用意している例。
Postmanにおけるnext-authのログイン認証エラーの解決

## はじめに
next-auth(credentials)とpostmanを使用し、apiの確認を行った時にsession TokenがCSRFのエラーが原因で取得できなかったので、その解決までの記録を記載しています。

## エラー内容
サーバー側のエラーログを以下に示します。
```bash
[auth][error] MissingCSRF: CSRF token was missing during an action callback.
```

### 環境
- next: 14.1.0,
- next-auth: 5.0.0-beta.8
- postman

### ディレクトリ構成
```bash
app
└── api
    └── auth
         └── [...nextauth]
                └── route.ts
```
[...nextauth].tsにするとpostmanからリクエストした時に機能しませんでした。(原因解明中)

## postmanの設定
### 環境変数
環境変数に以下の設定を行います。csrfTokenのinitial valueは空にして、baseUrlは環境に応じて変更してください。

![スクリーンショット 2024-03-05 18.07.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2601888/76f183fe-2755-34dd-f66e-425836178d12.png)

### bodyの設定
workspaceに移動し以下の設定を行います。
リクエストの送信先は {{baseUrl}}/api/auth/callback/credentials と設定し、Bodyの種類はx-www-form-urlencodedを選択しました。
リクエストには6つのBodyパラメータが含めました。
- redirect: false
- email: test@gmail.com(テスト用のメールアドレス)
- password: 1234567(テスト用のパスワード)
- callbackUrl: {{baseUrl}}
- csrfToken: {{csrfToken}}
- json: true

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2601888/8d54ed69-44f4-288b-09e9-d9576339f91b.png)

### Pre-request Scriptの設置
都度発行されるcsrfTokenを取得するためのscriptの設定を行いました。以下に設定した画像とコードの説明を行います。
```bash
const baseUrl = pm.collectionVariables.get("baseUrl");
pm.sendRequest(`${baseUrl}/api/auth/csrf`, function (err, response) {
    var jsonData = response.json();
    pm.collectionVariables.set("csrfToken", jsonData.csrfToken);
});
```
baseUrl変数を設定しており、これはPostmanのコレクション変数から取得しています。
pm.sendRequest関数を使用して、CSRFトークンを取得するためのリクエストを${baseUrl}/api/auth/csrfに送信しています。ここで、テンプレートリテラルを使用しbaseUrl変数をURLに組み込んでいます。
リクエストのレスポンスからJSONデータを取得してjsonData変数に格納します。
jsonDataオブジェクトからcsrfTokenプロパティを取得し、Postmanのコレクション変数にセットし完了
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2601888/39e16cd8-6264-5757-0063-f6279570c6ab.png)

### 結果
上記の手順を踏むことで以下の画像のようにcookiesにauthjs.session-tokenが保存されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2601888/ac9be343-522b-b25e-3e7d-9cbb5c8ff5ed.png)

## 参考文献
https://www.postman.com/calcom/workspace/cal-com-workspace/environment/5215839-4af4f9bc-aa2f-4180-8a45-f41ef155dfff
Databricks 認定データエンジニアアソシエイトが日本語で受験可能に

Databricks の提供する認定試験、設問が英語なので受験を躊躇していらっしゃる方も多いのではないでしょうか。なんとこの度、Databricks 認定データエンジニアアソシエイトの試験が日本語で受験できるようになりました！

私自身今まで四つほど Databricks の認定試験を英語で受験してきましたが、英文の設問を解読するのに多くの労力と時間を費やしました。今回の日本語版リリースにあたり、日本語版のデータアソシエイトを(再)受験しましたが、母国語で長文の問題に挑めるのは感動ものです。言語バリアがないだけで合格の可能性はグッと上がると確信しました！

日本のデータエンジニアの皆さん、ぜひチャレンジしてみてください！

2024-03-05 時点では、以下資料と試験問題が日本語訳されています。試験の申込、試験に関するメールや Web画面で表示される手順の案内、試験問題以外の Web画面表示 ("Submit" ボタンなど) 、試験官とのやりとり (発生した場合) などは英語表示になっております。

## 試験概要ページ
[Databricks サイト上の試験概要ページ](https://www.databricks.com/jp/learn/certification/data-engineer-associate)が日本語で閲覧可能になりました！

## 試験ガイド PDF
試験概要ページにもリンクがありますが、[試験ガイド PDF](https://www.databricks.com/sites/default/files/2024-03/databricks-certified-data-engineer-associate-exam-guide.docx_ja.pdf) も日本語版が利用可能です。注: 本リンクは 2024-03-05 時点のもの、最新版は試験概要ページをご覧ください。

## 試験申込画面
実際の申し込み画面はこのようになっています。[Databricks Certified Data Engineer Associate 試験申込画面](https://www.webassessor.com/wa.do?page=enterCatalog&branding=DATABRICKS&tabs=111) で **Japanese** が選べるようになりました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3735715/75030523-4e6c-8fd7-4c51-7c08affb902f.png)

## 日本語のトレーニングも定期的に開催中
Databricks でデータエンジニアリングを実装する際に役立つ知識が体系的に学べる Data Engineering with Databricks を始め、いろいろなコースを日本語教材、日本人講師により定期的に開催しています。
試験対策にも効果的なトレーニングをぜひご活用ください。コース詳細、開催日程は[こちら](https://www.databricks.com/training/catalog/data-engineering-with-databricks-911)からご確認ください。
PythonでExcelの加工　フィルタ設定、セル塗りつぶし、中央揃え

仕事でPythonでExcelの加工を依頼されたため、
その時に使用したフィルタ設定、セル塗りつぶし、中央揃えをメモにまとめておきます。
どなたかの役に立つと嬉しいです。

```
import openpyx|
from openpyxl.styles import PatternFill
from openpyxl.styles import Alignment

wb = openpyxl.load_workbook('対象ファイルパス') 
ws = wb['対象シート名']

#A〜D列をフィルタ設定
ws.auto_filter.ref = 'A1:D1'

grayfill = PatternFill(patternType='solid' , fgColor='d3d3d3')
for row in ws['D2:D5']:
  for cell in row:
    #D列のセルを中央揃えに設定
    cell.alignment = Alignment(horizontal='general")
    #D列の2行目〜5行目を灰色塗りつぶし
    cell.fill = grayfill
```
CipherTrust Manager とは？

Thales の 企業向け __暗号鍵管理システム (KMS: Key Management System)__ 
略称"CM"

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613085/6b4d2919-52f3-dec6-a1ea-5d79f6004a32.png)

## 主な特徴
- 一元的な暗号鍵の管理
- セキュリティポリシーに応じた、ロールベースのアクセス制御
- 暗号鍵の生成、ローテション、破棄、インポート＆エクスポートなど暗号鍵のライフサイクルタスクを管理
- GUI、CLI、REST APIによる管理をサポート
- 仮想アプライアンス、及び、物理アプライアンスの両方で利用可能
- FIPS 140-2 準拠
    - HSM利用によるRoTにより ”FIPS 140-2 Level 3" サポート
- 監査ログサポート
- HAクラスタサポート

## 動作環境(仮想アプライアンス)
- Public Cloud
    - AWS
    - GCP
    - Azure
    - OCI
    - Alibaba Cloud
- Private Cloud
    - VMware vSphere - 'OVA' image file
    - Microsoft Hyper-V - 'VHDX' image file
    - Nutanix AHV - 'VMDK' image file
    - OpenStack - 'qcow2' image file

## 各種"コネクタ”(鍵管理＆暗号関連ソフトウェア)対応 
CMと連携して動作する、企業向け暗号処理モジュール/機能群(別ライセンス)
- CipherTrust Data Security Platform (CDSP)
    - KMIP
        - KMIP(鍵管理標準プロトコル)による、各種NAS/SAN/仮想環境/DBの鍵管理対応
    - トークナイゼーション(CT-VL)
    - [ファイルシステムレベル暗号化(CTE)](https://qiita.com/shinyaarai/items/ef4ddaef397a05335cac)
        - Linux/Windows のファイルシステムレベルでの透過的な暗号処理
        - システム管理者に対してもアクセス制限可能
    - DB暗号化(CDP)
        - Oracle/MS-SQL/SAP HANA/Teradata対応
    - クラウド鍵管理(CCKM)
        - 各種 Public Cloud/SaaS上のKMSへの”BYOK”及び"HYOK"対応)
    - シークレット管理(CSM)
        - 一時的、ローテーション型シークレット対応
    - 暗号化ライブラリ(CADP)
        - C/C++/Java/.Net対応暗号化ライブラリ
    - 機密情報検索(DDC)
        - 各種コンプライアンスの対象となる機密データの検索

## ライセンス
- Community Edition (無償版ライセンス - 機能制限付き)
    - 制限: HAクラスタ、HSM接続できない等
- Trial Evaluation (評価用ライセンス - 90日限定)
    - Community Edition での機能制限が外れ、90日間限定で全機能利用可能
- Purchased License (有償正規ライセンス)


## 関連URL
- [CipherTrust Manager 製品紹介](https://cpl.thalesgroup.com/ja/encryption/ciphertrust-manager)
- [CipherTrust Manager Community Edition 紹介](https://cpl.thalesgroup.com/ja/encryption/ciphertrust-platform-community-edition)
- [CipherTrust Manager 製品ドキュメント](https://www.thalesdocs.com/ctp/cm/index.html)

https://qiita.com/shinyaarai/items/4007d20851e7b1d6e0f1

## YouTube
https://www.youtube.com/@ThalesCloudSec
【ノーコード】FlutterFlowってどんな感じなの??

# はじめに
FlutterFlowがどんな感じのツールか体感すべく、色々と触ってみました。
本記事を読めばなんとなく使用感が伝わるかと思います。
使用を検討している方々の参考になれたら幸いです。

# TL;DR
以下は実際に使用した所感を簡潔に纏めたものです。
結論としては、プロトタイプを制作したい場合にかなり有用なツールだと感じました。

**■良い点**
・動きのあるモックがノーコードで作成可能
・データベースとの統合が容易
・約70種類に及ぶ、おしゃれな画面テンプレートを利用可能

**■良くない点**
・英語がつらい人にはつらい
・プログラミング知識が皆無だとつらい

# 詳細
TL;DRの内容に対する詳細を記載します。

## 1. 動きのあるモックがノーコードで作成可能
アプリのプロトタイプの評価は、スマホで動かしてみるとよりリアリティがあり良いと考えます。
GUIのみで作成したモックが↓のようにスマホでの操作同様に動きます(初回の投稿制約で動作のgifを添付できず...)
また、画面遷移図等の設計資料も自動で作ってくれます。
![画面遷移図.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3694358/19f9e35f-be3d-c042-4962-232538384c37.png)


## 2. データベースとの統合が容易
FlutterFlowはFirebaseと手軽に統合できます。データベース、ストレージなど、Firebaseの多岐にわたる機能を手軽にアプリ内で使用することが可能です。
![データベース.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3694358/f8fbda9a-044b-1b39-e77b-3b1797c027f4.png)


## 3. 約70種類に及ぶ、画面テンプレートを利用可能
下図のような画面テンプレが用意されています。
お洒落な画面が多いため、デザインが苦手なエンジニアでも安心安全！
![画面テンプレ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3694358/47b3ff57-480f-6e8b-748d-a433b82417b0.png)

## 4. 英語がつらい人にはつらい
下図は基本画面ですが、何から何まで英語です。
英語は全く分からない。という方にはつらいと思います。
※もちろんサポート等もすべて英語です
![基本画面.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3694358/abb30dcf-fd3e-1a37-7eb5-492960870d38.png)


## 5. プログラミング知識が皆無だとつらい
エラーの対応等はプログラミング知識やデータベース知識が多少ないとつらいと思います。
レベル的にはなんとなく何が怒られているのか分かれば大丈夫だと思いますが、
全く何言ってるのかわからん！という人は先に基礎知識を付けないと触っていてつらいツールだと思います。
![エラー.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3694358/7dbe2c40-36da-3b74-9543-b57ed7bab74a.png)


# まとめ
正直なところ、ノーコードというより、突き詰めると結局はローコードツールなのかなと。
ただ、作ったプロトをそのままFlutterプロジェクトとして吐けるのはかなり便利です。
ここがFlutterFlowの最大のメリットなのではと思います。

**今後FlutterFlowを使ったアプリ開発の記事を投稿予定です！:grinning:**

# 参考文献
- [https://flutterflow.io/](URL)
- [https://www.youtube.com/@FlutterFlow](URL)
JavaScript でIF文付きのリスト内包表記を書く

Python で書いていたIF文付きのリスト内包表記を JavaScript で実現するにはどうすればいいのかというのを毎年のようにググっているのでメモを残しておきます。

ちなみに JavaScript での書き方については Qiita の以下の記事が大変参考になります。(毎回ググって読んでいます)
https://qiita.com/yukiB/items/87ab3f313a75b547c278

```python: Python
[x * 100 for x in range(10) if x % 2 == 0]
```
```javascript: JavaScript で書いた同等の処理
[...Array(10).keys()].filter(x => x % 2 == 0).map(x => x * 100)
```

JavaScript の場合は Python に比べてリスト内包表記がそもそも冗長なのに加えて、IF文の代わりに filter を挟まなければならないので長いですが、それでも普通に同様の処理を書くよりは簡潔に書けるので使い道はあるかなと思います。
FreeCADの直方体のワイヤーフレームの体積計算をChatGPT-3.5先生に聞きました。

# オリジナル
日本語フォーラム

https://forum.freecad.org/viewtopic.php?t=85802

# ChatGPT 3.5先生 へ
```
freecadのマクロを教えて下さい。
直方体のワイヤーフレームを書いて、それをソリッドに変換、4等分したその体積を教えて下さい。
```

# ChatGPT 3.5先生 より
以下抜粋
```python
import FreeCAD as App
import Part

# 直方体を作成
length = 10  # 長さ
width = 5    # 幅
height = 8   # 高さ
box = Part.makeBox(length, width, height)

# ソリッドに変換
solid = box.makeSolid()

# ソリッドを4つに分割
cut_plane = App.Placement(App.Vector(0, 0, 0), App.Rotation(App.Vector(0, 0, 1), 45))
splits = solid.cut(box.copy().Placement.multiply(cut_plane))

# 4つのソリッドの体積を計算
total_volume = 0
for split in splits:
    total_volume += split.Volume

# 結果を出力
print("直方体の体積:", solid.Volume)
print("4等分した各体積の合計:", total_volume)
```
以下のエラーがでました。
```
<class 'AttributeError'>: 'Part.Solid' object has no attribute 'makeSolid'
```

# つづく
勉強中
Tello-Console2 の紹介

# Tello-Console2
:::note
この記事は短期間かつ不定期に更新します。
:::
　こんにちは。GAI-313 です。前回2年ほど前に Tello-Console を開発し、数多くの方々にご利用いただき、さまざまな意見をいただきました。その結果以下の重大な問題が見つかりました。

- **Windows での動作が安定しない**

　私の環境では Windows がなかったこともあり、Windows に対応するパッケージをうまく開発できませんでした。しかし、ここで新たにクロスプラットフォームで動作する新たな Tello-Console。**Tello-Console2** をリリースします。

## Tello-Console と Tello-Console2 の違い
　わざわざ番号を振って分けたのは、ドローンを制御およびドローンからの情報を取得するコードの記述方法を大幅に変更したことあります。Tello-Console ではすべて OpenCV を用いて画像データの取得を行っていたことで、データ受信に大きな遅延が発生してしまいました。しかし Tello-Console2 では FFmpeg を用いて画像データをエンコードして取得することで受信速度を大幅に向上させ、クラスプラットフォームで安定した画像データの取得に成功しました。
　コマンド送信時もいちいちドローンからのレスポンス時に診断処理を加えるのではなく、コマンドの種類に応じて適切な受信診断を行うよう調整したことで送受信のラグや失敗を大幅に下げました。

## Tello-Console2 のねらい
　TELLO ドローンを Python を使って制御するパッケージは数多く存在しており、メーカー公式もリリースしています。しかし環境が変わると動作しなかったり、セットアップが複雑すぎたりなどの課題が多く見受けられます。
 　Tello-Console2 はこれから Python の勉強をしたい方がドローンという動くツールを使って学びたいというニーズに応えて作成しました。教育用途や勉強、研究の一環として使用していただけたら幸いです。

## Tello-Console2 をダウンロードする
　Tello-Console2 をダウンロード、セットアップする方法を記事にまとめました。使用する環境に応じた記事をお読みください。

https://qiita.com/GAI-313/items/f8ea418b9820b2360374

https://qiita.com/GAI-313/items/8712fcd1ced36613a13f

- **Linux 版の記事は作成中…**

# Tello-Console2 チュートリアル

https://qiita.com/GAI-313/items/8cdb167368a620d809d8#基本制御メソッド

*今後作成予定*
[GAS]Gmailの検索、本文の取得

# 検索、本文を取得する方法

1. `GmailApp.search()`：Gmailの検索。スレッドの配列が返される。
1. `.map()`：配列を展開してスレッドを取得する。
1. `.getMessages()`：メッセージを取得する。スレッド内のメッセージの配列が返される。
1. `.map()`：配列を展開して（スレッド内の個々の）メッセージを取得する。
1. `.getPlainBody()`：本文を取得する。文字列が返される。

```js
  //Gmail内を検索。Gmailスレッドの配列が返される。
  let all_threads = GmailApp.search('from:(***@****) subject:(*********)');

  //スレッドの配列から個々のメッセージのオブジェクトを取り出す。
  let messages = all_threads.map((thread) => {
    let messages = thread.getMessages();

    let each_message = messages.map((each) => {
      return each.getPlainBody();
    });

    return each_message;
  })

  //階層構造をリセットする
  messages = messages.flat(3);
  ```
Gitを基本からまとめてみた【便利なコマンド】

## commit --amend

commit --amendを利用することで、直前のコミットを書き換えることができる。
変更を追加したり、コミットメッセージを書き換える事ができる。

#### （1）現在の変更を直前のコミットに統合する

```
git status
// 現在のコミット履歴のログの確認
git log --oneline

//現在の変更をaddして、commitコマンドを --amendオプションをつけて実行する
git add .
git commit --amend
//コミットメッセージを書き換えられるエディタが開く。必要があればここでコミットメッセージを書き換える。

git status
// 現在のコミット履歴のログの確認
git log --oneline
git show (指定番号)
```

#### (2) 直前のコミットメッセージを修正する

```
git status
git log --oneline
git commit --amend

ログメッセージを追加

git log --oneline
```
## git rebase -i


####  (1)コミット同士を合わせたい

```
git rebase -i (指定番号)
pick
git rebase --continue
git log --oneline
```



## 参考サイト
[Git中級者への第1歩！ レビュー品質向上の秘訣、コミットに便利なコマンドを紹介](https://codezine.jp/article/detail/18937?p=2)
JavaScript の非同期処理は難しい

年末に社内向けには共有していた話ではあるのですが、公開記事として記録を残しておきます。

とあるシステムにて、map の中のループの中でやっている3種類のボタンクリック処理を順番に実行してほしかっただけなのですが、なかなか思い通りに動かなかったのでメモを残しておきます。

- Promise チェーンはチェーンの内部でしか実行順番が保証されない。チェーンの上部で非同期のループを回してしまうと、複数の Promise チェーンが並列実行されることになる。
- Promise.all は全部の処理が終わっていることは確認してくれるが、内部の処理が順番に実行されるとは限らない。
- 普通の for の中で await を書くのが簡単。

このあたりの詳細については以下の記事が分かりやすいのでお勧めです。
https://zenn.dev/sora_kumo/articles/612ca66c68ff52

今すぐに理解できなくとも、非同期処理の問題だと知っていれば、問題解決までの時間が短縮されるので、まずは知っていることが重要かと思います。
[Google Sheets API] 埋め込みオブジェクト(グラフ、画像、スライサーなど)のサイズ、配置位置を変更したり、埋め込みオブジェクトを削除する

Google Sheets API v4（Java）を使用して、
スプレットシートに埋め込まれたオブジェクトのサイズ、配置位置を変更する方法と
スプレットシートに埋め込まれたオブジェクトを削除する方法
についてご紹介します。

**埋め込みオブジェクトとは**
グラフ、画像、スライサーなど、スプレットシート上に配置され、
マウスなどで動かすことができるオブジェクトのことを指します。
埋め込みオブジェクトは、グラフや画像などの種類に関わらず一意のIDを持ちます。

:::note info
APIを利用する環境の準備から始める場合や、コードを実行する際は、
[⧉[Google Sheets API] Google Sheets API v4をJavaで操作する](https://qiita.com/doran/items/3d43f776188b2281044c)
を参照ください。
```
例：requests.add(moveDimension(sheetId)); //実行したいリクエストのMethodを指定
```
:::

:::note info
その他のGoogle Sheets APIは、下記の記事を参照ください。
[⧉[Google Sheets API] JavaでスプレットシートのメニューとAPIを関連づけてみた](https://qiita.com/doran/items/2f6f8932b994fbd1a170)
:::

|No|目次|
|---|---|
|1|[サイズ、配置位置の変更](#1-サイズ配置位置の変更)|
|2|[埋め込みオブジェクトの削除](#2-埋め込みオブジェクトの削除)|

## 1. サイズ、配置位置の変更
埋め込みオブジェクトのサイズや配置位置を変更します。

変更可能な項目は、OverlayPositionクラスで設定可能な項目のみです。
UpdateEmbeddedObjectPositionRequestクラスのsetFields()で
変更する項目を指定します。指定がない場合は更新されません。
複数の項目を同時に更新したい場合は、「,」で繋げて指定します。
|type|更新内容|
|---|---|
|anchorCell|配置の起点となるセル情報|
|offsetXPixels|起点となるセルからのX座標|
|ffsetYPixels|起点となるセルからのY座標|
|heightPixels|オブジェクトの高さ|
|widthPixels|オブジェクトの幅|

なお、座標の位置は起点となるセルの右下を開始としています。

**サンプル コード**
```
public Request updateEmbeddedObjectPosition(Integer sheetId) {
    Request request = new Request();

    EmbeddedObjectPosition position = new EmbeddedObjectPosition();
    OverlayPosition overlay = new OverlayPosition();
    
    //起点となるセルの指定
    GridCoordinate grid = new GridCoordinate();
    grid.setSheetId(sheetId); 			//配置するシートID
    grid.setRowIndex(10); 				//開始行(0スタート)
    grid.setColumnIndex(10); 			//開始列(1スタート)
    overlay.setAnchorCell(grid);
    
    //起点となるセルからのオフセット値
    overlay.setOffsetXPixels(0);		//開始X座標
    overlay.setOffsetYPixels(0);		//開始Y座標
    overlay.setHeightPixels(200);		//グラフの高さ
    overlay.setWidthPixels(200);		//グラフの幅

    position.setOverlayPosition(overlay);
    
    UpdateEmbeddedObjectPositionRequest r = new UpdateEmbeddedObjectPositionRequest();
    r.setObjectId(1);                         //更新するオブジェクトID
    r.setFields("heightPixels,widthPixels");  //更新する項目
    r.setNewPosition(position);               //更新内容

    request.setUpdateEmbeddedObjectPosition(r);
    return request;
}
```
## 2. 埋め込みオブジェクトの削除
埋め込みオブジェクトを削除します。

**サンプル コード**
```
public Request deleteEmbeddedObject() {
    Request request = new Request();

    DeleteEmbeddedObjectRequest r = new DeleteEmbeddedObjectRequest();
    r.setObjectId(1);			//削除するオブジェクトのID。

    request.setDeleteEmbeddedObject(r);
    return request;
}
```
<br>
おしまい。。
SIerのトンチキスクラムについて (4)

# SoS

今回のスクラムはScrum of Scrums(以下SoS)という、複数のスクラムチームがあり、スクラムマスターでもチームを組むというフレームワークを採用しています。

これによって３０００人規模の企業で５階層か６階層くらいの朝会を実施し、全社へ口頭での情報伝達を午前中に終わらせるといったことをしているところもあるんだとか。

# 妥協
スクラムの中に彼らの居場所はなく、スクラムチームに干渉することはできないという原則を踏まえつつ私がとった案は、「スクラムマスターたちの朝会でなぞのひとたち発言を許す」でした。

これによって被害をスクラムマスターの皆様の間だけに留めることができます。

つまり、yamamotodinをはじめとしたはじまりの４人がなぞのひとたちの話を仄聞しつつ、彼らも動向が把握できるというものです。

本来スクラムイベントは決まった曜日、決まった時刻に行われてリズムがあることが望ましいとされていますが、スクラムマスターの朝会は時間を問わず、１日の間に複数回行われることもありました。

そこで出る下記の様な干渉からスクラムチームを守ったと思います。もっとたくさんあったけどくだらないことは忘れたい派です・・・

1. バグ指標とエラー係数についてまとめたいという話→レトロで出た内容を集計するからそれでいいよね
2. なにかにつけ何かを決めきって進めようとする考え方の排除→変化を受け入れましょう。スプリントのプランニングで毎回変えるでいいじゃん
3. 設計がいつ終わるのか、実装は、テストはと期間を決めたがる→最終テストであるリグレッションテストの期間は設けていいと思うけどそれ以外はスプリントの中でリリース品質まで持っていくから却下
4. なにかにつけてご指導したがる→とりあえず話は聞くよ　主にyamamotodinが

克明に覚えているから２について話をしよう。

ある日の夕方、プロジェクトの前提となる部分においてのお話で、変化を受け入れないとどうにもならんと理解するスクラムマスターズとなぞの人たちの会話。
議題は「お客様が触るUIは一度決めたら変更されない」となぞの主張をなぞの人たちがするのです。

なわけねーだろってのを理詰めで話していくだけどどうしてもここは折れそうにない。
喧々囂々とホワイトボードの前で不毛なやりとりが行われてから４５分、事件は起こった。

伝令がドアがバーン！と開いて曰く

「お客さんがUI変えてます！！」

いままさにその話をしていたところで、変えないという前提を主張していたなぞのひとたちは沈黙。
スクラムマスター側の意見が通りました。

たぶん、リスクをとりたくないからUIは決めたら変えないという方向で話をもっていきたかったんだと思うけど、すごくいいタイミングで先制されましたね、ざまみろです。

これ以後。彼らのよくわからないかウォーターフォールを根拠とした発言は積極的にナーフされていくことになります。

風向きが変わった一瞬でした。
`refusing to allow an OAuth App to create or update workflow` を解決する

## 遭遇したエラー
ある日突然
`refusing to allow an OAuth App to create or update workflow `.github/workflows/hoge-action.yml` without `workflow` scope`

```bash:エラー全文
Enumerating objects: 33, done.
Counting objects: 100% (33/33), done.
Delta compression using up to 16 threads
Compressing objects: 100% (21/21), done.
Writing objects: 100% (24/24), 1.17 MiB | 2.97 MiB/s, done.
Total 24 (delta 15), reused 5 (delta 1)
remote: Resolving deltas: 100% (15/15), completed with 8 local objects.
To https://github.com/hoge/moge.git
 ! [remote rejected]       0/foo -> 0/bar (refusing to allow an OAuth App to create or update workflow `.github/workflows/hoge-action.yml` without `workflow` scope)
error: failed to push some refs to 'https://github.com/hoge/moge.git'
```

## 解決方法
### やること
今回は `workflow` の権限が足りなかったので
```bash
gh auth refresh -s workflow
```

### なぜ
* `push` に使っている権限に `workflow` が許可されていなかった
* `gh auth` を使って権限を付与する
```bash
$ gh auth refresh --help
Expand or fix the permission scopes for stored credentials.

The `--scopes` flag accepts a comma separated list of scopes you want
your gh credentials to have. If no scopes are provided, the command
maintains previously added scopes.

The `--remove-scopes` flag accepts a comma separated list of scopes you
want to remove from your gh credentials. Scope removal is idempotent.
The minimum set of scopes (`repo`, `read:org`, and `gist`) cannot be removed.

The `--reset-scopes` flag resets the scopes for your gh credentials to
the default set of scopes for your auth flow.


USAGE
  gh auth refresh [flags]

FLAGS
  -h, --hostname string         The GitHub host to use for authentication
      --insecure-storage        Save authentication credentials in plain text instead of credential store
  -r, --remove-scopes strings   Authentication scopes to remove from gh
      --reset-scopes            Reset authentication scopes to the default minimum set of scopes
  -s, --scopes strings          Additional authentication scopes for gh to have

INHERITED FLAGS
  --help   Show help for command

EXAMPLES
  $ gh auth refresh --scopes write:org,read:public_key
  # => open a browser to add write:org and read:public_key scopes
  
  $ gh auth refresh
  # => open a browser to ensure your authentication credentials have the correct minimum scopes
  
  $ gh auth refresh --remove-scopes delete_repo
  # => open a browser to idempotently remove the delete_repo scope
  
  $ gh auth refresh --reset-scopes
  # => open a browser to re-authenticate with the default minimum scopes
```



## 参考
ref: https://github.com/cli/cli/issues/5355#issuecomment-1367157797
MarkDown&Gitの社内利用を普及するには（考察）

## 0.はじめに
MarkDownやGitの社内利用をもっと増やしたいなと思ってはいるが、社内利用では特定のメンバーのみ利用していたりするため、MarkDownやGitが少しでも身近にするためには、どうしたらよいかと考えてまとめた記事になります。
ちなみに、私自身は決してマークダウンが得意という分けではありません。 

:::note warn
ここでいうGitとはGitHub以外のGit系のバージョン管理製品を含みます  
:::

以降に、メリット、デメリットと考察をまとめてみました。
あくまで、個人的な見解です(;^_^A）

----
### 1.　:sunny:メリット
- テキストエディタで編集可能
専用ソフトがなくても、編集できる。ツールを利用するとしたらMarkDownを利用した補助ツールがあると便利なぐらい。エディタはいろいろあるが、無料で揃えることが可能。
- 中身はテキストなので、ファイル自体が軽い
ファイルが軽いと何が良いかというと、読み込みに時間がかからないのと、受け渡しもしやすい。
- PDFやHTMLへの変換も可能
他のツールを利用する必要はあるが、PDFやHTMLの変換は容易。
[Visua lStudio Code](https://code.visualstudio.com/)のプラグインを利用したり、[MkDocs](https://www.mkdocs.org/)など、目次付きでHTM変換してくれるものもあります
- Gitとの相性が良い

以下のように５W1Hが満たせるので利にかなってます
| 5W1H | Gitの機能 |
|:---|:---|
|Who（だれが)|コミット時のユーザ名|
|When（いつ）   | コミットの時刻  |
|Where（どこで）   | リポジトリ　※これは若干こじつけ  |
|What（なにを）   | コミットに紐づくファイル |
|Why（なぜ）   |コミットコメント   |
|How（どのように）   | Gitの差分表示機能を使って変更箇所を確認  |

WordやExcelのような変更履のファイルもしくはシートを作成して管理している場合は、手間が省けます。履歴を作ることを目的にしてしまいがちですが、どちらかというと、上記のことがわかること重要です。私は５年以上前にコミットされた情報から探し出すこともしばしばありますが、詳細な履歴が残っていることに助けられたことは何度かあります。ソースコードの管理でgit利用は今や当たり前ですが、ドキュメントも同様になって欲しいと思います

- AI活用で何かいいことあるかも
OpenAIなどの自然言語処理においては、大量にMarkdownのデータを学習している可能性が高く、実際にプロンプトエンジニアリングでも、MarkDownの形式で情報を与えた方が良い回答を得られる場合があります。
その為、あらかじめMarkDown形式でドキュメントを残しておいた方が、後々メリットがあるのでは？と思っています。
具体的、何か事例とかがあるということではないため、こちらについてはあくまで考察です。

----
### 2.　:umbrella2:デメリット
- MarkDownの記述を覚える必要がある
ただし、最初は主要な書き方を覚えるだけで十分実用的に使える
- インデントの調整がなれないと違和感がある
MarkDown固有のレイアウトはある程度、割り切りが必要。
テキストで書いたものと、実際のページで見た目が違うとストレスに感じる人も。
→プレビュー表示しながら編集するぐらいしか改善策はみあたらない。。。
　慣れるしかない。
- Excel、Wordに比べ、表現の自由度は下がる
- 利用するインフラを整える必要がある
利用用途、目的によって、どこで管理するかの選択肢が多く、クラウド上で管理したくない場合は、自社内にサーバを作る必要がある。
- gitの使い方になれる必要がある
Markdownとgitはセットで利用しないと、有用にならないため、このあたりに抵抗がある人（特に事務系の方）はある。ただし、git操作は、ブラウザ上で操作すれば、UI的にわかりやすく編集も直接できるので、あまり弊害にはならい。

- 利用するドキュメントフォーマットがあらかじめ決められている
取引先や利用者向けのドキュメントの場合は、困難かもしれませんが


## 3.考察

#### 3-1．普及の障壁
社内利用を普及するうえで見えてきた障壁は、以下に尽きるのではないかなと思われます
- インフラ検討が面倒（※オンプレ利用の場合に限る）
- 何を対象にMarkDownでの管理対象とするか決められる人がいない
- Word、Excelで管理していたものを、今さらMarkDonwに置き換えるのは面倒

####  3-2．どんな風に進めれば
作成済みのドキュメントであったり、すでに様式やルールが決まっているものには導入は難しいため、入れやすいところから適用範囲を広げて、利用できる人を増やしていくのが一番、ベストな進め方と思われます。

- 新規プロジェクトで、最初にルールを決め
- ノウハウ共有
  Qiitaとかが良い実例です:grinning:

## Appendix
- Gitのあれこれ
Gitを利用する場合、選択肢がいくつかあります。
以下に関しては様々な記事がでており、情報集めには苦労しないのでここでの説明は割愛します。 
１）GitHub
　クラウド上での会社として問題なければ、ここが王道の選択肢 
　他のクラウドサービスとの連携など、拡張性が高いため、こちらを推奨
２）GitLab
　GitHubと同様に以前からgitのサービスを提供
　コミュニティ版は、一部、機能制限はあるが、無償で自社に作ることが可能。 
３）GitBacket
　利用したことないので、説明は割愛。上記のサービスと基本的な機能は、ほぼ同じ
　
- その他、MarkDownのユースケース
１）Gitのpagesやチケット
２）Jupyter Notebook で Markdown セル　
３）Qiitaの記事
４）Backlog
５）Mattermost
etc
chezmoiでdotfilesを管理したメモ

## 1. インストール
```bash
$ brew install chezmoi
```
## 2. 初期化
僕はすでにdotfiles用のレポジトリを持っていたので、それを使いました
```bash
$ chezmoi init git@github.com:ZOI-dayo/dotfiles.git
```
## 3. ファイルのインポート
現時点では、~/.zshrcなどのファイルが他の場所へのシンボリックリンクになっていたので、`--follow`をつけます
```bash
$ chezmoi add --follow ~/.zshrc
$ chezmoi add --follow ~/.config/nvim/

# dot_config/nvim/.keep しか生成されなかったので
$ cp -r ~/.config/nvim/* `chezmoi source-path`/dot_config/nvim/
$ rm `chezmoi source-path`/dot_config/nvim/.keep

$ chezmoi add --follow ~/.vimrc
```
ついでに、元のdotfilesにあったファイルを一時的によけておく
```bash
$ chezmoi cd
$ mkdir tmp
$ mv ./.* ./tmp/
$ mv tmp/.git .git
$ mv bash init.vim nvim tmp/
```

## 4. 特定のPCでのみ適用される設定を作る

```bash
$ chezmoi chattr +template ~/.zshrc
```
.tmplファイルではいろいろな変数や制御文が使えるので、dot_zshrc.tmplを好きに編集すればよいです

## 5. chezmoiignoreを整備する
```bash
$ chezmoi cd
$ touch .chezmoiignore
$ nvim .chezmoiignore

README.md
LICENSE
```
## 6. 適用
```bash
$ chezmoi apply
```

# 参考記事
https://zenn.dev/ryo_kawamata/articles/introduce-chezmoi

https://zenn.dev/johnmanjiro13/articles/d14825f4ef3184
SIerのトンチキスクラムについて (3)

# まずはスクラムとは何かを確認しよう

## スクラムの定義
ガイドから和訳して引用します。

```
スクラムは、人、チーム、組織が価値を生み出すのに役立つ軽量のフレームワークで、複雑な問題に対する適応的なソリューションです。

一言で言えば、スクラムでは、スクラムマスターが次のような環境を促進する必要があります。

1. プロダクト オーナーは、複雑な問題に対する作業をプロダクト バックログに発注します。
2. スクラム チームは、スプリント中に作業の選択を価値の増分に変えます。
3. スクラム チームとその関係者は結果を検査し、次のスプリントに向けて調整します。
4. 繰り返します

```

で、PM(様)とかPMOってのはこの中に入らんのですよ。
それはウォーターフォール開発における重要なロールで、なんでその話がこの現場ででるのかわからんのですよ・・・

ボトムアップで小さな問題を解決していく仕組みで、メンバー、スクラムマスター、プロダクトオーナーが居て一連の儀式をグルグル回しつつ、状況に応じてスクラムチームを外側から適切な手法にのっとって支援するひとたちがあってもいいかなというものが、スクラム・フレームワークというものです。

## 推測してみる
数日の間、このなぞの人たちを観察したところ、どうもPM様やPMO他なぞの人たちは、アジャイルやスクラムといったものを**さらさら理解するつもりはなく**、ソフトウェアは川が上流から下流に流れるのとおなじりくつで、つまりウォーターフォールで進捗していくもので、ソレ以外に道はないと思い込んでいるような気がします。

そりゃそうかもな、それしか見たこと無いんだしと一定の（比率でいうと１０％未満）の理解を示しつつ、そんな理論をスクラムに持ち込んだら数日で破綻することがわかっているため、私はスクラムマスターのRoEに従い、彼らからスクラムチームを守る決意を固めました。

ただ、現実問題ある種のステークホルダーであることは認めているため、げんじつてきなだきょうを行っていくことになります。

これがyamamotodinのもっとも重要で隠されたミッションでした。
langchainでChatGPT APIの使用トークン(llmOutput)が返ってこない

# つまった問題
langchain.jsでChatGPTAPIを利用したチャットボットを作る際に、トークンをかぞえたかったので以下のようにコールバックを設定していた。

```js
import { OpenAI } from "@langchain/openai";

let totalCompletionTokens = 0;
let totalPromptTokens = 0;
let totalTokens = 0;

const model = new OpenAI({
		openAIApiKey: process.env.OPEN_AI_API_KEY, 
		modelName: "gpt-3.5-turbo",
        callbacks: [
            {
                handleLLMEnd(output) {
                    console.log(JSON.stringify(output, null, 2));
                    totalCompletionTokens += output.llmOutput?.tokenUsage?.completionTokens ?? 0;
                    totalPromptTokens += output.llmOutput?.tokenUsage?.promptTokens ?? 0;
                    totalTokens += output.llmOutput?.tokenUsage?.totalTokens ?? 0;
                },
            },
        ],
	});

 //以下省略
```

しかし、ログを確認すると`output`に`genetations`だけが存在しており、`llmOutput`が含まれていなかった。
```shell
{
  "generations": [
    [
      {
        "text": "やほー"
      }
    ]
  ]
}
```

`llmOutput`がないと、以下の変数たちにtoken数がカウントアップできない。
```js
totalCompletionTokens += output.llmOutput?.tokenUsage?.completionTokens ?? 0;
totalPromptTokens += output.llmOutput?.tokenUsage?.promptTokens ?? 0;
totalTokens += output.llmOutput?.tokenUsage?.totalTokens ?? 0;
```

# 解決策
[langchainjs](https://github.com/langchain-ai/langchainjs)のissueですでに聞かれてた。

https://github.com/langchain-ai/langchainjs/issues/965

>I think the reason is that the GPT-3.5-turbo model can only be used for Chat models.
I had to update my old code from 'OpenAI' to 'ChatOpenAI', and that fixed the issue.

つまり、`OpenAI`をインポートしていたのを
```js
import { OpenAI } from "@langchain/openai";
//・・・
const model = new OpenAI({
//・・・
```
`ChatOpenAI`をインポートするように変えるだけみたいです。
```js
import { ChatOpenAI } from "@langchain/openai";
//・・・
const model = new ChatOpenAI({
//・・・
```

### 結果
`llmOutput`が返ってきた。（途中でConversationSammaryを使うようにしたから結果の対称性が微妙ですみません。）
```shell
{
  "generations": [
    [
      {
        "text": "The human greets the AI with \"やほー.\" The AI responds enthusiastically with \"やほー！\"",
        "message": {
          "lc": 1,
          "type": "constructor",
          "id": [
            "langchain_core",
            "messages",
            "AIMessage"
          ],
          "kwargs": {
            "content": "The human greets the AI with \"やほー.\" The AI responds enthusiastically with \"やほー！\"",
            "additional_kwargs": {}
          }
        },
        "generationInfo": {
          "finish_reason": "stop"
        }
      }
    ]
  ],
  "llmOutput": {
    "tokenUsage": {
      "completionTokens": 25,
      "promptTokens": 150,
      "totalTokens": 175
    }
  }
}
```

# 参考記事
https://js.langchain.com/docs/modules/model_io/chat/token_usage_tracking
AWS CLF入門 - デプロイ編

## はじめに
AWS CLF (AWS Certified Cloud Practitioner) を取得した際の学習記録をアウトプットとして以下に記す。

## リンク
[ネットワーク](https://qiita.com/yashiuri/items/31b2c9c3c49c2584cd01)
[セキュリティ](https://qiita.com/yashiuri01/items/73e5310b09ff41912862)
[コンピューティング](https://qiita.com/yashiuri01/items/9eaf71a1590e7815f9ef)
[コンテナ](https://qiita.com/yashiuri01/items/708b57ee179ae29e72a9)
[スケーリング](https://qiita.com/yashiuri01/items/79050093aff66b0f0665)
[ストレージ](https://qiita.com/yashiuri01/items/6d48d81f5a1651dcc999) 
[データベース](https://qiita.com/yashiuri01/items/159ea63b197f7a836d1c)
[メッセージ](https://qiita.com/yashiuri01/items/d98772b540ef2201c4e2)
[モニタリング](https://qiita.com/yashiuri01/items/64f6dbf38603cdb4828a)
[デプロイ](https://qiita.com/yashiuri01/items/85151311897d6afd429c)
[コストとサポート](https://qiita.com/yashiuri01/items/bac23130a43d62677330)
[移行とイノーベーション](https://qiita.com/yashiuri01/items/6e327034a7c50d56ca88)
[AWS用語集](https://qiita.com/yashiuri01/items/bd36c99623ca596b76e4)


## デプロイ

### AWS マネジメントコンソール

- Webベースのインターフェース
- ユースケース
    - テスト環境
    - AWS請求書の表示
    - モニタリングの表示
    - 非技術リソースでの作業

### AWS CLI (Command Line Interface)

- マシン上のターミナルを使用してAPIコールを行う

### AWS ソフトウェア開発キット(SDK)

- プログラミング言語でのAWSの操作

### **AWS Elastic Beanstalk**

- ユーザーがコードと設定情報を提供することによってタスクの実行に必要なリソースが自動的にデプロイ
- アプリケーションの複数のバージョンを実行する必要がある場合は、複数の環境をデプロイできます

### **AWS CloudFormation**

- IaC
- jsonかyaml
- インフラストラクチャをコードとして扱える
AWS Config の ルールを検索する

## 何がしたいのか

AWS Config のルールを名前で検索したいです。
AWS Config ルールのコンソール画面には検索窓がなく、名前等でフィルタできません。

![Screenshot_20240305_config.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109270/2fb28466-b387-573f-5eb8-bae5addc0ca8.jpeg)



## こうしたらできた

### 検索方法

AWS CLI を使って一覧化する（AWS CLI の利用設定済み前提）。
ConfigRuleId、ConfigRuleName、ConfigRuleStateを一覧表示。

#### コマンド

変数
```
SEARCH_STRING={検索したい単語}
```

AWS CLI
```
aws configservice describe-config-rules --output json | jq -r '.ConfigRules[] | select(.ConfigRuleName | contains("'"$SEARCH_STRING"'")) | [.ConfigRuleId, .ConfigRuleName, .ConfigRuleState] | @tsv'
```

#### サンプル
ルール名に「tag」がつく config rule を探す。

```
% SEARCH_STRING=tag
% aws configservice describe-config-rules --output json | jq -r '.ConfigRules[] | select(.ConfigRuleName | contains("'"$SEARCH_STRING"'")) | [.ConfigRuleId, .ConfigRuleName, .ConfigRuleState] | @tsv'
config-rule-wnod5z	required-tags	ACTIVE
config-rule-yabmkx	securityhub-ecr-XXX	ACTIVE
config-rule-xmuqst	securityhub-fsx-XXX	ACTIVE
config-rule-odxr2a	securityhub-neptune-XXX ACTIVE
config-rule-qveleo	securityhub-rds-XXX ACTIVE
config-rule-uejkbj	securityhub-rds-XXX ACTIVE
```

securityhub が邪魔な場合は grep で除外。

```
% SEARCH_STRING=tag
% aws configservice describe-config-rules --output json | jq -r '.ConfigRules[] | select(.ConfigRuleName | contains("'"$SEARCH_STRING"'")) | [.ConfigRuleId, .ConfigRuleName, .ConfigRuleState] | @tsv' | grep -v "securityhub"
config-rule-wnod5z	required-tags	ACTIVE
```


### 詳細確認

ここまでだと、idと名前と状態しかわかりません。
ルールの詳細をこのままコマンドで確認してもよいのですが、詳細はコンソールで確認したい場合は、確認したルール名を以下のリンクに追記してブラウザから直接飛べばOK。

#### リンク

```
https://{リージョン}.console.aws.amazon.com/config/home?region={リージョン}#/rules/details?configRuleName={ルール名}
```


#### サンプル
リージョンや名前は変えてください。

```
https://ap-northeast-1.console.aws.amazon.com/config/home?region=ap-northeast-1#/rules/details?configRuleName=required-tags
```

![Screenshot_config_tags.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109270/ce31842e-b06d-d111-e433-cc6b09fe8627.png)
Pythonでひらがな, カタカナを濁音にする

## 動機
踊り字とは, "いらいら"を"いら/＼"のように, 繰り返しを省略するものですが, 中には"それ/″＼ -> それぞれ"のように, 濁音を付与するものもあります.
自然言語処理の前処理でこれらをどうにかしようと思って調べてみたら, 案外これについての記事がなかったので書きました.

## コード
Pythonで書きます
```python
def dakuon_for_char(c: str) -> str: 
    # 一文字だけ濁音に直す
    if ord('か') <= ord(c) <= ord('ち') and ord(c) % 2 == ord('か') % 2:
        return chr(ord(c) + 1)
    if ord('つ') <= ord(c) <= ord('と') and ord(c) % 2 == ord('つ') % 2:
        return chr(ord(c) + 1)
    if ord('は') <= ord(c) <= ord('ほ') and ord(c) % 3 == ord('は') % 3:
        return chr(ord(c) + 1)
    if ord("カ") <= ord(c) <= ord("チ") and ord(c) % 2 == ord("カ") % 2:
        return chr(ord(c) + 1)
    if ord("ツ") <= ord(c) <= ord("ト") and ord(c) % 2 == ord("ツ") % 2:
        return chr(ord(c) + 1)
    if ord("ハ") <= ord(c) <= ord("ホ") and ord(c) % 3 == ord("ハ") % 3:
        return chr(ord(c) + 1)
    if (c == "う"):
        return "\u3094"
    if (c == "ウ"):
        return "\u30F4"
    return c

def dakuon(s: str) -> str:
    return "".join(map(dakuon_for_char, s))
```

## テスト
```python
print(dakuon("あいうえお")) # あいゔえお
print(dakuon("かきくけこ")) # がぎぐげご
print(dakuon("さしすせそ")) # ざじずぜぞ
print(dakuon("たちつてと")) # だぢづでど
print(dakuon("なにぬねの")) # なにぬねの
print(dakuon("はひふへほ")) # ばびぶべぼ

print(dakuon("アイウエオ")) # アイヴエオ    
print(dakuon("カキクケコ")) # ガギグゲゴ
print(dakuon("サシスセソ")) # ザジズゼゾ
print(dakuon("タチツテト")) # ダヂヅデド
print(dakuon("ナニヌネノ")) # ナニヌネノ
print(dakuon("ハヒフヘホ")) # バビブベボ
```
## 解説
ordはunicodeコードポイントを取ってくる関数で
chrはそれを文字列に戻す関数です.

以下, う以外について
[Unicode一覧](https://ja.wikipedia.org/wiki/Unicode%E4%B8%80%E8%A6%A7_3000-3FFF)を眺めてみると, 文字コードについて, 濁音は常に清音より1だけ大きいことが分かります.

"か"から"ち"までは連続しているので, ここの範囲に属する文字は偶奇が"か"と一致すれば清音と
促音の"っ"でずれているので上と別処理になってしまいますが, "つてと"も同じ考え方で処理できます.
は行は半濁音が入ってきて, "は"と"ひ"のようにとなり合わせの清音は3だけずれるので, ここは3で割った剰余で判定します.

最後に"う"と"ウ"だけは別処理にしていますが, これらについては別に濁音にしたくないときのほうが多いと思うので, 必要に応じて消してください.

#### 以下20240306追記

## 青空文庫の踊り字を解決する
[青空文庫作業マニュアル](https://www.aozora.gr.jp/KOSAKU/MANUAL_2.html)によれば, 踊り字は"／＼"となっていますが, 実際のテキストを確認したところ"/＼"となっているものもあったので, 念のため両方に対応します.
上で紹介したdakuon関数をどっかに入れてください.

```python
import re

def preprocess(text):
    text = re.sub(r"(?P<mae>..)[／|/]＼", r"\g<mae>\g<mae>", text)
    f = lambda s: s.group("mae") + dakuon(s.group("mae")[0]) + s.group("mae")[1]
    text = re.sub(r'(?P<mae>..)[／|/]″＼', f, text)  # ″は全角文字であることに注意
    return text

text = "ニャー、ニャーと試みにやつて見たが誰も來ない。其内池の上をさら／＼と風が渡つて日が暮れかゝる。"
print(preprocess(text))
# ニャー、ニャーと試みにやつて見たが誰も來ない。其内池の上をさらさらと風が渡つて日が暮れかゝる。
text = "其時におさんと云ふ者はつく／″＼いやになつた"
print(preprocess(text))
# 其時におさんと云ふ者はつくづくいやになつた
```

ただし, これでは対策できない例外もあります.

[吾輩は猫である](https://www.aozora.gr.jp/cards/000148/files/790.html)を見ていただくと, 「ニャー／＼泣いて居た」という文章が出てきます. これを上の関数を用いて処理すると「ニャーャー泣いて居た」になってしまうでしょう. 
対策として考えられるのは, "ニャ"のような, 小文字付きのものを一文字として見るように, (?P\<mae\>..)の部分を工夫することです.
プログラムを自在に操る感覚を得るために(決意表明)

## 私の最大の悩み 
私は現在大学4年生で2024年4月からデータ分析の仕事に就く。
大学生活のみならず人生を通じてずっともやもやとした悩みを抱えてきた。
それは「物事が操れた感覚がない」ということである。
そしてそれは自分が一番手に入れたいものである。

## kaggleとの出会い
情報系の学部に入り、大学3年生のときにkaggleを始めた。

大学までろくにパソコンも触ってこず、プログラミングも初めてだった私にとってkaggleは難しすぎた。

わからないことが多すぎてどこから手をつけていいか分からず、そのような体験は初めてであったため当然挫折した。

その後、本やインターネットでkaggleについて調べて再チャレンジし、なんとかコンペを完走できるようになった。

## いつのまにかコピペエンジニアになっていた
やがて銅メダルが取れるようになってきたが、ふと思ったことがある。
私は本質的に理解していないのではないかと。

私のkaggleでの立ち回りはvoteの多いnotebookとdiscussionをひたすら読んで、良さそうな手法を実装していくという王道のものである。

それは銅・銀メダルを取りに行く戦略としては正しいだろうが、kaggleをやる本来の目的であるスキルアップには貢献するだろうか？
私はいちからbaselineとなるnotebookを自分で書けるだろうか？
何も見ずにEDAなどを正しく行えるだろうか？

答えは「ノー」である。

なぜなら私は他人のコードをcopyして使っていただけであって、スコアを上げることに囚われて、本質的な理解を放棄していたからである。
いわゆるコピペエンジニアになっていたのである。

## 世界一流エンジニアの思考法
これは有名な本だが最近になって初めて読んだ。

この本を超要約すると「理解が大切」ということである。

この本によると、物事ができるようになるには理解・記憶・反復が必要らしい。

料理で例えると以下のようになるだろう

1. **理解（Understanding）: レシピの理解**

   料理を作る際には、レシピを理解することが不可欠。各材料や手順が料理の成功にどのように寄与するかを理解することは、調理の基本。
   
   例えば、なぜ特定の調味料や調理法が使われているのかを理解することで、料理のバランスや味わいをコントロールできる。

2. **記憶（Memory）: 材料と手順を覚えること**

   料理には多くの要素が絡んでいる。過去に作った料理の成功や失敗から学び、その経験を記憶することで、次の料理に活かすことができる。

3. **反復（Repetition）: 同じ料理を何度も作ること**

   料理のスキルを向上させるには、同じ料理を何度も作る必要がある。同じメニューを繰り返し作ることで、手順や調理時間を覚え、よりスムーズに料理することができる。

ここで、大切なのは記憶と反復は無意識下で行われるということ。
つまり、理解は意識的に行う必要があり、もっとも時間のかかる工程である。

## 理解とは 
[参考文献](https://learn-tern.com/understanding-6aspects/)

理解とは6つの側面から成り立つといわれている

1.説明できる
関係性に注目し、体系化された説明ができる

2.解釈できる
抽象的な理解を自分の話・作り話で具体化できる

3.応用できる
多様な文脈で応用できる

4.パースペクティブを持てる
批判的に複数の視点から考えられる

5.共感できる
経験とそれに伴う感情が大切である

6.自己認識
理解しようとしている自分に対する理解

このうちコーディングに必要なのは1・2・3だろう。
これらができれば、コードを理解している状態になると思われる。

## 具体的に何をするのか

1.複雑なコードを簡単なものに分解する

2.簡単なものを体系化されたもので学び・実装する

3.図や作り話を用いて説明する

4.再度組み立てる
Pythonで決定木分析して可視化してみる

# 背景
あるcsvデータを決定木で可視化したくなったのでやってみる by python

# まずはChatGPTに聞いてみる

俺: *python x google colabでcsvデータを決定木で可視化したい。手順教えて。*

ChatGPT: *Python で CSV データを読み込み、決定木で可視化するためには、pandas ライブラリでデータを読み込み、scikit-learn ライブラリで決定木モデルを構築し、matplotlib および graphviz を使って可視化するのが一般的です。 ~略~*

# 前処理
- 数値型以外のデータは受け付けなかったので事前に取り除きました

# 実装

```python
# 必要なライブラリのインポート
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier, export_graphviz
from sklearn.metrics import accuracy_score
import graphviz

# /content/hoge.csv ファイルの読み込み
df = pd.read_csv('/content/hoge.csv')

# ターゲット変数と特徴量を指定 (ここでは 'target' 列をターゲットと仮定)
X = df.drop('target', axis=1)  # 'target' 列を除外
y = df['target']  # 'target' 列
X.fillna(0, inplace=True) # Nanがあるとエラーになるので0にする

# データを訓練セットとテストセットに分割
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 決定木モデルの構築
clf = DecisionTreeClassifier(random_state=42)
clf.fit(X_train, y_train)

# テストデータでの予測と精度の評価
y_pred = clf.predict(X_test)
print("Accuracy:", accuracy_score(y_test, y_pred))

# 決定木の可視化
dot_data = export_graphviz(clf, out_file=None, 
                           feature_names=X.columns,  
                           class_names=str(clf.classes_),
                           filled=True, rounded=True,  
                           special_characters=True)  
graph = graphviz.Source(dot_data)  
graph.render("/content/decision_tree")  # PDF ファイルとして保存
graph  # Jupyter Notebook または Colab で直接表示
```

簡単！
Hello Wordからの復習 ～static編～

##### お品書き
+ staticって？
+ static変数、staticメソッド
+ 使いどころは？
+ 

---

◆staticって？
-
staticを使わないパターン。
カウンター変数を設定し入力された人数は？

まずはひとつみてみよう。

```java:java
class Student4{
  String name;
  int counter = 0;

  Student4(String n){
    name = n;
    counter++;
    System.out.println(name + "さんをインスタンス化しました");
  }
  void display(){
    System.out.println(counter + "人です");
  }
}

```

```java:java
class StuSample4{
  public static void main(String[] args){
    Student4 stu1 = new Student4("大輔");
    stu1.display();

    Student4 stu2 = new Student4("湊丞");
    stu2.display();
  }
}

```

```cmd:cmd
C:\Java\1>java StuSample4
大輔さんをインスタンス化しました
1人です
湊丞さんをインスタンス化しました
1人です

C:\Java\1>
```

お分かりだろうか。。

staticキーワードを使っていないため、生成した変数領域にそれぞれメモリが作られ、それぞれ表示している。

なので、人数はバラバラで集計されません。

```mermaid
classDiagram
    direction RL
    counter <|-- stu1
    class counter{
    +0（初期値）↓
    +1(インクリメント後)
    }
```

```mermaid
classDiagram
    direction RL
    counter <|-- stu2
    class counter{
    +0（初期値）↓
    +1(インクリメント後)
    }
```

counterでインスタンスの個数を取っておきたいが、
0が1に変わる、また0が1に変わるという処理が続くだけなので、何個インスタンスを作っても1という値しか入らないという結果。

インスタンスの個数を取っておくには、このインスタンスの中では**無理**

じゃぁどうしよう。
インスタンスがみんな一緒に**共通して**使える変数があれば良いという話。


```mermaid
classDiagram
    direction RL
    counter_stu2 <|-- stu2
    class counter_stu2{

    }

    counter_stu1 <|-- stu1
    class counter_stu1{

    }
    class Counter{
    +0（初期値）
    +1(++)..
    }
      Counter <|-- "共通で参照"counter_stu1
      Counter <|-- "共通で参照"counter_stu2
```

◆static変数、staticメソッド
-
staticのついた変数や、メソッドのこと
つけ方は変数の型の前、メソッドは戻り値の前。

全インスタンス変数が使えるメンバー変数やメソッドを定義するには**static**を指定する。

オブジェクトを生成していなくても利用できる。
→クラス名.変数[メソッド]名と記述


```mermaid
stateDiagram-v2
    Studentクラス
    state Studentクラス {
        stu1-->name[]
        stu2-->name[_]
        counter[]
        display()
    }
    
```
インスタンスが持っている変数を使いたいときは
stu1.nameやstu2.name等と記述
インスタンスの外のstatic変数やstaticメソッドの`counter`や`display`をつかいたいときは
`Student.counter`や`Student.display`と記述する。


◆使いどころは？
-
●全部のインスタンスから共通して使う変数やメソッドを作りたいとき。

●クラスの関連する便利なメソッドをまとめたいというようなとき

例えば、`Integer.parseInt()`という処理文があったが、Integerとは「整数」という意味なんだけど、Integerクラスというもともと提供されているものがあって、そのなかに、parseIntメソッドなど整数に関するint型に関するメソッドがまとめられている。
それをクラス名.Integer.parseIntと呼び出して使っていた。
なので、クラスの情報をオブジェクトを作らずに呼び出したい、そんなメソッドをまとめたいというときに良くstaticメソッドが使われる。


◆static Sample
-
```java:java
class Student4{
  String name;
  static int counter = 0;

  Student4(String n){
    name = n;
    counter++;
    System.out.println(name + "さんをインスタンス化しました");
  }
  static void display(){
    System.out.println(counter + "人です");
  }
}

```

```java:java
class StuSample4{
  public static void main(String[] args){
    Student4.display();
    
    Student4 stu1 = new Student4("大輔");
    Student4.display();

    Student4 stu2 = new Student4("湊丞");
    Student4.display();
  }
}

```

```cmd:cmd
C:\Java\1>java StuSample4
0人です
大輔さんをインスタンス化しました
1人です
湊丞さんをインスタンス化しました
2人です

C:\Java\1>
```

最初とは違い、ちゃんと人数がまとまりました。
ファイアウォール

```
iptables -F
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
iptables -A INPUT -s 192.168.0.137 -j ACCEPT
iptables -A OUTPUT -d 192.168.0.137 -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
```
DNS ゾーンファイル設定　OCN とりあえず、表示テンプレ

### ■OCN ゾーンファイル テンプレ

``` zone.txt
$TTL	86400
@			IN	SOA	ns6-tk01.ocn.ad.jp.	root.ocn.ad.jp.	(
11111
86400
3600
604800
1200
)
			IN	NS	ns6-tk01.ocn.ad.jp. ; OCN DNS のプライマリー
			IN	NS	ns6-tk02.ocn.ad.jp. ; OCN DNS のセカンダリー
			IN	A	155.777.77.777 ; グローバル IP 値は適当な IPです。
www			IN	A	155.777.77.777 ; グローバル IP www は NAMEへ入力
192			IN	PTR	dokuzi-domain.jp. ; 逆引きのためのPTRレコード へ独自ドメインを入力
```