OmniAICreator/Qiita-1.07M huggingface dataset:
Laravelでエラー「failed to open stream: Permission denied」が表示された時の解決方法

webサーバーにアクセスした際に、ログが書き込めない内容のエラーが表示されました。
その時の原因と解決方法を記載します。

<h2>原因</h2>
apacheを動かしているユーザーに権限が付与されていないため、エラーが発生しています。

<h2>解決方法</h2>
/app/storage/以下のパーミッションを変更する必要があります。

```
$ chmod -R 777 /app/storage/
```

<h2>終わりに</h2>
Laravelのログは、デフォルトでstorage/logs/larave.logに出力されます。
エラーの詳細が確認できるので、便利ですね:grin:
Gatsby テンプレート「Gatsby Photo Book」をNetlifyデプロイするまで

![スクリーンショット 2020-08-15 14.24.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692347/8e24612e-8e62-92ab-ab2d-b61a2dc370f1.png)

Gatsbyのテンプレートを厳選したサイト
***[Jamtemlates](https://jamtemplates.com)***から画像ギャラリーのようなサイトのテンプレートを使ってNetlifyデプロイしました。

![スクリーンショット 2020-08-15 14.28.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692347/0ab7837e-f7e9-5698-8951-03fafb746029.png)
>ReadMeの説明では

1.Forkしてnpm install
2.content/images に画像をドロップ
3.gatsby develop
の３ステップで簡単そうですが、色々ハマったので記録のため書いておきます。

>結論

1.Forkしてnpm install→Forkして**yarn install**
2.content/images に画像をドロップ
→**src/content/images**に画像をドロップ＆**gatsby-config.js**修正
3.gatsby develop
これでlocal 、NetlifyもGitHubから追加するだけで特に設定なくデプロイできました。


##テンプレートサイトを選ぶ
テーマ選びは
***[Gatsby公式サイト](https://themejam.gatsbyjs.org/showcase)***のShowcaseからテーマを選ぶこともできますが、

Gatsbyの高品質なテーマだけを集めたサイト（Aboutに書いてました)
***[Jamtemlates](https://jamtemplates.com)***から選びました。


今回は画像のURL化のために画像をアップするためだけのサイト
***[Gatsby Photo Book](https://github.com/baobabKoodaa/gatsby-starter-photo-book)***
を選びましたが、他にもブログサイトやポートフォリオサイトなどGatsbyでサクッと作りたい時に使えそうな物が揃ってます。
＊この存在を知るまではUdemyなんかを見ながら一から作ってました。。
![スクリーンショット 2020-08-15 14.24.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692347/ced79cb1-28b1-34a3-a007-307d4dbc8478.png)



##Git Clone
***[Gatsby Photo Book](https://github.com/baobabKoodaa/gatsby-starter-photo-book)*** まずは本家のGitHubリポジトリをForkして普通にcloneします。

```
% git clone git@github.com:[自分のGithubName]/gatsby-starter-photo-book.git
```
![スクリーンショット 2020-08-15 14.25.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692347/1b1994db-3f39-1b94-a685-f7bf2dc8c7a2.png)

##Yarn Install

ReadMeには`npm install`すると書いていますが、
`npm i`するとめちゃめちゃエラー出ます。

```
% yarn install
```
ですんなり解決しました。。（```% yarn```でもオッケーです。）

##localで確認
ここで`gatsby develop`すると画像がないと怒られるので画像用のディレクトリを準備します。
####画像ディレクトリ追加
scr/content/imagesとディレクトリを作成しimagesに画像を入れます。
![スクリーンショット 2020-08-15 23.21.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692347/32fd15eb-44d4-5441-c789-6375b92b4665.png)
####config設定

```javascript:gatsby-config.js
{
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `images`,
        path: `${__dirname}/content/images`,//ここを修正
      },
    },
```

src下に置いていないとlocalでは問題ないですが、Netlifyでこけます。

```javascript:gatsby-config.js
{
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `images`,
        path: `${__dirname}/src/content/images`,//修正後
      },
    },
```
####gatsby develop
念のため```yarn run```でdevelopコマンドを確認
![スクリーンショット 2020-08-15 23.34.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692347/6b97ef5f-f4bc-4789-2623-f5ce8e8a1b20.png)
```gatsby develop```を実行します。


##Netlifyデプロイ
####GitHubからNetlifyデプロイ
DeploySettingは特に変更しなくても大丈夫でした。
![スクリーンショット 2020-08-15 23.31.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692347/af88c74d-6e01-6337-dad8-e5b5a876a3f9.png)
ラムダ 、ジェネレーター

#ラムダ
ラムダ（無名関数）

使用例
所々、先頭の文字が小文字の曜日リストを全て先頭の文字を大文字にしたいとき、
![スクリーンショット 2020-08-15 23.12.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527694/eff16c1e-b6b0-118b-08bc-e0c2df8b185c.png)

ラムダならreturnを省いてかけるため
単純なファンクションであれば一行でかける
![スクリーンショット 2020-08-15 23.15.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527694/8c0ad1e4-7407-e03d-b602-f0592575ad47.png)

このように書くことも可能
![スクリーンショット 2020-08-15 23.18.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527694/3dd9404f-b520-88d5-36d6-30ba877e8548.png)

##ラムダの使いどころ
単純な関数を一行で書くことでコード量削減

#ジェネレーター
forループとは違い、1つずつ要素を作り出していく
そのため、途中で他の処理を挟むことも可能
![スクリーンショット 2020-08-15 23.33.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527694/567cc4f2-df3c-90b9-abec-891b581c516a.png)
PythonでABC175のA,B,Cを解く

### はじめに
毎回言ってる気がしますが、おひさしぶりです。4連続冷えを防ぐことに成功しました。

### [Rainy Season](https://atcoder.jp/contests/abc175/tasks/abc175_a)
1WA  

**考えたこと**
Rが連続でいくつあるかをカウントします。

```python

s = input()

if 'RRR' in s:
    print(3)
elif 'RR' in s:
    print(2)
elif 'R' in s:
    print(1)
else:
    print(0)
```
if文は上から処理されていくので順番に処理されていくので、順番に注意しましょう。私はこれでWAでした。

### [Making Triangle](https://atcoder.jp/contests/abc175/tasks/abc175_b)
**考えたこと**
三角形の存在条件をやるだけですが、問題文を誤読して時間がかかりました。$N$が小さいの全探索します。

```python
n = int(input())
n = int(input())
l = list(map(int,input().split()))

ans = 0
for i in range(n):
    for j in range(i,n):
        for k in range(j,n):
            if l[i] == l[j] or l[i] == l[k] or l[j] == l[k]:
                continue
            else:
                ver = [l[i],l[j],l[k]] #3辺の長さ
                ver.sort()
                if ver[0] + ver[1] > ver[2]:
                    ans += 1

print(ans)

```
### [Walking Takahashi](https://atcoder.jp/contests/abc175/tasks/abc175_c)
**考えたこと**

- $X$が正で、$X-K*D$も正ならば絶対値が一番近いのは$X-K*D$になります。

- 同様に、$X$が負で、$X+K*D$も正ならば絶対値が一番近いのは$|X+K*D|$になります。

- 上のどちらでもない場合を考えます。正の数かつ$K$回以内に移動可能な一番小さい値を$dis$とし、負の数かつ$K$回以内に到達可能な一番小さい値を$dis'$とします。$T (T \leq K)$回目で$dis$に到着したとすると、
    - Tが偶数ならば、$dis → dis' → \dots dis$となります
    - Tが奇数ならば、$dis → dis' → \dots dis'$となります

```python
x, k, d = map(int,input().split())

if x - k * d >= 0:
    print(x - k * d)
elif x + k * d <= 0:
    print(abs(x + k * d))
else:
    dis = x % d
    dis_p = d - dis
    t = k - x // d

    if t % 2 == 0:
        print(dis)
    else:
        print(dis_p)
```

### まとめ
Dの指針は当ってましたが、実装でコケました。
ではまた、おやすみなさい。
AtCoder Beginner Contest 175 A問題「Rainy Season 」解説(C++,Python3,Java)

Ruteです。

AtCoder Beginner Contest 175 A問題「Rainy Season」の解説を行います。

>問題URL:
https://atcoder.jp/contests/abc175/tasks/abc175_a

#問題概要
`"R"`が最大何文字連続しているかを出力しなさい。

##制約
・ $|S| = 3$
・$S$の各文字は`'S'`または`'R'`である

#解説
ls = []と定義します。
$S$を文字列として受け取ります。
now = 0とします。 これは後で利用します。
以下の様な繰返し処理を行います。
・もし`S[i](Sのi文字目)`が"R"だった場合
　　now に1を加算します。
・そうでない場合
　　lsにnowの値を挿入し、nowの値を0とします。
最後に、lsに繰返し処理が終わった後のnowの値を挿入します。
lsにある数のうち、最大の数が答えなのでこれを出力すれば良いです。

もしくは、制約がかなり小さいので、全ての文字列について`'R'`が何文字あるかどうかをあらかじめ計算して、条件分岐でその都度出力してもよさそうです。
#各言語解答例
Python3はループを用いる方法で、C++,Javaは全ての文字列で条件分岐する方法で解いてみました。
C++,Javaでループを用いる方法、Python3で全ての文字列で条件分岐する方法でもACすることは可能です。
<details><summary>Python3での解答例</summary><div>

```{ABC175A.py}
S = input()
ls = []
now = 0
for i in range(3):
    if S[i] == "R":
        now += 1
    else:
        ls.append(now)
        now = 0
ls.append(now)
print(max(ls))
```

</div></details>

<details><summary>C++での解答例</summary><div>

```{ABC175A.cpp}
#include<bits/stdc++.h>
using namespace std;
int main(){
  string S;
  cin >> S;
  if (S == "RRR"){
    cout << 3 << endl;
  }else if (S == "RRS"){
    cout << 2 << endl;
  }else if (S == "SRR"){
    cout << 2 << endl;
  }else if (S == "SRS"){
    cout << 1 << endl;
  }else if (S == "RSR"){
    cout << 1 << endl;
  }else if (S == "RSS"){
    cout << 1 << endl;
  }else if (S == "SSR"){
    cout << 1 << endl;
  }else{
    cout << 0 << endl;
  }
}
```


</div></details>



<details><summary>Javaでの解答例</summary><div>

```{ABC175A.java}
import java.util.Scanner;
public class Main{
  public static void main(String[] args){
    Scanner scan = new Scanner(System.in);
    String s = scan.next();
    if (s.equals("RRR")){
      System.out.println(3);
    }else if (s.equals("RRS")){
      System.out.println(2);
    }else if (s.equals("SRR")){
      System.out.println(2);
    }else if (s.equals("RSR")){
      System.out.println(1);
    }else if (s.equals("RSS")){
      System.out.println(1);
    }else if (s.equals("SRS")){
      System.out.println(1);
    }else if (s.equals("SSR")){
      System.out.println(1);
    }else{
      System.out.println(0);
    }
  }
}

```
`'=='`を使って文字列が同じかを比較すると、Javaの参照によって期待していた出力とは違う条件分岐となる可能性があります。詳しくは[こちら](https://www.sejuku.net/blog/14621 "==を使うとマズイ理由")をご覧下さい。

</div></details>
さくらのレンタルサーバー 　php.iniをドメインごとに設定したい

環境
さくらのレンタルサーバー　ビジネス
ドメイン6つ　6サイト

php.iniには
output_buffering = On
display_errors=Off
error_reporting=E_ERROR
の記述

display_errors=offにしたのは
他サーバーで他社が作成したソースを移行したときに、エラーが表示されたため。
直せばよいのですが、誰もわからない、直す時間がないので、
display_errors=offにしています。
エラーさえ表示されなければきちんと動いているのでとりあえずめでたし、めでたし。

月日は流れ・・・・

新たなサイトを作成することになりました。

開発中はエラーを表示したい。
でも、display_errors=OffをOnにすると既存サイトにエラーが表示されてしまう。

そこで さくらのレンタルサーバーでPHP.iniをドメインごとに設定できないか調べました。


##環境・前提
さくらのレンタルサーバービジネス
PHP　モジュールモード
プログラムの ini_set()は使わない
sshコマンドは使わない
初心者に優しく


##結論
ディスプレイにエラーを表示するのはあきらめて、
php.ini でエラーログの出力設定をする

以下この結論に至った道のりです。

##php.iniを複数作成してみる。
※結論　だめでした

さくらのレンタルサーバーの場合
php.iniは
/home/〇〇〇/www/php.ini

そこでphp.iniを作成し、ドメインフォルダ以下においてみました。
/home/〇〇〇/www/〇〇〇/php.ini

で、phpinfo()で php.iniのパスを確認したのですが・・・・
/home/〇〇〇/www/php.ini　と初期設定のまま。残念

[php.iniの設定項目](https://www.php.net/manual/ja/ini.list.php)
[php.ini以外でも設定できるのか](https://www.php.net/manual/ja/configuration.changes.modes.php)
[エラーログの設定で使う定数](https://www.php.net/manual/ja/errorfunc.constants.php)

##.user.ini ファイルを使ってみる
.user.iniでディレクトリ単位での ini　ファイルを使えます。
ただし、モジュール―モードでは使えない。
なので今回は×　残念。

[.user.ini マニュアル](https://www.php.net/manual/ja/configuration.file.per-user.php)

## .htaccess　を使ってみる

.htaccessを使ってPHPの設定を行う場合には、「php_value」ディレクティブ、または、「php_flag」ディレクティブを使用します。

でさくらのレンタルサーバーで使えるのか調べてみました。
なんと、
PHPに関する設定を ［ php.ini ］ にせず、[ .htaccess ] に 「 PHP_Flag 」 や 「 PHP_Value 」 などを記述すると500エラーになるのです。

[さくらのレンタルサーバー500エラー](https://help.sakura.ad.jp/206053862/)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/369082/ade36f2d-02c8-7934-486a-0b57c5c7d8b6.png)

##画面にエラーを表示するのはあきらめてエラーログにする
結局PHPのエラーログを出力するようにしました。

さくらのレンタルサーバーの初期設定では
log_errors　は　off　になっています。
そこで www以下にphplogフォルダを作成し、
以下の設定をします。


log_errors=On
error_log="/home/〇〇〇/www/phplog/error.log"

設定箇所は
さくらのレンタルサーバーコントロールパネル→スクリプト設定→php.ini設定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/369082/a7b5f7b2-5372-6be1-f282-17095654f817.png)

通常はエラーログの出力先はWEBからアクセスできない場所がよいのですが、
FTPでアクセスしたときのドキュメントルートがWWW以下なので、
「ログのありかがわからない」という問い合わせをさけるために www以下にしています。

##さくらのレンタルサーバーのエラーログも出力する
さくらのレンタルサーバーにもエラーログを出力する設定はあります。
ただし、初期では出力しないようになっているので出力するようにします。

サーバーステータス→アクセスログ→アクセスログの保存→エラーログも保存するにチェックをいれます。

[さくらのレンタルサーバーエラーログについて](https://help.sakura.ad.jp/360000208561/#05)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/369082/94bc158b-900c-5baa-1f52-9a43dd2ceb5e.png)


正直エラーログをみてもよくわからないので、さくらのレンタルサーバーのエラーログ＆PHPのエラーログの二つを照らし合わせ乗り切りたいです。

どなたかよい方法を教えてください。
便利なショートカット

#Windowsで使えるショートカット
###エクスプローラーを開く
[WIN]+E

###タスクバーを選択
[WIN]+T
[WIN]+(数字)

###ファイル名を指定して実行
[WIN]+R

###設定を開く
[WIN]+I

###シャットダウン
ウィンドウがアクティブじゃない状態で「Alt+F4⇒Enter」
[WIN]+X⇒U⇒U

###複数コピペできる機能
[WIN]+V

###スクリーンショット
[WIN]+Shift+S
[WIN]+W

#GoogleChromeで使えるショートカット

##検索系
###検索枠に移動
Ctrl+L
Alt+D

###検索（上とほぼ同じ）
Ctrl+K
Ctrl+E

##タブ系
###新しいタブ
Ctrl+T

###タブ移動
Ctrl+TAB
Ctrl+Shift+TAB

###タブを閉じる
Ctrl+W

##メニュー系
###右上のメニュー
Alt+E
Alt+F

###履歴(History)
Ctrl+H
【PHP】Composer が「updating dependencies」でフリーズした時に試したこと

composer.jsonを作成して、<code>composer install</code>すると、以下のように　Updating dependencies で時が止まってしまいました。

```
Loading composer repositories with package information
Updating dependencies (including require-dev)
```

初歩的なことかもですが、解決するために試したことを列挙していきます。

##試したこと
###1. Composerのキャッシュを削除
composerにはローカルキャッシュがあるらしく、キャッシュが使われていることで変更や更新などがうまく動作しないのかなーと思い、以下のコマンドでキャッシュ削除しました。

```
composer clear-cache
```

しかし、解決に至らずでした。

###2. composerが参照するリポジトリを変更

```
composer config -g repos.packagist composer 
```

\\\ **これで解決しました！**//

地理的要因で応答が遅くなっていたらしく、composerが参照するリポジトリを「packagist.org」から「[packagist.jp](https://packagist.jp "packagist.jp")」に変更することで解消できるそうです。

しかし、フリーズが解消されたのはいいが、下記のエラーが発生。

```
[RuntimeException]                                                                                                                                                                                                                                         
  sh: 1: git: not found   
```


gitをインストールして解決しました↓


```
yum install git -y

もしくは

apt-get install git -y
```
Gradle で JAR ファイル名にタイムスタンプを付加する

## 概要

- Gradle で JAR ファイルを作成する際、ファイル名にタイムスタンプを付加する
- 動作確認環境: Gradle 6.6 + Groovy 2.5.12

## build.gradle

build.gradle ファイルにて project.version に日時文字列を付加する。

```groovy
plugins {
  id 'java'
}

project.version = '1.2.3' + '_' + getTimestamp()

def getTimestamp() {
  // 年月日_時分秒_ミリ秒
  return new Date().format('yyyyMMdd_HHmmss_SSS')
}
```

jar タスクや build タスクで JAR ファイルを作成する。

```
$ gradle build
```

build/libs に以下のようなファイル名で jar が生成されているのを確認できる。

```
$ ls build/libs
myapp-1.2.3-20200815_220925_236.jar
```

## 参考資料

- [The Java Plugin](https://docs.gradle.org/6.6/userguide/java_plugin.html)
- [Project \- Gradle DSL Version 6\.6](https://docs.gradle.org/6.6/dsl/org.gradle.api.Project.html)
- [Date \(Groovy JDK enhancements\)](http://docs.groovy-lang.org/docs/groovy-2.5.12/html/groovy-jdk/java/util/Date.html)
１行掲示板

```php

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>１行掲示板</title>
</head>

<body>
  <?php
  // データベースに接続する
  $pdo = new PDO("mysql:host=127.0.0.1;dbname=lesson;charset=utf8", "root", "");
  // print_r($_POST);

  // 受け取ったidのレコードの削除
  if (isset($_POST["delete_id"])) {
    $delete_id = $_POST["delete_id"];
    $sql  = "DELETE FROM bbs WHERE id = :delete_id;";
    $stmt = $pdo->prepare($sql);
    $stmt -> bindValue(":delete_id", $delete_id, PDO::PARAM_INT);
    $stmt -> execute();
  }

  // 受け取ったデータを書き込む
  if (isset($_POST["content"]) && isset($_POST["user_name"])) {
    $content   = $_POST["content"];
    $user_name = $_POST["user_name"];
    $sql  = "INSERT INTO bbs (content, user_name, updated_at) VALUES (:content, :user_name, NOW());";
    $stmt = $pdo->prepare($sql);
    $stmt -> bindValue(":content", $content, PDO::PARAM_STR);
    $stmt -> bindValue(":user_name", $user_name, PDO::PARAM_STR);
    $stmt -> execute();
  } ?>

  <h1>１行掲示板</h1>

  <h2>投稿フォーム</h2>
  <form action="bbs.php" method="post">
    <label>投稿内容
      <input type="text" name="content">
    </label>
    <label>投稿者
      <input type="text" name="user_name">
    </label>
      <button type="submit">送信</button>
  </form>

  <h2>発言リスト</h2>
  <?php
  // データベースからデータを取得する
  $sql = "SELECT * FROM bbs ORDER BY updated_at;";
  $stmt = $pdo->prepare($sql);
  $stmt -> execute();
  ?>

  <table>
    <tr>
      <th>id</th>
        <th>日時</th>
        <th>投稿内容</th
        <th>投稿者</th>
        <th></th>
    </tr>
    <?php
    // 取得したデータを表示する
    while ($row = $stmt -> fetch(PDO::FETCH_ASSOC)) : ?>
      <tr>
        <td><?= $row["id"] ?></td>
        <td><?= $row["updated_at"] ?></td>
        <td><?= $row["content"] ?></td>
        <td><?= $row["user_name"] ?></td>
        <td>
            <form action="bbs.php" method="post">
              <input type="hidden" name="delete_id" value= <?= $row["id"] ?> >
              <button type="submit">削除</button>
            </form>
        </td>
      </tr>
    <?php endwhile; ?>
  </table>
</body>

</html>

```
javaでAtCoder Beginner Contest 175を解く

AtCoder Beginner Contest 175お疲れ様でした！
[公式ページ](https://atcoder.jp/contests/abc175)

今回の自分の書いたコードは[こちら](https://github.com/ko-flavor/atcoder-java/tree/master/atcoder/src/abc/abc175)
結果はA-CまでACできました。DもEもなんか難しかった・・・

以下簡単に解説します。

##[問題A](https://atcoder.jp/contests/abc175/tasks/abc175_a)

文字列が最大で何回連続しているかを答える問題。
`String.charAt()`
で指定文字取得して、愚直に条件文書きました。

##[問題B](https://atcoder.jp/contests/abc175/tasks/abc175_b)

3辺の長さが与えられて、それが三角形になるかどうかを出力する問題。
注意点として、同じ長さの辺は使用してはいけないことです。

計算量は気にせず3重ループでも十分間に合います。
3重ループ内はこんな感じ。まず辺の長さが同じものが無いかをチェックし、三角形かどうかを判定しました。

```java
if (first == second || second == third || third == first) {
	continue;
}
if (isTriangle(first, second, third)) {
	count++;
}
```
三角形かどうかの判定は以下のように行いました

```java
public static boolean isTriangle(int i, int j, int k) {
	int max = Math.max(i, j);
	max = Math.max(max, k);
	return i + j + k - max > max;
}
```
##[問題C](https://atcoder.jp/contests/abc175/tasks/abc175_c)

数直線上のXからK回Dだけ移動して、原点にどれだけ最も近い位置を出力する問題。
ちょっと図を書いてみると、Xに比べてKとDが小さいときはひたすら原点に向かって移動すればよく、
そうでない場合は偶数か奇数かで値が決まることが分かります。

ある程度Xに比べてKかDが十分大きいと、原点のまわりでうろちょろするようなイメージです。

また、X, K, D全て大きいので、むやみに掛け算を使わないのがポイントです。(オーバーフローしてしまいます。)
まずは、Xが十分大きいときの分岐はこのように書けます。

```java
if (x / d > k) {
	print(x - d * k);
	return;
}
```

そうでない場合は`x%d`か`d-x%d`を偶奇で判別して出力しましょう。
また、Xは負の値も取りうるので注意です。これでめちゃくちゃ手間取りました・・・

##[問題D](https://atcoder.jp/contests/abc175/tasks/abc175_d)

(後日追記)

##[問題E](https://atcoder.jp/contests/abc175/tasks/abc175_e)

(後日追記)

----

### 感想

20分寝坊しちゃったのもあり、最低パフォーマンス(592)でした、、
レーティングも4回連続低下し、930にorz

D問題とE問題はしっかり復習して、後日きちんと更新してソースコードも書きます・・・！
くやしー！

最後まで読んでくださり、ありがとうございます！
クロジャー

#クロジャー

returnで呼び出さずファンクションのオブジェクトをそのまま返す

結果を見るとオブジェクトの情報が記載されており、実行がされていない


![スクリーンショット 2020-08-15 22.14.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527694/2f3eb243-03a8-e004-dc59-046f02075f80.png)

この時点ではじめて実行される

![スクリーンショット 2020-08-15 22.17.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527694/e39b0bd9-9476-7bb7-7f82-eca790fcd7d1.png)

はじめに設定した引数をもとに
このように使い分けが可能
![スクリーンショット 2020-08-15 22.20.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527694/958de77c-d834-2eab-0b02-12f75e529090.png)

#デコレータ
関数を上書きする
例えば、関数を実行する前にスタート、エンドを付け加えたい時は。。。
![スクリーンショット 2020-08-15 22.38.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527694/c5b40e9f-4863-7315-2086-5c574b916234.png)

デコレーターを2つつなげると@で呼び出された順序で処理される
![スクリーンショット 2020-08-15 22.55.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527694/627473a3-fdb5-0ecf-5275-625034465917.png)


##メリット
一度作ってしまえば、
新しいファンクションを作って同じような操作をしたい時は@を付ければデコレーターが呼び出せる

![スクリーンショット 2020-08-15 22.47.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527694/50967ab9-94b3-8927-ac54-00445e5181ea.png)
【Laravel】ORM

こちらの記事は以下の書籍を参考にアウトプットとして執筆しました。
[PHPフレームワーク Laravel入門 第2版](https://www.amazon.co.jp/dp/B08625YD7H/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)

#Eloquentの基本
ORMによりDBのレコードをオブジェクトとして扱えるようになる

LaravelのORMはEloquent
##ORMとは
テーブルをクラスにように定義して、レコ0度をクラスにインスタンスのように扱うようにする仕組みによりPHPらしい操作をできるようにするための橋渡しの仕組み

##異なる仕組みへの橋渡し
ORMは互換性のないデータを変換して双方でやり取りができるようにする仕組み
DBからのレコードがPHPに渡されるとき、PHPのオブジェクトに形に変換
PHPからDBへ渡すときもレコードに変換する

##EloquentとORM
Eloquentは**モデル**というクラスを定義して、以降これを使ってDBを操作する
モデルはテーブルの内容を定義したクラスで、そのテーブル内のフィールドをプロパティとして持たせている。
これにより、テーブルとフィールドをモデルクラスとインスタンスを触る感覚で操作できる。
#モデル作成
```
php artisan make:model モデル名
```
上記コマンドで作成できる

以降ではpoepleテーブル操作するモデルPersonを作成して扱う。
##モデル名の命名規則
poepleテーブルのモデルがPersonになっているが、これはLaravelには「**テーブル名は複数形、モデルは単数形**」という命名規則があるため。
こうすることでテーブルとモデルと自動的に関連付けて動くようになっている。

##PersonControllerの作成
```
php artisan make:controller コントローラ名
```
#Personモデル
##前レコードの取得
```php5
$変数=Person::all();
```
取得されたレコードは`Illuminate\Database\Eloquent\Model`名前空間のCollectionクラスのインスタンスとして得られる。
これで全レコードをforeachで処理できる
##IDによる検索
```php5
$変数=モデルクラス::find(整数);
```
これでidによる検索ができるがプライマリキーの**フィールド名はidである必要がある**
###id以外のプライマリキーの場合
id以外のマナエで用意してしまった場合はモデルのプライマリキーの値を変更する。

モデルクラスの`$primaryKey`というプロパティを用意してこれにフィールド名を設定する。
これによりプライマリキーのフィールド名を変更できる。
pythonで英語の音声認識 [speech to text]

##英語を文字起こししよう
オンライン(wifiあり)での認識と、オフライン(wifi無し)での認識をそれぞれ紹介します。
####環境
ubuntu 18.04
python3

----

##オンラインでの認識

googleを使います.
環境構築は以下のコマンドでインストールします.

```sh:
pip3 install SpeechRecognition --user
sudo apt-get install portaudio19-dev
sudo apt-get install python-pyaudio python3-pyaudio
pip3 install pyaudio
```

動作確認

```python:google_test.py
import speech_recognition as sr  

# get audio from the microphone                                                                       
r = sr.Recognizer()                                                                                   
with sr.Microphone() as source:  
    r.adjust_for_ambient_noise(source)                                                                     
    print("Speak:")                                                                                   
    audio = r.listen(source)   

try:
    print("-----------detect!----------\n",r.recognize_google(audio))
except sr.UnknownValueError:
    print("Could not understand audio")
except sr.RequestError as e:
    print("Could not request results; {0}".format(e))
```
比較的精度もいいと思います

##オフラインでの認識
pocketsphinxを使用します。
環境構築は以下のコマンドでインストールします.

```sh:
sudo apt-get install -y python python-dev python-pip build-essential swig git libpulse-dev
sudo apt-get install libasound2-dev
git clone https://github.com/cmusphinx/pocketsphinx-python.git
sudo pip install pocketsphinx
```

動作確認

```python:pocket_test.py
from pocketsphinx import LiveSpeech
for phrase in LiveSpeech():
    print("-----------detect!----------\n",phrase) 
```
文字が出力されれば成功です。

"https://pypi.org/project/pocketsphinx/"
このページに色々なサンプルコードが載っているので参考にしてください.

----
pocketsphinxで、独自辞書というものを作成し精度を上げる↓(続き)
"https://qiita.com/hir-osechi/items/7d1b100c721f34896a90"
ポートフォリオ（Toretomo）解説

#アプリ概要
自分の住んでいる地域（現時点では大阪市内の区のみ）やカテゴリーなどから自分の理想のジムを探すことができ、それと同時にそれぞれのジムに契約または活動しているトレーナーを探せるアプリです。

下記ページで公開中です！
http://toretomo.work/

#制作背景
**筆者自身が困った経験、トレーナーとして勤務していた時の悩み、そして「一人でも多くの人にトレーニングの楽しさを伝えたい」という思い**が制作背景にあります。

具体的には

``` 
1. ジムとフリーのフリーのパーソナルトレーナーをまとめて見れるサイトがない
2. そもそもフリーのパーソナルトレーナーの認知度が低い
3. より多くの人にトレーニングの楽しさを知って欲しい
```

#1. ジムとフリーのパーソナルトレーナーをまとめて見れるサイトがない

筆者自身、大学生の時にボディビルの大会に出場するにあたって、**フリーのパーソナルトレーナーを探すのに苦労しました。**なぜならフリーのパーソナルトレーナーを探せるサービスと各地域にあるジムをまとめているサービスが別々だったからです。

トレーナーと連絡を取り、筆者が通っているジムに来れるのかどうか、さらにそのジムはパーソナル指導ができるのかという過程を経てやっと、フリーのパーソナルトレーナーにトレーニングの指導を受けていました。

**トレーナーとして働いていく中で見つけた課題**（２に関係します）も重なり、今でもそのようなサイトはなかったので、**「じゃ自分で作ってみよう！」と思ったのが一番大きな理由**です。

#2. そもそもフリーのパーソナルトレーナーの認知度が低い
トレーナーとして働いてみて気づいたことですが**フリーのパーソナルトレーナーの認知度はかなり低いです。**

フリーのパーソナルトレーナーとは、各々が契約しているジム、または利用可能であるジムであれば、そこで出張パーソナルを依頼できるトレーナーです。

退会する人を中心にフリーのパーソナルトレーナーを知っているのかを尋ねてみると、知っている方はほとんどいませんでした。パーソナルトレーナーの認知度はかなりあるのですが。。（おそらくRI○APのおかげ）

そこで**「ジムをまとめたサイトの各ジムの詳細ページにそのジムで利用可能なフリーのパーソナルトレーナーを載せれば便利なのではないか？」**と思い、**「それを実現できるサービスを作ってみたい」**と今回の作成に至りました。

#3. より多くの人にトレーニングの楽しさを知って欲しい

筆者自身、トレーニングを通して人生が変わりました。自信がつき、自己管理ができるようになり、目標ができるなど、様々なメリットがありました。それを一人でも多くの人たちに知ってもらいたくてトレーナーになりました。**しかしトレーナーが与えれる価値提供の範囲はジムにきてくださる方のみでした。**

**一人でも多くの方にトレーニングの楽しさを知ってもらいたい！**

この悩みを解決できるのが**Webサービスを作ること**でした。

#機能
```
ユーザー登録・ログイン機能(Devise)
管理画面(Active admin)
いいね機能
コメント機能
５段階評価機能(Raty)
一覧表示(一部にSwiper)
文字列省略機能(Readmore)
画像拡大機能(Lightbox2)
ページネーション(Kaminari)
検索機能(Ransack)
地図機能(Google MapとGeocoder)
お問い合わせフォーム(Action Mailer)
```
#ユーザー登録・ログイン機能(Devise)
ユーザーを登録することで、各ジムとトレーナーにいいねやコメントの投稿ができます。
#管理画面(Active admin)
ジム、トレーナー、ユーザーの情報の編集、登録、削除ができます。
#検索機能(Ransack)
・フリーワード検索
・カテゴリー、地域別での検索
・価格の絞り込み検索
・ソート機能（口コミの多い順、新着順など）
#ポイント
・現役のエンジニアにレビューをしてもらいフィードバックをもらった
・フリーのパーソナルトレーナーからの意見を取り入れた
・現場を想定し、実装する機能ごとにブランチを切って実装していった
・エラーが出てもサロンのメンターに頼らず、自力でYoutubeやQiitaの記事を参考に解決した
・開発に取り掛かる前に使用する機能、DBのアソシエーション、デザイン（Figmaを使用）などの準備をした
#使用技術・環境
・Ruby 2.6.5, Rails 5.2.4
・HTML, SCSS, Javascript, jQuery
・Nginx, unicorn
・AWS (EC2, S3, VPC ,Route53)
・MySQL
・Github

#最後に
最後まで読んでいただきましてありがとうございます！

初投稿は自身のポートフォリオの概要でしたが、これからは開発中に苦労したところや、気づいたことなどの投稿をしていこうと思います。
matplotlibで複数画像を表示させたい。

#実行環境
[Google Colaboratory](https://colab.research.google.com/notebooks/welcome.ipynb?hl=ja)

#Google Colaboratoryで画像を読み込む為の準備
```python:
from google.colab import files
from google.colab import drive
drive.mount('/content/drive')
img = cv2.imread("/content/drive/My Drive/Colab Notebooks/img/Lenna.bmp")
img2 = cv2.imread("/content/drive/My Drive/Colab Notebooks/img/Mandrill.bmp")
```

#必要なライブラリの読み込み
```python:
import cv2 #opencv
import matplotlib.pyplot as plt 
%matplotlib inline
```

#コードの確認

```python:
#新規ウインドウ作成
fig = plt.figure()

#flg全体をX*Yに分割し、plot位置に画像を配置する。
X = 2
Y = 2


#imgの表示
imgplot = 1
ax1 = fig.add_subplot(X, Y, imgplot)
#タイトルの設定
ax1.set_title("img",fontsize=20)
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))


#img2の表示
img2plot =  4
ax2 = fig.add_subplot(X, Y, img2plot)
#タイトルの設定
ax2.set_title("img2",fontsize=20)
plt.imshow(cv2.cvtColor(img2, cv2.COLOR_BGR2RGB))

plt.show() #なくても表示された。
```
#結果
![q2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610285/89a20257-938e-a461-2c56-ba51eea45cb9.png)
※青色線、青文字はペイントで加筆したもの。

これで、今後の動作結果の比較記事とか書きやすそう！
IBM Cloud: Transit Gatewayの作成場所によってVPC間通信のlatencyが変わるか確認してみた

#1. はじめに

IBM CloudのTransit GatewayはVPC間やClassic Infrastructureとの間の通信を可能としてくれる。しかし、このTransit Gatewayは、以下のように実際にはロケーションを意識して作成する必要があるようだ。

- VPC-A(Tokyo1)-VPC-B(Tokyo1)間を東京(Japan)に配置するTransit Gateway経由で通信するケース
- VPC-A(Tokyo1)-VPC-B(Tokyo1)間をダラス(U.S.)に配置するTransit Gateway経由で通信するケース

でlatencyの差が出るのかを確認してみた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/aabec5d6-1295-74a0-998f-d33936076dd5.png)

#2. 検証結果
##2-1. 東京(Japan)のTransit Gatewayを利用する場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/8b332cfd-7a5d-ec76-c869-284df5e90fb7.png)

```
[root@syasuda5-vpc1 ~]# ping 172.16.0.4
PING 172.16.0.4 (172.16.0.4) 56(84) bytes of data.
64 bytes from 172.16.0.4: icmp_seq=1 ttl=59 time=0.711 ms
64 bytes from 172.16.0.4: icmp_seq=2 ttl=59 time=0.728 ms
64 bytes from 172.16.0.4: icmp_seq=3 ttl=59 time=0.689 ms
64 bytes from 172.16.0.4: icmp_seq=4 ttl=59 time=0.739 ms
64 bytes from 172.16.0.4: icmp_seq=5 ttl=59 time=0.614 ms
64 bytes from 172.16.0.4: icmp_seq=6 ttl=59 time=0.552 ms
64 bytes from 172.16.0.4: icmp_seq=7 ttl=59 time=0.674 ms
64 bytes from 172.16.0.4: icmp_seq=8 ttl=59 time=0.640 ms
```

##2-2. ダラス(U.S)のTransit Gatewayを利用する場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/bed71469-02b8-4157-7c38-2b9b1de54013.png)

```
[root@syasuda5-vpc1 ~]# ping 172.16.0.4
PING 172.16.0.4 (172.16.0.4) 56(84) bytes of data.
64 bytes from 172.16.0.4: icmp_seq=1 ttl=43 time=275 ms
64 bytes from 172.16.0.4: icmp_seq=2 ttl=43 time=275 ms
64 bytes from 172.16.0.4: icmp_seq=3 ttl=43 time=275 ms
64 bytes from 172.16.0.4: icmp_seq=4 ttl=43 time=275 ms
64 bytes from 172.16.0.4: icmp_seq=5 ttl=43 time=275 ms
64 bytes from 172.16.0.4: icmp_seq=6 ttl=43 time=275 ms
```

#まとめ
ダラスのTransit Gatewayを使った場合は、同じDC間の通信なのにRTTが275msecもかかっているため、やはりダラスまでの往復が発生していると思われる。
2020/08現在では、1つのVPCは1つのTransit Gatewayにしか接続できない。もちろん東京Region内のVPC間接続だったり、２拠点間のVPC接続であればそれほどTransit Gatewayの配置場所は悩まないだろうが、複数拠点間でのVPC接続の場合はどこにTransit Gatewayを作成するかは考えた方がいいかもしれない。
【Drupal】Drupalをローカル環境にインストールする

業務で[Drupal](https://www.drupal.org/)を使ったWebサイト構築をすることになりました。
検証やら調査やらでローカル環境にDrupalをインストールしたので、備忘録も兼ねてやり方をご紹介します。

# Acquia Dev Desktopのインストール
ローカルでDrupalを動かすために、[Acquia Dev Desktop](https://www.acquia.com/jp/drupal/acquia-dev-desktop)というものを使います。
通常Webサイトを作るとなるとWebサーバーとかDBを準備する作業がありますが、
Acquia Dev Desktopを使えばApacheやらMySQL、PHPなんかを全部用意してくれるわけです。
Drupal向けの統合開発環境みたいなものですね。
[こちら](https://dev.acquia.com/downloads)からダウンロードしてください。


## インストーラーの実行
ダウンロードしたら実行してAcquia Dec Desktopをインストールします。
![スクリーンショット-2020-04-29-16.07.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622183/0a081da3-3a5c-7849-325f-8d255d58fa6e.png)

基本的にNextを選んでいけば問題ないです。
途中Acquia Dev Desktopのインストールフォルダを聞かれますが、お好みで設定してください。


## Drupalのダウンロード
Acquia Dev Desktopのインストールが完了したら、
画面左下の「New Drupal Site...」を選択します。
![スクリーンショット-2020-04-29-16.16.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622183/63f679d2-39c4-6ee9-6461-5047c7a1d048.png)

次にダウンロードするものを聞かれますので、「Drupal8」を選択します。
![スクリーンショット-2020-04-29-16.16.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622183/8a2735cc-d027-8d63-5593-ed9dfce6c4b5.png)

ダウンロード時のミドルウェアの簡単な設定です。
![スクリーンショット-2020-04-29-16.17.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622183/60ee169f-db3c-e548-ebf7-ccf0a5e77030.png)

| 項目              |説明                             | 
|:-----------      |------------:                     |
| Local code base  | Drupalのコアファイルを保存する場所      |
| Local site name  | Acquia Dev Desktopの管理用ラベル    |
| Use PHP          | 使用するPHPのバージョン               |
| Database         | 基本的に「Create a new database」でOK|
| New database name| データベースの名前                   | 

完了した「Finish」を選択。

## Drupalのインストール
ダウンロードが完了するとAcquia Dev Desktopのトップ画面に今ダウンロードしたDrupalが表示されます。
「Local site」をクリックして、Drupalをインストールします。
![スクリーンショット-2020-04-29-16.19.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622183/e68b18e4-5b65-abd7-c7f9-4e00d9648d96.png)


まず言語の設定をします。日本語で良いでしょう。
![スクリーンショット-2020-04-29-16.21.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622183/ca09710e-9e87-9e3a-2d5f-bac771f246cf.png)

次にインストールプロフィールを選択します。ここでは「標準」を選択します。
![スクリーンショット-2020-04-29-16.23.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622183/990cc8c4-48c8-b23f-6f1f-6f5c95be4dd4.png)

最後に作成するサイトの基本設定を行います。
サイト名やら管理者（admin）の設定やらをします。
メールアドレスを入力する欄がありますが、特にメールが送られてきたりはしません。
![スクリーンショット-2020-04-29-16.25.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622183/b2248d23-eae5-4b40-5d73-cba1fe68032e.png)
ここで設定する項目は後でいつでも変えられます。


で、これで終わりです。
![スクリーンショット-2020-04-29-16.27.29-2048x914.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622183/9118b0ea-8969-559e-7fe8-0a9f40c79110.png)


あとは好きなようにコンテンツやブロックを作ったり、カスタムテーマを入れてみたり、モジュールを入れてみたり遊んでみてください。
AcquiaDevDesktopを使えば複雑な設定なしに、簡単に、ローカルでDrupalサイトを構築できるようになります。
是非試してください。
高専キャリアとマイクロソフトがコラボしたクラウドAI開発講座進捗報告[7]

# クラウドAI開発講座進捗報告- 7週目

[これ](https://qiita.com/teruto725/items/222b011a8dd63bf76158)の続き

さあそろそろ8月終わりの締め切りが近づいてきました。
学校の夏休み課題、卒論等、8月の終わりは修羅場と化しそうなのは目に見えています。
そんな修羅場で確実に倒すのに時間がかかりそうな敵はこいつです（いい意味で！）。
なのである程度攻略のめどをつけておきたいわけです。
というわけで今週の進捗です！！！
なんだかブログ書くのが楽しくなってきてちょっとテンション高めです笑。


## やったこと
### 1. Teamsで画像を読み込めないエラー
emulator上では読み込めてるんだけど、teams上では読み取れないっていう現象に陥っていた。
メンターさんが解決してくださった。
emulator上とteams上で画像の形式が違うっぽくて、専用のコードに書き換えたらできた！
manifest.jsonにsupportFiles=trueと追加する必要があります。
コードは以下参照

```python
public async Task<List<string>> getPictureUrls()//pictureのstreamを取得する
        {
            List<string> urls = new List<string>();
            foreach( Attachment attachment in turnContext.Activity.Attachments)
            {
                bool messageWithFileDownloadInfo = attachment.ContentType == FileDownloadInfo.ContentType;
                if (messageWithFileDownloadInfo)
                {
                    var file = turnContext.Activity.Attachments[0];
                    var fileDownload = JObject.FromObject(file.Content).ToObject<FileDownloadInfo>();

                    string filePath = Path.Combine("Files", file.Name);//保存先

                    var client = _clientFactory.CreateClient();
                    var response = await client.GetAsync(fileDownload.DownloadUrl);
                    using (var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None))
                    {
                        await response.Content.CopyToAsync(fileStream);
                        urls.Add(filePath);
                    }
                }
            }
            return urls;
        }
```

これでできたんだけど今度はAzureのwebappにデプロイしたら動かなくなった。
これもメンターさんが解決してくださった。本当にありがたい！

webappにデプロイするファイルの中にFilesフォルダが含まれておらず、高度なツール＞CMDからディレクトリにアクセスし、filesフォルダにアクセスすることで動くことが確認できた。



### 2. リアクションの取得
teamsのリアクション（いいねとか、ハートとか）を取得したかったので公式ドキュメントでしらべるとできるみたい。ただいろいろ調べたがどのメッセージに対してのリアクションなのかは判断できなくて単純にアクションに対応した文字列が取得できるだけ（たぶん）。
コードはこんな感じ。

```python
public class TeamsFileUploadBot : TeamsActivityHandler
{
　　　　protected override async Task OnMessageReactionActivityAsync(ITurnContext<IMessageReactionActivity> turnContext, System.Threading.CancellationToken cancellationToken)
        {
　　　　　　　　//リアクションに対応した文字列取得
              String reactType = turnContext.Activity.ReactionsAdded[0].Type;
        }
}
```


### 3. コーディング
今の進捗はこんな感じです。
だいぶできてきましたね。完成度は70%くらいでしょうか。
さすがに何作ってるかはばれそう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573723/f8ed9bcc-e68a-670c-65a0-cad6ef0cb023.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573723/7e01ce9a-b457-4c77-e300-15ca2d89b907.png)



## 来週の予定
コーディング！！とりあえず基本的な機能は来週中に全部完成させたい。
HTMLだけでherokuにdeployしてサイトが見えるようにしよう！

herokuに初めてdeployしようとしたとき

あれ、vscodeのlive viewerではページ開くのにdeployできないなということがあると思います

https://qiita.com/Hai-dozo/items/f0829dd121f477754b98

ほぼほぼこの記事の内容になりますが

htmlだけのフォルダに

記事にあるように　index.php

と
package.jsonを追加しましょう

それぞれ内容は

index.php
> <?php include_once("index.html"); ?>

package.json
> {}

です！

良いherokuライフを！
【Python】Djangoプロジェクトに UIKit3 を導入する

#はじめに
DjangoプロジェクトにCSSフレームワークである
**UIKit3** を導入していきます。

##UIKit3
[UIKit](https://getuikit.com/) は、CSSフレームワークの１つ。
知名度ではBootstrapやFoundationにはやや劣るものの
シンプルなデザインで人気のフレームワークです。

クラス名が`uk-`で始まるように統一されており、
他のCSSとコンフリクションが起きにくいのも良いポイントです。

##UIKitをダウンロード
ダウンロードは [こちら](https://getuikit.com/) から。

zipファイルを解凍して、
今回は下記の３ファイルを使用します。

>uikit-3.5.6/
>　├ css/
>　│　└ uikit.min.css
>　└ lib/
>　 　└ uikit-icons.min.js
>　 　└ uikit.min.js

※UIKitのバージョンは3.5.6

##staticディレクトリを作成
プロジェクトディレクトリ直下に`static`ディレクトリを作成し、
下記のようにファイルを格納します。

>[projectname]/
>　├ [projectname]/
>　├ static/
>　│　└ css/
>　│　│  └ uikit.min.css
>　│　└ js/
>　│　 　└ uikit.min.css
>　│　 　└ uikit.min.css
>　└ manage.py

##settings.pyを変更
`[projectname]/settings.py` に'static'ディレクトリの情報を定義します。

```Python:settings.py
STATICFILES_DIRS = (
	os.path.join(BASE_DIR, 'static'),
)
```

##staticを読み込む

Point1:
>`{% load static %}`
>loadタグを使ってstaticタグを使用できるようにします。

Point2:
>`{% static '[css or js]/[filenama]' %}`
>staticタグを使って静的ファイルのパスを相対パスで定義できます。

Point3:
>`UIKitを読み込む`
>\<link href="{% static 'css/uikit.min.css' %}" rel="stylesheet">
>\<script src="{% static 'js/uikit.min.js' %}"></script>
>\<script src="{% static 'js/uikit-icons.min.js' %}"></script>
>
>公式ドキュメント：https://getuikit.com/docs/introduction#html-markup



試しに[ドロップダウンリスト](https://getuikit.com/docs/button#button-group-with-dropdowns)を表示してみます。
画面をスクショする関係でmarginが欲しかったので、
`uk-margin-top`なども使ってみました。

```html:uikit-sample.html
{% load static %}

<!DOCTYPE html>
<html lang="ja">
<head>
    <title>TEST</title>

    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <link href="{% static 'css/uikit.min.css' %}" rel="stylesheet">
    <script src="{% static 'js/uikit.min.js' %}"></script>
    <script src="{% static 'js/uikit-icons.min.js' %}"></script>
</head>
<body>
    <h1 class="uk-margin-top uk-margin-left">UIKit サンプル</h1>

    <div class="uk-button-group uk-margin-left">
        <button class="uk-button uk-button-default">Dropdown</button>
        <div class="uk-inline">
            <button class="uk-button uk-button-default" type="button"><span uk-icon="icon:  triangle-down"></span></button>
            <div uk-dropdown="mode: click; boundary: ! .uk-button-group; boundary-align: true;">
                <ul class="uk-nav uk-dropdown-nav">
                    <li class="uk-active"><a href="#">Active</a></li>
                    <li><a href="#">Item</a></li>
                    <li class="uk-nav-header">Header</li>
                    <li><a href="#">Item</a></li>
                    <li><a href="#">Item</a></li>
                    <li class="uk-nav-divider"></li>
                    <li><a href="#">Item</a></li>
                </ul>
            </div>
        </div>
    </div>

</body>
</html>
```

無事に表示されました。
シンプルで良い感じです！
![uikit-dropdown.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641252/f1219a53-d93d-6b27-5205-9471b3dee954.png)

##おわりに
UIKitを導入する機会がありましたので、まとめてみました。

まだまだUIkitを使いこなせていませんが、前述したように
クラス名が`uk-`で統一されているのは非常に使いやすいです。
【初心者でもわかる】自分のホームぺージにメールアドレスをそのまま載せるのは危険！

# どうも7noteです。メールアドレスはエンティティ化して掲載が基本

どうも7noteです。
この記事は以下へ引っ越しました。

https://naruweb.com/tool/entity/
git stash関連のコマンド（備忘録）

ブランチを切り替えるのを忘れてしまったり、`git pull`するのを忘れてしまったりと、
気をつけていてもやらかしてしまうことありますよね。

そんなときの強い味方、`git stash`のコマンドの備忘録です。

# コードを退避する

```
git stash 

Saved working directory and index state WIP on master: ....
```

# 一覧を見る

```
git stash list

stash@{0}: WIP on master: 8af0e2a Merge branch ....
stash@{1}: WIP on master: c8743b8 Merge branch ....
stash@{2}: WIP on master: 49a6d3c Merge branch ....
```

# stashを適用する（stashを適用後、残す場合）

```
git stash apply stash@{n}
```

# stashを適用する（stashを適用後、削除する場合）

```
git stash pop stash@{n} 
```

# stashを削除する

```
git stash drop stash@{n}

Dropped refs/stash@{0} (2aaab50a6a629d3f9cac314f4491dac85231583f)
```

<br>
<br>
[VSCode] settings.jsonをショートカットキーで開けるようにする

デフォルトの設定だとsettings.jsonを開くショートカットキーが設定されていません。
そのため、settings.jsonを開くためには
**`ctrl + ,`で設定画面を開く > 右上のファイルアイコンをクリック**
というように一度設定画面を開く必要がありやや面倒です。
そこで以下の方法でショートカットキーの登録をすることで簡単にsettings.jsonを開けるようにしました。

# 方法

**1. ショートカットキーの設定画面を開く**
コマンドパレットを開く。
`keyboard`と入力して`Preferences: Keyboard Shortcuts`を選択してショートカットキーの設定画面を開く。
`ctrl + K ` `ctrl + S`(macなら`cmd + k` `cmd + S`)でも開ける。

**2. settings.jsonを開くコマンドを検索**
`opensettings`と検索して`Preferences: Open Settings(JSON)`を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618785/3c817b7f-3075-0941-a923-08d9ad453bb2.png)

**3. ショートカットキーの登録**
コマンドの上でダブルクリックまたは`ctrl + K` `ctrl + K`でポップアップを表示。
登録したいキーをタイプしてエンター。

これでショートカットキーが登録され直接settings.jsonを開けるようになります。

# 追記

別の方法をコメントで教えて頂きました。
settings.jsonに以下の設定を加えれば`ctrl + ,`(macなら`command + ,`)でsettings.jsonが開けるようになります。
UIの設定画面が`ctrl + ,`で開けなくなりますが、ショートカットキーの設定を変更する必要が無いため、UIの方をあまり使ってない人には便利かもしれません。

```json:settings.json
{
  "workbench.settings.editor": "json"
}
```

@katsuya_Uさん情報ありがとうございます。
JRE環境でスレッドダンプを取る

JREでアプリを動かしてるWindowsサーバで、スレッドダンプを取得する要件が発生した。
考えること、多い

- JDKなら普通に取れるけど、JREだとjstackは存在しないので、JDKインストールしないといけない? 
- JREで動いてるアプリを、別のパスでインストールしたJDKでスレッドダンプ取れんのか?
- アプリをJDKで動かさないといけないんじゃ?
- JREはそのままにしてJDKを追加でインストールする? Pathとか気を付けないと
- JREとJDKはver合わせないとだよね

色々わからないので、ためしにどういうエラーメッセージでるのかなーと、適当なJDKダウンロードしてきて、適当なJavaアプリにjstack仕掛けてみる
と思ったが、適当なJavaアプリがないので、EclipseがJavaで動いてることを思い出して、試しにEclipse (eclipse.exe) にやってみる
#動いた
 (スレッドダンプ取れた) 
↑見出しの間違った使い方 (でかい文字にしたかったが方法がこれしかない残念)

eclipse.exeがどのverのどういうJava実行環境なのか全然知らないが、これで分かった
jstackは適当でも全然動く
jstackと取得対象のjavaとで、パスとかverとか違っても全然大丈夫だ

次に本番での取得を想定して検証してく

- JREでアプリが動いてる社内サーバに
- 同じverのJDKをダウンロードしてきてインストールして
- コマンドプロンプトでJDKにpathを通して、JREアプリに対してスレッドダンプ取得

これもOK

じゃさらにつっこんで、jstack.exeとライブラリだけコピって実行できるか試してみる

- JREのbinに、JDKのbinのjstack.exeをコピー
- JREのlibに、JDKのlibのtools.jarをコピー
- JREのbinにコピーしたjstackでJREで動かしてるアプリにスレッドダンプ取得
- エラー

```
java.util.ServiceConfigurationError: com.sun.tools.attach.spi.AttachProvider: Provider sun.tools.attach.WindowsAttachProvider could not be instantiated
1548: no providers installed
```

(すいません、最初の投稿でいけたと書きましたが、あとからやり直してみるとやっぱだめでした)

ということで、JDKのインストールは必要なものの、jstackさんであれば、JRE相手でも簡単にスレッドダンプが取れることが分かりました

(備考)

- そもそも最初からJDK使えばいんだけどね..
- コマンドはこれだけ

```
jstack -l <PID>
```

- tools.jarを配置しないとこんなエラーがでた
    - ここにでてるメッセージでlibをあさったらtoolsってのがあったので、置いたら次に進んだ(雑)

```
エラー: メイン・クラスsun.tools.jstack.JStackが見つからなかったかロードできませんでした
```

おしまい
ImageHashのみで類似画像検知ができるか？

# はじめに
ImageHashのハミング距離が **0** が同一画像、 **1～10** が潜在的に似ている画像とのことだが、
ImageHashのみで類似画像検知ができるか再確認する。

# ソースコード
ハッシュは、dhushを使用する。

参考:
https://tech.unifa-e.com/entry/2017/11/27/111546

```python:sample.py
import imagehash
from PIL import Image

hash1 = imagehash.dhash(Image.open('./images/001.png'))
hash2 = imagehash.dhash(Image.open('./images/002.png'))
hash3 = imagehash.dhash(Image.open('./images/003.png'))

print(hash1, hash2, hash3)

print('001.png:002.png - {}'.format(hash1 - hash2))
print('001.png:003.png - {}'.format(hash1 - hash3))
print('002.png:003.png - {}'.format(hash2 - hash3))
```

## 使用した画像

本プログラムでは以下の画像を使用する。
002.png と 003.png は似た画像を選び、
001.png は、ポーズは違うが中央にキャラクターがいる構図は同じ様になっている。

| 1 | 2 | 3 |
|:-:|:-:|:-:|
| ![001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202825/3bdd4232-b79f-23d6-c9a4-6d9f5deb138f.png) | ![002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202825/43c52a6c-3ed0-b910-f9d0-469b8116860f.png) | ![003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202825/ee319d16-ba10-e37d-c2d2-faefa1a59c65.png)   |
| 001.png | 002.png | 003.png |

## 実行結果
001.pngとほかの画像のハミング距離は、それぞれ16と12となっていて大きく異なっている。
002.pngと003.pngはハミング距離が8となっている。
通常「1～10」が潜在的に似ている画像とのことだが、全く異なる画像であるため誤検知といえる。
[先日の投稿](https://qiita.com/haho-haho/items/cf9451fe3a943167a418)でも記載したが、Imagehashのみで類似画像を判定させるというのは難しいといえる。

```bash
3868e0f870706979 a269e8e8f0f4f070 b860e0e8f1f0f070
001.png:002.png - 16
001.png:003.png - 12
002.png:003.png - 8
```
Submitボタンをクリックしたときに出る青い枠線を消す方法

htmlでSubmitボタンをクリックしたあと、ボタンに青い枠線が出しまうのを回避する方法を紹介します。

`クリック前`
![Bildschirmfoto 2020-08-15 um 15.02.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626057/8456b09f-e24e-c206-0880-e414cadf802b.png)


`クリック後`
![Bildschirmfoto 2020-08-15 um 15.02.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626057/183d3bf3-3729-6a6a-e783-d191f2d8001f.png)


# cssに以下のコードを追加する
```css
#formbtn:focus{
    outline:0;
}
```

`#formbtn`はボタンのidなので、環境に合わせて変えてください。

<br>
<br>
pythonで音声発話 [text to speech]

##音声発話させよう

####環境
ubuntu 18.04
python3

----
##日本語を発話
日本語の発話はOpenJtalkでできます、以下のQiitaが分かりやすいです.
[OpenJTalk + python で日本語テキストを発話](https://qiita.com/kkoba84/items/b828229c374a249965a9) 

----
##英語を発話
英語での音声発話は, espeakとsvoxpico を紹介します.


####espeak

環境構築は以下のコマンドでインストールします.

```
$sudo apt-get install espeak
```

動作確認

```python:
from subprocess import call
call(["espeak","hello world"])
```
---
####svoxpico

環境構築は以下のコマンドでインストールします.

```
sudo apt-get install -y libttspico-utils
```

動作確認
注意！ファイル名はmodule_pico.pyにしています、
他の名前で作成する場合、# Define path の部分を変えないと動作しません.

```python:module_pico.py
import os
import subprocess
file_path = os.path.abspath(__file__)

# Define path
speech_wave = file_path.replace('/module_pico.py', '/speech.wav')

def speak(content):
    print("[*] SPEAK : {0}".format(content),flush=True)
    #subprocess.call('amixer sset Master 90% -q --quiet', shell=True)  # big voice
    subprocess.call(['pico2wave', '-w={}'.format(speech_wave), content])
    subprocess.call('aplay -q --quiet {}'.format(speech_wave), shell=True)
    #subprocess.call('amixer sset Master 75% -q --quiet', shell=True)  # default voice

if __name__ == '__main__':
    speak("I like apple!")

```

----
モジュールとして使う場合、同じフォルダ内で以下のようにすれば発話できます。
ファイル名は気にしなくて大丈夫です。

```python:test.py
import module_pico
    module_pico.speak("I like apple!")
```
Redmine Wiki を GitLab Wiki に変換する

[Trac/Redmine+Subversion+Jenkinsなどを捨ててGitLabに移行するまでの道のり](https://qiita.com/hkato/items/3ddfe72985f7536bdf97)

つづき

Trac Wiki からは MkDocsで GitLab Pagesだが[こちら](https://qiita.com/hkato/items/c567bb76e538564f3307)の記事を書いている。

## [Redmine to Gitlab migrator](https://github.com/redmine-gitlab-migrator/redmine-gitlab-migrator)

- 開発者の引き継ぎが完了しておらずPyPIをアップデートできずv1.0.2は古いまま(2015)
- ~~これを書いている時点でもうまく動かなかった(v1.0.3)~~
   - ~~Wikiが上書きされてしまう~~
- ~~[バグ報告](https://github.com/redmine-gitlab-migrator/redmine-gitlab-migrator/issues/57)と[Pull request](https://github.com/redmine-gitlab-migrator/redmine-gitlab-migrator/pull/58)を送ってる(これ書いてる時点で未適用)~~
- 添付ファイルには非対応

とりあえず、 Textile で書かれた Wiki のテキスト内容だけはざっくり移行できた。

### 問題点と修正

Redmine ではデフォルトでトップページが `Wiki` になると思うが、 GitLab ではデフォルトのトップページは `home.md` 。 上記変換ツールは親ページがないものを `home.md` に置き換えるので、複数トップページがある場合(親のWikiページが無い場合) `home.md` をどんどん上書きしていた。ここらへんに対応しておいた。採用されるかは不明。

## 変換方法

### 変換ツールの準備 ~~(+パッチ適用)~~

~~上記の`redmine-gitlab-migrator`にパッチをあてたものを用意。
あるいは[私の修正版](https://github.com/hkato/redmine-gitlab-migrator/tree/fix-wiki-start-overwrite)を利用。~~

マージされました。PyPIのものは古いので、

```sh
$ pip install git+https://github.com/redmine-gitlab-migrator/redmine-gitlab-migrator
```


### Wiki リポジトリーの準備

GitLab の Wiki は Git リポジトリーに Markdown ファイルを格納し、それをWeb上のエディタで編集することにより実装されている。(ここは、GitLab Pagesにするか悩みどころ)

既に、[Milestone/Issueの移行](https://qiita.com/hkato/items/0d79813824cb7d563d66)などで移行済みのプロジェクトの Wiki ローカルに clone する。

プロジェクトの右ペインの Wiki を選ぶと、まだ Wiki がないと思うので次のような画面が表示される。

![empty-wiki.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132537/754b533f-ef1e-92e3-47bc-8c070517e1c2.png)


これをCreateすると `Home` ができるので仮の内容を書いて作成する(空だと作成できない）。

これにより、 Wiki 専用の Git リポジトリーが作成されるので、これを clone する。

![repo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132537/88e9f6b8-cc8c-598d-fe4f-e6083f84619c.png)

リンクをたどればわかると思うが`git@gitlab.example.com:namespace/project.wiki.git` のような、プロジェクト名に `.wiki.git` が付与された URL になるので、

```sh
$ git clone git@gitlab.example.com:namespace/project.wiki.git
```

などで、ローカルに取得(以下 `~/tmp/project.wiki` に clone したとする)。

### Wiki 変換

すでにMilestone/Issueを変換していれば、APIキーも取得済みだと思うので、同じ手順で、 GitLab Wiki のローカルリポジトリパスと Redmine プロジェクトの URL を指定。

```sh
$ migrate-rg pages --redmine-key my_redmine_api_key \
  --gitlab-wiki ~/tmp/project.wiki \
  https://redmine.example.com/projects/ｐroject
```

すると、ローカルリポジトリーに Redmine Textile Wiki から Markdown に変換したものが git add & commit されていく。

### 適用

内容を確認し問題がなければ、

```sh
$ git push -u origin
```

などでリモート側に適用すれば、

Redmine上だと、だったものが

![redmine-wiki.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132537/cf071474-de5f-11f2-c913-b8af8e26cf1d.png)

こんな形に変換される

![gitlab-wiki.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132537/475a367b-f447-0dc6-1b40-68bd1ba50d27.png)

## おわり

週末自宅開発なので本番環境でテストしておらず、テストデータだけだが、多分こんな感じでいけるはず。
Diginnos Stick DG-STK1 に Ubuntu20をインストール

Diginnos Stick DG-STK1 に Ubuntu20をインストールします。

まずはじめに、unetbootin などを用いて USB から起動インストールできる ubuntu20 を作成。

32bit 用の efi ファイルをを usb メモリ内の /boot/efi に配置する

ファイルはこちら
https://github.com/jfwells/linux-asus-t100ta/blob/master/boot/bootia32.efi

live usb から起動を行う

live な ubuntu が起動したら端末（Terminal）を開いて下記コマンドを実行する

````
sudo ubiquity -b
````

※-bオプションはgrubインストールをスキップの意味

インストールが終わったらエンターキーを押して再起動を行う。
このときUSBメモリは抜かないで指したままにしておく

起動すると grub メニューが表示されるので c キーを押してコマンドラインモードにする

````
grub> set root=(hd1,gpt2)
grub> linux /boot/vmlinuz root=/dev/mmcblk1p2
grub> initrd /boot/initrd.img
grub> boot
````

これで ubuntu が手動で boot される。

次に起動した ubuntu の端末（Terminal）から grub を設定更新する。

````
sudo apt-get update
sudo apt-get install grub2-common grub-efi-ia32
sudo grub-install --efi-directory=/boot/efi
sudo update-grub
````

これで再起動すると普通に ubuntu が起動するようになる。

参考リンク

32bit UEFIのPCに64bit版Ubuntu18.04をインストールする | e-DIYで行こう! 
https://blog.goediy.com/?p=440

32bit UEFI搭載の2in1にLinuxをぶち込んだお話 | ちゃろのガジェット日記 
https://ameblo.jp/cirno76/entry-12189828057.html

YOGA Tablet 2にUbuntu 20.04 LTSをインストールする（32bit UEFIの問題回避） | ヒト・ログ・ドライブ 
https://hito-log.com/2019/05/27/post-9196/
またPHPビルドしてる

MacでPHPをビルドできなくて困ったのでまたメモをとる

# 基本的に
この辺がいる。
特にconfiigureオプションとか入れないといけないものを書く。

* oniguruma
* curl
* openssl
* libxml
* pkg-config
* zlib
* libiconv
* php

# openssl
configureしてmake installするのだが
```
 ./Configure --prefix=$HOME shared darwin64-x86_64-cc
```
と書く。

# libxml2
普通にconfigureしてmake installする。
僕はインストール時にシステム領域に入れたくないので、prefix=$HOMEとしているが、それをするとシステム領域にあるPythonに書きに行くので死ぬ。
行儀は悪いが、

```
sudo chown -R sato /Library/Python/
```

とした
# pkg-config
こんなかんじでconfigureする。

```
env LDFLAGS="-framework CoreFoundation -framework Carbon" ./configure --with-internal-glib --prefix=$HOME
```

# PHP
本丸。こんな感じ。

```
./configure --prefix=$HOME --with-curl --with-zlib --with-openssl --with-iconv=$HOME --without-mysqli --without-sqlite3 --without-pdo-sqlite --enable-mbstring --enable-cli --enable-fpm
```
vi ユーザーのための VScode キーボード ショートカット

# vi ユーザーのための自分用メモ

昔はViViなどを使っていたけれど、とうとうIDEになってしまった。。

## 単語単位で移動
> (vi) w または b
 (vscode) Ctrl + 矢印キー

## 単語を選択

> (vi) cw
 (vscode) Ctrl + D


## 指定行番号に移動

30行目に行くには、

> (vi) 30G
 (vscode) Ctrl + G 30

## カーソル行を削除

> (vi) ^D
  (vscode) Ctrl+Shift+K 

## 指定したキーワードを含む行を削除

> (vi)  :g/Hoge/d
 (vscode)
 1. キーワード検索
 Ctrl + F で"Hoge"と入力
 2. 検索結果を全選択
 Alt + Enter
  3. 選択行を削除
 Ctrl + Shif + k
 

## インデントを上げる、下げる

> (vi) >>
 (vscode) Tab
 (vi) <<
 (vscode) Shift + Tab

# 対応するカッコに移動

> (vi) %
 (vscode) ctrl+shift+\ 

## 分割したウィンドウを切り替える
> (vi) Ctrl-w + D
 (vscode) Ctrl + (1～9)

# see also
* https://qiita.com/12345/items/64f4372fbca041e949d0