OmniAICreator/Qiita-1.07M huggingface dataset:
Logging function with automatic call path/function with CustomDebugStringConvertible

It is convenient to use a static logging function which automatically prints both the values of the parameters, but also details about where the log call was made, to aid debugging.

e.g. call at line 999 in function someFunctionName() in file User/QiitaUser/project/someFileName.swift 

```swift
log(someDouble, someCustomObject) 
```

The Xcode Application output is:

```swift
someFileName -> line 999 -> someFunctionName -> someDouble, someCustomObject values...
```

Here, we take advantage the protocol CustomDebugStringConvertible. All native types (string, double) conform to this protocol, and so will show useful information when printing e.g. someDouble.debugDescription, String(reflecting: someDouble). It is also simple to conform custom objects to this protocol in their definition. 

See https://developer.apple.com/documentation/swift/customdebugstringconvertible for official implementation details for CustomDebugStringConvertible

```swift

// call the function with the "args" paremter only - the other paramters are assigned automatically 
static func log(_ args: Any?..., tag: String = "", file: String = #file, function: String = #function, line: Int = #line) {
  
// define a value for DEBUG_LOGGING in Build Settings -> Active Compilation Conditions for the debug target
#if DEBUG_LOGGING
        
   // extract the calling filename from the complete path, or the complete path, as necessary
   let parsedFileName = String(file.split(separator: "/").last?.split(separator: ".").first ?? "")
   let fileName = (parsedFileName.isEmpty) ? file : parsedFileName

   // extract the calling function name from a string containing the arguments and enclosing brackets
   let functionName = String(function.split(separator: "(").first ?? "")

   // this line defines the location of the log statement
   let header = fileName + "-> line " + String(line) + " -> " + functionName 
               
   // extract the arguments which conform to CustomDebugStringConvertible, and combine their
   // descriptions via reflection
   let argsAsString = args
      .compactMap{$0 as? CustomDebugStringConvertible}
      .map{
         String(reflecting: $0).replacingOccurrences(of: "Optional", with: "")
      }
      .joined(separator: " ")
        
   // print to the Application Output
   Swift.print(text + " " + argsAsString)

#endif
}
```
Chart.jsでメモリ間隔の調整

グラフで詰まってるメモリを等間隔にしたい


```code:x軸の場合
~~ 略 ~~ 
options: {
  scales: {
    xAxes: [{
       ticks: {
         maxTicksLimit:12
       }
    }]
 }
}
```

xAxesのticks:maxTicksLimitで最大表示数を指定。
あとはChart.jsがいい感じにやってくれる(はず)
Windows10でロック画面の画像を壁紙にする方法(Pythonスクリプトの小技アリ)

#ロック画面の画像を壁紙にしたい！
Windowsだと、ロック画面にMSさんが素敵な画像を出してくれますよね。

↓にある上海の画像を壁紙にしたくて調べてみました。
備忘録代わりにやり方を残します。

(浦东から見た大陸部の写真)
![image000024.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445854/e94b79dd-7eda-036f-873b-b5c2d6ba1264.jpeg)

#ロック画面の画像ってどこにあるの？
結論からいうと、
<b>「C:¥Users¥ユーザー名¥AppData¥Local¥Packages¥Microsoft.Windows.ContentDeliveryManager_cw5n1h2txyewy¥LocalState¥Assets」</b>
にあります。

<b>「了解！もう用はないです！」

「・・・あれ、AppDataフォルダないんですけど」</b>
![キャプチャ_LI (2).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445854/0e84af32-659c-95b1-e768-147123b769ce.jpeg)

####「表示」タブから「隠しフォルダ」にチェックを入れましょう

<b>「・・・出てきた！」</b>
![キャプチ ャ_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445854/b3bc9649-736f-b1d5-9305-c93efd9ca673.jpeg)
<b>上記パスの「～Assets」まで来ました。ここにあるファイルのどれかの
拡張子を「.jpg」に変えれば、デスクトップの壁紙に使えるのですが…</b>

<b>一々探すのがめんどくさいので、
Pythonスクリプトで全ファイルの拡張子を「.jpg」にしちゃいます。</b>
<img width="513" alt="キャプ  チャ.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445854/6ca320fa-ddb3-9fde-82eb-a7c32896e0d9.png">

##ここから先はAnacondaを入れてる前提です
Anacondaのイントール方法から知りたい方は[こちら](https://weblabo.oscasierra.net/python-anaconda-install-windows/)
####「~Assets」にあるファイルを全て別フォルダへ
「ピクチャ」配下に新しく「ロック画像」みたいな名前でフォルダを作り、
その中に「~Assets」配下のファイルを全てコピー&ペーストしましょう
<b>※一般的に、隠しフォルダ中身を直接いじるのはお勧めできません</b>
<img width="496" alt="キ ャプチャ.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445854/ff554162-8c6f-2a9a-3257-32e406a16191.png">

<b>ファイルが置かれたパスからコマンドプロンプトを開き、
「python」と入れて対話モードにします。</b>
![キャプチ   ャ_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445854/6c624a27-8010-d575-b4c9-faa6a5895a34.jpeg)

<b>以下のコードをコピー&ペーストしてしばらく放置しておくと、
該当パスにあるファイルの拡張子が全て「.jpg」になります。
(数分待った後、コマンドプロンプト上でEnterキーを押してください)</b>

```
#!/usr/bin/env python
# coding: UTF-8
import sys
import os
import re
a = 1

files = os.listdir('.')
for file in files:
  os.rename(file, "image%06d.jpg" %(a))
  a+=1
```

<b>こんな感じ
(画像ファイル以外は真っ白になるので画像を見つけやすい)</b>

<img width="439" alt="キャ  プ     チャ.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445854/7a21e12e-c187-8d28-c5a3-453012e12a38.png">

<b>見つかったら右クリック＞「デスクトップの背景として設定」</b>
![image000024.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445854/e94b79dd-7eda-036f-873b-b5c2d6ba1264.jpeg)
<b>戻すときは左下Windowsマーク＞歯車「設定」＞個人用設定＞背景</b>

備忘録完了～以上です。
ご質問あればお答えいたします！
roslaunchで引数を与える書き方メモ

roslaunchで引数を与える場合にはlaunchファイルを以下のように書く必要がある。

```  (hoge.launch)
<launch>
<arg name="argParam" default="true" /> <!--ここに入力引数を記述-->
<node name="hoge_node_name" pkg="hoge_package_name" type="hoge_node_name" > <!--nodeのたちあげ-->
    <param name="argParam" value="$(arg argParam)"/> <!--nodeに入力引数をあたえる-->
</node>
</launch>
```
上記のように記述すると、デフォルトではargParamにtrueが与えられて、
```roslaunch hoge_package_name hoge.launch argParam:=false
```
とすれば、falseが与えられる。
その他の書き方は
https://qiita.com/honeytrap15/items/550c757f2964b575883c
参照
安物買いの銭失い??(Raspberry Pi ラズベリーパイ用の USB－TTLシリアルコンソールのUSB変換COMケーブルモジュールのケーブル)

# ここのところ、だんだん気温が上昇し、我が家のRaspberry piの温度も上昇している。

-何が原因かわからないのでConsole接続が欲しくなった。networkでなく、線でつながっているconsoleである。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/c7cab6ff-1554-de78-a22c-94d0ebe6fdba.png)
げげげ、ポイントで買えるぞ。しかも、送料こみで313円。

```
シリアルチップ: PL-2303Xa/HXA chip
Driver Name: Prolific USB-to-Serial Comm Port
Provider: Prolific
Date: 2011/10/07
Version: 3.4.25.218
Signature: Microsoft Windows Hardware Compatibility Publisher

黒: GND 6番ピン
白: UART TXD(14) 8番ピン
緑: UART RXD(15) 10番ピン
赤は結線なし
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/bc589e4b-32ee-f06f-023f-247d76c33194.png)

こんな代物である。
何が問題かというとWindows 10 64bit用ドライバーがない。
# 結局どこにもドライバーなかったのでググることになった。
## 原因

中国から来る偽造「Prolific」チップがあったということです。偽造チップは、本物のProlificチップと同じベンダーID（VID_067B）と製品ID（PID_2303）を使用します。そのため、Prolificは新しいチップを作り、古いチップのサポートをすべて中止したため、偽造チップは使用できなくなりました。残念ながら、それは初期のチップを使用している何百ものレガシーデバイスを動作不能にします。普通のユーザーが正常に動作するドライバをインストールするのは、ほとんど不可能です。

## 世の中名は、私も含めて暇な人がいます。ありがたいものです。
[**ありがたいサイト**](http://www.ifamilysoftware.com/news37.html) http://www.ifamilysoftware.com/news37.html
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/3825348f-223b-6bf5-313e-752edb2043ec.png)

# うまく入りました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/8e1cba5b-4e8e-f030-972e-cccc38354a18.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/5b137f4f-11fd-31c8-6458-0e998e8b28a5.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/5c406cb4-5352-a3af-394e-0bdf43deda25.png)

```/boot/config.txtの最終行に追記
・・・・・・
dtoverlay=pi3-miniuart-bt
```

```/boot/cmdline.txtに追記
dwc_otg.lpm_enable=0 console=tty1 console=serial0,115200 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait
```
結線方法

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/0f3a3da6-0803-c8d2-6126-ad27962c9d97.png)

Rlogin 設定方法
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/d4460b7a-c671-1243-8097-56a049ae2687.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/d7a9e66c-0a52-ebc0-2b64-77678129797d.png)
## 無事動作する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/b2c77ad7-32b5-0b77-8541-1b159e124a7f.png)
CSS の配置

自分用の備忘録。
真ん中にしたいのになかなかできない

１つずつ載せる。

#Hamlは共通
    .payment-information
      .payment-information__form
        %span.payment-information__form--item-price ¥680
        %span.payment-information__form--item-shipping 送料込み
      .payment-information__form--point
        %button{:type => "submit"} ポイントはありません

#1-1 SCSS
.payment-information{
  width:320px;
  height: 300px;
  margin: 0 auto;
  background-color: aqua;
  text-align: center;
  &__form{
    display: flex;
    justify-content: center;
    &--item-price{
      font-weight: bold;
    }
    &--item-shipping{
      color: red;
      font-weight: normal;
      margin-left: 20px;
      }
  }
}
#1-2
<img width="379" alt="スクリーンショット 2019-06-26 16.12.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442488/5ff699fe-4987-2a80-8c81-6c07c99aa12e.png">

#2-1
.payment-information{
  width:320px;
  height: 300px;
  margin: 0 auto;
  background-color: aqua;
  text-align: center;
  &__form{
    // display: flex;
    // justify-content: center;
    &--item-price{
      font-weight: bold;
    }
    &--item-shipping{
      color: red;
      font-weight: normal;
      margin-left: 20px;
      }
  }
}
#2-2
<img width="412" alt="スクリーンショット 2019-06-26 16.18.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442488/13fb6668-6b6c-c77a-2aa0-852984924341.png">

#3-1
.payment-information{
  width:320px;
  height: 300px;
  margin: 0 auto;
  background-color: aqua;
  text-align: center;
  &__form{
    display: flex;
    justify-content: center;
    &--item-price{
      font-weight: bold;
    }
    &--item-shipping{
      color: red;
      font-weight: normal;
      margin-left: 20px;
      }
  }
}

#3-2
<img width="376" alt="スクリーンショット 2019-06-26 16.20.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442488/3a665f78-6999-23b5-86e6-c96a7279aa60.png">

親要素にtext-align: center;をしているので、全て真ん中に行くかと思いきや、行かなかった。
子要素にdisplay:flex;がある為だった。
子要素のdisplay:flex;を外すか、justify-content: center;を記述する事で解決！

justify-contentは「display:flex;」したやつをどこに置くのかを指定できるとのこと。
Ubuntuに保存されているアカウントとパスワードをGUIで管理したい

#Ubuntuに保存されたアカウントを管理したい
ubuntuはアカウントやパスワードを記憶してくれる時があります。
`□remember forever`や`□パスワードを保存する`などにチェックを入れると
次回からログイン名とパスワードをの省略が可能になります。

一方で**アカウントを変更・削除**したい、**追加**したい、
**ssh鍵も管理**したい、**システム証明書も管理したい**...
これらをGUIでできる便利なツールがあります。

(全部コマンドラインでできます。
Linuxといえばコマンドラインです。
私もほとんどコマンドラインで設定します。
慣れてくるとコマンドラインの方が早いし安心感があるんですよね。)

#アカウント管理の手順
###Passwords and Keys (seahorse)の立ち上げ

commandlineから

```
$ seahorse
```

と入力するとGUIが立ち上がります。

(注: アプリ検索からpasswordなどと入力すればPasswords and Keysというアプリが見つかるのでそれをクリックしても同じです。)


![Screenshot from 2019-06-26 15-29-35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285516/9fd459a3-6fe4-99e0-813a-b3c2287e6325.png)

左のバーにメニューが表示され、上から

Passwords: Ubuntu上に保存されたアカウントとそのパスワードの管理
Certificates: システム証明書などの管理
Secure Shell: sshの公開鍵などの管理
PGP Keys: pgp鍵の管理

の管理画面となっています。

それぞれに``+``ボタンがあり、選択することでアカウントや鍵を追加することも可能になっています。

###おわりに
####こんな時に便利だなあと感じています
自分はUbuntuのファイルマネージャー(Nautilus)からサーバーに接続しています。
ユーザ名やパスワードなどは保存して毎回の入力を省いていたのですが、
ある日ユーザー名を変更したくなったり以前登録した情報を見たくなったりします。
そんな時このseahorseで確認したり、ユーザー名を変更したりしています。

鍵のかかったpdfのパスワードなどもここに保存されています。
忘れてしまったときの確認などにも使えます。

ssh鍵もシステム証明書もここで見れるので便利ですね...
nuxtで非同期で取得したデータに合わせてチャットを一番下までスクロールする

# 対象
- nxutを使ってLINEやmessengerのようなチャットを作っている人
- (非同期で取得したデータを使ってDOMが更新された後のイベントをフックしたい人)

# やりたいこと
- チャット画面を開いた時点で、メッセージの一番下までスクロールしたい（以下この画面のことをチャットコンポーネントと呼ぶ）
- メッセージはチャットコンポーネントを表示するタイミングで非同期でサーバから取得する（先に読み込んでおくとかはなし）

# とりあえずチャットの一番下までスクロールする方法
このやり方がベストかどうかはわからないが、とりあえず以下のコードでできる（templata部分は省略。とりあえずoverflow: scrollになっているなにかしら）

```scroll.vue
<script>
method: {
    scrollToEnd() {
          const chatLog = this.$refs.'スクロールしたいref属性'
          if (!chatLog) return
          chatLog.scrollTop = chatLog.scrollHeight
        }
    }
}
</script>
```

## 解説
- `this.$refs.'スクロールしたいref属性'`でスクロールさせたいHTML要素を取得して、それのTOPをそれの高さにしてあげることで、一番したまでスクロールした状態にしているだけ
https://jp.vuejs.org/v2/api/#ref

# 問題点
チャットコンポーネントが表示されたタイミングで一番したまでスクロールして欲しい。
しかしチャットコンポーネントに表示するメッセージはコンポーネントを表示するタイミングで非同期で取得するため、Vueのライフサイクルの`mounted`や`created`ではまだ取得できていない。
（ライフサイクルに関してはここを→[Vue インスタンス](https://jp.vuejs.org/v2/guide/instance.html)）  
  
# 試したこと
## updatedを使う
非同期通信が終わったタイミングでは`beforeUpadate`や`updated`が呼ばれる
DOMが更新され終わったタイミングでないと`chatLog.scrollTop`が取得できないため、使うとしたら`updated`
つまりこういうこと↓
    
```scroll.vue
<script>
updated() {
    this.scrollToEnd()
},
methods: {
    scrollToEnd() {
          const chatLog = this.$refs.'スクロールしたいref属性'
          if (!chatLog) return
          chatLog.scrollTop = chatLog.scrollHeight
        }
    }
}
</script>
```

しかし、`updated`はメッセージ以外のpropsやdataが変わったタイミングでも呼ばれてしまうため、予期せぬタイミングでscrollToEnd()が呼ばれてしまう。 これはよくない

## カスタムウォッチャを使う
メッセージの変更のみを拾いたいならカスタムウォッチャを使えばいい。
つまりこういうこと↓

```scroll.vue
<script>
watch: {
    messages: function(newValue) {
        this.scrollToEnd()
    }
  },
methods: {
    scrollToEnd() {
          const chatLog = this.$refs.'スクロールしたいref属性'
          if (!chatLog) return
          chatLog.scrollTop = chatLog.scrollHeight
        }
    }
}
</script>
```

しかし、カスタムウォッチャでメッセージの変更を拾ったとしても、DOMが変更されるのはその後であり、`chatLog.scrollTop`が取得できないためこれもうまくいかない

## 結論
`Vue.nextTick( [callback, context] )`をつかう
[Vue公式ドキュメント](https://jp.vuejs.org/v2/api/index.html#Vue-nextTick)
[nuxtのドキュメント](https://ja.nuxtjs.org/api/configuration-loading/#loading-%E3%83%97%E3%83%AD%E3%83%91%E3%83%86%E3%82%A3)でもひっそり登場している

これはcallbaclで与えた処理をDOMの更新が終わるまで待つというもの。
カスタムウォッチャで`nextTick`を呼び、その中で`scrollToEnd()`呼ぶことで、メッセージが非同期で更新され、DOMの表示が終わったタイミングでメッセージの一番したまでスクロールすることができる

最終的にこういうこと↓

```scroll.vue
<script>
updated() {
    this.scrollToEnd()
},
methods: {
    scrollToEnd() {
          this.$nextTick(() => {
              const chatLog = this.$refs.'スクロールしたいref属性'
              if (!chatLog) return
              chatLog.scrollTop = chatLog.scrollHeight
           })
        }
    }
}
</script>
```

# 終わりに
propsやdataが更新されたタイミングで何かをしたいというのはよくあるが、DOMが更新されたあとに何かをしたいというのは初めてだったため、結構悩んだ。
しかし、DOMの更新後を拾いたいタイミングはこれからも結構ありそうなのでnextTickは結構便利なんじゃないだろうか



Twitterもやってるので、よければフォローお願いします。
→https://twitter.com/ObataGenta
Vue CLIを用いた環境変数の設定方法

基本的には[Vue CLI の公式ページ](https://cli.vuejs.org/guide/mode-and-env.html#modes)や他の方の記事を確認すればわかりますが、実際に適用するやり方が明記されていないように思えたので記載しました。

# 環境

・ Vue CLI: 3.6.3

# 作成前提

今回はローカル環境、開発環境、本番環境の 3 つを用意します。

# 環境変数設定方法

## .env ファイルの作成

プロジェクトファイルのルートディレクトリに  
`.env.local`  
`.env.development`  
`.env.prod`  
を作成します。

それぞれのファイルの書き方の例は下記の通りです。
それぞれの環境で使用したい、API の Base URL 等を記載します。
Vue CLI では`.local`がつくものは.gitignore で git には push しないように初期設定されています。  
.env ファイルの変数には`VUE_APP_`の接頭辞が必要になります。

```:.env.local
NODE_ENV='local'
VUE_APP_API_BASE_URL='https://localhost:8080/api/v1/xxx'
```

```:.env.development
NODE_ENV='development'
VUE_APP_API_BASE_URL='https://development/api/v1/xxx'
```

```:.env.production
NODE_ENV='production'
VUE_APP_API_BASE_URL='https://production/api/v1/xxx'
```

## package.json の設定

package.json の`scripts`に下記のように追記します。  
package.json の`scripts`ではエイリアスを作成することができます。

```:package.json
"scripts": {
    "local-serve": "vue-cli-service serve --mode local",
    "dev-serve": "vue-cli-service serve --mode development",
    "prod-serve": "vue-cli-service serve --mode production",
    "dev-build": "vue-cli-service build --mode development",
    "prod-build": "vue-cli-service build --mode production",
  }
```

## 使用方法

package.json を上記のように設定することで、  
`yarn local-serve`  
を実行すると`.env.local`の環境変数が適応されるようになります。  
同様に`yarn dev-build`  
を実行すると`.env.development`に定義された環境変数を用いた build モジュールが作成されるので、各々の開発環境にデプロイしてください。

# 参考

.env ファイルについて: [vue-cli で環境変数を使う](https://qiita.com/uni-3/items/2b79f3705149375ac7c7)←リンクがきれています。
初心者がローカルからEC2にお引越しした時に躓いたこと

#経緯
プログラミングスクールでAWS(cloud9)を使い、ローカルサーバーで学習していましたが、卒業しその時に使っていたアカウントが使えなくなってしまったので、自分のアカウントにし、使えるようにしました。

#環境
Rails 5.1.7
ruby 2.6.3p62

#最初にやったこと
ディレクトリをGithubにpushして新しく作成したアカウントにcloneしました。
#躓き

MySQLが入っていないとエラー、gemインストール時にさらにエラー

```

Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
    /usr/local/bin/ruby extconf.rb
checking for ruby/thread.h... yes
checking for rb_thread_call_without_gvl() in ruby/thread.h... yes
checking for rb_thread_blocking_region()... yes
checking for rb_wait_for_single_fd()... yes
checking for rb_hash_dup()... yes
checking for rb_intern3()... yes
-----
Using mysql_config at /usr/bin/mysql_config
-----
checking for mysql.h... no
checking for mysql/mysql.h... no
```
解決

```
sudo yum -y install mysql-devel
```

rails sでサーバー起動するもエラー

```
Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)
```

念のため
MySQLがインストールされているか確認　OK
MySQLが起動できるか？・・・できず

```
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)
```

おそらくソケットを通してローカルのMySQLに接続できていない

解決するためには
ソケットの設定を変更する方法もある
socketを合わせるためにやったこと

環境変数を取得

```
mysqladmin variables | grep socket
```

database.ymlで
socket /var/run/mysqld/mysqld.sock → /var/lib/mysql/mysql.sock に変更


rails s でようやく開けるかと思いきや・・・

```
Cannot render console from　〇〇  Allowed networks
```

config/application.rbに
config.web_console.whitelisted_ips = '〇〇'に変更

解決したのにまだ開けない・・・

```
amazonaws.com で接続が拒否されました。
```
更新したり、開き直しても解決しない

単純に別タブで開いたら開きました！！！

参考
https://qiita.com/oke-py/items/81f5db332131e5d88cf4

初心者で環境構築に躓いてしまいましたが、エラーの内容を読んだり
検索することでなんとか自分だけの力で解決することができました。

この経験から、何が問題で何がわかっていなくてどうすればいいのかが少しわかった気がします。また、検索能力も高まったのでエラーは苦しかったが解決できてよかったです。
[勉強用] React hooksで非同期処理を書く (ステップ1)

## はじめに

[以前の記事](https://qiita.com/daishi/items/f12f524e9d1df0b52d2b)で、useFetchの実装を紹介しましたが、もう少し単純なバージョンを順を追って書いていきたいと思います。

## 例題

非同期処理には色々ありますが、一番よく使われるであろうデータ取得を例にします。
https://reqres.in/api/user/1?delay=1
からダミーのユーザデータを取得するとします。
delayを指定するとデータ取得を遅延させることができます。

## ステップ１: 最低限の実装

```javascript
const useFetch = url => {
  const [result, setResult] = useState({});
  useEffect(() => {
    const fetchData = async () => {
      const response = await fetch(url);
      const data = await response.json();
      setResult({ data });
    };
    fetchData();
  }, [url]);
  return result;
};
```

一つのポイントは、async関数をそのままuseEffectに渡さないことです。戻り値がpromiseになるので、useEffectが怒ります。[参考](https://qiita.com/daishi/items/4423878a1cd7a0ab69eb#promiseを返さない)

もう一つのポイントは、useEffectの第二引数(deps)に `[url]` を渡すことです。この非同期処理はurlに依存するためです。urlが変わると再度処理が走ります。eslintの[exhaustive-deps](https://www.npmjs.com/package/eslint-plugin-react-hooks)ルールを有効にすると簡単に検知できます。

## 動作確認

実際に動くコードはこちらです。[codesandbox](https://codesandbox.io/s/awesome-rain-ecmt2)

## おわりに

本コードは勉強用ですので、そのままでは使わないでください。
課題と解決は[次のステップ](https://qiita.com/daishi/items/2c40e27f7589231dbcef)へ。
FirefoxでhttpsからWebSocket接続(ws)するにはnetwork.websocket.allowInsecureFromHTTPS

# 結論

実行するページが`https`なら
`network.websocket.allowInsecureFromHTTPS`
を`true`に変更する。

***

自分用タイトル:UserScriptからlocalhostにWebSocket接続(ws)するにはallowInsecureFromHTTPS

UserScriptだからといってローカルへのWebSocket接続に制限はなさそう。

# 起こったエラー

UserScriptで

`const socket = new WebSocket('ws://127.0.0.1:1234');`
としたときに

`ERROR: Execution of script 'スクリプト名' failed! The operation is insecure.`

と出力される。
プロトコルを`wss`に変更すればエラーは出ないが、今回はサーバー側が対応してなかったので`ws`で動かしたかった。

UserScript特有のセキュリティーかと考えていたが、違ったよう。
UserScriptで検索も上手くいかず、Firefoxを検索ワードにしないとたどり着けなかった。



# 情報源

* [[Firefox] SecurityError: The operation is insecure. · Issue #332 · apollographql/subscriptions-transport-ws · GitHub](https://github.com/apollographql/subscriptions-transport-ws/issues/332)
* [Firefox Websocket security issue - Stack Overflow](https://stackoverflow.com/questions/11768221/firefox-websocket-security-issue/12042843#12042843)
5日目　CSSのAnimationプロパティ簡単まとめチートシート

#今日大変だったこと
**・animation関連のプロパティがパッと思い出せない**

毎度毎度調べるのも大変。
[この記事が非常にわかりやすかった。](https://qiita.com/7968/items/1d999354e00db53bcbd8)
↑具体的な機能を一から見直すのには便利だけど、ささっと見直して思い出せるチートシートみたいなのが欲しいので、簡単に自分でまとめてみる。

##animationプロパティ基本の使い方

animationプロパティは
・animation-name 　　　　　　　　/使用するkeyframesの名前
・animation-duration　　　　　　　/アニメーション一回の長さの指定
・animation-timing-function　　　　/進行割合の指定
・animation-delay　　　　　　　　　/アニメーションがいつ始まるのかの指定
・animation-iteration-count　　　　/アニメーション繰り返し数
・animation-direction　　　　　　　/繰り返し方の方向指定
・animation-fill-mode　　　　　　　/アニメーション終了後の処理について
・animation-play-state　　　　　　/実行中or停止中

name,duration以外のプロパティは省略可で順不同。
但し時間指定に関しては、前の指定がanimation-duration,後ろの指定がanimation-delay扱いとなる。

```CSS
img {
   animation: zoom 3s linear 1s infinite alternate;
}

@keyframes {
   from {
   }
   to   {
   transform: translateY(10px);
}
```

##animation-name(使用するkeyframesの名前)
カンマ区切りで複数指定可。
##animation-duration(アニメーション一回の長さの指定)
単位s→秒
単位ms→ミリ秒
**初期値は0(実行しない）なので忘れずに指定すること。**
##animation-timing-function(進行割合の指定)
３次ベジエ曲線的で指定されている。
**ease**: 開始と終了が滑らか(初期値）
**linear**: 常に一定
**ease-in**: 始まりがゆっくり
**ease-out**: 終わりがゆっくり
**ease-in-out**: ゆっくり始まりゆっくり終わる
**cubic-bazier(x1,y1,x2,y2)**: 3次ベジエ曲線のP1、P２の座標を指定

*ステップ系*
**step-start**: 開始時に最終の状態になる。（過程なし）
**step-end**:　終了時に最後の状態になる。（過程なし）
**steps(数,start)**:　開始時にすでに一コマ進む
**steps(数,end)**:　開始時は動かず、次のコマから進む

##animation-delay(アニメーションがいつ始まるのかの指定)
ms,sで指定。
初期値0で直ちに始まる。
マイナス指定をすると、直ちに始まるが途中からの再生。
例）animation-delay: -1s
→１秒後のアニメーションからスタート。
##animation-iteration-count(アニメーション繰り返し数)
**infinite**: 無限に繰り返す。
小数点での指定も可、その場合途中で打ち切られる。
##animation-direction(繰り返し方の方向指定)
**normal**: 毎回最初から再生（初期値）
**reverse**: 毎回逆方向から再生
**alternate**: アニメーションを毎回反転させる、初回は最初から再生
**alternate-reverse**: アニメーションを毎回反転させる、初回は逆方向から再生
##animation-fill-mode(アニメーション終了後の処理について)
**none**: 何も指定しない。その他のCSS規則を元に表示（初期値）
**forwards**: 最後の状態を保持
**backwards**: 最初の状態を保持(delay期間中)
**both**: forwards＆backwards

##animation-play-state(実行中or停止中)
**paused**: 停止
**running**: 再生中

##keyframesについて
指定方法は２種類！
**①form to**

```CSS
@keyframes popopo {
   from {
     /*始まり、省略可*/
   }
   to {
     /*終わり*/
   }
}
```

**②％指定**

```CSS
@keyframes popopo {
   0% {
       /*省略可,始まり*/
   }
   50% {
      /*パーセント指定は幾つでも可*/
   }
   100% {
        /*終わり*/
   }
}
```
owncloud 10.0.7 への update手順

# to owncloud 10.0.7
IDCF上のowncloudをアップデートしたときの自分用の手順書メモ

### backup
```
cd /var/www/html/
mv owncloud owncloud.old
```

### wget
```
wget -O /tmp/owncloud.tar.bz2 'https://download.owncloud.org/community/owncloud-10.0.7.tar.bz2'
```

### unpack
```
tar xvf /tmp/owncloud.tar.bz2
```

### data
```
cp owncloud.old/config/config.php owncloud/config
chown -R apache:apache owncloud
rm -r owncloud/data
mv owncloud.old/data owncloud/data
sudo -u apache owncloud/occ upgrade
```

### finally
```
rm -fr owncloud.old
```

### if...
```ownCloud is in maintenance mode - no app have been loaded```

```php:owncloud/config/config.php
'maintenance' => true,
```
↓

```php:owncloud/config/config.php
'maintenance' => false,
```
Windows10でpip installしたときSSL周りで怒られたので解決法をメモ

普段macOS使いなのですが、Windows 10の環境で機械学習環境を構築したらちょっとつまづいたので備忘録的にメモ。

# OpenCV のインストール

まずはanaconda…は重いのでminicondaをインストール。

https://docs.conda.io/en/latest/miniconda.html

インストール先はデフォルトの通りユーザーフォルダの下 `C\:Users\kmotohas\Miniconda3` としました。

`conda`コマンドを使えるように、 `C\:Users\kmotohas\Miniconda3\condabin` を環境変数 `Path` に追加。
同様に`pip`コマンドを使えるように、`C\:Users\kmotohas\Miniconda3\Scripts` を `Path` に追加。

これでpipが使えるようになったので試しにOpenCVをインストールしてみると、エラーが出ました。
（色々事情があるので、初めからcondaでインストールすればいいだろうというツッコミは勘弁）

```shell-session:
$ pip install opencv-python
pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.
...
```

SSL周りで怒られているので、condaでopensslをインストールしたら問題なく動作しました。

```shell-session:
$ conda install openssl
...
$ pip install opencv-python
...
```

しかし、PythonのインタープリターからOpenCVをインポートしようとするとnumpy周りでエラーが出ます。

```python:
>>> import cv2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\kmotohas\Miniconda3\lib\site-packages\cv2\__init__.py", line 3, in <module>
    from .cv2 import *
ImportError: numpy.core.multiarray failed to import
```

これはnumpyをアンインストールしてからインストールしなおすと解決します。

```shell-session:
$ pip uninstall numpy
...
$ pip install numpy
...
```

という感じで、僕のWindows 10の初期設定でつまづいた点でした。

# 関係ないけど…

condaとpipでインストールしたnumpyは実は中身違うので注意が必要です。

https://orizuru.io/blog/machine-learning/anaconda_pip_difference/

numpyはご存知行列計算ライブラリなわけですが、裏で使われている行列演算の実装が異なります。

`pip install numpy` -> `OpenBLAS`
`conda install numpy` -> `MKL` (多分使っているマシンのCPUがIntel製の場合のみ。ARM CPUだったら何が使われるのでしょう。）

condaとpipの使い分けにはご注意を。
ROSでHello World

##はじめに
ROSを使った初歩的なコードを記述します。
自分のメモ代わりです。
関連記事は以下のとおり。

| 記事タイトル  |  内容 |
|:----------------:|:-----------------:|
| [ROSでHello World](https://qiita.com/keinko/items/880ff30e5a4ae57c6315)    | ROSに慣れるために簡単な処理を行う|
| [ROSで簡単な通信を行う](https://qiita.com/keinko/items/7d0f26c19414291660d9)             | ROSの基本である通信の処理をテストする |
| [ROSを使って画像情報でロボットを動かす](https://qiita.com/keinko/items/c8f9390419cb1cbb6467)          | 少し実践的に複数のシステムを動かす |

##コーディング

好きなディレクトリに以下の`hello_world.py`を作成。

```python:hello_world.py
## coding: UTF-8
import rospy

rospy.init_node('hello_world_node') # 引数で与えられる名前のノードを生成
rospy.loginfo('Hello World') # ROSネットワークに文字列送信
rospy.spin() # 無限ループ開始
```

##実行
ターミナルを２つ立ち上げる。

```bash:ターミナル1
$ roscore
```

```bash:ターミナル2
$ python hello_world.py
```
上記を打つと、

```bash:実行結果
$ python Documents/ros_06/hello_world.py 
[INFO] [1561530970.398307]: Hello World
```

表示された！

次のステップとしてこちらの記事も書きました！
[ROSで簡単な通信を行う](https://qiita.com/keinko/items/7d0f26c19414291660d9)
画像にリンクを貼る方法

画像にリンクを貼る方法

ちょっと戸惑ったので備忘録として:point_up_tone1:


###link_toでimage_tagにリンクをつける

```
.infomation-header--logo
      = link_to image_tag(src= "画像のリンク先", class: "クラス名"), パスの指定
        
```

これだけでOK:v_tone1:
知識ゼロから学ぶ ソフトウェアテスト(3章 ブラックボックステスト② 境界値分析法)

知識整理のために投稿しています。
本は `知識ゼロから学ぶ ソフトウェアテスト[改訂版]`です。
テストってなかなか書けない。

## 境界値分析法

- プログラムでは「境界」に常にバグが潜んでいる
- 同値分割法とセットで使われることが多い

(例) 1ページ未満の印刷をユーザーが要求した場合にエラーを表示する
```
if ( a >= 1 ) {
    // 印刷処理
} else {
    // エラー処理
}
```
4つのバグが起こりうる

1.>と>=の間違い
```
if ( a > 1 ) {
    // 印刷処理
} else {
    // エラー処理
}
```
2.数字の書き間違いやスペックの読み違いなど
```
if ( a >= 2 ) {
    // 印刷処理
} else {
    // エラー処理
}
```
3.境界がない
```
if ( a >= 1 ) {
    // 印刷処理
}
// このあとがコメントアウトされているなど
```
4.余分な境界
```
if ( a >= 1 && a < 10 ) {
    // 印刷処理
} else {
    // エラー処理
}
```

### 境界のテストをするために ~On-Off ポイント法~

- 異なる処理が行われる一番近い２地点をテストする方法
- 前述の4つのケースが満たされることを意識する

**今回書くべきテストケース例**

- 1を入力→正常な処理がなされること
- 0を入力→エラー処理がなされること
  
## 同値分割法と境界値分析法の組み合わせ
(例) 
入力A：1~999まで入力可能
入力B：同上
入力C：A*B

| |有効同値クラス|無効同値クラス|境界値 |
|:--:|:--:|:--:|:--:|
|入力A |  1~999 | 0以下1000以上 | 0,1,999,1000 |
|入力B |  1~999 | 0以下1000以上 | 0,1,999,1000 |

テストケースは、A・Bに以下の数を入れて作れば良い

- 0：常にバグになりやすい数
- 1：有効な値の下限
- 499：有効な値の真ん中
- 999：有効な値の上限
- 1000：無効な値の下限

## 経験則によるテストケース

いつでも上記のような表を作ってテストケースを書けるとは限らない

- データが複雑に絡まりあっている
- 十分なスキルがない
- 時間がない… などなど

**良いデータと悪いデータを入力する**ということを意識するだけでもテストは改善する

**良いデータ**

- ユーザがよく使いそうなデータ
- プログラムが許す最小のデータ
- プログラムが許す最大のデータ
- ゼロ(これが悪いデータの場合もあり)

**悪いデータ**

- 非常に小さなデータ(-99999999, 0.0000001など)
- 非常に大きなデータ(99999999, 10999999など)
- 長いデータ(abcdefghijklmnopqrstuvwxyz.txtなど)
- 無効なデータ
WIPの代わりにDraft Pull Requestを利用する (GitHub)

[Draft Pull Requestをリリースしました](https://github.blog/jp/2019-02-19-introducing-draft-pull-requests/) を読めばおわりです

## Draft Pull Requestとは
[GitHub Flow](https://qiita.com/tatane616/items/aec00cdc1b659761cf88) などを利用してチーム開発をしていると、すぐマージはできなくても Pull Request(PR) を出したくなる場面があると思います。
そのような時は、 **WIP(Work in Progress)** を利用することが多いでしょう。
作業中の PR のタイトルに `WIP: PR title` や `[WIP] RP title` のようにつけるのが一般的です。

WIP を利用することで以下のような恩恵があります

- 作業ログやコメントを残せるため、思考の整理になる
- PR を見ることでコンテキストをレビュワーと共有できるため、レビューが楽になる

また、マージ目的ではなく他のメンバーからのフィードバックをもらうために PR を出すこともあります。

このような場合に便利なのが、今年2月にリリースされた **Draft Pull Request** です。
Draft PR を利用することで、PR が作業中であることを示すことができ、誤ってマージしてしまうこともなくなります。


## 使い方
PR を作成するときに、 **[Create pull request]** の横のプルダウンから **[Create draft pull request]** を選択して PR を作成します。
![draft-pr 2019-06-26 15-12-21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196629/0309af0d-3349-9abc-6224-6362c5424571.png)

実際の PR は以下のようになり、 **Draft** タグが付き、作業が完了したら **[Ready for review]** をクリックすることで通常の PR へ変更することができます (通常の PR → Draft への変更も可能です。参考リンク：[プルリクエストのステージの変更 \- GitHub Docs](https://docs.github.com/ja/github/collaborating-with-issues-and-pull-requests/changing-the-stage-of-a-pull-request))
![draft-pr 2019-06-26 15-13-50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196629/6acef862-00db-d65e-ac06-a769c6b5e425.png)
exawsでS3のPresigned URLを作ってPutする

# はじめに

フロントからファイルを受け取ってからS3アップロードするのは流石にサーバーの負担が大きい。
Presigned URLを利用して、直接クライアント側からS3にPutしよう！

実際は簡単ですが、途中のConfigに少々問題があったので、一応メモを残そうと。

# 実装
まずは[exaws](https://github.com/ex-aws/ex_aws), [exaws s3](https://github.com/ex-aws/ex_aws_s3)をゲット。

## mix.exs

```elixir
  defp deps do
    [
      {:phoenix, "~> 1.4.0"},
      {:phoenix_pubsub, "~> 1.1"},
      {:phoenix_ecto, "~> 4.0"},
      {:ecto_sql, "~> 3.0"},
      {:postgrex, ">= 0.0.0"},
      {:phoenix_html, "~> 2.11"},
      {:phoenix_live_reload, "~> 1.2", only: :dev},
      {:gettext, "~> 0.11"},
      {:jason, "~> 1.0"},
      {:phauxth, "~> 2.0.0"},
      {:argon2_elixir, "~> 1.3"},
      {:bamboo, "~> 1.1"},
      {:bamboo_ses, ">= 0.1.0"},
      {:plug_cowboy, "~> 2.0"},
      {:httpoison, "~> 1.5"},
      ##
      {:ex_aws, "~> 2.1"},
      {:ex_aws_s3, "~> 2.0"},
      ##
    ]
  end
```

```bash
mix deps.get
```

## config.exs
ここで少々時間をかかってしまった。
同じプロジェクトでsesも使ってるが、Regionが違う。
もしそのまま使うと下記のエラーが返される。

```xml
<?xml version="1.0" encoding="UTF-8"?>
<Error>
    <Code>PermanentRedirect</Code>
    <Message>The bucket you are attempting to access must be addressed using the specified endpoint. Please send all future requests to this endpoint.</Message>
    <Endpoint>authpractice.s3.amazonaws.com</Endpoint>
    <Bucket>authpractice</Bucket>
    <RequestId>485F22E3265A08E1</RequestId>
    <HostId>vmSaFTUKuz9azNZkjOcevjn7II5cPsZivRlz6QRf8pgfT2jIf50f4etFfgUVULBnL4GbltWTZdk=</HostId>
</Error>
```

なので、このようにConfigを分けると、後でサービスごとのConfigをロードできるようなのでこのように書けよう。

```elixir
config :ex_aws,
  access_key_id: System.get_env("AuthIAMUserAccessKey"),
  secret_access_key: System.get_env("AuthIAMUserSecretAccessKey")  

config :ex_aws, :s3,
  region: "ap-northeast-1",
  host: "s3.ap-northeast-1.amazonaws.com"
```

実際にPresigned URLを生成するコード：

```elixir
# ここでConfigをロードする
  ExAws.Config.new(:s3)
  |> S3.presigned_url(
    :put,
    "bucketname",
    "filename"
  )
```
Node.jsアップデートでSQLiteのコンパイルが失敗する現象の対処方法

macOSで、Node.jsをアップデートした後、モジュールをインストールすると、大抵SQLiteのコンパイルで失敗する。その対処方法のメモ。

```
npm cache clean --force
npm install sqlite3 --build-from-source --unsafe-perm 
```

上記コマンドを実行したら直った。

参考) https://stackoverflow.com/questions/49190938/sqlite3-macos-sierra
Confluence ページ編集時ショートカットキーまとめ

#コンフルショートカットキーまとめ
個人用備忘録(Windows)

##概要
最近よくConfluence 使うことが多く、
作業手順書などもそちらで作成することが多い。
効率良く作業実施するため編集時のショートカットキーを
自分なりにまとめておく


##見出し関連
段落：Ctrl+0
見出し1：Ctrl+1
見出し2：Ctrl+2
見出し3：Ctrl+3
見出し4：Ctrl+4
見出し5：Ctrl+5
見出し6：Ctrl+6
書式設定済み：Ctrl+7
引用符：Ctrl+8

##書体関連
太字：Ctrl+B
斜体：Ctrl+I
下線：Ctrl+U

##リスト関連
記号付きリスト：Ctrl+Shift+B
番号付きリスト：Ctrl+Shift+N
　※Chromeだとシークレットウィンドウひらく

##挿入関連
ファイルと画像挿入：Ctrl+M
リンク挿入：Ctrl+K
コンテンツ挿入：Ctrl+Shift+A
　※コードマクロとかパネルとか目次とか

##その他
元に戻す：Ctrl+Z
やり直し：Ctrl+Y
検索と置換：Ctrl+F

##感想
アウトプットの練習も兼ねて
新たに使いこなせそうなショートカットキーがあれば
随時更新していこうかなと思う

まだまだ駆け出しの為
知識も記事の書き方も稚拙

こんなショートカットキーあるよとか
もっとこういう記事かけよとか
色々ご指摘あればありがたいです
【VSCode】ファイル検索でnode_modulesなど検索できない対象のファイルを検索する方法

# やりたいこと
- vscodeでは.gitignoreで除外されているファイルは検索できない
- そのため `node_modules` 配下のファイルを検索対象にしたい時、検索できない
- .gitignoreで指定されているファイルも検索対象にするようにする

# 方法
1. vscodeの環境設定を開く
2. `ignore` などで検索する
3. `Search: Use Global Ignore Files` チェックを外す

# 参考
https://developer.feedforce.jp/entry/2017/11/24/195644
Could not launch "project name"でRunできない場合の対応方法

## トリガー
iPhoneをUSB接続し`Run`したところ、下記の内容のダイアログが表示された。

```
Could not launch "project name"

iPhone has denied the launch request.
Internal launch error: process launch failed: failed to get the task for process 519
```

## 環境
* iPhone6
    * iOS 11.2
* Xcode 10.2.1

## 原因
`Run`だとデバッグでのビルドになるが、証明書がDestributionになっていた。

## 修正方法
1. `General -> Signing(Debug)`の証明書を`development`のものに変更する。ない場合は作成する
2. `Build Settings -> Code Signing Identify -> Debug`を`iOS Developer`に変更する
3. 完了
Noodlで画面遷移

## Noodlで今度は画面遷移
### Noodlとは
[スウェーデン発のプロトタイピングツールNoodlを触ってみた - Qiita](https://qiita.com/ryusukefuda/items/bafd6deb402f4277bdc7)

## 画面遷移する
`Pages` `Page` `Page Navigation` ノードを使うとできる

### Create New Porject

### 各ページのComponentをつくる
左のナビバーの `+Component` から3つつくる

- page-top
- page-pink
- page-blue

<img width="463" alt="Screen Shot 2019-06-26 at 11.55.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50232/efe3c0ec-81ff-df1a-8b2a-7d6270e13ef5.png">


### Main componentをつくる

- Pagesノードを追加してRootの下に配置
- Pagesノードのプロパティ設定
  - Start Page: `/page-top`
   

### page-top componentつくる
トップ画面用の画面
page-pinkへ遷移するボタンを持つ

- Pageノード追加し背景用のRectangleとボタン用のRectangleをPage配下に追加
- Page Navigation追加しプロパティ設定
    - Destination: `/page-pink`
- ボタンRectangleからPage Navigationへビヨーンと伸ばしプロパティ設定
    - Tap
    - Navigate To Page

<img width="855" alt="Screen Shot 2019-06-26 at 12.11.31.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50232/6261cc2f-2c82-4a3d-5115-6aac8932841d.png">


### page-pink componentつくる
トップから遷移先の画面
page-blueへ遷移するボタンをもつ

- page-topと同じくPageノード追加し背景用のRectangleとボタン用のRectangle追加
- page-topと同じ方法で`page-blue`へのnavigation設定

### page-blueつくる
最後の画面
page-pinkとトップへ戻るボタンをもつ

- これまでと同じようにPageノードつくりボタン2つおく
- `Page Navigation Back`ノードを追加し、ボタンと接続する。Backは前の画面へ戻るノード。
    - Tap
    - Back
- もうひとつのボタンにはトップへ遷移する`Page Navigation` 追加する


### デモ
![Jun-26-2019 12-19-27.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50232/a8021465-81ba-399f-329a-88cf8c812c98.gif)

### 補足
- 遷移時のアニメーションはPageのプロパティの`Transition`から設定可能
- トップへの遷移等遷移の履歴を削除するときは`Page Navigation` のプロパティ`Reset History` でチェックできる
TailwindCSSで作られたサイト・ページ・コンポーネント

## サイト

* ブログ
    * [Liam Hammett](https://liamhammett.com/)
* キュレーションメディア
    * [Fifty.one – Curating the wild world of crypto](https://fifty.one/hot)
* デザインTips
    * [The “Design Tips” series now in TailwindCSS](https://design-tips.caneco.xyz/)

## ページ

* レジュメ
    * [Universal Resume Template](https://gumroad.com/l/universal-resume?ref=producthunt)
* 管理画面
    * [Simple App Layout with Tailwind](https://codepen.io/Log1x/pen/VOqLpV)
* 請求書
    * [Vue Quote Template](https://codepen.io/adamwathan/pen/rgjQQd)

## コンポーネント

* 複雑なドロップダウンメニュー
    * [tailwind menu on hover](https://codepen.io/diomed/pen/gJrQgR)
CircleCIで2FAを突破してAppStoreConnectにバイナリをアップする

現在は秘密鍵を利用する[こちら](https://zenn.dev/moga/articles/752b5f5a8fc001060d1a)の方法で簡単にバイナリアップできるようになっています。

以下は、過去記事
---

CircleCIでiOSアプリをAppStoreConnectにアップしようとしたところ盛大にハマったのでノウハウを共有します。

まず[Fastlaneの公式ドキュメント](https://docs.fastlane.tools/best-practices/continuous-integration/#authentication-with-apple-services)を確認します。
・2FAでない専用のaccountを作るのが簡単
とありますが、今回は2FAが有効なユーザーで自動アップロードを行いたいです。

# ジョブに必要な環境変数

ジョブの設定に必要な環境変数は次の通りです。

- FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD  
  [アプリ用パスワード](https://support.apple.com/ja-jp/HT204397)です。 
- FASTLANE_USER  
  Apple IDです
- FASTLANE_PASSWORD  
  Apple IDのパスワードです
- FASTLANE_SESSION  
  2FA済みのセッションです。取得方法は後述します。
- MATCH_PASSWORD  
  `fastlane match`の復元パスワードです

検証に使用したaccountが複数チームに所属していたため、私の環境では `FASTLANE_ITC_TEAM_NAME` も指定しましたが、1つのチームにだけ所属しているなら必要ないと思います。

2FAアカウントですがパスワードを環境変数に設定する必要があるのが少し不気味です。でも外したら動かないので必要なんでしょう。

FASTLANE_SESSION は 認証したリージョンと同じリージョンでないと使用できないので、実行中のCircleCIのコンテナにVNCで接続して、FASTLANE_SESSIONを取得します。
30日ごとにFASTLANE_SESSIONの生成が必要になりますが、現時点で他に方法はなさそうです。

# FASTLANE_SESSION の取得方法
[VNC接続手順](https://support.circleci.com/hc/en-us/articles/360020345334-How-do-I-connect-to-a-macOS-container-via-VNC-)を参考にしました。

1. CircleCIのジョブ失敗画面から、"Rerun job" with SSH を実行  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18273/26e8abd5-715a-3d16-af33-7c6da9e1eba2.png)
1. コンテナへの接続情報を確認する  
ジョブの詳細に以下の用にsshでコンテナに接続するために情報が表示されるので確認する
![figure.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18273/135f05d2-4e31-2e0a-6ac5-9b163c61fb40.png)
1. ローカルMacからコンテナにssh接続する(ローカルで実行)
sshの接続情報をもとにssh接続する。鍵はGitHubリポジトリへ接続するための鍵と同じものを使用する。私の環境では`-i` で明示的に鍵を指定する必要がありました。  
```
ssh -p <指定されたポート> <指定されたIP> -i ~/ssh/hoge_rsa
```
1. vnc用のユーザーを作成する(コンテナで作業)  
```
sudo /usr/sbin/sysadminctl -addUser vncuser -fullName "VNC User" -password <password> -admin
```
1. vnc 接続用のポートフォワーディング設定(ローカルで実行)  
```
ssh -p 54782 <コンテナのIP> -L5901:localhost:5900 -N -i ~/ssh/hoge_rsa
```
1. vnc viewerでvnc接続する  
viewerは何でも良いと思いますが私は[realvnc](https://www.realvnc.com/en/connect/download/viewer/)を使用しました。
接続先は `localhost:5901` です。  
ログイン画面が出てきたら先程作成した `vncuser` でログインします。パスワードは先程指定したものです。
1. FASTLANE_SESSIONの取得  
以下のコマンドを実行しセッション情報を取得します。
```
fastlane spaceauth -u <Apple ID>
```
1. セッション情報をCircleCIの環境変数に設定する

# 確認
すべてが正しく設定されていれば `fastlane deliver` が動くはずです。

# まとめ
CircleCIのサポートに問い合わせてどうにかCIにバイナリアップを組み込むことができました。
vncでコンテナに接続できるとは思っていなかったので勉強になりました。トラブルシューティングなどに応用できそうです。
MySQL BigQuery 誕生日から年齢を取得する関数

# 概要
誕生日から年齢を取得する。誕生日を迎えれば年齢が上がるようにする。

|誕生日       |年齢 |
|:-----------|:---|
| 2008-12-16 | 10 |
| 1978-12-30 | 40 |
| 1981-01-22 | 38 |

こんな感じに書いていたが、便利な関数があったので紹介！

```sql

FLOOR((current_date() - u.birthday) / 10000) age
```

# MySQL
```sql

SELECT
  u.birthday
  ,TIMESTAMPDIFF(YEAR, u.birthday, CURDATE()) age
  -- TIMESTAMPDIFF(unit, datetime_expr1, datetime_expr2)
FROM
  users u
```







# BigQuery

```sql

SELECT
  u.birthday
  ,DATE_DIFF(current_date(), u.birthday, YEAR) age
  -- DATE_DIFF(date_expression, date_expression, date_part)
FROM
  users u
```
railsのredirect_to

Railsで、ページ遷移の際に、配列エラーが出て、かなり悩んだ際のメモ

##状況
レコードを投稿し、投稿後にレコード一覧画面へ移行する。
レコードの投稿は出来ているが、ページ遷移が出来ない。
(newページから、cretaeアクションを通してindexページに移行する際にエラーが発生)


```article_cnotroller.rb
class ArticleController < ApplicationController
    def index
        @article = Article.all
    end

    def new
        @article = Article.new()
    end

    def create 
        @article = Article.new(article_params)
        if @article.save
            render 'index'
        else
            render 'new'
        end
    end

    private 
    def article_params
        params.require(:article).permit(:main_text, :title, :header_photo, :maintext_photo)
    end

end
```

簡単ではありますが、保存後にindexページに移行するようにと思い、上記のコードを記述しています。


こちらも簡単に、投稿内容のタイトルだけを表示させるコードにしています。

```index.html.erb

<% @article.each do |article| %>
    <tr>
        <td><%= article.title %></td>      
    </tr>

<% end %>
<br>
```


エラー内容はスクショの通りです。

![スクリーンショット (43).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203857/216775fc-6ce6-f893-d296-fbbbd365c3ec.png)



エラーの内容は、eachが使えないと出ています。。

投稿内容のデバックを取っても、ちゃんと？配列が投稿できてるし、配列のエラーでは無いっぽい！けど何が原因か分からない！状態でした。



投稿は出来ているものの、createアクションを通した際に、
```
<% @article.each do |article| %>
```

配列が入っていないことは確かで、どこか怪しげ。

```
render 'index'
```

犯人はこいつだ！とまで分かると、エラーの内容はすぐわかりました！！

renderでアクションを呼び出すと、ページのデータのみが呼び出されるんです！
エラーページで見えなかったんですが、恐らく、http://localhost:3000/article/indeじゃなくて、http://localhost:3000にindex.html.erbのページが呼び出されている。はず。


なので、こう書き替えました。

```
class ArticleController < ApplicationController
    def index
        @article = Article.all
    end

    def new
        @article = Article.new()
    end

    def create 
        @article = Article.new(article_params)
        if @article.save
            redirect_to :action => 'index'
        else
            render 'new'
        end
    end

    private 
    def article_params
        params.require(:article).permit(:main_text, :title, :header_photo, :maintext_photo)
    end

end
```

redirect_toでアクションを呼び出すと、URL付きのページで呼び出されるみたいです。


なかなか手ごたえのあるエラー内容でした。
楽しいーーー！！！
Googleアナリティクス基本の使い方

#Googleアナリティクスとは
Google社が無料で提供しているアクセス解析ツールです。アクセス解析とはWebサイトへのアクセスを様々な観点から分析し自社のサイトの状況を把握することです。それによってサイトのどの部分を改善すればCVアップなどの効果を見込めるか発見することができます。
具体的には以下のようなことがわかります。他にも使いこなせばたくさんわかるけど代表的なものだけ。

・ユーザーの特性（性別、地域）
・どこからユーザーがサイトに流入しているか
・人気のページはどれか
・離脱しやすいページはどれか

Googleアナリティクス導入方法はこちら
https://wacul-ai.com/blog/access-analysis/google-analytics-setting/ga-beginner/

#これさえ見ておけば大丈夫！基本の機能4つ
ユーザーメニュー
集客メニュー
行動メニュー
コンバージョンメニュー

#ユーザーメニュー
Googleアナリティクスを開くと最初に表示されるデフォルトページです。ユーザーメニューではサイト全体の訪問者数や、PV数、デバイス毎の訪問数など、ユーザーに関する情報はこのページで全て確認できます。
<img width="1440" alt="Screen Shot 2019-06-26 at 13.07.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294829/af488719-194f-4090-0242-7bf671b6aa8e.png">


最低限この3つのデータ項目の意味を理解していればOKです。
写真の赤枠で囲まれたプルダウンによって選択できます。
##セッション
ユーザーがサイトに訪問した数です。
一回そのサイトに訪れたら１セッション。同じユーザーの場合は30分以上間隔が開いたら新たなセッションとしてカウントされます。

###ユーザー
サイトに訪問したユーザーの数です。同じ人が何回も訪問してもユーザー数は１です。どれだけの人数が利用してくれているのかを見る際に重要な指標です。

###ページビュー数
PV数とも言います。そのサイトの中でユーザーが見たページの数です。
セッションとPVの割合が同じということは相当つまらないサイトと言えるでしょう。なぜなら、訪問してみたもののランディングページを見ただけで他のページに移動することなく離脱してしまってるからです。

###直帰率
直帰とは仕事が終わってどこにも寄り道せずに家に帰ることを言います。
、、、、、しーん
改めて、直帰とはサイトを訪れた時、つまり一回のセッションで他のページを見ずに去ってしまうことです。
直帰率とは全体のセッションの内、直帰した割合です。

##問題：この日のセッション数、ユーザー数、ページビュー数、直帰率は？
Aさん：朝、昼、晩に一回ずつサイトを訪問。どれも最初のページだけ見てサイトを閉じた。
Bさん：10時〜10時15分の間に3回サイトに訪問。1回目と2回目は３ページ閲覧し、3回目は5ページ閲覧
cさん：12時〜12時20分の間に2回サイトに訪問して4ページ閲覧。夜に１ページ閲覧。



#集客メニュー
集客メニューではユーザーがどこから訪れたのかを知ることができます。
「集客」>「すべてのトラフィック」>「チャネル」で確認してみましょう。
<img width="1440" alt="Screen Shot 2019-06-26 at 13.31.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294829/27147d0c-fdf2-3b0a-547f-45a9827355ce.png">

覚えておくべき流入経路は以下です。
僕のサイトはしょぼしょぼなのでDirectしかありませんね、、
###Direct
URLを直接入力、もしくはブックマークからの流入
###Organic Search
Google、Yahooなどの検索エンジンからの流入
自然流入とも言います。
###Paid Search
Google、Yahooなどの検索エンジンのリスティング広告からの流入
リスティング広告とは？
https://liskul.com/what-is-listing-95
###Social
FacebookやTwitterなどのSNSからの流入
###Referral
他のサイトに貼られたリンクをクリックしての流入



#行動メニュー
集客メニューではサイトに訪問する前のユーザーの行動が見れましたが、行動メニューではユーザーのサイト内での行動を知ることができます。
ザックリ見るべきページは２つです。

##「サイトコンテンツ」>「すべてのページ」
サイト内のすべてのページのPV数やセッション数などをザックリ確認することができます。

##「サイトコンテンツ」>「ランディングページ」
ランディングページはユーザーが最初に訪れたページになります。
改善すべきページは以下の３つのデータからわかります。

####セッション数が多いページ
セッション数が多いと言うことは見ているユーザーが多いと言うことでセッション数の多いページを改善することが効果が一番期待できます。

####直帰率が高いページ
直帰率とはランディングページだけみて去ってしまった率でしたね。
一般的に直帰率の目安は40%ほどと言われています。
直帰率が高いと言うことはユーザーがサイトを訪問する前に想像していたサイトと実際のサイトに乖離があると言うことです。直帰率が低いページと見比べて少しずつ改善していきましょう。

####CVR（コンバージョン率）が高いページ
コンバージョン率は全セッションの内CVした割合を表しています。
セッション数はあまり多くないがCVRが高いページがあれば、デフォルトページをそのページにしたり、広告をクリックした時の入り口をそのページに設定するだけでCV数が簡単にUPするでしょう。
コンバージョンの設定については次の章で詳しく説明します。


#コンバージョンメニュー
コンバージョンとはサイト内でユーザーに行って欲しいゴールです。商品購入、投稿、会員登録などがコンバージョンに当たります。Googleアナリティクスを利用してページを改善していくのは結局はコンバージョン数を増やすためということを忘れないようにしましょう。
EコマースのサイトなのにPV数やセッション数ばかり増やしても最終的に商品購入がされなければ意味がありませんねw。

コンバージョンの設定方法はこの記事がまとまっているので参考にしてください。
https://wacul-ai.com/blog/access-analysis/google-analytics-setting/ga-cv/
Fluentd間でログを自己署名証明書で暗号化して送る

# 概要
タイトルのとおり、Fluentdで送信元サーバーと送信先サーバー間のログ送信する際に自己署名証明書を使用する際の設定で苦戦したのでメモっておきます。

## 証明書の作成
とりあえず有効期間30年の証明書作成。頻繁に証明書を置き換えられるならもっと短くてもいいと思います。

```
$ openssl req -new -x509 -sha256 -days 10800 -newkey rsa:4096 -keyout fluentd.key -out fluentd.crt
# パスフレーズいれる
your_passphrese

Generating a 4096 bit RSA private key
..........................++
....................................++
writing new private key to 'fluentd.key'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:eg
Common Name (e.g. server FQDN or YOUR name) []:
Email Address []:
```

## ログ送信元での設定
上記で作成したcrtファイルをログ送信元に置きます。
今回は`/etc/td-agent/certs/fluentd.crt`に置いています。
shared_keyはまぁ適当に設定してください。
バッファーなどの設定は適当ですので適宜変えてください。

```
<match **.*>
    @type forward
    transport tls
    tls_cert_path /etc/td-agent/certs/fluentd.crt
    # 自己署名証明書を使用するにtrue
    tls_allow_self_signed_cert true
    # 自己署名証明書を使用する際にはfalseを設定する必要があります。
    tls_verify_hostname false
    <server>
      host forward.exmple.com
      port 24224
    </server>
    <security>
      self_hostname outputlog.exmple.com
      shared_key hogehoge
    </security>
    <buffer>
      @type file
      path /var/log/td-agent/buffer/sec_forward
    </buffer>
    flush_interval 60s
</match>
```

## ログ送信先での設定
ログ受信時の設定を下記のようにします。
crtとkeyは作成したもの、shared_keyは送り元・送り先で同じフレーズを設定する必要があります。

```
<source>
  @type forward
  port 24224
  bind 0.0.0.0
  <security>
    self_hostname forward.exmple.com
    shared_key hogehoge
  </security>
  <transport tls>
    cert_path /etc/td-agent/certs/fluentd.crt
    private_key_path /etc/td-agent/certs/fluentd.key
    private_key_passphrase your_passphrese
  </transport>
</source>
```

# あとがき
もしよかったら私の[ブログ](https://toshi.click)でも同じようなこと書いてるので来てくれたらうれしいです。
lubridateのチートシートを和訳してみた

前々回は[stringrのチートシート](https://qiita.com/taro_6974/items/07b4d6b2b741d77989ee)、前回は[readrのチートシート](https://qiita.com/taro_6974/items/150454bc9fe260f94b32)を自分用に和訳してみたものを公開しましたが、今回はlubridateパッケージを和訳してみました。

これまで通り雑な翻訳をしてきているので原文と違うところがあると思います。
「いや、俺が知っているのと明らかに違うから！」と思われた箇所がありましたらお手数ですがコメントにてご指摘ください。ちょっとお時間いただくかもしれませんが修正します。

###lubridateのチートシートを和訳してみた

![lubridate_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162354/bf224da6-907b-c19a-bee2-287b4314bbe6.png)

![lubridate_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162354/ef76e509-b132-e95f-6738-d9ce2e90d925.png)

日付の処理にはlubridateっていうパッケージを使うと楽にやっつけられるんだなー、ということをお分かりいただければ幸いです。

やっていきましょう。

###参考

[lubridateのチートシート](https://lubridate.tidyverse.org/)
apache + laravel でURLのindex.phpの省略

[【Laravel 5.7対応】掲示板を作成するチュートリアル](https://blog.hiroyuki90.com/articles/laravel-bbs/)
こちらのチュートリアルでlaravelの使い方を一通り触ってみた。
環境は

| パッケージ | バージョン |
|:--|:--|
| OS | Centos7.6 |
| WEB | apache 2.4.6 |
| DB | MariaDB 10.3.16 |
| php | 7.2.18 |
| laravel | 5.8.24 |

記載がなく詰まったところ
・テストデータの流し込みで文字化け⇒なぜかJISファイルになっていたためUTF-8に変換
・storage配下のアクセス権限エラー⇒該当ディレクトリの権限をapacheに変更
・新規へのリンクを作成するも「Not Found(or Forbidden)」となる
⇒後述のrewrite設定が必要
・seeder周りでClass does not existとか出る。
⇒以下のコマンドを実行

```
$ composer dump-autoload
```

一通り終わりまでできたが
laravelで何も考えずにcreate-projectするとURLが
https://hoge.com/bbs/publicとなってしまう。
さらにactionを呼び出すと

https://hoge.com/bbs/public/index.php/posts/create
となり、URLが長くなる。

#### publicを消す方法

1. apahceのaliaseを使用

http.conf(もしくはssl.conf)のDocumentRootとAliasで対応
管理権限で上記ファイルを編集し、httpdの再起動

```http.conf(もしくはconf.d/ssl.conf)
<VirtualHost *:443>
(略)
Alias /bbs /var/www/hoge-bbs/public
<Directory "/var/www/hoge-bbs/public">
AllowOverride all
</Directory>
(略)
```
#### index.phpを省略

public配下にある.htaccessを編集

```(.htaccess)
RewriteEngine On
RewriteBase /bbs/ # 追加(ドメイン直下なら/だけでいい)
```
AtCoder灰色の駆け出しプログラマ

###灰色？
AtCoderとは競技プログラミングを開催してるサイトです。
そこでは、レートといって各々の成績にそって、ランクが分けられており、
上から順に
赤・橙・黄・青・水・緑・茶・灰・黒ってなってます
灰色は参加しただけでとれます。
つまり、灰色は本当にプログラミング初心者って感じです。
最近始めたばかりで弱弱ですけど、これから伸びるはず...
ちなみに僕の今のレートはこんな感じです！
<img width="646" alt="スクリーンショット 2019-06-26 13.50.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407528/b358737b-cfb7-f498-104f-bf88a73fa1e2.png">
他の人のブログみてても、すぐに灰色から抜け出していたので、こういうケースは珍しいと思います。
なにせ始めは標準入出力がよく分からず。時間をただただ潰していただですから...
はい、0点でしたwww

###なぜこんな事を書くのか
ほとんどの人は、僕の記事をみても役に立たないと思いますが、
本当に始めたばかりで色んな記事をみてきて、上の人をみて自分の実力の低さを悲しむ人にとっては、
あぁこんな人もいるんだなぁってぐらいにはなると思います！

ちなみにこれ、初投稿なのでMarkdownとかも全然わかってないです...
MacでRubyをバージョン管理するにはrbenvインストールをする


## MacでRubyをバージョン管理するにはrbenvインストールをする



```
$ brew install rbenv
```

```
$ gem install rbenv-rehash
```



### とりあえず最新バージョンをインストール

```
$ rbenv install 2.6.3
```



### 全体で使うRubyのバージョンを設定

```しかしこのままでは
$ rbenv global 2.6.3
```

```
$ ruby -v
```



してもMacで標準で入っているrubyのバージョンが出てしまいします



```
$ which ruby
/usr/bin/ruby
```



### Rubyのpathをrbenvに変更する



```
$ vi ~/.bash_profile
export PATH="~/.rbenv/shims:/usr/local/bin:$PATH"
eval "$(rbenv init -)"
$ source ~/.bash_profile 
```



これでもう一度

```
ruby -v
```

で確認するとインストールしたrubyのバージョンが表示されるはずです。