OmniAICreator/Qiita-1.07M huggingface dataset:
Djangoのテンプレートでデバッグモードかどうかを判断させる

# デバッグ判断させるプログラムを作成
アプリケーションディレクトリに、`custom_context.py`を作成する。
```python:app/custom_context.py
from django.conf import settings

# HTMLテンプレートでデバッグ判断させられるようにする
def is_debug(request):
    return {"DEBUG": settings.DEBUG}
```

# 設定を追加
コンフィグディレクトリの`settings.py`のテンプレート設定部分を編集する。
```python:config/settings.py
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            BASE_DIR / 'templates'
        ],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
                'base.custom_context.is_debug',    # app/custom_context.py
            ],
        },
    },
]
```

# 使い方
settings.pyに記述されているDEBUGの値がHTMLテンプレートに渡されてくる。
これでテンプレートファイルでデバッグモードかどうか判断できるようになった。
```html:template_name.html
{% if DEBUG %}
<!-- This is template_name.html -->
{% endif %}
```

テンプレートに渡した値を表示しても良いし、ログインしているユーザー名を表示させてもいい。応用次第で色々と使えます。

`custom_context.py`は、すべてのHTMLテンプレートに同じデータを渡すことができるので、こちらも応用が効くと思います。
【Android】M1 Macでadbコマンドのパスを通してapkファイルをAndroid端末へインストールする方法

# 前提
- Android studioセットアップ済み
# 環境
- Mac M1 OS Monterey12.6
- Android12(実機)
- Android Studio Chipmunk | 2021.2.1 Patch 2

# 「Android SDK Location」に表示されるパスを確認
Android studioの環境設定(Preferences)`command + ,`を開き、 System Settingsを開いてAndroid SDKで**Android SDK Location**を確認する。
デフォルトだと下記のようになっている。
```
/Users/ユーザ名/Library/Android/sdk
```
![スクリーンショット 2022-12-18 15.12.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2604036/2ff51c90-9b03-bd88-d083-777ba0a6bb1f.png)

# Macのデフォルトのシェル環境が「zsh」と「bash」どちらか確認
ターミナルを開き`echo $SHELL`とコマンドを入力し、`/bin/〇〇〇`と出力されるのでどちらか確認。
ターミナルを開いた時のタイトルにも表示されているので、そちらでも確認できます。

# シェルに応じた設定ファイルが、すでに存在するか確認
ターミナルで`cd ~`  と入力しホームディレクトリに戻り、`ls -a`でファイルの一覧を確認。
zshの場合、ここで.zshrcが表示されなければ、`touch .zshrc`で作成、`open ~/.zshrc`で開く。
bashの場合は.bash_profileがなければ`touch .bash_profile`で作成、`open ~/.bash_profile`
で開く。
開いたら以下の内容を記述、Android SDK Locationの場所は先ほどの手順で確認したものを入力する。
```
export PATH=$PATH:<Android SDK Locationの場所>/platform-tools
```
デフォルトであれば、下記のようになる。
```
export PATH=$PATH:/Users/ユーザ名/Library/Android/sdk/platform-tools
```
最後にzshの方は`source ~/.zshrc`、bashの方は`source ~/.bash_profile`とコマンドを入力し、変更したパス（Path）と環境変数を反映する。
これで`adb`コマンドが使用できるようになりました。試しに`adb`とコマンドを入力してみましょう。
色々表示されるはずですが、`command not found`と表示されてしまう方はもう一度手順を確認しましょう。

# 実機との接続を確認
MacとAndroidをケーブルで接続し、端末側で接続の許可を行い、`adb devices`と入力してみましょう。
```
List of devices attached
xxx(デバイス名) device
```
と表示されれば接続完了です。

# apkファイルを端末にインストール
pathの入力がめんどくさい時はfinderからapkファイルをターミナルにドラッグ&ドロップするとpathが入力されるので便利。
```
adb install {apkを保存しているpath}
```
インストール後、下記の表示がされれば成功です。
```
Performing Streamed Install
Success
```
既に同じアプリがダウンロードされている場合はエラーが出ることが多いので一度アンインストールしてもう一度実行すると成功しやすいです。

# 参考になったサイト

https://sp7pc.com/google/android/17843#toc9
バグ除けの神様にお参りしてきた件


この記事は [Unityゲーム開発者ギルド2 Advent Calendar 2022](https://adventar.org/calendars/7638) 12月17日の記事(飛び入り参加)です。

# 引っ越しました
　フルリモートの会社に転職してから仕事部屋が欲しいと思っていたのですが、1年半以上を経てからようやく引っ越しました。
　で、引越した先の近所にどうもエンジニアにご利益がありそうな神社があるようなので、ちょいと散歩がてらお参りしてきました。

# バグ除け？
　[三宅八幡宮](https://www.miyake-hachiman.com/)
　こちらでございます。子供に関するご利益の他に『虫退治の神様 として「害虫駆除」 などの御利益で知られ、通称 「虫八幡さん」（むしはちまん）とも呼ばれて親しまれて』いるそうです。
　グレース・ホッパーが不具合を起こしたHarvard Mark IIの中に蛾を発見して以来、我々エンジニアにとってバグは不倶戴天の敵です。この小さな虫がアリアン５を爆発させ、みずほ銀行の信頼は地を超えマントルまで落ち、ガンジーに核攻撃までさせたのでしょう。唾棄すべき存在です。一刻も早くお祓いに行きましょう。

# アクセス
　京都市街北部にあります。叡山電鉄八幡前駅から徒歩5分。地下鉄国際会館駅からでも15分と歩けなくもない。駐車場もあります。

# 様子

### 参道
![参道](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439286/e35fbea7-b8ac-9617-b1ff-89396a178be5.jpeg)

### 鳥
![鳥](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439286/002cab54-03c1-b921-4d8f-890de440a6c7.jpeg)

### 噴水？
![噴水？](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439286/98ca5f79-d72e-4b3d-b67a-8af38caefa38.jpeg)

### 本殿
![本殿](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439286/d3ae7023-04f0-6fc5-5740-5cbb07ad31cc.jpeg)

### 境内にある茶店「ポッポ」
冷えた体に生姜の効いた甘酒が美味しい。砂糖を使っていないのだとか。
![P_20221218_144201.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439286/efce8011-512c-542f-1318-4ca899c73f66.jpeg)
プログラミングの勉強に困った時の対処法

プログラミングを学習し始めると、必ず壁にぶつかります。
* 環境構築が分からない。
* 作るたびにエラーが起こる。
* CSSを書いているのに、スタイルが当たらない。

エラーが解決できない時は、モチベーションも下がります。
私もずっと独学で勉強していたので、エラーが起こるたびにモチベーションが下がったものです。

今回は、プログラミングの学習で困った時の対処法をまとめています。

## プログラミングの勉強に困った時の対処法

### 先生を作る
**プログラミングの学習の難しいところは、分からないことが多いことです。**
分からないことが続くと、楽しくなくなるのは誰でも同じです。

そういう時に、教えてくれる人がいると壁を乗り越えやすいです。
多くの職場で、メンターや師匠のようなポジションの人を作ったりします。

独学でやっていると、どうしても難しいところです。
当時は、理解するまでドットインストールを何回も再生しました。

独学の場合は、ある程度まで覚えたら就職して実際の実務で磨いていくのもありです。

### 解決するまで試す
エラー、理解できないことにぶつかった時は、一度は自分で解決できるか試します。
試しているうちに、エラーの解決方法今まで出来なかったことが出来るようになります。

幸い、2022年現在は、Google検索すれば、ある程度のエラーであれば解決策が見つかります。
テラテイルやスタックオーバーフロー、Qiitaで検索してみましょう。

また、最初の頃は、メソッドの使い方を間違えていたり、勘違いしていることも多いです。
**プログラミングスクールのサイトや個人ブログも検索でヒットしますが、公式のマニュアルを読むのがオススメです。**
公式に書いていることを”そのまま”試して解決することは、よくあります。

https://www.php.net/manual/ja/index.php


### 次の日に試す
今日わからないことが、翌日になると分かることがあります。
これはプログラミングに限った話ではありません。
**人間の脳みそは、不思議なもので睡眠を取ったり、他のことをしていると全然関係ないものの理解が深まったりします。**

プログラミングは、「覚えること」と「考えること」が多いです。
そのため、よりよく動くように脳みそをしっかり休めることです。

### さいごに
まとめると

:::note
先生を作る
解決するまで試す
次の日に試す
:::

最初のうちは、学習のハードルが高いですが、ある程度までプログラミングへの耐性ができると、スムーズにできるようになります。
プログラミングにエラーは付き物なので（笑）

https://dotinstall.com/
【Unity】円内の格子点を返す関数

# 概要
![gif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307985/28a5ea66-dbb3-a157-2d7f-a9afe7c9ad0f.gif)
円内の格子点をVector2[]で返す関数を作りました。左下を0にする引数もあります。
円内の判定に自信が無いのでコメントを頂けると助かります（```if (x * x + sqrY - sqrRadius <= -0.5f)```）。

# コード
お手持ちの MathUtil クラスに追加してご利用ください。

``` 円内の格子点を返す関数.cs
public static List<Vector2> GridPointsInCircle(int diameter, bool bottomLeftCenter)
{
    if (!bottomLeftCenter) return GridPointsInCircle(diameter);
    var list = GridPointsInCircle(diameter);
    var offset = Vector2.one * (diameter * 0.5f - 0.5f);
    for (int i = list.Count - 1; i >= 0; i--) list[i] += offset;
    return list;
}
public static List<Vector2> GridPointsInCircle(int diameter)
{
    if (diameter <= 1)
    {
        if (diameter == 0) return new List<Vector2>();
        return new List<Vector2>() { Vector2.zero };
    }

    var odd = diameter % 2 == 1 ? 0.5f : 0f;
    var radius = diameter * 0.5f;
    var sqrRadius = radius * radius;
    var list = new List<Vector2>();
    var prevX = radius + 0.5f;

    for (var y = 0.5f + odd; y <= radius; y += 1f)
    {
        var sqrY = y * y;
        for (var x = prevX; x >= 0; x -= 1f)
        {
            if (x * x + sqrY - sqrRadius <= -0.5f)
            {
                for (float i = x; i >= -x; i -= 1f)
                {
                    list.Add(new Vector2(i, y));
                    list.Add(new Vector2(i, -y));
                }
                prevX = x;
                break;
            }
        }
    }

    if (odd == 0.5f) for (float x = radius - odd; x >= -radius; x -= 1f) list.Add(new Vector2(x, 0f));
    return list;
}
```
レスポンシブ対応について

# レスポンシブ対応とは
スマホ、PC、タブレットなどデバイスにより画面幅が異なります。
それぞれのレイアウトに対応を変えることをレスポンシブ対応と言います。

# はじめに
事前の準備と、それぞれのブレークポイントを確認します。

## ブレークポイントを確認
今回はPC・タブレット・スマホの3つのレイアウトに対応させるため、それぞれの画面幅（ブレークポイント）を確認します。
タブレット：1024以下
スマホ：599以下

## 事前準備
HTMLファイルに以下記述をします。



```ruby
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
```
# CSSファイルに記述
@media (max-width: 599px) {  } 内に各デバイスで対応したいレイアウトの記述をしていきます。

```ruby
/* タブレット表示時 */
@media (max-width: 1024px) {

}

/* スマホ表示時 */
@media (max-width: 599px) {

 }
```

# 検証ツールで確認
検証ツールを立ち上げ、「Responsive」を選択し、横幅を変更し、実装確認します。

無事に実装できていたら完了！
えっ！？　御社のSSL費高いかも！？

この記事は、[ConoHa Advent Calendar2022](https://qiita.com/advent-calendar/2022/conoha)の19日目の記事です。
こんにちは、19日目担当の[Susumu@susumu_taka](https://twitter.com/susumu_taka)です。

最近、問い合わせで微妙に増えているのが **「ドメインのビックリマーク問題」** です。

↓コレですね
![nossl.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100025/eb8cf25d-f5b2-1e44-31ae-89a8dfc30e2e.png)

このビックリマークはSSLを取得し、Webサーバーに設定する事で鍵マークに変更され、俗に言うセキュアな接続（暗号化されたHTTPS通信）となります。

↓コレですね
![sslyes.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100025/e2a5d955-5d19-36e3-cc29-69be17e8c90d.jpeg)


# SSLは高い？
実際に私のお客様が、**「SSL無いHPの問い合わせなんか、怖くて誰も使わんよ！」** と取引先から言われ、Wordpressで作成した企業サイトにSSL導入されたそうです。

その時の費用です。

某レンサバのSSL導入費
　〇SSL年間費：38,280円（月額3,190円）
　〇固定IP費用：13,200円（月額1,100円）
　※グローバルサインのクイックSSL（ドメイン認証）であった為、作業費は発生せず

SSLを維持するだけで、**年間51,480円の負担増** となり、そこに**レンサバ費22,440円（月額1,870円）** が乗ってきます
グローバルサインのクイックSSLで無ければ、更に**作業費27,500円**が上乗せとなるそうな・・・

しかも・・・
帝国データバンクコード、TSRコード、登記簿謄本などが必要となり、かなり手間もかかったとの事

**「SSL費用は高い！」** って聞いたり、言われてたようですが。。。

# 御社！ ConoHaに変えちゃいなYO！！
**「SSL化どうしよう？？？」** と相談された場合、特段の条件が無い限り **「WebサーバーをConoHaに変えちゃいなよ！」** と言ってます。

何故かって？

**独自ドメインでのSSL費用が0円で運用出来るオプションがあるから！**

そうなんです！！
**ConoHa WINGでは高いSSL費用を浮かせる事が出来るんです**
↓
**[ご利用ガイド無料独自SSLを設定する](https://support.conoha.jp/w/letsencrypt/)**


手間と言えば、Webサイトの引っ越しですが、**Wordpressならば[ConoHaに丸ごとお願いする](https://www.conoha.jp/wing/wpmigration/?btn_id=wing-pricing--specs_wing-wpmigration)事も可能**です！
※国外サーバー、wordpress.comで公開してるサイトは非対応

**当然、ConoHaでもグローバルサイン社が提供するSSL証明を取る事も出来ます。**
「しっかりした証明が必要なんだ！」という企業さんにも安心！
![ssl.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100025/7ffd65df-9efc-455b-a488-00545d65dc7d.jpeg)
クイック認証、ConoHaの方が安いな・・・

Wordpressの移行であれば、[ConoHa WING](https://www.conoha.jp/wing/?btn_id=wing-top--wingHeader_wing-top)がオススメですね
なんせ早いのよ・・・

# どれだけ安くなるか比較
前段のSSL導入事例が **「ConoHa WINGに載せ替え」** だった場合で費用を比較してみましょう！

**「社内にWebサーバー触れるスキル持った社員がいない！」という設定です。**
**こういう企業さんが絶対的に多いハズ・・・！**

Webサーバー引っ越しは、社内に専門家がいないので[ConoHaのWordPress移行代行](https://www.conoha.jp/wing/wpmigration/?btn_id=wing-top--wordpress_wing-wpmigration)をお願いしたという事にします。また、SSLの設定も引っ越しの時にお願いしてしまう事にします。

**全部おまかせコースです**

※グローバルサインのSSL使わず、無償オプション使えばSSL設定費用いらない？
　教えて[ConoHaちゃん](https://twitter.com/MikumoConoHa)！






![費用.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100025/bc0e5a00-a015-1696-fade-0880899ce73b.jpeg)



**年間のSSL費用はかからない**やら、**サーバー費は下がる**やらで良い事づくしですよ！
しかも、[ConoHa WINGパック](https://www.conoha.jp/wing/pricing/?btn_id=wing-top--wingHeader_wing-pricing)なら、**サーバーのレスポンス改善も見込める**という
まさに**一石３鳥！**



### 業務改善提案出したいけどネタないなぁ・・・ とお悩みの社員のあなた！
### SSL対応含めたWebサーバー見直し提案なんていかがですか？


## 余談
ちなみに、[某ロリ〇おじさん](https://mobile.twitter.com/lolipo_ojisan)とこでも**独自ドメインで無償SSL運用出来たりします。**
まぁ、でも・・・
そもそも、ConoHa Advent Calendarだし
向こうはおじさんだし
このはちゃん、清楚可愛いし
~~でも、こっちもオッs・・・~~　いや、何でもない
②電子帳簿保存法に対応するアプリをノーコード Appsheetとタイムスタンプ認証局STIIさんを使って作ってみた

# ②電子帳簿保存法に対応するアプリをノーコード Appsheetとタイムスタンプ認証局STIIさんを使って作ってみた


[①電子帳簿保存法に対応するアプリをノーコード Appsheetとタイムスタンプ認証局STIIさんを使って作ってみた](https://qiita.com/shawnseo/items/21048164cbb8d9c32deb)の続きです

### 4.5. Tableの属性設定
先日の投稿通り、Spreadsheetが順調にインポートされたら下記のようなTableができているはず、

![Image- 2022-12-16 at 14.16.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236263/204a5311-5bd2-57aa-0878-5619ce7bf9e5.png)

ここから少し属性を設定していく

#### 4.5.1. CategoryのTable

このテーブルはそのままで良くて

![Image- 2022-12-16 at 14.18.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236263/1e54df9e-fb82-868d-49ce-caebc8152b8e.png)

#### 4.5.2. DocumentsのTable
次はDocumentsのTableで下記のような設定をしておく
- Idは追加するダータが自動的に番号を振られて欲しいので、FORMULAのところ、 =[_RowNumber] に設定、ユーザーが触る事はないのでSHOWのところは OFFに設定
- Datetimeは自動的に写真スキャンする時間を記録して欲しいので、FORMULAのところ、=NOW()　に設定
- Categoryは事前に作ったCategoryのTableを参照して表示して欲しいので、TYPEをRefを選択して、ダイアログからSource tableをCategoryを参照。
- Photoの場合、TYPEをImageにする
![Image- 2022-12-16 at 14.26.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236263/8aee3169-c515-daaa-6ce9-b23d5e836bed.png)


全体的にこんな感じになるように設定を行う
![Image- 2022-12-16 at 14.27.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236263/619647ab-9164-ec5d-f44d-ec9e3aaa9912.png)

#### 4.5.3. MenuのTable

- Idは見せる必要がないので、SHOWをOFF
- Viewも同じくSHOWをOFF

![Image- 2022-12-16 at 14.38.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236263/13566578-3bd7-63b3-ca47-e882713219b7.png)

これでテーブルの設定は完了

### 4.6. Actionを作成
テーブルの設定が終わったら今度はMenuを押した時、DocumentsのForm画面に移りたいので
新しいActionを追加したい。

左メニューのAppでNew Actionを押して新しいActionを作る

![Image- 2022-12-18 at 14.56.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236263/c3498ec7-62ca-0185-d96f-e6693b6283bd.png)

そしてそれぞれの欄に下記のように設定しておく
- Action name : Goto_Documents
- For a record of this table : Menu 
- Do this : App go to another view within this app ← アプリ内のViewに移動する時使う
- Target : LINKTOVIEW("Documents_Form")　← Viewの名前


そしてMenu画面のメインハンドラーを作って、先のGoto_Documentsを追加したいので
また、左メニューのAppでNew Actionを押して新しいActionを作って

![Image- 2022-12-18 at 15.00.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236263/062b0d23-2c18-f1fc-6e3d-8e2e7eb1150f.png)

ここもそれぞれの欄を下記のように設定
- Action name : Main_Handler
- For a record of this table : Menu 
- Do this : Grouped execute a sequence of actions  ← これは色んなActionのグループ作る時使うらしい
- Actions : Goto_Documents　← 先のActionを追加しとく


今作ったメインのハンドラーの指定は、Viewsのところでしないといけないので
左メニューのAppからMenuのViewに移動して、BehaviorのところにEvent Actions(Row Selected)で事前に作ったMain Handlerを選択する

![Image- 2022-12-18 at 15.05.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236263/b94d15a6-33b5-e0b0-be4a-e93262e06547.png)

そして、ちゃんと右上のSAVEボタンを押して今までの作業を保存する

そうすることによって、「写真スキャン」Menuを押した時にDocumentを登録する画面に移ることが可能

![Image- 2022-12-18 at 15.34.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236263/9a3eb486-44b4-063e-faae-ed918d36aeda.png)


メニューを押してちゃんとDocumentsの登録Formに移ってれば良し


これでアプリの操作のところActionの作成は完了です。


あとはBotを作ったり、メールをSTIIさんに飛ばしたりする作業が残っているが
それは次のステップは連載される「③電子帳簿保存法に対応するアプリをノーコード Appsheetとタイムスタンプ認証局STIIさんを使って作ってみた」を参考まで。。。
【フロントエンド】GraphQLを導入する時はFragmentを理解しよう

## はじめに

GraphQLを用いたフロントエンド開発は多くなってきているように思います。
フロントエンドから柔軟にデータを取ってくることができるということは、今までバックエンドが担保してきていた部分をフロントエンドが担わないといけなくなった

ということを意味します。
保守性をちゃんと考えないといけない。

ということですね。

今回は、Fragmentについての話

## Fragmentとは？

GraphQLにおけるFragmentとは複雑なクエリを小さくまとめ上げるために生み出されました。

これはとてもComponentの概念に似ていますね。
僕たちはComponentという小さな単位に分割し、それを組み合わせることで複雑なアプリケーションを構築しています。

これと同じです。
**データをFragmentという小さな単位に分割し、複雑なクエリを役割ごとに分割してやろう**。
という話です。

## どうやって実現する？

親コンポーネントで子コンポーネントを呼び出すのと同じように、親のクエリで子のfragmentを呼び出します。

```graphql:fragment.ts
fragment UserFragment on User {
  name
  age
  profile_picture(scale: 2) {
    uri
  }
}
```

```graphql:query.ts
query UserQuery($id: ID!) {
  user(id: $id) {
    id
    name
    ...UserFragment
  }
}
```

こんな感じにUserFragmentという共通化を行います。

ただ、このように共通化をおこなっていくと、問題が発生してきます。
みなさんも知っているように、共通化というのは保守性を上げる時もあれば、下げる時もあります。

下手に共通化をおこなっていくと、「オーバーフェッチ」を招いてしまうんです。

## Fragmentによるオーバーフェッチとは

Fragmentを使うことでクエリの一部を共通化することができます。

ここで発生してしまうのはFragmentの乱用です。
ユーザーの情報を全て取得してくるUserDetailFragmentをユーザー一覧のページでも利用してしまう。

こういうことが発生してしまいます。

:::note warn
今回はオーバーフェッチについて取り上げましたが、TypeScriptを用いていない場合、型エラーが発生せず、アンダーフェッチ（必要な値が足りない）みたいなことも発生しうるかと思います。
:::

そこで生まれたのがFragment Colocationという概念です。

## Fragment Colocationとは？

Colocationというのは一緒の場所において管理する。
みたいな意味合いを持っています。

何と一緒において管理するのかというと、コンポーネントです。

データを欲するコンポーネントに、そのコンポーネントが欲しいだけのデータを一緒にFragmentとして書きましょう。

と言う話です。

```tsx:UserDetail.tsx
import type {UserComponent_user$key} from 'UserComponent_user.graphql';

const React = require('React');

const {graphql, useFragment} = require('react-relay');

type Props = {
  user: UserComponent_user$key,
};

function UserDetail(props: Props) {
  const data = useFragment(
    graphql`
      fragment UserComponent_user on User {
        name
        profile_picture(scale: 2) {
          uri
        }
      }
    `,
    props.user,
  );

  return (
    <>
      <h1>{data.name}</h1>
      <div>
        <img src={data.profile_picture?.uri} />
      </div>
    </>
  );
}

module.exports = UserComponent;
```

このように、コンポーネントと一対一でFragmentを定義することで、下手に共通化されることを防ごうという概念です。

:::note
Fragment Colocationと呼ばれることが多いですが、GraphQLの公式ガイドにもRelayの公式ガイドにもColocationという言葉は載っていない気がします。
正確な呼び名はあまりないのかもしれません。
:::

## まとめ

最後までご覧いただきありがとうございました。
今回はGraphQLを導入する上で必要になってくるFragmentという知識について書かせていただきました。
gnuplotでtxtではなくcsv,tsvを使う

## やり方

gnuplotを使うとき，たくさんの`txt`ファイルを作成してはいないでしょうか？
例えば，
```
plot "hoge.txt" u 1:2 with points lc "red", \
"aaa.txt" u 1:2 with lines lw 1
```
みたいな．
`txt`をメモ帳や秀丸で開こうにも，やはり表計算ソフトであるExcelから開けたほうが楽ではるでしょう．

そこで，Excelから開きやすい`csv`, `tsv`ファイルの使用を提案します．

といっても，要するに普段開いている`txt`をExcelで開くだけ．
拡張子をcsv, tsvに変えればOKです．
csvは`Comma Separated Value`．tsvは`Tab Separated Value`の略称です．tsvは聞き馴染みないかもだけど，データがカンマじゃなくてタブで区切られてるだけのテキストファイルです．

ちなみにgnuplotは通常時はタブでデータの列を見分けているので，普通に処理するには`tsv`を使えばいいかと思います．
ただし，`tsv`よりメジャーな`csv`を使いたいというあなた．
```
set datafile separator ","
```
を入れてやると，csvでも処理できそうです．

## カラム名について
データの1列目がなんの値だっけなぁってなりませんか？
きちんとカラム名を使えば，回避できる問題です．

すなわち，
```hoge.csv
data1,velocity,a
12,0.4,1
63,0.68,2
:,:,:
```
みたいなデータが合ったとして，
```
set datafile separator ","
plot hoge.csv u 1:2
```

とするのではなく，
```
set datafile separator ","
plot hoge.csv u "data1":"velocity"
```
みたいにするといいでしょう．

## 参考
https://gam0022.net/blog/2012/12/31/gnuplot-tips/
【所感】信号処理分野から見たデータサイエンスの難しさ


# はじめに
- [LIGTHzアドベントカレンダー 2022](https://qiita.com/advent-calendar/2022/lightz)の19日目の記事です。
- この記事は個人の感想です。
- この記事で触れる『データサイエンス』は、データの特徴量を分析し、特徴量の振る舞いを
把握するまでの一連の取り組みを指します。
- データサイエンスや機械学習モデリングの検討プロセスに対する、私個人の理解や自戒を
箇条書きにしています。
# 信号処理の基本的な設計プロセス
　・信号処理では、まず
　　　・路面と車両
　　　・大気と航行ロケット
　　　・観測/撮像と姿勢変更
　　　・加工材と工作機械
　　などの間で起きうるシステムと物理現象の相互作用のメカニズムを仮説します。
　・次に仮説されたメカニズムをモデルとして用い、シミュレーションを行い、モデルの出力から
　　相互作用で発生しうる物理事象の予測などを行います。
　・最後に予測した物理事象と実測された物理事象の突合せを行い、不整合やずれの要因を分析して
　　分析結果をモデルへ反映する事で、モデルの精度を向上させます。

# 信号処理エンジニアがデータサイエンスに取り組むモチベーション
　設計システムと自然現象の相互作用を理解する取り組みと理解しています。（＝相手のある仕事）

　・発生条件が別々の業務ドメインや技術ドメインに散在する性能課題に対し、
　　要因と中間事象の組合せを推定したい
　・発生メカニズムの複雑な性能課題に対し、要因候補を洗い出したい
　（『風が吹けば桶屋が儲かる』の様にイベント間の因果を見通しずらい時、
　　　要因候補の仮説を立てるために使いたい）
　・類似の相互作用と性能課題が起きうるユースケースへ、設計済みの信号処理システムを横展開したい

# 補足：　データ『サイエンス』というwordingに含まれるニュアンス
　・『サイエンス』は、『as is』（自然現象）の理解を目的としている
　・主体が自然現象なので、『to be』の概念は存在しない
　・要求の達成を目指す『エンジニアリング』とは目的意識や主体が異なる
|Science|↔|Engineering|
|:---|:---:|--:|
|long-term(長期)||short-term(短期)|
|idealism(理想的)||compromise(妥協的)|
|certainly(確実さ)||risk management(リスク管理)|
|perfection(完璧さ)||adequacy(適切さ)|
|generality(一般性)||specificity(特異性)|
|separation(分離)||amalgramation(融合)|
|unification(単一性)||diversity(多様性)|
|originality(独自性)||best practice(最善)|
|fomality(形式)||intuition(直観)|
|correctness(正確さ)||dependability(信頼性)|

(典拠：　Tony Hoare, man of Science
　http://drj11.files.wordpress.com/2009/07/tony_hoare_science_and_engineering.ppt)

# 信号処理分野でデータ『サイエンス』を扱う難しさ
- 信号処理と『モデル』の定義が違う
　　・信号処理でのモデルは、『入力を出力へ変換する処理のメカニズム』を指す
　　・データサイエンスでのモデルは、『統計に従い分析対象データを分類する分類基準』
　　（＝特徴量の振る舞い＝統計モデル）を指す
　　（※参考：　要求工学におけるモデルは『やりたい事を実現するための機能の組合せ』を指す）
- 特徴量の振る舞いを把握するまで、モデル仮説構築やデータ分類方法の決定ができない
（＝データドリブン）
- 特徴量の振る舞いを把握するまで、データ分類結果の使い方を決める事もできない
- ゆえに、値域や定義域を合目的に切り出す事が困難である
（いわゆる『やってみないと分からない』）
- 因果関係は特徴量の振る舞いから直接的に識別されるのではなく、
相関関係に対するベイズ推論などの適用で間接的に推定される
- 統計に基づく推論よりドメイン知識に基づく因果関係の推論を用いた方がいい結果
の出る場合もあるため、注意が必要である

# 特徴量の振る舞いとはデータの分類基準の事
- 設計者は、
『入力データ（分類対象）』、『出力データ（分類結果）』、『統計モデルの種類（分類手段）』
を設定する事（＝教師データの設定）により、『間接的に』特徴量の振る舞い、
すなわち分類基準を設計する事ができる
- システムの外部環境や運用条件が変動した時、『特徴量の振る舞い』も変わるため、
データの分類基準も変わる
- 設計者の持つデータの分類基準を説明できる『特徴量の振る舞い』が見つからない場合もあるため、
この場合は設計のアプローチを見直す必要がある
- 設計者は外部環境や運用条件の変動毎に、
　『入力データ（分類対象）』、『出力データ（分類結果）』、
『仮説される統計モデル（分類手段）』の組合せを調節する必要がある
# まとめ
- 信号処理とデータサイエンス（機械学習）とでは定義域や値域の決め方がかなり異なる（合目的か実体に合わせるスタイルか）
- データサイエンスでは定義域や値域を合目的に設定する前に、特徴量の振る舞いを把握する必要がある

# 今後の予定
　・特徴量の要件定義における実務課題と対策を取り上げていきます
　・実際の機械学習システムにおけるデータ分析事例を取り上げていきます
# 最後に
弊社では、自動車・機械産業のお客様に向けたソリューション開発エンジニアを絶賛採用中（2022/12時点）です :muscle: :muscle:
https://www.wantedly.com/projects/1181162
# 参考
- The Science of Computing and the Engineering of Software, Tony Hoare※, 1 July 2009
http://drj11.files.wordpress.com/2009/07/tony_hoare_science_and_engineering.ppt 
　※Tony Hoare：　クイックソートの考案者
- 深層学習技術と信号処理・通信系アルゴリズム―概観と展望―, 和田山 正
　https://www.ieice.org/ess/sita/forum/article/2018/201807311720.pdf
- ディープラーニング・機械学習のための信号処理(Matlab社youtube動画)
　https://www.youtube.com/watch?v=XG8lA_QlKgM
- 閉ループ制御システムに対する異常シナリオ分析のための情報検索, 小口 一浩
　https://www.juse.jp/sqip/symposium/2021/timetable/files/B2-2_ronbun.pdf
Elixirでつくりたいもの


## はじめに

[「プログラミング Elixir」](https://www.amazon.co.jp/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-Elixir-%E7%AC%AC2%E7%89%88-Dave-Thomas/dp/4274226379/ref=sr_1_1?crid=QYNU9WDH9C4N&keywords=elixir+%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0&qid=1671342236&sprefix=%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0+elixi%2Caps%2C490&sr=8-1)はひと通り読みました。（理解できたかはさておき）
何か手を動かしたいものの、特に作りたいものもなく、このあとどのようにelixirを勉強をしていこうか考えていました。

## 黃リー教
英語は昔から苦手科目なのですが、ここ数年で必要性を痛感することがあり、改めて勉強しないとなと思っていました。

そんな中、[「基本文法から学ぶ　英語リーディング教本」](https://www.amazon.co.jp/%E5%9F%BA%E6%9C%AC%E6%96%87%E6%B3%95%E3%81%8B%E3%82%89%E5%AD%A6%E3%81%B6-%E8%8B%B1%E8%AA%9E%E3%83%AA%E3%83%BC%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0%E6%95%99%E6%9C%AC-%E8%96%AC%E8%A2%8B-%E5%96%84%E9%83%8E-ebook/dp/B0B2VJ8BL5/ref=sr_1_1?crid=3H8CUWOBVY6SY&keywords=%E8%96%AC%E8%A2%8B%E5%96%84%E9%83%8E&qid=1671340598&sprefix=%E8%96%AC%E8%A2%8B%2Caps%2C584&sr=8-1)（通称：黃リー教）という本を見つけました。

「中学英語レベルのゼロの状態から始めて、難しい原書も確実に読めるようになる」という言葉につられました。
半信半疑でしたが、私にとっては一番分かりやすく納得できる本でした。

すごく簡単にいうと、F.o.R(Frame of Reference)という独自の体系をもとに「品詞と働きと活用の相互作用」を理解し活用できるようにしてくれる内容になっています。

「品詞と働きと活用の相互作用」を使って英文を理解していく過程は、英文の構造が徐々に決まっていくので、プログラムを構文解釈しているように感じられました。
英語が苦手なエンジニアには相性のいい勉強法な気がします。

ただ1つ困ったことは、F.o.Rの構造図を理解しようとすると紙に書く必要がありました。


![構造図サンプル](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385793/3b95b425-3eb5-7fd6-c664-806ae4e77f38.jpeg "構造図サンプル")

また添付画像のように修飾先の単語に矢印を引くので、英文の下にある程度空白が必要です。

## F.o.Rエディタ
作りたいものもなんて無かったのですが、このF.o.Rの構造図を記入できるエディタが欲しいなと思うようになりました。

これは Phoenix LiveView で実装してみるのがいいかもしれないと思いつきました。
今年は F.o.Rの習得に時間を使ったので、それを補完できるF.o.Rエディタの実装に取り組もうと思います。

#### 記号一覧
英文に対して、下のような記号を追記するのと、修飾-被修飾関係を矢印で表現したい。

| 記号 | 意味 |
|:-:|:-|
| S | 主語  |
| O | 目的語|
| C | 補語  |
| ① | 完全自動詞  |
| ② | 不完全自動詞  |
| ③ | 完全他動詞  |
| ④ | 授与動詞  |
| ⑤ | 不完全他動詞  |
| －③ | 完全他動詞の受身形  |
| －④ | 授与動詞の受身形  |
| －⑤ | 不完全他動詞の受身形  |
| n  | 名詞  |
| a  | 形容詞  |
| ad  | 副詞   |
| aux  | 副詞  |
| V  | 動詞  |
| +  | 等位接続詞  |
| 接  | 従属接続詞  |
| p.p.  | 過去分詞  |
| [  ]  | 名詞節  |
| (  )  | 形容詞節  |
| <  >  | 副詞節  |
|   | 準動詞  |
gnuplotで，ファイルのある位置にカレントディレクトリを移動する

カレントディレクトリを移動したいのは，参照したいファイルの絶対パスを取得するのが面倒くさいからと推察します．

そこで，以下を冒頭に書くことでカレントディレクトリが移動できます．

```move.gp
max(x,y)= ( (x) > (y) ) ? (x) : (y)
strstrlt_sub(str,index,target)=(strstrt(str[index:],target)==0 ? \
    max(index-strlen(target),0) : \
    strstrlt_sub(str, index-1+strstrt(str[index:],target)+strlen(target),target))
strstrlt(str,target)=strstrlt_sub(str,1,target)
dirname(path)=strstrt(path, "\\")!= 0 ? substr(path, 1, strstrlt(path,"\\")-1) : ""

cd dirname(ARG0)
```

ところで，そもそもカレントディレクトリを移動しなくても，`plt`ファイルを実行すれば，`plt`ファイルのあるディレクトリのファイルを相対パスで取得できます．
グラフを取得するだけなら，`plt`ファイルにて処理すると良いでしょう．

ただし，`stats`コマンドを使うなどして入力データに対する標準偏差や平均値を使いたいということがあるかもしれません．（というか，筆者がそれでした）
そういうときは，`gnuplot`を立ち上げて，上記の`move.gp`を書いた`gp`ファイルを`gnuplot`で実行すると良いでしょう．
※ PythonやFortranにおけるような，input関数的なやつが`gnuplot`にあるなら，それを使えばいいのですが…探しても見つけられなかったので．

## 他にできそうなこと
釈迦に説法かとは存じますが，参考先のページにて，ファイル名の取得も紹介されています．
すなわち，`plt`ファイルや`gp`ファイルと同じ名前の`eps`ファイルを作成する，という処理も，いちいち書き換えなくてもできそうです．

## 参考
https://qiita.com/u1and0/items/222038aca388680595a2#%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E3%83%91%E3%82%B9
Go ファイル分割

## 初めに
ファイルを分けて管理したい
Nodeみたいに `const hoge = require("hoge")`すればよいだけではないらしい
備忘録として残しておく


## 同一package(同じディレクトリ)で分ける
```go:main.go
package main

func main() {
	// 同一packageなのでimportが必要ない
	Bar()
}
```
```go:bar.go
package main

import (
	"fmt"
)

func Bar() { // 外部ファイルで使用する場合、頭文字は大文字
	fmt.Println("bar")
}
```
```shell
# go.modがある場合
# runやbuild時に全てのmain packageを指定する
go run main.go bar.go

# go.modがある場合
go run .
```


## 別package(ディレクトリ)に分ける
*go.modが必要*
***`go mod init go_test`***
```
go_test
  - main.go
  bar
    - bar.go
```

```go
package main
// bar.goまでのpath
// go mod initで決めたmodule名から始める
import "go_test/bar" 

fun main() {
  bar.Bar() // package名.関数名
}
```
```go:bar/bar.go
package bar // DirNameと同じにする

import "fmt"

func Bar() { // public(大文字始め)関数にする
	fmt.Println("bar")
}
```

## 終わりに
`go mod init [module名]` module名が結構大事だと思うのですが、githubに上げない時はiとか適当な名前にしちゃいます。
あとからgithubに上げようと心変わりしたら変更がめんどくさそうですね・・・


## 参考

https://zenn.dev/fm_radio/articles/ca2ff1dfcf89b5
AtCoderの検証用プログラムをPythonで自作した(subprocess版)

AtCoderってinput()で入力を受け取って、print()で結果を出力しているので
- 標準入力をファイルにして
- 標準出力をio.StringIOにすれば

検証用プログラム自作できるよね、ってことで、ちょっと雑なプログラムですが作ってみました。


# 使い方
## 前提
- data/inXXX.txtに入力データ、data/outXXX.txtに正解データが出力されており、それらを検証に使用しています。(XXXは0埋め整数)
- Python 3.9.15 で動作確認しています(macOS Monterey)

## コマンド
```shell
python try2.py answer.py
```
- 検証用プログラム(try2.py)に解答プログラム(answer.py)のpathを指定して実行します
- 全部正解だと最後に'AC'と出力します。不正解の場合は'WA'です。

# try2.py
- 日本語の正規化にneologdn使ってます(AtCoderなら要らないはず）

## というわけでソースはコチラ(try2.py)

```python
import glob
import sys, os
import io
import neologdn
import subprocess

def try_all(exec_python_path):
    in_path_all = sorted(glob.glob("data/in*.txt"))
    error_count = 0
    for in_path1 in in_path_all:
        out_path1 = in_path1.replace("in","out")
        
        with open(in_path1,"r") as f_in:
            # 標準入力を file に、標準出力を io.StringIO に結びつけてsubprocessで実行する
            proc = subprocess.Popen(['python', exec_python_path], encoding='utf-8', stdin=f_in, stdout=subprocess.PIPE)
            stdout, stderr = proc.communicate()
            stdout_io = io.StringIO(stdout)
        
        with open(out_path1,"r") as f_out:
            all_output = f_out.readlines()

        all_temp = stdout_io.getvalue().split('\n')
        for out_str1 in all_output:
            stdout_str1 = neologdn.normalize(all_temp.pop(0)) # neologdnで正規化してから比較する
            out_str1 = neologdn.normalize(out_str1) # neologdnで正規化してから比較する
            if out_str1 != stdout_str1:
                print(f"Error! temp={stdout_str1}, answer={out_str1}, in_path={in_path1}")
                error_count += 1
            else:
                print(f"OK temp={stdout_str1}, answer={out_str1}")
                pass

    print("AC" if error_count == 0 else "WA")


if __name__ == "__main__":
    try_all(sys.argv[1])
```

## 徒然なる補足
- 日本語の正規化が不要な場合はそっくりそのまま取り外してください。
- 入力データと出力データは、先に正解のプログラムを作っておいて、ファイル出力しています。
- 途中で”Error”とか"OK"とかprint文で出していますが、邪魔なときはコメントアウトして使ってください。
- [AtCoderの検証用プログラムをPythonで自作した(雑)](https://qiita.com/yasubei/items/2c3ad8648db0ce6d48e6) のsubprocess版です。
説明が重複している部分はごめんなさい

## バッドなノウハウ
- 最初はNotebookでやろうと思ったんですが標準入力と標準出力を切り替えられなかったので断念しました。なので.pyファイルで作っています。
- subprocess.run()でstdoutにio.String()を渡すとエラーが出てちょっとハマりました。上記のようにPopen()とcommunicate()使うと解決できました。

# 感想
- ちょっと便利になりました。
- AtCoder用のテスト自動化ツール（コンテスト中も使えるやつ）はもっと高機能なものがあるので、本格的な利用にはそちらを使ってみることをおすすめします。[ここ](https://qiita.com/EngTks/items/a542c8f8585ca9e3f23f)とか。
DNS登録されていないサイトにDatadogのブラウザテストを実行する方法


# 何の話？

DNS登録していないサイト(例えばステージング環境とか)に対してブラウザテストをするときってないですか？
そういうときローカルの/etc/hostsファイルに

```:/etc/hosts
XX.XX.XX.XX  www.example.com
```
のようなエントリを追加してテストしたりすると思います。

これをDatadogのSyntheticsブラウザテストで実施したい場合、Hostヘッダを追加すればいいかと思ったんですが・・・
↓のようにHostを追加して、テストを実行すると、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3246/6cd48771-d6e8-ee48-cb7a-1bc5ed192c77.png)


Warningと表示されて、Hostヘッダが追加されません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3246/927235c3-5545-5d17-356a-0297e9c641fd.png)


サポートにも聞いてみたんですが、HostヘッダはForbidden header nameとして定義され、変更が禁止されているらしく、ブラウザテストでも変更できないそうです。

https://developer.mozilla.org/ja/docs/Glossary/Forbidden_header_name

(ちなみにAPIテストの方はHostヘッダの変更が可能でした)

# Workaround

こういう場合、プライベートロケーションをつくって、そこのhostsファイルを修正するというやりかたができます。

プライベートロケーションは、環境つくるのはちょっと面倒ですし、どこに置くとか考慮は必要ですが、設定自体は簡単です。

https://docs.datadoghq.com/ja/getting_started/synthetics/private_location/

https://blog.serverworks.co.jp/datadog-pl-setting

プライベートロケーションをKubernetes上に構築した場合、`spec.hostAliases` でhostsファイルのエントリが作成できます。

https://kubernetes.io/ja/docs/tasks/network/customize-hosts-file-for-pods/


```yaml
spec:
  hostAliases:
  - ip: "XX.XX.XX.XX"
    hostnames:
    - "www.example.com"
```

# まとめ

DNS登録されていないサイトでもプライベートロケーションならブラウザテストできるよ！とうい話でした。
Introduction to SystemVerilog - 7

## 数値と型

この記事シリーズでは暗黙に数値や演算子を使用して式を記述していました。今回の記事ではを数値と型を取り上げます。

### 数値表現
回路、特にデジタル回路では0或いは1のどちらかの値を扱いますが、回路なので不定（**x**で表記）とハイインピーダンス（**z**で表記）も記述できます。そしてそのような2進数で常に書くのは面倒でもあり、また数値に何らかの目的がある際、視認性が低い時があります。このため複数の基数をサポートしています。

数値は整数と浮動小数点数をサポートしています。小数点を記述しなければ整数、記述すれば小数表現で他の言語と同じです。また、デジタル回路は2進数や16進数で表現したい場合があります。例えば、符号化した値を記述したい場合は2進数、回路上の整数値を割り当てたい場合は16進数で記述したいことがよくあります。

### 基数ラベル

例えば5-bit幅の2進数表現は以下のように記述します。
```verilog
5'b10000
```
プリフィックスとして幅（例では５）を指定し、 2進数指示ラベルとして**b**を記述して続けて2進数の各桁を記述します。幅指定は（ローカル）パラメータ記述でも問題ないですが、念の為処理系でのコーディングルールを確認してください。

先の例を16進数表現で記述すると以下のようになります。
```verilog
5'h10
```
16進数指示として**h**を記述して続けて16進数の各桁を記述します。この例では下位4ビットは"0"として記述しています。16進数は各桁4ビットずつ表現するので上位1ビット（下から5ビット目）は```4'b0001```として上記のような記述をします。

まとめると
```
幅+'+基数ラベル+基数に基づいた数値
```
の文法で、幅は省略して記述することもできます。その際は幅が不定の数値ということでオブジェクトへの割り当ての際に気をつける必要があります。主な基数ラベルは以下の通りです。

|基数ラベル|基数|
|--------|---|
| h      | 16|
| d      | 10|
| b      |  2|

基数ラベルは大文字でも記述できます。基数ラベルを省略すると10進数として扱われます。符号付き数値（２の補数）を記述したいときは```s+基数ラベル```と符号を指示する**s**を付与します。符号を用いる場合は例えば
```verilog
-10'sh10a
````
と記述でき、これは2の補数なので
```verilog
10'h2f6
````
と等しいです。
### 繰り返し表現

また、文字列表現の際に値を繰り返し記述したい場合があります。
例えば数値"2"を3回繰り返したい場合、
```verilog
3{2}
````
と記述すれば
```verilog
222
````
と等しく```繰り返し回数+{+文字+}```という文法に従います。これは例えば1ビットのフラグ信号を使用して値をマスクしたい際に有益です。

### ネット型
他の言語と同じくあらかじめ型が用意されており、回路特有の型もサポートされています。ネット型には**wire**と**tri**があり、ネット型もユーザー定義できます。例えばデータの型として```type T```がある場合、例えば
```verilog
nettype T wT;
```
と宣言できます。
特定のネット型のオブジェクトに複数の信号が割り当てられている場合、これを**マルチドライブ**と呼びます。ネット型は不定とハイインピーダンスの状態を含む状態を持ち、マルチドライブの際に割り当てられる値について気をつける必要があります。下の表は縦軸と横軸二つのネット型によりマルチドライブしている時のSystemVerilogでの扱いを定義しています。

|wire/tri   | 0 | 1 | x | z |
|-|-|-|-|-|
| 0 | 0 | x | x | 0 |
| 1 | x | 1 | x | 1 |
| x | x | x | x | x |
| z | 0 | 1 | x | z |

### 整数型
SystemVerilogは整数型として下記をサポートしています。
|型名        |幅[bits] | 符号 | ベクタ | 状態数 |
|--|--|--|--|--|
|shortint   | 16    | 有    | 無    | 2 |
|int        | 32    | 有    | 無    | 2 |
|longint    | 64    | 有    | 無    | 2 |
|byte       | 8     | 有    | 有    | 2 |
|bit        | UD    | 有    | 有    | 2 |
|logic      | UD    | 無    | 有    | 4 |
|reg        | UD    | 無    | 有    | 4 |
|integer    | 32    | 無    | 有    | 4 |
|time       | 64    | 無    | 有    | 4 |

UDはユーザー定義であり、宣言時に幅を指定する必要があります。ベクタとは今までの説明でたびたび出てきたユーザーが定義した**幅**あるは要素を持つことを意味します。そして他の言語同様に
```verilog
[3:2]
```
と言った形で大カッコを用いて表現しスライス":"を使用してベクトル内の要素の参照範囲を指定できます（上の例では下位3ビット目から4ビット目まで計2ビットの範囲を指定）。状態数が2の型は純粋に整数値を表現するのに用いられます。例えばforループでの型に用いたりします。状態数が4の型は実際回路として扱われ、不定（xで表記）とハイインピーダンス（zで表記）の状態も含みます。
MongoDBをMacOSにインストール

## 概要
MacOSへのMongoDBインストールのメモ.
参考にした公式Document 
[Install MongoDB Community Edition on macOS](https://www.mongodb.com/docs/v6.0/tutorial/install-mongodb-on-os-x/)

今回は関係ないですが，MongoDB Atlasと呼ばれるクラウド版があるようで，クラウド版であればインストールの手間が無いです．


## インストール

まず，homebrewフォーミュラをダウンロード
```
$ brew tap mongodb/brew
```

次に，mongodbをダウンロード
```
$ brew install mongodb-community
```
## パスを通す
インストール完了後，`mongo`コマンドや`mongod`コマンド等が使用できない場合はパスを通します．

**~/.zshrcファイルを開きます．**
```
$ open ~/.zshrc
```
**~/.zshrcファイルに以下の文を追加してパスを通します．**
```
export PATH=/opt/homebrew/Cellar/mongodb-community/${version}/bin:$PATH
```
環境に合わせて`${version}`を書き換えてください．
例：自分の場合は，最新版ではなくバージョン4.4を指定したため，
`PATH=/opt/homebrew/Cellar/mongodb-community@4.4/4.4.16/bin:$PATH`となっています．

ファイルを保存して閉じます．

**~/.zshrcファイルを読み込み直して，設定を反映させましょう．**
```
source ~/.zshrc
```
ターミナルを再起動する方法でも読み込みを行えます．


## 起動
`mongo`コマンドでmongoDBを操作することができますが，まずmongoDB(mongdプロセス)を起動する必要があります．

起動はMacOS service実行する場合と，バックグラウンドで実行する場合の2パターン用意されています．

### MacOS serviceとして実行する場合
```
//起動
$ brew services start mongodb-community
//停止
$ brew services stop mongodb-community
```
### バックグラウンドで実行する場合
```
mongod --config /opt/homebrew/etc/mongod.conf --fork
```

#### メモ
mongodを起動するときに，データベースのパスを指定する必要がありますが，ここで紹介した方法では明示的にパスを指定する必要がないです．

指定しない場合、`mongod.conf`ファイルに設定された`dbPath`がパスとなります． 
`mongod.conf`は`mongodb`インストール時に`/opt/homebrew/etc/mongod.conf`に同時にダウンロードされています．

```
$ more /opt/homebrew/etc/mongod.conf
systemLog:
  destination: file
  path: /opt/homebrew/var/log/mongodb/mongo.log
  logAppend: true
storage:
  dbPath: /opt/homebrew/var/mongodb
net:
  bindIp: 127.0.0.1, ::1
  ipv6: true
```

### mongoシェルの起動
MongoDBの操作はmongoシェルで行います．mongoシェルは`mongo`で起動できます．

```
$ mongo
MongoDB shell version v4.4.16
>
```

以上です．
基本的なHTTPまとめ[備忘録]

<h2>Get</h2>
URLをリクエストする。
<h2>Post</h2>
サーバーに情報を送信する。
<h2>Patch</h2>
サーバーの情報を更新する。
<h2>Delete</h2>
サーバの情報を削除する。
zapとzerologをlumberjackと組み合わせてログローテーションする

# はじめに
今回の記事では、高速なロギングライブラリであるzap、zerologと豊富なログローテーション機能を持つlumberjackライブラリを組み合わせる方法を紹介しようと思います。

# lumberjackの設定項目

lumberjackでは以下の項目でログローテーションを制御できます。
- ログファイルのパス
- ローテーションサイズ（メガバイト単位）
- 最長保持期間（日単位）
- 最大保持数
- ログの日時情報にローカル時刻を利用するかUTCを利用するか
- ローテーション後にgzipで圧縮するか

https://pkg.go.dev/gopkg.in/natefinch/lumberjack.v2#Logger
```golang
type Logger struct {
	// Filename is the file to write logs to.  Backup log files will be retained
	// in the same directory.  It uses <processname>-lumberjack.log in
	// os.TempDir() if empty.
	Filename string `json:"filename" yaml:"filename"`

	// MaxSize is the maximum size in megabytes of the log file before it gets
	// rotated. It defaults to 100 megabytes.
	MaxSize int `json:"maxsize" yaml:"maxsize"`

	// MaxAge is the maximum number of days to retain old log files based on the
	// timestamp encoded in their filename.  Note that a day is defined as 24
	// hours and may not exactly correspond to calendar days due to daylight
	// savings, leap seconds, etc. The default is not to remove old log files
	// based on age.
	MaxAge int `json:"maxage" yaml:"maxage"`

	// MaxBackups is the maximum number of old log files to retain.  The default
	// is to retain all old log files (though MaxAge may still cause them to get
	// deleted.)
	MaxBackups int `json:"maxbackups" yaml:"maxbackups"`

	// LocalTime determines if the time used for formatting the timestamps in
	// backup files is the computer's local time.  The default is to use UTC
	// time.
	LocalTime bool `json:"localtime" yaml:"localtime"`

	// Compress determines if the rotated log files should be compressed
	// using gzip. The default is not to perform compression.
	Compress bool `json:"compress" yaml:"compress"`
	// contains filtered or unexported fields
}
```

# zap ✖️ lumberjack
zapとlumberjackを連携させるには、zapcore.WriteSyncerを利用します。

```golang
package main

import (
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	"gopkg.in/natefinch/lumberjack.v2"
)

func main() {
	sink := zapcore.AddSync(&lumberjack.Logger{
		Filename:   "logs/zap.log",
		MaxSize:    10,
		MaxBackups: 10,
		MaxAge:     10,
		Compress:   true,
	})
	core := zapcore.NewCore(
		zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig()),
		sink,
		zap.InfoLevel,
	)
	logger := zap.New(core)
	logger.Info("hoge")
}
```
出力されるログファイルは以下になります。
```
{"level":"info","ts":1671340569.6598823,"msg":"hoge"}
```

# zerolog ✖️ lumberjack

zapの場合はLogger生成時にlumberjackで作成したWriterを渡すだけなのでかなりシンプルです。

```golang
package main

import (
	"github.com/rs/zerolog"
	"github.com/rs/zerolog/log"
	"gopkg.in/natefinch/lumberjack.v2"
)

func main() {
	writer := &lumberjack.Logger{
		Filename:   "logs/zerolog.log",
		MaxSize:    10,
		MaxBackups: 10,
		MaxAge:     10,
		Compress:   true,
	}

	log.Logger = zerolog.New(writer).With().Timestamp().Logger()
	log.Info().Msg("hoge")
}
```
出力されるログファイルは以下になります。
```
{"level":"info","time":"2022-12-18T05:17:56Z","message":"hoge"}
```
UE5 BPだけでGameplayAbilityを使用する

# 概要
UEのGameplayAbilityシステムをBluePrintだけで扱う方法がないかと調べた結果のメモ
環境
UE5.1.0

# セットアップ
GameplayAbilityを使えるようにする設定は公式ドキュメントの通り
https://docs.unrealengine.com/5.1/ja/gameplay-ability-system-for-unreal-engine/
プラグインの設定と、Build.csに追加するところまでです。

# BPでGameplayAbilityを扱うために必要なもの
BP側にノードが追加されているので、以下のノードを呼び出せばBPだけで完結します。

## AddAbilitySystemComponent
ActorのBeginPlay時にAddAbilitySystemComponentを呼び出し、変数に保存
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157391/de90295b-1e96-836c-2ccb-befb2d048588.png)

## GiveAbility
AbilitySystemComponentのGiveAbilityノードを呼び出して任意のGamePlayAbilityを与える
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157391/25505761-afbb-b43d-17cc-075281072df3.png)

# アビリティ実行
AbilitySystemComponentからTryAcitivateAbilityノードを呼び出して実行
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157391/3fb16823-ccae-22ff-52a8-a0b58173e1b6.png)
TryAcitivateAbilityは一通りあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157391/55157669-4e38-8059-0abc-533d70be4457.png)

タグを使用しキャラクターが使用できるアビリティをリストで管理する使い方もできます。

## 実行結果
単純にPrintStringで実行されてるかを確認するGamePlayAbilityをBPで作成しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157391/36cc0120-d92a-8d30-bdf6-2bdca7562239.png)
Zキー推しでAbilityを実行してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157391/b047fbee-1ce7-8bd6-8e97-692b1ab48984.png)

呼び出しに成功してGamePlayAbilityのBPで指定した文字が出力されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157391/8c40b3b5-fb49-73bd-c7d3-ef81dc8ba830.png)

# 終わり
GameplayAbilityって便利らしいけど、ググってみたらC++が必須のようなサンプルばかりで
まだBPだけでは扱えないままなのか？と思っている人に届けば幸いです。
【Swift】初心者のランダム通話アプリ開発奮闘記 #14

# 今日の積み上げ
`Swift Tutorial`>`Swift Tutorial`>`ContentView.swift` 編集し、プレビューに「Hello, world!」を出力するだけのソースコードを変更
![2022:12:18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/997222/0bfbec55-43b9-af57-59de-d04ea34c48ce.png)

熱出ました。。
バイトとかカフェ巡りの予定が全部パーになりました。
病みそう。。笑
SNSの宛先をGmailにしてみる

# はじめに
今後CloudWatchなどを触っていく前にSNSを設定しようと思ったが、
自身のメールアドレスがGmailのためSNSの宛先にGmailが設定できるのかを試してみることにした。


# 試してみる

### トピックの作成

設定値
タイプ：スタンダード
名前：test-sns-gmail
表示名：test-sns-gmail

![sns-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953845/b571b4df-76e8-73c9-49d4-b825ba46e93c.png)


### サブスクリプションの作成

設定値
トピックARN：先ほど作成したtest-sns-gmail
プロトコル：Eメール
エンドポイント：自身のGmailアドレス
![sns-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953845/21aae4ac-847d-c0a3-64d7-afe115973874.png)

### 確認メール

メールボックスを確認したところ届いていたため、Confirm subscriptionで確認まで実施。
Gmailは問題なしと分かったが一応テストメールの配信までやってみることにする。
![sns-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953845/4e2de306-887c-83d4-fa0b-67e354812176.png)

### ステータスの確認

ステータスが確認済みになっていたため問題なし。
![sns-5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953845/1e6c6522-c2e5-2d6a-bed0-9ee9b5c00483.png)

### テストメールの配信

件名：Test Message From AWS
本文：Test message.

![sns-6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953845/80a490ed-dea5-a191-8628-ee9542361d7c.png)

### テストメールの確認

問題なくテストメールが届いていた。
![sns-7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953845/0a98b9e5-d7fc-b059-ccc8-2b3589bfc3f3.png)

# まとめ
SNSの宛先がGmailでも特段問題なく動作するということが分かったため、
今後のメール連携系の触ってみることも安心して行えることがわかった。
ただ受信メールボックスのプロモーションの欄に入っていたためメールマガジンなどと勘違いされるのか？
そこだけはメールを探すときに注意したい。
![sns-8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953845/e568dcf7-9dc6-feda-7619-779cec0ed031.png)
enebularでnode-red

# 概要
enebularでnode-redやってみる。
herokuの無料枠が消えたので、再構築する。
久々にenabularでeditor開いたらエラー出た。

# 状況
- enabularでプロジェクトをクリック
- フローをクリック
- 編集をクリック
- 3分待つ。
- v2.2.2-n.2と出る。
- デプロイする。
「ワークスペースに未知の型のノードがあります。」のエラー

# 対処
- 画面右上のメニューから、グローバル設定ノードを選択します。
- あやしいノードをダブルクリック
- 削除します。


以上。
Auroraへの接続にはSSM Session Managerを利用したリモートホストへのポートフォワーディングがおすすめという話

# 何それ？

雑に言うと、手元のPCからAuroraにセキュアかつ便利に接続できる仕組みです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123126/96af31df-abbc-b237-b8a5-55b790974c87.png)

# 何がいいの？

下記のメリットがあります。

- 受信ポートを開く必要がない
- SSHキーの管理が不要
- 踏み台ホストをプライベートサブネットに配置可能
- IAMで認証認可できる
- MySQL WorkbenchなどローカルPCにインストールしているツールが使える

# 難しい単語が多いな…

1つずつ説明します。

まず、SSM Session Managerとは、EC2インスタンスなどにセキュアにアクセスできる仕組みです。下記のようなメリットがあります。

- 受信ポートを開く必要がない
- SSHキーの管理が不要
- 踏み台ホストをプライベートサブネットに配置可能
- IAMで認証認可できる

リモートホストとは、ネットワークを介して接続した先の機器のことです。今回の場合ですと、Auoraのことです。

ポートフォワーディングとは、あるポートに届いた通信を別のポートに転送することです。今回の場合ですと、踏み台サーバーが手元のPCとの通信で使用しているポートに届いた通信をAurora(MySQL)との通信のポートに転送することということです。

つまり、SSM Session Managerを利用したリモートホストへのポートフォワーディングとは、SSM Session Managerを用いて踏み台サーバーであるEC2インスタンスにアクセスしつつ、踏み台サーバーでは手元のPCからの通信をリモートホスト（Aurora）のポートに転送することで、手元のPCからAuroraにセキュアかつ便利に接続できる仕組みということになります。手元のPCとAuroraをつなぐため、通常のSSM Session Managerのメリットに加えて、MySQL WorkbenchなどローカルPCにインストールしているツールが使えるというメリットがあります。

# どうやって使うの？

1. 踏み台サーバーとなるEC2インスタンスにバージョン 3.1.1374.0 以降の SSM エージェントをインストールします。

2. 以下のコマンドでSSM Session Managerを利用したリモートホストへのポートフォワーディングを行います。なお、EC2インスタンスID、RDSのクラスターエンドポイント、ポート番号は環境に応じて値を書き換えて下さい。

    ```shell
    aws ssm start-session --target {EC2インスタンスID} \
      --document-name AWS-StartPortForwardingSessionToRemoteHost \
      --parameters '{"host":["{Auroraのクラスターエンドポイント}"],"portNumber":["{ポート番号}"], "localPortNumber":["{ポート番号}"]}'
    ```

    接続に成功した場合、下記のような表示になります。

    ```shell
    Starting session with SessionId: 1663719728-session-042fd961289fd0cfe
    Port 3308 opened for sessionId 1663719728-session-042fd961289fd0cfe.
    Waiting for connections...
    ```

3. Aurora(MySQL)に接続するには別のターミナルで下記を実行します。

    ```shell
    mysql -u admin -p -h 127.0.0.1 -P 3308
    ```

    また、MySQL Workbenchに接続するには下記のように実行します。

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123126/725e76b3-ec9c-f758-b93e-9e5efa68145e.png)


# 参考

https://aws.amazon.com/jp/about-aws/whats-new/2022/05/aws-systems-manager-support-port-forwarding-remote-hosts-using-session-manager/

https://dev.classmethod.jp/articles/aws-ssm-support-remote-host-port-forward/
railsコマンドまとめ[備忘録:随時追加予定]

<h2>コントローラの自動生成</h2>

```
rails generate controller コントローラ名　アクション名
rails generate controller StaticPages index help
```

<h2>作成したコントローラの削除</h2>

```
rails destroy controller コントローラ名 アクション名
rails destroy controller StaticPages index help
```

<h2>モデルの自動生成</h2>

```
rails generate model モデル名 データ名:データ型
rails generate model User name:string email:string
```

<h2>作成したモデルの削除</h2>

```
rails destory model モデル名 データ名:データ型
rails destory model User name:string email:string
``` 

<h2>データベースのマイグレーションを変更</h2>

```
rails db:migrate
```

<h2>データベースのマイグレーションを一つ前に戻したい時</h2>

```
rails db:rollback
```

<h2>データベースのマイグレーションを最初の状態にしたい時</h2>

```
rails db:migrate VERSION=0
```
ちなみに、railsではマイグレーションするたびにバージョンが番号で記録されるので、上記のoptionの[VERSION =]の数字を指定すれば、そのバージョンに戻すことができます。
Goのhttp.Clientでリダイレクトを判定して処理を行う方法

# TL;DR

GoでHTTPリクエストを送信送るnet/httpライブラリの`http.Client`はデフォルトだと自動リダイレクトする仕様ですが、`http.Client.CheckRedirect`をオーバーライドすればリダイレクトする前の結果を返すことができます。

# 外部要因でリダイレクトがかかる際にシステムでエラーが起きる

Amazonの商品の分類によって処理を変えるようなシステムを実装していました。
Amazonの商品は「靴」などの分類を「BrowseNodes」という単位で管理しており、こちらはAPIのドキュメントにも書かれています。

https://webservices.amazon.com/paapi5/documentation/use-cases/organization-of-items-on-amazon/browse-nodes.html

メンズスニーカーの場合、「[https://www.amazon.co.jp/b?node=2221112051](https://www.amazon.co.jp/b?node=2221112051)」というURLの「2221112051」がメンズスニーカーのBrowseNodeのIDに相当します。

![スクリーンショット 2022-12-18 14.02.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238254/acd2ebaf-a75c-39db-80ef-7a8fa690f9a8.png)

このBrowseNodeのIDをもとにしたシステムをGoにて作成していたところ、このIDがときどき変更されて、リダイレクトされていることがわかりました。事前にシステムにIDを登録しておくと、そのIDで上記のAPIを利用した際にエラーになってしまいます。

このリダイレクトをシステムで検知することができないかを考えてみたので、今回はその方法を紹介したいと思います。

# リダイレクト時にリダイレクト先を表示させるコード

こちらが実際に実装したコードです。

```go:main.go
package main

import (
	"fmt"
	"log"
	"net/http"
	"os"
)

func main() {
	targetUrl := os.Args[1]
	c := &http.Client{
		CheckRedirect: func(req *http.Request, via []*http.Request) error {
			return http.ErrUseLastResponse
		},
	}
	resp, err := c.Get(targetUrl)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()

	if resp.StatusCode == 301 {
		fmt.Println(resp.Header["Location"][0])
	}
}

```

```sh
$ go run main.go "https://www.amazon.co.jp/b?node=15326491"
/b?node=2231280051
```


# http.Client.CheckRedirectをオーバーライドしてリダイレクト前のレスポンスを返す

HTTPのリクエストを送信するnet/httpライブラリの`http.Client`はデフォルトだと自動リダイレクトする仕様ですが、`http.Client.CheckRedirect`をオーバーライドして、エラーを返すようにすればClientのGetメソッドは、bodyが閉る前のレスポンスとCheckRedirectの結果を返してくれます。


https://pkg.go.dev/net/http#Client.CheckRedirect

今回のケースでは`ErrUseLastResponse`を返していて、これが返されると次のリクエストの前の最新の応答を返してくれます。

https://pkg.go.dev/net/http#ErrUseLastResponse

# `http.GET`の結果がリダイレクト前のものになる

これによって`http.GET`で返される結果が、リダイレクトされている場合にはリダイレクトされる前の結果が返るようになったので、ステータスコードによる分岐を追加することで、リダイレクト先のパスも取得することができるようになりました。

# 留意点

今回のコードに関しては、検討した結果として実際のプロダクションコード等では使っておりません。
スクレイピング等に使う用途を想定しておりませんので、ご注意ください。

https://topcourt-law.com/internet_security/scraping-illegal

# 参考

https://zaburo-ch.github.io/post/get-redirect-url-in-go/

https://blog.freedom-man.com/golang-nethttp-redirect
Splunk: 単体積み上げ棒グラフの作り方


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

### 1. 概要

 Splunk で以下のような、1本だけの積み上げ棒グラフを作りたい場合があります。

![WS000374.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/ae1e78bc-0b1b-0427-df72-bd2dfa1a872c.jpeg "単体積み上げ棒グラフ")

積み上げ棒グラフ自体は視覚エフェクトの「 Bar Chart 」や「 Column Chart 」で「スタックモード」を変更すれば作成できます。

![WS000375.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/5bd5ba5a-607e-34fc-19a6-ae6c4bb3ce33.jpeg "スタックモード")

ですが、単に stats コマンドの結果を使うだけだと以下のように普通の棒グラフが並ぶだけになってしまいます。

```Splunk:Splunk
index="_internal"
| stats count BY sourcetype
```

![WS000370.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/a4b1285d-7397-100c-cab6-bcb47cab3728.jpeg "stats")

では、どのようにすれば1本だけの積み上げ棒グラフが作れるでしょうか。

先ほどのSPLの結果を表形式で見ると、以下のようになっています。

![WS000371.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/78a6e78f-a6bf-916f-762f-a3d9a1230832.jpeg "stats表形式")

| sourcetype | count |
| :- | -: |
| mongod | 166 |
| scheduler | 4 |
| ... | ... |

これを積み上げ棒グラフの形にするには、実は以下のような表にする必要があります。

| (ダミー値) | mongod | scheduler | ... |
| :- | -: | -: | -: |
| (ダミー値) | 166 | 4 | ... |

今回は方法を2つ紹介します。

### 2. chart コマンドを使う方法

1つ目の方法は、 chart コマンドを使う方法です。
ただし、集計に使うキーが sourcetype 1つだけだと先ほどの stats コマンドと同じなので、ダミーのフィールドを生成して OVER 句に指定する必要があります。

```Splunk:Splunk
index="_internal"
| eval dummy = "test"
| chart count OVER dummy BY sourcetype
```

![WS000372.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/d0f277c2-42b0-e3a6-0452-188465a482ff.jpeg "chart")

### 3. xyseries コマンドを使う方法

2つ目の方法は、 xyseries コマンドを使う方法です。
このコマンドはあまり馴染みがないかもしれませんが、以下のように「一番左の列の項目」「一番上の行の項目」「その他の箇所の項目」の 3 つを指定することで、縦横2次元の表を作成できるコマンドです。

 xyseries <一番左の列> <一番上の行> <その他の箇所>

なお、こちらもダミーのフィールドを生成して一番左の列に指定する必要があります。

```Splunk:Splunk
index="_internal"
| stats count BY sourcetype
| eval dummy = "test"
| xyseries dummy sourcetype count
```

![WS000373.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/ca521eda-e5db-ee13-b0f6-0f781130d6d2.jpeg "xyseries")

### 4. ダミー値の非表示

上記のようにすれば単体積み上げ棒グラフを作れますが、グラフの根本に余分なダミー値の表示が残ってしまいます。

![WS000376.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/45f7c0fe-c057-4ca4-34c7-10fbc8f7861f.jpeg "ダミー項目")

これを消すことも考えてみましょう。
まずは、「フォーマット」から「 X 軸」のタイトルを「なし」に変更します。

![WS000377.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/bf452327-c6fa-d5a3-8ac5-438bf1de787e.jpeg "X軸タイトル")

すると、項目名が消えました。

![WS000378.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/ca2d5e0f-74f9-ada6-8cd2-855d60d7d591.jpeg "ダミー値")

あとは、ダミー項目の値を空の文字列に変更します。

```Splunk:Splunk
index="_internal"
| eval dummy = ""
| chart count OVER dummy BY sourcetype
```

![WS000379.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/de0e5a97-4e30-8479-6dd7-b61902f58b37.jpeg "ダミー非表示")

これで、ダミー値の表示を消すことができました。