OmniAICreator/Qiita-1.07M huggingface dataset:
PyTorchのSoftmax関数で軸を指定してみる

#はじめに
掲題の件、調べたときのメモ。

#環境
- pytorch 1.7.0

#軸の指定方法
nn.Softmax クラスのインスタンスを作成する際、引数dimで軸を指定すればよい。

#やってみよう
今回は以下の配列を例にやってみる。

```py
input = torch.randn(2, 3)
print(input)
```

```py
tensor([[-0.2562, -1.2630, -0.1973],
        [ 0.8285, -0.9981,  0.3171]])
```

##dimを指定しない場合

```py
m = nn.Softmax()
print(m(input))
```

こんな風に怒られる。

```py
/usr/local/lib/python3.6/dist-packages/ipykernel_launcher.py:2: UserWarning: Implicit dimension choice for softmax has been deprecated. Change the call to include dim=X as an argument.
```
  

##dim=0を指定した場合
```py
m = nn.Softmax(dim=0)
print(m(input))
```

列単位でSoftmaxをかけてくれる。

```
tensor([[0.2526, 0.4342, 0.3742],
        [0.7474, 0.5658, 0.6258]])
```

念のため列単位で集計をすると、各列合計が1になる。

```py
torch.sum(m(input), axis=0)
tensor([1., 1., 1.])
```  


##dim=1を指定した場合

```py
m = nn.Softmax(dim=1)
print(m(input))
```

行単位でSoftmaxをかけてくれる。

```py
tensor([[0.4122, 0.1506, 0.4372],
        [0.5680, 0.0914, 0.3406]])
```
  
念のため行単位で集計すると、各行合計が1になる。

```py
torch.sum(m(input), axis=1)
tensor([1.0000, 1.0000])
```
緯度経度と直交座標を相互変換する

# はじめに

緯度経度高さで表される座標と、XYZの三次元直交座標を相互変換します。
Unityで使いたかったため、C#とUnityのタグをつけていますが、特にUnityに制限されるものではありません。

計算方法については、「世界測地系と座標変換」（飛田幹夫著、日本測量協会発行）を参考にしました。
[世界測地系と座標変換（Amazon）](https://www.amazon.co.jp/dp/4889410147/)
この本は日本測量協会に問い合わせれば定価で購入できると思います。

**※注意※**
著者は本稿の内容について、精度や正確さ正しさを必ずしも保証するものではありません。
著者は本稿の内容を利用したことにより起こった事柄に関して一切の責任を負わないものとします。
実際に使われる場合は、値域の制限などを入れることや、精度保証などのテストを行って、ご自身の責任においてご利用ください。

# 前提

緯度経度はWGS84に基づいているものとします。変換パラメータを変えれば、他の測地系にも対応できると思いますが、本稿の範囲外とします。
緯度は北側が+、南側に-で、-90~90度。経度は東に+、西に-で、-180~180度とします。
高さは、WGS84に基づく楕円体高でメートルを単位とします。標高ではないのでご注意ください。
XYZ座標は、+X軸が子午線、東向きに+Y軸、北向きに+Z軸とします。こちらも単位はメートルになります。

# プログラム

``` CoordConv.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

using System;

/// <summary>
/// 座標の変換用クラス。なるべくシンプルに必要な変換だけ。
/// 測地系はWGS84を使用。
/// 計算方法は「世界測地系と座標変換　飛田幹夫　日本測量協会」を参考にした。
/// </summary>
public class CoordConv
{
    private const double a = 6378137.0;
    private const double f = 1.0 / 298.257223563;
    private const double e2 = f * (2.0 - f);

    /// <summary>
    /// 緯度経度（WGS84）から直交座標（ECEF）に変換するメソッド。
    /// </summary>
    /// <param name="b">緯度</param>
    /// <param name="l">経度</param>
    /// <param name="h">楕円体高</param>
    /// <returns>直交座標のXYZ。+Zが北極、+Xが子午線、+Yが東経方向</returns>
    public static (double x, double y, double z) BLH2XYZ(double b, double l, double h){
        b = Math.PI * b / 180.0;
        l = Math.PI * l / 180.0;

        double N = a / Math.Sqrt(1.0 - e2 * Math.Pow(Math.Sin(b),2.0));

        return (
            (N + h) * Math.Cos(b) * Math.Cos(l),
            (N + h) * Math.Cos(b) * Math.Sin(l),
            (N * (1.0 - e2) + h) * Math.Sin(b) 
        );
    }

    /// <summary>
    /// 直交座標（ECEF）から緯度経度（WGS84）に変換するメソッド。
    /// </summary>
    /// <param name="x">X</param>
    /// <param name="y">Y</param>
    /// <param name="z">Z</param>
    /// <returns>緯度経度。b緯度、l経度、h楕円体高</returns>
    public static (double b, double l, double h) XYZ2BLH(double x, double y, double z){
        double p = Math.Sqrt(x*x + y*y);
        double r = Math.Sqrt(p*p + z*z);
        double mu = Math.Atan(z / p * ((1.0 - f) + e2 * a/r));

        double B = Math.Atan( (z * (1.0-f) + e2*a*Math.Pow(Math.Sin(mu),3)) / ((1.0-f)*(p-e2*a*Math.Pow(Math.Cos(mu),3))) );
        return (
            180.0 * B / Math.PI,
            180.0 * Math.Atan2(y,x) / Math.PI,
            p * Math.Cos(B) + z*Math.Sin(B) - a*Math.Sqrt(1.0 - e2*Math.Pow(Math.Sin(B),2))
        );
    }
}
```

# 注意点

必ず、doubleで値を渡してください。floatでは一般的な用途でも演算の精度が不足する可能性が高いです。得られた値は、なるべく小さな値になるようにdoubleのまま平行移動などしてからfloatに変換し、Unityのオブジェクトの座標（Vector3など）に代入してください。
計算部分では値域のチェックなどもしていません。必要なら追加してください。
変換パラメータがWGS84の改訂などで変わることがあります。高い精度を求める場合は都度信頼できる情報を確認してください。
【JavaScript】現在時刻をリアルタイムで表示し続ける方法

#プログラミング勉強日記
2021年1月9日
以前、[こちらの記事](https://qiita.com/mzmz__02/items/e316d3962e7d3ecfebf8)でJavaScriptでの日付と時刻を取得する方法をまとめた。今回は、現在時刻をリアルタイムで表示し続ける方法を紹介する。

#方法
1. 現在時刻を格納するDateオブジェクトを作成する
2. 作成したDateオブジェクトから時間・分数・秒数を取り出す
3. 時計として表示する文字列を作成する
4. 文字列を時間に書きかえる
5. 1秒ごとに特定の処理を実行する


##1. 現在時刻を格納するDateオブジェクトを作成する方法
　以下のように`new Date()`で現在の日付・時刻する。

```js
var nowDate = new Date();
console.log(nowDate);
```

```:コンソール結果
Sun Sep 27 2020 09:22:20 GMT+0900 (日本標準時)
```

##2. 作成したDateオブジェクトから時間・分数・秒数を取り出す方法

```js
let nowTime = new Date(); //  現在日時を得る
let nowHour = nowTime.getHours(); // 時間を抜き出す
let nowMin  = nowTime.getMinutes(); // 分数を抜き出す
let nowSec  = nowTime.getSeconds(); // 秒数を抜き出す
```

##3. 時計として表示する文字列を作成する方法
```js
let msg = "現在時刻：" + nowHour + ":" + nowMin + ":" + nowSec;
```

##4. 文字列を時間に書きかえる方法

```js
document.getElementById("id名").innerHTML = msg;
```

##5. 1秒ごとに特定の処理を実行する方法
　etIntervalメソッドを使う。(詳しくは後日Qiitaに乗せようと思う)

```js
// 第1引数は指定時間後に自動実行される関数
// 第2引数はミリ秒で指定時間を設定する(1000=1秒)
setInterval('関数名',1000);
```

#サンプルコード
　以上を踏まえてできたコードがこちら。

```html
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8" />
  <title>sample</title>
  <style>

  </style>
  <script>
    function showClock() {
      let nowTime = new Date();
      let nowHour = nowTime.getHours();
      let nowMin  = nowTime.getMinutes();
      let nowSec  = nowTime.getSeconds();
      let msg = "現在時刻：" + nowHour + ":" + nowMin + ":" + nowSec;
      document.getElementById("realtime").innerHTML = msg;
    }
    setInterval('showClock()',1000);
  </script>
</head>

<body>

  <p id="realtime"></p>

</body>

</html>
```

実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/8cd2e53b-37f8-81ad-7a91-c9036fa64baa.png)


　`23:7:35`よりは`23:07:35`の方が見やすく、デジタル時計としては常に2桁で表示させたい。そのコードを紹介する。

```html:常に2桁で表示するコード
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8" />
  <title>sample</title>
  <style>

  </style>
  <script>
    function twoDigit(num) {
      let ret;
      if( num < 10 ) 
	    ret = "0" + num; 
      else 
   	    ret = num; 
      return ret;
    }
    function showClock() {
      let nowTime = new Date();
      let nowHour = twoDigit( nowTime.getHours() );
      let nowMin  = twoDigit( nowTime.getMinutes() );
      let nowSec  = twoDigit( nowTime.getSeconds() );
      let msg = "現在時刻：" + nowHour + ":" + nowMin + ":" + nowSec;
      document.getElementById("realtime").innerHTML = msg;
    }
    setInterval('showClock()',1000);
  </script>
</head>

<body>

  <p id="realtime"></p>

</body>

</html>
```

実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/cd6a9894-c28f-5c1f-a95a-54b4eec47dd4.png)
vimrcの設定

# 我が家のvimrc
VMを作ったり消したりしていると、必要な時にvimrcがなくてチョイチョイ困るので・・・

```vim

"----------------
" 基本設定
"----------------
"文字コードをUFT-8に設定
set encoding=utf-8
"文字コードの自動判別
set fileencodings=utf-8,iso-2022-jp,euc-jp,sjis
"改行コードの自動認識
set fileformats=unix,dos,mac
"ファイルを保存する時の文字コード
set fileencoding=utf-8
"------------
" バックアップファイルを作らない
set nobackup
" スワップファイルを作らない
set noswapfile
" 編集中のファイルが変更されたら自動で読み直す
set autoread
" バッファが編集中でもその他のファイルを開けるように
set hidden

"----------------
" 見た目系
"----------------
" colorschemeの変更
colorscheme desert
" 行番号を表示
set number
" 現在の行を強調表示
set cursorline
" 行末の1文字先までカーソルを移動できるように"set virtualedit=onemore
" インデントはスマートインデント
set smartindent
" 括弧入力時の対応する括弧を表示
set showmatch

"----------------
" ステータスライン
"----------------
" ステータスラインを常に表示
set laststatus=2
" 現在のモードを表示
set showmode
" コマンドをステータスラインの下に表示
set showcmd

"----------------
" コマンドラインの補完
set wildmode=list:longest
" シンタックスハイライトの有効化
syntax enable

"----------------
" Tab系
"----------------
" Tab文字を半角スペースにする。
set expandtab
" softtab(スペース)の数
set softtabstop=2
" 行頭以外のTab文字の表示幅（スペースいくつ分）
set tabstop=2
" 行頭でのTab文字の表示幅
set shiftwidth=2
" インデントはスマートインデント
set smartindent
" 自動でインデント
set autoindent

"----------------
" Buffer操作系
"----------------
" bufferを進む/戻る
nnoremap <silent><C-j> :bnext<CR> 
nnoremap <silent><C-k> :bprev<CR>
```
Couldn't find Item without an IDというエラーが出た時の対処法

# idが見つからない時の対処法
自分がエラーが出た時のコントローラーはこちらでした。

```rails:order_controller.rb
  def index
    @item = Item.find(params[:id])
    @user_item = UserItem.new
  end
```

# 解決方法
結論は、ネストしている時のID名が変わることを知らなかったが故に起きたエラーでした。
rails routesで検索したところ

item_orders GET    /items/:item_id/orders(.:format)                                                      orders#index

という結果が返ってきたのですが、注意すべきは/:item_id/の部分。
ネストで子要素となっている要素のid名は[:（親要素の名前）_id]に変わるのだそうです。
つまり、正解の記述はこちらになります。

```rails:order_controller.rb
  def index
    @item = Item.find(params[:item_id])
    @user_item = UserItem.new
  end
```

# メモ
ネストしている子要素にあたるモデルのID名が変わることが知れて良かった。
PHP学習（Mac導入）

## はじめに
はじめまして、初投稿になります
私はテックキャンプと言う今、良い意味でも悪い意味でも話題になっているプログラミングスクールに通っております
今回知的好奇心からPHPを学習する事にしたのそこでメモがわりとして記録したいと思います
## PHPとは？
PHPとはjavaやrubyと言ったサーバーサイドを構築する上で必要なスプリクト言語です
PHPはHTML内に記述する事ができます
例えば

```<?php
print('PHPを勉強中です！');
?>
```
と記述しMAMPを起動すると”PHPを勉強中です！”と表示されます
といきなりMAMPと書きましたがトンチンカンになるので次でMAMPについて説明します

## MAMPとは？
MAMPとは「Macintosh」「Apache」「MySQL」「PHP」の頭文字をとったものです
つまり、PHPとMySQLをローカル環境で開発できちゃうんですね

ruby on railsで言う

```
rails db:create
rails s
http://localhost:3000/
```
でローカル環境を開けるものみたいですね
ターミナル使わない分ちょい楽ですね笑

## 環境構築

- MAMPのインストール

で、そのMAMPはどうすれば手に入るんだよって話ですが
https://www.mamp.info/en/windows/
上のサイトから
TRY NOWの項目からOSのアプリをダウンロードしインストールするだけでいいみたい

インストール中パスワード求められるからそいつも入力でOK

- DBの設定
 
```
[mysqld]
sql_mode=NO_ENGINE_SUBSTITUTION
```
この記述をテキストエディター（私はvscode）に記述し
アプリケーション→MAMP→conf内にmy.cnfと言う名前で保存

これで一連の環境が完了しました

- PHPファイルの保存

MAMP内のhtdocsに起動する為のPHPファイルを作りましょう
ここでは仮にPHPフォルダーを作成し、その中にsample01.phpと言うファイルを作成します
これで起動準備ができました

- 起動

```
http://localhost:8888/php/sample01.php
```

これによって先ほど作ったPHPファイルがローカル環境で動きました
この8888は

![8210f2aa30665328ab36549421c647f7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672760/f2ea8c34-f744-6f42-89c9-4e1e8f9fdf93.png)

８８８８の数字はポート番号みたいですね
私はそのままですが変更したらlocalhost:~の数字もこれに合わせるのでしょうか？

```
~ php/sample01.php
```

このポート番号以降の記述は先ほどhtdocsで保存したファイルの場所ですね
PHPフォルダー内のsample01.phpを起動しなさいみたいな指定をするわけです


## 最後に
今回初めてQiitaに投稿しました
正直私は文章作成能力がとんでもなく低く、まだ学習開始と言う部分で至らない点もあります
もし間違えていたらお知らせください


以上
Linux 基本コマンド　備忘録


###Linuxとは
MacOSやWindowsと同じOS
OSはコンピュータのハードウェアを管理しているソフトウェアのことです
#基本コマンド
###ls
カレントディレクトリ直下のファイルを確認

```terminal.
% ls　　//直下のファイル確認
Applications		Pictures
Desktop				Public
~%
```
###pwd
カレントディレクトリ確認

```terminal.
Desktop % pwd　　//現在のディレクトリ確認
/Users/Desktop
Desktop %
```
###mkdir
ディレクトリ作成


```terminal.
Desktop % mkdir sample  //sampleディレクトリ作成
Desktop %
```
###cd
ディレクトリの移動

```terminal.
Desktop % cd sample　　//sampleディレクトリへ移動
sample %
```
###touch
空のファイル作成

```terminal.
sample % touth sample.html  //空のファイル作成
sample %
```
###mv
名前の変更

```terminal.
sample % mv smaple.html sample2.html  //変更
 sample % ls　　//直下のディレクトリ確認
 sample2.html
sample %
```
###rm 
ファイル・ディレクトリの削除

```terminal.
sample % rm -r sample2.html  //削除
ample % ls  //直下のディレクトリ確認

sample % 
```

###history
過去のコマンドの記録

```terminal.
sample % history  //履歴の確認
 1010  ls
 1011  cd sample.thml
 1012  cd sample.html
 1013  echo sample.html
 1014  echo "Hello world > sample.html\na\n
sample %
```

##まとめ
今回の記事は万が一忘れてしまった時の備忘録です
Unityでの2Dジャンプアクションゲームの作成(Stage作成編)


Unityでの2Dアクションゲームの作り方をメモしていきます。

まずはプロジェクトを作っていきます。
Unity Hubから新規プロジェクトを作成を選択。
テンプレートは2Dを選択してプロジェクト名はActionGameとします。
![Unityプロジェクト2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542570/d6274bde-17c5-92ad-e9c9-0863b5332ab3.png)

素材をインポートするためにWindow→Asset Storeを選択してAsset Storeから素材をダウンロードします。今回はFree素材であるPixel Adventure 1をダウンロードしていきます。
![rapture_20210109163115.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542570/e6c5bedf-84fd-9f5d-20df-60f408aea7c1.jpeg)


ダウンロードしてimportを行うと左下にあるProjectに表示されるAssetsフォルダ内にPixel Adventure 1が出来ます。その中に素材が正常にダウンロード出来ているか確認します。
![rapture_20210109165730.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542570/41cc8e17-fcf3-ac9c-c4e8-323313d66b81.jpeg)


次にステージを作成するためにTilemapを使用します。Hierarchyウィンドウの+をクリックして2D Object→Tilemapをクリック。

![Unity画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542570/4d1da477-722f-c580-a1c8-bac71f82fa09.png)

HierarchyウィンドウにGridが作成されクリックするとSceneにグリッドが表示されることを確認します。


次に2D Tilemap Editorを使えるようにするためWindow→Package Managerをクリックします。Package Managerの検索欄にtileと入力すると出てくのでインストールします。
![rapture_20210102151322.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542570/f4baa079-2d8f-13d9-f857-10a179be1bdf.jpeg)

インストールするとWindow→2Dの欄に2D tilemap Editorが追加され使用できるようになります。

tilemapを管理するフォルダを作成します。Assets内で右クリックからCreate→Folderを選択してstagesフォルダを作成します。

その後window→2D→Tile Paletteをクリックすると以下の画面が表示されます。
![rapture_20210109160522.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542570/de10d4a2-e4f7-9d16-9076-4ba69304a830.jpeg)

そこでCreate New Paletteをクリックし、新しいパレット(名前は何でもいいですがStagePaletteとにしときます)を先ほど作成したstagesフォルダ内に作ります。

作成したStagePaletteへ"Assets/Pixel Adventure 1/Assets/Terrain"内のTerrain Sliced(16×16)をドラッグアンドドロップします。しばらく処理が走った後に以下の画面のようになりパレットが作成されます。

![rapture_20210109162107.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542570/8ed6d53b-7ed1-09d8-697b-736c24e8b750.jpeg)

パレットの画面上の筆ボタンを押してSceneにStageを描いていくのですが…何もせず書くととても小さく表示されると思います。

こんな感じ
![rapture_20210109162146.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542570/f1f13b5c-c0e3-e041-1fc4-459c7d8ca7ac.jpeg)

このままでは使えないのでサイズの変更を行います。"Assets/Pixel Adventure 1/Assets/Terrain"内のTerrain Sliced(16×16)を選択したのちにInspectorタブのPixels Per Unitを100から16へ変更してApplyします。
![rapture_20210109162237.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542570/deecc83b-bf94-fb26-5dad-702229efcf37.jpeg)

そうすると1マス毎にパレットを置けるようになりました。
![rapture_20210109164612.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542570/dfa9b744-c0ca-1175-85f0-bba3c2409030.jpeg)

というわけでパレットを適当に置く事でstageが作れるようになりました。
![rapture_20210109165337.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542570/11affdc8-905e-cfcd-d4d0-6ace89142770.jpeg)

今のままではstageに引っ掛かる可能性があるので

[次回](https://qiita.com/tokoroten_346/items/9a148e2ef84b7d1b0fef)はプレイヤーキャラを作る方法書いていきます。
Python + paramiko でSFTP転送

# 環境
macOS 10.14.6
Python 3.8.5
paramiko 2.7.2

# 目次
1. [背景](#Chapter1)
1. [実装方法](#Chapter2)
1. [参考文献](#reference)


<!-- 各チャプター -->
<a id="#Chapter1"></a>
# 背景
SFTP通信を行うフリーソフトは色々ありますが、

- 特定のファイルだけ送りたい
- 日次バッチで自動連携したい

のようなニーズがでできたのでPythonとparamikoというライブラリを使ってSFTPによるファイル転送を実装してみました。


<a id="#Chapter2"></a>
# 実装方法
まずはライブラリのインストール

```
pip install paramiko
```

SFTP転送コードは以下の通り。
SFTP通信はSSHで暗号化された通路を使ってFTP通信を行いファイルデータのやりとりを行います。
そのためSSH接続をしてから通信を開始する実装手順となっています。


```python
import paramiko

# SFTP接続設定
sftp_config = {
    'host' : 'example.com',
    'port' : '22',
    'user' : 'user',
    'pass' : 'pass'
} 

#SSH接続の準備
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy)
client.connect(sftp_config['host'], 
               port=sftp_config['port'],
               username=sftp_config('user'),
               password=sftp_config['pass'])

# SFTPセッション開始
sftp_connection = client.open_sftp() 
    
### 相手先サーバにファイルを転送する場合
CONNECT_PATH = 'XXX' # 相手先サーバのフォルダパス

for f in files:  #転送対象ファイルリストがfilesに入っていると仮定
    sftp_connection.put(f, CONNECT_PATH + f)
    sftp_connection.close()

### 相手先サーバからファイルをダウンロードする場合
#第1引数が相手先サーバのファイル名、第2引数がダウンロードしてくるときのファイル名
sftp_connection.get(CONNECT_PATH + 'test.csv', 'download_test.csv')

client.close()
```




<a id="#reference"></a>
# 参考文献
- [PythonでSFTPを利用してファイル転送する方法を現役エンジニアが解説【初心者向け】](https://techacademy.jp/magazine/31549)
【基本情報】その他のハードウェア

###入力装置

* キーボード
* ポインティングデバイス

マウス、トラックパッド、タッチパネル、タブレット、ジョイスティック
* 読み取り装置

イメージスキャナ、OCR、OMR、キャプチャカード、デジタルカメラ、バーコードリーダー

バーコードは二種類
JANコード、、、商品コードを表す。数字を表現。
QRコード、、、３個の検出用シンボルによって、回転角度と読み取り方向が認識できる。

###ディスプレイ

CRT（ブラウン管）、液晶、有機EL、プラズマディスプレイ

###プリンタ

ドットインパクトプリンタ
インクジェットプリンタ
レーザプリンタ

dpi、、、ドットパーインチ
CPS、、、一秒間に何文字印刷できるか（ドットインパクトプリンタの指標）
PPM、、、一分間に何ページ印字できるか（レーザプリンタの指標）

###入出力インタフェース

パラレル（並列）とシリアル（直列）がある。

* パラレルインタフェース

IDE、、、シリアルATAが今は主流。
SCSI、、、デイジーチェーンという数珠つなぎの接続方法をとる。

* シリアルインタフェース

USB、、、複数の規格がある（1.1はロースピード、2.0はハイスピード、3.0はスーパースピード）
IEEE1394、、、音声、映像などに適したアイソクロナス転送を採用しており、ブロードキャスト転送モードをもつシリアルインタフェースである。
【Git】masterブランチを削除した世にも恐ろしい話〜答えは英語の中に〜

オリジナルアプリを作って今日で3日目。
要件定義をしっかりしたつもりだったがあれやこれやと出てきてしまい、
「あ、これもやらなきゃ」
「あれ？スペルミス」
「あれ？ここどうしたらいいんだっけ？」
こんなことの連発。
こまめにcommitしなければいけないと思いつつ作業ブランチのことをやっていて、他のブランチに戻る、そんなことを繰り返していてわけがわからなくなってしまったので、
**「一度マージし終わっているブランチを削除しよう！」**
そう思いついたのが地獄の始まりじゃったそうな・・・




### やっちゃったこと


```terminal
% git branch -D master     
```

「記事を見ながらやった。なぜこうなってしまったのかはわからない。後悔はしている。」
(プライバシー保護のため音声を加工してあります

masterブランチって消えるんですね。恐ろしいよ。
その後、下記コマンドでreflogを抽出

```terminal
% git reflog
　　　　　　　　　　　　　　　　　　　⬇️⬇️⬇️以下結果⬇️⬇️⬇️

0422208 (HEAD -> master) HEAD@{0}: checkout: moving from ユーザー管理機能 to master
444f2b7 (origin/ユーザー管理機能, ユーザー管理機能) HEAD@{1}: checkout: moving from master to ユーザー管理機能
0422208 (HEAD -> master) HEAD@{2}: checkout: moving from ユーザー管理機能 to master
444f2b7 (origin/ユーザー管理機能, ユーザー管理機能) HEAD@{3}: checkout: moving from master to ユーザー管理機能
0422208 (HEAD -> master) HEAD@{4}: checkout: moving from ユーザー管理機能 to master
444f2b7 (origin/ユーザー管理機能, ユーザー管理機能) HEAD@{5}: checkout: moving from master to ユーザー管理機能
0422208 (HEAD -> master) HEAD@{6}: checkout: moving from ユーザー管理機能 to master

〜以下略〜

```
出てきたHEADの表示を確認し、該当の数字を入力

```terminal
% git branch master HEAD@{21}       
```

ザオリク成功。やったね！

<br>
そして時は流れ、新たなブランチでの作業が終わった時に事件は起こった。
コミット→プッシュ→
Delete Branchする前にmasterに反映されているか確認するか・・・
・・・あれ？
・・・おかしいな
・・・Fetch Origin、ん？
・・・なんでViewファイルが更新されてないんだ？
え？！他のファイルも更新されてない！なんで？！
Fetch Originすると



![748108df3a83983d5d6af2bdd6af5266.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/887559/9b308ca3-cc50-ca7d-eabc-e2685dcbf44b.png)


**Newer Commmits on Remote**

もうコミットされてるよ！と怒られた。
え、どこに？反映されてないんだけど・・・
確認するとこんな状態。

```terminal
% git branch -a  

* master
  テーブル新規作成
  ユーザー管理機能
  remotes/origin/master
  remotes/origin/テーブル新規作成
  remotes/origin/ユーザー管理機能
```
remotesあるじゃない！なんで反映されないのかわからない。
ここで2時間ぐらいハマる。
復活の呪文がうまくいってなかったのか？あれはザオリクじゃなくてザオラルだったのか？
そんなことを考えながらどうにもこうにもうまくいかなくなってエラー文で検索をかけて出てきた英語の記事を読む。

どうやらローカルリポジトリのmasterブランチにトラッキングブランチが設定されていないことで出るエラーらしい（ちょっと何言ってるかよくわかんない
リポジトリのクローンを作成することで回復するとのこと。

感覚としては削除しちゃったから完全な状態でmasterブランチが復活してなかったよ！ってこと？
とりあえずやってみる。

```terminal
% git branch -u origin/master
```

これで見事にpullできるようになりました！ホッとした・・・
色々調べたんですが「-u」コマンドってどういう意味なのかわかりません。
何をしてくれているコマンドなんでしょうか？
**remotes/origin/master**
ってリモートブランチのことだと思ってましたけど違うんですね。
何回か読んだけどめちゃくちゃ難しい。
まだまだわからないことがいっぱい。やりがい。


### 参照させて頂きました

https://qiita.com/forest1/items/db5ac003d310449743ca

ありがとうございました。
リモート環境で共同作業

# リモートワークしてて、画面共有したくなったとき

主にLinuxを使ってリモートワーク中、別の作業者と画面共有したくなった場合お手軽に共有する方法。

## xrdpで画面共有

`/etc/xrdp/xrdp.ini`を編集し、ポートを固定することで、ログインユーザが同じセッションを共有するため、結果画面共有ができる。

```ini:/etc/xrdp/xrdp.ini
[xrdp1]
name=sesman
lib=libvnc.so
username=ask
password=ask
ip=127.0.0.1
#port=-1  #xrdpが接続用のポートを検索する
port=5912 #固定ポートにすることで、ログインユーザが同じセッションを共有する　
```

## screenコマンドでターミナル共有
同じサーバにターミナルでログインしている場合、screenのセッションを別のユーザが覗き見ることで、結果ターミナルを共有できる。

#### ターミナルを公開する人
screen名をつけなくても良いが、分かりやすく名前をつけてscreenセッションを起動する。

```shell_session
[userA]$ screen -S my-screen ←screen名
```

#### ターミナルを覗き見したい人
同一サーバにログインし、アタッチされているスクリーンの画面を共有できる。

```shell-session
[userB]$ screen -ls
There is a screen on:
	50534.my-screen	(Attached)　←覗き見したいスクリーンセッション

[userB]$ screen -x my-screen ←アタッチされたscreenセッションにお邪魔
```
Anacondaの仮想環境でJupyter Notebookを動かすときにエラー

Jupyter NotebookをAnacondaの仮想環境で動かそうとしてトラブルに見舞われたので、自分の施した対処法を書いておきます。

#環境
- Windows10 64bit Home バージョン20H2
- Anaconda3-2020.11-Windows-x86_64

#仮想環境の作成～Jupyter Notebookのインストールまで
Web上には様々な情報がありますが、自分が試した中ではこれが一番簡単だと思いました。

まずは仮想環境を作成します。

```python
$ conda create -n 環境名 python=バージョン ライブラリ名
```

作成した仮想環境に入ります。

```python
$ conda activate 環境名
```

仮想環境でJupyter Notebookをインストールします。
（仮想環境作成時にライブラリ名で「jupyter」を指定して一緒にインストールしていた場合は不要）

```python
$ conda install jupyter
```

Jupyter Notebookのカーネルに作成した仮想環境を表示するように設定します。

```python
$ ipython kernel install --user --name=環境名
```

#エラー発生
この状態で仮想環境で以下のコマンドでJupyter Notebookを起動できます。

```python
$ jupyter notebook
```

が、Pythonコードを書いても実行されず。Jupyterはカーネルに何回も接続をトライした挙句エラーが発生。以下のようなメッセージが出てきたのでDLLの読み込みに失敗しているようです。

```
 File "C:\Users\ユーザ名\anaconda3\envs\環境名\lib\site-packages\zmq\backend\cython\__init__.py", line 6, in <module>
    from . import (constants, error, message, context,
ImportError: DLL load failed while importing error: 指定されたモジュールが見 つかりません。
```

#エラー対処策
解決策がないか探し回ったところ、以下の情報にたどり着きました。

[Anacondaの仮想環境がjupyterに認識されないorエラー出るときの対処](https://takscho.hatenablog.com/entry/2020/08/20/040752)

コマンドをそのまま引用させていただきますが、自分の環境でもこのコマンドを仮想環境で実行することで解決できました！

```python
$conda uninstall pyzmq

$conda install pyzmq

$conda install jupyter
```

#補足：カーネルの削除
Jupyterに追加した仮想環境のカーネルを削除する方法は以下の通りです。

```oython
$ jupyter kernelspec uninstall 環境名
```
VirtualBoxが異常に遅くて困ってる人

VirtualBox 6.1.16だと、WSL2と同時に使うことができます。

しかし、WSL2導入前には、仮想サーバでyoutube見えるくらいサクサク動作していたWindows10が使えないレベルに遅くなりました

管理者権限のPowerShellで次のコマンドを実行して、WSL2を無効にすると快適になります。
再起動が必要なのがちょっと面倒。

WSLを無効にする時

```
Disable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform
```

WSLを有効にする時

```
Enable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform
```
swaggerをjsonで書いて、ついでに分割して管理する


## 概要
タイトルの通り。
コードが肥大するので分割して管理する。
jsonでやってますが、スクリプトの拡張子変更すればyamlでもいけるはず。

[完成物](https://github.com/kanemototomoki/swagger-module-example)

## アーキテクチャ
- [swagger](https://swagger.io/)
    - v3.0.0
- [swagger-cli](https://www.npmjs.com/package/swagger-cli)
    - bundle担当
- [chokidar](https://www.npmjs.com/package/chokidar)
    - ファイル監視
- [Swagger Viewer](https://marketplace.visualstudio.com/items?itemName=Arjun.swagger-viewer)
    - VSCの拡張機能


## ディレクトリ構造

```sh
root
├── docs
│   ├── paths 　　　　 // 監視対象ディレクトリ
│   ├── info
│   ├── _index.json  // rootファイル
│   └── swagger.json // bundleされたファイル
└── package.json
```

## 手順

### 1. packageなどをインストール  

```sh
$ npm i -D swagger swagger-cli chokidar chokidar-cli
```

### 2. npmスクリプト編集

```json
"scripts": {
  "build:swagger": "swagger-cli bundle ./docs/_index.json > ./docs/swagger.json",
  "watch:swagger": "chokidar './docs/paths' -c 'npm run build:swagger'"
}
```

### 3. スクリプトを実行してファイルを監視

```sh
$ npm run watch:swagger
```

### 4. VSCで `swagger.json` を `Swagger Viewer` で開く

`swagger.json` を開いて(activeにして)から、 `Command + Shift + p` を押下し、 
`OpenAPI: show preview using~` を選択する。
previewが展開されればOK。
Pythonで学ぶアルゴリズム　第16弾：並べ替え（挿入ソート）

# #Pythonで学ぶアルゴリズム< 挿入ソート >

##はじめに
基本的なアルゴリズムをPythonで実装し，アルゴリズムの理解を深める．
その第16弾として挿入ソートを扱う．

##挿入ソート
リストの先頭から順にソート済みとして，その隣のデータを挿入データとする．それから挿入データがソート済みのデータの中のどこに位置するのかというのをソート済みデータの末尾から順に比較し必要があれば入れ替えを行い，所望の位置に移動させる．そのイメージ図を次に示す．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951300/71cb235f-085a-e01a-972f-3fb4654fb8d7.png)

上図のように，ソート済みデータを拡張していくような形で徐々に昇順に並べ替えられていく様子が分かる．

##実装
先ほどの手順に従ったプログラムのコードとそのときの出力を以下に示す．

#####コード

```python:insert_sort.py
"""
2021/01/09
@Yuya Shimizu

挿入ソート
"""

def insert_sort(data):
    """挿入ソート：少しずつソート済み箇所を広げ，昇順に並べ替える"""
    #1つずつ挿入データを吟味する
    for i in range(1, len(data)):
        temporary = data[i]         #挿入データを一時的に記録
        j = i - 1
        while (j >= 0) and (data[j] > temporary):   #挿入データがソート済みデータ内のデータよりも小さく右にあれば繰り返し入れ替え
            data[j + 1] = data[j]       #右へ1つデータを移す
            j -= 1
        data[j + 1] = temporary     #上の操作で移動を終えた所に一時的に記録していた挿入データを代入

    return data


if __name__ == '__main__':
    DATA = [6, 15, 4, 2, 8, 5, 11, 9, 7, 13]

    sorted_data = insert_sort(DATA.copy())

    print(f"{DATA} → {sorted_data}")
```

#####出力
```
[6, 15, 4, 2, 8, 5, 11, 9, 7, 13] → [2, 4, 5, 6, 7, 8, 9, 11, 13, 15]
```

ちゃんと昇順に並べ替えられていることが分かる．
今回は並べ替える前後での比較をしたいがために，あえて``sorted_data``という変数に結果を格納し，さらに関数への引数は``DATA.copy()``というようにcopy関数により，引数に影響が出ないようにしている．並べ替えるだけなら，そのような操作は必要でなく，``insert_sort(DATA)``とすればよい．

##挿入ソートの計算量
最後に計算量について触れる．
基本的に選択ソートと同様，**計算量はオーダー記法で表すと，$O(n^2)$**となる．
ただし，一度も交換が発生しない場合は，比較のみ（入れ替えなし）で済むため**$O(n)$**となる．


##感想
前回に引き続き，そこまで複雑ではなかった．後ろから並べ替えることにはなるほどと学べた．次回以降の並べ替えアルゴリズムも楽しみである．

##参考文献
Pythonで始めるアルゴリズム入門　伝統的なアルゴリズムで学ぶ定石と計算量
　　　　　　　　　　　　　　　　　　　　　　　　 増井 敏克　著　　翔泳社
後から追加でgitignoreしたいときメモ

#問題

特に何もしていないのにgit statusで変更が記録されてしまう。

```
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   .dart_tool/flutter_build/0a841d3e0c969c64421ac67442114662/.filecache
        modified:   .dart_tool/flutter_build/0a841d3e0c969c64421ac67442114662/debug_android_application.stamp
        modified:   .dart_tool/flutter_build/0a841d3e0c969c64421ac67442114662/flutter_assets.d
        modified:   .flutter-plugins-dependencies
        modified:   .idea/workspace.xml
        modified:   build/app/intermediates/flutter/debug/flutter_build.d
```

#解決策


```bash
git rm -r --cached .dart_tool/flutter_build/0a841d3e0c969c64421ac67442114662/.filecache
git rm -r --cached .dart_tool/flutter_build/0a841d3e0c969c64421ac67442114662/debug_android_application.stamp
git rm -r --cached .dart_tool/flutter_build/0a841d3e0c969c64421ac67442114662/flutter_assets.d
git rm -r --cached .flutter-plugins-dependencies
git rm -r --cached .idea/workspace.xml
git rm -r --cached build/app/intermediates/flutter/debug/flutter_build.d

git add .
git commit -m ".gitignoreを反映"
```

```bash:gitignore
.DS_Store
.dart_tool/
.packages
.pub/
build/
.flutter-plugins
.flutter-plugins-dependencies
ios/Flutter/flutter_export_environment.sh
ios/Flutter/.last_build_id
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
```

参考：https://awesome-linus.com/2019/03/01/how-to-reflect-gitignore/
taichiのトリセツ② ~初期化~

## このシリーズについて
[taichi](https://github.com/taichi-dev/taichi)というpythonで使えるグラフィックのライブラリに最近ハマっているので、使い方をまとめてます。シリーズの目次は[こちら](https://qiita.com/Hiroaki-K4/items/49c9c9cb4c915397a431)。

## 初期化について
今回はtaichiを使ったプログラムで、必ず実行する初期化の処理のやり方についてまとめてみました。具体的には計算に使うアーキテクチャとデザインを描写するフィールドを初期化します。

## 手順
今回も[前回](https://qiita.com/Hiroaki-K4/items/7607b54fbcfaea171215)と同じくfractal.pyという公式が用意してくれているデモプログラムを使って説明してきます。まずは計算に使うアーキテクチャの初期化です。下のコードのti.init(arch=ti.gpu)のところですね。CPUを使う場合は、ti.cpuとすれば大丈夫みたいです。

```fractal.py
import taichi as ti

ti.init(arch=ti.gpu)

n = 320
pixels = ti.field(dtype=float, shape=(n * 2, n))

# 以下省略
```
gpuのバックエンドをcudaなどに指定もできるみたいです。ti.gpuとしておけば、バックエンドは自動的に見つけてくれるみたいですが。以下の様な感じです。
![Screenshot from 2021-01-09 21-53-42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663246/b6524794-b33b-7c9a-18f8-e6907183a752.png)
もう1つの初期化としては、fieldの初期化をします。taichiでは作成したデザインが描写される場所をfieldと呼ぶそうです。このfieldの大きさはshapeに代入する値で変更することが出来ます。ti.field()で初期化すると上のコード(fractal.py)のpixelsにはfloat型の0がfieldの大きさに合わせて入れられます。出来たフィールドに、その後の処理による数値を入れていくという流れになります。

## まとめ
次はfunctionとkernelについてまとめようと思います。

**間違いや質問、ご意見等ありましたらお気軽にコメントください。頑張って答えますので(笑)。**
Raspberry Pi の画面を他のパソコン上に出力する

Raspberry Pi を買った。

しかし余ってるディスプレイがないので、いま持ってるパソコン（iMac）にラズパイの画面を出す方法はないか、と調べたらあった。ラズパイの映像を HDMI キャプチャで USB に取り込んで、Web カメラとして認識させればいいらしい。
（Windows でも多分おなじ方法がつかえる）

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">iMac の画面に居候するラズパイ <a href="https://t.co/szHlmpdh8P">pic.twitter.com/szHlmpdh8P</a></p>&mdash; 柞刈湯葉（いすかり・ゆば） (@yubais) <a href="https://twitter.com/yubais/status/1347884966735085570?ref_src=twsrc%5Etfw">January 9, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## 用意するもの

USB-HDMI キャプチャ。1000円以下のも売ってるけど iMac は背後に USB 端子があるのでケーブルがあるのにした。1780円。
https://www.amazon.co.jp/gp/product/B08FJ5DF3J/

パソコン側ではカメラアプリを起動する。macOS にデフォルトで入っている Photo Booth は左右逆になってしまうため、App Stpre で適当に見つけた [Quick Camera](https://apps.apple.com/jp/app/quick-camera/id598853070?mt=12) というのを入れた。

## 利点
* 普通の液晶ディスプレイよりは安い。
* コンセントが減らない。
* パソコン側でスクショが撮れる。

## 欠点
* 遅延が結構ある。
* パソコン側の USB は減る。

## その他
* 音の出し方は調べてない。（使わないので）
* Zoom で画面共有ではなくカメラとして出力できる。特に意味はない。

## おわりに

別に Raspberry Pi でなくても HDMI 出力なら同じ手順が使えるが、試しにファミコンミニをつないでみたら遅延でまともにプレイできなかったので、実用的な用途はサーバー類の CUI 操作に限られると思う。
[ECCUBE4(symfony3)]言語切替プラグインを作ってみた

こんにちは！

kamotetuと申します

久しぶりの投稿になります

今回はタイトルの通りECCUBE4でフロントから言語切替できるプラグインを作ってみたということで紹介したいと思います。

↓リポジトリ
[CrossBorder1](https://github.com/kamotetu/eccube4_plugin_cross_border_1)

eccubeの対応バージョンは4.0.4 ~ 4.0.5で、4.0.3では動かないことを確認しています

ということでgithubに公開しましたのでよかったら試してみてください！
(試作品ですので完全自己責任のもと利用してください！)

↓インストール、有効化後の挙動(画像悪くてすみません)
![ezgif.com-gif-maker (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480146/fe8c85dd-0465-6ea7-1c85-1e8024a02b55.gif)

![ezgif.com-gif-maker (2).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480146/b464097f-f745-9f5f-bf87-7f1e8133729c.gif)

画像は商品登録ですが、他にもタグやカテゴリなどもできます(出来なかったらすいません！)

正直プラグイン開発の練習ということで去年の秋ごろまで作ってたものなのですが、githubのreadmeにも書いてある通り危ない箇所がたくさんあったので途中で開発を中止したものになります

なんで今頃公開したかというと、eccubeの[Q&Aサイト](https://xoops.ec-cube.net/)に多言語化にする方法の質問があったというのと、開発当時(今も)情報がほとんどなくて非常に頭を悩ませながら作った思い出があったのでコードを含め紹介しようと思い記事にしました

ちなみに、当時参考にした記事はこれらになります

- [Symfonyでの国際化(i18n)対応](https://sterfield.co.jp/programmer/symfony%E3%81%A7%E3%81%AE%E5%9B%BD%E9%9A%9B%E5%8C%96i18n%E5%AF%BE%E5%BF%9C/)
- [【EC-CUBE4】DoctrineExtensionsでEC-CUBEのDBを多言語化する](https://panda-telecoms.github.io/2020/06/26/%E3%80%90EC-CUBE4%E3%80%91DoctrineExtensions%E3%81%A7EC-CUBE%E3%81%AEDB%E3%82%92%E5%A4%9A%E8%A8%80%E8%AA%9E%E5%8C%96%E3%81%99%E3%82%8B/)

今回プラグインということで、紐付けたいentity(商品テーブルなど)のフィールドにアノテーションを追加することが出来なかったので(やり方あるのかな？)[【EC-CUBE4】DoctrineExtensionsでEC-CUBEのDBを多言語化する](https://panda-telecoms.github.io/2020/06/26/%E3%80%90EC-CUBE4%E3%80%91DoctrineExtensions%E3%81%A7EC-CUBE%E3%81%AEDB%E3%82%92%E5%A4%9A%E8%A8%80%E8%AA%9E%E5%8C%96%E3%81%99%E3%82%8B/)を参考に似たようなentityを作成して無理やり保存させるやり方を行いました

それで、コードの説明もしたいところですが、ファイルの数も多いので主要な処理をしているファイルとアクションだけご紹介します

#### ヘッダーの言語選択で多言語にしている処理
https://github.com/kamotetu/eccube4_plugin_cross_border_1/blob/master/CrossBorder1/Event/EventListener.php

```CrossBorder1/Event/EventListener.php
public function onKernelRequest(GetResponseEvent $event)
{
...
}
```

#### 多言語保存処理
https://github.com/kamotetu/eccube4_plugin_cross_border_1/blob/master/CrossBorder1/Event/SaveContentEventSubscriber.php

```CrossBorder1/Event/SaveContentEventSubscriber.php
public function postFlush(PostFlushEventArgs $args)
{
...
}
```
是非githubからダウンロードしてデバッグなどして確認してみてください

作りは非常に力技の部分が多いですが、多言語化カスタマイズしようと思っている方の参考になれば幸いです！
GitHubのリリースノートの自動作成

# 背景

開発プロジェクトのソースコードをGitHubで管理しており、リリースのたびに前回リリース時から作成されたプルリクエスト一覧をリリースノートに書くルールにしていたのですが、これが地味に手間だったので改善したいと考えました。

# gren-release-notesパッケージのインストール
[gren-release-notes](https://www.npmjs.com/package/github-release-notes)は、前回タグ付けしたコミットからの差分を基にリリースノートを作成してくれるツールです。以下の手順でインストールと設定をします。

1. `npm install github-release-notes -g` を実行します。Linuxなどの環境で権限が足りない場合は、先頭に`sudo`を足してください。
2. [個人アクセストークンを使用する](https://docs.github.com/ja/free-pro-team@latest/github/authenticating-to-github/creating-a-personal-access-token)を参考に、`repo`スコープを指定した個人アクセストークンを作成し、環境変数`GREN_GITHUB_TOKEN`に設定します。Linux環境だと`export GREN_GITHUB_TOKEN={個人アクセストークンの文字列}`のように設定します。`~/.bashrc`など、起動シェルに設定しておくと便利です。

![access_token.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377165/65a08e9d-eab9-5774-2d4e-fc154b675913.png)
3. GitHubで管理しているgradleプロジェクトへ移動し、`gren init`を実行して設定ファイルを作成します。２つ目の質問だけ`Pull Requests`を指定し、あとは必要に応じて変更します。

```
$ gren init
I can't get your repo labels, make sure you are online to use the complete initialisation

🤖 : Hello, I'm going to ask a couple of questions, to set gren up!

? What type of APIs do you need? Normal
? Where shall I get the informations from? Pull Requests
? Do you want to add a prefix to release titles? e.g. v
? Do you want to only include issues/prs that belong to a milestone? No
? Do you want to ignore tags containing certain words? No
? Do you want to group your notes? No
? What file name do you want for your changelog? CHANGELOG.md
? Which extension would you like for your file? .grenrc.yml
```

`.grenrc.yml`という設定ファイルが作成されたら準備完了です。

# リリース手順
それでは早速試してみましょう。まず、GitHubのリポジトリに移動し、右側のペインから新しいリリースを作成します。
![create_release.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377165/903d2713-aaa9-67f9-19b5-d94ae8978513.png)

リリースのドラフト作成画面では、バージョンだけを指定して`Publish release`ボタンをクリックします。タイトルや本文は、後ほどgrenコマンドで上書きするので入力不要です。
![tag.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377165/22814e98-4f78-fdb9-0bed-6ccc75c3fa3e.png)

GitHub上でリリースしたら、次にgrenコマンドを実行します。`gren release --override`を実行して以下のような結果になったら成功です。

```
$ gren release --override
Getting gren config from local file /home/ec2-user/github/gren-test/.grenrc.yml

🤖  - Generate release notes:
===================================
✔ Releases found: 1
✔ Tags found: 0.1.0
✔ Pull Requests found: 1
✔ 0.1.0 has been successfully updated!
See the results here: https://github.com/kazntree/gren-test/releases/tag/0.1.0
```

GitHubのリリースノートを確認すると、grenによってタイトルと本文が更新されています。前のバージョンからのプルリクエスト一覧が表示され、プルリクエストにラベルが付けられていた場合はそれも表示されます（以下の場合だと`bug`と`documentation`）。

![スクリーンショット 2021-01-09 21.24.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377165/6928b061-bb78-fcb8-4385-f46ff41a42f8.png)
JavaScript (ES6) 基礎編　繰り返し処理とは？

こちらではJavaScript学習の備忘録となります。
プログラミング初心者や他の言語にも興味、関心をお持ちの方の参考になれば幸いです。
* * *
###繰り返し処理とは？
よくある例だと

『1から100までの数字を出力する』

場合などに用いる**繰り返し処理**のことです。
繰り返し処理を行うには「**While文**」と「**for文**」がある。

■**While文**

while文は下記のように、「条件式がtrueの間、{ }内の処理を繰り返す」ことができます。 {}の後にセミコロンは不要です。

```javascript:script.js
while (条件式) {
  処理
}
```
上記『1から100まで数字を出力する』例で、while文を用いると下記のようになる。
まず条件式の判定が行われ、trueの時のみ{}の中の処理が1度実行される。
その後、再び条件式がtrueかどうかチェックされ、trueであれば処理が実行される。
条件式がfalseになるまで繰り返し処理が続く。

```javascript:script.js
let number = 1;

while (number <= 100) {  // 変数numberの値が100以下の時に処理を繰り返す
  console.log(number);
  number += 1;
}
```
**※ while文の注意点**
while文を用いる場合、条件式の部分がいつかはfalseになる。
しかし、上記「number += 1;」のような変数numberを更新するコードを書き忘れてしまうと、条件が永遠にtrue(上記だと永遠に100以下)となるため、繰り返し処理も永遠に続いてしまう。
これを**無限ループ**と呼ぶ。

■**for文**

できることはWhile文と同じだが、while文よりシンプルに書くことができるのが特徴。
for文では「変数の定義」「条件式」「変数の更新」の3つを括弧の中に書く。括弧の中ではそれぞれをセミコロン（;）で区切ること。

```javascript:script.js
for (変数の定義; 条件式; 変数の更新) {
  処理
}
```

```javascript:script.js
// 上記の例をfor文で書いてみる

for (let number = 1; number <= 100; number += 1) {
  console.log(number);
}
```
■**計算式の省略**

「number += 1」は「number ++」のように省略して書くことができる。
また、引き算の場合にも、「number -= 1」を「number --」と省略することができる。
while文やfor文では、この省略した書き方を使ってコードを短くすることができる。

```javascript:script.js
// 足し算
number = number + 1

number += 1

number++

// 引き算
number = number - 1

number -= 1

number--
```
■**繰り返し処理の応用**

またまた、よくある例ですが、
『1から100の数字を出力してください。ただし、3の倍数の時は「3の倍数です」と出力』する場合をfor文を用いて書く。

```javascript:script.js
for (let number = 1; number <= 100; number++) {
  if (number % 3 === 0) {
    console.log("3の倍数です");
  } else {
    console.log(number); 
  }
}
```

■**配列とfor文**

配列の中に格納されているすべての値を出力する。
この際、変数の値は0から始めることに注意する。

```javascript:script.js
const fruits = ["apple", "banana", "orange"];

for (let i = 0; i < 3; i++) {  // iが０〜2の間ループする
  console.log(fruits[i]);  // 変数iを用いて要素を取得 
}
```
また、「**配列.length**」とすることで、配列の要素数を取得できる。
上記、for文の条件式を下記のように書き換えることができる。
配列の要素数が変わっても問題なく繰り返すことができるので便利である。

```javascript:script.js
const fruits = ["apple", "banana", "orange"];

for (let i = 0; i < fruits.length; i++) {  // 条件式を、「配列.length」とする
  console.log(fruits[i]);  // 変数iを用いて要素を取得 
}
```


* * * 
####おわりに
このあたりは、基本中の基本ですね。
何かありましたらご指摘願います。
宜しくお願いいたします！！
【Rails】アプリ新規作成--備忘録--

#アプリ新規作成

作成したいディレクトリに移動してから

```ruby:ターミナル 
rails new [アプリ名] -d mysql
```

「-d mysql」でデータベース作成時にmysqlを指定

#データベース作成

作成されたアプリのディレクトリまで移動する。
下記のコマンドで、database.ymlに記述された設定通りにデータベースが作成される。

```ruby:ターミナル 
rake db:create
```
想定通りに作成されなければ、database.ymlを確認する。
sqliteが初期のデータベースに指定されているので、必要ならばgemにmysqlを記述し、bundle installする。

[参考: Railsアプリケーション開発をしよう！ 〜開発の準備編〜](http://yebisupress.dac.co.jp/2015/09/18/%E3%80%90%E6%9C%AA%E7%B5%8C%E9%A8%93%E3%81%8B%E3%82%89%E3%81%AEruby-rails-%E7%AC%AC4%E5%9B%9E%E3%80%91rails%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E9%96%8B/)

#コントローラーの作成

```ruby:ターミナル
rails g controller [コントローラー名]
``` 

#ルーティング設定

```ruby:routes.rb
root "[コントローラー名]#index"
```
rootはurlでアクセスした時に、トップページに表示されるコントローラーとアクションを表示しています。
今回は[index]アクションを指定しています。

#コントローラーアクション記述

必要なアクションを記述していきます。

```ruby:[コントローラー名]_controller.rb
def index
end
```
#ビューファイル作成
[app/views/コントローラ名/]ディレクトリが作成されれいるので、index.html.erbのファイルを作成します。

```html:index.html.erb
<p>Hello, World!</p>
```
こちらで、railsサーバーを立ち上げて、ローカルでアクセスすると「Hello, World!」と表示されます。

#テーブル作成
```ruby:ターミナル 
rails g model [モデル名]
```
モデルを作成すると、テーブルを作成する為のマイグレーションファイルが自動生成されます。
マイグレーションファイルを記述し、マイグレーションファイルを実行します。

```ruby:ターミナル
rails db:migrate
```

[参考 Active Record マイグレーション](https://railsguides.jp/active_record_migrations.html)
[参考 RailsのMigrationに関する基本まとめ](https://qiita.com/pon-san/items/c54aee04e56e6bb26eff)

以上。
Dockerの設定やあれこれ

## はじめに  
Windows10 ProにおけるDockerの導入と使用するコマンドについてまとめる  
Windows10 Homeについては、Hyper-Vが使えないため別の手順になるので、参考サイトを参照してください  

## 導入の流れ
1. Windows機能の設定
    1. Windowsキーを右クリックで選択し、`アプリと機能`を選択  
    ![2021-01-09-17-32-28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517181/d9f4bd91-1158-f219-2f2a-13c7276f5efc.png)

    1. `プログラムと機能`を選択  
    ![2021-01-09-17-33-55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517181/927f3916-d042-0f53-d25a-925c23e36870.png)
  
    1. `Windowsの機能の有効化または無効化`を選択  
    ![2021-01-09-17-35-41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517181/783fc9a0-d6b5-a4e9-237c-135ad05cdfdf.png)
  
    1. `Hyper-V`を選択  
    ![2021-01-09-17-39-30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517181/0fccf80b-0383-bf90-6196-8e2c9e7e6520.png)

    1. `Linux用Windowsサブシステム`を選択  
    ![2021-01-09-19-28-26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517181/314e754c-ac51-28c4-45e2-2caa39b12203.png)

1. WSL2 Linuxカーネル更新用プログラムパッケージをインストール
    1.  [Microsoft Docs](https://docs.microsoft.com/ja-jp/windows/wsl/install-win10#step-4---download-the-linux-kernel-update-package)から最新版のパッケージをダウンロード  
    ![2021-01-09-19-31-17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517181/c418e884-e133-6160-c642-25cac9de3c80.png)


1. Dockerのダウンロード  
    [サイト](https://hub.docker.com/editions/community/docker-ce-desktop-windows/)に移動して`Get Docker`を選択  
    ![2021-01-09-19-13-58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517181/dd6f0bd8-bd1b-6105-2a79-0b7826d9f91d.png)


    
1. インストール        
    1. `Docker Desktop Installer.exe`を選択  
        ![2021-01-09-19-16-25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517181/c3ed057e-5cd3-c37f-ae72-92de07b79380.png)
    1. コンフィグの設定  
        初期設定のまま使用  
        ![2021-01-09-19-18-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517181/98187672-b7f1-05c5-82db-08d664cee708.png)

## コマンド  

### 基本コマンド
```
# hello-world
docker run hello-world
# Docker イメージのダウンロード
docker pull [image name]
# 所有しているDockerイメージリストの取得
docker images
# 現在動いているDockerコンテナを取得
docker ps
# 所有している全てのDockerコンテナを取得
docker ps -a
# Dockerコンテナの削除
docker rm [Container ID]
# Docker イメージの削除
docker rmi [image name]
# Dockerコンテナの停止
docker stop [Container Name]
# Dockerコンテナの実行(2回目)
docker start [Container Name]
# Docker Versionの取得
docker --version
```
### docker runコマンド
```
# Dockerコンテナ名の指定
docker --name [Container Name] [Image Name]
# インタラクティブに通信を行う
docker -it [Container Name]
# Dockerコンテナをバックグラウンドで実行
docker -d [Container Name]
# Dockerコンテナに外部からアクセス
docker run -p [外部ポート]:[コンテナポート]
```

### Docker仮想ディスクサイズの最適化(自己責任で)
```
wsl --shutdown
cd %LocalAppData%\Docker\wsl\data\ext4.vhdx
Optimize-VHD -Path .\ext4.vhdx -Mode full
```

    
## 参考リンク先
- Docker 公式ドキュメント : [Docker Docs](https://docs.docker.com/docker-for-windows)  
- 共有Dockerイメージ : [Docker Hub](https://hub.docker.com/search?q=&type=image)  
- Hyper-V 有効化 公式ドキュメント : [Microsoft Docs](https://docs.microsoft.com/ja-jp/virtualization/hyper-v-on-windows/quick-start/enable-hyper-v)
Micro:bitとMATLABでメール着信アラートをつくる

###１．はじめに
Raspberry piなどのワンボードコンピュータがいろいろ出回っている今日この頃ですが、世間の人から見ると「あんなものを買って何に使うのだろう？」というのが不思議らしいです。
「音声リモコンなどを作ることができますよ」というと、必要以上に驚かれます。
（世間の人が何を考えているのかは、よくわかりません）。
しかし、残念なことに「Lチカ」（発光ダイオードを点滅させる）というのは、世間的に言うと目的ではないようです（光ったから何？、という）。
ということで、今回は世間の人でも目的が納得できるように、機能を連結させてみます。

###２．Micro:bitをBluetooth Low Energy(BLE)で使う
BLEを使えるようにして、MATLABから文字を送ることについては、
@motorcontrolman さんの[この記事](https://qiita.com/motorcontrolman/items/fa6a2435f6b8dd5d4e64)を参照にしていただければと思います。
Micro:bitにはMakecodeで下記のようにプログラムしておきます。
![WS000123.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434947/7e28f7a5-06f7-9021-365b-4296b8754c26.jpeg)

###３．MATLABの実行プログラム
これも上記の記事を参考に書いてみると、このようになります。
デバイス名（もしくはアドレス）とUUIDは適宜変えてください。

```matlab　microbitTest.m
function microbitTest
% BLE接続
b = ble("BBC micro:bit [vozet]"); 

% micro:bitに所定の文字を流すためのUUIDを設定
ledTextCharacteristic =  characteristic(b,"E95DD91D-251D-470A-A062-FA1922DFA9A8", "E95D93EE-251D-470A-A062-FA1922DFA9A8");

% 文字を流す
write(ledTextCharacteristic,"YouGotMail!");
pause(1);
clear b;
quit;
```
最後のquitはMATLABを終了させるコマンドです。
~~MATLABで作業している場合はquitさせると作業中のものも終わってしまうので注意が必要です。~~やってみたところ、２つめのMATLABが起動するようです。
このプログラムを実行ファイル化させるには、MATLAB Compilerを使う手があります（Compilerを使って、非MATLABユーザに配布しなければならない何かがあるということで、私は持っています）。

```
mcc -e microbitTest.m
```
'-e'オプションでコマンドウィンドウなしで実行できます。

Compilerがない場合は、バッチファイルを作成します。
バッチファイルには、

```
matlab -r "microbitTest"
```
というように書いて、"microbitTest.bat"というように名前を付け、matlabのpathを通しておきます。
pathの設定は、ここから（基本設定の歯車の下）してください。
![WS000124.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434947/b12a12c2-8059-6f7d-2477-629df45f51d4.jpeg)

###4. メーラーの設定
ここでは、outlookでの設定を示します。
「移動」の中にある「ルール」を開きます。
![WS000109a.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434947/d5a5be2b-8b28-399c-ec11-b1226a020012.jpeg)
「仕分けルールと通知の管理」を開きます。
![WS000112.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434947/6ae5725d-51ad-f59a-5ed9-5d72231d721d.jpeg)
「新しい仕分けルール」をクリックします。
![WS000113.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434947/1e804487-ba6c-fc3c-25a2-d58955c8ad14.jpeg)
「受信メールにルールを適用する」を選択し、「次へ」。
![WS000114.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434947/0e33527d-705f-1672-80d5-3bdb566d7d05.jpeg)
「このコンピュータで送受信を行なった場合のみ」をクリックします。
![WS000116.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434947/cf58885b-d939-f90b-a267-21b5b3db8303.jpeg)
「アプリケーションを開始する」にチェックを入れ、ステップ２の青字の「アプリケーション」をクリックします。
![WS000119.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434947/babe8619-0b24-e8e0-a6a2-bcb8bccbb782.jpeg)
「アプリケーションを開始する」が見つからなかった場合は、[この辺のページ](https://answers.microsoft.com/ja-jp/msoffice/forum/all/%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC/b113864a-75da-417f-830c-10197a8edbac) を見て、なんとかしてください。

青字の「アプリケーション」をクリックしたら、先ほどの実行ファイルを選択します。
バッチファイルの場合は「すべてのファイル」にしないと選択できません（というかファイルが見えないはず）。

メーラーの設定はここまでです。

###５. デモ画像
インライン動画でなくてすみませんが。
[<img width = 400 src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434947/e1ef9b63-a3b1-48ac-b3a2-b36f4b958cbe.jpeg">](https://streamable.com/s22nyo)
こんな感じです。

ということで。
おつかれさまでした。
【無益】小説サイト作ります。

こんにちは、シロウです。

2021年になって、早くも9日経ちました。

最近、凄く寒いですね。
僕は冬眠しながら、なんかWebアプリを作りたいなーと考える日々を送っていました。

そして「そうだ、小説サイトでも作ろう！」と思い至ったので、これから1ヶ月~2ヶ月ぐらいで小説サイトを作ろうと思います。

おそらく、多くの方は興味ないと思いますが、 どんな感じにするか〜とか現時点での構想をお話ししておきます。

##小説サイトを作ろうと思った理由

**理由としてはシンプルで「才能ある小説家が埋もれてほしくないから」です。**

というのも、僕はとても小説が大好き（特に異世界系。笑）でして、昔に自分で小説を書いて、投稿していたこともあります。（草生えますね。）

ただ、その時に思ったのが「ちょっと面白いだけだと、全く日の光を浴びれない」ということ。

なぜなら、既存の小説サイトはあまりにも強豪が多するからです。実にシンプル。

それなら、僕が新しい小説サイトを作って、何か面白い小説には支援やPRできるような仕組みを作ればいいんじゃね！？と考えたわけです。

##小説サイトの機能

小説サイトといっても必要な機能は沢山ありますよね。

でも、色々と機能をつけすぎても、わかりにくいと思うんです・・・（経験談）

なので、作家さんは楽に執筆活動ができて、読者は自分が好きな小説をすぐに見つけられるようにしたい。

その中でも、特に重要視したいのは収益の部分。

できる事なら運営費を差し引いた広告収入を全部、作家さんに回そうかな〜とか考えてます。

これに関しては、小説サイトがそれなりの規模になっていかないと難しいと思いますが、、、ぜひ実現したい。

##小説サイトを作成するにあたっての意気込み
とにかく色んな作家さんにチャンスが回ってくるようにしたいので、色々とがんばります。（ざっくり）

そして、面白い小説がもっと世の中に溢れて、僕が好きな小説ももっと増えることを願います。

ちなみに、漫画も好きなので、次は漫画サイトも作りたいですね、はい。笑笑

こんな感じで、とりあえずこれから作っていこうと考えてるWebアプリのお話しでした。

最後まで読んで頂きありがとうございましたm(_ _)m
WSL2(Windows10) で Ansible を使って、RaspberryPi3 を WifiAPにするためのPlaybook を書いてみた。

今回の目的は、Wifi機能がないPanasonicレコーダーと、WifiがないYAMAHAルータで
パナソニック製HDD TVレコーダーに録画された番組をiPhone からどこでもディーガというアプリで
鑑賞するために、ラズパイをWifiのアクセスポイントにしたいというのがスタートです。

※セットアップするだけなら手でやった方が早いというのは無しです。
　1年後にラズパイのSDカードが壊れてもPlaybookで１発 OKという状態にしておきたい

・作り方
ラズパイを使ったWifiのAPを導入する方法は沢山あります。
今回は、下記を満たしているものを作成します。
・WifiのIPアドレスはルータと同じセグメントのDHCPから払い出します。

＜用意するハードウェア＞
・ラズパイ１台　　　　　Raspberry Pi 3 Model B Rev 1.2　を使用(WifiAPにする）
・Micro SDカード１枚　 今回は16GBを用意 (ラズパイのOSを書き込む）
・Windows10 バージョン2004 ビルド19041.685に、WSL2　https://docs.microsoft.com/ja-jp/windows/wsl/install-win10（Ansible 実行環境）をインストールしておく

＜前提＞
・Ansible を実行するLinuxが１台ある（今回はWSL2で行う）

＜Windowsの手順＞
・公式のイメージ書き込みツール「Raspberry Pi Imager」をダウンロードしてhttps://www.raspberrypi.org/software/
　SDカードにRaspbianを書き込んでおく
　今回は、Linux raspberrypi 5.4.79-v7+　を使用
　Imagerで書き込み後、SDカードのドライブで、Explorer で、右クリック、新規作成で、
　SDカードに ssh という空のファイルを作成する。（ラズパイ起動時に、sshに接続するため）
＜ラズパイの手順＞
　Windowsで作成したSDカードをラズパイに差し込んで電源を入れる。
　ラズパイにＬＡＮケーブルを差して、WindowsのWSLから接続できる状態にしておく。

＜Windowsの手順＞
・Windows10上のWSL2で、Ansible 実行環境を構築する
$ sudo apt-get install ansible 
$ ansible --version
ansible 2.9.6
$ sudo useradd -s /bin/bash -d /home/pi pi
$ su - pi
　鍵認証するため公開鍵を作成する
$ ssh-keygen -t rsa
　鍵をラズパイにコピーする
$ ssh-copy-id pi@raspberrypi.local
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
$ cd ~
$ pwd
 /home/pi
$ mkdir -p playbook/inventory
$ cd playbook
ラズパイのIPアドレスをhosts.iniに書き込む
$ echo 192.168.2.110 >inventory/hosts.ini
Playbookを記載する
$ vi wifi-ap.yml
 :
$ ansible-playbook -i inventory/hosts.ini wifi-ap.yml
PLAY RECAP *************************************************************************************************************
192.168.2.110              : ok=18   changed=5    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

＜備考＞
・ラズパイのWifi APのソフトは下記の通り。apt でバージョン指定していないため、
　実行する時期で、バージョンは変わる可能性があります。
　hostapd v2.8-devel
　bridge-utils/stable,now 1.6-2 armhf

・今回は、Playbookが140行と長いため割愛します。
【Go】io.Writerについて見てみる

Goのio.Writer interfaceについて調べました。

## io.Writerとは
`io.Writer` は以下のようなinterfaceです。

```
type Writer interface {
    Write(p []byte) (n int, err error)
}
```

writeメソッドを持ちます。

## 色んなwriteメソッドを見かける

- ファイルの入出力
- connectionへの書き込み
- バッファへの書き込み

など色々なwriteメソッドがあります。

これは上記のwriteメソッドをfileやTCPConn,Bufferで実装しているので
それぞれの`ファイル` に関して書き込みが可能です。

## ファイルという考え方
先ほど、 `ファイル` という言い回しをしましたが、 `ファイルディスクリプター` というものがあります。
これは、 `OSがカーネルのレイヤーで用意している抽象化の仕組み` です。
具体的には、数値の識別子のようなもので

- 0:標準入力
- 1:標準出力
- 2:標準エラー出力

のように数値ごとに対応するものが決まっています。

この対応するものが、ファイルだけでなくソケットなど様々なものがあります。
ただ、どれもファイルと同じようにアクセスし書き込むことができるので、
`ファイルという考えで抽象化しています。`

この `io.Writer`はファイルディスクリプターを模倣しGo言語で実装したようなものとなっています。

## 参考記事
ありがとうございました。
- [低レベルアクセスへの入り口（1）：io.Writer](https://ascii.jp/elem/000/001/243/1243667/)
cannot find type definition file for 'node'. ts2688のエラー

#cannot find type definition file for 'node'. ts268のエラーが出たときの対処
コマンドで下記のコードを実行

```
npm install @types/node --save-dev
```
#参考
https://www.it-swarm-ja.tech/ja/javascript/typescript-react%E3%82%A2%E3%83%97%E3%83%AA%E3%81%A7%E3%80%8C%E3%83%8E%E3%83%BC%E3%83%89%E3%80%8D%E3%81%AE%E3%82%BF%E3%82%A4%E3%83%97%E5%AE%9A%E7%BE%A9%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%8C%E8%A6%8B%E3%81%A4%E3%81%8B%E3%82%8A%E3%81%BE%E3%81%9B%E3%82%93/809518464/
【初心者でもわかる】hover時のCSSをhtmlのタグに直接書く方法

# どうも7noteです。hover時にだけCSSを当てる方法。

CSSは.cssファイルに書くか、`<style></style>`の中に書くのが一般的ですが、HTMLのタグの中に書くことも可能です。

```index.html
<!-- HTMLのタグに直接CSSを書く方法 -->
<div style="background:#CCF;">てすとてすと</div>
```

しかし、この方法には欠点があり:hoverなどの疑似セレクタがついた時のCSSを指定することができません。
（※ほかにも管理がしにくいなどの欠点もあります。）

ですが、onMouseOutとonMouseOverの属性を使うことで:hoverと同じようにCSSを反映することができます！

## hover時のCSSをhtmlのタグに直接書く方法

```index.html
<div style="background:#CCF;" onMouseOut="this.style.background='#CCF';" onMouseOver="this.style.background='#EEF'">てすとてすと</div>
```

**結果**
![sample.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/30af6641-d18b-bd82-4a16-32f3116e4c4b.gif)


このようにボタンの上にカーソルが乗った時に色が変わります。


## 文字色も変えたい！複数処理をするときはセミコロン（;）で繋ぐ。

```index.html
<div style="background:#CCF;" onMouseOut="this.style.background='#CCF';this.style.color='#000';" onMouseOver="this.style.background='#EEF';this.style.color='#F00';">てすとてすと</div>
```

**結果**
![sample02.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/ed82311e-2542-4260-a9be-ba3b32e6e284.gif)


またjavascriptで関数を動かすこともできるので以下のような書き方でも同じ処理をすることが可能です。

```index.html
<div id="hover-btn" style="background:#CCF;" onMouseOut="omOut();" onMouseOver="omOver();">てすとてすと</div>

<script>
function omOut(){
  document.getElementById('hover-btn').style.background='#CCF';
  document.getElementById('hover-btn').style.color='#000';
}
function omOver(){
  document.getElementById('hover-btn').style.background='#EEF';
  document.getElementById('hover-btn').style.color='#F00';
}
</script>
```
同じ結果になりました。
![sample02.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/cad849b8-7a71-1478-c742-a27ee64bb0ed.gif)


## まとめ
htmlだけやjsを使って:hoverの代わりの処理を入れることはできますが、可能なのであればやはりCSSファイルでちゃんと:hoverとかける方が作りやすいし管理もしやすいですね。
でもどうしてもhtmlのタグしかかけないときに使える技です！

困ったときに使えるTipsでした。


参考：https://teratail.com/questions/151338

#### おそまつ！
~ Qiitaで毎日投稿中!! ~
[【初心者向け】WEB制作のちょいテク詰め合わせ](https://qiita.com/7note)