OmniAICreator/Qiita-1.07M huggingface dataset:
【設計時の見落とし】バッチ系とシステム系の考慮について

# はじめに
これは[設計時の見落とし Advent Calendar 2018](https://qiita.com/advent-calendar/2018/overlook)の25日目の記事となります。

業務アプリケーションの設計をするときに、見落としがちなところに焦点をあてて紹介します。 
下流工程からの手戻りを少なくして 双方の負担を減らしましょう。
バッチ系とシステム系について書いてみます。ただ元記事が10年前なので今となっては古いところがあるかも知れません。

## これまでの記事一覧

* [【設計時の見落とし】画面をクリアする](https://qiita.com/yaju/items/0e8ca1168089bd268caf)
* [【設計時の見落とし】システム日付にまつわる話](https://qiita.com/yaju/items/4c4ac71439f93700b763)
* [【設計時の見落とし】端数処理について](https://qiita.com/yaju/items/6c90e600f9ca7fb30eef)
* [【設計時の見落とし】請求処理系で指摘されたこと](https://qiita.com/yaju/items/fcf4dd328f68f3919562)
* [【設計時の見落とし】関連項目値の変更について](https://qiita.com/yaju/items/90704ccc1922a02a3215)
* [【設計時の見落とし】抽出処理系の考慮ついて](https://qiita.com/yaju/items/663eb65ff577057a8465)
* [【設計時の見落とし】画面系の考慮について](https://qiita.com/yaju/items/b771a5bad7c6430b4929)
* [【設計時の見落とし】帳票系とDB系とファイル系の考慮について](https://qiita.com/yaju/items/97e58ae45aae1bd523fe)


# バッチ系
## バッチ系の考慮点
1. いつ行うか（日次/週次/月次の処理頻度）
2. どの程度処理に時間がかかるのか(1回当たりの処理件数)
3. バッチ処理中はその期間内のデータ更新を不可としているか
4. 許容時間より処理がかかった場合はどうするのか
5. DB更新ならCommitする単位(件数)をどうするのか
6. ログ出力が考慮されているのか(異常箇所の把握)
7. 異常終了した場合の再実行の考慮をしているか(運用含め)<br>
再実行する場合、データ全体を処理前に戻して再実行する方法と、異常終了した時点から再実行する方法があります。
8. 仮処理(締め前に現在の集計結果をみたい)でバッチを流すことも考慮する(完了フラグを更新するかしないかの違い)

バッチの場合、バインド変数を使わずリテラルSQLにした方がいい場合もあります。
[【Oracle】クエリパラメータ(バインド変数)を使うとパフォーマンスが悪くなることもあるバインドピーク問題](https://qiita.com/yaju/items/dc0df5f32c0ea1a131b5)

## 日次バッチ
* 事前の入力が完了しているかどうかチェックする。<br>
入力が未完了なのに、集計しても意味がありません
* 二重実行かどうかチェックする。<br>
一日に二回実行すると二回集計されてしまい、倍の値が 入ってしまうのでは意味がありません。

## 月次バッチ・年次バッチ 
* 月に一度や年に一度の処理は忘れやすいので、忘れていることに気が付くような工夫があるといい。
* 事前の処理が完了しているか(月次バッチ未完了で年次バッチの処理はしてはいけない)
* 許容時間にかぎりがあるので、計算結果だけ専用テーブルに格納するなどの考慮するといい。

# システム系
## マスタの考慮点
* マスタ名に正式名と略名をもたせた場合に使い分けをはっきりさせる。
* マスタのある項目をある時をもって変更した場合に、 過去のデータを参照すると最新のマスタ内容で出力される。

マスタの履歴を考慮するとか、変更されることが考えられるマスタはトランデータにマスタの内容ごとセットするとかの考慮が必要。
マスタを変更すると過去のデータを参照した場合も、最新のマスタ内容で出力されることをユーザーに周知しておく必要がある。

## 採番の取得
**採番する単位をどうするのか？**
所属ごと分けるのか、全社共通とするのかなど

### 採番の飛び番の発生の確認
伝票番号など飛び番があると、あとで問題になることがあります。 
例外エラーの発生等により飛び番で作成されてしまう場合がありますので、ユーザーに了解を得ておく必要があるかと思われます。
ログなどで追える考慮は必要かもしれませんね。

※上場企業では伝票番号の飛び番は許されません、不正があると思われるため

## 途中登録の考慮
**途中登録をどうするのか？**
例えば見積入力画面では「保存」、「確定」の2つの状態が存在する。

業務担当者が忙しいなどの理由で完全な情報として登録出来ない場合には「保存」を行いデータベースに書き込む、この状態の場合には見積りとして確定させない。

## 戻し処理の確認
**順序を追って処理する場合、登録した行為を戻す処理を考えておく。**

≪例≫

* 受注して出庫した後の戻し
* 売上を計上した後の戻し
* 請求書を発行したけど、間違えてたから戻して再処理

どこまでシステムで対応するか、どこまで手で対応するか？
それとも放置なのか？

## アクセスログの確認
**アクセスログをどの単位で、どこまでとるのか？**
個人情報保護により調査する必要性も考慮し、かつ、アクセスログを取ることで動作が遅くならないか・・・などなど

## システム運用の確認
* データの保存期間はどのくらいとするのか
何年間まで保存するのかユーザに確認しておく
* サーバ機器電源のオン／オフ操作・データバックアップ処理(容量、サイクル等)
* ウィルスを検知するパターンファイルのダウンロード
* 配布・ウィルス検知処理・Windows Updateの更新

## その他
* DB名や変数名などのローマ字使用<br>
訓令式かヘボン式のどちらからに統一させる
* システム日付の統一<br>
DBを使うなら、DBのシステム日付に統一する。
* 伝票の修正伝票の打ち間違い処理方法<br>
赤伝票を発行して調整する。
* コードの始値の統一<br>
区分など項目値は0からか、1から始めるのか<br>
0:しない / 1:する<br>
1:する / 2:しない


# 最後に
[設計時の見落とし Advent Calendar 2018](https://qiita.com/advent-calendar/2018/overlook)の最後の記事でした。
参加して頂いた皆様ありがとうございます。

最後の3日くらいは箇条書き状態になってしまいました。本来はもっと一つ一つに焦点をあてて記事を書ければ良かったのですが、まだ至らないところです。
設計時の見落としについては、ネタがあればたまに書いていきたいと思っています。
ExpoはデフォルトでTypeScriptが使える!!!

![alt](https://user-images.githubusercontent.com/26253721/39765058-e8d0eae4-531b-11e8-9305-4c852f269517.png)

expoでtypescriptを使うのが簡単で感動したのでメモ

Expo31.0.0では、FlowからTypeScriptへの移行が進んだ。
そのため、.jsファイルを.tsや.tsxに書き換えるだけで、typescriptの導入が出来る!!!
babelをいじる必要なし！！！
yarn addいらない！！！
最高だ。Expo結婚してくれ。
ただルートファイルであるApp.jsだけは.jsのままにする必要がある。App.jsに.tsxファイルをimportするのは大丈夫。

##  まず何も考えずにexpoでアプリを作成。

```bash
$ npm i -g expo
$ expo init my-folder
$ cd my-folder
```

## tsconfigを作成
とりあえず以下をプロジェクト直下に記述。
設定の意味は、考えるんじゃない感じるんだ。

```json
// tsconfig.json
{
  "compilerOptions": {
  "outDir": "build",
  "rootDir": "src",
  "sourceMap": true,
  "noImplicitAny": true,
  "noUnusedLocals": true,
  "noUnusedParameters": true,
  "module": "commonjs",
  "target": "es6",
  "jsx": "react",
  "strict": true,
  "typeRoots": ["node_modules/@types", "screens/custom-types"], 
  "baseUrl": ".",
  "moduleResolution": "node",
  "esModuleInterop": true  },
  "include": ["./screens/**/*"],
  "exclude": ["node_modules"]
}
```


## 最後にreactとreact-nativeの型をインストールする

```
npm i -D @types/react @types/react-native
```

## 拡張子を.jsから.tsxに変えてみよう。
これでtypescriptを使い始められる。

```
expo start
expo ios
```
MockKでsuspend functionをモックした際にMockKExceptionが発生したのでメモ

[MockK](https://mockk.io/)はKotlinフレンドリーなMockingライブラリです。特徴は[こちら](https://mockk.io/#nice-features)にまとめられていますが、その一つに`mocking coroutines`があげられています。

## suspend functionのmocking

MockKを利用することでsuspend functionについても簡単にモックを作成できます。例えば次のようなinterfaceが定義されていて、Result型を返すとします。

```kotlin
sealed class Result {
    data class Success(val value: String) : Result()
    data class Failure(val exception: Exception) : Result()
}

interface UseCase {
    suspend fun execute(): Result
}
```

この場合次のようにモックを作成し、`coEvery`を使用することでsuspend functionである`execute`の戻り値を明示的に指定できます。

```kotlin
val mock: UseCase = mockk {
    coEvery { execute() } returns Result.Success("success")
}
```

## io.mockk.MockKException: Add coroutines support artifact…

`coEvery`を使用したテストを実行すると次のようなエラーが表示されテストが失敗します。

```
io.mockk.MockKException: Add coroutines support artifact 'org.jetbrains.kotlinx:kotlinx-coroutines-core' to your project 
```

`Add coroutines support artifact 'org.jetbrains.kotlinx:kotlinx-coroutines-core' to your project`とありますが、既にプロジェクトに追加済みの場合でもこのエラーは発生します。

## 対処方法

MockKのバージョンに`1.8.13.kotlin13`を指定することで上記の問題を回避できます。`dependencies`での定義は次のようになります。

```gradle
testImplementation 'io.mockk:mockk:1.8.13.kotlin13'
testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.0.1'
```

こちらのissueを見つけて無事解決できました。[^1]

https://github.com/mockk/mockk/issues/151

[^1]: 後から気づいたのですが、READMEには`1.8.13.kotlin13`がcurrentとしっかり書いてあるのでREADMEをとちゃんと読もう！という話だったりします。
Alexa APLのParametersについて

覚書。

## mainTemplateでのParametersの扱い
`.mainTemplate.parameters`に指定した変数でハンドルできるようになる。

```json
{
    ...略
    "mainTemplate": {
        "parameters": [
            "payload"
        ],
        "items": [
            {
                "type": "Container",
                "items": [
                    {
                        "type": "AlexaHeader",
                        "headerTitle": "${payload.bodyTemplate7Data.title}",
```


### parameterの型について
サンプルではstringの配列ですが、objectでの登録が推奨の様子です。

> 手間を省くため、パラメーターオブジェクトの代わりに単一のパラメーター名を使用できます（{ "name": "title", ... }の代わりに"title"など）。この形式は非推奨ですが、強制型変換やデフォルト値が不要な場合に用いることで、レイアウトの定義を手短に行うことができます。
> https://developer.amazon.com/ja/docs/alexa-presentation-language/apl-layout.html#parameters

なので以下の２つは等価です。

```
"parameters": ["payload"]

"parameters": [{
  "name": "payload",
  "type": "any"
}]
```

### ASK SDK(Node.js)からデータを受け取る

だいたいこんな感じでAPLのレンダーを指定します。
`document`でAPLのJSONを読んで、`datasources`のオブジェクトが`.mainTemplate.parameters`で指定した値に入ります。

```
   .addDirective({
        type: 'Alexa.Presentation.APL.RenderDocument',
        token: 'pagerToken',
        version: '1.0',
        document: require('./pager.json'),
        datasources: {
                examplePayload: {
                        title: "hello Alexa"
                }
        }
   })
```
これを受け取るにはこう書きます。

```
{
    "type": "APL",
    "version": "1.0",
    "theme": "dark",
    "import": [
        {
            "name": "alexa-layouts",
            "version": "1.0.0"
        }
    ],
    "resources": [],
    "styles": {},
    "layouts": {},
    "mainTemplate": {
        "parameters": [{
          "name": "payload",
          "type": "any"
        }],
        "items": [
            {
                "type": "Container",
                "items": [
                    {
                        "type": "AlexaHeader",
                        "headerTitle": "${payload.examplePayload.title}",
                        "headerAttributionImage": "https://d2o906d8ln7ui1.cloudfront.net/images/cheeseskillicon.png"
                    }
                ]
            }
        ]
    }
}
```

## layoutsでのParametersの扱い
layoutsで利用することで、再利用可能なコンポーネントを増やせます。

```
    "layouts": {
        "myFirstLayout": {
            "parameters": [
                {
                    "name": "title",
                    "description": "Title",
                    "type": "string",
                    "default": "Hello"
                }, "subTitle"
            ],
            "item": [
                {
                    "type": "Text",
                    "text": "<b>${title}:</b>${subTitle}"
                }
            ]
        }
    },
```

こちらで使う場合はデフォルト値なども指定できるようすです。stringのまま突っ込んでも動きます。
使うときはこんな感じ。

```

    "mainTemplate": {
        "parameters": [],
        "items": [
            {
                "type": "myFirstLayout",
                "title": "Hola",
                "subTitle": "こんにちは"
            },
```

このサンプルではあまりありがたみがないですが、ヘッダーフッターなどをちゃんと作り込んでいくなら必須でしょう。
レイマーチングでも遠景や角度のキツイカメラアングルを再現したかった

この記事は [WebGL Advent Calendar 2018 25日目](https://qiita.com/advent-calendar/2018/webgl)の記事です。

Tokyo Demo Fest2018の作品を作るに当たり目指したこと出来なかったことを書こうと思います。

# 概要
まずは TDF2018に応募した作品です。
https://www.shadertoy.com/view/MlyBRd
※非常に重いです
![image.png](https://qiita-image-store.s3.amazonaws.com/0/154377/33098624-b3db-46e8-9fe8-336357e0def8.png)

要素はたった２つ

- 雲
- 戦闘機

これだけです。
雲については以前書いた [レイマーチングで潜れる雲を作る](https://qiita.com/archeleeds/items/d99283212525eff182fc) を見てください。
ここでは戦闘機についてあれこれ書きます。

# 戦闘機
作品ではいくつか戦闘機が通過するだけでしたが、本来はこれらのドッグファイトを表現したいと思ってました。
しかし、一般的なレイマーチングでは難しい表現があります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/154377/ef2f8592-60e0-1356-dcef-05bd2a24c820.png)

それが物量と地平線です。
レイマーチングというと同じものを大量に表示するのが得意なイメージがありますが、
大量に表示出来るのはmod関数で量産出来る幾何学的な模様だけです。

戦闘機は（本来の目標では）空間を等間隔に並んで飛ぶわけではなく、敵機の後ろに張り付いたり逃げ回ったりするわけですからその分だけ戦闘機の距離関数の実行回数は増えていきます。
これは戦闘機の形状が複雑であれば複雑であるほど計算量が倍増していきます。

そこでざざーっと考えたのが戦闘機全体をすっぽり覆うだけの球体を定義し、その球体にレイがヒットしたら球体の半径分レイを戻し、そこからレイマーチングを開始するというものです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/154377/661b69e8-92a2-d83a-a931-d88e80bc4632.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/154377/836edb37-e9b3-d3f6-f249-1e4f5a8cd21f.png)

当たったらdepth color normalを返して他の色と合成します。
まぁifやらなんやら使いまくるので実際のところどっちが軽量かどうかは測定しないとわからないですが
メリットがいくつかあります。

## メリット
#### レイがオブジェクト周辺を横切っても霞まない
レイマーチングの特徴として描画するしないにかかわらずオブジェクト付近を通過するとレイのマーチ幅が減ります。
レイが戦闘機に届かなければ当然戦闘機は画面に表示されません。
![image.png](https://cdn-images-1.medium.com/max/1600/1*iKsvsAWcMVBq6zhi62rQxQ.gif)
これは冒頭のような手前から奥に見せたいシチュエーションを再現する際に非常には不利です。
mod関数を使える場合は一回の距離関数で判定出来ますが、戦闘機が十何機出て機銃やらミサイルやら表現しようと思ったらタダじゃすまないでしょう（多分）

#### Farを無視出来る
レイマーチングは上記の理由からそもそも遠景の描画には向いてません。
多くのレイマーチング作品でもカメラから一定距離離れると被写界深度Fogで誤魔化しているのがわかると思います。
しかし、この方法であればどんなに遠方であってもしっかり描画します。

#### オブジェクトの整理がしやすい
コードの書き方の問題になりますが、いくつもの距離関数の中に放り込んだレイが誰のかわからない距離やら法線やらを拾って帰ってくるのは稀に書いてる本人ですらそれがなにか忘れます。

# 遠景を表現したい
こちらは非常に簡単です。
TDF用の作品を作ったときの過程で生まれた作品です。
https://www.shadertoy.com/view/MtyfRc

![image.png](https://qiita-image-store.s3.amazonaws.com/0/154377/5ae9b4a0-25db-9254-6c36-76dfb296a94c.png)

考え方は上記と同じで、レイが付近のオブジェクトに引っ張られるなら当たるところまで無視ればいいじゃないというものです。
シェーダー芸を生業としている人にとっては言うまでもないテクニックだと思いますが簡単に図解を作りました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/154377/07ac5a6e-b6f0-2857-9a91-8b2f9c92cfb9.png)


# 他

来年はsin波を使った無限に続くterrainで遠景を作ろうと思います
#PowerApps で詳細リストからまとめリストを作成する

#今回やったこと
会社で使うランチマップ＆口コミまとめアプリを作成している中で、社員のレビュー一覧から、お店ごとの評価一覧をPowerApps上で作成した際のTIPSです。
社員のレビュー一覧はSharePointのカスタムリストで管理している前提で、
<u> **レビュー一覧側** </u> 
  { お店の名前, お店のID, 評価(1~5), コメント }

   から ↓ このような表を作成することを目指します。 

<u> **お店ごとの評価一覧側** </u>
  { お店の名前, 評価の数, 評価の平均 }

#セットアップ
サンプルとしてSharePointのカスタムリストは以下のようなものを利用します。
![SharePointList.PNG](https://qiita-image-store.s3.amazonaws.com/0/202779/2fed86e7-b080-4cb0-77fa-cedab36dcd2c.png)

レビューの一覧なので、お店の名前、お店のIDに重複があるリストです。別のリストで、評価の数や評価の平均を格納してもよいのですが、今回はなるべく管理するリストを減らすためにこの一覧のみで対応しました。

単純にPowerAppsでGalleryコントロールを用意して、各列を表示すると以下のようになります。
![AllItems-PA.PNG](https://qiita-image-store.s3.amazonaws.com/0/202779/5a7665a2-a78b-8a9c-fa0f-3d1aa7b396ab.png)

ここから、たとえば「コーヒーショップA」は評価数3, 評価の平均2.3 のような値を取り出します。

#まとめリストを作成する
重複を含むリストをいずれかの列で重複を排除するには、**Distinct** 関数を利用します。
関数の詳細は[Distinct 関数 - PowerApps | Microsoft Docs](https://docs.microsoft.com/ja-jp/powerapps/maker/canvas-apps/functions/function-distinct) こちらから。

今回はお店のIDでリストの重複を排除し、得られたID一覧から、再度元のリストを参照するような操作を行います。
まずまとめリストを表示するGalleryコントロールのItemsは
![DistList-Items.PNG](https://qiita-image-store.s3.amazonaws.com/0/202779/4225e43c-a637-9430-d13c-02c50a014b36.png)

```
Gallery.Items=Distinct(もとのリスト,重複を排除する列)
```
で指定します。この結果、Itemsには重複を排除した列の値が入ります。（この場合はShopIDが3つ入っています）

あとは、{ お店の名前, 評価の数, 評価の平均 } を、このGalleryコントロールの各アイテムに入っているShopIDから、もとのリストを参照することで表示させます。

お店の名前：```LookUp(レビュー一覧.ShopID = ThisItem.Result,Title)``` 
　※ThisItem.Resultに重複を排除した結果が入ります
評価数：```CountRows(Filter(レビュー一覧.ShopID = ThisItem.Result))```
評価の平均：```Average(Filter(レビュー一覧.ShopID = ThisItem.Result).Stars)```

![Field.png](https://qiita-image-store.s3.amazonaws.com/0/202779/5cfc01a7-f23f-f1ec-1a43-77cb57fd88fa.png)
以上で簡単なまとめリストがPowerApps上で作成されます。
**注意**：評価数と評価の平均では、Warningが出ていますが、これはSharePointリストがここで使っている、Average, CountRowsの委任をサポートしていないためです。（実際には期待通り動いています）

最終的には下図のようなリストができました。
![DistinctedList.PNG](https://qiita-image-store.s3.amazonaws.com/0/202779/8e6303ad-8136-f233-0237-81c53116f605.png)
【Unity(C#)】時間差の処理いろいろ

　　
　　
　　
この記事は

**『プログラミング完全未経験からUnityでの開発現場に迎え入れてもらえた世界一の幸せ者』**

の記事です。そのつもりでお読みください。
　　

##Invokeで秒数指定
`Invoke("メソッド名",秒数);`で指定した秒数後にメソッドを呼び出します。
いちいちメソッド作らないといけないのであまり使わないですが、
時間差の処理が少ないのなら一番手っ取り早いですね。


##Coroutineで処理を遅らせる
コルーチンはいろいろな条件を指定して処理を遅らせたり、中断したり、再開したりできます。
他にも`～秒後する`とか、`条件がtrueになったら再開`など非常に便利なので日々感謝してます。

  
便利な分、コルーチンの使い方は少しだけ面倒です。
まず、`IEnumerator 自分で考えたコルーチンの名前()`を書いて、その中に処理を書きます。
これだけでは、処理は行われません。コルーチンはスタートさせてあげる必要があります。


  
`StartCoroutine(自分で考えたコルーチンの名前())`でコルーチンがスタートします。
　　
コルーチンの名前は文字列にして指定してもOKです。
こんな感じ→`StartCoroutine("自分で考えたコルーチンの名前")`

 
コルーチンは中の処理をループして使用することで
同じ処理を一定間隔で繰り返すことができます。

そのため、コルーチンを止めたい方法も存在します。
~~`StopCoroutine(自分で考えたコルーチンの名前())`もしくは~~
`StopCoroutine("自分で考えたコルーチンの名前")`です。

>文字列でないタイプのStopCoroutineでコルーチンを止めるには以下のようにする必要があります。

>// ケース1
>var coroutine = StartCoroutine(自分で考えたコルーチンの名前());  // コルーチン開始
>StopCoroutine(coroutine);  // コルーチン停止

>// ケース2
>var ienumerator = 自分で考えたコルーチンの名前();
>StartCoroutine(ienumerator);  // コルーチン開始
>StopCoroutine(ienumerator);   // コルーチン停止
>のようにコルーチンメソッドの結果、もしくはStartCoroutineの結果を渡す必要があります

↑コメントにて修正頂きました！私のよりはるかにわかり易いじゃないか...ｗ

---
　　
私がよく使うのはこの三つです。

| コード       |       機能 |  
|:-----------------|------------------:|
| yield return new WaitForSeconds(秒数); |指定秒数待つ|       
| yield return new WaitUntil(条件); |条件がtrueで再開|   
| yield return new WaitWhile(条件); |条件がfalseで再開|   


###yield return new WaitForSeconds(秒数);
これが一番わかりやすいですね。指定した秒数後に処理を行います。

```C#
IEnumerator JibundeKangaetaYatsu()
    {
        yield return new WaitForSeconds(3.0f);
        //遅らせたい処理
    }
```
`JibundeKangaetaYatsu()`をどこかで
StartCoroutineしてあげれば3秒後に処理が走ります。


###yield return new WaitUntil(条件);
条件の部分がtrueになったらコルーチンを再開します。
これはコルーチンをループで回しながらも特定の条件で中断、再開させたいときに使えます。

ただし、条件の部分にはそのままbool型変数を入れられません。
デリゲートを指定する必要があります。
正直デリゲートとかラムダ式とか説明できるレベルまで理解してないので使い方だけ書きます。

`() => bool型変数 == true`と書けば
bool型変数がtrueになったときにコルーチンが再開します。
こんな感じ→`yield return new WaitUntil(() => a == true);`


###yield return new WaitWhile(条件);
条件の部分がflaseになったらコルーチンを再開します。
これもコルーチンをループで回しながらも特定の条件で中断、再開させたいときに使えます。

 WaitUntilと同様に条件の部分にはそのままbool型変数を入れられません。

`() => bool型変数 == true`と書けば
bool型変数がfalseになったときにコルーチンが再開します。
こんな感じ→`yield return new WaitUntil(() => a == true);`


---

###書いてて思ったんですがWaitUntilとWaitWhileって一緒じゃないの？
偉い人教えてください。私には同じ使い方しか思いつきません...

>条件が逆なだけで一緒のものです。
>否定を入れるとコードが読みづらくなるのでその配慮と思われます。

>// 文章が肯定： hogeobjectがアクティブな間止まる
>yield return WaitWhile(() => hogeobject.activeSelf);


>// 文章が否定： hogeobjectがアクティブでなくなってなければ止まる
>yield return WaitUntil(() => !hogeobject.activeSelf);


↑なんという親切設計...
[Python3] 重み付きでランダムに値を取り出す

## Python 3.6 以降
[random.choices](https://docs.python.org/ja/3/library/random.html#random.choices)を使う

```python
import random

target_dict = {"a": 3, "b": 4, "c": 2}
candidates = [*target_dict]
weights = [*target_dict.values()]

x = random.choices(candidates, weights=weights)[0]
print(x)
```

## 以前
[bisect](https://docs.python.jp/3.5/library/bisect.html)を使う

```python
import random
import itertools
import bisect

target_dict = {"a": 3, "b": 4, "c": 2}
candidates = [*target_dict]
weights = [*target_dict.values()]

accumulation_weights = list(itertools.accumulate(weights))
x = candidates[bisect.bisect(accumulation_weights, random.random() * accumulation_weights[-1])]
print(x)
```
Dockerでaws-cli環境を作ればアカウント切替が簡単に

# はじめに
aws-cli環境作成にあたりローカルを汚したくない。`--profile`オプションで切替めんどくさい。
そんな思いでDockerで環境作れないか試してみました。

# 実行環境
- ubuntu 18.10
- Dockerインストール済

# 1. Dockerfileの作成
- 軽量なalpineを選択。
- aws-cliのバージョンはお好きなものに変更してください。
- 取得したjsonを`jq`で整形したいなどお好みでインストール内容は変更してください。
- `PS1`はお好みの設定に変更してください。
    - 今回は起動時に指定するDockerホスト名を表示し、どんなaws-cli環境なのかわかるようにしています。
    - `[root@awscli-dev:/]$`と表示し開発環境のaws-cliのように見せてみました。

``` Dockerfile:Dockerfile
FROM alpine

ARG pip_installer="https://bootstrap.pypa.io/get-pip.py"
ARG awscli_version="1.16.76"

# Install dependent packages
RUN apk --update add \
    bash \
    python \
    curl \
    groff \
    jq \
    less

# Install awscli
RUN curl ${pip_installer} | python && \
    pip install awscli==${awscli_version}

# 入力補完
RUN bash -c 'echo complete -C '/usr/bin/aws_completer' aws  >> $HOME/.bashrc'

ENV PS1="[\u@\h:\w]$"

```
# 2. docker build
``` bash
docker build -t aws-cli .
```

# 3. 実行スクリプトの作成
- アカウント単位ですぐ使えるようにスクリプト化。
- `tmux`などで複数ターミナルを開けば同時に別のaws-cliを複数起動も。
- 起動したコンテナは`--rm`オプションでexitしたら削除しコンテナのゴミは残さないように。
- hオプションを付けてどんな環境なのかわかる名前を付けます。 ※複数実行した場合の作業ミス防止
- s3などでローカルディレクトリを利用したい場合は、Dockerfile作成時に作業ディレクトリを作成しておき `-v` オプションでマウントしても良いかも知れません。

``` bash:run.sh
AWS_ACCESS_KEY_ID="アクセスキー"
AWS_SECRET_ACCESS_KEY="シークレットキー"
AWS_DEFAULT_REGION="リージョン"

docker run -ith awscli-dev  --rm \
    -e AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID \
    -e AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY \
    -e AWS_DEFAULT_REGION=$AWS_DEFAULT_REGION \
    aws-cli /bin/bash
```

# 4. スクリプト実行
``` bash
# 実行権限はchmod +x run.sh
./run.sh
[root@awscli-dev:/]$ aws コマンド入力
```

# さいごに

- スクリプトを実行するだけで好きなアカウントのaws-cli環境に切替れるようになりました。
- `--profile`オプションでアカウント切替える面倒から開放されましたが、どちらが良いか個人差ありそうです。
- `awscli`でDocker環境つくりましたが`aws-shell`でも少しDockerfileを変更するだけでOKでした。
- ここまで読んで頂きありがとうございました。
ng test を実行した時にscssファイルのimportでエラーになる問題の解決方法

Angular を利用したプロジェクトで、`ng test` コマンドで Karma + Jasmine でユニットテストを行った際にハマったことの備忘録です。
本記事では、Angular のテストツールは Karma + Jasmineを想定しています。

## 問題
`ng test`を実行して、下記のようなエラーが出た場合を想定します。

```
ERROR in ./src/app/app.component.scss
Module build failed (from ./node_modules/sass-loader/lib/loader.js):

@import 'theme';
^
      File to import not found or unreadable: theme.
      in /Users/xxxx/project/src/app/app.component.scss (line 1, column 1)
 @ ./src/app/app.component.ts 16:21-52
 @ ./src/app/app.component.spec.ts
 @ ./src sync \.spec\.ts$
 @ ./src/test.ts
```

該当の scss ファイルは例として、下記のようなものを想定します。

```src/app/app.component.scss
@import 'theme';

h1 {
  color: $main;
}
```

インポート先のテーマ用 scss ファイルは下記とします。

```src/theme/default/theme.scss
$main: red;
```

app.component.scss の`@import 'theme';`のようにルート相対パスで記述するために、 angular.json の`architect.build.options`に`stylePreprocessorOptions.includePaths`に任意のパスを追加しています。　

```angular.json
"architect": {
  "build": {
    "builder": "@angular-devkit/build-angular:browser",
    "options": {
      "stylePreprocessorOptions": {
        "includePaths": [
          "src/theme/default"
        ]
      },
...
```

## 解決方法
`architect.build.options`と同様に`architect.test.options`に`stylePreprocessorOptions.includePaths`を設定します。

```angular.json
"test": {
  "builder": "@angular-devkit/build-angular:karma",
  "options": {
    "stylePreprocessorOptions": {
      "includePaths": 
        "src/theme/default"
      ]
    },
...
```

上記の記述を追加すると、`ng test`を実行すると、 Karma が動作するようになります。

## 参考

https://github.com/angular/angular-cli/issues/11212
MacでCython環境構築してたらOpenMPの設定で手間取った話

ついに念願のMacBook Proを手にしました！
一通り使い勝手のよさを味わったので，こちらでもCythonの作業環境を整えてみることにしました。

まあWindowsじゃないんだし`pip install cython`で一瞬だろうと思っていたら，OpenMPの設定で軽くつまずきました。

Cのコンパイラを最新版にして環境変数の設定をいじったところ動くようになったので，その時の対処方法を記事にしました。

# 環境
OS : macOS Mojave 10.14.1
Python version : 3.7.1
Cython version : 0.29.2

# Cythonのインストール後実行するも，コンパイルエラー

[前回の記事](https://qiita.com/tatamiya/items/d108f9e5f70b9683ef3d)で扱ったコードを実行してみたいと思います。
（使用コードは，[こちら](https://github.com/tatamiya/HPPython_Chapter7_9/tree/master/simple_sum)にアップしてあります。）


冒頭で述べたように，Cython自体は`pip install cython`の一瞬で入りました。
ただし，そこから`.pyx`をコンパイルしようとしたところ，うまくいきませんでした。


```
tatamiya$ python setup.py build_ext --inplace
（中略）
clang: error: unsupported option '-fopenmp'
error: command 'clang' failed with exit status 1
```

並列処理に使うOpenMPがどうやら入っていないか認識されていないようです。

# Cコンパイラを最新のものにする
調べてみたところ，macOSデフォルトのCコンパイラはgcc, g++ではなくclangというのが使われていて，こちらにはOpenMPがサポートされていないそうです。
（参考：https://qiita.com/ligerbolt/items/6e27c882838fdcc1a490）

なので，コンパイラを最新のgcc, g++に指定しました。

### 最新版コンパイラのインストール
```
tatamiya$ brew install gcc
```

さらに，[こちらのページ](https://qiita.com/wawawa/items/50c2c612b0937f28d92b)に従ってシンボリックリンクを作成しました。

```
tatamiya$ ln -s /usr/local/bin/gcc-8 /usr/local/bin/gcc
tatamiya$ ln -s /usr/local/bin/g++-8 /usr/local/bin/g++
```

### 環境変数の設定
ただコンパイラをインストールしただけでは動かず，環境変数もいじる必要がありました。
理屈はよくわからないのですが，vimで`bash_profile`に[こちらのページ](https://shinaji.bitbucket.io/2014/09/03/Cython_OpenMP.html)のように追記したら動くようになりました：

```:~/.bash_profile
export CC=gcc
export CXX=gcc
export ARCHFLAGS="-arch x86_64"
```

# 実行結果

```
In [1]: %run -t simple_sum_cython.py                                            

IPython CPU timings (estimated):
  User   :       0.01 s.
  System :       0.00 s.
Wall time:       0.01 s.
```

ちなみに，おおよそ0.01~0.02sくらいでした。
今までのWindows PCでの実行時間が0.5秒程度だったことを考えると，少なくとも20倍は速くなってます。
さすがMacBook Pro!

# 参考サイト
https://shinaji.bitbucket.io/2014/09/03/Cython_OpenMP.html
https://qiita.com/wawawa/items/50c2c612b0937f28d92b
https://qiita.com/ligerbolt/items/6e27c882838fdcc1a490
CppUMockの使い方これで合ってる？

#CppUMockを使ってみたい

説明を読んでもCppUMockの使い方がよく分からなかったので実際にやってみた。
自分でモックを書いてもいいが公知の技術であるCppUMockを使うとオレオレ実装よりも他の人に理解してもらいやすいというメリットがあると思う。
https://cpputest.github.io/index.html
執筆時点のバージョンはCppUTest 3.8であった。

##単純な呼び出し検査

これは説明通りなので特にハマりどころはないと思われる。

```c++:test.cpp
#include "CppUTest/TestHarness.h"
#include "CppUTestExt/MockSupport.h"

TEST_GROUP(Sample)
{
void setup() {}
void teardown()
{
	mock().clear();
}
};

// 製品コードを呼ぶ代わりにこの関数を呼ぶようにしてMockに記録する
void production()
{
	mock().actualCall("production");
}

TEST(Sample, SimpleCall)
{
	// ここで１回呼ばれる事を期待するよう設定している
	mock().expectOneCall("production");

	// このテストが成功する条件はこの関数が１回呼び出される事となる
	production();

	// テストの評価：ここでは関数が１回呼び出されていればテスト成功
	mock().checkExpectations();
}

```

##戻り値がある関数の検査

製品コードからの戻り値をコントロールしたい場合などに使うことができる。呼び出す事を期待するときに`andReturnValue(int value)`メソッドなどを使ってその関数の戻り値を制御することができ、戻り値はモック側の`returnIntValue()`メソッドなどに渡されて利用できる。型ごとに戻り値のバリエーションが用意されている。また、期待側で戻り値を明確に設定しなかった場合にデフォルトの戻り値をモック側で用意する方法も用意されている。例えば`returnIntValueOrDefault(int default_value)`など。自分としてはandReturnValue(Hogehoge)がreturnHogehogeValue()に渡されるという風に説明してくれたらわかりやすかったなと思うなど。あれ？書いてあった？

```c++:test.cpp

int intProduction()
{
	return mock()
	.actualCall("intProduction")
	// andReturnValue(int)で設定された戻り値を受け取る
	.returnIntValue();
}

TEST(Sample, ReturnValue)
{
	int ret;
	mock().expectOneCall("intProduction")
	// 戻り値をここで制御することができる。
	.andReturnValue(1);
	ret = intProduction();
	CHECK_EQUAL(1, ret);
	mock().checkExpectations();
}

```

##パラメータのある関数の検査

パラメータを持つ関数のパラメータに期待値を設定することができる。これもパラメータの型ごとにメソッドが用意されている。

```c++:test.cpp
void parameterProduction(int prm)
{
	mock()
	.actualCall("parameterProduction")
	.withIntParameter("prm", prm);
}

TEST(Sample, Parameter)
{
	mock().expectOneCall("parameterProduction")
	.withIntParameter("prm", 1);
	parameterProduction(1);
	mock().checkExpectations();
}

```

##オブジェクトを渡す？

これは使用例にすぎないと思う。最初の単純な呼び出しを間接的に使っているだけでやっていることは同じだと思う。

```c++:test.cpp

class ClassFromProductionCode
{
	public:
	virtual void importantFunction()
	{
	}
	virtual ~ClassFromProductionCode() {}
	};

class ClassFromProductionCodeMock : public ClassFromProductionCode
{
	public:
	virtual void importantFunction()
	{
		mock().actualCall("importantFunction");
	}
	virtual ~ClassFromProductionCodeMock() {}
};

TEST(Sample, Object)
{
	mock().expectOneCall("importantFunction");
	ClassFromProductionCode *obj = new ClassFromProductionCodeMock;
	obj->importantFunction();
	mock().checkExpectations();
	delete obj;
}

```
2018 に読んだチーム系の本おすすめ3選

あと12分で書かなくては間に合いません。Advent Calendar 2018 Plaidの最終日に詰め込んでいただきました @nashibao です。去年に続いて今年も本の紹介をしてお茶を濁そうと思います。お勧めが5選から3選に減っているのはめんどくさがったわけでは決してありません。


# 1位: HIGH GROWTH HANDBOOK

<img width="1235" alt="スクリーンショット 2018-12-25 23.51.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/4850/f6ce8899-acb1-8a29-d245-31a3bc5f43fa.png">
[link](https://www.amazon.co.jp/High-Growth-Handbook-English-Elad-ebook/dp/B07DRPGGQ7)

開発に限らないですが、スタートアップでぶつかる組織的な課題の多くが網羅されている本です。Board Memberのマネージメントからプロダクトマネージメント、ファイナンスやM&Aについてまで（！）の話題を広く拾ってくれています。価値が高いのは、有名スタートアップの経営者のインタビューが各章に詰め込まれているところです。必見の書です。僕は個人的にマーケットはもちろんのこと、ファイナンスや組織形成あたりも含めてプロダクト計画に含むべきだと思っているので、こういう本で接合点を提供してもらうのは非常に為になります。


# 2位: エンジニア組織論への招待

<img width="1105" alt="スクリーンショット 2018-12-26 0.02.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/4850/f858e0d7-2e28-1dd8-ec36-306268ea0214.png">
[link](https://www.amazon.co.jp/dp/B079TLW41L)

不確実性が強く絡む問題としてエンジニア組織に関する問題（に限らない気がしたけど）を定義して、それに対するアプローチ方法をまとめているのが俊逸で本当によく完成された本だと感じました。人の認知の問題にも深く入り込んでいるのが共感しました。
個人的にも、"時系列変化し超高次元でさらに観測もほとんど出来ない環境での最適化"として組織を考える向きがあるので、その嗜好ともあっているところがありました。


# 3位: 超「個」の教科書

<img width="1122" alt="スクリーンショット 2018-12-26 0.12.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/4850/f23e9490-9fe0-4bd1-8f93-9eb9ee4e989f.png">
[link](https://www.amazon.co.jp/dp/B074C37KFR)

「組織を作ることで個を生かす」のではなく「個を生かすことで組織にする」ことをゼロベースで考えて実際に実践している風間監督の本。弊社もレアルマドリッド組織というのを半分冗談半分本気で言ってますが、本当に何かを突破するのは個人でしかない場合が多いと思うので、どのように「個」に対して考えるかを研ぎ澄ます必要があると思い読んだ本です。サッカー起点なので他の本とは異なった視点の話が多く非常に刺激になります。また、目的思考が非常に強い方だと思うので、その点でも面白いかと思います。

# 最後に

今年は対して本を読まなかったですが、上記の本はどれも当たりで豊作の年でした。それではみなさん良いお年を。
強化学習の今後

## Intro
すっごい短い記事ですいません。

今強化学習のいろんな側面に焦点を当てて学習をしてます。
今まとめている限りでは、下記のような感じです。

- ベーシックな強化学習
- MARL
- MORL
- Safe RL
- Transfer RL

そしてレポにまとめているので、もし、もっとこんな角度で研究が進んでいるよっ！！っているのがございましたらコメントなどいただけると幸いです。
ほぼliterature reviewばかりですが、、よろしくお願いいたします。

## URL
https://github.com/Rowing0914/Reinforcement_Learning
Ruby on Railsチュートリアルで躓くところ

#はじめに
Ruby on Rails チュートリアル ( https://railstutorial.jp/ )を実習中の際に引っ掛かった箇所を備忘録として残しておきます。

#前提
クラウドIDE(AWS Crowd9)を使用します。そのために発生する躓き対策が主です。

#引っ掛かった箇所

##herokuコマンドにパスが通っていない
チュートリアル中断の翌日、２章の途中から開始したために遭遇しました。

###対処
要はパスを通す処理が一時的なため、（１章のリスト1.15で以下のようにパス通しの処理をしていますが）

```bash:
$ source <(curl -sL https://cdn.learnenough.com/heroku_install)
```
・・・ですよね？　なので素直に上記コマンドをクラウドIDEのターミナルで打ち直しました。

###対策（調査中）
`curl`で得られる`heroku_install`スクリプトの中身をbash起動時のスクリプトに追記すればいいはずなんですが、`.bashrc`と`.bash_profile`のどっちが正しいのか調べ中。

##以下、遭遇したら追記します。
LINE Messaging APIノードを作ってみたけど設計ミスだった話 #enebular


少し前のNodeRED UGのイベントで登壇した時の話です。

<script async class="speakerdeck-embed" data-id="4a9682773b864fccafdb1869115f41a0" data-ratio="1.33333333333333" src="//speakerdeck.com/assets/embed.js"></script>

> アドベントカレンダー迎撃で書いたけど不発で終わりました（良き）

## LINE Messagin APIノードを作った

https://flows.nodered.org/node/node-red-contrib-line-messaging-api

![](https://i.gyazo.com/b580097a4050144728345667e4523717.png)

こんな雰囲気です。

## なぜ作ったか

授業とかやるタイミングが多くて、手軽にLINE BOT作成試して欲しいなぁという気持ちです。

* 高専生などの授業だと開発環境がバラバラ
* プログラム出来る人とできない人がいる
* 時間は90分などと限られている

みたいな感じだとNode.jsの環境用意してngrokで...ってのも結構辛い部分はあります。

[このハンズオン](https://qiita.com/n0bisuke/items/ceaa09ef8898bee8369d)みたいに、みんなエンジニアっていう前提だといいんですけどね。

## シンプルに......を追求したら使い勝手が悪くなってしまった

どれくらいシンプルかというと

![](https://i.gyazo.com/1da6ce2060ccf370286fbfe7cd303d8c.png)

これだけでおうむ返しBOTが作れます。

シンプル！

ただしシンプルすぎて変更の余地がなくなってしまってハンズオンなどで早く終わった人が応用としてカスタマイズするといったときの使い勝手が最悪になってしまいました。

この辺はNodeREDのノードのデザインパターンを学んだほうがいいなと反省中。

ただ、ノード作り直すのも結構しんどい（書いた時のやり方けっこう忘れてる）ので...(次に続く)

## enebularのLINE Messaging API向けのフローも作ってみた

ので取り急ぎはこっちを使って最初試すとよさそうです。enebularオンリーですが！

> https://enebular.com/discover/flow/80f9970e-2224-4d39-a4d1-9d252b7ae4d8

enebularは作ったフローをフローごと公開する機能があるので、とりあえずこんなイメージになるといいなぁという内容でLINE BOTのフローを作ってみました。

### 実際に使う場合

`linebot-sample-flow`という名前でenebularで`discover`する or ↑のURLからenebularの自分のプロジェクトに追加していじってみましょう

![](https://i.gyazo.com/d44601da4a130dc92ea67c4a9dceb397.png)

## まとめ（何がいいたかったか）

この記事で何が言いたかったというと（走り書きだったので）

* 1. ノード作成をする前にこんな使い勝手だといいなぁというイメージをする
* 2. イメージを一旦形にして公開、使ってみてもらう
* 3. 使ってみてもらってフィードバックもらう
* 4. フィードバックを得て改善などある程度したら実際にノードを作ってみる

(色々なアプリやサービスなども含めて)こういった流れで作ると思いますが、この2と3の部分を実際にノードを創り込まなくてもフローでやれるってところがenebularの利点にもなるのかなぁと思いました。

通常のNodeREDもjsonでシェアとかはできるんですけど、それってGoogle Play通さないでapk落としてねってのと同じだしDL数とかも分からない（enebularだとフォークされた数が分かる）ですからね。

**ノード開発する人はまずenebularでテストマーケ！** って感じですね。

参考になれば幸いです！
フランスsim: Orange Holiday Europeの購入・使用方法まとめ(2018/10)

仕事柄よくパリに行くのですが，その都度現地でOrange SIMカードを使ってきました。２年前までは一度買ったSIM(pass let's go)をずっとリチャージして使っていたのですが，simの仕様変更があったのかいつからか使えなくなり，最近では現地で短期旅行者用のsimを毎回買うようになっていました。

そのsimではwebでのリチャージ方法が見直されていたようで，以前はフランス国内で発行されたクレジットカードしか受け付けてくれなかったものが（当時は毎回Orangeの店舗に行って店員さんにリチャージしてもらってた），現在は国外のクレジットカードでもwebからリチャージできるようになっていました。

というわけで一気に利便性が向上したように思うフランスのOrange SIMですが，私が前回使ったOrange Holiday Europeの設定方法を今回まとめます。

# APNの設定

モバイルwifiともなればAPNの設定が必要となります。Orangeの店舗であれば店員さんが自らやってくれることもしばしばなので，やってもらうかもしれない人は端末の言語を英語化してくと良いかも。各項目は次の通り（ただしSIMロックされた端末ではこの設定を変更できないので要注意）。

APN: orange.fr
ユーザー名: orange
パスワード: orange
認証方式: CHAP

# Orange SIMカードの購入

このsimカードは国内でも入手可能です。Amazonだと割高ですが，<a href="https://www.obonparis.com/ja/magazine/orange">O'bon Parisのwebページ</a>だと定価で購入できるらしいです（ただし受け取りまでが長い）。出発前に購入できる安心感は大きいかと思いますので，不安であれば購入することをオススメします。

フランス現地では，Orange店舗に行けばOrange SIMカードを購入することができます。Orangeショップはそこら中にありますが，ただ大きなメトロの近くだと訪れる人はその分多くなるため，自分の番になるまで長く待つことになります。ここら辺は国内のキャリアショップと同じですね。

あとOrangeは，2018年10月時点でCDGのTerminal 2EのBaggage Claimにも出店していました。私は前回そこでsimを買ったのですが，店員さんも手際が良く，ものの数分で購入できてしまいました（なおここではパスポートの提示は不要でした）。JAL便でパリに来る人たちにとってはこの店舗はかなり使いやすいのではと思います。通話回線は未使用なので分かりませんが，データ通信はすでにアクチベーション済みのため，SIMを差してAPNの設定を行えば，モバイルネットワークもすぐに利用可能です（初回通信時から利用期間の積算開始）。

【オレンジ色の店舗の隣がOrangeのCDG T2E分店】
<img width="300" alt="terminal1.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/327826/77e5a7a4-8d56-cba4-5ad2-f0e42659ebb3.jpeg"> <img width="300" alt="terminal2.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/327826/80845453-97bb-7dd2-b975-f3d0eba8795a.jpeg">

# Orange SIMへのwebでのリチャージ（topup）方法

かつてのOrange SIMはフランス国内のクレジットカードでしかリチャージできませんでしたが，2018/10時点では国外のクレジットカードでも決済できるようになっていたので利用してみました。

アクセスURLは下記のwebページ。ここでOrange Holiday SIMの電話番号を入力します。

<a href="https://topup.orange.com"><img width="500" alt="sim0.png" src="https://qiita-image-store.s3.amazonaws.com/0/327826/e0bebe7d-1644-7475-de8c-f826cbd28769.png"></a>

すると通話時間とデータ通信の容量，利用期間に応じたプランを選択します。

<img width="500" alt="sim1.png" src="https://qiita-image-store.s3.amazonaws.com/0/327826/6982cbf9-2c4b-94e3-58a6-b75eeab357d5.png">

氏名とメールアドレス，パスワードを入力し，SMSを通して本人確認をします。私の場合はモバイルwifiを利用していたので，SMSには日本国内のモバイル回線を一時利用しましたが，おそらくOrange Holiday SIMの番号でも大丈夫でしょう。

<img width="350" alt="sim2.png" src="https://qiita-image-store.s3.amazonaws.com/0/327826/7ebf7790-8852-d5b7-dea5-28a57209b12c.png"> <img width="250" alt="sim3.png" src="https://qiita-image-store.s3.amazonaws.com/0/327826/5759d8f5-b896-acd7-9365-696821cf8f07.png">

決済価格を確認して確定すればリチャージ完了です。リチャージまでかなり簡単なので，長期間の滞在でも繰り返し使うことができるでしょう。ただその場合は，webページ中のOrange Holiday SIM > Registar your SIM Cardから個人情報を登録してパスポートの写しを送付しておいた方が良さそうです。短期間の利用でも念の為登録しておいた方が良いかもしれません（過去にOrange店舗でSIMを購入した時にもパスポートのコピーを用いて登録していたので，その代わりのようです）。

<img width="270" alt="sim4.png" src="https://qiita-image-store.s3.amazonaws.com/0/327826/bffb21ed-94d4-7609-7259-f43e82504ba0.png"> <img width="330" alt="sim5.png" src="https://qiita-image-store.s3.amazonaws.com/0/327826/f956bbc4-bd83-67b4-efbb-1e627d188894.png">
正の数なら1,負の数なら-1,ゼロなら0を返す式

```swift
// aはある数
let result1 = a > 0 ? 1 : (a < 0 ? -1 : 0)

let result2 = a == 0 ? 0 : Int(a / abs(a))
```

これらよりいい式ありますでしょうか？
初学者検索機能がんばる

何を検索できるようにしたい？

タイトルを入力したらその本の情報が出てくる
著者名を入力したらその本の情報が出てくる
あいまい検索したい（今回初めて知りました）
複数の入力で検索をできるようにする

## 検索画面の表示部分

```header.html.rb
          <%= form_with(url: '/search', local: true, method: :get) do |form| %>
            <%= form.text_field :search_key %>
            <%= form.submit 'ぼたん' %>
          <% end%>
```
デフォルトがpostなので`method: :get`でgetを指定する

form_with で生成されたフォームは、デフォルトで非同期で送信される。それを避けるために`local: true`を指定しないとform_withがどの場所で処理を行えばいいのかわからなくなってしまう
## table

```db/migrate/books.rb
   def change
    create_table :books do |t|
      t.string :title
      t.string :author
```
タイトルと著者名をとってこれる

## controller
```controller.rb
    def search   
      # 検索結果をurlに埋め込むのと、モデルで部分一致させる検索結果を送るための処理
      @books = Book.search(params[:search_key])
      if @books
        redirect_to "/search/#{params[:search_key]}"
      else
        @books = Book.all
        redirect_to "/search/#{params[:search_key]}"
      end
    end

    def search_page  # 検索結果を表示させるページのコントローラーです！
      search_key_word = params[:search_key]
      @books = Book.where('title LIKE ? OR author LIKE ?', "%#{search_key_word}%", "%#{search_key_word}%")    # titleかauthorのカラムどちらかと部分一致すれば取り出す
      if  @books.empty?
        @book_not_found_message = 'キーワードに該当するページが見つかりません'
        render 'search_page'
      end
    end
```
```ruby
# booksテーブルのtitleカラムに部分一致したレコードを返す
Book.where('title LIKE ?', "%#{search_key_word}%")
``` 
```ruby
# booksテーブルのtitleカラムもしくはauthorカラムに部分一致したレコードを返す
Book.where('title LIKE ? AND author LIKE ?', "%#{search_key_word}%", "%#{search_key_word}%")
```


## model
```app/models/application.rb
  def self.search(search) #selfはBook
    if search
      where(['content LIKE ?', "%#{search}%"]) #検索結果がcontentと一部でも一致するかどうかをみて一致するものがあればそれをwhereで受け取るはず
    else
      all #全て表示
    end
  end
```
```ruby
# この部分に対する私の認識は儀式
where(['content LIKE ?', "%#{search}%"])
```


### 反省
二つ以上のテーブルを対象に検索することを複数検索だと思ってたけどそんなわけないですね。やはり理解していなかったので気付けてよかった

## 参考にさせていただきました

[railsで複数ワードでの検索機能(or)とマイナス検索機能(-)を実装してみる]
(https://qiita.com/Orangina1050/items/ca4e5dc26e0a32ee3137)


よんでくれてありがとう
Metcalf's Law (メットカーフの法則)とは？

ネットワークに関する（おそらく）基本的な法則のひとつである．

[Wikipedia:メトカーフの法則](https://ja.wikipedia.org/w/index.php?title=%E3%83%A1%E3%83%88%E3%82%AB%E3%83%BC%E3%83%95%E3%81%AE%E6%B3%95%E5%89%87)によれば...

> 「**通信ネットワークに関する法則で『ネットワーク通信の価値は、接続されているシステムのユーザ数の二乗（$n^2$）に比例する』という**」

と書かれている．

まぁそうなんだが，もう少し詳細に記載してみようかなと...
注：厳密さにかける説明になっています．コメントでご指摘ください！！！

## 仮定と説明
とりあえず，

* $U_i = u(N)$　：　ユーザー$i$にとっての効用$U_i$は，$N$の関数，つまりネットワークのノード数によってきまる．
* $u_i'(N) > 0$ 　：　ユーザー$i$にとっての効用$U_i$は，正である．
* $i \in N$　 ：　ユーザー$i$は$N$に含まれる　

とします．

そして，
1. 全てのユーザーは対照的である．（互いに全てのノードにつながっていることを意味）
$u_i(N) = u(N)$
2. 全てのユーザーは区別されない．（ノードは全く同じであるから，その数のみで説明される）
$u_i(N) = u(n), where n = |N|$
3. ネットワークの価値は，加えられたものである．
$V = \sum_{i \in N} u(n) = n* u(n)$
4. それぞれの個別の価値は，線形である．
$u(n) = cn$    $c$:価値の定数

とした場合において，このネットワークの価値は以下のようにかけます．
<b>$V=cn^2$</b>

ということで，メットカーフの法則はこうなったわけですね．

> 「そのネットワークの価値は，$n^2$に比例する」

## 余談：ビットコインの話

ビットコインの価値は，これによって示せそうですねって話があります．
あくまで，メットカーフの法則は，すごく理想的な状態の上で成り立っています．
なので，だいたいこんな法則があるんじゃない？ってぐらいの気持ちで考えましょう．


さて，ビットコインのみならず，仮想通貨の市場は
> <b>（板に乗っている）ウォレットをノード，取引のできるコネクションをエッジ</b>

としたネットワークとして考えることができます．取引所ごとにエッジがあるため，取引所ごとにネットワークが構成されます．

そして，
それぞれのウォレットは，どのユーザーとも取引が可能です．
言い換えると，どの他のウォレットともつながっています．（1つ目の仮定は成り立ってますね．）

それ以外の3つの法則に関しては，過程が成立するとは言い切れません．
でも，まぁそういうことが成り立つ可能性もあります．

利用者数，もしくは，取引数によって価値が変わっていくっていうことなんじゃないでしょうか？チャートとかを眺めてみるとそんな気配があります．気が向いたら，計算してみようかな．
（あとは，これの法則で説明しきれない増減の部分は，それぞれの取引額とかどれだけお金を持っているウォレットなのかっていうので説明できるんじゃないでしょうか？）

つまり，利用者数が一気に増えそうなとき，取引が増えそうな時にその市場の価値が高まる
$\Leftrightarrow$ ビットコインの価格が上昇する．ってことになるのかもですね．
UIStackViewのspacingを個別に指定する方法

#UIStackViewの`spacing`
UIStackViewの`spacing`は一度値を入れるとずっとその幅でレイアウトされます。
これを一つのstackViewで、viewとviewの間ごとに空白の幅を指定できるようにします。

#手順
##1. sizeだけを持つUIViewのカスタムクラスを作る
以下をコピペ

```
import UIKit

final class SpacerView: UIView {
    
    private let space: CGFloat
    
    init(_ space: CGFloat) {
        self.space = space
        super.init(frame: .zero)
    }
    
    override var intrinsicContentSize: CGSize {
        return .init(width: space, height: space)
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}
```

##2. 使う
`.spacing`の指定はせず、`SpacerView`の`initializer`からサイズの指定をする

```
let stackView = UIStackView(arrangedSubviews: [
        view, SpacerView(5), view, SpacerView(10), view, SpacerView(20), view
])
```
Windows Server 2016 OS日本語化

## はじめに
 [Rosso Advent Calendar 2018](https://qiita.com/advent-calendar/2018/rosso)の２５日目の記事になります。

AWS環境で、WindowsServer2016英語版をOS日本語化する必要がある場合があるため、
備忘録として残しておきます。
※すでにいろんなところでWindowsServerOS日本語化の手順があるので、そちらを参考に
させていただきました。

## GUI操作手順
1. Windows Server 2016(英語版）　EC2インスタンスをデプロイさせる。
1. クライアント端末（WindowsOS/MacOS)からリモートデスクトップ接続する。
1. ［Windowsキー］→［Control Panel］をクリックする。(Control Panelが表示される。）
1. [Clock, Language, and Region]→［Add a Language]をクリックする。
1. 右真ん中付近の［Add a Language]をクリックする。
1. [Add a language]画面が表示されるので、[日本語］を選択する。
1. [Language]の設定画面に戻るので、［日本語］の項目が追加されたことを確認する。
1. [日本語]の項目行を選択し、[Move up]をクリックする。（言語の順番が上から日本語、English(United States)になること）
1. [日本語]項目行の右側の[Options]をクリックする。
1. [Language options]の画面が表示されるので、[Download and install language pack]をクリックする。
1. [Download and Install Updates] が表示され、日本語言語パックのダウンロードおよびインストールが開始される。
1. 項番11のインストールが完了すると、［Installation complate]のメッセージが表示されるので、［Close］をクリックして画面を閉じる。
1. [Language]の画面に戻るので、[Change date, time, or number formats] をクリックする。
1. [Region] メニュー画面で [Location]タブをクリックし、［Home location］プルダウンより［Japan]を選択する。
1. [Region] メニュー画面で [Administrative]タブをクリックし、[Copy settings] をクリックする。
1. [Change Regional Options] のポップアップが表示されるので、[Apply] をクリックする。
1. [Welcome screen and new user accounts setings] のメニューが表示されるので、以下２つのチェックボックスにチェックを入れる。
      - [Welcome screen add system accounts]
      - [New user accounts]

1. [Change Display Language] の画面で [Restart now] をクリックしてOSを再起動させる。

※OS再起動後、システムロケールの設定などを行います。

## 参照元
サーバーワークス様の以下のサイトを参考にさせていただきました。ありがとうございました。　
[Windows Server 2012 R2英語版の日本語表示](http://blog.serverworks.co.jp/tech/2016/06/20/windows-server-2012-r2-japanese-localization/)
Rails Girls Nagoya more!を振り返る。（オフライン勉強会から、オンライン勉強会へ）

この記事は、[Rails Girls Japan Advent Calendar 2018](https://qiita.com/advent-calendar/2018/railsgirlsjapan)最終日の記事です。
Ruby2.6リリースされましたねー！

そして、昨日は、emorimaさんの「[2019年よりオンラインでRubyチャレンジ始めます!](https://emorima.blogspot.com/2018/12/rgadventcalendar24.html)」でした。

## いちおう自己紹介

@yadaita です。Nagoya 1st〜4thのオーガナイザーです。
くまモン好きです。（来年福岡で開催されるRubyKaigiに参加して、
そのあと熊本まで足伸ばそうと考えてる程度には、くまモン好きです。）
あと、関西圏で開催されているRails Girlsでも、コーチでお手伝いしたりしています。
と、いいつつ、今年はOsaka5th(コーチ)くらいしかお手伝いできず…。
来年は少し余裕ができる（はず）なので。Japan業務含めて色々とお手伝いできるよう頑張ります・・・！

## Rails Girls Nagoya more!を振り返る。
今年は何を書こうかな・・・と考えていたのですが、17日目、
cobachieさんの[Rails Girlsのつづき - 「Rails Girls, more!」](https://note.mu/co_bachie/n/ne47cbe8a8c5b)を見ていて、
ふと書きたくなった、Nagoya more!のネタです。

Nagoya more!は、今はオンラインが中心ですが、始めた当初はオフラインでした。
どうやって、オフライン勉強会から、オンライン勉強会へと、変わっていったのか
過程をざっくり振り返ってみよう。と思います。

### 始まりはオフライン・主にお菓子の会
元々のスタートは、Rails Girls Nagoya 1stが終了したあと、
Rails Girls Tokyo more!の真似をするところから始まりました。
Rails Girls Nagoyaの卒業生を対象に、
・今回のRailsGirlsNagoyaでよくわからなかったところを、もう少し聞いてみたい
・こういうことをやりたいけど、どうすればできるんだろう…
など、色々と相談できる場になれば良いなあ、ということで、５週間に１度、
名古屋市内のコワーキングスペースに集まり、みんなでお菓子を持ち寄り食べながら
主にワイワイ近況報告する茶話会形式が強い集まりでした。
（時々、Rails Girls Nagoyaの開催相談をする会になっていたりしてました）


### オンラインがオフラインと共存をはじめる
2017年の1月から「オンライン参加」という枠が増えました。
これは、当時の私が、名古屋まで行くためのハードルが上がったことがキッカケで増えた枠で、
コワーキングスペースに集まるのはベースだけど、コワーキングスペースに行けない人は、
オンライン（Google1ハングアウト）で参加するという形に変わりました。
内容も、この頃から近況報告に加えて「これってどうするんだっけ？」というQAや、
「こういう勉強やってるよ」という情報共有も増えてきた感じでした。
ちなみに、オンラインでも、特に不自由はしないのですが、困ったことにお菓子がね・・・（遠い目）

### 今はオンライン多数派
ここ１年は大半のメンバーが自宅（もしくは外出先）から繋ぐことが多くなりました。
Googleハングアウトで、どこでも変わらない感じで会話ができるので、
場所はどこでも大丈夫だよね、というのがわかるようになったのもあるかと思います。
（個人的には、コワーキングスペースの都合でお菓子持ち込みNGになったのも
若干影響している気はしますが・・・）

### オンライン勉強会に変わってのメリットとデメリット。
個人的にはメリットが大きいかな、と。
どこにいてもネットと、集合時間の都合さえつけば参加ができるというのは
すごく良いなと思います。
とくに地方だと、勉強会の場所を探すのにも一苦労なので、
もし他の地域のRails Girlsで、勉強会の場所が理由で勉強会ができない・・・という場合、
オンラインおすすめです。一度チャレンジしてみるのオススメします。
デメリットは・・・さっきも書きましたが、お菓子くらいな気がします・・・。


### これからのRails Girls Nagoya more!
今は、オンラインという形で落ち着いているNagoya more!ですが、
これからも、自分たちにあった形でよりよいやり方があれば、
チャレンジしていければいいなあ・・・と思っています。
＃将来はVRを使った勉強会、なんかも出てくるのかもしれないですね！


##### （そして、どうでもいい余談）今回振り返って見て気づいたこと
今回、この記事を書くために改めて過去の情報を振り返ってみていたら、
最初more!って名乗ってなかった・・・。
３回目まで「近況報告会兼おさらい会」って名乗ってた・・・（汗）
Qiitaアドベントカレンダーをやってみて

2018年も終盤、クリスマスが終わろうとしています。
アドベントカレンダーも今日で終わり。今回は振り返りです。

##自己評価

- [全て与えられてきた新人が自力でフロントエンド環境構築［1］](https://qiita.com/oniam/items/c7ddb32836a7317af434)
頑張った度 ★★★★☆
せっかくQiitaで記事を書くなら、自分や自分に近い知識量の人がみたときにわかるものにしたいと思い、奮闘。それでもやっぱり難しいこと書いてるなあと思うし（お仕事でずっと触れている人からすればそうでもないのかもしれないけれど）全てを説明しだすとキリがなくて、技術的なことを分かりやすくまとめるって大変だなあと痛感。
なんとなくわかっている事も、しっかり説明しようとすると調べないと上手く言葉にならなかったり、意外とわかってなかったなあと思ったり、記事にすることで自分の頭の整理になっていくのが凄くわかった。みなさんが記事を書く理由はここにもあるのかなと思った。

- [全て与えられてきた新人が自力でフロントエンド環境構築［2］](https://qiita.com/oniam/items/f65c09307d980aeaa836)
頑張った度 ★★☆☆☆
1記事目が頑張れたので、続きもしっかりやろうとして、まだ途中な記事。笑
もう公開しちゃったので、自分の頭の整理をするために、徐々に追記してこうと思います。

##マークダウン記法
大学の時に少し触れ、でもあまり使う事もないまま、ここまできたマークダウン。
Qiitaで記事を書いてみたことでしっかり触れられたし、マークダウンで書いたものが読みやすい形になっていると気持ちよくて面白い。
これに慣れるにはとってもいいなあと思いました、Qiita。

##カンファレンス
記事を書いたり自分から勉強してみたことで、フロントエンドやそれを使うための技術に関する理解が深まった。結果、今月参加したフロントエンドカンファレンス福岡の登壇者のお話を聞いた後の理解度が、きっと違ったと思う。

少しわかる分野が出てくると、やってみたいことが色んな方面から出てきて、WEB業界の技術の壮大さにわくわくして、ちょっと絶望した。
どこまで知っていたらフロントエンドエンジニアと名乗れるのか。
WEBデザイナーとは、どこまで出来る人のことをいうのだろうか。
環境や要件によってどこまで求められるかは変わってくると思うけれど、多方面の情報を知っていて損はないなと思ったのと、どれだけ勉強したって時間が足らないほど、沢山の技術やその情報が世界にはあるのだなあと思った。

沢山の人の手で技術が作られて、使われて、共有されていることが面白くてこんな仕事が出来て楽しいなあと思う。

##おわりに

結果的にこのアドベントカレンダーへの参加は、知識欲とモチベーションを上げてくれた。
1回記事書いてみたら書けるよ、と言われてそうかなあと思っていた11月に比べたら、少しは分かることが増えたんじゃないだろうか。

もっと色んなことが分かるようになりたいと思った。
分かる方が楽しいに決まってる。

Qiitaに限らず、技術的なことに限らず、自分の頭の中を文字や見えるものに起こすことは楽しい。私はパソコンを触ることが（タイピングだけでも）好きなので、もっと文章を書く機会も増やしたい。

記事を書ける自信がなかったし、実際まだ書き上げられていないけれど、これからの行動のきっかけを作ってくれたアドベントカレンダーに誘ってくださって、ありがとうございました〜！
CloudWatch Logs Insights とはどんなものか

[Mobingi Advent Calendar 2018](https://qiita.com/advent-calendar/2018/mobingi) の 11 日目の記事です。

# 概要
- ロググループに対してクエリできる
- 2018/11/5 以降に CloudWatch に送られたログに使える
- スキャンされたデータ 1 GB あたり 0.0076 USD
- 各クエリは Unix コマンドのようにパイプ `|` でつなげることができる
- クエリコマンドは 6 つ
  - `fields`: ログフィールドの取得
  - `fileter`: 絞り込み
  - `stats`: 集合関数を指定して実行
  - `sort`: ソート
  - `limit`: 返すログイベント数の指定
  - `parse`: データを抽出し、クエリに使用する一時的なフィールドを作成する
- それに加え関数がいろいろとある（[ドキュメント](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CWL_QuerySyntax.html#CWL_QuerySyntax-operations-functions)）
  - 日付関数
  - 数値関数
  - 正規表現 など

# Lambda のログをクエリしてみる
クエリ

```
fields @timestamp, @logStream, @message
```
こんな感じで結果が出ます

<img width="546" alt="スクリーンショット 2018-12-25 23.49.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/135946/f911020f-2b05-149b-7ac0-ce1b08fdba79.png">

@memorySize や @duration などのフィールドが見えますが、これは Insights が自動で検出してくれるものです。自動検出してくれるフィールドはサービスごとに違うので[ドキュメント](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CWL_AnalyzeLogData-discoverable-fields.html)を見て確認しておくと良いと思います。

これらのフィールドと関数を使えばいろいろな処理が簡単にできそうです。

# クエリ例
ドキュメントにサンプルクエリが載っていますが、簡単にいくつかクエリ例です。

大文字小文字区別されます

```
filter @message =~ /Exception/ | fields @timestamp, @logStream, @message
```

区別しない場合

```
filter @message =~ /(?i)Exception/ | fields @timestamp, @logStream, @message
```

timestamp でソートして 25 件表示

```
fields @timestamp, @message | sort @timestamp desc | limit 25
```


# まとめ
- ログストリームを横断的にパパっとクエリするには便利そうだと思いました。
- CloudWatch Logs Insights のコンソールからサービスに合わせたサンプルクエリが選べますし、ドキュメントの[サンプルクエリ](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CWL_QuerySyntax-examples.html) も今後充実してくるのではないかと思います。
CustomEditorとCustomPropertyDrawerのどちらが先に動くのか

# CustomEditorとCustomPropertyDrawerのどちらが先に動くのか

Version : Unity 2017.4.17f1

CustomEditorに全項目の表示を書き連ねることで分割衝動にかられた為、CustomPropertyDrawerで項目別に書けないかと検証した。

## 実際のコード

namespaceの記述は手間の都合でそのままにしています。申し訳ない。

```C#:A.cs
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace Example004
{
	[Serializable]
	public class A : MonoBehaviour {
		private string name;
	}
}
```

```C#:B.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace Example004
{
	public class B : MonoBehaviour {
		[SerializeField]
		private A a;
	}
}
```

```C#:APropertyDrawer.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

namespace Example004
{
	[CustomPropertyDrawer(typeof(A))]
	public class APropertyDrawer : PropertyDrawer {
		public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
		{
			Debug.Log("APropertyDrawer");
		}
	}
}
```

```C#:BEditor.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

namespace Example004
{
	[CustomEditor(typeof(B))]
	public class BEditor : Editor {
        public override void OnInspectorGUI()
        {
            Debug.Log("BEditor");
            this.DrawDefaultInspector();
        }
	}
}
```

## そしてこうなる

![image.png](https://qiita-image-store.s3.amazonaws.com/0/199767/1e36fb08-1315-3f3f-930b-a113ac714ae5.png)

CustomEditorが先でそのあとにCustomPropertyDrawerが動く。
やってからそりゃそうだなってなったよ。
C++と死の秘宝OpenCascade Technology

# OpenCascade Technology(OCCT)

[opencascade](https://www.opencascade.com/)

>Open CASCADE テクノロジー(オープンカスケード、OCCT)は、Open CASCADE SASによって開発とサポートが行なわれているオープンソースソフトウェアで、三次元CADやCAM、その他のための開発プラットフォームである。OCCT自体はCADやCAMといったアプリケーションではなく、C++といったプログラミング言語から呼び出して用いるライブラリである。
--- Wikipediaより

FreeCADというそこそこ有名なフリーのCADソフトが内部で使っているので、そこそこ実績がある。
1999年から開発が始まっており、今なお手入れされ続けていてすごい。
すごいが、C++11が出た頃に書き直して新しくしておいてほしかった。
現代C++erからは想像もできない荒野が広がっている。

# あまりの闇の深さにビビった

この記事はOCCTの深淵を覗いた結果僕の心が崩壊しかけた話です。

## 分霊箱

まず、分霊箱（ファイル）に魂を分割しすぎている。
LLVM、V8などの名だたるプロジェクトなどと比べても、というか比べるのも馬鹿馬鹿しいほどだ。


![範囲を選択_033.png](https://qiita-image-store.s3.amazonaws.com/0/100319/3da7c22e-199a-ab30-6ce5-b27f7f032577.png)

### lxx???

lxxファイルはインライン関数が書かれたファイル。

### gxx!?

これがとんでもないやつで、ヘッダを自動生成する闇の魔術の塊。
魔黒でファイルまるごと生成してインクルードしだす。

### 仕組み

lxx/gxxファイルの文字列をdefineでインクルードファイルに書き換える。
考えたやつ天才。

```cpp
#define Pnt gp_Pnt
#define Pnt_hxx <gp_Pnt.hxx>
#define Extrema_Point Extrema_POnCurv
#define Extrema_Point_hxx <Extrema_POnCurv.hxx>

#include <Extrema_Point.lxx> // < !!

#undef Pnt
#undef Pnt_hxx
#undef Extrema_Point
#undef Extrema_Point_hxx
```

```cpp
#include <Extrema_POnCurv.hxx>

#include <gp_Pnt.hxx>

#define Pnt gp_Pnt
#define Pnt_hxx <gp_Pnt.hxx>
#define Extrema_Point Extrema_POnCurv
#define Extrema_Point_hxx <Extrema_POnCurv.hxx>
#include <Extrema_Point.gxx>　// < !!
```

タグジャンプできないときの僕の口癖「はいはい、どうせgxxなんでしょ」。

### たった7ノードでも複雑な継承

よく見ると完全グラフになってる継承の図。

![dot_schema_all_modules.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100319/4a636ca6-4a49-6ea8-1fd8-c1f8f5a57c3b.png)


### API名

わかりやすいのか、わかりにくいのかわからない。

```cpp
TopTools_MapOfShape
TopTools_IndexedMapOfShape
TopTools_DataMapOfShapeShape
TopTools_DataMapOfShapeListOfShape
TopTools_IndexedDataMapOfShapeListOfShape
TopTools_DataMapIteratorOfDataMapOfShapeListOfShape
```

ちなみに、`BRepTools`と`BRep_Tool`の違いが未だに記憶できない。

## 唐突にあらわれるフランス語

RecadreOnPeriodic?
Recadreってなんぞや？？？
唐突なフランス語やめろ、読めんわ。

```cpp
TopAbs_State BRepTopAdaptor_FClass2d::TestOnRestriction	(const gp_Pnt2d &Puv,
                                                         const Standard_Real Tol,
                                                         const Standard_Boolean RecadreOnPeriodic = Standard_True 
                                                        ) const
```

ドキュメント読みに行ったら、

```
(Caution: Internal use . see the code for more details)
```

って書いてあったわ、ふざけんな。

## ヤバすぎる実装

とにかく色々とヤバイ。

### 巻き起こる未定義動作

const_castとかやらかしているので、未定動作起こりまくりのキレまくりです。

### バグるAPI

普通にロジックもバグっているが、実装が複雑すぎてどうにも修正する気になれない。

### 公開されてないテスト

そもそもOSSとは何だったのか？？？
テストが存在しないはずないよね！？
なんで公開されないの。

### 動的メモリ確保の走りすぎ

パフォーマンスが悪すぎて計測したら、メモリの確保で30~40%の時間を使っている。
馬鹿すぎる。

### 新しいリリースをビルドしたら、セグフォする

使うの諦めて古いやつで戦ってます。
新しいAPI使いたかったんだけど......

## ほめポイント

このライブラリC++17でコンパイルできます。
すごくないですか？？？
ちゃんとメンテナンスされてるんですねえ......

そこじゃねえよ！
書き換えろよ。

備考：C++の後方互換性が優れているだけです

## さいごに

いろいろ文句しかないけど、これ以外に選択肢ある気がしないのでありがたく使ってます。
5年隠居して実装し直したほうが幸せになれる気がしないでもないですが。