OmniAICreator/Qiita-1.07M huggingface dataset:
僕の質問テンプレート (流用可)

# 日本語版
日本語のサイトのQiitaなどで使っているテンプレートです。
参考コードのところはなるべくかいけつに参考になりそうな部分のコードを抜粋して情報漏えいを避ける形を取りましょう。

**また質問タイトルはなるべくひと目でどのような質問かわかるものにしましょう**
極端なものだと以下のような質問のタイトルが挙げられます。

悪い例 : pandasの使いかた
良い例 : pandasで集計した表をcsvファイルとして出力する方法は？

この例のように質問を見ただけでどのような状況なのか、何を解決してほしいのかを明瞭にするような質問のタイトルを付けましょう。

いかから文章構成 (Markup記法として記述しています)

```
## 概要
{学習段階}のものです。

// どのような作業をしたのかの作業手順と目標を詳細に伝える
{}をしたいと考えているのですが、以下のエラーが発生します。


エラーコード



// 実際に添付すると長くなるので
エラーが発生した該当のコードはこちらです。


↑問題を再現できる最小限のコードをコード形式で記入


//　または、publicのgithubの場合、該当の作業ブランチのURLを添付する
// 会社のものだと情報漏えいになる
該当のエラーが発生したgithubのブランチはこちらから確認できます。
{github 作業ブランチのurl}


// 具体的に書く
しかし{}という動作ができません。

//　試したことを記述する (わかるようにコードも入れると良い)
いままで以下のことを試しましたがうまく機能しませんでした。

// もしうまく試してことを記述できないようなら参考にした記事やstackoverflowなどの情報を入れる
以下の記事内容はすでに試してあります。
・{}
・{}

どうか問題の解決方法を知っている方、ご教授のほどよろしくお願いいたします。

## 環境
// 共通の環境
端末：MacBook Pro (15-inch, 2018)
OS：macOS Catalina (10.15.7)
シェル：bash

// 言語とDBの情報
Ruby on rails ： 5.2.3
MySQL　： 5.7


```

# 英語版
基本的には日本語版と同じです。
しかし、stackoverflowを見てると日本語版に比べてコンパクトに纏まっているようだったので日本語版のような冗長な質問は避けるべきです。


```
## Overview

// 学習段階を記入
I am in the {learning phase}.

{}, and I am getting the following error.


Error code


// エラーを再現できる最小限のコードを記述
Here is the relevant code where the error occurred.

// 想定していた結果と実際の結果を記述
But I can't get the behavior {}.

// 試したことを記述
I've tried the following, but it didn't work.
・I try
・I try

If you know how to fix the problem, please let me know. Thank you for reading my question.

## environment
// Common environment
Device: MacBook Pro (15-inch, 2018)
OS: macOS Catalina (10.15.7)
Shell: bash

// Language & DB information
Ruby on rails ： 5.2.3
MySQL　： 5.7

```

以上をうまく改良して自分なりの質問テンプレートを作成してみて下さい。
テンプレートをAlfredのsnippetsに登録するとコマンドからテンプレートをペーストすることが出来るので便利です。

## 参考記事

・[良い質問をする技術 〜質問テンプレートのススメ〜](https://www.youtube.com/watch?v=P6yRjOyM4jU)

・[質問は恥ではないし役に立つ](https://qiita.com/seki_uk/items/4001423b3cd3db0dada7)

・[良い質問をするは？](https://ja.stackoverflow.com/help/how-to-ask)
LaravelのSQLを開発環境時のみログ出力する

#はじめに

開発用ライブラリの『Laravel Debugbar』では、
APIやバッチ処理実行時のSQLが確認できないため、
開発時のみ発行しているSQLをログファイルに出力するようにする。

#環境
PHP 7.4.9
Laravel Framework 8.25.0

#SQLログ出力設定

```app\Providers\AppServiceProvider.php
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        //
        // 開発環境以外の場合、SQLログを出力
        if (!app()->isProduction()) {
            $this->dataBaseQuery();
        }
    }

    private function dataBaseQuery()
    {
        \DB::listen(function ($query): void {
            $sql = $query->sql;
    
            foreach ($query->bindings as $binding) {
                if (is_string($binding)) {
                    $binding = "'{$binding}'";
                } elseif (is_bool($binding)) {
                    $binding = $binding ? '1' : '0';
                } elseif (is_int($binding)) {
                    $binding = (string) $binding;
                } elseif ($binding === null) {
                    $binding = 'NULL';
                } elseif ($binding instanceof Carbon) {
                    $binding = "'{$binding->toDateTimeString()}'";
                } elseif ($binding instanceof DateTime) {
                    $binding = "'{$binding->format('Y-m-d H:i:s')}'";
                }
    
                $sql = preg_replace('/\\?/', $binding, $sql, 1);
            }
    
            // SQL・queryTimeログ出力
            // \Log::debug('SQL', ['sql' => $sql, 'time' => "{$query->time} ms"]);
            // SQLログ出力
            \Log::debug($sql);
        });
    
        \Event::listen(TransactionBeginning::class, function (TransactionBeginning $event): void {
            \Log::debug('START TRANSACTION');
        });
    
        \Event::listen(TransactionCommitted::class, function (TransactionCommitted $event): void {
            \Log::debug('COMMIT');
        });
    
        \Event::listen(TransactionRolledBack::class, function (TransactionRolledBack $event): void {
            \Log::debug('ROLLBACK');
        });
    }
```

```storage\logs\laravel.log
[2021-01-30 23:02:43] local.DEBUG: SELECT * FROM users
```

```.env
APP_ENV=local
```
本番環境は『APP_ENV=production』に変更するとSQLは出力されません。

#参考記事

Laravel SQLの実行クエリログを出力する
https://qiita.com/ucan-lab/items/753cb9d3e4ceeb245341
階調数の少ないグラデーションを簡単に作る Sass 関数

![a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248832/f4a14865-5101-2315-8eb1-7e9638e526a5.png)
階調数の少ないグラデーション、つまり「切れ目」のあるグラデーションを作るには次のようなCSSを書きますが、

```scss
background-image: linear-gradient(to bottom, #ff0000 0% 25%, #ffff00 25% 50%, #00ff00 50% 75%, #00ffff 75% 100%);
```

カラーストップの記述が少し面倒ですよね。というわけで関数にしました。

```scss
@function lowtone ($colors) {
  $results: null;
  $length: length($colors);
  $step: 100 / $length;
  @for $i from 1 through $length {
    $results: join($results, unquote(nth($colors, $i) + " " + ($step * ($i - 1)) + "% " + ($step * $i) + "%"), "comma");
  }
  @return $results;
}
```

---
_追記：上記のコードは「カラーストップは一度に複数書ける」ことをコメント欄で教えていただいた後に修正したものです。修正前はこちら。_

```scss
background-image: linear-gradient(to bottom, #ff0000 0%, #ff0000 25%, #ffff00 25%, #ffff00 50%, #00ff00 50%, #00ff00 75%, #00ffff 75%, #00ffff 100%);
```

こんなもの書いてられませんよね。というわけで関数にしました。

```scss
@function lowtone ($colors) {
  $results: null;
  $length: length($colors);
  $step: 100 / $length;
  @for $i from 1 through $length {
    $results: join($results, unquote(nth($colors, $i) + " " + ($step * ($i - 1)) + "%, " + nth($colors, $i) + " " + ($step * $i) + "%"), "comma");
  }
  @return $results;
}
```

---

使い方は以下の通り。カンマは付けちゃダメ。

```scss
background-image: linear-gradient(to bottom, lowtone(#ff0000 #ffff00 #00ff00 #00ffff));
```

もしかしたら既出かもしれませんが…ところでこういう表現技法は何て呼ぶんでしょうね？
【Java】AtCoderのABC-190に参加しました。

こんばんは。

2021/1/30に、AtCoderのABC-190に参加しました。
レートは以下の通りとなっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402487/c6ffe908-010d-44ba-c99d-8de96a6344e2.png)


https://atcoder.jp/users/ishikawaryou

今週もC問題が解けませんでした。
ぐやじいい・・。
レートは51→71に更新！ですが、今は参加回数が少なく本来のレートに近づいているだけのようです。そのうち横ばいになるんですね。
A問題でちょっと苦戦しまして、10分程度。今回はB問題の方が簡単だった気がします。

###A問題

高橋くんがA個、青木くんがB個のアメを持っていて、Cが0であれば高橋くんが先攻、1なら青木君が先攻。
1個ずつアメを交互に食べて、先になくなった方が負け。
「先攻の個数>=後攻の個数+1だったら先攻の勝ち」という法則を見つけてコーディングしました。
不等号の付け方でちょっとね・・。
あと、Cをint型で定義したのに、C=='0'といったchar型の判定をしていたことに気付くのに3分ほどかかりました。
コンパイルエラーもないし、一定正解になってしまうので、「あれ？」となりまして・・。

```java
import java.util.Scanner;
import java.util.ArrayList;

public class Main{
public static void main(String args[]){
  Scanner sc = new Scanner(System.in);
  int a = sc.nextInt();
  int b = sc.nextInt();
  int c = sc.nextInt();
  if(c==0){
    if(a>=b+1){
    //System.out.println("t" + a + " " + b+1);
    System.out.println("Takahashi");
    }else{
    //System.out.println("A");
    System.out.println("Aoki");
    }
  }else{
    if(b>=a+1){
        System.out.println("Aoki");
    }else{
        System.out.println("Takahashi");
    }
  }

}
}
```


###B問題
N 種類の呪文を使うことができる。 
i 番目の呪文はX秒,威力はY。
呪文にS秒以上かかるもの、威力がD以下のものでは倒せない。

こちらの方がスッと入ってきまして、すぐ解けました。

```java
import java.util.Scanner;
import java.util.ArrayList;

public class Main{
public static void main(String args[]){
  Scanner sc = new Scanner(System.in);
  int n = sc.nextInt();
  int s = sc.nextInt();
  int d = sc.nextInt();
  int x[] = new int[n];
  int y[] = new int[n];
  char ok = '0';
  for(int i=0;i<n;i++){
    x[i] = sc.nextInt();
    y[i] = sc.nextInt();
    if((x[i]<s)&&(y[i]>d)){
      ok='1';
      i=n;
    }
  }

if(ok=='1'){
System.out.println("Yes");
}else{
System.out.println("No");
}

  
}
}
```

###C問題
＊不正解のためソースは割愛します。
「どちらかを選択できる」という条件を、どうロジックに落とすか苦慮しました。

###感想
C問題が自分には大きな壁なので練習します。
今回は家の用事で中断がありましたが、B問題まで15分～20分で解けるので多少の中断は何とかなりそうなので毎週参加できます。
今の実力から「あと3回でレート150」を目標にしてみることにしました。

これからもコツコツ取り組んで、茶色を目指したいと思います！
同じく灰色レベルで頑張っている方、お互い頑張りましょう！
Active Storage

#Active Storage
画像ファイルアップロード機能を簡単に実装できるGemです。
元々はインストールが必要なGemでしたが、Railsに統合されました。


#ImageMagick

コマンドラインから画像に処理を加えることができるツールです。
処理としては、画像の作成やサイズ変更、保存形式の変更などがあります。
ImageMagickはGemではなくソフトウェアです。
そのため、Homebrewからインストールします。
GemではないImageMagickをRubyやRailsで扱うには、MiniMagickというGemが必要となります。

#MiniMagick

ImageMagickの機能をRubyで扱えるようにしてくれるGemです。RailsでImageMagickを扱うために必要となります。
MiniMagickによって、ImageMagickの機能がRailsで使用できるようになりますが、画像サイズの変更には、もう1つImageProcessingというGemを追加する必要があります。

#ImageProcessing

MiniMagickでは提供できない、画像サイズを調整する機能を提供するGemです。

#手順


```
% brew install imagemagick
```

```
gem 'mini_magick'
gem 'image_processing', '~> 1.2'
```

```
% bundle install
```

```
% rails s
```

```
% rails active_storage:install
```

```
% rails db:migrate
```

以下のテーブルが作成されていれば成功です。
[![Image from Gyazo](https://i.gyazo.com/5befb9fefc1b8b40ce60a6dc68557fb6.png)](https://gyazo.com/5befb9fefc1b8b40ce60a6dc68557fb6)


#Active Storage紐付け
**has_one_attachedメソッド**

各レコードとファイルを1対1の関係で紐づけるメソッドです。
has_one_attachedメソッドを記述したモデルの各レコードは、それぞれ1つのファイルを添付できる

```message.rb
class モデル < ApplicationRecord
  has_one_attached :ファイル名
end
```
has_one_attached :imageなど

**permitメソッド**
Controllerで許可する。

```messages_controller.rb

  private

  def message_params

    params.require(:message).permit(:content, :image).merge(user_id: current_user.id)

  end
```

**attached?メソッド**

レコードにファイルが添付されているかどうかで、trueかfalseを返すメソッド

```
モデル.ファイル名.attached?
```

```
<%= image_tag message.image, class: 'message-image' if message.image.attached? %>
```


**variantメソッド**

Active Storageを導入している場合に使用可能なメソッド

ファイルの表示サイズを指定できる

```
モデル.ファイル名.variant(resize: '幅x高さ')
```

```
 <%= image_tag message.image.variant(resize: '500x500'), class: 'message-image' if　message.image.attached? %>
```
udemyによるAWSの勉強③ - AWS S3とdjangoの連携

#◆udemyの教材
本記事を作成するにあたって、参考にしたudemyの教材は以下のものになります。

これだけでOK！ AWS 認定ソリューションアーキテクト – アソシエイト試験突破講座（SAA-C02試験対応版）
https://www.udemy.com/share/101WKk/

#◆本記事の内容
udemyにてAWS S3がどういうものかを理解しました。
そこで、簡単なWebサイトを作り、AWS S3と連携させます。

#◆備忘録
以下のサイトを参考に作業を行いました。
https://simpleisbetterthancomplex.com/tutorial/2017/08/01/how-to-setup-amazon-s3-in-a-django-project.html
https://blog.narito.ninja/detail/27

#◆AWS S3の準備
S3のバケットを作成し、公開としました。
以下、参照
https://simpleisbetterthancomplex.com/tutorial/2017/08/01/how-to-setup-amazon-s3-in-a-django-project.html

#◆djangoの準備

以下を実行します。

```
pip install django-storages
pip install boto3
```

#◆設定ファイルの変更

setting.pyに追記する。

```
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    ~~~~
    'storages',
]
```

settings.pyに以下を追記。

```
#◆共通の設定
AWS_ACCESS_KEY_ID = 'メモしたアクセスキー'
AWS_SECRET_ACCESS_KEY = 'メモしたシークレットアクセスキー'
AWS_STORAGE_BUCKET_NAME = 'narito-blog'
AWS_S3_CUSTOM_DOMAIN = '%s.s3.amazonaws.com' % AWS_STORAGE_BUCKET_NAME
AWS_S3_OBJECT_PARAMETERS = {
    'CacheControl': 'max-age=86400',  # 1日はそのキャッシュを使う
}


# ◆静的ファイルの設定
AWS_LOCATION = 'static'
STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
STATIC_URL = "https://%s/%s/" % (AWS_S3_CUSTOM_DOMAIN, AWS_LOCATION)


# ◆メディアファイルの設定。
DEFAULT_FILE_STORAGE = '[プロジェクト名].backends.MediaStorage'
```

上記の設定にした理由は以下の理由です。

* /staticと/mediaを別々のURLとして配信するため
* 静的ファイルとメディアファイルで同名ファイルがあった時に、挙動を変えるため

#◆storageクラスを作る

settings.pyと同じ階層にbackends.pyを作る。

#◆時刻のずれ
AWSの時刻とDockerコンテナ内の時刻がずれており、静的ファイルのやりとりができませんでした。
そこで以下コマンドを実行し、Dockerコンテナ内の時刻を正常に戻しました。

```
# hwclock -s
# date
Sat Jan 30 21:29:46 JST 2021
```

#◆最終的な階層

```
app/
 |-- app/
 |    |-- static/
 |    |    |-- css/
 |    |    |    +-- app.css
 |    |    +-- img/
 |    |         +-- thumbs-up.png
 |    |-- templates/
 |    |    +-- home.html
 |    |-- __init__.py
 |    |-- settings.py
 |    |-- urls.py
 |    +-- wsgi.py
 +-- manage.py
```

#◆htmlファイル

```
{% load static%}
<!DOCTYPE html>

<html>
<head>
  <meta charset="utf-8">
  <title>S3 Example Static only</title>
  <link rel="stylesheet" type="text/css" href="{% 'css/app.css' %}"
</head>
<body>
  <header>
    <h1>S3 Example Static Only</h1>
  </header>
  <main>
    <img src="{% static 'img/thumbs-up.png' %}">
    <h2>It's Working.</h2>
  </main>
  <footer>
  </footer>
</body>
</html>
```

#◆静的ファイルをAWS S3にアップロード

以下を実行することでローカルにあった静的ファイルをAWS S3にアップロードします。

```
python manage.py collectstatic
```

静的ファイルが正常にアップロードされています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/764778/6a3a50e3-c75d-852d-b92a-81c05d30ce76.png)


#◆Webブラウザでの表示

AWS S3上の画像を表示、cssが適用されていることを確認出来ました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/764778/8d619664-a5cb-e11e-87c4-5fe0cf72d8ad.png)
ArchLinuxでパッケージの更新ができなくなった時の対処

# 結論

```
sudo pacman -S archlinux-keyring
sudo pacman -Syu
```

# 症状

記事書く前に消してしまったので正確な文章は定かではありませんが、
`pacman —sync —refresh —sysupgrade` したところ
散々時間かかった挙句

```
error: pkgconf: signature from "Johannes Löthberg <johannes@kyriasis.com>" is unknown trust
```

と表示され、`No Package upgrade`的なことを言われました

`pacman-key —refresh`すると良いと見かけたのでしてみましたが

```
sudo pacman-key --refresh
gpg: refreshing 124 keys from hkps://hkps.pool.sks-keyservers.net
gpg: keyserver refresh failed: General error
==> ERROR: A specified local key could not be updated from a keyserver.
```

とこれまたエラー

`pacman -S archlinux-keyring` をした後治ったと書いてあったので、こちらを実行しました
この後に再度 `pacman-key —refresh`しても同様にエラーでしたが、
`sudo pacman —sync —refresh —sysupgrade`すると今度は正常にアップグレードできました

# 参考
* https://bugs.archlinux.org/task/69006
* https://bbs.archlinux.org/viewtopic.php?id=226770
vimにて文字列ブロックを右にペーストする

# Summary
  
  vimにて文字列ブロックを右にペーストする

## したいこと

### before

```fsharp
分割前
--------------------------------
{
  支払日   = 2021/01/30 0:00:00
  支払者   = "callmekohei"
  カテゴリ = "おやつ"
  購入品   = "牧のうどん肉入り"
  価格     = 350
}


分割後
--------------------------------
{
  支払日 = 2021/01/30 0:00:00
  支払者 = "callmekohei"
  Category = {
    カテゴリ = "おやつ"
    購入品 = "牧のうどん肉入り"
    価格 = 350
  }
}
```

### after

```fsharp
 分割前                             分割後
 --------------------------------   --------------------------------
 {                                  {
   支払日   = 2021/01/30 0:00:00      支払日 = 2021/01/30 0:00:00
   支払者   = "callmekohei"           支払者 = "callmekohei"
   カテゴリ = "おやつ"                Category = {
   購入品   = "牧のうどん肉入り"        カテゴリ = "おやつ"
   価格     = 350                       購入品 = "牧のうどん肉入り"
 }                                      価格 = 350
                                      }
                                    }
```

## 方法

ポイント：左文字列ブロック、右文字列ブロックともに矩形にする

```

1. 左側の文字列を矩形にする（行末にスペースを詰め込む）

set virtualedit=all
visual mode で行末から選択して矩形選択
カット
ペースト

2. 右側の文字列を矩形にする

3. ペースト
```

## see also

[Neovimでclipboardにunnamedを設定してるとペーストした際にレイアウトが崩れるのを回避する方法](https://qiita.com/callmekohei/items/ac62c10e9f3396e1f422)
[行末を適切な数のスペースで埋めて行の幅を整える](https://qiita.com/ka_/items/8e7a5e681db857b2ee26#comment-8d7a434b595f023cd12c)
方言翻訳機制作大作戦 その1

前回の続きです。
[前回の記事](https://qiita.com/Bandolu/items/0173bdf97abb94a4d813)

# 結論
及第点としました。理由は以下。

* 「ない」が「にゃ」「ねぇ」に変換されている（「否定」を学習できた）
* 「かたつむり」が「まいまい」に置き換えられている（単語自体が変化したものも学習できている）
* 推論で使う単語に未知語が含まれると文章全体が`<unk>`となる

課題は山積しているので、調査を続けます。

## 結果
+ 既知語のみ
input :「行ったなあ」
![既知語のみ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315665/43bed6cb-4f34-c6c9-b4c4-58cc9139d330.png)

+ 未知語含む
input :「中村ではない」
今回は「中村」を含む文章を学習させていない。
![output13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315665/dfaae61f-4ed5-7355-5b43-567a76ebc0af.png)

やっぱり`<unk>`は機能しないじゃないか！

# 改善点
カタカナで記載された方言訳を**擬似的に**平仮名に置き換えました。
~~本当は鼻濁音は「カ゜」としたいのですが、それをすると前回の二の舞に略~~
（標準語をカタカナに開く作業をやめました）


# やったこと
1. 方言アライメントを用意する（ネットサーフィンしまくりました）
1. アライメントをtsvに変換する(リポジトリ内 Hiraki_Sudahi.ipynbで実行可能です)
2. カタカナで記載された方言訳を**擬似的に**平仮名に置き換える**（変更点）**
3. 参考ソースコードを用いてアライメントをベクトル化する
3. Tensorflowを用いて学習・予測する

# 課題
方言訳に余計な文字がくっつく-> アライメント（コーパス）が足りない？
推論で使う単語に未知語が含まれると文章全体が`<unk>`となる -> これもコーパス不足？
（因みに、「中村」をコーパスに入っていた「山田」に変えると上手く動きます）

# おわりに
コーパスを増殖させる方法を編み出したら、また記事を書きます。

## ソースコード
[リポジトリ(github)](https://github.com/Bandolu/Hogen)
mdb5 datepicker 「(index):187 Uncaught TypeError: mdb.Datepicker is not a constructor ]というエラーが出た。


#エラー経緯とエラー内容
１．[Bootstrap 5 & Material Design 2.0](https://mdbootstrap.com/docs/standard/)のPro版（MDB PRO ESSENTIAL € 17/month ）を購入。
２．左上のメニューボタン > Getting started > Installation > Step 1 の「MDB 5 DOWNLOAD」ボタンをクリックし、「MDB5-STANDARD-UI-KIT-Free-3.2.0.zip」をダウンロード。
３．ダウンロードした「MDB5-STANDARD-UI-KIT-Free-3.2.0.zip」を解凍。
４．左上のメニューボタン > Forms > Datepicker の Basic example のコードをコピーして、index.htmlに張り付け。
５．ブラウザで確認。
６．下記エラーが出力された。
`(index):187 Uncaught TypeError: mdb.Datepicker is not a constructor`

pro版を購入したから動かせるはずなのになんで！？ってなって解決までに手こずりました。(笑)

#エラー原因
pro版を購入していたのに、free版をダウンロードして使っていたから(;'∀') 

#解決方法
１．右上のアカウントボタン > Orders > 画面中央の青色のボタンをクリック
　→「MDB5-STANDARD-UI-KIT-PRO-ESSENTIAL.zip」みたいな名前です。
２．ダウンロードしたzipファイルを解凍。
３．左上のメニューボタン > Forms > Datepicker の Basic example のコードをコピーして、index.htmlに張り付け。
４．ブラウザで確認。
５．下記のように「Select a date」のinputタグとカレンダーiconが表示されて、iconをクリックしたら、カレンダーが表示されればOK。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/640981/01b2a654-29b0-692a-d545-417e3493b19b.png" width=400px>

#感想
MDB 5 めちゃ便利。開発が楽に進みます！
お金はかかりますが、かかった分のもとはすぐに取れますね！
↑こんな感じのカレンダーセレクト画面を用意するとなると、それなりに工数かかりますし、なにしろ、メンテナンスがしっかりされているので、安心感があります！
ぜひ今後も MDB 5 を使ってみて、感想を投稿していこうと思います。
React 使用したことのあるライブラリ

#react-twitter-widgets
https://github.com/andrewsuzuki/react-twitter-widgets
twitterのスクレイピングやシェアボタンの作成で使用。<a href="https://github.com/saurabhnemade/react-twitter-embed">react-twitter-embed</a>の方はドキュメントが充実しているがtypescriptで使えなさそうだったため使用を断念。
実際に書いたコード

```tsx:sample.tsx
<Tweet tweetId="表示させたいツイートのID" />
<Timeline
  dataSource={{
    sourceType: 'profile',
    screenName: '表示させたいユーザーの名前(@から始まる方)',
  }}
  options={{
    height: '400',
  }}
/>
<Share
  url="シェアツイートに載せたいurl"
  options={{ text: 'シェアツイートに載せたい文章', via: 'シェアツイートをするユーザーの名前' }}
/>
```


#react-flip-move
アニメーションをつけるためのライブラリ。
https://github.com/joshwcomeau/react-flip-move


#dayjs
日付の取得や操作を簡単に行えるライブラリ。
https://day.js.org/docs/en/display/format

#material-ui-pickers
日付選択の立地なUIを簡単に作成出来る。
https://material-ui-pickers.dev/

DatePickerを使用した。
https://material-ui-pickers.dev/demo/datepicker
Pythonで正規表現を使って\を含む文字列に置換したいときの挙動の調査

`Python`の正規表現モジュール`re`の`re.sub()`を使って、検索した文字列を`\`(エスケープ、バックスラッシュ、円マーク)を含む文字列に置換したいとき、予期しない挙動やエラーを起こすことがあります。その備忘録を記します。


通常の文字列操作、例えば`+`を使って文字列を連結する際などは、文字列内の`\`は別の`\`でエスケープさえしておけば、特に予期しない挙動は起こしません。

```python
test_str="\\a"+"_ccc"
print(test_str)# \a_ccc
```

しかし、`re.sub()`は`re.sub(検索したい文字列,置換後の文字列,元の文字列)`と使いますが、この「置換後の文字列」内の`\`が`re.sub`を実行した時点でエスケープとして解釈されてしまいます。これについて挙動を詳しく調べてみます。  

## 挙動の調査

```python
old_str = "bbb_ccc"
```

この`bbb`を`\`を含む文字列に置換することに考えます。

```python
new_str = re.sub("bbb","\\a",old_str)
```   
としたときの`\\a`の`\`を2つ、4つ、6つ、8つとしたときの挙動を見てみます。また、最後にraw文字列を用いた場合についても調べます。

### 2つの場合

```python
new_str = re.sub("bbb","\\a",old_str)
print(new_str)
```   
で`□_ccc`と表示されます。挙動としては次のようになります。

1. `re.sub`で最初の`\`が2番めの`\`のエスケープに使われる、結果的に`\a`が残る
2. `\a`が生成された瞬間、Pythonは`\a`を制御コードとして解釈し、変換し`\x07`となる。
3.  `print`で`\x07`が`□`と表示される

この際、変換後の文字列を`\\a`ではなく`\\c`とする、つまり

```python
new_str = re.sub("bbb","\\c",old_str)
```   
とすると、は`\c`に対応する制御コードがないので2の段階、つまり`re.sub`を実行した段階で`bad escape`エラーとなります。

制御コードとは`\n`が改行コードに該当するなど、文字ではなく動作を指定するものです。`\a`はビープ音の制御コードに該当するらしいです。

>制御文字（せいぎょもじ、英: control character）とは、文字コードの規格で定義される文字のうち、ディスプレイ・プリンター・通信装置などに対して、特別な動作（制御）をさせるために使う文字である。

[制御文字 (フリー百科事典『ウィキペディア（Wikipedia）』 2020年12月6日 (日) 23:14 UTC)](https://ja.wikipedia.org/wiki/%E5%88%B6%E5%BE%A1%E6%96%87%E5%AD%97)

### 4つの場合

```python 
new_str = re.sub("bbb","\\\\a",old_str)
print(new_str)
```
だと`\a_ccc`と表示されます
 
1. `re.sub`で最初の`\`が2番めの`\`のエスケープに使われ、3番めの`\`が4番めの`\`のエスケープに使われ、結果的に`\\a`が残る
2. `print`で`\\a`の最初の`\`が2番めの`\`のエスケープに使われ、`\a`と表示される

### 6つの場合

```python 
new_str = re.sub("bbb","\\\\\\a",old_str)
print(new_str)
```
だと`\□_ccc`と表示されます。

1. `re.sub`で最初の`\`が2番めの`\`のエスケープに使われ、3番めの`\`が4番めの`\`のエスケープに使われ…と3回エスケープが起こり結果的に`\\\a`が残る
2. `\\\a`が生成された瞬間、Pythonは最初の`\`を2番めの`\`のエスケープとして解釈しそのままにし、残った`\a`を制御コードとして解釈し、`\x07`と変換する。結果的に`\\\x07`となる。
3. `print`で`\\\x07`の最初の`\`が2番めの`\`のエスケープに使われ、`\x07`が`□`と表示され、結果的に`\□`と表示される  

この際も、変換後の文字列を`\\\\\\a`ではなく`\\\\\\c`とすると`\c`に対応する制御コードがないので`re.sub`を実行した段階で`bad escape`エラーが発生します。

### 8つの場合  
```python 
new_str = re.sub("bbb","\\\\\\\\a",old_str)
print(new_str)
```
だと`\\a_ccc`と表示されます。  

1. `re.sub`で最初の`\`が2番めの`\`のエスケープに使われ、3番めの`\`が4番めの`\`のエスケープに使われ…と4回エスケープが起こり結果的に`\\\\a`が残る
2. `print`で`\\\\a`の最初の`\`が2番めの`\`のエスケープに使われ…と2回エスケープが起こり、`\\a`と表示される

### raw文字列

raw文字列さえ使っておけばエラーが起こらないと思うかもしれません。raw文字列は`"..."`や`'...'`の前に`r`をつけることで文字列内の`\`をエスケープできるものです。たとえば

```python
test_str=r"\a"
```
は

```python
test_str="\\a"
```
と同じことです。つまり単純に文字列内の`\`が二倍になると考えればいいわけです。よって`\`が3つの`"\\\a"`の前に`r`をつけた`r"\\\a"`は、`r`をつけない場合の`\`が6つの場合と同じです。つまり

```python
new_str = re.sub("bbb",r"\\\a",old_str)
print(new_str)
```   
は`\□_ccc`と表示されます。当然、変換後の文字列を`r"\\\c"`とすれば先程述べたのと同じ理由で`bad escape`エラーが発生します。raw文字列さえ使っておけばエラーが起こらない、ということではないわけですね。

ちなみに文字列の変数をraw文字列に変換したい場合は組み込み関数の`repr()`を使えばいいです。

```python
test_str="\\a"
raw_str=repr(test_str)
```
このとき`raw_str`には、`'\\\\a'`と先頭と末尾に`'`が付け加わったraw文字列が保存されているので、スライスを使って

```python
raw_str[1:-1]
```
とすればraw文字列が取り出せます。

## 感想

2つの場合、4つの場合の挙動はなんとなく解っていたのですが、6つと8つになるとちょっと追いつかなくなりました。一つ一つ挙動を追って行けばわからないこともないですね。
Group Normalizationについて解説


## はじめに
Group Normalizationについて調べていたので、まとめました。

## Group Normalizationとは

Group Normalization（GN）は、入力のチャネルをより小さなサブグループに分割し、それらの平均と分散に基づいてこれらの値を正規化します。 GNは単一の例で機能するため、この手法はバッチサイズに依存しません。
>https://www.tensorflow.org/addons/tutorials/layers_normalizations


## 正規化の種類

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/837628/97292e9b-5cba-3773-a552-83a0557f1787.png)


各サブプロットは、入力テンソルを示しています。Nはバッチ軸、Cはチャネル軸、（H、W）は空間軸（画像の高さと幅など）です。青のピクセルは、これらのピクセルの値を集計することによって計算された、同じ平均と分散によって正規化されます。
>https://www.tensorflow.org/addons/tutorials/layers_normalizations


## Group Normを導入すると

### ResNet-50
<img width="400" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/837628/ebb6b0a8-42b4-a5d3-6744-daee300b59f0.png">

ImageNetの分類誤差とバッチサイズの比較の図。これは、ImageNet訓練セットで訓練されたResNet-50モデルで、検証セットで評価されています。Group Normはバッチサイズに依存しないので、よりよいパフォーマンスが期待できます。



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/837628/c1697633-3c69-2801-7eba-13c7887025e8.png)

ResNet-50での検証誤差を示した図。バッチサイズを変えると、BNは誤差にブレがあるが、GNはほとんど同じだということが分かる。



<img width="400" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/837628/d5a845ae-b912-edf6-c32a-9dba65b0248f.png">


一見良いように見えるが、精度を比較してみると、バッチサイズを低くするにつれてGNの精度が低くなることが分かる。特にバッチサイズ２のときには（-10.6）とかなり低くなっている。
これらの結果は、バッチ平均と分散の推定が過度に確率的で不正確になり得ることを示している。

### VGG-16


正規化を行わない場合と比較してGN/BNを検討するために，正規化層がなくても健全に学習できるVGG-16を考える。各畳み込み層の直後にBNまたはGNを適用する．


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/837628/fb573b12-efd8-36a3-89b8-956c69079070.png)


VGG-16では、GNはBNよりも0.4%優れています。これは、VGG-16ではBNの正則化効果の恩恵が少なく、学習誤差の少ないGNの方がBNよりも優れていることを示唆していると考えられる。

## 今後の展望

GNベースのモデルには最適ではない可能性があることに注意が必要です。システムを再設計したり、GNのために新しいハイパーパラメータを探索したりすることで、より良い結果が得られる可能性があります。さらに、我々は、GNがリカレントモデル（RNN/LSTM）やジェネレーティブモデル（GAN）の訓練で適応しているので今後に期待です。


## まとめ
バッチサイズが増えるとメモリが増えて大変だったので、簡易的なモデル構築を行っている身としてはありがたいです。



## 参考文献
https://arxiv.org/pdf/1803.08494.pdf
Ajaxを使ってテーブルを書き換えたらtablesorterが効かなくなったときの対処

###参考
[tablesorter：動的に行追加（先頭）した後でもソートを有効にする方法（及びスクロール位置の記憶）](https://qiita.com/fj58p/items/2b47b84fd7223de8b9be#22tablesorter%E3%82%92update%E3%81%99%E3%82%8B)

###現象

一覧ページからAjaxを使って絞り込み検索をして一覧テーブルを書き換えたらtablesorterが効かなくなった


###tablesorterとは
jQueryのプラグイン。

テーブルのthタグの部分をクリックすると、並び替えてくれる。

↓ここからダウンロードできます
https://mottie.github.io/tablesorter/docs/index.html#Download

↓下の方にZIPでダウンロードするボタンがあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668402/eee80f76-07d0-5562-2930-23ecde9c568a.png)

###解決

```javascript

$("#テーブルID").trigger("update");

```
これをAjaxの関数に追加しました。

テーブルの書き出しを行った後に実行します

```javascript

/* Ajaxの処理 */
$.ajax({
// 略
// 成功時の処理
.done(function(response){
  // テーブルを書き換える関数を呼び出す(自作の関数)
  updateTable(response); 
)};


/* テーブルを書き換える関数 */
function updateTable(response){
  // テーブルのtbodyの中身を空に
  $("テーブルID > tbody").text("");

  // テーブルの書き出し
  $.each( response, function( index, res ){
  // 略(tdなどの書き出し)
  });

  // tablesorterをupdateして有効にする
  $("テーブル名").trigger("update");
}

```


###検索力を上げるための教訓

「ググれば分かる」っていうのはググれるようになってから。

ググるって検索ワードが必要ですね。

参考のページにほぼそのまま答えは書いてあるので、
検索力がある人からしたら、「ググったら出てくるやん」
検索力がない人からしたら、「検索ワードは？」

ちなみに自分は
`「ajax tablesorter 効かない」`
で調べてなんとか見つけられました。

でもちょっと前の自分なら
`「tablesorter 効かない」`
で調べていたと思います。

なぜなら、 `Ajaxで書き換えたから効かなくなった`という仮説を自分でたてられたから、キーワードに入れました

「これが原因かな？」という仮説が、検索力を高める第一歩だと思いました。

###用語も覚えていかないといけませんね

参考のページでは「動的に」という言葉を使っています。

「ああ、javascriptとかjQueryでDOM操作をした時ね」っていうのは、その都度用語を調べて、分からなくても調べて少しずつ触れて覚えていかないといけません。

そのために有効なのが仮説を立てるですね。

すぐに思いつくワードで調べるんじゃなくて、原因を自分なりに考えて、それをキーワードに含めるとヒットしやすくなりますし、そのときに用語も「なんかこんな感じの用語があったなぁ」となって記憶にも定着しやすくなります。

###jQueryで「動的に」なんかしたあとはイベントが効かなくなったりすることがある

「あれ！？ボタンがきかんやん！！」というのが自分には何回かありました。

基本的にjqueryを使うときには意識することなのでしょうかね。

同じ様な境遇の方がいたら参考にしてみてください＼(^o^)／
【SQL】別々のテーブルにある値を結合して条件として活用する

# はじめに
タイトル通りですが、仕事で別々のテーブルにある値を結合して条件として活用する機会があったので備忘録です。

DBはMySQLを使用しています。

# テーブルの作成
例として、病院の予約システムを構築する案件があります。
画面としては予約画面があり、受診日と受診可能開始時間を入力することで予約可能な日時が一覧として表示されるよう機能があるとします。

テーブルとしては以下のテーブルを作成します。
・予約テーブル
・予約時間テーブル

```sql:SQL
CREATE TABLE reserves(
	id MEDIUMINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
	reserve_date DATE NOT NULL,
	created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
	updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB;
```

```sql:SQL
CREATE TABLE reserve_times(
	id MEDIUMINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
	reserve_id MEDIUMINT NOT NULL,
	reserve_time TIME NOT NULL,
	reservation_status TINYINT NOT NULL DEFAULT 0 COMMENT '0: 空き, 1: 予約済み',
	created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
	updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB;
```

データはそれぞれ以下になります。

```sql:SQL
INSERT INTO reserves (reserve_date) VALUES('2021-01-30');
```

```sql:SQL
INSERT INTO reserve_times (reserve_id, reserve_time) VALUES(1, '16:00:00')
,(1, '17:00:00')
,(1, '18:00:00')
,(1, '19:00:00')
,(1, '20:00:00');
```

# データを取得する
ユーザが入力した値は以下とします。

```
2021-01-30 18:00:00
```
以下は取得するためのSQLです。

```sql:SQL
SELECT r.id AS reserve_id,
reserve_date,
reserve_time
FROM reserves AS r
JOIN reserve_times AS rt ON rt.reserve_id = r.id
WHERE CONCAT(r.reserve_date, space(1), rt.reserve_time) >= '2021-01-30 18:00:00';
```
予約テーブルと予約時間テーブルを結合してから、WHERE句でCONCATを使って予約日（reserve_date）と予約時間（reserve_time）を結合して条件判定に利用しています。

実行してみると以下のような値が取れるかと思います。

| reserve_id | reserve_date | reserve_time |
|:-----------|-------------:|:------------:|
| 1          |    2021-01-30|      18:00:00|
| 1          |    2021-01-30|      19:00:00|
| 1          |    2021-01-30|      20:00:00|
<br>
以上、CONCAT関数を使った条件判定の方法でした。
【JavaScript】sortメソッドの使い方

#プログラミング勉強日記
2021年1月30日
sortメソッドの使い方を簡単にまとめる。


#sortメソッドとは
　JavaScriptで並び替えを行うメソッド。具体的には文字列や数字の昇順・降順で対象の値を並び替えることができる。ただ、sortメソッドは、元の配列データを変更してしまうメソッドでもあるので、注意が必要。

```:使い方
配列名.sort();
```

#文字列をソートする
　文字列をソートするためには、ソートしたい文字列が格納されている配列を対象にsortメソッドを呼び出す。

```js
let str = ["baseball", "soccer", "tennis", "swimming", "basketball"];
str.sort();
 
console.log(str);
```

```:実行結果
["baseball", "basketball", "soccer", "swimming", "tennis"]
```

#数字をソートする
　数値をソートするためには、引数に比較関数を指定する。比較関数は2つの値を比較しながら1つずつ順番を変えてく方法である。

```js:昇順に並び替え
// 比較関数
function sortNumber(a, b) {
  return a - b;
}
 
let num = [5, 3, 10, 6, 72, 27];
num.sort(sortNumber);
```

```:実行結果
[3, 5, 6, 10, 27, 72]
```

```js:降順に並び替え
// 比較関数
function sortNumber(a, b) {
  return b - a;
}
 
let num = [5, 3, 10, 6, 72, 27];
num.sort(sortNumber);
 
console.log(num);
```

```:実行結果
[72, 27, 10, 6, 5, 3]
```

#sortメソッドの注意点
　記事の冒頭でsortメソッドは元の配列を変更してしまう破壊的メソッドであると書いた。元の配列を残しておきたい場合には、sliceメソッドで配列のコピーを作成しておくといい。

```js
let str = ["baseball", "soccer", "tennis", "swimming", "basketball"];
let str_copy = str.slice();
str.sort();
 
console.log(str);
console.log(str_copy);
```

```:実行結果
["baseball", "basketball", "soccer", "swimming", "tennis"]
["baseball", "soccer", "tennis", "swimming", "basketball"]
```
【Nuxt.js】default.vueが読み込まれない

```layout/default.vue
<template>
  <div>
    <my-header />
    <nuxt /> 
  </div>
</template>

<script>
import MyHeader from "~/components/MyHeader.vue"

export default {
  components: {
    MyHeader
  }
}
</script>
```

これがうまく読み込まれない。

layout/default.vue
ではなく、layouts/default.vueだった、ディレクトリ名がlayoutでｓが抜けていた。
composer requireでPHP extension ext-httpが出た際の解決方法

# 環境
mac
docker
php7.4

# 問題

composer requireを実行した際に以下のエラーが発生しました。

```
Problem 1
    - Root composer.json requires PHP extension ext-http * but it is missing from your system. Install or enable PHP's http extension.

To enable extensions, verify that they are enabled in your .ini files:
    - /usr/local/etc/php/php.ini
    - /usr/local/etc/php/conf.d/docker-php-ext-bcmath.ini
    - /usr/local/etc/php/conf.d/docker-php-ext-intl.ini
    - /usr/local/etc/php/conf.d/docker-php-ext-pdo_mysql.ini
    - /usr/local/etc/php/conf.d/docker-php-ext-sodium.ini
    - /usr/local/etc/php/conf.d/docker-php-ext-zip.ini
You can also run `php --ini` inside terminal to see which files are used by PHP in CLI mode.
```

# 解決方法
composer.jsonから"ext-http": "*"を消す。
【Ruby】配列の%w記法

## はじめに

Rubyのアルゴリズムを学習していて積極的に使いたい記法があったので記事にさせていただきました。


## %ｗ記法

Rubyで配列を作るときに下記のような記法で置き換えることができます。
`%w` を使うことで **クォーテーション** で囲わなくて良いですし、 **カンマ** も必要ありません。

- 通常の配列記法。

```ruby
array = ['a', 'b', 'c', 'd', 'e']
p array
# => ["a", "b", "c", "d", "e"]
```

- %w記法

```ruby
array = %w(a b c d e)
p array
# => ["a", "b", "c", "d", "e"]
```

## まとめ
- このような記法は使うかは自由だが、このような書き方を見たときに何をしているのかわかるようにしておく。

## おわりに

調べていったら他にも **%記法** があることを知りました。
このように **知見を得たり、深めたり** することができるので記事を書くなどのアウトプットは重要だと思いました。

## 参考文献

- [Ruby 3.0.0 リファレンスマニュアル ( リテラル ) ](https://docs.ruby-lang.org/ja/3.0.0/doc/spec=2fliteral.html)
- [Ruby の文字列配列・シンボル配列を複数行で書く](https://qiita.com/scivola/items/a958edfb9008109472e1)
- [Rubyで%記法（パーセント記法）を使う](https://qiita.com/mogulla3/items/46bb876391be07921743)
Railsチュートリアル　1.5.1 Herokuのセットアップとデプロイ　で「source <(curl -sL https://cdn.learnenough.com/heroku_install)…」ができなかったとき

#環境
AWS cloud9

#詰まった箇所
1.5.1 Herokuのセットアップとデプロイ
手順通り
source <(curl -sL https://cdn.learnenough.com/heroku_install)
を実行したら下記のエラーが出た


```Rails:cloud9console
ubuntu:~/environment/sample_app (master) $ source <(curl -sL https://cdn.learnenough.com/heroku_install)
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 30.5M  100 30.5M    0     0  26.1M      0  0:00:01  0:00:01 --:--:-- 26.1M
mv: cannot move 'heroku' to '/usr/local/heroku': Directory not empty

```

ここでHerokuのバージョン確認をした時のコマンド結果を思いだした

```Rails:cloud9
ubuntu:~/environment/sample_app (master) $ heroku --version

Command 'heroku' not found, but can be installed with:

sudo snap install heroku

```

sudo snap install herokuを指示通り打ってみた

```Rails:cloud9
ubuntu:~/environment/sample_app (master) $ sudo snap install heroku
error: This revision of snap "heroku" was published using classic confinement and thus may perform
       arbitrary system changes outside of the security sandbox that snaps are usually confined to,
       which may put your system at risk.

       If you understand and want to proceed repeat the command including --classic.

```

 --classicオプションをつけろと怒られたのでもう一度トライ

```Rails:cloud9
ubuntu:~/environment/sample_app (master) $ sudo snap install heroku --classic
heroku v7.47.6 from Heroku✓ installed
```

無事Herokuインストールできました

```Rails:cloud9
ubuntu:~/environment/sample_app (master) $ heroku -v
 ›   Warning: Our terms of service have changed: https://dashboard.heroku.com/terms-of-service
heroku/7.47.6 linux-x64 node-v12.16.2
```
AWS RDSにPDOで接続

#PDO - MySQL を使用して RDS データベースに接続

ユーザーネームにMySQLで作成したユーザー名を入れてしまい接続できずハマりました

```
$dbhost = 'RDS_エンドポイント';//RSDで確認できます
$dbport = 'RDS_ポート';//RSDで確認できます
$dbname = 'データベースネーム';//MySQLのCREATE DATABESEで作ったデータベースネーム
$charset = 'utf8' ;

$dsn = "mysql:host=$dbhost;port=$dbport;dbname=$dbname;charset=$charset";
$username = 'RDS_ユーザーネーム';//RDSでデータベース作成時に設定したユーザーネーム
$password = 'RDS_パスワード';//RDSでデータベース作成時に設定したパスワード

$pdo = new PDO($dsn, $username, $password);
```
参考
https://qiita.com/dxtomochika/items/ee6a056b2686a7e7fb64
https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/create_deploy_PHP.rds.html
material-uiで使用したコンポーネント

#何の記事？
Reactアプリ開発で使用したことのあるmaterial-uiコンポーネントの備忘録。

#ブレークポイント
画面幅に応じてブレークポイントがある。Gridなどで利用される。

```
value         |0px     600px    960px    1280px   1920px
key           |xs      sm       md       lg       xl
screen width  |--------|--------|--------|--------|-------->
range         |   xs   |   sm   |   md   |   lg   |   xl
```

xsだけを指定すると全ての画面サイズでそれが適用される。
xsとsmを指定すると、600px以上のときにsmが適用されるようになる。

https://material-ui.com/ja/customization/breakpoints/

#Grid
Gridレイアウトを作成出来る。
https://material-ui.com/components/grid/

- containerかitemかを指定することが出来る。
- spacing:１当たり8pxのスペースをあける。
- xs, smなどの属性で使用するGridのマス目を指定する。画面いっぱいは12マス。


#GridList
繰り返しのパターンで項目を表示する。
https://material-ui.com/api/grid-list/

#Typography
HTML要素とCSSを結びつけて簡単に文字列のデザインを作ることができる。
https://material-ui.com/api/typography/
https://material-ui.com/components/typography/

variant属性で使用するテーマを決めて、component属性で実際のhtmlタグを決めることが出来る。

#TextField
ユーザー入力のインプット要素を作成する。
https://material-ui.com/components/text-fields/

#Toolbar
メニューバーを作成することが出来る。
デフォルトで`display: flex;`や`position: relative`がかかっている。
https://material-ui.com/api/toolbar/

#IconButton
丸いbuttonタグを作成する。focusした際にbackgroundが変化するアニメーションもついている。
https://material-ui.com/api/icon-button/#iconbutton-api

#Dialog
モーダルウィンドウを作成する。
https://material-ui.com/components/dialogs/#dialog

escキーを押したり周囲をクリックするとonCloseで設定した関数が呼ばれる。

#DialogContent
ダイアログのコンテンツをラップするときに使う。
良い感じのpaddingやflexがかかっている。
https://material-ui.com/api/dialog-content/#dialogcontent-api

#DialogActions
ダイアログ内のアクション（OKボタンやCancelボタンなど）を作成するときに使用。
`justify-content: flex-end`がかかっており、要素が右端に配置される。
https://material-ui.com/api/dialog-actions/#dialogactions-api

#Snacbar
スナックバーを作成
https://material-ui.com/components/snackbars/

#Tooltip
ホバーしたときやクリックしたときに文章を表示させることが出来る。
https://material-ui.com/components/tooltips/

#withStyles
Material-UIのコンポーネントにスタイルを適用することが出来る。
コンポーネントではない。
【Rails】gem wheneverで定期実行する方法

# 目的
現在制作中のrailsアプリにおいて、楽天APIからゴルフ場情報を取得、DBに保存して、変更、追加があったらDBを更新する処理を定期的に実行する必要が出てきました。

wheneverというgemを使うと、簡単にcronを回すことができます。
※cronとは、UNIX系のOSで動いている定期実行プログラムです。


# 導入
gemfileに追加。

```gemfile
gem 'whenever', require: false
```
インストール実行。

```terminal
$ bundle install
```

# 設定用の初期ファイルの生成
```terminal
$ bundle exec wheneverize .
```

このコマンドを実行すると、config/schedule.rbというファイルが生成されます。

# 定期実行する処理を実装する

lib/tasks/whenever_test.rakeというファイルを作ります。

```ruby
# lib/tasks/whenever_test.rake
namespace :whenever_test do  # ファイル名と合わせること
  desc 'テスト'
  task test: :environment do
    # ここに定期実行する処理を記述する。
    puts 'hoge'
  end
end
```

次に、taskが問題なく作られたか確認してみます。

```$ rails -T```を実行すると、taskの一覧がみれます。
先ほど作った、whenever_test:testがあれば問題ないです。

```$ rails　whenever_test:test```を実行しても手動で実行可能です。

# 定期実行する頻度の設定

```$ bundle exec wheneverize .```で生成したshedule.rbを編集していきます。

```rb
# config/schedule.rb
set :output, 'log/crontab.log'
set :environment, ENV['RAILS_ENV']
 
every 1.minute do
  rake "whenever_test:test"
end
```
今回は1分に一回の頻度で実行します。これで頻度の設定は終わりです。

# cronの実行
最後に、cronにて実行させる処理を設定します。
※wheneverというgemは使いますが、定期実行するのはあくまでcronになります。

先ほど作成したrakeファイルが存在するか次のコマンドで確認。

```terminal
$ bundle exec whenever
```

問題なければ、次のコマンドでcrontabをアップデート

```
$ bundle exec whenever --update-crontab
```

crontabをカラにして、定期実行を辞めたいときはこのコマンド。

```
$ bundle exec whenever --clear-crontab
```

log/crontab.logを確認して、'hoge'が出力されていれば、完了です。


# 参考
私の場合、理由はわかりませんが、wheneverで発行したcronのRAILS_ENVがproductionになっていたため、productionの設定を読み込んでしまってエラーがでておりました。
なので、開発環境で実行するには、このコマンドで行けました。

```
$ RAILS_ENV=development bundle exec whenever --update-crontab
```

参考にした記事
https://kyoto-diary.com/rails-whenever-cron/
zapierの紹介 | 鹿児島.mk #14 ノーコード with ヒラマサ定例会

#この記事について
[鹿児島.mk #14 ノーコード with ヒラマサ定例会](https://kagoshima-mk.connpass.com/event/200560/)でノーコードの一部である「Zapier」を紹介するために用意しました．

---

#発表の流れ
- 自己紹介
- What is Zapier?
- 利用例
- 実演
- 類似サービス
- まとめ

---

#自己紹介
名前：reodon
職業：AIエンジニア？
趣味：運動，アニメ鑑賞

---

#What is Zapier?
（[https://zapier.com/](https://zapier.com/)）

- 「Zaps」というワークフローで様々な処理を自動化してくれる
- Zapsは「Trigger」と「Action」で構成され，2,000以上のサービスで利用できる

---

#利用例
([https://zapier.com/roles](https://zapier.com/roles))

##ソフトウェアエンジニアの場合
[**Trigger**] GitHubのpull requestを出したら → [**Action**] Trelloのcardを作成する

##デザイナーの場合
[**Trigger**] Dropboxにファイルを追加したら → [**Action**] Slackのチャンネルに通知する

##学生の場合
[**Trigger**] Zapierのスケジュール機能で朝になったら → [**Action**] SMSを携帯に送る
[**Trigger**] Google Calendarのeventを追加したら → [**Action**] Trelloのcardを作成する（または，その逆も可能）

---

#実演
鹿児島.mkのSlackワークスペースの「#01-第1回もくもく会」チャンネルに送ったメッセージを，「#雑談」チャンネルにエコーします！！  
（Google Formsの投稿をSlackに通知してみますが，すぐに反映されないかもしれません）

---

#類似サービス
##[IFTTT](https://ifttt.com/)
  - 「if this then that」の頭字語？
    - [SwitchBot Hub Mini](https://www.switch-bot.com/products/switchbot-hub-mini)とGoogle Homeを連携させて，赤外線のリモコン代わりに利用した経験がある
      - 「Ok Google, 電気を消して」，「Ok Google, テレビをつけて」

##[Huggin](https://github.com/huginn/huginn)
  - 自身のサーバで動作するハック可能なIFTTTやZapier
    - 雨が降りそうならメールする
    - 事前に登録したキーワードでTwitterをモニターする（Twitterで「機械学習」の話題が盛り上がっていたら通知する）
    - Webサイトをスクレイピングして，変更があれば通知する
    - 自分の位置情報を常にトラッキングする
    - JavaScriptとCoffeeScriptを実行できる  

##[n8n](https://n8n.io/)
  - [fair-code](https://faircode.io/)ライセンス，[Apache 2.0 with Commons Clause](https://github.com/n8n-io/n8n/blob/master/packages/cli/LICENSE.md)
  - オープンで，拡張可能で，パワフル
  - 150以上のアプリにデータを同期できる

---

#まとめ
- 色々なサービスを連携させると生活が豊かになる
- 個人的にHugginが気になるので時間があれば試したい
Unityのコルーチンを止める可能性があるものはインスタンスを控えるか名前指定で呼び出す

ストーリーパートを作っていて文字を1文字ずつ表示するスクリプトを作っていたのですが、スキップしようとした時にコルーチンが止まらずセリフが悪魔合体していたバグを見つけたのでその対処方法を紹介します。

# 環境
Unity 2020.2.2f1 Personal

# 修正前のコード

```csharp
private void Update()
{
    if (Keyboard.current.zKey.wasPressedThisFrame)
    {
        StopCoroutine(NextStep());
        StartCoroutine(NextStep());
    }
}

private IEnumerator NextStep()
{
    // コルーチン処理
}
```

個人的には文字列での指定よりIEnumerator型で渡す方が好きです。

特に止める必要のないコルーチンであればこれでも問題ありませんが、
残念ながらこれではコルーチンが止まらず、2つのコルーチンが実行されてしまいます。

原因はStopCoroutineの仕組みです。
IEnumerator型で開始するタイプの書き方で止めるには同一インスタンスをStop側に渡してあげる必要があります。
上の書き方ではStartとStopは別インスタンスとなってしまうため、止まらないということです。

# 修正後のコード

1つはStartとStopで同じインスタンスを渡してあげるよう変更します。

```csharp
private IEnumerator nextStep;

private void Update()
{
    if (Keyboard.current.zKey.wasPressedThisFrame)
    {
        StopCoroutine(nextStep);
        nextStep = null;
        nextStep = NextStep();
        StartCoroutine(nextStep);
    }
}
```

または文字列での指定の方法でも問題なく止まります。
その際は少しでもタイポミスを防ぐようnameofを使うことをおすすめします。

```csharp
private void Update()
{
    if (Keyboard.current.zKey.wasPressedThisFrame)
    {
        StopCoroutine(nameof(NextStep));
        StartCoroutine(nameof(NextStep));
    }
}
```
スクリーンショットを画像ファイルで保存

#Wnodws標準機能ショートカットキー

Wnodws標準機能を使用したやり方は以下がある。
今までコピー機能しか知らず、使っていなかったのでこれを使えば便利そう。

ただし、私の使用しているノートPCの場合はPrintScreenキーはFnキーを押しながらとなるので
アクティブウィンドウのスクショの場合キーを4つ同時押しとなるので、慣れが必要か。

__デスクトップ全体__
```Win + PrintScreen
```

以下に保存されます。
PC\ピクチャ\スクリーンショット
(C:\Users\xxx\Pictures\Screenshots)

__アクティブウィンドウ__
```Win + Alt + PrintScreen
```

以下に保存されます。
PC\ビデオ\キャプチャ
(C:\Users\xxxx\Videos\Captures)
いざとなれば会社に通える田舎を探す(その2 挫折)

# 背景

コロナで在宅勤務が続いているため、都会で手狭な家に住んでいるのが苦しくなってきました。週に数日や月に数日しか出社しないなら、通勤に片道2時間ぐらいかかる田舎で暮らすことも現実的かも。（定期代がフルに支給されない）新幹線通勤までも視野に入れれば結構遠くに住めるかも？

今ひとつ土地勘がないので、会社の最寄り駅に平日朝9時に到着するための乗車時間を地図にマッピングして候補地を探していきたい。

ということで、[その１駅情報取得](https://qiita.com/aerialist/items/6fe3ad2590c218274c55)では「駅すぱあとWebサービス フリープラン」を利用して全国の駅情報（駅名と緯度経度）をゲットしました。

# 結論: 駅すぱあとWebサービスでの解決は断念

今回は次のステップとして各駅から最寄り駅までの経路を検索し所要時間を取得していく。。。 予定だったのですが、結局断念しました。

駅すぱあとWebサービスそのものにはそもそも経路検索の機能がありません。そのかわりに[駅すぱあと for web URL生成](https://docs.ekispert.com/v1/le/api/search/course/light.html)APIあり、[駅すぱあと for web](https://roote.ekispert.net/ja/) で探索結果を表示するためのURLを生成することができます。

[その１で取得した](https://qiita.com/aerialist/items/6fe3ad2590c218274c55)日本全国の9,274駅から会社の最寄り駅に対して平日朝9時に到着する経路検索をするURLを生成し、順にアクセスしていきながら検索結果をパースしていけばいいはず。。。
いいはずではあるのですが、駅すぱあと for webはスクレイピングしていいのか？

駅すぱあと for webの[利用規約](https://roote.ekispert.net/ja/help/terms)では、コンテンツ内容をWebやアプリに表示することが禁止事項としてあげられています。

> 「駅すぱあと for web」のコンテンツ内容の全部又は一部を、他のWebサイトやアプリケーションの内部に表示させる行為（フレーム内リンクを含む）を行わないものとします。

明確にスクレイピングでデータ取得することを禁止する項目は見当たらず、取得したコンテンツを公開しなければいいのか？？ とも思ったのですが、念の為運営元のヴァル研究所に問い合わせたところやはりスクレーピングは禁止との回答でした。

# Workaround

フリープランではどうしても経路検索ができないようなので、他の手を考えます。

有料の[駅すぱあとWebサービス」](https://ekiworld.net/service/sier/webservice/index.html)スタンダードプランならバッチリ探索APIが使えます。ただし30日の無償評価期間終わったあとの料金はWeb上でぱっと見つけられずコワイ。おそらく月々のサブスクリプションタイプ？

有料プランの中に、[駅すぱあとWebサービス for Amazon](https://www.amazon.co.jp/dp/B07D45461J)というのもありました。こちらは明朗会計で、10000リクエストが¥11,000。今回の目的で使おうと思うと1地図約1万円ですね。ただしamazon版は時刻情報を利用した探索機能が利用できないらしく、「朝9時に到着できる駅を探す」形は実現できないようです。

ということで駅すぱあとは一旦諦めます。

[ジョルダン](https://norikae.jorudan.co.jp/openapi/)は3,000回/月の制限はありますが無料で検索が使えるようです。3ヶ月かければできるかも？ 利用登録を申し込んだのですが、残念ながらすぐにアクセスキーを発行してもらえなかったのでスキップ。

[ナビタイム](https://api-sdk.navitime.co.jp/api/)は500回/月まで無料。9,274件検索するには何ヶ月かかるのか！と思ったら、[NAVITIME Reachable](https://api.rakuten.net/navitimejapan-navitimejapan/api/navitime-reachable)というAPIがある。

> 到達圏探索（トータルナビ）
> 電車（航空路線、徒歩含む）を移動手段として、指定した地点から指定した時間または乗換回数で到達可能な駅を探索します。

これはいけるかも！？ その３へつづく。
Swift5 カウントダウン後、効果音が鳴り止まない


#はじめに
カウントダウンタイマーを作成している時に、終了したら効果音を鳴らすコードを書いていました。
効果音はAudioToolboxを使用しました。
カウントダウンが終了し効果音を鳴らしました。
そうしたところ効果音が止まらなくなり、鳴り続けるという現象が起きました。
凄く初歩的なミスでしたが、効果音を鳴らすための処理に原因があると考えていたため凄く調べるのに時間を取られてしまいました。
そこで何が原因かを調べたので、忘却録として書こうと思いました。

#環境
Xcode12.3
Swift5.3.2
macOS Catalina 10.15.4

#AudioToolboxを使う準備
[こちら](https://github.com/TUNER88/iOSSystemSoundsLibrary)を参考にして準備します。

#カウントダウン終了時の画面
カウントダウン終了で終わらないで、カウントダウンがプリントされ続けると同時に効果音が鳴り続いてしまいました。
![スクリーンショット 2021-01-30 18.30.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/683624/0eedfd20-023d-3247-dcf6-4e98e6c8ae2e.png)
※全コードは下の方にあります。

#原因
凄く初歩的なミスで、タイマーを破棄しなかった事でした。

```ViewContlloer.swift
  timer.invalidate()
```

#原因を探す時に役立った事
[teratail](https://teratail.com/questions/input)さんの質問用テンプレートに書き込みながら、頭を整理していく事で原因部分を特定する事が出来ました。

今回コードを書いている時は、効果音を鳴らす事を目的にしていました。
そのため、効果音を鳴らすためのコードに原因があると思い長い時間調べました。

```
AudioServicesPlaySystemSound(soundID)//これが原因と仮説
```
そのためTimerに原因があるとは思いませんでした。
質問テンプレートに書いていると問題が解決するという事を聞いていましたが、本当にその通りだなと感じました。

これからは、活用していきたいと思います。

#効果音が終わらない全コード

```ViewContlloer.swift
import UIKit
import AudioToolbox

class ViewController: UIViewController {

    var timerValue = 5

    var timer:Timer = Timer()
    let soundID:SystemSoundID = 1304


    override func viewDidLoad() {
        super.viewDidLoad()

        startTimer()
        // Do any additional setup after loading the view.
    }


    func startTimer() {

        timer.invalidate()

        timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(self.countDwon(timer:)), userInfo: nil, repeats: true)
    }

    @objc func countDwon(timer: Timer) {

        timerValue -= 1

        if(timerValue > 0) {

            print(timerValue)
        } else {
            AudioServicesPlaySystemSound(soundID)
            print("カウントダウン終了")
        }
    }
}
```

#効果音が正しくなるようにした全コード

```ViewContlloer.swift
import UIKit
import AudioToolbox

class ViewController: UIViewController {

    var timerValue = 5

    var timer:Timer = Timer()
    let soundID:SystemSoundID = 1000


    override func viewDidLoad() {
        super.viewDidLoad()

        startTimer()
        // Do any additional setup after loading the view.
    }


    func startTimer() {

        timer.invalidate()

        timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(self.countDwon(timer:)), userInfo: nil, repeats: true)
    }

    @objc func countDwon(timer: Timer) {

        timerValue -= 1

        if(timerValue > 0) {

            print(timerValue)
        } else {
            AudioServicesPlaySystemSound(soundID)

            //タイマーを破棄
            //ここを書かないと繰り返しAudioServicesPlaySystemSound(soundID)が呼ばれる
            timer.invalidate()
            print("カウントダウン終了")
        }
    }
}

```

#終わりに


これから、上手く動かない時は質問テンプレートを活用していきたいと思います。

もし間違いがあれば優しく教えていただけると嬉しいです。

#参照サイト
https://github.com/TUNER88/iOSSystemSoundsLibrary
https://teratail.com/questions/input
https://qiita.com/KikurageChan/items/5b33f95cbec9e0d8a05f

Twitterやってます。
[Twitter](https://twitter.com/koara1237)
Swiperを使ってスライダー機能の実装

#Swiper

##Swiperとは
jQuery 不要でレスポンシブ及びタッチデバイス（スマホやタブレット）対応のスライダープラグイン Swiperを使うことで簡単にスライダーを実装することができる。

[![Image from Gyazo](https://i.gyazo.com/0a495302e6fcb5e776fad62270b26a3f.gif)](https://gyazo.com/0a495302e6fcb5e776fad62270b26a3f)

[Swiper公式サイト https://swiperjs.com/]

##Swiperのダウンロード方法
Swiperのダウンロードは様々あるが今回はnpmでSwiperをインストールするものとする。

>1.　Swiperのインストール

```console
$ npm install swiper
```
コンソールでswiperをインストールする

>2.　node_modulesをassetsに追加

```ruby:config/initializers/assets.rb
Rails.application.config.assets.paths << Rails.root.join('node_modules')
```
node_modulesをassetsに追加するためにconfig/initializers/assets.rbに上記を記入

>３. Swiperをアプリに反映させる

```js:app/assets/javascripts/application.js
//= require swiper/swiper-bundle.js
```
jsファイルにSwiperのコードを記述したら反映できるようにjsファイルに上記を記述する。

##Swiperを記述する
Swiper公式リファレンスに沿って記述していく

[![Image from Gyazo](https://i.gyazo.com/e7dd6ebcdc0bf537b8d99c0cff89b5a5.png)](https://gyazo.com/e7dd6ebcdc0bf537b8d99c0cff89b5a5)

```html
<!-- Slider main container -->
<div class="swiper-container">
  <!-- Additional required wrapper -->
  <div class="swiper-wrapper">
    <!-- Slides -->
    <div class="swiper-slide">Slide 1</div>
    <div class="swiper-slide">Slide 2</div>
    <div class="swiper-slide">Slide 3</div>
    ...
  </div>
  <!-- If we need pagination -->
  <div class="swiper-pagination"></div>

  <!-- If we need navigation buttons -->
  <div class="swiper-button-prev"></div>
  <div class="swiper-button-next"></div>

  <!-- If we need scrollbar -->
  <div class="swiper-scrollbar"></div>
</div>
```
各スライド(Slide1,Slide2)に画像を貼ることでスライダーになる

##Swiperの各オプション
縦スライドや自動スクロールなど様々なスライドオプションはjsファイルに記述することによって
しようを変えることができる

[参考　https://garigaricode.com/swiper/]


>今回はslim形式で自動スクロールを実装する

[![Image from Gyazo](https://i.gyazo.com/b456074a306475f7874e8b6e9fbbfbe1.gif)](https://gyazo.com/b456074a306475f7874e8b6e9fbbfbe1)


```slim
<!-- Slider main container -->
.swiper-container
  <!-- Additional required wrapper -->
  .swiper-wrapper
    <!-- Slides -->
    .swiper-slide
      Slide 1  （ここには画像をはる）
    .swiper-slide
      Slide 2　（ここには画像をはる）
    .swiper-slide
      Slide 3　（ここには画像をはる）
    .swiper-slide
      Slide 4　（ここには画像をはる）
  <!-- If we need pagination -->
  .swiper-pagination

  <!-- If we need navigation buttons -->
  .swiper-button-prev
  .swiper-button-next

  <!-- If we need scrollbar -->
  .swiper-scrollbar
```

```js
var mySwiper = new Swiper('.swiper-container', {
	autoplay: {
		delay: 3000,
		stopOnLastSlide: false,
		disableOnInteraction: false,
		reverseDirection: false
        }
});
```

基本的に上のオプションのサイトをみながらコードを記述すると実装することができる。
Python vs PyPy vs Pyston ...ﾌｧｲｯ

# はじめに

先日、"[Pythonより約40％高速な「Pyston 2.1」が登場](https://ledge.ai/pyston-2-1/)" というニュースを見た

「Pyston か〜、PyPy も早いらしいけどどんなもんなんやろか？」と思ったため簡単に検証



# 結論

```
[早い] PyPy >> Pyston > Python [遅い]
```



# 検証

## 環境構築

環境は Docker コンテナで行う

以下の Dockerfile をビルドして検証

```dockerfile
FROM ubuntu:20.04
WORKDIR /usr/local/src
RUN apt update && apt -y install python3 pypy3 wget vim\
    && wget https://github.com/pyston/pyston/releases/download/v2.1/pyston_2.1_20.04.deb
```

これで Python,  PyPy はインストールできるが肝心の Pyston に関しては `apt install ./pyston_2.1_20.04.deb` でインストールしようとすると途中でキー入力を求められるため Dockerfile でやるのは断念



それぞれのバージョンは以下の通り

```
# python3 -V
Python 3.8.5

# pypy3 -V
Python 3.6.9 (7.3.1+dfsg-4, Apr 22 2020, 05:15:29)
[PyPy 7.3.1 with GCC 9.3.0]

# pyston -V
Python 3.8.2 (heads/rel2.1:da378ef, Jan 12 2021, 15:46:12)
[Pyston 2.1.0, GCC 9.3.0]
```



## フィボナッチ数列

こういった処理速度系の検証はフィボナッチ数列が定番だと勝手に思っているため以下のコードで検証を行う

```python
from datetime import datetime

count: int = 0

def fib(n: int) -> int:
    global count
    count += 1

    if n == 0:
        return 0
    if n == 1:
        return 1
    return fib(n - 1) + fib(n - 2)


def main():
    n = 40
    start_time = datetime.now()
    fib(n)
    end_time = datetime.now()
    print(f'count: { count }')
    print(f'time: { end_time - start_time }')


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



# 結果

```
# python3 fib.py
count: 331160281
time: 0:00:38.562256

# pyston fib.py
count: 331160281
time: 0:00:26.015875

# pypy3 fib.py
count: 331160281
time: 0:00:02.939397
```

PyPy が早すぎる... 

Pyston も Python に比べたら 30% くらい早くなっている

**ただ、Pyston も PyPy も使えるサードパーティのライブラリには制限があるようなのでこの結果は一つの参考までになればと思います**