OmniAICreator/Qiita-1.07M huggingface dataset:
BigQueryの標準SQL -with句って便利だね- 編

BigQueryを使うシステムの開発中、レガシーSQLでだらだらと1000行を超えるようなクエリを目の前にして絶望を感じることはありませんか？

レガシーSQLのFROM句の中にSELECT文によるクエリが50個くらいカンマ区切りで並んでいて、圧倒されることはありませんか？

ありますよね、きっと。

それ、標準SQLで解決できるかもしれません。（注：できないことも多々あります）

下のようなレガシーSQLがあるとしましょう。

```sql
SELECT
  *
FROM (
  SELECT
    *
  FROM (
  -- 任意のSELECT文	(a)
  )
  LEFT JOIN (
  -- 任意のSELECT文 (b)
  ) ON a.a = b.a
  LEFT JOIN (
  -- 任意のSELECT文 (c)
  ) ON a.pk = c.pk
  LEFT JOIN (
  -- 任意のSELECT文 (d)
  ) ON c.pk = d.pk
)
WHERE
  c.col3 = 'hoge'
```

これを標準SQLのWITH句を利用すると次のように書けます

```sql
WITH A AS (
-- 任意のSELECT文(a)
),  B AS (
-- 任意のSELECT文(b)
), C AS (
-- 任意のSELECT文(c)
), D AS (
-- 任意のSELECT文(d)
), E AS (
    SELECT * FROM A LEFT JOIN B ON A.a = B.a
)
SELECT
    *
 FROM
    C
LEFT JOIN D ON c.pk = d.pk
LEFT JOIN E ON c.pk = e.pk
WHERE
    C.col3 = 'hoge'
```

これだけでは何が便利かよくわからないと思います。

任意のSELECT文に対してA, B, C, D, Eなどと名前がつけられ、またそれをテーブルのように扱うことができます。

似たようなSQLが繰り返し出てきてわかりにくいときなど、このWITH句で名前をつけることによって繰り返しをテーブルのように扱い、SQLを簡潔に書くことができるようになります。

今回の例では「Cの結果とDの結果とEの結果を左外部結合したもののうちCの3列目が'hoge'であるものと抽出したい」という要件がレガシーSQLと比較して容易に読み取れるように・・・なってないなぁ、例が悪いなぁ・・。

実際の業務で扱うテーブルではそれぞれのSELECT文が複雑怪奇なので、レガシーSQLと比較すると明らかにWITH句を利用した標準SQLの方が読みやすいのですが、ちょっと適当な例が思い当たりませんでしたorz
DXRuby 1.4.6 をWindows10で使う時の注意点とインストール方法

（2021.1.17 追記；DXRuby 1.4.7 の記事を書きました。
　→・[DXRuby 1.4.7 でエラーになった時の対処法とインストール方法](https://qiita.com/noanoa07/items/7df5886c619781d8d2ee)）

（2021.1.18 修正；Devkit（MSYS2）は必要なかったので修正）

Windows向けのRuby用2Dゲームライブラリ「DXRuby」をWindows10で使う場合、いろいろとハマったので、注意点のメモです。

・[DXRuby HP](http://dxruby.osdn.jp)
・[DXRuby GitHub](https://github.com/mirichi/dxruby)

# 注意点
## ・ DXRubyは、Windowsでないと動かない
WindowsのDirectXを使うので、macOS、Linuxでは動きません。
Windows環境以外で、DXRubyとほぼ同じコードで動くようにするライブラリとしては、[DXOpal](https://yhara.github.io/dxopal/doc/ja/index.html)（ただし、完全互換ではない）などがあります。


## ・ DXRubyは、32bit版Rubyでないと動かない
64bitマシンのWindowsであっても、Rubyは32bit版にしないとDXRubyは動きません。
（※ 追記；DXRuby 1.4.6以下の場合）
Rubyのインストールには、[「RubyInstaller for Windows」](https://rubyinstaller.org)が便利ですが、その場合 32bit版Ruby（`"x86"`と書いてある版）を使います。Devkit（MSYS2）付きでなくても、DXRubyはかまいません。
DXRuby 1.6.4は、Ruby 2.3~2.6に対応しています。


## ・ Windows10では、d3dx9_40.dllを追加しないと動かない
DXRubyでは、Windowsの`DirectX 9`ライブラリを使っています。（なので、Windows以外では動かない。）
Window10から、`DirectX 9`が付属しなくなったので、自分で追加する必要があります。

参考）
→・[DXRuby 1.4.6 does't work on Ruby 2.4~2.6 on Windows 10 · Issue #1 · mirichi/dxruby](https://github.com/mirichi/dxruby/issues/1)

### ※ d3dx9_40.dllのインストール方法
1．`d3dx9_40.dll`は、公式のMicrosoftのサイトからダウンロードするのが安全。
`DirectX End-User Runtimes(June 2010)`をダウンロードします。

https://www.microsoft.com/en-us/download/details.aspx?id=8109

2．ダウンロードした`directx_Jun2010_redist.exe`をダブルクリック。
適当なフォルダを指定して、解凍します。

3．解凍先のフォルダに`DXSETUP.exe`があり、ダブルクリックするとDirectX をインストールできるので、手順としては完了。

それでもよいのだが、必要なのは`d3dx9_40.dll`だけなので、これのみを使う手順も以下に紹介しておきます。
a) 必要なのは`32bit版のd3dx9_40.dll`なので、`Nov2008_d3dx9_40_x86.cab`をダブルクリックします。

b) 中にある`d3dx9_40.dll`（まだこれを解凍しなければならない）をダブルクリックして、適当なフォルダを指定して解凍します。

c) 解凍先のフォルダの中に欲しい`d3dx9_40.dll`ができます。

d) インストールしてあるRubyのフォルダの中の、binフォルダ（C: > Ruby26 > bin など、各自の環境に依る）に`d3dx9_40.dll` をコピーします。
以上。

# DXRubyのインストール方法
DXRuby 1.4.6のインストールは、RubyGemsからできます。

```bash
> gem install dxruby
```


# DXRubyが動作するかの確認

```bash
> irb
irb(main):001:0> require 'dxruby'
=> true
irb(main):002:0> exit
```

`true`と表示されればOKです！
スクレイピングは違法？スクレイピング前に注意すべきこと

####Webスクレイピングは違法？
ほとんどの場合、[Webスクレイピング](https://jp.scrapestorm.com/)は違法ではありません。実際、私たちの生活の中でほぼ毎日スクレイピングアプリケーションを使用しています。例えば、Yahoo、Googleなど、Yahooで検索されたほぼすべての情報がク[ローラー](https://jp.scrapestorm.com/)によって収集されます。したがって、テクノロジーとして、Webスクレイピングは違法ではなく、ほとんどの場合、スクレイピングテクノロジーを安全に使用できます。
では、Webスクレイピングはどのような状況下でデータを収集した後に法律的なリスクを抱えますか？
####1.スクレイピングとサーバー負荷
Webサイトへの過度なアクセスを直接禁止する法律はありませんが、程度を超えてアクセスをしてしまうと、サーバに過度の負荷をかけることになり、場合によっては、自社のシステムだけでなく、アクセス先のシステムにも何らかの支障が生じるおそれがあります。
この場合、有名なLibrahack事件のように[スクレイピング](https://jp.scrapestorm.com/)をした者は理論的には「偽計業務妨害罪」として逮捕される可能性があります。
![Librahack事件.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482909/04313bbf-1e43-e011-2930-c8dee3d822b6.jpeg)
####2.利用規約
スクレイピングのサイトに、スクレイピング収集または商用化のための転載を禁止する利用規約がある場合、規約を違反すると、その場合、事業者から損害賠償請求や差止を請求される可能性があります。
![Amazon.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482909/bb6ed185-6edf-059b-6c61-3b4ef32294c0.png)
####3.robots.txt プロトコル
Robots Exclusion Standard(RES) または Robots Exclusion Protocol は、クローラやボットがウェブサイト全体またはその一部を走査することを防ぐ規約です。ロボット排除規約、robots.txt プロトコルとも呼ばれます。
Webサイトはrobots.txt プロトコルを通じて、ページ内の情報スクレイピングを許可するかどうかを伝えます。ブラウザに「http://目標サイトのURL/robots.txt」を入力して、robots.txt プロトコルが表示されます。
![robots.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482909/abeb042a-902c-860b-01d4-4bd7af9d6e8f.png)
最後、99%のスクレイピングは法律違反ではありませんが、念の為、Webサイトの利用規約などをちゃんと調べてください。
UX JAM '04に行ってきた話

去る12/11に「UX JAM '04」なるイベントに行ってきました。
そのレポートを書きます。
![99c2d1022aaa5cec91069354c9cb9e4a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154934/27e32588-68e7-62c1-10db-c42aecb6a22c.png)

##UXJAMとは
>UX MILK主催の、UXデザインを題材にした「ゆるい」ミートアップイベントです。現場の人たちの対話の中から学びを得れるように、交流しやすい場を目指して運営している勉強会です。

>LTと交流会を交互に行っていくスタイルのイベントで、初学者や若手も積極的に登壇できるくらいのハードルで運営しています。常に新しい人が出入りする場を目指しているので新参の方はむしろウェルカムです。ぜひお気軽に飲み語りに来てください。

※以上下記より抜粋
[UX JAM '04（conpassの予約ページ）](https://uxmilk.connpass.com/event/157573/)

##LTとは
>Lightning Talks（ライトニングトーク）の略です。"Lightning"は英語で"稲妻"という意味。つまり、稲妻のように短い時間でプレゼンテーションを行う、というイメージです。
>勉強会やイベント、カンファレンスなどで行われる5分程度の短いプレゼンテーションなんかは、LTです。

>LTには基本的にルールはなく、どんなテーマでも、どんな風に発表してもOKです。ただし制限時間は設けられていて、時間をすぎると強制的に終了、次の発表者に交代！という流れがあります。

今回は１人5分でした。どの参加者の方もスライド等工夫されていて、濃い5分間の連続でした。
よくある講演会やトークセッションなどと比べ間延びすることもなく、刺激的で楽しかったです。

ちなみに主催の「UX MILK」とは下記のようなメディアです。
[UX MILKについて](https://uxmilk.jp/about)

##感想
何か勉強になればいいなぁ、程度の軽い気持ちでポチッと予約したのですが、参加してみると「意外と交流の割合が大きい」ことに驚きました。
各LTの合間のフリートークタイムがLTより長く取られており、あまり「交流するぞ！」というテンションで臨んでいなかった自分は少し戸惑いました…。みんなめっちゃ話すやん…。

しかし、おかげで下記のような普段接することのない方々と話すことができまして、なかなか勉強になりました。
・普段クライアントとして接するような方とフラットな立場で発注側/制作側の悩みを語り合う
・SEO会社の方とSEOの成功/失敗について情報を交換
・フリーランスでコンサルをされている方の業務領域の広さに驚く
・ストレージサービスの管理をされている方が趣味で作ったメモアプリの紹介を受ける
などなど。
参加者はデザイナーがメインで残りはエンジニアとディレクターかな？と思っていましたが、かなり多様な業種/職種の方々が来てまして、「UX」という概念のカバーする範囲の広さを体感しました。


##イベント後、共有されたスライドの紹介
・[UXデザイナーあるある言いたい](https://www.slideshare.net/ShoheiMiterashi/ux-204423463)
→3Dスキャナで大量の靴データを記録し、お客さんの足の形をスキャン → ぴったりサイズの靴をご提案！という画期的なサービスを立ち上げようとしたスタートアップの失敗談。街頭アンケートで８割が使いたいと答えたサービスがなぜ使われなかったのか。

・[幼稚園児はできている超高速PDCA](https://www.slideshare.net/ShoheiMiterashi/pdca-125002107)
→上記の人の別スライド。マシュマロチャレンジというおもしろワークショップを通してPDCAを高速で回すことの重要さをわかりやすく解説。

・[UXデザイナーのスキルセットってどうなっているの？](https://speakerdeck.com/endout/uxdezainafalsesukirusetutotutedounatuteirufalse)
→海外サイトからの転用でUXデザイナーのスキルについて説明。自分にとっては高レベルな内容だけど驚くべき”UXデザイン”の領域の広さがうかがえます…。

・[Googleの考える ユーザーにとって優れたデザイン](https://docs.google.com/presentation/d/1HdXSY90YkVhDGzoTvJ6vCMDqBrytdt54r-2g3X3jZ5E/edit#slide=id.g793a809fe5_0_0)
→ざっくりまとめるとデザインも大事だけど、そもそもデザインが表示されるまでのスピードが~~絶対神Google様に愛される上で~~すごく重要。という話。イベントのフランクな空気感が味わえるスライド。

##社外イベントに参加するメリット
・社外の同業種の人々の雰囲気に触れられる
・普段の生活では得られない情報に触れられる
・モチベーションが上がる
・仕事/スキルアップが楽しくなる

ネットで大体の情報は得られる昨今ですが、
生の体験ならではの実感は、より原動力になるような気がします。

あとは外で得てきたナレッジを社内で共有できる仕組みがあると相乗効果が期待できるので、
アドベントが終わってからもなにかしら継続したいなあ...

皆さんも外からナレッジを得て、共有しましょう！
Rails carrierwaveで画像をダウンロードさせる

**※carrierwaveでアップロードはできている前提です。**

### carrierwaveの設定

developmentでは`app/public/uploads`配下に保存して、
productionではGoogle Cloud Storageに保存します。

```rb:fuga_uploader.rb
class FugaUploader < CarrierWave::Uploader::Base
  ...
  # Choose what kind of storage to use for this uploader:
  if Rails.env.production?
    storage :fog
  else
    storage :file
  end
  ...
```
### 1. コントローラーに処理追加

```rb:app/controllers/hoge_controller.rb
  def download
    hoge = Hoge.find(download_params[:id])
    image = hoge.image # imageはFugaUploaderオブジェクト
    send_data(image.read, filename: "download#{File.extname(image.path)}")
  end
...
  def download_params
    params.permit(:id)
  end
```

### 2. viewにリンク設置

ターボリンク使っている場合は、`turbolinks: "false"`しないとURLが変わっちゃいます。

```erb:app/views/hoge/show.html.erb
        <div>
          <%= link_to download_hoge_path(@hoge), data: { turbolinks: "false", confirm: 'ダウンロードしますか?' } do %>
            <%= image_tag @hoge.image.to_s %>
          <% end %>
        </div>
```

### 3. ルーティング設定

```rb:config/routes.rb
  resources :hoge do
    member do
      get :download
    end
  end
```
Rails API Client比較

Ruby on RailsにてAPI Clientとして使用できるgemについてどんなものがあるのか簡単に概要をまとめてみました。

## ActiveResource
Railsの標準機能としてRails2にて登場しましたが、Rails4以降は標準機能から分離されています。
REST APIを使用するRailsアプリケーションにおいて、ActiveRecordのような振る舞いで実装が可能です。
もともと標準機能として存在していただけに、使い方に関する文献は多いです。
https://github.com/rails/activeresource

## Her
ORM機能とHTTP Client機能が分離されているのが特徴です。
Her::Modelを使用するモデルにincludeすることで、ActiveRecordのように操作することができます。
https://github.com/remiprev/her

## ActiveRestClient
Herよりも後に登場したgemです。これもActiveRecordのようにモデルを操作することができます。
wikiにはActiveResourceは、リソースの命名規則がRailsに従っていない場合は機能せず、柔軟性がないとの記述がありますが、ActiveResourceを使っていて特にこれらを問題に感じたことはないです。※あくまで主観です。
wikiにこのgemは更新していないので、Flexirestを参照してくれと記載されています。
https://github.com/whichdigital/active-rest-client

## Spyke
他のgemと同様にActiveRecordのように操作することができます。
Herはパフォーマンスの問題とメンテナンスがあまり行われないので、Herからインスピレーションを受けて新しく作りましたとwikiに書いてあります。
大量のJSONの高速処理と書いてあるので、パフォーマンス面に力を入れているようですね。
https://github.com/balvig/spyke

## Flexirest
ActiveRestClientの作成者のひとりがActiveRestClientに代わるgemとして作成したものです。
ActiveRestClientと似ているが、柔軟性の面で優れているとのことです。
https://github.com/flexirest/flexirest

# まとめ
どのgemもActiveRecordのように振る舞うことを全面でアピールしています。
簡単にですが一覧に現時点（2019/12/16）での各gemの情報をまとめてみました。

| gem              | Github スター数 |    登場    | 最新バージョン | 公開日         | リリース数 |
|:-----------------|--------------:|:----------:|:----------:|:-------------:|-------------:|
| ActiveResource   |           960 | 2013年     | v5.1.0      | 2018年11月03日 | 5 |
| Her              |         1,860 | 2012年     | v1.1.0      | 2019年02月14日 | 65 |
| ActiveRestClient |           389 | 2013年     | v1.0.3      | 2014年07月30日 | 87 |
| Spyke            |           562 | 2014年     | v5.3.4      | 2019年05月31日 | 49 |
| Flexirest        |           136 | 2013年     | v1.8.7      | 2019年12月06日 | 121 |

スター数で見るとHerが一番人気ですね。
2019年もリリースがあるのは、Her、Spyke、Flexirestでした。ActiveResourceは元々標準機能に備わっていただけあり、成熟期は終わっているということでしょう。
また製作者がFlexirestのwikiに書いていたように、ActiveRestClientはもう更新が止まってしまっているようです。

有名どころはActiveResourceだと思いますが、こういった観点で見るとまたどれを使うべきなのか悩みどころですね。
処理速度や使いやすさの観点からの比較検討が今後の課題です。
metabaseで日本の地図を表示する

#環境
metabase v0.33.6
metabaseはこちら→https://www.metabase.com/

#metabase付属の地図
metabaseをインストールしただけではUSの地図しか表示されない。

![スクリーンショット 2019-12-15 15.22.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539241/92696528-1218-e5bb-0e09-44734f5fe4f6.png)

せっかく良い機能があるんだから、日本の地図も表示してみる。
結論から言うと、下記の通りできた。

![スクリーンショット 2019-12-15 15.24.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539241/201d7365-89fe-cbd1-8fe7-6fa9a9de5647.png)

#日本の地図に変更する手順
##MAPの設定を行う
1.右上の設定から管理者モードになる。
2.設定ページからMAPメニューを選択する。
3.カスタムMAPのGEOJSONを登録する。
　今回は下記からいただきました。
　https://github.com/dataofjapan/land

![スクリーンショット 2019-12-15 15.30.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539241/e33b6883-856b-a2e7-f0cb-05e56e54b78c.png)

4.管理者モードの設定は以上。管理者モードから抜ける。

##MAPの可視化を行う
5.データを用意する。
　今回のJSONファイルは都道府県名がキーになっているため、それに合わせたデータを用意する。　
　![スクリーンショット 2019-12-15 15.32.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539241/8a74619b-9ec9-4677-4a9f-bcf45ab564ed.png)

6.ビジュアライゼーションからMAPを選択し、下記のように入力して完成。
![スクリーンショット 2019-12-15 15.35.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539241/fcb726dd-167a-4acb-1642-42e595b9f9f5.png)


#終わりに
簡単にできた。
データにあったgeojsonを用意するところが一番難しいかも。
[VS Code]勝手に閉じタグにカーソルが複製されてしまう機能の無効化

先日、HTML ファイルで開始タグにカーソルを合わせると、勝手に閉じタグにカーソルが生成されていることに気づいた。

<img width="193" alt="スクリーンショット 2019-12-16 19.25.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202008/f7e3ff3e-e466-c10a-8ed3-2d779cfb2878.png">

おそらく最近追加された機能の様だが、不要というかかなり煩わしいので消す方法を探していたら見つけることができた。

設定（ [左下の歯車アイコン]>[設定]、または `Ctrl`+`,`、Macは`⌘`+`,`）から「Mirror Cursor」 で検索すると出てくる、
`HTML: Mirror Cursor On Matching Tag` の `Enable/disable mirroring cursor on matching HTML tag`のチェックをはずすと無効になる。

<img width="398" alt="スクリーンショット 2019-12-16 19.26.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202008/353e9f65-f1de-d49b-ca5f-10d531a6aaa9.png">

↑ のチェック

なお、settings.json で無効にする場合は下記を json に追記すると良い。

```
"html.mirrorCursorOnMatchingTag": false,
```
ワークフロー開発において意識したほうがいい（と思っている）こと

以前に「UiPath
シナリオ
ワークフロー研究会」というものがあり、そこでLTした内容をちょっと修正しました。
※これらはあくまで個人の見解です。

## Flowchart（フローチャート）を極力使わない

フローチャート自体は大変便利な機能です。ワークフローの流れが一見してわかりやすいし、もともとフローチャートで書かれたドキュメントなどがあればそれを踏襲して開発することで、比較・確認しやすいワークフローになります。
ただし、新規で開発をするのであれば基本的には**Sequence（シーケンス）を第一選択とすべき**と、私は考えます。以下に理由をいくつか記します。

- フローチャートに配置されたアクティビティ（シーケンスを含む）は、そのアクティビティの「開発ペイン上に表示される」設定項目が表示されません。
  - 表示するためにはクリックして右側のプロパティ画面を見るか、ダブルクリックしてアクティビティの詳細を表示しなければなりません。
  - ダブルクリックして表示した場合、もとのフローチャートに戻るためには、開発ペインの上部にあるパンくずリストを用いる必要があります。
- アクティビティの配置（位置や接続）を意識する必要があります。
  - 特に配置については、個々人での美学に依るところがあります。何かしらのルールがあれば良いかもしれませんが、そうでなければワークフロー内がいわゆるスパゲティ状態になる可能性が高いように思います。
- そもそも、フローチャートでないと実装できないようなプロセスがそれほど多くないように思います。
  - 例えばループ処理を実装する中で、「A→B→C→D→E」と進むプロセスが存在して、CやDで何かしらループを戻る処理を、「CのときにはB」「DのときにはA」という要件に基づいて実装したい場合、これはフローチャートでないと実装できないです。少なくとも For each のループにおける Continue では、前述の例でいうと A にしか戻れないからです。
  - 逆を返すと、上記のような要件が生じるようなプロセスが現状どれほどあるか、に尽きるかと思います。これまでにビジネスにおいて開発した経験では、上記のようなプロセスのタイミングに依る戻り先の変更の要件はありませんでした。

## 変数名に型の名称を含めない

変数を命名するときに、プレフィックスやサフィックスとして、変数の型を表す文字列 （ex. `str`）をつけるケースを良く見ます。これを「システムハンガリアン」と言います。この記法は、ケース・バイ・ケースではありますが**原則としては採用する必要は無い**と考えています。

- この記法の意義のひとつである「変数の意味」が、「型」に含まれるため。
  - プログラミング言語においては「型」という概念を含まないものが存在し、そのようなプログラミング言語による開発においては、変数名に、変数に含まれると想定されるデータ型を記載することに意義がありました。しかしながら、UiPath のバックエンドである .NET Framework ないし C# では、この「型」が概念に含まれているため変数名に記載する意義が存在しません。
- .NET Framework において、この記法を禁止しているため。
  - この記法を使用したことに依るペナルティなどが存在するわけではありませんが、少なくともこのフレームワークを開発した Microsoft の公式ドキュメントにおいては、上記の通りこの記法を *DO NOT （すべきではない）* と表現しています。
- 変数名を無用に長くしてしまい、その意味を読み取ることを困難にするため。
  - これは悲しいことではありますが、UiPath Studio においては変数名などのパラメーターを設定する画面のサイズが十分ではないケースが多々あります。その貴重なスペースをプレフィックスを表示するために利用してしまうと、その先にある「意味」を表すべき文字列が表示されず、可読性を下げてしまう結果となります。

（以降、追記作業中。。。）
犠牲的アーキテクチャとは

# 犠牲的アーキテクチャとは

Martin Fowlerさんが2014年に提唱したソフトウェア開発の概念です。
https://martinfowler.com/bliki/SacrificialArchitecture.html

## 概要
現在書いている最良のコードは数年後には捨てるという事を受け入れる。
その上将来リプレイスする事を考慮した開発を行うという概念

### googleでも犠牲的アーキテクチャ

> 実際、この指針を組織の行動原理に焼き込むこともできるだろう。Google では、現時点の十倍の負荷を捌けるようシステムを設計するのがはっきり定められたルールとなっている。負荷がある規模を超えたら現行の版を捨て、最初から作り直した方が良いという含みがここにはある [1]。サブシステム群を数年おきに再設計しては捨てるのが普通なのだ。

犠牲的アーキテクチャの採用をしている企業のメリットをいくつか書くと、

* 事業規模にあったパフォーマンスの維持
＊ 常に時代にあったその時の最適な技術を選択する為、
* 今のメンバーにノウハウを蓄積する

があるそうです。

## 具体的なアプローチ

> 初期のシステムなら丸ごと捨てるのも悪くないかもしれないが、システムが大きくなるにつれて個々のモジュールを捨てる方が良くなる。それができるのは、うまい具合のモジュール境界がある時だけだ。

との事なので
例えば、shopifyの様にrailsアプリでもユースケース単位でコントローラーを分割するのは良いアプローチだなと思います。
https://engineering.shopify.com/blogs/engineering/deconstructing-monolith-designing-software-maximizes-developer-productivity

# 名言

出来の悪いコードの上に多すぎるユーザを抱え込むのはふつう、その逆よりもマシだ。
かけだしのフロントエンドエンジニアがもらったレビューを振り返る

みなさん、初めまして。mashuです。

[playgroundのアドベントカレンダー](https://qiita.com/advent-calendar/2019/playground)17日目です。

かけだしの僕が javascript でもらったコードレビューを振り返ってみたいなって思います。

---

### 変数名はわかりやすく

```javascript
// 変更前
colorValue

// 変更後
hogeColor
```


全人類の悩みの種ですね。
`hoge` の色を指定したいときに、`colorValue`という命名ではなんの色か全くわかりません。
`hoge` の色であることを誰が見てもわかるように`hogeColor`にすると直感的にわかるようになります。

javascript は作りたい機能をもとにコードを書くことが多いと思うので、その変数が何に使われるかを意識して命名したいですね。

---

### アロー関数を使おう

```javascript
// 変更前
function fuga () {
  console.log("piyo");
}

// 変更後
const fuga = () => {
  console.log("piyo");
}
```

javascript 初心者の僕はアロー関数という超便利なものを使ってませんでした。
アロー関数を使いたいけど書き方が `function` と全然違うから…って思ってる人は関数宣言から関数リテラル、`function` からアロー関数が2つ一気に変わっていてごっちゃになってるかもです。(僕も最初はごっちゃになってました。)
なので、まずは**関数リテラル**から調べてみて、次に**アロー関数**というふうに段階を踏むとわかりやすいと思います。

---

### ネストを浅く

```javascript
const list = ["hoge", "fuga", "hoge"];

// 変更前
if ( list.length === 3 ) {
  if ( list[0] === list[2] ) {
    console.log(list);
  }
}

// 変更後
if ( list.length !== 3 ) return;
if ( list[0] === list[2] ) {
  console.log(list);
}
```

ネストは2段を超えると読みづらくなります。ネストを浅くできるところは他の表現がないか、ちょっとだけ考えてみたらいいと思います。
三項演算子を使うことで、if文が1文で完結することがあるので、三項演算子も使いたいですよね。

---

### 共通部分は一回で書く

```javascript
// 変更前
isHoge ? console.log("hoge") : console.log("fuga")

// 変更後
console.log( isHoge ? "hoge" : "fuga" )
```

三項演算子は書き方次第ではコードが読みづらくなります。
共通部分を一回で書くようにすると、読みやすく短いコードになると思います。

---

### マジックナンバーを使わない

```javascript
// 変更前
$("button").on("click", event => ({
  const buttonWidth = $(event.currentTarget).css("width")
  $(event.currentTarget).css("width", `${buttonWidth + 25}`);
});

// 変更後
const extendWidth = 25;

$("button").on("click", event => ({
  const buttonWidth = $(event.currentTarget).css("width")
  $(event.currentTarget).css("width", `${buttonWidth + extendWidth}`);
});
```

自分ではなんの数値か分かっていても、レビューする人はなんのための数値かわからないので、なんのための数値かわかるような変数名に代入したらいい感じになります。

---

### ifに空文は絶対にダメ

```javascript
// 変更前
if ( a === 1 && b === 1 ) {
  ;
} else if ( a === 1 ) {
  console.log("hoge");
} else if ( b === 1 ) {
  console.log("fuga");
} else {
  console.log("piyo");
}

// 変更後
if ( a === 1 && b !== 1 ) {
  console.log("hoge");
} else if ( a !== 1 && b === 1 ) {
  console.log("fuga");
} else if ( a !== 1 && b !== 1 ) {
  console.log("piyo");
}
```

空文は、コードを書いてるときはわかりやすいですが、レビューしている人は ん??? ってなるし、無駄なif分岐が増えるのもよくありません。
上手にif分岐をして、空文の使用を避けるといいと思います。

---

## 最後に
案件に参加させてもらって、コードは自分がわかるだけじゃダメなんだなぁと思いました。
読みやすいコード書けるように頑張ろ。

p.s. 次回リーダブルコード編でお会いしましょう
IEx.configureを設定してiex上のリスト結果を変更する

[こちらの記事](https://qiita.com/torifukukaiou/items/8c37f9710e45b50b6aba)を読んで、`IEx.configure(inspect: [limit: :infinity]) `の使い方を知ったので、簡単に整理しておきます。
なお、動作は「 **Elixir1.9.0（Erlang/OTP 22）** 」で確認しています。

## 最初にまとめ

リストの出力結果を「 **無制限** 」にしたい場合、以下のようにiex上で設定します。

```
IEx.configure(inspect: [limit: :infinity])
```

また、特定の値に設定したい場合には、以下のように指定値を設定します。（例では「**9**」にしています）

```
IEx.configure(inspect: [limit: 9])
```

## 解説＆実施結果

実施結果も含めて、設定内容を確認してみます。

### デフォルトではiex上でのリストの出力結果は50件に制限される

iexでは、`Enum.map/2`の実行結果などで出力される件数が制限されています。
以下の例では、要素数が100個のリストを作成していますが、表示されている内容は50件までになっています。

```
iex> 1..100 |> Enum.map(& &1)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
 43, 44, 45, 46, 47, 48, 49, 50, ...]
```

通常時はこれで問題ないが、大きい値の結果も見たい場合は不便です。

この結果を変更するには、iexで`IEx.configure/1`を利用します。
引数に「`inspect`」を指定し、さらに`inspect`対して「`[limit, 件数]`」を指定します。

念のため、`IEx.configure/1`の`inspect`をヘルプで確認してみます。

```
h IEx.configure/1
```

ヘルプを見たところ、デフォルトでは50件で設定されています。
また、全てのエントリを表示する場合は「`:infinity`」を設定しろ、と書いてありますね。

```
## Inspect

A keyword list containing inspect options used by the shell when printing
results of expression evaluation. Default to pretty formatting with a limit of
50 entries.

To show all entries, configure the limit to :infinity:

    IEx.configure(inspect: [limit: :infinity])

See Inspect.Opts for the full list of options.
```

### 出力する件数を「制限なし」にしてみる

ヘルプの内容に従い、「制限なし」で実施してみます。
結果、1000件のデータはすべて出力されました。

```
iex> 1..1000 |> Enum.map(& &1)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
 43, 44, 45, 46, 47, 48, 49, 50, ...]
iex> IEx.configure(inspect: [limit: :infinity])   # ここで「制限なし」を指定する。
:ok
iex> 1..1000 |> Enum.map(& &1)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,

～（出力の中略）～

 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997,
 998, 999, 1000]
```

### 出力する件数を指定してみる

今度は、出力件数に任意の値を指定します。

```
iex> 1..10 |> Enum.map(& &1)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
iex> IEx.configure(inspect: [limit: 3])  # 3件にしてみる
:ok
iex> 1..10 |> Enum.map(& &1)
[1, 2, 3, ...]
iex> IEx.configure(inspect: [limit: 9])  # 9件にしてみる
:ok
iex> 1..10 |> Enum.map(& &1)
[1, 2, 3, 4, 5, 6, 7, 8, 9, ...]
```

## おわりに

知っている人には今更ではあるのですが、これまで自分はずっとiexを抜けてコンソール上で確認していました。自分と同じようにやり方を知らなかった人が知ってもらうきっかけになれば。

ちなみに、今回のやり方で設定した値は、iexを抜けるとリセットされます。
なので、必要に応じて都度実施してください。
気づきの種まき~SFTP編~

### 身内向けで恐縮ですが、今後の気づきの種まき
いつも通り、データを送るような処理をレビューして、テストをしていたある日。
送るファイルの指定：OK、終了ファイルの指定：OK、ディレクトリの指定：OK・・・確認は順調だ。

「よし、テストしちゃうぞ！　おや、、、様子がおかしい。」
「何故かうまくいかない…　なんでだろう…　んー」

- 前提の確認漏れ

　そもそも、要件には『SFTP』と記載あるにもかかわらず、FTPで実装を進めていた。(ちゃんと読めよ)

　＊FTP：サーバーへファイルをトランスファーするためのプロトコルのことをいい、暗号化はしていない。[1]
　＊SFTP：FTPで転送される情報を「SSH（Secure Shell）」を利用して暗号化するプロトコルのことです。[2]

　要するに、FTPは何も安全に関する加工せず送っているため、加工しているSFTPの方が安全な連携

- 突然ぶつかった壁

　ネット上にある、phpでSFTP送信を試みる処理、ライブラリがいくつかあった。
　①https://qiita.com/taiba/items/6a1cfd53f0fdcfce14bf
　②https://weblabo.oscasierra.net/php-phpseclib-2/

　上記を参考に②を利用して作ってみた。

　よし、これなら行けるだろう。テスト実施。うまくいかない。
　エラーとしては、タイムアウトし続け、なぜだなぜだと考えた。

　teratermの様なファイル転送ツールでは、問題なく繋がった。
　きっと書き方が悪いのだろう。修正を繰り返すもなかなかうまくいかない。

　社内で少し、事例を聞いたところ、SFTP接続するには、インフラの設定が必要とのことだ。

### あとがき
- 何か外部と連携するものを作るときは、ちゃんと仕様書の確認をすること
- 目的を達成するために別の確認手段があったら試すこと（今回でいうteratermのログイン確認）
- 確認を行った上で、事象を周囲のメンバー、先輩に確認すること

そうすれば、自ずと答えにもたどり着き、自らの知見と経験になります。
定期的に予期せぬ壁にぶつかっていきたいですね。（トリッキーな内容でもなかったけど、思い出に）

以上

---- 
引用・参考
[1][2]：https://liginc.co.jp/398039
OpenSiv3Dで非同期処理をする

# OpenSiv3Dで非同期処理をする

久し振りに `C++`を触り、`OpenSiv3D` で単純な非同期の処理をした際に色々知らなかったことが多かったので忘れないうちに備忘録として書いておきます。バージョンは OpenSiv3D 0.4.1です。タイトルにデカデカと入れといてなんですが、あまりOpenSiv3D要素はありません。

## 最小コード
時間がかかる関数を `heavyFunction()` を非同期で実行し、計算中は `"計算中..."` と表示し計算が完了したら結果を表示するコードは以下のようになります。

```cpp
# include <Siv3D.hpp> // v0.4.1
# include <future>

double heavyFunction() {
    // 何か重い処理
    System::Sleep(3s);
    return 1.0;
}

// 非同期関数の結果をOptional型で返す関数
template<class T>
Optional<T> resultOr(std::shared_future<T> task) {
    if (task.valid()) {
        auto status = task.wait_for(0s);
        if (status == std::future_status::ready) {
            return task.get();
        }
    }
    return none;
}

void Main() {
    const Font font(24);
    std::shared_future<double> task = std::async(std::launch::async, heavyFunction).share();
    
    while(System::Update()) {
        font(resultOr<double>(task).map(Format).value_or(U"計算中...")).draw();
    }
}

```

`std::shared_future` は `shared` な `std::future` みたいな感じです。(これ以上説明できません)

関数 `Optional<T> resultOr(std::shared_future<T> task)` は Siv3Dの Optional型を返り値とし、 `std::shared_future` の処理が完了していたら `std::shared_future::get()` し、そうでなければ、 `none` を返す関数です。 
`task.wait_for(0s)` の部分はメインスレッドをブロックせずにタスクの状態を取得する為 `0s` ウェイトしている様です。

`C++` 無限に知らないことが出てくるから怖い。正直これがベストプラクティスだとは思っていないので ~~マサカリお待ちしております。~~
個人的には OpenSiv3Dに `JavaScript/TypeScript` の `Promise` 並に扱いやすい非同期処理まわりのラッパがあると嬉しいかも？
最近は3Dの機能も着々と実装され増々便利になっています！

**OpenSiv3Dはいいぞ！**

# 参考
[AziOGroup Lab,: std::asyncで開始したスレッドの終了確認 [C++]](http://aziogroup.blogspot.com/2016/05/stdasync.html)
[std::future as a parameter to a function C++ - Stack Overflow](https://stackoverflow.com/questions/27186233/stdfuture-as-a-parameter-to-a-function-c)
ファイル名に日本語が含まれるとMac版Chrome76でファイルアップロードができない

これは [TOWN Advent Calendar 2019](https://adventar.org/calendars/4335) 16日目のエントリーです。

ファイル名に日本語が含まれるとMac版Chrome76でファイルアップロードができないという問題が発生したことがありました。

原因としてはPOSTメソッドのときにもService Worker と Cache API経由でリクエストをしていたためでした。

以下のようにしてGETメソッドのときだけ fetch(event.request) を呼ぶように修正しました。

```javascript

self.addEventListener('fetch', (event) => {
  if (event.request.method === 'GET') { //GETリクエストだけ fetch(event.request) を呼ぶように修正
    event.respondWith(caches
      .open('cache-name')
      .then(cache => cache.match(event.request))
      .then(response =>
        response || fetch(event.request).catch(() => offlineAsset('offline.html'))));
  }
});
```

https://medium.com/web-on-the-edge/offline-posts-with-progressive-web-apps-fc2dc4ad895
CentOS7のDockerコンテナでsystemctlを使えるようにする

`Failed to get D-Bus connection: Operation not permitted` が出た場合の対処法まとめ

色々な場所で色々な対処法が書かれていますが、結論として以下の2つが必要です。

* privilegedを有効(true)にする
* /sbin/initで起動実行する

片方だけ指定して、うまくいかないな〜とかなっていませんか？（僕です）

#### privileged を有効(true)にする
privileged は、特権モードという意味です。これがデーモンを操作するのに必要な権限になりますが、デフォルトでこれがOFFになっているため起動できていないという事になります。

#### /sbin/initで起動実行する
起動時にサービスを開始し、ランレベルを設定してくれます。これでprivilegedが有効になった状態で読み込みしてくれるようになります。

## docker runの場合
起動時のコマンドに以下を追加する
* `--privileged`
* `/sbin/init`

```
# 例)
docker run -d --privileged --name hoge centos /sbin/init
docker exec -it hoge /bin/bash
```

`/sbin/init` で特権モードで起動させてから接続するようにします。

> (参考) [CentOS7のコンテナでsystemctlを使うための方法](https://qiita.com/Targityen/items/6e80b855b79d521412f0)
> (参考) [DockerでCentOS7起動時にsystemctlが動かないとき](https://www.tcmobile.jp/dev_blog/devtool/docker%E3%81%A7centos7%E8%B5%B7%E5%8B%95%E6%99%82%E3%81%AEsystemctl%E3%81%8C%E5%8B%95%E3%81%8B%E3%81%AA%E3%81%84%E3%81%A8%E3%81%8D/)

## docker-composeの場合
こちらも書く場所が違うだけで、やることは同じです。
* `privileged: true`
* `command: /sbin/init`

```docker-compose.yml
services:                                      
  app:                                         
    build:                                     
      context: ./                              
    privileged: true                           
    command: /sbin/init                        
```

```
docker-compose up -d
docker-compose exec app /bin/bash
```

> (参考) [docker-compose(CentOS7系やMySQLのオプションなど)](http://skill-up-engineering.com/2019/07/28/docker-composecentos7%E7%B3%BB%E3%82%84mysql%E3%81%AE%E3%82%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AA%E3%81%A9)
【初心者】量子コンピュータの学習サイト【無料】

#はじめに
量子コンピュータの学習で見つけた使えるサイトなどをまとめておく。

★適宜更新中★

#✅Qiskit Community
+ https://qiskit.org/
+ https://github.com/qiskit-community
+ Qiskiに関するドキュメントや学習教材がある。
+ Slackでの情報交換も行われており、だれでも自由に参加できる。

#✅IBM Q  Quantum Challenge 2019
+ https://quantumchallenge19.com/ja/
+ コンテストの開催に伴いWeek1~3に「Learning Challenge」が設定されている。
+ ゲートの基礎学習から行える。

#✅量子コンピュータ授業（慶應大学）
+ http://www.appi.keio.ac.jp/Itoh_group/spintronics/
+ https://www.youtube.com/playlist?list=PLB1324F2305C028F7
+ 2005年に慶應大学矢上キャンパスで開催された集中講義。
+ 動画で見ることが出来る。

#✅マルレク「量子コンピュータで学ぶ量子プログラミング入門」
+ https://github.com/maru-labo/ibm-q-handson
+ マルレクは、IT技術の普及などを目的に運営されており、量子プログラミングも扱っている。
+ Pyhon, IBM Qiskit を使用する。

#✅古典プログラマ向け量子プログラミング入門
+ https://www.slideshare.net/OsSAL-org/ss-198802364
+ プログラマ向けに量子プログラミングの解説をした資料。
+ 基礎からわかりやすくまとめられている。

#✅Quantum Native Dojo!
+ https://dojo.qulacs.org/ja/latest/
+ Qunasys社が開発しているQulacs（量子回路シミュレータ）に関連して公開されている次週教材。

#✅blueqat Slackチャンネル
+ [こちら](https://qnn.connpass.com/)にSlackチャンネル参加のURLが掲載されている。　
+ blueqat社が開催している勉強会に関連して公開されているSlackチャンネルで、CEOの湊氏らにより学習に関するトピックや最新情報等が共有されている。

#✅Blueqatチュートリアル
+ https://github.com/Blueqat/Blueqat-tutorials/tree/master/tutorial-ja
+ MDR社が開発しているBlueqat（Python）を使ったチュートリアル。
+ 実際にコードを動かしながら学ぶことができる。
開発ディレクターとしての役割

[QualiArts Advent Calendar 2019](https://qiita.com/advent-calendar/2019/qualiarts)、17日目の記事です。

弊社には、開発ディレクター（以下、開発D）という役職が2015年に作られました。開発Dが発足した時からかれこれ5年間くらい、そのポジションで奮闘していますが、今回はその役割について個人的に感じている事などを交えながら、記載しようと思います。
一般的には、PMやPOと近しい役割を一部担ったりもしていますが、会社により定義は様々だと思いますので、あくまでも「QualiArtsとしての開発D」という観点で読み進めていただけたらと思います。

#QualiArtsの開発ディレクター
### 作られた経緯
ネイティブゲームへと事業の方向性がシフトし、ゲーム開発の規模拡大に伴って、「開発全体のリーダー」が必要となった為。

### 責任領域
- 開発管理
- 品質管理

要は、新規プロジェクトでも運用プロジェクトでも、しっかりとスケジュール通りに不具合なくリリースをしましょうという感じです。
他にも、「メンバーのマネジメント」や「評価」などの役割も担っています。
「スケジュール通り不具合なく」と聞くと、何を当たり前のこと！！という感じかもしれませんが、この当たり前の実現には、たくさんの壁があります。その壁にぶつかった時に判断し、それを正解に導く働きを全力でするのが開発Dの役割なのではないかと僕は感じています。

### 本当によくある壁
基本的にはどのプロジェクトでも必ずと言っていいほど挙がる内容ではないかなと思います。

- スケジュール
- 人員、コスト計画
- 技術選定、実現可能性
- チームビルディング　
- メンバー同士の合う合わない問題
- コミュニケーション

細かいものを羅列したらキリがないくらいあるかと思います。
僕自身も、普段からできる限り事細かく注視して違和感を感じた場合は先延ばしにはせず、自分で解決、もしくはメンバーを頼って解決するように働きかけています。
開発を進める上で、問題になりそうな所、なった所に関しては役割を超えてでも行動を起こし、どうにかするための働きがけをするというのがQualiArtsの開発Dの特徴かもしれません。会社全体の判断が必要な場合には、経営層に混ざり議論をすることもあります。

### 色の異なり
責任領域は明確ではありますが、各プロジェクトの開発Dによって動き方は全然違います。

例)

- サーバーサイドに特化した開発D
    - 必要に応じてAPI実装、管理画面の実装、インフラ構築をする
- クライアントサイドに特化した開発D
    - 技術判断や、必要に応じて画面実装をする
- 事業に特化した開発D
    - 事業課題を把握し、必要に応じて事業の課題解決に向き合う

上記の例は極端な部分もありますが、開発Dの中でもそれぞれの強みも違うので、明確な責任は持ちつつ必要に応じて、動きを変えたりします。
余裕がある時は自身のスキルアップに時間を使ったり、本を読んだり、興味がある分野に足を突っ込んだりと、開発Dというポジションをうまく利用できたりもします。

# まとめ
開発Dについてまとめてきましたが、将来的には開発Dがいなくてもチームが成り立つような状態にしたい、そのような状態に近づけるために試行錯誤しながらプロジェクトの成功に貢献できたらと考えています。
この記事を書きながら、「なんでも」ってなにやったかな？と考えた時に、過去のプロジェクトでひたすらゲーム内のボタンのタップ領域を広げるという作業をしていたことを思い出しました。

最後まで読んでいただいてありがとうございました。
シェルスクリプト 位置パラメータをシフトする shift

shift コマンドはそのシェルにセットされている位置パラメータをシフトします。

##### 1つずつシフトしている例
以下のスクリプトを実行すると、
a 
b 
c 
d 
e 
と出力されます。
shift コマンドによって、$1 に入っている値が1つずつシフトされます。

```bash:example1.sh
set a b c d e
while [ $# -gt 0 ]
do
  echo $1
  shift
done
```

##### 2つずつシフトしようとした場合
以下のスクリプトを実行すると、
a
c
e
e
e
と e 出力が無限に出力されます。
shift コマンドに与えた引数の数ずつ $1 に入っている値がシフトされますが、e の後に shift 2 を実行することが出来ず、永遠に e の位置にとどまってしまいます。

```bash:example2.sh
set a b c d e
while [ $# -gt 0 ]
do
  echo $1
  shift 2
done
```

##### サブシェル内でシフトさせた場合
サブシェル内でシフトはされますが、元のシェルではシフトされていません。

```bash:example3.sh
set a b c d e
(
while [ $# -gt 0 ]
do
  echo $1
  shift 1
done
echo "sub shell $#" # 0 が出力されます(つまり全ての引数がシフト済)
)
echo "main shell $#" # 5 が出力されます(つまり全くシフトされていない)
```
Quarryを使ってPythonで擬似的なMinecraftサーバーを作る

PypiでMinecraft系のライブラリがないかなーって探ってたらQuarryというライブラリがあったので使ってみました。

# インストール

これだけ。

```
pip install quarry
```

# 擬似的なサーバーを作る

結論から言うとコレで動く。

```python
from twisted.internet import reactor
from quarry.net.server import ServerFactory, ServerProtocol


class QuarryProtocol(ServerProtocol):
    def player_joined(self):
        ServerProtocol.player_joined(self)
        self.close("Pong!")

class QuarryFactory(ServerFactory):
    protocol = QuarryProtocol
    motd = "Powered by Quarry!"

def main():
    factory = QuarryFactory()
    factory.listen("")
    reactor.run()


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

スクリプトを作動させても何も出ないかもだけどそれが正解。

これでMinecraftで接続すればPong!と切断メッセージが返ってくるはず。

# 弄ってみる

## ServerFactory

サーバーのmotdやオンラインモード（割れ対策機能）のオン・オフ、サーバー画像の変更などが行えるクラス。

### プロパティ
- ```protocol```
  
  必須。```ServerProtocol```クラスを代入。詳細は後述にて。
  
- ```motd```
  
  サーバーの説明。サーバーリストに表示されるアレ。

- ```icon_path```

  サーバーのアイコンを指定。PNG形式（だったはず）で64x64までのサイズ。

- ```max_players```

  プレイヤーの最大接続数。最低でも1にしないとダメ。

- ```online_mode```

  Mojangオンライン認証を有効にするか。特に理由がなければTrueのままでヨシ。

## ServerProtocol

このクラスでプレイヤーの接続時などの処理を行います。

いくつかの関数がありますが、分かる範囲だけ書いておきます。

### 関数

- ```player_joined```（置き換え関数）

  プレイヤーが入ってきたときに行う処理。オンラインモードがオンになっている場合、認証が完了したときにこの関数が呼び出されます。
  あと、親クラスの```player_joined```関数を呼び出しておくらしいです。

- ```close```

  この関数を呼び出すとプレイヤーが切断されます。引数に文字を入れるとその文字がプレイヤー側の切断メッセージに表示されます。

# あとがき

このライブラリを使えば何かしらの認証サーバーとして使えるかも。結構面白いライブラリだと思います。

気になった方はドキュメントがあるようなので、そちらの方を見ていただければ。（英語）

https://quarry.readthedocs.io/en/latest/index.html
jQuery使ってボドゲ作ってみよう説

美しすぎるカードゲームjQueryで作る神経衰弱
https://magnets.jp/web_design/6308/#midashi3

JavaScriptでシェフィを実装する(UI本格化編/カード可視化の巻)
http://labs.timedia.co.jp/2014/09/shephy-in-javascript-rendering-cards.html

jQueryってなに？超初心者向け入門講座
https://webkikaku.co.jp/blog/webdesign/jquery_start/

翡翠の商人るるぶ
http://spa-game.com/wp-content/uploads/Jade_rule1-01.jpg

★HTMLタグリファレンス
http://www.htmq.com/html/ul.shtml
Git インデックスへのステージングを取り消したいとき

# 目的

- Gitでインデックスにステージングしたファイルのステージングを解除する方法を先輩に教えてもらったので忘れないようにまとめる。

# 実施方法の例(本方法はGitのバージョン依存あり)

- コマンド`$git add`を実行したあとに下記のコマンドを実行して特定のファイルのステージングを取り消す。

    ```terminal
    $ git rm --cached ファイル名
    ```

# より具体的な例

- ファイルtest.mdをコマンド`$ git add test.md`を実行してステージングを行う。
- test.mdの内容に追記したい内容を見つけたのでステージングを取り消す。
- 前述の一連の作業を下記に記載する。

    ```terminal
    $ git add test.md
    $ git rm --cached test.md
    ```

# 実は。。。

- この方法実はコマンド`$ git status`を実行した時に「このコマンドを実行するとステージングを取り消せます。」と書いてある。
- 先輩には「コマンドが正常実行されたかだけではなく出力された内容も読みましょう」と言われてしまった。(先輩すいません。)
- 下記にコマンド`$ git status`を実行した際の出力を記載する。(下記の`(use "git rm --cached <file>..." to unstage)`に方法が書いてあった。。。)

    ```
    $ git status
    On branch master

    No commits yet

    Changes to be committed:
       (use "git rm --cached <file>..." to unstage)
            new file:   aaa.md
    ```

# 本件について

- Gitのバージョンによってインデックスへのステージング取り消しコマンドは異なる。
- コマンド`$ git status`の出力にステージング取り消しのコマンドが記載されているためそこをあてにすると良いかも。
日本語で書く言語

## 発端
事の発端というか、いつもコードを書いていて思ったこと
**「絶望的に英語が出来ないのが辛い」**
単語の意味がパッとわからない。意味がわかってもイマイチ意味が伝わらない。
出来るようにしたいけど、やる気とかが起きない。「勉強なんてしたくない。でも英語を話したい」の精神。

ということで、日本語で書ければ、サクサクなんだろーなーと思い、日本語で出来るプログラミング言語「[なでしこ](https://nadesi.com/top/)」をやってみることにしました。
Winを持っていないので、[ブラウザ版](https://nadesi.com/doc3/index.php?%E3%81%AA%E3%81%A7%E3%81%97%E3%81%933%E7%B0%A1%E6%98%93%E3%82%A8%E3%83%87%E3%82%A3%E3%82%BF)で楽しむことに。

日頃のストレスを発散や！(´・ω・)ｷﾘｯ


## 例えば
Javascriptで書くと、

```
alert("こんにちは");
```

を

```
「こんにちは」と言う
```
と書くと、アラートを出してくれる。
なるほど、完全に日本語。
これはサクサク出来そうだ！ということで、、、

## お遊び
### 仮面ライダーBlack・RXおみくじ作ってみました。
下記のソースをブラウザ版に入れて実行してみてください。

```
A＝「今日のあなたの運勢を、仮面ライダーBlack・RX的なおみくじで占います。」と二択。
もしAがはいならば

#運勢
占い結果=[
{"名前":"仮面ライダーBlack吉","詳細":"空気が張り詰めた辛い1日になります。困難がありますが、越えれることが出来ます。1日頑張りましょう。"},
{"名前":"仮面ライダーBlack RX吉","詳細":"今日のあなたは最強です。どんな不運にあっても越えることができます。"},
{"名前":"仮面ライダーBlack RX ロボライダー吉","詳細":"悲しい出来事があるでしょう。しかし、それを越えればあなたはガチマッチョになっています。"},
{"名前":"仮面ライダーBlack RX バイオライダー吉","詳細":"怒りに満ち溢れた1日になります。怒りを制御し、相手の懐に入って戦うことをオススメします。"},
{"名前":"バトルホッパー吉","詳細":"ピンチの時は最強の仲間が駆けつけてくれます。周りを大切に。"},
{"名前":"シャドームーン凶","詳細":"仲間だと思っていた人が敵になります。身内に注意してください。"},
{"名前":"ゴルゴム凶","詳細":"今まで積み重ねたものを破壊しようとする敵が現れます。注意してください。"},
{"名前":"クライシス凶","詳細":"今まで積み重ねたものを乗っ取ろうとする敵が現れます。注意してください。"},
]
結果数=占い結果の要素数
占い番号=結果数の乱数

#ラッキーカラー
色=["黒","Black","Black！","ヴュリャッキュ！！！！"]
色数=色の要素数
色番号=色数の乱数

#出力
「今日のあなたの運勢は、{占い結果[占い番号]["名前"]}です。」を表示。
「{占い結果[占い番号]["詳細"]}」を表示。
「ラッキーカラーは{色[色番号]}です。」を表示。

ここまで
```
※偏見が含まれています。
※「これは違う！」などの意見がございましたら、コメントください。

## 感想
#### 別に英語が辛いわけではないことに気づく
辛いのは英語じゃない。文法でした。日本語で書いても、「こう書けばいいのかなー」という感覚では書けない。
めちゃめちゃエラー出すし、ドキュメント見ないと書けない。
[文法](https://nadesi.com/doc3/index.php?%E6%96%87%E6%B3%95)
[命令一覧](https://nadesi.com/doc3/index.php?%E5%91%BD%E4%BB%A4%E4%B8%80%E8%A6%A7%252F%E6%A9%9F%E8%83%BD%E9%A0%86)

#### メリットだと思った、よかったこと
- プログラミングをやるような仕事じゃない人が、どんなものなのか理解をするきっかけになる気がした。
- ずっと英語で書いていたので、指示を出しているという感覚が薄かったけど、日本語で書くことによって再認識できた気がする。
- 遊びの気持ちでやるのにはちょうどいい。

---

:christmas_tree: [FORK Advent Calendar 2019](https://qiita.com/advent-calendar/2019/fork)
:arrow_left: 19日目 [Advent Calendar だから Illustrator + JavaScript でお菓子を作ってみる](https://qiita.com/momo_r/items/5e86eb91adb4a73e7c95) @momo_r さん
:arrow_right: @sunnyplace さん

編集リクエスト
ESP32でmDNSからIPアドレスを取得したい

# TL;DR
MDNS.queryHost()を使う

# 背景
DHCPを使っているネットワークで通信相手のホストネームがわかっていてもIPがわからない場合や、
諸事情により固定IPにできない時などにmDNSを使って通信相手のIPを取得したい。

# やり方
- mDNSサーバを起動する
- queryHostを使って通信相手のIPを探す

```C
#include <ESPmDNS.h>

void setup() {
   // … <略> …
   // MDNSサーバ起動
   // 自分自身の端末名を決めて設定する
   MDNS.begin("SELF_HOST_NAME");
   // … <略> …
}

void hoge() {
   // … <略> …
   // .localを含まないhostnameを入力する
   // 見つからなかった場合は0.0.0.0が帰ってくる
   IPAddress ip = MDNS.queryHost("TARGET_HOST_NAME");
   // … <略> …
}
```

# おまけ
https\://example.localと通信したい場合や普通にhttps\://example.comと通信したい場合が混じってる時用

```C
#include <ESPmDNS.h>

// この関数を呼ぶ前にMDNSサーバを立ち上げておくこと
String resolveMDNS(String url) {
    // 末尾が.localではないものはmDNSではない
    if(false == url.endsWith(".local")) {
        return url;
    }

    // URLをプロトコルとホストネームに分割する
    String protocol="http://";
    String hostname = url;
    int index = hostname.indexOf("://");
    if(0 < index) {
        protocol = hostname.substring(0,index+3);
        hostname = hostname.substring(index+3);
    }

    // .localを除いたホストネームからMDNSを解決する
    int length = hostname.length();
    hostname = hostname.substring(0,length-6);
    IPAddress ip = MDNS.queryHost(hostname);

    // ipを文字列にして元々のプロトコルと結合する.
    String ipStr="";
    for (int i = 0; i < 4; i++) {
        ipStr += i  ? "." + String(ip[i]) : String(ip[i]);    
    }
  
    return protocol+ipStr; // https://AAA.BBB.CCC.DDDが帰る 
}
```

関数名resolveでよかったのかな？たまに失敗することもあるのでお好みでリトライ機能をつけると良いと思います :D
PandocでMarkdownからHTMLに変換すると箇条書きのネストが反映されない

# TL;DR

PandocでMarkdownからHTMLに変換した際、箇条書きのネストが反映されない(全てフラットになってしまう)原因は、Pandocが空白4つのインデントを期待しており、空白2つのインデントを無視するから。

# 問題

VSCodeでMarkdown文書を書いてみる。こんな感じ。

```md
# This is test

* test
  * test1
  * test2
```

プレビュー画面を見ても、問題ない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79744/5df6f1dd-df3a-d72a-4b11-57eebb598b21.png)

しかし、Pandocで変換するとネストが消えてしまう。

```sh
$ pandoc -s test.md -o test.html
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79744/e2f74264-6946-b704-cdda-5f4250b03e07.png)

# 原因

原因は、Pandocがリストのインデントとして「空白4つ」をデフォルトにしているから。なので、空白4つで書けば良いのだが、そうするとmarkdownlintに怒られてしまう。VSCodeでMarkdown文書を書く時、markdownlintを入れている人は多いと思う。このmarkdownlintのデフォルトのインデントが「空白2つ」になっている。なので空白4つにすると怒られる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79744/5dfe2d78-dbdf-7ce7-95c0-09cb71c85718.png)

# 解決策

解決策は簡単で、markdownlintの設定を「インデントは空白4つ」にすれば良い。適当な場所に`.markdownlint.json`を書けば良い。

```json:.markdownlint.json
{
  "MD007": {
    "indent": 4
  }
}
```

# まとめ

markdownlintのインデントのデフォルトが2、pandocが4で、pandocに「インデント2」の箇条書きを食わせても何もメッセージを出さないため、ネストした箇条書きがフラットになっていることにしばらく気がつかない人もいるんじゃないかと思う(例えば私)。他の人が同じミスをしないように、ここに経験を供養しておきます。

ちなみにmarkdownlintのissueでもインデントを2にするか4にするか議論になってるみたいですね。→[MD007: default value of 2 vs. 4 spaces](https://github.com/DavidAnson/markdownlint/issues/141)
GitHub APIを使ってコミットハッシュからPR名やURLを取得する

# パブリックリポジトリの場合

```console
curl -H "Accept: application/vnd.github.cloak-preview" https://api.github.com/search/issues?q=is:pr+repo:(オーナー名)/(リポジトリ名)+sha:(コミットハッシュ)
```

URIは`.../search/issues`ですが、クエリストリングに`is:pr`とすることで、PRの情報を取得できるところがポイントです。

例えば、

- [laravel/laravel](https://github.com/laravel/laravel)

の

- [DRY up path]( https://github.com/laravel/laravel/pull/5173/commits/6f615b425c2647ed2c19c9a4e8f0513591a743dc)

というコミットは、コミットハッシュ`6f615b425c2647ed2c19c9a4e8f0513591a743dc`ですが、

```console
curl -H "Accept: application/vnd.github.cloak-preview" https://api.github.com/search/issues?q=is:pr+repo:laravel/laravel+sha:6f615b425c2647ed2c19c9a4e8f0513591a743dc
```

とすると、以下の結果が返ってきます。

```json
{
  "total_count": 1,
  "incomplete_results": false,
  "items": [
    {
      "url": "https://api.github.com/repos/laravel/laravel/issues/5173",
      "repository_url": "https://api.github.com/repos/laravel/laravel",
      "labels_url": "https://api.github.com/repos/laravel/laravel/issues/5173/labels{/name}",
      "comments_url": "https://api.github.com/repos/laravel/laravel/issues/5173/comments",
      "events_url": "https://api.github.com/repos/laravel/laravel/issues/5173/events",
      "html_url": "https://github.com/laravel/laravel/pull/5173",
      "id": 535748469,
      "node_id": "MDExOlB1bGxSZXF1ZXN0MzUxNDA1Mjk1",
      "number": 5173,
      "title": "[6.x] DRY up path to /home",
      "user": {
        "login": "taylorotwell",
// 以下略
```

- PRのURLは、`html_url`に(https://github.com/laravel/laravel/pull/5173)
- PR名は、`title`に([6.x] DRY up path to /home)

にあります。

なお、リクエスト時に指定するコミットハッシュはフル桁でなくても構いません。

# プライベートリポジトリの場合

`-H "Authorization: token xxxx"`を追加します。

```console
curl -H "Authorization: token xxxx" -H "Accept: application/vnd.github.cloak-preview" https://api.github.com/search/issues?q=is:pr+repo:(オーナー名)/(リポジトリ名)+sha:(コミットハッシュ)
```

トークンには、

- Settings > Developer settings > Personal access tokens

で、`Full control of private repositories`の権限を付けておく必要があります。

<img width="1013" alt="スクリーンショット 2019-12-16 18.02.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317369/43ed33c6-1bdc-03fb-c541-c4046854835c.png">
天井裏サーバーのすゝめ

自宅サーバーの置き場所って地味に困るけど、天井裏に置くといいよ！という話です。
140字以内で済む話ですが、いろいろ広げていきたいと思います。


#天井裏の環境

天井裏というとどんな環境を思い浮かべますか？

キタナイ、ホコリだらけ、湿ってる、温度変化が激しい・・・

コンピューターにとっては最悪の環境だという印象がありますよね。

確かに、木造住宅の天井裏はそんな感じだと思います。

しかし、鉄筋コンクリートマンションの天井裏は、想像よりずっと環境がいいです。

特に、ホコリに関しては住空間より少ないです。

自宅で天井裏サーバーを1年以上運用していますが、ファンにつくホコリがめっちゃ少ないです！


#天井裏へのアクセス

浴室の天井に、天井裏へアクセスできる点検口がある物件が多いです。
浴室は天井高が低くても気にならないことと、浴室乾燥機とそれにつながるダクトを設置する空間が必要で、それのメンテナンス需要もあって、「ちょうどいい作業性の良さ」がある感じです。

![DSC00151.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104360/722dc879-de63-edf3-2826-f0c8515b5a8f.jpeg)


ということで、浴室の天井裏にサーバーを置きます。

湿度が心配でしょうか？

自宅で実際に運用していて、湿度センサーで湿度ログを取ってみている限りでは全然問題ナッシングです。

となりで浴室乾燥機さんが元気に動いているので、コンピューターもきっと大丈夫です！

なお、初めてサーバーを置く際は、建築時のホコリ（主に石膏ボードの削りカス）があると思うので、掃除機で吸っとくといいと思います。


#電源と有線LANの確保

最大のネックはコレだと思います。

最近の間取りだと、浴室に隣接する脱衣所や納戸の天井付近に、宅内LANのハブがあることが多いと思います。メンテナンス性に考慮されている物件なら、配線がコンクリに埋め込まれてなく、天井裏への配線が割と自由にできるようになっていると思います。
そこから浴室の天井裏に配線します。

![DSC_0106.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104360/3c5c4485-e1be-3295-06f0-76207a8ac03b.jpeg)


ちょっと遠くて手が届かない場合は、マジックハンドを使うといいかも。100均にも売ってます。
（机の裏に落ちたケーブルを拾う時などにも便利なので、一家に一本あると便利です）
あるいは、針金ハンガーを伸ばしてなんとかするとか・・・。

ウチの場合は、納戸にもとからある配線穴は浴室から微妙に遠くて不便なので、納戸と浴室天井裏を仕切る壁に穴を開けましたｗ

![line1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104360/a0acaf46-012e-f10a-8cfa-1a236b788e04.jpeg)

![line2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104360/9f792e1b-0ec0-c42f-95f6-00a4e3b7d736.jpeg)

なお、物件によっては元から浴室天井裏に宅内ハブがある場合もあるようです。その場合は配線に困ることはないですね！

#天井板の強度

天井板は、めっちゃ弱々です！自重を支えることしかできないと思ってください！

となりの浴室乾燥機さんは、天井（天井板のさらに上にある、コンクリートの天井）にぶっ刺さされたボルトにぶら下がってると思います。

でもまあ、スリムPCぐらいは置けると思います。

心配なら、浴室の壁の板の上端にかかるように板を置いて、その上にサーバーを置くといいでしょう。曲げ強度より圧縮強度のほうが強いです。

ウチの場合は、スリムPCとHDD4本のNASを置いてて強度が心配なので、ちゃんと板を置いてます。

![P1000574.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104360/9b3a99dd-4e43-8cdb-7777-d72586436b78.jpeg)


（理想を言うと、浴室乾燥機さんと同様に、コンクリートの天井からボルトでぶら下げたいところですが、コンクリートの天井に穴を開けるのは分譲マンションであっても管理規約上ダメなところが多いと思います。）

#デメリット

ここからはデメリットについて書いていこうと思います。

##メンテナンス作業が面倒

なんらかのトラブル時や、部品交換増設などのときのアクセスが面倒です。家族が入浴中はどうにもなりませんｗ

トラブル対応については、ディスプレイケーブルや、キーボードマウス用のUSBケーブルを外だししておくと、若干捗るかもしれません。電源やリセットスイッチも引き出せるとモアベターです。

ただまあ、運用が安定しているサーバーを天井裏に移転するのがいいと思います。

##大きい機材は点検口から入らない

荒井注のカラオケボックスみたいなことにならないように注意してください。

##ダウンライトが邪魔かも

グレードの高いマンションは、浴室の照明がダウンライトなんだそうです。
そうすると自宅サーバーを置くのに不都合ですね。

ウチはダウンライトじゃなくて良かったなー！
\#ぴえん

##火災リスク

サーバーも電気機器なので、燃えることがあります。

住空間にあれば、燃える前に異臭や異音がして、早めに気づくことができますが、天井裏に置くと気づいたときには手遅れになってしまうかもしれません。

ウチでは念のための処置として、火災報知器を置いてます。

でもまあ、ホコリが少ないので、その分火災リスクは少なくなってるような気がしています。
あと、ウィークポイントは電源だと思うので、自宅サーバーには信頼性の高い電源ユニットを選ぶといいと思います。（天井裏に置く置かないにかかわらず）

#はみだし情報

天井裏は、災害備蓄品を置くのにもいいと思います。水は重いのでNGですが、トイレットペーパーなんかを置くのには最適です。

#おわりに

クラウドコンピューティングで幸せになれるこの時代に、私は、自宅にサーバーを置きたいのです！
Zabbix 4.4 と Redmine の連携

この記事は[SRA Advent Calendar 2019](https://qiita.com/advent-calendar/2019/sra)の19日目の記事です。

良いネタがあったので投稿することにしました。
2019年10月7日に Zabbix 4.4 がリリースされました。
https://www.zabbix.com/whats_new_4_4

4.4 では Zabbix Agent 2 の登場や TimescaleDB の正式サポートなど
様々な機能追加がありました。
4.4 に関する新規機能等のリリース情報は検索していただけたら、
沢山出てくると思うのでぜひ検索してみてください。

今回は 4.4 から新しくメディアタイプに追加された、
「webhook」を使った Redmine との連携について紹介していきたいと思います。

# webhook
まず最初に webhook とは何かを簡単に説明すると、
何かのイベント発生時に指定した URL に Post リクエストを送信する仕組みのことです。
(本当に簡潔すぎてごめんなさい)

今まで Zabbix で障害検知後に Slack や Redmine に通知を送るには少し手間が必要でしたが、
今回メディアタイプに webhook が追加されたことによって、それらへの通知がより簡単になりました。

# 設定手順
OS : CentOS 7.7
Zabbix 4.4.1 (Server, Agent 共に)

Redmine API を有効可
[管理] → [設定] → [API] の 「RESTによるWebサービスを有効にする」
にチェックを入れる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186780/bb9779e5-fb66-90f2-cada-8afcdc28a488.png)

次にZabbix 側の設定をします。
チケット登録用のメディアを作ります。
![createticket.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186780/91c2c0fa-ba7e-1a0a-2d4a-c517f4c3d30a.png)


tracker id を 確認する際は
xxx.xxx.xxx.xxx/redmine/trackers.xml 
で確認することができます。
API アクセスキーは個人設定の右側で確認することができます。
![redmineapi.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186780/5b7b790b-b1d0-3f53-52f4-fb74930af78a.png)

ちなみに Include event menu entry にチェックを入れておくと
障害のイベントメニューから指定した URL にリンクできるようになります。

スクリプトの中身はこちら
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186780/c31e9a00-40a3-792b-44e2-6a2390279574.png)



チケットを登録したら Zabbix 側には endpoint タグ と ticket_id タグが付きます。
endpoint タグは Redmine が、ticket_id タグには Redmine 側で自動採番された id が設定されます。

次にクローズ用のメディアを作ります。
![resolveticket.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186780/86123c51-df27-afc0-84bc-5f02c1a89e54.png)

スクリプトの中身はこちら
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186780/a6a5a183-467f-5129-ab64-63bbff71127b.png)

最後にアクションの実行内容にメディアに先ほど作成した「Redmine create ticket」を、
復旧時の実行内容に「Redmine resolve ticket」を指定します。

# 実際に動かしてみる
障害を発生させます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186780/b1e202e3-8e5a-3cdc-6b31-5d44bbc0c635.png)
そうすると Redmine 側にチケットを登録
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186780/d7b5429e-36b9-1bb6-404f-67dbf42cc8eb.png)
障害を手動クローズします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186780/8958e88c-ef5e-b217-32ea-a74b579ef2b6.png)
チケットに復旧時の内容が記載され、チケットがクローズ（解決）します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186780/1ba320fb-56b1-085b-b0fd-c1c75d008ecf.png)
以上が Zabbix 4.4 と Redmine の連携手順の紹介となります。
flaskで運用してるサービスににbasic認証をつけた日

[これ](https://gist.github.com/Raykeymas/e1a422ee8b4b9a37fdde181119d841de#file-flask-httpauth-basic-py)を参考にした。


```ruby:
| #必要なライブラリのインポート |
|:--|
| from flask import Flask |
| from flask_httpauth import HTTPBasicAuth #HTTP"Basic"Auth |
|  |
| #Flask、HTTPBasicAuthクラスのインスタンスを作成 |
| app = Flask(__name__) |
| auth = HTTPBasicAuth() |
|  |
| #"id":"パスワード" |
| id_list = { |
|     "Tanaka": "1111", |
|     "Suzuki": "1234" |
| } |
|  |
| #入力されたidに該当するパスワードを |
| #比較のために取得する |
| @auth.get_password |
| def get_pw(id): |
|     if id in id_list: |
|         return id_list.get(id) |
|     return None |
|  |
| #実際の処理部分 |
| @app.route('/') |
| @auth.login_required #ここで認証が行われる |
| #認証に成功したら以下の処理を実行する |
| def index():  |
|     return "Hello, %s!" % auth.username() |
|  |
| if __name__ == '__main__': |
|     app.run() |コード
```


###やったこと
もう動いているものがあったので、
①必要なライブラリをimportしたら、

```
@app.route('/') 
```
↑の処理部分直前に

```
@auth.login_required
```
を挟む。

②ID/PASSを任意のものに修正。

##参考
[ Raykeymas/flask-httpauth-basic.py](https://gist.github.com/Raykeymas/e1a422ee8b4b9a37fdde181119d841de#file-flask-httpauth-basic-py)
カレンダーAPIを使用して、スケジュールの参照・登録を行ってみた

LINEWORKS Advent Calendar 2019 / 17日目の記事です。

# はじめに
LINEWORKSで提供されているカレンダー機能について、
「予定を簡単に入力したい」「1週間分の予定を参照したい」というコンセプトで、
カレンダーの登録機能(Webアプリケーション)を作成しました。

# 作成した機能でできること
 - LINEWORKSカレンダーに登録されているスケジュールの表示
 - LINEWORKSカレンダーへのスケジュール登録
 - 
![カレンダー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541047/52d59b68-940c-0cdc-cd93-f12aa2fd3bdc.png)

# 使用したAPIなど
 - LINE_WORKS
   - サービスAPI
     - service/token
   - カレンダーAPI
     - calendar/getDefaultCalendarId
     - calendar/getScheduleList
 - AWS
   - CloudFront：SPAのコンテンツを配信
   - S3：SPAのコンテンツを保存
   - APIGateway：Lambda関数をAPIとして呼び出したい
   - Lambda：LINE_WORKSのサービスAPIを利用し、LINE_WORKSにアクセス
   - Cognito：認証で使用
 - その他
   - Vue.js：SPAでカレンダー機能のフロント部分を作成
   - vuetify：カレンダーの表示で大活躍
![アーキテクチャ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541047/f076a387-8c05-6443-97d2-d7d3cbb68df7.png)

# 感想
LINE_WORKSの管理者機能により、カレンダー機能(LINE_WORKS)のUIを自由にカスタマイズできると嬉しいなと思いました。スマホを普段あまり使わない人には、カレンダー機能(LINE_WORKS)で提供されている入力項目が少し難しいようです。
【SwiftUI】複数端末でのPreview

## Apple公式からのコピーです。
https://developer.apple.com/tutorials/swiftui/building-lists-and-navigation

```Swift
struct LandmarkDetail: View {
    var landmark: Landmark

    var body: some View {
        VStack {
            MapView(coordinate: landmark.locationCoordinate)
                .edgesIgnoringSafeArea(.top)
                .frame(height: 300)

            CircleImage(image: landmark.image)
                .offset(x: 0, y: -130)
                .padding(.bottom, -130)

            VStack(alignment: .leading) {
                Text(landmark.name)
                    .font(.title)

                HStack(alignment: .top) {
                    Text(landmark.park)
                        .font(.subheadline)
                    Spacer()
                    Text(landmark.state)
                        .font(.subheadline)
                }
            }
            .padding()

            Spacer()
        }
        .navigationBarTitle(Text(verbatim: landmark.name), displayMode: .inline)
    }
}


//ここ
struct LandmarkDetail_Previews: PreviewProvider {
    static var previews: some View {
        ForEach(["iPhone SE", "iPhone XS Max", "iPhone X"], id: \.self) { deviceName in
            LandmarkDetail(landmark: landmarkData[0])
                .previewDevice(PreviewDevice(rawValue: deviceName))
                .previewDisplayName(deviceName)
        }
    }
    
}
```