OmniAICreator/Qiita-1.07M huggingface dataset:
SAP ERP6.0を非BASIS要員がインストールしてみた

# **インストールの経緯**
SAP社とパートナー契約を結び、デモライセンスでのソフトウェア利用が可能となったため、社内にERP検証環境を構築することにしました。

ただ、社内にBASIS要員もインストール経験者もおらず、~~社外から調達する予算もなく、~~私一人で構築することにしました。

その際に気が付いたこと、苦戦したところを書きます。
※インストール作業は無事に完了しています。多分

私は、SAP ERPの導入/保守プロジェクトでロジ系コンサルのお仕事をしてます。
過去にNetweaverのトライアル版のインストール経験はありますが、BASIS経験はゼロです。

# **インストール対象/環境**
- SAP ERP6.0 EhP8
- DB：MaxDB 7.9 - SP8 Build 35 Windows Server on x64 64bit
- OS：Windows10 PRO
- SWPM：SOFTWARE PROVISIONING MGR 1.0 SWPM10_IM_WINDOWS_X86_64
- Kernel：SAP Kernel 7.49 Windows Server on x64 64bit

(補足) ノートPCにインストールしました

#**環境設定**
そもそもコンピュータの基本的なことに明るくないため、ここでも苦戦

- インストール中のスリープ/再起動/セキュリティチェックを防ぐために以下を設定
  - 電源オプションの設定
  - 自動 Windows UpdateをOFF
  - ウィルスバスターOFF
  - ファイアウォールOFF

- インストール事前チェックでの警告への対応
  - ロケールを英語に変更
  - ページサイズの設定変更(20480GB)

#**インストール作業**
##SAPPAMで確認
- Product Availability Matrix(製品出荷マトリクス)
- インストールする製品の確認

- 参考　 [PAM（製品出荷マトリックス）の使い方](https://wiki.scn.sap.com/wiki/pages/viewpage.action?pageId=448474237)

##SWPM
- Software Provisioning Manager
- SAPCARの使用方法で苦戦
- 参考　[SAP ERP 6.0 EHP4 on Oracle RAC ⑦]
(http://ojaoki.blog.so-net.ne.jp/2014-09-26)

##Kernel
ここが一番苦戦しました。。。
調べた結果、ファイルの差し替えが2箇所必要でした。

- 51051432_10\DATA_UNITS\K_749_U_WINDOWS_X86_64\ADA
 - SAPEXEDB.SAR　→　SAPEXEDB_101-70001661.SAR


- 51051432_10\DATA_UNITS\K_749_U_WINDOWS_X86_64\DBINDEP
 - SAPEXE.SAR　→　SAPEXE_101-70001664.SAR



#**インストール後**
- GUIログオンパッドのメニューが文字化け⇒ロケールを日本語に戻したら解決


#**参考**
以下のサイトにお世話になりました。
ありがとうございました。

**Qiita**
[SAP NetWeaver 7.03 64-bit トライアル版を試す](https://qiita.com/seijimomoto/items/d8f273df0f37178acd2e)


**SAP Basis Cafe**
[Installing SAP ERP 6.0 EhP 8 on MaxDB 7.9](https://sapbasis.wordpress.com/2016/08/25/installing-sap-erp-6-0-ehp-8-on-maxdb-7-9/)
⇒今回のインストール対象に一番近い環境。

**[おじゃあお木](http://ojaoki.blog.so-net.ne.jp/)**
⇒日本語で画像ありで説明。様々なバージョンのインストール記事あり。

**[SAP Basis の窓](http://sapbasis.blog.fc2.com/)**

**ITsiti**
[SAP ERP 6.0 SR3 Installation Steps](http://itsiti.com/sap-erp-6-0-sr3-installation-steps)

**BeeX Technical Blog**
[SAPのバージョンとカーネルリリースの関係を理解する](https://www.beex-inc.com/blog/sap-version-kernel-release/)


#**その他**
- スクリーンショット自動保存(win+prt)が便利でした(知らなかったw
- S/4HANAのオンプレ版のインストールってできるのかな(契約とかスペックとか)
- BASIS様、~~うちの会社にきてください~~仲良くしてください。
- Special Thanks　Kさん
- Qiita初投稿でドキドキ
- [はてなブログ](http://www.sapsumikko.jp/entry/2017/12/25/223625)にも追記
MySQLの再インストールができなくなった Ubuntu16.04

# 前置き
この記事は、ｓｕｄｏコマンドを多く使います。
自分は新しく構築した環境下で行ったため、データが消える心配はありませんでしたが、以下のコマンドを試すことで、データが消えてしまったり、壊れてしまう可能性があります。
実行は***自己責任***でお願いいたします。
至らない点がありましたら、教えていただけたらと思います。

# 問題
環境：ubuntu16.04
mySQL5.7を使用しようとしたところ、

```
$ mysql -u root

ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)
```
というエラーが、、、。

# アンインストールする前に実行したこと
よくあるエラーみたいなので、
https://www.youtube.com/watch?v=oXjJRrbKjp0

https://qiita.com/donaldchi/items/afeabaffc8be39577ef0
をみて、解決を試みました。

```
$ sudo mkdir /var/run/mysqld
$ sudo touch /var/run/mysqld/mysqld.sock
$ sudo chown mysql:mysql /var/run/mysqld/
$ sudo /etc/init.d/mysql restart
[....] Restarting mysql (via systemctl): mysql.serviceJob for mysql.service failed because the control process exited with error code. See "systemctl status mysql.service" and "journalctl -xe" for details.
failed!
```

、、、。
ほかにもいろいろ試したのですが、うまく行かないので、いっそのことアンインストールしてしまうことにしました。

# アンインストール編
```
$ sudo apt-get remove --purge mysql-server* 
$ mysql-common 
$ sudo apt-get autoremove --purge 
$ sudo rm -r /etc/mysql
$ sudo rm -r /var/lib/mysql
```
参考：https://a-zumi.net/ubuntu-mysql-server-purge/
こちらのコマンドでアンストールをしました。

# 再インストール編
再インストールの基本的な手順は以下のとおりです。

```
$ sudo apt-get update
$ sudo apt-get install mysql-server
$ mysql_secure_installation
```
 参考：https://www.digitalocean.com/community/tutorials/how-to-install-mysql-on-ubuntu-16-04

これでうまく行くかとおもいきや、、。

```
$ sudo apt-get install mysql-server
```
こちらのコマンドを試したところ、、。

```
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています                
状態情報を読み取っています... 完了
インストールすることができないパッケージがありました。おそらく、あり得
ない状況を要求したか、(不安定版ディストリビューションを使用しているの
であれば) 必要なパッケージがまだ作成されていなかったり Incoming から移
動されていないことが考えられます。
以下の情報がこの問題を解決するために役立つかもしれません:

以下のパッケージには満たせない依存関係があります:
 mysql-server : 依存: mysql-server-5.7 しかし、インストールされようとしていません
E: 問題を解決することができません。壊れた変更禁止パッケージがあります。
```

依存関係のエラーが、、。

# 依存関係のエラー解決編
apt-getではこれ以上対応ができなさそうなので、aptitudeを使います。
aptitudeを導入し、パッケージをアップデートするのに、実行したコマンドは以下の通りです。

```
$ sudo apt-get install aptitude
$ sudo aptitude update
$ sudo aptitude safe-upgrade
```
これを行った後、mysql-serverをインストールします。

```
$ sudo aptitude install mysql-server
```

そうすると、「以下のアクションでこれらの依存関係の問題は解決されます:」
と、解決方法を提示してくれるので、ひたすらｙを押していきます。
あとは、mysqlのパスワードを設定していけば無事、
mysql -u root -p
でmysqlに入れるようになります。

参考：https://server-setting.info/debian/apt-get-upgrade-error-loop.html
【Unity】Unity2017.3で追加されたAssembly Definitionをちょっと触ってみた

本記事は[サムザップ Advent Calendar 2017](https://qiita.com/advent-calendar/2017/sumzap)の21日目の記事です。
昨日は@you1933さんの「[Unity　ちょっとシェーダーで遊んでみた](https://qiita.com/you1933/items/7640fae55da1c9e4fbda)」でした

## Assembly Definitionとは何か？

[Script compilation and assembly definition files](https://docs.unity3d.com/2017.3/Documentation/Manual/ScriptCompilationAssemblyDefinitionFiles.html)
上記に概要が書かれています。
読み解くと、今まではいわゆる通常のスクリプトは`Assembly-CSharp.dll`にまとめられるので、
スクリプトを変更すると`Assembly-CSharp.dll`に含まれる全てがリコンパイルされるので時間がかかっていたけれど、
いい感じのアセンブリーの単位に分ける事ができるようになるので、スクリプトを変更してもそれに関連するものしかリコンパイルが走らなくて、時間が稼げるよという事みたいです。

## Unity2017.3でのスクリプトのインスペクター

実際に、Assembly Definitionを試してみる前にUnity2017.3でスクリプトを選択するとそれ以前のUnityバージョンとの表示の違いに気づくと思います。

![AssemblyDefinition_01.PNG](https://qiita-image-store.s3.amazonaws.com/0/6790/aade6cec-5f84-e7be-bc61-49cb4cb379cc.png)
Assembly Informationという項目が増えていて、
Filenameが`Assembly-CSharp.dll`となっています。

なるほど、特殊フォルダ以外のフォルダに格納されているスクリプトは`Assembly-CSharp.dll`にまとめられるよね、というのが分かります。
では、`Editor`フォルダにスクリプトを置いてみましょう。

![2017-12-21_17h19_52.png](https://qiita-image-store.s3.amazonaws.com/0/6790/6b2d521a-a5ab-fe5a-8d98-d1480385b4ad.png)
こちらは、Filenameが`Assembly-CSharp-Editor.dll`となっています。

このように、Unity2017.3から選択中のスクリプトがどのアセンブリーに属するのかがインスペクターで確認できるようになっています。


## Assembly Definitionを使ってみる

![AssemblyDefinition_02.gif](https://qiita-image-store.s3.amazonaws.com/0/6790/ee930e86-1c8b-68d8-d44a-eac1a9f952e0.gif)
`Crate` > `Assembly Definition`でAssemblyDefinitionファイル(拡張子は`.asmdef`)を作成し名前を`TestA`とします。

![2017-12-21_17h58_07.png](https://qiita-image-store.s3.amazonaws.com/0/6790/b0e0fe38-96d7-a67f-70d5-b9b07918d036.png)
このファイルを、TestAというフォルダに移動するとTestAフォルダ内にあるスクリプトのアセンブリーが、`TestA.dll`になります。

なんとなく理解できてきました。
それなら、まずは外部アセットを格納しているフォルダのトップに外部アセット用の`Assembly Definition`の設定をすれば、
開発中のコードを編集しても、外部アセットのスクリプトはコンパイルが走らないので手っ取り早く効果を試せると思ったのですが、
ここで1つ問題が起きました。


## 問題点

通常、`Editor`フォルダの中にあるスクリプトは、`Assembly-CSharp-Editor-firstpass.dll`か`Assembly-CSharp-Editor.dll`にまとめられます。
![2017-12-21_18h13_01.png](https://qiita-image-store.s3.amazonaws.com/0/6790/e3962fb4-a1b9-80ef-c80e-11a0edd00fff.png)
上記画像の配置だと、`Assembly-CSharp-Editor.dll`になります。

ここで、TestAフォルダに`Assembly Definition`を設定してみると、
![2017-12-21_18h15_23.png](https://qiita-image-store.s3.amazonaws.com/0/6790/1fe80a26-1d59-4603-9a85-26501810fb5f.png)
おや、Editorフォルダにあるのに`TestA.dll`になっています。

このように、特殊フォルダである`Editor`フォルダであっても親の`Assembly Definition`の影響を受けるようです。
`Editor`フォルダは、親フォルダに`Assembly Definition`のファイルが置いてあっても、そのまま`Assembly-CSharp-Editor-firstpass.dll`か`Assembly-CSharp-Editor.dll`になると思っていたので、ここはちょっと意表を突かれました。

特に、AssetStoreのアセットをもってきたときに、それぞれのアセットの`Editor`フォルダに`Assembly Definition`の設定をしないといけないような気がしてきて、実用性がよく分からなくなってきました。


## これから

上記のように、まだいまいちどう使うのがいいのか疑問点が多いのですが、コンパイル時間を減らせる大きな魅力があるので、
引き続き、色々と試行錯誤やフィードバックをしていきたいと思います。


## 参考
[Unity2017.3bのアセンブリ定義ファイルを使ってみた](https://qiita.com/mao_/items/f5b64658041d2999ddc3)
[Unity2017.3のAssembly Definitionがコンパイル時間短縮の救世主になりそうな予感](http://www.shibuya24.info/entry/assembly_definition)

----
明日は、[noguchi_toma](https://qiita.com/noguchi_toma) さんの [パケットキャプチャツール/Charlesを試してみた](https://qiita.com/noguchi_toma/items/d50a85c6b42b75f61fed)です。
ヘッダでstaticな関数をテンプレート関数から呼ぶ

# はじめに

VimにALEを入れてたら不可思議な警告が出たのでメモ。とあるシングルヘッダライブラリ内で`static inline`宣言された関数にALEが文句をつけたのが発端だが、以下の例では`inline`は外してある。

# 現象

こんなコードを書く。

```test.hpp
static int func(int a){
  return a;
}

template <class T>
int hoge(T a){
  return func(sizeof(a));
}
```

ヘッダファイル`test.hpp`内に、static関数`func`とテンプレート関数`hoge`が定義されている。これを、`clang++`で`-Wall`つきでシンタックスチェックしてみる。

```shell-session
$ clang++ -fsyntax-only -Wall test.hpp 
test.hpp:1:12: warning: function 'func' is not needed and will not be emitted
      [-Wunneeded-internal-declaration]
static int func(int a){
           ^
1 warning generated.
```

「関数`func`はどこからも呼ばれないから必要ないんじゃね？」という警告(`-Wunneeded-internal-declaration`)が出る。

g++は何も言わない。

```shell-session
$ g++ -fsyntax-only -Wall test.hpp 

```

`static`宣言を外すと`clang++`も何も言わなくなる。

```test2.hpp
int func(int a){
  return a;
}

template <class T>
int hoge(T a){
  return func(sizeof(a));
}
```

```shell-session
$ clang++ -fsyntax-only -Wall test2.hpp  

```

テンプレート関数`hoge`を実体化させても文句は言わない。

```cpp:test3.hpp
static int func(int a){
  return a;
}

template <class T>
int hoge(T a){
  return func(sizeof(a));
}

void hoge2(void){
  hoge(1);
}
```

もちろん、普通のプログラムにインクルードして実行させることはできるし、文句も言われない。

```cpp:test.cpp
#include <iostream>
#include "test.hpp"

int
main(void){
  std::cout << hoge(1) << std::endl; // => 4
}
```

# なぜこんなことが起きた？

`static`宣言をした関数`func`は、そのファイルスコープローカルな関数になる。従ってそのファイルスコープ外から呼ばれることはないはずである。さて、テンプレート関数`hoge`は、`test.hpp`の段階では実体化されない。従って、このヘッダファイル単体だけを見ると、この関数`func`はまだ呼ばれていないように見える。実際には別のファイルにインクルードされて、`hoge`が実体化したら呼ばれる可能性があるのだが、`clang++`はその可能性を考えず(チェックしているのがヘッダであることを考慮せず)、警告を出した。・・・本当かな？

# clang++の警告は妥当なの？間違ってるの？

そもそもこういう、テンプレート関数から同一ファイルスコープにstatic宣言された関数を呼ぶ、というのは、C++的にやっていいことなんだろうか？[^1] `static`をつけたということは内部リンケージしか無いという宣言で、たしかに内部の関数からしか呼ばれないのだが、呼んでいる関数がテンプレート関数で、そのファイルスコープ中では実体化されない時にもこれを「内部リンケージ」と言っていいのかな？

[^1]: 僕が書いたライブラリじゃないから「そもそも`static inline`とか指定しなくていいんじゃない？」みたいなことは言わないでね。
matplotlibだけで画像からマウスで指定した領域を抜き出す

# 目的
matplotlibだけで画像からマウスで指定した領域を抜き出したい

# 結果
![Dec-21-2017 18-04-35.gif](https://qiita-image-store.s3.amazonaws.com/0/35426/d8460025-d74e-d583-bbd8-c0feda80ed1c.gif)

# ソースコード
```py3
import numpy as np 
import matplotlib.pyplot as plt 

# 押した時
def Press(event):
    global x1,y1,DragFlag
    # 値がNoneなら終了
    if (event.xdata is None) or (event.ydata is None):
        return 
    
    # 丸める
    cx = int(round(event.xdata))
    cy = int(round(event.ydata))

    x1 = cx
    y1 = cy

    # フラグをたてる
    DragFlag = True

# ドラッグした時
def Drag(event):
    global x1,y1,x2,y2,DragFlag
    
    # ドラッグしていなければ終了
    if DragFlag == False:
        return

    # 値がNoneなら終了
    if (event.xdata is None) or (event.ydata is None):
        return 
    
    # 丸める
    cx = int(round(event.xdata))
    cy = int(round(event.ydata))

    x2 = cx
    y2 = cy
    
    # ソート
    ix1, ix2 = sorted([x1,x2])
    iy1, iy2 = sorted([y1,y2])

    # 画像の一部を抜き出す
    cimg = img[iy1:iy2,ix1:ix2,:]
    
    # 画像を更新
    im2.set_data(cimg)
    
    # 四角形を更新
    DrawRect(x1,x2,y1,y2)
    
    # 描画
    plt.draw()

# 離した時
def Release(event):
    global DragFlag
    # フラグをたおす
    DragFlag = False

# 四角形を描く関数
def DrawRect(x1,x2,y1,y2):
    Rect = [ [ [x1,x2], [y1,y1] ],
             [ [x2,x2], [y1,y2] ],
             [ [x1,x2], [y2,y2] ],
             [ [x1,x1], [y1,y2] ] ]
    for i, rect in enumerate(Rect):
        lns[i].set_data(rect[0],rect[1])

# 画像を開く    
from PIL import Image
fnm = 'lena.tif'
img = Image.open(fnm)

# numpy.ndarrayに
img = np.asarray(img)

# 初期値
x1  = 0 
y1  = 0
x2  = 50
y2  = 50

# ドラッグしているかのフラグ
DragFlag = False

# ソート
ix1, ix2 = sorted([x1,x2])
iy1, iy2 = sorted([y1,y2])

# 画像の一部を抜き出す
cimg = img[iy1:iy2,ix1:ix2,:]

# plot
plt.close('all')
plt.figure(figsize=(8,4))

# subplot 1
plt.subplot(1,2,1)

# 画像を描画
im1 = plt.imshow(img, cmap='gray')

# 四角形を描画
Rect = [ [ [x1,x2], [y1,y1] ],
         [ [x2,x2], [y1,y2] ],
         [ [x1,x2], [y2,y2] ],
         [ [x1,x1], [y1,y2] ] ]

lns = []
for rect in Rect:
    ln, = plt.plot(rect[0],rect[1],color='r',lw=2)
    lns.append(ln)

# 軸を消す
plt.axis('off')

# subplot 2
plt.subplot(1,2,2)
im2 = plt.imshow(cimg, cmap='gray')

# カラーマップの範囲を合わせる 
plt.clim(im1.get_clim())

# 軸を消す
plt.axis('off')

# イベント
plt.connect('button_press_event', Press)
plt.connect('motion_notify_event', Drag)
plt.connect('button_release_event', Release)

plt.show()
```
# 動作確認
[mac]
Python 3.6.2 
matplotlib 2.0.2
backend : MacOSX and Qt5Agg

[win7] 
Python 3.6.3 
matplotlib 2.1.0
backend : Qt5Agg

# 参考文献
[Event handling and picking](https://matplotlib.org/users/event_handling.html)
GEEのオリジナル背景を作成する


GEEデフォルトではGoogle Mapsの画面が背景になりますが、
任意で作成することが可能です。

例えばこんな感じ。標高を強調しています。

https://code.earthengine.google.com/114bd893733f7d3dbd44c5722e3c03a6

```javascript


var elv = ee.Image('NOAA/NGDC/ETOPO1');
var Ter = elv.select(0).gte(0);
var shade = ee.Terrain.hillshade(elv.select(0)).mask(Ter);
Map.addLayer(shade, {min:170, max:300, gamma:1.5}, 'hillshade');

var style = {
  'Deep': [{
      featureType: 'all',
      stylers: [{ color: '#708090'}]
  }]
};

```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/224794/157ef545-e41a-61d9-b521-f7f0baca3c37.png)
[メモ] Jupyter Notebook のショートカットを変更したら動かなくなった問題の解決法

Winsows に Jupyter Notebook をインストール後、ショートカットのプロパティを変更したら起動しなくなった。元に戻しても直らない場合の原因と修正方法のメモ。

## 原因

Windows のショートカットのパス長には上限があり、インストール時に設定されるショートカットはそれを超えてる場合があるため（インストールパス次第）、変更後、OKを押すと、パスが途中で切れてもはや起動しなくなる。

## 修正方法

環境変数に `%ANACONDA%` という名前で `anaconda3` のインストールパスを登録し、
パス上にある `anaconda3` のパスをすべて置き換える。具体的には下記のようになる。

```
%ANACONDA%\python.exe %ANACONDA%\cwp.py %ANACONDA% %ANACONDA%\python.exe %ANACONDA%\Scripts\jupyter-notebook-script.py "ルートとなるディレクトリ"
```
アルゴリズムメディア化するIT業界

リブセンスの代表 @murakami_taichi です。
先日、月に一度のMonthlyMeetup(全社会)で社員のN君からAdvent Calendarの告知がありました。リブセンスの年中行事となったAdvent Calendar。とても良い文化のひとつです。ただ、N君いわく、なにかが足りないと。
その場でN君から代表の私に、根回しなしの突然の無茶振りが。。。はい、わかりました、書きます。
ということで、今回のエントリーになります。

簡単に自己紹介をすると、2006年、19歳のときに会社を創業して以来11年間IT業界にどっぷり浸かっています。
小学生だった1995年、初めてWindowsPCを買ってもらってから、VisualBasicでゲームをつくったり、J研に着メロを投稿したり、お金のない中どうにか自作してハイスペックPCをつくったり、、、IT業界、インターネットを愛する人生を送ってきました。
今回は、サービスを進化させるにあたり今後重要になる、アルゴリズムメディアという概念について、投稿したいと思います。


# アルゴリズムメディアとは
「アルゴリズムメディア」という言葉。聞きなれないかと思います。はい、私が勝手に作った造語です(笑)。
勝手ながら「データを元に、自動的に最適化されていくサービス」と定義をしています。

ハードウェアの進化により、昨今あらゆる情報の蓄積・解析が可能に。
どこに居る、どの辺りに住んでいる、といった情報の他にも、サービス利用時の行動ログ。例えばどのくらいスクロールしたか、何秒閲覧しているか、どこをクリックしたか、などなど、知らず知らずに情報が保存されています。
そうしたデータを元に、自動的に最適化されていくサービスを「アルゴリズムメディア」と定義しています。

例えばGoogle。
SERPsでの動き、Chromeを始めとした行動ログから、検索結果の品質を自動的に最適化し続けています。
Facebookも同じく、クリック、いいね、検索といった行動ログから、自動的にフィードの最適化を図っています。
サービス設計において、アルゴリズムメディアを前提においた設計かどうかが、今後のサービス成長の明暗を分けると考えています。
Facebookの成功は、アルゴリズムメディア化を前提とした、フィードという仕組みにあると思っています。ページを増やして複雑化するのではなく、シンプルなUIでアルゴリズムでの最適化が容易な設計にすることで、UXを高めていくことが出来ます。


# リブセンスにおけるアルゴリズムメディア化の事例
アルゴリズムメディア化の事例として、当社の事例(今後やりたいことも含めて)を紹介したいと思います。
当社は現在、求人・不動産をはじめとしたメディアを提供しています。

求人サイトを例にすると、アルゴリズムメディア化するとは、このようなことです。
![search.png](https://qiita-image-store.s3.amazonaws.com/0/215135/934cfa9a-f938-4fd9-bbe7-50cf2a36e66e.png)


上記のような変化を、行動ログを元に自動的に最適化するイメージです。

検索パネルであれば、使われる度合いにより、時には表示しない。
絞込パーツは、そもそもの表示の有無を調整する。絞込キーワードを利用される度合いが高いものに変更する。
並び順に関しては、クリック率によって変える。
といった具合です。

ユーザー体験(行動ログ)を元に自動的に最適化する為、UXが自動的に向上するメディアが実現できます。


# アルゴリズムメディア化にあたって
ユーザー体験を高めるにあたり、アルゴリズムメディア化する重要性は、今後飛躍的に高まっていくと感じています。

アルゴリズムメディア化実現に向けては
- プロダクト設計：取得するデータの設計、プロダクトへの価値転換の設計
- データ収集基盤の整備：クリックログはもちろん、スクロール、滞在時間などを取得・蓄積する基盤
- アルゴリズムの開発：どんなアルゴリズムで最適化するか
が重要です。

データ収集基盤は当社でも数年前から力を入れています。
DWHにAmazon Redshiftを採用した基盤で、JavaScriptを介してページビューやクリックなどのイベント情報をブラウザから収集し蓄積しています。
加えて、リブセンスのメディアのデータベースも取り込まれていて、例えば転職サイトにおいて転職者の応募までの行動と、その後の採用までの情報を突き合わせた分析が可能になっています。
社内でLivesense Analyticsと呼んでいるこの自社開発の基盤は、リリース当初はWeb広告の効果分析等のデータ分析で威力を発揮しましたが、データが蓄積されてくるに従って、サイト内表示の最適化などアルゴリズムメディア化の流れの中での実績が増えてきました。
これらの技術領域については、最近始まった[DATA ANALYTICS BLOG](http://analytics.livesense.co.jp)でも紹介されています。

このような基盤のもと、自動的にサービスが最適化される仕組みを志向しています。
一見シンプルに見えるサービスの裏にも、ユーザー体験を向上させる為のテクノロジーを駆使しています。

# おわりに
当社では「リアルデータエンジニアリング」という戦略の元、今回紹介したインターネット上での行動ログを元にしたアルゴリズムメディア化はもちろん、リアルデータ(採用されたかどうか、成約したかどうか、など)を元にしたサービス最適化も行っています。
インターネット上での最適化だけではなく、現実世界でのユーザー体験ログまで取得することで、満足度の高いサービス提供を実現していきたいと考えています。
rworldmapで入手可能なNatural Earth dataの全球国別ポリゴンデータをGEEで使う

Google Earth Engine内のカタログをみてみてもみあたらなかったので、仕方なくローカルからポリゴンデータをアップロードしました。

##やったこと
ただ、Rからrworldmapを読み込み、ポリゴンデータを入手し、GEEにあげただけです。

```r
  library(rworldmap)
  library(tmaptools)
  map <- getMap("coarse")
  write_shape(map, "globalmap_rworldmap.shp")
```


##GEEで確認
https://code.earthengine.google.com/114bd893733f7d3dbd44c5722e3c03a6

シェア可能なはずです。


![image.png](https://qiita-image-store.s3.amazonaws.com/0/224794/3c6e6ded-7876-14bc-e382-a905c371728c.png)
tcpdumpの結果をS3に送る

# これはなに

pt-query-digestなどで利用するために、特定のサーバから数分間tcpdumpを観測し収集したいという要件があります。
このとき、その特定のサーバがオートスケーリングの対象であったりすると非常にめんどうなため、S3など、クラウドストレージにサクッと収集できると良いです。

なお要件の性質上厳密に全てのログを収集する必要はないものとします。

# どうするの
tcpdumpの結果を標準出力に吐き出し、それをawsコマンドのS3 Streamingで拾ってあげます。

# つまり

```shell-session
$ tcpdump  -W1 -G60 -w - | aws s3 cp - s3://bucket/path/dump.pcap
```

とすることで実現できます。

# 解説

> tcpdump  -W1 -G60 -w -

`-W1`はファイルローテートを1回。
`-G60`は60秒でローテート。
`-w`は続くファイルに出力。
`-`は標準出力です。

このtcpdumpのキャプチャ結果をパイプで繋ぎ、S3に送ります。

S3では、
`-`標準入力で受け取った結果を、S3の特定のパスへアップロードします。


# 使用例
現実的には以下のようにcronに設定することで毎日0時に5分間だけポート3306へのTCP通信内容をキャプチャできます。

```
0 0 * * * tcpdump -W1 -G300 -w - port 3306 | aws s3 cp -  s3://log-bucket/tcpdump/$(date +\%Y/\%m/\%d)/$(date +\%s)-$(hostname).pcap
```
Ancient C探訪記：ラベル編

 **おことわり**： この記事では「1975年頃のC言語」仕様を解説します。2017年現在のC言語仕様とは異なるため、あなたのC言語ライフには役立たないことを予めご承知おきください。

（本投稿は [Ancient C探訪記](https://qiita.com/yohhoy/items/6631443736ab779d3fbb) シリーズの一部です。）

続いては「ラベル(Label)」を見ていきます。goto文と組み合わせるアレです。アレ。


# Ancient Cのラベル
"[C Reference Manual][cman]" §9.11 Goto statement, §14.4 Labels からそれぞれ引用します。Ancient Cのgoto文には、ラベル(label)名 または **ラベルに評価される`int`型へのポインタ** を指定します。

> Control may be transferred unconditionally by means of the statement
>
> ```c
> goto expression ;
> ```
>
> The expression should be a label (§9.12, 14.4) or an expression of type "pointer to `int`" which evaluates to a label. It is illegal to transfer to a label not located in the current function unless some extra language provision has been made to adjust the stack correctly.

Ancient Cでは、「ラベルそれ自身は型(type)を持たないが`int`の配列型とみなす」「ラベル変数は`int`へのポインタ型として宣言する」という仕様になっています。なんという日和見主義。

> Labels do not have a type of their own; they are treated as having type "array of `int`". Label variables should be declared "pointer to `int`"; before execution of a `goto` referring to the variable, a label (or an expression deriving from a label) should be assigned to the variable.

```c:ancient-label.c
int *target;     /* ラベル変数を宣言(intへのポインタ型) */

target = label;  /* ラベル名をラベル変数へ代入 */

goto target;     /* ラベル変数が指す先のラベルにジャンプ */

label:
  /* 処理 */
```


## 標準規格との差分
標準規格ではgoto文にラベル名のみを指定でき、このような「ラベル変数」はサポートされません。同機能が無いことで困る人はあまり居ないかもしれませんが、ラベル変数を用いた [computed goto][computed-goto] というテクニックは、プログラミング言語の処理系（インタプリタや仮想マシン）実装では高速化に大きく貢献するそうです。

なお標準Cではありませんが、[GCC CコンパイラのGNU拡張][gnu-label]では少し違う構文でラベル変数を実現しています。

```gnuc-label.c
void *target;      /* ラベル変数を宣言(voidへのポインタ型) */

target = &&label;  /* &&演算子によりラベルを値として扱う */

goto *target;      /* ラベル変数が指す先のラベルにジャンプ */
```

適当に明日以降につづきます。

[cman]: https://www.bell-labs.com/usr/dmr/www/cman.pdf
[gnu-label]: https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html
[computed-goto]: http://dsas.blog.klab.org/archives/51393628.html
ラズパイでkeras その2

#概要
ラズパイでkerasやってみた。
gymのcartpoleやってみた。
kerasで強化学習やってみた。

#写真
![2017-12-21-153530_1024x768_scrot.png](https://qiita-image-store.s3.amazonaws.com/0/18104/1aa9e313-292e-ddd8-fdfe-68db2897654c.png)

#サンプルコード

```
import gym
import numpy as np
import random
from tensorflow.contrib.keras.python.keras.models import Model
from tensorflow.contrib.keras.python.keras.layers import *
from tensorflow.contrib.keras.python.keras import backend as K
from collections import deque
import matplotlib.pyplot as plt

def randf(s, e):
	return (float(random.randrange(0, (e - s) * 9999)) / 10000) + s;

def discount_rewards(r, gamma = 0.99):
	discounted_r = np.zeros_like(r)
	running_add = 0
	for t in reversed(range(0, len(r))):
		running_add = running_add * gamma + r[t]
		discounted_r[t] = running_add
	return discounted_r

def one_hot(index, categories):
	x = np.zeros((categories, ))
	x[index] = 1
	return x

def loss(advan):
	def f(y_true, y_pred):
		respons = K.sum(y_true * y_pred, axis = 1)
		policy_loss = -K.sum(advan * K.log(respons))
		return policy_loss
	return f

env = gym.make('CartPole-v0')
state = Input(shape = (4, ))
x = Dense(24)(state)
x = Dense(24)(x)
x = Dense(2)(x)
x = Activation('softmax')(x)
model_a = Model(state, x)
state = Input(shape = (4, ))
adv_input = Input(shape = (1, ))
x = model_a(state)
model_b = Model([state, adv_input], x)
model_b.compile(optimizer = 'adam', loss = loss(adv_input)) 
all_rewards = deque(maxlen = 100)
epsilon = 1
epsilonMinimumValue = 0.001
reward_trend = []
for i_episode in range(200):
	observation = env.reset()
	state_history, action_history, reward_history = [], [], []
	for t in range(200):
		env.render()
		state_history.append(observation)
		pred = model_a.predict(np.expand_dims(observation, axis = 0))[0]
		if (randf(0, 1) < epsilon):
			action = np.random.choice(len(pred), 1, p = pred)[0]
		else:
			action = np.argmax(pred)
		if (epsilon > epsilonMinimumValue):
			epsilon = epsilon * 0.999
		observation, reward, done, info = env.step(action)
		reward_history.append(reward)
		action_history.append(one_hot(action, 2))
		if done:
			reward_sum = sum(reward_history)
			reward_trend.append(reward_sum)
			print (i_episode, "Episode finished with reward {} {:.2f}".format(reward_sum, np.mean(all_rewards)))
			if reward_sum > 198:
				reward_sum += 100
			all_rewards.append(reward_sum)
			adv = discount_rewards(reward_history)
			state_history = np.array(state_history)
			action_history = np.array(action_history)
			model_b.train_on_batch([state_history, adv], action_history)
			break
plt.plot(reward_trend)
plt.savefig("gym26.png")
plt.show()

```

#結果

![gym26.png](https://qiita-image-store.s3.amazonaws.com/0/18104/a242d570-5d25-2f00-8d89-774eb45a0262.png)

以上。
Vagrant：vagrant sshで反応が無い場合の対処法備忘録

# 問題
`vagrant ssh`コマンドでいつものように開発マシンに入ろうとしたところ、全く反応が無くなった

```
$ vagrant ssh

# 反応無し
```

# version

## Host側
* windows 7
* cygwin 2.9.0-3
* virtualbox 5.2.2
* Vagrant 2.0.1
    * vagrant-vbguest 0.15.0
* guestadditions 5.2.2

恐らく全て最新です（2017年12月21日時点）

# Guest側
不明！

とりあえずguestadditionsは5.2.2で同じです。

# 原因
直前にvagrantやらvirtualboxやらGuestAdditionsやらを入れなおしていたので、その影響かと思います。

ggると下記のようなページがヒットします。結構同じ症状に悩んでいる人は多い様子。

version upで治るよみたいなコメントが多い気がします。

* [teratail - Vagrant upで仮想マシンが起動しない](https://teratail.com/questions/84506)
* [github - Vagrant up hangs forever on Windows 7, Vagrant 1.9.7, VirtualBox 5.1.22.r115126](https://github.com/mitchellh/vagrant/issues/8777)
* [stackoverflow - Vagrant 1.9.6 hangs on command “vagrant ssh”
](https://stackoverflow.com/questions/44884700/vagrant-1-9-6-hangs-on-command-vagrant-ssh)


また、`vagrant up`時に下記のような出力がありちょっと気になります。

```
$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Checking if box 'lamudi/centos-7.0' is up to date...
==> default: Clearing any previously set forwarded ports...
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
    default: Adapter 1: nat
    default: Adapter 2: hostonly
==> default: Forwarding ports...
    default: 3000 (guest) => 3000 (host) (adapter 1)
    default: 4000 (guest) => 4000 (host) (adapter 1)
    default: 22 (guest) => 2222 (host) (adapter 1)
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
    default: SSH address: 127.0.0.1:2222
    default: SSH username: vagrant
    default: SSH auth method: private key
    default: Warning: Connection reset. Retrying...
    default: Warning: Connection aborted. Retrying...
    default: Warning: Connection reset. Retrying...
    default: Warning: Connection aborted. Retrying...
    default: Warning: Connection reset. Retrying...
    default: Warning: Connection aborted. Retrying...
    default: Warning: Connection reset. Retrying...
    default: Warning: Connection aborted. Retrying...
==> default: Machine booted and ready!
[default] GuestAdditions 5.2.2 running --- OK.
==> default: Checking for guest additions in VM...
==> default: Configuring and enabling network interfaces...
    default: SSH address: 127.0.0.1:2222
    default: SSH username: vagrant
    default: SSH auth method: private key
==> default: Mounting shared folders...
    default: /vagrant => C:/projects/hoge
==> default: Machine already provisioned. Run `vagrant provision` or use the `--provision`
==> default: flag to force provisioning. Provisioners marked to run always will still run.

```

この部分が怪しいです。

```
default: Warning: Connection aborted. Retrying...
default: Warning: Connection reset. Retrying...
```




# 対処法
`vagrant ssh`を使わずにsshすることで無事入れました。

コマンド例

```
$ ssh -i /cygdrive/c/projects/hoge/.vagrant/machines/my_app/virtualbox/private_key -p 2222 vagrant@127.0.0.1
```

書式

```
ssh -i 鍵のパス -p ホスト側のポート ゲスト側のユーザー名@ゲスト側のipアドレス
```

# まとめ
根本的な解決には至っていません。。
csgraph has to be imported explicitly from SciPy 1.0.0


## Detail

You could import csgraph implicitly via `from scipy.sparse import*` until SciPy 0.19.1. However, in SciPy 1.0.0 (https://github.com/scipy/scipy/commit/0d173ca0ec85ae5366351382a8afc56b30ae0889#diff-8d4b6341c98c33c3eaf1d8c7e769cf5d), csgraph stuff is gone from `__all__` in scipy/sparse/\_\_init\_\_.py.
(`__all__` is explained in https://docs.python.org/3/tutorial/modules.html#importing-from-a-package .)
This caused that csgraph has to be imported explicitly (`from scipy.sparse import csgraph`).

## Conclusion
As codegolf, some of my codes use this snippet, so they will stop working when the judge servers are updated... :(
Chromium OSをビルド

# はじめに
Chromebookを触って見たいが、なかなか機会が有りませんでした。
そこで、ソースからビルドしてみることにしました。
折角なので、手順をシェルにしました。つまり、Ubuntuのクリーン環境でシェルを実行するとイメージができちゃいます!!

# 公式ドキュメント
http://dev.chromium.org/chromium-os
http://dev.chromium.org/chromium-os/quick-start-guide
上記の手順をシェルにしました。

# 環境
CPU 3GHz
メモリ 8G
HDD 100G
OS Ubuntu 14.04
クリーンな環境で実行して下さい。

# 手順
## フォルダの作成
お好みの名前のフォルダを作って下さい。

```
$ mkdir -p ${HOME}/chromiumos
$ cd ${HOME}/chromiumos
```

## シェルの配置
上記のフォルダに下記のシェルを配置して下さい。

```sh:build.sh
#!/usr/bin/env bash
sudo apt-get install -y git-core gitk git-gui subversion curl lvm2 thin-provisioning-tools python-pkg-resources python-virtualenv expect
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
export PATH=$PATH:$PWD/depot_tools
git config --global user.email "you@example.com"
git config --global user.name "Your Name"
(
echo '#!/bin/sh';
echo 'echo Defaults \!tty_tickets > $1';
echo 'echo Defaults timestamp_timeout=180 >> $1';
) > sudo_editor
chmod +x ./sudo_editor
sudo EDITOR=./sudo_editor visudo -f /etc/sudoers.d/relax_requirements
expect -c "
set timeout -1
spawn repo init -u https://chromium.googlesource.com/chromiumos/manifest.git
expect \"Enable color display in this user account (y/N)?\"
send \"y\n\"
"
repo sync
export BOARD=amd64-generic
cros_sdk -- ./build_packages --board=${BOARD}
cros_sdk -- ./build_image --board=${BOARD}
cros_sdk -- cros flash --board=${BOARD} file:///home/ubuntu/chromiumos.iso
```

## シェルの実行
実行権限を付与して、実行して下さい。

```
$ chmod 744 build.sh
$ ./build.sh
```
## イメージの確認
イメージはだいたい4Gくらいになります。
あとは、USBに焼いたりして、PCでブートして下さい。

```
$ ls ${HOME}/chromiumos/chroot/home/ubuntu/chromiumos.iso
```

## GitHub
上記を保存しておきました。
https://github.com/maedamikio/public/tree/master/chromiumos

# おわりに
とりあえず、起動、ログイン等はできました。
ただ、WiFiのドライバーが対応していなく、有線接続になりました。本格的に利用するのであれば、色々大変だと思います。
なので、Chromebookの雰囲気を感じたい人が対象となります。
どんなメソッドにもコールバックをつけたい (Ruby on Rails)

# TL;DR

`after_save` などRails(ActiveRecord)のコールバックメソッドと同じようなテイストでメソッド呼び出しに対してコールバックを設定できるようにする方法について。

# ケース

[Nazrin](https://github.com/tsuwatch/nazrin)というCloudsearchクライアントgemがあります。

説明は作者の方の記事に譲ります。
[Amazon CloudSearch用Gem、Nazrinをつくった](https://qiita.com/tsuwatch/items/8424ee0722d723186839)

このgemを使うと、モデルのインスタンスに `add_to_index` (Cloudsearchにレコードを登録する)などのメソッドが生えます。
これらのメソッドが実行されたあとに追加で処理を行いたいなぁという用事があり、 `after_save` コールバックと同じノリで `after_add_to_index` コールバックなど作れないかなぁと思いたったのです。

まぁ、他にもやりようはいくらでもあるのですがせっかくなのでCallbackクラスなどを活用して実現してみようと。

# 実装

## 目標

このようなクラスがあります。

```ruby
class SampleKlass
    def foo
     puts "foo"
    end
end
```

このクラスの `foo` メソッドに対して `after_foo` コールバックをセットすることを目標としましょう。

## コールバッククラス

これは本題から少しそれるのですが、コールバック処理が複雑になる場合はコールバック処理をコールバッククラスに分離するとよいそうです。もっと知りたい方は、こちらをどうぞ。四年前の記事ですが、とても参考になります。

[てめえらのRailsはオブジェクト指向じゃねえ！まずはCallbackクラス、Validatorクラスを活用しろ！](https://qiita.com/joker1007/items/2a03500017766bdb0234)

コールバッククラスには、セットしたいコールバックの種類(今回の場合は `after_foo` )と同名でメソッドを定義しておきます。

```ruby
class SampleCallbackKlass
  def after_foo(record)
    puts "after_foo"
  end
end
```

## フックを起こす

`foo` メソッドは現状実行されてもその実行が感知されることはありません。コールバックを起こすには、 `foo` が実行されたよ！という通知(フック)を飛ばして上げる必要があります。通知をあげるにはこのようにします。

```ruby
run_callbacks(:hoge) do
  hoge
end
```

`run_callbacks` メソッドの引数にフックの名前、ブロック引数に実行したい処理を渡します。メソッド名とフック名は同一でなくてもかまいません。ここで注意すべきは `after_hoge` の `hoge` はフック名としての `hoge` ということです。

今回は、 `foo` メソッドを持つどんなクラスにも対応可能にするため、includeすると `foo` メソッドがフックを飛ばすようになるモジュールを作ります。

```ruby
module SampleHooks
  extend ActiveSupport::Concern

  included do
    method = :foo

    orig = "#{method}_without_hook".to_sym

    alias_method orig, method

    define_method(method) do |*args, &block|
      run_callbacks(method) do
        send(orig, *args, &block)
      end
    end
  end
end
```

アラウンドエイリアスを使い、 `foo` メソッドがフックを飛ばすようにしました。

## コールバックをセットする

では、実際にフックを受けてコールバックが実行されるようにしましょう。
以下の二行をSampleKlassの定義に追加します。

```ruby
define_callbacks :foo, scope: %i[kind name]
set_callback :foo, :after, SampleCallbackKlass.new
```

一行目の `define_callbacks` はクラスに `:after_foo ` コールバックをサポートさせるおまじないで、二行目の `set_callback` が具体的にそのコールバックはどんな処理なのか割り当てるおまじないです。
`scope: %i[kind name]` を省略すると、コールバックの名前が `before` とか `after` になってしまい何に対するコールバックなのかわかりづらくなります。なので、つけたほうがよいでしょう。

# 完成

```ruby
require 'active_model'
require 'active_support'

module SampleHooks
  extend ActiveSupport::Concern

  included do
    method = :foo

    orig = "#{method}_without_hook".to_sym

    alias_method orig, method

    define_method(method) do |*args, &block|
      run_callbacks(method) do
        send(orig, *args, &block)
      end
    end
  end
end

class SampleCallbackKlass
  def after_foo(record)
    puts "after_foo"
  end
end

class SampleKlass
  def foo
    puts "foo"
  end

  extend ActiveModel::Callbacks
  
   # fooメソッドの定義後じゃないとダメ
  include SampleHooks
  
  define_callbacks :foo, scope: %i[kind name]
  set_callback :foo, :after, SampleCallbackKlass.new
end

s = SampleKlass.new
s.foo
```

以上のファイルを実行すると、

```
foo
after_foo
```

と表示されるはずです！
`foo`　のあとに `after_foo` がちゃんと実行されました。
Quilting Lining is composed of a accumulation

After the accomplishing on the changes, a assay action is bald to appraise the outcome. You should consistently assay the outcomes to ensure whether they are benign at all. You should consistently allocution with the advisers on the assembly line. They accomplish or adviser the machines everyday, and get the aboriginal duke after-effects on the aftereffect of interlining online writing like alloyed interlining, non-woven interlining and Interlining China .

The fabric, as may be seen, is an accustomed apparent single-ply braid and is formed, as will be accepted by those accomplished in the art, by

interchanging the wefts of horsehair and linen.

The ambit adumbrated are approximate and are artlessly allegorical of the mannerin which the bolt may be cut for use.

Fusing altitude : fusing altitude includes bonding temperature, columnist time and pressure, three elements of alternation will creat affiliation aural assertive limits. If the temperature and burden increasing, the acute time is about short, and carnality versa. Top temperature or continued acute time will aftereffect in damaging the achievement of fabric, aswell simple to change color.

The appulse of acumen is apparent in every date of the Bergen Brunswig's archetypal to beforehand chump success. It is capital to accrue aggregate below ascendancy and be cost-effective throughout the accomplished process. Suppliers should be fair in the bazaar admission to lath basal akin services. 

Quilting Lining is composed of a accumulation or several groups of alongside yarns are appropriately ranged on the knitting needles, and alloyed knitting alternating the longitudinal direction. In generally, the burning and addendum of bastardize knitted fabrics are abate than the those of weft, absolutely the adherence of anatomy and actualization are better.

See more at http://www.interlining-factory.com/
Passenger Elevator is a connected focus of innovation

Passenger Elevator accept to aswell accept affirmation warnings acquaint axial to acquaint the cartage what to do if adeptness goes out. Inform the cartage to actuate any all-overs systems appropriate away, and never force the doors attainable to escape. 

Adding an elevator to your home is one way to achieve it added accessible. However, as residential elevators become added affordable, a new trend has bent on: custom home elevators. These yield the basal functions of a residential elevator and action a customized design. In abounding cases, the custom architectonics matches the autogenous of the home and blends in seamlessly. 

As abacus an elevator increases the all-embracing bulk of the home or building, installing one is beneficial, and accepting a customized architectonics allows it to accept like it was congenital in the anatomy originally.

Calmness and cooperation accept to be ensured to abstain any panic, and cartage accept to not do any attempts to escape at all. Architectonics administrators accept to consistently be attainable to acquaint with entrapped elevator cartage in case of adeptness abeyance so that elevator technicians can yield allegation appropriate abroad in accouterment a safe avenue for them.

A Quick Journey

Humans tend to be bedeviled with time. We are advised backward if we admission late, anticipation of as careless if we blot too abundant time on a task. And for a lot of of us, it's accustomed to ambition any time in a bedfast amplitude like an elevator to be limited. 

No admiration then, that accretion the dispatch of commuter elevators is a connected focus of innovation, with abounding engineers advancing up with admirable plans. It is attainable these canicule for elevators to be so fast they chase through an elevator shaft at a bulk of 3,313 all-overs per minute.

But, because the bulk for abacus the Panoramic Elevator is aural adeptness for many, the next footfall up for those searching for accessibility and affluence is a custom home elevator. In general, custom home elevators are advised amid the homeowner and manufacturer.

See more at http://www.dskelevator.com/
ブラウザ上でtype=fileのinputでアップされた画像の縦横サイズを取得する

入力画面で、アップされた画像に対するパラメータを設定する機能を実装することになりそうなので予備調査。

type="file"にアップされたファイルの画像サイズを取得するには、
FileReaderオブジェクトのreadAsDataURLを使って読みこんだデータをImageオブジェクトのsrcに入れてやればサイズが取得できるみたい。

```html
<script>
  function fileload() {
    if ( ! file.files[0] ){
      return;
    }   
    image = new Image();
    reader = new FileReader();
    reader.onloadend = function() {
      image.src = reader.result;
      image.onload = function() {
        result = {width: image.naturalWidth, height: image.naturalHeight};
        console.log(result);
      }   
    }   
    reader.readAsDataURL(file.files[0]);
  }   
</script>
<input type="file" id="file" onchange="fileload()">
```

参考:
[JavaScriptで縮小画像の作成](http://am-yu.net/2014/03/16/javascript%E3%81%A7%E7%B8%AE%E5%B0%8F%E7%94%BB%E5%83%8F%E3%81%AE%E4%BD%9C%E6%88%90/)
[FileReader.readAsDataURL()](https://developer.mozilla.org/ja/docs/Web/API/FileReader/readAsDataURL)
[Image](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/Image)


# 追記：

コメントで @gtk2k さんに教えて頂きました。

```html
<script>
  function fileload() {
    if ( ! file.files[0] ){
      return;
    }
    image = new Image();
    image.onload = function() {
      result = {width: image.naturalWidth, height: image.naturalHeight};
      console.log(result);
    }
    image.src = URL.createObjectURL(file.files[0]);
  }
</script>
<input type="file" id="file" onchange="fileload()">
```

URL.createObjectURLでもとれるようです。
こちらの方が短くてシンプルですね。
Do you ache from decrepit teeth  Bucket Adapters

In all uses of Bucket Adapters it is important to accomplish abiding it does not get ingested as it is absolute baneful to the body. It is aswell recommended to bathe your aperture out afterwards words and use a cranberry abstract to accomplish the audible aftertaste go away.

These methods about will yield a bit of time to apprehension results. If you ambition to blanch your teeth quickly, I'd acerb acclaim appliance the ability beneath and actuate your Chargeless whitening kit that already contains the safe and able ingredients.

Do you ache from decrepit teeth? If so afresh you're in fact not alone. Bags of individuals do not celebrity white teeth either but aswell don't accept the agency to bend out lots of money in dentist bills which is why they attending for bargain teeth whitening solutions. Accepting bedimmed teeth is rather accepted abnormally for those who smoke, but it abiding makes a big consequence on your all-embracing actualization and how you feel about yourself.

Appliance harder copse ash.

Hard copse ash contains potassium hydroxide which can admonition blanch your teeth. You can either administrate it anon assimilate your teeth appliance a toothbrush, or you can mix it with your toothpaste. Potassium hydroxide aswell helps to abolish adamant plaque. However, you should not use harder copse ash for continued periods of time aback accepted use can abate the tooth enamel.

A Arrangement To The Dentist - Dentists are accomplished professionals who knows in fact what to do and how to do it to abolish even the toughest of stains from your teeth. If you accept a few hundred dollars to bend out afresh this would be the best option. However, that would go adjoin our capital algid - to blanch your teeth afterwards spending a fortune. Appropriately we accept to attending at added options available.

Fork Teeth , and a lot of humans will adjure up an angel of an babyish bawl in the accoutrements of balked parents who accept approved everything, and are accommodating to do annihilation (safe of course!) to affluence their little one's pain.

See more at http://www.xinke-casting.com/
Angularを簡単にビルドして無料でWeb公開する

FirebaseとAngularとParcelを使って、
Angularで実装 -> ビルド -> デプロイ -> Webサイト公開
まで全部やってみよう

## Firebase
「firebase hosting」でググると画像付きで詳しい環境構築が紹介されているので、ここでは省略します

事前に以下を準備する必要があります
■ Nodeをインストール（Yarnを使う場合はYarnもインストール）
■ Googleアカウントの取得
■ 以下のコンソールから新規プロジェクトの作成
https://console.firebase.google.com

`firebase-tools`を使えば、以下のコマンドだけで作成したHTMLを公開することができます

```sh
yarn global add firebase-tools

firebase login

firebase init
 - １つ目の選択肢は「Hosting」を選ぶ
 - ２つ目の選択肢は「自分が作ったFirebaseプロジェクト」を選ぶ

firebase deploy
```

```json:firebase.json
{
  "hosting": {
    "public": "dist"
  }
}
```

`firebase.json`と同階層に`dist`ディレクトリを作成し、以下のindex.htmlを置く

```html:index.html
<h1>Hello Firebase!</h1>
```

## Angular

https://github.com/kurosame/flashcard

Angularの学習で単語帳アプリ作ろうと思ってるので
flashcardって名前になってます

今はHello Worldを出すだけのコードです

## Parcel
最近話題になったモジュールバンドラー
webpackやFuseBoxと違い設定ファイルが不要です

```sh
yarn add --dev parcel-bundler
```

Hello Worldを出すぐらいのAngular実装であれば、以下のパッケージだけでビルドまでできます

```json:package.json
"dependencies": {
  "@angular/common": "^5.1.1",
  "@angular/compiler": "^5.1.1",
  "@angular/core": "^5.1.1",
  "@angular/platform-browser": "^5.1.1",
  "@angular/platform-browser-dynamic": "^5.1.1",
  "rxjs": "^5.5.5",
  "zone.js": "^0.8.18"
},
"devDependencies": {
  "parcel-bundler": "^1.2.1",
  "typescript": "^2.6.2"
}
```

ビルド関連で必要なのは`parcel-bundler`と`typescript`だけです
Hello World出すだけだと不要ですが、`parcel-plugin-typescript`もそのうち必要になるでしょう

```json:package.json
"scripts": {
  "start": "parcel index.html",
  "build": "parcel build index.html --public-url .",
  "deploy": "firebase deploy"
}
```

`parcel`
開発向けのビルドでHMRで起動します

`parcel build`
本番向けのビルドでminifyしてdist配下にbundleファイルを出力します

今まで`webpack.config.js`に色々書いたり、`webpack-dev-server`使ったりしてたのが嘘みたいですね

webpackとの違いで、デフォルト実行時に`.cache`ディレクトリができます
おそらくwebpack.DllPluginで作られる`manifest.json`のような感じで依存性をマッピングしておいて、
コンパイルを高速化するものだと思います

webpackなどより後発のツールだけあって、必要なものがビルドインされているのは良いですね

最後に上のnpm-scriptsの以下を実行して、サイトをデプロイする

```sh
yarn deploy
```

おわり

サイトがちゃんとデプロイされているか確認してみましょう
https://[自分のFirebaseのプロジェクトID].firebaseapp.com

## 感想
すごいかんたん
モダンなフロントエンドの言語で開発して、Web公開するのはこれが最短ではなかろうか

ただ、他のParcelの記事でも言われてますが、
商用や大規模プロジェクトでの利用は避けたほうがいいでしょう

今回みたいに学習や遊びでやる分にはこれで十分です
C++ Builder XE4, 10.2 Tokyo > エラーメッセージウィンドウ > エラーメッセージを別ソフトから取得する

```txt:動作環境
C++ Builder XE4
RAD Studio 10.2 Tokyo Update 2 (追記: 2018/01/05)
```

### 関連

[C++ Builder > メモリが足りません (Abnormal Program Termination) > 再現方法](https://qiita.com/7of9/items/5b64b5ad82ce0e2119cf)

### 処理

エラーメッセージが表示されている状態で、そのエラーメッセージを別ソフトから取得する。

参考: https://stackoverflow.com/questions/27260843/get-textbox-value-and-show-it-as-messagebox-winapi
> answered Dec 2 '14 at 23:52
FelipeDurar

該当のHWND値をどう取得するか。

Microsoft Spy++で確認したところ、エラーメッセージは下記のようになる。

- 'OK' Button
- '' Static
- 'メモリが足りません.' Static

方針としては、「Staticの次のStatic」を取得する。

参考: [Zオーダーのウインドウを取得](http://blog.goo.ne.jp/masaki_goo_2006/e/7421fd026d0aa6b375fbbd8dedeea881)

### code

```Unit2.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit2.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm2 *Form2;
//---------------------------------------------------------------------------
__fastcall TForm2::TForm2(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm2::Button1Click(TObject *Sender)
{
	HWND winhwnd;

	winhwnd = FindWindow(NULL, L"Project1");
	if (winhwnd == NULL) {
		return;
	}

	HWND msghwnd = FindWindowEx(winhwnd, NULL, L"Static", NULL);
	HWND nexthwnd = GetWindow(msghwnd, GW_HWNDNEXT);

	HWND target = nexthwnd;

	int len = GetWindowTextLength(target) + 1;
	wchar_t text[100]; // 100: 任意の長さ
	GetWindowText(target, text, len);
	ShowMessage(text);
}
//---------------------------------------------------------------------------
```

### 実行例

- [C++ Builder > メモリが足りません (Abnormal Program Termination) > 再現方法](https://qiita.com/7of9/items/5b64b5ad82ce0e2119cf)でビルドしたProject1.exeを実行する。
- Project1のフォーム上のボタンを押して、エラーメッセージを表示しておく
- 上記のコードをビルドしたソフトProject2.exeを実行する
- Project2のフォーム上のボタンを押す

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/d8bb7027-505d-eadb-db8a-d4809333a6dc.png)

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/1f770d37-58ca-5482-5989-3ae6e6eac3f8.png)

### 10.2 Tokyo

10.2 Tokyoでも動作した。
エラーメッセージは異なる。

参考: [C++ Builder 10.2 Tokyo > Error: OleStr型からDate型へのバリアント型変換はできません。](https://qiita.com/7of9/items/d95e8dbadb0858b06d3d#_reference-b0dc31de07a6da05a9be)

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/b06f1d22-010a-61cb-8b51-df510c16841c.png)
Linuxコマンドメモ

```ruby:圧縮
tar zcvf 〇〇.tar.gz 〇〇
```

```ruby:解凍
tar xvf 〇〇.tar.gz
```

```ruby:圧縮
zip -r 〇〇.zip .
```
```ruby:解凍
unzip 〇〇.zip
```

```ruby:検索
find . -type f | xargs
```

```ruby:検索
grep "〇〇"
```

```ruby:検索
find . -name "〇〇" -ls
```

```ruby:ファイルのアップロード(FTP)
curl -T 【送信ファイル】 -u 【ユーザー】:【パスワード】 --ftp-create-dirs -k ftp://【サーバー名】/【送信先フルパス】
```
```ruby:ファイルのダウンロード(FTP)
curl -O ftp://【ユーザー】:【パスワード】@【サーバー名】/【ファイルパス】
```

```ruby:ファイルのダウンロード(FTP2)
wget ftp://【ユーザー】:【パスワード】@【サーバー名】/【ファイルパス】
```

```ruby:フォルダサイズの求め方
du -s -m 【フォルダ名】
```
美術の人が考える Haskell

sketchで作成しました。
普段日銭を稼ぐためwebデザインをしておりますが本業は油絵です。
Haskell初心者なので間違っている部分があるかもしれません。
数学的なこと・エンジニア的な部分は本当に難しく、単語ひとつ理解するのに非常に時間がかかります。

アーティストとエンジニアは似ている部分が数多く見受けられます。
美しいものを大切にする気持ちがとても強いところ。
何度も試行錯誤を繰り返し、形を研ぎ澄ましていくところ。
世の中の「既存」から外れた部分に価値を見出すところ。

これからも、Haskellをゆっくりとですが気長に勉強していきたいと思います。
美術もHaskellも、どちらも美しいです。




----




![は.png](https://qiita-image-store.s3.amazonaws.com/0/206725/c873728e-e9c7-5fe1-532f-98f56c65219e.png)

----

![ハ.png](https://qiita-image-store.s3.amazonaws.com/0/206725/86d2f792-1fb2-d650-78b1-6d68387a7567.png)

----

![す.png](https://qiita-image-store.s3.amazonaws.com/0/206725/42e3092f-0c83-787b-7048-4161cadf9150.png)

----

![ス.png](https://qiita-image-store.s3.amazonaws.com/0/206725/1cbb7f9c-c2c6-95cc-e358-0371dd1a9833.png)

----

![け.png](https://qiita-image-store.s3.amazonaws.com/0/206725/182507af-3346-6231-9b8c-d902b97f7840.png)

----

![ケ.png](https://qiita-image-store.s3.amazonaws.com/0/206725/400ac92b-72f8-ead6-608e-b799a9fe20e3.png)

----

![る.png](https://qiita-image-store.s3.amazonaws.com/0/206725/d24610f6-3719-6948-cdc1-a0b22ce09412.png)

----

![ル.png](https://qiita-image-store.s3.amazonaws.com/0/206725/5a00df6a-8244-0a76-660a-c3ef59f51509.png)

以上で 美術の人が考えるHaskell を終わります。
GAEコマンド関係まとめ with Golang

自分への備忘録。日々更新していく予定

## Setup

gcloud, goapp を使えるようにする。　　
ベンダリングしたいのでgoappは必須。

https://gist.github.com/voluntas/892570de9c38e9b3a4170c5728ba72ed#go-sdk

## プロジェクト変更

```
$ gcloud config set project ${project_id}
$ gcloud auth login # これはいらないかも？
$ gcloud auth application-default login #これをしないと、ローカルのGAEサーバーが自動でAPI叩くときに　Authorization Error を吐いてしまう
```

## 開発用ローカルサーバー起動

```
$ goapp serve path/to/app.yaml 
```

## デプロイ

```
$ appcfg.py -A ${project_id} -V ${version_name} update path/to/app.yaml
```

${version_name}　は `1.0.1` とは書けない。.が禁止されている。 `v1-0-1` とでも書くべし。　　
1プロジェクトに複数サービスを用意する場合のことは、今後調べる。。
マイニングと譲渡を改めてやってみる（ethereum3）


前回はこちら。[テストネットワークで、Ethereumを使ってみる](http://qiita.com/joji/items/9b8e111ae782281cd468 "テストネットワークで、Ethereumを使ってみる。")

ユーザーを作成する

```javascript:geth_console
personal.newAccount("user1")
```

```:shell-session
"0x3b1a887c19bd3e39e926121db232f9376f2aebed"
```

```javascript:geth_console
personal.newAccount("user2")
```

```:shell-session
"0xe2a98f7bfc8c08fffc8fdfbabc74e80a9ccb0c6f"
```

```javascript:geth_console
personal.newAccount("user3")
```

```:shell-session
"0xa7732a8a03be095a4c51dd1174e1dc531b67751b"
```

EtherBaseをuser1に変更

```javascript:geth_console
miner.setEtherbase("0x3b1a887c19bd3e39e926121db232f9376f2aebed")
```

check

```javascript:geth_console
eth.coinbase
```

```:shell-session
"0x3b1a887c19bd3e39e926121db232f9376f2aebed"
```

マイニング

```javascript:geth_console
miner.start(1)
```

マイニング停止

```javascript:geth_console
miner.stop(1)
```

user1の残高を確認

```javascript:geth_console
web3.fromWei(eth.getBalance("0x3b1a887c19bd3e39e926121db232f9376f2aebed"), "ether")
```

この値は、マイニングをしている時間による

```:shell-session
35
```

EtherBaseをuser3に変更。user3がマイニングをするということ。

```javascript:geth_console
miner.setEtherbase("0xa7732a8a03be095a4c51dd1174e1dc531b67751b")
```

check

```javascript:geth_console
eth.coinbase
```

```:shell-session
"0xa7732a8a03be095a4c51dd1174e1dc531b67751b"
```

###user1からuser2に送金してみる

ロック解除

```javascript:geth_console
personal.unlockAccount("0x3b1a887c19bd3e39e926121db232f9376f2aebed")
```

送金

```javascript:geth_console
eth.sendTransaction({from: "0x3b1a887c19bd3e39e926121db232f9376f2aebed", to: "0xe2a98f7bfc8c08fffc8fdfbabc74e80a9ccb0c6f", value: web3. toWei(10, "ether")})
```

pending transactionをチェック

```javascript:geth_console
eth.pendingTransactions
```

```shell-session
[{
    blockHash: null,
    blockNumber: null,
    from: "0x3b1a887c19bd3e39e926121db232f9376f2aebed",
    gas: 90000,
    gasPrice: 20000000000,
    hash: "0x43f44eee8875d8ece62a5c9cc1e98a79ce7081b6e618e7d732dc7d879fb0d768",
    input: "0x",
    nonce: 0,
    r: "0xc489c97a13a39d8d3e95ad021990451f753460b731cf8bc7e9bbd115e8a82728",
    s: "0x66e66cb65f4dc7cbcde5663e5dabc80390ee25e58311e973186da7aa3a6df0e4",
    to: "0xe2a98f7bfc8c08fffc8fdfbabc74e80a9ccb0c6f",
    transactionIndex: null,
    v: "0x1b",
    value: 10000000000000000000
}]
```

マイニング

```javascript:geth_console
miner.start(1)
```

ペンディングが空であることを確認

```javascript:geth_console
eth.pendingTransactions
```

```shell-session
[]
```

マイニング停止

```javascript:geth_console
miner.stop()
```

user1の残高を確認

```javascript:geth_console
web3.fromWei(eth.getBalance("0x3b1a887c19bd3e39e926121db232f9376f2aebed"), "ether")
```

10.00042が減っている。

```shell-session
24.99958
```

user2の残高を確認

```javascript:geth_console
web3.fromWei(eth.getBalance("0xe2a98f7bfc8c08fffc8fdfbabc74e80a9ccb0c6f"), "ether")
```

10が増えている。

```shell-session
10
```

user3の残高を確認

```javascript:geth_console
web3.fromWei(eth.getBalance("0xa7732a8a03be095a4c51dd1174e1dc531b67751b"), "ether")
```

```shell-session
20.00042
```

user1; - (10 + 0.00042)
user2; +10
user3; +20 + 0.00042
user3の20はマイニング報酬です。(5 ether/block)
0.00042は、トランザクションの手数料になります。