OmniAICreator/Qiita-1.07M huggingface dataset:
[初めてのIntro.js]アプリ起動時のチュートリアルを実装する

#環境

Rails 5.2.4.1

#Intro.jsとは

Javascriptのライブラリです。
アプリなどを起動したときに出てくるチュートリアルを実装するためのものです。
このような動きをします。
![intro.jfif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561934/108466c1-1ad1-2e63-2420-906ed728c3db.jpeg)

>公式HP:https://introjs.com/

#手順
[1．必要ファイルをダウンロード・配置](#1-必要ファイルをダウンロード・配置)
[2．チュートリアルを表示させたい画面でファイルの読み込み](#2-チュートリアルを表示させたい画面でファイルの読み込み)
[3．チュートリアル番号とメッセージの挿入](#3-チュートリアル番号とメッセージの挿入)
[4．チュートリアルをスタートするための関数呼び出し](#4-チュートリアルをスタートするための関数呼び出し)

順に見ていきます。

#1.必要ファイルをダウンロード・配置

>https://github.com/usablica/intro.js/tags

こちらにアクセスし、更新日時の最も新しい「Tags」の「zip」をクリック。PCにzipファイルをダウンロードします。

ダウンロードしたら、zipファイルを右クリックし「すべて展開」。

展開したフォルダの中から「intro.js」と「introjs.css」を探します。

「intro.js」は「/assets/javascripts/intro.js」

「introjs.css」は「/assets/stylesheets/introjs.css」

となるように各ファイルをコピペすると配置は完了です。

#2．チュートリアルを表示させたい画面でファイルの読み込み

表示させたい画面のHTMLファイルを開きます。
head部分に下記を追記します。

```erb:×××.html.erb
<head>
...
...
<script src="js/intro.js"></script>
<link rel="stylesheet" href="css/introjs.css" type="text/css">
</head>
```
※この際、「src=""」および「href=""」内のパスについては編集の必要はありません。

以上でファイルの読み込みは完了です。

#3.チュートリアル番号とメッセージの挿入

![intro.jfif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561934/b3ac517a-d6e3-41a3-a176-cc9af397c7aa.jpeg)

左上に出てくる赤丸の数字と、説明文を先ほどと同じファイルに記述します。

```erb:×××.html.erb
<div data-intro="説明のテキストを入力します" data-step="1">
<div data-intro="説明のテキストを入力します" data-step="2">
```

#4.チュートリアルをスタートするための関数呼び出し

最後に設定した説明文を表示させましょう。

「body閉じタグ」の直前に以下を追記します。

```erb:×××.html.erb
...
   </div>
   <script>
    jQuery(function(){
        introJs().start();
    });
   </script>
   </body>
</html>
```

#サンプル

実際に動作確認できたHTMLファイルです。

```html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
    <script src="js/intro.js"></script>
    <link rel="stylesheet" href="css/introjs.css" type="text/css">
  </head>
  <body>
   <div class="icons clearfix">
    <div class="box">
     <div class="col-xs-2 col-md-1 left icon">
      <img src="/assets/log.jpg" data-intro="過去の記録が見れます" data-step="1">
     </div>
     <div class="col-xs-2 col-md-1 right icon" data-intro="110番通報します" data-step="2">
      <img src="/assets/police.jpg">
     </div>
    </div>
    <div class="col-xs-4 col-md-2 center icon">
     <img src="/assets/microphone.jpg">
    </div>
    <div class="box">
     <div class="col-xs-2 col-md-1 left icon" data-intro="ボイス「録音を開始します」ON/OFF" data-step="3">
      <img src="/assets/sound.jpg">
     </div>
     <div class="col-xs-2 col-md-1 right icon" data-intro="N国党に通報します" data-step="4">
      <img src="/assets/nkoku.png">
     </div>
    </div>
   </div>
   <script>
    jQuery(function(){
        introJs().start();
    });
   </script>
   </body>
</html>
```
データサイエンティスト育成講座　Chapter2　2日目

今日はChapter2に関して進めた。
例によって環境はDockerを使用。

主に使用したライブラリは以下の内容

- Numpy
- Scipy
- Pandas
- Matplotlib

## Numpyメモ
基本的には前回まででNumpy自体には触っているが、チョコチョコわからない点が出てきたりしているので都度調べながら進めている

データフレームの計算になると、PandasのDataFrameを使うことが多くなるのかもしれない。そう考えると、Numpyではここの計算であったり、乱数の生成によくお世話になるんじゃないだろうか。

Numpyの乱数生成としては、ここでは

> np.random.randn()

を使うことが多いように見える。
randn関数はstandard normalな乱数。つまり正規分布な数値を生成するようだ
[randn](https://docs.scipy.org/doc/numpy-1.15.1/reference/generated/numpy.random.randn.html)

乱数の生成としては、randn以外にもいくつかあり、最後の最後にはuniformが出てくることになる。
複数の乱数を生成するときには

> np.random.randn(1000)

と書くことで1000個の乱数を作成することができる。この場合、返却値は配列になる

また、順序だった数値を取得するのに

> np.arrange(1000)

のような使い方もあった。上記の場合は、1〜１０００までの配列を返す。
グラフを描画するときのX軸の値として使用した。

## Scipyメモ
行列計算に主に使用した。
行列計算自体をかなり忘れているため、読みながら進めるものの、行列の固有値だとか逆行列だとか、確かにそういうのがあったような気がするなぁ・・・というレベル。
必要に応じてこの辺りは復讐が必要になるんだろう。

方程式の解法として、Newton法というやり方を知った。

> from scipy.optimize import newton
> newton(sample_function, 0)

というような記述でsample_functionが引数の0だったときの値。
つまりはf(x) = 0 だったときのｘを求めてくれるというもの。

例題としては、x**2 + 2*x + 1の式。つまりはf(x)=x^2+2x+1の解をNewton関数に当てはめて答えを求めていた。
ところが、f(x)=2x^2+2x+1をNewton関数に食わせてみるとエラーになった

> Failed to converge after 50 iterations, value is 0.6246914113887032

５０iterationsやってみたけれどダメだったということらしい。

> newton(sample_function2,0,maxiter=1000)

Newton関数は引数としてこのiterationを指定できるようなので、試しに１０００回転ほどさせてみたけれど結局はダメだった。
この辺りは、Newton関数自体の特性だとかをちゃんとわかっていないからうまく行かないんだろうけれど、なかなかどうしたものか・・・という気持ちになった。


## Pandasメモ
基本的んはふんふんと読んでいった。
複数のDataFrameをRDBのテーブルのように結合する方法としてmerge関数が用意されているが、Chapter場ではオートな結合しかなく、結合条件を手動で指定する方法が見当たらなかった。

これに関しては、公式のReferenceに詳しい例題付きで書かれていた。

[pandas.DataFrame.merge](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.merge.html)

よくよくみてみると、Chapterではpd.merge(data_frame1, data_frame2)というような呼び出し方だが、リファレンスではdata_frame1.merge(data_frame2)という呼び出し方だ。
merge関数の第１引数にはselfがあるので、書き方として双方をサポートしているということなんだろう。

調べるときにどうしても日本語訳として書かれている記事が多くHitしてしまい、そちらを参照したくなる衝動にかられてしまうのだが、公式をしっかりと読むという癖をつけたほうがいいと思うのでまずはそちらに挑戦するようにしていく。
涙を流しながら。

## Matplotlibメモ
意味をちゃんと理解しているかどうかは別にして、グラフという形で描画されるものがあると少し嬉しくなるのは疲れてきているせいであろう。

> import matplotlib.pyplot as plt
> plt.plot(x, y, "o")

という形で描画させるのだが、この"o"部分を適当に変えてみたら、Plotされたものが変わった。"x"ではバツになったのは予想通りだったけれど、例えば"g"とかにしてみると、棒グラフになった。
Referenceをみてみると、gにすることで棒グラフになるのではなく、そもそもデフォルトが棒グラフで、gは色指定が緑という形だった。

[matplotlib.puplot.plot](https://matplotlib.org/3.1.0/api/_as_gen/matplotlib.pyplot.plot.html)

他にもいくつかPlotのMarkersは指定できるようなので、面白がって試してみるといい

## おしまい
なんとかChapter2まで終わらせることができた。
覚えればいいだけなので進められるのだが、1Chapter進めるのになかなか時間が取れないのが痛いな。

ここまでが、基本的なPythonとライブラリの使い方となり、次のChapterからは実際の統計学や分析に入っていくことになるので一気に難易度は上がっていくことになるんだろう。
Kotlinジェネリクス - 複数の制約のあるジェネリクス

分かっているつもりで、たまに、これどうやって表現するんだっけ？となることがあるKotlinのジェネリクスについて一発ネタ。詳細は以下のページ読めで終わってしまうものですし、Qiita内でも何番煎じだかというものではあります。
[ジェネリクス - Kotlin Programming Language](https://dogwood008.github.io/kotlin-web-site-ja/docs/reference/generics.html)

# 複数の制約のあるジェネリクス

Javaで以下のようにinterface Keyを継承したEnumがいくつかあるとして、

```java
interface Key {}
enum Main implements Key {}
enum Sub implements Key {}
```

ジェネリクス記述として、任意のEnumをあらわす記述は、メソッド、インターフェース、それを継承したクラスの順で以下のように書きます。

```java
public <K extends Enum<?>> String getString(K key);
interface Hoge<K extends Enum<?>> { }
class Fuga<K extends Enum<?>> implements Hoge<K> { }
```

interface Keyを実装したEnumという複数の制約をつけたい場合は、`&`で条件を続けます。

```java
public <T extends Enum<?> & Key> String getString(T key);
interface Hoge<K extends Enum<?> & Key> { }
class Fuga<K extends Enum<?> & Key> implements Hoge<K> { }
```

あまり使わないものの、Javaではこういう表現が可能です。

さて、これをKotlinで書くにはどうすればいいでしょうか？
最初の任意のEnumの場合、以下のように、幾分Javaよりもシンプルに、似たような記述で表現可能です。

```kotlin
fun <K : Enum<*>> getString(key: K): String {}
interface Hoge<K : Enum<*>> {}
class Fuga<K : Enum<*>> : Hoge<K> {}
```

interace Keyを実装したEnumを表現する場合は、Javaのように`&`で続けることはできず、外に`where` を使って制約を表現します。

```kotlin
fun <K> getString(key: K): String where K : Enum<*>, K : Key {}
interface Hoge<K> where K : Enum<*>, K : Key {}
class Fuga<K> : Hoge<K> where K : Enum<*>, K : Key {}
```

となります。初めて知ったときは
ええっ、そこにそうやって書くの？
ってなりました。
でも分かってしまえば、制約条件を列挙するだけなのでJavaよりもわかりやすそうではありますね。

上記は一行に圧縮して書いちゃいましたが、改行した方が可読性の面でよいですね。
IntelliJではタイプパラメータがそろうよう、いい感じにインデントしてくれます。
Javaの記述法ではこういう書き方はできないのでよい感じです。

```kotlin
fun <K> getString(key: K): String
        where K : Enum<*>,
              K : Key

interface Hoge<K>
        where K : Enum<*>,
              K : Key

class Fuga<K> : Hoge<K>
        where K : Enum<*>,
              K : Key
```

なお、`where`は複数の制約をつけるとき限定ではなく、制約が一つの時でも使えます。

```kotlin
fun <K> getString(key: K): String where K : Key {}
interface Hoge<K> where K : Key {}
class Fuga<K> : Hoge<K> where K : Key {}
```

ただ、こちらの場合は、whereを使わない方が何に対してどのような制約なのかわかりやすいので

```kotlin
fun <K : Key> getString(key: K): String {}
interface Hoge<K : Key> {}
class Fuga<K : Key> : Hoge<K> {}
```

こちらの書き方の方が可読性の面でも良さそうです。
RxTestでVoidのEventをテストする

RxTestのObserverを使ってVoidイベントの発火をテストするために以下のようなことをするとコンパイルに通りません。

```swift
// ViewModel.swift
struct ViewModel {
  let somethingOccurred: Signal<Void>
  ...
}

// ViewModel_Test.swift
let observer = testScheduler.createObserver(Void.self)
vm.somethingOccurred
  .emit(to: observer)
  .disposed(by: disposeBag)

expect(observer.events).to(equal([.next(100, ())])) // Compile Error!! Expression type Protocol type 'Any' cannot conform to 'Equatable' because only concrete types can conform to protocols
```

## 原因
なぜこうなるかというと、VoidがEquatableではないからです。

Voidはなにかというと空のtupleです。

```swift

public typealias Void = ()
```

tupleはEquatableではないのでVoidもそうなります。

## 対策

```swift

expect(observer.events).to(haveCount(1))
expect(observer.events[0].time).to(equal(100))
```

## 参考
https://stackoverflow.com/questions/59467791/rxtest-how-to-compare-eventvoid-as-void-is-not-equatable

https://nshipster.com/void/
Decodableで未知のenumの値がきたときの対策

## 課題
APIのレスポンスをDecodableを使ってstructにdecodeしたりしますよね。
そのstructにenumが含まれていた場合にこんな感じになります。

```swift
struct Hoge: Decodable {
  enum Type: String, Decodable {
    case type1
    case type2
  }

  let type: Type
  ...
}
```

しかし、将来的に仕様の追加があり、typeの種類が増やしてしまうと、上記のようにしていると過去にリリースしたアプリがdecodeに失敗してしまいます。

enumの種類が増やすということはAPIの後方互換性のない変更となるので、クライアント側からするとこれは致し方ない問題ではあります。

が、諸事情で、decode失敗ではなく知らないenumが来たとき用の処理を入れておいてAPIバージョンあげずにAPI変更したいケースがもしかしたらあるかもしれない・・・のでそのときの対策です。

## 対策
なんでもよいのですが`unknown`のように知らないenumの値用のcaseを追加します。
そして`init(from decoder)`を実装し、decodeに失敗したときに追加したcaseになるようにします。

```swift
struct Hoge: Decodable {
  enum Type: String, Decodable {
    case type1
    case type2
    case unknown

    init(from decoder: Decoder) throws {
      self = try DisplayPosition(rawValue: decoder.singleValueContainer().decode(RawValue.self)) ?? .unknown
    }
  }

  let type: Type
  ...
}
```
SEC642講師のお勧め書籍(英語)

忘れずに備忘録
どれを先に読むべきか、本の難易度とか詳細を質問するの忘れた:grin:
The Tangled Webは日本語版があるようですね。

The Web Application Hacker's Handbook: Finding and Exploiting Security Flaws
https://www.amazon.co.jp/Web-Application-Hackers-Handbook-Exploiting/dp/1118026470/

Burp Suite Essentials
https://www.amazon.co.jp/Burp-Suite-Essentials-Akash-Mahajan/dp/1783550112/

The Penetration Tester's Guide to Web Applications
https://www.amazon.co.jp/Penetration-Testers-Applications-Computer-Security-ebook/dp/B07V4GKYYT/

Mastering Modern Web Penetration Testing
https://www.amazon.co.jp/Mastering-Modern-Web-Penetration-Testing/dp/1785284584/

The Tangled Web: A Guide to Securing Modern Web Applications
https://www.amazon.co.jp/Tangled-Web-Securing-Applications-English-ebook/dp/B006FZ3UNI/
CoreNFCのFelica(NFC Type F)

#はじめに
[前回](https://qiita.com/HAL27241/items/a2e04cf1a6ade2f7d2af)までで一応、NFC Type F のリードまではできるようになっていました。
今回はちょっとだけ補足とまとめをしますね。

#処理の流れ
##Session
まずは CoreNFC のセッションを作成します。

```swift
let session = NFCTagReaderSession(pollingOption: [.iso14443, .iso18092],
                                  delegate: self)
session?.begin()
```

このとき、Type F 以外にも Type A/B も同時にスキャンしたい時はこんな感じになります。
もちろん、Type F だけで良い場合は `.iso18092` を指定すれば OK です。

スキャンして NFC タグが見つかったら、デリゲートが呼び出されます。
Type A/B/F でスキャンしている場合は、TypeA/B と Type F でアクセスする実装が違ってくるので、ここで判別することになります。
大雑把にはこんな感じです。

```swift
func tagReaderSession(_ session: NFCTagReaderSession, didDetect tags: [NFCTag]) {
    let t : NFCTag = tags.first!
    switch t {
    case .feliCa:
        // Type F
    case .iso7816:
        // Type A/B
    default:
        return
    }
}
```

##Service
タグに接続できたらアクアスしたいサービスを指定します。
サービスコードはリトルエンディアンになります。

```swift
let serivces = [Data([0x8b, 0x00])]
feliCaTag.requestService(nodeCodeList: serivces,
                         completionHandler: {
    (nodes, error) -> Void in
})
```

##Read
サービスを指定したらリードできます。
アクセスしたいブロックを指定します。Type F ではブロック単位でのリード・ライトになるんですが、１ブロックは16バイトのバイト列になります。swift なら Data 型ですけどね。
ただ、この時もサービスをしている必要があるのと、ブロックの指定もリトルエンディアンです。

```swift
let serivces = [Data([0x8b, 0x00])]
let blockList = [Data([0x80, 0x00])]
feliCaTag.readWithoutEncryption(serviceCodeList: serivces,
                                blockList: blockList,
                                completionHandler: {
    (status1, status2, dataList, error) in
})
```
ステータスフラグとデータとエラーが取得できます。
ちなみに本来の NFC の通信なら、ここでレスポンスコードとか PICC とかも取得できるみたいなんですが、端折られるみたいなんです。
ま、普通はそこまで不要だとは思うんですけど、取得する方法はあるんでしょうかね？

##Write
サービスを指定したらライトもできます。
ほぼリードと同じですね。ライトしたいデータを渡せるようになっているのが違いです。

```swift
feliCaTag.writeWithoutEncryption(serviceCodeList: services,
                                 blockList: blockList,
                                 blockData: blockData,
                                 completionHandler: {
    (status1, status2, error) in
})
```

#まとめ
処理の流れをまとめてみました。
Type A/B はちょっとだけ厄介ですが、Type F はずいぶんスッキリした API でアクセスできるのが良いですね。
今回は暗号なしでしたが、暗号ありはサービス提供者との契約が必要になるみたいです。
STREAM APIを使ってみた

# STREAM APIを使ってみた

## anyMatch：判定（一部合致）
```console:セット
		List<TestBean> list = new ArrayList<>();
		TestBean bean1 = new TestBean();
		bean1.setCd("A");
		bean1.setName("商品A");
		bean1.setNum(100);
		list.add(bean1);
		TestBean bean2 = new TestBean();
		bean2.setCd("B");
		bean2.setName("商品B");
		bean2.setNum(100);
		list.add(bean2);
```
```console:実行
		list.stream().anyMatch(b->b.getCd().equals("A"));//true
		list.stream().anyMatch(b->b.getCd().equals("C"));//false
```

## allMatch： 判定（全て合致）
```console:セット
		List<TestBean> list = new ArrayList<>();
		TestBean bean1 = new TestBean();
		bean1.setCd("A");
		bean1.setName("商品A");
		bean1.setNum(100);
		list.add(bean1);
		TestBean bean2 = new TestBean();
		bean2.setCd("A");
		bean2.setName("商品A");
		bean2.setNum(100);
		list.add(bean2);
```
```console:実行
		list.stream().allMatch(b->b.getCd().equals("A"));//true
		list.stream().allMatch(b->b.getCd().equals("B"));//false
```

## noneMatch：判定（全て非合致）
```console:セット
		List<TestBean> list = new ArrayList<>();
		TestBean bean1 = new TestBean();
		bean1.setCd("A");
		bean1.setName("商品A");
		bean1.setNum(100);
		list.add(bean1);
		TestBean bean2 = new TestBean();
		bean2.setCd("A");
		bean2.setName("商品A");
		bean2.setNum(100);
		list.add(bean2);
```
```console:実行
		list.stream().noneMatch(b->b.getCd().equals("A"));//false
		list.stream().noneMatch(b->b.getCd().equals("B"));//true
```

## max：最大値を返す
```console:セット
		List<TestBean> list = new ArrayList<>();
		TestBean bean1 = new TestBean();
		bean1.setCd("A");
		bean1.setName("商品A");
		bean1.setNum(100);
		list.add(bean1);
		TestBean bean2 = new TestBean();
		bean2.setCd("C");
		bean2.setName("商品C");
		bean2.setNum(200);
		list.add(bean2);
```
```console:実行
		list.stream().map(b->b.getNum()).max(Comparator.naturalOrder()).get();//200
```

## findAny：任意の値を返す
```console:セット
		List<TestBean> list = new ArrayList<>();
		TestBean bean1 = new TestBean();
		bean1.setCd("A");
		bean1.setName("商品A");
		bean1.setNum(100);
		list.add(bean1);
		TestBean bean2 = new TestBean();
		bean2.setCd("C");
		bean2.setName("商品C");
		bean2.setNum(200);
		list.add(bean2);
```
```console:実行
		list.stream().findAny().map(b->b.getCd()).orElse(null);//A
```

## findFirst：先頭の値を返す
```console:セット
		List<TestBean> list = new ArrayList<>();
		TestBean bean1 = new TestBean();
		bean1.setCd("A");
		bean1.setName("商品A");
		bean1.setNum(100);
		list.add(bean1);
		TestBean bean2 = new TestBean();
		bean2.setCd("C");
		bean2.setName("商品C");
		bean2.setNum(200);
		list.add(bean2);
```
```console:実行
		list.stream().findFirst().map(b->b.getCd()).orElse(null);//A
```

## sum：合計を返す
```console:セット
		List<TestBean> list = new ArrayList<>();
		TestBean bean1 = new TestBean();
		bean1.setCd("A");
		bean1.setName("商品A");
		bean1.setNum(100);
		list.add(bean1);
		TestBean bean2 = new TestBean();
		bean2.setCd("B");
		bean2.setName("商品B");
		bean2.setNum(100);
		list.add(bean2);
		TestBean bean3 = new TestBean();
		bean3.setCd("A");
		bean3.setName("商品A");
		bean3.setNum(100);
		list.add(bean3);

```
```console:実行
		list.stream().filter(b->b.getCd().equals("A")).mapToInt(b->b.getNum()).sum();//200
```
初学者向けのSQLまとめ

SQLについての研修があったので復習を兼ねて内容をまとめました。

SQLはプログラミング初学者が重要視していません。
(あくまでも推測です。)

しかし、
先輩エンジニアはSQLはしっかり勉強すべき
と言っていたので
初学者の方も疎かにしないようにしましょう。

###基礎的なSQLに関連のある言葉
#####SQL(structured query language)
データベースを操作する言語

#####DB(データベース)
データを格納する箱

#####RDB(リレーショナルデータベース)
データを表形式で扱うデータベース
複数のテーブルでデータベースを管理する方式

#####テーブル
データの格納領域
データの種類ごとに分けられている

#####カラム
テーブルの列

#####ロウ
テーブルの行

#####レコード
水平方向にあるデータそのものをさす言葉
ロウと混同してはいけない

#####フィールド
レコードを構成する1つ１つの要素

#####クエリ
SQLを実行した時にデータベースに送る命令文

### SQL接続方法

```
-- 起動
mysql.server start

-- 停止
mysql.server stop

-- rootでログイン
mysql -u root -p

-- 起動状況確認
mysql.server status
```

###SQLの例
```
-- クエリの最後に";"を忘れない

-- 全てのレコードを抽出する
select * from テーブル名;

-- 指定したカラムを含むレコードを抽出する
select カラム名　from テーブル名;

-- 列に別名をつける
select カラム名　as 新しいカラム名　form テーブル名;

-- asは省略可能
select カラム名 新しいカラム名　form テーブル名;

-- where句で条件を指定してレコードを抽出
select * from テーブル名　where 条件;

--　他の言語で見ることがなかった比較演算子
-- 値がnulのレコード
is nul

-- 値がnulではないレコード
is not nul

-- ある値が値セットに含まれているかどうか
in()

-- ある値が値セットに含まれていないかどうか
not in()

/* パターンマッチング
% 0文字以上の文字列
_ 任意の1文字
''で囲む */
select * from テーブル名 where カラム名 like '***';

-- limit句で抽出するレコード数を制限する
-- オフセットは省略可能
select * from テーブル名 limit オフセット number;
```

###集約関数
```
-- 合計値を求める
select sum(カラム名) from テーブル名;

--- 平均値を求める
select avg(カラム名) from テーブル名;

-- 最小値を求める
select min(カラム名) from テーブル名;

-- 最大値を求める
select max(カラム名) from テーブル名;
```

###集約関数におけるnullの扱い
nullは「値がないこと」を表す時に使う言葉
集約関数では基本的にnullは無視される
nullを含んだ計算結果は全てnullになる。


```
-- 数える
select count(カラム名) from テーブル名;

-- 重複を取り除く
select count(distinct カラム名) from テーブル名;
```

###select文の記述順序と実行順序
記述順序
select from where group by having order by limit;
実行順序
from where group by having select order by limit;

###order by
昇順、降順を指定する

```
-- 昇順を指定
select * from テーブル名 order by カラム名 asc;

-- 降順を指定
select * from テーブル名 order by カラム名 desc;
```

###演算子
```
-- 絶対値を求める。
select abs(引数);

-- 四捨五入
-- 桁数で0にすると、小数点第1位を四捨五入する。
select round(引数,桁数);
```

###文字列の連結
```
select concat(引数1, 引数2) from テーブル名;
```

###日付と時刻の関数と演算子
```

-- 現在の日付
select current_date();

-- 現在の時刻
select current_timestamp();

-- n日後の日付
select current_date() + interval n day;

-- n日前の日付
select current_date() - interval n day

n時間後の時間
select current_timestamp() + interval n hour;

n時間前の時間
select current_timestamp() - interval n hour;

-- extract
-- 日時や日付の特定の部分を取り出す。
-- 条件に当てはまるyearを含むレコードを取り出す
select * from テーブル名 where extract(year from カラム名) = 条件;
```

随時更新します。
気軽にディスクを暗号化してみる

# はじめに

中古ハードディスクの中身を覗かれて困っている人が居るようです。
暗号化していれば、物理的に覗かれたとしても論理的には覗かれません。

Linux だと非常に気軽にディスクを暗号化できます。


# 概略

luks を使って暗号化します。コマンドとしては `cryptsetup` を使います。


### 暗号化手順

```
# cryptsetup luksFormat <device_name>
```

デバイスの中身が消えるけど良いかと尋ねてきます。大文字で `YES` と応じます。
続いてパスフレーズを尋ねられます。例によって同じパスフレーズを２回入力します。


### オープン手順

暗号化されているデバイスにアクセスできるようにするステップです。

```
# cryptsetup open <device_name> <mapped_name>
```

パスフレーズを聞かれます。
`/dev/mapper/<mapped_name>` にマップされます。


### 利用

ブロックデバイス `/dev/mapper/<mapped_name>` を好きなように利用します。
`mkfs` したり `mount` したり。何なら `pvcreate` も。


### クローズ手順

オープンの逆です。
もしマウントしているなら先にアンマウントしましょう。

```
# cryptsetup close <mapped_name>
```


# おまけ

単一パーティーションで非暗号化 rootfs を使っているなら、swapfile のようにファイルを使うのも手です。`dd if=/dev/zero` で空ファイルを作って `cryptsetup luksFormat` すればいいだけです。
SSD なら気になるほど性能低下しないと思います。
Python detailEnhanceFilter(詳細強化フィルタ)を用いた靄(かすみ)除去

## 背景
撮影した写真などが意図せず霞む場合があります。そのため、霞画像に対して画像処理を用いて霞を除去したいというニーズがあります。

実際に下記のサイトを拝見するとAdobeの製品にも霞除去機能があります。
site: https://blogs.adobe.com/japan/cc-adobe-stock-contributor-j-curbon-lightroom-how-to-goto-2/

今回はPythonとOpenCVを用いて簡易な靄除去方法をご紹介します。

## detailEnhanceFilter

今回はOpenCVのNon-Photorealistic Renderingに実装されているdetailEnhanceFilterを使用します。

ライブラリの詳細は下記サイトにてご確認ください。
https://docs.opencv.org/master/df/dac/group__photo__render.html

## 実装
```image_processing.py
from PIL import Image
import numpy as np
import cv2

def main():
    img = np.array(Image.open('images/input.jpg'))
    dst = cv2.detailEnhance(img, sigma_s=10, sigma_r=0.15)
    Image.fromarray(dst).save('images/result.jpg')

if __name__ == '__main__':
    main()
```

## 実行結果
入力は先ほどご紹介したサイトの画像をお借りしました。
site: https://blogs.adobe.com/japan/cc-adobe-stock-contributor-j-curbon-lightroom-how-to-goto-2/
#### 入力画像
![input.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135147/b519835c-002e-4e2a-64c3-559a1b9b04af.jpeg)
#### 出力画像
![result.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135147/0db7099e-b0d8-611f-900a-7a36941757cc.jpeg)
#### Adobe様の霞除去
![ado.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135147/258f35f2-fd3b-6e7a-1fb4-426f21f9a9ee.jpeg)


## 所感
~~怪しくないか...~~
詳細強化フィルタという名前の通りでエッジが強化されているのが分かります！
しかしエッジ周辺画素が白い印象がありますね。
ただ1行の関数でこの変換能力！OpenCVは素晴らしいですね。
今回はdetailEnhanceフィルタのみの効果を試したかったので前処理は一切していません。
前処理を増やすとより良くなる印象です。
パラメータも未調整です。
ご興味のあるお方はぜひお試しください。
最後にライブラリのバージョンは下記の通りとなります。

## ライブラリ
|       |       version | 
|:----------------|--------------|
| Python          |         3.7.6 |
| opencv-python   |      4.1.2.30 |
| numpy   |      1.18.1 |
| pillow   |      7.0.0 |
【PHP】Qiita 週間いいね数ランキング【自動更新】

# タグ別

[`Android`](https://qiita.com/items/8b3af051428d746f26c5) [`AWS`](https://qiita.com/items/e24b6279326a462d456c) [`初心者`](https://qiita.com/items/402899ec543aff109505) [`Docker`](https://qiita.com/items/ae11fca7d2eba445b037) [`Git`](https://qiita.com/items/74eacdbf363e260981c3) [`Go`](https://qiita.com/items/49d4537d95f878b3e91a) [`iOS`](https://qiita.com/items/e61a29a383d0403e92fc) [`Java`](https://qiita.com/items/4c3f84836bfdbb137226) [`JavaScript`](https://qiita.com/items/eaa7ac5b62a0a723edbb) [`Linux`](https://qiita.com/items/362e81e53c3f9dee22f1) [`Node.js`](https://qiita.com/items/66ed7ad8f7c9673e9d50) [`PHP`](https://qiita.com/items/3318cbdbc45c6ebd4014) [`Python`](https://qiita.com/items/9d7f2ffeafb36cf59a77) [`Rails`](https://qiita.com/items/93b9e7f7d143e9ce650e) [`React`](https://qiita.com/items/f9712f8acace22815b99) [`Ruby`](https://qiita.com/items/72c3d2e896bdc3e1a6b3) [`Swift`](https://qiita.com/items/e2b6f0645e29f0e2b761) [`TypeScript`](https://qiita.com/items/25b7c0870afa6d41d19b) [`Vim`](https://qiita.com/items/f5361177baef95e447d1) [`Vue.js`](https://qiita.com/items/2774e02c6eea5c830d99) 

# 集計について

- 集計期間: 2025-06-16 ~ 2025-06-23
- 条件: ストック数が **2** 以上の記事


# GitHub

https://github.com/koki-develop/qiita-ranking

スターをもらえるととっても励みになります :bow:

# いいね数ランキング

## 1 位: [和製プログラミング英語の悲劇 - あなたの英語、実は通じてないかも!?](https://qiita.com/tsuyoshi-otake/items/272fa08baf96c91d0a5f)

[`Java`](https://qiita.com/tags/Java) [`Python`](https://qiita.com/tags/Python) [`PHP`](https://qiita.com/tags/PHP) [`JavaScript`](https://qiita.com/tags/JavaScript) [`初心者`](https://qiita.com/tags/初心者) 
**43** いいね　**33** ストック
[@tsuyoshi-otake](https://qiita.com/tsuyoshi-otake) さん ( 2025-06-16 12:02 に投稿 )

## 2 位: [アプリケーションのパフォーマンス最適化のTipsをシェアしよう！～PHP編～](https://qiita.com/CureSaba/items/46b5626ca96f11fe7306)

[`PHP`](https://qiita.com/tags/PHP) [`最適化`](https://qiita.com/tags/最適化) [`パフォーマンス`](https://qiita.com/tags/パフォーマンス) [`高校生`](https://qiita.com/tags/高校生) 
**8** いいね　**2** ストック
[@CureSaba](https://qiita.com/CureSaba) さん ( 2025-06-18 15:14 に投稿 )

## 3 位: [【WordPressプラグイン】ユーザーのプロフィール内容を見てコンテンツを出し分けたい](https://qiita.com/ikeiral/items/74c72516a422b40498eb)

[`PHP`](https://qiita.com/tags/PHP) [`HTML`](https://qiita.com/tags/HTML) [`WordPress`](https://qiita.com/tags/WordPress) [`認証`](https://qiita.com/tags/認証) [`SPIRAL`](https://qiita.com/tags/SPIRAL) 
**2** いいね　**2** ストック
[@ikeiral](https://qiita.com/ikeiral) さん ( 2025-06-20 19:12 に投稿 )
【Vue.js】Qiita 週間いいね数ランキング【自動更新】

# タグ別

[`Android`](https://qiita.com/items/8b3af051428d746f26c5) [`AWS`](https://qiita.com/items/e24b6279326a462d456c) [`初心者`](https://qiita.com/items/402899ec543aff109505) [`Docker`](https://qiita.com/items/ae11fca7d2eba445b037) [`Git`](https://qiita.com/items/74eacdbf363e260981c3) [`Go`](https://qiita.com/items/49d4537d95f878b3e91a) [`iOS`](https://qiita.com/items/e61a29a383d0403e92fc) [`Java`](https://qiita.com/items/4c3f84836bfdbb137226) [`JavaScript`](https://qiita.com/items/eaa7ac5b62a0a723edbb) [`Linux`](https://qiita.com/items/362e81e53c3f9dee22f1) [`Node.js`](https://qiita.com/items/66ed7ad8f7c9673e9d50) [`PHP`](https://qiita.com/items/3318cbdbc45c6ebd4014) [`Python`](https://qiita.com/items/9d7f2ffeafb36cf59a77) [`Rails`](https://qiita.com/items/93b9e7f7d143e9ce650e) [`React`](https://qiita.com/items/f9712f8acace22815b99) [`Ruby`](https://qiita.com/items/72c3d2e896bdc3e1a6b3) [`Swift`](https://qiita.com/items/e2b6f0645e29f0e2b761) [`TypeScript`](https://qiita.com/items/25b7c0870afa6d41d19b) [`Vim`](https://qiita.com/items/f5361177baef95e447d1) [`Vue.js`](https://qiita.com/items/2774e02c6eea5c830d99) 

# 集計について

- 集計期間: 2025-06-16 ~ 2025-06-23
- 条件: ストック数が **2** 以上の記事


# GitHub

https://github.com/koki-develop/qiita-ranking

スターをもらえるととっても励みになります :bow:

# いいね数ランキング

ランキングに入る記事が見つかりませんでした。
vim 備忘録

##vim サーチハイライトを消す
`:noh`
##vimでターミナルを開く

`:term`
ターミナルを開ける

##vimでターミナルを閉じる
`exit`

`di'` シングルクォーテーションで囲まれた文字列の削除
ターミナルを終了する
【Docker】Qiita 週間いいね数ランキング【自動更新】

# タグ別

[`Android`](https://qiita.com/items/8b3af051428d746f26c5) [`AWS`](https://qiita.com/items/e24b6279326a462d456c) [`初心者`](https://qiita.com/items/402899ec543aff109505) [`Docker`](https://qiita.com/items/ae11fca7d2eba445b037) [`Git`](https://qiita.com/items/74eacdbf363e260981c3) [`Go`](https://qiita.com/items/49d4537d95f878b3e91a) [`iOS`](https://qiita.com/items/e61a29a383d0403e92fc) [`Java`](https://qiita.com/items/4c3f84836bfdbb137226) [`JavaScript`](https://qiita.com/items/eaa7ac5b62a0a723edbb) [`Linux`](https://qiita.com/items/362e81e53c3f9dee22f1) [`Node.js`](https://qiita.com/items/66ed7ad8f7c9673e9d50) [`PHP`](https://qiita.com/items/3318cbdbc45c6ebd4014) [`Python`](https://qiita.com/items/9d7f2ffeafb36cf59a77) [`Rails`](https://qiita.com/items/93b9e7f7d143e9ce650e) [`React`](https://qiita.com/items/f9712f8acace22815b99) [`Ruby`](https://qiita.com/items/72c3d2e896bdc3e1a6b3) [`Swift`](https://qiita.com/items/e2b6f0645e29f0e2b761) [`TypeScript`](https://qiita.com/items/25b7c0870afa6d41d19b) [`Vim`](https://qiita.com/items/f5361177baef95e447d1) [`Vue.js`](https://qiita.com/items/2774e02c6eea5c830d99) 

# 集計について

- 集計期間: 2025-06-16 ~ 2025-06-23
- 条件: ストック数が **2** 以上の記事


# GitHub

https://github.com/koki-develop/qiita-ranking

スターをもらえるととっても励みになります :bow:

# いいね数ランキング

## 1 位: [【中学生の挑戦】DockerとGitHub Actionsで『開発環境の未来』を創る！ 〜爆速開発と自動デプロイの秘密〜](https://qiita.com/Aqua-Studev/items/0f59991b1f36484d995c)

[`Docker`](https://qiita.com/tags/Docker) [`GitHubActions`](https://qiita.com/tags/GitHubActions) 
**3** いいね　**6** ストック
[@Aqua-Studev](https://qiita.com/Aqua-Studev) さん ( 2025-06-21 13:20 に投稿 )

## 2 位: [DockerfileのCOPYの--excludeオプションを使うために（RHEL・Amazon Linux・Ubuntu・MacOsシステム別 / Docker・Podman）](https://qiita.com/Surlive/items/28935d21a2f64b42c566)

[`Mac`](https://qiita.com/tags/Mac) [`Linux`](https://qiita.com/tags/Linux) [`Docker`](https://qiita.com/tags/Docker) [`container`](https://qiita.com/tags/container) [`Podman`](https://qiita.com/tags/Podman) 
**2** いいね　**2** ストック
[@Surlive](https://qiita.com/Surlive) さん ( 2025-06-17 16:52 に投稿 )

## 3 位: [Docker Bake を使って複雑なビルドオプションを管理しよう](https://qiita.com/il-m-yamagishi/items/5d06b39630d900f5a3f9)

[`Docker`](https://qiita.com/tags/Docker) [`bake`](https://qiita.com/tags/bake) [`ECR`](https://qiita.com/tags/ECR) [`BuildKit`](https://qiita.com/tags/BuildKit) 
**2** いいね　**2** ストック
[@il-m-yamagishi](https://qiita.com/il-m-yamagishi) さん ( 2025-06-17 09:54 に投稿 )
【Rails】Qiita 週間いいね数ランキング【自動更新】

# タグ別

[`Android`](https://qiita.com/items/8b3af051428d746f26c5) [`AWS`](https://qiita.com/items/e24b6279326a462d456c) [`初心者`](https://qiita.com/items/402899ec543aff109505) [`Docker`](https://qiita.com/items/ae11fca7d2eba445b037) [`Git`](https://qiita.com/items/74eacdbf363e260981c3) [`Go`](https://qiita.com/items/49d4537d95f878b3e91a) [`iOS`](https://qiita.com/items/e61a29a383d0403e92fc) [`Java`](https://qiita.com/items/4c3f84836bfdbb137226) [`JavaScript`](https://qiita.com/items/eaa7ac5b62a0a723edbb) [`Linux`](https://qiita.com/items/362e81e53c3f9dee22f1) [`Node.js`](https://qiita.com/items/66ed7ad8f7c9673e9d50) [`PHP`](https://qiita.com/items/3318cbdbc45c6ebd4014) [`Python`](https://qiita.com/items/9d7f2ffeafb36cf59a77) [`Rails`](https://qiita.com/items/93b9e7f7d143e9ce650e) [`React`](https://qiita.com/items/f9712f8acace22815b99) [`Ruby`](https://qiita.com/items/72c3d2e896bdc3e1a6b3) [`Swift`](https://qiita.com/items/e2b6f0645e29f0e2b761) [`TypeScript`](https://qiita.com/items/25b7c0870afa6d41d19b) [`Vim`](https://qiita.com/items/f5361177baef95e447d1) [`Vue.js`](https://qiita.com/items/2774e02c6eea5c830d99) 

# 集計について

- 集計期間: 2025-06-16 ~ 2025-06-23
- 条件: ストック数が **2** 以上の記事


# GitHub

https://github.com/koki-develop/qiita-ranking

スターをもらえるととっても励みになります :bow:

# いいね数ランキング

## 1 位: [【個人開発】アニメ好きのための聖地巡礼をサポートするアプリを開発しました。](https://qiita.com/fune_6900/items/fd2085bc135dd7b09cfe)

[`Ruby`](https://qiita.com/tags/Ruby) [`Rails`](https://qiita.com/tags/Rails) [`ポートフォリオ`](https://qiita.com/tags/ポートフォリオ) [`未経験`](https://qiita.com/tags/未経験) [`個人開発`](https://qiita.com/tags/個人開発) 
**4** いいね　**2** ストック
[@fune_6900](https://qiita.com/fune_6900) さん ( 2025-06-20 07:04 に投稿 )

## 2 位: [VSCodeやRails開発で行末に空行を入れるべき理由まとめ](https://qiita.com/Ryuta-prog/items/c6f6aca22b7ff205561e)

[`Ruby`](https://qiita.com/tags/Ruby) [`Rails`](https://qiita.com/tags/Rails) [`RuboCop`](https://qiita.com/tags/RuboCop) [`VSCode`](https://qiita.com/tags/VSCode) 
**3** いいね　**2** ストック
[@Ryuta-prog](https://qiita.com/Ryuta-prog) さん ( 2025-06-21 17:12 に投稿 )
Gitコマンド（ブランチの作成）

#はじめに
先日[「基本のGitコマンド」](https://qiita.com/yukachin0414/items/3cf802f30ebc6f526fea)にて簡単なGitコマンドについてまとめました。
今回はローカル環境でのブランチの作成についてまとめたいと思います。

#ブランチとは
ブランチとは、変更などの履歴の流れを分岐して記録していくものです。
分岐したブランチは他のブランチの影響を受けないため、同じリポジトリ中で複数の変更を同時に進めていくことができます。
<img width="609" alt="スクリーンショット 2020-01-25 21.39.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384180/e4bbf014-02df-b80a-f9c0-7144c17c06ba.png">
この図でいくとbranchAとbranchBは並行した作業でそれぞれが独立した関係性になっています。
またbranchA1はbranchAから派生したbranchになっています。

#ブランチの作成時に必要なコマンド

```php
//どのブランチいるかの確認
$ git branch
```

```php
//新規ローカルブランチを作る
$ git branch (作成するブランチ名)
//リモートのあるブランチを元に新規ローカルブランチを作る
$ git branch (新しいブランチ名) (元にするブランチ名)

//新規ローカルブランチを作りそのブランチに移動する
$ git checkout -b (作成するブランチ名)
//リモートのあるブランチを元に新規ローカルブランチを作りそのブランチに移動する
$ git checkout -b (新しいブランチ名) (元にするブランチ名)
```

```php
//作業ブランチの親ブランチ（派生元）の確認
$ git show-branch | grep '*' | grep -v "$(git rev-parse --abbrev-ref HEAD)" | head -1 | awk -F'[]~^[]' '{print $2}'
```

```php
//作業ブランチの変更
$ git checkout (移動したい先のブランチ名)
```

```php
//強制的にマスターブランチに移動する
$ git checkout -f master
```

#さいごに
gitコマンド結構多いなと思いましたが覚えて使いこなすと意外と便利なので慣れるまで試すのがいいとおもいます。

【参考】
[ブランチとは｜サルでもわかるGit入門【プロジェクト管理ツールBacklog】](https://backlog.com/ja/git-tutorial/stepup/01/)
[Gitで今のブランチの派生元ブランチを特定する - Qiita](https://qiita.com/upinetree/items/0b74b08b64442f0a89b9)
Brainf**kセルフインタプリタを実装した話(リンク)

以前、Brainf\*\*kセルフインタプリタを実装した時の記事のリンクを載せます。
http://ange1.hateblo.jp/entry/2016/02/29/203105

※Brainf\*\*kの実践については[Brainf**k講座(リンク)](/angel_p_57/items/618bed4e96c5e96778a5)をどうぞ
【Ruby】Qiita 週間いいね数ランキング【自動更新】

# タグ別

[`Android`](https://qiita.com/items/8b3af051428d746f26c5) [`AWS`](https://qiita.com/items/e24b6279326a462d456c) [`初心者`](https://qiita.com/items/402899ec543aff109505) [`Docker`](https://qiita.com/items/ae11fca7d2eba445b037) [`Git`](https://qiita.com/items/74eacdbf363e260981c3) [`Go`](https://qiita.com/items/49d4537d95f878b3e91a) [`iOS`](https://qiita.com/items/e61a29a383d0403e92fc) [`Java`](https://qiita.com/items/4c3f84836bfdbb137226) [`JavaScript`](https://qiita.com/items/eaa7ac5b62a0a723edbb) [`Linux`](https://qiita.com/items/362e81e53c3f9dee22f1) [`Node.js`](https://qiita.com/items/66ed7ad8f7c9673e9d50) [`PHP`](https://qiita.com/items/3318cbdbc45c6ebd4014) [`Python`](https://qiita.com/items/9d7f2ffeafb36cf59a77) [`Rails`](https://qiita.com/items/93b9e7f7d143e9ce650e) [`React`](https://qiita.com/items/f9712f8acace22815b99) [`Ruby`](https://qiita.com/items/72c3d2e896bdc3e1a6b3) [`Swift`](https://qiita.com/items/e2b6f0645e29f0e2b761) [`TypeScript`](https://qiita.com/items/25b7c0870afa6d41d19b) [`Vim`](https://qiita.com/items/f5361177baef95e447d1) [`Vue.js`](https://qiita.com/items/2774e02c6eea5c830d99) 

# 集計について

- 集計期間: 2025-06-16 ~ 2025-06-23
- 条件: ストック数が **2** 以上の記事


# GitHub

https://github.com/koki-develop/qiita-ranking

スターをもらえるととっても励みになります :bow:

# いいね数ランキング

## 1 位: [【個人開発】アニメ好きのための聖地巡礼をサポートするアプリを開発しました。](https://qiita.com/fune_6900/items/fd2085bc135dd7b09cfe)

[`Ruby`](https://qiita.com/tags/Ruby) [`Rails`](https://qiita.com/tags/Rails) [`ポートフォリオ`](https://qiita.com/tags/ポートフォリオ) [`未経験`](https://qiita.com/tags/未経験) [`個人開発`](https://qiita.com/tags/個人開発) 
**4** いいね　**2** ストック
[@fune_6900](https://qiita.com/fune_6900) さん ( 2025-06-20 07:04 に投稿 )

## 2 位: [VSCodeやRails開発で行末に空行を入れるべき理由まとめ](https://qiita.com/Ryuta-prog/items/c6f6aca22b7ff205561e)

[`Ruby`](https://qiita.com/tags/Ruby) [`Rails`](https://qiita.com/tags/Rails) [`RuboCop`](https://qiita.com/tags/RuboCop) [`VSCode`](https://qiita.com/tags/VSCode) 
**3** いいね　**2** ストック
[@Ryuta-prog](https://qiita.com/Ryuta-prog) さん ( 2025-06-21 17:12 に投稿 )

## 3 位: [AIツールが開発者のモチベーションに与える影響とは？JetBrainsの心理学的アプローチ](https://qiita.com/nattogohan123/items/a265271b835957789df9)

[`Ruby`](https://qiita.com/tags/Ruby) [`Python`](https://qiita.com/tags/Python) [`JavaScript`](https://qiita.com/tags/JavaScript) [`初心者`](https://qiita.com/tags/初心者) [`AI`](https://qiita.com/tags/AI) 
**2** いいね　**3** ストック
[@nattogohan123](https://qiita.com/nattogohan123) さん ( 2025-06-20 12:43 に投稿 )

## 4 位: [JetBrains Plugin Developer Conf 2025に登壇しませんか？](https://qiita.com/nattogohan123/items/9b21f18a2997b6867af3)

[`Ruby`](https://qiita.com/tags/Ruby) [`Python`](https://qiita.com/tags/Python) [`JavaScript`](https://qiita.com/tags/JavaScript) [`初心者`](https://qiita.com/tags/初心者) [`JetBrains`](https://qiita.com/tags/JetBrains) 
**1** いいね　**2** ストック
[@nattogohan123](https://qiita.com/nattogohan123) さん ( 2025-06-18 11:01 に投稿 )
npm で全ての package をアップデートする

```sh
$ npx npm-check-updates -u
```

これで `package.json` のみ更新される。
あとは、いつも通り `npm i` 。

以下、オプション例。

```sh
# "devDependencies" のみアップデートしたい
npx npm-check-updates -u --dep dev

# 特定の package はアップデートしたくない
npx npm-check-updates -u --reject typescript,@types/node
```

## Ref.

https://www.npmjs.com/package/npm-check-updates
AWS Lightsailと既存VPCをピアリング接続する

# AWS Lightsailと既存VPCをピアリング接続する
## 概要
LightsailはAWSのVPSサービスとして通信料込みの破格なサービスです。
全てをEC2で構築している方が多いですが、テスト環境その他、Lightsailで十分という要件も多いと思います。

Lightsailで構築し、その上で既存のAWS環境と接続し、有効活用するためにLightsailの既存VPCをピアリング接続したいと思います。

## ピアリング接続すると何がうれしいの？
LightsaiでEC2から接続するかのようにEFSやRDSが使えます。
グローバルIPでインターネット経由であれば、もちろんピアリング接続しなくても使えますが、ピアリング接続すると内部IPでの接続になるので、通信料もセキュリティ面でも安心です。

## 注意点
Lightsailと接続できるのはどうやらDefaultのVPCだけのようです(2020年1月時点)。
自分で構築したVPCと接続したい場合は、直接ピアリング接続はできませんので、注意してください。

尚、LightsailはSLAが設定されていません。
AWS側が原因でサービスが停止した際に文句を言いたいサービスはLightsailで構築せず、EC2を使用してください。

## やり方
### Lightsail側
#### (1) Lightsail設定画面へ移行
AWSコンソールにサインインし、Lightsail設定画面へ移行し、右上の「アカウント」から「アカウント」を選択します。
![WS000057.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/400941/48b5c1c3-c666-4a97-8279-71d3459cbb6b.jpeg)

#### (2) アカウント設定画面
アカウント画面へ移行したら、「アドバンスト」を選択します。
![WS000059.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/400941/30128c60-73c5-ddc1-2bfe-251e67c719fd.jpeg)

#### (3) VPC接続を有効にする
「VPCピア接続を有効にする」のチェックボックスを有効にします。
![WS000061.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/400941/8c6d934e-6288-cf5a-003a-667b04ae1af4.jpeg)

Lightsail側は以上です。

### AWS側
#### (1) AWS側でVPC設定画面よりピアリング接続の設定画面を開きます。
![WS000018.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/400941/4ee11918-a091-5777-455c-47118bd5d0e1.jpeg)

#### (2) 作成されたピアリング接続先の確認
新しいピアリング接続が追加されているのが確認できると思います。
![WS000066.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/400941/3daab447-b613-1a1e-93dc-9aec490a30f9.jpeg)

#### (3) タグをつける
そのままではわかりづらいので、タグをつけてあげましょう。
![WS000069.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/400941/5dae343e-d028-d749-04dc-ae45dd35398a.jpeg)

#### (4) 追加されたルートテーブルの確認１
ルートテーブル設定画面を開きます。
![WS000070.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/400941/d70a2a83-fb3d-9234-063e-26db10ceb235.jpeg)

#### (5) 追加されたルートテーブルの確認２
Defaultのルートテーブルを選択し、「ルート」タブをクリックします。
![WS000072.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/400941/8a49cc8c-ecab-5258-2fee-a75168290219.jpeg)


#### (6) 追加されたルートテーブルの確認３
追加されたルートテーブルをクリックします。
![WS000074.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/400941/b7dc3c37-b5e2-c75d-bd7b-854ea846c234.jpeg)

#### (7) 追加されたルートテーブルの確認４
ルートテーブルも自動で追加されていることが確認できると思います。
![WS000075.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/400941/52396b59-c4aa-9e42-81dd-75e83caf3751.jpeg)

## 雑記
やり方は以上です。
この後にセキュリティグループの設定がありますが、それは各自でやってみてください。

できれば、Defaulだけでなく、自作したVPCとも接続できるようになれば便利ですね。
今後のアップデートに期待しましょう。
dockerで始めたNode-REDにnode-red-node-discoveryをインストールする

# node-red-node-discoveryがインストールできない

「パレットの管理」からnode-red-node-discoveryノードをインストールしようとしても、失敗してしまった。

[node-red-node-discovery - npm](https://www.npmjs.com/package/node-red-node-discovery)
には

> please read the install instructions for the underlying npm.
>
> For Debian / Ubuntu this requires installing
>
> ```
> sudo apt-get install libavahi-compat-libdnssd-dev
> ```

と書いてあるが、dockerで実行しているのでそもそもコマンドが実行できない…
その後もsudoコマンドがなかったり、apt-getがなかったりで色々苦労したので、メモを残しておく。

# インストール手順

dockerにrootでbashログインする。

```
docker exec -it --user root mynodered /bin/bash
```

パッケージマネージャapkを使ってlibdnsをインストールする。

```bash
apk update
apk apk add avahi-compat-libdns_sd avahi-dev
```

その後、Node-REDの「パレットの管理」からnode-red-node-discoveryがインストールできる。

---

追記

# 実行に失敗する

上記手順でインストールできて安心していたところ、discoverノードを使っても `Error: dns service error: unknown` となってしまい、実行に失敗してしまう。

# 対処方法　募集中

`avahi-discover` を実行してみて、エラーに関係しそうな以下パッケージをインストールしてみた

```
apk add py-gtk py-dbus dbus py-avahi py-gdbm py-gobject py-gobject3 gtk+3.0
```

が、

```
bash-5.0# avahi-discover
Traceback (most recent call last):
  File "/usr/bin/avahi-discover", line 304, in <module>
    main()
  File "/usr/bin/avahi-discover", line 297, in main
    main_window = Main_window()
  File "/usr/bin/avahi-discover", line 70, in __init__
    self.ui.add_from_file(path)
gi.repository.GLib.Error: g-file-error-quark: Failed to open file “/usr/share/avahi/interfaces/avahi-discover.ui”: No such file or directory (4)
```

の解決法がわからず断念。
命名規約について(駄文)

駄文と書いて、セーフティネットひいてます。
---
昔は10年程度しかプログラマーとかやっていましたが、命名規約は大事です。
とはいうものの、活躍する場所次第だと思いますので、
・金融機関の基幹系
・移動通信の基幹系
・予備校システム
とか言えば、あたりがつく方はいるかな。

unityでも命名規約は大事だと思っていて、子どもたちのオブジェクトの名前を見ていると頭が痛くなることも多々あります。
ただ、これは職業病であって、子供たちはあとから命名規約の大切さを知ればいいと思いますよ。
とはいうものの、

a;:kfa:mi;rewmi@pqv]:,p

みたいなプロジェクト名とか、周りの人ノーツッコミで放置されていると、それはなんだかちょっと違くないかい。

言の葉とかいいますが、名前あっての大切さというのはマインドでどうにでもなると思うので、一生ひとりで作品作って、過去作を顧みない以外は、命名規約というカタい言葉とも付き合っていってほしいです。

---
余談ですが、
Character Controller　を扱うための変数が　Character Controller　になっているのを見ると、毎回脳内で「デュヘイン、デュヘイン」(※)しています。

※...吼え立てよ、我が憤怒(ラ・グロンドメント・デュ・ヘイン)
Python3のScapyでWOLを発行する（LANコン指定型）

## コントローラを直接指定してWOLを発行したい

WOLの仕様は以下（WireSharkのWiki）とか。

https://wiki.wireshark.org/WakeOnLAN

要はパケット内に

* 0xffを６つ
* その後に対象のMACアドレスを16個並べる

で普通は起きます。ポートとかは関係なくパターンの一致で見れば良いという事もあり、ハードで検出させて割り込み出すとかもまーやれるのかなこれだという感じです。

で、これを送出する場合はUDPパケット作ってでやるのが簡単だと思います。そういうツールもあるみたいですが、私がざっと調べた限りIPアドレスで指定させる物が多かったです。これだとIPアドレスを適当にして発行とかが厳しくなります。なのでコントローラを直接指定して送るやり方を実装してみました。

## Scapy

Scapyを使ってWOLパケットの生成と送信を行います。Scapy自体は前にもチラッと書いてます。以下

https://qiita.com/ken_hamada/items/736e1c22f6c40702d1a7

## 環境

* Mac OS 10.14.4
* Python3.7

あとScapyを使ってます。恐らくLinux系でも動くのではないかと思います。

## 参考にさせて頂いたサイト

以下のコードを参考というか、これらをベースに切った貼ったした感じです。ありがとうございました！

* koさんのブログ

    https://thinkami.hatenablog.com/entry/2018/01/13/224841

* thinkAmiさんのブログ

    https://irukanobox.blogspot.com/2017/08/raspberry-pipython3pc.html


## コード

実際にどうやってるかはもうコード見た方が早くて、以下です。

```py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from scapy.all import *
import binascii

# ----> ここを適切に設定してください。

# 制御対象。これは本物を指定してあげて下さい。
TARGET_MAC_ADDRESS = "11:22:33:44:55:66"

# パケットに乗せるIPアドレス。これは何でも良いです。
IP_ADDRESS = "66.77.88.99"

# パケットを創出するコントローラ。これも本物を指定してあげて下さい。
PCAP_ifname = "en0"

# <----- ここまで

def issue_WOL():

    '''
    まずはペイロードを作ります。コード見ると分かりますが、
    以下のPassword (optional)を省いたものを作っているだけです。

    https://wiki.wireshark.org/WakeOnLAN
    
    '''
    synchronization_stream = b"\xff" * 16
    mac_bin = binascii.unhexlify("".join(TARGET_MAC_ADDRESS.split(":")))
    payload = synchronization_stream + mac_bin * 16

    '''
    上記のpayloadを送るWOLパケットをUDPとして生成します。
    '''
    ether_layer = Ether(dst=TARGET_MAC_ADDRESS)
    ip_layer = IP(dst=IP_ADDRESS)
    udp_layer = UDP(sport=44444,dport=33333) # 適当
    raw_layer = Raw(load=payload) # ペイロードはbytesで指定すればよしなにしてくれます
    wol_packet = ether_layer / ip_layer / udp_layer / raw_layer

    '''
    生パケ送るだけで良いのでLayer2が使えます。
    この時にコントローラを指定すれば、そこから出してくれるはず…
    '''
    sendp(wol_packet, iface=PCAP_ifname)
    
    print ("sent WOL ", TARGET_MAC_ADDRESS, IP_ADDRESS)


if __name__ == "__main__":
    issue_WOL()


```

使い方としては、TARGET_MAC_ADDRESS 、IP_ADDRESS、PCAP_ifnameを自分の環境や対象に合わせて書きかえて、本コードを実行すればWOLパケットが出ていくはずです（sudo が必要）。

IP_ADDRESSは別に今の対象アドレスがどうとか考えなくても良いです。実際、メチャメチャなアドレスを指定しても以下のように届きます（対向のWireSharkで確認）。レイヤー２から行けるので、コントローラを直接しているためです。

<img width="561" alt="wol.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294469/0efb5ae7-f0dc-acfb-c2b1-6b5db1dc3c0c.png">


以上です。ま、scapyを使えばそんなに難しくはなかったです
（と書きつつ上記でいうRaw(load= ...で指定するデータの型式で結構自分はハマりましたが）
書籍「15Stepで踏破 自然言語処理アプリケーション開発入門」をやってみる - 2章Step07メモ「評価」

# 内容
[15stepで踏破 自然言語処理アプリケーション入門](https://www.amazon.co.jp/dp/4865941320) を読み進めていくにあたっての自分用のメモです。
今回は2章Step07で、自分なりのポイントをメモります。

# 準備
- 個人用MacPC：MacOS Mojave バージョン10.14.6
- docker version：Client, Server共にバージョン19.03.2

# 章の概要
- 機械学習システムの予測精度を様々な指標で定量評価する
    - 既存のシステムに改良を加える場合に、かえって性能低下を起こしていないことを評価によって保証し、安心してシステムをアップデートできる
- 過学習について理解し、発生を防ぐ

# 07.1 学習データとテストデータ、そして過学習と汎化
学習によって、識別器が学習データに対して過剰に適合してしまうことを**過学習**と呼ぶ。

学習データに含まれる特徴ベクトルを100%識別できるようにすると、無視しても良いノイズまでも正しく識別できるように細かい識別面になってしまう。
学習データ以外に対しても安定して予測が行えるようになることを**汎化**と呼ぶ。

学習と評価で同じデータを使うと、過学習したシステムを高く評価してしまうことになるので、**評価用のテストデータは学習データと違うものを使って評価しなければならない**。
（いくら学習データで良い精度が出てもあまり意味がないし、過学習していないことも確認しなければいけない）

# 07.2 評価指標
|項目 |内容 |
|--- |--- |
|Accuracy（正解率） |全テストデータに対する正解テストデータの割合|
|Precision（適合率） |対象クラスに予測したテストデータのうち、正解テストデータの割合|
|Recall（再現率） |対象クラスのテストデータを正しく予測できた割合|
|F値 |PrecisionとRecallのバランスを表した指標|

## 実装
```python
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score

accuracy_score(y_true, y_pred)
precision_score(y_true, y_pred)
recall_score(y_true, y_pred)
f1_score(y_true, y_pred, average='macro')
```

- `average`を指定することで、マクロ平均`='macro'`やマイクロ平均`='micro'`を算出できる
- precisionとrecallはトレードオフの関係

# 07.3 評価の際の注意点
|項目 |内容 |
|--- |--- |
|精度の下限 |精度の下限は当てずっぽうに予測した場合である |
|分類クラスの数 |2クラス分類より多クラス分類の方が難易度は当然高いので、評価指標はアプリケーションによって値は異なる |
|テストデータの種類 |色々なシステムを相対評価する場合、同一のテストデータで実施すべきである|
|データ数の偏り |テストデータには各クラスのデータがなるべく均等に含まれるようにするのが望ましい |
色の作り方(マテリアル)

プロジェクトウィンドウの　作成　をクリックして、
マテリアル　をクリックする
<img width="256" alt="b1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/2f0fd443-41cf-ad5f-4ae5-2efe0dc307eb.png">
下図のように、なにかが作られる
<img width="314" alt="b2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/2f23b377-f90e-064b-bcb8-882bd79a6627.png">
作る色が決まっているのであれば、先に名前をつけるのもあり。
右クリックでメニューを出して、そこから　名前の変更　をクリックする。
<img width="86" alt="b3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/d9823937-266e-e53b-6cbd-5cb7934a7666.png"> <img width="319" alt="b4.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/790cf45b-bb45-a3cb-8aa0-6df2651381b5.png">
名前の付け方は人それぞれかもだけど、
red
blue
yellow
だと五十音順でごちゃごちゃで(自分は)気持ち悪いので、
color_red
color_blue
color_yellow
とかしています。(命名については別記事で!!)

マテリアルのインスペクタウィンドウの上部、白い四角をクリックする。
<img width="89" alt="b5.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/6f7fd825-5367-90d1-5a24-b8e02b03b80b.png">　<img width="287" alt="b6.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/75381d16-e062-5e3b-d802-3e6160847a6f.png">

下図のように、色を決める。
決まったら、左上の赤いボタンをクリックして、ウィンドウを閉じる。
<img width="228" alt="b7.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/1fce6595-19e2-d4f1-e12c-c908d511f862.png">　→　<img width="228" alt="b8.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/bfd17fe8-6577-89d7-be65-378e6fe86cf3.png">

---

オブジェクトへの色の反映の仕方。

やり方①
マテリアルを、オブジェクトに直接ドラッグアンドドロップをする。
<img width="717" alt="b9.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/888a6c31-ce40-66c4-20e1-19a971557cf8.png">

やり方②
マテリアルを、ヒエラルキーウィンドウのオブジェクトにドラッグアンドドロップをする。
<img width="809" alt="bx.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/7fdfc7d4-3277-a061-51b1-fad4d6ce5f86.png">
AWS AmplifyのAPI.graphqlで"TypeError: Must provide Source. Received: undefined"

# 前提
amplify add apiでgraphqlを追加して、

> const todos = await API.graphql(graphqlOperation(queries.listTodos));
> console.log(todos)

のようなコードでAPIを呼び出すときに、
"TypeError: Must provide Source. Received: undefined"
のエラーが出た場合の対処について。

# 対応
結論、サンプルコピペのままで、存在しないクエリを設定してました。。
queries.listTodosじゃなくて、別のだった。

# 追記
またおんなじエラーでハマった。。

> export const createAnswers = `mutation CreateAnswers(
>   $input: CreateAnswersInput!
>   $condition: ModelAnswersConditionInput
> ) {
> ...

今回は、生成されたコードが上記のような場合に、

> await API.graphql(graphqlOperation(mutations.CreateAnswers, {input: result}));

だとダメで、

> await API.graphql(graphqlOperation(mutations.createAnswers, {input: result}));

が正解ですね。
何が違うかというと、createのcが大文字か小文字かの違いです。いずれにしても名前の間違いなんですが、間違って"`mutation CreateAnswers("の方をコピペしてました。正しくは"export const createAnswers"の方ですね。

# というわけで
名前を間違えないようにしましょう。エラーメッセージが大変わかりづらいので、もうちょっとがんばってほしいところです。
チーム開発の時にpushできなくなったお話

# 事件発生
あ、コンフリ起きてる、よしなおそう！
よし治った！
`git push origin CurrentBuranch`
いざ！実行！
あれ？
なんかcommitログがありませんだって⁉︎なんぞ？
私コンフリを直してpushしたいだけですけど？
## とりあえず自分が何をやっていたかを確認
何が起こったかわからなかったのでとりあえず自分が今までどこで何をしていたかを確認することにしました。(※これ以降の話を聞くと気づく人速攻で気付きます。こいつは**バカ**だ！ということに…誰がバカじゃい！)
なんか聞こえたけど進めていきましょう。
私が行ったことは......
1. ファイルをpushする
2. なぜかpullrequestを見に行った
3. コンフリクトに気づく
4. どこがコンフリしてるかweb上で確認した
5. web上で直した
6. shellに戻る
7. pushする
8. gitさん『お前さんのcommitLogないで〜』
9. 私『は？』
ってことがあったような気がする（ありました！）
もう気づく人は気づきましたよね！
そうです！私はいつもならエディタ上でコンフリを治すのにこの日はなぜかwebのgithub上でコンフリを直したんです。そしてそこでなぜかshellに戻りいつものようにpushしたんです。そりゃgitさんが怒るわな！
## 何が起こっていたのか
web上のgithubでコンフリを直したことでmyPCのローカルブランチの外で直したことになります。つまりGitHubの更新履歴がローカルに取り込めていないという状況が出来上がっているんです。
これにより自分がいくらpushしてもそんなものはないと怒られるんです。いや〜アホですね！
まぁ何はともあれ原因さえわかってしまえばこっちのもんだ！
## どう直したか
結論から言います！！
GitHubから自分のブランチの変更点を持って来ればいいのです。
つまり
`git pull origin CurrentBuranch`
このコマンド打ち込んで差分をひっぱてきました。
以上！
終わり！
ちゃんと解説しますね
先ほども述べたように自分のパソコンの中ではweb上での更新点がないことになっています。これではいつまで経ってもpushはできません。何せPC内ではcommitしてないことになっているのですから。そこでGitHubと自分のPCのbranchの状態を同じにすることが必要になります。よって上のコマンドを打つことでGitHubのCurrentbranchの状態を自分のPCに持ってくるのです。

**GitHubが先行する状況が出来上がってるとは思いませんでしたね**