OmniAICreator/Qiita-1.07M huggingface dataset:
【WordPress】投稿文字数を制御するための構文

WordPressでサイト制作をする際に、記事一覧を表示させる際に、本文の文字数を制御する必要があります。
（そうしないと、本文がすべて表示されてレイアウトが整わない）

文字数を制限するために、つよつよエンジニアが書いたコードをそのままコピペで使って書いていたんですが、一度整理しようと思い記事を書いております。

##この記事でわかること
投稿の文字数の制御の方法

##やりたいこと
投稿した本文を１２０文字だけ表示させる。



#使用したコード

```index.php
<?php
$post_content = strip_tags(get_the_content());
if(mb_strlen($post_content)>120 ) {
$post_content = mb_substr($post_content,0,120);
$post_content = str_replace(array("\r", "\n"), '', $post_content).'…';
} else {
$post_content = str_replace(array("\r", "\n"), '', $post_content);
}
echo $post_content;
?>
```
うおっ、全然わからない。
ちょっと話がそれますが、毎回コピペコードを使っているようじゃ成長できないなと感じます。
必ず、コピペしたコードを読み解くようにすべきですね。

では、何が行われているのかみていきましょう！

###１行目

```index.php
$post_content = strip_tags(get_the_content());
```

変数を定義しています。変数`$post_content`に`strip_tags(get_the_content());`を格納しています。

`strip_tags(get_the_content());`では、HTMLタグを取り除く、`strip_tag()`関数を使用しています。

`strip_tag()`関数については、こちらの記事が参考になります。
https://thewppress.com/libraries/get-the-content/

###2行目

```index.php
if(mb_strlen($post_content)>120 ) {
```
きました、if文です。
もし〜の条件のときということで、何か条件が指定されているのでしょう。

みてみます。
`(mb_strlen($post_content)>120 )`
`strlen()関数`では、引数にしてした文字列の長さを取得してくれます。
ただ、バイト数での取得となります。
コンピューターの世界では、半角と全角でバイト数が異なるようで、半角1文字1バイト・全角1文字2バイトとなるようです。

１２０文字だけ表示させたいって考えたときにいちいちバイト数を考えるのはめんどくさいですよね？その際に便利なのが、`mb_strlen()`関数です。

バイト数ではなく、文字数を取得してくれますので、半角も全角も１文字として扱えます。

なので、`もし、文字数が120文字以上の場合は⋯？`という文になっています。

###3~4行目
```index.php
$post_content = mb_substr($post_content,0,120);
$post_content = str_replace(array("\r", "\n"), '',$post_content).'…';
```
3行目:$post_contentの0文字目から120文字までを取得しています。
4行目:`str_replace`では検索した文字列を変換しています。

`str_replace("検索を行う文字列","置き換えを行う文字列","対象の文字列");`となるようなので、

検索を行う文字列=array("\r", "\n")
置き換えを行う文字列 =なし
対象の文字列 = $post_content).'…'

となります。

ここれは、改行を削除して、120文字以上のときには、...を表示するようにプログラミングされています。

##5~6行目
```index.php
} else {
$post_content = str_replace(array("\r", "\n"), '', $post_content);
}
```
ここでは、本文が120文字以下の文章に対してのプログラミングとなります。
改行を削除して、本文を表示するようにされています。

##7行目
```index.php
echo $post_content;
```
echoで`$post_content`を表示する指示がだされています。

##まとめ
結構理解するのが大変でしたね。イマイチ理解できていない箇所(`array("\r", "\n")`)
もあったりしますが、少しずつ理解していきたいと思います。

そして、私の説明で違っている点があればTwitterのDMでも良いので教えていただけると嬉しいです!
変数名、クラス名、メソッド名などで困ったときに辿る命名フロー

コードを書いていて、変数名やメソッド名で悩むことが多々あります。
この記事は、自分がいつも辿る命名までのフローを超簡単に、メモ的にまとめてみたものです。

## 1.何をする処理なのかを自分で把握する
ここで命名フローのほぼ90%が終わると思います。筆者はまず定義箇所に、日本語で何をする処理なのかをコメントで記述します。

ここで、筆者が気をつけていることは、なるべく具体的に書き出すということです。

```
// 都道府県、市区町村部分のスラッグ(slug)を元にURLを作成する
```

## 2.参考情報を漁る
何をする処理・ものに名前をつけるのかがまとまったところで、次は他力本願です。

全てに共通する決まったお作法というものはないと思いますが、例えばメソッドでは

- 動詞・助動詞を用いて命名する

- 真偽値を返す場合、オブジェクトが期待する状態に**なっているかどうか**は`is`を使う、期待するデータ・プロパティを**持っているかどうか**は`has`を使う

...など、そのメソッドを使う人達が名前からどんなことをするか理解できるようにするためには、ある程度ルールにのっとった命名が求められます。
中学生の英語じゃないか!と言われそうですが、案外自分一人で即座に適切な命名ができません(少なくとも筆者は)。

ネットには、先人がまとめた上手く命名するための良質な情報がたくさんあります。
命名対象が何をする処理なのかは1,で把握しているので、↓の参考記事を調べつつ、適切な単語を探します。

### 2.1.クラスの命名に関する参考記事
[うまくクラス名を付けるための参考情報](https://qiita.com/KeithYokoma/items/ee21fec6a3ebb5d1e9a8)

### 2.2.メソッドの命名に関する参考記事
[うまくメソッド名を付けるための参考情報](https://qiita.com/KeithYokoma/items/2193cf79ba76563e3db6)

### 2.3.命名全般に関する参考記事
[モデルやメソッドに名前を付けるときは英語の品詞に気をつけよう](https://qiita.com/jnchito/items/459d58ba652bf4763820)

## 3.命名候補が世界中でどの程度ポピュラーなのかを調べる
[プログラムのネーミングに迷ったら GitHub でコード検索すると参考になる説](https://qiita.com/kyoshidajp/items/c5d4f060df636ea20cbb)

筆者の場合は、GitHub上で自分の考えたネーミングがどのぐらい使われているかを調べるツール（↑の記事中で紹介されている）を使っています。
https://github.com/kyoshidajp/ghkw


## 4.コーディングスタイルに適合しているかチェック
あとは、キャメルケース or スネークケース or ケバブケースなど、言語・プロジェクトのコーディングスタイルに適合した記述かどうかをチェックします。
linter などの静的解析ツールが整備されてあれば、指摘・自動的に修正される部分ですが、念のためチェック。

## 5.チームメンバーに相談する
おそらく、この段階で名詞以外の品詞の部分に関しては、大丈夫なはずです。最終的な命名候補が決まったら、チームメンバーに相談してみましょう。事業ドメインによっては、適切な命名が変わってくる場合もあります。

結局、命名した変数や関数・クラス名を読むことになるのは一緒に開発をしているチームメンバーです。
1回相談してみて、チームメンバーにとってわかりやすいものかどうかを判断してもらうことが確実でしょう。

## 雑記
命名について調べていると、筆者は今まで知らなかったのですが日本語を入力するとネーミングを生成してくれるサービス、というものがありました。

こういったツールを用いることも1つの選択肢だと思います。

https://codic.jp/

# 参考資料
- [モデルやメソッドに名前を付けるときは英語の品詞に気をつけよう](https://qiita.com/jnchito/items/459d58ba652bf4763820)

- [うまくメソッド名を付けるための参考情報](https://qiita.com/KeithYokoma/items/2193cf79ba76563e3db6)

- [モデルやメソッドに名前を付けるときは英語の品詞に気をつけよう](https://qiita.com/jnchito/items/459d58ba652bf4763820)

- [リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)](https://www.amazon.co.jp/%E3%83%AA%E3%83%BC%E3%83%80%E3%83%96%E3%83%AB%E3%82%B3%E3%83%BC%E3%83%89-%E2%80%95%E3%82%88%E3%82%8A%E8%89%AF%E3%81%84%E3%82%B3%E3%83%BC%E3%83%89%E3%82%92%E6%9B%B8%E3%81%8F%E3%81%9F%E3%82%81%E3%81%AE%E3%82%B7%E3%83%B3%E3%83%97%E3%83%AB%E3%81%A7%E5%AE%9F%E8%B7%B5%E7%9A%84%E3%81%AA%E3%83%86%E3%82%AF%E3%83%8B%E3%83%83%E3%82%AF-Theory-practice-Boswell/dp/4873115655)
AWS EC2とは

AWSクラウド上の仮想サーバー。インスタンスというのはEC2から建てられたサーバーのこと。
---


### 作成手順

1. AMIの選択
2. インスタンスタイプの選択
3. ストレージの追加
4. セキュリティグループの設定
5. SSHキーペアの設定

### AMIとは

Amazon Machine Image。インスタンス起動に必要な情報が入った、OSのイメージ。
サーバーのテンプレートのようなもの。自前で作成したものをカスタムAMIとして登録しておくことも可能。

### インスタンスタイプとは

サーバースペックを定義する。

+ CPU、メモリ、ストレージ、ネットワーク帯域が異なる。
+ インスタンスタイプにより料金が異なる。スペックが高いほど料金も高い
+ アクセス数等に応じて必要なスペックのあるインスタンスタイプを選択する

次のような表記で表現される

m5.xlarge

m：インスタンスファミリー

5：インスタンス世代

.xlarge：インスタンスサイズ

m5.xlarge：インスタンスタイプと呼ぶ。

### ストレージとは

サーバーのデータを保存する場所。EC2のストレージには２種類ある。

+ EBS

 + メリット
     + 高い可用性と耐久性を持つ。
     + 他のインスタンスと付け替えが可能。
     + インスタンスをStop/TerminateしてもEBSは保持することが可能。
     + Snapshotを取得してS3に保存可能。
 
 + デメリット
     + 費用が別途発生する。

 + 利用用途

     + OS,DB等の永続性と耐久性が必要なデータを置く。

+ インスタンスストア

 + メリット
     + 追加費用がない(無料)

 + デメリット
      + インスタンスがStop/Terminateされると削除される。
      + 他のインスタンスと柄変えを行うことはできない。

 + 利用用途
      + 一時ファイル、キャッシュ等の失われても問題ないデータを配置する

+ SSHとは

  + サーバーにログインする時の仕組み。サーバーと自分の目の前のパソコンを安全な形で通信するサービスのこと。

### 参考
[Udemy AWS：ゼロから実践するAmazon Web Services。手を動かしながらインフラの基礎を習得](https://www.udemy.com/course/aws-and-infra/learn/lecture/14781780#content)
[Ruby]tapメソッドでHashの初期化と同時にその階層を定義する

参考書とかに書いてあるのだろうと思いますが、備忘録代わりに。

## たとえば

以下のような複数の要素が混ざった配列を連想配列で分離させたい場合

```rb

array = [1, 2, "a", 3, "b", "c", 4]

ideal_hash = {
  hoge: [1, 2, 3, 4],
  fuga: ["a", "b", "c"]
}
```

## 今まで自分が書いていたコード

```rb

ideal_hash = { hoge: [], fuga: [] }

array.each do |i|
  i.is_a?(Integer) ? hash[:hoge] << i : hash[:fuga] << i
end
```

## こうも書けるということを最近知った

tapメソッドは生成した自分自身を返すので、スッキリ書けるというのもあり、できるだけ使っていきたいという気持ちがあります。

```rb

ideal_hash = { hoge: [], fuga: [] }.tap do |hash|
  array.each do |i|
    i.is_a?(Integer) ? hash[:hoge] << i : hash[:fuga] << i
  end
end
```
Could not open input file　でエラー



ターミナルにphp artisan serveを実行する際に
Could not open input file
と、エラーが出ました。

初心者の私は・・・なんで？ってなりました。


色々調べて理解した事！
そもそもターミナルの使い方がわかっていなかった！


php artisan serveを実行するためには
ターミナルのなかで、自分がどこの位置にいてるのかを理解する必要がありました。
そうです・・・artisanという場所がどこのフォルダに存在しているのか。

Laravelの中の、applicationの中に存在しているはずです。

ディレクトリの移動に使うコマンドは
cd
そのあと、次の選択肢を探すために
ls -a
を使います。
applicationまでたどり着いたら
php artisan serve
を実行しましょう。
これで解決します。

基本が理解できてないと変なところで時間取られます・・・。
脱Excel Elastic Stack（docker-compose）でcsvログを分析・可視化 - PipelineFilterを[input/filter/output]の3ファイルに分割し、保守性と再利用性向上

## はじめに

どうも！生産技術部で製品の検査工程を担当しているエンジニアです。[脱Excel Elastic Stack（docker-compose）でcsvログを分析・可視化 - Elastic Stack](https://qiita.com/TomoyukiSugiyama/items/619ab258ba230dfcf0a0)とはの続きになります。

## 対象読者
この記事では、Elastic Stackをそもそも知らない方、これから試そうと思っている方を対象としています。

## この記事の内容
公式のブログに記載されていた[保守性と再利用性にすぐれたLogstashパイプラインの作り方](https://www.elastic.co/jp/blog/how-to-create-maintainable-and-reusable-logstash-pipelines)を実践してみました。パイプラインの数が増えても、メンテナンスできるように[input/filter/output]の３つのフォルダに分けました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/451049/ad293d2c-4a14-f478-dafd-03521226c63c.png)


GitLabに設定ファイル一式を置いておきましたので参考にしてください。
リポジトリはこちら -> [elastic-stack](https://gitlab.com/iyama_yuki/elastic-stack/-/tree/master/)

## 分割方法
logstash.confをinput,filter,outputの３つに分割します。

```config:logstash/pipeline/logstash.conf
input {
  beats {
    port => "5044"
  }
}

filter {
  csv {
    columns => ["Step","TestName","Value1","Judge"]
    separator => ","
  }
}

output {
  elasticsearch {
    hosts    => [ 'elasticsearch' ]
    index    => "%{[@metadata][beat]}-csv-%{+YYYY}-%{+MM}"
  }
}
```

以下の_in,_filter,_outに分割し、拡張子を`.cfg`とします。

```config:logstash/pipeline/input/logstash_in.cfg
input {
  beats {
    port => "5044"
  }
}
```
```config:logstash/pipeline/lfilter/ogstash_filter.cfg
filter {
  csv {
    columns => ["Step","TestName","Value1","Judge"]
    separator => ","
  }
}
```
```config:logstash/pipeline/output/logstash_output.cfg
output {
  elasticsearch {
    hosts    => [ 'elasticsearch' ]
    index    => "%{[@metadata][beat]}-csv-%{+YYYY}-%{+MM}"
  }
}
```

## docker-composeの設定
pipelineフォルダを丸ごとマウントします。

```yml:docker-compose.yml
logstash01:
    build: ./logstash
    container_name: logstash01
    links:
      - es01:elasticsearch
    volumes:
      - ./logstash/config/logstash.yml:/usr/share/logstash/config/logstash.yml
      - ./logstash/config/jvm.options:/usr/share/logstash/config/jvm.options
      - ./logstash/config/log4j2.properties:/usr/share/logstash/config/log4j2.properties
      - ./logstash/config/pipelines.yml:/usr/share/logstash/config/pipelines.yml
      - ./logstash/pipeline/:/usr/share/logstash/pipeline/
      - ./logstash/extra_patterns/date_jp:/opt/logstash/extra_patterns
    networks:
      - esnet
```

## pipelineの設定

grob表現の`{}`を使ってpath.configに３つのファイルを設定します。[input/filter/output]のディレクトリに分けたため、以下のように記述します。

```config
- pipeline.id: filebeat-processing
  path.config: "/usr/share/logstash/pipeline/{input/logstash_in,filter/logstash_filter,output/logstash_out}.cfg"
```

## 最後に
フィルタのみを変えたいシチュエーションなどでは、再利用性の面でもメリットがあると思いますが、今のところは恩恵を受けてないです。
【Kotlin】バージョン番号のソート

バージョン番号のソートが流行っているようなので、Kotlin でやってみた[^Kotlinでやってみた]。

[^Kotlinでやってみた]: というか Kotlin 以外めんどくさくて書きたくない。

元ネタ：「[アルゴリズムのせいで面接に落ちた](https://zenn.dev/rana_kualu/articles/efd74e8525ccab6c8474)」

```Kotlin
/**
 * バージョン番号を表す文字列を比較する [Comparator]。
 *
 * バージョン番号は数値を `.` で区切ったもの。
 */
class VersionComparator : Comparator<String> {
    override fun compare(a: String, b: String): Int {
        if (a == b) return 0

        val numberListA = a.toNumberList()
        val numberListB = b.toNumberList()

        return (numberListA zip numberListB)
            .find { (numberA, numberB) ->
                numberA != numberB
            }
            ?.let { (numberA, numberB) ->
                numberA.compareTo(numberB)
            }
            ?: numberListA.size
                .compareTo(
                    numberListB.size
                )
    }

    companion object {
        private fun String.toNumberList(): List<Int> =
            split(".").map { it.toInt() }
    }
}
```

記事「[[JavaScript] Version のソートアルゴリズムを高階関数縛りで考えてみた](https://qiita.com/StewEucen/items/7fdef77a53e98ef676fb)」を参考にさせていただいた。

バージョン番号に数字以外が入ってくる場合については考えていない（実行時例外がスローされる）。
パターンがありすぎてきりがない（その都度 `Comparator` を実装した方がよい）ため。

動作確認。

```Kotlin
fun main() {
    // ソートする対象。
    val versions = listOf(
        "1.3.0.9",
        "0.2.0",
        "3.1.2",
        "0.1.6",
        "5.0.0",
        "3.3.3.3",
        "3.3.3.3.3",
        "3.10",
        "0.2.0",
    )
    // 期待されるソート結果。
    val output = listOf(
        "5.0.0",
        "3.10",
        "3.3.3.3.3",
        "3.3.3.3",
        "3.1.2",
        "1.3.0.9",
        "0.2.0",
        "0.2.0",
        "0.1.6",
    )

    versions.sortedWith(
        VersionComparator()
            .reversed() // 降順にする。
    ).also {
        println(it == output) // > true
    }
}
```
レジストリとレジストラの違い

## 勉強前イメージ

どっちかが、ドメインの管理をしている会社 ってイメージ
後はよく知らない....

## 調査

普通にドメインを取得しようとすると
ドメインの取得を代行する事業者・または事業者の代理店に依頼するのが一般的です。

### レジストリ

数多くのドメイン、`.com` や `.net` など各トップレベルドメイン毎に1つ存在する最上位機関になります。
各トップレベルドメインに関してすべての情報を蓄積したデータベースを持っており、どのドメインが登録済みかを管理しています。	

### レジストラ

レジストラはドメインを登録する事業者のことを指します。
ドメインの管理をしているレジストリに対して、ドメイン情報を登録する権利を持っているのがレジストラになります。
通常、個人でドメインの取得をする際にもレジストラ(ドメインを登録する事業者)を介してレジストリ(トップレベルドメインの最上位機関)に申請することになります。

### リセラー

リセラーとはドメインを登録する権利を持っていない代理店のことを指します。
ドメインの登録を行う権利がないので、レジストラ(ドメインを登録する事業者)を介してレジストリ(トップレベルドメインの最上位機関)に申請を行う。

![無題の図形描画.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/262a0fe8-e888-ec1a-223d-21d84f44dcd2.jpeg)


## 勉強後イメージ

今までドメインって全部をどこか一つが管理してるのかと思ってたけど、各トップレベルドメイン毎に管理している場所があるのね。
お名前.comとかがレジストラに当たるところか。


## 参考

- [レジストリとレジストラ](https://www.nadukete.net/domain-guide/setting/registry-registrar.html)
- [ICANN認定公式レジストラのお名前.com](https://www.onamae.com/clever/about/regist.html)
- [レジストリ、レジストラ、リセラー（上位組織）について。](https://help.sakura.ad.jp/206357901/)
C#の基本的な構文を試すための環境をVisualStudioCodeで作成する

# C#の基本的な構文を試すための環境をVisualStudioCodeで作成する

## 参考URL
[チュートリアル: Visual Studio Code を使用して .NET Core コンソール アプリケーションを作成する](https://docs.microsoft.com/ja-jp/dotnet/core/tutorials/with-visual-studio-code)

## 対象者
- C#の基本的な構文を試すための環境を簡単に作成したい方

## 実践
### プロジェクトの作成

以下のコマンドを実行

```
> dotnet new console
```

以下のようなディレクトリ、ファイルが作成される。
プロジェクト名は`現在のディレクトリ`の名前になる

```
C:.
│  ConsoleTest.csproj
│  Program.cs
└─obj
    ConsoleTest.csproj.nuget.dgspec.json
    ConsoleTest.csproj.nuget.g.props
    ConsoleTest.csproj.nuget.g.targets
    project.assets.json
    project.nuget.cache
```

### Program.cs

> Main はアプリケーションのエントリ ポイントで、アプリケーションを起動するときに、ランタイムによって自動的に呼び出されるメソッドです。 アプリケーションが起動されるときに提供されるコマンドライン引数はすべて args 配列にあります。

```c#
using System;

namespace ConsoleTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
        }
    }
}
```

### アプリケーションの実行

以下のコマンドを実行すると`Program.cs`の`Main`メソッドが実行される

```
> dotnet run
Hello World!
```

### まとめ
作成された`Program.cs`内でいろいろと試せると思います。

### 補足
[@ktz_alias](https://qiita.com/ktz_alias)さんからコメントで別の方法を教えていただきましたので参考にさせていただきます。
[dotnet/interactive](https://github.com/dotnet/interactive)
メール を指定した時間で定型分を送信するプログラム by Python

#モジュールをインポートする。
import datetime
import smtplib
import ssl
from email.mime.text import MIMEText
import sys, codecs

sys.stdout = codecs.getwriter("utf-8")(sys.stdout)
gmail_account = ""　#→自分のメールアドレスを入れてください。
gmail_password = ""　#→自分のメールアドレスパスワードを入れてください。
gmail to = "" #→送信したいメールアドレスを入れてください。
send_name = "ぷーやん"

#メールを送る期間を決める。
today_date = datetime.date.today()
delivery_date = today_date + datetime.timedelta(days=7)
print(today_date,delivery_date)

#メールデータ（MIME)の作成
subject = "{0}様、{1}分の発注書をお送りします。". format(send_name, today_date)
body = "表題の発注書をお送りします。<br>添付ファイルをご確認ください。<br>本発注の納期は{0}となります。<br><br>株式会社ぷーやん".format(delivery_date)

print(subject) #確認用

print(body)　#確認用

msg = MIMEText(body, "html")
print(msg)

msg["Subject"] = subject
msg["To"] = mail_to
msg["From "] = gmail_account
print(msg)

server = smtplib.SMTP_SSL("smtp.gmail.com", 465,context=ssl.create_default_context())
server.login(gmail_account, gmail_password)
server.send_message(msg)
server.close()
print('送信完了')
脱Excel Elastic Stack（docker-compose）でcsvログを分析・可視化 - LogstashのOutOfMemoryErrorが出た時の２つの対応方法

## はじめに

どうも！生産技術部で製品の検査工程を担当しているエンジニアです。[脱Excel Elastic Stack（docker-compose）でcsvログを分析・可視化 - Elastic Stack](https://qiita.com/TomoyukiSugiyama/items/619ab258ba230dfcf0a0)とはの続きになります。

## 対象読者
この記事では、Elastic Stackをそもそも知らない方、これから試そうと思っている方を対象としています。

## この記事の内容
大量のファイルをfilebeatからlogstashに転送すると、以下のエラーが出てlogstashが落ちることがあります。その対応方法を紹介します。

```systemd
java.lang.OutOfMemoryError: Java heap space
Dumping heap to java_pid1.hprof ...
Heap dump file created [3178685347 bytes in 34.188 secs]
warning: thread "[main]>worker11" terminated with exception (report_on_exception is true):
warning: thread "[main]>worker4" terminated with exception (report_on_exception is true):
java.lang.OutOfMemoryError: Java heap space
```

GitLabに設定ファイル一式を置いておきましたので参考にしてください。
リポジトリはこちら -> [elastic-stack](https://gitlab.com/iyama_yuki/elastic-stack/-/tree/master/)

## エラーの原因
エラー内容が示す通り、ヒープサイズが足りないことが原因です。

## 物理メモリのサイズに余裕がある場合の対応方法
jvm.optionsファイルを作成し、以下のヒープサイズを変更します。
どれくらいに設定すればいいのかは、[JVM Setting](https://www.elastic.co/guide/en/logstash/current/jvm-settings.html#jvm-settings)の説明に従い、使用するマシンと相談してください。

```config:logstash/config/jvm.options
## JVM configuration

# Xms represents the initial size of total heap space
# Xmx represents the maximum size of total heap space

-Xms1g
-Xmx1g
```

## 物理メモリのサイズに余裕がない場合の対応方法
pipeline.batch.sizeもしくはpipeline.workersを変更することで、処理量に制限をかけることが出来ます。
batchサイズのデフォルト値は125、workersはホストPCのCPUの数となっています。
公式のドキュメントは[こちら](https://www.elastic.co/guide/en/logstash/current/logstash-settings-file.html)です。

```yml:logstash/config/pipelines.yml
- pipeline.id: filebeat-processing
  pipeline.batch.size: 50
```


## 最後に
Elasticsearchに関してですが、[公式のブログ](https://www.elastic.co/jp/blog/significantly-decrease-your-elasticsearch-heap-memory-usage)によると、7.7からElasticsearchのヒープ領域使用量が大幅にダウンするそうです。Elasticsearchのメモリでお困りの方はバージョンを見直してみてください。
無料版のsentryでslackに通知を送る（lambda利用）

# この記事について
slackに通知させるには、sentryのintegrationとして用意があるのですが、利用できるのが有料版のみとなっています。

個人でのプロジェクトでの利用で、有料化するつもりはなく、無料版でもできるようにしてみました。
通知の部分のみにフォーカスしているので、sentryの設定などは、説明を省いております。

# 対象
- sentryの無料版を利用していて、slackに通知したい
- awsのアカウントを持っている

# 方法について
sentryのwebhookを利用します。
送信先にlambdaのURIを指定して、lamdaからslackのwebhookにリクエストします。

# 手順

- slackのincoming webhookを設定して、リクエスト先を用意します。（いろいろ記事があるので省略）
- lambdaを作成し、環境変数`SLACK_INCOMING_WEBHOOK_URL `に、slackのURIを設定する
- lambda処理を下記をコピペして保存・デプロイ（サンプルはruby）

```ruby
require 'json'

def lambda_handler(event:, context:)

    body = JSON.parse(event['body'])
    
    post_query = {
      "attachments": [
        "pretext": "<#{body['url']}|Exception>\r\nproject: #{body['project_slug']}\r\nenvironment: #{body['event']['environment']}\r\ndetail: #{body['event']['metadata']['filename']}`#{body['event']['metadata']['function']}`",
        "color": "#D00000",
        "fields": [
          "title": "#{body['event']['title']}",
          "value": "#{body['culprit']}"
        ]
      ]
    }
    
    uri = URI.parse(ENV['SLACK_INCOMING_WEBHOOK_URL'])
    http = Net::HTTP.new(uri.host, uri.port)
    http.use_ssl = true
    http.post(uri.path, post_query.to_json)

    { statusCode: 200, body: JSON.generate('') }
end
```

# 結果

下記のような通知が届きます。
（サンプルはRailsで発生させたエラーです）

![スクリーンショット 2020-11-01 19.34.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/330639/76e592b3-858a-8235-0380-a62e2fe23626.png)


# 最後に

lambdaの処理は、Railsでのエラーを前提にしているので他のフレームワークだと情報が正しく表示されない可能性はあります。
カスタマイズは、sentryのwebhookパラメータを覗けばできると思います。
prestoとhiveで同じSQL文を使うときでハマったこと


参加したプロジェクトでhiveとpresto両方で確認する必要がある。同じ意味のクエリをhiveで走らせたり、prestoで走らせたりするのに、毎回違うSQLを実施するのが面倒である。また、同じSQLでも微妙に「方言」が違う。そこまでならばまだ大丈夫で、なれるか、hiveのmacroを用い、表現を統一するなどのやり方がある。しかし、たまに基本の考え方が違っていてはまりやすいところもある。
ここで、自分が引っかかったものを共有する。少しでも役に立てば嬉しい。

# 環境
```
今回、以下の環境を用いた。
Presto CLI 333
Beeline version 1.2.2 by Apache Hive
```


# 正規表現の違いについて

- 特殊文字（例えば$のエスケプ）の表現が hiveにおいて ¥¥$であるが、presto において ¥$である。この違うによって、特にエラーなどがなっていないためはまりやすい。

hiveの場合

```sql:hive
> select 'This is a $test' rlike '\\$test';
+-------+--+
|  _c0  |
+-------+--+
| true  |
+-------+--+

> select 'This is a $test' rlike '\$test';
+--------+--+
|  _c0   |
+--------+--+
| false  |
+--------+--+

> select 'This is a $test' rlike '$test';
+--------+--+
|  _c0   |
+--------+--+
| false  |
+--------+--+
```

prestoの場合

```sql:presto
presto> select regexp_like('This is a $test','\$test');;
 _col0
-------
 true

presto> select regexp_like('This is a $test','$test');;
 _col0
-------
 false

presto> select regexp_like('This is a $test','\\$test');;
 _col0
-------
 false
```

- 正規表現で文字列から特定のパターンを抽出する際、prestoではマッチしないときに、NULLを戻すが、hiveでは、空（文字列）を戻す！これははまりやすいところである。

hiveの場合

```hive
> select regexp_extract('This is a test','(test)',1);
+-------+--+
|  _c0  |
+-------+--+
| test  |
+-------+--+

> select regexp_extract('This is a test','(testx)',1);
+------+--+
| _c0  |
+------+--+
|      |
+------+--+

> select regexp_extract('This is a test','(testx)',1)='';
+-------+--+
|  _c0  |
+-------+--+
| true  |
+-------+--+
```

prestoの場合

```sql:presto
presto> select regexp_extract('This is a test','(test)',1);
 _col0
-------
 test

presto> select regexp_extract('This is a test','(testx)',1);
 _col0
-------
 NULL
```

# 配列の違いについて

hiveの配列が 0 からカウントされるが、prestoがなぜか 1からカウントされる

hiveの場合

```sql:hive
> select split('1,2',',')[0];
+------+--+
| _c0  |
+------+--+
| 1    |
+------+--+
```

prestoの場合

```sql:presto
presto> select split('1,2',',')[0];
Query 20201031_122624_05800_juuv8 failed: SQL array indices start at 1

presto> select split('1,2',',')[1];
 _col0
-------
 1
```

# windows関数の違い

last_valueやfirst_valueを使いときに、NULLを無視する他場合、hiveではこのようにパラメターでしていできる

```sql:hive
> select last_value(item1,TRUE) over ...
一方、presto において、このように構文が変わる
```

```sql:presto
presto> select last_value(item1) ignore nulls over ...
```
ここの違いはまだ統一SQL文にな統一できていないところである

# hive macroを用い、prestoと同じsql文

簡単なhiveマクロを使いhiveとprestoのSQLを合わせることによって、SQLクエリをあわせることができる。例えば、以下のmacroを先頭に入れれば、同じpresto用SQL文（to_unixtime, nullif, regexp_like,replace）でもhiveで使える。

```sql:hive
create temporary macro to_unixtime(s string) unix_timestamp(s);
create temporary macro nullif(src string,s string) if(src = s, null, src);
create temporary macro regexp_like(str string, pattern string) str rlike pattern;
create temporary macro `replace`(str string,src string,dst string) translate(str,src,dst);
```
ただし、regexp_likeのようなsql文は同じでも、中身のエスケプルールについて気をつけないといけない。

# 参考
- https://prestodb.io/docs/current/migration/from-hive.html
Growi

## 起動方法

* [GitHub - weseek/growi-docker-compose: growi-docker-compose - The fastest way to boot All-in-One GROWI](https://github.com/weseek/growi-docker-compose)

```sh
git clone "https://github.com/weseek/growi-docker-compose.git" growi
cd growi

sed -i \
 -e 's/# - FILE_UPLOAD=local/- FILE_UPLOAD=local/' \
 docker-compose.yml

docker-compose up -d
```

* 1分まつ
* http://localhost:3000 にアクセス

## APIへのアクセストークン取得

* 右上の`ユーザー` →  `ユーザー設定` → `API Tokenの取得`

![スクリーンショット_2020-05-13_12-31-21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/390181b0-cc26-0811-6aba-531cc09ece48.png)


## (API) 記事の投稿

* /user/user1/hoge に aa という内容の記事を投稿する例。

```py:create_page.py
import requests

# 接続先。http://localhost:3000 を想定。
protocol = 'http'
host_address = 'localhost:3000'
access_token = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

# 投稿API
def pages_create(path, body):
    url = f'{protocol}://{host_address}/_api/pages.create'
    requests.post(url, data={'body':body, 'path':path, 'access_token':access_token})

# 投稿先と内容の指定
page_path="/user/user1/hoge"
template_body="aa"
# 投稿
pages_create(page_path, template_body)
```

```sh:投稿実施
python3 create_page.py
```
IFTTTとGASで自分のTwitterアカウントをガンダム名言集botにしてみた

#ガンダム好きのエンジニアにフォローされたい

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">聞けませんね!僕にとっては、エゥーゴもティターンズも関係ないって言ったでしょ! 大人同士の都合の中で死んで言った、馬鹿な両親です。でもね…僕にとっては親だったんですよ!<a href="https://twitter.com/hashtag/protoout?src=hash&amp;ref_src=twsrc%5Etfw">#protoout</a><a href="https://twitter.com/hashtag/protooutstudio?src=hash&amp;ref_src=twsrc%5Etfw">#protooutstudio</a><a href="https://twitter.com/hashtag/%E3%82%AC%E3%83%B3%E3%83%80%E3%83%A0%E5%90%8D%E8%A8%80%E9%9B%86?src=hash&amp;ref_src=twsrc%5Etfw">#ガンダム名言集</a></p>&mdash; sawa (@sawakoshi_yy) <a href="https://twitter.com/sawakoshi_yy/status/1322830249504235521?ref_src=twsrc%5Etfw">November 1, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

ちなみに一番好きなガンダムはZガンダムです。

#ガンダム名言募集中です

#作り方
この方法だと、TwitterのAPIトークンの取得も不要です。

#IFTTT

「If This」にWebhooks
「Then That」にTwitterのPost a tweetを選択
<img width="300" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737363/0c6b8c07-d74d-b5f6-fdbb-920b38dcb8a5.png">

Event Nameは何でもいいです。
Value1にガンダム名言が入ります。

<img width="300" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737363/f1bd980a-1c8e-4f1a-98c7-e029624fb867.png">
IFTTT側の設定はこれだけ。
Webhook用のURLを確認しておきましょう。
↓のページで赤枠をクリック
<img width="500" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737363/a11d21ef-28e6-0b89-0ff5-664785a2e714.png">
Documentaionをクリック
<img width="500" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737363/05dd0528-f8f9-e959-b9de-567cc71b65b1.png">
↓の赤枠部分をコピーしておく。
<img width="500" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737363/06c57cdf-3f33-267f-45f4-a2da60096332.png">

#GAS
スプレッドシートのA列に好きなガンダム名言を入れます
<img width="500" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737363/392d0ec4-d101-484c-d2ab-d3412d79c9ac.png">

ツール　→　スクリプトエディタ　を開き、↓のコードを入力
webhookのURLは先ほどコピーしたものに変えてください。

```javascript
function myOutgoingFunction() {
  const sheet = SpreadsheetApp.getActiveSheet();
  let currentRow = 1;
  while (true) {
    // 記録されていない行が見つかったとき：
    if (!sheet.getRange(currentRow, 1).getValue()) {
      break;
    }
    // 次の行へ
    currentRow++;
  }
  let random = Math.ceil( Math.random () * (currentRow-1) );
  let text = sheet.getRange(random, 1).getValue();
  // さっきコピーしたWebhook URLを貼り付け
  //triggerとwithの間にIFTTTで設定したEvent Nameを入れる
  const URL = 'https://maker.ifttt.com/trigger/text/with/key/doEKaaaaaaaaaaaaaaaaaaa';

  // POSTする中身
  const teamsPayload = {
    'value1': text,
  };

  // UrlFetchAppのオプション
  const params = {
    'method': 'POST',
    'contentType': 'application/json',
    'payload' : JSON.stringify(teamsPayload),
  };
  
  // HTTPリクエスト送信
  const res = UrlFetchApp.fetch(URL,params);
}
```

これでスプレッドシートのA列に記載された言葉の中からランダムにどれかをTwitterでつぶやきます。
あとはトリガー設定すれば、好きなタイミングでつぶやけます。
トリガーの設定方法は↓を参考にしてください。

[【初心者向けGAS】時限式のイベントトリガーを設置して決まった時刻にBotを送信する方法]
(https://tonari-it.com/gas-timed-driven-trigger/)


#あとがき

好きなキャラクターは、

ん～

ルナマリア
Amazon Cognito / CSVファイルを用いたユーザープールへのユーザーインポート方法 概要

* 自社で持つ認証基盤のCognitoへの移行を検討する際に、自サービスのユーザーデータのCognito ユーザープールへの一括移行手段について調査した。

## CSVインポート

* CSVファイルに自サービスで持つユーザー情報を入力し、そのCSVファイルをCognitoへインポートさせることでデータ移行を行う方法。

### 手順

#### 1. ユーザーインポート .csv ファイルの作成

1. ユーザーインポート .csv ヘッダー情報をCognitoコンソールからダウンロードする。

   ※AWS CLIからも取得可能

2. .csv ファイルのフォーマットの条件に一致させるようにインポートファイルを作成する。

   ```csv
   cognito:username,name,given_name,family_name,middle_name,nickname,preferred_username,profile,picture,website,email,email_verified,gender,birthdate,zoneinfo,locale,phone_number,phone_number_verified,address,updated_at,cognito:mfa_enabled
   ```

   ※フォーマット入力条件については、[公式ドキュメント](https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/cognito-user-pools-using-import-tool-csv-header.html)参照のこと。最大行数が500,000などいくつか制約があるため、移行検討には工数を取って慎重に実施したほうがよさそう。

#### 2. ユーザープールインポートジョブを作成し実行する

1. ジョブ名、IAM、CSVファイルを指定してジョブを作成する。
2. ジョブを開始する。
3. ジョブのステータスが「成功」になれば、インポート成功。

※AWS CLIからも実行可能。

#### 3. ユーザーにパスワードの再設定を要求する

1. ユーザーにパスワードリセット要求通知を送信する。
2. ユーザーは、パスワードリセットを行う。

※インポート直後のユーザーのステータスは、`FORCE_CHANGE_PASSWORD`(パスワード変更必須状態)になる。そのため、ユーザーがパスワードリセットをして初めて利用可能になる。[Cognito API](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/Welcome.html)を使用した作りこみが必須。



#### その他

* インポート失敗時の解析には、CloudWatch Logsで確認する。



## 参考情報

* [CSV ファイルからユーザープールへのユーザーのインポート](https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/cognito-user-pools-using-import-tool.html)
【JavaScript 読み込み】勉強メモ⑥

JavaScriptちゃんと学習中。
ほぼ自分の勉強メモです。
過度な期待はしないでください。


JavaScriptのコード読み込み
-
- HTMLドキュメントに直接書く方法

　HTMLドキュメント内に、`<script>、</script>`を追加すれば、その中にJavaScriptを直接書く事が
　出来る。
　`<script>ダグ`は、`<head>~</head>`内、または`<body>~</body>`内のどこにでも追加出来る。
　が、一般的には`</body>`終了ダグの直前に追加する。

```.html:例
<body>
・・・省略

  <script>
    'use strict';
    ここにJavaScriptのコードを書く
  </script>
</body>
```
　`use strict`は、相互性を確保する為のもの
　要は、新しいJavaScriptをちゃんと実行させる為のものという認識で良いかと
<br>

- JavaScriptファイルを指定して読み込む

　`<script>`ダグにsrc属性を追加して、そこに外部JavaScriptファイルのパスを指定。
　<b>`<script src="JavaScriptファイルのパス"></script>`</b>

```index.html
<body>
・・・省略

  <script src="script.js"></script>
</body>
```

```script.js
'use strict';
 ここにJavaScriptのコードを書く
```
<br>

RailsにおけるJavaScriptの読み込み
-

　railsにはAssets Pipelineという、app/assetsの配下に置いたファイルと、
　application.js・application.cssを自動的にコンパイルされる仕組みがある。
　なので、app/assetsの配下に設置したJavaScriptもすべてのviewで実行される。

- 手順

　１、JavaScriptを記述するディレクトリを作成
　　assetsディレクトリ内に、javascriptsというディレクトリを作成

　２、 JavaScriptを記載する準備
　　先程作成した、app/assets/javascriptsの中に、application.jsを作成

　３、記述したJavaScriptを読み込む為の記述
　　app/views/layouts/application.html.erbの`<head>~</head>`内に、
　　`<%= javascript_include_tag 'application' %>`を加える。

　４、manifest.jsに記載
　　app/assets/config/manifest.jsに下記を記載する。

```manifest.js
//= link_directory ../javascripts .js
```
　これで作成したapplication.jsのファイルを呼び出せるようになる。

　５、application.jsに下記を記述

```application.js
//= require rails-ujs
//= require_tree .
```
　//= require rails-ujsはRailsでJavaScriptを使用する為のもの。

　//= require_tree .は、application.jsが存在するディレクトリの、JavaScriptファイルを
　全て読み込む為のもの。
　↓↓↓　こういう事です。
<img width="1000" alt="ファイル名" src="https://i.gyazo.com/dcb5c81186918bf48e7f73b86069c291.png">
　application.jsに、//= require_tree .記載すれば、
　application.jsの下にある、３つのjsファイルもちゃんと読み込まれる。
<br>

　これで、ちゃんとJavaScriptが読み込まれていると思うので
　console.logで確認してみてください！

<br>

過去投稿記事
-
[【JavaScript ~変数・定数、if文・switch文~】勉強メモ](https://qiita.com/k-yasuhiro/items/1fb63f0881faf67bcb29)
[【JavaScript ~for文、配列、オブジェクトについて~】勉強メモ②](https://qiita.com/k-yasuhiro/items/6625942cc901feb6bfdf)
[【JavaScript ~関数について~】勉強メモ③](https://qiita.com/k-yasuhiro/items/52e3ebb79bb0248a7c5e)
[【JavaScript ~クラスやインスタンス、メソッドについて~】勉強メモ④](https://qiita.com/k-yasuhiro/items/52e3ebb79bb0248a7c5e)
[【JavaScript ~ファイルの分割について~】勉強メモ⑤](https://qiita.com/k-yasuhiro/items/209eda27bbc61ae961a1)
[【JavaScript ~配列のメソッド~】勉強メモ⑦](https://qiita.com/k-yasuhiro/private/279b7bb59f112f917c51)
[【JavaScript ~コールバック関数~】勉強メモ⑧](https://qiita.com/k-yasuhiro/private/ded7e2cad732774d059e)
[【JavaScript ~HTMLを置き換え、ダイアログボックス~】勉強メモ⑨](https://qiita.com/k-yasuhiro/items/7a72bf38d78b141d6fac)
[【JavaScript ~イベント~】勉強メモ⑩](https://qiita.com/k-yasuhiro/items/b0d4037d0edaae38a495)
[【JavaScript ~イベント(入力内容を取得)とDateオブジェクト~】勉強メモ11](https://qiita.com/k-yasuhiro/items/fa586154cf7064eb7058)
[【JavaScript ~Mathオブジェクト~】勉強メモ12](https://qiita.com/k-yasuhiro/items/b931a15fb71322ee3cca)
Goの関数について

##関数の基本構文
関数定義の基本形は下記のようになります。

```
func 関数名(引数) 戻り値型 {
   処理の内容...
}
```

関数に対して引数を取り、関数の戻り値を指定して、処理内容を書いていく流れです。

##名前付き関数
では、簡単な関数を定義してみます。

```main.go
func test(x, y int) int {
   a := x * y
   return a
}

func main() {
   fmt.Println(test(10, 5))  //50
}
```

関数testをint型のx, yで定義し、戻り値型にint型を指定しています。変数aに処理を代入し、returnした値をmain関数で受け取り、値を指定して出力しています。

また、戻り値は複数返すことができます。

```main.go
func test(x, y int) (int, int) {
   a := x * y
   b := x / y
   return a, b
}

func main() {
   a, b := test(10, 5)
   fmt.Println(a, b)  //50 2
}
```

下記のように、戻り値型を省略することで戻り値のない関数も定義できます。

```main.go
func test() {
	fmt.Println("こんにちは！")
	return
}

func main(){
   test()  //こんにちは！
}
```

##エラー処理
エラー処理は下記のようなイディオムがあります。

```main.go
import (
   "os"
   "log"
)

func main() {
   _, err := os.Open("test.txt")
   if err != nil {
      log.Fatal(err)
  }
}
```

このプログラムは、ファイルをオープンする際に、エラーがあればエラーメッセージとともに出力する処理です。そのため、osパッケージとlogパッケージをインポートしています。

##無名関数
無名関数は、明示的に定義する名前付き関数と違い、その名の通り「無名」で関数定義をします。

```main.go
func main() {
   a := func(x, y int) int { return x + y }
   fmt.Println(a(2, 5))  //7
}
```
また、無名関数にそのまま引数を取ることで、さらに短く描くこともできます。

```main.go
func main() {
   fmt.Println(func(x, y int) int { return x + y }(2, 5))  //7
}
```

これは、関数リテラルを使用した無名関数定義でも、同じように出力します。

##関数で関数を返す
無名関数を使用することで、関数で関数を返すことができます。

```main.go
func test() func() {
   return func() {
      fmt.Println("出力")
   }
}

func main() {
   a := test()
   a()  //出力
}
```

このプログラムは、**引数も戻り値も持たない関数を戻り値として返した関数**を、暗黙的に変数aに代入して出力しています。

##関数を引数に取った関数
同じように、関数を引数にとることも可能です。

```main.go
func test(a func()) {
   a()
}

func main() {
   test(func() {
      fmt.Println("出力")  //出力
   })
}
```

このプログラムでは、**引数も戻り値も持たない関数**を関数testの引数にとり、呼び出したものを、関数mainで無名関数として引数に渡すことで出力されています。

##クロージャーを応用したジェネレータ

Goでは、無名関数は**クロージャー**で、関数閉包のようなものです。通常、関数内で定義されている変数(ローカル変数)は関数の実行が完了したのちに破棄されるのですが、クロージャーと結びついていることで、クロージャーが参照されている限り破棄されることはないのです。このロジックを利用することで、Goにはない**ジェネレータのような機能を実現する**ことが可能になります。

```main.go
func test() func() int {
   a := 0  //クロージャー内から参照されているローカル変数
   return func() int {
      a++
      return a  //ローカル変数(クロージャーに属する変数)を参照している
   }
}

func main() {
   b := test()

   fmt.Println(b())  //1
   fmt.Println(b())  //2
   fmt.Println(b())  //3
   fmt.Println(b())  //4
}
```

##最後に
今回は、関数についてまとめました！オブジェクト指向の機能のないGoでは関数の定義というのが中心的になるのではないでしょうか。

次からは、制御構文についてまとめようと思います！！

##参考文献
著者　松尾愛賀
[翔泳社　スターティングGo言語](https://www.shoeisha.co.jp/search?search=%E3%82%B9%E3%82%BF%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0Go%E8%A8%80%E8%AA%9E)
【Ruby】正規表現で特定のパターンを除外して置換する

## 背景

- `http://aaa/ccc` → `http://aaa/bbb/ccc` にしたい
- しかし、元々、`http://aaa/bbb/ccc`のものはそのままで良い

という状況で使えるコマンドが欲しかったです。
つまり、置換はするのですが、なんでも置換するのではなく除外するパターンもあるという除外です。

## コマンド

正規表現の否定的先読みを使います

例えば、playの過去系のみ置換しないのなら、

``` ruby
"play plays played".gsub(/play(?!ed)/, "eat")
#=> "eat eats played"
```
というコマンドになります。
前述のurlに関しては、

``` ruby
"http://aaa/ccc".gsub(/http:\/\/aaa\/(?!bbb\/)/, "http://aaa/bbb/")
#=>"http://aaa/bbb/ccc"

"http://aaa/bbb/ccc".gsub(/http:\/\/aaa\/(?!bbb\/)/, "http://aaa/bbb/")
# => "http://aaa/bbb/ccc"
```
Effect callbacks are synchronous to prevent race conditions. Put the async function inside: エラーが発生した時の対処法

useEffect内で非同期処理を記入しようとしたら、ESlint拡張機能に怒られた

## エラー時のコード

```jsx:example.jsx
  useEffect(async() => {
    await getTrashPageList();
  }, []);
```


```jsx:ESlint拡張機能によるエラー内容
Effect callbacks are synchronous to prevent race conditions. Put the async function inside:

useEffect(() => {
  async function fetchData() {
    // You can await here
    const response = await MyAPI.getData(someId);
    // ...
  }
  fetchData();
}, [someId]); // Or [] if effect doesn't need props or state
```
`Effect callbacks are synchronous to prevent race conditions. Put the async function inside:`

つまり、エフェクトコールバックは競合状態を防ぐために同期されているので、非同期関数はuseEffectの内部に書いてねーと言っている。


## エラーの解消方法

```jsx:example.jsx
  useEffect(() => {
    async function fetchData() { // featchDataという関数を定義し、それにasyncをつける
      await getTrashPageList();
    }
    fetchData(); // ここで呼び出す
  }, [trashPageData]);
```
1. 関数を新たに定義し、その関数にasyncをつけてあげる
2. その関数をuseEffect内部定義する
3. その定義した関数を同ブロック内で呼び出す

これで解決!

## 参考サイト
[How to call an async function inside a UseEffect() in React?
](https://stackoverflow.com/questions/56838392/how-to-call-an-async-function-inside-a-useeffect-in-react)
windows10 home においてwsl2でdocker desktopを使えるようにするためにubuntuのエラー0x80370114、0x80000000と闘った話

# windows 10 home でdocker desktopを使うための手順
####※ubuntuのエラー0x80370114の解決策だけが見たい方はページの最下部まで飛んでください

1. powershellスクリプトが実行できるか確認
2. windowsでLinuxを使えるようにする（windows subsystem for Linux2　通称wsl2を使用）
3. docker desktop for windowsをダウンロード、展開
 
##1. powershellスクリプトが実行できるか確認
簡単にpowershellを説明すると、
コンピューターは宇宙人だと思ってください。私たちが宇宙人に命令を出したいとします。powershellは人間語を宇宙人語に翻訳して宇宙人に命令を出してくれる仲介者です。

ここから本題。windowsにはpowershellが備え付けられています。
1.windowsの左下の検索コマンドにて"powershell"と入力してください。
2.右クリックを押して管理者として実行を押します。
3.赤字でエラーが書かれていなければpowershellに関しては問題ありません。もし「このシステムではスクリプトの実行が無効になっているため～～」と書かれている場合、powershellの画面に

```
Set-ExecutionPolicy RemoteSigned
```

と記述します。これだけでpowershellに関してはOKです。
_参考文献_
[セキュリティ エラー 「このシステムではスクリプトの実行が無効になっているためファイル (スクリプトファイル) を読み込むことができません。…」のメッセージが表示されPowerShellスクリプトが実行できない](https://www.ipentec.com/document/windows-powershell-not-executable-by-execution-settings)

##2. windowsでLinuxを使えるようにする
マイクロソフト公式の以下のURLを参考にしてwsl2をwindowsに導入することができます。
[Windows 用 Linux インストール ガイド](https://docs.microsoft.com/en-us/windows/wsl/install-win10#step-5---set-wsl-2-as-your-default-version)
私の場合は、これの手順にしっかり従っていったのですが、ubuntuのインストールにてエラーが発生しました。エラー0x80370114,0x80000000の解決方法を記事の最下部に示します。

##3. docker desktop for windowsをダウンロード、展開
dockerの公式サイトからダウンロードしてください。
[Windows ホームにドッカー デスクトップをインストールする](https://docs.docker.com/docker-for-windows/install-windows-home/)
このときdownload from docker hubを押してdocker hubのページに飛び、アカウントを作成する必要があります。

##エラー0x80370114,0x80000000の解決方法
私の場合は0x80000000が最初に出ました。ubuntu,docker desktopをアンインストールし、インストールしなおすと0x80370114が出るようになりました。エラー0x80370114の解決手順を以下に示します。

設定
→更新とセキュリティ
→左側のwindowsセキュリティ
→アプリとブラウザーの制御
→スクロールしexploit protectionの設定
→プログラム設定タブをクリック
→スクロールしC:\WINDOWS\System32\vmcompute.exeを見つけ、編集をクリック
→制御フローガードのシステム設定の上書きをオフにし、チェックを外し、適用をクリック
→powershellにて以下のコードを打ち込む

```
net start vmcompute
```
```
wsl --set-default-version 2
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659845/195d04fe-ff88-fc1b-8fbb-68de52b9fc8a.png)

このような画面が出れば完了です。
参考文献
[WSL 2 Installing Linux failed, error code: 0x80370114](https://answers.microsoft.com/en-us/insider/forum/insider_wintp-insider_install-insiderplat_pc/wsl-2-installing-linux-failed-error-code/bae391d1-4215-4d93-b0c4-3d96404a7c74)
unbutuを起動し、手順２の通り進めることができたら、docker desktopはうまく起動します。

ちなみに様々なエラーに関して、日本語で検索してダメな場合は英語で検索するとヒットすることがあります。google翻訳など使えば簡単に読めるので、試してみてはいかがでしょうか。
[Rails]星評価の実装方法

# 実装したい機能
- 星評価で入力、登録できるようにする
- 登録した星評価を表示
![](https://i.gyazo.com/70c7d28382557f1bda0ce13beead9af7.png)

# 目次
1. カラムの設定
2. 星評価の準備
3. 星評価の入力と保存
4. 星評価の表示

# 1. カラムの設定
評価を保存しておくカラムを設定します。
カラム型は星半分評価をできるようにするため、float型を用います。

```ruby:db/migrate/20XXXXXXXXXXXX_create_posts.rb
class CreatePosts < ActiveRecord::Migration[6.0]
  def change
    create_table :posts do |t|
     ~略~
      t.float :evaluation, null: false
     ~略~
    end
  end
end
```

# 2. 星評価の準備
### 星の画像
https://github.com/wbotelhos/raty/tree/master/lib/images
上記リンクから星の画像をダウンロードします。
assets/imagesにフォルダの中に配置します。

### JavaScriptで動作
https://github.com/wbotelhos/raty/blob/master/lib/jquery.raty.js
上記リンクからコードをコピーします。
assets/javascript/application.jsに貼り付けます。
**jqueryで記述するためjqueryの導入も必要となります。**

# 3. 星評価の入力と保存
ビューファイルに以下を記述することで、星評価の入力ができます。

```ruby:app/views/posts/new.html.erb
<%= form_with model: @post, local: true do |f| %>
~略~
<div class="field" id="star">
  <%= f.label :evaluation, "星評価：" %>
  <%= f.hidden_field :evaluation, id: :review_star %>
  <script>
    $('#star').raty({
      size     : 36,
      starOff:  '<%= asset_path('star-off.png') %>',
      starOn : '<%= asset_path('star-on.png') %>',
      starHalf: '<%= asset_path('star-half.png') %>',
      scoreName: 'post[evaluation]',   # evaluationカラムへの保存
      half: true,   # 星半分の入力
    });
  </script>
</div>
~略~
<% end %>
```

# 4. 星評価の表示
詳細を表示させるビューファイルに以下を記述することで、星評価の結果を表示することができます。

```ruby:app/views/posts/show.html.erb
<% @posts.each do |post| %>
~略~
<div class="relative-post-evaluation">
  <span>評価：</span>
  <span id="star-rate-<%= post.id %>"></span>
  <script>
    $('#star-rate-<%= post.id %>').raty({
      size: 36,
      starOff: "<%= asset_path('star-off.png') %>",
      starOn: "<%= asset_path('star-on.png') %>",
      starHalf: "<%= asset_path('star-half.png') %>",
      half: true,   # 星半分表示
      readOnly: true,   # 読み取り専用
      score: <%= post.evaluation %>,   # 星評価の表示
    });
  </script>
  <%= post.evaluation %>
</div>
~略~
<% end %>
```

# 参考リンク
https://qiita.com/yuki_0920/items/a966d9fa2bdb621f805d
https://qiita.com/kitaokeita/items/1e40724c3384507cec13
https://qiita.com/busitora2/items/5b59d1ea9e90c1b016b4
【解決！！】ActiveRecord::RecordNotFound (Couldn't find User without an ID)


#【エラー内容】
![スクリーンショット 2020-11-01 14.16.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584233/59f0b42e-a54e-dc7a-682d-c4e2fd424b14.png)

```ruby:
ActiveRecord::RecordNotFound (Couldn't find User without an ID)
```

#####「IDないで！！」っていうエラー。

〜エラー出るまでの経緯〜
1:ググりながらフォロー機能完成🙋‍♀️
2:フォローボタン``Submit``を``FontAwesome（link_to）``に変更してみよう💡
3:今回のエラー発生💥
4:DBにはちゃんとデータがあることを確認👀
5:機能は動いてるのに、値が渡せてないってこと？？？🤔なんで？???🤢




めちゃくちゃ悩まされた結果、無事に解決したのですが

なんと

#【結論】
###そもそもフォロー機能ができていなかったw


え？？どういうこと？？😂

#【原因】

元々``Submit``でフォロー機能を実装。(この時はきちんと機能が**生きていた**）

``Submit``から``FontAwesome``(``link_to``で``Path``の受け渡し)に変更。(この時点で機能が**お亡くなりになっていた…**チーン😭)

#【解決策】

1.DBテーブルを空にする。
2.フォローアクション実行
3.再度DB確認→データが空＝**結局フォロー機能できていなかったことに気づくw**

```ruby:terminal
mysql> delete from relationships;
Query OK, 1 row affected (0.02 sec)
```

```ruby:terminal
mysql> select *from relationships;
Empty set (0.00 sec)
```


#【スランプに陥った原因】

1.DBでフォローデータがあるか確認。
2.結果：ある。（←実は``Submit``で実行した時のデータだった。)
3.フォロー機能は実装できていると解釈。(**←ここがスランプの元凶！！！**)

```ruby:terminal
mysql> select *from relationships;
+----+---------+-----------+----------------------------+----------------------------+
| id | user_id | follow_id | created_at                 | updated_at                 |
+----+---------+-----------+----------------------------+----------------------------+
| 16 |       1 |         2 | 2020-10-31 07:34:37.912469 | 2020-10-31 07:34:37.912469 |
+----+---------+-----------+----------------------------+----------------------------+
1 row in set (0.01 sec)
```


#【反省】
DBを確認する大切さ…涙ちょちょぎれるくらいに身に染みました…(´；ω；`)

本日参加させていただいた、もくもく会の主催者様が一生懸命このエラーと向き合ってくださり

無事、このように解決いたしました。。心から感謝いたします。。精進します。。。
Python備忘録（アルゴリズム）

Pythonをしっかりと根本面での学習をしなおそうという備忘録。
基本的な問題などに取り組んでいるものを成果として上げていこうと思う。

# フィボナッチ数列
フィボナッチ数列の結果表示プログラムを作成せよ。
ちなみに、公式は、

```math
a_{1} = a_{2} = 1 \\ 
a_{n+2} = a_{n+1} + a_{n}\;\;\;\;\;(n >= 1) 
```

である。


# 公式通りに書いてみる

```python:fibonacci_simple.py 
# フィボナッチ数列の公式から立てると以下のようになる。
# この時、nの数値を出すのに、fibonacci関数を呼び出す回数が多い。
# よって、アルゴリズムは簡単だけど、処理が遅い。
import time 


def fibonacci_simple(n):
    if (n == 1) or (n == 2):
        return 1
    return fibonacci_simple(n - 2) + fibonacci_simple(n - 1)


start = time.time()
print(fibonacci_simple(20))
elapsed_time = time.time() - start
print ("elapsed_time:{0}".format(elapsed_time) + "[sec]")
```
### その結果
```terminal
6765
elapsed_time:0.002089977264404297[sec]
```


# メモ化で高速処理にしてみる

```python:fibonacci_memo.py
# メモ化によって処理を高速化する。
# memoという連想配列に条件配列の値を入れている。
# memo常にあれば、終了。なければ、計算とmemoへの挿入
# 同じ計算をなくすことができる。
import time


memo = {1: 1, 2: 1}
def fibonacci_memo(n):
    if n in memo:
        return memo[n]
    memo[n] = fibonacci_memo(n - 2) + fibonacci_memo(n - 1)
    return memo[n]


start = time.time()
print(fibonacci_memo(20))
elapsed_time = time.time() - start
print ("elapsed_time:{0}".format(elapsed_time) + "[sec]")
```

### その結果
```terminal
6765
elapsed_time:0.0002808570861816406[sec]
```
# ループを使ってみる
```python:fibonacci_loop.py
# ループを使って、求める。
import time


def fibonacci_loop(n):
    fib = [1, 1]
    for i in range(2, n):
        fib.append(fib[i -2] + fib[i - 1])
        
    return fib[n - 1]


start = time.time()
print(fibonacci_loop(20))
elapsed_time = time.time() - start
print ("elapsed_time:{0}".format(elapsed_time) + "[sec]")
```

### その結果
```terminal
6765
elapsed_time:0.00026702880859375[sec]
```

# 比較してみると
単純なものより、重複する計算量を減らすだけで、1/10の処理時間になるのはすごいなぁ。
Gravity - micro:bit用モータードライバ拡張基板の使い方を忘れてしまうのでメモしておく

# 単なるメモです
Gravity - micro:bit用モータードライバ拡張基板を買いました。
https://www.switch-science.com/catalog/4016/

micro:bitから使おうとすると毎回使い方を忘れてしまうので、ここにメモしておきます。

# 使い方
## micro:bit の拡張機能追加ページで、、
[micro:bit](https://makecode.microbit.org/)のプロジェクトページで「高度なブロック」の「拡張機能」をクリック。
![20201101.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449620/dfca1819-518b-a541-52d3-ce495810f218.png)

拡張機能の「検索または、プロジェクトのURLを入力…」に以下のURLを入力
![20201101-2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449620/72875ebe-4579-3680-1899-f41c4a260fd5.png)

## スイッチサイエンスの商品説明から
[スイッチサイエンスの商品説明ページ](https://www.switch-science.com/catalog/4016/)の
[商品wiki](https://wiki.dfrobot.com/Micro_bit_Driver_Expansion_Board_SKU_DFR0548)のページを開く。
さらに Tutorial にある[URL](https://github.com/DFRobot/pxt-motor)をクリックする。

![20201101-3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449620/0d569235-c5e3-fb17-1dd6-27b3817f308b.png)

で、書いてある "URL" のところに書いてある
https://github.com/DFRobot/pxt-motor
↑ このURLをコピー

![20201101-4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449620/4c5409a3-91c9-0eb6-4e7e-797ce0776cb7.png)

これを上で開いてた micro:bit のページに貼り付け。

![20201101-5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449620/2c8508f3-c96b-e56d-8ad6-b2e856bdeabb.png)

拡張機能が出てくるのでこれをクリック。

![20201101-6.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449620/647046f0-77f9-bcd5-90a2-ecf27917782e.png)

これでモータードライバ用のブロックが追加される。
Reactのライフサイクル

#ライフサイクルとは
コンポーネントが配置されて、変更されて、破棄されるまでの流れのこと

#ライフサイクルには３種類ある
上記にほぼ書いてありますが、それぞれこういう意味

* Munting  
コンポーネントの配置
* Updating  
コンポーネントの変更
* Unmounting  
コンポーネントの破棄


#主要メソッド
それぞれのライフサイクルには主要なメソッドがあるそうで、取り合えずこれだけ覚えておきましょう
###Muntingの主要メソッド
* constructor()  
初期化  
stateを初期化するときに多く使っている  
これからコンポーネントの中で使おうとする変数等を最初に定義するとき使う
* render()  
Virtual DOMを描画
JSXを返す
* componetDidMount()  
render()後に一度だけ呼ばれる  
コンポーネントに対してイベントリスナーを設定することが多い  
`addEventListener`をよく使っている

###Updatingの主要メソッド
* render()  
Virtual DOMの再描画  
コンポーネントに変更が加わったときに再度呼ばれる
* componentDidUpdate()  
再render()後に呼ばれる  
条件付きイベントを使うときに使う

###Unmountingの主要メソッド
* componentWillUnmount()  
コンポーネントが破棄される直前、リソースを開放する  
リスナーを解除するために使うこと多い  
`removeEventListener`をよく使っているということ

<br>
動画見てそれ通りにやるとこういう基礎の部分が抜け落ちることがよくあるので、こうやってアウトプットすることはやっぱり大事ですね
この記事書いててやっとこの辺の知識がわかってきました汗
##参考
https://www.youtube.com/watch?v=2jRkPz4-hSo&t=147s
【GitHub】〜 does not appear to be a git repository が出た時の対処法

##エラー内容
GitHubの別のエラーに対処している時に、$ git remote set-url origin にて
remote先の設定をし直した後に、下記のエラーが発生。

```
fatal: 'github.com/####/####' does not appear to be a git repository
```
##対処方法
まずは下記コマンドで設定を確認。

```
$ git config -l 
```

ユーザー名など色々と出てくると思いますが
remote.origin.url の部分を確認。

```
remote.origin.url=github.com/###/###
```

どうやら github.comの後ろにコロンが必要なようなので

```
$ git remote set-url origin github.com:/###/###
```

特に反応は無いので、再push。
これでうまくいくかと思います。
Bootcamp な Windows 10 で、電源抜くと原因不明で落ちる件


MacBook Pro Retina mid 2014 に、
Bootcamp で Windows 10 Pro をインストールした。
電源アダプタをつないでいるときは問題なかったんだけど、
電源を抜くと不明なエラーで落ちてしまう現象が発生。

環境：
Macbook Pro Mid 2014 13インチ
MacOS Catalina
NVMe Sintech 変換コネクタ経由 ADATA SX8100 1TB SSD
Windows 10 Pro パッケージ版（USB キー）

https://discussions.apple.com/thread/7545746

上記を参考に、ようやく問題解決。

原因ははっきりしないけど、
Windows 10 側の電源の設定で、標準の「バランス」から、
「高パフォーマンス」で作ったプランに変更したところ、落ちなくなった。
/usr/bin/env: ‘bash\r’: No such file or directoryが出たときの対処法

# ```docker-compose up```すると以下のエラーが出た

```
/usr/bin/env: ‘bash\r’: No such file or directory
```
## 原因
私の開発環境がWindowsであったため，***改行コードがUnixフォーマットになっていなかった***ことが原因でした．
5人チームでの開発をしていて，MacとWSLの環境の方はこのエラーは出ていなかったのでWindows特有のエラーだと思われます．

##解決策
原因となっている```bash```が記述されている場所を特定し，改行コードをUnix形式に変更する．
以下の手順に従って解決できました．

1. VSCodeの場合は，エディタの右下のほうに```CRLF```と書いてあるので，それをクリック．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486404/18e038ac-8b4a-fd87-941c-6c5c71836e83.png)

2. その後，改行コードを選択できるようになるので，```LF```を選択すれば解決です．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486404/e6b1397b-c4da-f6d4-67b0-624a460519b4.png)

## おまけ
改行コードはOSによって以下のように異なるそうです．

| OS | コード |
| ---- | ---- |
| UNIX | LF |
| Win | CRLF |
| Mac | CR |

# 参考
[改行コードについて｜とほほのWWW入門](http://www.tohoho-web.com/wwwxx011.htm)
【param is missing or the value is empty:】を個人的にまとめた。

##背景
DM機能の作成途中に、遭遇
Entryはチャットルームに入るユーザーを管理するためのテーブル
Roomはチャットを行うための中間テーブル

##エラー内容
![スクリーンショット 2020-10-25 19.00.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/724449/152754ad-572b-3b62-4da0-8c73f7c0a395.png)

entryにparamが存在しない、もしくはparamの値が空であることを指す。

##解決した対応
①ストロングパラメータのrequireメソッドを削除
②permitメソッドのみ記載

##ストロングパラメータとは
フォームからデータを送信する際に、
「マスアサインメント脆弱性」と呼ばれるセキュリティ上の問題がある。
例えばデータ送信時のタイミングで不正リクエストが行われた場合、
そのデータが想定されるものと異なる恐れがある。

➡︎この脆弱性を防ぐための仕組みのこと。
各メソッドにあらかじめ登録や更新を許可するカラム名を指定することで、
もし許可外のカラムデータが送られてきた場合、判別して登録や更新アクションの対象から除外してくれる。

###requireメソッド
params内の特定キーに紐付く値のみを抽出する。
引数には取り出したい値のキー名を指定しなければならない。

###permitメソッド
許可されたカラムの値のみを取得する。
引数にはそのためのカラム名を指定しなければならない。
未許可のカラムがparams内に存在する場合、そのカラムデータは未取得扱いになり無視される。

###mergeメソッド
ハッシュ（キーとバリューを持つ配列のこと）同士を結合する。
受け取ったparamsには含まれていないが、別に一緒に含めたい値がある場合など。

###privateメソッド
各メソッドの呼び出しに制限をかける。
そのため、コントローラーからアクションとして認識されなくすることができる。

##原因
requireメソッドが上手く機能していなかったように思われる。
RoomコントローラでEntryテーブルに保存されたデータを呼び出したかったのだが、
requireメソッドで指定すると、どうしてか動いてくれなかった。
重複していると認識されてしまったのだろうか。

##参考記事
https://stackoverflow.com/questions/47391168/param-is-missing-or-the-value-is-empty-in-nested-resource-method
https://railsguides.jp/action_controller_overview.html#strong-parameters
https://qiita.com/kazuki13070311/items/cdd4917af204e00de001
https://qiita.com/takuyama/items/d0f1aa073a8e2e7212f2
https://qiita.com/Takka_Log/items/32dae78d7e3892e7b051
https://qiita.com/ozackiee/items/f100fd51f4839b3fdca8
https://qiita.com/akiupdate/items/514b107090c16a2e1b47
https://qiita.com/zenfumi/items/694edc863527f91c8976
[Jupyter Notebook]Markdown の数式に数式番号を振って、参照する

# はじめに

Jupyter NotebookのMarkdownで数式番号を振って、参照する方法を記します。数式の書き方は、よく忘れるので、備忘録です。qiitaの数式入力ではうまくいかないのであしからず。

# 数式番号の振り方

調べる限り、Jupyter NotebookのMarkdownで、数式番号を自動で振る機能はないようです。\labelと\tagを使って数式番号を振ります。参照は、文中の`$(\ref{label_symbol})$`で\labelの記号を記入します。注意点は、同じコードブロック内でしか機能しません。

## $$数式$$を使う

```
$$
\frac{\partial u}{\partial t} = \alpha \nabla ^2 u \label{a}\tag{1}
$$
$(\ref{a})$は熱拡散方程式です。
```
![numbering1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/585573/44e9dede-81e6-9581-2602-a1c1f814dbe3.png)


## \begin{equation}数式\end{equation}を使う

```
\begin{equation}
\frac{\partial u}{\partial t} = \alpha \nabla ^2 u \label{b}\tag{2}
\end{equation}
$(\ref{b})$も熱拡散方程式です。
```
![numbering2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/585573/15183e17-aa26-80e5-7b7d-31a4670088a8.png)