OmniAICreator/Qiita-1.07M huggingface dataset:
C# WPF 画面外をクリックすることで画面を閉じる方法

# 概要

画面がフォーカスロストしたタイミングで対象の画面を閉じる必要があり、ハマったので備忘録用に。
厳密にはフォーカスロストではなく、ウィンドウの非活性化を検知することで対応。
分かってしまえば簡単。以下のコードを対象画面のCSに追記するだけ。

```
protected override void OnDeactivated(EventArgs ea)
{
    base.OnDeactivated(ea);
    Close();
}
```

***
#### 簡単なサンプルコード
* メイン画面(MainWindow)上のボタンから子画面(SubWindow)を開く。  
* 子画面の画面外をクリック（ウィンドウを非活性化）することで子画面が閉じる。
* 親画面は閉じないよ！

:::note warn
【制約】
子画面を×ボタン等で閉じると例外エラーが出るから注意。
このため、×ボタン等で閉じられないように 子画面には WindowStyle="None" を入れている。
:::

```c#:MainWindow.xaml
<Window x:Class="sample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:sample"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Button Content="Button" HorizontalAlignment="Left" Margin="50,50,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
    </Grid>
</Window>
```

```c#:MainWindow.xaml.cs
using System.Windows;

namespace sample
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            var SW = new SubWindow();
            SW.Show();
        }
    }
}
```

```C#:SubWindow.xaml
<Window x:Class="sample.SubWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:sample"
        mc:Ignorable="d"
        Title="SubWindow" Height="200" Width="300" WindowStyle="None">
    <Grid>
        
    </Grid>
</Window>
```

```c#:SubWindow.xaml.cs
using System;
using System.Windows;

namespace sample
{
    /// <summary>
    /// SubWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class SubWindow : Window
    {
        public SubWindow()
        {
            InitializeComponent();
        }
        protected override void OnDeactivated(EventArgs e)
        {
            base.OnDeactivated(e);
            Close();
        }
    }
}
```

###### 以上。
I2Cセンサ値をCANに流すI2CtoCANinterfaceを開発した話

今回使っている「CANdino」は前回の記事[CAN搭載Arduino互換ボード「CANdino」作った話](https://qiita.com/Yu-Tomo/items/e30f2b3abf415f76f6f1)をご覧ください。

CANを搭載したArduino互換機なら動作するはずです。

##目的
直接CAN通信を行えるセンサってなかなか販売してないし、販売していたとしてもとても<b><font color ="red">高価</font></b>になってしまいます。

なら、<b>センサ値を読んでCANにデータを流してくれるインターフェイスを開発すればいいじゃん！</b>ってなったので開発しました。

##I2CtoCANinterfaceのI2Cとは？

I2Cというのは、<b>安価で一般的に使われる通信です。</b>秋月電子でセンサを調べてみるとI2C通信センサが見つかると思います。

![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485495/bfafdad5-d009-3fb7-9523-fce358232758.png)
####<font color = "red">I2C通信は二本の線だけで複数のセンサと通信できます。
マイコンに取り付ける線が少なくて済むので便利な通信方式です。

##I2CtoCANinterfaceのCANとは？

<b>車載関係でよく使われる通信</b>です。
二本の線で通信ができます。
二本の線の電位差で0と1を表しているので、ノイズに強いという特徴があります。
![図2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485495/ef3499ad-fa36-4662-a54e-db79af1a0578.png)

##I2CtoCANinterfaceメリット
直接CANを使用できるセンサがあまり無いため、電子制御ユニットに直接線を繋げる必要が出てきます。

I2C通信とCAN通信を接続することで接続する線を少なくできます。
![図3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485495/643949ee-6f5f-7c4b-647f-11005f0311af.png)

##EEPROMからI2CとCAN設定を読み込む
CANdinoには決まったフォーマットで書き込まれたDIPのEEPROMが搭載されていて、EEPROMからI2Cセンサ用の設定とCAN通信用の設定を読み込むことで接続されているI2Cセンサと通信し、CAN BUSにI2Cのセンサデータを流すことが出来ます。


##ソースコード
https://github.com/Yu-Tomo/I2CtoCANinterface

##詳しくは、別の資料.pdfを用意しています。

https://drive.google.com/file/d/1WG4btia293gUnD_GRn8cUiSVqdHZPErU/view?usp=sharing
Swift 色々な高さを取得

## 環境
Swift5
Xcode12.5

## 画面サイズ

```Swift
let mainBoundSize: CGSize = UIScreen.main.bounds.size
```

## StatusBarの高さ

```Swift
let statusBarHeight = self.view.window?.windowScene?.statusBarManager?.statusBarFrame.height ?? 0

```

## NavigationBarの高さ

```Swift
let navigationBarHeight = self.navigationController?.navigationBar.frame.height ?? 0
```

## 参考

https://stackoverflow.com/questions/57023899/how-to-get-the-status-bar-height-in-ios-13
【DJITelloPy】遠隔飛行中のドローンの一人称視点カメラ画像に、ぼかし処理と色反転処理をかけて、PC側のウィンドウに表示してみた


###やったこと

__[前回の記事](https://qiita.com/electronics_diy721/items/d13c67d2d19adb97b1f2)__で作成したソースコードを拡張しました。

前回は、Telloをキーボード操作しながら、Telloの単眼カメラから送られてくる画像を、Macbookのウィンドウにそのまま出力しました。（ウィンドウ名： "drone"）

今回は、オリジナルの画像に加えて、OpenCV2の組込みメソッドで加工した画像を、別のウィンドウに出力してみました。

####__（ 追加したウィンドウ ）__

- __*'Canny'* ウィンドウ__　： エッジ検出処理をかけたフレーム画像
- __*'bitwised_image'* ウィンドウ__ ： 色反転処理をかけたフレーム画像


###実行方法

```bash:Terminal
% python3 keyboard-control-multi_window.py
```

###動作結果

まず、- キーボード入力に反応して、意図した通りにTelloが動きました。

さらに、３つのウィンドウが立ち上がり、各ウィンドウに、オリジナル画像、エッジ処理後の画像、色反転処理後の画像が、次のように正常に出力されました。

- Tello離陸前に、Telloを手で持って動かしたり、カメラの前にかざした手を動かすと、遅延なく、リアルタイムに画像がウィンドウに表示される。

- Telloが移動中の単眼カメラのフレーム画像が、滑らかにウィンドウに出力される。

:sunny:

###スクリプト・ファイル

```Python3:keyboard-control-multi_window.py
from timeout_decorator import timeout, TimeoutError
from djitellopy import Tello
import cv2, math, time

TIMEOUT_SEC = 0.1

@timeout(TIMEOUT_SEC)
def input_with_timeout(msg=None):
   return input(msg)


tello = Tello()
tello.connect()

tello.streamon()
frame_read = tello.get_frame_read()

#tello.takeoff()

while True:
    # In reality you want to display frames in a seperate thread. Otherwise
    #  they will freeze while the drone moves.
    img = frame_read.frame
    cv2.imshow("drone", img)
    cv2.imshow('Canny', cv2.Canny(img, 100, 200))
    bitwised_img = cv2.bitwise_not(img)
    cv2.imshow('Bitwised', bitwised_img)
    
    #次の行（key = cv2.・・・）を削除すると、画像が受信できなくなる。
    key = cv2.waitKey(1) & 0xff
    
    try:
        msg = input_with_timeout('\n{}秒以内に操作コマンドを入力して下さい :'.format(TIMEOUT_SEC))
        print('\n操作コマンド：　{} を受信しました。\n'.format(msg))
        if msg == "i":
            tello.takeoff()
        elif msg == "w":
            tello.move_forward(30)
        elif msg == "s":
            tello.move_back(30)
        elif msg == "a":
            tello.move_left(30)
        elif msg == "d":
            tello.move_right(30)
        elif msg == "e":
            tello.rotate_clockwise(30)
        elif msg == "q":
            tello.rotate_counter_clockwise(30)
        elif msg == "r":
            tello.move_up(30)
        elif msg == "f":
            tello.move_down(30)
        elif msg == "g":
            tello.land()
    except TimeoutError:
        print('\n操作コマンド入力時間切れ。次のフレーム画像を読み込みます。\n')

tello.land()

```
Next.js(TypeScript) に Google Analytics



## 公式Example

この情報をもとに設定しました

[next.js/examples/with-google-analytics at canary · vercel/next.js](https://github.com/vercel/next.js/tree/canary/examples/with-google-analytics)


### TypeScript対応

公式ExampleはJSなので、`window.gtag`でエラーになります。
よって、`@types/gtag.js`を追加します。

```
yarn add -D @types/gtag.js
```



### gtagを扱うライブラリの作成

lib/gtag.ts を作成します。
（パス/ファイル名は適宜変更してOKです）
参考もとには存在しなかった、GA_TRACKING_IDが未設定の処理を追加してます。


```:lib/gtag.ts
export const GA_TRACKING_ID = process.env.NEXT_PUBLIC_GA_ID

// https://developers.google.com/analytics/devguides/collection/gtagjs/pages
export const pageview = (url) => {
  if (!GA_TRACKING_ID) return // GA_TRACKING_ID が設定されていない場合は、処理しない
  window.gtag('config', GA_TRACKING_ID, {
    page_path: url,
  })
}

// https://developers.google.com/analytics/devguides/collection/gtagjs/events
export const event = ({ action, category, label, value }) => {
  if (!GA_TRACKING_ID) return // GA_TRACKING_ID が設定されていない場合は、処理しない
  window.gtag('event', action, {
    event_category: category,
    event_label: label,
    value: value,
  })
}
```


### _app.tsへの適用

_app.ts

```:_app.ts
import { useEffect } from 'react'
import { useRouter } from 'next/router'
import * as gtag from '../lib/gtag'

const App = ({ Component, pageProps }) => {
  const router = useRouter()
  useEffect(() => {
    const handleRouteChange = (url) => {
      gtag.pageview(url)
    }
    router.events.on('routeChangeComplete', handleRouteChange)
    return () => {
      router.events.off('routeChangeComplete', handleRouteChange)
    }
  }, [router.events])

  return <Component {...pageProps} />
}

export default 
```



### _document.tsへの適用

_document.ts のHeadタグに以下を追加します。

```:_document.ts
<Head>
  {/* Global Site Tag (gtag.js) - Google Analytics */}
  <script
    async
    src={`https://www.googletagmanager.com/gtag/js?id=${GA_TRACKING_ID}`}
  />
  <script
    dangerouslySetInnerHTML={{
      __html: `
    window.dataLayer = window.dataLayer || [];
    function gtag(){dataLayer.push(arguments);}
    gtag('js', new Date());
    gtag('config', '${GA_TRACKING_ID}', {
      page_path: window.location.pathname,
    });
  `,
    }}
  />
</Head>
```


### イベントを送信したい場合

例）pages/contact.ts 

[next.js/contact.js at canary · vercel/next.js](https://github.com/vercel/next.js/blob/canary/examples/with-google-analytics/pages/contact.js)

```:pages/contact.ts

  handleSubmit = (e) => {
    e.preventDefault()

    gtag.event({
      action: 'submit_form',
      category: 'Contact',
      label: this.state.message,
      value: ''
    })

    this.setState({ message: '' })
  }


 render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <button type="submit">submit</button>
      </form>
    )
  }
```


イベントについては以下を参照ください

[Google アナリティクスのイベントを測定する  |  ウェブ向けユニバーサル アナリティクス（gtag.js）](https://developers.google.com/analytics/devguides/collection/gtagjs/events?hl=ja)
ワンライナーで作るウソ発見器で「新型コロナウイルス新規陽性者数」を調べてみる

## ワンライナーで作るウソ発見器
最初、pythonで書きはじめたら、自宅のpython環境が壊れていて実行できなかったので、Excelでやり直しました。これはこれで、追試したり、応用したりする人の層が広がりそうなので、結果オーライかな、と思います。でも、ワンライナーじゃなくなっちゃうね。

アニメDVDの売上とか、誰かが自慢しているアクセス数推移とか、新規陽性者数とか、そういう数字って、自分の側からは統計の裏側を見通すことなんてできないですよね。でも、「ウソ発見器」があれば大丈夫。たちどころにウソが暴けるのです、というのは**もちろん誇大広告極まりないのですが**、でもまあ、やりたいことはそういうことです。この手法は、企業の不正会計を探すためのスクリーニングにも応用する研究があるくらいで、ぶっちゃけバカみたいに見えるのですが、案外パワフルなのです。

さて、上記は大きく出すぎましたが、何のことはない、「ベンフォードの法則」です。桁をまたがって散らばっている数値の一番上の桁の数字が、自然なデータでは一定の割合になる、という面白い法則です。

「数値の一番上の数字」というのは、値が5000兆だったら5、値が3257だったら3、値が0.015なら1です。値が0の時は考えず、除外して集計します。川の長さ、石の重さ、企業の売上高など、何かしら単位を揃えてデータを集めると、多くの場合、上の桁が一定の割合になるのです。ただ、上限があるような数字、例えばcmで表した身長なんかは、ほぼ1ばっかりになりますし、人為的に桁を意識した数字、例えば商品の単価なんかは、逆に9が異常に多くなることになります。特価98円、とかそういうやつですね。しかし、そういう本質的に偏っている場合以外は、概ね一定の割合になってしまうのです。

では、この「一定の割合」とはどんな風になるのでしょうか。

|最上位桁の数字|自然な率|
|:-:|--:|
|1|30.10%|
|2|17.61%|
|3|12.49%|
|4|9.69%|
|5|7.92%|
|6|6.69%|
|7|5.80%|
|8|5.12%|
|9|4.58%|


特徴としてはなにより、1が一番上の位に来るのが30%もある分布が自然である、という点です。均等だったら11%ですから、かなり盛り盛りです。でも、0.3010と来たら、ぴちぴちの高校生の人たちは、ピンと来るんじゃないでしょうか？　そう、対数と関係がありそうですね。細かい話は、追記するかもしれないけど、今は結論を急ぎましょう。

このベンフォードの法則は、下記のような応用の仕方もできます。

+ **人為的にでたらめに作った数字は、上記とかけ離れたでたらめな分布になる**
+ **人為的に調整した数字は、上記と微妙に逸れた分布になる**

という結果になります。このベンフォードの法則だけで何かの結論を出すことはできませんが、疑惑を定量的に示すことができるのです。上記の率に対して、集計対象から得られた率を比較して、「最上位桁1の率」から「最上位桁9の率」まで、それぞれの差の絶対値を求めると、簡便な評価関数になります。不正会計のスクリーニングでは、0.6ポイントの乖離でちょっと変、1.5ポイントの乖離で結構変、という目安が提唱されているようです。

詳しい人は、ここまでの説明で言いたいことが色々出てくると思いますが、しずまりたまえ。

## では、データを処理しよう
[厚生労働省のオープンデータ](https://www.mhlw.go.jp/stf/covid-19/open-data.html)から、「新規陽性者数の推移（日別）」を持ってきました。前処理として、値が0の行を母集団から削除します。ここはExcelワークで。

数値だけをA列に並べ、B列に ``` =INT(LEFT(TRIM(A参照行),1)) ``` という感じの数式を入れます。コピペドン。Ctrl+Shift+@ で数式表示をすると、下記のような画面になります。同じキーで元に戻ります。

![数式1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79187/7ce18ce9-f6f0-643b-a29b-87cc983fc98c.png)

もう簡単ですね。自動選択範囲からピボットテーブルを新規作成します。
行に「最上位桁」、値に「人数」を入れますが、「人数」については設定が必要です。「値フィールドの設定」から、「集計方法」タブで「個数」を選択、「計算の種類」タブで「総計に対する比率」を選択します。これで、欲しかった最上位桁の数字のシェアが分かります。せっかくなので、その集計値の隣に、 ``` =LOG10(1+1/A参照行) ``` という上に挙げた「望ましい分布」の率を入力しましょう。

そしてその隣には評価関数です。 ``` =ABS(B4-C4) ``` 簡単ですね。これを入れて、また Ctrl+Shift+@ で数式表示にすると、こんな画面になります。

![数式2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79187/a7e95e28-8f7c-c443-89bd-9131211b367a.png)

同じ操作で元に戻します。

![数式3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79187/e45239fc-ed37-0c15-d017-bfc7923dd729.png)

## 暫定的な結論
さて、もう色を付けてしまいましたが、ちゃんと分析できた感じの結果になったと思います。

### でたらめではない
理屈上対数的な分布が想定されるデータ群に対して、全体的に概ね対数的な分布をしており、でたらめではなさそうです。でたらめに作ったら、なかなかこうはなりません。

### でも無視できないズレがある
1と2は明らかに多く、4～9は小さめです。とくに、6～9が一律0.9ポイント前後の乖離を見せているのが気になります。これが何を意味するのかは、もうちょっと色んな切り口で（例えば上2桁で分析するとか、期間ごとのサブセットで分析するとか、直値のヒストグラムを取るとか、そういう）追加の分析が必要です。

1が多いというのは、水増しの傾向があるときによく見られるのですが、この場合、過小報告をするインセンティブならば働く可能性もありますが、水増しをしたい人は考えづらいので、ちょっと謎です。もしかしたら、切り上げで丸めて報告した数字が混じっているとか、そういう何かがあるのかも知れません。

いずれにせよ、このゆがみの正体は、あなたの追試にかかっています。なんてね。面白いでしょ？　というわけで、久々に[AWS資格の話](https://qiita.com/mrpepper/items/64039b828c82e12ad35f)のアクセスが集まっているので、ついでにちょっと面白げな話を書いてみました。セルフ小判鮫上等です。

ベンフォードの法則×コロナ統計というネタが既出だったらごめんなさい。なお、今期はAWS三昧で初動乗り遅れまして、アニメはメイドラゴンSと転スラ2期だけしか観ていません。おすすめがあれば教えて欲しいと思います。
インスタンス変数とローカル変数の違い

# はじめに
本記事は、インスタンス変数とローカル変数の違いをまとめたものです。
正確な理解ができていなかったため、アウトプットします。

# 結論
いきなり結論ですが、
`スコープ`の違いです。

スコープとは、
ある変数や関数などの名前を参照できる`範囲`のこと。

### ローカル変数の範囲
ローカル変数は、極端に言いますと、
`定義した場所`でしか使えない。ということです。

例えば、def~endで定義したのであれば、その場所でしか使えない。
という認識です。

### インスタンス変数の範囲
インスタンス変数は、
`定義した場所以外でも使用可能`です。

例えば、def~endで定義していない場所、
コントローラー内で定義したのであれば、`ビュー`でも使用できる。
という認識です。`→（８月４日訂正、以下の通り）`

```
コントローラーで作ったインスタンス変数は、
ビュー側でも同じ名前のインスタンス変数を作ることができ、
その変数の値を使用することができる。
（@scivola さん　ご指摘ありがとうございます！）
```

# 例文
コントローラーやビューなどを考慮せずに、
この文章内だけで考えた場合、
①と②、どちらが正しいだろうか。

①

```ruby
def update
    @tweet = Tweet.find(params[:id])

    if @tweet.update(tweet_params)
      redirect_to tweet_path
    else
      render :edit
    end
 end
```
②

```ruby
def update
    tweet = Tweet.find(params[:id])

    if tweet.update(tweet_params)
      redirect_to tweet_path
    else
      render :edit
    end
 end
```

#### 正解は、①も②も正しい。

では、
①②それぞれコントローラーで記述し、ビューでも使用する場合だと
どちらが正しいだろうか。
・
・
・
・
・
・
・
・
#### 正解は、①となります。

`ビューでも使う`ということは、
スコープの関係から、インスタンス変数を使用している①が正しいということになります。


# 疑問点
#### ローカル変数を使うメリットはあるのか？
ここで疑問点です。
全てをスコープの大きいインスタンス変数にすることで、
エラーが起こりにくくなり、コードが楽に記述できるのではないかと思えます。

しかし、
ローカル変数を使う`理由があります。`

#### ローカル変数を使う理由
全てをインスタンス変数として設けてしまうと、
・結果的に必要のない部分にまでインスタンス変数を使用することで、
`可読性`に欠けてしまう。

・逆に、分かりづらくなることで、`予期せぬエラー`が発生してしまう。

```
大規模な開発になると、
どの記述がうまくいっていないのか、どこでエラーを起こしているのか、
などを把握しづらくなってしまいます。
```
インスタンス変数を使わずに済む部分であれば、
ローカル変数を用いることで、そのような事態を`未然に防ぐ`ことができます。

# 終わり
過去に、私が疑問に思ったことでしたので、
忘れないためにもここに記述いたしました。

基礎の基礎の部分ですが、
いざコードを記述するときに`基礎の部分が抜けてしまいがち`です。

不安に思うことや、理解できていそうで`言語化できない`部分については、
`理解できていない`ことの方が多いです。

これからも学習中に疑問に思うことは、
どんどん深堀していきます。

引き続き頑張ります！！！
bashで参照変数（変数の変数）の値が設定されているかの判定

# 目的
- 変数で変数を定義したいことがあります。これを参照変数と呼ぶとすると、元の変数で参照先の変数が設定されているかを判定できるか？の記事です。
- 探してもすぐに出てこなかったので自分で試しました。

# 環境
```bash
bash --version
GNU bash, バージョン 5.1.0(1)-release (x86_64-apple-darwin18.7.0)
...
```

# 変数の値に変数名の定義

```bash
# 変数hogeの値はfooでこれが変数名になっている
hoge=foo
# 2つ目の変数(foo)を参照変数と呼ぶことにします。
foo=bar
# hogeから参照変数（foo）の値にアクセスする
## 方法１
eval echo '$'$hoge # -> boo
## 方法2
echo ${!hoge} # -> boo
```

# 参照変数(foo)に値がない場合の振る舞い
```bash
# 変数のクリア
unset foo
# 未定義変数でエラーとする
set -u
echo ${!hoge} # -> -bash: !hoge: 未割り当ての変数です
# scriptで組んでいると止まってしまいます。
```

# 参照変数の判定

- bashには`[ -z ${hoge} ]`とかが出てくるのですが、参照された変数が未定義かどうかわかりませんでした。少なくとも`[ -z ${!hoge} ]`ではうまくいきません。
- そこでbashの-vオプションを使います。

```bash
unset foo
# 変数(hoge)の設定判定は$なしの変数名(hoge)でチェックします
[ -v hoge ] && echo 'Y' || echo 'N' # -> Y
# 変数(hoge)の値が示す参照変数(foo)の設定判定は$ありの変数名($hoge)でチェックします
[ -v $hoge ] && echo 'Y' || echo 'N' # -> N
# 再設定します。
foo=bar
[ -v $hoge ] && echo 'Y' || echo 'N' # -> Y
# できました。
```

# 結論

- bashの`-v`のオプションで`$hoge`で参照変数の設定判定ができました。
- どなたかのお役に立てれば嬉しいです。
[Flutter]　テンプレート（コメントアウトなし）


Flutterで新しくアプリを作成する上で、テンプレートがありますね。
自分用ではありますが、コメントアウトを削除したものを下に載せます。

```dart
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }
}

```
【kotlin】NestedScrollViewで最下部までスクロールした際に処理を実行する


#状況
NestedScrollViewで最下部までスクロールした際に処理を実行したい



#解決方法
setOnScrollChangeListenerを利用してスクロール位置を検出する

```
 //Fragment
 it.scrollView.setOnScrollChangeListener { v, _, scrollY, _, _ ->
   it.isScrolled = (v as ViewGroup).getChildAt(0).bottom <= (scrollY + v.height)
 }


 //xml内にボタンを設置
 <data>
       <variable
           name="isScrolled"
           type="Boolean" />
 </data>

 <TextView
    android:id="@+id/button"
    android:enabled="@{isScrolled}"/>

```


![ダウンロード.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694541/d3f19f95-ada1-5ae4-cb01-f65861a3d8eb.gif)

拡張関数にすればもっと使いまわせそう。

[setOnScrollChangeListener](https://developer.android.com/reference/kotlin/androidx/core/widget/NestedScrollView#setonscrollchangelistener)
VSCodeのターミナルでAnacondaを使用可能なpowershellを起動する

VSCodeでPythonを書いている最中に，パッケージのインストールなどでターミナルを操作したくなることが多数あり，そのたびに統合ターミナルでcondaが使用できないことに不満がたまっていた．
調べると`Setting.json`を編集することで使用できるとの事だったが，記載内容が自分の環境と微妙に一致しなかったためメモを公開しておく．

### 環境
Windows 10 Home
Visual Studio Code 1.58.2
Miniconda3 py39_4.9.2

# Anacondaのコマンドを確認する
左下のWindowマークを押してAnaconda Powershell Promptを表示する．
ファイルの場所を開くを実行する．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267183/23f042fa-ee7a-362a-2b97-2f4b17411bc3.png)
ショートカットを選択し，右クリックからプロパティを表示すると以下のようにリンク先が確認できる．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267183/1ba87612-baf2-2fcc-0044-fae183e5ae67.png)
著者環境ではリンク先は以下のように記載されていた．

```
%windir%\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy ByPass -NoExit -Command "& 'C:\Users\sakir\miniconda3\shell\condabin\conda-hook.ps1' ; conda activate 'C:\Users\sakir\miniconda3' "
```

# Settings.jsonを開く
[ファイル]>>[ユーザー設定]>>[設定]から設定画面を開く．
検索タブに`terminal profiles windows`などと入力して以下のように表示されるので，`settings.jsonで編集`をクリックする．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267183/abbdb006-89ed-faaf-bfe9-12b2d44a800f.png)
`settings.json`が開き，元の設定から新たに以下の記載が追加されている．
この箇所を変更することでPowerShellが立ち上がる際にAnacondaの初期化を行うことができる．

```
    "terminal.integrated.profiles.windows": {
        
        "PowerShell": {
            "source": "PowerShell",
            "icon": "terminal-powershell"
        },
        "Command Prompt": {
            "path": [
                "${env:windir}\\Sysnative\\cmd.exe",
                "${env:windir}\\System32\\cmd.exe"
            ],
            "args": [],
            "icon": "terminal-cmd"
        },
        "Git Bash": {
            "source": "Git Bash"
        }
    },
```

# Settings.jsonを編集する
上で確認したAnacondaのリンク先をもとにして，PowerShellの箇所を以下の通りに変更する．

```
        "PowerShell": {
            "source": "PowerShell",
            "args": [
                "-ExecutionPolicy",
                "ByPass",
                "-NoExit",
                "-Command", 
                "C:\\Users\\sakir\\miniconda3\\shell\\condabin\\conda-hook.ps1",
            ],
            "icon": "terminal-powershell"
        },
```
注意点としては，&が不要になっていることと，最終行のconda activateを記載するとエラーが発生することなどである．
以上で新規ターミナルの起動時にcondaが使用できるようになっている．
[Ruby on rails] グループ作成機能⑥ Action mailerの環境変数化　gem(dotenv-rails) /.env

<h2>環境変数を設定する</h2>

グループ作成機能⑤でグループメンバーにメールを送信する機能を実装しました。
gmailのアドレス、パスワードを直打ちしてるので、セキュリティ的にあまりよろしくありません。
そこで使うのが環境変数です。
<h6>なんか大変そう・・・:frowning2:と思ってたのですが、すぐ出来ます！！！</h6>

もうメールの機能は出来上がってる前提です。
メール機能の実装については⑤の記事をご確認ください。

https://qiita.com/ki_87/items/67f8965e8de17e95ac1c

<h2>gemのインストール</h2>

```perl:Gemfile
# 環境変数化のためのgem
gem 'dotenv-rails
```

そしたら```bundle install```で取り込みます。

<h2>.envファイル作成</h2>

Gemfileなどが置いてあるルートディレクトリに .env というファイルを作成します。
以下のような感じになるはずです！

![スクリーンショット 2021-08-03 21.17.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633266/258f052f-92a1-7147-1234-8e08f5e84b47.png)

<h2> .envファイル記述</h2>

```perl:.env
KEY='ki.abcdfgh@gmail.com'    ←gmailのアドレス
SECRET_KEY='abcdefsgsdhsgjd'  ←アプリパスワード
```

<h2>.gitignoreに書き、pushされないようにする</h2>

```perl:.gitignore
#環境変数化で作成したファイル
/.env
```

これで、大事な情報の入ってる.envはgithubにプッシュされません。

<h2>config/enviroment.rbを書き換える</h2>

```perl:config/enviroment.rb
 config.file_watcher = ActiveSupport::EventedFileUpdateChecker
  config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
  config.action_mailer.raise_delivery_errors = true
  config.action_mailer.delivery_method = :smtp
  config.action_mailer.smtp_settings = {
      :user_name => ENV['KEY'],
      :password => ENV['SECRET_KEY'],
      :domain => "gmail.com",
      :address => "smtp.gmail.com",
      :port => 587,
      :authentication => :plain,
      :enable_starttls_auto => true
  }
end
```

以上のように環境変数を入れました。

```perl:mailers/application_mailer.rb
class ApplicationMailer < ActionMailer::Base
  default from: ENV["KEY"]
  layout 'mailer'
end
```

ここもメールアドレスを直打ちしてたので、環境変数に書き換えました。

以上で、⑤で作成したメール機能の環境変数化は完了です。




<h2>参考にさせていただいた記事</h2>


https://qiita.com/yuichir43705457/items/7cfcae6546876086b849


https://qiita.com/tkc310/items/7aa476ef541b755af4ca
自分用Angularメモ

## プルダウンの操作
https://stackblitz.com/edit/angular-ivy-vlovqy?file=src/app/pages/test1/test1.component.html

  * オブジェクトを扱う場合は、optionにngValueを使う

## 結果をコンポーネント化
https://stackblitz.com/edit/angular-ivy-qhrpgb?file=src/app/pages/test1/test1.component.html
それでもFreeBSDを使い続けるわけ

力武さんが「さよなら、愛しのFreeBSD」というコラムを書かれていたが、こちらはなかなかFreeBSDから離れられない。というのは最初に触ったのがBSDであまり物覚えがよくないので、他のものを覚える事ができないからというのが一番大きな理由かもしれない。

また以前いた会社がプロダクションでFreeBSDを使っていた時期があり、創業者が作った元祖kqueueのような仕組みがFreeBSD 2ベースに入ったシステムを使っていたり、jailを使った開発環境などで仕事をしていたのも要因です。

とはいえ、FreeBSDにも問題はたくさんある。

自分がポートしたarmv5のsocのコードがあったのだが、まったくパフォーマンスが出ない状態だった。FreeBSDのarmサポートはもともとはNetBSD由来なのだが、v6をサポートするときに独自に開発をしてv5環境を壊したみたいだ。NetBSDのarmv5はちゃんとパフォーマンスが出る。臭いものには蓋で、armv5のサポートは13Rで消されてしまった。

BSD自体はUCB発だが、アメリカ国防省からの援助でsoketは作成されている。その色合いはFreeBSDにも残っていて、FreeBSDを支える団体はすべてアメリカの法律に従う形になる。すなわちアメリカの利益にならないことはできない。

しかし私がいじっているZRouter.orgはウクライナのrayが始めたものだし、ロシアのMichaelも手伝ってくれている。

またsys/mips/mediatekのポートをしたStanislav Galabovも旧東側のユーゴスラビアの人らしい。

昨今日本ではめっきり人気が無いFreeBSDだが、2000年位にはかなりな開発者が日本にもいた。一つはPC-9801へのポートをしていた人たちで、もう一つはモバイル関係のPAOという仕組みを作っていた人たちだった。

PC-9801はNECが開発を止めた事もありしりつぼみになり終了してしまったが、PAOの方は後味の良くない終わり方になってしまった。これはPAOのグループが2.xベースで開発していたPCMCAIのサポートの仕組みを3.xに採用してもらえるように話をしていたようだが、却下されnewcardという仕組みが入ったが、技術的にPAOの方が優位なところはあったので、それ以来PAOな人々はFreeBSDから消えていった。

FreeBSD 3ではa.outからELFへの変更やカーネルモジュールのサポートなど大きく変わっていて、PAOは従来のISA依存の部分があり、またcardbus(PCI)のサポートの不十分さなどもあり、impさんなどがPAOを取り込まず、独自実装してしまったような感じだ。

ソフトウエアプロジェクトにおいて、コミュニケーションしていても、なんらかの期限があり、強行されてしまう事は多々ある。そのようなケースはあまり良い結果にならないことが多い。そもそもその期限が正当なものかのプロジェクトの判断にも関わるのかもしれない。

このほかIPV6の参照実装のKAMEプロジェクトでもFreeBSDの開発者がいたが実装の完成とともにいなくなってしまった。

最近impさんがpccardのコードをいろいろ消しているのを見ていると、昔の人たちの無念がよみがえってきた。

どこの国にもまともな人もいるし、そうでない人もいる、オーブーンソースを支える人も同じかもしれない。BSDがある一国の利益のためでなく技術的な価値のために開発を続けるのがUCBの人たちの志をつなぐ事になるのではないだろうか。
【 TelloPy失敗コード例 】画像が入らないか、入っても数十秒遅延したフレームが表示


###【 急募！ 】 デバック模範解答:cold_sweat:

TelloPyの失敗コード例です。
原因が分かる方、そして、どうコードを直したら良いのかが分かる方、教えて下さい。

###動作結果

####__（ 実行手順 ）__

手順１： MacbookのWifiアクセス先一覧から、Tellを選択して、Wifi接続
手順２： MacbookのTerminalで、__*python3 trial.py*__で実行

####__（ 動作結果 ）__

- 画像が入るまでに、30秒近くかかる
- 画像が20秒前後、遅延する （Telloを手で動かしたり、カメラレンズの前で手を動かしたりして確認）
- 画像が入らないときもある （実行するたびに、画像が入ったり、入らなかったり）

###実行環境

- Macbook OS Catalina
- Python 3.9.6

###スクリプト・ファイル

```Python3:trial.py
# キーボード入力で操作できるが、画像が最初のフレームのまま動かない
import sys
import traceback
import tellopy
import av
import cv2.cv2 as cv2  # for avoidance of pylint error
import numpy
import time

drone = tellopy.Tello()
drone.connect()
drone.wait_for_connection(60.0)

container = av.open(drone.get_video_stream())
    
for frame in container.decode(video=0):
    image = cv2.cvtColor(numpy.array(frame.to_image()), cv2.COLOR_RGB2BGR)
    cv2.imshow("Original",image)
    cv2.imshow('Canny', cv2.Canny(image, 100, 200))
    #画像を取得するために、次行のコードを残しておく（key変数は使わない）
    key = cv2.waitKey(1) & 0xff

drone.land()

```

###（ 関連 ）

このコードを組み込んだ以下のコードは、次の事象が発生しました。

- __キーボード入力には反応し、意図した飛行動作をする。__
- __画像が最初のフレームのまま、固まって動かない。__

```Python3:controll_ok_movie_ng.py
# キーボード入力で操作できるが、画像が最初のフレームのまま動かない
import sys
import traceback
import tellopy
import av
import cv2.cv2 as cv2  # for avoidance of pylint error
import numpy
import time
from timeout_decorator import timeout, TimeoutError

TIMEOUT_SEC = 0.5

@timeout(TIMEOUT_SEC)
def input_with_timeout(msg=None):
   return input(msg)

drone = tellopy.Tello()
drone.connect()
drone.wait_for_connection(60.0)

container = av.open(drone.get_video_stream())
    
for frame in container.decode(video=0):
    image = cv2.cvtColor(numpy.array(frame.to_image()), cv2.COLOR_RGB2BGR)
    cv2.imshow("Original",image)
    cv2.imshow('Canny', cv2.Canny(image, 100, 200))
    #画像を取得するために、次行のコードを残しておく（key変数は使わない）
    key = cv2.waitKey(1) & 0xff
            
    try:
        msg = input_with_timeout("\n{}秒以内に操作コマンドを入力して下さい ：　".format(TIMEOUT_SEC))
        print('\n操作コマンド：　{} を受信しました。\n'.format(msg))
        if msg == "s":
            print("離陸します。")
            drone.takeoff()
        elif msg == "n":
            print("30下降します。")
            drone.down(30)
        elif msg == "u":
            print("30上昇します。")
            drone.up(30)
        elif msg == "h":
            print("15左移動します。")
            drone.left(15)
        elif msg == "j":
            print("15右移動します。")
            drone.right(15)
        elif msg == "b":
            print("15後進します。")
            drone.backward(15)
        elif msg == "f":
            print("15前進します。")
            drone.forward(15)
        elif msg == "c":
            print("10度時計回りに回転します。")
            drone.clockwise(10)
        elif msg == "q":
            print("着陸します。")
            drone.land()
        else:
            print("そのキーボード操作は無効（未定義）です。")
                                                
    except TimeoutError:
        print("\n操作コマンド入力時間切れ。次のフレーム画像を読み込みます。\n")

drone.land()

```
【ざっくり解説】Rails×Vueでエラー記録アプリ作ってみた

## はじめに

エンジニアになって半年が経ちました。
膨大なエラーと向き合う中で、**「あれ？前もこのエラー見たよな…」**という機会が多くなり、
**「いちいちググるのめんどくさい」**と感じた刹那、私は`rails new`していたのでした。

## 目次
1. [アプリケーションの概要](#アプリケーションの概要)
1. [ざっくり機能紹介](#ざっくり機能紹介)
1. [苦労したポイント](#苦労したポイント)
1. [まとめ](#まとめ)

## アプリケーションの概要

![logo (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751808/575b805f-fbef-2843-a6ea-67098d88d96b.png)

https://www.error-note.com

エラー記録用アプリケーション「**Error Note（エラーノート）**」
エラーを記録しておくだけの超シンプルなアプリケーションです。

![capture_mac.001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751808/7753d77d-3a99-cd2d-90b1-8cd314eeded5.png)


### システム要件
| item                 | require               | version |
| -------------------- | --------------------- | ------- |
|  OS                  | AmazonLinux AMI       | 2.0     |
|  Application Server  | Unicorn               | 6.0.0   |
|  Web Server          | Nginx                 | 1.20.0  |
|  DB Server           | AWS RDS(MySQL)        | 8.0.25  |
|  Backend             | Ruby                  | 2.7.2   |
|  BackendFramework    | Ruby on Rails         | 6.1.3.2 |
|  Frontend            | HTML, CSS, Javascript | -       |
|  FrontendFramework   | Vue.js                | 2.6.12  |
|  AutomaticDeployment | Capistrano            | 3.1.0   |

### 開発期間
4ヶ月間（設計・デモ版作成・Vue.jsのインプット含む）


## ざっくり機能紹介

### エラー記録機能
その名の通り、エラーを記録します。タイトル、エラーの内容を入力すれば保存できるので、ちょっとしたエラーでもサクッと書き留めておくことができます。

エラーが解決した際には、解決法を入力しておくことができます。
しばらく経ってから「このエラーどこかで見たな…」と思ったときは、「マイページ」から過去に作成したノートを参照します。

他の人にエラーを見られたくないときは、作成したノートを「非公開」に設定することもできます。

### ストック機能
ノートの詳細画面から、他の人が作成したノートをストックすることができます。
ストックしたノートは、「マイページ」から確認することができます。

### 検索機能
キーワードを入力することで、ノートを検索できます。
使い勝手を良くするための機能改修を検討中です。


## 苦労したポイント

### Vue.jsとRailsの融合
今回の開発で初めて**Vue.js**を使いました。
Railsを用いた開発では、Controllerで定義したインスタンス変数をView側に渡して、動的なデータを表示します。
対するVue.jsは、RailsをAPIとして使用します。フロント側からバック側（RailsAPI）にリクエストを投げ、バック側でデータをゴニョゴニョして、jsonとしてフロントに返却。フロントでそれらを表示します。

Vue.jsに関しては最小限のインプットで挑んだため、正直かなりしんどい戦いになりました。
いまだに定数の管理とかライフサイクルを咀嚼できていません。

まだまだVue.jsと仲良くなるための戦いは続きそうです。

### ちょっとだけ視野が広がったからこその悩み
まだエンジニアではなかった頃に、[ポートフォリオ](https://qiita.com/WAKO_program/items/fc941095d278c1893cfe)を作りました。
その頃はまだアプリを「動かす」ことで精一杯でしたが、ようやく「動かす」以外の部分にも視野が広がってきました。

* 開発フローはどうするのか
* ログはどのように管理していくのか、どうしたら参照しやすいか
* メールの送信等を検証しやすくするにはどうすれば良いか

などなど、気になる範囲が広がったことで、もちろんそれらに費やす時間も増えました。
まだまだエンジニアとしては半人前以下ですが、継続的なアウトプットを続けて、視野を広げていきたいです。 

## まとめ
アプリケーションを１から作るというアウトプットは、かなりの時間と労力を使います。
しかし、学習効果としてのリターンは十分にあったと感じられました。

エンジニアとしての業務も忙しいですが、合間を縫ってアウトプットを続けていきます。
最後までご覧いただきありがとうございました。

（↓Githubのスターを頂けると泣いて喜びます。）

https://github.com/k-kudo-hub/error_note_sample

## あとがき

共同開発に誘ってくれて、一緒にErrorNoteを開発してくれた[toshiro](https://qiita.com/kobachii)に心からの感謝を。
[Ruby] AtCoder過去問　B - Cycle Hit

##はじめに
RubyでAtCoderのB問題解いてみました。
私のレベル的にB問題のレベルが解いてて一番気持ちいいです。

C問題にもなれていかなくては。
それではよろしくお願いします。

問題はこちらからご確認ください↓

https://atcoder.jp/contests/abc211/tasks/abc211_b

##B- Cycle Hit

まずは入力の受け取り方ですが、配列に全ての入力を格納していきます。
空の配列を用意して、四つの入力を受け取るので繰り返し処理で4回放り込みます。

```ruby
s = []
4.times do
  s << gets.chomp
end
```

これで配列の中に四つの入力が入りました。
あとはinclude?メソッドで、配列にH, 2B, 3B, HRの四つが存在するかを調べて、TrueならYesをFalseならNoを出力させればいいはずです。

```ruby
s = []
4.times do
  s << gets.chomp
end

if s.include?("H") && s.include?("2B") && s.include?("3B") && s.include?("HR")
  puts "Yes"
else
  puts "No"
end
```

これでもし、全種類が格納されていなかったら、Noが返されます。
全種類あったらYes!

私はinclude?メソッドの使い方を間違えて一度は下記のような書き方をしてしまいました。

```ruby:間違った解答
s = []
4.times do
  s << gets.chomp
end
 
if s.include?("H", "2B", "3B", "HR")
  puts "Yes"
else
  puts "No"
end
```

めちゃ恥ずかしい。。。

##最後に
他の書き方コメントにて教えていただけると幸いです。

冒頭にも書きましたが、B問題が一番ちょうどよく気持ちいいです。
たまーに問題によってはC問題が解けるのですが。

そういえばpaizaとシュタゲのコラボが気になっています。
僕のレベルじゃ難しいかなあ。
bashのTMOUT周りについて

bashにはTMOUTと呼ばれる変数がある。
これは文字通りタイムアウトの秒数を設定するための組み込みの変数で、
例えば以下のようにするとbashはTMOUT秒たったあとに終了する。

```sh
$ TMOUT=10
#10秒以上放置
```
man bashを見ると以下のように書いてあった。

>TMOUT
>If set to a value greater than zero, TMOUT is treated as the default timeout for the read builtin.The select command terminates if input does not arrive after TMOUT seconds when input is coming from a terminal.  In an interactive shell, the value is interpreted as the number of seconds to wait for a line of input after issuing the primary prompt.  Bash terminates after waiting for that number of seconds if a  complete line of input does not arrive.


翻訳すると以下のような感じ

TMOUT変数にゼロより大きい値が設定されている場合、タイムアウトが設定される。
selectコマンドや対話モードのシェルのときに入力が一定時間発生しないとTMOUT秒後にbashは終了する。


この仕組みが実装されているのは eval.cのread_command()の中で以下のようになっている。


```c

int read_command()
{

SHELL_VAR *tmout_var;
  int tmout_len, result;
  SigHandler *old_alrm;

  set_current_prompt_level (1);
  global_command = (COMMAND *)NULL;

  /* Only do timeouts if interactive. */
  tmout_var = (SHELL_VAR *)NULL;
  tmout_len = 0;
  old_alrm = (SigHandler *)NULL;

  if (interactive)
    {
      tmout_var = find_variable ("TMOUT");

      if (tmout_var && var_isset (tmout_var))
    {
      tmout_len = atoi (value_cell (tmout_var));
      if (tmout_len > 0)
        {
          old_alrm = set_signal_handler (SIGALRM, alrm_catcher);
          alarm (tmout_len);
        }
    }
    }

  QUIT;

  current_command_line_count = 0;
  /*この関数が、パーサなどを呼び出しコマンドオブジェクトを生成する。*/
  result = parse_command ();

  if (interactive && tmout_var && (tmout_len > 0))
    {
      /*シグナルハンドラを解除する。*/
      alarm(0);

      set_signal_handler (SIGALRM, old_alrm);
    }

  return (result);
}

```

このコードを見ると、タイムアウトはシグナルハンドラとして実装されていることがわかる。
alarm()システムコールは０より大きい整数が渡されると、カーネルがそのプロセスに対してSIGALRMを発行するように設定する。
bashがシグナルを受け取ると、set_signal_handler()によって設定された関数が呼び出される。
この関数がbashを終了させる。
alarm()システムコールに０を渡すと、その設定が解除される。（man alarmを参照)
bashはこの手順を繰り返している。

このコードを見るとおもしろいことがわかる。
上のコードではコマンドのパースが終了したあとにシグナルハンドラを解除するという動作を行っている。
つまり、こんなことが実際に起こるのかはわからないが、コマンドの入力が完了したとしても、
待機時間中にコマンドの解析が終わらなかった場合、bashは終了すると思う。（おもしろい）


TMOUTを1秒にして、パースに1秒以上かかるコマンドを入力すれば、確認できるが
コマンドが思いつかなかったので、実験はしていない。

***********************************
[追記]
コマンドを思いついたので追記する。

```sh
$ TMOUT=1; echo {1..255}{1..255}{1..255}{1..255}
```

このコマンドを実行すれば、大体の場合はブレース展開している間にタイムアウトになると思う。
自分の場合はパース中にタイムアウトした。

ちなみに、

```sh
$ {1..255}{1..255}{1..255}{1..255}
```
はバッシュのメーリングリストで見た。
単体で実行すると、メモリの使いすぎでプロセスがキルされる。
***********************************


もしこの考え方が正しかったら、bashのマニュアルは
”コマンドのパースにTMOUT秒以上の時間がかかったらbashは終了します。”
と書いたほうがいいと思った。

bashは歴史のあるプログラムであり、いろんな人の目が入っていることはわかるが、
このタイムアウトの設定コードはあまりきれいに思えないのは自分だけだろうか。
何かしらの理由があってこのような書き方になっているとは思うが、
もうちょっといい書き方があるのではないかと思う。
なので、今度の記事ではこのへんをもうちょっと詳しく見てみようと思う。


自分の考えは完全に間違っている可能性があります。
もし知っている人は教えてくれると嬉しいです。
Python3でbasemapをインストールする際に出力されるエラーへの対処

# basemapのインストール

地理データなどを表示するために役立つbasemapは[ここから](https://github.com/matplotlib/basemap)ダウンロードできる。
しかし、basemapを使用する際に必要なlibgeosをビルドする際に問題が起きる。

basemapのリポジトリのREADEME.mdのインストール方法は、以下のように掲示されている。

```sh
cd geos-3.3.3
./configure --prefix=$GEOS_DIR 
make; make install
```

2行目まではパスするが、3行目でマクロに関するエラーが出力される。
このエラーには、環境変数のCXXにコンパイラの情報を設定することで解決できる。

```sh
export CXX="g++ -std=c++98"
```

## matplotlibの呼び出し

再度インストールを実行しようすると，今度はmatplotlib関連のエラーが出力される。
このエラーには、以下のコマンドを入力することで対処できる．

```sh
pip install --user git+https://github.com/matplotlib/basemap.git
```

##### 参考
https://gis.stackexchange.com/questions/289409/error-building-geos-on-ubuntu-18-04
iwd で無線を使う

iwd ([iNet Wireless Daemon](https://iwd.wiki.kernel.org/)) は切断時や電波不良時の高速な再接続を目指してIntelが開発した[wpa_suplicant](https://ja.wikipedia.org/wiki/Wpa_supplicant)と[hostapd](https://w1.fi/hostapd/) の代替ソフトウェアで、wpa_supplicantとhostapdの組み合わせでできることはたいていできます。その使い方を紹介します。Ubuntu 20.04 と Debian 11 で確認

# /etc/iwd/main.conf

```config:/etc/iwd/main.conf
[General]
UseDefaultInterface=true
DisableANQP=false
RoamThreshold=-60
```

を作ります。

# [NetworkManager](https://ja.wikipedia.org/wiki/NetworkManager) と共に使う

```config:/etc/NetworkManager/conf.d/nm.conf
[device]
wifi.backend=iwd
wifi.iwd.autoconnect=yes
```

を作ります。

# インストール

インストールした瞬間に無線が使えなくなる可能性があるから注意して下さい。

1. `apt-get install iwd`
1. `systemctl disable --now wpa_supplicant`
1. `systemctl restart NetworkManager`
1. NetworkManagerに設定した接続情報を一度削除してもう一度無線SSIDとそのパスフレーズを再登録

でNetworkManagerがiwdを使えるようになります。

# NetworkManager と併用しない場合
## ifconfig と併用する場合
`pre-up /usr/bin/iwctl --passphrase=パスフレーズ station DEVICE connect SSID`とします。詳しくは[ifupの説明](https://qiita.com/JhonnyBravo/items/135aa654d7a4b5c64c34#pre-up-command) を参照。

## iwd にネットワークの設定をさせる
NetworkManager も ifup も使わずに iwd 単体でネットワーク設定する場合です
### EnableNetworkConfiguration=true
```config:/etc/iwd/main.conf
[General]
EnableNetworkConfiguration=true
```

と書いておくと、iwdがDHCPクライアント（アクセスポイント（SSID)に繋ぐ場合）およびDHCPサーバー（アクセスポイントになりSSIDを提供する場合）として動作します。IPアドレスを自分で決める設定もできます。

### SSID に接続しにいく場合
`iwctl --passphrase=パスフレーズ station DEVICE connect SSID` とします。eduroam などもっと複雑な設定をする場合は[こちら](https://iwd.wiki.kernel.org/networkconfigurationsettings) を参照して `ナントカ.8021x` というファイルを作成する必要があります。

# iwd にSSIDを提供させる
アクセスポイントにして他の機器からの接続を受け付けられるようにする設定です。
1. `apt-get install crda`
1. `/etc/default/crda` に `REGDOMAIN=JP` を設定
1. `iwctl device wlan0 set-property Mode ap`
1. `iwctl ap wlan0 start-profile SSID パスフレーズ`

接続して来た機器のIPアドレスなどを自動的に設定するように、iwdにDHCPサーバーもやらせる場合は[ここ](https://iwd.wiki.kernel.org/ap_mode) を見て下さい。iwd と組み合わせるDHCPサーバーに[systemd](https://qiita.com/kakinaguru_zo/items/f3dbf5c44bf28fc27f9c) や [ISC DHCPサーバー](https://qiita.com/4201tosiyuki/items/1c604b4a235fac80fb4b#4isc-dhcp-server%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%97%E8%A8%AD%E5%AE%9A%E3%81%99%E3%82%8B) や [dnsmasq](https://qiita.com/lex_naturalis/items/dc64b536bd4ae478cecc#dnsmasq%E3%81%AE%E8%A8%AD%E5%AE%9A) を使うこともできます。
elasticsearchインストール

# 公式さま

https://www.elastic.co/guide/en/elasticsearch/reference/7.13/deb.html#deb-repo

# 公式さまによると
リポジトリ？が最新のものになってしまう？
バージョンが新しいものが来る？

```
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -
sudo apt-get install apt-transport-https
echo "deb https://artifacts.elastic.co/packages/7.x/apt stable main" | sudo tee /etc/apt/sources.list.d/elastic-7.x.list
sudo apt-get update && sudo apt-get install elasticsearch
```

# 開始

```
sudo systemctl start elasticsearch.service
```

# 確認

```
ps aux | grep elasticsearch
ifconfig
curl -XGET 127.0.0.1:9200/_cat/health?v&pretty
curl http://localhost:9200/_nodes/plugins?pretty
```
Pythonで九九表を一行で作る

# 概要
プログラミングのテスト前日、Pythonのテキストにある演習問題にこうあった。
> 次のような九九表を作成してみよう

```
1 2 3 4 5 6 7 8 9
2 4 6 8 10 12 14 16 18
3 6 9 12 15 18 21 24 27
4 8 12 16 20 24 28 32 36
5 10 15 20 25 30 35 40 45
6 12 18 24 30 36 42 48 54
7 14 21 28 35 42 49 56 63
8 16 24 32 40 48 56 64 72
9 18 27 36 45 54 63 72 81
```

コードゴルファー（クソ弱い）としてはこれを一行で書いてみたい。
というか書けるの、これ？ググってもだれもやってない。

だったらやるしかないじゃない。
明日がテストなので足早に、テンション高めで書いていきます。



......ということで完全にネタです。
個人の趣向ですが、フォーマッタは使用します。
普通に書いたほうが短いとかいうツッコミはNGです。

# 実際に書いたコード

実際に考えたのは次のようなコードです。

```python:
print(*[f"{[i*j for i in range(1,10)]}"[1:-1].replace(",", "") for j in range(1,10)], sep="\n")
```

104byte、ぼちぼちの出来栄えである。これで、問題とおなじ出力を得られる。

# 中身のお話


発想としては

- どうやっても``for``文か``map``を２つ使う。
- 一度文字列に変換して、``,``や``[]``を削除しよう。

の２つが柱です。まず、

```python
[[i*j for i in range(1, 10)] for j in range(1,10)]
```

で、表のデータを作ってしまいます。これに一つ工夫をして、

```python
[f"{[i*j for i in range(1, 10)]}" for j in range(1,10)]
```

とすると、二重のリストではなく、文字列のリストになります。
この文字列の一文字目と最終文字を消すために``[1:-1]``を、``,``を消すために``.replace(",", "")``を入れます。これを改行区切りで出力すれば、最初のコードになります。

# 試行錯誤のあと

実は最初は``map``を使おうと思っていました。

```python
print(*map(lambda x: f"{list(map(lambda y: x*y, range(1, 10)))}"[1:-1].replace(",", ""), range(1, 10)), sep="\n")
```

リスト内包表記にかえれば最初のコードと同じになります。122byteあるので、ボツになりました。

# 終わりに

ここまでお付き合いくださり本当にありがとうございます。
テスト前日ということもあり、マジで駄文ですが楽しんでいただければ幸いです。
みなさんもぜひ、一度考えて見てください。これより短いのが見つかると嬉しいです。

----------
追記
コメント欄で、答えがでました。
elasticsearch消す

#elasticsearch消す

```
sudo apt-get --purge autoremove elasticsearch
sudo rm -rf /etc/elasticsearch
sudo rm -rf /var/lib/elasticsearch/
```

# 権限とかおかしかったら変更

```
sudo chown root:root  elasticsearch
```

# ダウングレードできない？
elasticsearchはダウングレードできない？
https://discuss.elastic.co/t/unwanted-upgrade-elasticsearch-version/191841
https://qiita.com/HiroakiYamashi/items/3457e43b252fcd6d20d4

# 参考
https://www.it-swarm-ja.com/ja/elasticsearch/ubuntu%E3%81%AFelasticsearch%E3%82%92%E3%[…]%88%E3%83%BC%E3%83%AB%E3%81%97%E3%81%BE%E3%81%99/959927845/
MacとRaspberry Piでshとbashの違いを確認

# 環境
macOS Catalina 10.15.7
Raspbian 10.3

# 実行するシェルスクリプト 
```test_sh.sh
#!/bin/sh
echo {0..10}                                                                                  
```

```test_bash.sh
#!/bin/bash
echo {0..10}                                                                                  
```

# Mac上で実行
```
$ chmod +x test_sh.sh
$ chmod +x test_bash.sh
```
実行権限を与える。それぞれ実行すると、

```
$ ./test_sh.sh
0 1 2 3 4 5 6 7 8 9 10

$ ./test_bash.sh
0 1 2 3 4 5 6 7 8 9 10
```
`sh`でも`bash`でも同じ結果が得られる。

`/bin/sh`のシンボリックリンクを調べてみる。

```
$ ls -l /bin/sh
-rwxr-xr-x  1 root  wheel  31440  9 22  2020 /bin/sh
```
`bash`にリンクしているわけでない

```
$ /bin/sh --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin19)
Copyright (C) 2007 Free Software Foundation, Inc.

$ /bin/bash --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin19)
Copyright (C) 2007 Free Software Foundation, Inc.
```
`/bin/sh --version`と`/bin/bash --version`は同じ内容が返ってくる。

Macでは`sh`と`bash`はほぼ同じもの。違いがあるとしたら、

```check_option.sh
set -o
```

```
$ sh check_option.sh | grep posix
posix          	on

$ bash check_option.sh | grep posix
posix          	off
```
`posix`と言うオプションが`bash`ではoffで`sh`だとonになっている点。

# Raspberry Pi
```
$ chmod +x test_sh.sh
$ chmod +x test_bash.sh
```
実行権限を与える。それぞれ実行すると、

```
$ ./test_sh.sh
{0..10}

$ ./test_bash.sh
0 1 2 3 4 5 6 7 8 9 10
```
`sh`と`bash`で得られる結果が異なる。

`/bin/sh`のシンボリックリンクを調べてみる。

```
$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4  2月 14  2020 /bin/sh -> dash
```
`dash`にリンクしている。

「[Ubuntuの/bin/shはbashではなくdash](https://siguniang.wordpress.com/2013/05/12/dash-is-not-bash/)」によると、
> ubuntu の /bin/sh は Almquist shell (ash) から派生したシェル Debian Almquist shell(dash) へのシンボリックリンクになっており、bash で OK な( … ) のシンタックスを dash は対応していないから。

Raspbianはubuntuと同様に`/bin/sh`が`dash`である。そのため、`/bin/sh`を`bash`感覚で使っていると、`bash`のシンタックスが使えないことがあるらしい。

# まとめ
- macOSでは`sh`と`bash`はほぼ同じもの、結果として`sh`と`bash`の実行結果が一致した。
- Raspbianでは`sh`と`dash`にシンボリックリンクが張られている。`bash`のシンタックス（ブレース展開`{1..10}`）が`dash`では対応していなかったため、結果として`sh`と`bash`の実行結果が異なった。

# 参考
- https://qiita.com/yn-misaki/items/6fcfab082dd664f10d4e
- https://siguniang.wordpress.com/2013/05/12/dash-is-not-bash/
- https://rcmdnk.com/blog/2016/09/20/computer-linux-bash/
- https://qiita.com/laikuaut/items/642aa329a8d214a2cccb
F# on WSL2 でグラフ描画

通常F#はWindows上で使っているが、諸事情によりWSL上で使っていた際にグラフ描画でつまづいたので、方法を記録しておく。

# 環境
- WSL2
- Ubuntu 20.04.2 LTS
- .NET 5.0.8
- F# 5.0
- F# Interactive version 11.4.2.0


# 方法
F#（や.NET）でのグラフ関係のライブラリはいろいろあるが、WindowsのAPIに依存していたり不足するファイルをインストールしなければならなかったりして、なかなかうまくいかなかった。そんな中で、グラフを画像ファイルとして保存できた方法を2通り紹介する。グラフをウィンドウとして表示させるのはまた面倒そうなので今回は避けた。
なお、いずれの方法も、Xサーバー（私はVcXsrvを使用）を起動しないと途中で停止してしまう（グラフィック系だから？）。Xサーバー等の導入は[こちら](https://astherier.com/blog/2020/08/run-gui-apps-on-wsl2/ "WSL2＋Ubuntu 20.04でGUIアプリを動かす")などを参照。

## ScottPlot

https://swharden.com/scottplot/

> Linux and MacOS users may need to install libgdiplus to use ScottPlot

とあるのでlibgdiplusをインストールする。

```shell
sudo apt install libgdiplus
```

### 簡単な例
```fsharp
#r "nuget: ScottPlot"
open ScottPlot
let x = [| 1. .. 10. |]
let y = x |> Array.map (fun n -> n * n)
let plt = Plot()
plt.AddScatter(x, y)
plt.SaveFig("hoge.png")
```

![hoge.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420816/905a00fd-b72f-0d08-5793-bcb5a1c9ba8a.png)


## Plotly.NET

https://plotly.net/

こちらも単体では動かず、以下のようなエラーが出た。

```
error while loading shared libraries: libxkbcommon.so.0: cannot open shared object file: No such file or directory
```
```
error while loading shared libraries: libgtk-3.so.0: cannot open shared object file: No such file or directory
```

そのため追加でインストールをする。

```shell
sudo apt install libxkbcommon0 libgtk-3-0
```

<details><summary>パッケージ名の検索について</summary><div>

今回は `libxkbcommon.so.0` と `libgtk-3.so.0` というファイルが不足しているためこれをインストールする必要があるが、 `apt install` では欲しいファイルが含まれている **パッケージ名** を指定する必要がある。このようなときに `apt-file` コマンドが使える。[こちら](https://blog.amedama.jp/entry/2016/05/29/160545 "Ubuntu: apt-file でファイルが含まれるパッケージを調べる")や[こちら](https://www.atmarkit.co.jp/ait/articles/1709/08/news020.html "【 apt-file 】コマンド――特定のファイルが収録されているパッケージを探す")を参考にした。インストールや使い方の簡単な説明は以下の通り。

```shell
sudo apt install apt-file
sudo apt-file update # パッケージリストを取得・更新
apt-file -l search <ファイル名> # -lオプション：パッケージ名のみ表示
```

</div></details>


### 簡単な例
```fsharp
#r "nuget: Plotly.NET, 2.0.0-preview.6"
#r "nuget: Plotly.NET.ImageExport, 2.0.0-preview.6"
open Plotly.NET
open Plotly.NET.ImageExport
let x = [ 0. .. 10. ]
let y = x |> List.map (fun n -> n * n)
Chart.Point(x, y)
|> Chart.savePNG("hoge")
```

![hoge.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420816/201c3bf5-89fa-5f1a-5150-db1a9d76f63f.png)
コマンドラインを学ぶ２

#ファイルのコピー
ファイルをコピーするには　cpコマンドを使い

```
cp コピーするファイル名　新しいファイル名
```
とすることでコピーすることができます。

#ディレクトリのコピー
cpコマンドでは　-r をつけることで、ファイルだけでなくディレクトリもコピーすることができます。

```
cp -r コピーするディレクトリ名　新しいディレクトリ名
```
とすることでコピーできます。

#ファイルの削除
ファイルを削除するには

```
rm ファイル名
```
　とるすることで削除できます。

#ディレクトリの削除
　rmコマンドは、　-r をつけることでディレクトリも削除することができます。


```
rm -r ファイル名
```
無料プログラミングスクールって闇深いの？

#無料プログラミングスクール
無料プログラミングスクールって実際どうなの？と思ったので調べてみました。

[無料プログラミングスクールまとめ](https://careerhub.jp/free-programming-school-10/)を参考にしました。

#有料プログラミングスクールとの違い
<h3>年齢制限付きが多い</h3>

<p>「年齢制限」を設けている無料スクールがあり、多くは30際以下と限定しています。その理由として前述した「無料スクールの収益は卒業生を転職/就職させた際に発生する成功報酬」というビジネスモデルだからです。</p>

<p>無料スクールの運営会社が、卒業生を企業へ提案(就業支援)する場合に「弊社のスクールでプログラミングの基礎を学習しています」という提案の仕方をします。受け入れる企業側も「テスター、運用監視のポジションで若年層が欲しいけど、全くの未経験は」という課題があり、無料スクールの卒業生はそこにフィットします。</p>

例えば[0円スクール](https://careerhub.jp/zero-school-reputation/)とかは、就職先が１社しかないです。

[0円スクールの就職先は1社だけ！？](https://careerhub.jp/zero-school-work/)を参考にしました。

<p>もちろん年齢制限を設けていないスクールもあり、無料で体験入学し、その後有料コースへ切り替えが可能なスクールもあります。</p>

<p>また運営会社経由で転職が成功した場合に、受講料をキャッシュバックする制度を設けているスクールもありますGEEK JOBとかがこれに当たります。</p>

[geekjobの口コミ](https://careerhub.jp/geek-job_20201019/)はこちら
[geekjob(有料)の口コミ](https://careerhub.jp/geek-job-premium-job-change/)はこちら

<h3>転職が条件</h3>

<p>無料スクールを受講する条件として「運営会社を通じて転職活動をする」事が前提となっています。理由として、スクール卒業生を企業へ売り込んで、転職が成功したときの成功報酬で収益をあげているからです。</p>

<p>「1年以内にIT業界への就職、転職の意思がある」など、コミットする必要はありませんが、就職(転職)の意思を伝える必要があります。</p>

<h3>転職先の企業が限定される可能性がある</h3>
<p>無料スクール卒業後の転職先は<span class="marker-under">受託開発企業かSESを専門としているシステム会社に限定されることがあります。</span>受託開発とはクライアントから依頼を受けて、自分が所属している会社の中でシステム開発をする会社で、SES専業会社は客先常駐を専門に実施している企業です。</p>
<p>エンジニア転職で人気な会社はプロダクトを自社開発している会社です。</p>

<p>しかし無料スクール卒業後の転職先は、受託開発企業かSES専業会社に限定されることがあります。理由として、プロダクトを自社開発している会社の求人は人気があり、倍率が高くなるため、スクール運営会社から提案しても書類や面接を通過しずらい可能性があります。</p>

<p>もちろん熱意ややる気でプロダクトを自社開発する企業への就職も可能なため、あきらめずにチャレンジする価値はあります。</p>

<p>別の方法として、未経験からSES専業会社でスキルを磨いて、自社プロダクトを開発する会社へ転職することも将来的に可能です。プログラムのスキルを身につけ、経験を積めば需要の高いエンジニアとなれます。</p>

<h3>学べる言語が限られているケースがある</h3>

<p>無料プログラミングスクールでは、学べる言語が限られているケースがほとんどです。同記事の「無料プログラミングスクールと有料プログラミングスクールの違い」でも解説しましたが、無料プログラミングスクールの場合は企業へ転職支援しやすい言語のみ受講できることがほとんどです。具体的には以下の言語が無料で学べます。</p>

<ul><li>Java</li><li>JavaScript</li><li>Python</li><li>Ruby</li><li>HTML/CSS</li></ul>

<h3>人数が限られているケースがある</h3>
<p>無料プログラミングスクールでは、人数制限が設けられている場合があり、注意が必要です。具体的には「一日何人」や「期間限定〇名まで」などです。</p>

#やる気があるならお金払ってプログラミングスクール通おう

[給付金がもらえるプログラミングスクール](https://careerhub.jp/benefits-programming-schools/)とかで流行りの技術を学ぶのも賢いと思います。
latexにおける複数行のコメントアウト

# はじめに
大学一年生の際に、少人数クラスを担任してくださっていた教授が教えてくれた`\if0`と`\fi`を用いた複数行のコメントアウト（ブロックコメントアウト）の方法が調べてもあまりでてこなかったため、意外と知られていないのかなと思い、記事を書いています。

# コメントアウト方法

一行の場合は`%`を使います。
複数行のときは`\if0`と`\fi`で囲みます。
またはcommentパッケージを用いた方法もあります。

```latex
% 一行コメント

\if0
複数行コメント
\fi

% commentパッケージを利用した方法
% プリアンブルに以下を追加
\usepackage{comment}
% 利用する場合はbegin-endで囲む
\begin{comment}
複数行のコメント
\end{comment}
```

複数人で共有するようなlatexファイルならcommnetパッケージを使った方法のほうがすぐコメントとわかるのでいいのかなと思っています。
しかし、一人で編集するようなlatexファイルで、一時的に複数行をコメントアウトしたい場合などにパッケージの追加削除なども管理するのは面倒です。
そこで今回紹介した`\if0`と`\fi`を用いたコメントアウトの方法が個人的に便利だなと感じています。
elasticsearchの7.9.3をインストール

# 初めに
elasticsearchの7.9.3がインストールしたかったので忘れぬようメモ。


#公式さま
https://www.elastic.co/guide/en/elasticsearch/reference/7.9/deb.html#deb-repo


# 公式さま

```
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.9.3-amd64.deb
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.9.3-amd64.deb.sha512
shasum -a 512 -c elasticsearch-7.9.3-amd64.deb.sha512 
sudo dpkg -i elasticsearch-7.9.3-amd64.deb
```

（.deb展開してよくわからないことになってしまったので、したらいけないのでしょうか……？）


# 取得

```
$ ls
elasticsearch-7.9.3-amd64.deb  elasticsearch-7.9.3-amd64.deb.sha512
```

# 開始

```
$ sudo systemctl start elasticsearch
```


# 確認

```
$ systemctl status elasticsearch
● elasticsearch.service - Elasticsearch
     Loaded: loaded (/lib/systemd/system/elasticsearch.service; disabled; vendo>
     Active: active (running) since Tue 2021-08-03 03:17:44 UTC; 1min 10s ago
       Docs: https://www.elastic.co
   Main PID: 22936 (java)
      Tasks: 49 (limit: 2282)
     Memory: 1.2G
     CGroup: /system.slice/elasticsearch.service
             ├─22936 /usr/share/elasticsearch/jdk/bin/java -Xshare:auto -Des.ne>
             └─23126 /usr/share/elasticsearch/modules/x-pack-ml/platform/linux->

Aug 03 03:17:23 ubuntu2004.localdomain systemd[1]: Starting Elasticsearch...
Aug 03 03:17:44 ubuntu2004.localdomain systemd[1]: Started Elasticsearch.
```


# 確認

```
$ curl http://localhost:9200/_nodes/plugins?pretty
{
  "cluster_name" : "elasticsearch",
  "nodes" : {
    "x4dTdr4DTSO7cEqDrTnzvw" : {
      "version" : "7.9.3",
```