OmniAICreator/Qiita-1.07M huggingface dataset:
vlang から C 関数を呼ぶ(c interop)

## 背景

C/C++ メインのグラフィックスアプリやグラフィックスライブラリがある.

スクリプト系言語でバインディングを書きたい. UI を作りたいとか, ユニットテストとかでパラメータをいじったりをスクリプト側で行いたいなど. 
元々グラフィックス用向けを想定して開発されていたらしい vlang を使ってみる.

https://vlang.io/

hot code reloading とか, graphics 周りに強いのをアピール(W.I.P だが)しています.

## vlang について

OpenGL binding とかが標準であります. go ライクで型付きで, gc が無いので素晴らしいですね.
(gc なしにいろいろうまく処理するのはまだ作業途中ですが)

基本 C compiler(gcc とか)に丸投げっぽい感じで処理していて, 本体は軽くてよい(LLVM とかつかっていない)

vlang 自体が C に変換してコンパイルして実行してる(はず)ので, C との親和性は高いと想像します.

## C 関数を呼ぶ

Windows を含む cross platform を謳っていますが, ここでは Linux 環境を想定します.

https://vlang.io/docs#calling_c

C/C++ ユーザーからすれば, 比較的すんなり理解できると思います.

複雑な struct は難しいかもしれませんので, C レイヤーのほうで完結なデータ構造にしておくのが吉です.


```c

#pragma once

#ifdef __cplusplus
extern "C" {
#endif

int myfunc(int x, int y);

#ifdef __cplusplus
}
#endif
```

こんなかんじでヘッダーを用意して,

```c
#include "mylib.h"

int myfunc(int y, int x)
{
  return x + y;
}
```

こんな感じで実体を書いて,

```
$ gcc -o libmylib.so -shared -c mylib.cc
```

とコンパイルして,

```
// test.v
#flag -I.
#flag -L.
#flag -lmylib
#include "mylib.h"

fn C.myfunc(x int, y int) int

fn main() {
	n := C.myfunc(3, 4)
    println(n)
}
```

```
$ ../v run test.v 
7
```

voala!


エラーが出る場合は,

```
$ v -show_c_cmd test.v
==========
cc  -std=gnu11 -Wall -Wextra -Wno-unused-variable -Wno-unused-parameter -Wno-unused-result -Wno-unused-function -Wno-missing-braces -Wno-unused-label -Werror=implicit-function-declaration -o "/home/syoyo/work/v/sandbox/test" "/home/syoyo/.cache/v/test.tmp.c"  -I "/home/syoyo/work/v/sandbox" -L "/home/syoyo/work/v/sandbox" -lmylib  -lm -lpthread   -ldl 
cc took 916 ms
=========
```

として, どのように内部でリンクなどの呼び出しが行われれているか確認できます!

## Windows(llvm-mingw) で動かす.

https://github.com/vlang/v/wiki/Installing-a-C-compiler-on-Windows

llvm-mingw と組み合わせてみます.

とりあえず llvm-mingw だと, MSVC と同様に, import lib を作らないとリンクできないことがわかりました.

https://stackoverflow.com/questions/47541722/create-msvc-import-library-with-mingw-tools

```
/d/local/llvm-mingw/bin/gcc -shared -o mylib.dll mylib.cc -Wl,--output-def,foo.def
/d/local/llvm-mingw/bin/llvm-dlltool -m i386:x86-64 -d foo.def -l foo.lib -D mylib.dll
```

という風にすればいけます!
最近の llvm-dlltool ですと, `-D` で dll ファイル指定も必要でした.

```
./v.exe -g -show_c_cmd -cc /d/local/llvm-mingw/bin/gcc.exe run test.v         
==========
D:/local/llvm-mingw/bin/gcc.exe  -std=gnu11 -Wall -Wextra -Wno-unused-variable -Wno-unused-parameter -Wno-unused-result -Wno-unused-function -Wno-missing-braces -Wno-unused-label -g3 -no-pie -Werror=implicit-function-declaration -o "test.exe" "C:\Users\syoyo\AppData\Local\Temp\v\test.tmp.c" -municode  -ldbghelp -I "C:\Users\syoyo\local\v_windows" -L "C:\Users\syoyo\local\v_windows" -lmylib
=========

7
```

Voala!

### TODO

* C コードに, dllimport, dllexport も記載しておくとよいか?
* import lib 作成用の .def を別コマンドで行う(.dll から抜き出す方法を調べる)

## まとめ

なんだかいい感じに C と連携できそうなので, Patoreon で vlang プロジェクト(実質的にはひとりで開発している?)に課金したくなってきますね! :money_mouth:
dataframeからmarkdownの表を作るサンプルです。


#pandas のversionは 1.0.0 以上が対応しています。

```
pd.__version__
'1.0.0'  
```
#事前にtabulateをインストールします。

```
pip install tabulate 
```

#テストデータ
```
data=[
 {"氏名":"山田","回数":5, "国語":40 ,"算数":40 },
 {"氏名":"山田","回数":4, "国語":40 ,"算数":50 },
]
```
#サンプルソース
```
import pandas as pd
df=pd.DataFrame(data)

print(df.to_markdown())
```
#結果
|    | 氏名   |   回数 |   国語 |   算数 |
|---:|:-------|-------:|-------:|-------:|
|  0 | 山田   |      5 |     40 |     40 |
|  1 | 山田   |      4 |     40 |     50 |

[参考 What’s new in 1.0.0 (January 29, 2020)]
(https://pandas.pydata.org/docs/whatsnew/v1.0.0.html?highlight=to_markdown)
vCenter Server Appliance 6.7のvSphere ClientにてESXiクラスタを作成する

ESXi6.7上に構築したvCenter Server Appliance6.7にて、clster作成及びホスト登録をします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201787/193c3865-7e02-3b93-b3d3-f58cb860feb5.png)



なお、事前に以下は構築済みです。
・vmware ESXi6.7 *2台
・vmware vCenter Server Appliance 6.7
・クライアント端末(Windows10,chrome)
・vCSA上のDatacenter


#1.クラスタの作成
vSphere Clientから、新規クラスタの作成を行います。

Datacenterのサマリ画面にて、`アクション`から`新規クラスタ`をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201787/255215a8-43af-a3ab-79fb-96b05472cc6e.png)

新規クラスタの画面から、クラスタ名を記入して`OK`をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201787/6aaba81b-8365-8da5-a285-973a6534f5ee.png)
＃この段階ではDRS/vSphereHA/vSANの選択はしないほうが良いそうです。
>**vSphere HA クラスタの作成**
新規クラスタ ウィザードを最後まで実行します。
vSphere HA (または DRS) を有効にしないでください。
https://docs.vmware.com/jp/VMware-vSphere/6.7/com.vmware.vsphere.avail.doc/GUID-4BC60283-B638-472F-B1D2-1E4E57EAD213.html

クラスタが作成されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201787/b609992d-c8c9-c3cb-859d-b475d3601156.png)






#2.クラスタへのホスト追加
クラスタへESXiホスト(および仮想マシン)を追加します。

クラスタのサマリ画面にて、`アクション`から`ホストの追加`をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201787/165f4f54-9795-bec6-ed80-b75c6343b76c.png)

ホストの追加の画面にて、ESXiホストを追加します。
今回は先にDatacenterを作成しているため、既存のホストにチェックを入れて`次へ`をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201787/10a7c6eb-c88e-30f7-a553-f6190ba42745.png)

ホストサマリを確認し、`次へ`をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201787/0191e8d9-6784-42a3-3d3f-596fe58bddd0.png)

設定の確認画面にて、`完了`をクリックします。

クラスタにホストが追加されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201787/e1122b82-dce0-3163-7897-40ac1861b29e.png)


以上です。

なお、以下の記事にてvSphereHAの設定および動作確認を行っています。
>vCenter Server Appliance 6.7にてvSphereHAを有効に、動作確認をする
https://qiita.com/Higemal/items/d3d2d8600a850d481741


#参考
vSphere HA クラスタの作成
https://docs.vmware.com/jp/VMware-vSphere/6.7/com.vmware.vsphere.avail.doc/GUID-4BC60283-B638-472F-B1D2-1E4E57EAD213.html

ESXi6.5 : vCSA : vSphere HA クラスタの作成(VMware Workstation 14 Player)
http://virtual.cocolog-nifty.com/virtualmachine/2017/11/esxi65-vcsa-vsp.html

VMware ESXi クラスタ設定
https://www.unix-power.net/networking/post-467

【VMware 6.5】VMware HA（High Availability）
https://go-journey.club/archives/7207
Promiseの処理をキャンセルする

Promise で Web Speech API をラップして使っていましたが、キャンセルできるように実装するのに試行錯誤しました。想定していたような動きが実現できたので、メモを残しておきます。

<p class="codepen" data-height="265" data-theme-id="dark" data-default-tab="js,result" data-user="7shi" data-slug-hash="PoqwPEz" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Web Speech API with Promise">
  <span>See the Pen <a href="https://codepen.io/7shi/pen/PoqwPEz">
  Web Speech API with Promise</a> by 七誌 (<a href="https://codepen.io/7shi">@7shi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

↑ エラーになる場合は一度 [CodePen](https://codepen.io/) を開いてから、この記事をリロードしてください。

# 概要

前回の記事では正常終了 `onend` を `resolve`、異常終了 `onerror` を `reject` として扱いました。

* [非同期APIをPromiseでラップしてasync/awaitで使う](https://qiita.com/7shi/items/a2bb35f27cd4a56f7bac)

```javascript
function speak(lang, text) {
    return new Promise((resolve, reject) => {
        let u = new SpeechSynthesisUtterance(text);
        u.lang = lang;
        u.onend = resolve;
        u.onerror = reject;
        speechSynthesis.speak(u);
    });
}
```

読み上げ中に `speechSynthesis.cancel()` を呼ぶことでキャンセルできます。通常終了と同じ `onend` イベントが発生するため、イベントではキャンセルされたことが検知できません。

何らかの手段でキャンセルされたことを通知する必要があります。

# 戻り値

`resolve` への引数は `await` を通して戻り値になります。

```javascript:ブラウザのコンソール
> p = new Promise((resolve, reject) => resolve(123))
> await p
123
```

これを利用して正常終了かキャンセルかを戻り値で区別するように `speak` を実装します。例外を無視するため終了と同じ扱いとします。

```javascript
let stop = () => false;
function speak(lang, text) {
  return new Promise((resolve, reject) => {
    let speakend = cancel => {
      speakend = () => false;
      if (cancel) speechSynthesis.cancel();
      resolve(cancel);
      return cancel;
    };
    stop = () => speakend(true);
    let u = new SpeechSynthesisUtterance(text);
    u.lang = lang;
    u.onend = u.onerror = () => speakend(false);
    speechSynthesis.speak(u);
  });
}
```

キャンセルするには外部から `stop()` を呼びます。Promise のコンストラクタで `stop` を書き換えて `speakend` 経由で `resolve(true)` を呼べるようにしておくことで、終了イベント `onend` よりも先に終了させます。

# 利用方法

複雑さは Promise の中に閉じ込めたため、利用側のコードは簡単になります。

```javascript
button.onclick = async function() {
  if (stop()) return;
  button.textContent = "Stop";
  for (let [element, lang, text] of texts) {
    element.classList.add("speaking");
    let cancel = await speak(lang, text);
    element.classList.remove("speaking");
    if (cancel) break;
  }
  button.textContent = "Start";
};
```

ループによっていくつかのテキストを読み上げます。`speaking` をマークすることで読み上げ個所を示します。`await speak()` から戻ってマークを解除して、キャンセルされていればループから抜けます。

`reject` で例外によってキャンセルを通知することも可能ですが、今回は `resolve` によって戻り値で通知した方が利用側のコードが簡単になると判断しました。

戻り値は正常終了のときに `true` にした方が自然かもしれませんが、今回はキャンセルに注目して値を設定しました。

# 参考

Web Speech API の使い方は以下の記事を参照してください。

* [Web Speech API で読み上げ位置を取得](https://qiita.com/7shi/items/43452dcd34e57100fc3c)
DC/AC電源を操作する

# はじめに

マイコンをいじっていると、おうちハックネタで、3.3Vや5Vではない、DC/AC電源を操作したくなることがある。

これまで、

* [Bluetooth LE (BLE) SATECHI LED電球 を Raspberry Pi3 から 制御](https://qiita.com/hidenorly/items/757ce2d949846e035bc2)
* [エアコン リモコン (K-1028E) を W-ROOM02 で WiFiリモコン化してみた (ハード編)](https://qiita.com/hidenorly/items/cc0373248070253f6091)
* [年末年始だし M5StickC を 触って、NTP 時計付 人感センサー赤外線スイッチを作る (M5StickC事始め)](https://qiita.com/hidenorly/items/81633b1b93452c2afc89)

* [Wemoのようなスイッチを真似てAlexaスキル経由で操作もしてみた](https://github.com/hidenorly/WiFiSwitch)


はたまたServoでシーソースイッチを操作してみたこともある。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100425/6bd27d7a-4fd6-5f87-4b32-7ca20b3f9fe5.png)


このようにより間接的に操作はしてきたが、マイコンからより直接操作する方法はある。

それは、リレーによる間接的なスイッチ操作である。

# 中華リレーについて

Amazonなどでおなじみの中華リレーSRD-05VDC-SL-C ([Datasheet](https://www.google.com/search?q=srd-05vdc-sl-c+%E3%83%87%E3%83%BC%E3%82%BF%E3%82%B7%E3%83%BC%E3%83%88)) を参考にされたい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100425/399431c2-861e-ad18-0c22-d4804e39b1c2.png)

2chのリレーボードのIN1/IN2にLOWで、NO(Normaly Open)(つまりスイッチOFF)をClose(つまりスイッチON)にできる。

リレーの駆動には、+5Vが必要だが、Active Lowなので、Open Drain設定にして、+5Vで、10Kオームなどでpull upしておけばよいのだが、そもそもこのボードではフォトカプラによる絶縁処理がされており、ESP32などの3.3V I/O系を直接接続できる。(制御のGPIO側と、実際にリレーのコイルの駆動側が絶縁されている。これにより直接リレーのコイルをドライブした際の逆起電力対策のるチェナーダイオードも不要である)

この場合、JD-VCCの端子とVCCの端子のジャンパーを取って、VCC側に+3.3Vを入れ、JD-VCC側(リレーコイル側)は+5Vにすることで、I/Oの電源で制御できる。

```
+3.3V      +3.3V      +5V
  |        |          |
  v        v(VCC)     v(JD-VCC)
[MCU] ===> [LED => Receiver] ===> [Relay] ===> [SW in Relay]
```

みたいに内部で光絶縁されていて、信号レベルの変換も結果的にできている。

なお、リレーの定格内で使用する必要があるので注意 (DC/AC別の定格の記載があるので参照のこと)

続く
SQlite3にてレコード作成日時のタイムスタンプ(ローカルタイム)設定でエラー

はまったのでメモ
環境：Python 3.7.1
利用モジュール：sqlite3

レコード新規作成時にローカルタイムのタイムスタンプを自動で挿入するようにテーブル作成

``` sql
create table user_data(
name text not null,
creation_datetime timestamp not null default datetime(current_timestamp,'localtime'))
```
上記のコードを実行。すると・・・
「sqlite3.OperationalError: near "(": syntax error」が発生。
「creation_datetime」カラムのdatetime関数を括弧で囲まないと文法エラーになるもよう。

``` sql
create table user_data(
name text not null,
creation_datetime timestamp not null default (datetime(current_timestamp,'localtime')))
```
上記コードで正常にテーブルが作成されることを確認。
【VBS】指定したフォルダの最新ファイルを取得する

# はじめに
監視ソフトのスクリプト(VBScript)で、バックアップソフトのログを監視して正常か異常かを判定する処理をしています。
最近になって、バックアップは正常に行われているのに異常の通知がされることが数回ありました。
原因を調べてみると、監視ソフト側でスクリプトの処理が60秒以上となりタイムアウトエラーになっていました。

ログフォルダを見てみると、2015年から1日1回出力されており単純計算でも365日x5＝1825件以上はあるわけです。でも、正常か異常かを判断するのは最新のログファイル1つだけです。この最新のログファイルを見つける処理に時間がかかってしまっていたわけです。

# 現行版
ログフォルダの最新ファイルを取得するのに、WMIのCIM_DataFileクラスを使用してました。
しかし、WQL(WMI Query Language)は、ソートサポートしてないので`ORDER BY`句は使えません。
最新ファイルを取得するには、ファイル数分の更新日時を比較して最新ファイルを求めることになります。

```vb
AIPLOG_PATH = "C:\Program Files (x86)\NetJapan\ActiveImage Protector\logs"
MsgBox GetLatestFileName(AIPLOG_PATH, "log")

' Logフォルダの最終更新日時が最新のログファイル名を返す
Function GetLatestFileName(path, ext)
    Dim fso, locator, service, files, drive, latest, latestFile

    Set fso = CreateObject("Scripting.FileSystemObject")
    Set locator = CreateObject("WbemScripting.SWbemLocator")
    Set service = locator.ConnectServer
    drive = fso.GetDriveName(path)
    path = Replace(path, drive, "") & "\"
    Set files = Service.ExecQuery("SELECT * FROM CIM_DataFile " _
              & "WHERE Drive = '" & drive & "'" _
              & "  AND Path = '" & Replace(path, "\", "\\") & "'" _
              & "  AND Extension = '" & ext & "'")

    latest = ""
    latestFile = ""
    For Each f In files
        If Latest < f.LastModified Then
            latest = f.LastModified
            latestFile = f.Filename & "." & f.Extension
        End If
    Next

    GetLatestFileName = latestFile

End Function
```

この方法は、ファイル数が多くなってくれば時間がかかってしまいます。1800件くらい大した数じゃないと思っていたのですが、予想に反して異様に遅いですね。ただ初回が遅くて2回目はキャッシュが効くのか数秒で結果が返ってきます。

結局、1年分のログファイルだけにすることでタイムアウトエラーにはならなくなりました。

# 高速版
大量ファイルがあっても高速に最新ファイルを取得する方法があります。それは、DOSのDirコマンドを使用することです。
Dirコマンドには、並び替えの方法を指定する「/o」オプションがあります。

`DIR [パス] /o-d` とすれば日時の降順になります。
その他に「/b」オプションでファイル名のみ、「/a:-d」オプションでディレクトリ以外の一覧にしています。

```vb
AIPLOG_PATH = "C:\Program Files (x86)\NetJapan\ActiveImage Protector\logs"
MsgBox GetLatestFileName(AIPLOG_PATH, "log")

' Logフォルダの最終更新日時が最新のログファイル名を返す
Function GetLatestFileName(path, ext)
    Dim wshShell, exec, line

    Set wshShell = CreateObject("WScript.Shell")

    Set exec = WshShell.Exec("cmd /c dir /a-d /b /o-d """ & path & "\*." & ext & """")
    exec.StdIn.Close()

    Do While Not exec.Stdout.atEndOfStream
        line = Trim(exec.StdOut.ReadLine())
        Exit Do
    Loop 

    Set exec = Nothing
    Set wshShell = Nothing

    GetLatestFileName = line

End Function
```

# 最後に
ファイル一覧を取得するならDirコマンドが高速でおすすめです。
以前、大量ファイルがあるフォルダのファイル一覧をFileSystemObjectを再帰処理で使用して取得したら全然遅くて、Dirコマンドにしたら数秒で結果が返ってきて驚いたことがあります。

今回に関してはログファイルはずっと保持しておく必要もないので、メンテナンスのタイミングで1年分程度残して削除する運用にすればいいでしょう。そうすれば高速版にしなくても速度的には問題にはならないです。
groupby rollingのサンプル

# groupby rollingの使い方の簡単なサンプルです。


#テストデータ
```

data=[
{"氏名":"山田","回数":5, "国語":40 ,"算数":40 },
{"氏名":"山田","回数":4, "国語":40 ,"算数":50 },
{"氏名":"山田","回数":3, "国語":30 ,"算数":40 },
{"氏名":"山田","回数":2, "国語":20 ,"算数":30 },
{"氏名":"山田","回数":1, "国語":10 ,"算数":20 },

{"氏名":"野田","回数":1, "国語":10 ,"算数":30 },
{"氏名":"野田","回数":2, "国語":20 ,"算数":40 },
{"氏名":"野田","回数":3, "国語":30 ,"算数":20 },
{"氏名":"野田","回数":4, "国語":40 ,"算数":50 },
{"氏名":"野田","回数":5, "国語":40 ,"算数":70 },

    
]
import pandas as pd
df=pd.DataFrame(data)
df.index.name="idx"
df

```

|   idx | 氏名   |   回数 |   国語 |   算数 |
|------:|:-------|-------:|-------:|-------:|
|     0 | 山田   |      5 |     40 |     40 |
|     1 | 山田   |      4 |     40 |     50 |
|     2 | 山田   |      3 |     30 |     40 |
|     3 | 山田   |      2 |     20 |     30 |
|     4 | 山田   |      1 |     10 |     20 |
|     5 | 野田   |      1 |     10 |     30 |
|     6 | 野田   |      2 |     20 |     40 |
|     7 | 野田   |      3 |     30 |     20 |
|     8 | 野田   |      4 |     40 |     50 |
|     9 | 野田   |      5 |     40 |     70 |

#氏名毎の「回数」の直近３回の和を出す過程でgroupby rollingを使います。


```
df2=df.sort_values(["氏名","回数"])  #この行を忘れると、こっそりとバグる

df2_sum=df2.groupby(["氏名"]).rolling(3)[["算数"]].sum()
df2_sum.reset_index(inplace=True)
df2_sum.set_index(["idx"],inplace=True)

df2["直近3回の算数の和"]=df2_sum["算数"]
df2
```

# 結果

|   idx | 氏名   |   回数 |   国語 |   算数 |   直近3回の算数の和 |
|------:|:-------|-------:|-------:|-------:|--------------------:|
|     4 | 山田   |      1 |     10 |     20 |                 nan |
|     3 | 山田   |      2 |     20 |     30 |                 nan |
|     2 | 山田   |      3 |     30 |     40 |                  90 |
|     1 | 山田   |      4 |     40 |     50 |                 120 |
|     0 | 山田   |      5 |     40 |     40 |                 130 |
|     5 | 野田   |      1 |     10 |     30 |                 nan |
|     6 | 野田   |      2 |     20 |     40 |                 nan |
|     7 | 野田   |      3 |     30 |     20 |                  90 |
|     8 | 野田   |      4 |     40 |     50 |                 110 |
|     9 | 野田   |      5 |     40 |     70 |                 140 |


## もっとスマートなやり方がありそうな気がする。ご存じの方は教えていただけると助かります。

@daikiclimateさんから、もっとスマートなコードをいただきました。

```
df = df.sort_values(["氏名","回数"]).reset_index().drop("idx", axis = 1)
df["math_sum"]=df.groupby(["氏名"]).rolling(3)["算数"].sum().reset_index()["算数"]
```


#参考
[Group by: split-apply-combine](https://pandas.pydata.org/pandas-docs/stable/user_guide/groupby.html)
PythonでABC154のA~Dを解く

### はじめに
こんばんは。tax_freeです。[前回](https://qiita.com/taxfree_python/items/3cf66e65b581673d66d8)からレートが34上がりました。今週は期末テストです()

### A問題
[問題](https://atcoder.jp/contests/abc154/tasks/abc154_a)

**考えたこと**
if文で条件分岐するだけです。

```python
s, t = map(str,input().split())
a, b = map(int,input().split())
u = str(input())

if u == s:
    print(a-1,b)
else:
    print(a,b-1)
```

###B問題
[問題](https://atcoder.jp/contests/abc154/tasks/abc154_b)

**考えたこと**
与えられる文字列の長さを調べて、文字列の長*'x'してあげればよい。
str()は自分で分かりやすいようにわざと書いています。
@shiracamus さんから指摘があったので修正しました。

```python
s = list(str(input())) → s = str(input())
```

```python

s = str(input())
print('x'*len(s))
```

###C問題
[問題](https://atcoder.jp/contests/abc154/tasks/abc154_c)

**考えたこと**
整数列の要素が全て異なってる→同じ要素がない、ことなのでpythonのsetに入れて調べました。
[~~コピペ~~した記事](https://note.nkmk.me/python-list-duplicate-check/)

```python

n = int(input())
a = list(map(int,input().split()))

def has_duplicates(seq):
    return len(seq) != len(set(seq))
if has_duplicates(a):
    print('NO')
else:
    print('YES')
```

###まとめ
Dは、期待値の考えかたが苦手(模試の選択問題も確率は選べばないようにしている)。
Eは、Kの値が3個しかなかったので気合で場合分けできると思ったけどできなかった
次回のABC155はA~Dくらいは解けるようにがんばる。期末テストも!
では、おやすみなさい
array_filterでarray？ってなったお話

## 前置き

* array_filter は何か便利そうだが、よく分かっていないので使っていないまま
* 使えるようになりたい！ので整理する


## array_filter とは？

> callback 関数によりフィルタ処理が行われた array の全ての要素を含む配列を返します。 callback 関数が TRUE を返した場合、 array の現在の値が結果の配列に入ります。 配列のキーは保存されます。
> 引用元 : [PHP_ array_filter - Manual](https://www.php.net/manual/ja/function.array-filter.php)

* ・・ざっくり「第二引数でtrueを返したものだけを配列として返す（それ以外は削除する。配列のキーはそのまま）」


## 使ってみた

```
$ary = [0, 1, 2, 2, 3];

$tmpAry = (array_filter($ary, function($num){
	return $num == 2;
}));

for($i=0; $i<count($tmpAry); $i++){
	var_dump($tmpAry[$i]);
}

/* 出力結果 : 
NULL
NULL
*/
```


## NULL??

* array_filterでフィルタリングした内容をvar_dumpで出力し、値を確認してみます

```
$ary = [0, 1, 2, 2, 3];

$tmpAry = (array_filter($ary, function($num){
	return $num == 2;
}));

var_dump($tmpAry);

/* 出力結果 : 
array(2) {
  [2]=>
  int(2)
  [3]=>
  int(2)
}
*/
```


### 検証結果

* フィルタに引っかかったものだけが（配列のキーはそのままに）残る
* 上の例では、0番目と1番目が存在しないので NULL と出力された
* 次：空いている要素を埋めたいので `array_merge` を使う


## array_merge とは？

> 前の配列の後ろに配列を追加することにより、 ひとつまたは複数の配列の要素をマージし、得られた配列を返します。
> （中略）
> 入力配列の中にある数値添字要素の添字の数値は、 結果の配列ではゼロから始まる連続した数値に置き換えられます。
> 引用元 : [PHP_ array_merge - Manual](https://www.php.net/manual/ja/function.array-merge.php)

* ・・ざっくり「配列を結合し、添え時の数値は0から振り直してくれる」（結合対象の配列がない場合は前者は無効、後者は有効）

## 使ってみた

```
$ary = [0, 1, 2, 2, 3];

$tmpAry = (array_filter($ary, function($num){
	return $num == 2;
}));

var_dump($tmpAry);

/* 出力結果 : 
array(2) {
  [0]=>
  int(2)
  [1]=>
  int(2)
}
*/

$tmpAry = array_merge($tmpAry);

for($i=0; $i<count($tmpAry); $i++){
    var_dump($tmpAry[$i]);
}

/* 出力結果 : 
int(2)
int(2)
*/
```

## まとめ

* array_filter後にfor文を制御変数で回す場合は、まずarray_mergeで空いている要素を前に詰める
* foreachで回す場合も、「array_filter後の配列のキーはそのまま」ということを意識する
M5StickCで六角形LEDをLチカしてみた

# はじめに
Switch Science で [M5Stack用NeoPixel互換LED搭載 六角形ユニット](https://www.switch-science.com/catalog/6058/) が発売されていました。
３７個のNeoPixel LEDを六角形に配置し、Groveで接続できるもので、さっそく試してみました。
[UIFlow](https://m5stack.github.io/UIFlow_doc/ja/)を使うと簡単に思い通りの光らせ方をすることができます。

<img width="800" alt="gif1" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149785/3cbb62ab-944e-d34a-8e54-2f2a209ec10a.gif">


# 使ったもの
- [M5Stack用NeoPixel互換LED搭載 六角形ユニット](https://www.switch-science.com/catalog/6058/)
- M5 StickC
- UIFlow Ver 1.4.4

# 事前準備
- UIFlowをM5StickCにインストール
- M5StickCにGroveでLEDを接続

M5StickCで試しましたが、M5Stackでも同じように使えると思います。

# UIFlowで光らせる
### ブロックの追加

最初にUnitsから＋ボタンで「RGB LED」にチェックを入れて追加します。
NumberにはLEDの数である「37」を指定してください。

<img width="800" alt="image1" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149785/d51a40d9-5902-835b-fab5-a6d91370fea7.png">

<img width="800" alt="image2" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149785/e2244016-fd17-4edc-443f-2eecef55fee0.png">

すると、ブロックメニューの「Units→RGB LED」から、色をパレットから選択するタイプと、数値で指定するタイプの、２つのブロックが使えるようになります。前者は色を直感的に指定でき、後者はロジックと組み合わせて数値を指定することができます。

<img width="800" alt="image3" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149785/e713f699-e38d-3aab-aeae-a615ca357c80.png">

どの場所を光らせるかは、チェックボックスで簡単に指定できます。

### パレットから色を指定
パレットから色を指定するタイプのブロックは、右上部分で色を指定、六角形の光らせたい部分にチェックを入れて場所を指定します。
以下は赤い明滅を繰り返すパターンの作例です。

<img width="800" alt="image4" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149785/1c40d0fe-a1f6-003a-2ccf-8ced65bf71b5.png">

<img width="800" alt="gif2" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149785/330b8b14-c74b-c551-cbc6-0ff32994c2b1.gif">

一秒毎に赤と黒（＝発光OFF）を繰り返すループにしています。

### 数値で色を指定
数値で色を指定するタイプのブロックは、変数を使ってセンサーや計算で求めた値で変化をさせることができます。
以下は傾きを検知して色を変化させるパターンの作例です。

<img width="800" alt="image5" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149785/8268d37e-ee33-b6cd-5006-934dd2c39661.png">

<img width="800" alt="gif3" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149785/330a3913-9524-a7f3-d8da-695b660d6be7.gif">

右に傾けると赤、左に傾けると青に光るよう、センサの傾きを色に連動させています。

# おわりに
六角形のLEDは色＋アイコンのようなシンプルな形で伝達する情報量を増やすことができそうです。複数を並べてみるのも面白そうです。
何に活用できるのか方法を探してみたいと思います！
ROS kineticでmove base使用時にDWAPlannerROS planner周りのエラーが出た時の対策メモ

# 目的
ROS kineticでmove base使用時にDWAPlannerROS planner周りのエラーが出た時の対策メモです

# エラー内容と対策

```
[FATAL] [1581261211.770393174, 364.342000000]: Failed to create the dwa_local_planner/DWAPlannerROS planner, are you sure it is properly registered and that the containing library is built? Exception: According to the loaded plugin descriptions the class dwa_local_planner/DWAPlannerROS with base class type nav_core::BaseLocalPlanner does not exist. Declared types are  base_local_planner/TrajectoryPlannerROS
[move_base-4] process has died [pid 15078, exit code 1, cmd /opt/ros/kinetic/lib/move_base/move_base cmd_vel:=cmd_vel odom:=odom __name:=move_base __log:=/home/seigot/.ros/log/79e9957e-4b4c-11ea-9eba-3df50c86ca42/move_base-4.log].
log file: /home/seigot/.ros/log/79e9957e-4b4c-11ea-9eba-3df50c86ca42/move_base-4*.log
```

DWAPlannerROSライブラリがないので、以下の通りインストールすればよい。（kineticの場合）

```
sudo apt-get install ros-kinetic-dwa-local-planner
```

# 参考
[navigation-problem-with-cob3-dwaplanerros-create-fail](https://answers.ros.org/question/266411/navigation-problem-with-cob3-dwaplanerros-create-fail/)
turtlebot3_gazebo起動時のエラー対策

# 目的
turtlebot3_gazebo起動時のエラー対策メモです

# エラー内容と対策

```
RLException: Invalid <arg> tag: environment variable 'TURTLEBOT3_MODEL' is not set. 

Arg xml is <arg default="$(env TURTLEBOT3_MODEL)" doc="model type [burger, waffle, waffle_pi]" name="model"/>
The traceback for the exception was written to the log file
```

env TURTLEBOT3_MODELがないので、以下の通り環境変数を与えればよい（burgerの場合）

```
$ export TURTLEBOT3_MODEL=burger
```


[export_turtlebot3_model](https://emanual.robotis.com/docs/en/platform/turtlebot3/export_turtlebot3_model/)
>TurtleBot3 has three models, burger, waffle, and waffle_pi, so you have to set which model to use before using. To do this, we specify the model to be used with the export command.
>
>export TURTLEBOT3_MODEL=burger
>export TURTLEBOT3_MODEL=waffle
>export TURTLEBOT3_MODEL=waffle_pi


# 参考
[export_turtlebot3_model](https://emanual.robotis.com/docs/en/platform/turtlebot3/export_turtlebot3_model/)
ただのメモ

#CentOS 7での使用したコマンド一覧
自分用の備忘録として残しますが、多少解説つきで交換いたします。
使用したコマンドはどんどん記載していくので随時更新予定です。

##scpコマンドによるデータダウンロード、アップロード
こちらはssh接続が可能なリモートホスト間でのファイル転送コマンドです。

まずは、リモートからssh接続先のサーバーへファイルをアップロードする方法です。ssh接続していたら抜けてくださいね。

```
# scp xxx.txt root@<ipアドレス>:/tmp
// rootユーザーの/tmpディレクトリに xxx.txtをアップロードします
```
次に、ssh接続先からファイルをダウンロードする方法です。

```
# scp root@<ipアドレス>: /tmp/xxx.txt /Users/Admin/Desktop
// tmpディレクトリのxxx.txtファイルをDesktop上に置く(Macです)
```
##IPアドレスの固定orDHCPの設定変更①
ESXi上のCentOSのIPアドレスを固定したかったのでファイルを編集しました。

```
# ls /etc/sysconfig/network-scripts/
ifcfg-ens160     ifdown-eth   ifdown-routes  ifup-aliases  ifup-plip    ifup-tunnel
ifcfg-lo         ifdown-ippp  ifdown-sit     ifup-bnep     ifup-plusb   ifup-wireless
ifdown           ifdown-ipv6  ifdown-tunnel  ifup-eth      ifup-post    init.ipv6-global
ifdown-Team      ifdown-isdn  ifup           ifup-ippp     ifup-ppp     network-functions
ifdown-TeamPort  ifdown-post  ifup-Team      ifup-ipv6     ifup-routes  network-functions-ipv6
ifdown-bnep      ifdown-ppp   ifup-TeamPort  ifup-isdn     ifup-sit

#vim /etc/sysconfig/network-scripts/ifcfg-ens16
```

```
TYPE="Ethernet"
PROXY_METHOD="none"
BROWSER_ONLY="no"
BOOTPROTO="static" #dhcp->static //変更
IPADDR=192.168.1.96 #add //追加
NETMASK=255.255.255.0 #add //追加
GATEWAY=192.168.1.1 #add //追加
DNS1=192.168.1.1 #add //追加
DEFROUTE="yes"
IPV4_FAILURE_FATAL="no"
IPV6INIT="yes"
IPV6_AUTOCONF="yes"
IPV6_DEFROUTE="yes"
IPV6_FAILURE_FATAL="no"
IPV6_ADDR_GEN_MODE="stable-privacy"
NAME="ens160"
UUID="53806499-7069-49cb-a15c-fd7e9eb89809"
DEVICE="ens160"
ONBOOT="yes"
```

```
#service network restart
//サービスを再起動
```

##IPアドレスの固定orDHCPの設定変更②
```
# nmcli connection modify ens33 ipv4.addresses 192.168.1.6
# nmcli connection modify ens33 ipv4.method manual
```

##SELinuxに新しいポートを追加
```
#semanage port --add --type ssh_port_t --proto tcp xxx
// ssh_port_tタイプにxxx番ポートを追加(プロトコルはtcp)
```

##ファイアーウォールポート許可
```
# firewall-cmd --add-port=22/tcp
```
flagパッケージを利用しているときに、オプションの値をスライスで受け取りたい / 同じオプションを複数回指定し、その値をすべてスライスに詰めたい

Go言語の`flag`パッケージを利用して、コマンドラインツールを作成していると、オプションの値をSliceで受け取りたい場合があります。たとえば「同じオプションを複数回指定し、その値をすべてスライスに詰めたい」という場合、どのように実装すればよいでしょうか?

__答えだけ先に述べておくと、[`flag.Value`インターフェース](https://golang.org/pkg/flag/#Value)を実装し、パース時には[`flag.Var`](https://golang.org/pkg/flag/#Var)を呼び出します。__

今回は一例を示すにあたって、`div`コマンドを作成してみます。`div`コマンドは標準入力から数値が与えられると、`-d`オプションで与えられた数値で割り切れるかどうかを確認し、割り切れる場合は標準入力の値をそのまま標準出力に出力するというものです。ここでは`-d`オプションは複数回指定でき、複数回指定した場合は、1つでも割り切ることができればOKということにします。

動作イメージは次の通りです。ここでは1から15までの数値のうち、3または5で割り切れるものを出力しています。

```
$ seq 15 | ./div -d 3 -d 5
3
5
6
9
10
12
15
```

`div`コマンドの実装例は次の通りになります。

```go
package main

import (
	"bufio"
	"flag"
	"fmt"
	"os"
	"strconv"
)

type Divisors []int

func (ds *Divisors) String() string {
	return fmt.Sprintf("%v", *ds)
}

func (ds *Divisors) Set(s string) error {
	d, err := strconv.Atoi(s)
	if err != nil {
		return err
	}
	*ds = append(*ds, d)
	return nil
}

func main() {
	var divisors Divisors
	flag.Var(&divisors, "d", "除数を指定してください")
	flag.Parse()

	stdin := bufio.NewScanner(os.Stdin)
	for stdin.Scan() {
		// 標準入力から1行読み込み、整数に変換。
		// 変換できない場合は理由を標準エラー出力に出力し、その行はスキップ
		line := stdin.Text()
		dividend, err := strconv.Atoi(line)
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			continue
		}

		// 標準入力から読み込んだ整数が、dオプションから取得した整数で割り切れるかどうかを検査。
		// 割り切れた場合は標準入力から読み込んだ値を標準出力に出力する。
		for _, divisor := range divisors {
			if dividend%divisor == 0 {
				fmt.Fprintln(os.Stdout, line)
				break
			}
		}
	}
}
```

ここでは`Divisors`型(実体は`int`スライス)を作成、`flag.Value`インターフェースの関数`String()`と`Set()`をそれぞれ実装しています。パース時に`flag.Var`関数を呼び出すと、`Divisors`型(実体は`int`スライス)に`-d`オプションの値が格納されることが分かります。
今日の外出するテンションをニューラルネットワーク使って雑に数式化してみたった

# Motive

今季は人生で経験のしたことがないくらいの暖冬でしたが、この数日は平年の状況に戻ってかなり寒かった気がします。
テラサムスハムニダです:oden:

外出する予定がなかったとは言えないですが、ここまで寒いとインドアになってしまいます。

ここでは、いろいろな要因を並べてみてとても根本的でかつ雑で簡易的な形でのニューラルネットワークを使い、自称ニートが外出するかしないかの判断を数式化してみました。

# Describe

![ fig1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288206/9bb4487a-54fb-e7d3-80d8-07f97153340a.png)

# Formula

```math
Y
\\=
X \times W
\\ =
\begin{bmatrix}
x_1 & x_2 & x_3 & x_4 & x_5 & x_6 
\end{bmatrix}

\times

\begin{bmatrix}
w_1 \\ w_2 \\ w_3 \\ w_4 \\ w_5 \\ w_6 
\end{bmatrix}
\\ = 

x_1 \times w_1 + x_2 \times w_2 + x_3 \times w_3 + x_4 \times w_4 + x_5 \times w_5 + x_6 \times w_6

\\
```

```math
w_1 = - \acute{w_1} \\
w_2 = \acute{w_2} \times 5 \\ 
w_3 =  \left\{
\begin{array}{ll}
-50 & (snow) \\
-25 & (rain) \\
10 & (cloud) \\
30 & (sun)
\end{array}
\right. \\
w_4 = - \acute{w_4} \\
w_5 = \acute{w_5} \\
w_6 = - \acute{w_6} \times 10 
```

新型ウイルスですが空気中でも感染するみたいです。今まで身体に異常がなければあまり重症化しないみたいですが、感染した場合は２〜３週間休まなければならないというリスクがあるので10倍にしてレバレッジを効かせています。
かかっても発熱とかあるので不特定多数の人が多い場所へは行きたくなかったすね:mask:

以上のことで出力値Yの値が低くなりそうなので外出しなかったとです。:smirk_cat:

今回はコンセプトの話なので、ここから具体的に値を出してシグモイド関数を使ってYの値を更新するかの判定をするなどについては割愛します。（てか詳しく知らんし）

# Postscript
今思えば専門の必修科目が９割5分くらいあって自由に選択できる講義がなかったです。現在では緩和されているのですが自由すぎて単位を落としている学生が多いと聞いているので逆によかったのですが。:expressionless:

数少ない選択講義で何も考えずにニューラルネットワークをとったのですが、ここまでトレンドになって役立つとは想像がつかなかったです。:sweat_smile:


# Reference
- ゼロから作るDeep Learning 3章 ニューラルネットワーク
    - かなり最初の方の話
- [痛いニュース - 新型コロナウイルス、エアロゾル感染を確認](http://blog.livedoor.jp/dqnplus/archives/1997862.html)
Rails6 バリデーションをかける

# 目的

- 空欄でのDB登録を避けるためのバリデーションの記載方法をまとめる

# 空での保存を避けるバリデーション

- 下記の記載を当該のモデルファイルに記載する。

    ```ruby
    class Post < ApplicationRecord
      validates :バリデーションをかけたいカラム名, {presence: true}
    end
    ```

# 空での保存を防ぎ、かつ総文字数を140文字以下にするバリデーション

- 下記の記載を当該のモデルファイルに記載する。

    ```ruby
    class Post < ApplicationRecord
        validates :content, {presence: true, length: {maximum: 140}}    
    end
    ```
セキュリティマネジメントの勉強-サイバー攻撃手法

#サイバー攻撃手法
日々進化してるので最新情報はIPA見てね
https://www.ipa.go.jp/security/

##パスワードに関する攻撃
パスワードクラックともいう

###ブルートフォース
適当な文字列で総当たり攻撃する。
同じパスワードをいろんなユーザーに対して使うリバースブルートフォースもある

###辞書
辞書の用語を順に使ってログイン試行する

###スニッフィング
盗聴することでパスワードを知る

###リプレイ攻撃
パスワードなどの認証情報を送信しているパケットを取得
それを再度送る事でユーザーになりすます攻撃
暗号化されてても有効なので厄介

###パスワードリスト攻撃
他のサイトで拾ったID/パスワードの組み合わせを使って
別サイトにログインを試みる

###レインボー攻撃
ハッシュ値に対するパスワードリストをつくっておく(レインボーテーブル)
これをつかってパスワードを推測する

##DoS攻撃
Denial of Service attack（サービス不能攻撃）
踏み台を使い、複数端末から一斉に攻撃するのをDDoS(Distributed DoS attack)という

##バッファオーバーフロー
メモリ領域を超えるデータを送りこみ、領域破壊をする攻撃
入力チェックが大事

##SQLインジェクション
不正な条件入れたりする
エスケープしたりバインドしたりするのが大事

##XSS
クロスサイトスクリプティング
悪意のあるスクリプトを標的のサイトに埋め込む
クライアント側で実行させてCookieを取ったりする
こいつも対処方法はエスケープ

##CSRF
クロスサイトリクエストフォージェリ
サーバー側で不正な書き込みをさせたりする

##HTTPヘッダインジェクション
ヘッダの中に不正なスクリプトを注入して行う
キャッシュサーバに不正キャッシュを作らせるHTTPレスポンス分割攻撃というのもある

##ディレクトリトラバーサル
パスに../とか突っ込んだりして、公開予定ではないファイルを指定する攻撃

##セッションハイジャック
セッションIDを不正利用する

##OSコマンドインジェクション
内部的にシェルに流し込まれたりするとやばい

##踏み台攻撃
関係のない第三者にサーバを中継されること
メールサーバの場合をオープンリレー
DNSサーバの場合をオープンリゾルバという

##IPスプーフィング
IPアドレスを艤装して、他のサーバに成りすます
DoSやDNSキャッシュポイズニングと合わせて
攻撃者の身元を隠すために使われる

##DNS攻撃
こいつを悪用するパターン

###DNSキャッシュポイズニング攻撃
DNSサーバのキャッシュに不正情報を入れ込む

###DNSリフレクタ
DNSを使ったDoS攻撃。DNSamp攻撃ともいう
IPスプーフィングを組み合わせて、DNSの応答が特定のサーバに集中するように仕向ける

###ランダムサブドメイン攻撃
オープンリゾルバに対して、特定ドメインに対する存在しないランダムなサブドメインを問い合わせる行為
特定ドメインに対するDDoS攻撃

###ドメイン名ハイジャック攻撃
何らかの方法でドメインを奪い取ること

##ソーシャルエンジニアリング
人間の心理的、社会的性質につけ込む手法
肩越しに盗み見るショルダハッキングや、ごみ箱からパスワードかかれた紙を探すスキャベジングなどがある

##フィッシング
銀行とか信頼できる機関を装って偽サイトに誘導するやつ

##クリックジャッキング
ボタンの要素を隠蔽したり偽装したりして意図しない動作をさせる行為

##ドライブバイダウンロード
WEBサイト見ただけでダウンロードさせたりするもの
昔流行ったガンブラーとか、広告を改ざんしたりする

##中間者攻撃
クライアントとサーバの間に割り込み、正規の相互認証が行われているように見せかける
MITM攻撃と略される場合もある(Man in the middle Attack)
応用としてMITB攻撃(Man in the Browser Attack)もある
マルウェアでブラウザの通信を中継して改竄するパターン

##サイドチャネル攻撃
暗号処理してる装置の動作を観察したりして、機密情報を取得しようとする
処理時間をみたり、電磁波を解析するとか。
これをテンペスト攻撃というらしい

##ゼロデイ攻撃
未対応セキュリティホールを突かれるやつ

##フットプリンティング
攻撃準備として、ネットワーク上に存在している情報を収集する。
OSバージョンや構成情報など。
代表的なのはポートスキャン。

##標的型攻撃
特定の企業の社員に向けて、関係者を装いウイルスメールを送ったりする
そこからさらに攻撃の手を広げて、企業の機密情報を奪いにかかる。
APT(Advanced Persistant Threat)と呼ばれることもある
取引先になりすまし、金銭をだまし取るBEC(Business Email Compromise)もある

感染したらC&Cサーバと通信を行って情報を外部へ持ち出す。

こいつ自身はセキュリティソフトで防げない場合もある。
ファイアウォールを別途用意したりするなど別途出口対策を行う必要がある

##攻撃に使われる技術や仕組み
###仮想通貨
仮想通貨取引所を介さない場合、身元確認がなくやりとりができてしまう

###プリペイド型電子マネーや携帯
前払いは身分を明かさずに送金できてしまったりする
後払い（ポストペイ）はクレジット相当の信用情報が必要

###Torなどの秘匿化プロトコル
Tor(The Onion Router)は通信経路を匿名化するための技術
通信そのものではなく、送信元を秘匿化する

###ディレクトリリスティング
URLでディレクトリを指定すると、ファイル一覧を出せるサービス。
一般的なWebサイトでは無効にしとくべき

##ダークウェブ
インターネットで到達可能で未使用のIPアドレス空間をダークネットという
この空間に存在する特殊なWebサービスをダークウェブというらしい
[随時更新]Podmanを使ってみて気になったところ

# メモ

Podman Composeの新しいバージョンが出たら
再度試して結果を更新します。

# 現在の最新バージョン (2020/09/26現在)

| 製品名        |バージョン |リリース日  |
|:------------  |:--------:|:---------:|
| [Podman](https://github.com/containers/libpod)|2.1.1     | 2020/09/26|
| [Podman Compose](https://github.com/containers/podman-compose)|0.1.5     | 2019/09/04|

# 環境

Fedora CoreOS testing 31.20200223.2.0
Podman 1.8.0
Podman Compose 0.1.5

# docker-compose.ymlでサービス名とコンテナ名が同じにした時

Dockerの時はエラーになったことはなかった。
Podmanでは、エラーになる場合がある。
サービス名とコンテナ名は、別々の名前にすること。

例

```docker-compose.yml
version: '3.7'
services:
  adminer:
    # container_nameをadminerにしたら
    # Error: name adminer is in use: container already exists
    # のエラーになったので別名にしています。
    container_name: adminer1
    image: adminer:4.7.6
    restart: always
    ports:
      - 8080:8080
    depends_on:
      - db
  db:
    container_name: mariadb
    image: mariadb:10.4.12
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=password
      - MYSQL_DATABASE=sample
      - MYSQL_USER=user
      - MYSQL_PASSWORD=pass
    volumes:
      - ./mariadb/data:/var/lib/mysql
```

# restartの指定はPodmanではまだ使えない？

podman run と podman-composeで、restart=always
つけましたが、以下の操作後にコンテナが起動した
状態にはなりませんでした。

・Podmanでコンテナ起動
・EC2のインスタンス停止→起動

[Restart Policy not set #91](https://github.com/containers/podman-compose/issues/91)
>I don't know exactly if restart policy is here in 1.4.x
> release. I'll check it and post here.
>But currently I am using "podman generate systemd" 
>to specify restart policy.

google翻訳
>再起動ポリシーが1.4.xリリースにあるかどうかは
>正確にはわかりません。 
>チェックしてここに投稿します。
>しかし、現在、「podman generate systemd」を
>使用して再起動ポリシーを指定しています。

コンテナの起動/停止をsystemdで
管理する方法を利用する必要があるようです。
[podman-generate-systemd](https://podman.readthedocs.io/en/latest/markdown/podman-generate-systemd.1.html)
[Using systemd to control the startup of Podman containers](https://podman.io/blogs/2018/09/13/systemd.html)
[Running containers with Podman and shareable systemd services](https://www.redhat.com/sysadmin/podman-shareable-systemd-services)

# podman-compose

## docker-composeの以下の構成の物はうまく動きませんでした

・MariaDB 3コンテナ + Maxscale
以下のdocker-compose.ymlを使用
(maxscaleのバージョンだけ2.3に変更)
https://github.com/mariadb-corporation/maxscale-docker/blob/master/maxscale/docker-compose.yml

## 複数のコンテナをpodman-composeで起動した時にpodman psのports表示がおかしい気がする

例

```
$ podman ps

CONTAINER ID  IMAGE                              COMMAND               CREATED         STATUS             PORTS                   NAMES
a80a97d42396  docker.io/library/adminer:4.7.6    php -S [::]:8080 ...  7 seconds ago   Up 6 seconds ago   0.0.0.0:8080->8080/tcp  adminer1
a507d52a1d84  docker.io/library/mariadb:10.4.12  mysqld                14 seconds ago  Up 13 seconds ago  0.0.0.0:8080->8080/tcp  mariadb
```

# docker-composeのようにdownの-vオプションでサービスで使用されているすべてのボリュームを削除する機能はない

[Remove all volumes when shutting down #105](https://github.com/containers/podman-compose/issues/105)
【GAS】特定のSheetを取得する(Spreadsheet)

#特定のSpreadsheetを取得する

##はじめに
この記事では、GoogleAppsScript上でSpreadSheetの特定のSheetを取得することを紹介する。
Sheetの取得はSpreadsheetの取得が大前提なので、Spreadsheetの取得方法は[こちら](https://qiita.com/ryoichi_ben/items/5a1d8c35112dfb015799 "SpreadSheetを取得する。")から。

##Class
```javascript
SpreadsheetApp
//スプレッドシートにアクセス・作成をするためのクラス。
```

##Type

```javascript

SpreadsheetApp.getActiveSheet();
//現在アクティブ中のシートを取得する。
SpreadsheetApp.getSheetByName("シート名");
//シート名を取得してシートを取得する。
```

##Other
```javascript

.getName();
//シート名を取得する。
```
##Example


###Sheetを取得する。
* 現在Active中のシートを取得する。

```javascript
var SheetObject = SpreadsheetObject.getActiveSheet();
    Logger.log(SheetObject.getName());
```

* シート名を指定してシートを取得する。

```javascript
var SheetObject = SpreadsheetObject.getSheetByName("シート名");
    Logger.log(SheetObject.getName());
```

##Sample
```javascript
function myFunction() {
  var ss1 = SpreadsheetApp.openById("1-rQe4tnalMfTKRDCRCN6LWTaGvum67Ok8wnlxyG3-lo");
  //spreadsheetをss1に格納。
  
  var sh1 = ss1.getSheetByName("sheet1");
  //特定のシート(sheet1)をsh1に格納
  
  Logger.log(ss1);
  Logger.log(sh1.getName()); 
}

```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573711/c04128c0-3520-4c91-f0a2-9d7d52c2d1ce.png)
【GAS】特定のSpreadSheetを取得する(SpreadSheet)

#特定のSpreadsheetを取得する

##はじめに
この記事では、GoogleAppsScript上で特定のSpreadSheetを取得することを紹介する。
※GoogleAppsScriptのはじめ方・使い方などは省略する。

###Class
```javascript
SpreadsheetApp
//スプレッドシートにアクセス・作成をするためのクラス。
```

###Type

```javascript

SpreadsheetApp.getActiveSpreadsheet();
//現在アクティブ中のSpreadsheetを取得する。
SpreadsheetApp.OpenById("key");
//Spreadsheetキーを指定してSpreadsheetを取得する。
```

###Sample
* 現在Active中のSpreadsheetを指定する。

```javascript

var SpreadsheetObrect = SpreadsheetApp.getActiveSpreadsheet();
    Logger.log(SpreadsheetObject);
```
* 特定のSpreadsheetを取得する。

```javascript
var SpreadsheetObject = SpreadsheetApp.openById("key");
    Logger.log(SpreadsheetObject);
```

keyはSpreadsheetURLの以下のXXX部分。
https://docs.google.com/spreadsheets/d/XXX/edit...
敢えてRubyで学ぶ「ゼロから作るDeep Learning」禁断のPyCallからのpickleファイルの取り込み

「ゼロから作るDeep Learning」の72p「3.6.2 ニューラルネットワークの推論処理」では、pythonのpickleファイルを呼び出している。このpickleファイルはraw binaryなので、簡単に呼び出せない。そこで、禁断のPyCallからpickleファイルを取り込んでみる。

# 環境構築
```bash
# pycallのインストール
$ gem install pycall
# pyenvの取り込み
$ git clone https://github.com/pyenv/pyenv.git ~/.pyenv
$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
$ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(pyenv init -)"' >> ~/.bash_profile
# .bash_profileの再取り込み
$ source ~/.bash_profile
# pythonのバージョン確認
$ python3 --version
3.7.3
# pyenvの共有ライブラリインストール
$ CONFIGURE_OPTS="--enable-shared" pyenv install 3.7.3
# numpyのインストール
$ pip install numpy
```
これで準備完了

# 取り込み方

```ruby
require 'pycall/import'
include PyCall::Import

pyimport :numpy
pyimport :pickle
pkl = open("sample_weight.pkl", "rb")
network = pickle.load(pkl) 
```

# 備考：ハマったこと

普通にpycallを呼び出すだけだと怒られた。

```irb
> require 'pycall/import'
true
> include PyCall::Import
Object
> hoge = PyCall.eval('0')
Traceback (most recent call last):
        9: from /usr/local/bin/irb:23:in `<main>'
        8: from /usr/local/bin/irb:23:in `load'
        7: from /usr/local/lib/ruby/gems/2.7.0/gems/irb-1.2.1/exe/irb:11:in `<top (required)>'
        6: from (irb):3
        5: from /usr/local/bundle/gems/pycall-1.3.0/lib/pycall.rb:39:in `eval'
        4: from /usr/local/bundle/gems/pycall-1.3.0/lib/pycall.rb:62:in `import_module'
        3: from /usr/local/bundle/gems/pycall-1.3.0/lib/pycall/init.rb:16:in `const_missing'
        2: from /usr/local/bundle/gems/pycall-1.3.0/lib/pycall/init.rb:35:in `init'
        1: from /usr/local/bundle/gems/pycall-1.3.0/lib/pycall/libpython/finder.rb:95:in `find_libpython'
PyCall::PythonNotFound (PyCall::PythonNotFound)
```

以下の記事を参考にpyenvの共有ライブラリインストールで解消できた

# 参考記事

pyenv と pyenv-virtualenv をインストールする
https://qiita.com/shigechioyo/items/198211e84f8e0e9a5c18
[Ruby] 機械学習①：Ruby入門
https://qiita.com/chamao/items/cd62715c6be2fad2f8e7
別の Docker コンテナから mysqldump !! 

ローカル環境で開発中に今のデータベースの状態保存しておきたい！
ってことたまにありますよね。

そんな時、汎用的に使えるコンテナ用意してみました :sunglasses:

MySQL の Docker コンテナの中でそれやればよくね？
っていうツッコミはご勘弁ください m(_ _)m 笑

## デモ用のプロジェクト

[こちら](https://github.com/tatsuya-okayama/operate_mysql_from_external_demo)

## ディレクトリ構成

```bash
operate_mysql_from_external
 - docker-compose.yml
 - .env
 - mysqldump
    - Dockerfile
    - mysqldump.sh
    - dumpfiles
       - 
```

### docker-compose.yml

自動で .env ファイルを読み込んでくれるのは楽チンですよね。

ちなみにここで環境変数の受け渡しをしているのは、環境変数を設定せずに実行した時に下記のようなエラーを出してくれるからです。 docker-compose 最高ですね :relaxed:
`You need to set the {環境変数名} environment variable.`

```yml
version: '3'

services:
  mysqldump:
    build: mysqldump
    container_name: "demo-mysqldump"
    volumes:
      - './mysqldump/mysqldump.sh:/mysqldump.sh'
      - './mysqldump/dumpfiles:/dumpfiles'
    environment:
      MYSQL_HOST: "${MYSQL_HOST}"
      MYSQL_PORT: "${MYSQL_PORT}"
      MYSQL_USER: "${MYSQL_USER}"
      MYSQL_PASSWORD: "${MYSQL_PASSWORD}"
      MYSQLDUMP_OPTIONS: "${MYSQLDUMP_OPTIONS}"
      MYSQLDUMP_DATABASE_OPTION: "${MYSQLDUMP_DATABASE_OPTION}"
    command: sh mysqldump.sh

networks:
  dafault:
    external:
      name: "${MYSQL_NETWORK}"
```

> 参考
[ネットワークの external 設定について](http://docs.docker.jp/compose/compose-file.html#id8)
[既存のネットワークを使う](https://docs.docker.com/compose/networking/#use-a-pre-existing-network)

「MySQL Docker コンテナが使用しているネットワーク名」については

```bash
docker network ls
```

を使って確認してみてください。

特別なことをしていなければ
`{プロジェクト名}_default`
もしくは
`{プロジェクト名}_{ docker-compose.yml で指定しているネットワーク名}`
となっているはずです！

### .env

コンテナ内で使用する環境変数を記述しておきます。
以下はサンプルなので必要に応じて変更してください :robot:

```env
MYSQL_HOST=mysql
MYSQL_PORT=3306
MYSQL_USER=user
MYSQL_PASSWORD=password

# MySQL Docker コンテナが使用しているネットワーク名
MYSQL_NETWORK=demo_mysql

MYSQLDUMP_OPTIONS=--quick --single-transaction
MYSQLDUMP_DATABASE_OPTION=demo
```

### mysqldump

mysqldump する Docker コンテナ関連をまとめたディレクトリです。

#### Dockerfile

軽量の alpine に mysql-client を入れて使います。

```Dockerfile
FROM alpine:3.11

RUN apk update \
    && apk add mysql-client \
    && rm -rf /var/cache/apk/*
```

#### mysqldump.sh

mysqldump の処理を行うスクリプトです。

```sh
#!/bin/sh

# コマンドが失敗したら終了
set -e

echo "Domping for ${MYSQLDUMP_DATABASE_OPTION} from ${MYSQL_HOST}..."

readonly local OUTPUT_FILE="/dumpfiles/$(date +"%Y-%m-%dT%H%M%SZ").dump.sql"
readonly local MYSQL_HOST_OPTS="-h ${MYSQL_HOST} -P ${MYSQL_PORT} -u${MYSQL_USER} -p${MYSQL_PASSWORD}"

mysqldump ${MYSQL_HOST_OPTS} ${MYSQLDUMP_OPTIONS} ${MYSQLDUMP_DATABASE_OPTION} > "${OUTPUT_FILE}"

echo "Successfully dumped"
```

#### dumpfiles

dump したファイルたちがここに出力されます。

## 使い方

1. MySQL の Docker コンテナが起動しているか確認
2. .env に環境変数を設定する
3. プロジェクトディレクトリで下記のコマンドを実行

```bash
# --rm を付けると実行後に自動でコンテナを削除してくれるよ
docker-compose run --rm mysqldump
```

## おわりに

いかがでしょうか。
無事に mysqldump できましたか？
もし、こうした方がいいよ〜なんてことがあればコメントお待ちしています ( ^ ^ )/

## 参考

・[docker compose run について](https://docs.docker.com/compose/reference/run/)
・[mysqldump 公式リファレンス](https://dev.mysql.com/doc/refman/5.7/en/mysqldump.html)
セキュリティマネジメントの勉強-不正と攻撃のメカニズム

#不正と攻撃のメカニズム
##不正のメカニズム
不正のトライアングル理論では、人が不正行為を実行するに至るまでの3要素が提唱されている
###機会
不正行為の実行が可能、または環境
全アクセス権限を持っている、など

###動機
不正行為を行うための事情
借金があるとか、給料が不当に低いなど

###正当化
不正行為を行うための良心の呵責を乗り越える理由の事
お金を盗むのではなく借りるだけ、みたいなやつ

##状況的犯罪予防論
英国で提唱されている

* 物理的にやりにくい状況を作る
* やると見つかる状況を作る
* やっても割に合わない状況を作る
* その気にさせない状況を作る
* 言い訳を許さない状況を作る

犯罪を生じさせる日常的な状況に注目し、日常活動理論というものがある
割れた窓みたいな軽微な不正や犯罪を放置する事でより大きな問題に繋がるという割れ窓理論もある

##攻撃者の種類
###スクリプトキディ
自分には技術はないが、公開されているクラッキングツールを使うやつ

###ボットハーダー
ボットを統制してサイバー攻撃をするやつ

###内部関係者
従業員や業務委託先の社員とか

###愉快犯
意地が悪いやつ

###詐欺犯
フィッシングとか偽サイトつくって個人情報を奪う詐欺をするやつ

###故意犯
意図して犯罪するやつ。
過失犯もある。

##攻撃の動機
攻撃の動機もいろいろある

###金銭奪取
金を奪い取る。
個人情報など金銭に繋がる情報を得る事も含む

###ハクティビズム
ハッカーの思想の事らしい
政治的や社会的思想に基づきハッキングするらしい
ウィキリークスとかアノニマスとか

###サイバーテロリズム
人に危害を加えたり社会機能に打撃を与えるためにやるもの

##サイバーキルチェーン
攻撃の段階を７つに分類し、攻撃者の意図や行動を理解する

###偵察
ネットで組織や人物を調査し、情報を取得する

###武器化
エクスプロイトやマルウェアを作成

###デリバリ
なりすましメールを送ったりする

###エクスプロイト
ユーザにマルウェアを実行させる

###インストール
エクスプロイトの成功により、PCが感染する

###C&C
マルウェアとC&Cサーバを通信させて感染PCを遠隔操作する
ここで感染拡大させたり、内部情報を探索したりする

###目的の実行
見つけた内部情報を持ち出す
Pythonのbisect_leftとbisect_rightをGo言語でも使いたい

Python3には`bisect`というモジュールがあり、この中には`bisect_left`、`bisect_right`という関数が用意されています。`bisect_left`はソート済みの配列を二分探索により探索し、挿入点のうちもっとも左側のものを戻り値とします。`bisect_right`はその逆で、挿入点のうち、もっとも右側が戻り値となります。

```python
import bisect

digits = [111, 222, 333, 333, 333, 444, 555]
bisect.bisect_left(digits, 333)  #=> 2
bisect.bisect_right(digits, 333) #=> 5
```

Go言語で`bisect_left`や`bisect_right`と同じようなことをしたい場合、すなわち、__二分探索でもっとも左側の挿入点を探したい、もっとも右側の挿入点を探したい__場合、`sort`パッケージの`Search`を利用し、それぞれ次のように実装します。

```go
digits := []int{111, 222, 333, 333, 333, 444, 555}
sort.Search(len(digits), func(i int) bool { return digits[i] >= 333 }) //=> 2
sort.Search(len(digits), func(i int) bool { return digits[i] > 333 })  //=> 5
```

つまり`bisect_left`の場合は等号付き不等号で比較、`bisect_right`の場合は不等号で比較すればよいわけです。
[Android Studio] ノッチ有り無しにおけるアプリの全画面表示についてまとめてみる

# はじめに
アプリの全画面表示をしようとするとノッチの有り無しでやり方がちょっと違ったのでまとめてみます。

# 開発環境
Android Studio 3.5.3

# フルスクリーン表示の方法
これは、ノッチ有り無しに関わらず同じです
`styles.xml`にて、以下を記述します

```xml:styles.xml
<style name="AppTheme.FullScreen">
<!-- アクションバーを削除 -->
    <item name="windowActionBar">false</item>
    <item name="windowNoTitle">true</item>
<!-- フルスクリーン -->
    <item name="android:windowFullscreen">true</item>
    <item name="android:windowContentOverlay">@null</item>
</style>
```

次に`AndroidManifest.xml`でthemeを設定すればOKです

```xml:AndroidManifest.xml
<application
    android:theme="@style/AppTheme.FullScreen"> <!-- Add -->
    <activity android:name=".MainActivity">
        ...
    </activity>
</application>
```

### 結果
![Screenshot_1581255462.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278251/5bc72e67-ba82-3a0e-4c74-3a809dae4549.png)

ここまでは、他のサイトと同じです
私は以下のサイトを参考にしました
[【 Android アプリ開発 】全画面表示を行う方法 ( 通知バー非表示 )](https://qiita.com/Futo23/items/7bf65c4158bec6f30ffb#1-stylexml%E3%82%92%E4%BF%AE%E6%AD%A3)

## フルスクリーンにはなるんだが...
問題はここからです。ノッチ付きのスマホだと以下のようになります。
![IMG_3228 (3).JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278251/f877e423-e803-ad61-35bb-5d1085179630.jpeg)
（画像はHuawei P30 Liteです）

わかりづらくてすみません...。
よく見てみるとノッチの周りにViewが表示されません。
これを解決するにはもうひと手間加えます

## ノッチ付きのスマホにおける全画面表示
### `styles.xml`の変更
`styles.xml`を以下のように書き換えます。

```xml:styles.xml
<style name="AppTheme.FullScreen">
    <item name="windowActionBar">false</item>
    <item name="windowNoTitle">true</item>
    <item name="android:windowFullscreen">true</item>
    <item name="android:windowContentOverlay">@null</item>
<!-- Add -->
    <item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
</style>
```

`windowLayoutInDisplayCutoutMode`に`shortEdges`を設定します。


### Activityの変更
使用するアクティビティにて、以下のコードを追加します

```kotlin:MainAcitivity.kt
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    // Add
    window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
}

```

これでノッチ周辺にもViewが表示されます

### 結果
![IMG_3230.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278251/c67750b5-aa69-12b4-a66e-42bf58ff565b.jpeg)

# おまけ
## ステータスバーを全画面上に表示する
`styles.xml`を以下のように変更します

```xml:styles.xml
<style name="AppTheme.FullScreen">
    <item name="windowActionBar">false</item>
    <item name="windowNoTitle">true</item>
    <item name="android:windowFullscreen">false</item>  <!-- update -->
    <item name="android:windowContentOverlay">@null</item>
    <item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
    <item name="android:windowTranslucentStatus">true</item>    <!-- add -->
</style>
```

### 結果
![IMG_3231.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278251/860dc28e-930d-20d6-0902-74143c5c37bc.jpeg)


# 参考サイト
https://developer.android.com/guide/topics/display-cutout
https://stackoverflow.com/questions/29311078/android-completely-transparent-status-bar
https://qiita.com/Futo23/items/7bf65c4158bec6f30ffb#1-stylexml%E3%82%92%E4%BF%AE%E6%AD%A3
Windows10でのRailsの環境構築の時にはまった話

#はじめに
自分のパソコンを使用したRubyOnRailsのlocal内での環境構築時にいくつかはまったところがありました。再び自分と同じような苦労をさせたくない（特にWindowsの方）という思いと備忘録として自分のために残したいという理由から、この記事を書きました。自分と同じような状況に陥った人はぜひこの記事を参考にしてみてください。
＜環境＞

- Windows10 Home
- ruby 2.6.5p114 (2019-10-01 revision 67812) [x64-mingw32]
- Rails 6.0.2.1


#はまったポイント
はまったポイントが二つあったので、そのポイントごとに起こったエラーとその解決方法を紹介していきます。（実際のエラーコードを示した方がどんなエラーだったか分かりやすいのですが、エラーコードを残し忘れました。）
##コントローラの作成（rails g controller）でドはまり
**はまったときのエラー**
Railsに標準で入っている`sqlite3`で`LoadError`が起きたことでコントローラーの作成ができなかった。`sqlite3`のバージョンを1.4 ⇒ 1.3.13 ⇒ 1.3.6とバージョンを変えても解決できず。

**解決方法**
`sqlite3`⇒`mysql2`へgemを変更。この方法については以下のサイト
[Ruby on RailsでMySQLを使用する際の接続手順](https://arma-search.jp/article/ruby-mysql)


##サーバーの立ち上げ（rails server）にも少しはまる
**はまったときのエラー**
Webpackがインストールされていないことによるエラー。また、Webpackをインストールするときもyarnがインストールされていないことによりエラー。

**解決方法**
yarnをインストールしたあとWebpackをインストールすることで、サーバーの立ち上げに成功。
方法については以下のサイト
[Rails6 開発時につまづきそうな webpacker, yarn 関係のエラーと解決方法](https://qiita.com/NaokiIshimura/items/8203f74f8dfd5f6b87a0)


#終わりに
コントローラの立ち上げの際の`sqlite3`関連のエラーにとても手を焼きました。
なんども「ふざけんな」と思いましたが、無事環境構築がなんとかできて良かったです。