OmniAICreator/Qiita-1.07M huggingface dataset:
Cloud FunctionsのPython Runtimeを使ってPOSTされたJSONをそのまま返すだけの関数を実装する

## 公式ドキュメント

例によって英語じゃないと情報が古い (Pythonランタイムについて書かれていない) のでリンクは英語です。

- [quickstart](https://cloud.google.com/functions/docs/quickstart?hl=en)
    - Cloud Functionsクイックスタート
- [The Python Runtime](https://cloud.google.com/functions/docs/concepts/python-runtime?hl=en)
    - Python Runtimeについての詳細な説明
- [HTTP Functions](https://cloud.google.com/functions/docs/writing/http?hl=en)
    - CORSまわりの設定など

プロジェクトを作成して、Google Cloud SDKの認証を済ますところまでは、よくある話なので省略します。

## 手順

適当にプロジェクトを作る (ここでは `gcf_parrot` とした)。[^1]

[^1]: Google Cloud Functionsでオウム返しする関数なので `gcf_parrot` というだけでとくに意味はない。

```bash
mkdir gcf_parrot
cd gcf_parrot
touch main.py
```

main.pyをいい感じに編集する。
ちなみに `type(request)` は `werkzeug.local.LocalProxy` です。
返り値は `(json文字列, レスポンスコード, ヘッダー)` です。


```python:main.py
import json


def generate_exp_design(request):
    param_dict = request.get_json()
    return (json.dumps(param_dict), 200, {})
```

↓[公式ドキュメント](https://cloud.google.com/functions/docs/writing/http?hl=en#handling_cors_requests)を参考にCORS設定したものはこちら。[^2]

[^2]: 別ドメインからAPIを叩こうとすると `No 'Access-Control-Allow-Origin' header is present on the requested resource.` と怒られる。この場合はCORSを有効にしておく必要がある。

```python:main.py
import json


def generate_exp_design(request):
    # preflight request時
    if request.method == 'OPTIONS':
        headers = {
            'Access-Control-Allow-Origin': '*',
            'Access-Control-Allow-Methods': 'POST',
            'Access-Control-Allow-Headers': 'Content-Type',
            'Access-Control-Max-Age': '3600',
        }
        return ('', 204, headers)

    # main request時
    param_dict = request.get_json()
    headers = {
        'Access-Control-Allow-Origin': '*',
    }
    return (json.dumps(param_dict), 200, headers)
```

アップロードする。1行目のupdateとinstallは初回のみでOK。

```bash
gcloud components update && gcloud components install beta
cd path/to/gcf_parrot
gcloud functions deploy parrot --runtime python37 --trigger-http
```

できたと思ったら叩いてみる。

```bash
curl -H 'Content-Type: application/json' -d '{"foo":"bar","x":[1,2,3]}' https://~~~
```

`{"foo": "bar", "x": [1, 2, 3]}` が返ってきたら成功。

## 余談

### axiosで呼ぶ

これがやりたかったんだ…。

```javascript
axios.post('https://~~~', {
  foo: "bar",
  x: [1, 2, 3],
}, {
  'Content-Type': 'application/json'
}).then(
  (res) => {
    console.log(res.data);
  }
);
```

### その他

- Flaskが全部いい感じにやってくれるとの噂もあるが試してない
- `gcf_parrot` ディレクトリにrequirements.txtを置けば色々ライブラリも用意してくれる
- curlを叩かなくてもGCPのコンソールからもテストできる
#python で #Twitter #API を叩き、日本時間基準で、昨日のまとめを #Markdown で作る例

#python で #Twitter #API を叩き、日本時間基準で、昨日のまとめを #Markdown で作る例

# Script

なんだか1時間ぐらいズレている気もする

```py
# https://developer.twitter.com/en/docs/tweets/timelines/api-reference/get-statuses-user_timeline.html

import json, config, os, re
from requests_oauthlib import OAuth1Session
import time
import datetime
from datetime import timedelta
 
CK = config.CONSUMER_KEY
CS = config.CONSUMER_SECRET
AT = config.ACCESS_TOKEN
ATS = config.ACCESS_TOKEN_SECRET
twitter = OAuth1Session(CK, CS, AT, ATS)

url = "https://api.twitter.com/1.1/statuses/user_timeline.json"

params ={
  'count' : os.environ.get('COUNT') or 1000,
  'trim_user' : True,
  'exclude_replies' : True,
  'tweet_mode' : 'extended'

}
res = twitter.get(url, params = params)

if res.status_code != 200:  
    print("Failed: %d" % res.status_code)
    exit()

def convert_datetime(datetime_str):
  tweet_time = time.strptime(datetime_str,'%a %b %d %H:%M:%S +0000 %Y')

  tweet_datetime = datetime.datetime(*tweet_time[:6])
  return(tweet_datetime)

def in_jst_yesterday(tweet_datetime):
  today_beggining_of_day = \
    datetime.datetime.utcnow() \
    .replace(hour=0, minute=0, second=0, microsecond=0) \
    - timedelta(hours=9)

  yesterday_beggining_of_day = \
    today_beggining_of_day \
    - timedelta(days=1)

  if today_beggining_of_day > tweet_datetime >= yesterday_beggining_of_day:
    return True

timelines = json.loads(res.text)

results = []

for line in timelines:
    tweet_datetime = convert_datetime(line['created_at'])

    if not in_jst_yesterday(tweet_datetime):
      continue

    text = re.sub(r'https://t\.co/\w+', '' ,line['full_text'])
    text = re.sub(r'#', '' , text)
    
    text = '# ' + text
    text += "\n" + '<a href="https://twitter.com/YumaInaura/status/' + str(line['id']) + '">' + line['created_at'] + '</a>'
    if 'media' in line['entities'].keys():
      for media in line['entities']['media']:
        text += "\n"
        text += "![image]("+media['media_url_https']+')'
    text += "\n"

    results.append(text)

results.reverse()

for result in results:
  print(result)
```


# REf

[PythonでTwitter API を利用していろいろ遊んでみる - Qiita](https://qiita.com/bakira/items/00743d10ec42993f85eb)

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/581








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
unityで音を鳴らす

unityで音をならす手順を勉強したのでメモしておきます。

参考にしたのは以下のサイト
https://increment-log.com/unity-sound-se-play/
https://qiita.com/2dgames_jp/items/b3d7d204895d67742d0c

unityでは
- 音の発信源であるAudio Source
- 音を聞く場所であるAudio Listener
を両方セットすれば音が出るようになります。

3Dの場合はAudio ListenerとAudio Sourceが遠いと音が小さく聞こえるといった演出ができるようになっているようです。2Dの場合は関係ないけど両方要るのは同じ。


ボタンに取り付けてクリックしたら音がなるようにしようと思います。

## 1. Buttonを配置する

HierarchyのCreateからUIのButtonを選択するとButtonが出てきます。実行してマウスオーバーやクリックで色が変わるのを確認しておきます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/277233/00a9b462-434c-fa5b-220e-d622c41c023e.png)

## 2. Sound Sourceを配置する

使用する音声データを用意します。今回は効果音ラボさんの音源をお借りしました。ダウンロードしたらdrag & dropでAssetに置きます。
https://soundeffect-lab.info/sound/button/

ButtonのInspectorを開き、Add ComponentからAudioのSound Sourceを追加したら、Assetに置いた音声ファイルをdrag & dropでInspectorのAudio Clipに置きます。decision7となってるところが今回置いた音声ファイルです。デフォルトではplay on awakeが有効になっているので試しに実行すると貼った音が鳴ります。なるのを確認したらplay on awakeを無効にしておきます。
<img src="https://qiita-image-store.s3.amazonaws.com/0/277233/311ba6c1-6226-7d06-532b-e5cdc2e51c65.png" width=50%>
Sound Sourceを置くと自動でSound Listenerも追加されます。Main Cameraをハイライトすると追加されてるのが確認できます。

## 3. コードで音を鳴らす

再度ButtonをハイライトしてAdd ComponentからNew Scriptを追加して以下のコードを書き込みます。同じオブジェクトにあるSound Sourceを取得してsound01に代入し、Buttonが押されたら1回鳴らすと書いてます。

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

public class MyButton : MonoBehaviour
{
    private AudioSource sound01;

    void Start()
    {
        sound01 = GetComponent<AudioSource>();
    }

    public void OnClick()
    {
        sound01.PlayOneShot(sound01.clip);
    }
}
```

## 4. Buttonのクリックイベントを伝える先を指定する
Buttonは押したときに誰に情報を伝えるかが選べるようになっている為にこれだけではクリックに反応できません。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/277233/acd88595-6cba-aaab-fdb2-bfedd818e45a.png)

Buttonを押したときに上で書いたScriptのOnClick()を呼べるようにします。項目を増やす為にButtonのInspectorのOnClick()の＋を押します。出てきた項目の左下が伝える対象ですので、HierarchyからButtonをdrag & dropします。次いで、呼ぶ関数を指定する為に右の選択肢からMyButton.OnClick()を選びます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/277233/3f87d6fb-0098-ecd5-8b86-d0ca2d23b7ad.png)

これで実行するとクリックする度に音が鳴る筈です。

## 複数の音源を鳴らす場合

Inspectorに複数の音源を登録します。
<img src="https://qiita-image-store.s3.amazonaws.com/0/277233/6324570c-8a36-be26-37e4-0f2c2d46b66d.png" width=50%>
複数のGetComponent<>ではなくGetComponents<>と複数形にすると複数あるAudioSourceをまとめて読み込めます。取り込んだAudioSourcesの1番目は[0]、2番目は[1]を付けると呼んでこれます。

以下のコードではOnClick()を呼べば1番目の音源、OnClick2()を呼べば2番目の音源が再生されます。

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

public class MyButton : MonoBehaviour
{
    private AudioSource sound01;
    private AudioSource sound02;

    void Start()
    {
        AudioSource[] audioSources = GetComponents<AudioSource>();
        sound01 = audioSources[0];
        sound02 = audioSources[1];
    }

    public void OnClick()
    {
        sound01.PlayOneShot(sound01.clip);
    }
    public void OnClick2()
    {
        sound02.PlayOneShot(sound02.clip);
    }
}
```
レッツエンジョイ！
Goで[]byteをターミナルで表示可能な感じでエスケープする

HTMLのテンプレートだと、HTMLセーフな感じで出力するじゃないですか。あれのターミナル版が欲しいと思ったわけですよ。バイナリデータが入ってきたときにそのまま出してしまうとたまにおかしくなってしまったりするし。かといって、テキストなのに全部バイナリにしてしまうと可読性とか困りますよね。一般人は脳内UTF-8デコードとかできませんし。

で、Goの標準ライブラリには[unicode.IsPrint()関数](https://golang.org/pkg/unicode/#IsPrint)があって、表示できるか判定ができるので、これを利用します。これの元ネタ？のC/C++の[ctype.hヘッダーのisprint()関数](http://www.cplusplus.com/reference/cctype/isprint/)はASCIIの範囲のみで日本語とかは判定できませんが、Goの方はOKのようです。

```go
import (
	"fmt"
	"strings"
	"unicode"
	"unicode/utf8"
)


func Printable(b []byte) string {
	var result strings.Builder
	for len(b) > 0 {
		if utf8.RuneStart(b[0]) {
			r, size := utf8.DecodeRune(b)
			if unicode.IsPrint(r) {
				result.WriteRune(r)
			} else if r == 0x0a {
				result.WriteString("\\n")
			} else {
				fmt.Fprintf(&result, "\\x%02x", r)
			}
			b = b[size:]

		} else {
			fmt.Fprintf(&result, "\\x%02x", b[0])
			b = b[1:]
		}
	}
	return result.String()
}
```

やっていることは、まずバイト列からRuneを取り出します。その後、 ``IsPrint()`` を見て、表示可能ならそのまま文字列にし、だめな場合はエスケープします。ただし、改行だけはよく出てくるので ``\n`` 表記に特別扱いしています。

こんなかんじでいいんですかね？非可逆を狙うなら、 ``\`` は ``\\`` とかにするなど、さらにエスケープが必要な気がしますが。

``unicode.IsPrint()`` の存在を教えてくれた @moriyoshi に感謝です。

**2/12修正**

``utf8.DecodeRune(b)`` は不正なコードがあると、不正なコードを表すマーカーの文字である[0xfffd](https://www.fileformat.info/info/unicode/char/0fffd/index.htm)に変換してしまうようです。stringのrangeループでruneを取り出すときも、この関数が使われます。

ということで、↑のコードを少し修正して、 ``utf8.RuneStart()`` でutf-8として正常な文字でないかどうかの判定を追加しています。ただ、これでも、1バイト目は正しいのに2バイト目がダメ、なケースは救えないと思うので、まだ修正が必要です。
#python 初心者が Twitter API で得られる created_at の String を日本時間で年月日出力しようとした記録コード

#python 初心者が Twitter API で得られる created_at の String を日本時間で年月日出力しようとした記録コード


# Script
```py
import pytz
import time
import datetime

tweet = {}
tweet['created_at'] = 'Wed May 23 23:01:13 +0000 2007'

t = time.strptime(tweet['created_at'],'%a %b %d %H:%M:%S +0000 %Y')

utc = pytz.timezone('UTC')

d = datetime.datetime(*t[:6], tzinfo=utc)
print(d)

tm = d.astimezone(pytz.timezone('Asia/Tokyo'))
print(tm)

zn = tm.strftime('%Y-%m-%d %H:%M:%S %Z%z')
print(zn)

ymd = tm.strftime('%Y-%m-%d')
print(ymd)
```

# Result

```
2007-05-23 23:01:13+00:00
2007-05-24 08:01:13+09:00
2007-05-24 08:01:13 JST+0900
2007-05-24
```

# Etc

- 動いてる気はする
- 日本人にはタイムゾーン周りがつらいのです、言語問わず
- datetime.py っていうスクリプト名を使ってたら、動かなかったので驚き


# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/580








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
React Navigationのインストール時のつまづきポイント

## バージョン
react-native-gesture-handler: 3.2.1

## 事象
公式の手順通りに、プロジェクトのディレクトリで下記コマンドをターミナルから実行する。

```sh
yarn add react-navigation
yarn add react-native-gesture-handler
react-native link react-native-gesture-handler
```

しかし、Xcodeでビルドしようとすると、以下のようなエラーが発生して失敗する。

```
'React/RCTEventDispatcher.h' file not found
```

## 対処法

これは `react-native-gesture-handler` のバグで、Reactライブラリの参照先がズレている模様。
以下の手順で解消できる:

- ios ディレクトリにある Podfileを開き、追加された `pod 'xxxxxxx', :path => '../node_modules/xxxxx'` をすべて削除する。
- Xcode を閉じる
- ターミナルで ios ディレクトリに移動して `pod update` を実行して、インストールされた `react-native-gesture-handler` を削除
- 続いて `react-native link` を実行して `react-native-gesture-handler` へのリンクを解除
- Xcode を開いて Xcodeのメニューから `Product` -> `Clean Build Folder` を実行
- Xcode でアプリケーションをビルド
- Finder上の `(プロジェクトルート/)node_modules/react-native-gesture-handler/ios/RNGestureHandler.xcodeproj` を Xcode 内の Project Navigator（左欄） の `Libraries` にドラッグ＆ドロップ
- Xcode で `RNGestureHandler.xcodeproj` の下の `Products/libRNGestureHandler.a` をプロジェクトの `Build Phases`　の `Link Binary With Libraries` にドラッグ＆ドロップ
- 必要に応じてプロジェクトの `Build Settings` の `Header Search Paths` に `${SRCROOT}/../node_modules/react-native-gesture-handler/ios/` を `recursive` で追加する
- するとエラーが出なくなるはず

## 蛇足
どのIssueを見ても `react-native-gesture-handler` の中の人の返答がおぼつかない感じなので、問題が修正されるまでに多少の時間を要するかも知れない。

## 参考
- [Getting started · React Navigation](https://reactnavigation.org/docs/en/getting-started.html)
- [Error: React/RCTEventDispatcher.h not found in iOS · Issue #179 · kmagiera/react-native-gesture-handler](https://github.com/kmagiera/react-native-gesture-handler/issues/179#issuecomment-450346252)
- [Linking Libraries · React Native](https://facebook.github.io/react-native/docs/linking-libraries-ios)
Swiftの配列とハッシュ（連想配列）

今更ながら頭の整理のため。

# Swift のバージョン

4.2.1

# 配列

```swift
// 宣言時に型を指定する場合。これは文字列の配列
var hoge: [String]

// こういう書き方もできる
var hoge: Array<String>

// 空で初期化
hoge = []

// 初期化時に代入する場合は型指定は無くても良い
var hoge = ["ほげ"]

// 最後に追加する場合はappend
hoge.append("ふが")

// 最初に追加する場合はinsert(at:)
hoge.insert("ふが", at: 0)
```


# ハッシュ（連想配列）

```swift
// 宣言時に型を指定する場合。これはキーと値両方が文字列のハッシュ
var fuga: [String: String]

// こういう書き方もできる
var fuga: Dictionary<String, String>

// 空で初期化
fuga = [:]

// 初期化時に代入する場合は型指定は無くても良い
var fuga = ["ほげ": "ふが"]

// 追加/更新する場合
fuga["test"] = "test2"
```

# 複合

```swift
// これは文字列の配列を値に、文字列をキーに持つハッシュの配列
// 例えば
// [
//     "test": ["a", "b", "c"],
//     "test2": ["d", "e", "f"],
// ]
var test: [[String: [String]]]
```
Windows 10 Pro x64 + Python3 で DLしたjsonファイルの処理を少し試してみる

#目的
[こちら](https://qiita.com/tabizou/items/10b65dce3413679fdd5b)でDLしたサンプルに対して少し試してみる
※自分用の確認メモ
※TODO:json.JSONDecoder,json.JSONEncoder,dump形式変換後の処理
##サンプルコード
```python
# Windows Add env PYTHONIOENCODING = UTF-8 & restart vscode

import json
import pprint

# json ファイルの読み込み：qiita.jsonは１行のファイル
with open('qiita.json', 'r', encoding='UTF-8') as f:
    jsonstr = json.load(f)

# jsonstr を JSON 形式の f へのストリームとして直列化する
with open('qiitadump.json', 'w', encoding='UTF-8') as f:
    json.dump(jsonstr, f)
# コメントアウトしないと以下の処理は一部動作しない

print(type(jsonstr))        # <class 'list'>
print(len(jsonstr))         # 35

# 各記事の構造は dict : DLしたデータは dict の list という構造
for i, contents in enumerate(jsonstr):
    print(type(contents))   # <class 'dict'>
    break

# １記事の tag の表示
for i, contents in enumerate(jsonstr):
    for j, tex in enumerate(jsonstr[i]):
        print(str(j).rjust(2, '0'), tex)
    break
# 00 rendered_body
# 01 body
# 02 coediting
# 03 comments_count
# 04 created_at
# 05 group
# 06 id
# 07 likes_count
# 08 private
# 09 reactions_count
# 10 tags
# 11 title
# 12 updated_at
# 13 url
# 14 user
# 15 page_views_count

# １記事分の tag と その内容
for i, contents in enumerate(jsonstr):
    for k, v in dict(contents[i]).items():
        print(k, v)
    break

# １記事文のデータを整形して表示
for i, contents in enumerate(jsonstr):
    pprint.pprint(contents, width=20)
    break
```
##Qiitaの[投稿](https://qiita.com/api/v2/docs#%E6%8A%95%E7%A8%BF)の構造(Docより抜粋)
<pre>
ユーザからの投稿を表します。
・rendered_body
    HTML形式の本文
    Example: "<h1>Example</h1>"
    Type: string
・body
    Markdown形式の本文
    Example: "# Example"
    Type: string
・coediting
    この記事が共同更新状態かどうか (Qiita:Teamでのみ有効)
    Example: false
    Type: boolean
・comments_count
    この記事へのコメントの数
    Example: 100
    Type: integer
・created_at
    データが作成された日時
    Example: "2000-01-01T00:00:00+00:00"
    Type: string
    Format: date-time
・group
    Qiita:Teamのグループを表します。
・id
    記事の一意なID
    Example: "4bd431809afb1bb99e4f"
    Type: string
    Pattern: /^[0-9a-f]{20}$/
・likes_count
    この記事への「いいね！」の数（Qiitaでのみ有効）
    Example: 100
    Type: integer
・private
    限定共有状態かどうかを表すフラグ (Qiita:Teamでは無効)
    Example: false
    Type: boolean
・reactions_count
    絵文字リアクションの数（Qiita:Teamでのみ有効）
    Example: 100
    Type: integer
・tags
    記事に付いたタグ一覧
    Example: [{"name"=>"Ruby", "versions"=>["0.0.1"]}]
    Type: array
・title
    記事のタイトル
    Example: "Example title"
    Type: string
・updated_at
    データが最後に更新された日時
    Example: "2000-01-01T00:00:00+00:00"
    Type: string
    Format: date-time
・url
    記事のURL
    Example: "https://qiita.com/yaotti/items/4bd431809afb1bb99e4f"
    Type: string
・user
    Qiita上のユーザを表します。
・page_views_count
    閲覧数
    Example: 100
    Type: null, integer
</pre>
##参考にしたのは以下のサイト
[Qiita API v2ドキュメント - Qiita:Developer](https://qiita.com/api/v2/docs)
[7.2.2. json による構造化されたデータの保存](https://docs.python.org/ja/3/tutorial/inputoutput.html#saving-structured-data-with-json)
[json --- JSON エンコーダおよびデコーダ](https://docs.python.org/ja/3/library/json.html)
##参考書
[退屈なことはPythonにやらせよう](https://www.oreilly.co.jp/books/9784873117782/)
輸入野菜と国産野菜の価格比較

スーパーで買い物をしている時、輸入野菜のほうが安いので全部そのようなのか気になって調べてみた。

データ自体はe-statAPIから得た。

```python
title = '00500_0003263855_統計表 全国の主要都市の並列販売店舗における生鮮野菜の品目別価格及び価格比　国産標準品と輸入品 国産標準品と輸入品_201601-201612.csv'
df = pd.read_csv(dir_path + title)
df["value"] = pd.to_numeric(df["value"], errors='coerce').fillna(0)
# 時間列の途中で年合算が入るのでendが月以外は除外
df = df[(df['時間軸(年次、月次)'].str.endswith('月'))]
df.sort_values('時間軸(年次、月次)', ascending=True, inplace=True)

g = sns.relplot(x='時間軸(年次、月次)', y='value', hue='価格及び価格比', size=None, style='unit', data=df,row=None, col='生鮮野菜の品目', col_wrap=3, row_order=None, col_order=None,legend="brief", kind="line")
g.savefig(title + '.png')

```

![00500_0003263855_統計表 全国の主要都市の並列販売店舗における生鮮野菜の品目別価格及び価格比　国産標準品と輸入品 国産標準品と輸入品_201601-201612.csv.png](https://qiita-image-store.s3.amazonaws.com/0/302092/3c018c07-448d-d526-111d-a04bf31eaba0.png)

トマトが輸入品のほうが高い場合が多いのが意外。ごぼうなど、野菜によってデータの取得がまちまちでした。元データを確認するも欠損したまま。
【C#】Microsoft.Office.Interop.Excelで使える二次元配列を作る

# はじめに

C#からExcelを操作する時、Microsoft.Office.Interop.Excelを利用すると、ExcelVBAと同じようにでExcelを扱えるのでとても便利です。

一方で、Excelから二次元配列としてデータを一括取得すると、配列の要素番号が1始まりになるなど、VBAと同じであるが故に少々癖が強い部分もあります。

特に、C#側で生成したデータをExcelに二次元配列として貼り付ける時は、配列の要素番号が1からスタートしていないとエラーになってしまうため、以下のような「通常の初期化」で生成した二次元配列を使うとエラーになってしまいます。

```c#
// この初期化だと、配列の要素番号が一次元、二次元ともに0からスタートする。
object[,] array2D = new object[100,100];
```

# コード

* 以下のように「二次元配列の最小要素番号を指定して初期化」することで、任意の要素番号からスタートする二次元配列を生成できます。
 * ここではExcelに貼り付けるための配列なので、要素番号は1からスタートさせています。

```c#
/// <summary>
/// 行数と列数を指定して、Excelに貼り付けられる二次元配列を生成する。
/// </summary>
/// <param name="rowIdx">行方向の要素数</param>
/// <param name="colIdx">列方向の要素数</param>
/// <returns>要素番号が1から始まる二次元配列</returns>
public static object[,] CreateArray2D(int rowIdx, int colIdx)
{
    // 二次元配列の各次元の最小要素番号
    int[] lower = { 1, 1 };
    // 二次元配列の各次元の要素数
    int[] length = { rowIdx, colIdx };

    return (object[,])Array.CreateInstance(typeof(object), length, lower);
}
```

# まとめ

* この方法を知らなくても、1セルずつ書き込めばエラーは起きません。
 * ただし、書き込むセル数が多いと処理速度が劇的に遅くなってしまいます...
* Microsoft.Office.Interop.Excelを使わずに、POIやNPOI、ClosedXMLなど、別のライブラリを使ってExcelを操作することも可能です。
【integromat】integromat 使ってみた

#概要
最近自分で自動ワークフローを作れるIntegromatにハマっているので、忘備録も兼ねて色々と書いてみようと思います。


#Integromatとは
TwitterやSlackなど、Webサービス同士を繋げて自動ワークフローを繋げるサービスです。
例えばタスク管理サービスであるTrelloでタスクを追加したらTwitterにも同じ内容のメッセージを投稿するなど、サービスの内容を他のサービスに橋渡しすることが出来ます。
対応してるサービスはTwitter、Slack、Github、Trello、Google　Splead Sheetなど色んなサービスがあります。

![2019-02-11_15h38_26.png](https://qiita-image-store.s3.amazonaws.com/0/59907/38ff144b-45cf-72bf-d800-c74063ef8096.png)
![2019-02-11_15h38_55.png](https://qiita-image-store.s3.amazonaws.com/0/59907/ebdb32c8-766d-90be-30e8-4d9eac0f4493.png)
![2019-02-11_15h39_48.png](https://qiita-image-store.s3.amazonaws.com/0/59907/82215721-271c-cf27-c245-3f69e126304c.png)

他にもサービスはありますので、ご興味ある方はぜひ公式サイトでご確認してみてください。
https://www.integromat.com/en/

#シナリオ
自動ワークフローを作るためには、各サービスで実行できる処理を追加していく必要があります。
このワークフローを環境する場所をシナリオといいます。

これがシナリオを作る画面になります。ここに各サービスが実行できる処理を追加していきます。
![2019-02-11_23h31_10.png](https://qiita-image-store.s3.amazonaws.com/0/59907/e38f0815-508f-8e19-547d-d4b873e11acf.png)


処理を作成するためには下の方に各サービスのアイコンが並んでるのでアイコンを選択します。
![2019-02-11_23h31_10.png](https://qiita-image-store.s3.amazonaws.com/0/59907/9230ebc4-87af-5f21-506b-5cf8062b430f.png)

各アイコンを押すとそのサービスで実行できるアクションの候補が一覧として出てきます。
![2019-02-11_18h01_09.png](https://qiita-image-store.s3.amazonaws.com/0/59907/cd180fc6-212f-27ea-5a73-cd1ab9e61e93.png)

アクションを選択するとそのサービスのアイコンとアクションの名前が生成されます。
![2019-02-11_18h05_10.png](https://qiita-image-store.s3.amazonaws.com/0/59907/437cf6bd-de8a-9f45-f4fc-bd4b1c05c25e.png)

これを繰り返していき、自分だけのシナリオを作ります。
例としてjsonを作成してパースした内容をTrelloに登録するようにしてみました。
![2019-02-12_00h07_56.png](https://qiita-image-store.s3.amazonaws.com/0/59907/c9231f09-439c-de81-c40b-844b73975a53.png)

自分だけのシナリオが出来たら、左下にあるRunを選択するとシナリオが実行されてきちんと通るかテストされます。
![2019-02-12_00h07_17.png](https://qiita-image-store.s3.amazonaws.com/0/59907/f5f4efca-6819-626f-c771-ea11b8858a24.png)


テストに成功するとこんな感じに成功したことが表示されます。
![2019-02-11_23h55_25.png](https://qiita-image-store.s3.amazonaws.com/0/59907/7f65f847-6103-c513-d4d7-37b09bcbc72e.png)
アイコンの右上にあるバルーンを押すとどういう値が入出力されているのかを確認できます。
![2019-02-12_00h00_45.png](https://qiita-image-store.s3.amazonaws.com/0/59907/f82613d2-e5e0-687a-de02-2526e2014198.png)


失敗すると赤い三角形で表示され、アイコンの右上にあるバルーンを押すと詳細が出てきますのでなぜ失敗したのかわかるようになっています。
![2019-02-11_23h59_54.png](https://qiita-image-store.s3.amazonaws.com/0/59907/983888ae-8db0-2c5c-ff75-2be5e4529eaf.png)

#終わりに

簡単に説明してみましたがいかがだったでしょうか。
触り始めてまだ日が浅いのですが、まだまだ便利にできそうな機能が多いので調べたらまた記事を書きたいと思います。

#参考
[Integromatの使い方](https://qiita.com/nendocode/items/b3f9f9810a0dfd744dcf)
【CentOS 7】gnome-initial-setup無効化

表題の通り、CentOS初回起動時（正確にはシステムアカウント以外のユーザがいない時）に
表示されるあいつがウザいので何とかならないか調べた備忘録

こいつがいるとrootでログインできないので非常に迷惑なのだ

<img width="912" alt="スクリーンショット 2019-02-11 23.48.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/333729/1f0c95bd-b6d3-261a-b9fb-cbfdf6191751.png">

こいつは、どうも「gnome-initial-setup」というパッケージらしい。
なのでサクッと削除しましょう。

```
yum remove gnome-initial-setup
```

※ 上記コマンドは不用意な削除をする可能性があるので真似しないでね。

対象なのは以下のパッケージ

+ gnome-initial-setup-3.28.0-1.el7.x86_64 @base
* initial-setup-0.3.9.43-1.el7.centos.x86_64 @base
- initial-setup-gui-0.3.9.43-1.el7.centos.x86_64 @base

baseに含まれているのでちゃちゃと削除しましょう

<img width="912" alt="スクリーンショット 2019-02-11 23.58.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/333729/29751c98-1d54-83b9-14a0-437d5132baba.png">

これで解決。
Fisher Information Matrix ノート

これも自分で導出確認できた範囲でのメモ。統計による推定値がどれくらい正しいか、を評価する際に、推定値の分散の下限をサンプルの分布から計算できる。

### 推定値

いつも$X$が確率分布$P(x|\Theta)$に従って分布するとして、平均やら分散やら、どうにかなる確率を計算したりする。今、確率分布$P(X|\Theta)$に従う$N$個の観測値$X_1,\cdots,X_N$を得たとき、これらの変数からもとの確率分布のパラメータ$\theta$を推定する問題を考えよう。
伝統的にこの推定値(estimator)を以下のように書くことにする。

```math
\hat{\theta}(X_1,\cdots,X_N)
```

これらは当然確率分布$P(X|\theta)$に従うので、$P(X_1,\cdots,X_N|\theta)$からその期待値を計算することができる。

```math
E[\hat{\theta}] = \int\cdots\int dX_1\cdots dX_N \hat{\theta}(X_1,\cdots,X_N)p(X_1,\cdots,X_N|\theta)
```

これは確率分布$P(X|\theta)$のパラメター多$\theta$がパラメータに入っている。

### unbiased estimator 

この推定値の期待値がパラメータに等しいものをunbiased estimator と呼ぶ。

```math
\theta = E[\hat{\theta}]
```

### Cramér–Raoの不等式

そしてunbiased estimator ともとの分布のパラメータとの間の誤差の期待値を計算すると、推定値の分散の下限を見積もれます。先に結論を書くと、unbiased estimator ともとのパラメータとの差 $\hat{\theta}-\theta$の共分散行列の下限はFisher information matrix の下限で与えられ、それは[Cramér–Raoの不等式](https://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A3%E3%83%83%E3%82%B7%E3%83%A3%E3%83%BC%E6%83%85%E5%A0%B1%E9%87%8F)と呼ばれている。自分がノートに書いているやり方で書くと

```math
E[(\hat{\theta}-\theta)(\hat{\theta}-\theta)^t] \geq I^{-1} \\
I = E[\left(\frac{\partial g}{\partial \theta}\right)\left(\frac{\partial g}{\partial \theta}\right)^t] \\
g(\theta) = \frac{\partial}{\partial \theta} \log p(x|\theta)
```
という感じです。不等号は正定値行列の意味。くどいですかね。$I$がFisher information matrix, $g(\theta)$はlog-likelihood の微分（gradient)です。

証明はunbiased estimator の定義の式の両辺を$\theta$で微分し、$E[\frac{\partial g}{\partial \theta}]=0$であることを強引に用いると

```math
{1} = E\left[ (\hat{\theta}-\theta) \left(\frac{\partial g}{\partial \theta}\right)^t \right]
```

が得られる。あとはCauchy–Schwarz inequalityより

```math
{1}^2 = \left(E\left[ (\hat{\theta}-\theta) \left(\frac{\partial g}{\partial \theta}\right)^t \right]\right)^2 \leq 
E\left[ (\hat{\theta}-\theta)(\hat{\theta}-\theta)^t \right]
E\left[ \left(\frac{\partial g}{\partial \theta}\right) \left(\frac{\partial g}{\partial \theta}\right)^t \right]
```

から得られる。
ASP.NET Core MVCでhiddenの値を変更する

# 概要
POSTされたhiddenの値を変更しても、その内容が変更内容が反映されない。
ContollerでModelStateをClearすると反映されるようになる。
詳細は下記を参照。

**環境**
.Net Core 2.2


# サンプルコード
```csharp:Controller
public IActionResult Index()
{
    var vm = new ViewModel { Value = 1 };
    return View(vm);
}

[HttpPost]
public IActionResult Index(ViewModel vm)
{
    vm.Value = 2;
    return View(vm);
}
```

```csharp:ViewModel
public class ViewModel
{
    public int Value { get; set; }
}
```

```html:View
@model ViewModel

<!DOCTYPE html>
<html>
<head></head>
<body>
    <form method="post">
        <input asp-for="Value" type="hidden" />
        <span>@Model.Value</span>
        <button type="submit">送信</button>
    </form>
</body>
</html>
```

# 対応前実行結果
POST前と後でspanの値は変わっているが、hiddenの値は変わっていない。

```html:POST前
<!DOCTYPE html>
<html>
<head></head>
<body>
    <form method="post">
        <input type="hidden" id="Value" name="Value" value="1" />
        <span>1</span>
        <button type="submit">送信</button>
    </form>
</body>
</html>
```

```html:POST後
<!DOCTYPE html>
<html>
<head></head>
<body>
    <form method="post">
        <input type="hidden" id="Value" name="Value" value="1" />
        <span>2</span>
        <button type="submit">送信</button>
    </form>
</body>
</html>
```


# 対応内容
```csharp:Controller
[HttpPost]
public IActionResult Test(ViewModel vm)
{
    ModelState.Clear();
    // もしくは
    // ModelState.Remove("Value");
    vm.Value = 2;
    return View(vm);
}
```

# 補足
リストデータの場合、POST前に存在するインデックスの値は変更が判衣されない。

```csharp:Controller
public IActionResult Index()
{
    var vm = new List<ViewModel> 
    {
        new ViewModel { Value = 1 },
        new ViewModel { Value = 2 }
    };
    return View(vm);
}

[HttpPost]
public IActionResult Index(List<ViewModel> vm)
{
    vm = new List<ViewModel> 
    {
        new ViewModel { Value = 3 },
        new ViewModel { Value = 4 },
        new ViewModel { Value = 5 }
    };
    return View(vm);
}
```

```html:View
@model List<ViewModel>

<!DOCTYPE html>
<html>
<head></head>
<body>
    <form method="post">
        @for (var i = 0; i < Model.Count; i++)
        {
            <input asp-for="@Model[i].Value" type="hidden" />
            <span>@Model[i].Value</span>
        }
        <button type="submit">送信</button>
    </form>
</body>
</html>
```

```html:POST前
<!DOCTYPE html>
<html>
<head></head>
<body>
    <form method="post">
            <input type="hidden" id="z0__Value" name="[0].Value" value="1" />
            <span>1</span>
            <input type="hidden" id="z1__Value" name="[1].Value" value="2" />
            <span>2</span>
        <button type="submit">送信</button>
    </form>
</body>
</html>
```

```html:POST後
<!DOCTYPE html>
<html>
<head></head>
<body>
    <form method="post">
            <input type="hidden" id="z0__Value" name="[0].Value" value="1" />
            <span>3</span>
            <input type="hidden" id="z1__Value" name="[1].Value" value="2" />
            <span>4</span>
            <input type="hidden" id="z2__Value" name="[2].Value" value="5" />
            <span>5</span>
        <button type="submit">送信</button>
    </form>
</body>
</html>
```
Flutter+vs code でhot reloadできない！

# main()の中身を変更するhotreloadされない！

言いたいことは以上です。
みなさんも気をつけてくださいね。

### 経緯
Flutterはじめようと思って、チュートリアルでもやるか！と思い立ち
1. vs codeでFlutterプラグインを入れて「Flutter: New Project」
　これで作られるアプリはカウンターするだけのアプリでした。
2. new projectで作られるmainを削除してチュートリアルの以下のコードを入れてみた。

```dart:main.dart
import 'package:flutter/material.dart';

void main() {
  runApp(
    Center(
      child: Text(
        'Hello, world!',
        textDirection: TextDirection.ltr,
      ),
    ),
  );
}
```
3. vs codeのdebugで「start debugging」をぽちっとしてアプリが立ち上がった。
4. Hello, world!をHello, aaaaa!に変更して保存！
5. ん？変わらない？

という感じでしたので、諦めてチュートリアルは読むだけにします。

ちなみにちゃんと公式に記載してありました。

https://flutter.io/docs/development/tools/hot-reload
>if you hot reload the app after this change, main() is not re-executed, and the widget tree is rebuilt with the unchanged instance of MyApp as the root widget. The result is no visible change after hot reload.



# まとめ
ちゃんと公式読みましょう！
「YAMLで履歴書を作る」をCodeBuildで実行する。

# はじめに

「[YAMLで履歴書を作る](https://qiita.com/kaityo256/items/e3884d0109223c324baf) 」を見かけ便利そうでした。また、「[YAML で履歴書を作るを Docker 環境でやってみた](https://ikasamak503.hatenablog.com/entry/make-resume-by-yaml-with-docker) 」に触発され、手元にPCがなくても作れるようにしたかったので、表題の通りCodeBuildで実行してみました。

# 事前準備
* CodeBuildおよびIAMRoleを操作できるIAMユーザー
* data.yamlがルートにあるgitリポジトリ
    * 最近できるようになったGitHubのプライベートリポジトリでもOK
    * 履歴管理が要らなければS3という手も
* できあがり配置先S3

# CodeBuildプロジェクトの設定
## Project configuration
名前と詳細なのでお好みで

## Source
Source providerは全部GitHub  
※Source2以降は右上に「Add source」というボタンがあるのでそちらをクリックすると増える。

* Primary

    |field name|value|
    |---|---|
    |Repository|Public repository|
    |Repository URL|https://github.com/tac-yacht/codebuild-yaml_cv.git|
* Source2

    |field name|value|
    |---|---|
    |Source identifier|script|
    |Repository|Public repository|
    |Repository URL|https://github.com/ikasam/yaml_cv.git|
* Source3

    |field name|value|
    |---|---|
    |Source identifier|data|
    |Repository|Public repository|
    |Repository URL|【事前準備：data.yamlがルートにあるgitリポジトリ】|

## Environment
※上から順番に選択していくと表の設定項目が現れます。

|field name|value|
|---|---|
|New environment image|Managed image|
|Operating system|Ubuntu|
|Runtime|Ruby|
|Runtime version|aws/codebuild/ruby:2.5.3|

## Artifacts
|field name|value|
|---|---|
|Type|Amazon S3|
|Bucket name|【事前準備：できあがり配置先S3】|

---
上記を設定すると最終的に以下の様になります。※抜粋
![image.png](https://qiita-image-store.s3.amazonaws.com/0/141402/97902bce-d70a-ca2e-9260-6412d3636454.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/141402/67550838-c833-ffe3-9ccc-3fdbcec1f3fc.png)

後は実行すればお手元で設定したS3に出力されますので自由に使えます。
※S3のputイベント契機でLambda->SESやDropboxに送るといった応用もできるかと
Mac+vagrant+ubuntu+nodejsインストールでいきなりつまずく

覚書き

MacのVagrant上のubuntuにsshで接続。そこにnode.jsをインストールする。

```
vagrant@vagrant-ubuntu-trusty-64:~$ sudo apt install -y nodejs npm
Reading package lists... Done
Building dependency tree
Reading state information... Done
npm is already the newest version.
nodejs is already the newest version.
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
```

ここまで順調。

```
vagrant@vagrant-ubuntu-trusty-64:~$  sudo npm install n -g
npm http GET https://registry.npmjs.org/n
npm http GET https://registry.npmjs.org/n
npm http GET https://registry.npmjs.org/n
npm ERR! Error: CERT_UNTRUSTED
npm ERR!     at SecurePair.<anonymous> (tls.js:1370:32)
npm ERR!     at SecurePair.EventEmitter.emit (events.js:92:17)
npm ERR!     at SecurePair.maybeInitFinished (tls.js:982:10)
npm ERR!     at CleartextStream.read [as _read] (tls.js:469:13)
npm ERR!     at CleartextStream.Readable.read (_stream_readable.js:320:10)
npm ERR!     at EncryptedStream.write [as _write] (tls.js:366:25)
npm ERR!     at doWrite (_stream_writable.js:223:10)
npm ERR!     at writeOrBuffer (_stream_writable.js:213:5)
npm ERR!     at EncryptedStream.Writable.write (_stream_writable.js:180:11)
npm ERR!     at write (_stream_readable.js:583:24)
npm ERR! If you need help, you may report this log at:
npm ERR!     <http://github.com/isaacs/npm/issues>
npm ERR! or email it to:
npm ERR!     <npm-@googlegroups.com>

npm ERR! System Linux 3.13.0-165-generic
npm ERR! command "/usr/bin/nodejs" "/usr/bin/npm" "install" "n" "-g"
npm ERR! cwd /home/vagrant
npm ERR! node -v v0.10.25
npm ERR! npm -v 1.3.10
npm ERR!
npm ERR! Additional logging details can be found in:
npm ERR!     /home/vagrant/npm-debug.log
npm ERR! not ok code 0
```

エラーで止まってしまった。
「npm ERR! Error:」で検索してみらたら
npm config set strict-ssl false
というコマンドを叩くらしい。完了したらtrueに戻すのを忘れないように。

```
vagrant@vagrant-ubuntu-trusty-64:~$ npm config set strict-ssl false
vagrant@vagrant-ubuntu-trusty-64:~$
vagrant@vagrant-ubuntu-trusty-64:~$  sudo npm install n -g
npm http GET https://registry.npmjs.org/n
npm http 200 https://registry.npmjs.org/n
npm http GET https://registry.npmjs.org/n/-/n-2.1.12.tgz
npm http 200 https://registry.npmjs.org/n/-/n-2.1.12.tgz
/usr/local/bin/n -> /usr/local/lib/node_modules/n/bin/n
n@2.1.12 /usr/local/lib/node_modules/n
```

これをクリアすれば、先に進める。
Go言語Marshal系インターフェースの拡張で使えるNoMethodイディオム

###NoMethod
Go言語、例えばJSONで、特に構造体などの(Un)Marshalerインターフェースを実装するとき、
外部ライブラリのJSONパーサを利用したかったり、ちょっとした処理を追加したいだけで基本的な処理は標準ライブラリと同じ処理をしてほしいときがあります。
しかし単に呼び直すと再実装されたMarshalメソッドを呼び出すことになるのでループしてしまいます。
メソッドを持たない別の型を宣言しラップすることでこれを解決できます。

```go

type Gopher struct{}

func (g *Gopher) MarshalJSON() ([]byte, error) {
	type NoMethod Gopher
	g.onJSONEncoding() //行いたい処理
	raw := NoMethod(*g)
	return json.Marshal(raw)
}

```

###応用
もう一つ、例えばTime型などjsonでサポートされていない型に対応させたいとき、Unmarshalメソッドを実装するために別の型を宣言しますがその型をそのままメンバにするとtime.Time型を直接使うのと比べていろいろと扱いづらいと思います。
これは元の型を埋め込んでいる冗長なメンバを持った一時的な構造体を定義することで解決できます。

```go

type Time time.Time

func (t *Time) UnmarshalJSON(b []byte) error {
	var tt time.Time
	tt, err := time.Parse(`"2006-01-02"`, string(b))
	*t = Time(tt)
	return err
}

type Gopher struct {
	Birthday time.Time
}

func (g *Gopher) UnmarshalJSON(data []byte) error {
	type NoMethod Gopher
	var gg struct {
		Birthday Time
		*NoMethod
	}
	gg.NoMethod = (*NoMethod)(g)
	if err := json.Unmarshal(data, &gg); err != nil {
		return err
	}
	g.Birthday = time.Time(gg.Birthday)
	return nil
}

```

GoPlayground
https://play.golang.org/p/lVSwnkJFDLv
julia v1.1から始めるJupyter Notebook

今後[julia](https://julialang.org/)がくる！[julia](https://julialang.org/)が熱い！と評判なので調べてみた。
調べてみた結果、まず、[Anaconda](https://www.anaconda.com/)や[Jupyter](https://jupyter.org/)があってそのあとjuliaを入れて連携という記事ばかりだった。

でもやってみたら、juliaからcondaやJupyterをインストールした方が実は簡単っぽいという話。

※[Julia1.3対応版はこちら](https://qiita.com/doorei/items/bac598bac28af074edab)

# やってみた環境
- Windows 10 Home (64bit) Ver 1809
- julia v1.1 (64bit)

# やり方
0. juliaがインストール済みの前提
1. juliaのコンソールを起動(緑字のプロンプト)
2. `]`キーを押してパッケージモードへ(青字のプロンプトになる)
3. `add IJulia`を実行(Cloning～となり、しばらく時間がかかる)
4. `build IJulia`を実行(Building～となり、しばらく時間がかかる)
5. バックスペースでパッケージモードを抜ける(緑字のプロンプト)
6. `using IJulia`を実行(Precompilingされる)
7. `notebook(detached=true)`を実行
8. 「install Jupyter via Conda, y/n? [y]:」と聞かれるので`y`を入力
9. 関連パッケージがダウンロードとインストールされる。(結構時間がかかるので気長に待つ)
10. Jupyterが起動する！「New」のプルダウンにはJulia 1.1.0とpython 3が出てくる

juliaからインストールしたcondaはjulia専用(?!)なのでDisk容量がもったいないといえばもったいないけど、面倒なことを考えないでJupyterが使えるようになるのでまずやりたいことをやる！という場合にはいいんではないでしょうか？

ちなみにjuliaからインストールしたcondaでインストールしたパッケージの確認などは次のようにします。

```
julia> using Conda                    
Julia> Conda.list()                   # Condaでインストールしたパッケージ一覧 
Julia> Conda.update()                 # Condaでインストールしたパッケージのアップデート
Julia> Conda.install("package_Name")  # Condaで"package_Name"をインストール⇒「conda install -y package_Name」を実行
```
アリババCloudを使って見ました。（hello worldまで）

![image.png](https://qiita-image-store.s3.amazonaws.com/0/310210/e28eb186-06fb-47bb-2b47-28576caf72d3.png)
## 環境：
・OS:Linux Ubuntu  14.04 64位
・Nginx
・Gunicorn
・supervisor

アリババcloudでECSを購入して、ssh接続方法でウェブサーバに接続できます。
```ssh root@[IPアドレス]
```
　パースワードを入力すれば、こんな画面表示されます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/310210/b9257ce6-562b-f27c-d57b-09251b258f70.png)





##step1: pythonの環境の用意
・ウェブサーバの方は、python２があ李ますが、python３ないので、必要な場合はダウンロードするべき。
・自分のプロジェクトをFTP　ソフトとか　scpでコマンドでウェブサーバーアプロードします。
```$ scp -r [localのpath] root@abc.com:[サーバーのpath]
```



## step2: Gunicornのインストール
Gunicornは仮想環境を使うべき（virtualenv）

```
(venv) $ pip install gunicorn
```
Gunicornを実行する
```gunicorn -w 4 -b 127.0.0.1:8000 「ファイル名」:app
```
ここでは簡単なhello.pyを実行してみます。

```hello.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
    return 'hello world'
if __name__ == '__main__':
    from werkzeug.contrib.fixers import ProxyFix
    app.wsgi_app = ProxyFix(app.wsgi_app)
    app.run()

```
実行成功したら、 webサーバで訪問できます。
```curl http://127.0.0.1:8000/
```
上のコマンドで、terminalで確かめることができます。

##step3: nginxのインストール＆環境設定
・nginxをインストール

```
$ sudo apt-get update
$ sudo apt-get install nginx
$ sudo chmod 777
```
・ngixnの環境設定

```
sudo cp /etc/nginx/site-avalidable/default /etc/nginx/site-avalidable/default.bak
sudo vim /etc/nginx/sites-avalidable/default
```
・相応な部分を編集します。

```
server {
    listen 80;
    server_name example.org; # ドメインまたは、IPアドレス

    location / {
        proxy_pass http://127.0.0.1:8080; # ここは gunicorn hostアドレス
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
  }
```
設定した後、再実行します。
```sudo service nginx restart
```

これで、OK。
ドメインとかIPアドレスで、自分のホームページを訪問できます。![image.png](https://qiita-image-store.s3.amazonaws.com/0/310210/769a2f3e-f9d7-e1c4-fd09-a5fbefe7c9f1.png)

##備考
・nginxコマンド

```
起動：　sudo service nginx start
restart：　sudo service nginx restart
stop：　sudo service nginx stop
テスト：　sudo service nginx configtest
```
例のUpdateからビルド用のWindowsをmacOSからマウントできなくなった問題対策

例のWindowsの共有フォルダのマウントができなくなる問題の対処法。
リスクも高いのでビルド専用マシン以外での適用は考えた方が良さそうではある。
http://blog.livedoor.jp/nichepcgamer/archives/1073140501.html
[cocoa][swift]作譜用言語PL/0 表駆動の構文解析

<p>『Algorithms + Data Structures = Programs』は、ニクラウス・ヴィルト氏の著名な書籍で、翻訳された書籍の表題は『アルゴリズム＋データ構造＝プログラム』だ。サンプルは、Pascalで記述され構造化プログラミングのバイブル的な書籍だ。</p>

<p>その次の版は、『アルゴリズムとデータ構造』と『翻訳系構成法序論』の二冊に分かれ、Modula-2で記述されている。その次の版は、Oberonで記述されているらしいが、残念ながら入手は困難だ。</p>

<p>ニクラウス・ヴィルト氏は、AppleのObject Pascalの開発にも関与したという話を聞いたことがある。</p>

<p>『翻訳系構成法序論』の感想は、最少限度の知識のみを必要とし、簡素な内容となっていて、初学者の教科書としては理想的ではないかと思っている。</p>

<p>それでは、続きを始める。</p>

<p>前回は、ゴリゴリと記述していたコードを「表駆動の構文解析」では、汎用的なコードを処理するという内容だ。</p>

<p>読み取った記号が終端記号か非終端記号か、そして、次の処理に移動するのか、if分の条件分岐のように、別候補に移動するのかを保持する表、Swiftでは構造体やクラスがそれに対応するので、実装してみる。</p>

<pre><code>class Node {
    public var successor: Node? = nil
    public var alternative: Node? = nil
    public var terminal: Bool = true
    public var terminalSymbol: Character = "\0"
    public var nonterminalSymbol: Header? = nil
}
</code></pre>

<p>上記では未定義だった見出しに相当するのが以下だ。</p>

<pre><code>class Header {
    public var symbol: Character = "\0"
    public var entry: Node? = nil
}
</code></pre>

<p>これを使いと前回の分析子の処理は以下となる。</p>

<pre><code>func parse(goal: Header, match: inout Bool) {
    var s: Node? = goal.entry
    repeat {
        if s!.terminal {
            if s!.terminalSymbol == ch {
                match = true
                readChar()
            }
            else {
                if s!.terminalSymbol == empty {
                    match = true
                }
                else {
                    match = false
                }
            }
        }
        else {
            parse(goal: s!.nonterminalSymbol!, match: &match)
        }
        if match {
            s = s!.successor
        }
        else {
            s = s!.alternative
        }
    } while s != nil
}
</code></pre>

ソースコード
GitHubからどうぞ。<br />
<a href="https://github.com/murakami/workbook/tree/master/mac/pl0">https://github.com/murakami/workbook/tree/master/mac/pl0</a> - GitHub<br />

【関連情報】
<a href="https://cocoa-kanto.connpass.com/event/117577/">Cocoa.swift 2019-02</a><br />
<a href="https://cocoa-kanto.connpass.com/">Cocoa.swift</a><br />
<a href="https://www.facebook.com/groups/cocoa.kanto/">Cocoa勉強会 関東</a><br />
<a href="https://mosa.connpass.com/">MOSA</a><br />
<a href="http://www.bitz.co.jp/weblog/">Cocoa練習帳</a><br />
<a href="https://qiita.com/m_yukio">Qiita</a><br />
TypeScript + hyperapp V1で、actionsにできるだけ短い記述で厳密な型定義をつける（hyperapp-types紹介）

hyperapp V1で、actionsに型付けを行うのが難しいという問題に対処するため、できるだけ短い記述で厳密な型定義をつけるためのライブラリ「hyperapp-types」を作りました。
この記事では、このライブラリについて紹介します。

※「actionsに型付けを行うのが難しいという問題」の詳細については、前回の記事「[TypeScript + hyperappでのactionの書き方ベタープラクティス](https://qiita.com/tetradice/items/2a92219264c73a50ee99)」を参照してください。

# 使い方

npmかyarnでhyperapp-typesをインストールしてください。

```sh
% npm install --save-dev hyperapp-types
# or
% yarn add -D hyperapp-types
```


これにより、`WiredActions`型が使用可能になり、下記のような形でhyperapp V1のコードを書けるようになります。

```tsx
import { app, h } from "hyperapp";
import { WiredActions } from "hyperapp-types"

// Stateの宣言
interface MyState {
  count: number;
}
// Stateの初期化
const state: MyState = {
  count: 0
}

// Actionsの実装
const actions = {
  down:     (value: number) => (state: MyState, actions: MyActions) => ({ count: state.count - value }),
  up:       (value: number) => (state: MyState, actions: MyActions) => ({ count: state.count + value }),
  reset:    () => ({ count: 0 }),
  getState: () => (state: MyState) => (state)
}

// Actionsの実装から、型を生成
type MyActions = WiredActions<MyState, typeof actions>;

// View
const view = (state: MyState, actions: MyActions) => (
  <div>
    <h1>{state.count}</h1>
    <button onclick={() => actions.down(1)}>-</button>
    <button onclick={() => actions.up(1)}>+</button>
    <button onclick={() => actions.reset()}>Reset</button>
  </div>
)

// 起動
const wiredActions = app(state, actions, view, document.body);  // => wiredActionsはMyActions型になる (型推論される)
```

この書き方のポイントは下記の箇所です。

-   `const actions`内の関数で`value`, `state`, `actions`の型を明示し、`WiredActions`型を使用することで、MyActions型が適切に生成されます。

-   `const view`の第2引数に`MyActions`型を指定することによって、`app`関数の戻り値が自動で`MyActions`型になります。

-   各Actionの戻り値の型付けが正確に行われます。このため、[hyperapp公式README](https://github.com/jorgebucaran/hyperapp#interoperability)の例にあるgetStateメソッドにも、正しい型付けが行われます。

    ```tsx

    // 起動
    const wiredActions = app(state, actions, view, document.body);

    // hyperappの外から、actions.getStateで現在のstateを取得することができ、currentStateは正しくMyState型になっている
    let currentState = wiredActions.getState();

    // もしWiredActionsを使用しなかった場合、戻り値がMyState型にならない！
    const view2 = (state: MyState, acts: typeof actions) => (
      <div>
      </div>
    )
    const wiredActions2 = app(state, actions, view2, document.body);
    let currentState2 = wiredActions2.getState(); // => currentState2はMyState型ではなく、関数型 (state: MyState) => MyState になる
    ```

-   [Nested Actions](https://github.com/jorgebucaran/hyperapp#nested-actions)にも対応しています。


より詳細なコード例については、[GithubのREADME](https://github.com/tetradice/hyperapp-types)も見ていただければと思います:thumbsup_tone1:　※英語です
nuxt-user-agentを使ってUser-Agentを判定する

実際にNuxt.jsでUser-Agentを判定したいことがあると思いますが、今回nuxt-user-agentを使ってみてすごい使いやすかったので手順などを書こうと思いました。

# 手順
まずモジュールのインストールからです。

```bash
yarn add nuxt-user-agent
or
npm install nuxt-user-agent
```

でインストールをします。

次にnuxt.config.jsのセットアップです。
modules部分に`nuxt-user-agent`を追加します。

```nuxt.config.js
modules: [
  'nuxt-user-agent',
]
```

これでセットアップは完了です。

次に実際に使ってみます。

### asyncData

```js
asyncData(context) {
  const deviceType = context.$ua.deviceType()
  return { deviceType }
}
```

### method

```js
methods: {
  something() {
    const deviceType = this.$ua.deviceType()
    this.deviceType = deviceType
  }
}
```

### store

```js
actions: {
  getDeviceType ({ commit }) {
    const deviceType = this.$ua.deviceType()
    commit('SET_DEVICE_TYPE', deviceType)
  }
}
```

### template

```html
<template>
  <div id="wrap">
    <div 
      v-if="$ua.deviceType() === 'pc'" 
      class="pc">PCです</div>
    <div 
      v-else-if="$ua.deviceType() === 'tablet'" 
      class="pc">TABLETです</div>
    <div 
      v-else-if="$ua.deviceType() === 'smartphone'" 
      class="pc">SPです</div>
  </div>
</template>
```

のような形で使用します。

また判定できる種類は[こちら](https://github.com/fukuiretu/nuxt-user-agent#methods)に載っています。

実際にnuxt-user-agentを使ってみましたが、かなり使いやすくまた判定できる種類が多いのですごいよかったです。個人的にUser-Agentの判定はmiddleware周りでやるよりもnuxt-user-agentを使ってUser-Agent判定した方がいいかなと思いました。
ポスト Uniduino に何を使おうか

Uniduinoを愛用していたけど、開発終わったっぽく、どうしようかなーと最近悩み中。

![40363fa4-799e-432c-adb2-5ec306a70100.jpg](https://qiita-image-store.s3.amazonaws.com/0/6047/39482bc8-325b-c621-21e8-043cf0a9ab98.jpeg)
https://portutility.com/ja/
あたりが、ガチなシリアルポートアセットで見た感じとてもよさげだが、1万円コースなので、試すの購入躊躇してる...

酔った勢いでポチった暁には、結果を改めて書こうと思う。

Raspberry Piとかやるときも問題なさそうではあるし、組み込んでいい感じに使えるなら、いいなぁ。
https://qiita.com/saitotak/items/e2006423a40bb89cb653
Nuxt.js(SPAモード)でユーザー認証を効率的にする方法を解説

今回は、Nuxt(SPAモード)で、ミドルウェアを使いユーザー認証をする方法を解説します。

`user/auth`というエンドポイントが、クッキーやローカルストレージを元に認証済みユーザーを返すAPIだとします。

以下のように、Vuexにuserが登録されていなければ、authを呼び出すことで、APIの呼び出しを抑えてログイン処理を書くことが出来ます。

クッキーやローカルストレージにトークンが保存されてるブラウザで、Nuxtアプリに訪れた時に任意のページについてユーザー認証を済ませることが出来ます。

```javascript:middleware/auth.js
export default async ({store}) => {
  if (!store.getters['user']) {
    await store.dispatch('auth')
  }
}
```

```javascript:nuxt.config.js
  router: { middleware: ['auth'] },
```

```javascript:store/index.js
export const state = () => ({
  user: null
})

export const getters = {
  user: (state) => state.user,
}
export const mutations = {
  setUser(state, { user }) {
    state.user = user
  }
}
export const actions = {
  async auth({ commit }) {
    const user = await this.$axios.$get(`/users/auth`)
    commit('setUser', { user })
  }
}
```
## 終わりに
私は現在、Web3のサービスの開発をしています。詳しくはこちらの記事をご覧下さい。
        [無料でイーサリアムが当たる、Web3時代の寄付サイトを作った話](https://note.com/kenroda/n/n814347fbdcd7)
ThymeleafでPUTする時 hidden型を使っている

## ThymeleafでPUTする時は、単純にformメソッドのactionにPUTを指定しているわけではない。

### 調べた経緯
PUTできるように実装したのに、chromeのdeveloperコンソールでRequest Methodを見ていたところ`POST`になっててあれ？ってなったため。。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/52335/d6782e28-8621-fb29-73d7-8265916fa28c.png)

From Dataのところをみるとputになっている。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/52335/3e70bb36-72a7-89c7-cd38-c50dfcd0050b.png)




### Thmeleafのソースがどのように展開されているかをみる
formタグのactionには`post`を指定した上で、hidden型を使って、putを実現していることがソースを見るとわかる。
・hidden型とは
https://developer.mozilla.org/ja/docs/Web/HTML/Element/Input/hidden
もともとフォームに表示させずに値を送信したいときなどに使うもの。


- Thymeleafのコード

```html:sample.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
  <head>
    <meta http-equiv='Content-type' content='text/html; charset=utf-8' />
    <title>test</title>
  </head>
  <body>
<!-- ここに注目 -->
    <form th:action="@{/user}" th:method="put">
      <input class="btn btn-default btn-xs" type="submit" value="更新" />
    </form>
<!-- ここに注目 -->
  </body>
</html>
```

- 画面に表示されたソースのコード(thymeleaf展開後)

```html:sample.html
<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv='Content-type' content='text/html; charset=utf-8' />
    <title>test</title>
  </head>
  <body>
<!-- ここに注目 -->
    <form action="/user" method="post">
      <input type="hidden" name="_method" value="put"/>
      <input class="btn btn-default btn-xs" type="submit" value="更新" />
    </form>
<!-- ここに注目 -->
  </body>
</html>
```



## 理由
formタグは、`get`と`post`メソッドしかサポートしていない。
そのため、formタグ上は`method="post"`を指定し、hidden型で`value="put"`を指定する方法を取っていると思われる。
結果としてRequest Methodは`POST`だが`_method`で指定したメソッドで送信されるため`PUT`で送信される。調べてみると他のRailsなどのフレームワークでもこのような方法でputを実現しているみたい。
Gitlab CI でタグ切ったときに走らせたパイプラインから保護した変数が見えなかった

# 概要

以下のような`.gitlab-ci.yml`で「Environment variables」にて「保護」を選択した変数が「script」内で使用できなかった（ブランクだった）

```yaml:.gitlab-ci.yml(抜粋)
deploy-production:
  stage: deploy
  only:
    - tags
    - triggers
  script:
    - <略>
```

# 結論
「Protected Tags」に対象のタグ名を設定しないと、保護した変数をパイプラインで利用できないため！
→ https://gitlab.com/help/ci/variables/README#protected-variables

> Variables could be protected. Whenever a variable is
protected, it would only be securely passed to pipelines running on the
protected branches or protected tags. The other pipelines would not get any
protected variables.
→ 保護された変数は「保護されたブランチ」「保護されたタグ」から実行されたパイプラインでのみ利用できる

[Protected Tagsの設定仕方](https://gitlab.com/help/user/project/protected_tags.md#protected-tags)
ChromeのNET::ERR_CERT_DATE_INVALIDの時刻ズレ検出の仕組み

## はじめに
Chromeでは、システムクロックがズレた状態でHTTPSのサイトにアクセスすると、`NET::ERR_CERT_DATE_INVALID`と言うエラーページが表示される。システムクロックがずれている場合は、サーバ証明書の有効期限外になることもあり接続を続けるわけにはいきません。

この時、システムクロックがズレてる旨表示されます。

![time.png](https://qiita-image-store.s3.amazonaws.com/0/32425/51a84a91-2c46-54aa-d8ac-fd2b8f172695.png)

## NET::ERR_CERT_DATE_INVALID で時刻ズレ検出の仕組み
この`NET::ERR_CERT_DATE_INVALID`で時刻ズレと出す仕組みについては単純で、Chromeが独自に現在時刻を確認し、時刻が大きくズレていれば画面を出している。

その具体的にな仕組みについては、Googleの人らがHTTPSのエラー状況について調査した「[Where the Wild Warnings Are: Root Causes of Chrome Certificate Errors](https://ai.google/research/pubs/pub46359)」について書かれている。余談だが、このPaperではHTTPSエラーの原因の統計をとっており、システムクロックも大きな割合を締めている。

このPaperに基づけば、2017年5月のChromeの安定版より入ったこのクライアントの時刻ズレ検出は以下の通り行われている。

証明書の日付が不正だった場合、Chromeはハードコードされた公開鍵に対応する鍵を持つアップデートサーバに時刻を問い合わせます。その間、3秒までエラー表示を遅延させます。3秒以内に時刻が得られ、システムクロックと大きく異なる場合は、最初に上げたように`NET::ERR_CERT_DATE_INVALID`の画面を表示します。

得られた時刻は以後の利用のためにキャッシュされます。

### Future work.
この論文ではFuture workが書かれています。曰く、信頼できるソースから得られた時刻を持ってしてサーバ証明書を検証すれば、このエラー表示を出す必要すらないということだと思う。

そのために下記の課題をあげている。

- プラットフォームの証明書検証ライブラリを使用しており、システムクロック以外の時刻を利用できない場合がある。独自の証明書検証実装を行う必要がある。
- 独自に得られた時刻を元に正しくサーバ証明書を検証できたとしても、ユーザにシステムクロックを修正するよう促すべきである。

また「[googleの新しい時刻同期プロトコル Roughtimeとは](https://asnokaze.hatenablog.com/entry/20161010/1476107348)」で書いたように、新しい安全な時刻同期プロトコルの開発は現在も続けられている。