OmniAICreator/Qiita-1.07M huggingface dataset:
[Circle CI]コンテキスト環境変数で、ワークフローごとの環境変数の設定を簡潔にする

Circle CIにはコンテキスト環境変数というものがある。基本的には、複数プロジェクト(=リポジトリ)で共通の環境変数を定義するときに使うが、ワークフローごと(≒ブランチごと)の環境変数の設定を簡潔にすることにも使える。以下、ケーススタディ形式で説明する。

## 状況設定

- developとmasterのpushに対してCircle CIのビルド実行
- developとmasterのビルド処理は全く同じで、ビルドパラメータだけが異なる
- ビルドパラメータは秘密にしたい情報も含まれているので、Circle CIの環境変数として定義する
- 以下の５つの環境変数があり、developとmasterで値は別にする
  - BUILD_TYPE
  - KEY_STORE
  - KEYSTORE_PASSWORD
  - KEY_STORE_ALIAS
  - KEY_STORE_ALIAS_PASSWORD


## コンテキスト環境変数を使って、ワークフローごとの環境変数を設定する場合

まず、Circle CIのコンテキスト環境変数を作る。

1. Circle CIのOrganization Settingsを開く
2. Contexts -> Create Contextで2つコンテキストを作る。"master", "develop"という名前にする[^1]
3. 最初に示した5つの環境変数を追加し、master/develop固有の値を設定する

次に、Circle CIのビルドスクリプトを書く。masterとdevelopブランチのワークフローを分けて、ワークフロー側からjobに対して環境変数を設定する。以下、例。

```yaml:.circleci/config.yml
version: 2.1

jobs:
  build:
    executor: foobar
    steps:
      - setup
      - build # この処理で環境変数を参照する
      - post_steps

workflows:
  version: 2
  internal_release:
    jobs:
      - build:
          context: develop
          filters:
            branches:
              only:
                - develop
  release:
    jobs:
      - build:
          context: master
          filters:
            branches:
              only:
                - master

```

この方法の良いところは、ワークフローごとで環境変数名を同じにできること。それゆえ、環境変数名による分岐処理をなくすことができる。

## コンテキスト環境変数を使わないで、ワークフローごとの環境変数を設定する場合

まず、Circle CIのProject Settingsの環境変数として、ビルドパラメータを定義する。この場合、masterとdevelopで同じ名前にすることはできないので、developブランチのビルド向けの環境変数名の末尾には"_DEV"を付けるようにする。

次に、Circle CIのビルドスクリプトを書く。環境変数CIRCLE_BRANCHをチェックし、"develop"であれば名前に"_DEV"が付いた環境変数を、"_DEV"が付かないものに変換する。以下、例。

```yaml:.circleci/config.yml
version: 2.1

jobs:
  build:
    executor: foobar
    steps:
      - setup
      - run:
          name: "Setup Env Vars"
          command: |
            if [ "$CIRCLE_BRANCH" = "develop" ]; then
                echo 'export BUILD_TYPE=Debug' >> $BASH_ENV
                echo 'export KEY_STORE=KEY_STORE_DEV' >> $BASH_ENV
                echo 'export KEY_STORE_PASSWORD=KEY_STORE_PASSWORD_DEV' >> $BASH_ENV
                echo 'export KEY_STORE_ALIAS=KEY_STORE_ALIAS_DEV' >> $BASH_ENV
                echo 'export KEY_STORE_ALIAS_PASSWORD=KEY_STORE_ALIAS_PASSWORD_DEV' >> $BASH_ENV
            fi
      - build # この処理で環境変数を参照する
      - post_steps

workflows:
  version: 2
  build:
    jobs:
      - build:
          filters:
            branches:
              only:
                - develop
                - master

```

この書き方の問題点は、config.ymlの見通しが悪くなること。

## コンテキストのリファレンス
https://circleci.com/docs/ja/2.0/contexts/


[^1]: 実運用では、もっと長いコンテキスト名を付けた方が良い。組織の全リポジトリで一意でないとNGなので。
XMLのフォーマットを決める時の判断基準

#XMLのフォーマットを決める時にどうすればいいか
動画を管理するツールを作ろうと思い、アプリケーションではXMLで情報を管理しようと思ったが、
XMLのフォーマットをどうしようか、と迷いました。
具体的には、、、

 - この情報は、要素？　属性？
 - 要素名は、大文字？　小文字？

方針を決めるべく、調べてみることに。

##参考になる情報がほしい
W3Cのサイトを見ればいいのかもしれないが、期待するものはなさそうなので、こういう時はGoogleに頼ろう。
なんと、GoogleがXMlスタイルガイドを公開していたので、これを元に「決まり」を考えることにしました。

[Google XML Document Format Style Guide](https://google.github.io/styleguide/xmlstyle.html)
https://google.github.io/styleguide/xmlstyle.html

どうやら2008年から存在しているドキュメントのようだ。（古い）
英語を読むのは疲れるので、Google翻訳の結果を掻い摘んで、自分用に必要なところだけまとめる。

##XMLフォーマットを決める判断基準はこうしよう
XMLのフォーマットに関するあれこれは、ドキュメントをみればいいとして（フォーマットを知りたいのではないので）、
要素と属性の判断基準はこうしようと思った。

 - 命名規則は「lowerCamelCase」にする→「sample」や「sampleData」や「sampleDataList」ね
 - 要素にする→項目が10個を超える場合
 - 要素にする→改行が必要なデータがある、複数行になる場合
 - 要素にする→繰り返し出てくるデータの場合
 - 要素にする→ユーザーに表示するデータの場合
 - 要素にする→独立したデータにできる場合
 - 要素にする→サブ要素が必要になる情報
 - 属性にする→XML内で固有のもの、XMLで変わらないもの（IDとか管理コードなど）
 - 属性にする→データの処理方法などの定義情報

##参考にXMLを作った
上記をベースに、動画を管理するためのXMLファイルを定義してみました。
※かなり簡単に、単純に、明瞭に。

```video_list.xml
<?xml version="1.0" encoding="UTF-8"?>
<video id="hogehoge">
    <item>
        <fileName>動画1.mp4</fileName>
        <fileSize>1024000</fileSize>
        <length>1:23</length>
    </item>
    <item>
        <fileName>Movie_hogehoge.mp4</fileName>
        <fileSize>82876258</fileSize>
        <length>10:59</length>
    </item>
</video>
```
アドベントカレンダー9日目：SREを読んでみた「サービスレベル目標」編③

前回は、サービスレベル目標の内、SLI：サービスレベル指標について、学びました。
サービス指標は、システム面から見たサービスレベルの客観的な値になります。SLIは、多すぎず、少なすぎず、システムを把握するのに十分な指標を持つべきであること、データを平均で見ると、実際のデータの変化を隠してしまうことがあるので、分布で把握することが重要であると学びました。
今回は、サービスレベルの残りの項目、SLO（サービスレベル目標）、SLA（サービスレベルアグリーメント）について学びます。

## 目標の在り方
サービスレベル目標はどのような目標に設定するのが良いのでしょうか？前回のSLIの内容から考えて、レイテンシやレスポンス、可用性などを良くすればいいのでしょうか？目標を定める段階では、できるだけわかりやすい目標を立てたいと考えてしまいます。目標がそのような形になっていることは重要ですが、考えのはじめとして、このように考えることは視野を狭めてしまう場合もあります。
サービスレベル目標を定めるのは、ユーザーに目標を明示することにより、過剰にシステムを信頼したり、疑念を持たれることを避ける意味もあります。目標は、ユーザーが気にすることが何なのか？それに合わせて、設定することが重要です。もちろん、その過程を経た後、サービスレベル目標の決定にSLIを用いることは、

#### 目標の定義
ユーザー間でインタラクティブな処理を行うシステムの場合、レイテンシが重要になります。バルク処理のような、レイテンシよりもスループットが重要なサービスもあります。
このような場合は、ユーザーの目的に応じて、SLOを個別に設定することが適切になります。
また、定義したSLOを常に満たし続けるのは、現実的でも、望ましいことでもありません。
なぜなら、そのような取り組みは、開発やデプロイの速度を落とし、高価で、過剰に保守的なソリューションになってしまうからです。それよりもエラーバジェットを認めて、それに応じた取り組みを行う。エラーバジェットの状態を追跡する方が重要です。

#### ターゲットの選択
あるシステムに適切なターゲット（SLO）を選択します。
その時のコツとして、以下がGoogleの教訓として、上がっています。

> * **現在のパフォーマンスに基づいて、ターゲットを選択してはならない**
* **シンプルさを保つ**
* **「絶対」は避ける**
* **SLOは最小限に止める**
* **最初から完璧でなくてもいい**

基本的な考えとして、SLOとはサービスの発展と共に変化するものです。
そのための教訓であると考えると理解できます。
SLOは厳しすぎても、チームがその達成の為に労力を使ってしまい、甘すぎてもプロダクトの質が落ちます。
重要なのは、どの程度のサービスの質をユーザーへ提供したいのかをチームで議論していくことです。

#### SLOによる期待の設定
SLOを設定し、それをユーザーへ説明することは、ユーザーの過剰なシステムの信頼が生まれることを防ぐことができます。また、ユーザーが自分のシステムを構築する上でも、サービスの特徴を知ることができるので、サービスの選択の助けになります。
このようなユーザーの期待を設定するときの戦略として、ユーザーに対するSLOより内部の
SLOを厳しくしたり、SLOを過剰に達成しようとすることを避けることが重要です。

## アグリーメントの在り方
SLAは、SLOとSLOが達成できない際のペナルティなどを示したものです。
適切なアグリーメントを設定することは、SREチームの責務ではないですが、SLOの設定の際に支援を行います。また、SLAは顧客へ見せるものなので、顧客の規模が大きくなるほど、変更が難しくなります。そのため、まずは目標は小さく設定しておくことが無難です。

##まとめ
* SLOの定義の際は、まず、ターゲットや目標定義を行うことが重要
* SLOは、最初から決定されるものではなく、育てるもの

#### 参考文献
1. Betsy Seyerほか　SRE サイトリライアビリティエンジニアリング　オライリー　47-49
Nuxt.jsでvue-slickを使う

# 前提条件

- [Nuxt.jsでpugとstylusを使う
](https://qiita.com/oblivion/items/95ffa0cd55be8f54fcfd)

これを設定している

# インストール

```shell
$ npm i -S vue-slick jquery slick-carousel
```

# 使う

```html:slider.vue
<template lang="pug">
.slider
  client-only
    Slick(:options="slickOptions")
      .slider-item(v-for="i in 3" :key="i")
        img(src="https://placehold.jp/150x150.png")
</template>

<script>
import '~/node_modules/slick-carousel/slick/slick.css'

export default {
  components: {
    Slick: () => process.browser ? import('vue-slick') : null,
  },
  data: () => ({
    slickOptions: {
      swipe: true, // スワイプできるか
      slidesToShow: 1, // スライドを何個表示するか
      infinite: true, // ループさせるか
      vertical: false, // 縦に表示するか
      verticalSwiping: false, // 縦にスワイプできるか
      draggable: true, // マウスでドラッグできるか
      arrows: true, // アローを使うか
      prevArrow: '<div class="slide-prev"></div>', // 戻るアローのdomを指定
      nextArrow: '<div class="slide-next"></div>' // 次へアローのdomを指定
    }
  })
}
</script>

<style lang="stylus" scoped>
.slider
  img
    width 100%
</style>
```

# Nuxt.jsのそのほか

- [Nuxt.jsを使う](https://qiita.com/oblivion/items/3488e41af630a3b07ff6)
【Java】substringメソッド(指定した部分を抜き出す)

# Javaのsubstringメソッド

についてまとめました。

## substringメソッドとは

一言でいうと「文字列から部分文字列を抜き出す」事ができるメソッドです。

## 【説明】

### substringメソッドの書き方

substring以下の書き方です。

- 第一引数に抜き出し開始の位置を指定
- 第二引数に抜き出し終了位置を指定（※この文字は含まない）

```java
"文字列".substring(抜き出し開始位置, 抜き出し終了位置);
```

### 文字列の長さを超える値を指定すると？

結論、例外が発生します

## 【サンプルコード】

サンプルコード内の引数の値と

```java
public class Main {

    public static void main(String[] args) {
        //抜き出し前の文字列
        String str = "恥の多い生涯を送って来ました。自分には、人間の生活というものが、見当つかないのです。";
         //1文字目から16文字目まで抜き出す
         String life = str.substring(0,15);
         //出力結果：恥の多い生涯を送って来ました。
         System.out.println(life);

    }

}
```

```java
恥の多い生涯を送って来ました。
```

## 【まとめ】

覚えておくポイントは以下です。

- 文字列の長さを超える値を指定すると例外が発生する。
- 第一引数に抜き出し開始の位置を指定
- 第二引数に抜き出し終了位置を指定
- 左から0スタート

結構便利なメソッドな気がしますが、今度これを使ったアプリとかも考えてみたいですね。

## 参考文献・記事

- [徹底攻略Java SE 11 Silver問題集[1Z0-815]対応](https://www.amazon.co.jp/%E5%BE%B9%E5%BA%95%E6%94%BB%E7%95%A5Java-SE-11-Silver%E5%95%8F%E9%A1%8C%E9%9B%86-1Z0-815/dp/4295007625/ref=pd_lpo_14_img_0/356-5238196-1895250?_encoding=UTF8&pd_rd_i=4295007625&pd_rd_r=1c21865b-a9fe-43e8-ac01-46170e44abca&pd_rd_w=9El0Q&pd_rd_wg=hh5Hc&pf_rd_p=4b55d259-ebf0-4306-905a-7762d1b93740&pf_rd_r=72AVH18EM90CKG00CH5W&psc=1&refRID=72AVH18EM90CKG00CH5W)
- [文字列を抜き出す！Javaでsubstringを使う方法【初心者向け】](https://techacademy.jp/magazine/17681)
【UE4】サウンドキューを使ってSEをランダムに鳴らす

# 最初に

どうも、ろっさむです。

今回はサウンドキューを使用してSEをランダムに鳴らす場合の作成方法を自分用にまとめておこうと思います。

作業環境は以下の通りです。

- UE4.26
- Windows 10

また、今回主に参考とさせていただいたのは以下のUdemy講座となります。

[Unreal Engine C++ Developer: Learn C++ and Make Video Games](https://www.udemy.com/course/unrealcourse/)
![image](https://user-images.githubusercontent.com/10665134/101935424-6a9a8c00-3c22-11eb-9d9d-ca3a2748cfdf.png)

# 手順

## サウンドキューを作成する

まずはサウンドキューを入れておく用のフォルダ `SFX`を作成します。

![image](https://user-images.githubusercontent.com/10665134/101930414-76cf1b00-3c1b-11eb-853e-9d5f6e8b1385.png)

フォルダ内にて右クリック（又は「Add New」）をして、メニューから**`Sounds > Sound Cue`**を選択します。

![image](https://user-images.githubusercontent.com/10665134/101930530-9d8d5180-3c1b-11eb-995e-912ec0726290.png)

ここではライフルのショット音用のサウンドキューを作成するため、名前を `SE_RifleShot_Cue`とします。

![image](https://user-images.githubusercontent.com/10665134/101932125-b0a12100-3c1d-11eb-885c-c3e439fcb4ba.png)

## SEをランダム再生する

エディタ上で右クリックを行って、**`Wave Player`ノード**を作成します。

作成したノードを選択して、`Details`から再生したいSEのアセットを設定し、`Looping`がオフになっていることを確認します。

![image](https://user-images.githubusercontent.com/10665134/101933159-28bc1680-3c1f-11eb-92c4-5de24279f295.png)

次に、**`Random`ノード**を作成します。

今回は6つの音を繋げたいため`Add input`で入力ピンを増やしておきます。
![image](https://user-images.githubusercontent.com/10665134/101933735-f5c65280-3c1f-11eb-94f4-689eba8f7867.png)

この`Random`ノードの`Details`では、サウンド毎の選択される確率を設定できたり、メモリ削減用のオプションを確認できます。

**`Randomize Without Replacement`**は`true`の場合、**入力に繋がれているサウンドが全て再生されるまでは再生されたサウンドが再度再生されることはありません**。例えばランダムで1つめのSEが再生された場合、次に再生されるのは残りの5つのSEの中からどれかになります。

入力ピンに全てのSEを繋いでから、`Random`から`Output`へ繋ぎます。

![image](https://user-images.githubusercontent.com/10665134/101935183-05df3180-3c22-11eb-87fe-28e9c8325ae2.png)

これでランダムに鳴るようにはなりました。

## ピッチをランダムにする

更に音にランダム性をつけるために、SEのピッチを変更します。

これは**`Modulator`ノード**を使用します。
![image](https://user-images.githubusercontent.com/10665134/101935673-c36a2480-3c22-11eb-821c-541e4c36f871.png)

ここの`Pitch Min`や`Pitch Max`で範囲を指定することで、ランダムなSEに更に範囲内のランダムなピッチ値を設定することができます。必要であれば`Volume`に関する項目も変更してください。

設定後は`Random`ノードの出力から`Modulator`ノードへ繋げます。

![image](https://user-images.githubusercontent.com/10665134/101935913-2360cb00-3c23-11eb-94fe-429017369aff.png)

これで少ないアセットでもバリエーションに富んだSEを用意することができるようになりました。


# 参考

- [UE4 Sound CueのRandomの使い方](http://mozpaca.hatenablog.com/entry/20180418/1524044012)
QueryJobConfig で DATE の後に括弧を付けずに文字列変数を与えるとシンタックスエラーになる

# エラーの発生

データを集計するために BigQuery でクエリを発行していました。日付を指定してデータを取得しようとしたときにエラーが発生しました。

# 内容

コードは本質的な箇所以外を簡略化しています。

```python
from google.cloud import bigquery

client = bigquery.Client()

start = "2020-12-01"

query = """SELECT DATE @start"""

job_config = bigquery.QueryJobConfig(
    query_parameters = [
        bigquery.ScalarQueryParameter("start", "STRING", start)
    ]
)

query_job = client.query(query, job_config = job_config)
```

`DATE` の後ろに `@start` で日付の変数を文字列で挿入して、 `SELECT DATE "2020-12-01"` のようにしようとしました。ここでエラーが発生しました。

```shell
google.api_core.exceptions.BadRequest: 400 Syntax error: Unexpected "@" at ...
```

この文言で、最初は変数がきちんと埋め込まれていない、要は job_config が間違えているのかと考えました。
しかしそれは間違いで、手順としては `@` マークの変数込みでシンタックスを解析し、問題なければ変数を埋め込むという流れのため、最初の段階でエラーが起きていたようです。

# 解決

`DATE "2020-12-01"` は日付を書く構文として正しいですが、これはリテラルで与える場合で、変数を用いる場合は次のように括弧をつけなければなりません。

```sql
SELECT DATE(@start)
```
コードの行末を改行してないとGithubで注意されるのは、editorの設定で防ぐ✏️【Android Studio】

この記事は、[岩手県立大学 Advent Calendar 2020](https://qiita.com/advent-calendar/2020/ipu) 12日目の記事です。

# できるもの
コードの行末を改行してないと、githubでこんな感じで注意されますが、
AndroidStudioやVSCodeなどののeditor側の設定で防ぐことができます✏️👀

![スクリーンショット 2020-12-12 2.11.39.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249786/160ecfb1-fdef-7631-bc85-8c332cc87bb9.jpeg)

# やること
1. Preferenceからチェックを入れる

## 1. Preferenceからチェックを入れる
`Preference` > `Editer` > `General` > `Save Files`より
`Ensure line feed at file end on Save`にチェックを入れるだけでokです。
※AndroidStudio4.1時点でのPreferenceの公正なので、バージョンが上がると仕様が変わる可能性があります

![スクリーンショット 2020-12-12 1.53.42.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249786/34c2e8f4-578b-0526-3c3d-d9e66851c32f.jpeg)

# なんで改行が必要なの？👀
[「行末改行って必要？」「インデントのタブとスペースってどっちがいいの？」とかのコード規約の話](https://bottoms-programming.com/archives/indent-tab-space-and-new-line.html)
>テキストファイルとは、いくつかの行の集合である。そして、行とは改行コードで区切られるまでの、一連のテキストデータの連続である。

# 参考
・[ファイル末尾をつねに改行で終端させる IntelliJ 系の設定](https://qiita.com/tanakahisateru/items/66359b6217e7ac728856)

今回参考にした記事を書かれた、`田中ひさてる`さんの各種アカウント👀
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ちょうぜつアドベントカレンダー2020 11話 マンガでわかるスパゲティコードアンチパターン <a href="https://twitter.com/hashtag/%E3%81%A1%E3%82%87%E3%81%86%E3%81%9C%E3%81%A4%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%82%81%E3%82%82%E3%82%8A%E3%83%BC%E3%81%A1%E3%82%83%E3%82%93?src=hash&amp;ref_src=twsrc%5Etfw">#ちょうぜつエンジニアめもりーちゃん</a> <a href="https://t.co/Q4gq3hVC12">https://t.co/Q4gq3hVC12</a> <a href="https://t.co/cxz1YsemJA">pic.twitter.com/cxz1YsemJA</a></p>&mdash; ひさてるさん (@tanakahisateru) <a href="https://twitter.com/tanakahisateru/status/1337437017953632259?ref_src=twsrc%5Etfw">December 11, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
Firebaseのカスタムクレームについて

こんにちは、M2のmarutakuです。これは[MYJLab Advent Calendar 2020](https://qiita.com/advent-calendar/2020/myjlab)の11日目の記事です。前回は、@nyaxによる[超簡単！Youtubeの動画をpytubeでダウンロード](https://qiita.com/nyax/items/f562ec10316323158ae6)でした。
今日の記事は、過去に自分が良かったなと思ったFirebaseの便利機能である、カスタムクレームについてです。

## カスタムクレームとは
カスタムクレーム(Custom Claim)は、Firebase Authenticationで持っているユーザ情報に対して、独自の属性を付与するための機能です。
https://firebase.google.com/docs/auth/admin/custom-claims

具体的な用例としては、以下のようなものが考えられます。

* 有料会員と無料会員の区別
* サービスの管理者権限を与える
* ユーザが所属するグループを分ける

## カスタムクレームのメリット、デメリット

* メリット
    * セキュリティルールの中で使用できる
    * ユーザによる書き換えの心配がない
* デメリット
    * Firebase Adminからしか操作できない
    * 1000バイト以上のデータは保持できない

## 使い方
```javascript
const admin = require('firebase-admin');
admin.initializeApp();

...

// uidはfirebase authenticationから提供されるuid
await admin.auth().setCustomUserClaims(uid, { role: 'teacher' });
```

これだけで、カスタムクレームがセットできました。
クライアント側でカスタムクレームを参照するときはこのように参照します。

```javascript
const tokenResult = await firebase.auth().currentUser.getIdTokenResult();
if (tokenResult.claims.role === 'teacher'){
    // 教員向けの処理
} else {
    // 学生向けの処理
}

```

簡単！！！


## 注意点
カスタムクレームは複数のkey-valueを持つことができますが、一部のkey-valueのみを更新することはできません。
例:

```javascript
const auth = admin.auth();
// 1回目
await auth.setCustomUserClaims(uid, { 
    role: 'teacher' 
});

// 二回目
await auth.setCustomUserClaims(uid, { 
    admin: true 
});

// 確認
const user = await auth.getUser(uid);
console.log(user.claims['role']); // undefined
console.log(user.claims['admin']); // true
```

一部の値のみを更新したい場合でも、全ての値を含めて更新をする必要があります。

```javascript
const user = await auth.getUser(uid);
await auth.setCustomUserClaims(uid, { 
    ...user.claims,
    admin: true 
});
```

## 終わりに
またあっさりとした記事になってしまいましたが、結構便利機能なので機会があればぜひ使ってみてもらいたいです！
anyenv command not found（with linuxbrew ・zsh)

#linuxbrewを使用するときは環境変数のパスに気をつけよう
　linuxbrewを経由して、anyenvを入れたら環境変数でハマったという話です。bashでは大丈夫だったパスでもzshへ移行したら途端に"anyenv"というコマンドが認識されなくなりました。
　私の環境では下記を.zshrcに書いてあげたら、上手く認識されたので、その詳細について書きます。

```zsh
export PATH="/home/linuxbrew/.linuxbrew/Cellar/anyenv/1.1.2/bin:$PATH"
```

　私はシェルとかに詳しくないのであくまで場当たり的な対処です。その点はご認識くださいませ。
##環境
OS：LinuxMint19.3 MATE
シェル：zsh

##解決策
　環境変数のパスに対して、linuxbrew内にあるanyenvのbinフォルダを指定してあげると、anyenvがコマンドとして認識されます。下にパスの一覧を並べたのでそちらを見ながらここからの解説を読んでください。③が私の環境で"anyenv"というコマンドを認識した例になります。

```zsh

#① 普通にanyenvを入れたときのパス
export PATH=$HOME/.anyenv/bin:$PATH

#②　linuxbrew使用時の（恐らく）本来利用が推奨されているパス
export PATH="/home/linuxbrew/.linuxbrew/bin/anyenv:$PATH"

#③　きちんとanyenvが認識されるパス
export PATH="/home/linuxbrew/.linuxbrew/Cellar/anyenv/1.1.2/bin:$PATH"
```

###①について
　これは通常の方法(OSがMac・git cloneで導入したなど）の時です。

###②について
　多分これがlinuxbrewを使用しているときの正しい環境変数の指定先なのだと考えられます。パスを見る限り非常にそれっぽいですし…。（全く確証はないです）
　では何故、私の環境のzshでは上手く行かないのか。それは、anyenvというショートカットファイルのパスがやや違うからみたいです。
　どういうことかというと、/home/linuxbrew/.linuxbrew/bin配下のanyenvというファイルはリンク（ショートカット）ファイルです。そしてそのリンクファイルに指定されているパスは/home/linuxbrew/.linuxbrew/Cellar/anyenv/1.1.2/bin/**anyenv**でした。
　どうやら、この最後のanyenvが環境変数の設定時には邪魔になるようです。
　余談ですが、②のパスをzshのターミナルに打ち込むと下記の画像のように普通に実行できます。何故環境変数になると駄目なんでしょうか…。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/455591/be621adc-3c0d-56d3-304d-4ff64d3f4497.png)

###③について
　①、②のパスを指定してanyenv command not foundがで続けたので色々考えて出した結論がこのパスです。環境変数なんだし、binフォルダを指定してやれば上手く行くのでは、と思ったら当たりでした。
　リンクファイル（②のパスにあるもの）のリンクを書き換えるのも考えたのですが、brewが生成したファイルを書き換えるのが怖いのでやめました。

##最後に
　何かご指摘あったら教えてください。何分、知識量が少ない故に誤った情報を書いている可能性がありますので…。
【Java】indexOfメソッド (指定した文字列が最初に出現する位置を返す)

# JavaのindexOfメソッド

についてまとめました。

## indexOfメソッド とは？

要約すると、「ある文字列の中で、指定した文字列が最初に出現する位置を返す」というStringメソッドの１つです。

## 【特徴 / メリット】

引数の型と数により、以下の4通りの使い方があります。

### 文字列(String)型で検索する用法1

```java
public int indexOf(文字列型変数名)
```

```java
public class Main {
    public static void main(String[] args) {
        String s = "あいうえおかきくけこあいうえおかきくけこ";
        int n = s.indexOf("かきくけこ");
        System.out.println(n);
    }
}
```

```java
5
```

### 文字列(String)型で検索する用法2

```java
public int indexOf(文字列型変数名, 検索位置数)
```

```java
public class Main {
    public static void main(String[] args) {
        String s = "あいうえおかきくけこあいうえおかきくけこ";
        int n = s.indexOf("かきくけこ", 8);
        System.out.println(n);
    }
}
```

```java
15
```

### 文字(char)型で検索する用法1

```java
public int indexOf(文字型変数名)
```

```java
public class Main {
    public static void main(String[] args) {
        String s = "あいうえおかきくけこあいうえおかきくけこ";
        int n = s.indexOf("き");
        System.out.println(n);
    }
}
```

```java
6
```

### 文字(char)型で検索する用法2

```java
public int indexOf(文字型変数名, 検索位置数)
```

```java
public class Main {
    public static void main(String[] args) {
        String s = "あいうえおかきくけこあいうえおかきくけこ";
        int n = s.indexOf("き", 7);
        System.out.println(n);
    }
}
```

```java
16
```

## 出現しない文字・文字列を指定すると？(結論：-1)

存在しない文字を指定すると「-1」が返ってきます。

```java
public class Main {
    public static void main(String[] args) {
        String s = "あいうえおかきくけこあいうえおかきくけこ";
        int n = s.indexOf("らりるれろ");//存在しない文字列を指定
        System.out.println(n);
    }
}
```

```java
-1
```

## 【まとめ】

上記の４パターンの挙動と、「存在しない文字を指定すると「-1」が返る」ということを覚えておきましょう。

## 参考文献・記事

- [徹底攻略Java SE 11 Silver問題集[1Z0-815]対応](https://www.amazon.co.jp/%E5%BE%B9%E5%BA%95%E6%94%BB%E7%95%A5Java-SE-11-Silver%E5%95%8F%E9%A1%8C%E9%9B%86-1Z0-815/dp/4295007625/ref=pd_lpo_14_img_0/356-5238196-1895250?_encoding=UTF8&pd_rd_i=4295007625&pd_rd_r=1c21865b-a9fe-43e8-ac01-46170e44abca&pd_rd_w=9El0Q&pd_rd_wg=hh5Hc&pf_rd_p=4b55d259-ebf0-4306-905a-7762d1b93740&pf_rd_r=72AVH18EM90CKG00CH5W&psc=1&refRID=72AVH18EM90CKG00CH5W)
- [JavaでindexOfメソッドを使う方法【初心者向け】](https://techacademy.jp/magazine/17754)
eksctlでノードを増やす・減らす


# 増やす
## ノードグループ名を取得

```
eksctl get nodegroup --cluster=<クラスタ名>
```

## ノードを増やす
- 最大5ノード
- 最小2ノード
- 現状3ノード
```
eksctl scale nodegroup --cluster=<クラスタ名> --nodes=3 --nodes-min=2 --nodes-max=5 --name=<ノードグループ名>
```

## 増えていることを確認
```
kubectl get nodes
```

# 減らす

## 減らす対象のノードからPodを追い出す
https://qiita.com/yuta_vamdemic/items/a9e5cf5a00257ddc73ae

## ノードを減らす
- 2に減らす
```
eksctl scale nodegroup --cluster=<クラスタ名> --nodes=2 --name=<ノードグループ名>
```
特定のノードから別のノードへPodを移動する


## Podを別ノードへ退避
- `--ignore-daemonsets`
    - Ignore DaemonSet-managed pods.
    - DaemonSetが管理しているPodは無視することで、別のノードで起動し直す
- `--delete-local-data `
    - -Continue even if there are pods using emptyDir (local data that will be deleted when the node is drained).
    - enmptyDirオプションでPod内にファイルがあった場合それが失われてしまう

```
kubectl drain <node> --delete-local-data --ignore-daemonsets
```

## ノードを確認

- `Ready,SchedulingDisabled`となっていれば、停止可能

```
kubectl get nodes
```

## ノードを復帰

```
kubectl uncordon <node>
```
nginx confの$is_args変数、$args変数とは

nginx.confに`/hoge$is_args$args;`と書いているものがある。

$is_argsとはリクエスト行に引数がある場合は?となり、引数なしの時は空文字列になる。

↓確認

```nginx.conf
        location / {
                add_header hoge is_args=${is_args};
        }
```

```
$ curl -I localhost
HTTP/1.1 200 OK
Server: nginx/1.14.1
Date: Fri, 11 Dec 2020 16:46:06 GMT
Content-Type: text/html
Content-Length: 4057
Last-Modified: Mon, 07 Oct 2019 21:16:24 GMT
Connection: keep-alive
ETag: "5d9bab28-fd9"
hoge: is_args= * 空文字になっている
Accept-Ranges: bytes


$ curl -I localhost?hoge=fuga
HTTP/1.1 200 OK
Server: nginx/1.14.1
Date: Fri, 11 Dec 2020 16:46:32 GMT
Content-Type: text/html
Content-Length: 4057
Last-Modified: Mon, 07 Oct 2019 21:16:24 GMT
Connection: keep-alive
ETag: "5d9bab28-fd9"
hoge: is_args=? * はてながついてる
Accept-Ranges: bytes
```

$argsとはurlに書かれたgetパラメータのこと

↓確認

```nginx.conf
        location / {
                add_header hoge is_args=${is_args}${args};
        }
```

```
$ curl -I localhost
HTTP/1.1 200 OK
Server: nginx/1.14.1
Date: Fri, 11 Dec 2020 16:51:17 GMT
Content-Type: text/html
Content-Length: 4057
Last-Modified: Mon, 07 Oct 2019 21:16:24 GMT
Connection: keep-alive
ETag: "5d9bab28-fd9"
hoge: is_args=
Accept-Ranges: bytes

$ curl -I localhost?a=b
HTTP/1.1 200 OK
Server: nginx/1.14.1
Date: Fri, 11 Dec 2020 16:51:32 GMT
Content-Type: text/html
Content-Length: 4057
Last-Modified: Mon, 07 Oct 2019 21:16:24 GMT
Connection: keep-alive
ETag: "5d9bab28-fd9"
hoge: is_args=?a=b
Accept-Ranges: bytes

curl -I localhost?a=b&c=d
[1] 644
[root@ebe2eb08b5b2 ~]# HTTP/1.1 200 OK
Server: nginx/1.14.1
Date: Fri, 11 Dec 2020 16:51:47 GMT
Content-Type: text/html
Content-Length: 4057
Last-Modified: Mon, 07 Oct 2019 21:16:24 GMT
Connection: keep-alive
ETag: "5d9bab28-fd9"
hoge: is_args=?a=b * あれc=dが消えてる・・・？
Accept-Ranges: bytes
```

localhost?a=b&c=dの時にargsにc=dのデータが入らないのが気になる。。。
Nuxt.jsでスムーススクロールする

# インストール

```shell
$ npm i -S vue-scrollto
```

# プラグイン作成

```shell
$ touch plugins/vue-scrollto.js
```

```javascript:plugins/vue-scrollto.js
import Vue from 'vue'
import VueScrollTo from 'vue-scrollto'

Vue.use(VueScrollTo)
```

# 設定

```javascript:nuxt.config.js
export default {
  plugins: [
    '~/plugins/vue-scrollto'
  ]
}
```

# 使用

```html
<nuxt-link v-scroll-to="'#target'" to>スムーススクロール</nuxt-link>
```

# Nuxt.jsのそのほか

- [Nuxt.jsを使う](https://qiita.com/oblivion/items/3488e41af630a3b07ff6)
RailsのHTTPステータス


## 分類
1. 情報レスポンス (`100` ~ `199`)
2. 成功レスポンス (`200` ~ `299`)
3. リダイレクト (`300` ~ `399`) 
4. クライアントエラー (`400` ~ `499`)
5. サーバエラー (`500` ~ `599`)

↓下記サイトで適宜確認する
[MDN web docs - HTTP レスポンスステータスコード](https://developer.mozilla.org/ja/docs/Web/HTTP/Status)

## 書き方
```ruby
# シンボルを使う

render json: @user, status: 201
or
render json: @user, status: :created

render status: 500
or
render status: :internal_server_error
```

```ruby:ステータスコードのみ返す
# リクエストが正常に処理された
head :ok

# リクエエストが不正
head :bad_request

def destroy
  @user.destroy
  head 204
end
```



## コンソールで確認

```bash
pp Rack::Utils::SYMBOL_TO_STATUS_CODE

{:continue=>100,
 :switching_protocols=>101,
 :processing=>102,
 :early_hints=>103,
 :ok=>200,
 :created=>201,
 :accepted=>202,
 :non_authoritative_information=>203,
 :no_content=>204,
 :reset_content=>205,
 :partial_content=>206,
 :multi_status=>207,
 :already_reported=>208,
 :im_used=>226,
 :multiple_choices=>300,
 :moved_permanently=>301,
 :found=>302,
 :see_other=>303,
 :not_modified=>304,
 :use_proxy=>305,
 :"(unused)"=>306,
 :temporary_redirect=>307,
 :permanent_redirect=>308,
 :bad_request=>400,
 :unauthorized=>401,
 :payment_required=>402,
 :forbidden=>403,
 :not_found=>404,
 :method_not_allowed=>405,
 :not_acceptable=>406,
 :proxy_authentication_required=>407,
 :request_timeout=>408,
 :conflict=>409,
 :gone=>410,
 :length_required=>411,
 :precondition_failed=>412,
 :payload_too_large=>413,
 :uri_too_long=>414,
 :unsupported_media_type=>415,
 :range_not_satisfiable=>416,
 :expectation_failed=>417,
 :misdirected_request=>421,
 :unprocessable_entity=>422,
 :locked=>423,
 :failed_dependency=>424,
 :too_early=>425,
 :upgrade_required=>426,
 :precondition_required=>428,
 :too_many_requests=>429,
 :request_header_fields_too_large=>431,
 :unavailable_for_legal_reasons=>451,
 :internal_server_error=>500,
 :not_implemented=>501,
 :bad_gateway=>502,
 :service_unavailable=>503,
 :gateway_timeout=>504,
 :http_version_not_supported=>505,
 :variant_also_negotiates=>506,
 :insufficient_storage=>507,
 :loop_detected=>508,
 :bandwidth_limit_exceeded=>509,
 :not_extended=>510,
 :network_authentication_required=>511}
```


## 参考URL
[Railsガイド - レイアウトとレンダリング](https://railsguides.jp/layouts_and_rendering.html)
[MDN web docs - HTTP レスポンスステータスコード](https://developer.mozilla.org/ja/docs/Web/HTTP/Status)

[RailsのHTTPステータスのシンボル表現](https://morizyun.github.io/ruby/rails-controller-status-code.html)
[Rails Controllerのrenderメソッドレシピ集](https://morizyun.github.io/ruby/rails-controller-basic.html)
【React】一定時間で消える表示を作る

前回作ったサクセスメッセージがいつまでも表示されるのは如何なものかと思い、今回は表示後に何秒か経ったら消えるようにしました。

前回
[【React】Railsでsaveされた時に、Reactでサクセスメッセージを表示](https://qiita.com/HashibamiAkira/items/d12d58f7c20719330abb)

今回の完成形

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">reactで表示したメッセージをn秒後に消えるようにしました <a href="https://t.co/H3YI09obJZ">pic.twitter.com/H3YI09obJZ</a></p>&mdash; きたやまかつや (@kitakatsu1992) <a href="https://twitter.com/kitakatsu1992/status/1337434216330477570?ref_src=twsrc%5Etfw">December 11, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

思った以上に簡単、と言うか思いっきりJavaScriptの書き方だったので勉強不足を感じました。

### setTimeout()を使ってstateを変更する

前回、state の値が true か false かでメッセージを表示させる、という風に作成しました。

初期値がfalseのstateをtrueでメッセージを表示させたので、逆にtrueをfalseに戻せばOKということです。

まずは初期値。

```javascript
  state = {
    books: [],
    successCreate: false
  }
```

```javascript

  createBook = (title, body) => {
    axios
      .post('http://localhost:3001/books', { title: title, body: body})
      .then((response) => {
        const newData = update(this.state.books, { $push: [response.data]})
        this.setState({books: newData, successCreate: true})
      })
  }
```

rails側のcreateが呼ばれ、データがsaveされるとfalseがtrueに変わる、というものです。

このtrueを何秒後かにfalseにsetStateするようにします。

```javascript
  createBook = (title, body) => {
    axios
      .post('http://localhost:3001/books', { title: title, body: body})
      .then((response) => {
        const newData = update(this.state.books, { $push: [response.data]})
        this.setState({books: newData, successCreate: true})
        // ここから追記
        setTimeout(function(){
          this.setState({successCreate: false})
        }.bind(this),3000)
      })
  }
```

これは3秒後にstateを変更するようにしています。

stateがfalseになるので表示されていたメッセージは消えるようになります。

おそらくあまりに初歩的な内容なので調べても全然出てこなかった！！
もっと精進してさくっと実装できる力を付けたいものです
マンガでわかるスパゲティコードアンチパターン

![50CA72C3-3CDA-404E-9510-57266EAD8CA5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11525/605e23fa-c7bf-3bb0-93ee-ab795adcc901.png)
http://wiki.c2.com/?SpaghettiCode

コード品質の悪さを表す言葉として、もっとも有名なのは、おそらくこのスパゲティコードでしょう。コードを読解するさい、あちこち行ったり来たりしなければならない、こんがらがって保守が困難なコードを意味します。

アンチパターン本にはオブジェクト指向ができていないからと表現されていますが、オブジェクト指向を使うというのはあくまで、**うまく使えば** スパゲティ化を防止するのに非常に有用、という意味にすぎません。まとまりを無視した継承や参照をしすぎると、こんどはオブジェクトのスパゲティが出来上がります。(当時はオブジェクト指向を扱える人とプログラムセンスが高い人が一致していただけと私は考えています)

多くの変数を同時に扱わず、やっていることを小さくまとめること。また、ごちゃっとした部分があっても、他と切り離して隠蔽し、ひとつ上の粒度から見て一様にシンプルに見えるようにしておくことが、スパゲティ化を防ぐ手です。スパゲティコードを放置すると、次々とスパゲティが生まれるので、予防が肝心です。

どこから参照されるかわからない、あらゆる粒度のものをフラットに置かざるをえない、という特徴を考えると、グローバル変数やそれに類するものがいかにコード品質を下げるかがわかると思います。
nginxのconfで文字列結合

nginxのconfで文字列結合する方法

変数は$aaaのように$記法で参照できるが、文字列結合したい時は${aaa}${bbb}のように${}を使う。

```nginx.conf
        location / {
                set $aaa aaa;
                set $bbb bbb;
                add_header hoge ${aaa}${bbb}ccc;
        }
```

↓確認

```
$ curl -I localhost
HTTP/1.1 200 OK
Server: nginx/1.14.1
Date: Fri, 11 Dec 2020 16:35:51 GMT
Content-Type: text/html
Content-Length: 4057
Last-Modified: Mon, 07 Oct 2019 21:16:24 GMT
Connection: keep-alive
ETag: "5d9bab28-fd9"
hoge: aaabbbccc * これ
Accept-Ranges: bytes
```
Nuxt.jsでスクロールに応じてフェード出現

プラグインファイルを作成・設定したら、スクロールに応じてイベントが走る

# 作成

```shell
$ touch plugins/v-scroll.js
```

```javascript:plugins/v-scroll.js
import Vue from 'vue'

Vue.directive('scroll', {
  inserted: function (el, binding) {
    let f = function (evt) {
      if (binding.value(evt, el)) {
        window.removeEventListener('scroll', f)
      }
    }
    window.addEventListener('scroll', f)
  }
})
```

#設定

```javascript:nuxt.config.js
module.exports = {
  plugins: ['~/plugins/v-scroll'] // 追記
}
```

#使用

```html:test.vue
<template lang="pug">
.test(:class="[{'is-active': flg}]" v-scroll="handleScroll") test
</template>

<script>
export default {
  data: () => ({
    flg: false
  }),
  methods: {
    handleScroll(evt, el) {
      const top = el.getBoundingClientRect().top
      const wh = window.innerHeight
      if (top < wh / 2) this.flg = true
    }
  }
}
</script>

<style lang="stylus">
.test
  opacity 0
  transition all 1s

  &.is-active
    opacity 1
</style>
```

# Nuxt.jsのそのほか

- [Nuxt.jsを使う](https://qiita.com/oblivion/items/3488e41af630a3b07ff6)
nginxのconfに変数を定義する

nginxのconfに変数を定義する

`set 変数名 値` で変数を宣言できる。
Contextがserver, location, ifとなっているのでhttpディレクティブの直下には定義できないようだ。

↓公式情報
http://nginx.org/en/docs/http/ngx_http_rewrite_module.html#set

```
Syntax:	set $variable value;
Default:	—
Context:	server, location, if
```

↓確認

```nginx.conf

location / {
    set $hgoe fuga;
    add_header hoge $hoge;
}
```


```
$ curl -I localhost
HTTP/1.1 200 OK
Server: nginx/1.14.1
Date: Fri, 11 Dec 2020 16:33:12 GMT
Content-Type: text/html
Content-Length: 4057
Last-Modified: Mon, 07 Oct 2019 21:16:24 GMT
Connection: keep-alive
ETag: "5d9bab28-fd9"
hoge: fuga * これ
Accept-Ranges: bytes
```
Nuxt.jsでLoadingページを設定する

`loading`コンポーネントを作る

```html:components/Loading/index.vue
<template lang="pug">
.loading-page(v-if="loading")
  p Loading...
</template>

<script>
export default {
  data: () => ({
    loading: false
  }),
  methods: {
    start () {
      this.loading = true
    },
    finish () {
      setTimeout(() => {
        this.loading = false
      }, 3000)
    }
  }
}
</script>
```

設定ファイルに変更を加える

```javascript:nuxt.config.js
export default {
  loading: '~/components/Loading/index.vue' // 追記
}
```

# Nuxt.jsのそのほか

- [Nuxt.jsを使う](https://qiita.com/oblivion/items/3488e41af630a3b07ff6)
Nuxt.jsでエラー用ページを作る

# ファイル作成

```shell
touch layouts/error.vue
```

# ファイル内容

```html:layouts/error.vue
<template lang="pug">
.container
  h1(v-if="error.statusCode === 404") ページが見つかりません
  h1(v-else) エラーが発生しました
</template>

<script>
export default {
  props: {
    error: {
      type: Object,
      default: null
    }
  }
}
</script>
```

# Nuxt.jsのそのほか

- [Nuxt.jsを使う](https://qiita.com/oblivion/items/3488e41af630a3b07ff6)
Nuxt.jsにgtm入れる

# インストール

```shell
$ npm i -S @nuxtjs/gtm
```

# 設定

```javascript:nuxt.config.js
export default {
  modules: [
    '@nuxtjs/gtm', // 追記
  ],
  gtm: {
    id: 'GTM-XXXXXXX' // 追記
  }
}
```

# Nuxt.jsのそのほか

- [Nuxt.jsを使う](https://qiita.com/oblivion/items/3488e41af630a3b07ff6)
Matlab画像処理「周波数フィルタ」（2次元FFT）

初投稿です。対戦よろしくお願いします。

画像処理には様々な手法がありますが、この記事で紹介するのは周波数フィルタ処理です。

そもそも知らねーよ！って人はこちらの記事が参考になるかと思います。
https://www.visco-tech.com/newspaper/column/detail20/

matlabで実装できたので、紹介します。

今回実装したのはローパスフィルタです。すなわち高周波ノイズ（点のように狭い領域でのノイズ）を除去します。

出力
左がフィルタ前、右がフィルタ後（伝わりづらい…）
![FFTfilter.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/923577/5987576c-2620-f44f-5e95-7ae56540e5d7.jpeg)




3つの関数にまとめましたので、
%%%ここから下をコピペする%%%以下をコピペすればすぐ使えると思います。

関数の説明

①function [pic2] = FFTfilter(pic1,Gain)
②function[pic2] = OddEsc(pic1)
③function [pic2] =PicConv(pic1)



①は名前の通りFFT計算をする箇所です。
計算の都合上、画像のサイズが奇数だった場合ピクセルを追加して偶数にしています。その処理を関数②に投げています。
周波数領域のトリミングをする際に、画像の象限を反対にすると都合が良いので、③でその処理をしています。

参考：
西住工房様（ https://algorithm.joho.info/image-processing/fourier-transform/ ）

便利なところ
カラー、白黒に関係なく変換できます。
FFTGain（0~1）の調整（0に近いほどフィルタが強くなります。）が出来ます。


欠点
ハイパスフィルタ、バンドパスフィルタの能力はないです。
もし追加するのであれば

```
if i < sz1/2-a || i > sz1/2+a || j < sz2/2-b || j > sz2/2+b
```
の部分が周波数トリミングに対応しているのでここの条件を変えてください。

画像サイズが奇数だったときに追加する処理を行うので右端（あるいは下端）の1列に輝度ゼロの領域が生まれることがあります。



以下サンプルコード



```
%%%画像の読み込み%%%
test = imread("C:\hogehoge\test.jpg");

%%%フィルタ処理(0.1はフィルタ透過率)%%%
FFTGain = 0.1 
test2 = FFTfilter(test,FFTGain);

%%%出力%%%
subplot(1,2,1)
imshow(test)
subplot(1,2,2)
imshow(test2)
imwrite(test2,"C:\hogehoge\test2.jpg")


%%%ここから下をコピペする%%%
function [pic2] = FFTfilter(pic1,Gain)
pic1 = OddEsc(pic1);

sz1 = size(pic1,1);
sz2 = size(pic1,2);
sz3 = size(pic1,3);

ftest=fft2(pic1);
ftest=PicConv(ftest);
a = ceil(sz1*Gain);
b = ceil(sz2*Gain);

for k =1:sz3
    for j=1:sz2
        for i=1:sz1
            if i < sz1/2-a || i > sz1/2+a || j < sz2/2-b || j > sz2/2+b
            ftest(i,j,k) = 0;
            end
        end
    end
end

ftest = PicConv(ftest);
pic2 = real(ifft2(ftest))/255;


end

function[pic2] = OddEsc(pic1)
sz1 = size(pic1,1);
sz2 = size(pic1,2);
sz3 = size(pic1,3);

if rem(sz1,2)==1
    sz1 = sz1+1;
    pic1(sz1,sz2,sz3) = 0;
end

if rem(sz2,2)==1
    sz2 = sz2+1;
    pic1(sz1,sz2,sz3) = 0;
end

pic2 = pic1;

end

function [pic2] =PicConv(pic1)
a = size(pic1,1);
b = size(pic1,2);
c = size(pic1,3);
pic2 = zeros(a,b,c);

pic2(1:a/2,1:b/2,:) = pic1(a/2+1:a,b/2+1:b,:);
pic2(a/2+1:a,1:b/2,:) = pic1(1:a/2,b/2+1:b,:);
pic2(1:a/2,b/2+1:b,:) = pic1(a/2+1:a,1:b/2,:);
pic2(a/2+1:a,b/2+1:b,:) = pic1(1:a/2,1:b/2,:);

end

```

干渉計の干渉縞のノイズ除去などに使ってみてください。それでは。
【Java】charAtメソッド（n番目の文字を抜き出す）

# JavaのcharAtメソッド

についてまとめました。

## charAtメソッドとは

一言でいうと「文字列から指定位置の1文字を取得する」メソッドです。

## 【説明】

charAtメソッドは、文字の位置を指定することで該当の1文字を取得することができます。

書き方は以下です。

```java
//chrAt
変数名.charAt(値)
```

- 数字は、左から0でスタートする
- 一番最後の文字の位置は文字列.length() – 1

## 【実際に書いてみる】

ひだりから数えて0スタートなので、「あいうえお」だと1を指定すると実質二番目の文字である「い」を取得してきます。

```java
public class Main {

    public static void main(String[] args) {
        String str = "あいうえお";
        System.out.println(str.charAt(1));
    }

}
```

```java
い
```

### 範囲外を選択すると？（結論: **例外発生**）

**範囲外を選択すると例外が発生します。**

例えば、文字列が5文字なのに対し、6番目を取得する「５」を指定した場合はjava.lang.StringIndexOutOfBoundsException 

という例外がスローされます。

## 【まとめ】

抑えるポイントは以下です。

- 範囲外を指定すると例外発生
- 左から0スタート

## 参考文献・記事

- [徹底攻略Java SE 11 Silver問題集[1Z0-815]対応](https://www.amazon.co.jp/%E5%BE%B9%E5%BA%95%E6%94%BB%E7%95%A5Java-SE-11-Silver%E5%95%8F%E9%A1%8C%E9%9B%86-1Z0-815/dp/4295007625/ref=pd_lpo_14_img_0/356-5238196-1895250?_encoding=UTF8&pd_rd_i=4295007625&pd_rd_r=1c21865b-a9fe-43e8-ac01-46170e44abca&pd_rd_w=9El0Q&pd_rd_wg=hh5Hc&pf_rd_p=4b55d259-ebf0-4306-905a-7762d1b93740&pf_rd_r=72AVH18EM90CKG00CH5W&psc=1&refRID=72AVH18EM90CKG00CH5W)
- [charAtメソッド | Javaコード入門](https://java-code.jp/185)
- [JavaのcharAtメソッドで文字列から指定位置の文字を取得する方法を現役エンジニアが解説【初心者向け】](https://techacademy.jp/magazine/34612)
Nuxt.jsでデフォルトで使うメタ情報を設定する

設定ファイルの`head`欄に変更を加える

```javascript:nuxt.config.js
export default {
  head: {
    title: 'test',
    htmlAttrs: { lang: 'ja' },
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      { hid: 'description', name: 'description', content: 'test' },
      { hid: 'og:title', property: 'og:title', content: 'test' },
      { hid: 'og:description', property: 'og:description', content: 'test' },
      { hid: 'og:url', property: 'og:url', content: 'https://test.com/' },
      { hid: 'og:image', property: 'og:image', content: 'https://test.com/assets/image/share/og.png' },
      { hid: 'twitter:card', name: 'twitter:card', content: 'summary_large_image' }
    ],
    link: [
      { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
    ]
  },
}
```

# Nuxt.jsのそのほか

- [Nuxt.jsを使う](https://qiita.com/oblivion/items/3488e41af630a3b07ff6)
【React】Railsでsaveされた時に、Reactでサクセスメッセージを表示

個人のブログで、ReactとRailsでDBとやりとりする記事を作りました

[フロントReact、バックRailsでデータベースに保存する](https://hashibamiakira.hatenadiary.com/entry/2020/12/09/030654)

某プログラミングスクール（◯MM）で課題で出されたものをReactで作ってみて、そこにサクセスメッセージを出そう、と言うのが今回の目的です。

メモ書き程度で書いていきます。

## 完成後の動作

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Reactでサクセスメッセージを出せるようにしました <a href="https://t.co/TjBkS0008y">pic.twitter.com/TjBkS0008y</a></p>&mdash; きたやまかつや (@kitakatsu1992) <a href="https://twitter.com/kitakatsu1992/status/1337423267527716866?ref_src=twsrc%5Etfw">December 11, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

フォーム内容の保存に成功するとサクセスメッセージが呼び出されます。
流れとしては、

 - stateを作る
 - createが呼ばれsaveされたらstateを変更する
 - stateをコンポーネントに渡してメッセージを表示させる

こんな感じです。

### stateを作る

```javascript
  state = {
    books: [],
    successCreate: false
  }
```

successCreateと言うstateを作りました。
ここは初期値はfalseとして、createが呼ばれたらtrueとします。

### createが呼ばれsaveされたらstateを変更する

```javascript
  createBook = (title, body) => {
    axios
      .post('http://localhost:3001/books', { title: title, body: body})
      .then((response) => {
        const newData = update(this.state.books, { $push: [response.data]})
        this.setState({books: newData, successCreate: true})
      })
  }
```

Rails側でbooksコントローラーのcreateを呼び出し、保存されたデータはbooksに追加し、successCreateはtureに変更します。
ちなみにbooksにはBookモデルのデータが全て入っています。

### stateをコンポーネントに渡してメッセージを表示させる

このsuccessCreateの値をコンポーネントに渡します。

```javascript
<BookCreateForm
  createBook={this.createBook}
  successCreate={this.state.successCreate}
/>
```

受け取った先で、stateがtrueの時にメッセージを表示するよう記述します。

```javascript
{this.props.successCreate && (
  <p style={{color: '#16de69', fontSize: 6}}>Book was successfully created.</p>
)}
```

これでBookがcreateされ、stateが変更した時にメッセージが出るようになりました。

react側とrails側でバリデーションをかけてより安全性を高めれば、思いがけないメッセージの表示はなくなるかと。

忘備録的なものなのでとりあえず動いた時点で記事にしております、あしからずです。
Windows10環境IntelliJでVue.jsの開発環境を作成する

# はじめに

Mac版の開発環境手順を「[IntelliJ IDEAでVue.jsを動かす](https://qiita.com/miyamotok0105/items/db06e22d13562918eb8f)」というタイトルでmiyamotok0105さんが公開されていました。
本記事を参考に、こちらではWindows10版の手順をまとめてみました。

なお、IntelliJのVue.jsプラグインですが、 **単一ファイルコンポーネントによる開発** を前提にしたテンプレートが生成されます。
そのため本手順で構築される環境も、単一ファイルコンポーネントによる開発を行うための環境となります。
通常（？）の下記のようなhtmlファイルにscriptタグでvue.jsを指定してjsをゴリゴリ書くような開発向けではないので、ご注意ください。

```html:こういうのは！！対象外！！
<html>
    <head>
        <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    </head>
 ～省略～
</html>
```

※ 参考：「[Vue.js公式：単一ファイルコンポーネント](https://jp.vuejs.org/v2/guide/single-file-components.html)」

# 環境

| ソフトウェア                    | バージョン|
|:-------------------------------|------------:|
| Windows 10 Professional        | -           |
| IntelliJ Ultimate              | 2020.3      | 
| nodejs                   （※）| 14.15.1     | 

※ nodejsはZIP版をC:\Programs\nodejs\node-v14.15.1-win-x64に展開。

# 手順

PluginsからVue.jsをインストールします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/515611/59e557f1-ab3f-e644-5244-1a6541ed6419.png)
New ProjectからJavaScriptを選択し、リストからVue.jsを選択してNextをクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/515611/10d6855b-6343-a4b4-b962-e2102d4030db.png)
Project Name：適当にプロジェクト名を入力
Project location：デフォルトのまま
Node interpreter：インストールしたnodejsの絶対パスを設定する（※）
Vue CLI：デフォルトのまま
Finishをクリック。
※ なお、Node interpreterの選択肢にDownload Node（うろ覚え）という選択肢があったので、こいつを選択すれば
事前にNode.jsをインストールしなくてもIntelliJが自動的に最新のNode.jsをインストールしてくれるかもしれません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/515611/0d86141b-9b07-166d-7f32-8d0057d753b3.png)
Finishをクリックすると、IntelliJが自動的にVueプロジェクトの初期化を行います。
そこそこ重い処理なのか、僕の環境では10分くらいかかりました。（10年くらい前のノートパソコン）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/515611/99525f8a-32bf-a871-d0e5-b5f1c5caec77.png)
Vueプロジェクトの初期化が完了すると、以下のようなテンプレートが生成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/515611/fbfcd460-7f53-6c38-fca9-335d56c5608a.png)

# 動作確認

単一ファイルコンポーネントのためビルドする必要があります。
今回生成されたテンプレートには、package.jsonのなかに下記が用意されています。

- server ビルドを行い確認用のサーバーを起動する
- build  ビルドを行う
- lint   リント（たぶん構文チェック。。。）

動作確認のため、「server」を実行します。

IntelliJ上で、「Ctrl + tab」を押してSwitcherを立ち上げ、0:npmに選択を合わせてEnterキーを押してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/515611/1c97dcdd-e15c-dc2c-71f3-8dd7ee33e7ed.png)

npmのWindowが表示されるようになります。
serverを右クリックし、メニューから「Run 'server'」を選択しクリックしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/515611/425641da-b384-8edc-fc34-44f9b4c2cc8f.png)

ビルドとサーバーの起動が実行されます。ビルドが成功し、サーバーが起動するとアクセスURLが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/515611/dd788e6e-9757-7d26-216c-c363b89d1f83.png)

ブラウザでアクセスしてみると、下図のようにテンプレートで自動生成されたサンプルのVue.jsサイトにアクセスできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/515611/9fe8fa71-a1f4-de10-cd12-15f585e949cc.png)
Lookerのアラート機能を使ったイベント発火の異常検知

こんにちは、株式会社CloudFitの瀬沼（[＠y_senuuu](https://twitter.com/y_senuuu)）です。
『[Looker Advent Calendar 2020](https://qiita.com/advent-calendar/2020/looker)』の12日目のエントリを投稿させて頂きます。

# 背景
Google Analyticsのようなサイトのアクセス解析や、GoogleやFacebookに代表されるWEB広告を扱うためには、タグを使ってサイト上でイベントを発火させて、サービスや媒体側にデータを送信する必要があります。
そして、タグに関連してどこでも発生するあるあるの問題が、「**イベント数の異常**」です。

今回はLookerのアラート機能を使って、イベント数に異常が発生した際に、メールやSlackに通知する方法を紹介したいと思います。

# イベント数の異常が発生する原因
- サイトの改修によってタグが削除されていた
- イベント発火の設定に誤りがあり、二重でイベントが飛んでいた
- ページの読み込み速度が遅くなり、タグの読み込み前にページ遷移が発生していた

などなど、イベント数の異常が発生する原因は様々です。
特に複数のチームにまたがってタグの運用・保守管理を行なっている場合は、事前に全ての原因を取り除くこと現実的でないため、イベント数の異常が発生した際に、それを検知できる仕組みが必要になります。


# アラート機能とは？
Lookerで作成したダッシュボードのデータに対して、任意の条件に該当した際に、メールやSlackに通知を行うことができる機能です。
https://docs.looker.com/sharing-and-publishing/alerts
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603058/3b048a6d-34d9-ffd2-1466-dd9eaee7be1b.png)

# サンプルケース
今回はKARTEで取得しているviewイベントのヒット数をサンプルに、アラートを設定したいと思います。

#### データの準備
まずはイベント×日付単位でヒット数を集計したテーブルを用意して、Lookerから参照できる状態に設定します。

日ごとのイベント数でもアラート設定は可能ですが、平日よりも土日の方がアクセス数が多い等の理由で、DaytoDayの比較では正常な状態がアラートとして検知されるリスクがあるため、表計算を利用して過去7日間の移動平均値を用意します。
移動平均は`offset_list`関数を使うと簡単に計算ができます。

```js:MovingAverage
mean(offset_list(${karte_event_hits.event_count},0,7))
```

さらに、表計算の `offset`関数を利用して、移動平均値に関する前日からの変化率を作成します。

```js:%Change
${moving_average} / offset(${moving_average}, 1) - 1
```

このような形で日次のイベント数に対する過去7日間の移動平均値と前日からの変化率が追加できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603058/e3a5747e-844c-2e9c-8850-2f1df8b4fcfa.png)


#### アラートの設定
上記で作成したExplolerをダッシュボードに保存すると、タイルの右上にアラートの設定アイコンが表示されているので、そちらをクリックします。
（**※開発モードでは表示されません！！**）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603058/428d6e3c-baaa-1e50-eaf8-6179ecfa1706.png)

アラートの設定画面が表示されるので、アラートを通知する条件や通知方法を設定します。

- 条件の値には先ほど作成した変化率を設定します
- 比較条件に `Changes by` を選ぶことで、変化率が上下に振れた場合も比率の絶対値を閾値とすることができます
- 通知方法はメールかSlackから選択します
 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603058/7055be06-a4e5-6624-3c05-e464b7174d91.png)

これでアラートの設定は完了です。
アラートにはフォロー機能があるため、他のユーザーが作ったアラートに関する通知を受け取ることも可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603058/21211b91-3f9f-af07-6b8f-6f6b1b674c72.png)

#### アラートの通知
設定したアラートの条件に該当すると、内容がメールやSlackに飛んできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603058/97179617-483a-1a4e-6783-b18c9f82d24f.png)

# まとめ
この手の異常検知はおざなりになりがちなので、Lookerを使って簡単に実装できるのは大変助かります。また、今回は異常検知を目的に設定しましたが、応用次第で以下のようなユースケースにも対応できると思います。

- 注目度が上がった商品のページを検知する
- 過去数カ月ログインがないユーザーを検知する
- 処理量が大きいクエリを検知する

自らデータを見に行かなくともシステム側からプッシュしてくれる状態をつくることは、データ活用の第一歩だと思いますので、是非みなさんもアラート機能を使ってみてください！
font-awesomeのアイコンを塗りつぶす

#font-awesomeのアイコンを塗りつぶそう

いいね機能を作る際に、ハートマークを赤く塗りつぶす方法をメモしときます。

font-awesomeのアイコンを塗る潰すにはsolidのアイコンを選ばないといけないらしいです。

![スクリーンショット 2020-12-12 0.51.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906968/091dcb66-42b5-adf2-068f-4d6bdbc79215.png)

こちらの画像の右上でsolidのアイコンを選択できてますね。

```rb

<i class="fas fa-heart"></i>
```

ちなみの上記のようなコードになっています。
classのfasのsがsolidのsなんだろうなと思います（多分）




細かいところで躓いてしまうことが多いので、一個一個わからないことを潰していきたいです。
半期でWBSを10個作成する新卒の話

この記事は[「PERSOL PROCESS & TECHNOLOGY Advent Calendar 2020」](https://qiita.com/advent-calendar/2020/ppt"「PERSOL PROCESS & TECHNOLOGY Advent Calendar 2020」")の11日目の記事です。

##はじめに
こんにちは、はじめまして！
910nagaiのQiita初投稿の記事になります。
普段は弊社([パーソル プロセス&テクノロジー株式会社](https://www.persol-pt.co.jp/""))のサイトである[CloudSteady](https://cloudsteady.jp/"")にて
主に業務で扱っているMicrosoft AzureやMicrosoft365の技術情報を月に数本投稿しています。
是非こちらも覗いてみてください！

今回は、今年新入社員として入社した910nagaiが下期にWBSを10個作成する事について
**(1)その目的
(2)学んだこと(WBS作成初心者に向けて)**
を途中ではありますが、備忘録もかねて書いていけたらなと思います。
(下期が終わったらまた改めて書きたいと思います)

一応、WBSとは
>Work Breakdown Structure (WBS、作業分解構造)は、プロジェクトを理解し管理する上で、プロジェクトの各工程を各担当者の作業レベルまで展開し木構造にまとめたもの。どのレベルまで展開するかはプロジェクトの全メンバーが作業内容を「具体的に〇〇をする」と理解出来るレベルまでに分解するのが理想であるが、最低でも作業担当者とプロジェクト管理者の理解が得られるレベルまでは必要である。
>WBSはガントチャートやPERT図に展開してプロジェクト管理に使われる。

>([wikipedia](https://ja.wikipedia.org/wiki/Work_Breakdown_Structure"")より引用)

こんなやつです(イメージ)
![202012110.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/914679/e3a00aae-d498-e5b7-5fe1-1a7c13e0b5a3.png)

**新卒がなんのWBSを書くんだ？**と思われた方もいると思います、
WBSと言えば、まず思う浮かぶのが構築や運用プロジェクトの設計に関するものでしょうか。

910nagaiはWBS作成能力が皆無に等しかったので(新卒研修ですこし勉強したくらい)
もちろんプロジェクトのWBS作成をポンポンと任されるわけはなく、、、

結果的にはステークホルダーの少ない、個人的なWBSが中心となりました。
(後半にはプロジェクトの運用設計も一つあります。)
例えば、[顧客への報告会]や[資格取得]のWBSです。
少し変わりダネとして[WBS10個作成]の為のWBSなんかもあります(！)
それぞれ、項目数や期間などで難易度が変わり、抽象的で項目がイメージしづらい物など
様々なものをテーマにして作成しています。

ではそろそろ本題に、、、
##(1)WBSを10個作成する目的
WBSを10個作成する目的はズバリ、
**・目的志向を磨く事
・論理的思考力を鍛えること**
です！
※もちろん今後の為にWBS作成に慣れること、もあります

WBS作成は奥が深く、必要な能力が無数(本当)にあります。
それらの能力は目的志向/論理的思考力に繋がるものが多いです。
目的志向とはなんぞや、という方は是非調べてください。
疎かにしてしまいがちですが、何をするにもとても大事なことです。
生産性を高めていきましょう。

##(2)学んだこと
12月11日現在の10個作成進捗は約40%完了です。
まだまだ道半ばではありますが、ここまでに学んだことやWBSに必要な事を書いておきます。
すべては書けません、初心者がまず意識すべきだと考えたことを910nagaiの主観で書きます。
WBSについてGoogle先生に聞けば素晴らしい記事がいっぱい出てきますので、、、

**①達成条件を明確に定める**
まずはこれです、これがなければ正確なWBSは完成しません。
WBS初心者が最初に意識すべき点だと思います。

例えば、あるプロジェクトの成功の為にWBSを作成したとき、
「プロジェクトの成功とはなにか」というのを明確に定義しておかないといけません。
当たり前のことだ！と思うかもしれませんが、特に抽象的なテーマのWBSを作成するときに意識するのは難しいことです。(910nagaiはできていませんでした)
「歌をうまくする」のWBSを作るとなったら、まずは"歌がうまい"とは何か考えなくてはいけませんよね。

WBSの最初の項目に、[達成条件策定]などを作ってもいいかもしれません。

**②項目の粒度を合わせる**
・項目通りにタスクを実行すれば目的を達成できる
というのが正確なWBSの要素の一つだと思います。
その為には、目的達成のために想定される作業をとことん分解することが必要です、
WBSのBはBreakdown(分解)ですからね。

よく例え話で、カレーを作るWBSの話があります。
「米を炊く」という作業(大項目)も分解すれば「米をとぐ/鍋を火にかける/弱火にして蓋をするetc....」になります。
さらに「米をとぐ」という作業(中項目)は「水を入れる/かき混ぜる/水を捨てるetc...」となります。
「水を入れる」(小項目)は「蛇口を回す<<以下略>>
と、このように分解していくと一つ一つの作業が明確になり、漏れがないWBSを作成する準備ができます。

さて、ここでたくさん出した項目をWBSに落とし込んでいくのですが、
ここで大事なのが**情報の粒度**です。
「米をとぐ」(中項目)と「ルーを作る」(大項目)を同じ列に書いてはいけません。
粒度が違う項目を並べているWBSは正確ではありませんし、なにより見づらく、違和感を感じてしまいます。
この点も初心者が最初に意識すべき点であると思います。

**③無駄な事を書かない**
これは初心者にありがちなことだと思いますが、WBSを"それっぽく"する為に行を埋めるだけの項目を書いてしまうことがあります。
私はいまだにやってしまいます、気を付けます。
WBSは目的を達成するために書くものです、WBS作成を目的にしないでください。

極端な例だと、「設計書を書く」の下の項目に「パソコンの電源を入れる」や「コンセントにプラグをさす」など、自明なことを書いてしまうようなものです。
"それっぽく"なるだけで、それらは言ってしまえばWBSの可読性や運用効率を下げてしまうゴミです。
書かなくても目的を達成できること、細かすぎること、ステークホルダー(やWBSを読むと想定される人)の中で共通認識として自明な事
は書かないようにしましょう。

##おわりに
以上になります。
初心者の910nagaiが初心者に向けて書いたものなので、参考になる方は少ないかもしれませんが、
少なくとも筆者は考えを多少まとめられていい経験となりました、ありがとうございます。

色々書きましたが結局は、
**最短でゴールを目指す**
という事です。

これからも頑張ります。
WBS10個作成が完了してる頃にはもう少し有益なことを書けるかもしれません。

それでは。