OmniAICreator/Qiita-1.07M huggingface dataset:
PHPでどうやってコンテンツのEncodingをチェック出来る？

システムを開発する時に、「ファイルのコンテンツ」を検証する場合も有るかもしてません。
CSVかExcelのコンテンツをチェックする為に、「mb_detect_encoding」をよく使いますので、メモ行ったします。
他の仕方があれば、コメントして頂けば、幸せです。

下は「Shift JIS」を検証の例です。

```PHP

$file_content = file_get_contents($file);
$encodings    = array('SJIS-win', 'UTF-8', 'UTF-16');
if (mb_detect_encoding($file_content, $encodings) !== 'SJIS-win') 
{
    throw new Exception(__("File encoding must be Shift JIS."));
}

// $convertCt   = mb_convert_encoding($file_content, 'UTF-8', 'SJIS-win');
```

:relaxed:よろしくお願いします。
ブラウザタブのアイコン変更

# ブラウザタブにアイコンを表示させたい！
ほとんどのホームページのブラウザタブには，アイコンが設定されています．
laravelをさわる機会があったので，ブラウザタブを好きな画像に変更してみました．
これのブラウザタブのアイコンはファビコン(favicon)と言うらしいです．

##必要なもの
ブラウザタブを変更するにあたって，必要なのは16×16の画像です．
このサイズの画像を加工する様々なサイトはありますが，今回はこちらのサイトを使用しました．
[Favicon & App Icon Generator](https://www.favicon-generator.org/)

設定したい画像(出来れば700×700ぐらいがいいらしい)を"ファイルを選択"から選んで，"Create Favicon"を押すだけ．あとはその画像をダウンロードする．

## 配置
~/"プロジェクトファイル"/public 内にダウンロードした画像(拡張子は.ico)を配置(初期では画像無しのfavicon.icoがあるので，置き換える)するだけ．
サイトをリロードしてみると，反映されているはずです．

# 参考文献
[2019年版】ホームページのタブ画像(favicon/touch-icon)作成と設定方法まとめ](https://homepagenopro.com/html/favicon.html)
firebase

###CloudFirestoreの公式ドキュメント

https://firebase.google.com/docs/firestore/


###Realtime Database と Cloud Firestore の違い

https://firebase.google.com/docs/firestore/rtdb-vs-firestore



###CloudFirestoreセキュリティルールのチュートリアル

https://firebase.google.com/docs/firestore/security/get-started



###CloudFirestoreの料金

https://firebase.google.com/pricing



###Cloud FireStoreのRestAPIのリファレンス

https://firebase.google.com/docs/firestore/reference/rest/v1beta1/projects.databases.documents



###Cloud FirestoreをSDKを使う方法。(初期化のコードはmain.jsのVueインスタンスを生成する前に書いてください。)

https://firebase.google.com/docs/firestore/quickstart



###チャット機能などのリアルタイム通信の機能を使いたい場合は、以下のURLにあるVuefireというライブラリを使用して効率よく書くこともできます。

https://vuefire.vuejs.org/
Oracle cloudにsshで接続する

# Oracle cloudにアカウント登録
登録しようにも、スマホにSMSでメールが届かず、チャットでサポートしてもらって、確認コードを聞かないとダメだった。
# サーバセットアップ
VMを作っては見たものの、sshのカギが登録されていないのかログインできない。。。(後で、そもそもデフォルトのユーザが作成されていないっぽいことがわかった。)
そこで、コンソール接続で物理ターミナルにログインして、rootでログインしてユーザを追加した。
詳しい手順は公式HP https://community.oracle.com/docs/DOC-1021396 に載っているが、要点は、コンソールに接続した状態でVMを再起動して、grub起動中にeを押して、linuxefiの行の最後に

```
 init=/bin/bash
```
を追加してCtrl-xで起動。
起動したら、

```
/usr/sbin/load_policy -i
/bin/mount -o remount, rw /
以上で書き込みができるようになる。

システム設定ファイルの変更が完了したら、以下のコマンドでリブートをかけます
/usr/sbin/reboot -f
```
このリブートまでの間に、下記のようなコマンドを入力してsshで接続できるようにする。

```
/usr/sbin/useradd user1
passwd user1
/usr/sbin/usermod -aG wheel user1
su - user1
mkdir .ssh
chmod 700 .ssh
nano .ssh/authorized_keys
#公開鍵を登録する。
```

なぜかMacからVMを作成したりするダッシュボード？をブラウザで開こうとしても上手く開けなくて、Windowsからしか開けなかったり、rootでログインしている間にダッシュボードで再起動をかけたりすると、普通は1分で再起動するのに、10分待っても再起動しないので、いったんVMを消して再度作ったりするなど、なんだか不安定な感じはしました。
だけど、VM2つを無料で使えるのはすごい！
ShellScript 変数 の "\" を "/" に   置換する

# 目的

- 変数に格納された`\`を`/`に置換する方法を知る。
- Windows表示のファイルパスをLinuxのものに書き換える方法を知る。

# 書き方の例

- 変数に格納された文字列の置換を用いて`\`を`/`に変換する。
- 変数には`\`を含む任意の文字列が格納されているものとする。
- 変数内の文字置換は${変数名//置換対象文字/置換後文字}で処理することができる。
- 下記にShellScriptの処理を記載する。

```shell

# 出力 ${変数名//置換前文字/置換後文字}
$ echo ${変数名//\\//}
```

- 上記の書き方だと若干分かりにくいので解説をする。
- 変数名の次の`//`はマッチしたものをすべて置換する命令
- `//`の後の`\\`は最初の`\`がエスケープ命令で、後ろの`\`が置換前文字
- `\\`の後の`/`は置換前文字と置換後文字を区切るもの
- 最後の`/`は置換後文字
- 前述の内容を踏まえ、今回の処理をわかりやすくスペースを入れて記載する。

```shell

$ echo ${変数名 // \\ / /}
```

# より具体的な例

- Windows表記のファイルパス(ディレクトリの区切りが`\`)を、Linux表記のファイルパス(ディレクトリの区切りが`/`)に置換する。
- 変数`file_path`にはWindows表記のファイルパス「C:\Users\miriwo\Documents\sample」を格納する。
- 下記にShellScriptの処理を記載する。

```shell

# 変数にファイルパスを格納
$ file_path="C:\Users\miriwo\Documents\sample"

# \を/に置換して変数file_pathに格納
echo ${file_path//\\//}
>C:/Users/miriwo/Documents/sample 
```
React hooks useReducer


- Store.jsで`App.js`をラップする
- iniialStateを設定をしないと`nil`でえら０になる


## キーワード
- createContext ← Proveider的な役割をしている
- useReducer
- store
-  <TodoItem key={item.id} {...item}/>)}

```javascript


<TodoItem key={item.id} {...item}/>)}

どっちも取れる
# id
function TodoItem({id}){
  return (<div>{id}</div> )
}
# text
function TodoItem({text}){
  return (<div>{text}</div> )
}
```





```javascript:src/App.js

import React, {Component} from 'react';
import logo from './logo.svg';
import './App.css';
import Store from './store'
import Fruits from './Fruits'

class App extends Component{
  constructor(props){
    super(props)
    this.state ={
      name: "react"
    }
  }

  render(){
    return (
      <Store>
       <div className="App">
        <Fruits/>
      </div>
      </Store>
    );
  }
}

export default App;


```

```javascript:src/Fruit.js

import React, {useContext} from 'react';
import {StoreContext} from './store'

const Fruits = () => {
  const [state, dispatch] = useContext(StoreContext);
  return(
      <div>
          <h1>Fruits</h1>
          <button onClick={() => dispatch({type:"addFruit", payload:"bnana"})}>add Banana</button>
          <button onClick={() => dispatch({type:"addFruit", payload:"apple"})}>add Apple</button>
          <ul>
          {state.fruits.map(fruit => <li>{fruit}</li>)}
          </ul>
          
      </div>
  )
}

export default Fruits


```


```javascript:src/store.js

import React, {createContext, useReducer} from 'react';


// これがcreateStore的なやつか？ createContext is Provider
export const StoreContext = createContext({})


const initialState = {fruits: []}

function reducer(state, action){
  switch (action.type){
    case 'addFruit':
      return {fruits: [...state.fruits, action.payload]}
    case 'addVeggitable':
      return {vegetables: [...state.vegetables, action.payload]}
    default: throw new Error("action type must....") 
  }    
}

const Store = ({children}) =>{
   const [state, dispatch] = useReducer(reducer, initialState)
   return(
       <StoreContext.Provider value={[state, dispatch]}>{children}</StoreContext.Provider>
   )   
}

export default Store;

```


## youtube

https://www.youtube.com/watch?v=corZt4Sb-fQ
新しくなったFlutter For Webを使ってみた(2019/9/23)

# 新しくなったFlutter For Webを使ってみた
Flutter 1.9になりFlutter For WebがFlutterに統合されたので使ってみました。今回実際に動かすバージョンはFlutter1.10ですが。

## 環境
* mac OS Mojave 10.14.6
* Visual Studio Code 1.38.1
* Flutter 1.10.5 channel dev
* Dart 2.6.0

## Flutterのインストール
[このページ](https://flutter.dev/docs/get-started/install/macos)に書いてある通りにすればFlutterをインストールすることができます。

## Flutter For Webを使えるようにする
基本的には[このページ](https://flutter.dev/docs/get-started/web)に書いてある通りにするといいのですが、2019/9/23現在は

```
flutter channel master
```

だとうまく動かないので、代わりに

```
flutter channel dev
```
にしてください。そのうちmasterでも動くようになると思います。

【2019/9/25 追記】
channel masterでも動くようになりました。

## Visual Studio CodeにFlutterとDartのExtensionを追加
Visual Studio CodeのMarketplaceで「Flutter」と「Dart」を検索してExtensionをインストールしてください。

## 新規プロジェクトを作成
* Visual Studio Codeで、Shift+Cmd+Pでコマンドパレットが開くので、Flutter:New Projectを選択して、任意の場所にプロジェクトを作成してください。
* ターミナルでプロジェクト配下に移動して

```
flutter run -d chrome
```

と叩くと以下のようなサンプルページが表示されます。

<img width="1312" alt="スクリーンショット 2019-09-23 8.49.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221257/b0b23fcc-cb12-c743-a0c5-8f33131d661b.png">

これで準備完了です。

## プラットフォームごとに画面の表示を変えてみようと思ったけど...
* Platform.isAndroidなどのコードを書くとプラットフォームを判定することができます。これでWebとモバイルで表示変えることができる！
![スクリーンショット 2019-09-23 13.15.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221257/5d628664-faf4-cfc7-7470-cc241280d92e.png)

* 以下のようなコードを書いてflutter run -d chromeを実行！

```dart:main.dart
import 'dart:io';

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Platform.isMacOS ?
            Text(
              'マック',
            ) : Text('マック以外')
          ],
        ),
      )
    );
  }
}

```


**※エラーが出ます。なんでや。**

## dart:ioはWebでは使えない
[ここの情報](https://github.com/flutter/flutter/issues/39998)によると、dart:ioはFlutter For Webでは使えないみたいです。そのうち対応するといいのですが、現状ではWebとモバイルで表示の切り替えは簡単にはできなさそうです。(画面サイズで表示を変えるとかそんな感じになりそう)

## まとめ
* 現時点では、Flutter For Webを使う場合は、flutter channel masterではなく、flutter channel devを叩くこと。
* Flutter For Webでは、現時点ではdart:ioは使えない。(対応してください。お願いします。)
Git 入門

# Git 入門

## 1. 基本

以下のサイトで基本的な使用方法を学んでください。
※ 入門編・発展編・プルリクエスト編を学修してください。
[サルでもわかるGit入門](https://backlog.caom/ja/git-tutorial/)


## 2. 練習問題

### 問題１

1. GitHub に新規リポジトリを作成してください。名前を `git-training` とします。

3. `a_work` と `b_work` というディレクトリを任意の場所に作成する。(Aさん・Bさんの２名が同じリポジトリで作業すると仮定)

1. `a_work` 配下に `git-training` というディレクトリを作成する。

4. `git-training` に移動。 git コマンドを使用し `リポジトリを新規作成`  する。
※ 以降、`a_work/git-training` 配下で作業する

1. ファイル `README.md` を追加し、コミットする。

1. GitHub のリモートリポジトリをローカルに追加する。※ ヒント: `git remote add origin`

1. ローカルの `master` ブランチをリモートブランチに反映し、合わせて上流ブランチに指定する。※ ヒント: `git push -u`

1. `developブランチを作成` する。以降 `develop` ブランチで作業する。

1. `test.txt` ファイルを追加。内容は１行 `aaabbbaaa` を追加する。

1. `text.txt` を コミットする。

1. `直前のコミットのコードやコメント修正`する。`text.txt` を `cccbbbccc` に変更する。

1. `develop` をリモートリポジトリに反映する。

1. `b_work/git-training` 配下で リモートリポジトリ を ローカルに取得する。※ 以降 `b_work/git-training` で作業する。

1. `develop` ブランチに切り替える

1. `develop` ブランチを元に 新規ブランチ `task/new_function` を作成する。

1. `test.txt` を `aaacccaaa`に変更しコミットする。

1. `task/new_function` をリモートリポジトリに反映する。

1. `test.txt` に任意の１行を追加し、コミットしプッシュする。

1. もう一度、`test.txt` に任意の１行を追加し、コミットしプッシュする。

1. 複数のコミットを一つにまとめたい。今追加した２つのコミットを１つにまとめてリモートリポジトリに反映する。ヒント）rebase
    - ここで、rebase する際に reword, fixup, squashなど、それぞれの使い方を学ぶ
    - オススメとしては、fixupでコミットを結合しつつ最上部で reword によりコミットメッセージを変更する手法

1. リモートリポジトリに反映する。ただし、ローカルとリモートでコミットの差分ができていているため強制的に反映する。
補足）本来、複数人で作業するブランチの場合、強制的に反映してはいけないが練習なので行う。

1. `a_work/git-training`に移動し `test.txt` を修正（`aaagggaaa`）して `develop` をリモートリポジトリへ反映する。

1. `b_work/git-training` に移動し、`develop` ブランチに切り替える。※ 以降 `b_work/git-training` で作業

1. リモートの状態をローカルへ反映（`fetch`）しリモートの履歴を取得（`pull`）する。

1. `develop` ブランチに `task/new_function` をマージする。ただし、**マージコミット** が必ずできるように merge にオプションをつける。

1. コンフリクトが発生。差分を解決して リモートに反映する。（今回差分については developの内容(HEAD)が不要という扱いで削除する）


### 問題２

1. `a_work/git-training` に移動し、`develop` から `task/new_branch1` というブランチを作成する。

1. `test2.txt` というファイルを追加し、コミット・プッシュする。

1. `b_work/git-training` に移動し、fetch する。※以降 `b_work/git-training` で作業する

1. `develop` から `task/new_branch2` というブランチを作成する。

1. 先程 `a_work/git-training` で追加したコミットを、 `b_work/git-training` に取り込み、コミットする。※ ヒント： cherry-pick -n

1. 今コミットした内容をステージに戻す。※ ヒント: reset --soft

1. ステージ上の変更内容を、一時保存する。※ ヒント: stash

1. 一時保存した変更内容をステージに戻す。 さらにコミットする。

1. 今コミットした内容は不要なので削除する。※ ヒント: reset --hard

1. 間違ってコミットを削除してしまったので元に戻す。※ ヒント: reflog

1. 最後に `develop` へマージして。`タグ` をつける。タグの名称は `2019xxxx` の形式で本日の日付とする。

### 問題３

問題１、問題２を `SourceTree` のみで行う。

##  3. Tips

|コマンド| 説明 |
| ---- | ---- |
|git fetch --prune| リモートで削除されたブランチがローカルの origin に残っているとき、ローカルからゴミブランチを消す|
|git reset --hard origin/branch_name| 差分の問題で pullできなとき、強制的にリモートをローカルへ反映する |
|git rm --cached [削除したいファイル]| ファイルを残してgitの監視対象から外す|
|git bisect|どのコミットで問題を混入させてしまったのかを特定する |
M5StickV MicroPython 画像取得<sensorクラス>

#カメラの設定に使えるメソッド
●sensor.set_pixformat(value)
　value=[sensor.RGB565, sensor.GRAYSCALE]

●sensor.setframesize(value)
　value=[sensor.VGA, QVGA, QQVGAなど]

 - その他，以下の形式が使用可能
  - sensor.LCD[128, 160]
  - sensor.B64X32[64, 32]
  - sensor.B64X64[64, 64]

●sensor.set_saturation(value)
　value=[-2 ～ 2]整数のみ

●sensor.set_brightness(value)
　value=[-2 ～ 2]整数のみ

●sensor.set_contrast(value)
　value=[-2 ～ 2]整数のみ
　引数に大きな数字を与えてもエラーにならないが，MaixPy DOCによると指定できるのは上記の範囲のみ

●sensor.set_windowing(value)
　valueはクリップする幅と高さをタプルで与える

●sensor.skip_frames(value)
　valueは時間，もしくはフレーム数

●sensor.width()
　カメラの画素数を取得（現在の設定値）
●sensor.height()
　カメラの画素数を取得（現在の設定値）
●sensor.snapshot()
　撮影

●sensor.get_fb()
　フレーム・バッファ(imageオフジェクト）を取得

●sensor.set_hmirror(value)
　value=[True or False]
　カメラの左右を反転

●sensor.set_vflip()
　value=[True or False]
　カメラの上下を反転

●sensor.get_id()
　筆者の環境では30530が返ってくる

●sensor.__write_reg(address, value)

●sensor.__read_reg(value)
　valueは読みたいレジスタのアドレスを与える
●sensor.reset()

#使えないメソッド
MaixPy DOCに書いてあるが，現状M5StickVで使えないAPI

●sensor.set_auto_gain(bool, value)
　bool=0:オートゲインOFF，value=floatでゲインを指定

●sensor.get_gain_db()

●sensor.set_colorbar(value)
　value=[0 or 1]
　MaxiPy DOCには0でカラーバーモード無効，1で有効と書いてあるが何を指定してもFalseが返ってくる．コンパイル，実行時共にエラーにはならない．

#●カメラの設定　ピクセルサイズ
[GRAYSCALE，RGB565, YUV422]など指定可能
BAYERはサポートされないようで，OS errorとなる．

```python
import sensor

sensor.set_pixformat(sensor.RGB565)
```


<br>
#●カメラの設定　撮像解像度
[VGA, QVGA, QQVGA]などが指定可能
QQQVGAは指定できるが，firmware(python実行環境）に処理が書いてないため，画像が乱れる．
https://github.com/sipeed/MaixPy/blob/master/components/micropython/port/src/omv/ov7740.c

```python
import sensor

sensor.set_framesize(sensor.QVGA)
```

<br>
#●カメラの設定　フレーム・レート
　firmwareをビルドするとき，menuconfigでOV7740のベースクロック？を設定できる．OV7740は最高27Mhzで動作可能だが，デフォルトでは12MHｚになっているようなので，クロックを上げてやると，若干レートが改善する．
　液晶表示も足を引っ張るかもなので，カメラ画像の画面表示ありでフレーム・レートを上げるには工夫が必要かも．
クロック24Mhz，QQVGA，RGB565の条件で34FPS程度出ている（液晶表示なし）
クロック24Mhz，QVGA，RGB565，`set_windowing((128,128))`で60FPS出ます
ファーム・ウェア・ビルドは下記参照
https://raspberrypi.mongonta.com/howto-build-firmware-of-m5stickv/
現在は，SipeedのリポジトリはMaixPyからMaixPy-v1に変わっている．

<br>
#●カメラの画像を切り出し
　内部的には`set_framesize()`に従い，VGAなりQVGAで撮像するが，`set_windowing()`しておくと，取り出す画像は設定した切り出し画像となる（多分OV7740側で処理される）
　4つの引数でx, yも指定してみたが，位置指定はできず，常に<del>中央を切り出す</del>ようだった．
<b>w, h の数値は8の倍数で指定する．</b>

```python
sensor.set_windowing((32, 32))     #32x32を切り出し
img = sensor.snapshot()
```

バグがあるようです．

```python
import sensor, image, time, lcd

lcd.init(freq=15000000)
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.set_windowing((240,104))    #8の倍数でも変な数字を指定するとダメかも
sensor.skip_frames(time = 1000)
clock = time.clock()

while(True):
    clock.tick()
    img = sensor.snapshot()
    lcd.display(img)
```

<br>
#●カメラの画像を左右/上下反転

```
sensor.set_hmirror(enable)    #左右反転
sensor.set_vflip(enable)    #上下反転
```

<br>
MAMP PRO で 1045エラーが出てphpMyAdminに入れない場合の解決方法

MAMPで同様の問題が起こったときにはconfig.inc.phpのパスワードを書き換えることで解決しますが、MAMP PROは設定方法が違います。

一旦、サーバーを止めてから作業します。

止めた状態で、黄色のChange passwordに自身で設定したパスワードを入力、そして、サーバーを再起動します。
（それだけです）

<img width="1157" alt="スクリーンショット 2019-09-23 16.31.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145650/4c97fcd6-cccc-74af-b198-f5811e0c4a07.png">
基礎カリキュラムで学習したRuby言語で作るアプリケーション(アルゴリズム)のまとめ

# 配列オブジェクトの生成、 空のハッシュの生成、 <<メソッド
```ruby:reviewApp.rb
def post_review(a_posts)
  # 変数の定義
  post = {}  # ハッシュの生成(空)
  puts "ジャンルを入力してください:"
  post[:genre] = gets.chomp
  puts "タイトルを入力してください:"
  post[:title] = gets.chomp
  puts "感想を入力してください:"
  post[:review] = gets.chomp
  line = "------------------------"
  # レビューの描画
  puts "ジャンル : #{post[:genre]}\n#{line}"
  puts "タイトル : #{post[:title]}\n#{line}"
  puts "感想 :\n#{post[:review]}\n#{line}"
  
  a_posts << post  # 配列オブジェクトに追加する

  return a_posts   # a_postsをメソッドの呼び出し元に返す(配列オブジェクトに追加されたデータを返すことになる)
end

def read_reviews(a_posts)
  # リストの表示
  number = 0
  a_posts.each do |post|
    puts "[#{number}]:#{posts[:title]}のレビュー"
    number += 1
  end

  puts "\n見たいレビューの番号を入力してください:"
  input = gets.to_i

  # レビューの取得
  post = a_posts[input]

  # レビューの描画
  line = "------------------------"
  puts = "ジャンル : #{post[:genre]}\n#{line}"
  puts = "タイトル : #{post[:title]}\n#{line}"
  puts "感想 :\n#{post[:review]}\n#{line}"
end

def end_program
  exit    # プログラムを終了する
end

def exception
  puts "入力された値は無効な値です"
end

  posts = []    # 配列オブジェクトの生成

while true do  # ループ処理
  # メニューの表示
  puts "レビュー数:#{posts.length}"
  puts "[0]レビューを書く"
  puts "[1]レビューを読む"
  puts "[2]アプリを終了する"
  input = gets.to_i

  if input == 0 then
    posts = post_review(posts)  # post_reviewメソッドの呼び出し
  elsif input == 1 then
    read_reviews(posts)    # post_reviewsメソッドの呼び出し
  elsif input == 2 then  # プログラムを終了する(ループの解除)
    end_program     # end_programメソッドの呼び出し
  else
    exception       # exceptionメソッドの呼び出し
  end
end
```

# まとめ

1. メソッド呼び出し元の引数の名前と実行されるメソッドの方の引数の名前は同じにしなくても問題なし。
2. 配列オブジェクトの生成は ```posts = []```とする。
3. 配列オブジェクトに要素を追加するために ```<<```メソッドを使う。　```a_posts << post```で```a_posts```の中に配列の要素が追加され、それを呼び出し元に返す目的で上記コードの場合は成り立つ。(```posts = a_posts```になっているため)
4. 空のハッシュの生成をしておくには ```post = {}```と書く。
5. ```posts.length```のように```length```メソッドを使えば配列オブジェクトのデータ数を取得できる。
【Rails】投稿したURLをリンク可能にする方法　【初心者メモ】

### 【1】投稿の詳細欄に、普通に記事を投稿または更新すると、
![88df536a7b5877847152203dbd916636.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501744/89ee4fa5-a76e-da59-454c-2a8a690be85d.png)

### 　　　　　　↓
### 【2】このように、URLのリンクがつかずに普通の文字としての投稿になってしまいます。
![24685ad6823ab91519f5e8a6961a90e6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501744/b36d21b1-0af2-7d74-5652-78e4f5fd9b06.png)
詳細部分の投稿を出力するERBのコード

```ruby:show.html.erb
<%= @task.task_syousai %>
```
　
　
　
　

### 【3】LinkuというGemを使うと、安全なURL、emailなどにlinkを埋め込んでくれるようです。
Gemfileに`rinku`を追加。

```ruby
gem 'rinku'
```
```
bundle install
```
これで`rinku`をインストールできました。
　
　
### 【４】先程のERBを、Rinkuに対応したコードに書き換えます。
先程の

```ruby:show.html.erb
<%= @task.task_syousai %>
```
を、下記のように書き換えます。
###　↓

```ruby:show.html.erb
<%= Rinku.auto_link(@task.task_syousai, :all, 'target="_blank"').html_safe %>
```
そして確認してみると、
　
　

URLの投稿記事に自動的にリンクが付与されています。
`'target="_blank"'`があると外部リンク、無いと内部リンクになるようです。
![93df355745a5bdaae67e7aa56fcb448b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501744/321e1ec1-dc6d-03ac-7600-a94d3fd528aa.png)
VRChatで自分をフレンドに追加する

## この記事について
[柊 釘葉](https://twitter.com/hiiragi_kugiha)さんのVRChatのステータスをTwitterに表示するスプリクト[twitter-vrc-status](https://github.com/kugiha/twitter-vrc-status)の導入で、自分自身をフレンドに追加するという部分の解説です。

##コード
これをコピペして実行すればフレンドリクエストが届きます。
Python3が必要です。

```AddFriendMyself.py
import json
import requests

API_BASE = "https://api.vrchat.cloud/api/1"

url = "{}/config".format(API_BASE)
response = requests.get(url)
apiKey = json.loads(response.text)["clientApiKey"]

from requests.auth import HTTPBasicAuth

USER     = "" #ここにVRChatのIDを入力
PASSWORD = "" #ここにパスワード

url = "{}/auth/user".format(API_BASE)
response = requests.get(url, 
                        params={"apiKey": apiKey},
                        auth=HTTPBasicAuth(USER, PASSWORD))
token = response.cookies["auth"]
uid = json.loads(response.text)["id"]


url = "{0}/user/{1}/friendRequest".format(API_BASE, uid)
requests.post(url, 
                        params={"apiKey": apiKey, "authToken": token})
```
## ここでつまった
VRChat APIのIDをログイン時のIDだと勘違いしていて3日悩みました。

## 参考
- [VRChatのオンラインなフレンドをPythonで取得する](https://qiita.com/y23586/items/484c8465b7a966d237c0)
- [VRChat API Documentation](https://vrchatapi.github.io/#/)
dotfiles管理にhomebrew-bundleを導入する

## はじめに
最近ようやくdotfilesをGitで管理するようにしました。
頻繁にマシンを入れ替えるわけではないけど、こういうのっていざというとき案外役に立つので馬鹿にできない。パッケージマネージャーにhomebrewを使っているのでhomebrew用のインストールシェルを用意していました。homebrewにはhomebrew-bundleというものがあることを恥ずかしながら最近知ったので試してみます。

## homebrew-bundle
Brewfileというファイルを作っておいてその中に必要なものを書いておいて**brew bundle**コマンドで
複数パッケージをまとめてインストールすることができるらしい。素敵。

## Brewfile
```
cask_args appdir: '/Applications'

tap "caskroom/fonts"
tap "homebrew/bundle"
tap "homebrew/cask"
tap "homebrew/core"
tap "sanemat/font"

# brew
brew 'awscli'
brew 'colordiff'
brew 'composer'
brew 'curl'
brew 'diff-so-fancy'
brew 'git'
brew "go"
brew 'neovim'
brew 'openssl'
brew 'peco'
brew "pyenv"
brew "pyenv-virtualenv"
brew 'ssh-copy-id'
brew 'tmux'
brew 'tree'
brew "vim"
brew 'wget'
brew 'zsh-completions'
brew "sanemat/font/ricty", args: ["with-powerline"]

# cask
cask 'alfred'
cask 'appcleaner'
cask 'clipy'
cask 'docker'
cask 'google-chrome'
cask 'google-japanese-ime'
cask 'iterm2'
cask 'sequel-pro'
cask 'visual-studio-code'
cask "caskroom/fonts/font-hack-nerd-font"
```

## brew bundle
```
▸ brew bundle     
Using caskroom/fonts
Using homebrew/bundle
Using homebrew/cask
Using homebrew/core
....
```

インストール済みのものはUsing、未インストールのものはInstallingで表示される

## おまけ
#### Brewfileに入っていないアプリを削除
```
brew bundle cleanup
```

#### Brewfileにインストール済みアプリのリストを出力
```
brew bundle dump
```
React Hooks useState

# React hooks

- useState
  - state
  - setStateを扱える

## メモ

- スプレッド演算子はまだ慣れないな
- setTodosするときに、`引数は`newTodoで、`todos`を認識してくれるんだな

```javascript

import React, {useState} from 'react'
import './App.css'

function Todo({todo, index, completeTodo, deleteTodo}){
  return(
    <div style={{textDecoration: todo.isCompleted ? 'line-through' : ''}} className="todo">{todo.text}
    
    <div>
    <button onClick={() => completeTodo(index)}>done</button>
    <button onClick={() => deleteTodo(index)}>done</button>
    </div>
    </div>)
}

function TodoForm({addTodo}){
  const [value, setValue] = useState('');


  const handleSubmit = e => {
    e.preventDefault();
    if(!value) return;
    addTodo(value);
    setValue('');
  }

  return(
    <form onSubmit={handleSubmit}>
      <input 
        type="text" 
        className="input" 
        value={value} 
        placeholder="put text"
        onChange={e =>setValue(e.target.value)}/>
    </form>
  )
}

function App(){
  const [todos, setTodos] = useState([
    {
      text:"helll",
      isCompleted: false
    },
    {
      text:"helll222",
      isCompleted: false
    },
    {
      text:"helll33333",
      isCompleted: false
    },
  ])


  const addTodo = text => {
    const newTodos = [...todos, {text, isCompleted: false}]
    setTodos(newTodos);
  }

  const completeTodo = index => {
    const newTodos = [...todos];
    newTodos[index].isCompleted = true;
    setTodos(newTodos)
  }

  const deleteTodo = index => {
    const newTodos = [...todos];
    newTodos.splice(index, 1);
    setTodos(newTodos)
  }

  return(
  <div className="app">
   <div className="todo-list">
     {todos.map((todo,index) => 
        <Todo key={index} index={index} todo={todo} completeTodo={completeTodo} deleteTodo={deleteTodo}/> 
      )}
      <TodoForm addTodo={addTodo}/>
   </div>
  </div>)
}

export default App
```
sudoのパーミッションを変更してsudoが使えなくなった

# 経緯
先日、`/usr/bin/sudo`のパーミションを変更してしまったために、sudoが使えなくなりました。
sudoを使用した際のエラーは以下のようになります。

```
sudo: /usr/bin/sudo must be owned by uid 0 and have the setuid bit set
```

経緯としましては、ローカルPCの/usr/bin/以下のとある実行ファイルのパーミッションを変更しようとしたところ、（面倒くさいので） `chmod 777 * -R` を `/user/bin`以下で行ってしまいました。
その中には `/usr/bin/sudo`がおり、こいつは変更してはいけなかったのです。

色々調べて解決を試みましたが、最終的に諦めたので、自戒の念を込めて調べたことを残しておきます。

# 症状
まずバージョンですがUbuntu 18.04を使っていました。
 
```
$ cat /etc/lsb-release 
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=18.04
DISTRIB_CODENAME=bionic
DISTRIB_DESCRIPTION="Ubuntu 18.04.3 LTS"
```

`/etc/usr/sudo` を誤って変更した後には、sudoを利用すると以下のようなエラーがでます。

```
(英語)sudo: /usr/bin/sudo must be owned by uid 0 and have the setuid bit set
(日本語)sudo: 実効 uid が 0 ではありません、sudo は setuid root を設定してインストールされていますか
```

## 修正方法１
１つめの修正方法はrootユーザーでログインしてパーミッションを変更しましょうというものです。
ただし<b>rootユーザーのパスワードが事前に設定されている必要</b>があります。

```
# rootユーザーに変更
su
# 権限変更
chown root:root /usr/bin/sudo
chmod 4755 /usr/bin/sudo
```
残念ながらデフォルトではrootユーザーはパスワードをもっていないので、特別設定してなければsudoなしにrootユーザーになれないかと思います。私もそうでした。

## 修正方法2
修正方法の２つめはリカバリーモードを利用してパーミッションを変更するという方法です。

再起動時にShiftキーかEscキーを押しっぱなしにするとGrabのブートメニューが表示されると思います。
![Selection_950.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81962/c79e98e9-3766-7c2f-17e7-d26daabdc264.png)
この中の `Advanced options for Ubuntu`を選び、その後 `Ubuntu 18.04 (recovery mode)`のようにRecovery Modeを選んで下さい。
そうしたら、別のスクリーンが立ちがりますので、 `Drop to root shell prompt`を選んで下さい。
コマンドラインのスクリーンが現れたと思います。そしたら以下のコマンド打って、パーミッションの変更を行って下さい。

```bash
mount -o remount,rw /
mount –all
chown root:root /usr/bin/sudo
chmod 4755 /usr/bin/sudo
```
最後に`restart`でPCを再起動します。

## 修正方法3
OS再インストール。

筆者はrootユーザーのパスワードを設定してなかったので、修正方法2のリカバリーモードによる解決を試みました。
しかし、再起動時にShiftやEscをいくら押しても、Grubのブートメニューが表示されないという問題にあたりました。
調べてみると、Grabの起動メニューの表示時間が0秒設定されているということがわかりました。
設定箇所は `/etc/default/grab`の中の `GRUB_TIMEOUT`の設定値です。

```bash:/etc/default/grab
...
GRUB_TIMEOUT=0
...
```
Ubuntu 18.04からこの設定がデフォルトのようです(そういえば昔14.04使っているときはブートメニューが毎回表示されていた気がする)。

これのせいで起動メニューが表示されなくなっていますので、この時間設定値を変更するなり、この設定をコメントアウトなりする必要があります。

しかし…このファイルの所有者はrootユーザーなんです。
`sudo`がないと編集できないんです。

詰んだ…

となりました。

泣く泣く諦めて、次回構築時はTIMEOUT設定を3秒にしておくことを誓って、OS再インストールとなりました。


以上
React Hooks useState

```
import React, {useState} from 'react'
import './App.css'

function Todo({todo, index, completeTodo, deleteTodo}){
  return(
    <div style={{textDecoration: todo.isCompleted ? 'line-through' : ''}} className="todo">{todo.text}
    
    <div>
    <button onClick={() => completeTodo(index)}>done</button>
    <button onClick={() => deleteTodo(index)}>done</button>
    </div>
    </div>)
}

function TodoForm({addTodo}){
  const [value, setValue] = useState('');


  const handleSubmit = e => {
    e.preventDefault();
    if(!value) return;
    addTodo(value);
    setValue('');
  }

  return(
    <form onSubmit={handleSubmit}>
      <input 
        type="text" 
        className="input" 
        value={value} 
        placeholder="put text"
        onChange={e =>setValue(e.target.value)}/>
    </form>
  )
}

function App(){
  const [todos, setTodos] = useState([
    {
      text:"helll",
      isCompleted: false
    },
    {
      text:"helll222",
      isCompleted: false
    },
    {
      text:"helll33333",
      isCompleted: false
    },
  ])


  const addTodo = text => {
    const newTodos = [...todos, {text, isCompleted: false}]
    setTodos(newTodos);
  }

  const completeTodo = index => {
    const newTodos = [...todos];
    newTodos[index].isCompleted = true;
    setTodos(newTodos)
  }

  const deleteTodo = index => {
    const newTodos = [...todos];
    newTodos.splice(index, 1);
    setTodos(newTodos)
  }

  return(
  <div className="app">
   <div className="todo-list">
     {todos.map((todo,index) => 
        <Todo key={index} index={index} todo={todo} completeTodo={completeTodo} deleteTodo={deleteTodo}/> 
      )}
      <TodoForm addTodo={addTodo}/>
   </div>
  </div>)
}

export default App
```
Linux & bashで自作コマンドを作成する

# 環境

UbuntuとRaspbianで確認した．

```shell:ubuntuの環境
$ lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 18.04.3 LTS
Release:	18.04
Codename:	bionic
```

```shell:raspbianの環境
$ lsb_release -a
No LSB modules are available.
Distributor ID:	Raspbian
Description:	Raspbian GNU/Linux 10 (buster)
Release:	10
Codename:	buster
```

# 結論

`/usr/local/bin`にスクリプトを追加するか，aliasとして追加する方法がある．

# 方法

ここでは，`/home/user/applications/my-command.py`を実行するコマンド`my-command`を例とする．

## /usr/local/bin

1. `/usr/local/bin`に以下のソースファイル`my-command`を追加する．

    ```shell:/usr/local/bin/my-command
    python3 /home/user/applications/my-command.py
    ```

    `/usr/local/bin`にファイルを追加する際は，rootの権限が必要になる．なお，`/usr/bin`など，他のdirectoryに追加する方法もあるが，Linuxにおいて，自作プログラムは`/usr/local/bin`に追加するように設計されている[^1]ため，`/usr/local/bin`に追加することを推奨する．

[^1]: [Learn Linux Shell Scripting – Fundamentals of Bash 4.4: A comprehensive guide to automating administrative tasks with the Bash shell (English Edition)](https://books.google.co.jp/books?id=Kx2CDwAAQBAJ&pg=PA61&lpg=PA61&dq=usr/bin%E3%80%81/usr/sbin%E3%80%81/usr/local/bin+diifference&source=bl&ots=M9uUg75u-0&sig=ACfU3U3MMwgWJy5gHW7ZvTF9-YeGhrbnpA&hl=ja&sa=X&ved=2ahUKEwiB9Nu0qObkAhWEMt4KHQX_APoQ6AEwB3oECAkQAQ#v=onepage&q=usr%2Fbin%E3%80%81%2Fusr%2Fsbin%E3%80%81%2Fusr%2Flocal%2Fbin%20diifference&f=false)

## aliasを追加する

1. `~/.bash_aliases`に以下のソースコードを追記する．

    ```shell:~/.bash_aliases
    alias my-command='python3 /home/user/applications/my-command.py'
    ```

    このとき，`=`の前後に空白がないように注意すること．

1. `~/.bashrc`を読み込む．

    ```shell:read_bashrc
    source ~/.bashrc
    ```

## 最後に

シェルで`my-command`を実行し，`/home/user/applications/my-command.py`が実行されれば，成功である．

# 両者の違いは何か

## /usr/local/binの特徴

- 自作アプリを作成した際，ソースファイルのコピーと削除のみで，アプリのインストールとアンインストールを容易に自動化することができる．
- 他のuserも利用できる．

## aliasへの追加の特徴

- User Directoryの中にあるため，rootの権限が不要である．
- 自作アプリのインストールとアンインストールの際，ファイルの編集を行わなければならないため，多少複雑である．また，これを自動化する際，`sed`コマンドを利用すれば良いが，パスの指定の際，`/`が特殊文字であることから，代わりに`\/`を使用しなければならならず，これの変換が多少複雑である．
- 他のuserは利用できない．
REVERSED_CLIENT_IDの取得方法

#GoogleService-Info.plistにある

iOS で Google ログインを使用して認証する場合などに必要となる**「REVERSED_CLIENT_ID」**

こういうのって、どこで確認すればいいかど忘れしたり、わからなかったりするものだ。

独自に発行されるものやから、コピペとかできないし。。。

このREVERSED_CLIENT_IDの確認方法は、GoogleService-Info.plistを見ればいい。

<img width="330" alt="スクリーンショット 2019-09-23 18.29.17.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/f209eb1a-bba0-689f-040c-3799caf18bc7.jpeg">

REVERSED_CLIENT_IDは**「com.googleusercontent.apps.YourREVERSED_CLIENT_ID」**みたいな感じ。

#GoogleService-Info.plistとは？

FirebaseのプロジェクトにiOSを追加すれば、勝手に作られるあれ。
ダウンロードするだけ。

<img width="719" alt="スクリーンショット 2019-09-23 18.34.46.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/8b526d90-0eba-4131-0d66-bb1620a004e2.jpeg">
GoogleスプレッドシートのWin版とAndroid版の違い

##環境
2019年5月版?(wikipediaより)
##画面
(参考)Win版の画面例
https://dekiru.net/article/17232/

(参考)Android版の画面例
【スマホ】Googleスプレッドシートの使い方を解説！＞ボタンから挿入
https://appli-world.jp/posts/5861

#Win版とAndroid版の共通編
###ctrl+↓ キー
(参考)Google Apps ScriptでGoogleスプレッドシートを開いたときに利用するセルに移動
https://usortblog.com/google-apps-script-onopen/

###「Ctrl」+「D」キー
(参考)Googleお役立ちテクニック - Googleスプレッドシートの「コピー」を便利に使う
https://news.mynavi.jp/article/20170731-google-tips103/

###Ctrl+;
(参考)Google スプレッドシートで”Ctrl+;”で「現在の日付を挿入」が使えない？と思ったら
http://loadpiece.xyz/blog/google-%e3%82%b9%e3%83%97%e3%83%ac%e3%83%83%e3%83%89%e3%82%b7%e3%83%bc%e3%83%88%e3%81%a7ctr%e3%81%a7%e3%80%8c%e7%8f%be%e5%9c%a8%e3%81%ae%e6%97%a5%e4%bb%98%e3%82%92%e6%8c%bf%e5%85%a5%e3%80%8d/

(参考)Is there any way to create a timestamp in a Google Spreadsheet?
https://webapps.stackexchange.com/questions/4056/is-there-any-way-to-create-a-timestamp-in-a-google-spreadsheet


#Win版


###コメントいろいろ
これがでても大丈夫でした。
「
Internet Explorer
Internet Explorer は動作を停止しました
問題の解決策をオンラインで確認できます。
オンラインで解決策を確認してプログラムを終了します
プログラムを終了します
問題の詳細の表示
」
「
Chrome に切り替えよう
わずらわしい広告を表示せず、ウェブ上の不正なソフトウェアをシャットアウト
切り替えない 切り替える
」
「
頻繁に開いたドキュメント
」
「
xxx Google スプレッドシート この曜日のこの時間帯に開くことが多いファイル
」
「
マイドライブ - Google ドライブ タブ グループ 1
xxx - Google スプレッドシート#gid=xxxxxxxxxx タブ グループ 1
」
「
この Web ページに問題があるため、Internet Explorer のタブを開き直しました
」

#Android版


#補足1:｢doc.new｣などのアドレスで、新規Googleドキュメントやスプレッドシートが作成できるってよ
https://www.gizmodo.jp/2018/10/google-drive-dot-new-urls.html

#補足2:タブレット・スマホ用の雑貨・日用品
姿勢が悪くなります。疲れます。でも便利。
(参考)キャンドゥ「マルチホルダースタンド」が便利すぎる！ パリジェンヌも驚く多変化ぶりとは?
https://getnavi.jp/zakka/249527/
MacでNodeGUIを動かそうとしたがnpm installでエラーになったのでググった

こちらのリンクを読んで、NodeGUIを動かしてみたいと思いましたが、エラーになって解消したので投稿しました

- [🐕 Announcing NodeGUI and React NodeGUI - Build native desktop apps with Javascript and CSS 🎉](https://blog.atulr.com/nodegui-intro/)

参考リンクによると、この手順のみで簡単にサンプルを起動起動できるとあったのですが、

```bash
git clone https://github.com/nodegui/nodegui-starter
cd nodegui-starter
npm install
npm run build
npm start
```

`npm install`の部分でエラーになってしまいました

```console
$ npm install

> @nodegui/qode@1.0.5 postinstall /Users/kengookumura/dev/tmp/nodegui/nodegui-starter/node_modules/@nodegui/qode
> node install.js

Local Qode 1.0.5 archive doesnt exists... Copying Qode from cache...
Extracting binaries...

> @nodegui/nodegui@0.2.1 postinstall /Users/kengookumura/dev/tmp/nodegui/nodegui-starter/node_modules/@nodegui/nodegui
> npm run build:addon


> @nodegui/nodegui@0.2.1 build:addon /Users/kengookumura/dev/tmp/nodegui/nodegui-starter/node_modules/@nodegui/nodegui
> cross-env CMAKE_BUILD_PARALLEL_LEVEL=8 cmake-js compile

[
  '/usr/local/Cellar/node/12.8.1/bin/node',
  '/Users/kengookumura/dev/tmp/nodegui/nodegui-starter/node_modules/.bin/cmake-js',
  'compile'
]
info TOOL Using Unix Makefiles generator.
info REP Build has been failed, trying to do a full rebuild.
ERR! OMG CMake executable is not found. Please use your system's package manager to install it, or you can get installers from there: http://cmake.org.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! @nodegui/nodegui@0.2.1 build:addon: `cross-env CMAKE_BUILD_PARALLEL_LEVEL=8 cmake-js compile`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the @nodegui/nodegui@0.2.1 build:addon script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm WARN Local package.json exists, but node_modules missing, did you mean to install?

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/kengookumura/.npm/_logs/2019-09-23T06_00_56_266Z-debug.log
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! @nodegui/nodegui@0.2.1 postinstall: `npm run build:addon`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the @nodegui/nodegui@0.2.1 postinstall script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/kengookumura/.npm/_logs/2019-09-23T06_00_56_858Z-debug.log
```

エラーを見るとCMakeの実行可能ファイルが見つかりませんといった内容なのなので、ググってみて以下が関係ありそうだったので試してみましたm(_ _)m

[C++初心者がMacでCMakeを利用してみる - Qiita](https://qiita.com/kai_kou/items/df335eb7ee78229ee46f)

```bash
$ brew install cmake
```

これで`npm install` を実行すると無事に正常終了しました

あとはこちらを実行すると、

```bash
npm run build
npm start
```

nodegui-starterのサンプルのアプリを起動することができました。

![Screen Shot 2019-09-23 at 15.22.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142910/5cc61cf3-b928-0a51-426d-67485599cd2f.png)

---

バージョン

- macOS Mojave 10.14.6
- node 12.8.1

---

以上です。失礼しました。m(_ _)m
シフト演算とは

#シフト演算とは
プログラミングをしている際にシフト演算とか出てきたのでそれを理解するための知識

##２進数について
2進数とは`0と1のみで数字を表したもの`である
普段使っている数は１０進数であり、9まで来ると次の位が１つ増える。（=10で繰り上がる）
例）9→10(２桁目が１になる)

つまり、
●●進数の●●の部分の数で繰り上がるということ。

では２進数では、
`2で繰り上がる（=1まで来ると次の位が１増える）`
10進数の２を２進数で表すと10となる。

```
10
 ↑
１つ目の位は1までしか入れないので２となると次の位が繰り上がり１となる
```

##符号付き２進数について
実はこの２進数にも`符号付き`と`符号無し`がある
<img width="361" alt="符号つき２進数.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178136/87855ac3-9297-df42-386a-34b76f1bd146.png">
([符号つき２進数](http://www.infonet.co.jp/ueyama/ip/binary/signedbin.html)より)

図のように符号付きの場合、一番高い位が0か1で符号が変わる。
（最上位の位がマイナスを表しているが他の位はプラスなので注意！）

つまり**符号無し**では0~256の数字が表せて、**符号あり**では-128~127が表せます。
<img width="607" alt="符号つき２進数.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178136/f58b54fb-08cf-5926-29b3-cd93cfabd093.png">
([符号つき２進数](http://www.infonet.co.jp/ueyama/ip/binary/signedbin.html)より)

#### 10000000→-128になるの？
符号付きの場合最上位の位が１であればマイナス。
今回は8桁のため、 2の8乗で128。
にマイナスをつける。

#### 11111111→-1になるの？
上記より符号付き２進数では`10000000=-128`。
最上位以降の位は1111111は全て１なので+127。
（最上位の位がマイナスを表しているが他の位はプラスなので注意！）
-128+127=-1。

##いざシフト演算
シフト演算には２種類あります。

- 論理シフト(符号なし)
- 算術シフト(符号付き)

###論理シフト
`符号無し`について行うときに使う。
`２進数を{左or右}にN個論理シフトする`と使いN個{左or右}にずらすことをいう。

↓左に2個論理シフト
<img width="683" alt="シフト演算.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178136/0730ff81-90e5-3662-a174-10d3c2298e2f.png">
([シフト演算](http://kccn.konan-u.ac.jp/information/cs/cyber03/cy3_shc.htm)より)

これは元の数を2のN乗することに相当。
（右は逆）

### 算術シフト
`符号付き`について行うときに使う。
`２進数を{左or右}にN個算術シフトする`と使いN個{左or右}にずらすことをいう。

↓右に2個算術シフト
<img width="648" alt="シフト演算.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178136/142aa9a7-5a4b-e28c-3477-d182d6930105.png">
([シフト演算](http://kccn.konan-u.ac.jp/information/cs/cyber03/cy3_shc.htm)より)



なるほどです。

#参考にしたサイト
ありがとうございました。
[符号つき２進数](http://www.infonet.co.jp/ueyama/ip/binary/signedbin.html)
[シフト演算](http://kccn.konan-u.ac.jp/information/cs/cyber03/cy3_shc.htm)
スマホ(Googleスプレッドシート)で、家計簿単品管理をしたい

#概要
スマホ(Googleスプレッドシート)で、家計簿単品管理をしたい。

#環境
freewifiで、できないと思います。

家計簿単品管理の部分は、別にスマホが、なくてもできます。
PC版の　　、Excelだけでも、Googleスプレッドシートだけでもできます。
スマホ版の、Excelだけでも、Googleスプレッドシートだけでもできます。
zaimのIDがなくてもいい。
zaimのIDがあると、いいような気がする。(zaimについて、APIについて勉強中)

#要約
外税・内税を考慮したい。(関数を使う。)
消費税8%,10%も考慮したい。(現在8%のみ、10%は未完成)
zaimも使ってみたい。(csvにして、ダウンロードアップロードします。)
WindowsExcelVBAでも計算可
バージョンアップを考慮して,消費税計算に正規表現を使っています。

#入力方法
画像があるといいですが、まだ作っていません
###1行目
＜A列＞日付
＜B列＞方法
＜C列＞カテゴリ
＜D列＞カテゴリの内訳
＜E列＞支払元
＜F列＞入金先
＜G列＞品目
＜H列＞メモ
＜I列＞お店
＜J列＞通貨
＜K列＞収入
＜L列＞支出
＜M列＞振替
＜N列＞残高調整
＜O列＞通貨変換前の金額
＜P列＞集計の設定

###L列目2行目の計算式例
####Googleスプレッドシートの場合
=round( IF(ISERROR(search("外税",H2)),REGEXEXTRACT(H2,"\d+"),REGEXEXTRACT(H2,"\d+")*108/100))
####おまけ:ExcelVBAの場合
=ROUND((IF(ISERROR(SEARCH("外税",H2)),REGEXP(H2,"\d+")      ,REGEXP(H2,"\d+")      *108/100)),0)

###CSV形式の例

```
日付,方法,カテゴリ,カテゴリの内訳,支払元,入金先,品目,メモ,お店,通貨,収入,支出,振替,残高調整,通貨変換前の金額,集計の
設定
2019/8/1,payment,食費,その他,クレジットカード,-,烏龍茶 525ml サントリー,外税:78,スーパー,（プレミアム会員で表
示）,0,84,（プレミアム会員で表示）,（プレミアム会員で表示）,（プレミアム会員で表示）,（プレミアム会員で表示）
2019/8/3,payment,食費,食料品,クレジットカード,-,烏龍茶 525ml サントリー,内税:150,コンビニ,（プレミアム会員で表
示）,0,150,（プレミアム会員で表示）,（プレミアム会員で表示）,（プレミアム会員で表示）,（プレミアム会員で表示）
```
84と150の位置に計算式を入れます。

#実行手順
日付とメモとお店欄を、入力する。
H列メモ欄(例)「外税：78」「内税：150」を入力して,L列支出は計算式で計算する。
入力が増えてきたら、日付以外、コピー操作だけでいける気がする。

繰り返し
1.Googleスプレッドシート（又はExcelシート）に入力する。

　zaimのIDがあれば、以下が使えるはずです。
2.csvにする。
3.zaimデータをリセットする。(注意：データは全部消えます。)
4.zaimにcsvファイルをアップロードする。




#入力の小技
品目入力の場合、AM○○ONで品目名を検索して、文字コピーする。
会社名と商品名の順を逆にしています。

#注意
Windows7で作業中でました
【偽警告】お使いのWindows10は5つのウイルスに感染しています！

win explorer 閲覧の履歴
レ 終了時に閲覧の履歴を削除する(W)
していたのに、でました。

#バージョンアップ予定
レシートをみて、いずれ時刻も入力したい。
スマホで、時刻登録できるかもしれない。
軽減税率？に対応したい。
小数点第2位？に対応したい。

#参考
(参考)エクセルでfindを使用した時に見つからないとエラーを回避する一般的な方法です。
https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q117434416

(参考)REGEXEXTRACT - ドキュメント エディタ ヘルプ - Google Support
https://support.google.com/docs/answer/3098244?hl=ja

(参考)Excelのワークシート関数で正規表現を使う
https://qiita.com/ktyubeshi/items/74228f18498224c7427d

#勉強中
(参考)お金が貯められる毎月の家計簿のつけ方の記入例
https://kakeibo.kosodate-info.com/archives/811

(参考)家計簿の出費項目にカテゴリを付けるのを自動化する
https://qiita.com/chase0213/items/2a99824963125562645c
plunkerでvue その30

#概要

plunkerでvueやってみた。
apexcharts使ってみた。

#成果物

https://embed.plnkr.co/IwH2bpbTBQFBF54UkK8s/

https://embed.plnkr.co/2bRMV2R86KqnvYPQJLlj/

https://embed.plnkr.co/HlVdREbmd8ZhK5mvZWRZ/

以上。
【Go】ポインタの基本

[こちらの記事](https://qiita.com/Sekky0905/items/447efa04a95e3fec217f)を参考に、Goにおけるポインタらへんについて雑にまとめます。

```go:
package main

import "fmt"

//変数nameはstring型と宣言
var name string

func main() {

	name = "aoki"
	//変数name_addressはnameのポインタ型と暗黙的に宣言
	name_address := &name
	fmt.Printf("%+v\n", name_address) //ポインタ変数を表示
	fmt.Printf("%+v\n", *name_address) //そのアドレスに入っている値を表示
}
```
実行結果

```
0x117a250
aoki
```

```go:
package main

import "fmt"

//変数nameはstring型と宣言
var name string

func main() {
	name = "aoki"
	name2 := name
	name2 = "tanaka"
	fmt.Printf("%+v\n", name2)
	fmt.Printf("%+v\n", name) //nameの値は変わらない

	name3 := &name
	*name3 = "nishimura"
	fmt.Printf("%+v\n", name3)
	fmt.Printf("%+v\n", *name3)
	fmt.Printf("%+v\n", name) //同じアドレスなので、nameの値は変わる
}
```
実行結果

```
tanaka
aoki
0x117a250
nishimura
nishimura
```
【Python】ABC - 097 - Exponential

#　問題
与えられた数字$X$以下で最大となるべき乗数を求める問題。べき乗数は1以上の整数$b$と2以上の整数$p$を使って$b^p$とかける整数のことを指す。

# 方針
基本的には、$X$以下の範囲の中で、$bとp$を全探索する方針は立ったが、あまり深く考えずに$bとp$をそれぞれ$X$まで探索したところTLEに。。。
ちゃんと証明する必要があると思うが、$\sqrt　X$付近までの探索で十分だろうと判断して18msでAC。

```python
import math
X = int(input())
res = 0
for b in range(1, int(math.sqrt(X))+1): # sqrt(X)付近まで探索
    for p in range(2, int(math.sqrt(X))+2): # sqrt(X)付近まで探索
        val = b**p
        if (val <= X) and (val > res): # X以下かつその値が最大値なら値を更新
            res = val
print(res)
```

# 追記
@konandoiruasa にコメントいただきましたので、$b,p$の範囲に関して追記する。

$bはp$が2のときが最大になるので、$1 \leq b  \leq \sqrt X$となる。

$p$は$X \geq b^p$を満たせば良いので、

```math
X \geq b^p \\
\log X \geq p \log b \\
\therefore p \leq \frac{\log X}{\log b}
```
となる。
pythonで小数型を整数型に変換したい

#やりたいこと
以下を実行すると

```
[in]
import numpy as np
print(np.logspace(0, 3, 4))
print(type(np.logspace(0, 3, 4)[0]))
```
以下のように、float64型になってしまうが、整数型に変換したい。

```
[out]
[   1.   10.  100. 1000.]
<class 'numpy.float64'>
```


#動作環境
jupyter Lab
Python3.6
numpy

#方法
追記。1つ目。

```
[in]
x = np.logspace(0, 3, 4, dtype=int)
print(x)
print(type(x[0]))

[out]
[   1   10  100 1000]
<class 'numpy.int64'>
```
コメントありがとうございます。

2つ目。numpy.arrayオブジェクトを利用して、第２引数にdtype=intと指定する方法。１つ目のやり方でやりましょう。

```
[in]
x = np.array(np.logspace(0, 3, 4), dtype=int)
print(x)
print(type(x[0]))

[out]
[   1   10  100 1000]
<class 'numpy.int64'>
```

3つ目。astypeをメソッドチェインで利用する。１つ目のやり方やりましょう。

```
[in]
y = np.logspace(0, 3, 4).astype(np.int64)
print(y)
print(type(y[0]))
[out]
[   1   10  100 1000]
<class 'numpy.int64'>
```

# そもそもの発端
以下のエラーが出たので、解決するために以上の方法を行った。

```
ValueError: n_estimators must be an integer, got <class 'numpy.float64'>.
```
Go言語でFintechアプリを作成してみる。

今回はUdemyを使って、Go言語でFintechアプリを作成してみました。
私は独学で勉強している初学者ですが、
同じような立場の方にも大変分かりやすく解説してくれています。

使用動画：
**現役シリコンバレーエンジニアが教えるGo入門＋応用でビットコインのシストレFintechアプリの開発**

Macの環境設定の仕方から、
初歩的なHelloWorldの表示の仕方であったり
基本的な書き方を例文を交えながらGO言語の基礎もしっかり学べます。

書籍も沢山買いましたが、
初めからこの講座を受けておけばよかったなぁと思ったくらいです！

ちなみに講座内では**Goland**というIDEを使用されてますが、
私は前から使っていたVScodeを使用しております。


基礎の講座が終わったら、
使用動画の題名でもあるビットコインのシストレFintechアプリの開発を実際にしてみます。

TickerAPIを作成して、実際にビットコインのデータを取得してみたり、
実際にキャンドルチャートを表示してみたり、

![スクリーンショット 2019-09-23 13.33.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378334/c70b1933-3407-7a42-aa0d-149ddf7e7c03.png)

自分のPC上でも表示できるようになると作っている感があり、
大変初歩的なことかもしれませんが感動しました。

バックエンド側だけではなくフロントエンド側もやっていくので、
JQueryやAjaxの対応も学べます。

また、今回仮想通貨が題材なので、
仮想通貨の歴史なども解説してくださるので
プログラミングの知識だけではなく仮想通貨の予備知識もつきます。

最終的にはもっと複雑なチャートが作れるようになります。

![スクリーンショット 2019-09-23 14.37.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378334/07e210d3-48d9-8d3a-0d33-316421e60cb9.png)

今回の講座を通して基礎知識がまだまだ頭に入っていないなと思ったので、
復習で基礎の部分を何度も実際に手を動かしながらチャレンジしていきたいと思います。

Udemyの今回記載した動画、とても分かりやすく
（めちゃくちゃ絶賛してますが回し者ではないです。笑）
初学者の私にも入りやすかったので同じような方でも入りやすいと思います。
社内向けathensの構築と0.6.0時点の問題

# 社内向けにathensを構築する

## athens

go1.13で`GOPROXY`環境変数のデフォルトが`proxy.golang.org`を向くようになりました。そのため会社などでプライベートなリポジトリを使っている場合、最初の一発目を`proxy.golang.org`に取りにいってしまいます。単純に無駄なリクエストなのと、社内開発のリポジトリ名が漏洩するという意味でもあまりよろしくありません。

これを防ぐには`GOPRIVATE`環境変数にリポジトリ名を書いておけばいいのですが、それだとModules Mirrorの恩恵に預かれなくなってしまうため、折角なので社内向けにproxyサーバーである[athens](https://docs.gomods.io/)を立ててみます。

## Helmによる構築

athensはドキュメントがかなり充実しており、基本的には[公式の手順](https://docs.gomods.io/install/)に従うだけで構築できます。

kubernetesの環境があれば[Helm chart](https://helm.sh/)による構築が一番楽そうなので、今回はこちらを使っていきます。

### ストレージ

athensはパッケージをキャッシュするためのストレージを以下の中から選ぶことができます。
https://docs.gomods.io/configuration/storage/

- memory
- disk
- mongo
- Google Cloud Storage
- AWS S3
- Minio

各々の環境次第で好きなものを選べばいいと思いますが、今回は試しという意味でも運用が容易な`disk`を使っていきます。

### 構築

まずは`override.yaml`という名前で設定ファイルを作成します。設定可能な値はドキュメントをあさるか、[chartの元ファイル](https://github.com/gomods/athens/blob/master/charts/athens-proxy/values.yaml) を見るのがいいと思います。

```yaml
storage:
  type: disk
  disk:
    persistence:
      enabled: true
      accessMode: ReadWriteOnce
      size: 4Gi
ingress:
  enabled: true
  hosts:
  - go-proxy.sample.com
service:
  type: NodePort
replicaCount: 2
configEnvVars:
  - name: ATHENS_GONOSUM_PATTERNS
    value: private.git.com/*
```

設定ファイルを作成したら、あとは以下のようにHelmでサクッと構築しましょう。helmの環境構築などは省いています。

```bash
helm repo add gomods https://athens.blob.core.windows.net/charts
helm repo update
helm install gomods/athens-proxy -n athens -f override.yaml
```

`go-proxy.sample.com`にアクセスして、`"Welcome to The Athens Proxy"`が表示されれば成功です。

## 使ってみる

試しに手元で`GOPROXY=https://go-proxy.sample.com`を設定して、`go mod download`や`go get`してみましょう。

```bash
export GOPROXY=https://go-proxy.sample.com
go get golang.org/x/tools/cmd/goimports
```

`storage=disk`の場合、athensはデフォルトで`/var/lib/athens`以下にパッケージをキャッシュします。試しにコンテナに入り、`/var/lib/athens`を覗くと、`goimports`がキャッシュされているのが分かると思います。

## v0.6.0 時点での問題点

ここまで書いておいてあれですが、実はathens v0.6.0時点では不具合でプライベートリポジトリを落としてくることができません。

https://github.com/gomods/athens/issues/1390

athensはパッケージをリクエストされた際、内部的にはただ`go mod download`を自分で叩いているため、`GONOSUMDB`などを設定しないとプライベートリポジトリのchecksumに失敗してしまいます。
そのため`ATHENS_GONOSUM_PATTERNS`に自分のプライベートリポジトリを指定する必要がありますが、不具合でこの環境変数の内容が`go mod download`に渡されていないため、現状うまくいかないようです。

ただ修正は既に行われているので、次回のリリースでは直っていそうです。
Python 日付の2進数変換

#問題
年月日をYYYYMMDDの8けたの整数で表したとき、
これを2進数に変換して逆から並べ、
さらに10進数に戻したとき、
元の日付を同じ日付になるものを探してください。
期間は、前回の東京オリンピック（1964年10月10日）から、
次回の東京オリンピック（2020年7月24日予定）とします。

**例）1966年7月13日の場合**
1. YYYYMMDDのフォーマット -> 19660713
2. 2進数に変換 -> 100101011111111110101001
3. 2進数を逆か並べる -> 1001010111111111110101001
4. 逆から並べた2進数を10進数に戻す -> 19660713
　　　　　　　　　　　　　　　　**・・・1966年7月13日（最初の数）に戻る**

>引用：「プログラマ脳を鍛える数学パズル　著者 増井 敏克」

#回答

```answer.py
from datetime import datetime
from datetime import timedelta

from_date = datetime(1964, 10, 10)
to_date = datetime(2020, 7, 24)

def return_reversed_number(n):
    binary_date = format(int(n.strftime("%Y%m%d")), "b")
    reversed_number = int(binary_date[::-1], 2)
    return reversed_number

def daterange(_from, _to):
    for i in range((_to - _from).days):
        yield _from + timedelta(i)


for j in daterange(from_date, to_date):
    if int(j.strftime("%Y%m%d")) == return_reversed_number(j):
        print(j)
    else:
        pass

```

#つまづいたところ
10進数、2進数の相互変換は過去に触れましたので、
今回は特につまづきはしませんでした。

何日から（from）何日まで（to）の期間を取得する方法は初め考えましたが、
ググってみると簡単に出てきたのでそのままコピペでいけました。

逆順も`[::-1]`で簡単にいけました。
便利ですねー`[::-1]`

本書ではさらに検索する範囲を絞り、
処理速度を速めた方法も紹介しています。
しかし、それだと求める期間が変更になったときの拡張性が乏しいみたいです。
なので検索する範囲を絞らない方法の方でPythonに書き換えています。

つまづいたといえば、
前回の更新日から１ヶ月経ってしまったところでしょうか・・・
SQLの種類 備忘録


#はじめに

社外研修がDBの内容に入りました。
自分の復習用にまとめたいと思います。

研修で使用しているDBは、
OracleDB 11g Express Editionです。

##SQLの種類

###DDL (データ定義言語)
Database Definition Language の略。
Definitionは定義という意味。
データを格納する入れ物であるDBやテーブルなどを作成や削除するために使用する


■ CREATE
データベースやテーブルなどを作成する


列制約　テーブル作成文

``` 
CREATE TABLE samp(
 samp_id   VARCHAR2(10) PRIMARY KEY,
 samp_name VARCHAR2(10) NOT NULL,
 tel       VARCHAR2(10) UNIQUE,
 age       NUMBER(2),
 dept_id   CHAR(2) PEFERENCES dept(dept_id)
);
```
■ DROP
データベースやテーブルなどを削除する

テーブルの削除

```
DROP TABLE samp;
```

■ ALTER
データベースやテーブルなどをの構成を変更する

列の追加

```
ALTER TABLE samp ADD temp_id VARACHAR2(500);
```



###DML (データ操作言語)
Data Manipulation Language の略。
Manipulationは操作という意味。

テーブルの行を検索や変更するために使用する

■ SELECT
テーブルからレコードを検索する

全ての列を出力

```
SELECT *
FROM samp;
```

■ INSERT
テーブルに新しいレコードを登録する

列の挿入

```
INSERT INTO samp(samp_id, samp_name, tel, age, dept_id) VALUES(1,"noname",xxxxxxxxxxx,20,1);
COMMIT;
```

※COMMITを忘れると挿入されない。
■ UPDATE
テーブルのレコードを更新する

samp_id行を全部777に変更

```
UPDATE samp SET samp_id = 777;
COMMIT;
```

■ DELETE
テーブルのレコードを削除する

指定した全レコードの削除

```
DELETE FROM samp;
```


###DCL (データ制御言語)
Data Control Language の略。
Controlは制御という意味。

データベースに対して行った変更内容の確定と取消、
または、RDBMSのユーザの権限の設定も行う

■ COMMIT
データベースに対して行った変更を確定する


```
COMMIT;
```

■ ROLLBACK
データベースに対して行った変更を取り消す

トランザクションの取

消

```
ROLLBACK;
```

■ GRANT
ユーザに操作の権限を与える

ユーザ(USERNAME)にSELECT ANY DICTIONARY以外の権限を付与

```
GRANT ALL PRIVILEGES TO USERNAME;
```

■ REVOKE
ユーザから操作の権限を奪う

全ての権限の削除

```
REVOKE ALL PRIVILEGES FROM USERNAME;
```

#おわりに

SQLは、インフラ時代に使ってましたが上記の分類などは知らなかったのでまとめてみました。

トランザクションで自動的にコミットされるDDLとコミットされないDMLなど
体系的に覚えて使いこなせたらと思います。

誤記等があればご指摘頂けるとありがたいです。
Vue.jsで株価チャートを表示する良さげなツールを紹介(APEXCHARTS)

##APEXCHARTS

以前の記事[[GolangとDBを接続して株価データをチャート表示する]](https://qiita.com/_kyamasan/items/a105cd97269feea7a30a)では、GoogleChartsを利用してチャート表示しましたが、最近Vueを勉強していて、APEXCHARTSという良さげなツールを見つけたので共有します。

(以下では、Vueでの実装方法について説明しますが、普通のjavascriptでもReactでも使えるので、詳しく知りたい方はAPEXCHARTSのホームページで調べてみてください。)

[APEXCHARTS](https://apexcharts.com/vue-chart-demos/)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/466621/492aafdd-50ec-f6d7-f5d0-26b4f4af5206.png)

今回は、DEMOにもあるCandleStickを使って実装していきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/466621/46174b13-3b57-01b4-1c25-02a8479addda.png)

今回はBasic版を採用します。

##準備

DEMOサイトでは細かい実装方法は載っていないので、APEXCHARTSの[Github](https://github.com/apexcharts/vue-apexcharts)を参考にしました。

##npm

npm install --save apexcharts


##ソース

```HelloWorld.vue
<template>
  <div>
    <apexchart width="1500" type="candlestick" :options="chartOptions" :series="series"></apexchart>
  </div>
</template>

<script>
import ApexCharts from 'apexcharts'

export default {
  data: function() {
    return {
      chartOptions: {
        title: {
          text: 'CandleStick Chart',
          align: 'left'
        },
        xaxis: {
          type: 'datetime'
        },
        yaxis: {
          tooltip: {
            enabled: true
          }
        }
      },
      
      series: [{
        data: [{
            "x": "2019-04-02",
            "y": [6629.81, 6650.5, 6623.04, 6633.33]
          },
          {
            "x": "2019-04-03",
            "y": [6632.01, 6643.59, 6620, 6630.11]
          },
          {
            "x": "2019-04-04",
            "y": [6630.71, 6648.95, 6623.34, 6635.65]
          },
        ]
      }],
    }
  },
};
</script>
```

data>series>dataの中身にjsonでxに日付、yに[始値,高値,安値,終値]をセットするだけで割としっかりしたチャートが表示できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/466621/5831618f-7dbd-4be1-62f1-2a369a13724f.png)

今回は紹介ということであまり実践的なソースではなかったので、次の記事ではGoで構築したWebサーバから株価データのjsonを渡す方法について、解説します。