OmniAICreator/Qiita-1.07M huggingface dataset:
初めてPHPUnitを使ってみた

初めて、PHPUnitを使ってみたので、メモ。

### 環境
- PHP 7.1.10

### 手順
[ここ](https://phpunit.de/getting-started/phpunit-7.html)の手順通り実施。

適当なディレクトリを作成して、その配下でcomposerを実行しPHPUnitを追加。

```bash
$ composer require --dev phpunit/phpunit ^7
```

追加できたか確認

```bash
$ ./vendor/bin/phpunit --version
PHPUnit 7.3.5 by Sebastian Bergmann and contributors.
```

ディレクトリ構造（抜粋）

```bash
$ tree
/適当に作ったディレクトリ
|--composer.json
|--composer.lock
|--vendor
| |--autoload.php
```

composer.jsonを以下の通り修正

```bash
{
    "autoload": {
        "classmap": [
            "src/"
        ]
    },
    "require-dev": {
        "phpunit/phpunit": "^7"
    }
}
```

手順通り、codeとtestsを作成

```php:src/Email.php
<?php
declare(strict_types=1);

final class Email
{
    private $email;

    private function __construct(string $email)
    {
        $this->ensureIsValidEmail($email);

        $this->email = $email;
    }

    public static function fromString(string $email): self
    {
        return new self($email);
    }

    public function __toString(): string
    {
        return $this->email;
    }

    private function ensureIsValidEmail(string $email): void
    {
        if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
            throw new InvalidArgumentException(
                sprintf(
                    '"%s" is not a valid email address',
                    $email
                )
            );
        }
    }
}
```

```php:tests/EmailTest.php
<?php
declare(strict_types=1);

use PHPUnit\Framework\TestCase;

final class EmailTest extends TestCase
{
    public function testCanBeCreatedFromValidEmailAddress(): void
    {
        $this->assertInstanceOf(
            Email::class,
            Email::fromString('user@example.com')
        );
    }

    public function testCannotBeCreatedFromInvalidEmailAddress(): void
    {
        $this->expectException(InvalidArgumentException::class);

        Email::fromString('invalid');
    }

    public function testCanBeUsedAsString(): void
    {
        $this->assertEquals(
            'user@example.com',
            Email::fromString('user@example.com')
        );
    }
}
```

ディレクトリ構造はこんな感じ

```bash
$ tree
/適当に作ったディレクトリ
|--composer.json
|--composer.lock
|--src
| |--Email.php
|--tests
| |--EmailTest.php
|--vendor
| |--autoload.php
```

テスト実行、しかしエラー。。

```bash
$ ./vendor/bin/phpunit --bootstrap vendor/autoload.php tests/EmailTest
PHPUnit 7.3.5 by Sebastian Bergmann and contributors.
EFE                                                                 3 / 3 (100%)
Time: 34 ms, Memory: 4.00MB
There were 2 errors:
1) EmailTest::testCanBeCreatedFromValidEmailAddress
Error: Class 'Email' not found
...
ERRORS!
Tests: 3, Assertions: 1, Errors: 2, Failures: 1.
```

composerをアップデート

```bash
$ composer update
```

再実行

```bash
$ ./vendor/bin/phpunit --bootstrap vendor/autoload.php tests/EmailTest
PHPUnit 7.3.5 by Sebastian Bergmann and contributors.
...                                                                 3 / 3 (100%)
Time: 28 ms, Memory: 4.00MB
OK (3 tests, 3 assertions)
```

なんとかできた。。
もっと調べて、使えるようにして行きたい。。
DialogFlow v2 APIの使い方１　API実行に必要なアクセストークンをコマンドプロンプトで取得する方法

DialogFlowのv2のAPIを用いてテスト環境から本番環境へワンクリックデプロイのバッチなどを作成したので、皆様の役に立てばと思い記事を記述しています。
<h2>前提条件</h2>
・DialogFlowのプロジェクトが存在する。

<h2>本ドキュメントのゴール</h2>
APIを実行するために必要なアクセストークンをコマンドプロンプトで取得する。
そのために必要なものは以下の二つです。
1.API実行権限があるサービスアカウント（Jsonファイル）作成
2.DialogFlowをコマンドプロンプトから実行するためのSDK（GSDK）インストール
それぞれの取得方法についてみていきます。

<h3>1.API実行権限があるサービスアカウント（Jsonファイル）作成</h3>
1.dialogflowのagentの設定画面からService accountのメールアドレスリンクをクリック
![Inkedapi権限設定１.jpg](https://qiita-image-store.s3.amazonaws.com/0/294965/f53a92f7-9ed4-f8db-a42d-8bd279b64206.jpeg)

<br/><br/>
2.サービスアカウントの作成をクリック
![InkedInkedapi権限設定2.jpg](https://qiita-image-store.s3.amazonaws.com/0/294965/e4f35a7c-8745-2dbb-8732-d04885953903.jpeg)

<br/><br/>
3.サービスアカウントをDialogFlow　API管理者として作成（APIクライアントだとうまく動かない場合があるみたいです。
![api権限設定3.png](https://qiita-image-store.s3.amazonaws.com/0/294965/8fa12485-527c-ad42-3a66-e7bea8fadce1.png)

<br/><br/>
4.キータイプJSONを指定し保存をクリック
![api権限設定4.png](https://qiita-image-store.s3.amazonaws.com/0/294965/f17f17b2-693f-b315-8cf7-50e3379275df.png)

<br/><br/>
以上で、API実行権限があるサービスアカウント（Jsonファイル）作成完了です。

<a href="https://developers.google.com/identity/protocols/OAuth2">https://developers.google.com/identity/protocols/OAuth2</a>
<h3>2.DialogFlowをコマンドプロンプトから実行するためのSDK（GSDK）インストール</h3>
コマンドプロンプトでDialogFlowと連携するためのgoogle cloud sdkをインストールします。
<br/><br/>
1.<a href="https://cloud.google.com/sdk/docs/?hl=ja">https://cloud.google.com/sdk/docs/?hl=ja</a>にアクセスし、SDKのインストーラーを取得します。
![gcloud設定２？.png](https://qiita-image-store.s3.amazonaws.com/0/294965/08c1b11b-f4a9-b57b-d20b-7318922f42ef.png)

<br/><br/>
2.インストーラーの指示に従いインストールを実行します。
![gcloud設定３.png](https://qiita-image-store.s3.amazonaws.com/0/294965/291fb12d-a11d-2537-6378-f4bb2e3f792c.png)
<br/><br/>
3.コマンドプロンプトが立ち上がるのでyを入力します。
![gcloud設定８.png](https://qiita-image-store.s3.amazonaws.com/0/294965/aafd7630-05bc-442f-d0d6-abef8be7dd7d.png)

<br/><br/>
4.ブラウザが立ち上がり、権限の許可を行います。
![gcloud設定９.png](https://qiita-image-store.s3.amazonaws.com/0/294965/379f5295-0cd9-f9bc-8bd5-50af68bd79e2.png)

<br/><br/>
以上で基本的な設定は終わりです。
<br/><br/>
GOOGLE~APPLICATION_CREDENTIALSの環境変数にダウンロードしたJsonのパスを指定します。
そしてgcloud auth application-default print-access-token　コマンドを実行することでアクセストークンが取得できます。
![Inkedgcloud設定１０_LI.jpg](https://qiita-image-store.s3.amazonaws.com/0/294965/63282768-5e27-75c7-6bc3-eefa0ef4e54a.jpeg)


私のブログにも同様の記事を記載しております。
http://itknowledgesince2015.com/2018/09/13/dialogflowapi-v2-%E5%88%A9%E7%94%A8%E6%BA%96%E5%82%99%E7%B7%A8%e3%80%80%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%83%88%E3%83%BC%E3%82%AF%E3%83%B3%E3%82%92%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%83%97/
DjangoでModel経由で実行したSQLをログに出力する

パフォーマンスチューニングって重要ですよね。

Djangoを使用していて、あれ、このAPI重いなとか負荷がかかってるな？と思ってSQLが原因かなーと、思ったのであれば、実行SQLとその実行にかかった時間をログに出してみましょう。
まずはともかく、ログに出さないことには何も調べようがないですしね:sob:

# ログに出す！

特に新規実装とかは不要です！
やることは簡単、設定値を変更するだけ:muscle:

```settings.py
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
        },
    },
    'loggers': {
        'django.db.backends': {
            'handlers': ['console'],
            'level': 'DEBUG',
        },
    },
}
```

これを追加してあげるだけです！
今回の場合だと、sqlが実行される度に、handlersで設定した先に対してログが出力されます！
便利:grin:
Hacker's coding golf python  Key Value

# Pythonには、Pythonの立場がある
+ 実行速度が遅いとか、早いとか
+ コンパイラーではないとか

### ご意見ありがとうございます。機械語に翻訳することのできる、コンパイラーではないとか
+ 中途半端なオブジェクト指向だとか
+ 入門者用言語とか
+ インタープリタには、インタープリタの立場がある
+ C言語類 (c#,c,c++とかjava)は、御作法(おさほう)が多すぎる

## 立場を利用してcodingすると
```convert.py
t1={"大正13":1924,"大正14":1925,"大正15":1926,"昭和1":1926,"昭和2":1927,"昭和3":1928,"昭和4":1929,"昭和5":1930,"昭和6":1931,"昭和7":1932,"昭和8":1933,"昭和9":1934,"昭和10":1935,"昭和11":1936,"昭和12":1937,"昭和13":1938,"昭和14":1939,"昭和15":1940,"昭和16":1941,"昭和17":1942,"昭和18":1943,"昭和19":1944,"昭和20":1945,"昭和21":1946,"昭和22":1947,"昭和23":1948,"昭和24":1949,"昭和25":1950,"昭和26":1951,"昭和27":1952,"昭和28":1953,"昭和29":1954,"昭和30":1955,"昭和31":1956,"昭和32":1957,"昭和33":1958,"昭和34":1959,"昭和35":1960,"昭和36":1961,"昭和37":1962,"昭和38":1963,"昭和39":1964,"昭和40":1965,"昭和41":1966,"昭和42":1967,"昭和43":1968,"昭和44":1969,"昭和45":1970,"昭和46":1971,"昭和47":1972,"昭和48":1973,"昭和49":1974,"昭和50":1975,"昭和51":1976,"昭和52":1977,"昭和53":1978,"昭和54":1979,"昭和55":1980,"昭和56":1981,"昭和57":1982,"昭和58":1983,"昭和59":1984,"昭和60":1985,"昭和61":1986,"昭和62":1987,"昭和63":1988,"昭和64":1989,"平成1":1989,"平成2":1990,"平成3":1991,"平成4":1992,"平成5":1993,"平成6":1994,"平成7":1995,"平成8":1996,"平成9":1997,"平成10":1998,"平成11":1999,"平成12":2000,"平成13":2001,"平成14":2002,"平成15":2003,"平成16":2004,"平成17":2005,"平成18":2006,"平成19":2007,"平成20":2008,"平成21":2009,"平成22":2010,"平成23":2011,"平成24":2012,"平成25":2013,"平成26":2014,"平成27":2015,"平成28":2016,"平成29":2017,"平成30":2018} # 和暦->西暦
t2={v:k for k,v in t1.items()}# 西暦->和暦
t3={i:v for i,v in enumerate(t2.items())}# offset
for x in t3.items(): print(x)
```
# pythonには、switchがない
+ 変換テーブルがpythonの命


```result
(0, (1924, '大正13'))
(1, (1925, '大正14'))
(2, (1926, '昭和1'))
(3, (1927, '昭和2'))
(4, (1928, '昭和3'))
(5, (1929, '昭和4'))
(6, (1930, '昭和5'))
(7, (1931, '昭和6'))
(8, (1932, '昭和7'))
(9, (1933, '昭和8'))
(10, (1934, '昭和9'))
(11, (1935, '昭和10'))
(12, (1936, '昭和11'))
(13, (1937, '昭和12'))
(14, (1938, '昭和13'))
(15, (1939, '昭和14'))
(16, (1940, '昭和15'))
(17, (1941, '昭和16'))
(18, (1942, '昭和17'))
(19, (1943, '昭和18'))
(20, (1944, '昭和19'))
・・・・・・
```
空になったファイルを尋ねずに自動削除

Emacsで編集作業をしていて、不要になった覚書書メモとかを空にしたら尋ねることなく自動的に削除してくれるという地味で便利な emacs-lispです。下記の記事からの引用です。

- [Youhei SASAKI's Official site](https://uwabami.github.io/cc-env/Emacs.html#org57f6557) 

## 設定

````lisp
;; Automatic deletion for empty files (Valid in all modes)
(defun my:delete-file-if-no-contents ()
  (when (and (buffer-file-name (current-buffer))
             (= (point-min) (point-max)))
    (delete-file
     (buffer-file-name (current-buffer)))))
(if (not (memq 'my:delete-file-if-no-contents after-save-hook))
    (setq after-save-hook
          (cons 'my:delete-file-if-no-contents after-save-hook)))
````
なんとかGo と なんとかOne のまとめ

# なんとかGo
|品名|説明|提供元|備考|
|:--|:--|:--|:--|
|AlphaGo|囲碁AI|Google DeepMind|
|Amazon Go|レジなし無人スーパー|Amazon|
|Android (Go Edition)|エントリー端末向け軽量版Android OS|Google|
|ETCGO|高速道路以外でETCカードを使える決済サービス|アマノ|
|Files Go|ファイル管理アプリ|Google|
|Gmail Go|軽量版Gmailアプリ|Google|
|GNU Go|囲碁ゲーム|Free Software Foundation|
|Go|プログラミング言語|Google|Google Go（アプリ）とは別物|
|GO|タクシー配車アプリ|Mobility Technologies|
|Google Assistant Go|軽量版Googleアシスタントアプリ|Google|
|Google Go|検索アプリ|Google|Google Search Liteより改称。Go言語とは別物|
|Google Map Go|軽量版Google Mapアプリ|Google|
|Lenovo Go|PC周辺機器のブランド名|Lenovo|
|Oculus Go|VRヘッドセット|Oculus|
|Pokémon GO|ゲーム|Niantic|
|Surface Go|タブレット型PC|Microsoft|
|Xperia Go|スマートフォン|Sony|
|YouTube Go|YouTube動画再生アプリ|Google|

# Goなんとか
|品名|説明|提供元|備考|
|:--|:--|:--|:--|
|GO Pay|タクシー用キャッシュレス決済アプリ|Mobility Technologies|
|GoPro|カメラ|GoPro|

# なんとかOne
|品名|説明|提供元|備考|
|:--|:--|:--|:--|
|Amazon One|生体認証|Amazon|
|Android One|スマートフォン|Google|
|Apple One|iCloud+、Apple TV+、Apple Music、Apple Arcadeのまとめ売り|Apple|
|AttritableONE|軍事用語。消耗可能な無人航空機|
|au one|ポータルサイト|KDDI|
|cdmaOne|2.5世代携帯電話規格|Qualcomm|
|Cisco ONE|SDN実行環境|Cisco|
|Ear(1)|イヤホン|Nothing|
|gatewayONE|軍事用語。航空機間の通信技術|
|Google One|Googleドライブの有料プラン|Google|
|HackerOne|バグバウンティサイト|HackerOne|
|ひかりone|FTTH|KDDI|auひかりに改称
|JP1|統合システム運用管理ソフト|日立製作所|
|LinuxONE|企業向けLinux専用サーバー|IBM|
|net one|SIer|ネットワンシステムズ|正式名ネットワンシステムズ株式会社|
|Nexus One|スマートフォン|Google|
|Nothing Phone(1)|スマートフォン|Nothing|
|OCNモバイルONE|格安スマホ|NTTレゾナント|
|ONE|CeVIO Creative Studio, CeVIO AI用ボイスデータ|1st PLACE|オネと発音する。OИEとも綴る。|
|Opera One|ブラウザ|Opera
|PS one|家庭用ゲーム機|Sony Computer Entertainment|
|RealOne|マルチメディア再生ソフト|Real Networks|
|SS1|IT資産管理・ログ管理ソフト|ディー・オー・エス|System Support best1の略
|Sun ONE|Webサーバ|Sun Microsystems|Sun Java Systemに改称|
|Trend Micro Apex One|企業向けセキュリティソフト|Trend Micro|ウイルスバスターコーポレートエディションより改称
|Trend Micro Cloud One|企業向けのクラウド向けセキュリティサービスプラットフォーム|Trend Micro
|Trend Vision One|企業向けXDR|Trend Micro
|XBox One|家庭用ゲーム機|Microsoft|
|Xperia 1|スマートフォン|Sony|

# Oneなんとか
|品名|説明|提供元|備考|
|:--|:--|:--|:--|
|OneDrive|オンラインストレージ|Microsoft|
|Fujitsu Network 1FINITY|光伝送装置|富士通|
|ONE-GX|ゲーミングPC|One-Netbook Technology|
|OneMap3D|3次元地図サイト|シンガポール土地管理局|
|OneMix|UMPC|One-Netbook Technology|
|One-Netbook Technology|PCメーカー|One-Netbook Technology|
|OneNote|デジタルノートアプリ|Microsoft|
|OnePlus|スマートフォンメーカー|OnePlus|
|ONEXFLY|ゲーミングPC|One-Netbook Technology|
|ONE XPLAYER|ゲーミングPC|One-Netbook Technology|

思い浮かび次第順次追加していきます。
sympyの素因数分解を本家StackOverflowで教えてもらった。


(参考)Unsupported operand type(s) for +: 'Symbol' and 'str' when forming a string with the factors of a number

https://stackoverflow.com/questions/52447310/unsupported-operand-types-for-symbol-and-str-when-forming-a-string-with/52448088#52448088

~~(参考)素因数分解　個人用メモ
https://qiita.com/y_s678/items/0de4fe81be0c192db29e~~

(参考)SymPyで素因数分解

http://boxheadroom.com/2010/02/22/py_primenumber
バッチファイルを経由すればPowerShellファイルの実行権限を変えずに指定権限で実行できた

# 方法

``` bat:sample.bat
powershell -ExecutionPolicy RemoteSigned -File ./sample.ps1
```

![2018-09-25_21h52_35.png](https://qiita-image-store.s3.amazonaws.com/0/216527/511a5187-2ef4-5a99-966a-b24ec153cd99.png)


# 利用シーン
- 権限設定(`Set-ExecutionPolicy`)せずにPowerShellファイルを実行したい
    - PowerShellって何？って人に「とりあえずこのバッチたたけばOK」とする
    - お客様環境等でPCの権限関係を変更をしたくない
Linuxでネットワークインタフェースの活動状況を調べる by Rust

以前、[Linuxでネットワークインタフェースの活動状況を調べる by Golang](https://qiita.com/tetsu_koba/items/490e8b33ebd129c5acfd) という記事を書いたのですが、最近Rustを勉強し始めたので、同様のものをRustで書いてみました。

# やっていること
`/sys/class/net/<network_if>/statistics/` から受信、送信の累計のバイト数がわかるので、周期的にそれを表示しています。

ソースをここに貼ります。

```rust:main.rs
use std::env;
use std::fs;
extern crate chrono;
extern crate schedule_recv;
use schedule_recv::periodic_ms;

fn read_transfer_bytes(f: &str) -> u64 {
    match fs::read_to_string(f) {
        Ok(s) => s.trim().parse().unwrap_or(0),
        Err(err) => {
            panic!("Failed to read:{} Err={:?}", f, err);
        }
    }
}

fn net_activity(ifname: &str) {
    let interval = 2000;
    let txf = &format!("/sys/class/net/{}/statistics/tx_bytes", ifname);
    let rxf = &format!("/sys/class/net/{}/statistics/rx_bytes", ifname);
    let tick = periodic_ms(interval);
    let mut tx_prev = read_transfer_bytes(txf);
    let mut rx_prev = read_transfer_bytes(rxf);
    let td = interval as f64 * 1e-3;
    loop {
        tick.recv().unwrap();
        let tx = read_transfer_bytes(txf);
        let rx = read_transfer_bytes(rxf);
        println!(
            "t={}, tx={}, rx={}, tx/s={:.1} KB/s, rx/s={:.1} KB/s",
            chrono::Utc::now().timestamp(),
            tx,
            rx,
            ((tx - tx_prev) as f64) / td / 1024f64,
            ((rx - rx_prev) as f64) / td / 1024f64
        );
        tx_prev = tx;
        rx_prev = rx;
    }
}

fn main() {
    let args: Vec<String> = env::args().collect();
    if args.len() < 2 {
        eprintln!("Usage: {} ifname", args[0]);
        eprintln!("  For example, {} eth0", args[0]);
        eprintln!("  You can find ifname by `ls /sys/class/net`");
        return;
    }
    net_activity(&args[1]);
}
```

Cargo.toml に追加したのは以下の通り。

```
[dependencies]
schedule_recv = "0.1"
chrono = "0.4"
```

# 実行例

```
$ ls /sys/class/net/
enp0s31f6  enx00051bd1473c  lo  wlp4s0

$ cargo run enp0s31f6
    Finished dev [unoptimized + debuginfo] target(s) in 0.01s                   
     Running `target/debug/net_activity enp0s31f6`
t=1537868984, tx=405623729, rx=98837205807, tx/s=0.0 KB/s, rx/s=0.1 KB/s
t=1537868986, tx=405623729, rx=98837206182, tx/s=0.0 KB/s, rx/s=0.2 KB/s
t=1537868988, tx=405623930, rx=98837208653, tx/s=0.1 KB/s, rx/s=1.2 KB/s
t=1537868990, tx=405624302, rx=98837209502, tx/s=0.2 KB/s, rx/s=0.4 KB/s
^C
```

# メモ

ファイルを一括で読んでStringにするのに、[std::fs::read_to_string()](https://doc.rust-lang.org/std/fs/fn.read_to_string.html)　というちょうどいいものがあったので、それを使った。

周期的に実行するには、[schedule_recv](https://crates.io/crates/schedule_recv)というクレートを使用した。Sleepで待つと少しずつ遅れてしまうので。

タイムスタンプには、[chrono](https://crates.io/crates/chrono)というクレートを使用した。[std::time::SystemTime](https://doc.rust-lang.org/std/time/struct.SystemTime.html) より機能が豊富。
Julia 入門以前 インストール編

## はじめに
前回はとりあえず、Jupyter notebookを立ち上げるところまで行きました。
[Julia 入門①](https://qiita.com/torininaritahi/items/6a3a431e1341e9057877)

しかし、今回入門②に進む前に別のPCにJuliaをインストールので、その手順の忘備録
になります。

## 対象
最新版(2018年９月25現在)
**Julia 1.0**


## インストール

いざインストールといっても、何も別に難しいことはなく、
[公式のダウンロードページ](https://julialang.org/downloads/)
から、自分の使っているPCにあったものをダウンロードしてインストールするだけです。

![スクリーンショット 2018-09-25 21.37.16.png](https://qiita-image-store.s3.amazonaws.com/0/275031/b312de64-d245-d211-cffc-30649afed00c.png)

私は、macなので、
**>macOS Package**
を選択してダウンロードします。

あとは、dmgファイルを開いてインストールをして、Applicationフォルダにjuliaを移して、インストールは終了です。

## パスを通す
上までの作業が終了した時点では、ターミナルから

```
>julia
```
と打っても反応してくれません。それもそのはず、パスが通っていないからです。

パスの通し方はJuliaの公式の[GitHub](https://github.com/JuliaLang/julia)のdocumentに掲載されています。(もちろん英語ですが)

一応私は、ApplicationsフォルダにJuliaをインストールしていたので、そこまでのパスを調べ、

```
hogepiyo$ pwd
/Applications/Julia-1.0.app/Contents/Resources/julia/bin
```

パスを通しました。(下記)

```
echo "alias julia='/Applications/Julia-1.0.app/Contents/Resources/julia/bin/julia'" >> ~/.bashrc && source ~/.bashrc
```

以上で、ターミナルを立ち上げて

```
julia
```
と打てば、下記の画面が出てjuliaが使えるようになります。

```
hogepiyo$ julia
               _
   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.0.0 (2018-08-08)
 _/ |\__'_|_|_|\__'_|  |  Official https://julialang.org/ release
|__/                   |

julia> 
```

## 終わりに
なぜか、Python3をインストールするのにものすごく苦戦した思い出があったので、今回個人的にはPython3をインストールした時より、苦労しなかったです。こういった風に簡単に動かせたりすると、嬉しいですね。
at coder beginner 049

B
縦 H ピクセル、横 W ピクセルの画像があります。全てのピクセルは . または * で表されるものとします。上から i 番目、左から j 番目のピクセルを表す文字を Ci,j で表します。
この画像を 2 倍縦長にした画像を出力してください。すなわち、縦 2H ピクセル、横 W ピクセルの画像であって、上から i 番目、左から j 番目のピクセルは、C(i+1)⁄2,j (ただし、割り算は切り捨て)と等しい画像を出力してください。

```
#include<iostream>
using namespace std;
int main() {
	int H, W;
	char C[110][110];
	cin >> H >> W;
	for (int i = 1; i <= H; ++i) {
		for (int j = 1; j <= W; ++j) {
			cin >> C[i][j];
		}
	}

	for (int i = 1; i <= H; ++i) {
		for (int j = 1; j <= W; ++j) {
			cout << C[i][j];
		}
		cout << endl;
		for (int j = 1; j <= W; ++j) {
			cout << C[i][j];
		}
		cout << endl;
	}
	return 0;
}
```
久しぶりに一発で通せた

C
英小文字からなる文字列 S が与えられます。 Tが空文字列である状態から始め、以下の操作を好きな回数繰り返すことで S=T とすることができるか判定してください。
T の末尾に dream dreamer erase eraser のいずれかを追加する。
制約
1≦|S|≦105
S は英小文字からなる。
既視感

```
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
int main() {
	string S;
	string set[4] = { "dream","dreamer","erase","eraser" };
	for (int i = 0; i < 4; ++i) {
		reverse(set[i].begin(), set[i].end());
	}
	cin >> S;
	reverse(S.begin(), S.end());
	bool ans1 = true;
	for (int i = 0; i < S.size();) {
		bool ans = false;
		for (int j=0; j < 4; ++j) {
			if (S.substr(i, set[j].size()) == set[j]) {
				i += set[j].size();
			    ans = true;
			}
		}
		if (!ans) {
			ans1 = false;
			break;
		}
	}
	if (!ans1)
		cout << "NO" << endl;
	else
		cout << "YES" << endl;
	return 0;
}
```
Kuinのファイル単位のスコープを拡張しよう

# Kuinのファイル単位のスコープを拡張しよう
Kuinにおいて、プログラムを別のソースファイルに分割した場合、他のファイルからは別のスコープとして認識されます。
別のソースファイルに定義された識別子を参照するには`\ソース名@識別子`の形式でアクセスします。
ただし、スコープが分かれるので参照できるのはグローバルな識別子だけになっています。

```Kuin:other.kn
func localFunc()
end func

+func globalFunc()
end func
```

```Kuin:main.kn
func main()
	do \other@localFunc() ... Error
	do \other@globalFunc()
end func
```

---

では、複数のクラスからなるモジュールを作成する場合はどうなるでしょうか？
条件として、各クラスはモジュール名で参照するものとします。
例）`\module@ClassA`や`\module@ClassB`など

```Kuin:module.kn
+class ClassA()
end class

+class ClassB()
end class
```

```Kuin:main.kn
var classA: \module@ClassA
var classB: \module@ClassB
```

このように、同じ名前で参照するには、１つのソースファイルの中にすべての機能を詰め込むようになります。
しかしこれでは、機能が膨らむほどにソースコードが膨大になり、メンテナンス性が良いとは言えません。


## include文
include文は、特定の名前で命名したサブソースのファイルを、自分のスコープに連結することができます。
例えば、先程の`module.kn`を分割したい場合は、
`module.class_a.kn`
`module.class_b.kn`
という２つのサブソースを作成し、`module.kn`からinclude文で連結します。

- サブソースの命名規則 `module名`.`サブソース名.kn`
- include文の文法 `include サブソース名`

```Kuin:module.class_a.kn
+class ClassA()
end class
```

```Kuin:module.class_b.kn
+class ClassB()
end class
```

```Kuin:module.kn
include class_a
include class_b
```

これで、別々のサブソースファイルに定義したクラスを、`module`の名前で参照できるようになりました。


## まとめ
１ファイル１クラスが正義ではありませんが、メンテナンス性やコーディング中のスクロール最小化を考えると、１つのソースファイルが膨大になる事を避けたいときがあります。
そのような時にinclude文を使うと、ストレスなく機能を実装することができるようになると思います。

また、ソースファイルを素材として１つのファイルで配布したい！って場合にも、参照方法を変更することなく集合させることができるので、作業性と配布のしやすさを両立させることもできます。


## 補足
Githubのissueより、くいなちゃんのコメントを引用します。
>Kuinの各ソースファイルは、「モジュール」という
インスタンスがただ1つ存在するクラスのようなもの(≒シングルトン) になっています。

>モジュールは、クラスのメソッドやプロパティのように、(グローバル)関数や変数を持ち、
外部に公開する部分だけを「+」でパブリックにします。

>モジュールから他のモジュールを参照するときは、クラスとは違い、インスタンスがただ1つ必ず存在することを知っているため、
クラスよりは密接に、直接モジュール間でやりとり(関数呼び出し等)ができます。

>Kuinではこのように、モジュール単位でプログラムを設計し、
インスタンスが複数になるものや、より疎結合にしたいものだけをクラスで実現するように想定しています。

クラスとモジュールの設計思想を理解し、きれいに使い分けるのが理想ですね。
npm ライブラリの date-fns で文字列 '2018-09-01 00:00:00' と '2018-09-18 00:00:00' が何日離れているか計算する

よくあるタイプの文字列で日時を受け取る API の場合、ここから何日離れているか、等を計算するには **fate-fns** が便利だ。

まず parse で文字列を parse して、JS の Date オブジェクトに変換する。
Date オブジェクトにしてしまえば、あとは比較系のメソッドで簡単に比較できる。

```js
import parse from 'date-fns/parse'
import differenceInDays from 'date-fns/difference_in_days'
import differenceInCalendarDays from 'date-fns/difference_in_calendar_days'

const startTime = '2018-09-01 00:00:10'
const endTime = '2018-09-02 00:00:00'

const difference = differenceInDays(parse(endTime), parse(startTime))
console.log(difference)

const differenceInC = differenceInCalendarDays(parse(endTime), parse(startTime))
console.log(differenceInC)
```

ちなみに、calendar days バージョンとの違いは、calendar days バージョンの方は、ぴったり24時間は慣れてなくても、日付が違えば１日にカウントしてくれる。そうじゃないバージョンの方は、ぴったり 24 時間は慣れていないと、1日とカウントしない。普通は in calendar の方でいいはず。
【3分でできる】ライブラリなしでファイルをドラッグ&ドロップでアップロード


# ライブラリなしでファイルをドラッグ&ドロップでアップロード


**ライブラリなし**でdropZoneを使ったファイルアップロードの記事が少なかったので書きました
### 注意
ライブラリなしと言ってますがajax通信に**jQuery**を使ってます
jQueryを使わない場合は[こちら](https://www.sejuku.net/blog/53627)を参考にしつつ生jsで置き換えてください

ライブラリを使える人は[この記事](https://qiita.com/saekis/items/207379a056af73f143b7)の実装を参考にdropzone.jsというライブラリを使うといいかと思います


## ドロップゾーンの実装
複数ファイルアップロードする場合は`enctype=multipart/form-data`を入れてください
### htmlの記述
``` html
    <div id="drop_zone">Drop a file here</div>
    <output id="list"></output>
    <form id="my_form" enctype=multipart/form-data>
        <input type="file" style="display:inline" name="upload_file">
        <br>
        <button type="button" onclick="file_upload()">アップロード</button>
    </form>
```
### 見た目
自分のサイトに合わせて調整してみてください

``` css
#drop_zone{
    width: 80%;
    height: 200px;
    border: 1px dotted black;
    border-radius: 1rem;
    margin: auto;
    margin-top: 2rem;
    font-size: 3rem;
}
```

### dropzoneの処理
[HTML5 rocksの記事](https://www.html5rocks.com/ja/tutorials/file/dndfiles/)を元に実装してます
詳しい解説は上の記事がわかりやすいです

``` js
//drop zoneの実装
function handleFileSelect(evt) {
  evt.stopPropagation();
  evt.preventDefault();

  files = evt.dataTransfer.files; // FileList object.

  // 以下に必要なFile Objectのプロパティを記述
  var output = [];
  for (var i = 0, f; f = files[i]; i++) {
    output.push('<li><strong>', escape(f.name), '</strong> (', f.type || 'n/a', ') - ',
                f.size, ' bytes, last modified: ',
                f.lastModifiedDate.toLocaleDateString(), '</li>');
  }
  document.getElementById('list').innerHTML = '<ul>' + output.join('') + '</ul>';
}

function handleDragOver(evt) {
  evt.stopPropagation();
  evt.preventDefault();
  evt.dataTransfer.dropEffect = 'copy'; 
}

// イベントリスナーを設定
var dropZone = document.getElementById('drop_zone');
dropZone.addEventListener('dragover', handleDragOver, false);
dropZone.addEventListener('drop', handleFileSelect, false);
```

### ajax通信
**request**の中身は```{upload_file:(ファイルデータ）}```のようなjson形式で表されます
サーバーサイド側でjson形式のデータのように扱えます

``` js
function file_upload()
{
    // フォームデータを取得
    let formdata = () => new FormData($('#my_form').get(0));
    // ファイルが未登録なら一番最初のファイルを追加
    // 複数ファイルアップロードの場合ここを修正
    if($('input[name="upload_file"]').val() == ""){
      formdata.append('upload_file',files[0])
    }

    //非同期通信
    $.ajax({
        url  : "/upload",
        type : "POST",
        data : formdata,
        cache       : false,
        contentType : false,
        processData : false,
        dataType: 'html',

    })
    .done(function(data, textStatus, jqXHR){
        console.log(data);
    })
    .fail(function(jqXHR, textStatus, errorThrown){
        console.log("fail");
    })
    .always(function(data){
        console.log("complete")
    });
}
```


**flask**の場合は以下の記述で取り出せます

``` python
file = request.files['upload_file']
```

---

- 他にもユーザー名等のパラメータがあった場合html上に**input要素**を適宜追加してみてください


- ちなみに複数ファイルの場合は
`{{upload_file1:(ファイル1), upload_file2:(ファイル2)}`
のような中身になります



## 参考
https://www.html5rocks.com/ja/tutorials/file/dndfiles/
MUNGEのPermissionを程良く設定する

# MUNGEとは

ジョブスケジューラSLURMのデフォルトの認証システムです。SLURMを起動するにはあらかじめMUNGEをインストールして鍵を配布しておく必要があります。
SLURMやMUNGEのインストールそのものについてはこのページでは触れないので、最後に記している参考リンク等を参照にして下さい。

# 何が起こったか
一度SLURMをインストールした後、最初は問題なく動作していたのだが、ある日急に使用できなくなった。
色々調べたところ、MUNGEが停止していたので、再起動を試みたところ、以下のエラーを吐かれた。

```
Starting MUNGE: mungemunged: Error: Failed to open logfile "/var/log/munge/munged.log": Permission denied
```

sudoで実行したりchmodでPermissionを広くしたりして、一般的に問題ない権限で実行しても同様のエラーが吐かれてしまう。SELinuxも悪さをしていない。

# 解決策
同様の手順でインストールしていて問題なく起動しているMUNGEの環境があったので、それとPermission等を合わせてみたら動いた。その時のPermissionは以下の通り。

```
[root@hogehoge ~]# ls -l /var/log/ | grep munge
drwx------  2 munge munge        4096 Sep 25 19:20 munge
[root@hogehoge ~]# ls -l /var/log/munge/
total 20
-rw-r----- 1 munge munge 17910 Sep 25 20:45 munged.log
```

ファイルの所有者とグループは全てmungeにして、ディレクトリのPermissionは700,logのPermissionは640に設定すれば問題なくMUNGEを起動できました。
MUNGEのファイルのPermissionは広すぎても狭すぎてもダメらしいということは噂に聞いてましたが、確かに細かいですね。Permission errorが出るからといって思考停止777はやったらダメみたいです。ごめんなさい。
同様のエラーでお困りの方がいれば試してみてください。

そもそもなぜ急にMUNGEが停止したかはわかっていないので判明したら追記します。

# 関連リンク

MUNGE/SLURMのインストールそのものに関しては下の記事が非常に参考になります。

・[SLURMのインストール](http://www-fps.nifs.ac.jp/ito/memo/slurm01.html)
・[Slurm Workload ManagerをUbuntu 16.04LTS に導入する](https://qiita.com/JeJeNeNo/items/c545e72373d4d1deb36a)
`brew cask install font-myrica`で発生するエラーを回避する方法

# 回避方法

`brew cask edit font-myrica`を実行し，以下のように書き換えてください[^1]．

* sha256
    * `a90eb9b79885f02ad9e0e752a0b979b699847be7de13dc3b6113658f006d12bd` （バージョンが2.006.20150301以外の場合は`shasum`で再計算してください）
* url
    * `https://codeload.github.com/tomokuni/Myrica/tar.gz/#{version}`

その後，`brew cask install font-myrica`を実行．

# 原因

ZIPファイルをダウンロードして展開を試みるのですが，ファイル名に日本語が入っていて`unzip`に失敗します．そのため，tar.gzファイルをダウンロードすることで問題を回避可能です[^2]．

Googleで検索すると見つかりますが，`unzip`は８ビット目が１の場合の扱いに問題があるようです．

[^1]: そのうちPRを送るかもしれません
[^2]: macOSの言語設定などによっては，書き換えなくてもインストールに成功するかもしれません
PythonでやるML

# Cycle List (link)
* [PythonでやるML Cycle1: Pythonに慣れる](https://qiita.com/kenji-kondo/private/44cf2f764c8facb9ae3b)
* [PythonでやるML Cycle2: 多項式回帰で未来を予測する](https://qiita.com/kenji-kondo/private/efea213df25823173fb8)
* [PythonでやるML Cycle3: 線形識別関数で自動分類機を作る](https://qiita.com/kenji-kondo/private/cb69541c12019c85ac51)
* [PythonでやるML Cycle4: k-means法でAIを作る](https://qiita.com/kenji-kondo/private/bdee506b6624ae30d2e5)
* [PythonでやるML Cycle5: SVM(1)-制約なし最適化問題とその解き方](https://qiita.com/kenji-kondo/items/77749b462d033e1a3189)
* [PythonでやるML Cycle6: SVM(2)-制約あり最適化問題とその解き方](https://qiita.com/kenji-kondo/private/02abb1c02aec97ad9a6f)
* [PythonでやるML Cycle7: SVM(3)-SVMで分類する]()
UnityでOpen VRを叩くときの勘所(Steam VR Plugin for Unity)

#はじめに
Unityで、例えばVRアプリケーションではないものからOverlayを使いたいときや、コントローラーの詳細情報が欲しいときなどは、Open VRの機能に直接アクセスしたほうが早いことがあります。
私もそうして知見が溜まってきたので、メモを残しておきます。


#メモ
##公式のWikiはアテになったりならなかったりする
とりあえず困ったら、まずはAPI Documentationを見ましょう。
https://github.com/ValveSoftware/openvr/wiki/API-Documentation

しかしながら、情報が不足していたり古かったりします。
openvr_api.csや、Steam VR Pluginのソースの中にヒントや答えがあることがあります。
新機能がしれっと増えていたりします。

他に当てになる情報は、正直ないです。
他の人の作ったサンプルソースを探してさまよう事が多いです。

##だいたい必要な定数は
OpenVR.k_～で定義されている

HMDのindexとか
k_unTrackedDeviceIndex_Hmd = 0;
デバイスの最大接続数とか
k_unMaxTrackedDeviceCount = 64;

##シングルトンなんだよなぁ
OpenVR.System
OpenVR.Overlay
などのクラスは、内部でシングルトンになっているので、引っ張り回す必要なく軽率に使える。

逆にこれらはstaticに確保されているようで、アプリケーションを終了する(UnityEditorで動作させている場合はUnityEditorを終了する)まで、変な挙動をし続けることがある。

なお、OpenVR.Systemがnullを返してくる場合は、OpenVRが適切に初期化されていない証拠となる。

##HMD持ってるユーザーか調べたい
IsHmdPresentを使うと、高速に判定できる。
ただしTrueだからといって本当に使える環境とは限らない

##初期化の必要性
OpenVR.Initは、すでに同じアプリケーション内にVRを動作させているやつがいる場合はやってはいけない。
一方、誰も居ない場合、明示的に呼び出してやらないと恐ろしく不安定な動作になる。
基本的にこれを手動で呼び出す場合は、ApplicationTypeはOverlayだろう。

ここで帰ってくるCVRSystemは、OpenVR.Systemで取得できるものと同じものだが、nullが帰ってくる場合は異常。

##明示的なshutdownは不要
基本的に不安定になるので不要。
きっちりオブジェクトが開放されていればそれで問題ないはず。
anlogic eg4s20 fpga/第一の挑戦

# 0. 前書き
2018.09.25
Anlogic EG4S20BG256 を入手したので、情報収集のため、晒してみます、
# 1.EG4S20BG256
EG4S20BG256はAltera/Intelでの EP4CE22シリーズに近いのかな。
2M*32bit SDRAMが同梱されている
12bit ADC(1Msps) もありとお得感があります。
alie??re??などで、$33程度で販売されています。
{FT2232 JTAG Debugger 付きのものがいいのかな？}
今回入手したものには、FT2232 JTAG debugger はなし、さらにPIN headerがx2 のはずが、 x1 しか付属してない、china quality.

![1.gif](https://qiita-image-store.s3.amazonaws.com/0/295124/01687938-27e0-afe9-860a-69d8843b2170.gif)

# 2.PIN LAYOUT
ところで、回路図が http://tang.lichee.pro/ でダウンロードできますが、古いようです。今回確認したのは 20180-08-08版で、ボード上のピン配置は下記のようになります。
かなりきわどい配置になっていますね。丸型スルホールを色付きで、半目ずれた
半円のスルホールを無地で示しています。

![2.gif](https://qiita-image-store.s3.amazonaws.com/0/295124/1d993515-d2eb-dc1c-dbb6-4c015dfc0025.gif)


# 3.IDE TD(Tang Dynasty)
EG4S20用のIDE は TD で、Altera/Intelでの QuartusIIみたいなものです。
だがしかし、これが baidu でしか配布していないので、厄介です。
 http://tang.lichee.pro/　
から baidu に行って、 baidu netdrive をインストールして、.... {baidu の netdrive からダウンロードは検索してください。
携帯の電話番号が必要になります。SMSでコードを知らせてくるので、60秒以内にコードを返すなど、スパイもどきの操作が必要になります。}
IDEを含めたダウンロードサイズは2Gbyte以上になります。
# 4.IDE インストール
まづは、TD をインストールします。(64bit版しかない）
![4.gif](https://qiita-image-store.s3.amazonaws.com/0/295124/7a2f5719-8e1d-a6f7-9e87-7e71fc104d6f.gif)

次に、USBケーブルで Tang FPGAをPCに接続し、driverを確認します。

![3.gif](https://qiita-image-store.s3.amazonaws.com/0/295124/ba2af8a4-bee4-0ba9-7fd3-3e6d0b0f3c17.gif)

USB JTAG-Cable とでたら、driverの更新を選択し、anlogic下のdriverをインストールします。
![5.gif](https://qiita-image-store.s3.amazonaws.com/0/295124/90e2d6c5-0568-0d21-6b5a-1d8bdf5b4141.gif)

UB ケーブルを抜き刺しして、Anlogic USB Cable とでたら、OKです。
![6.gif](https://qiita-image-store.s3.amazonaws.com/0/295124/6bb495e5-a9d4-0c13-f077-cc0532cc2313.gif)

# 4.LED
試しに、LED を点滅するbit stream を書き込んでみましょう。
TD のMenu から Tools->Download を選択します。

![7.gif](https://qiita-image-store.s3.amazonaws.com/0/295124/c892317f-3cee-880f-2997-f6ea38f50df4.gif)
Download 画面の Add+ でbit stream を選択します。

![8.gif](https://qiita-image-store.s3.amazonaws.com/0/295124/bf2c5e18-f6ca-da20-e720-9ba8b5ac649d.gif)
![9.gif](https://qiita-image-store.s3.amazonaws.com/0/295124/9c5cc878-6d65-6634-4312-35d8f6cf12b3.gif)
あとは Run をクリックで FPGAに bit streamが書かれます。
なお、Mode 切り替えでJTAG、Program FLASHなど、書き込む場所も選択できます。
# 5. RISC-V
基板のうらには RISC-V とシルクがあるのですが、まだ到達できていません。
# 6. SDRAM
具体的に SDRAM の接続を調べたかったのだが、IP Generator で自動生成されたマクロで定義されていて云々、よくわからなかった。
Zabbix、条件に合うトリガーを一括取得

Zabbix UIではトリガーを細かな条件指定の上で検索がし辛く、トリガーの棚卸しを行う際手間がかかる。
そこでZabbixで使用しているMariaDBより条件指定したトリガーを一括取得する。


(例)トリガー名に「Zabbix」または「Disk」を含み、かつトリガーステータスが「有効」のものを検索

```sql

SELECT
  CASE 
    WHEN t.priority LIKE '0' THEN '未分類'
    WHEN t.priority LIKE '1' THEN '情報'
    WHEN t.priority LIKE '2' THEN '警告'
    WHEN t.priority LIKE '3' THEN '軽度の障害'
    WHEN t.priority LIKE '4' THEN '重度の障害'
    WHEN t.priority LIKE '5' THEN '致命的な障害'
  END "priority",
  h.host,
  t.description,
  t.expression,
  CASE
    WHEN t.status = '0' THEN '有効'
    WHEN t.status = '1' THEN '無効'
  END "status",
  t.error
FROM triggers t
  inner join functions f on t.triggerid = f.triggerid
  inner join items i on f.itemid = i.itemid
  inner join hosts h on i.hostid = h.hostid
WHERE
     t.description Like '%Zabbix%' 
  or t.description Like '%Disk%' 
  and t.status = '0'
ORDER BY t.priority;
ファイルの有無を確認しインストールされていない時はインストールするバッチファイル

##キッカケ
仕事柄、OSがクリーンインストールされているPCにツールをインストールする事が多く毎回同じ作業をするのも非効率なので、バッチを作って自動化して仕事をサボろ...楽にしてしまおうと思い作りました。
今回せっかく作ったので同じ事を考え探している方のためにコードを公開いたします。

##今回のバッチで要求される事
1. インストールの有無確認
↑レジストリ覗くのが確実ですが、32bitと64bitで場所が違うので今回はファイルを直接参照して確認します。
2. 再インストールするかキャンセルするかの確認
3. インストーラーの実行(スキップのパターンあり)
4. iniファイルのコピー

##今回使うコマンド
・echo : コマンド画面への文字出力
・title : コマンドプロンプトのウインドウタイトル
・set : 変数宣言
・if : 分岐
・goto : ラベル
・rem : コード内へのコメント
・cls : コマンドプロンプトの文字クリア
・xcopy : コピー(copyコマンドの上位互換の認識で大丈夫です)
・pause : 一時停止

##今回使う無くてもいいけどあると便利なオプション(個人の意見)
・@ : "@"を付けた行のコマンドを非表示にする
・> nul : コマンドの後ろに付ける事で"echo off"でも表示される文字を消せる

##バッチファイルを使う上でこれだけは覚えておけコマンド(あくまで個人の意見)
・@echo off : 頭に"@"を付けて"echo"コマンドを非表示にし"off"オプションで以後のコマンドを非表示にする
・pause : 一時停止は大事だよね！
・echo : "echo off"で非表示にしていてもこのコマンドを付けるとその行を表示できます(文字出力で大活躍します)

##コピーするファイルとバッチファイルの入っているフォルダ構成
hogesoft\
>Installer.bat
>deta\
>>hogesoft.exe
>>hogehoge.ini

##バッチのクセ
こちらの記事で詳しくまとめられております
参考にさせていただきました！
[バッチファイルでの試行錯誤を回避するためのメモ](https://qiita.com/yz2cm/items/8058d503a1b84688af09)
[.bat（バッチファイル）のifコマンド解説。](https://qiita.com/sawa_tsuka/items/8edf3d3d33a0ae86cb5c#2-if%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%81%AE%E6%A7%8B%E6%96%87--)

##自分が"IF"文でハマった事
```.bat(dos):Installer.bat
if exist "C:\\Program Files (x86)\hoge\hogehoge.exe" (
set /p stetas="インストール済みです。インストールしますか？(y/n)"
if /i %stetas% == y goto start
if /i %stetas% == n goto cancel
goto error
)
```

当初はこのコードを書いていたのですが`goto の使い方が誤っています。`
のエラーが出てしまったので最終的にこのコードにしました。
独り言)柔軟な思考って大事ですね...まさかこの解決に1週間かかるとは...

```.bat(dos):Installer.bat
if not exist "C:\\Program Files (x86)\hoge\hogehoge.exe" goto start
set /p stetas="インストール済みです。インストールしますか？(y/n)"
if /i %stetas% == y goto xstart
if /i %stetas% == n goto cancel
goto error
```

##コード本体
```.bat(dos):Installer.bat
@echo off
title ほげソフト Installer

rem インストール済みかの確認と続行確認
if not exist "C:\\Program Files (x86)\hoge\hogehoge.exe" goto start
set /p stetas="インストール済みです。インストールしますか？(y/n)"
if /i %stetas% == y goto start
if /i %stetas% == n goto cancel
goto error

rem インストールの実行
:start
cls
set /p stetas="ほげほげのインストールを開始してもよろしいですか？(y/n)"
if /i %stetas% == y goto install
if /i %stetas% == n goto cancel

rem インストーラーの実行
echo インストールを開始します...
"deta\hogesoft.exe"
rem 設定ファイルのコピー
xcopy /y "deta\hogehoge.ini" "C:\Program Files\hogesoft\"
cls
echo Complete!
goto end

:cancel
cls
echo インストールをキャンセルしました。
goto end

:error
cls
echo 入力された値が不正です
goto end

:end
echo 終了するには何かキーを押してください。
pause > nul
```

##最後に
仕事で使う関係上完全なコードを書けなかったのでかなりアレンジしてあり分かりづらい箇所があるかと思いますが、なにかの参考になれば幸いです。
また、あくまでCUIでの操作になるためGUIに慣れ浸しんだ方からするとだいぶとっつきにくいかと思います。
EC-CUBE3の注文完了メールに注文詳細URLを記載する

#注文完了メールに注文履歴URLを記載します。
たまに場所を忘れるのと、EC-CUBE3は使えないけど、メール内容だけ変えたい！
って人向けのメモ
※初心者向け記事です。

##環境
- EC-CUBE 3.016
- PHP 7.19


##EC-CUBE3のメール内容はどこで管理しているの？
メールに関するファイルは全て`src/Eccube/Resource/template/default/Mail/`内にあります。

※ここを直接触るのは非推奨となっているので、`app/template/default/`にコピーして触るようにしましょう。

##注文完了メールはどこ？
`src/Eccube/Resource/template/default/Mail/order.twig`です。
ここに注文完了メールの内容が記述されています。

##メール内容に注文詳細URLを載せます。
好きな位置に以下のコードを記述（URLは自分の環境に合わせてください）

```twig:app/template/default/Mail:order.twig
注文詳細URL：http://ここにURL/mypage/history/{{ Order.id }}
```
※必ず for文の外で記述するようにしてください。


##2019.1.29追記

```twig:app/template/default/Mail:order.twig
注文詳細URL：{{ url('mypage_history', {'id': Order.id}) }}
```

上記のようにした方が、依存がなくなり簡略化できないか？
とコメントをいただきました！
ありがとうございます。

```app/template/default/Mail:order.twig
{% if Order.Customer %}
{% for OrderDetail in Order.OrderDetails %}`
//何らかの処理
{% endfor %}
{% endif %}
```
↑こういうやつです。かならず`//何らかの処理`の場所には置かないようにしてください。
※`{% if Order.Customer %}`この部分は会員か非会員かを分岐するif文です。

###そうすればメールに注文詳細URLが載って、ユーザーが注文後に注文状況を把握できるようになります。

以上。
CocoaPodsでライブラリを管理しているプロジェクトを人からもらった時にやること

最近改修をするとき毎回つまづくのでJKのメモ程度に。
#なにするか
ターミナルで該当プロジェクトファイルまでcdして

```
pod update
```

を叩くだけ。

これだけなのに忘れるのでメモ。
この記事を書いたからきっと覚える。
SAMLについて、理解しやすいように例えてみる

# はじめに
SAMLって専門用語が多くてわかりにくくないですか？
仕事で初めて使う事になった時、非常に大変でした。
専門知識が無い方でもある程度、わかりやすいように表現してみようと思います。

# SAMLとは？
>[IT用語辞典](https://www.weblio.jp/content/SAML)
SAMLとは、ユーザー認証に用いる情報を複数の企業やインターネットサービスプロバイダ（ISP）間で安全に交換するための言語仕様のことである。

この時点で、すでに難しいですよね。
とりあえずは、**「インターネット上で利用される認証の仕組み」**と思ってください。

# SAMLってどんな仕組み？
どんな仕組みなんでしょうか？

身近なケースで例えてみます。
病院に行く場合を想像してみましょう。

身分を証明するためには、受付で「保険証」を出しますよね。

絵にしてみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/172015/63c4ebc6-8896-7993-c2f5-0c8347126f1f.png)

**ここでは、自分の身分を証明するために、
第三者機関の発行した「証明書」を利用しています。**

SAMLも基本的にはこれと同じような考え方だと思っています。
仕組みを理解するうえで、上図にすこし説明を加えます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/172015/58d8a1ca-0bfc-f898-2519-ccb3781473f0.png)

このやり取りの中の要素が見えてきたかと思います。

では、ここで、SAMLの仕組みをみてみましょう。

>[クラウド時代のシングルサインオン基礎講座](http://www.keyman.or.jp/at/30004616/)より抜粋
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172015/21e5688a-478f-8b2b-3fad-9a366a4133b7.png)


**この図、どこか似ていないでしょうか？**

概念としては、先程の例とほぼ同じだと思います。
整理すると以下です。

Identity Provider(IdP) = 保険団体 = 証明するヒト
ユーザー = 患者 = 証明されるヒト
Service Provider(SP) = 病院 = 証明を確認するヒト
アサーション = 保険証 = ヒトを証明するモノ

これを踏まえた上で図を見比べていただけると、理解が進むかと思います。

# アサーションって何？
上図（図4 SAMLによるSSOの概要）を見ていると、
アサーションってどんなものなんだろう？という疑問がわかないでしょうか？
私は最初パッとイメージができませんでした。

こちらも少し解説しておきたいと思います。

SAMLの仕組みの中では、HTTPリクエストにのせて
以下のような証明書（アサーション）が飛び交います。

>[サンプルSAMLアサーション](https://developer.salesforce.com/docs/atlas.ja-jp.sso.meta/sso/sso_saml_assertion_examples.htm)より抜粋
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172015/35f85cc4-5d8f-a467-3bdd-8b88d35ee466.png)

先程の例えを思い出してください。

「保険証」には何が記されているでしょうか？

以下のような情報が書かれているかと思います
・氏名
・保険証発行元
・被保険者の属性情報
　生年月日、性別など

SAMLアサーションも同じです。
・認証済みのユーザーID
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172015/70e1bbe4-9dbd-8135-1967-5061d1cf0d2e.png)

・認証元IdP
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172015/6661ba19-c0ab-3a4c-1bba-7ac781f2c3a6.png)

・属性情報
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172015/28298a3c-0657-b67e-7f85-0fa7270be5a2.png)

「保険証のような証明書がコード化(xml)されたものがアサーションなんだ。」
と理解するとわかりやすいのではないでしょうか？

# 最後に
「パッときいただけでは拒否反応を示してしまいそうなIT用語も、
現実の世界のなにかに置き換えることで、より身近で理解しやすくなる。」
と思ってこの記事を書きました。

アサーション = 我々が普段持っている証明書　というイメージがわけば、
SAMLに関する仕様がスッと頭に入ってくると思います。

読んでいただいたあなたの理解が、少しでもすすめば幸いです。


※私の理解が間違えていた場合、土下座案件です。
Katalonのテストを別ネットワークにあるAndroid実機を使って実行する

OpenSTFを使うと、接続しているAndroidの端末情報とか使用中かどうかとかがAPIから管理できて便利。
これを別のネットワークからも使いたい、というのが今回のニーズ。
例えば、

- AWS Device Farmと同じことを低コストで実現したい
- 東京の本社にはテスト用端末がたくさんあるけど、島根の開発拠点にはほとんどなくて不便

みたいなケースで有用なはず。

### やったこと

OpenSTFは同一のLAN内からの利用を想定しているので、別ネットワークから使いたい場合は一工夫いる。
VPNで繋ぐのは、CircleCIとかがVPN使えないので避けて、SSHポートフォワーディングを使った。

[メルカリの記事](https://tech.mercari.com/entry/2017/10/27/125637)の劣化版みたいな感じです。
違いとしては、

- 構成がメルカリのほど高度じゃない
- テストの実行にKatalonを使ってる

とか。

### 使い方

READMEに書いてあります。
https://github.com/spinylobster/openstf-katalon-test
日本語はこっち -> https://github.com/spinylobster/openstf-katalon-test/blob/master/README.ja.md

#### *注意事項*

原因は詳しく見れてないんだけど、OpenSTFが起動から数分で落ちてめちゃくちゃ不便。調査中にいつの間にか落ちるようになってて謎
OpenSTFが落ちた時は、

1. `docker-compose down` Katalon側を一度止める
2. `docker-compose up stf` でOpenSTFを再度立ち上げる
3. `http://127.0.0.1:7100` でアクセスできることを確認したら、再度Katalon側の `start.sh` を実行する

という手順でリカバリーしてください :bow:

その他の課題としては、

- 個別のテストケースのコードを直接変更している (最低限、Test Suitesのsetupに入れるべき)
- 複数端末・並列実行に対応していない
- CircleCIやBitriseから実行できるか試してない

など。

### 参考情報

- [OpenSTF](https://github.com/openstf/stf)
- [Android Device Farm at Mercari](https://tech.mercari.com/entry/2017/10/27/125637)
- [OpenSTF+Dockerで社内Android端末管理システムをMac上に構築する](https://qiita.com/KazaKago/items/26db0f68ba224eb094d3)
Selenium と google-chrome でページを取得して保存 (Golang)

```go:chrome_save.go
// ---------------------------------------------------------------
//
//	chrome_save.go
//
//					Sep/26/2018
// ---------------------------------------------------------------
package main

import (
	"github.com/sclevine/agouti"
	"fmt"
	"os"
	"log"
	"io/ioutil"
        "time"
)

// ---------------------------------------------------------------
func main() {
	fmt.Fprintf (os.Stderr,"*** 開始 ***\n")

	url := "https://ekzemplaro.org/storytelling"
	driver := agouti.ChromeDriver()

	err := driver.Start() 
	if err != nil {
		log.Printf("Failed to start driver: %v", err)
	}

	page, err := driver.NewPage(agouti.Browser("chrome"))
	if err != nil {
		log.Printf("Failed to open page: %v", err)
	}

	err = page.Navigate(url)
	if err != nil {
		log.Printf("Failed to navigate: %v", err)
	}

	fmt.Printf(page.Title())
	fmt.Printf("\n")
	fmt.Printf(page.URL())
	fmt.Printf("\n")

	page.Screenshot("tmp001.jpg")

        time.Sleep(100 * time.Millisecond)

	html, err := page.HTML()
	fmt.Printf (html)
	fmt.Printf("\n")

	out_filename := "tmp001.html"
	ioutil.WriteFile (out_filename,[]byte(html),0666)

        defer driver.Stop()

	fmt.Fprintf (os.Stderr,"*** 終了 ***\n")
}

// ---------------------------------------------------------------
```

```text:Makefile
chrome_save: chrome_save.go
	go build chrome_save.go
clean:
	rm -f chrome_save
```

コンパイル

```text
$ make
go build chrome_save.go
```

実行方法

```bash
export PATH=/opt/chromedriver:$PATH
./chrome_save
```
広告代理店でSREチームを立ち上げるためにやったこと

## 自己紹介
渋谷　充宏 @m4buya

* 株式会社オプト テクノロジー開発部 チームマネージャー
* Ruby / Scala / インフラ
* https://github.com/mshibuya
* RailsAdmin/CarrierWave committer
* ISUCON8本戦に「チーム人間性」で出場します!!

---
## アジェンダ
- プロダクトについて
- SREチームの立ち上げ前
- SREチーム立ち上げにあたってやったこと
- 結果どうなったか
- 今後どうなっていきたいか

---
# プロダクトについて
---
## 広告効果計測ツール「ADPLAN」
![ADPLAN screenshot](https://qiita-image-store.s3.amazonaws.com/0/27474/fd4dae20-dc5e-fde2-7709-b510f253758f.png)

---
## 広告効果計測ツール「ADPLAN」

- 2000年にサービス開始した、広告効果計測ツールの草分け的存在
- その後更新を重ね、最新のバージョンは7。2016年9月サービスイン
- ユーザがバナー広告やリスティング広告をクリックし、お客さんのサイトに遷移し、商品を購入して…といった一連の行動を集計し、広告ごとにどのくらい成果が上がっているのかを示せる

---
## プロダクトの特性
- 大きく計測・集計・画面の3部分に分かれる
- 計測部分は高信頼性が必要
    - 特に、応答が返せなくなるのはデッドリンクとなってしまい最悪
- 集計は毎時行っており、遅延するとCS低下

---
## アーキテクチャ
- AWS様サイトに掲載されているインタビュー記事（ `AWS オプト` で検索）
  - https://aws.amazon.com/jp/solutions/case-studies/opt/

---
# SREチームの立ち上げ前
---
## 体制
- 機能系開発チーム
    - ユーザが求めていたりビジネス価値に直結する機能の開発
- 非機能系開発チーム
    - パフォーマンス
    - 信頼性
    - セキュリティ
    - インフラの維持管理も

---
## SREチーム立ち上げ前の体制
- 開発当初よりInfrastructure as Codeなプラクティスは実践できていた
- 「システムに対し定常的なオペレーションが必要になるなら必ず自動化する。それゆえ運用タスクというのは発生しない」というポリシー

---
## 課題感
- 限られたメンバーしか緊急対応を担うことができない
    - あまり自信がないから手を出せない→いつも同じ人が対応するのでノウハウが広まらないの悪循環
- 「ベストエフォートでの障害対応」では責任感頼みとなり、持続可能でない
- 他の開発タスクが優先され、信頼性向上が進まない

---
## SREという考え方との出会い
- SRE本
- SRE Meetup Tokyo

運用タスクや障害は「運が悪ければ発生するもの」ではなく、「発生する前提で準備しておくべきもの」であるとの思いを強くした

---
# 立ち上げのためにやったこと

---
## やったこと：組織として
- 3名のメンバーからなる独立したSREチームとして組織した
- 交代で時間外も含めた緊急対応当番を回すようにした
    - 負担が増える分、評価に上乗せ
- 他チームとは独立したバックログを持ち、主体的に優先度を決められるようにした

---
## やったこと：組織として
- 名刺の肩書きに「SRE」と入れた

![image.png](https://qiita-image-store.s3.amazonaws.com/0/27474/e47fc84f-9def-4204-c1b4-d6dad2ce8607.png)

---
## SLO策定

ビジネスインパクトや直近の実績値も踏まえ、妥当かつ客観的に計測可能なことを意識して設定

```
直近の３ヶ月間における
- 計測リクエスト成功率99.95%以上
- 計測データ永続化率99.95%以上
- 集計定時完了率99%以上
    - うち、日中については定時完了率99.5%
- 日次集計・外部集計がすべてAM9:00までに完了
- 画面のリクエスト成功率99.9%以上
```

---
## サービスレベル可視化
![image.png](https://qiita-image-store.s3.amazonaws.com/0/27474/be0a6d03-14ac-e0f1-5e50-c57a92f0503f.png)

---
## やったこと
- SRE本輪読会
- 障害対応トレーニング
- 障害事例共有会

---
## やったこと：技術的に
信頼性関連の開発が大いに進展した

- デプロイシステムの微妙なところとか改善
- 監視周りの細かい調整
- セキュリティ(進行中)

---
## 結果どうなったか
- 3人のSREチーム内で緊急対応の当番を回せる体制を作れた
- 「オペレーションでカバーする」みたいなタスクが減り、より本質的な作業に使える時間が増えた
- 本番で緊急ではないちょっとした問題が起きている、みたいな時も機動的に対処がしやすくなった
- 「我々がシステムの信頼性を担っているんだ」というチーム感が生まれた（と思っている）

---
# 今後どうなっていきたいか
---
## エラーバジェットの運用
サービスレベルは可視化されたものの、そこに現れた達成状況を次のアクションに反映させる、という点はまだこれから

- 問題部分の改善タスクの優先度を上げる
- 問題のあったコンポーネントをあまり触らないようにする
    - 開発項目を先送りする。とはいえビジネス価値との兼ね合いも…

---
## プロダクトチームを超えた展開
現状はひとつのプロダクトチームの中で閉じた取り組みであり、組織を横断するような取り組みとはなっていない

- とはいえプロダクトごとに技術スタックもモニタリングもまちまちで、プロダクト横断でできる部分はそんな多くなさそうな…？

---
## ミッションの拡大
現状SREチームとして明確に責任を持っているのは「信頼性」のみ

- すなわち、一般にSREチームの守備範囲とされているパフォーマンスやコストなどについても信頼性に直結する部分しか見ていない

---
## まとめ
- 手探り感は大きいものの、一定の成果は出せているはず
- 同じように手探りで運用のあり方を模索している皆様と情報交換したい！
- オプトではSREを含め、エンジニア絶賛募集中です！！
検索条件のチェックボックスの選択肢にトランザクションデータにある項目だけを表示する

初心者です。ransackでの検索のチェックボックスの選択肢を天気情報のマスタテーブルのカラムとしていたんですが、「砂あらし」や「竜巻」などトランザクションデータにない項目も表示されてしまい、それで検索かけると検索結果になにも表示されないので、トランザクションデータにある項目だけチェックボックスに表示させたいと考えました。

調べたところ、joinsやincludesで２つのテーブルを結合するとできそうでした。
[ActiveRecordのjoinsとpreloadとincludesとeager_loadの違い](https://qiita.com/k0kubun/items/80c5a5494f53bb88dc58)

joinsで結合して、groupで集合化することでデータにある項目だけ表示することできました（includesではできず、joinsでできたんですが、理由はわかりません）。

**huntsテーブル（釣果を登録するテーブル）**
string :weather_main
・・・

**weathersテーブル（マスタ）**
string :weather_main（Clear、Cloud など）
string :weather_name（晴れ、くもり など）
・・・

**アソシエーション**

```hunt.rb
belongs_to :weather, foreign_key: 'weather_main', primary_key: 'weather_main'
```

```weather.rb
has_many :hunts, foreign_key: 'weather_main', primary_key: 'weather_main'
```


**コントローラー**

```hunts_controller.rb
def index
  # weathersテーブルをhuntsテーブルのweather_mainにあるものに絞り込んで検索の選択肢をviewに渡す
  @weather = Weather.joins(:hunts).group('weather_main')
end
```

**ビュー**

```hunts/index.html.erb
<%= search_form_for @search do |f| %>
  <%= f.collection_check_boxes :weather_main_in, @weather, :weather_main, :weather_name %>
```
catapult-service-bootstrap その４ チェーンの手動削除

# 概要

[catapult-service-bootstrap](https://github.com/tech-bureau/catapult-service-bootstrap)を使って[catapult48gh23s.xyz](http://catapult48gh23s.xyz:8000) というオレオレcatapultをやっています。

自腹なので、お金をかけてません。なのでスペックは低いです。

ちょっとAPIノードをフル同期しようとしたら、DB書き込みか何かが重すぎて、レスポンスタイムアウト連発する事態になりました。

サーバースペック上げるか、DBを別サーバーに移すかをするにもコストが要るので、今回はチェーンを削除することにしました。

いろいろ設定を書き換えてて、`generate-config`とか動きそうになかったので、`docker-compose start`でなんとかなるように、チェーンのデータだけを削除します。

# 作業

#### 停止

```bash
$ docker-compose stop peer-node-x
$ docker-compose stop api-node-x
$ docker-compose stop db
```

#### data/peer-node-x

```absh
$ cd data/peer-node-x
```

ファイルの状況

```bash
$ ls -l
合計 9040
drwxr-xr-x. 2 root root 1601536  8月 31 00:02 00000
drwxr-xr-x. 2 root root 1601536  9月  2 07:36 00001
drwxr-xr-x. 2 root root 1601536  9月 13 17:47 00002
drwxr-xr-x. 2 root root 1318912  9月 23 09:06 00003
drwxr-xr-x. 4 root root      60  8月 30 23:50 audit
-rw-------. 1 root root       8  9月 23 09:06 index.dat
drwxr-xr-x. 2 root root    4096  9月 23 11:47 logs
drwxr-xr-x. 2 root root     246  9月 23 11:47 state
```

`00000/00001.dat`と`00000/hashes.dat`以外をすべて消します。

```bash
$ sudo mv 00000/00001.dat .
$ sudo mv 00000/hashes.dat .
$ sudo rm -r 00000/ 00001/ 00002/ 00003/ audit/ index.dat state/
$ sudo mkdir 00000
$ sudo mv 00001.dat 00000/
$ sudo mv hashes.dat 00000/
```


#### data/api-node-x

同じく

```bash
$ cd data/api-node-x
$ ls -l
合計 7624
drwxr-xr-x. 2 root root 1601536  9月 22 23:35 00000
drwxr-xr-x. 2 root root 1601536  9月 22 23:53 00001
drwxr-xr-x. 2 root root 1601536  9月 23 00:08 00002
drwxr-xr-x. 2 root root  372736  9月 23 17:17 00003
drwxr-xr-x. 4 root root      60  9月 22 23:09 audit
-rw-------. 1 root root       8  9月 23 17:17 index.dat
drwxr-xr-x. 2 root root      99  9月 23 17:17 logs
drwxr-xr-x. 2 root root     246  9月 23 17:17 state

$ sudo mv 00000/00001.dat .
$ sudo mv 00000/hashes.dat .
$ sudo rm -r 00000/ 00001/ 00002/ 00003/ audit/ index.dat state/
$ sudo mkdir 00000
$ sudo mv 00001.dat 00000/
$ sudo mv hashes.dat 00000/
```

#### data/mongo

```bash
$ cd data
$ sudo rm -r mongo
```

#### 起動

```bash
$ docker-compose start db
$ docker-compose start init-db
$ docker-compose start peer-node-x
$ docker-compose start api-node-x
```


# 確認

とくにこれといった確認はない

# 所感

どうやるのかわからなかったときは、探り探りだったけど、こうやって書いてしまえばとてもシンプル。

全ノード消してしまわないと、復活してしまうので注意。

# 関連記事

catapult-service-bootstrapにpeer-nodeを追加する その１ サービス追加
https://qiita.com/planethouki/items/b80fe29157d80a63122c

catapult-service-bootstrapにpeer-nodeを追加する その２ サーバー編
https://qiita.com/planethouki/items/4c73a6b924b92529bd32

catapult-service-bootstrap その３ ホスト名とポート変更
https://qiita.com/planethouki/items/d365f2344c0f7a6c3523

catapult-service-bootstrap その４ チェーンの手動削除
https://qiita.com/planethouki/items/7ec5404701adeb96bb8e

catapult-service-bootstrap その５ catapult.tools.health/network
https://qiita.com/planethouki/items/5ed19ae8ceb67ad6fee0
at coder beginner 048

B
非負の整数 a, b (a≤b) と、正の整数 x が与えられます。 a 以上 b 以下の整数のうち、x で割り切れるものの個数を求めてください。

```
#include<iostream>
using namespace std;
int main() {
	long long a, b, x;
	cin >> a >> b >> x;
	long long count = 0;
	for (long long i = a; i <= b; ++i) {
		if (i%x == 0)
			count++;
	}
	cout << count << endl;
	return 0;
}
```
なんだこの簡単な問題はとか思ってたらTLEになった。

```
#include<iostream>
using namespace std;
int main() {
	long long a, b, x;
	cin >> a >> b >> x;
	if (a == 0) {
		cout <<( b / x)+1 << endl;
		return 0;
	}
	long long count = b / x - (a - 1) / x;
	cout << count << endl;
	return 0;
}
```
これで通った。ちょっとしたひっかけって感じ

C
N 個の箱が横一列に並んでいます。 最初、左から i 番目の箱には ai 個のキャンディが入っています。
すぬけ君は次の操作を好きな回数だけ行うことができます。
キャンディが 1 個以上入っている箱をひとつ選び、その箱のキャンディを 1 個食べる。
すぬけ君の目標は次の通りです。
どの隣り合う 2 つの箱を見ても、それらの箱に入っているキャンディの個数の総和が x 以下である。
目標を達成するために必要な操作回数の最小値を求めてください。
制約
2≤N≤105
0≤ai≤109
0≤x≤109

貪欲法

```
#include<iostream>
using namespace std;
int main() {
	long long N, x;
	cin >> N >> x;
	long long a[100001];
	for (long long i = 0; i < N; ++i) {
		cin >> a[i];
	}
	long long sum = 0;
	long long nextscore[100001];
	if (a[0] > x) {
		sum += a[0] - x;
		a[0] = x;
	}
	for (long long i = 0; i < N-1; ++i) {
		nextscore[i] = a[i] + a[i + 1];
		if (nextscore[i] > x) {
			sum += a[i] + a[i + 1] - x;
			a[i + 1] = x - a[i];
		}
	}
	cout << sum << endl;
	return 0;
}
```