OmniAICreator/Qiita-1.07M huggingface dataset:
VRChatで他のプレイヤーにダメージを与える銃を作る

[前回](https://qiita.com/void_vtuber/items/4b911269e49b9c9aec61)の続きです。
前回作った銃を使って、弾を当てた別のプレイヤーに、VRC_CombatSystemのダメージを与えられるシステムを作ります。PvPです。

(※VRC SDK 2019.2.5の仕様に従っており、遠回りな方法かもしれません。またこのSDKでしか使えない方法かもしれません。)

##自身の当たり判定の作成

以下のようなHitという名前のCubeを作成します。Box ColliderはTriggerにしておきます。
分かりやすく色を付けていますが何色でもかまいません。
(VRCMirrorで見ない限り、相手からも自分からも見えないので)
![11キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398685/01e1bbde-4285-a21a-f786-29814efdb2fd.png)

次にこのCubeを選択したまま、AnimationタブからAnimatorを作成します。
(タブの右上からAdd Tabで出ます)
![12キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398685/94ab1454-cdbc-b4ad-9644-4a8e470ebeaa.png)

Add PropertyからTransform->PositionとScaleを追加して、以下のように設定します。
サンプル数1だけのアニメーションです。
![13キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398685/eae759c7-2cba-2ac6-ea0b-499b8799d489.png)

このように作成するとHitにAnimatorが追加されており、このアニメーションがずっと実行されます。

このHitはPrefabにします。

##VRC Combat Systemの設定
空のGameObjectにVRC_Combat Systemを追加します。
設定は以下の通りです。
Visual Damege Prefabという項目に先程作成したHitを設定しています。
![14キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398685/75cb9132-47c2-994d-88c5-5db2ea9bedb1.png)

本来こちらには、VRCSDKの中にあるVRC_PlayerVisualDamageのPrefabを設定します。
そうするとダメージを受けたときの張り付きエフェクトが表示されますが、今回このシステムを流用して自分に追従するオブジェクトを実現しています。

HitでAnimationを作成した理由ですが、Visual Damege Prefabに設定したものはScaleが変わってしまうので、Animationで上書きして固定しています。

ToyBoxのテクニックを参考にしました。
https://vrcworld.wiki.fc2.com/wiki/Toybox

##レイヤー設定
以前作成した銃弾のSphereのPrefabで、以下の赤丸をクリックしてAddLayerします。
![15キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398685/f260c6a2-7f72-bf0c-f762-36ccb53a6d7b.png)
 
ProjectileとHitというLayerを追加しました。
![16キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398685/09deae77-f7c6-ba9d-c0dc-d9f29e08be7f.png)

銃弾のSphereにProjectileのレイヤーを設定します。
![17キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398685/598955f2-12ad-6786-4ba2-b5dd6f71cdd1.png)

(今回Hitのレイヤーは使いませんが、ProjectileとHitだけ判定するようにした方が軽くなるはず)

#ダメージ
HitのPrefabを選択し以下のようにVRC_TriggerでAdd Damageを設定します。
Projectileのレイヤーのオブジェクトに当たったら自分がダメージを受けるようになります。
![18キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398685/9b21d83f-1fde-eeb8-70e3-1e20059e0a76.png)

Broadcast TypesをLocalに設定することで、自分にのみ影響するようにします。
(現在の仕様では、Local以外では他のプレイヤーにもダメージが入ってしまうと思われます)
Broadcast Typesについてはこちら
https://docs.vrchat.com/docs/trigger-broadcast-types

ローカルテストではうまく動作しないため、実際にPublishして確認してみてください。
私はPCとOculus Questでアカウントを2つ作って確認していました。

あとHitの方はローカルでしか作用しないため、被弾エフェクト等は銃弾の方のトリガーで出すようにした方がいいと思います。

#環境
Unity 2017 4.2.8f1
VRC SDK 2019.2.5 (31 July 2019)
androguardを使ってapkを解体する

androguardというツールを使ってapkを解体してみる。
どのへんがガードなんだ逆じゃないか、と言いたくなるのは置いておくとして。

# TL;DR

```shell
pip3 install -U androguard[magic,GUI]
androguard analyze TestActivity.apk
In [2]: dx.classes
:
In [3]: for meth in dx.classes['Ltests/androguard/TestActivity;'].get_methods():
    print("inside method {}".format(meth.name))
    for _, call, _ in meth.get_xref_to():
        print("  calling -> {} -- {}".format(call.class_name, call.name))
androguard axml TestActivity.apk
androguard arsc TestActivity.apk --list-types
androguard arsc TestActivity.apk --type string --locale ja
androguard axml TestActivity.apk -r res/layout/main.xml
```

# 環境

- MacOS Mojave 10.14.6（18G87）
- Python 3.7.4
- Androguard version 3.3.5

# `androguard` の導入

以下を実行。

```shell
pip3 install -U androguard[magic,GUI]
```

# apkの中身を見る

以下を実行。

```shell
androguard analyze TestActivity.apk
```

すると `In [1]: `のような表示が出るので、そこで `dx.classes` してみる。
するとすべてのクラスの一覧が表示される。

次に `a.get_activities()` してみる。
するとapkに含まれるすべてのアクティビティのクラスが列挙される。

その他、以下のようなコマンドが実行できる。

```
In [4]: a.get_package()
Out[4]: 'com.greenaddress.abcore'

In [5]: a.get_app_name()
Out[5]: u'ABCore'

In [6]: a.get_app_icon()
Out[6]: u'res/mipmap-xxxhdpi-v4/ic_launcher.png'

In [7]: a.get_androidversion_code()
Out[7]: '2162'

In [8]: a.get_androidversion_name()
Out[8]: '0.62'

In [9]: a.get_min_sdk_version()
Out[9]: '21'

In [10]: a.get_max_sdk_version()

In [11]: a.get_target_sdk_version()
Out[11]: '27'

In [12]: a.get_effective_target_sdk_version()
Out[12]: 27
```

コマンドラインは通常通り、 `Ctrl+D` で抜ける事ができる。

# `AndroidManifest.xml` を読む

以下コマンドを実行するだけ。

```shell
androguard axml TestActivity.apk
```

# res(リソース)を一覧する

```shell
# 種類を一覧する
androguard arsc TestActivity.apk --list-types

# 色を一覧する
androguard arsc TestActivity.apk --type color

# 日本語リソースの文字列を一覧する
androguard arsc TestActivity.apk --type string --locale ja
```

# layoutを読む

下記のようなコマンドで解体できる。

```shell
androguard axml TestActivity.apk -r res/layout/main.xml
```

リソースは探すのが手間なので、拡張子を `apk`　から `zip` に変更して解凍し、バイナリXMLにしてからandroguardしたほうが楽。

ただし、これで出てくるのはリソースのIDの状態なので、例えば `android:id="@7F0802F9"` という値があるとして、 `R.java` から `0x7f0802f9` になっている値を探して、それが `hoge_id` だと判明する。色や文字列の場合は、そこから更に `--type color` などで追いかける必要があって結構難儀。

# 備考

`androlyze.py` はどうやら動かない。
プログラムを解体したいだけなら、 [jad](https://varaneckas.com/jad/) や [dex2jar](https://github.com/pxb1988/dex2jar) を組み合わせたほうが楽。

# 参考

- [Installation — Androguard 3.4.0 documentation](https://androguard.readthedocs.io/en/latest/intro/installation.html)
Web技術についての備忘録3

# Webサイトが表示される仕組み

1. Webブラウザで目的のドメインかURLを打ち込む

2. WebブラウザがDNSサーバーへIPアドレス(Web上での住所)を問い合わせる

3. DNSサーバーからドメインに紐づくIPアドレスが返ってくる

4. 取得したIPアドレスをWebサーバーへ問い合わせし、目的のURLのファイルをWebサーバーから取得

5. Webブラウザがファイルを人間が読めるように変換する
→ Webサーバーから取得するファイルはコンピュータが読める言語(HTMLやCSSなど)なので、コンピュータは人が読めるよう解読してくれる

# 参考
[【基本のき】ホームページの仕組みをイラスト付きでまるっと解説！
](https://webliker.info/65123-2/)
【php】メールフォーム

##html フォームパーツ

```
<form action="sent.php" method="post">

  Emailを入力
  <input type="text" name="email">

  内容
  <textarea name="content"></textarea>

  <select name="fruit">
    <option value="apple">りんご</option>
    <option value="banana">ばなな</option>
    <option value="orange">みかん</option>
  </select>

  <input type="submit" value="送信">

</fomr>
```

##$_POST
フォームで送信した値を受け取るには、「＄_POST」を使う。
「＄_POST」は連想配列になっている。[ ]の中に、＜input＞と＜textare＞のname属性に指定した値を入れることで、それぞれの送信した値を受け取る事ができる。

```
echo $_POST['name'];
echo $_POST['email'];
echo $_POST['fruit']; //選択されたvalueが入る

//$_POSTの中身は連想配列になっている
array(
  'name' => 'formで入力した値',
  'email' => 'formで入力した値';
)

//option
for($i = 1; $1 < 4; $i++){
  echo "<option value='{$i}'>{$i}</option>";
}

//上記のfor文は下記と同じ意味
echo "<option value='1'>1</option>"
echo "<option value='2'>2</option>"
echo "<option value='3'>3</option>"
```
Railsチュートリアル（第9章）

# はじめに
Railsチュートリアルの第9章が終わりました。
ポイントだけメモしておきます。

# トークンの考え方
永続的なログインを実装するために、cookieというものに値を保持します。
しかし、そのままログイン情報を保持してしまうと、情報を盗み見られたりするとサイバー攻撃に繋がってしまうため、複雑にして保持する必要があります。
流れを簡単にまとめると以下のようなイメージです。

・ログイン時、ユーザーIDを暗号化したものと、ランダムな文字列トークンをcookieに保持
・ランダムな文字列トークンをハッシュ化して、ユーザーテーブルに保持
・ログインチェック時、cookieからユーザーIDを取り出してテーブル検索
・取得したデータのトークンとcookieのトークンのハッシュ値を比較

# トークンの生成
以下の記述で、64種類の文字（A–Z、a–z、0–9、"-"、"_"）からランダムに22文字生成してくれます。

```rb
SecureRandom.urlsafe_base64
```

# モデルの仮想の属性
モデルにトークンを保持する際、データベースに保存せずに値を取得したいです。
その際に、以下のように`attr_accessor`でゲッターとセッターを定義して仮想の属性を定義できます。
rememberメソッドの2行目は、トークンをハッシュ化してデータベースに保存しています。

```rb
class User < ApplicationRecord
  attr_accessor :remember_token

 # ランダムなトークンを返す
  def User.new_token
    SecureRandom.urlsafe_base64
  end

  # 永続セッションのためにユーザーをデータベースに記憶する
  def remember
    self.remember_token = User.new_token
    update_attribute(:remember_digest, User.digest(remember_token))
  end
end
```

# cookieの保持
実際にcookieに値を保持する際は、sessionと同じようにハッシュの形式で値を設定します。
以下のように、`expires`によって有効期限を設定できます。

```rb
cookies[:remember_token] = { value:   remember_token,
                             expires: 20.years.from_now.utc }
```
また、以下のように`permanent`メソッドを使用することで、自動的に20年を設定してくれます。

```rb
cookies.permanent[:remember_token] = remember_token
```
ユーザーIDを保持する際など、暗号化して格納する場合は、`signed`メソッドを使用します。

```rb
cookies.signed[:user_id] = user.id
```
2つを合わせて記述すると以下のようになります。

```rb
cookies.permanent.signed[:user_id] = user.id
```
取り出す際は同じように`cookies.signed[:user_id]`で複合化して取得できます。

# cookieの削除
cookieを削除する際は、`delete`を使用します。

```rb
cookies.delete(:user_id)
cookies.delete(:remember_token)
```

# チェックボックス
`form_for`の中にチェックボックスを記述する際は、`f.check_box`で記述します。
以下のように、ラベルの内側に書くことで、チェックボックスと文字列をひとまとまりにしています。

```erb
    <%= form_for(:session, url: login_path) do |f| %>
      ...
     <%= f.label :remember_me, class: "checkbox inline" do %>
        <%= f.check_box :remember_me %>
        <span>Remember me on this computer</span>
      <% end %>
      ...
    <% end %>
```
値を取得する際は、チェックボックスがオンの時`1`、オフの時`0`になります。
宝くじの当たる確率の話

# n分の1の確率で当たる宝くじ

確率$\frac{1}{n}$で当選する宝くじを$n$個購入することを考えます。
$n$個のうちひとつでも当選すればよいので、当選する確率$P_n$は$1$からひとつも当選しない確率を引いた値で表すことができます。

$$ P_n = 1 - \left( 1 - \frac{1}{n} \right)^n $$

たとえば$n = 10$のとき、1つの宝くじが外れる確率は$1 - \frac{1}{10} = \frac{9}{10}$なので、$10$個引いたときの当選確率$P_{10}$は

$$ P_{10} = 1 - \left(\frac{9}{10}\right)^{10} = 0.65132\dots $$

となります。

ここで$n$を非常に大きくとった場合、確率$P_n$はどんな値に収束するかを考えます。

$$ \lim_{n \to \infty} P_n = 1 - \lim_{n \to \infty}\left( 1 - \frac{1}{n} \right)^n $$

定数$e$を下記の通り定義します。(自然対数の底、またはネイピア数)
$$ e = \lim_{h \to \infty} \left( 1 + \frac{1}{h} \right)^h $$

$e$をこのように定義すると、下記のような関係を導くことができます。

```math
\begin{align}
\lim_{n \to \infty} \left( 1 - \frac{1}{n} \right)^n
&=
\lim_{n \to \infty} \left(\frac{n - 1}{n} \right)^n \\
&= 
\frac{1}{\lim_{n \to \infty} \left(\frac{n}{n - 1} \right)^n} \\
&=
\frac{1}{\lim_{n \to \infty} \left(1 + \frac{1}{n - 1} \right)^{n-1}  \left(1 + \frac{1}{n - 1} \right) }
 =
\frac{1}{e}
\end{align}
```

この関係式を上の式に代入すると

$$ \lim_{n \to \infty} P_n = 1 - \frac{1}{e} $$

$e \fallingdotseq 2.71828$であることが知られているので、$P_n$の収束先は

$$ \lim_{n \to \infty} P_n \fallingdotseq 1 - \frac{1}{2.71828} = 0.63212 \dots $$

であることがわかります。



### 感覚と一致してるか

ソシャゲなどで最高レアカード排出率0.1%だから1000回引けば...などと冗談っぽく言うこともあると思います。が1000回引いても63%程度の確率でしか求めるものは得られないんですね。

### 解決策

当たるまでくじを引けばいい。
ビジュアルデザインとアクセシビリティ

この記事はWWDC19の[Visual Design and Accessibility](https://developer.apple.com/videos/play/wwdc2019/244/)のセッション動画をまとめたものです。

※ここに貼っている画像は、上記動画をスクショしたものです。

# 概要

アクセシビリティを視覚的に向上させる3つの方法について

# Dynamic Type

Dynamic Type はユーザがフォントサイズをカスタマイズできる機能。Dynamic Type を実装するときは、次の4点に気をつける必要がある。

* 拡張性を持たせ、テキストはできるだけ動的に
* 画面の幅を最大限に利用する
* テキストを切り捨てず、デフォルトと同じだけの量を表示する
* テキストだけでなくグリフのサイズも調整して、UI のバランスを取る　　　　　　　　　

iOS では11種類のテキストスタイルで Dynamic Type を使うことができる。Dynamic Type を使う場合は次のように書く。

```swift
label.font = UIFont.preferredFont(forTextStyle: .body)
label.adjustsFontForContentSizeCategory = true
```

iOS 11 ではカスタムフォントでも利用しやすくなった。

```swift
var fontDict: [UIFont.TextStyle : UIFont] = myCustomFontDict()
if let font = fontDict[style] {
  label.font = UIFontMetrics(forTextStyle: style).scaledFont(for: font)
} else {
  label.font = UIFont.preferredFont(forTextStyle: style)
}
```

さらに Xcode 11 では Dynamic Type のプレビューが簡単に見られるようになった。Environment Overrides ボタンをクリックするとこのポップアップが出てきて、スライダーでリアルタイムに文字の大きさを変えることができる。
<img width="300" alt="スクリーンショット 2019-08-17 22.36.19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100736/510ccd3a-aa88-9af3-f07f-7f7afb12165b.png">

# 視覚効果を減らす

没入感を出すために視覚効果が使われることはあるが、これを望まないユーザもいる。3人に1人が動きに敏感で、車内で読書するのが苦手だったり、動きのある画面を見るのが苦手だったりする。iOSには動きを減らす設定がある。提供されているAPIは次の通り。

```swift
static var UIAccessibility.isReduceMotionEnabled: Bool { get }
static let UIAccessibility.reduceMotionStatusDidChangeNotification: NSNotification.Name
```

ビデオの自動再生の設定が iOS 13 から新しく追加されている。Auto-Play Video Previews の設定をオフにすれば動画が自動再生されなくなる。

<img width="360" alt="スクリーンショット 2019-08-17 22.56.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100736/9dfb8acb-7cb0-5bfc-3cb0-8e4ad34df1bb.png">

この新しいAPIはパブリックで提供されている。アプリ内で設定を設けている場合は、グローバル設定とミラーリングするようにすればよい。

```swift
static var UIAccessibility.isVideoAutoplayEnabled: Bool { get }
static let UIAccessibility.videoAutoplayStatusDidChangeNotification: NSNotification.Name
```

画面切り替え時の視覚効果の設定もある。「クロスフェードトランジションを優先」という設定が新しくできており、この設定をオンにすると画面遷移アニメーションがディゾルブに変わる。

# カラー以外で区別

2型2色覚の人には赤、緑、黄色が同じ色に見える。iOS 13 では設定のアクセシビリティの「画面表示とテキストサイズ」から「カラー以外で区別」という項目が使える。

<img width="360" alt="スクリーンショット 2019-08-17 23.17.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100736/68057e4a-b832-6612-3667-4de7c0ac977e.png">

開発者はこの新しいAPIを使って設定の監視と変更を行う。shouldDifferentiateWithoutColorがtrueなら色だけで情報を伝えているところには形や他のインジケータを追加するようにする。

```swift

public func UIAccessibility.shouldDifferentiateWithoutColor() -> Bool
public static let UIAccessibility.differentiateWithoutColorDidChangeNotification: NSNotification.Name
```

このようなAPIはあるとはいえ、色だけで意味づけを行うのはできるだけやめた方が良い。
【HTMLのみ】ボタンクリックでボタン下部の表示・非表示を切り替える

# detailsタグとsummaryタグ

こちらがとても便利だと思ったため、投稿します。

※現在、IEとEdgeは未対応となっております。
※HTMLの対応バージョンや使用方法の詳細については参考URLを参考にしてください。

### 具体的な使用例

```html:index.html
 <details>
   <summary>ボタンとして表示したい文字列</summary>
   クリック時に表示したい文字列
 </details>
```

### 動作確認

 <details>
   <summary>ボタンとして表示したい文字列</summary>
   クリック時に表示したい文字列
 </details>

### 備考

cssと組み合わせてレイアウトの修正も可能です。

### 参考URL

・[MDN web docs | details 詳細折りたたみ要素](https://developer.mozilla.org/ja/docs/Web/HTML/Element/details)

・[MDN web docs | summary 概要明示要素](https://developer.mozilla.org/ja/docs/Web/HTML/Element/summary)
MNCTF2017 不審起動☆★★

#問題

http://mnctf.info/mnctf2017/top.php

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/a3e554f7-455f-9524-1641-7dbf9bfbd425.png)

#解いてみた

問題文に書いてあるものそのまま？

と思ったら「pastebin.com」は不正解。

コマンドの内容を確認する必要があるみたいです。
トレンドマイクロのブログにほぼ同じコマンドの説明がありました。
[より高度な「ファイルレス活動」を実現した一連のマルウェアを確認 ...](https://blog.trendmicro.co.jp/archives/15653)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/df818148-c02f-325e-38d9-fd586299c6bf.png)

これは早い話、ここにアクセスしてダウンロードされるファイルの通信先を答える問題ということだったのか？
アクセスしてみると

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/970a33a5-17b5-d845-4887-44cf12486336.png)

いかにもなソースが出てきました。
とりあえずjsの部分が一行に書かれているので整形します。
今回は以下を使用しました。
[JavaScriptのコード整形ツール - SYNCER](https://lab.syncer.jp/Tool/JavaScript-PrettyPrint/)

そうすると最後のところに普通にURLが書かれていました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/23983787-da88-0f39-6a3d-446d01ee25eb.png)

これが答えです。
Pythonのクラスやインスタンスをおさらいしよう

##はじめに


未来電子テクノロジーでインターンをしている宮﨑です。
Pythonの基礎であるクラスとメソッドを再確認するためにまとめたいと思います。
もし誤りがあれば修正するのでどんどん指摘してください。



##語句説明

**クラス**・・・設計図や型のようなもの。カテゴリー（動物、フルーツなど）のようなもの。
**インスタンス**・・・クラスをもとに作られる「もの」。一つのクラスから複数のインスタンスを作れる。
**メソッド**・・・クラスの中で定義した関数（処理のまとまり）のこと。


##書き方の流れ


####クラスを用意する
クラス名を`class`の後に書く。

```
class クラス名:
```

####クラスにメソッドを定義する

メソッド名を`def`の後に書く。
メソッドは、それぞれのインスタンス自身を示す`self`を第一引数にする。


```py:例
def info(self):
    print(self.name)
```

####(補足)コンストラクタ
インスタンスを生成した時に、自動的に呼び出すメソッドのことをコンストラクタといい、そのうちインスタンスを初期化するメソッドとして`__init__`を定義できる。
`__init__`の他には、インスタンスを作るときに呼ばれる`__new__`メソッドもある。



####クラスからインスタンスを生成
`クラス名()`でインスタンスを生成でき、インスタンスを変数に代入する。

```
変数名 = クラス名()
```

####メソッドを呼び出す
どのインスタンスに対してメソッドを呼び出すのかを明らかにするために、メソッド名の前にインスタンス名をつける。

```
インタンス名.メソッド名()
```




##具体例

```py
# クラス定義
class Fruit:
    # 初期化メソッド定義
    def __init__(self, name):
        self.name = name
    # 一般メソッドの定義
    def info(self):
        print(self.name + "です。")

# インスタンスの生成
apple = Fruit("リンゴ")
# メソッドの呼び出し
apple.info()
# 「リンゴです」と出力される
```

##まとめ

今回は、Pythonのクラスやインスタンスについてまとめました。
何気なく使っているものも、再確認してみるとより使いやすくなるのではないでしょうか。
【php】戻り値【return】

##return
関数は値を返すことが可能。その値を戻り値と呼ぶ。
関数を実行した結果、その関数実行部分が戻り値に置き換わるイメージ。
「return」で指定する。

```
//関数の定義
function getSum($num1,$num2){
  return $num1 + $num2;
}

//関数の呼び出し
$num = getSum(2,3);
echo $num; //結果: 5

//実行されると、値が戻り値(2+3)に置き換わる
```
MNCTF2017 通信記録☆☆★

#問題

http://mnctf.info/mnctf2017/top.php

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/66508f41-bdb8-0090-8b2b-9b694c55c6d7.png)

#解いてみた

pcapファイルをダウンロードしてwiresharkで見てみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/8e17c79c-ec84-3939-4afa-97c7e9ae3bab.png)

4万件もあるので順番に見ていくことは不可能です。

プロトコルの統計を見てみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/d818b86a-38c0-d3a1-701a-641b2aff26fc.png)

TLSとSMBがかなり多い。
ということで「TLS SMB 脆弱性」で検索してみるも答えにたどり着けず。
が、「SSLに脆弱性」みたいな記事が何個か出てきたので「SSL SMB 脆弱性」で検索してみる。
「smb 脆弱性 wannacry」というキーワードが出てくる。検索してみる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/037afc8c-6703-b1c2-9170-fafeadf08b85.png)

これが正解ですが、ほぼ運。。。
アーキテクチャパターンとは何か

# 概要
ソフトウェアのアーキテクチャの種類について調べようとすると、アーキテクチャパターンという用語に遭遇する。似た表現としてデザインパターン、アーキテクチャスタイルなどがあるため、混乱してしまう人もいるだろう。本記事ではソフトウェアにおけるアーキテクチャパターンという言葉の定義を検証してみる。
なお、アーキテクチャスタイルについては<a href="https://qiita.com/cocoa-maemae/items/69fe13def286c7e37d5d">アーキテクチャスタイルとは何か</a>で検証している。

# パターン(pattern)とは
語源はラテン語のpatronus。中世ラテン語では模倣すべき見本という意味であり、中世の英語ではpatron(=父)という語形になった。patronの綴りがpatarne,patternなどと変わっていき、最終的にpatronとpatternが独立した２語になった。

# ソフトウェアのアーキテクチャパターンとは
<a href="https://en.wikipedia.org/wiki/Software_architecture#Architectural_styles_and_patterns">wikipedia</a>によると、アーキテクチャパターンとは「ソフトウェアアーキテクチャで発生する問題の解決策」と説明されている。


## ソフトウェアのアーキテクチャパターンの例
<a href="https://www.amazon.co.jp/%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3%E2%80%95%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E9%96%8B%E7%99%BA%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3%E4%BD%93%E7%B3%BB-F-%E3%83%96%E3%83%83%E3%82%B7%E3%83%A5%E3%83%9E%E3%83%B3/dp/4764902834">POSA本</a>や<a href="https://www.amazon.co.jp/dp/B01B5MX2O2/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1">エンタープライズアプリケーションアーキテクチャパターン</a>には下記が挙げられている。
- 階層化
- パイプアンドフィルター
- ブラックボード
- キャッシュサーバー
- MVC(Model-View-Controller)
- PAC(person-abstract-controll)
- マイクロカーネル
- リフレクション
- webプレゼンテーション
- ドメインロジック

# デザインパターンとの違い
ソフトウェアの世界ではアーキテクチャパターンと似たデザインパターンという用語もよく利用される。<a href="https://www.amazon.co.jp/Clean-Architecture-達人に学ぶソフトウェアの構造と設計-Robert-C-Martin/dp/4048930656">クリーンアーキテクチャ</a>によると「デザイン(=設計)とアーキテクチャには違いがない」と説明されている。もちろん本来的な意味において、アーキテクチャ(=建築)とデザイン(=設計)は異なる意味を持っている。あくまでソフトウェアの開発現場において、アーキテクチャとデザイン(=設計)とという用語が区別されることなく利用されると捉えていいだろう。よってソフトウェア開発においては、デザインパターンもアーキテクチャパターンも同じ意味を表す用語として捉えて良いと思われる。


# 建築のアーキテクチャパターンとの比較
建築ではアーキテクチャパターン、もしくはArchitectural Patternではなく、<a href="https://en.wikipedia.org/wiki/Pattern_(architecture)">Pattern (architecture)</a>という言葉で定義されている。wikipediaによると、建築におけるPatternとは「建築設計のアイデアを典型的かつ再利用可能な記述として取り込む考え方である。」と説明されている。


# 結論
アーキテクチャパターンと似た表現であるアーキテクチャスタイルという言葉の定義については<a href="https://qiita.com/cocoa-maemae/items/69fe13def286c7e37d5d">アーキテクチャスタイルとは何か</a>で検証している。結論としては、アーキテクチャパターンもアーキテクチャスタイルも言葉の意味するものはほとんど変わらないと思われる。語源を辿ってみても、スタイル(=型)、パターン(=見本)なのでどちらも意味としては通る。
ただし、インターネット検索や出版されている書籍を調べると、アーキテクチャスタイルよりもアーキテクチャパターンという表現の方が多く利用されている印象がある。これを考慮すれば、アーキテクチャスタイルもパターンも一纏めにしてアーキテクチャパターンで表現しても問題ないように思われる。

# 参考
- https://blogs.yahoo.co.jp/eigo_etymology/14939395.html
- https://en.wikipedia.org/wiki/Architectural_pattern
- https://en.wikipedia.org/wiki/Software_architecture
- https://www.amazon.co.jp/Clean-Architecture-達人に学ぶソフトウェアの構造と設計-Robert-C-Martin/dp/4048930656
Goの実行ファイルがどの OS/アーキテクチャ 向けにビルドされたか判別する

ちゃんとテストしてませんが、だいたいこれで行けると思います。

```sh
strings $(BIN_FILE_PATH) | grep -oP '(?<=rt0_).+(?=\.s)'
```

## 解説
Goの実行ファイルにはビルド時に使用したソースファイルへのパスが含まれており、さらに Go をビルドする際には必ず `GOOS` と `GOARCH` に対応した `runtime/rt0_XXX.s` が使用されるため、この方法が使えます。

## 補足
Windows 環境には `strings` も `grep` もデフォルトでは入っていないので、[busybox](https://frippery.org/busybox/) を使いましょう。
【環境構築】サクラエディタの設定メモ

サクラエディタを再インストールしなければならないことが、一生のうちに何度かあると思う。そんな時のための備忘録。
----------
■設定＞共通設定＞
Alt→O→C


ウィンドウ＞
基本設定＞ファンクションキー表示：ON

タブバー＞
タブバーを表示する：ON

編集＞
ファイルダイアログの初期位置：マイドキュメント

マクロ＞
よく使うマクロを読み込んで設定

キー割り当て＞
外部マクロをF1、Shift＋F1に割付

バックアップ＞
保存時にバックアップを作成する：ON
指定フォルダに作成する：ON。マイドキュメントのsakura_bckフォルダを指定
作成前に確認する：OFF

書式＞
日付書式：カスタム。yyyy'/'MM'/'dd


■設定＞タイプ別設定＞

スクリーン＞レイアウト＞折り返し方法：右端で折り返す

カラー＞色指定＞
行番号(変更行)：文字色赤
カーソル行の背景色：ON
カーソル位置縦線：ON
対括弧の強調表示：背景色ピンク
【php】関数の作成【function】

##関数の作成
重複する処理を一箇所にまとめることで、コードに変更があった時に関数の中身を変更するだけ良くなる為便利。
###円の面積を求める

```
$radius1 = 3;
echo $radius1 * $radius1 * 3;

$radius2 = 5;
echo $radius2 * $radius2 * 3;

//上記は同じ処理を実行している。

//関数の定義
function printCircleArea($radius){
  echo $radius * $radius * 3;
}
//関数の呼び出し
printCircleArea(3); //結果: 27
printCircleArea(5); //結果: 75
```

##関数の記述方法
関数を作るには「function 関数名(){処理}」の形式で記述する。関数名は自由。呼び出しは「関数名()」。

```
//関数の定義
function hello(){
 echo 'Hello, world!';
}

//関数の呼び出し
hello();
//結果: Hello, world!
```

###引数有り
```
//関数の定義
function printSum($num1,$num2){
  echo $num1 + $num2;
}

//関数の呼び出し
printSum(8,14);
//結果: 22;
```
【SVG・CSS・Vue.js】SVGが画面サイズの変化時にちらつく場合の対処

# width・heightの設定を確認

svgのある画面でVue.jsにてv-bindで要素の表示・非表示を切り替えていたところ、
svgの中身がピクピクと小さくなったり大きくなったりする（ちらつく）場面に遭遇。
height・widthの片方を指定するとサイズが定まらず事象が起こる模様。

簡単な対処法にも関わらず手間取ったためメモします。

```
  // svgをwrapした要素
  #svg_img {
    width: 100px;
    height: 20px; // heightの指定が抜けていた
  }
```
パケットフィルタを使用してパケットドロップを発生させる

# 目次

* [はじめに](#はじめに)
* [フィルタ作成と削除](#フィルタ作成と削除)
* [パラメータ毎のまとめ](#パラメータ毎のまとめ)

# はじめに

クラスタを分断してスプリットブレインを発生させたい！(サーバ間のハートビートが出来ないようにしたい！)
...ということでパケットドロップが起きるようにiptablesによるフィルタを実施しました。
※その時のメモです。

# フィルタ作成と削除

## フィルタ作成

```bash
$ iptables -A INPUT -t filter -p tcp --dport 50000 -j DROP
```

<パラメータ説明>

|パラメータ|意味|
|:--|:--|
|-A|ルールの追加|
|INPUT|入力(受信)パケット|
|-t filter|対象テーブル＝filter(パケットフィルタリングを参照するテーブル)|
|-p tcp|プロトコル＝tcp|
|--dport 50000|送信先ポート番号＝50000|
|-j DROP|ターゲット＝パケット破棄|

## フィルタ確認

```bash
$ iptables --list
```

<パラメータ説明>

|パラメータ|意味|
|:--|:--|
|--list|ルール一覧表示|

こんな感じで表示されたらちゃんと設定されています！

```bash
[root@host ~]# iptables --list
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
DROP       tcp  --  anywhere             anywhere            tcp dpt:50000
```

## フィルタ削除

```bash
$ iptables -D INPUT -t filter -p tcp --dport 50000 -j DROP
```

※フィルタ追加で使用するパラメータ`-A`を`-D`にすればOK

<パラメータ説明>

|パラメータ|意味|
|:--|:--|
|-D|ルールの削除|
|INPUT|入力(受信)パケット|
|-t filter|対象テーブル＝filter(パケットフィルタリングを参照するテーブル)|
|-p tcp|プロトコル＝tcp|
|--dport 50000|送信先ポート番号＝50000|
|-j DROP|ターゲット＝パケット破棄|
  
# パラメータ毎のまとめ

フィルタ作成、フィルタ削除で使用した下記コマンドで設定したパラメータについて
まとめて記載します。

`iptables コマンド チェイン -t テーブル -p プロトコル 照合オプション -j ターゲット`

1. コマンド

    |オプション|意味|
    |:--|:--|
    |-A|指定したチェインにルールを**追加**|
    |-D|指定したチェインからルールを**削除**|

1. チェイン

    |オプション|意味|
    |:--|:--|
    |INPUT|入力(受信)|
    |OUTPUT|出力(送信)|
    |FORWARD|転送|

1. テーブル

    |オプション|意味|
    |:--|:--|
    |filter|パケットフィルタリングを参照するテーブル|

1. プロトコル

    |オプション|意味|
    |:--|:--|
    |tcp|TCPプロトコル|
    |udp|UDPプロトコル|
    |icmp|ICMPプロトコル|

1. 照合オプション

    |オプション|意味|
    |:--|:--|
    |--sport port|portに**送信元**ポート番号/ポート範囲を指定|
    |--dport port|portに**送信先**ポート番号/ポート範囲を指定|

1. ターゲット

    |オプション|意味|
    |:--|:--|
    |ACCEPT|パケット**許可**|
    |DROP|パケット**破棄**|
AWS DynamoDBとDynamoの違いを調べてみた

実はDynamo論文[^1] の実装に一番近いAWSサービスはS3らしい [^2] です。DynamoとDynamoDBはアーキテクチャ/実装が違っていて[^9] [^7]下記のような違いがあるようです。

| | 可用性 | アプリからの使いやすさ |
|---|---|---|
| Dynamo | ◎ | △？ |
| DynamoDB | ○ | ◎ |

## 構成の違い

### Dynamo

- リーダーレス
- クライアントが更新データを複数ノードに書き込む（クライアントサイドでレプリ）

### DynamoDB

- シングルリーダー（パーティションキーごとの）
    - Paxosでリーダー選出 / 1.5秒ごとのハートビート [^3]
- イメージ的にはマスタースレーブ形式の同期レプリみたいな
    - クライアントはリーダー経由で書き込みをリクエスト

## 書き込みの衝突の有無

### Dynamo 

- 複数クライアントからの書き込みが衝突するケースがある
    - → 書き込みが衝突したら、アプリ側で読み込み時に解決する必要がある（後述の補足参照）
    - （調整してくれるリーダーはいない...）
    - （常にスプリットブレインし続けているのをアプリがなんとかし続けるイメージ...）
 
### DynamoDB

- 書き込みが衝突しない（リーダーが調整）
    - → アプリで特に何か注意する必要はない

## 重要視しているもの / 犠牲にしているもの

### Dynamo

- 可用性を重視
    - 単一障害点（リーダーノード）がなく、対象ノードのいくつかにアクセスできれば読み書きできる。
    - Dynamoの論文では可用性をめっちゃアピールしている
        - `always-on`, `always writable`
        - `writes are never rejected`
        - `high availability where updates are not rejected even in the wake of network partitions or server failures`
        - `no updates are rejected due to failures or concurrent writes`
-  逆にデータの一貫性（アプリからの使いやすさ）は犠牲にしている。

### DynamoDB

- データの一貫性（アプリからの使いやすさ）を重視
    - アプリが書き込みの衝突を解決しないでいい
- 逆に多少の可用性は犠牲にしている
    - フェイルオーバーの時間分（リーダーが落ちて最大1.5秒＋Paxosのリーダー選出の時間）は書き込みできない（と思う）。

## 補足： アプリが読み込み時に書き込みの衝突を解決する とは？
Dynamoなどでは例えば下記のように書き込みが衝突します 。[^4] [^1]

```
1. クライアントAが次のような更新をします：

  { key = user_id:1234, value = name:Alice }

2. 同時にクライアントBが次のような更新をします：

  { key = user_id:1234, value = name:Bob }

3. このとき、書き込みが衝突して次のようになります：

  { key = user_id:1234, value = name:Bob and/or value = name:Alice }
```

このときアプリがデータを読んだとき、いったいAliceとBobのどちらが正しいのでしょうか？

「アプリによる書き込みの衝突の解決」とは、このどちらが正しいか（or どちらも正しい）をアプリで判断しなければならないということです。これは大変だと思います（そのためかDynamoは `adoption lagged` らしいです [^7]）。

Last Write WinsであるCassandraなどはアプリで書き込みの衝突を解決しなくても済むようになっています。ただそれが好ましい衝突の解決方法なのかは別かもしれません(Facebookが自身で作ったCassandraではなくデータの一貫性がわかりやすいHBaseを採用した例[^8] など)


[^1]: [Amazon's Dynamo - All Things Distributed](https://www.allthingsdistributed.com/2007/10/amazons_dynamo.html) [Dynamo: Amazon’s Highly Available Key-value Store](https://docs.riak.com/riak/kv/2.2.3/learn/dynamo/) 
[^2]: https://en.wikipedia.org/wiki/Dynamo_(storage_system)
[^3]: [AWS re:Invent 2018: Amazon DynamoDB Under the Hood: How We Built a Hyper-Scale Database (DAT321) - YouTube](https://www.youtube.com/watch?v=yvBR71D0nAQ)
[^4]: [Vector Clocks Revisited – Riak](https://riak.com/posts/technical/vector-clocks-revisited/index.html)
[^5]: [Conflict Resolution](https://docs.riak.com/riak/kv/latest/developing/usage/conflict-resolution/index.html)
[^6]: [Causal Context](https://docs.riak.com/riak/kv/2.2.3/learn/concepts/causal-context/index.html)
[^7]: [Amazon DynamoDB - Wikipedia](https://en.wikipedia.org/wiki/Amazon_DynamoDB)
[^Impl]: [`derives its name from Dynamo, but has a different underlying implementation` --  Amazon DynamoDB - Wikipedia](https://en.wikipedia.org/wiki/Amazon_DynamoDB)
[^8]: [Facebookが新サービスの基盤にしたのは、MySQLでもCassandraでもなく、HBaseだった － Publickey](https://www.publickey1.jp/blog/10/facebookmysqlcassandrahbase.html)
[^9]: [O'Reilly Japan - データ指向アプリケーションデザイン](https://www.oreilly.co.jp/books/9784873118703/)
MNCTF2017 昇進試験☆☆★

#問題

http://mnctf.info/mnctf2017/top.php

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/55193613-4044-6b82-d7ad-ddf1aa5464ab.png)

#解いてみた

クロスワードを解く問題のようです。
リンクをクリックしてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/aeaf674f-3510-d408-4ad9-b584ccc535c4.png)

こんな感じで空欄を埋めると答えが出てくるようです。
全部プログラム関連の問題のようなので上から順に解いていきます。
ほとんどわからなかったので検索しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/0377b10b-9221-dd63-9f78-11730380a8f2.png)

権限の変更。chmod。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/56a75c49-31e6-5e62-22d1-9d0efd353682.png)

素因数分解するコマンド。factor。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/f4ecc508-db5f-5b8f-4f46-4b7e854f0aca.png)

システムの負荷を確認するコマンド。uptime。

ここから縦。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/0dc84df3-bb13-92dd-dd44-6009128368cf.png)

プロセスの親子関係を表示するコマンド。pstree。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/4fd5e098-9283-99ce-5360-0b9eca000b9c.png)

カレンダーを表示するコマンドなのでcal。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/5418ec03-a04e-405c-5a8a-7db1d3158406.png)

ファイルを比較するコマンド。diff。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/82d0e510-00bd-4d96-0b52-dd2997b4beb5.png)

区切り文字の変更。column。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/371b8f3d-2a2c-eca0-7d9a-35ed3146a1d9.png)

実行中のプロセスを見るコマンド。top。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/04306bbd-56fe-cfd2-605f-768b7cc90138.png)

全部入力すると答えが出てきます。
Redisの使用整理

# Redisが？役目

Redisの名前は誰でも聞いたことがある。

１、キャッシュサーバーとして、`Memcache`もよく使うだろうが、NoSQL型としてのRedisは開発や運営に便利ではないかと思います。

２、DBとして使えるだろうが、複雑なデータ構造の場合、MySqlかと思いますが、簡単なデータ構造だと、例えば、TODOリストとか、Redisはすごく早く使えるDBサーバーになれる。


## 適用の場面

今のビジネス開発では、RedisをDBサーバーとして使わないだろう。

キャッシュサーバーとして、サーバーの性能を十分に発揮するのが主流になっています。

* `ランキング`：
  RedisのSortSetで簡単にしかも高速にランキングできました。
* `カウンター`：
  Redisのカウンター性能を使って、色々統計したり、制限することができます。
* `データ集合体`：
  Redisは豊富な集合体コマンドあります。
* `通知`：
  Redisのpub/subで簡単に使える。
* `Session/Token`：
  Redisは保存すると、SessionかTokenなど一時的なものは全部シェアできます。
  そして、時間制。


## 災厄の場面

さて、何か災厄でしょうと一旦イメージしました。

* ビッグデータのDBとして扱う場合。
* 頻繁にアクセスしないもの、リソースの濫用になるですね。
* 複雑な通知をしようとしている場合。

# 結論

Redisはキャッシュサーバーとして役目一番果たしていて、`C言語`で書いているので、速度も早い。

サポートしているデータ型が多い。

```
１、String
２、Hash
３、List
４、Set
５、ZSet（順番あるSet）
６、Bitmaps
７、HyperLogLog（？使ったことないが、Logかなぁ）
８、GEO（GPSで使う）
```

具体的に使うときが、Redisはキャッシュサーバーとしての性能を発揮するため、Redisの特性を見て判断しましょう。

* 同じものは[私のブログ](http://zamberform.github.io/blog/)に投稿しています。
【php】組み込み関数

##組み込み関数: strlen
phpには便利な関数がもとから組み込まれており、それを組み込み関数と呼ぶ。組み込み関数「strlen」は文字列の文字数を返す。

```
echo strlen('string'); //文字列を返す
//結果: 6

$lang = 'japanese';
echo strlen($lang); //変数もok
//結果: 8
```

##組み込み関数: count / rand
「count」は配列の要素の数を返す。
「rand」は1つ目の引数と2つ目の引数の間のランダムな整数を返す。

```
$data = array('team1','team2','team3','team4');
echo count('$data');
//結果: 4

echo rand(10,15);
//結果: 10~15のランダムな整数を返す
```
鍵盤画像からの輪郭検出の練習PGM

#鍵盤画像からの輪郭検出の練習PGM

openCVを用いた輪郭検出の練習PGMです

今回作成したPGMのgithubURL: https://github.com/NanjoMiyako/RinkakuKensyutuTest1

処理手順
1. makeOriginPicture.pyで元画像から鍵盤領域だけを抜き出した
画像を取得
2.RinkakuKensyutu.pyから1で作成した画像から輪郭領域を取得
各輪郭の矩形範囲を描画

<b>参考URL</b>
<a href = "https://qiita.com/taka_baya/items/453e429b466ffaa702c9">
Pythonを用いた画像処理(openCV,skimage) - Qiita</a>

<a href="https://note.nkmk.me/python-opencv-imread-imwrite/">
Python, OpenCVで画像ファイルの読み込み、保存（imread, imwrite） | note.nkmk.me
</a>

<a href="https://qiita.com/y_kani/items/c9861b1f3517c32491d6">
[OpenCV][Python3]検出した輪郭を描画し、輪郭線を近似して滑らかにする - Qiita
</a>

<b>参考素材</b>
<a href="https://www.youtube.com/watch?v=n7P9H8JfuTg">
米津玄師【パプリカ】2020応援ソング 簡単ドレミ楽譜 初心者向け1本指ピアノ - YouTube
</a>

<b>サンプル出力データ</b>
参考画像1
![concat.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412430/5cb0b88f-587f-1e2f-921d-43d69dd4bc53.jpeg)

参考画像2
![img_gray3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412430/9c6c06cd-7f5e-9cae-589e-f3aa78918375.jpeg)

参考画像3
![img_contour.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412430/3b4ee6b6-9dfa-80dc-70b0-f5832c376a07.jpeg)
Serverless Frameworkでboto3をモックしてテストする

Serverless FrameworkやSAMなどのサーバーレスアプリを開発するためのフレームワークでは、Lambda関数をテストする手法として、LocalStackやDynamoDB localを用いてローカルでテストを実行することができます。しかし今回は、それよりも単体テストに近い様なテストをPythonのライブラリである[moto](https://github.com/spulec/moto/tree/master/moto)を用いてboto3をモックし、lambdaのテストを簡単に行う方法を書いていこうと思います。

# 環境
- Python 3.6
- Serverless Framework 1.39.0
- boto3 1.9.208
- moto 1.3.13

# 使用例
### lambda関数
ここではDynamoDBからアイテムを取得して、レスポンスする簡単なlambdaを作成しました。

```python
import json
import boto3
from decimal_encoder import DecimalEncoder

def get_article(event, context):
    dynamodb = boto3.resource('dynamodb')
    table = dynamodb.Table('article')

    article_id = event['pathParameters']['article_id']
    res = table.get_item(
        Key={
            "article_id": article_id
        }
    )
    article = res.get('Item')

    response = {
        "statusCode": 200,
        "body": json.dumps(article, cls=DecimalEncoder)
    }

    return response
```

### テストコード
`@mock_dynamodb2`を書くことによってその関数内のboto3のDynamoDB関係のライブラリをモックしてくれる様になります。GETメソッドをテストするときなどはあらかじめテーブルにデータが入っていてほしい場合があるかと思います。そういう時も、テストコード内で通常と同様にput_itemをすることでデータを入れることができます。

```python
import unittest

import boto3
from moto import mock_dynamodb2

from handler import get_article
from test.utility import init_dynamodb

class TestEvent(unittest.TestCase):

    @mock_dynamodb2
    def test_get_article(self):
        # articleテーブルを作成
        init_dynamodb()

        # テストのためのarticleを一つ追加
        dynamodb = boto3.resource('dynamodb')
        table = dynamodb.Table('article')
        item = {
            'article_id': 1,
            'title': 'test_title',
            'body': 'test_article_body',
        }
        table.put_item(Item=item)

        # lambdaに渡すパラメーターを設定
        event = {
            'pathParameters': {
                'article_id': 1
            }
        }

        # 関数を実行
        response = get_article(event, [])
        print(response)
        # {'statusCode': 200, 'body': '{"article_id": 1, "title": "test_title", "body": "test_article_body"}'}

        # テスト
        self.assertEqual(200, response['statusCode'])
```

ちなみに、init_dynamodb()の内容は以下の様になっていて、articleというテーブルを事前に作成しています。この様な形で必要なテーブルを全て事前に作成することで、簡潔で綺麗なテストコードにすることができます。

```python
import boto3
from moto import mock_dynamodb2

@mock_dynamodb2
def init_dynamodb():
    dynamodb = boto3.resource('dynamodb')
    dynamodb.create_table(**{
        'TableName': 'article',
        'AttributeDefinitions': [
            {
                'AttributeName': 'article_id',
                'AttributeType': 'N'
            }
        ],
        'KeySchema': [
            {
                'AttributeName': 'article_id',
                'KeyType': 'HASH'
            }
        ],
        'ProvisionedThroughput': {
            'ReadCapacityUnits': 1,
            'WriteCapacityUnits': 1
        }
    })
```

## まとめ
今回はDynamoDBの機能だけしか使いませんでしたがmotoでは、同様にして様々なAWSのサービスをモック化することができます。対応しているサービスはmotoのgithubに詳しく書いてあるので興味のある人は読んでみてください。サーバーレスアプリのテスト手法の一つとして非常に便利そうなので、ぜひ活用してみてください。
Pythonのproxy回避

# はじめに
会社内でmnist.load_data()などで外部のdatasetを利用しようとした場合に、社内のproxyに阻まれてしまいました。さらに、proxyに認証が必要な場合の記事が見つからなかったので、情報共有のために記事にしました。

# 回避方法

```python
import urllib
proxy_support = urllib.request.ProxyHandler({'https':'http:userName:password@proxy_adress:portNumber'})
opener = urllib.request.build_opener(proxy_support)
urllib.request.install_opener(opener)
```
こちらの2行目のuserNameとpasswordに自分の社内の認証IDとPASSを記入してください。
そして、@の後に自分の会社のプロキシサーバのアドレスとポート番号を各々当てはめてくれれば通過できると思います。
英辞郎第十版をMacにインストール

書店で[英辞郎 第十版 辞書データVer.151\[2018年1月18日版\] (DVD-ROM2枚付)](https://www.amazon.co.jp/dp/4757430604/)を購入したのですが，Macにインストールしようとしたところ，
処理が終わっているにも関わらず，インストールできずでした．．．

Macにインストールする方法の備忘録です．

# 動作環境

* macOS Mojave 10.14.6

# インストール手順
1. DVDを開く
1. 画面で「英辞郎第十版.dictionary」がFinderに表示される
2. Finderを選択して，「メニューバー」-「フォルダへ移動」
3. 「フォルダの場所を入力:」というウィンドウが現れるので，「Library」と入力して「移動」を押す
4. 「Dictionaries」フォルダがあるので，「英辞郎第十版.dictionary」をコピーする
5. 「辞書」アプリで「環境設定」を開いて，辞書一覧から「英辞郎 第十版 (辞書データVer.151／2018年1月18日版)」が追加されているのでチェックして完了．
Railsのvalidatesとは？

##validatesとは?

フォームに値や文字を入力するときに、必須の項目ってありますよね。

<img width="708" alt="スクリーンショット 2019-08-19 21.16.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398610/a9bc2602-334c-e90c-a540-baf7c2814686.png">

こんな感じの。会員登録の時、「必ず入力してください」っていう項目、誰でも一度は目にしたことがあると思います。

このように**入力欄に制限をかける機能のこと**をvalidatesといいます。

##例:空欄を拒否するvalidation

では、実際にコードを記述してvalidationを設定します。

validationはmodelファイルで設定します。

```ruby:product.rb
class Product < ApplicationRecord
  validates :name, presence: true
end
```

`validates カラム名, バリデーションの条件`の記述でバリデーションを設定しました。

今回はproductモデルのnameカラムにpresence: trueというバリデーションをかけました。

**presence: true**は`空ではない`という条件のバリデーションです。これによりnameカラムに何らかの文字列が入ってないといけない状態になりました。

##例:値を被らないようにするvalidation

次に同じ名前が被らないようnameカラムにバリデーションをかけます。

```ruby:product.rb
class Product < ApplicationRecord
  validates :user_name, uniqueness: true
end
```
**uniqueness: true**でnameカラムの値がかぶることを防ぐことができます。

##様々なバリデーション

バリデーションにはたくさんの種類があるので、以下の記事を参考にしてみてください

[Railsバリデーションまとめ](http://https://qiita.com/shunhikita/items/772b81a1cc066e67930e)
CI/CDについて調べてみました！

##CI/CDってなに？

まず調べていく中で参考にしたのは、
こちらの2つのURLです。
https://codezine.jp/article/detail/11083
無料の範囲でもとても分かりやすく記載してくださってます。

https://pfs.nifcloud.com/navi/words/ci_cd.htm
図もあってとても分かりやすいです。


自分用に少しポイントをまとめようと思います。
URL内にも記載がありますが自分用にもメモ。


**CI(Continuous Integration)**　→　継続的インテグレーション
**CD (Continuous Delivery)**　→ 継続的デリバリー

上記２つの考え方がメインとなります。

勉強して思ったのがCI/CDって技術を指すのではなくて、
ソフトウェア開発の手法を意味しているということに初学者の私は少し驚きました。

取り入れるメリットとしては、
**・自動テスト**
**・自動ビルドと自動デプロイ**の２点

つまり、**CI**はテストを自動化して、**CD**は本番環境向けのビルドの作成を自動的に行い、
本番環境にデプロイが可能な状態にするということ！



##どうしてCI/CDは導入されるのか


例えば、GitHubへソースコードをコミットすると、
上記であげたようにCIに各種のテストを行い、
CIを行うことでバグを早期に検出し、
リリース用のブランチにバグが入らないようにする。
→
CIによるテストをパスするとCDによってコードがリリース用のブランチにマージされ、
ビルドが行われる。
→
ビルドされたアプリケーションは自動でテスト用のサーバーに「デリバリー」され、
すぐに動作確認が行えるようになる！

つまり、
**CI/CDを使うと、コードの変更が発生するたびに自動でテストが行われるので、
テストの実行忘れや、環境依存のテストを失くすことでの品質を向上させることができる！**


様々な企業の技術スタックをみる中で、
**CI/CD**をよく目にしていたので導入されている意味が分かりました。

自分で導入するにはどうすれば良いか、についても
詳しく調べて行こうと思います。
書籍『たのしいRuby』の練習問題を解いてみた Part.6

# 本題
今回は第17章の練習問題を解いていく。今回はIOクラスの内容だ。それでは早速解いてみる。
**(1)**　テキストファイルからデータを読み込んで次の処理を行うスクリプトを作成してください。なお、ここでは空白や改行以外の文字の並びのことを単語と呼ぶことにします。
(a) テキストの行数を数える。
(b)テキストの単語数を数える
(c)テキストの文字数を数える

```ruby:1_1.rb
file_name = ARGV[0]
file = File.open(file_name)
#aの結果の準備
ans=0
#b,cの結果の準備
txt = []
file.each_line do |line|
	ans+=1
	txt.push(line.split(" "))
end
file.close
#多次元配列を一次元配列にする(bの処理)
txt.flatten!
num1 = txt.size
#cの処理
word = txt.join
num2 = word.size
#aの結果
puts "このファイルは#{ans}行です"
#bの結果
puts "このファイルは#{num1}単語です"
#cの結果
puts "このファイルは#{num2}文字です"
```

a,b,cを一つのプログラムにして解いた。
コマンドラインから引数を受け取るようにした。まず、File.openでファイルを開く。aはeach_lineメソッドを使用し行数をカウントした。次に、bの単語だ。each_lineメソッドを使用したとき、txt配列に空白で区切った単語を格納させたので、その配列の要素の数をsizeメソッドで返させた。cの文字数は、flatten!メソッドを利用し、文字一つ一つを配列の要素に変換し、その配列の数を数えるようにした。自作wcコマンドのようなものだろうか。

**(2)**　テキストファイルからデータを読み込んで次の条件に従って上書きするスクリプトを作成してください。
(a)ファイルの中の行を逆順に並べ替える
(b)ファイルの中の最初の1行だけを残して残りを削除する
(c)ファイルの中の最後の1行だけを残して残りを削除する

```ruby:2_a.rb
file_name = ARGV[0]
file = File.open(file_name,"r+")

rev_arry = []
file.each_line do |line|
	rev_arry << line
end
#
rev_arry.reverse!
file.truncate(0)
file.puts rev_arry.join()

file.close
```

1行ずつ配列の要素として格納。それを逆さにして、頭から入れ直すようにしました。ちなみに、truncateを使いファイルの中身は空にしました。

```ruby:2_b.rb
file_name = ARGV[0]
file = File.open(file_name,"r+")

arry = []
file.each_line do |line|
	arry << line
end

file.truncate(0)
file.puts arry[0]

file.close
```

ほぼ先ほどと同じ処理です。違うとしたら、配列の一番最初の要素だけをファイルに書き込んだことくらいです。

```ruby:2_c.rb
file_name = ARGV[0]
file = File.open(file_name,"r+")

arry = []
file.each_line do |line|
	arry << line
end

file.truncate(0)
file.puts arry[-1]

file.close
```

b問題とほぼ同じ、こちらは配列の末尾を書き込むようにしました。

**(3)**　Unixで使われる"tail"コマンドと似たことが出来るメソッドtailsを定義しなさい。なお、tailメソッドは2つの引数を受け取ります(tail(行数,ファイル名))

```ruby:3_1.rb
def tail(num,file)
	f = open(file)
	arry = []
	f.each_line do |line|
		arry << line
	end
	a = -1 * num.to_i
	result = arry[a..-1]
	result.each{|i| p i.chomp}
end
```

2_cの問題を少しイジった感じです。2_cは末尾のみだったのでそれを必要な行の要素から末尾まで返すようにしました。

**(4)**　Fileオブジェクトへの出力が何バイトまでバッファリングされるか調べるスクリプトを作成してください。

```ruby:3_1.r
file_name = "Test.txt"
file = File.open(file_name,"w")

10000.times do |i|
	file.write("X")
	size = File.size(file_name)
		if size == i and i>0
		break
	end
	p "#{i+1}回目：#{size}"
end
#実行結果：1回目：0
# 　　 　　2回目：0
#　    　　　省略
#         8192回目：8192
```

Test.txtというファイルに"X"という文字を増やし続けるようなプログラムにしました。すると、8192回目でTest.txtに書き込まれたことを確認することが出来ました。
# 最後に
今回はIOクラスについて学習した。使う機会はあるものの、使いこなせていない現状があるので上手く使えるようになりたい。
FirebaseのProjectをstaging, productionで分けるときの指針

Firebaseのstagingとproductionの切り分けには大きく分けて2通りのアプローチがある

1. **1project内にproduction / staging向きアプリを登録する**
1. **project自体を分ける**

## 必須でprojectを分けるパターン
* Cloud Firestoreを利用する場合
* Cloud Functionsを利用する場合
* Storageを利用する場合
* Hostingに静的サイトを構築する場合

上記の機能は、1projectに1つの環境しか作れないので、projectを分ける必要がある
それぞれローカルで作業して、Firebase CLIやCIを経由でデプロイするフローを踏むことになるので、運用的にもproject自体を分けることになる

CLIで環境の切り替え方:
https://firebase.google.com/docs/cli?hl=ja#project_aliases

## 必須じゃないけど分けた方がいいパターン
### Authentication, Remote Config, FCMなど本番ユーザーに影響しかねない設定を触る場合

* Remote Configのキー名を `hogehoge_stg` のように運用で分けても良いが、同じprojectに本番・ステージの環境変数が乗っかっているのは事故の元になる
* FCMも、ターゲットのアプリを慎重に切り替えれば良いが人的ミスの温床になる
* Authenticationも言わずもがな

### ユーザー数が少ない状態でAnalyticsを頻繁にウォッチする場合
たとえアナリティクスだけしか使わない(予定)のアプリだとしても、
ダッシュボードで毎回、productionのアプリにフィルタをかけないと調査データが濁るので、ユーザー数が少ないアプリは注意が必要。
これを毎回やるくらいならprojectを分けた方がいい

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30423/a76395a8-6b4b-e07e-5991-ef7afba85df4.png)

## 結論
将来的に分ける場合、移行が面倒だったりするので**少しでもFirebaseを利用するなら最初から分けたら良いと思う**。
そして、productionの環境を編集できる人は権限を厳密に管理すれば事故りにくい

## 宣伝
フルFirebaseで実装した個人アプリをリリースしました!! :rocket:

[App Store📱](https://t.co/s1M4D3r24O?amp=1)

下記の機能をフル活用したアプリです。
家族・カップルのタスク管理にお困りの方、是非使ってみてください

* Analytics
* Authentication
* Crashlytics
* Firestore
* Storage
* Cloud Messaging
* In-App Messaging
* Storage
* Remote Config
* Dynamic Links

<img width="2688" alt="store_1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30423/8741afd8-cf22-a7e7-881b-f93e95dfe6d3.png">
Leetcode #347: Top K Frequent Elements

```swift
func topKFrequent(_ nums: [Int], _ k: Int) -> [Int] {
    var dict = [Int: Int]()
    for num in nums {
        if let value = dict[num] {
            dict[num] = value + 1
        } else {
            dict[num] = 1
        }
    }
    var sortedKeys = dict.keys.sorted{ dict[$0]! > dict[$1]! }
    return Array(sortedKeys[0..<k])
}
```
Visual Studio CodeでPHPをデバッグする方法


## 実施環境
- Windows10
- Visual Studio Code 1.37.1（以下VSCode）がインストール済
- xamppがC直下にインストール済（PHP 7.3.7）

## 手順
1. VSCode設定ファイル追記
2. VSCode拡張機能「PHP Debug」のインストール
3. PHPデバッグツール「XDebug」のインストール
4. 「XDebug」をVSCodeに紐づけ
5. デバッグを行う


## 1. VSCode設定ファイル追記
VSCodeを立ち上げ
ファイル＞基本設定＞「settings.json」を検索＞「settings.jsonで編集」をクリック

JSONファイルに以下の内容を追記します。

```json
"php.validate.executablePath": "C:\\xampp\\php\\php.exe"
"php.validate.run": "onType"
```

## 2. VSCode拡張機能「PHP Debug」のインストール

Ctrl + Shift + X で拡張機能検索ウィンドウを開きます。
「PHP Debug」と入力するとパッケージが表示されるので「インストール」をクリックします。
ボタンが「アンインストール」になったら成功。

![php-extension.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286938/d18d2b2b-5cad-fa05-2909-4b28f4ddd664.png)


## 3. PHPデバッグツール「XDebug」のインストール
C:\xampp\htdocsの階層にphpinfo.phpというファイルを作成し、以下のコードを記述。

```php
<?php
	phpinfo();
?>
```

xamppのコントロールパネルを開き、Apacheを起動。
C:\xampp\xampp-control.exe
<br>
起動後、http://localhost/phpinfo.php にアクセスすると下記のような画面が表示されるので、Ctrl + A で全文コピー。

![phpinfo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286938/23308472-06cf-2656-5cb4-b133c2b1f029.png)


https://xdebug.org/wizard.php を開き、テキストボックスに貼り付け。
Analyse my phpinfo() outputボタンをクリックし、表示されたDLLファイルをダウンロード。<br>
![ddl-download.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286938/20677a92-ff84-08c3-2b59-4af8b3337a07.png)



ダウンロードしたDLLファイルは下記ディレクトリ配下へ移動。
C:\xampp\php\ext


## 4.「XDebug」をVSCodeに紐づけ
C:\xampp\php\php.iniに以下のコードを追記します。
※ zend_extensionの値は3.でダウンロードしたDLLファイル名

```ini
...
[XDebug]
xdebug.remote_enable = 1
xdebug.remote_autostart = 1
xdebug.remote_connect_back = 1
xdebug.remote_port = 9000
zend_extension = C:\xampp\php\ext\php_xdebug-2.7.2-7.3-vc15-x86_64.dll
```

## 5. デバッグを行う

ファイル＞フォルダーを開く＞デバッグしたいファイルのある階層を選択＞デバッグするファイルを開く＞左メニューバーからデバッグボタンをクリック

「デバッグ開始」ボタン横のプルダウンから「PHP」を選択。
再度プルダウンより「構成の追加」を選択すると、launch.jsonが開くので下記のように修正。

```json
{
    // IntelliSense を使用して利用可能な属性を学べます。
    // 既存の属性の説明をホバーして表示します。
    // 詳細情報は次を確認してください: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Listen for XDebug",
            "type": "php",
            "request": "launch",
            "port": 9000,
            "pathMappings": {
                "${workspaceRoot}": "${workspaceRoot}"
            }
        },
        {
            "name": "Launch currently open script",
            "type": "php",
            "request": "launch",
            "program": "${file}",
            "cwd": "${fileDirname}",
            "port": 9000,
            "pathMappings": {
                "C:\\xampp\\htdocs\\test": "${workspaceRoot}"
            },
            "runtimeExecutable": "C:\\xampp\\php\\php.exe"
        }
    ]
}
```

デバッグしたいファイルにブレークポイントを置く。
「Launch currently open script」が選択されていることを確認し、デバック開始ボタンを押下。
Windows で atom . ができない対策

# 概要

Windows のコマンドプロンプトで `atom .` としても Atom がカレントディレクトリーで開かない。

これを簡易的（対症療法的）に解決した。


# 現象

対象：Windows の Atom 1.40.0 およびその少し前のバージョン

コマンドプロンプトで

```shell
atom .
```

と打ったら，カレントディレクトリーをプロジェクトディレクトリーとして Atom が起動するはずだ。
実際，Atom を使い始めてから長らくそうであった。

ところが，最近，カレントディレクトリーではなく，Atom のインストールディレクトリーをプロジェクトディレクトリーとして Atom が起動するようになった。

すべての Windows 版 Atom でそうなのか，私の環境で何か異変が起こったのかは分からない。
ウェブ検索しても何も出てこないので，何か特殊な再現条件があるのかもしれない。

# 解決

Windows では `%cd%` がカレントディレクトリーのパスになるらしいので，

```shell
atom %cd%
```

と打ったらうまくいった。大文字／小文字は区別されないので，`%CD%` でもいい。

`%CD%` は「動的な環境変数」と呼ばれるものの一つで，カレントディレクトリーのパスを表す文字列に展開されるらしい。

しかし，もう少し打ちやすいようにできないか。Shift キーを使わなくていいように。
ええと，パスが通ったディレクトリーに

```bat:atomhere.bat
atom %CD%
```

というバッチファイルを置けばいいのか。
これで `atomhere` と打つだけでよくなった。
（うーん，名前がイマイチ。もう少し短く分かりやすい名前はないものか）
【GAS】Googleドライブ内のファイル名検索

## Googleドライブ内のファイル名検索

### 記述方法（Googleドライブ内のファイル取得）
```javascript:test.ga
// ドライブ内のファイル取得
var fileList = DriveApp.getFolderById("GoogleドライブのID").getFiles();
while (fileList.hasNext()) {
    //ファイルのオブジェクト取得
    var file = fileList.next();
    // ファイル名取得
    var fileName = file.getName();
    // ファイルID取得
    var fileId = file.getId();
}
```

---
### サンプル
下記のようなGoogleドライブ上のファイルをファイル名で検索する
- 検索ファイル名［searchFileName］：テスト_20190301
- ドライブID［driveId］:1e9K40zNGi-CmbyeqBpN13uxxxxxxxxxx
※ドライブIDは、GoogleドライブのURLの一部で下記画像の赤い四角の部分の一意な文字列
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363906/a1b5b9a3-e4c2-a2c1-3fa1-97e665594558.png)

```javascript:test.ga
function executeSearchFile() {
    var searchFileName = 'テスト_20190301';
    var driveId = '1e9K40zNGi-CmbyeqBpN13uxxxxxxxxxx';
    searchFile(driveId, searchFileName)
}

/**
 * Googleドライブ内のファイル検索
 *
 * @param {string} driveId  検索するGoogleドライブID
 * @param {string} searchFileName 検索するファイル名
 * @returns {boolean}
 */
function searchFile(driveId, searchFileName) {
        // 指定されたGoogleドライブIDからフォルダのファイルリストを取得する
    var fileList = DriveApp.getFolderById(driveId).getFiles();
    while (fileList.hasNext()) {
        //ファイルを取得
        var file = fileList.next();
        if (searchFileName === file.getName()) {
            this.spreadsheetId = file.getId();
            Logger.log('ファイルが見つかりました');
            Logger.log('ファイルID：' + file.getId());
            return true;
        }
    }
    Logger.log('ファイルが見つかりませんでした');
    return false;
}
```
#### 実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363906/bbd8c7e2-6ac3-6d09-57bb-7f391d40d7ca.png)
検索対象ファイルが、スプレッドシートの場合、ファイルIDを使用することでスプレッドシートにアクセスすることが可能（SpreadsheetApp.openById('ファイルID');）
Leetcode #540: Single Element in a Sorted Array

Solution 1:

```swift
func singleNonDuplicate(_ nums: [Int]) -> Int {
    var i = 0
    while i + 1 < nums.count {
        if nums[i] != nums[i+1] {
            return nums[i]
        } else {
            i += 2
        }
    }
    return nums.last!
}
```

Solution 2: Binary Search

```swift
func singleNonDuplicate(_ nums: [Int]) -> Int {
    var start = 0
    var end = nums.count - 1
    while start < end {
        let mid = start + (end - start) / 2
        let n = mid % 2 == 0 ? mid + 1 : mid - 1
        if nums[mid] == nums[n] {
            start = mid + 1
        } else {
            end = mid
        }
    }
    return nums[start]
}
```
Raspberry Pi 2B でMirakurun(PX-S1UD V2.0)を動かす

# はじめに

表題の通り、今更メモリ1Gしかないラズパイ2Bでmirakurunを動かします。

(アンテナ線のコネクタが直射日光の当たるところにしかないので、サーバーと分離させたかったのです。)



### 環境

Linux raspberrypi 4.19.63-v7+ #1249 SMP Thu Aug 1 16:26:30 BST 2019 armv7l GNU/Linux

PX-S1UD V2.0

ACR39NTTCom (B-CASカードリーダー)



node v10.15.2

mirakurun@2.11.0



### 必要ソフトウェア類のインストール

###### PX-S1UDのモジュール

```bash
wget http://plex-net.co.jp/plex/px-s1ud/PX-S1UD_driver_Ver.1.0.1.zip
unzip PX-S1UD_driver_Ver.1.0.1.zip
sudo cp PX-S1UD_driver_Ver.1.0.1/x64/amd64/isdbt_rio.inp /lib/firmware/
```

再起動します



###### カードデーモン

```bash
sudo apt install pcscd libpcsclite-dev libccid pcsc-tools
sudo pcsc_scan
```

Japanese Chijou Digital B-CAS Card (pay TV)と認識されていればOKです。

Ctrl + C で終了します。



###### node

```bash
sudo apt install nodejs npm
```

Mirakurunはnodeのバージョン8,10 (安定板)のみサポートしています。

```bash
sudo npm install -g npm
```

npmを更新しておきます。



###### recdvb

B-CASのライブラリであるarib25をインストールします。

```bash
sudo apt install build-essential git automake cmake g++
git clone https://github.com/stz2012/libarib25.git
cd libarib25
cmake .
make
sudo make install
```

チューナーへのフロントエンドであるrecdvbです。

```bash
wget http://www13.plala.or.jp/sat/recdvb/recdvb-1.3.2.tgz
tar xvzf recdvb-1.3.2.tgz
cd recdvb-1.3.2
./autogen.sh 
./configure --enable-b25
make 
sudo make install
```

```bash
recdvb --b25 --strip <物理チャンネル> <秒数> test.m2ts
```

テスト録画ができます。



###### Mirakurun

いよいよ本命です。

サービス管理ソフトであるPM2をインストールします。

```bash
sudo npm install pm2 pm2-logrotate -g
```

Mirakurunをインストール、サービスとして登録します。

```bash
sudo npm install mirakurun -g --unsafe-perm --production
sudo mirakurun init
```

```bash
sudo mirakurun config tuners
```

```yam
- name: PX-S1UD-1
  types:
    - GR
  command: recdvb --b25 --dev 0 <channel> - -
  isDisabled: false
```

最終行に追記します。

```bash
sudo mirakurun restart
```

しばらくするとepg取得が始まります。

十五分後くらいにcurlを叩くとチャンネルスキャンが始まります。

```bash
curl -X PUT "http://<ラズパイのアドレス>:40772/api/config/channels/scan"
```



vlc等から

http://<ラズパイのアドレス>:40772/api/channels/GR/<物理チャンネル>/stream

を開くとストリーミング再生できます。



### 最後に

以上で作業は終了です。あとはm3u8ファイルを作るなりリモートのchinachuから接続するなりしてください。

## 追記(2019/09/22)

数週間稼働させてみたところ、メモリを使いつぶしてRaspbianが停止してしまいました。

週一回くらいは再起動したほうが安心できます。

最後までお読みいただきありがとうございました。