OmniAICreator/Qiita-1.07M huggingface dataset:
Firebase 静的サイト（html CSS JavaScript)をデプロイ

##Firebaseにてデプロイの記録##

【使用環境】
html 
CSS 
JavaScript
macbook

＜次回の時短の為に記録＞

---

##Firebaseにて登録、 （googleアカウント必要）ログイン##

https://firebase.google.com/


新しいプロジェクトフォルダをFirebase　HP内で作成する。
<img width="361" alt="スクリーンショット 2020-01-18 17.31.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547910/d8478159-dc39-5998-bc49-fc8b7699e6fd.png">


---

ここからターミナルで

###今回は下記②の設定のために　public ディレクトリ　配下にデプロイアプリ（html CSS JavaScript　img等)を配置###

URL　＞　ルートパスの為

---

デプロイにGitHubは必須ではないが、
git add   ←必要なら
git commit　　　←必要なら
push  ←必要なら

---

###① firebase-tools をインストール###

```
（npm がインストールされている前提）
$ npm install -g firebase-tools

$ npm -v

$ firebase -V

$ firebase login

```

アプリディレクトリへ移動後、

###①初期化###

```
$ firebase init
```
この画面が出る
<img width="634" alt="スクリーンショット 2020-01-18 16.53.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547910/7f6125b7-8616-b1cb-5784-2d74e2f12816.png">







PCの矢印キーで　Hosting: 　を選択。　（色が変わる。かつ●へ）
エンター
<img width="642" alt="スクリーンショット 2020-01-18 16.53.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547910/8d58e187-d56d-c0cd-8fd1-b9dd359b8260.png">



####firebaseのHPで作成した####
####アプリを関連付けるプロジェクトを選択するよう求められる####
Use an existing project を選んで エンター
<img width="496" alt="スクリーンショット 2020-01-18 16.55.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547910/bb961b23-8adb-61d2-91fd-5740d0c5518e.png">

HPで作成したプロジェクト一覧がでる。
今回のものを選択し、エンター

（画像はありません）


#②#

ディレクトリのパスを聞かれるのでデフォルト (/public) のまま エンター

<img width="548" alt="スクリーンショット 2020-01-18 17.19.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547910/e2436517-827b-0386-7f01-f1a603f13608.png">

>Configure as a single-page app (rewrite all urls to /index.html)? (y/N) 
他も動かすため、推奨　Nを選択

>File public/index.html already exists. Overwrite? 
作成したindex.htmlが上書きされるので　推奨　Nを選択



###complete!###
<img width="421" alt="スクリーンショット 2020-01-18 17.23.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547910/dd25df6b-2385-8a0e-0868-fcda58f6f70f.png">

初期化が完了

---

##デプロイ##

そのままの階層で　

```
＄　firebase deploy
```

<img width="331" alt="スクリーンショット 2020-01-18 17.25.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547910/d2207fab-ef1e-834f-f88e-975f35ca3897.png">

↑　ここの下に　URLがある。

###デプロイ完了###

（修正後の再デプロイは、＄　firebase deployだけで↑は不要）


---


##2回目以降の事象##


```
$ firebase login

>Error: Server Error. certificate has expired
```

<img width="406" alt="スクリーンショット 2020-01-18 16.47.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547910/55889823-1280-f2a0-a33d-9d242ab37cee.png">



その為、
###firebase-toolsをupdateする必要がある###

```
$ sudo npm i -g firebase-tools 

$ firebase login　　　
```

ログインできた
uGUIで線を引く～その３：線の端を垂線にする～

# はじめに
前回の続きです
[uGUIで線を引く～その２：線の描画編～](https://qiita.com/inpax23/items/5af5eb2a8d9722fadcad)
線の先端が縦固定になってしまっているため、線の角度によって、変更するようにします
# 流れ
①実際に引きたい線（以下、本線という）の単位垂直ベクトルを求める
②本線の端座標から、垂直線を引く
③本線の端座標から、垂直線上の双方向にweight/2分ずらした座標を、メッシュ描画時に使用する
#垂直ベクトルを求める
垂直のベクトルは内積が1なので、本線の傾きを表すベクトルを(x,y)、垂直ベクトルを(a,b)とすると
`x * a + y * b = 0`
が成り立つ。
手順③を考えると、単位ベクトルがほしいので、
`a * a + b * b = 1`
も成り立つようにする。
上記２つの式から、aとbを求めることができる。
....が！！ただ、実際計算したら、ルートを含むごちゃごちゃした式が出てきたので、シンプルに以下のようなコードにしてみた

①一度単位ベクトルにせず、a = 1として垂直ベクトルを取得
②Vector2のnormalizedプロパティで単位ベクトル取得

```cs
    private Vector2 CalcurateVerticalVector(Vector2 vec)
    {
        Vector2 v = new Vector2(1.0f, -vec.x / vec.y);
        return v.normalized;
    }
```
これを使って、以下のようなコードになりました

```csharp
using UnityEngine;
using UnityEngine.UI;

// ↓ugui描画に必須なコンポーネント達
[RequireComponent(typeof(CanvasRenderer))]
[RequireComponent(typeof(RectTransform))]
public class UIOneLine : Graphic
{
    [SerializeField]
    private Vector2 _position1;
    [SerializeField]
    private Vector2 _position2;
    [SerializeField]
    private float _weight;

    protected override void OnPopulateMesh(VertexHelper vh)
    {
        // （１）過去の頂点を削除
        vh.Clear();

        // （２）垂直ベクトルの計算
        var pos1_to_2 = _position2 - _position1;
        var verticalVector = CalcurateVerticalVector(pos1_to_2);

        // （３）左下、左上のベクトルを計算
        var pos1Top = _position1 + verticalVector * -_weight / 2;
        var pos1Bottom = _position1 + verticalVector * _weight / 2;
        var pos2Top = _position2 + verticalVector * -_weight / 2;
        var pos2Bottom = _position2 + verticalVector * _weight / 2;

        // （４）頂点を頂点リストに追加
        AddVert(vh, pos1Top);
        AddVert(vh, pos1Bottom);
        AddVert(vh, pos2Top);
        AddVert(vh, pos2Bottom);


        // （５）頂点リストを元にメッシュを貼る
        vh.AddTriangle(0, 1, 2);
        vh.AddTriangle(1, 2, 3);
    }
    private void AddVert(VertexHelper vh, Vector2 pos)
    {
        var vert = UIVertex.simpleVert;
        vert.position = pos;
        vert.color = color;
        vh.AddVert(vert);
    }

    private Vector2 CalcurateVerticalVector(Vector2 vec)
    {
        // 0除算の防止
        if (vec.y == 0)
        {
            return Vector2.up;
        }
        else
        {
            var verticalVector = new Vector2(1.0f, -vec.x / vec.y);
            return verticalVector.normalized;
        }
    }
}

```
# 結果
できました！
![VerticalOneLine.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321577/b61a1887-fcbd-7244-063d-c5609ed1222d.gif)

# ランタイムで線を動かす
今回の例ではインスペクターの値をいじって線を動かしていますが、
もしランタイムでスクリプトから変更を加える場合は、毎回ダーティフラグをたてて、システム側に変更があったことを伝える必要があります。

ダーティフラグは、 `SetVerticesDirty();`で立てることができるので、忘れないよう注意！

# おわりに
気が向いたら、LineRendererみたいに配列でもらった座標をもとに折れ線を作れるようにします。
ここまで読んでくださって、ありがとうございました！

<img width="200" src="https://media1.tenor.com/m/2lS4R2J4ZRMAAAAd/grilla-yes.gif">
FontAwesomeをhamlに導入する際に詰まったお話

TwitterやFacebook等のリンク用のアイコンとしてよく使われるFontAwesomeだが、今回はこれをRailsアプリケーションに導入する方法を記述していく。

## FontAwesomeのサイト

https://fontawesome.com/
こちらのサイトから利用する。Proと付いているものは有料だが、それ以外であれば無料で使える。

## 前提
RailsにFontAwesomeを導入する方法として2通りある。
gem 'font-awesome-rails'を利用するか、gem 'font-awesome-sass'を利用するか
の2種類。

FontAwesomeが導入できるという点では変わらないが、違いとしては、
**'font-awesome-rails'ではfa_icon, fa_stacked_iconの二種類のヘルパーメソッドが使用できる**が、**最新版のfont-awesome5に対応していない**
**'font-awesome-sass'では上記二種類のヘルパーメソッドが使えない**が、**最新版のfont-awesome5が利用できる**

という事。
エラーは出ないけど表示されないなと思ったらfont-awesome-railsでfont-awesome5のアイコンを使おうとしていた。
また、fa_iconやfa_stacked_iconを使っているのにundefined methodと怒られている場合はfont-awesome-sassを使っている、という点に気を付けよう。

## 先に結論を言うと

**gem 'font-awesome-sass'を使いましょう**。新しいアイコンも使いたくなるでしょうし。
下に記述するが、fa_iconが使えないだけで他の記述で使えるので。

## 導入手順（font-awesome-sass）
今回は例としてbookを導入する。
<img width="67" alt="スクリーンショット 2020-01-18 17.03.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517665/798bb527-2d6e-4125-2aa3-b723163c1aaa.png">
①gemを記述する

```ruby:Gemfile
gem 'font-awesome-sass', '~> 5.4.1'
```

②bundle installを行う

```
$ bundle install #bundleでも可
```

③application.scssに下記を追加

```css:application.scss
@import 'font-awesome-sprockets';
@import 'font-awesome';
```

④実際に使えるかを確認する。

```haml:
= icon("fas", "book")
```

fontawesome上では`<i class="fas fa-book"></i>`と記述されており、それを上記に当て込む事で利用可能である。

## 手順（font-awesome-rails）
一応こちらも記述する。
①下記gemをGemfileに記述する。

```ruby:Gemfile
gem "font-awesome-rails"
```

②bundle installを行う

```:ターミナル
$ bundle install #bundleでも可
```

③application.scssにて下記を追加する。

```css:application.scss
@import 'font-awesome-sprockets';
@import 'font-awesome';
```

ここまでは同じ。使い方が先程とは異なる。

```haml:
= fa_icon 'book'
```

## 総評
これまではあまり深く考えてなかったが、qiitaの記事の中でもfont-awesome-sassを入れながらもfa_iconを使う記事があり、そこで少し詰まってしまった。
自分で検証しているので今回の内容に相違は恐らくないとは思うが、他にも書き方はあるのだと思う。
間違っていたらご指摘頂けたら喜んで土下座します。
GASで日本地図を表示する

GAS(Google App Script) で日本地図を表示します。D3のバージョン違いで結構つまずいたので、2020年1月時点での下記バージョンでの例をまとめておきます。

- d3.js v5.15.0
- topojson v3.0.2

# ツールのインストール

地図データを変換するために使うツールをインストールします。

```bash
$ brew install gdal node jq
$ npm i -g topojson json-to-js
```

# 地図データのダウンロード

地図データは[元記事](https://qiita.com/ran/items/d88c5126362576be3291)と同じ通り、[Natural Earth](http://www.naturalearthdata.com/)から地図データをダウンロードします。

```bash
$ curl -#L http://www.naturalearthdata.com/http//www.naturalearthdata.com/download/10m/cultural/ne_10m_admin_1_states_provinces.zip | bsdtar -xf- -C .
```

日本地図データの GeoJSON を作成します。

```bash
$ ogr2ogr -f GeoJSON -where "adm0_a3 = 'JPN'" pref.json ne_10m_admin_1_states_provinces.shp
```

同様に`静岡県`の修正をします。

```bash
$ cat pref.json | jq '.features[30].properties.name_local|="静岡県"' > pref2.json
```

次に TopoJSON を作成します。

```bash
$ geo2topo -p name -p name_local -p latitude -p longitude -o japan.json pref2.json
```

作成された japan.json を後の GAS で使いやすくするために、JavaScript のリテラルに変換します。

```bash
$ cat japan.json | json-to-js > japan.js
```

# GASでHTMLを用意する

Google Drive を開き、Google Apps Script を新規作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59468/877ac5d0-90c8-5d9e-87c2-5e57b57a08df.png)

下記３つのファイルを追加します。

```javascript:コード.gs
function doGet() {
  return HtmlService.createTemplateFromFile("index").evaluate();
}
```

```html:index.html
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <script src="https://d3js.org/d3.v5.min.js"></script>
    <script src="https://unpkg.com/topojson@3"></script>
  </head>
  <body>
    <div class="japan"></div>
    <script>
      var width = 960,
          height = 1160;
      var color = d3.scaleOrdinal(d3.schemeCategory10);
      var projection = d3.geoMercator()
        .center([135, 35])
        .scale(2400)
        .translate([width / 2, height / 2]);
      var path = d3.geoPath().projection(projection);
      var svg = d3.select(".japan").append("svg")
        .attr("width", width)
        .attr("height", height);
      var topoJapan = <?!= HtmlService.createHtmlOutputFromFile("topoJapan").getContent() ?>;
      var geoJapan = topojson.feature(topoJapan, topoJapan.objects.pref);
      svg.selectAll(".pref")
        .data(geoJapan.features)
        .enter()
        .append("path")
        .attr("stroke", "#999")
        .attr("fill", "none")
        .attr("d", path);
    </script>
  </body>
</html>
```

元記事では `d3.json(...).then(...)` を使っているが、GAS では XHR が使えないため、作成した japan.js をそのまま読み込ませている。

```javascript:topoJapan.html
/* TODO: japan.js ファイルをコピー */
```

ここで、GAS ではすごく長い１行をレンダリングするために５分くらいかかってしまうので、**絶対に japan.json を GAS に貼り付けてはいけない。**（体験談）


# ウェブに公開する

公開 > ウェブアプリケーションとして導入... をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59468/43e0428a-dcf3-7b48-3131-d91db266401c.png)

アクセスを全員にして、公開/更新をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59468/acb322f2-9c28-e96d-f350-391853076d4d.png)


実際のページはこちら
https://script.google.com/macros/s/AKfycbyhpbiK4wsFBwEI0uKT6iOctE9mK9f4-LxrpgRiLGnBb61nqA5o/exec

# 参考

- https://qiita.com/ran/items/d88c5126362576be3291
- http://deep-blend.com/jp/2014/06/d3-js-map-japanese-map/
Rust で素数計算

# コード

Rust で素数計算のプログラムを書いた。
私が新しい言語を覚えるたびにいつもするやつである。

```rust
fn main() {
    for i in 1..100 {
        if is_prime(i) {
            println!("{}", i);
        }
    }
}

fn is_prime(n: u32) -> bool {
    if n < 2 {
        false
    } else if n == 2 {
        true
    } else if n % 2 == 0 {
        false
    } else {
        let mut i = 3;
        while i * i <= n {
            if n % i == 0 {
                return false;
            }
            i += 2;
        }
        true
    }
}
```

# 感想

まだ所有権の勉強をしていないので、いまのところは、スクリプト言語のようにお気楽な言語という印象。静的型付き言語だが、型推論が賢いのでほとんど明示的に型注釈を書く必要がない。あと、エラーメッセージが本当に親切！！これは感動する。

`if` が式だったり、関数の最後に式があれば `return` 不要で戻り値として扱われるのは、Ruby の影響だったりするのかな？

`{}` はあるけど、`if` の後ろにカッコが不要なあたりとか、パッと見では Go 言語にも似ている。もちろん、中身はぜんぜん違うわけだけど。  

# 参考

[公式チュートリアル（日本語)](https://doc.rust-jp.rs/book/second-edition/)
PyQt5 vs. Qt for Python(PySide2)

# 概要
本記事は、12/15 投稿記事 [PyQt入門編](https://qiita.com/ynuma/items/6452927e4332f1923f59)で調べ切れなかったことについての追加調査結果をまとめます。

具体的には、PyQt5, Qt for python(PySide2) 両者の違いを比較したいと思います。

# 簡易比較表

以下、Web 上の情報を元に、主な違いを表にまとめてみます。

| Category | PyQt5 | Qt for Python |
| :--- | :--- | :--- | 
| Vendor | Riverbank Computing 社 | The Qt Company |
| License | GPLv3<br>Com.[^1] | LGPLv2.1<br>GPLv3<br>Com.[^1] |
| Python Version | 3.5+(3.7.3で確認済) | 3.5+ |
| URL | https://www.riverbankcomputing.com/software/pyqt/intro | https://www.qt.io/qt-for-python |
| 開発開始時期 | 早い | 遅い |
| シェア | 大 | 中？ |
| Version up | 早くて多い | ある程度まとめて？ |
| Document | 多い(英語) | 少ない(英語) |
| 言語制約 | 緩め | 厳密 |
| QtQuick,QML | Full support | Full support |

[^1]: Commercial Licence の略

# 解説

ライセンスについては、LGPL が選択できる Qt for Python に分がありますが、PyQt5 は先行して開発した分、アプリケーションやライブラリ、ドキュメントなどが充実しているようです。

API について、 PyQt は Qt のオリジナルにはない独自のクラスを残している事があるようです。言語レベルでの制約は比較的緩めのようです(色々な書き方をしても、比較的安定して動作するようです)。
Qt for Python は過去の縛りが少ないためなのか、Qt の Core クラスをそのまま使えるように配慮するなど、スッキリしたAPIを目指しているようです。
例えば、以下の signal, slot の定義です。

```:PyQt5
valueChanged = pyqtSignal([dict], [list])

@pyqtSlot(int, str)
def foo(self, arg1, arg2):
    """ C++: void foo(int, QString) """
```
```:PySide2
speakNumber = QtCore.Signal(int)

@QtCore.Slot(str)
def saySomeWords(words):
    print words
```

# 近年の傾向

数年前までは、Qt for Python(PySide) は PyQt の一部の API をサポートするレベルであり、Python のサポートバージョンも古く、動作が不安定、というような問題もあったようです。
しかし、Qt 開発元の The Qt Company が力を入れてサポートしているため、徐々に差がなくなって来ているようです。


# まとめ

まとめると、どちらかが突出してよい、というわけではなさそうです。
個人的見解となりますが、PyQt は、商用利用する必要がない社内評価用アプリケーションなどを作成するのに適しているのではないか、と思っています。なぜなら、過去の豊富な PyQt アプリ・ライブラリ・ドキュメントが利用可能なため、開発スピードも早く済むのではないか、と思います。
一方、Qt for Python は商用利用に適しているかと思われます。PyQt から Qt for Python への移植も比較的楽にできるようなので、PyQt でプロトタイプ作成し、Qt for Python に移植する、という流れが良いかもしれません。
ScriptRunnerを使ってスクリプトを実行してみた

# はじめに
　SuperStream-NXシステム連携ツールで作成したスクリプトの実行方法として、外部からスクリプトの実行ができるScriptRunnerを利用してみました。

# 環境情報
- OS：Windows Server2012
- SuperStream-NXシステム連携ツール：4.1 SP2(2018-06-01版)


# 設定手順
1. 設定ファイルを作成する
    1. Studioを開く
    2. プロジェクトを開く
    3. 設定ファイルを作成したいプロジェクトを右クリックし、「プロジェクトをサービスとして登録」をクリック
    ![プロジェクト.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390247/f59f344f-f27d-8663-0e9f-5208f45b75f0.png)

    4. 設定ファイルを作成したいスクリプトを右クリックし、「スクリプト実行用XMLの出力」をクリック
    ![実行用XML.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390247/bd139689-eb04-79d8-7089-deaec4bddddb.png)





# 実行手順
1.スクリプトの実行
　　1. コマンドプロンプトから「..\NXConnect\client\bin」のScriptRunner.exeを起動
　　2.  正常終了をを確認する
    ![ステータス.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390247/c8c683db-4f35-a936-bd27-ac85b87622c7.png)
※設定ファイルがデフォルトでない場合、引数にxmlファイルを指定する


# 最後に
　ScriptRunnerを使う事で、ユーザーに手動実行を行わせることができます。
システム連携ツールについては他にも便利な機能があるため別の機会で纏めようと思います。
GitHub ActionsでRe:VIEW StarterのPDFを生成する

### 概要
[Re:VIEW Starter](https://kauplan.org/reviewstarter/)を使うと、GUIを使って簡単に綺麗な体裁を作ることが出来ます。
GUIで質問に答えるだけでRe:VIEW一式がZIPファイルでダウンロードできます。
非常に便利で使いやすいのでオススメです。
今回は**時代に乗るため**、このZIPファイルにひと手間加えてPDFを[GitHub Actions](https://help.github.com/ja/actions)で生成してみたいと思います。
なお、前回は[Wercker](https://kawahara-ci.hatenablog.com/entry/2019/06/28/wercker)で原稿をビルドしていました。
### 手順
1. Re:VIEW Starterを使って、Re:VIEW一式のZIPファイルを作成しダウンロードする。
2. ZIPファイルを解凍する。
3. 下記のワークフローファイルを作る。
4. GitHubのGUIで解凍したZIPファイルのディレクトリー名でレポジトリを作成する。
5. すべてのファイルをGitHubにpushする。
6. GitHub Actionsのページに行きZIPファイルをダウンロードする。
7. ZIPファイルを解凍するとPDFができています。
あとは、ファイルを更新してGitHubにpushするだけでPDFが作成できます。

![zip.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77441/058735e1-af65-a2a3-3828-1b3a98a46fd8.png)

そして、次の項目から、この記事の肝である、ワークフローファイルについての説明です。
なお、特に内容を変更しなくても、ワークフローファイルを追加してGitHubに入れるだけでPDFが作成されます。

### ワークフローファイルを作る
ワークフローファイルは `.github/workflows`に用意する。
今回用意したファイルは`.github/workflows/pdf.yml`になります。

```yml:.github/workflows/pdf.yml
name: Generate pdf
on: push

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@master
      - uses: docker://kauplan/review2.5
      - run: docker run --rm -v $PWD:/work kauplan/review2.5 /bin/bash -c "cd /work; rake pdf"
      - name: Get Repository Name
        id: Repository
        run: echo ::set-output name=name::${GITHUB_REPOSITORY##*/}
      - uses: actions/upload-artifact@v1.0.0
        with:
          name: ${{ steps.Repository.outputs.name }}
          path: ${{ steps.Repository.outputs.name }}.pdf
```
### 説明
簡単に説明します。
### on
`on: push`はコミットしたら動くという記述です、ここを変えることで色々なトリガーを決めれます。
### runs-on
`runs-on: ubuntu-latest`は動かす環境です、課金が安いubuntuを使いますが、FREEプランでも課金に達することは無いです。
### actions/checkout@master
`uses: actions/checkout@master`は対象のレポジトリーをチェックアウトします、今回はmasterブランチをチェックアウトします。
### docker
`docker://kauplan/review2.5`はDockerHubからイメージをPullします。標準のRe:VIEWなら`docker://vvakame/review:4.0`などを使います。
### run
runでコマンドラインを実行させます。
### id
`id: Repository`で変数名を定義します。
### ::set-output
`run: echo ::set-output name=name::${GITHUB_REPOSITORY##*/}`で、`steps.Repository.outputs.name`の変数名にGitHubレポジトリー名を取得します。そのままだとユーザー名も入ってしまうので、`##*/`を使いリポジトリー名の`/`の後半を取ります。
### actions/upload-artifact＠v1.0.0
`actions/upload-artifact@v1.0.0`は出来上がったpdfをダウンロードするためのアクションツールです。
これを使用すると、GitHub Actionsの画面に以下のようなビルドしたPDFをダウンロードできるリンクが出ます。
![zip.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77441/058735e1-af65-a2a3-3828-1b3a98a46fd8.png)
よく使うHTMLタグ一覧

使用頻度が高いHTMLタグをまとめてみました。



<h1>基本構造</h1>
|タグ|名前|用途|
| --- | --- | --- | 
|html|エイチティーエムエル|HTML文書を表す|
|head|ヘッド |HTML文書のヘッダー部分。説明文、CSSファイルのリンク、ページタイトルを記述する|
|mata|メタ |言語や説明文など、ページ情報を記述する|
|title|タイトル|ページのタイトル。この部分がページタイトルとして表示される |
|link|リンク|参照する外部ファイル(CSSファイルなど)|
|body|ボディー|HTML文書のコンテンツ部分。この中に記述されたものがブラウザに表示される |

<h2>コンテンツ内</h2>

|タグ|名前|用途 |  
| ---| ---| --- |
|h1-h6|エイチワン・ヘディング|見出し　数字の順に記述|
|p|ピー・パラグラフ|文章の段落|
|a|エー・アンカー|リンクを貼る。リンク先href属性|
|img|イメージ|画像を表示。src属性で画像を指定|
|ul|ユーエル・アンオーダードリスト|番号のない箇条書きリスト|
|li|エルアイ・リスト|リストの各項目|
|br|ビーアール・ブレーク|改行|
|span|スパン|意味を持たないインライン要素。CSSで一部のみ装飾するとき使用する|
|strong|ストロング|強い重要性要素。一般的に太文字|
|small|スモール|著作権・法的表示|
|blockquote|ブロッククォート|引用文・転載であることを表わす|
|audio|オーディオ|音声データ埋め込む|
|video|ビデオ|動画データを埋め込む|
|script|スクリプト|scriptデータ埋め込んだり参照。javascriptのコードを使用する。|

<h3>表</h3>

|タグ|名前|用途|
|---|---|---|
|table|テーブル|表を示すタグ。表全体で囲む|
|tr|ティーアール・テーブルロウ|表の一行を囲む|
|th|ティーエイチ・テーブルヘッダー|表の見出しセルを表す|
|td|ティーディー・テーブルデータ| データセルを表す|

<h4>フォーム</h4>

|タグ     |  名前 | 用途|
|---|---|---|
|form|フォーム|フォームを作成|
|input|インプット|フォームにおける入力フォーム作成|
|<input type="text">|テキスト|1行テキスト入力欄|
|<input type="checkbox"|チェックボックス|チェックボックス。複数の項目を選択可能|
|<input type-"radio"|ラジオ|ラジオボタン複数項目のうち一つ選択可能|
|select|セレクト|セレクトボックス|
|option|オプション|セレクトボックスの選択項目を作成|
|textarea|テキストエリア|複数行テキストの入力欄|
|label|ラベル|フォームのラベル。フォームのパーツと項目の名前を関連つける|
|placeholder|プレースホルダ|入力欄に(例)初期表示する内容を指定できる|

<h5>グループのブロック要素</h5>
|タグ     |  名前      |    用途|
|---|---|---|
|div|ディブ・ディヴィジョン|意味を持たないブロック要素|
|header|ヘッダー|ページ上部にある要素。主にロゴやメニューで使用|
|nav|ナビ|メインのナビゲーションメニュー|
|artcle|アーティクル|ページ内の記事となる部分。その文章やコンテンツだけが独立しても意味が通るような箇所を示す要素。(例)ブログの記事やニュースサイトの記事など|
|aside|アサイド|本文ではない補足情報。メインコンテンツとは関連性が低い情報。(例)サイドナビに配置した補足的なテキストや他サイトへのリンク、バナー、広告など|
|section|セクション|一つのテーマを持ったグループ|
|main|メイン|ページのメインコンテンツ部分|
|footer|フッター|ページ下部にある要素。メニュー一覧（フッターメニュー）や著者情報、会社情報、免責事項ページなどへのリンクや、コピーライトなど|
CentOS 8 で Ruby 2.5 から Ruby 2.6 へアップグレード（AppStream）

# はじめに

Application Stream(AppStream)を利用してCentOS8にRuby2.6をアップグレードインストール
参考：[ユーザー空間コンポーネントのインストール、管理、および削除 Red Hat Enterprise Linux 8 \| Red Hat Customer Portal](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/8/html-single/installing_managing_and_removing_user_space_components/index#switching-to-a-later-stream_managing-versions-of-appstream-content)

## サポート

各Streamのサポート期間は[Red Hat Enterprise Linux 8 Application Streams Life Cycle - Red Hat Customer Portal](https://access.redhat.com/node/4079021)を参照。
それ以降に報告された脆弱性や不具合への対応は実施されない可能性がある。
なおCentOS Linux 8が2021-12にEOLを迎えるため、それ以降の更新を受けるためにはCentOS Stream8を含めた他ディストリビューションへの移行が必要。

## LOG

### Ruby2.5(default)インストール

```shell-session
# cat /etc/redhat-release
CentOS Linux release 8.1.1911 (Core)

# yum install -y ruby
... 略

# ruby -v
ruby 2.5.5p157 (2019-03-15 revision 67260) [x86_64-linux]
```

### Stream切り替え

```shell-session
# yum distro-sync
# yum module reset ruby
# yum module enable ruby:2.6
# yum distro-sync

# ruby -v
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-linux]
```
初めてのGitHubを使ったのでその手順をまとめてみた

# 最初に
初めてGitHubを使ったのでその手順をシェアしたい。
これは、[侍エンジニア塾の記事](https://www.sejuku.net/blog/70775)を自分なりにまとめたものである。
GitHubでは次の４つの用語がよく使われる
1. リポジトリ
2. コミット
3. プッシュ
4. ブランチ
それぞれの説明は[TechAcademy](https://techacademy.jp/magazine/6235)などが説明してくれるので参考に。
**事前に[侍エンジニア塾の記事](https://www.sejuku.net/blog/70775)を見て[GitHub](https://github.co.jp/)の登録は済ませてください** 

# 具体的な手順
### 事前準備
まずは、適当なディレクトリ(ここでは 'github' を作り、その中に 'pushtest')を作る。

```terminal
$ mkdir github     
$ cd gitbub
$ mkdir pushtest
$ cd pushtest
```
###ローカルリポジトリの作成
次に、ローカルリポジトリを作成する

```terminal
$ git init
```
すると、'pushtest' 直下にローカルリポジトリが作成され、ターミナルに次のように表示される。

```terminal
Initialized empty Git repository in ... /github/pushtest/.git/
```
基本的にローカルリポジトリで作業を行い、その作業内容をリモートポジトリへプッシュする流れで行う。

### ファイルをローカルリポジトリにコミット
続いて、'pushtext' 内に、内容は何でも良いので適当なテキストファイル作る。ただし、ファイルの名前は 'pushtest.txt' にする。
これをリポジトリに追加していくのだが、まずは 'pushtest.txt' がGitの管理下に入ってほしいので、

```terminal
$ git add pushtest.txt
```
を入力する。
そして、いよいよファイルをリポジトリに追加するために、

```terminal
$ git commit -m "ここにコメントを書くこともできる"
```
を入力する。すると、

```terminal
Your name and email address were configured automatically based
on your username and hostname. Please check that they are accurate.
You can suppress this message by setting them explicitly: ...
```
のように表示される。**なお、この瞬間にmasterブランチが生成される**

詳しいgit addコマンドの使い方：[エンジニアの入り口](https://eng-entrance.com/git-add)
詳しいgit commitコマンドの使い方：[TechAcademy](https://techacademy.jp/magazine/10172)

### リモートリポジトリにプッシュ
最後に、ローカルリポジトリにコミットされたファイルを、リモートリポジトリにプッシュする。手順は、以下の通り。

```terminal
$ git remote add origin https://github.com/ユーザーID/push_test.git 
$ git fetch                                                      
$ git merge --allow-unrelated-histories origin/master              
$ git push origin master                                            
```
やっていることは、
1. リモートリポジトリをoriginと名付けて生成。
2. fetchでリモートリポジトリの状態を取得。
3. mergeで、リモートリポジトリのmasterブランチの状態をローカルリポジトリに反映。
4. originというリモートリポジトリのmasterというブランチにプッシュ。

これで、

```terminal
Counting objects: 3, done.
Writing objects: 100% (3/3), 245 bytes | 245.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To https://github.com/takataka58/push_test.git
 * [new branch]      master -> master
```
となれば成功！！
[git mergeコマンド](https://www.sejuku.net/blog/71003)と[git fetchコマンド](https://www.sejuku.net/blog/71164)の詳しい説明は侍エンジニア塾に図付きである。

#[サルでもわかるGit入門](https://backlog.com/ja/git-tutorial/)
だいぶわかりやすい。サルでもわかると銘打っているだけはあります。
CentOS 8 で PHP 7.2 から PHP 7.3 へアップグレード（AppStream）

# はじめに

Application Stream(AppStream)を利用してCentOS8にPHP7.3をアップグレードインストール
参考：[ユーザー空間コンポーネントのインストール、管理、および削除 Red Hat Enterprise Linux 8 \| Red Hat Customer Portal](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/8/html-single/installing_managing_and_removing_user_space_components/index#switching-to-a-later-stream_managing-versions-of-appstream-content)

## サポート

各Streamのサポート期間は[Red Hat Enterprise Linux 8 Application Streams Life Cycle - Red Hat Customer Portal](https://access.redhat.com/node/4079021)を参照。
それ以降に報告された脆弱性や不具合への対応は実施されない可能性がある。
なおCentOS Linux 8が2021-12にEOLを迎えるため、それ以降の更新を受けるためにはCentOS Stream8を含めた他ディストリビューションへの移行が必要。

## LOG

### PHP7.2(default)インストール

```shell-session
# cat /etc/redhat-release
CentOS Linux release 8.1.1911 (Core)

# yum install -y php
... 略

# php -v
PHP 7.2.11 (cli) (built: Oct  9 2018 15:09:36) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
```

### Stream切り替え

```shell-session
# yum distro-sync
# yum module reset php
# yum module enable php:7.3
# yum distro-sync

# php -v
PHP 7.3.5 (cli) (built: Apr 30 2019 08:37:17) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.5, Copyright (c) 1998-2018 Zend Technologies
```
Heroku にデプロイすると"Process exited with status 143"が出たとき

# Process exited with status 143
Heroku にアプリをデプロイしてコンソールを眺めているとエラーが出ました。
```
Process exited with status 143
```
しかし```Build succeeded```とは表示されます。気になったので調べてみると、Herokuアプリを再起動する必要があるようです。

## 参考
https://stackoverflow.com/questions/15767685/understanding-heroku-server-status-143
CentOS 8にNode.js 10をインストール（AppStream）

# はじめに

Application Stream(AppStream)を利用してCentOS8にNode.js 10をインストール
参考：[RHEL8のパッケージ構成 - BaseOSとApplication Stream - 赤帽エンジニアブログ]( https://rheb.hatenablog.com/entry/rhel8_baseos_and_appstream)

## サポート

本手法で導入した場合、[Red Hat Enterprise Linux 8 Application Streams Life Cycle - Red Hat Customer Portal](https://access.redhat.com/node/4079021)より、2021-04がEOLだと思われる。
それ以降に報告された脆弱性や不具合への対応は実施されない可能性がある。

## LOG

### インストール

```shell-session
# cat /etc/redhat-release
CentOS Linux release 8.1.1911 (Core)

# yum install -y @nodejs:10
... 略
```

### 各種確認

```shell-session
# which node
/usr/bin/node

# node -v
v10.16.3

# yum module info nodejs:10
Failed to set locale, defaulting to C.UTF-8
Last metadata expiration check: 0:01:24 ago on Sat Jan 18 08:05:14 2020.
Name             : nodejs
Stream           : 10 [d][e][a]
Version          : 8000020191007212731
Context          : 55190bc5
Architecture     : x86_64
Profiles         : common [d] [i], development, minimal, s2i
Default profiles : common
Repo             : AppStream
Summary          : Javascript runtime
Description      : Node.js is a platform built on Chrome's JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.
Artifacts        : nodejs-1:10.16.3-2.module_el8.0.0+186+542b25fc.src
                 : nodejs-1:10.16.3-2.module_el8.0.0+186+542b25fc.x86_64
                 : nodejs-debuginfo-1:10.16.3-2.module_el8.0.0+186+542b25fc.x86_64
                 : nodejs-debugsource-1:10.16.3-2.module_el8.0.0+186+542b25fc.x86_64
                 : nodejs-devel-1:10.16.3-2.module_el8.0.0+186+542b25fc.x86_64
                 : nodejs-devel-debuginfo-1:10.16.3-2.module_el8.0.0+186+542b25fc.x86_64
                 : nodejs-docs-1:10.16.3-2.module_el8.0.0+186+542b25fc.noarch
                 : nodejs-nodemon-0:1.18.3-1.module_el8.0.0+14+a5a48e73.noarch
                 : nodejs-nodemon-0:1.18.3-1.module_el8.0.0+14+a5a48e73.src
                 : nodejs-packaging-0:17-3.module_el8.0.0+186+542b25fc.noarch
                 : nodejs-packaging-0:17-3.module_el8.0.0+186+542b25fc.src
                 : npm-1:6.9.0-1.10.16.3.2.module_el8.0.0+186+542b25fc.x86_64

Hint: [d]efault, [e]nabled, [x]disabled, [i]nstalled, [a]ctive
```
Raspberry Pi イメージの最小化を行う装置

![IMG_7226.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6047/3907e9e4-7369-50fe-8592-4effbedd8d0d.jpeg)

## モチベーション

SDイメージ最小化装置、Raspberry Piのイメージのバックアップや、配布用の最小イメージ作成には欠かせないツール。
しかし、これといって、手軽なものが世にないので、適当に自作する。

なお、手元では何故かRaspbian系だとうまくいかないことが多かったので、CentOSで構築する。

## イメージの用意

CentOSのArmイメージは、 https://wiki.centos.org/Download の、AltArch Releases から拾える。
ちなみに、Raspi4向けは、Infoから辿ってゆくと発見できるらしい。

なお、今回使用したのはこちらのイメージ。
CentOS-Userland-7-armv7hl-RaspberryPI-Minimal-1908-sda.raw

> その昔は、色々弄らないと正常にyumとか動かなかったが、もう今は何もせずともちゃんと動くみたい。

macOSで、SDカードを差し込んでから、焼くまでのコマンド（いつも忘れる...）

```
sudo diskutil list
sudo diskutil unmountDisk /dev/<sdcard>
sudo dd bs=1m if=<image> of=/dev/<sdcard>
```
=> 例 <sdcard> : disk2

## ログインからセットアップまで

初期ID/Password => root/centos
なので適当にログイン。

```
/usr/bin/rootfs-expand
yum install emacs
emacs /etc/sysconfig/network-scripts/ifcfg-eth0
```

アドレスは自分の環境に合わせて、適当に。

```
TYPE="Ethernet"
BOOTPROTO="static"
NM_CONTROLLED="yes"
DEFROUTE="yes"
NAME="eth0"
ONBOOT="yes"
IPADDR="192.168.10.230"
NETTMASK="255.255.255.0"
GATEWAY="192.168.10.1"
DNS1="192.168.10.1"
```

dd/resize2fs/parted 等...デフォで入っているので、特に追加インストールとかなく、作業が行えるはず。

## 最小イメージ作成工程

###  parted での縮退

> 縮退後のイメージで作業してて、再度拡張されてないなら、いきなり次のddコマンドフェーズいっていい。

- 適当な変換器を用意しましょう。
    - /dev のどこかわからない時は、一回抜いて、/var/log/messages を tail -f しながら刺せばでてくる。
    - 多分、 /dev/sda で /dev/sda* がパーティションで認識されてるはず
- resize2fs /dev/sda2 7G とかでpartedで丸めるサイズよりちょい小さめの値でresizeする
    - このコマンド、帰ってくるまでが長い...
- parted 起動
    - select /dev/sda
    - unit s
    - print /dev/sda
        - 一番後ろの番号の開始セクタを控える
    - rm {一番後ろの番号}
    - mkpart primary ${控えておいた開始セクタ} 16000000s
        - 16000000s? => 大体8GBぐらい
    - e2fsck -f /dev/sda2
        - deviceではなく修正を加えたパーティションを対象とすることに注意
    - もっかい resize2fs /dev/sda2

### CentOSの空き領域に DD

- dd bs=512 if=/dev/sda of=/backup/hoge.img count=16000001 （上記で切り詰めたセクタの最大値+1を指定する

### 補足：バックアップイメージからのResotre...etc

- dd bs=8096k if=/backup/hoge.img of=/dev/sda
    - なんかm指定だとエラーになる...
- rdisk, disk の違いとは
    - アンバッファードモードとバッファモードの違い。ddでwriteする場合、理由がなければ前者使え
- 所要時間
    - 8GB（上記パラメータ）にかかる時間
        - backup : 1034.12 sec = 17 min
        - restore : 875.212 sec = 15 min

## AWS対応

イメージの置き場として、ローカルにおくのにSDカードはあまりに小さい & 保管場所として不安
なので、AWS Cliを入れておき、S3にマスターをおくようにする。

```
curl -kL https://bootstrap.pypa.io/get-pip.py | python
pip install awscli --upgrade --user
emacs ~/.bash_profile
```

で、末尾に

```
export PATH=~/.local/bin:$PATH
```

を追加

```
source ~/.bash_profile
mkdir ~/.aws
emacs ~/.aws/credentials
```

で

```
[default]
aws_access_key_id=*******************
aws_secret_access_key=***********************
region=ap-northeast-1
```

とか、自分の環境に合わせてセット。

あとは適当に...

```
aws s3 cp <コピーイメージ> s3://<S3のbucket>/<適当なdir object>/
```

### 参考リンク

- [CentOS6のパーティション容量をpartedで拡張する](http://qiita.com/biatunky/items/85461d00be3b4bae7ea8)
- [Raspberry Piで最小限に切り詰めたSDカードのイメージをバックアップする手順メモ.md](https://gist.github.com/yoggy/394b73ea35cbb2f1463d)
- [partedコマンドでディスクを切る時の備忘録的な](http://qiita.com/409_nu/items/69c5564794ff6fdc0fd6)
LaravelのEloquent ORMでどっちがhasでどっちがbelongsなのか？

# はじめに

LaravelのEloquent ORMでは、Modelに対してhasOne、hasMany、belongsTo、belongsToManyを定義することにより、Model間の関連を表すことが出来ます。
主従（親子）関係より、主（親）となる側にhasOne、hasManyを定義し、従（子）となる側にbelongsToを定義すれば良いのですが、初心者の方には主従関係の見極めが難しいので、どっちにhasを定義し、どっちにbelongsToを定義するのかの決め方をまとめてみました。

# どっちがhasかbelongかの決め方

* 1対1の場合
 * テーブル構造において、相手のidのカラムを持っているModelにbelongsToを定義し、他方のModelにhasOneを定義する。
* 1対多の場合
 * テーブル構造において、相手のidのカラムを持っているModelにbelongsToを定義し、他方のModelにhasManyを定義する。
* 多対多の場合
 * 両方のModelにbelongsToManyを定義する。

# Laravelの関連の定義

LaravelのModelでの関連の定義については、以下をご参照ください。

https://readouble.com/laravel/5.8/ja/eloquent-relationships.html#one-to-one-polymorphic-relations

# 例

## １対多の場合

### こんな関連

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254172/e5c9ef41-e949-bf01-286d-5b1732810d94.png)

### Modelの定義

productsテーブルにmaker_idが存在するので、ProductモデルにbelongsToを定義する。

```php
class Product extends Model
{
    public function maker()
    {
        return $this->belongsTo('App\Maker');
    }
}
```

他方のMakerモデルにhasManyを定義する。


```php
class Maker extends Model
{
    public function products()
    {
        return $this->hasMany('App\Product');
    }
}
```

## 多対多の場合

### こんな関連

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254172/4152efab-9e65-4993-448c-817557ae927c.png)

### Modelの定義

両方のModelにbelongsToManyを定義する。

```php
class Product extends Model
{
    public function categories()
    {
        return $this->belongsToMany('App\Category');
    }
}
```

```php
class Category extends Model
{
    public function products()
    {
        return $this->belongsToMany('App\Product');
    
}
```
VSCodeでGo Toolsにビルドタグを渡す方法

## 背景

VSCodeのGo拡張を使用している際、異なるビルドタグを持ったファイルにある変数や関数等を参照しようとするとコード補完が上手く働かずundeclaredになってしまいます。これはLanguage Serverであるgopls[^1]がタグ無しの状態で参照しているため起こる事象なのでタグを渡してあげる必要があります。

```go:lib_util.go
// +build test

package lib

var (
	testUtil = "test util"
)
```

```go:lib.go
package lib

import (
	"fmt"
)

func p() {
	fmt.Println(testUtil) // undeclared name: testUtil
}
```

## 対処法

`settings.json` に以下のような形で追記してやることでgoplsを含む各種Go Toolsにビルドタグを渡せます。プロジェクト毎に変更したい場合はWorkspaceレベルで設定してやると良いでしょう[^2]。

適用後はVSCodeを再起動するかF1メニューから "Developer: Reload Window" する必要があります（私の環境では "Go: Restart Language Server" だと上手くいきませんでした）。

```json
    "go.toolsEnvVars": {
        "GOFLAGS": "-tags=test"
    },
```

## 参考文献

* [x/tools/gopls: does not handle build tags #29202](https://github.com/golang/go/issues/29202)

[^1]: https://github.com/golang/tools/tree/master/gopls
[^2]: https://www.atmarkit.co.jp/ait/articles/1507/10/news028_5.html
SEOはかんたんか意味不明か

おそらくSEOを理解している人は一人もいない。責任者であろうが、プロジェクトのメンバーであろうが同じだ。彼らは自分で検索結果を決めていない。プログラミングか、自分でランキングを手動決定することもない。だから誰にもわからない。検索結果の下に「フィードバッグ」という項目がある。これもGoogleにメッセージを送る機能だが、彼らはその結果についてよく知らない。把握してないのだ。
<a href="https://alphard-discount.com/taiyo-no-matue-netabare-arasuji/" >韓国ドラマ太陽の末裔評判あらすじ</a>
昔から言われていたことだが、Googleというのはただ人気のあるサイトを上位に出しているだけだという。そこにいろいろな評価基準が加わり、実際の検索結果が表示されるわけだ。そこにはもはや、単純なプログラムはない。巨大化しすぎて彼らもわからない。そんな世界でSEOとは意味がないのか。ECサイト、HP製作者にとっては以前と同じか、それに手を加えた手法がまだ用いられている。しかし昔の方法はすでに終わった。
for文とforeach文で配列の要素をすべて表示させる


```csharp
class Program
{
    
    static void Main(string[] args)
    {
        string[] array = {"月曜日", "火曜日", "水曜日", "木曜日", "金曜日", "土曜日", "日曜日" };

        //arrayの要素数を表示
        Console.WriteLine(array.Length);

        Console.WriteLine("");

        //要素数の数だけ繰り返す
        for (int i = 0;i <array.Length;i++)
        {
            Console.WriteLine(array[i]);
        }

        Console.WriteLine("");

        //foreachで要素数の数だけ繰り返す
        foreach (string a in array)
        {
            Console.WriteLine(a);
        }

    }
}
```

【結果】

```text
7

月曜日
火曜日
水曜日
木曜日
金曜日
土曜日
日曜日

月曜日
火曜日
水曜日
木曜日
金曜日
土曜日
日曜日
```
Googleの医学研究（ディープラーニングによる網膜眼底画像からの貧血検出）

近年、Googleがディープラーニングを用いて医学研究を行っているのは有名な話ですが、
実際にどのような研究が行われているのかよくわかりません。

自分自身の勉強も兼ねて、
Googleが国際的医学雑誌に投稿している論文をフォローしてみたいと思います。

検索は、医学研究で頻繁に使用される以下からです。
Pubmed(https://www.ncbi.nlm.nih.gov/pubmed/)

今回は、昨年末（2019/12）にNat Biomed Engに投稿された以下論文です。
Detection of anaemia from retinal fundus images via deep learning. 
https://www.ncbi.nlm.nih.gov/pubmed/31873211

日本語訳では、「ディープラーニングによる網膜眼底画像からの貧血検出」
中高年になってくると健康診断の項目で検査される方もおられるかと思いますが、
今回、眼の網膜眼底画像から貧血をディープラーニングを用いて検出しています。

英国バイオバンクから11,388人の研究被験者からの検証データを用いて、
①網膜画像②メタデータ（人種、年齢、性、血圧）③網膜画像＋メタデータから、
貧血の指標とされるヘモグロビン濃度を予測

その結果、③網膜画像＋メタデータでROC*0.88 (0.86-0.89)と ヘモグロビン濃度を最も良く予測できており、
さらに自己報告による糖尿病患者593人の被験者でも、貧血をROC 0.89 (0.85-0.93)で予測することができた。

*ROC曲線(Receiver Operatorating Characteristic curve、受信者動作特性曲線)

2018年にNature Communicationsに報告されている、
非侵襲的にスマートフォンで指の爪画像から貧血を予測する研究が行われており、
今回のGoogleの研究と類似していると考えられます（おそらく研究グループは異なると思います。）。

Smartphone app for non-invasive detection of anemia using only patient-sourced photos
Robert G. Mannino, et al. Nature Communications volume 9, Article number: 4924 (2018) 
https://www.nature.com/articles/s41467-018-07262-2

今回の結果を、患者視点から考えると採血でなく眼底画像から貧血を診断してもらえるなら本当に有難いと思います。また、糖尿病による網膜症は、貧血が網膜症の危険因子と考えられているため、早期に貧血を発見できることは、糖尿病網膜症による失明の早期治療につながり大変意味ある研究だと感じました。

今後のGoogleによる医療現場で活用できるAIの研究開発が楽しみですね。
CentOS 8にNode.js 12をインストール（AppStream）

# はじめに

Application Stream(AppStream)を利用してCentOS8にNode.js 12をインストール
参考：[RHEL8のパッケージ構成 - BaseOSとApplication Stream - 赤帽エンジニアブログ]( https://rheb.hatenablog.com/entry/rhel8_baseos_and_appstream)

## サポート

本手法で導入した場合、[Red Hat Enterprise Linux 8 Application Streams Life Cycle - Red Hat Customer Portal](https://access.redhat.com/node/4079021)より、2021-11がEOLだと思われる。
それ以降に報告された脆弱性や不具合への対応は実施されない可能性がある。

## LOG

### インストール

```shell-session
# cat /etc/redhat-release
CentOS Linux release 8.1.1911 (Core)

# yum install -y @nodejs:12/common
... 略
```

### 各種確認

```shell-session
# which node
/usr/bin/node

# node -v
v12.4.0

# yum module info nodejs:12
Failed to set locale, defaulting to C.UTF-8
Last metadata expiration check: 0:09:35 ago on Sat Jan 18 07:24:40 2020.
Name         : nodejs
Stream       : 12 [e] [a]
Version      : 8010020191122190621
Context      : cdc1202b
Architecture : x86_64
Profiles     : common [i], development, minimal, s2i
Repo         : AppStream
Summary      : Javascript runtime
Description  : Node.js is a platform built on Chrome's JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.
Artifacts    : nodejs-1:12.4.0-2.module_el8.1.0+251+8afea200.src
             : nodejs-1:12.4.0-2.module_el8.1.0+251+8afea200.x86_64
             : nodejs-debuginfo-1:12.4.0-2.module_el8.1.0+251+8afea200.x86_64
             : nodejs-debugsource-1:12.4.0-2.module_el8.1.0+251+8afea200.x86_64
             : nodejs-devel-1:12.4.0-2.module_el8.1.0+251+8afea200.x86_64
             : nodejs-devel-debuginfo-1:12.4.0-2.module_el8.1.0+251+8afea200.x86_64
             : nodejs-docs-1:12.4.0-2.module_el8.1.0+251+8afea200.noarch
             : nodejs-nodemon-0:1.18.3-1.module_el8.1.0+251+8afea200.noarch
             : nodejs-nodemon-0:1.18.3-1.module_el8.1.0+251+8afea200.src
             : nodejs-packaging-0:17-3.module_el8.1.0+251+8afea200.noarch
             : nodejs-packaging-0:17-3.module_el8.1.0+251+8afea200.src
             : npm-1:6.9.0-1.12.4.0.2.module_el8.1.0+251+8afea200.x86_64

Hint: [d]efault, [e]nabled, [x]disabled, [i]nstalled, [a]ctive
```
Pandas 抽出基礎文法 / レスポンスを matplotlib に適用

# OverView
Pandas で各集計結果を取得する際の指定について、基本的な用法をまとめる。
以下、`data` をDataFrameオブジェクトとする。



# 基本編
### 指定インデックスの行を取得
```python
data[<index>]

# インデックス1の行を取得する
# (インデックスは0始まりなので、2行目となる)
data[1]
```

### 指定カラム名の列を取得
```python
data[<column_name>]

# カラム名'name'の列を取得する
data['name']
```


### 条件を満たす行のみを取得
```python
data[<インデックス単位のboolean>]
```

インデックス単位のbooleanイメージは以下。
こちらの例だと、インデックス0,2の行のみを抽出する。

```python
0     True
1    False
2     True
3    False
```

インデックス単位boolean生成例は以下。Pythonの判定式もそのまま使える。

```python
# ageカラムの値が20以上
data['age'] >= 20

# nameカラムが'郎’の文字を含む
data['name'].str.contains('郎')

# nameカラムが重複していない
data[~data['name'].duplicated()]
```

# 応用編
基本編最後で扱った「**条件を満たす行のみを取得**」をベースに、色々なレスポンスフォーマットを出力してみる.

ここで、`data` に格納されている統計データは、以下とする。

| index | height | class | grade | weight |
| --- | --- | --- | --- | --- |
| 0 | 178.820262 | a | 2 | 65.649452 |
| 1 | 172.000786 | b | 5 | 55.956723 |
| 2 | 179.337790 | a | 4 | 56.480630 |
| 3 | 181.204466 | b | 1 | 62.908190 |
| 4 | 169.483906 | a | 4 | 65.768826 |
| 5 | 174.893690 | b | 4 | 56.188545 |


### 条件を満たす行のみを取得
まずは基本編のおさらい。

```python
data[data['class'] == 'a']

       height class grade weight
0   178.820262   a   2  65.649452
2   179.337790   a   4  56.480630
4   169.483906   a   4  65.768826
```

### 条件を満たす行の各値をリスト形式で取得
`.values` を実行することで、1レコードの各値を1リストとし、それをレコードごとに要素にもつ2重リストを取得する。

```python
data[data['class'] == 'a'].values

[[178.8202617298383 'a' 2 65.64945209116877]
 [179.33778995074982 'a' 4 56.48062978465752]
 [169.4839057410322 'a' 4 65.76882607944115]]
```

### 条件を満たす行のインデックスとカラム値を取得
`.loc`を実行し、インデックスと指定したカラム値を取得する。
この形式は、matplotlib の plot に渡せる形式になる。

```python
data.loc[data['class'] == 'a', 'height']

0     178.820262
2     179.337790
4     169.483906

# args を使って plot 描写
args = data.loc[data['class'] == 'a', 'height']
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
ax.plot(args)
plt.show()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38277/1c2dd479-95e2-b7be-5304-d412e0f0095b.png)


### 指定条件を満たす行のカラム値のみをリスト形式で取得
`.loc` した結果を `.values` すると、指定カラム値のみをリスト形式で取得できる。
こちらは、 matplotlib の hist で利用できる。

```python
data.loc[data['class'] == 'a', '身長'].values

[178.82026173 179.33778995 169.48390574]

fig = plt.figure()
ax = fig.add_subplot(1,1,1)
ax.hist(data.loc[data['クラス'] == 'a', '身長'].values)
plt.show()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38277/13868faa-5643-cc1b-a17b-4e43bfaba430.png)

レコード数が増えれば、もっと映えるグラフになります！
Railsチュートリアル第１章で勉強をブロックしたやつ

#はじめに
この記事では私が[Railsチュートリアル](https://railstutorial.jp/chapters/beginning?version=5.1#sec-up_and_running)の第１章でつまづいた所を共有します。
個人的な備忘録ですが、プログラミング学習入門で人気のRailsなのでお役に立てればうれしいです！

#実行環境
[AWS Cloud9](https://console.aws.amazon.com/cloud9/home/product?#)を使用しました。チュートリアルの手順通りに環境設定しました。
#問題
[Railsチュートリアル1.3.2](https://railstutorial.jp/chapters/beginning?version=5.1#sec-up_and_running)で、

```Console
rails server
```

を実行し、アプリケーションをブラウザで開こうとしたところ、
まったく開きませんでした...

#解決策
色々調べた結果、ブラウザに導入していた広告ブロックが邪魔をしていました。広告ブロックを停止するとブラウザでRailsのウェルカム画面が無事表示されました。

また、下図のような表示がずっとでていましたが、EC2を再起動すれば解決しました。
[こちらの記事](https://qiita.com/yonabe710/items/2001a7d48384231d5e01)が参考になります。
<img width="411" alt="Oops.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464948/0c0413b4-82c7-fa1e-724c-27ed0c906661.png">

#まとめ
広告ブロックはプログラミング学習以外では非常に便利ですが、プログラミング学習するときは常時切っておくほうがよいかもしれません。
【GAS】リダイレクト先のURLを取得する

# はじめに
「GAS　リダイレクト　URL」でググって上位に来たteratailの情報がイマイチだったので、より適切な情報を広く共有したい。
teratailは私も活用しているので悪く言いたくないのだけど。
なお、私自身は何の貢献もしていない。人の褌で相撲を取るというやつだ。

# 主旨
Google Apps Scriptの`UrlFetchApp.fetch()`でURLを投げてレスポンスを得てスクレイピングする。指定したURLから他ページにリダイレクトされた場合、飛ばされた先の内容を取得するのは当然として、移転先のURLを取得するにはどうしたらよいかという話。
なお、Pythonのurllibにはそのための関数がある。`geturl()`だ。


# 方法
teratailの質問者が参考にしたという[Stack Overflow](https://stackoverflow.com/questions/27098169/)に答えが載っていた。Thank you, Mr.Chris!
あとで気づいたが[こちらの方](https://qiita.com/y-murata/items/d901afea86bd5c00fde7)も同様のことをしている。

```Javascript:
function getRedirect(url) {
  var response = UrlFetchApp.fetch(url, {'followRedirects': false, 'muteHttpExceptions': false});
  var redirectUrl = response.getHeaders()['Location'];  // undefined if no redirect, so... 
  var responseCode = response.getResponseCode();        // ...it calls itself recursively...
  if (redirectUrl) {                                    // ...if redirected... 
    var nextRedirectUrl = getRedirect(redirectUrl);
    return nextRedirectUrl; 
  } else {                                              // ...until it's not 
    return url;
  }
}
```

# 確認
いくつかのURLでリダイレクトを試してみた。Wikipediaのランダムリンク`http://ja.wikipedia.org/wiki/Special:Randompage`と短縮URLの`amzn.to`と`bit.ly`。`amzn.to`と`bit.ly`は同じ仕組みらしいけど。

```Javascript:
function tryRedirect() {
  var url_list = ["http://ja.wikipedia.org/wiki/Special:Randompage",
                  "https://amzn.to/2tUlU0r",
                  "https://bit.ly/2Rfs7Mr"]

  for (var i=0 ; i < url_list.length ; i++) {
    var url = url_list[i];
    var redirect_url = getRedirect(url);
    Logger.log(redirect_url);  
  }
}
```

結果は以下の通り、リダイレクト先を取得するのに成功している。
amzn.toは503エラーを返すことが多かった。本格的に使うならエラー対策が必要だ。というか、遊ぶなら相手の迷惑にならないように遊ばなくては。

```
[20-01-18 15:46:45:530 JST] https://ja.wikipedia.org/wiki/%E9%88%B4%E6%9C%A8%E5%8B%89
[20-01-18 15:46:45:962 JST] https://www.amazon.co.jp/dp/B00H6V3BWA
[20-01-18 15:46:46:418 JST] http://www.tokoroza-one.jp/index.html
```

# 活用例
Done is better than perfect。本知見を織り込んだTwitterボットを作ってみた。Twitterなんて自分自身ではまったくやっていないのに。
GAS＋タイマー（トリガー）なので24時間営業の全自動だ。

　　[**THE_SCRAPER**](https://twitter.com/the_scraper)

# 終わりに
GASでTwitter APIを使えるようにするためにいくつかの記事のお世話になりました。ありがとうございます。

 - [Twitter API 登録 (アカウント申請方法) から承認されるまでの手順まとめ　※2019年8月時点の情報](https://qiita.com/kngsym2018/items/2524d21455aac111cdee) 
 - [GASでTwitterの投稿とタイムライン取得](https://qiita.com/golyat/items/6b430986dbfd8dd1c239)
while文で「10000」を「2」で何回割ると「100以下」になるか調べる

```csharp
    class Program
    {
        
        static void Main(string[] args)
        {
            int count = 0;
            int kazu = 10000;
            
            while (kazu > 100)
            {
                kazu = kazu / 2;
                count++;
            }
            Console.WriteLine(count);
        }
    }
```

【結果】

```text
7
```
windows10のdockerでのwordpress立ち上げでerror establishing a database connectionが表示される時

## 環境
- OS：Windows10 home（重要）
- Docker：Docker Toolbox（重要）

docker-composeを実施したときに、
毎回つまるエラーなのでメモ。

Macでも何度か立ち上げているが、
そちらでは一度も詰まったことがないので
環境が違う場合は別の要因だと考えてほしい。
その場合は**この記事以外**を参考にしてください。

## 実施手順
[docker-composeでwordpress環境をサクッと構築する - Qiita](https://qiita.com/mom0tomo/items/7e611ac829863d4c5c82)
↑こちらの記事を参考に、`docker-compose.yml`を作成。

docker-toolboxの画面に記載されている
`docker is configured to use the default machine with IP 192.xxx.xx.xxx`
を参考にして、
ブラウザで`192.xxx.xx.xxx:9000`にアクセス。

## error establishing a database connectionの対処法
この場合よくある問題として、`mysql:latest`が指定されているので`mysql:5.7`を指定して回避することができるが、
今回は最初から5.7が指定されているので別の問題。

今回の問題は、docker-compose.yml内の
wordpress、dbの二箇所の
`restart: always`を
`restart: unless-stopped`
に変更して解決。

この記事を参考にした。↓
[docker-compose wordpress mysql connection refused - Stack Overflow](https://stackoverflow.com/questions/34068671/docker-compose-wordpress-mysql-connection-refused)
初心者による jQuery 基礎

#jQueryの基本的な構文
jQueryで行われる処理の流れは、

```
1. $()関数で命令の対象となるHTML要素をjQueryオブジェクトに変換
2. そのjQueryオブジェクトに対して独自メソッドを呼び出して変更を加える
```
jQueryの基本的な構文は、

```javascript:sample.js
//jQueryオブジェクト.変更する命令
$(HTML要素).メソッド('引数', '引数')
```
また、HTMLを最後まで読み込んだ時点で実行するために、jQueryは以下のようになる。

```javascript:sample.js
$(function){
 //HTMLがロードされたのちに実行する処理
}
```
#onメソッド
onメソッド構文は次のように書く

```javascript:sample.js
on('イベントタイプ', 'イベントハンドラ')
```

ちなみに、thisプロパティは「onメソッドに指定してあるイベントが発生した要素」が格納される。
thisを使うことで、

```
1. 処理のパフォーマンスが上がる
2. コードの汎用性を持たせられる
そして一番重要なのが、
3. $()関数に複数のセレクタを指定した場合にthisを使うことで処理の切り分けをしてくれる
```
というメリットがある。

##イベントタイプ
主なイベントタイプは、

```
mouseover : 要素にマウスが乗った時
mouseout : 要素からマウスが離れた時
mousedown : 要素上でクリックボタンが押されたとき
mouseup : 要素上でクリックボタンが離れた時
mousemove : 要素上でマウスが動かされたとき
click : 要素がクリックされたとき
dbclick : 要素がダブルクリックされたとき
keydown : 要素にフォーカスした状態で、キーボードのキーが押されたとき
keyup : 要素にフォーカスした状態で、キーボードのキーが離れた時
focus : 要素にフォーカスが当たった時
blur : 要素からフォーカスが離れた時
change : 入力内容が変更されたとき
resize : 要素がリサイズされたとき
scroll : 要素がスクロールされたとき
```

##イベントハンドラ

```javascript:sample.js
function() {
 //任意の処理
}
```

たとえば、

```javascript:sample.js
$('#type').on('mouseover', function(){
 $('#type').css('color', '#ebc000')
})
```
のように使う。

#メソッドチェーン
メソッドチェーンとは、「メソッドを鎖(チェーン)のようにつなげて記述し、実行するプログラム手法」です。書き方は、

```javascript:sample.js
$('セレクタ').メソッドA().メソッドB().メソッドC()...
```
たとえば、

```javascript:sample.js
$(function(){
 $('#type')
  .on('mouseover', function(){
   $('#type').css({
    color: '#ebc000',
    backgroundColor: '#ae5e9b'
   })
  .on('mouseout', function(){
   $('#type').css({
    color: '',
    backgroundColor: ''
   })
  })
  })
})
```
なお、実行の順番が結果に関係しないメソッドについては、順番を変えても同様の結果となる。
このメソッドチェーンのメリットは、

1. $()関数の記述が一回で済むため可読性が上がる。
2. プログラムの処理速度が上がる。

#stopメソッド
実行中のアニメーションを途中でキャンセルするにはstop()メソッドを使います。

```javascript:sample.js
stop( true | false )
```


#参考資料
「jQuery最高の教科書」
LaTeXの\todayで月日を2桁表示にする．

# 問題
通常，`\date{\today}`とすると，2020年1月1日のように月日が1桁で表示されてしまう．
これを，2020年01月01日のようにしたい．

## 環境
MacTeX

```
e-pTeX 3.14159265-p3.8.0
-180226-2.6 (utf8.euc) (TeX Live 2018)
kpathsea version 6.3.0
ptexenc version 1.3.6
Copyright 2018 D.E. Knuth.
There is NO warranty.  Redistribution of this software is
covered by the terms of both the e-pTeX copyright and
the Lesser GNU General Public License.
For more information about these matters, see the file
named COPYING and the e-pTeX source.
Primary author of e-pTeX: Peter Breitenlohner.
```

# 解決方法
プレアンブルに，

```
\makeatletter
\newcommand*{\themonth}{\two@digits\month}
\newcommand*{\theday}{\two@digits\day}
\makeatother
\renewcommand{\today}{{\the\year}年{\themonth}月{\theday}日}
```

と追記する．
また，5行目の年，月，日をハイフンにすれば2020-01-01と出力される．
for文のbreakとcontinueの使用例

```csharp
class Program
{
    static void Main(string[] args)
    {
        //Program2のインスタンスを生成
        Program2 obj = new Program2();

        //Program2クラスのstarメソッドを実行
        obj.star();
    }
}

class Program2
{
    public void star()
    {
        //五回繰り返す
        for (int i=1;i<=5;i++)
        {
            //変数jが変数iの数以下になるまで繰り返す
            for (int j = 5; j >= i; j--)
            {
                //変数iが3の時はfor文を抜ける(Console.Write("☆")は実行されない)
                if (i == 3)
                {
                    break;
                }
                Console.Write("☆");
            }

            //変数iのが3の時はcontinue以下の処理は実行しない
            if (i == 3)
            {
                continue;
            }
            Console.WriteLine("");
        }
    }
}
```

【結果】

```text
☆☆☆☆☆
☆☆☆☆
☆☆
☆
```