OmniAICreator/Qiita-1.07M huggingface dataset:
画像の代わりにaltのテキストを表示する

## スマホの時だけ画像非表示にしてくださいってたまに言われます
本当はスマホ用の画像を用意した方がいいのですが時間や予算がまったくなかったりするときのための方法

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

完成版
<p class="codepen" data-height="265" data-theme-id="dark" data-default-tab="html,result" data-user="sphenisc" data-slug-hash="ZEGWrgd" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="ZEGWrgd">
  <span>See the Pen <a href="https://codepen.io/sphenisc/pen/ZEGWrgd">
  ZEGWrgd</a> by sphenisc (<a href="https://codepen.io/sphenisc">@sphenisc</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
imgタグには疑似要素を付けられないのでimgの上のh4にafterを付けてJSで imgのalt → afterのdata-label へと中身を移してからCSSのafterのcontentとして表示しています。
alt属性はそもそも画像が表示できない場合の代替テキストを書くための場所なのでSEO的にも問題なし

JSなしでやりたい場合
<p class="codepen" data-height="265" data-theme-id="dark" data-default-tab="css,result" data-user="sphenisc" data-slug-hash="jOPqzPd" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="jOPqzPd">
  <span>See the Pen <a href="https://codepen.io/sphenisc/pen/jOPqzPd">
  jOPqzPd</a> by sphenisc (<a href="https://codepen.io/sphenisc">@sphenisc</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
LeapMotionでジェスチャデータを出力してOculusQuestでテストするあれこれ作ってみた( 発展途上 )

OculusQuestのハンドトラッキングが実装されてからUnityでジェスチャを自前で作成してテストする際にいちいち実機に転送するのが結構煩わしかったのでそれっぽいもの作ってみた

最近はOculusLink使ってエディタでテストできるみたいだけど僕は持ってないのでLeapMotionで代用的な
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Oculus Integration 13.0も来てた。Oculus LinkでUnityエディタ上でハンドトラッキングが使えるようになってるみたい。 <a href="https://t.co/rNaDt6ygiC">https://t.co/rNaDt6ygiC</a></p>&mdash; こりん@VR (@korinVR) <a href="https://twitter.com/korinVR/status/1225683030418706442?ref_src=twsrc%5Etfw">February 7, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


# 対象となる人
- OculusQuest持ってる
- LeapMotion持ってる
- OculusLink持ってない or 持ってるけどうまく動かなくて使ってない
- Windowsユーザー( LeapMotionのSDKのバージョンで最新版はWindowsしか利用できないので )
- ハンドトラッキングの自前ジェスチャを作って何かしたい


# 環境
|||
|---|----|
| OS | Windows10 |
| Unity | 2018.4.14f1 |
| LeapMotionSDK | UnitySDK 4.4.0 |
| OculusIntegration | 12.0 |


# できること
現段階では指の伸びたか否かでの判定を用いてのジェスチャのデータ出力及びOculusQuestでのテスト
今回は グー、チョキ、パーの三つのジェスチャデータを出力してOculusQuestでテストしています


データの出力
![A.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212999/61abfe71-dd92-06ab-bacf-f40bde05a2d9.gif)


出力されたジェスチャデータをOculusQuestでテスト
![B.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212999/a4769a6d-b5ac-d52c-a916-beb35abffe2e.gif)

[こちら](https://github.com/D-RyusukeMatsumoto/hand-gesture-record)のリポジトリで公開しています

まだリファクタリング等行ってないのでコードは若干ゃごちゃごちゃしてて扱いにくいけどとりあえず後悔した後で整備していく方針です

# あとがき
今後ぼちぼちアップデートをしてできることをもう少し増やしたい...
HoloLensのブルームみたいな特定の一連の指の動きとか
この記事は今後ちょくちょく手を入れる予定
Rift Sでハンドジェスチャのテストができればいいんだがなぁとも思ったり思わなかったり、現時点ではRift Sでのハンドトラッキングは実装されてないので致し方なし
【準備中】5.Salesforce Training(Sales Cloud<Lightning UI>)

#【前言】
準備中

#【Training内容】
##第 1 次课（時間：8時間）

準備中
##第 2 次课（時間：8時間）
準備中

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/4ac7a610-3e57-24fc-92d3-7609c3c9951d.png)
「The name 'Todo' is either already used in your application or reserved by Ruby on Rails. Please choose an alternative and run this generator again.」エラー対処法

```sh

$ rails g model Todo item:text
Running via Spring preloader in process 83975
      invoke  active_record
The name 'Todo' is either already used in your application or reserved by Ruby on Rails. Please choose an alternative and run this generator again.
```

参考ページ
https://qiita.com/tu-kun/items/4fede82431e546abd941

原因：今回作ろうとしてるRailsアプリケーションのモジュール名とモデル名が重複していたためエラーになった

## 1.モジュール名の変更 Todo → RailsTodo

```diff:config/application.rb
require_relative 'boot'

require 'rails/all'

# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)

- module Todo
+ module RailsTodo
  class Application < Rails::Application
    # Initialize configuration defaults for originally generated Rails version.
    config.load_defaults 6.0

    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration can go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded after loading
    # the framework and any gems in your application.
  end
end

```

## 2.モジュール名を変更したあと、フォルダ名を変更する　todo →　rails_todo

* フォルダ名はスネークケース（小文字で単語区切りが`_`）
* モジュール名はアッパーキャメルケース（単語区切りが大文字でそれ以外は小文字）
* Railsにおいてアプリケーション名を表す部分は`config/application.rb`のモジュール名のことをいう

参考ページ
https://designsupply-web.com/developmentlab/4052/

## エラー解消

```sh
$ rails g model Todo item:text completed:boolean
Running via Spring preloader in process 84393
      invoke  active_record
      create    db/migrate/20200216151440_create_todos.rb
      create    app/models/todo.rb
      invoke    test_unit
      create      test/models/todo_test.rb
      create      test/fixtures/todos.yml
$ rails db:migrate
== 20200216151440 CreateTodos: migrating ======================================
-- create_table(:todos)
   -> 0.0018s
== 20200216151440 CreateTodos: migrated (0.0018s) =============================
```
spring-cacheのキャッシュのキー作成の仕組み

## springのキャッシュ機能
- [spring-abstraction](https://docs.spring.io/spring/docs/4.3.15.RELEASE/spring-framework-reference/html/cache.html) というキャッシュの実装がSpringフレームワークには存在する、それについて調べた

### キャッシュのアノテーション
- 雑な説明をすると、`@Cacheable`アノテーションをメソッドにつけることで、メソッドの返り値をキャッシュすることができる

### どのタイミングでキャッシュされるのか
- キャッシュ取得/再取得
  - [org.springframework.cache.annotation
Annotation Type Cacheable
](https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/cache/annotation/Cacheable.html) の動作に従う
  - このアノテーションがついたメソッドが呼ばれるたびに、その引数ですでに呼ばれたことがないかチェックされる（引数をkey() or keyGenerator()で一意にして、過去に呼ばれたか見ている）。もし過去に呼ばれたことがあればキャッシュされている値を返す。key(), keyGenerator()の仕組みは次の節で書く。

#### spring-cacheのキャッシュキー作成の仕組み

- spring-cacheはデフォルト実装では`SimpleKeyGenerator`で引数のリストからハッシュ値を計算してキーを作成している
  - 引数が１つの場合は、その引数自体のObjectを返し、それをキーとする
  - 引数が複数の場合は、`Arrays.deepHashCode`の結果をキーとする

以下、関連するソース
https://github.com/spring-projects/spring-framework/blob/master/spring-context/src/main/java/org/springframework/cache/interceptor/SimpleKeyGenerator.java#L47
https://github.com/spring-projects/spring-framework/blob/c2367b3ad23a5c90920ca0d8f18bda6bbedbf855/spring-context/src/main/java/org/springframework/cache/interceptor/SimpleKey.java#L59

- 以上から
  - オブジェクト単体が引数ならばそのオブジェクト自体がキーになる
  - 複数の引数ならば、`Arrays.deepHashCode`の結果がキーになる
- よって
  - 単体オブジェクトの場合キーがそのオブジェクト自体になる。ConcurrentMapのキーの同一性の判定は普通の[Map](https://docs.oracle.com/javase/jp/8/docs/api/java/util/Map.html#get-java.lang.Object-)と同じなので、`Object.equals`で判定される。`Object.equals`はオブジェクトのhashcodeの同一性で決まるので、キーに使用するオブジェクトがちゃんとしたhashcodeを返していればOKということになる。参考: [Listのhashcode計算](https://stackoverflow.com/a/35702670/2565527)
  - 複数の引数の場合、データが大きくなっても`Arrays.deepHashCode`は一定のデータを返すしデータの中身によって一意にキーが定まるので問題ない
緑コーダーによる、AtCoder Beginner Contest 155 E - Paymentの解説

ACしたらビビるくらいのパフォーマンスが出た

# 問題の概要

[E - Payment](https://atcoder.jp/contests/abc155/tasks/abc155_e)
（要約）通貨は$1,10,100,...,10^n$ の紙幣しかありません。ある価格に対して、払うお札の枚数と、もらうお釣りの枚数の合計の最小値を計算してください。

# まず考えたこと

制約が $|N|=10^6$ なので計算量 $O(|N|)$ でないと間に合わないと考えました。サンプルケースから考えて、次のように計算の順序を考えました。

1. 下の桁から計算を行う（後述する桁上がりを考慮するため）
2. その桁の数によって次の2つに分岐する（その桁の数を $d$ とする）
    3. $d\leq5$ なら、そのまま払う方がお釣りをもらうより枚数が少ないので、答えに $d$ を足す。(5は同数ですがこちらに入れる)
    4. $d\geq6$ なら、お釣りをもらう方が枚数が少ないので、答えに $10 - d$ を足す。お釣りをもらうために次の桁に $1$ を足す（桁上がり）。
1. 最後の桁で桁上がりが起きた場合、答えに $1$ を足す。

このようにして記述したコードがこちらになります。

```cpp
int main(void)
{
    string s; cin >> s;
    int sl = s.size();
    ll ans = 0;
    bool keta = false;
    for(int i = sl-1; i >= 0; i--) { // ルール1
        int d = s[i] - '0';
        if (keta) d++; // 桁上がり
        keta = false;
        if (d > 5) {  // ルール2-2
            ans += 10 - d;
            keta = true;
        }
        else ans += d; // ルール2-1
    }
    if (keta) ans++; // ルール3

    cout << ans << '\n';

    return 0;
}
```

これでサンプル1、2は正解しましたが、3は間違った数が出てきてしまいました。
桁上がりの数を5以上にしたり、連続する9の数に注目したりしましたが、サンプル3の答えが合いませんでした。

# 5は払う枚数もお釣りをもらう枚数も同じだが…

その桁の数が5の時は払う枚数もお釣りをもらう枚数も同じですが、桁上がりとしたとき、次の桁が1なら払う枚数が1増えるが、次の桁が6だと次の桁のお釣りをもらう枚数が減るということに気づきました。
というわけで、前項の計算順序 （2） を、以下のように変更しました。

1. $d\leq4$ なら、そのまま払う方がお釣りをもらうより枚数が少ないので、答えに $d$ を足す。
1. $d\geq6$ なら、お釣りをもらう方が枚数が少ないので、答えに $10 - d$ を足す。お釣りをもらうために次の桁に $1$ を足す（桁上がり）。
2. $d=5$ の時、次の桁が4以下ならそのまま払う。5以上ならお釣りをもらって桁上がりする。

これに従ってコードを記述し、ACしました。コードは以下のようになりました。（1行しか変わってない）

```ABC155e.cpp

int main(void)
{
    string s; cin >> s;
    int sl = s.size();
    ll ans = 0;
    bool keta = false;
    for(int i = sl-1; i >= 0; i--) { // ルール1
        int d = s[i] - '0';
        if (keta) d++; // 桁上がり
        keta = false;
        // ルール2-2,2-3
        if (d > 5 || (d == 5 && i > 0 && s[i-1] - '0' > 4) ) {
            ans += 10 - d;
            keta = true;
        }
        else ans += d; // ルール2-1
    }
    if (keta) ans++; // ルール3

    cout << ans << '\n';

    return 0;
}
```
Matplotlibを使ったグラフ描画する方法 

# 概要
Matplotlibでのグラフの書き方を自分用の備忘録としてまとめる。


## とりあえず一つグラフを書きたいとき
横軸（x）と縦軸（y）を設定して、plt.plot(x, y)とするだけ。


```とりあえず一つ描画.py
import matplotlib.pyplot as plt
import numpy

x = np.linspace(0, 10)
y = np.sin(x)
plt.plot(x, y)
plt.show()
```
![matplotlib_base.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/339647/060e99b4-1b0e-31a8-174d-f1962bafe097.png)

## pltの引数
c : 色。"r"、"g"、"b"、"c"、"m"、"y"などでグラフの色を変えれる。 
marker : マーカーの形を指定。"o"、"^"、"v"、"+"などがある。 
lw : 線の太さを指定。線を消したいときは0にする。
alpha : 透明度を指定。0に近いほど透明に近づく。
label : 名前を指定。複数グラフを書くときは名前を付けとくとよい。（凡例に表示できる）
　　　　 ※凡例の付け方は後述。

```pltの引数.py
x = np.linspace(0, 10)
y = np.sin(x)
plt.plot(x, y, c="r", marker="^", lw=1, alpha=0.5, label="test")
plt.show()
```
![matplotlib_hikisu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/339647/bc7dabcd-d3b4-c00f-08e5-28ab7869b2ee.png)


## グラフに様々な情報を追加
plt.〇〇で、グラフに様々な情報を追加できる。
plt.titleでタイトルを追加
plt.xlabe/ylabelでx軸/y軸のラベルを追加
plt.xlim/ylimでx軸/y軸の最小値と最大値を指定
　※最大値と最小値は直接数値を入れてもいいが、下記例のようにyのnp.minなどで指定してもよい
plt.gridでグラフにグリッドを表示
plt.legendでグラフに凡例を表示


```グラフに情報を追加.py
x = np.linspace(0, 10)
y = np.sin(x)

plt.plot(x, y, c="c", marker="+", lw=0, alpha=0.5, label="test1")
plt.title("Figure_test")
plt.xlabel("axis_x")
plt.ylabel("axis_y")
plt.xlim(0, 15)
plt.ylim(np.min(y)-2, np.max(y)+2)
plt.grid()
plt.legend()

plt.show()
```
![matplotlib_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/339647/9c38f9a3-4605-2d03-c11a-7d155a5c5651.png)

## 複数のグラフを描画
初めに、plt.figure()で大きな箱を準備する。箱の大きさはfigsizeで指定可能。
準備した箱の中にplt.subplot()で複数のグラフを入れていくイメージ。
plt.subplot()の第一引数に行、第二引数に列、第三引数に番号を指定する。
番号は、左上が1から始まり、右方向、下方向の順に数字が大きくなる。


```複数のグラフを表示.py
x = np.linspace(0, 10)
y1 = np.sin(x)
y2 = x
y3 = x ** 4
y4 = np.cos(2*x)

plt.figure(figsize=(8, 5))

plt.subplot(2, 2, 1) # 左上
plt.plot(x, y1, c="r", marker="^", lw=1, alpha=0.5, label="left_up")

plt.subplot(2, 2, 2) # 右上
plt.plot(x, y2, c="g", marker="o", lw=1, alpha=0.5, label="right_up")

plt.subplot(2, 2, 3) # 左下
plt.plot(x, y3, c="b", marker="v", lw=1, alpha=0.5, label="left_down")

plt.subplot(2, 2, 4) # 右下
plt.plot(x, y4, c="y", marker="+", lw=1, alpha=0.5, label="right_down")

plt.show()
```
![matplotlib_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/339647/864f217b-a29a-c1d5-da84-83c30b5dda79.png)

以下のようにも書ける。（結果は↑と同じ）
subplots()で、figという大きな箱の中にグラフをどこに配置するかを先に指定する。
ax[行, 列]で場所を指定しグラフを描画。
（こっちの書き方はまた別でまとめようかと思います。）

```複数のグラフを表示2.py
x = np.linspace(0, 10)
y1 = np.sin(x)
y2 = x
y3 = x ** 4
y4 = np.cos(2*x)

fig, ax = plt.subplots(2, 2, figsize=(8, 5))

# 左上
ax[0, 0].plot(x, y1, c="r", marker="^", lw=1, alpha=0.5, label="left_up")

# 右上
ax[0, 1].plot(x, y2, c="g", marker="^", lw=1, alpha=0.5, label="right_up")

# 左下
ax[1, 0].plot(x, y3, c="b", marker="^", lw=1, alpha=0.5, label="left_down")

# 右下
ax[1, 1].plot(x, y4, c="y", marker="^", lw=1, alpha=0.5, label="right_down")

plt.show()

```
![matplotlib_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/339647/b6d7ca54-c992-dec6-0a37-8181c8c70eb7.png)
## まとめ
非常に基本的な事ばかりですが、初心者の自分用に、よく使う機能だけ書いてみました。
おすすめの機能なんかあれば、コメントください。
TypeScriptを使ってReactのFunctionalComponentに型安全にpropsを渡す

```tsx
import React, { FunctionComponent } from 'react';

type Props = { title: string }
const Title: FunctionComponent<Props> = props => {
  return <>
    <h1>{props.title}</h1>
  </>
}
```

または、以下のようにtypeの定義省略することも出来る。

```tsx
import React, { FunctionComponent } from 'react';

const Title: FunctionComponent<{ title: string }> = props => {
  return <>
    <h1>{props.title}</h1>
  </>
}
```

使用する時はこのように使う。

```tsx
function App() {
  return <>
    <Title title="Hello World" />
  </>
}
```

## 関連記事

- [雰囲気で使わない @types/react - Qiita](https://qiita.com/Takepepe/items/0bbe4ab6ff4858a4e186)
Fiddlerでレスポンス書き換え（カスタムスクリプト使用）

レスポンスヘッダーを書き換える必要がありました。
Fiddlerのカスタムスクリプトを用いればリクエストやレスポンスの内容が改竄可能です。
※デバッグ機能もあり、レスポンスを都度止めて内容を書き換えることも可能です（[参考](https://jemsec.blog.ss-blog.jp/2013-07-02)）。

## 編集方法
1.  Fiddlerにて，メニューバー「Rules」→「Customize Rules..」を選択
2.  FiddlerScript Editorが開かれる
3.  スクリプト内の`OnBeforeResponse`メソッドを文字列検索

### カスタムスクリプト修正

### 指定したパスのレスポンスヘッダーを変更

画像ファイルに対して`Cache-Control`に値`no-store`を設定。

```javascript
static function OnBeforeResponse(oSession: Session) {
    if (oSession.PathAndQuery == "/img/something.png") {
        oSession.oResponse["Cache-Control"] = "no-store";
    }
}
```

### 指定したドメインからの特定ヘッダーを削除

`www.fizzbuzz.com:8080` からのレスポンス全てに対して`Cache-Control`ヘッダーを削除。

```javascript
static function OnBeforeResponse(oSession: Session) {
    if (oSession.host == "www.fizzbuzz.com:8080") {
        oSession.oResponse.headers.Remove("Cache-Control");
    }
}
```

### 指定したURLのレスポンスボディーを変更

外部のWebAPIのレスポンス内容を`{"mean": "意味はない"}`に変更。

```javascript
static function OnBeforeResponse(oSession: Session) {
    if (oSession.url== "www.hoge.com/rest/api/get/means") {
        oSession.oResponse["Content-Type"] = "application/json";
        oSession.utilSetResponseBody('{\"mean\": \"意味はない\"}');
    }
}
```
TBD: JavaScriptオブジェクトからJSON文字列への変換で簡単な方法は調査中

### 指定した拡張子のファイルのレスポンスコードを変更する

CSSファイルの全レスポンスを404に変更する。

```javascript
static function OnBeforeResponse(oSession: Session) {
    if (oSession.uriContains(".css")){
        oSession.oResponse.headers.HTTPResponseCode = 404;
        oSession.oResponse.headers.HTTPResponseStatus = "404 Not Found";
    }
}
```

## 参考

[Modifying a Request or Response](https://docs.telerik.com/fiddler/knowledgebase/fiddlerscript/modifyrequestorresponse#modifying-a-request-or-response)
[Fiddlerでレスポンスを止める方法](https://jemsec.blog.ss-blog.jp/2013-07-02)
基本情報17週目(2月10日)

##目標と結果##

##目標##

•午前試験を一回通し、自分の未だ理解できていない部分の分析をすること。
•午後試験[データ構造及びアルゴリズム]勉強を一週間の内10時間勉強する。
##振り返り##
午前試験を通すことができなかったが、自分の不得意な部分が多数あったため、何度もやり直す。午後試験に関しては、10時間の内6時間しか出来なかった。解き方のコツを掴めることが出来ていない。
__KEEP__
1日隙間時間に1つでも言語を覚える。
__TRY__
一週間のうちしっかりと言語そして、解き方をを習得する。

__PROBLEM__
アルゴリズム問題のコツを掴めていない。

次週 and more...
[2/17](https://qiita.com/Comitakato0515/items/324e5f6ed2f4971ed145)
Vue.nextTickとthis.$nextTick

再描画を待つために使う `nextTick` ですが、グローバルな `Vue.nextTick` を使うべきか、それとも `this.$nextTick` を使うべきか。
迷ったら `this.$nextTick` を使った方がよさそうと感じました。

Vue.jsでは **アロー関数** は期待しない動作になる場合があります。つまり `this` が直感的に使えないです。[こちらの記事](https://qiita.com/_Keitaro_/items/d48733a19c10889e2365)にも書いています。

例えば **アロー関数** がそのまま使えない `watch` で `Vue.nextTick` を使う場合は以下のようになります。 `this` の参照を同一スコープ内に保持しておく必要があります。

```javascript
watch: {
  hoge() {
    const vm = this; // 参照を保持
    Vue.$nextTick(function() {
      vm.fuga++; // thisを使う処理
    });
  }
}

```

これに対して `this.$nextTick` を使うと `this` の束縛が行われるため直感的です。

```javascript
watch: {
  hoge() {
    this.$nextTick(function() {
      this.fuga++; // thisがそのまま使える
    });
  }
}
```

迷ったらとりあえず `this.$nextTick` でよいと感じます。

### 参考

[公式リファレンス](https://jp.vuejs.org/v2/guide/reactivity.html#%E9%9D%9E%E5%90%8C%E6%9C%9F%E6%9B%B4%E6%96%B0%E3%82%AD%E3%83%A5%E3%83%BC)
基本情報18週目(2月17日)

##目標と結果##

##目標##
•アルゴリズム問題、ソフトウェア設計問題及びストラテジ系問題の解き方のベースを学習する。(使用テキスト-午後問題が解ける本)
•速習言語テキストの第1章C言語〜第6章JAVAの理解を深める。

##振り返り##

__KEEP__

__TRY__

__PROBLEM__


##次週 and more...##
2/24
Power Apps レスポンシブ対応

## Power Apps とは

[Power Apps](https://docs.microsoft.com/ja-jp/powerapps/powerapps-overview) は、アプリ、サービス、コネクタ、データプラットフォームのスイートであり、ビジネスニーズに合わせてカスタムアプリを構築するための迅速なアプリケーション開発環境を提供します。 

Power Apps を使用すると、基になるデータプラットフォーム ([Common Data Service](https://docs.microsoft.com/ja-jp/powerapps/maker/common-data-service/data-platform-intro))またはさまざまな**オンラインおよびオンプレミスのデータソース (SharePoint、Excel、Office 365、Dynamics 365、SQL Server など)に格納されているビジネスデータに接続するカスタムビジネスアプリをすばやく作成できます。**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/b04f64ff-27f8-8313-16fb-e1ef9bd31664.png)

## レスポンシブ対応
[以前作成したアプリ](https://qiita.com/tetsukick/items/34ee4459304d2d4b7c73)のレスポンシブ対応をしてみます。

ちなみに公式では、このような記述がされています。
> 携帯電話用の Dynamics 365 およびタブレットアプリがインストールされていない場合でも、デバイスの画面解像度が十分に高い限り、タブレットで web ブラウザーを使用できます。

Power Appsは、スマホアプリやタブレットアプリ、ブラウザ表示でも使用することができます。

ちなみにレスポンシブ対応前は、このような感じになってしまい、スマホサイズの画面がタブレットやブラウザ([Dynamics 365 ホームページ](https://home.dynamics.com/))で表示できます。

＜スマホ画面(iPhone7)＞
<img width="375" alt="iOS の画像 (4).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/dc7e06ef-23cd-cce1-6ad2-e7d2f4023579.png">


＜タブレット画面(iPad)＞
<img width="768" alt="iOS の画像 (2).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/914f6114-9af8-ad69-8dcb-9b730aa758b7.png">

<WEBブラウザ(Dynamics 365 ホームページ)>
![demo002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/af2f9c9a-dfa1-741d-4ff6-cb0ab720182d.png)


### STEP1 設定変更

Power Appsの設定を変更します。
これで、全ての端末で開いた際にスマホサイズ表示になっていた状態が解除されます

![demo001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/3d501384-cea0-a5db-03df-3e36ad5c6dbc.png)
![demo005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/f07db4b8-7e8d-e2bd-ed57-76f028243c84.png)


上記に設定変更後、以下のように、表示が崩れた状態になります。

![demo003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/98f370f4-05dd-4f49-a6c6-73875b74565a.png)


### STEP2 画面サイズの取得方法

画面サイズは、コードから以下の値で取得できます。

```
横幅: App.Width
縦幅: App.Height
```

トップ画面のGallery部分にこの値を適応させると、、

![demo006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/bbf9e689-6c6f-b5f4-2152-845e3747fe1b.png)

横幅

```
App.Width
```

高さ

```
App.Height - (RectQuickActionBar1_1.Height + TextSearchBox1.Height)
```

Y座標

```
RectQuickActionBar1_1.Height + TextSearchBox1.Height
```

これで、トップ画面はこのような感じになります。

＜タブレット画面＞

![iOS の画像 (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/a9f83e75-3ac3-68f9-10c6-1adb08f4a543.png)

＜ブラウザ画面＞

![demo004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/3ff0611f-157c-5549-7054-aee146638dfa.png)


誤り、改善点や疑問点ありましたらコメント下さい。宜しくお願い致します。

### 参考記事
[PowerAppsでレスポンシブなアプリを作る](https://qiita.com/MasatoFukakusa/items/73bdf54c78ff036933cd)
APRS その後

Aprs について書きました。その後について書こうと思います。

私はXastirをラズベリーパイに展開して、APRS Igateを
構築して動かしています。
受信専用なので、30年くらい前の無線機で十分ですので
FT203を使って数ヶ月継続させてきました。

やはり、古い無線機なので受信感度が不足しており、
プリアンプの必要性を感じました。

そもそも昔の無線機の入手にヤフオクを使いましたので
無線機の当たり外れが大きく、4台入手した中で2台は使用でき、
残りは外れでした。 

確かに今の無線機を使っても良いのですが、
デジタル化され過ぎていて、ちょっとしたことで壊れてしまうことを
懸念して、そうしたところです。
アナログ無線機は、メモリは無し、DSPは無し、省電力。
固定周波数であれば十二分です。

プリアンプですが、ミニサーキットのものを個人輸入して
使用しています。 NFはイマイチですが、確実に中継されるパケットの
数は増加するという現象が現れています。

読まれている皆様のご参考になれば幸いです。

デジタルな部分ではなく、ほぼアナログなところで役目を果たされるかどうか決まるようです。
使えるようになって(いて)欲しいプログラミング言語

# はじめに

私はすでに全く若手ではないのだが、個人的な意見として、また新たに入ってくる技術者に言っていることを書いてみる。勿論賛否あって良い。

何気に私はいわゆる組込み系の仕事をしているのだが、ソフトウェア・オリエンテッドであまり組込みっぽくない人種です。

# 使えるようになって(いて)欲しいプログラミング言語

概ね以下の3種類でそれぞれ1つずつ。

## システム記述系

こういう括りが正しいかは別として、C/C++、Java、C#など。

プログラムの動きとか、コンピューターの動きとか、きちんと知るにはCが最適。アセンブラとは言わない。アセンブラでもいいけど、プロセッサごとに違うしね。概念は知ってると良い。

ただ、Cを実務で使うのはどうしても必要でなければ避けたいのが本音。スキルの差がモロに品質に直結するので。

後、オブジェクト指向しづらいし。それができるというのとはまた別。C++は好きだが、仕様がカオスになりすぎて完全にマニアの世界。Javaはできると実務でも使えて、オブジェクト指向にも慣れるので良いかもしれない。

C#も簡単で分かりやすかった。Windowsでしかいまいち使わないが。

## スクリプト系

Ruby、Python、今更使わないがベテランはPerlか。何でも良い。何か使えれば考え方は大概一緒で応用が効くだろう。

スクリプト言語は超絶楽に何でもできる。製品開発だって個人的な業務効率化だっていける。なので、使えるようになっておくと様々な場面で重宝される。

## JavaScript

というか、TypeScriptか。

クライアント系はもうこれ一択。組込み系だって最近はWebブラウザ内蔵してるし、UIやるには必需品。

デスクトップでも node.js で何でもできるし。

ただ、node.js はひとつのザ・ワールドになっていて全くライトな感じではないのがちょっと引っ掛かるが。

## まとめ

上記は網羅的な形ではないが、上記の方針で取り組んでいれば、新たに何か学ばなくてはならなくなってもどこかのスキルがベースになって応用が効く。

どちらかというと言語そのものよりもライブラリやフレームワークのスキル習得のほうが重要になるが、それを使いこなす上での前提知識の習得に時間がかかるようでは心許ない所なので、ある程度応用が効く形でスキル習得していくのが良い。

その上で、技術は知識よりも実践(熟練)なので、沢山書く機会を作ることを意識してもらえれば、嬉しい。
GCPバックエンドサービスのサンプリングレートが勝手に変更される問題

お疲れ様です。
GCPのバックエンドをいじっていたらバックエンドサービスのサンプリングレートが勝手に切り替わっていたため、その事象について共有します。
※記事執筆日: 2020-02-17

# 事象説明 

実際どういうことなのか、動かしながら説明します。

▼バックエンド一覧（ここでもサンプリングレートが0.001なのを確認できます）
![スクリーンショット_2020-02-17_7_10_44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88176/bc9a61ef-8449-03e9-1388-a927d7082ba6.png)

▼CLIからもサンプリングレートを確認。
今は0.001になっている。

```
$ gcloud beta compute backend-services describe backend-service01 --global --format
="value(logConfig.sampleRate)"
0.001
```

▼バックエンドの設定を少し更新してみる。

```
gcloud compute backend-services update-backend backend-service01 --balancing-mode
=RATE --max-rate-per-instance=10 --capacity-scaler=0.1 --instance-group=instance-group-1 --instance-group-zone=us-central1-
a --global
Updated [https://www.googleapis.com/compute/v1/projects/gcp-study01/global/backendServices/backend-service01].
```

▼サンプリングレートが1.0になってしまっている。

```
gcloud beta compute backend-services describe backend-service01 --global --format
="value(logConfig.sampleRate)"
1.0
```

▼画面表示も同様
![スクリーンショット_2020-02-17_7_11_28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88176/6f7c01a7-651b-a017-31cf-c1438a5eb1ba.png)

## バックエンド追加でも同様の事象が発生 
▼バックエンド追加前（サンプリングレート=0.001）

```
gcloud beta compute backend-services describe backend-service01 --global --format
="value(logConfig.sampleRate)"
0.001
```

▼バックエンド追加

```
gcloud compute backend-services add-backend backend-service01 \
  --balancing-mode=RATE \
  --max-rate-per-instance=3 \
  --capacity-scaler=1 \
  --instance-group=instance-group-2 \
  --instance-group-zone=us-central1-a  \
  --global
```

▼バックエンド追加後（サンプリングレート=1.0）

```
gcloud beta compute backend-services describe backend-service01 --global --format
="value(logConfig.sampleRate)"
1.0
```

## GUIからの操作では勝手に切り替わらない

GUIからバックエンドを一部更新してみる。

▼変更前（0.001）
![スクリーンショット_2020-02-17_7_19_16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88176/00a1339c-aa1a-6f54-aece-2ebbcf93c349.png)

▼バックエンドの容量を100→99に変更
![スクリーンショット_2020-02-17_7_19_59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88176/9d0fde52-946f-c2c5-2857-58e557bd3060.png)

▼変更後（0.001）
![スクリーンショット_2020-02-17_7_20_33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88176/c03bf988-347e-9407-7c43-91fe996aebf0.png)

なぜかGUIからの操作ではサンプリングレートには影響ありませんでした。

# まとめ
GCP側の不具合なのか分かりませんが、サンプリングレートが高いと大量のログが出力され無駄な費用が発生してしまうため、この点は直して頂きたいです。
引き続き調査するので、分かったことがあればまたこちらで共有します。

以上、読んで頂きありがとうございました。
例外処理

```python:ex.py
l = [2,4,5,8]

try:
    l[5]
except NameError as ex:
    print('エラーメッセージ:', ex)
except Exception as ex: #その他の例外をキャッチ（ただし、この使い方は推奨されない）
    print('エラーメッセージ:',ex)
else:
    print('成功した時のみ実行されます')
finally:
    print('例外をキャッチできなかった場合（プログラムが正常終了しなかった場合）も含めて、必ず実行されます')
```
0から分かるCSSだけでフェードアウトしてみた

#はじめに
お久しぶりです！今回は小ネタみたいなものですが、サイトに取り入れると少しかっこよくなる
「CSSによるフェードアウト」です！！
とても簡単なのでちらっと見ていってください(^^)/

#この記事を読むとどうなるの？
→CSSでのフェードアウトの方法が分かる

#どうやってやるの
##①HTMLを作る（当たり前ですね）
何をするにしてもCSSを使うので、まずはHTMLを適当に作りましょうね。

```html:index.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <!--CSSの読み込みを忘れないようにしましょうね-->
    <link rel="stylesheet" href="stylesheet.css">
    <title>Document</title>
  </head>
  <body>
    <div class = fadeout>
        <img src = "画像やgifのURL">
    </div>
  </body>
</html>
```

##②アニメーションを使おう
CSSでアニメーションを使うのであれば２つのことをする必要があります。
以下のコードを見ながら理解していきましょう！

```css:stylesheet.css
.fadeout { 
    animation: fadeOut 2s; /*keyframesで命名したものを使う。2秒間で消える*/
    animation-fill-mode: both; /*0%の時と100%の時の状態を保つ*/
}
  
@keyframes fadeOut {
    0% {
        opacity: 1; /*初めに存在する*/
    }
    100% {
        opacity: 0; /*最後に消える*/
    }
}
```

###.fadeoutの部分について
```animation: fadeOut 2s;```
ここがアニメーションの全てです！
読んでの通り、アニメーションとして二秒間でフェードアウトしますよっていうコードです。

```animation-fill-mode: both;```
これはフェードアウトする前とした後の状態をずっと継続させるというコードです。
これをかかないと**フェードアウトしても消えた状態が維持されません**。

ここまでは大丈夫でしょうか？
これだけでできたら楽勝なのですが流石にそこまで単純ではありません。
```fadeOut```の部分が何を表すのかを書かなければなりません。

###keyframes部分について
keyframesというものを使ってどのようなアニメーションをさせるのかを決めないといけないのです。
次のように書きます

```css

@keyframes 任意の名前 {
    0% {
        opacity: 1;
    }
    100% {
        opacity: 0;
    }
}
```
今回はフェードアウトをするのでfadeOutという名前をつけたというだけです。
0%と100%というのは「最初」と「最後」を表しています。
opacityは「存在するかしないか」を表していて、１は存在、０は存在しないということです。

#最後に
久しぶりに書いた記事ですがいかがだったでしょうか
皆さんもフェードアウトを使ってサイトをかっこよくしましょう！！
【Laravel】DB::transactionに引数渡そうとしたらUndefined propertyエラーになった件

# 環境
- Laravel Framework 6.14.0

# 結論
↓は怒られます。

```php

DB::transaction(function ($request) {
    dd($request->all());
});
```

なので、こう書きましょう。

```php

DB::transaction(function () use ($request) {
    dd($request->all());
});
```
黄金分割法のRcppでの実装例

# 1.はじめに
表題の通り．Rだと計算に時間がかかる際にC++ライクに書いて実行速度を挙げる対処法がよく利用されます．[前回の記事(囲い込みによる非線形最適化入門(私が))](https://qiita.com/m1t0/items/f14bd2e17de96dc5c5db)の黄金分割法のRcppによる実装を行いました．
# 2. サンプルプログラム
```{cpp, goldensection.cpp}
#include<Rcpp.h>
using namespace Rcpp;
//[[Rcpp::export]]

List Gsearch(Function f, List interval, double tol = 1e-6, int niter = 1000){
  double upper, lower, gam, ai, bi;
  List output(3), fs(2);
  lower = interval[0];
  upper = interval[1];
  gam = (3-sqrt(5))/2;
  //std::cout << gam << std::endl;
  ai = lower + gam*(upper - lower);
  bi = lower + (1-gam)*(upper - lower);
  output[2] = niter;
  for(int i = 0; i < niter; i++){
    //std::cout << lower << " " <<  ai << " " << bi << " " << upper << std::endl;
    double fai = as<double>(f(ai));
    double fbi = as<double>(f(bi));
    if(fai <= fbi){
      upper = bi;
      bi = ai;
      ai = lower + gam * (upper - lower);
    }else{
      lower = ai;
      ai = bi;
      bi = lower + (1-gam)*(upper - lower);
    }
    if(abs(upper - lower) < tol){
      output[2] = i;
      break;
    }
  }
  output[0] = lower;
  output[1] = upper;
  return output;
}
```

f(ai) <= f(bi)の評価の際に，そのまま評価すると，結果が安定しないという点に詰まりました．f(ai),f(bi)の返り値の型をdoubleに変換することで解決しました．
Windows(VisualStudioCode remote WSL)でPythonの開発環境を作る。

https://www.youtube.com/watch?v=eiqXgj9EUnc

いちおうYoutubeで動画とともに詳しく解説！

# motivation
WindowsPCを再インストールしたので、新たに環境構築を行う事にした
今までPyCharmを使っていたが、出先でMacbookでも開発を行う時にはVSCodeを使っていたので環境統一させたい
なんとなくremote WSLを使ってみたい

ちなみに色々あってWSL2にしている。つまり OSは Windows10 ProのInsiderPreview

# Goal
今回のゴールは以前作ったPython Pyramidのサンプルを動かすところまで
https://github.com/YukiMiyatake/YukiMiyatakeWorks/tree/prj/Python/Pyramid/main


# Pythonの設定
## minicondaインストール
PythonにはAnacondaという、Pythonのバージョン管理システムがあるが
Anacondaは機械学習など非常に多くのパッケージが入っているので
最小パッケージしか入ってない Minicondaを使う
もちろん、必要なパッケージは個別にインストール可能だ

https://docs.conda.io/en/latest/miniconda.html
より、Linux用のインストーラーを取得する。
くれぐれもWindows用を使わないこと！！

そして、ダウンロードしたシェルスクリプトを起動しインストールする


# VSCodeの設定
## VSCodeのインストール
割愛

## remoteWSLで開く
通常はWindowsで開かれている。VSCodeの左下の緑の部分に WSLと書かれてない。
なのでremote WSLで開きなおそう
左下の緑の部分をクリックし
Remote-WSL:New Window
を選ぶ。

新しいウインドウが立ち上がるが、左下の緑の部分にWSLの文字があることを確認しよう
そして OpenFolderを選ぶのだが、ShowLocalからフォルダを選ぶとWindowsになってしまうので
WSLでのパスを入力してOKを押そう
デフォルトではCドライブは /mnt/cになっているが、設定をかきかえ /cにしてある
そのあたりは別のQiitaに書いた

Terminalから pythonやcondaと入力して、先ほどインストールされたものが表示されることを確認しよう

##各種プラグインを入れる
Pythonのスニペット等必要なものを入れよう

##setup.py
必要なパッケージをインストール

```bash
$ python setup.py develop
```

##コマンドライン実行
まずはコマンドラインより、実行しブラウザで確認する

```bash
$ pserve development.ini
```

##VSCodeからDebugで立ち上げる
launch.jsonを設定します

```json
{
    "version": "0.2.0",
    "configurations": [
        
        {
            "name": "Python: Testapp",
            "type": "python",
            "request": "launch",
            "module": "pyramid.scripts.pserve",
            "args": [
                "${workspaceFolder}/development.ini"
            ],
            "pyramid": true,
            "jinja": true
        }
    ]
}
```

ブレークポイントをおいてデバッグ実行して止まればOK

##Linterの設定
Pylintは厳しすぎるので、flake8を使うことにする
ただしflake8は自動で直してくれないのでオートフォーマッタにblackを使う

condaあるいはpipで、flake8とblackをインストール

Preferenceで、Linterの設定をしていく

flake8は79文字で改行を指摘してくるがblackは88行で改行を行う
そのため、80～88文字だとflake8の指摘が残るため
flake8の設定を88文字改行にする

Preferenceから flake8の引数を設定していこう

ファイル保存時にblackでフォーマットする設定にしたのでそれを確かめる

#UnitTest
今回はunittest.pyを使う

まずはコマンドラインからunittestが叩けることを確認する

しかしこのままではテストをデバッグ実行できないのでVSCodeで設定を行う

コマンドパレット（Ctrl+Shif+P）より、単体テストの設定を行う
ここを適切に設定したのち、コマンドパレットからテスト実行をすると
Testメニューに結果が出る
今回はテスト失敗が2個出た

メニューから再テストも行えるし、ブレークポイントをはりテストをデバッグすることも可能



以上、Windowsの VisualStudioCode remote WSLでPythonの開発環境を作るメモでした
競技プログラミングテンプレ自分用

#競プロテンプレ記録用
今後追加するものがあったら追加する

```cpp
#include <bits/stdc++.h>
#define rep(i,n) for (int i = 0; i < (n); ++i)
#define all(v) (v).begin(),(v).end()
using namespace std;
using ll = long long;
using P = pair<int,int>;
using G = vector<vector<int>>;
```

```c++
//数値比較交換（ネットで見つけた）
template<class T> inline bool chmin(T& a,T b) {
    if(a > b) {
        a = b;
    }
    return false;
}

template<class T> inline bool chmax(T& a, T b){
    if(a < b){
        a = b;
        return true;
    }
    return false;
}
```
ガウスカーネルをpythonでも爆速で計算する

# はじめに
ガウス過程等で計算が必要になるガウスカーネルをバク速で計算するコードを書きます．

# コード

高速化するためにNumbaで記述しました．Numbaによる制約でコード自体は若干冗長になるのが残念ですが，高速化の効果は絶大です．Numbaで高速化するために2乗を掛け算で記述する，numpyの関数を自分で定義した関数内で使わない等の制約がありました．

```py
from numba import jit, void, f8
import numpy as np
import time


@jit(void(f8[:, :], f8[:, :]))
def gauss_gram_mat(x, K):
  n_points = len(x)
  n_dim = len(x[0])
  b = 0
  sgm = 0.2

  for j in range(n_points):
    for i in range(n_points):
      for k in range(n_dim):
        b = (x[i][k] - x[j][k]) / sgm
        K[i][j] += b * b


def gauss_gram_mat_normal(x, K):
  n_points = len(x)
  n_dim = len(x[0])
  b = 0
  sgm = 0.2

  for j in range(n_points):
    for i in range(n_points):
      for k in range(n_dim):
        b = (x[i][k] - x[j][k]) / sgm
        K[i][j] += b * b


n_dim = 10
n_points = 2000
x = np.random.rand(n_points, n_dim)
K = np.zeros((n_points, n_points))

start = time.time()

gauss_gram_mat(x, K)
K = np.exp(- K / 2)

print("Namba: {}".format(time.time() - start))

start = time.time()

gauss_gram_mat_normal(x, K)
K = np.exp(- K / 2)

print("Normal: {}".format(time.time() - start))
```

# 検証
1パターンのみですが，上記の点の数及び次元数において通常のコードとNumbaによるコードで計算速度を比較しました．

見たところ500倍近く早くなりました．（内包表記等を活用すれば，Numba無でも早くなりますが，さすがにここまでは不可能．）

```terminal
Numba: 0.11480522155761719
Normal: 50.70034885406494
```


# 補足

Numpyでも検証しました．

```python
import numpy as np
import time

n_dim = 10
n_points = 2000
sgm = 0.2
x = np.random.rand(n_points, n_dim)

now = time.time()
K = np.exp(- 0.5 * (((x - x[:, None]) / sgm) ** 2).sum(axis=2))
print("Numpy: {}".format(time.time() - start))
```

Numbaの方がNumpyより高速という結果になりました．

```terminal
Numpy: 0.3936312198638916
```
perspective modeの設定

以下の記事を参考に、perspective modeの設定を書いてみた。

https://qiita.com/atsisy/items/1b7249bf3cd6046b5681

キーバインドを設定するための`persp-set-keybind`において、バッククオートによる評価を埋め込んだところが違う点である。元記事では`lexical-let`を使っていた。

筆者はivyをよく利用しているので、`persp-ivy-switch-buffer`は重宝する。これは`ivy-switch-buffer`によるバッファ切り替えの対象を、現在のperspectiveで開いているバッファたちに限定するコマンドである。C-uをつけて実行すれば、切り替え対象が全バッファになる（つまり通常の`ivy-switch-buffer`と同じ挙動）。その他、バッファ一覧表示のための`bs-show`のperspective版もあり、たまに利用している。

```emacs-lisp
;; -*- mode: emacs-lisp; coding: utf-8-unix -*-

(require 'perspective)

;; 有効化
(persp-mode 1)

;; 現在のperspectiveに限定したivy-switch-buffer
(global-set-key (kbd "C-x b") 'persp-ivy-switch-buffer)

;; 現在のperspectiveに限定したbs-show
(global-set-key (kbd "C-x C-M-b") 'persp-bs-show)

(setq persp-state-default-file "~/.emacs.d/persp-state-file")
(add-hook 'kill-emacs-hook #'persp-state-save)

(defvar persp-switch-prefix "C-M-%d")
(defvar persp-first-perspective "2") ;; 最初のワークスペースは"2"に設定
(defvar persp-top-perspective "0")
(defvar persp-bottom-perspective "5")

(defun persp-set-keybind ()
  (mapc (lambda (i)
          (persp-switch (int-to-string i))
          (global-set-key (kbd (format persp-switch-prefix i))
                          `(lambda ()
                             (interactive)
                             (persp-switch ,(int-to-string i)))))
        (number-sequence (string-to-number persp-top-perspective)
                         (string-to-number persp-bottom-perspective))))

(defun persp-my-setup ()
  (persp-set-keybind)
  (persp-switch persp-first-perspective)
  (persp-kill "main"))

(add-hook 'persp-state-after-load-hook 'persp-my-setup)
(add-hook 'after-init-hook 'persp-my-setup)
```
GitHubにpushするのに毎度パスワードを打ちたくない！

## はじめに

開発用にUbuntu 18.04を導入しましたが、、、

GitHubにpushするときに、毎回認証情報（IDとパスワード）を入力させられて嫌になってしまいました。

Git credentialを安全にlinux上で使う方法を調べたのでメモしておきます。

## 環境

OS：Ubuntu 18.04.4 LTS
Git：version 2.17.1

なお、この方法はGit versions 2.11以上でのみ可能です。

## 方法

### Gitのインストール

`apt`を使って入れてます。

```terminal
sudo apt install git
```

### `Libsecret`のインストール・設定

Gitの`credential.helper`に`libsecret`を登録してあげることで、認証情報を暗号化してlocalに記憶できます。

```terminal
sudo apt-get install libsecret-1-0 libsecret-1-dev
cd /usr/share/doc/git/contrib/credential/libsecret
sudo make
git config --global credential.helper /usr/share/doc/git/contrib/credential/libsecret/git-credential-libsecret
```

ただし、Xserverが必要という情報がありますので、GUIを使っていない方はもしかしたら使えないかもしれません。

### 認証を通す

適当なリポジトリで認証を通せば、その認証情報が保存されて次から聞かれなくなります。やったね！

## おわりに

これにて、GitHub等にプッシュしまくれる環境が整いました。
さあ草を生やしましょう。

## 参考

https://hawksnowlog.blogspot.com/2018/10/try-git-credential.html
https://www.softwaredeveloper.blog/git-credential-storage-libsecret
CentOS 7にPython 3とpipenvをインストール

### Python 3のインストール

Python 3はEPELリポジトリからインストールできる。

```
# yum install epel-release
# yum install python3
```

pipが`pip3`という名前でインストールされることに注意。

```
$ python3 --version
Python 3.6.8
$ pip3 --version
pip 9.0.3 from /usr/lib/python3.6/site-packages (python 3.6)
```

### pipenvのインストール

```
$ pip3 install --user pipenv
```

```
$ pipenv --version
pipenv, version 2018.11.26
```
Docker上でGUIのROS1/ROS2を一瞬でセットアップする方法

<img width="640" alt="docker-ros-desktop-vnc.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81919/7dcd2db8-d18f-3a4d-0815-ee86f52334e6.png">

# Docker上でGUIのROSを動かす
　[Tiryoh](https://twitter.com/tiryoh)さんがGitHub上で素晴らしいリポジトリを公開していました。

https://github.com/Tiryoh/docker_ros-desktop-vnc

　素晴らしさに感動してしまったので、素晴らしさを少しでも広めるために、簡単な紹介記事を書いてみます。

　このリポジトリは、Docker上でGUIのROSを動かすことができます。Dockerさえ入っていればMacでもLinuxでも（多分）Windowsでも、一瞬でUbuntu+ROSの環境が手に入ります。ROSはセットアップがそれなりに大変なので、Dockerさえ入っていればコマンド一発で環境構築できるのは最高ですね。

　Dockerって何？という方やインストール方法が分からない方は、以前私のブログに書いた下記記事を参照下さい。

https://karaage.hatenadiary.jp/entry/2019/05/17/073000

　Dockerをインストールしたら、後は以下のコマンドを実行するだけです。

```sh
$ docker run -p 6080:80 --shm-size=512m tiryoh/ros-desktop-vnc:melodic
```

　初回は、イメージのダウンロードから始まるので時間かかります（2回目以降はすぐ起動します）。

　Docker上でVNCが走っているので、リモートログインができます。特殊なソフトは必要なくて、好きなブラウザで以下のアドレス（自分のPCのアドレス）にアクセスするだけです。

```sh
http://127.0.0.1:6080/
```

　これで、ブラウザ上でROS環境が動きます。ヒュー！最高ですね。あとは、2つターミナル起動して、それぞれに以下のようにコマンドを打つと、おなじみのカメさんのシミュレータが動きます。

```sh
$ roscore
```

```sh
$ rosrun turtlesim turtlesim_node
```


<img width="640" alt="docker-ros-desktop-vnc.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81919/7dcd2db8-d18f-3a4d-0815-ee86f52334e6.png">
　カメさん！

　うれしくて、Twitterで呟いたら、[Tiryoh](https://twitter.com/tiryoh)さんからROS2版もあるよというコメント。まさに欲しかったやつです。最高かよ！ブログ記事も楽しみです！

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ありがとうございます！近々ブログに書きます……<br>ROS2版もあるので、もしよければ是非！<a href="https://t.co/JlRolBxcBg">https://t.co/JlRolBxcBg</a></p>&mdash; たいりょーくん (@Tiryoh) <a href="https://twitter.com/Tiryoh/status/1229034297736097792?ref_src=twsrc%5Etfw">February 16, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

　ROS2版のGitHubリポジトリは以下です。ROS版と同じ要領で動かせます。

https://github.com/Tiryoh/docker_ros2-desktop-vnc

# まとめ
　Docker環境のGUIにブラウザでアクセスできるの、めちゃ良いですね。この組み合わせは他にも色々応用効きそうです。

# 追記
　リポジトリ製作者の[Tiryoh](https://twitter.com/tiryoh)さんが、公式にブログで解説記事を公開していらっしゃいますので、こちらも是非読みましょう！

https://memoteki.net/archives/2955

　以下はスライド資料です。様々な環境構築手法に関してまとめられています。

https://docs.google.com/presentation/d/1Pmwb5wAY2JKZah-uniEo3M7polo7UeWSMiQxUQioR3s/edit?usp=sharing

# NVIDIA Docker版

https://twitter.com/dandelion1124/status/1570024533368905729

# 参考リンク
https://docs.google.com/presentation/d/15DhhHjSwhhrKQMRPGz4D6EdmAjMkLcudqijz6JTokzI

https://qiita.com/ina_ta/items/80689b2061cd0b057fd7

https://memoteki.net/archives/4471

https://qiita.com/porizou1/items/d6ff78035544999d7c1c

https://qiita.com/takahashiakari/items/f096e5bcdfecf3d5ba90
【c言語】implicit declaration of functionを回避するプロトタイプ宣言

エラーとなるコード

```c
#include <stdio.h>
int main(void){
    int value;
    average(50, 100, &value); 
    printf("%d\n", value);
    return 0;
}

void average (int min, int max, int *answer) {
    *answer = (min + max)/2;
    return;
    
}
```

プログラムは上から処理される。
main関数ではaverage関数を呼び出している。しかし、average関数はmain関数より後に書かれているため下記のようなエラーが生じる。
つまり、使用する関数は呼び出す前に定義されていないといけない。

```
Main.c:8:5: warning: implicit declaration of function 'sum' is invalid in C99 [-Wimplicit-function-declaration]
    sum(50, 100, &value); 
    ^
Main.c:13:6: error: conflicting types for 'sum'
void sum (int min, int max, int *answer) {
     ^
Main.c:8:5: note: previous implicit declaration is here
    sum(50, 100, &value); 
    ^
1 warning and 1 error generated.
```

上記エラーを回避するための方法は2つ。

1つ目は記載順を変えること。average関数をmain関数より前に記述すればOK。
2つ目はプロトタイプ宣言をすること。
プロトタイプを宣言すると、関数について並びを考慮する必要がなくなり良い。
プロトタイプ宣言は、関数の中身の処理は省いて名前だけ先に定義できる機能。

下記のようにコードの先頭で宣言しておけばよい。

```c
#include <stdio.h>

void average (int, int, int*); //プロトタイプ宣言！

int main(void){
    int value;
    average(50, 100, &value); 
    printf("%d\n", value);
    return 0;
}

void average (int min, int max, int *answer) {
    *answer = (min + max)/2;
    return;
    
}
```



つぶやき。
main関数ってコードの一番下に書かれてることが多いなーなんでだろうなーと思っていたけど、
関数が宣言されてから使う必要がある（もしくはその名残？）からだったのか！と思った。
Nutanix Files使ってみた

# Nutanix Filesを使ってみた

Nutanixクラスタ上にファイルサーバーを作って欲しいという依頼があったので
去年から1TiBまでなら無償で利用出来るようになったNutanix Filesを構築してみました。
※商用版Nutanixユーザー限定です。

## はじめに

今回以下は以下のサイトと公式ドキュメントを参考に構築しています。

「**インフラ屋とアプリ屋のあいだ**」様
http://infraapp.blogspot.com/2019/12/nutanix-files1.html

公式ドキュメント
Nutanix Portal
NUTANIX FILES GUIDE
※全編英語、つらい。


## 環境
AOS:5.10.5LTS
ESXi:6.7
Nutanix Files:3.6.11

## やってみる
1. 左上のクラスタ名称の辺りをクリックすると、「**クラスタ詳細**」が出てくるので、ここでiSCSIのデータサービスIPを設定されている事を確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117450/afcf24d2-ac3f-951a-6c7f-71f8e5c4a656.png)

2. 右上の歯車アイコンをクリックして。「**ソフトウェアアップグレード**」から「**File Servewr**」を選択します。
今回はすでにダウンロード済みなので「Continue」と表示されている事を確認
Proxyの設定を行えば1クリックでダウンロードできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117450/0001e7c2-3202-0f70-8ae6-82d06b67902f.png)

3. 「**Continue**」をクリックすると、新規ファイルサーバープリチェックが実施されます。
問題ないことを確認したら、「**続行**」を押してしまいましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117450/11b697d7-0cfe-0808-fac6-7da30da36552.png)

4. まずは基本設定ということで、以下項目を設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117450/d8d85873-0c61-ca1b-1a53-3a5ce7902f8e.png)

名前：ファイルサーバーの名称
ドメイン：ドメイン名を入力
ファイルサーバー容量：ここでは1TiBを入力
容量設定はカスタマイズ可能なようですが、ここは最小構成のままで

5. 次にネットワーク回りの設定を行います。
設定は「**クライアントネットワーク**」と「**ストレージネットワーク**」に分かれていてまずはクライアント側から

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117450/bddd29cf-edea-c23c-3e4a-492df5893be9.png)

項目は以下の通り
ポートグループ：利用するポートグループを選択
サブネットマスク：利用するNWのサブネットマスクを入力、24だと怒られた
ゲートウェイ：デフォルトゲートウェイを入力

必要なIPアドレス：
+IPアドレスのボタンを入力すると、IPアドレス入力欄が出てくるので入力する。
Nutanix FilesはFSVMを各ノード分作成されるのでノードの個数分だけ必要です。
標準で利用するIPアドレスレンジを入力する仕様になっているので、先頭のIPアドレスを入力しました。

次はストレージ側、上に図があって設定している部分がわかりやすい気がする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117450/f292097e-b9f8-a0e5-fbf7-9ece3fadb398.png)

同じようにストレージ側の設定を入力していきます。
基本的に必要な項目はクライアント側と一緒ですが、
ストレージ側で設定するIP/はiSCSIのデータサービスIPと同じセグメントにする必要があるので認識しておきましょう。

6. 次は「**ディレクトリサービス**」という項目で利用するプロトコルを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117450/7a59cd60-a390-ff8c-3839-a7827de5cc52.png)


今回はSMBで利用するので、SMBにチェックを入れ必要な項目の設定を入力します。
ドメインや、ドメイン参加に利用するIDなどの設定が必要です。

7. 最後にサマリーが表示されるので、問題なければ「**Create**」してしまいましょう！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117450/a399bb80-1996-4aab-8a99-e7026ba7264e.png)


以上、意外と簡単に作るとこまでは出来ました。

ただ、上手くいった！？と思ったら以下のような事件も
・各ノードにFSVMがデプロイされるかと思いきや、同じノードに2つFSVMがデプロイされるというよくわからない出来事
　⇒とりあえずvMotionで移行しといた。やってよかったのかは謎
・正引きアドレスはADDNSに登録されたが、逆引きが登録されなかった。
　⇒これに関しては使ったADアカウントが悪かった説があり、大人しく逆引きを手動で登録しました。

「**インフラ屋とアプリ屋のあいだ**」様がまとめてる当時と名前が変わっちゃっていますが、
設定する項目などは変更がなさそうです。
あと**UIがちゃんと日本語化されてます！！！**

以上、意外と簡単に構築することは出来たので、使う機会があれば使ってみるといいかもしれません。

時間があればいろいろな設定を入れて動かしてみたのでそれについてもまとめたいと思います。
【Python Tips】辞書から最大値を持つkeyを複数取り出す方法

[ABC155 C - Poll](https://atcoder.jp/contests/abc155/tasks/abc155_c)で連想配列で解ける問題が出たが、表題の処理がうまく書けなかったのでメモ。

最大値を持つkeyは複数あることを想定しています。(2020/02/19更新)

```python:dic_max.py
# 適当に辞書初期化
d = {}
d["k1"] = 10
d["k2"] = 20
print(d)
# {'k1': 10, 'k2': 20}
```

```python:dic_max.py
# 辞書dのvalueの最大値を取り出す処理 -> max(d.values())
max_val = max(d.values())
print(d.values())
print(max(d.values()))
# dict_values([10, 20])
# 20

# これはエラー
# print(d.value[0])
# TypeError: 'dict_values' object does not support indexing
```


```python:dic_max.py
# keyとvalueをfor文で回す前処理 -> d.items()
print(d.items())
# dict_items([('k1', 10), ('k2', 20)])

# これはエラー
# print(d_i[0])
# TypeError: 'dict_items' object does not support indexing

```

```python:dic_max.py
max_k_ls = [kv[0] for kv in d.items() if kv[1]==max_val]
# d.items() = dict_items([('k1', 10), ('k2', 20)])からループ一回目は
# kv = ('k1', 10)として取り出せる(kv[0] = 'k1'、kv[1] = 10)。
# kv[1] == max_valでvalue最大値と同じ値の時だけリストにkv[0](=key)追加
# 二回目以降も同様


# リストやタプルに*を付けて引数に指定 -> 展開されてそれぞれの要素が個別に渡される
print(*max_k_ls)
# k2
```
# 参考サイト
[AtCoder Beginner Contest 155](https://atcoder.jp/contests/abc155)
[Pythonで辞書の値の最大値・最小値とそのキーを取得](https://note.nkmk.me/python-dict-value-max-min/)

# 追記

コメントでアドバイス頂いた手法
@shiracamus さん
@konandoiruasa さん
@nkay さん
ありがとうございます。

・keyの最大値に被りが無い場合

```python
>>> d = {"k1": 10, "k2": 20}
>>> d
{'k1': 10, 'k2': 20}
>>> max(d, key=lambda k: d[k])
'k2'
```

・pandasを使った手法

```python
>>> import pandas as pd
>>> import numpy as np
>>> d = {"k1": 10, "k2": 20, "k3": 20}
>>> df = pd.DataFrame([d])
>>> list(df.columns[np.where(df.iloc[0] == df.iloc[0].max())])
['k2', 'k3']
```
内包表記

## リスト内包表記

```py
l = []
for i in range(10):
    if i % 2 == 0:
        l.append(i)
print(l)
```

同じことがリスト内包表記では下記のようになる

```py
l = [i for i in range(10) if i % 2 ==0]
print(l)
```

```text:出力
[0, 2, 4, 6, 8]
```

## 辞書内包表記

```py
w = ['Monday', 'Tuesday','Friday']
f = ['banana', 'apple', 'orange']
d= {}
for x, y in zip(w,f):
    d[x]=y
print(d)
```

同じことが辞書内包表記では下記のようになる

```py
w = ['Monday', 'Tuesday','Friday']
f = ['banana', 'apple', 'orange']
d = {x:y for x,y in zip(w,f)}
print(d)
```

```text:出力
{'Monday': 'banana', 'Tuesday': 'apple', 'Friday': 'orange'}
```

## 集合内包表記

```py
s = set()
for i in range(10):
    if i % 2 == 0:
        s.add(i)
print(s)
```

同じことが集合内包表記では下記のようになる

```py
s = {i for i in range(10) if i % 2 == 0}
print(s)
```

```text:出力
{0, 2, 4, 6, 8}
```

## ジェネレータ式

```py
def g():
    for i in range(10):
        if i % 2 == 0:
            yield i
g = g()
print(next(g))
print(next(g))
print(next(g))
print(next(g))
```

同じことがジェネレータ式では下記のようになる。

```py
g = (i for i in range(10) if i % 2 == 0) #タプルではないので注意が必要
# g = tuple(i for i in range(10) if i % 2 == 0) タプルの内包表記
print(next(g))
print(next(g))
print(next(g))
print(next(g))
```

```text:出力
0
2
4
6
```

なお、公式ドキュメントに「ジェネレータ表記法」と書いてあり「ジェネレータ内包表記」ではない。
https://docs.python.org/ja/3/reference/expressions.html#generator-expressions
> ジェネレータ式 (generator expression) とは、丸括弧を使ったコンパクトなジェネレータ表記法です:
ジェネレータ式は新たなジェネレータオブジェクトを与えます。この構文は内包表記とほぼ同じですが、角括弧や波括弧ではなく、丸括弧で囲まれます。
【NEAT】python3(anaconda3)を使ってNEATを実装してみた(5/5)

前回は交配をして新たな子供の世代を作りました。この最終記事では、今までと同じ操作をwhileを用いて一気に操作します。



###whileでループ

```python:
while 1:
    '''種に分ける'''
    species.speciate(population, generation)
    
    '''成績を計算'''
    FeedForwardNetwork.eval_genomes(list(population.items()))

    best = None
    for g in population.values():

        if best is None or g.fitness > best.fitness:
            best = g

    if best_genome is None or best.fitness > best_genome.fitness:
        best_genome = best

    fv = max(g.fitness for g in population.values())
    if fv >= fitness_threshold:
        print('\nBest individual in generation {0} meets fitness threshold - complexity: {1!r}'.format(generation, best.size()))
        break

    '''交配'''
    popus = DefaultReproduction()
    population = popus.reproduce( species, pop_size, generation)

    generation += 1

'''水準を超えた成績最優秀ネットワークの発表'''
winner=best_genome

print('\nBest genome:\n{!s}'.format(winner))

print('\nOutput:')
winner_net = FeedForwardNetwork.create(winner)
for xi, xo in zip(xor_inputs, xor_outputs):
    output = winner_net.activate(xi)
    print("  input {!r}, expected output {!r}, got {!r}".format(xi, xo, output))
```
![スクリーンショット 2020-02-16 19.56.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/582794/6d655b6e-e1d4-32a1-6d64-81dfbd678f9f.png)

NodesとConnectionsの数が最初に比べてかなり大きくなりました。これを図にすると、次のようになります。
![image (9).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/582794/79994ccb-435b-1a85-c72b-b79c3e04525f.png)

1,2,3のNodesは中間層として存在します。論文を見ると、中間層がないと出力の精度は良くならないらしいので、その点で中間層ができていることは納得がいきます。

以上でNEATの説明を終わります！

今回は比較的挑戦しやすいと考えている排他的論理和について触れましたが、さらにSingle-Pole-Balancingなども挑戦したいと考えています。

ここまで続いた全5回の記事はここで終了となります。少しでも読者様のお役に立てれば嬉しいです。ここでまで読んでくださった方がいれば本当にありがとうございます。

何か誤りやご指摘があれがぜひコメントください。よろしくお願いします。

* [NEAT実装してみた（1. NEATの概要、populationの用意）](https://qiita.com/suna__ck/items/6229fd0f05c05f398af2)
* [NEAT実装してみた（2. 種に分ける）](https://qiita.com/suna__ck/items/52582925f41415d7308d)
* [NEAT実装してみた（3. 成績の計算）](https://qiita.com/suna__ck/items/31824504cae8caacaec8)
* [NEAT実装してみた（4. 交配・突然変異）](https://qiita.com/suna__ck/items/15baee6926f05d8894e8)
* [NEAT実装してみた（5. 最終結果）](https://qiita.com/suna__ck/items/762317a8da5d3cd42af9)
SlackAPIを使う際に参考にさせて頂いた記事メモ

# 目的
SlackAPIを使う際に参考にさせて頂いた記事メモです

# 記事
色々手間取ってしまいましたが、こちらの手順でSlackAPIの確認ができました。
ありがとうございました。

> [Slack APIを使用してメッセージを送信する](https://qiita.com/kou_pg_0131/items/56dd81f2f4716ca292ef)

# 参考
[Slack APIを使用してメッセージを送信する](https://qiita.com/kou_pg_0131/items/56dd81f2f4716ca292ef)
[Slack API 推奨Tokenについて](https://qiita.com/ykhirao/items/3b19ee6a1458cfb4ba21)
[Slack APIを使用してメッセージを送信する](https://qiita.com/rubytomato@github/items/6558bfdb37d982891c09#curl)
[GitHub ActionsでSlackに通知を飛ばそう](https://www.flywheel.jp/blog/notify-slack-via-github-actions/)
[GitHub Actionsでリポジトリにスターが付いたらSlackに通知する](https://note.com/anatoo/n/n16e875c065f9)