OmniAICreator/Qiita-1.07M huggingface dataset:
C++ Builder XE4 > 違い > this->ScaleBy(100 / s_curFactor, 100); と this->ScaleBy(100, s_curFactor * 100); > 前者では計算誤差が生じる

```txt:動作環境
C++ Builder XE4
```

### 関連

- [C++ Builder XE4 > geometry > 右配置のTEditのフォントサイズを拡大時、左配置のTChartを残りスペースで描画するサイズに落とす > ScaleBy()での処理](https://qiita.com/7of9/items/cc15ee09f96652409595)

上記にて作業中、IDEのバグによる誤差の蓄積に気づいた。

今後、同じ問題に遭遇するかもしれないので、記事として切出す。

### 症状と実装

- フォントサイズを変更可能なソフト
- ScaleBy()を使う
- フォントサイズ変更を繰返すことで誤差が蓄積される
    - TButtonの横幅が狭くなる

```Unit1.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------

enum {
    FONT_SMALL = 0,
    FONT_MEDIUM,
    FONT_LARGE,
    FONT_EXTRA_LARGE,
    FONT_HUGE,
};

static float s_curFactor = 1.0; // 拡大率
static int s_cntChangeSize = 0; // フォントサイズ変更回数

__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::CMB_fontSizeChange(TObject *Sender)
{
	s_cntChangeSize += 1;
	Label1->Caption = IntToStr(s_cntChangeSize);

//-----------
	int preH = this->Height;
	int preW = this->Width;

	this->ScaleBy(100 / s_curFactor, 100); // 拡大率を使って拡大するため、一旦1.0の倍率に戻す
//	this->ScaleBy(100, s_curFactor * 100); // 拡大率を使って拡大するため、一旦1.0の倍率に戻す

	switch(CMB_fontSize->ItemIndex){
	case FONT_SMALL:
		s_curFactor = 1.00; // 結果を見て調整する
		break;
	case FONT_MEDIUM:
		s_curFactor = 1.20; // 結果を見て調整する
		break;
	case FONT_LARGE:
		s_curFactor = 1.40; // 結果を見て調整する
		break;
	case FONT_EXTRA_LARGE:
		s_curFactor = 1.60; // 結果を見て調整する
		break;
	case FONT_HUGE:
		s_curFactor = 1.80; // 結果を見て調整する
		break;
	}

	this->ScaleBy(100 * s_curFactor, 100);

	// 元の高さ、幅に戻すことで、パネルのコンポーネントのサイズだけを拡大できる
	// (結果として、TChartは小さくなる)
	this->Height = preH;
	this->Width = preW;
}
//---------------------------------------------------------------------------
```

### 再現方法

- 1. フォントサイズをHugeにする
- 2. フォントサイズをSmallにする
- 3. 手順1に戻る (s_cntChangeSizeが16になるまで)

![2018-10-22_17h27_23.png](https://qiita-image-store.s3.amazonaws.com/0/32870/36e06b57-c6d4-717b-c450-854471155963.png)

ButtonのBの文字が半分消えてしまう。

### 対策

対策を行うが、以下を検討した。

- IDEのバージョンアップ時にも問題がないような対策

バージョン固有の不具合対応は、将来のIDEバージョンアップ時にはまる。
どのバージョンでも問題がない実装が望ましい。

下記の方法で対処できることを見つけた。

```cpp
//	this->ScaleBy(100 / s_curFactor, 100); // 拡大率を使って拡大するため、一旦1.0の倍率に戻す
	this->ScaleBy(100, s_curFactor * 100); // 拡大率を使って拡大するため、一旦1.0の倍率に戻す
```

![2018-10-22_17h31_17.png](https://qiita-image-store.s3.amazonaws.com/0/32870/0f81994e-af5e-a706-f1f7-6781ac26951a.png)

ButtonのBの文字表示に問題がなくなった。
ROC sample

お勉強させていただきました。

```{r}

library(mlbench);library(caret);library(xgboost)


#ROC curve

n=2000

k=10

dat=mlbench.spirals(n,cycles=1.2,sd=0.16)

x=dat$x;y=dat$classes

data=data.frame(x1=x[,1],x2=x[,2],class=as.numeric(as.character(y)))

data$class=data$class-1


iris.train<-data 
iris.test<-data

y <- iris.train[,3] # 目的変数

train.x<-iris.train[,1:2]
x <- rbind(train.x,iris.test[,1:2]) 
x <- as.matrix(x)

trind <- 1:length(y) 
teind <- (nrow(train.x)+1):nrow(x) 
set.seed(131) 
param <- list("objective" = "multi:softprob",
              "eval_metric" = "mlogloss", 
              "num_class" = 2 
              )

k<-round(1+log2(nrow(train.x)))
cv.nround <- 100 #search
bst.cv <- xgb.cv(param=param, data = x[trind,], label = y,  nfold = k, nrounds=cv.nround)

set.seed(131)
nround <- 20
# モデルの構築
bst <- xgboost(param=param, data = x[trind,], label = y, nrounds=nround)
pred <- predict(bst,x[teind,]) # モデルを使って予測値を算出
pred <- matrix(pred,2,length(pred)/2) # 今回は2クラスあるので
pred <- t(pred)
colnames(pred)=c("sign0","sign1")

iris.test=cbind(iris.test,pred)

iris.test=iris.test %>% mutate(predict=ifelse(sign0>sign1,0,1)) %>% rename(sign=class)

#ROC 曲線,PR 曲線

ROC=data.frame(c=seq(0,1,0.01),FPR=0,TPR=0,precision=0)

for(j in 1:nrow(ROC)){

c=ROC$c[j]

iris.result_0=iris.test %>% filter(sign==0 & sign1>c)

iris.result_1=iris.test %>% filter(sign==1 & sign1>c)

TP=iris.test %>% filter(sign==1 & sign1>c)

FP=iris.test %>% filter(sign==0 & sign1>c)

precision=nrow(TP)/(nrow(TP)+nrow(FP))

FPR=nrow(iris.result_0)/length(iris.test$sign[iris.test$sign==0])

TPR=nrow(iris.result_1)/length(iris.test$sign[iris.test$sign==1])

ROC$FPR[j]=FPR;ROC$TPR[j]=TPR;ROC$precision[j]=precision

}

plot(ROC$FPR,ROC$TPR,type="o",main="ROC")

plot(ROC$TPR,ROC$precision,type="o",main="PR")

AUC_data0=iris.test %>% filter(sign==0)

AUC_data1=iris.test %>% filter(sign==1)

count=0

for(j in 1:nrow(AUC_data1)){

value=AUC_data1$sign1[j]

count=count+sum(value>AUC_data0$sign1)

}

AUC=(1/(length(iris.test$sign[iris.test$sign==0])*length(iris.test$sign[iris.test$sign==1])))*count

p_AUC=data.frame(c=seq(0,1,0.01),p_AUC=0)

for(i in 1:nrow(p_AUC)){
  
c=p_AUC$c[i]

count=0

for(j in 1:nrow(AUC_data1)){
  
value=AUC_data1$sign1[j];

count=count+sum(value>AUC_data0$sign1[AUC_data0$sign1>c])
  
}

p_AUC$p_AUC[i]=(1/(length(iris.test$sign[iris.test$sign==0])*length(iris.test$sign[iris.test$sign==1])))*count

}


```
movie api활용해서 react 어플리케이션 제작

## react state 변경하기
```react:qiita.rb
import React, { Component } from 'react';
class App extends Component {
  state = {
    title : 'onemore movie'    
  }

  // after 3 second chante the state
  _renderMovie() {
    const title = this.state.title;
    setTimeout(() => {
      this.setState({
        title : 'hi sean'
      })
    },3000)
    return title;
  }

  render() {
    const {title} = this.state;
    return (
      <h1>{title ? this._renderMovie() : "app-loading"}</h1>
      
    );
  }
}

export default App;
```

```react:qiita.rb
import React, { Component } from 'react';
import Movie from './Movie'

class App extends Component {
  state = {}
  // component 가 mount 된 후 아래 함수를 불러온다.
  componentDidMount() {
    this._getMovie()
  }

  // after 3 second chante the state
  _renderMovie = () => {
    const movies = this.state.movies.map(
      movie =>
          <Movie 
          title={movie.title} 
          poster={movie.small_cover_image} 
          key={movie.id} 
          />
    )
    return movies; // map으로 돌린것을 리턴함
  }
  //javascript 의 새로운 컨셉 promise
  _getMovie = async() => {
    const movies = await this._callApi();
    this.setState({
      movies
    })
  }
  // ajax 를 이용해서 영화 api를 가져온다
  _callApi() {
    return(
      fetch("https://yts.am/api/v2/list_movies.json?sort_by=download_count")
      .then(response => response.json())    
      .then(json => json.data.movies)
      .catch(err => {
        console.log(err)
      })
    )
  }

  render() {
    const {movies} = this.state;
    console.log({movies});
    return (
      <div className={movies ? 'app' : 'app-loading'}>
      <h1>{movies ? this._renderMovie() : "Loading"}</h1>
      </div>
      
    );
  }
}

export default App;
```

## what is different?
많이 헤맸다 코드를 좀 더 정확하게 자세하게 볼 필요성이 있음

```react:qiita.rb
  _renderMovie = () => {
    const movies = this.state.movies
    movies.map(movie =>
      <Movie 
      title={movie.title} 
      poster={movie.small_cover_image} 
      key={movie.id} 
      />
    )
    return movies; // map으로 돌린것을 return 하는것이 아니다.
  }

  _renderMovie = () => {
    const movies = this.state.movies.map(
      movie =>
          <Movie 
          title={movie.title} 
          poster={movie.small_cover_image} 
          key={movie.id} 
          />
    )
    return movies; // map으로 돌린것을 리턴함
  }
```
react-beautiful-dnd パフォーマンス最適化

## まえがき
React で Drag and Drop をしたかったので、[atlassian/react-beautiful-dnd](https://github.com/atlassian/react-beautiful-dnd) を使った。
Trello みたいにヌルヌル dnd できるのですごい。[Github Star](https://www.timqian.com/star-history/#atlassian/react-beautiful-dnd) の伸びも React ライブラリにしてはすごい。
![サンプル動画](https://raw.githubusercontent.com/alexreardon/files/master/resources/website-board.gif?raw=true)

## 動作重い問題
README.md でも performance の話がちょいちょいあるが、無駄な re-render を防がないと重くなってしまう。
僕が今回実装してみても、はじめ動きがカクカクになってとても使いにくかったので、README.md 参考にパフォーマンス最適化をした。


## 最適化
[Recommended Droppable performance optimisation](https://github.com/atlassian/react-beautiful-dnd#recommended-droppable-performance-optimisation) を参考にした。
ドキュメントのとおり実装してみてもカクカクし続けたけど、下の `DraggableListItem.shouldComponentUpdate`を書いてからカクカクしなくなった！

```react:未選択リストと選択中リスト間でitemを移動させるやつ.jsx
class DraggableListItem extends React.Component {
  shouldComponentUpdate(nextProps) {
    return this.props.index !== nextProps.index; // これ！
  }

  render() {
    return (
      <Draggable draggableId={this.props.item.id} index={this.props.index}>
        {(provided, snapshot) =>
          <li
            ref={provided.innerRef}
            {...provided.draggableProps}
            {...provided.dragHandleProps}
          >
            {item.name}
          </li>}
      </Draggable>
    );
  }
}

class InnerList extends React.Component {
  shouldComponentUpdate(nextProps) {
    return this.props.items !== nextProps.items;
  }

  render() {
    const { items } = this.props;
    return items.map((item, index) => {
      return (
        <DraggableListItem
          key={item.id}
          item={item}
          index={index}
        />
      );
    });
  }
}

// DragDropContext の中身
class ItemPicker extends React.Component {
    render() {
        return (
          <>
            <div>
              <h2>未選択</h2>
              <Droppable droppableId="unselected">
                {(provided, snapshot) =>
                  <ul ref={provided.innerRef}>
                    <InnerList items={this.props.unselectedItemList} />
                    {provided.placeholder}
                  </ul>}
              </Droppable>
            </div>
    
            <div>
              <h2>選択中</h2>
              <Droppable droppableId="selected">
                {(provided, snapshot) =>
                  <ul ref={provided.innerRef}>
                    <InnerList items={this.props.selectedItemList} />
                    {provided.placeholder}
                  </ul>}
              </Droppable>
            </div>
          </>
        );
    }
}
```
個人開発iOSアプリケーション向けアーキテクチャーに関する一考察

# はじめに

最近、個人開発iOSアプリのアーキテクチャを考えるにあたり、MVC、MVVM、ReSwift、Clean Architecture等のQiita記事が大変参考になりました。

感謝の意を込めて、はなはだ僭越ながら成果をフィードバックさせて頂きます。

# 価値観

- MVC/MVP/MVVMのシンプルさは、個人開発目的ならいいかも
  - Fat ViewControllerはもうやだ
  - UnitTestできる範囲を多くしたい
  - とはいえ、Clean ArchitectureやVIPER、ReSwiftはちょっとヘビー

- ViewModelからViewへの一方通行DataBindingはよさげ
  - RxSwift、ReactiveSwift、Bond等、どれにするか迷う
  - 外部ライブラリに依存したくない 	 	
  - 片方向なら学習コスト低くて、大きい効果を期待できるかも

- ReSwift のdispatchの考え方はよさげ
  - 開発したいアプリは、画面数３で画面遷移も少ない一方、画面が複雑
       - 親ViewControllerr:1
       - 子ViewControlller:4
  - 子ViewControllerのイベントを、親や他の子に通知したい
  - 親や子のイベントを１箇所に集約すれば、実行ログが見やすくなるのでは



# 出来上がったアーキテクチャ

## レイヤー

ExternalLayerとInternalLayerの２層

- ExternalLayerは、Clean Architectureの一番外側のイメージ
- InternalLayerは、Clean ArchitectureのContollers, Use Case, Entityのイメージ

ViewControllerは、この絵のViewに属します。
MVCモデルのVとCがviewに対応して、MがUseCase/ViewModel/Actorに対応するイメージです。
![DuotingZ_アーキテクチャ.001.jpeg](https://qiita-image-store.s3.amazonaws.com/0/269553/9034f796-2284-fe5d-405c-9cb44650d19a.jpeg)

## 処理の流れ

①Viewは、ユーザからの入力を受け付けたら、Dispatcherにイベントを通知する。
②Dispatcherは、イベントを適切なUseCaseにマッピングする。
③UseCaseは、Actorにデータ更新Actionを依頼する。
④Actorは、データ更新処理を行う。
⑤UseCaseは、ViewModelにデータ更新通知をする。
⑥ViewModelは、Actorにデータ参照アクションを依頼して、自身に反映する。
⑦Viewは、購読しているViewModelの値を自身に反映する。
⑧Viewは更新された画面をユーザに表示する。


## Viewの責務

- ユーザ入力やシステムイベントをDispatcherに通知する
- ViewModelを購買して、ViewModelの値に変化があったら画面に反映する 

## UseCaseの責務
- Viewに、イベント通知のインタフェースを提供する
	- func dispatch(from:, event:) 
- ユースケース（データ更新アクション）を実行する
	- ユースケースの実態は、どのアクターにどのアクションどの順番で依頼するかを決めたもの
- 更新結果を画面に反映するため、ViewModelに通知する

## Actorの責務

- UseCaseやViewModelに、アクション実行依頼のインタフェースを提供する。
- データ更新アクション、およびデータ参照アクションを実行する。

## Service Interfaceの責務

- Actorに、ExternalLayerのAPIを隠蔽するためのインタフェースを提供する。

## ViewModelの責務

- UseCaseに、データ更新通知のインタフェースを提供する
- Actorにデータ参照依頼して、結果を自身に反映する。

# おわりに

どなたかのお役に立てたら幸いです！

# 大変勉強になった記事

[Redux+Rxを活用したiOSアプリアーキテクチャ](https://qiita.com/susieyy/items/23d44f28c6a6915c58e2)

[【考察】iOS 開発において MVVM（RxSwift）は本当に MVC よりいい選択肢になるか](https://qiita.com/lovee/items/ea3000d941333de6bd9b)
【Rails】JSONの形式で必要な値だけを返す方法

## JSONとは

データをやりとりする際の形式のことです。
2018年現在、「謎の拡張子JSON」とニュースの記事になる程度には広く使われています。

## JSON形式のデータを返す
controllerのアクションの処理で該当するviewのディレクトリに
新規ファイルを`ファイル名.json.jbuilder`となるように作成します。
今までhtml.rbが格納されていた場所ですね。


## テンプレートの形式
curlコマンドで、きちんと動くか該当のアクションを叩いてみた所、下の内容が返ってきました。

```
$ curl http://localhost:3000/api/users/1
{"user":{
"id":1,
"email":"hoge@gmail.com",
"crypted_password":"〜〜〜〜",
"salt":"〜〜〜〜",
"created_at":"2018-10-15T03:57:04.000Z",
"updated_at":"2018-10-15T03:57:04.000Z",
"reset_password_token":null,
"reset_password_token_expires_at":null,
"reset_password_email_sent_at":null,
"access_count_to_reset_password_page":0,
"name":""}
```
jbuilderファイルに何も記述をしないと作成日時や更新日時も合わせて送られる仕様のようです。

## 特定の値だけを返すようにする
先ほど作成したjbuilderファイルに、記述を足して欲しいデータだけを返すように渡す内容を絞ります。
今回は、下記の３つだけが返るように絞ってみました。

１．id
2.メールアドレス
3.名前


```view/app/users/ahow.json.jbuilder
json.extract! user, :id, :email, :name
```

## 検証

```
$ curl http://localhost:3000/api/users/1
{"id":1,"email":"hoge@gmail.com","name":""}
```
jbuilderファイルにて返す項目を絞ったところ、きちんと必要なデータだけが返ってきました。

今日はこのあたりで失礼します。
google java format

#はじめに
javaでformatが整ってないと言われたことはありませんか？
簡単です。build.gradleに以下を追加するだけです。

```gradle:build.gradle
plugins {
  id 'com.github.sherter.google-java-format' version '0.7.1'
}
```
プラグインが追加されたか確認します。
Other tasksにgoogleJavaFormatが追加されていると思います。

```
$ gradle tasks --all
Other tasks
-----------
googleJavaFormat
```
あとは実行するだけです。

```
$ gradle tasks googleJavaFormat
```

はい、綺麗。
もう怒られない。
Rider で System.Web.Http が見つからない問題

# 問題

ASP.net MVC のプロジェクトで Web API を使うために `System.Web.Http` をインポートしようとしたところ、`Cannot resolve symbol 'Http'` と怒られてしまいました。

**OS** - Windows 10 pro
**IDE** - Rider 2018.2.3
**.NetFramework** - 4.6.1

# 解決
↓のリンクによると、nugetでインストールする必要があるそうです。
https://stackoverflow.com/questions/27819109/system-web-http-missing-after-net-4-5-upgrade

1. ツールバーから `Tools > NuGet > Manage NuGet Packages for [Project Name]` を選択
2. 検索バーに `Microsoft.AspNet.WebApi` を入力
3. 検索結果を選択し、インストールボタンを押す

※ `System.Web.Http` は Core で解決しますが、ほかの WebAPI の機能を使うには `Microsoft.AspNet.WebApi` のほかのパッケージもインストールが必要です。

# Microsoft.Net.Compilers のエラーが出る場合

自分の環境では、↓のようなエラーで WebAPI がインストールできませんでした。

```
Unable to resolve dependencies. 'Microsoft.Net.Compilers 1.3.2' is not compatible with 'Microsoft.CodeDom.Providers.DotNetCompilerPlatform 1.0.8 constraint: Microsoft.Net.Compilers (>= 2.4.0)'.
```

メッセージによると `Microsoft.Net.Compiler` のバージョンが古い（要求2.4.0以上に対し1.3.2がインストールされている）とのことなので、NuGetからアップデートします。

1. ツールバーから `Tools > NuGet > Manage NuGet Packages for [Project Name]` を選択
2. 検索バーに `Microsoft.Net.Compilers` を入力
3. 検索結果を選択し、アップデートボタンを押す
4. アップデートが終わったら再度 `Micorosft.AspNet.WebApi.Core` を検索してインストール
現場で見つけたAWS Lambdaクイズ


お仕事やら趣味やらでAWS Lambdaを使っています。

そんなLambdaを使っている現場で見つけた、ちょっとわかりにくかったLambdaの仕様をクイズ形式でご紹介いたします。


## Q1. 何故か動かないLambda

次の画面の様に、CloudWatch Eventsのcronスケジュール式がトリガーになっています。
しかし、該当の時間になってもLambdaが動いていません。なぜでしょう？

![lambda1](https://raw.githubusercontent.com/rednes/blog/master/items/201810_LambdaQuiz/image/lambda1.png)


（※回答は下へスクロールしていってください）

↓

↓

↓

↓

↓

↓

↓

↓

↓

↓

↓

↓

↓

↓

↓


**A1. CloudWatch Eventsの状態が無効だから**

正解はCloudWatch Eventsの状態が無効だからです。
これはLambdaの画面からわかりません。
CloudWatch Eventsの状態は、CloudWatch Eventsの画面で確認しましょう。

![lambda1](https://raw.githubusercontent.com/rednes/blog/master/items/201810_LambdaQuiz/image/cwe.png)


## Q2. 何故か動くLambda

次の画面の様に、トリガーがセットされていないLambdaがあります。

![lambda1](https://raw.githubusercontent.com/rednes/blog/master/items/201810_LambdaQuiz/image/lambda2.png)

しかし、CloudWatch Logsを見るとこのLambdaが定期的に動いているように見えます。なぜでしょう？

![lambda1](https://raw.githubusercontent.com/rednes/blog/master/items/201810_LambdaQuiz/image/cwl.png)

（※回答は下へスクロールしていってください）

↓

↓

↓

↓

↓

↓

↓

↓

↓

↓

↓

↓

↓

↓

↓

**A2. StepFunctionsが使っているから**

正解はStepFunctionsが使っているからです。

StepFunctionsでLambdaを動かす場合、Lambdaのトリガーに何も表示されないので、誰がLambdaを実行しているのかLambdaの画面からわからなくなります。注意しましょう。

![lambda1](https://raw.githubusercontent.com/rednes/blog/master/items/201810_LambdaQuiz/image/stepfunctions.png)


「いやいや、こういう場合もLambdaのトリガーに表示されないよ！」といった、他の答えを知っている方は教えていただけると嬉しいです！
【Python3】Djangoで登録されたデータをCSV出力する

# はじめに
Python（Django）でWebアプリケーション作ってると、「データをCSVで出せるようにしてほしい」という要望はほぼマストなので備忘録的にまとめます。
# CSVファイルを生成する
例えば毎月1日に、前月の受注リストなんかを集計してその結果をCSVとして出力する、という動作を考えます。
ファイル名は `yymm_billing.csv` という命名規則とします。
また、クライアントはWindows端末のExcelでCSVを閲覧することを想定し、文字化けさせないために出力するCSVの文字コードを `cp932` とする。
`Order` テーブルは以下のように定義する。

```python:models.py
class Order(models.Model):
    order_date = models.DateField("受注日", auto_now=False, auto_now_add=False, default=date.today)
    customer = models.CharField("顧客名", max_length=255)
    phone_number = models.CharField("電話番号", max_length=255)
    item = models.CharField("商品名", max_length=255)
    num = models.IntegerField("数量", null=True, blank=True)
    cost = models.IntegerField("原価", null=True, blank=True)
    earnings = models.IntegerField("売上", null=True, blank=True)
    gross_profit = models.IntegerField("粗利", null=True, blank=True)
```

で、実際のCSV出力の処理ですが、結構長くなってしまった。
日付の計算をするために `relativedelta` を利用しているので

```
pip install python-dateutil
```
でインストールしておきます。

```python:output_csv.py
from datetime import datetime, date, time, timedelta
from dateutil.relativedelta import relativedelta
from myapp.models import Order # モデルは適当です
import csv


"""
例えば2018年10月1日にこのスクリプトを実行すると
/path/to/output_dir に
201810_billing.csv
というファイルが生成されるようにする。
"""
t = date.today()
output_path = '/path/to/output_dir'
output_name = t.strftime('%Y%m') + '_billing.csv'

# 検索対象レコードの抽出
start_date = date.today().replace(day=1) - relativedelta(months=1) # 前月の1日を取得
end_date = date.today().replace(day=1) - timedelta(1) # 前月の最終日を取得

order_list = Order.objects.filter(order_date__gte=start_date)\
                          .filter(order_date__lte=end_date)

# CSV出力処理開始
with open(output_path + output_name, 'w', encoding='cp932', newline='') as csv_file:
    # 1行目にヘッダーを書き込む
    header = ['受注日時', '顧客名', '電話番号', '商品名', '数量', '原価', '売上', '粗利']
    writer = csv.writer(csv_file, quoting=csv.QUOTE_ALL)
    writer.writerow(header)

    for order in order_list:
        order_date = order.order_date
        customer = order.customer
        phone_number = order.phone_number
        item = order.item
        num = order.num
        cost = order.cost
        earnings = order.earnings
        gross_profit = order.gross_profit

        row = []
        row += [order_date, customer, phone_number, item, num, cost, earnings, gross_profit]

        writer.writerow(row)
```

これで対象のディレクトリに定義した命名規則のCSVが吐き出されるようになります。
あとはダウンロードボタンを作ってあげてファイルをダウンロードできるようにしてあげればOKです。

モデルの定義などはこの記事を書くために適当に用意したものなのであまり参考にしないようお願いします。
ストプロでIFを書くのが面倒な時の書き方(CASE WHEN)

うちの会社ではストプロが主流みたいでぼちぼち書く機会があるんだけど、
コードレビューいただいた時に、書き方を教わったのでメモ。

普通にIFで書く時
```
IF w_no_target_content IS NOT NULL AND w_no_target_content <> '' THEN
    w_result.no_target_content = w_no_target_content;
  END IF;
```

今回教わった書き方
```
CASE WHEN w_no_target_content IS NOT NULL AND w_no_target_content <> '' THEN     w_result.no_target_content = w_no_target_content END
```

一行で書けていい感じに…！！ELSEも書けるよ。
rubyでだと後置IFとか三項演算子とかで書いてたから同じような書き方ができないかなーと思ったりしてたからよかった。
cakephp3 で sendgrid 使おうぜ

# sendgrid って何よ？

使うと迷惑メールにならんのよ。

# 特徴は？

webapi 早い
smtp 遅い

# 設定

https://sendgrid.kke.co.jp/

から申し込む。
1社につき、1アカウントしか使えんみたいんなので、注意。

# 設定

以下をクリックしてから

※画像が間違っている。MailSettingsの下の
Sender Authentication をクリックする


![SendGrid.png](https://qiita-image-store.s3.amazonaws.com/0/31338/94703299-e1e3-ad85-7054-e8f49b018435.png)


参考に設定（情報がちょい古い）
https://xn--hckj0bf8p.com/wordpress-mail-does-not-arrive-and-delayed-resolve-with-sendgrid/

まぁCNAMEをコピペしてくだけなんだけど。

# APIキーを取得

![SendGrid (1).png](https://qiita-image-store.s3.amazonaws.com/0/31338/a1c9adc8-0d64-3eb2-cd99-8de3031e8335.png)

一回しか表示できんので、
ちゃんとメモること。


# CAKEPHP3で使おうぜ

composer でインストール

```

composer require iandenh/cakephp-sendgrid

```


```app.php


    'EmailTransport' => [
        'SendgridEmail' => [
            'className' => 'SendgridEmail.Sendgrid',
            'api_key' => '[YOURKEY]'
        ]
    ],

    'Email' => [
  
        'Sendgrid' => [
            'transport' => 'SendgridEmail',
        ],
    ],


```

を設定。

## いざ送信

```

        //    use Cake\Mailer\Email;


        //そのまま送る
        $email = new Email('Sendgrid');
        $email->from(['from@from.com' => 'ふろーむ'])
            ->transport('SendgridEmail')//config変更

            ->to('send@sendo.com')
        ->subject('こんにちわ。')
        ->send('
        はじめまして。
        https://yahoo.co.jp
        にご登録頂きありがとうございます。');




```


これで送信できます。

## 変なurl に飛ぶやん？

SMTPまたはWeb APIを利用している場合

Settings>Tracking>Click Tracking設定から無効化できます。くわしくはユーザマニュアルをご覧ください。
TravisCI でcomposer とbundle を両方動かして、phan も入れてみた

# やりたいこと

+ PHP のプログラムをいっぱい書いた
+ phanとか、phpcs は基本的に入れるでしょ！
+ phan とかの実行結果がそのままコードレビューのコメントとかで実行できると楽だなぁ。。
    + そうだ。[saddler](https://github.com/packsaddle/ruby-saddler)をいれよう

# travis.yml の設定

```yml
language: php
before_script:
  - composer install --dev
  - bundle check || bundle install --without production --deployment
  - git clone https://github.com/nikic/php-ast
  - cd php-ast
  - phpize
  - ./configure
  - make
  - make install
  - echo "extension=ast.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
  - cd ../
php:
  - 7.1
branches:
  only:
    - master
    - develop
git:
  depth: 500
  submodules: false
sudo: false
cache:
  directories:
    - $HOME/.composer/cache
    - vendor/bundle
job:
  include:
    - stage: inspection
      if: type IN (pull_request)
      script:
        - bash ./bin/phan_inspect.sh;
        -　　# 後はテストしたい内容を書いて下さい
```

# yml解説

+ `before_script:` に環境構築に必要な諸々のパッケージを入れる設定を書いた
    + composer のinstall
    + bundle のinstall
    + php-ast（phanの実行に必要）のinstall
+ `cache` の設定で少し高速化

# phan_inspect.sh に書いてある内容（本物はGithubのPrivateRepoにあるよ）

```
#!/bin/bash

echo "Start"
TARGET_LIST=`git diff --name-only origin/$TARGET_BRANCH | grep -e '.php$'`

if [ -z "$TARGET_LIST" ]; then
    echo "PHP file not changed."
    exit 0
fi

RESULT_TEXT=`echo $RESULT | bundle exec saddler report \
    --require saddler/reporter/text \
    --reporter Saddler::Reporter::Text`
if [ -n "$RESULT_TEXT" ]; then
    if [ -n "$COMMON_PULL_REQUEST" ]; then
        `echo $RESULT | bundle exec saddler report \
            --require saddler/reporter/github \
            --reporter Saddler::Reporter::Github::PullRequestReviewComment`
    fi

    echo ""
    echo "An error has been detected,this following:"
    echo "$RESULT_TEXT"
    exit 1
else
    echo "Passed"
    exit 0
fi
```

# 補足

現在、Github でテスト中なんだけど、Github が落ちてて暇なのでQiitaに書いてみた
CSS transitionをちょっと調べてみた

### レビューきっかけ
コードレビューしていると、transitionの記述がありました。
そういえばちゃんと理解したことなかったので、ちょっと調べてみました。

### transitionの基本的なこと
transitonは訳すると、遷移。
つまり最初の状態から、最後の状態への遷移に関するCSSです。
例えばhoverの時に、opacityを変更したかったとする。
最初の状態：hover前
最後の状態：hover後
この状態遷移に関して記述する。



### transition(時間的変化)をまとめて指定する
以下の4つをまとめて記述する

- transition-property : どのプロパティ
- transition-duration : アニメーション開始から終了までの所要時間
- transition-delay : アニメーションが開始するまでの遅延時間
- transition-timing-function : アニメーションのイージング

##### 初期値
- transition-property : none
- transition-duration : 0
- transition-delay : 0
- transition-timing-function : ease

### ちなみに
UX的目線で見たアニメーションに関する記事
[ユーザーを魅了する！UXデザインの正しいアニメーション完全ガイド 2018年版](http://photoshopvip.net/111431)
アニメーションをつけるときはこれを参考にするとUXが向上するかと思います。

### 参考
- [transition](http://www.htmq.com/css3/transition.shtml)
- [ユーザーを魅了する！UXデザインの正しいアニメーション完全ガイド 2018年版](http://photoshopvip.net/111431)
Instagramから投稿をスクレイピングする

KOLという言葉をご存じですか？「Key Opinion Leader」の略で、SNS上で影響力の高いアカウントのことを指します。いわゆるインフルエンサーで、人気のあるKOLを商品のプロモーションにうまく利用すれば、大きな利益を上げることができます。中国でKOLはマーケティング上欠かせない存在となっており、中国のECサイトで商品を売りたい日本企業などの間では、KOLを使ったプロモーションが常識になっています。

「インスタ映え」の流行語に象徴されるように、すでに多くの人が楽しんでいる人気SNSのInstagram（インスタグラム）にも多くKOLがいます。今回は[WebスクレイピングツールOctoparse](https://www.octoparse.jp)を使って、KOLの投稿をスクレイピングしてみます。

この記事では、Instagramから投稿をスクレイピングする方法を示すために、https://www.instagram.com/izkiz/ を例として使います。さて、始めましょう！


#1) 「Go To Web Page」 - 内蔵ブラウザで対象のWebページを開く

 · 「Advanced Mode」でタスクを作成します。

 · URLを「Extraction URL」ボックスに貼り付け、「Save URL」をクリックして移動します。

 · Webページの内容を読み込めない場合は、「setting」でブラウザを変更してください。
![save-url.gif](https://qiita-image-store.s3.amazonaws.com/0/262932/9198078d-eb4d-005a-5fa7-e721c2c0f645.gif)





#2)  ページ遷移のループを作る - 複数のページからデータを取得する

 · 一番目の画像をクリックし、「Action Tips」の下部にある「UL」から「A」にタブを変更してください。（[データ/ URL /画像/ HTMLを詳細に選択して抽出する方法](https://www.octoparse.jp/tutorial/extract-data)をご覧ください。）

 · 「Action Tips」にある「Click the link」をクリックします。

 · 「>」をクリックし、 「Loop click next page」を選択します。

 · 「Advanced Options」パネルで「Load the page with AJAX」をチェックし、「AJAX timeout」を設定します。
![pagination-loop-1.gif](https://qiita-image-store.s3.amazonaws.com/0/262932/cf6cd2fe-fbe7-ae85-f8de-a015c1ca976b.gif)

  

*ヒント！*
*AJAXとは「Asynchronous JavaScript + XML」の略で、簡単に言えばページを再読み込むことなくコンテンツの一部をWebページが更新できるようにする一連のWeb開発テクニックです。*
*AJAX技術を使ったページには「AJAX Load」を選択するほうがいいです。AJAXの詳細は[こちら](http://jp.octoparse.com/tutorial/ajax/)。*

  

 

#3)  データを抽出する - 抽出したいデータを選択する

 · 必要なデータをクリックし、「Action Tips」にある「Extract data」を選択します。

 · 必要に応じて、フィールド名を編集します。
![extract-text-data.png](https://qiita-image-store.s3.amazonaws.com/0/262932/afca89ec-ad8f-a9f7-36ea-e461c52f8dfa.png)

 

*ヒント！*
*OctoparseはWebサイトから選択した画像のURLのみを抽出することができます。場合によっては、「Action Tips」の下部にあるタブを調整し、正しい情報を得る必要があります。*
![extract-url-of-selected-image.gif](https://qiita-image-store.s3.amazonaws.com/0/262932/c69bb7ae-d990-3646-c44e-0b2a5953c3bb.gif)

 

 

#4) 抽出タスクを始める - タスクの実行を行いデータを取得する

 · 「Save」をクリックします。

 · 「Start Extraction」をクリックします。
![run-extraction.gif](https://qiita-image-store.s3.amazonaws.com/0/262932/9c4c642f-9ef2-85de-4c53-67549cd89b9d.gif)



 


いかがでしょうか？[ここ](https://www.dropbox.com/sh/bky1hbh5v70mbnt/AAA-kOgrJRsMgcw2xg2VA4AIa?dl=0)でサンプルWebクローラーをダウンロードできます。興味を持ち方は是非お試してください。
侍エンジニア塾の記事が炎上しているので追撃してみる

この記事話題になってますね。セキュリティホールの宝石箱や！って感じ。
https://qiita.com/hamichamp/items/7b7a7ee091a6856ac900

同じ作者の記事で、問題あるのがまだまだ掘れそうだなぁと思ったので、キャストの記事について突っ込んでみます。
https://www.sejuku.net/blog/25737

# 数値型の精度
まず数値の精度について、以下の順と紹介されてるけど、明らかに間違いですね。

>精度の順序は下記のとおりです。
>double型 > float型 > long (int)型 > int型 > short (int)型 > char型

longとfloatのどちらが精度が良いか?longで表せる整数範囲に限っては十中八九longの方が良いです。
(処理系依存の話ですが一般的なx86PCであれば)long型とfloat型はともに32bit。ただしfloatは浮動小数点の情報分、有効桁数が落ちます。したがってlongの方が高精度なわけです。
つまりここに紹介されている順列は、あくまで暗黙的型変換の順列でしかありません。精度ではありません。
でも今どきの開発環境ならlong -> floatなんて型変換したら警告出るんじゃないかなぁという気もしますが…。

# char型の範囲
>char型の変数は文字を格納することができますが、-128から127までの値も格納します。
>また、unsigned char型の変数は0から255までの値を格納します。

char型はsignedという話ですが、これは処理系依存の話なので誤りです。
符号付き整数が欲しいなら横着しないでsigned charを使おう！charを使うのは危険だぞ！

# ポインタ型へのキャスト
```c
#include <stdio.h>
 
int main(void) {
    char str[8] = "Hello";
    char *ptr;
    
    // char型ポインタへのキャスト
    ptr = (char*)str;
    printf("char型ポインタのアドレス先の値は: %s\n", ptr);
    
    return 0;
}
```
>このサンプルコードではchar型の配列「str」をchar型のポインタ「ptr」にキャストして「ptr」のアドレス先の値を表示しています。

**その説明はアカン**
コードそのものは動きます。動きますが、この説明はどんな変数でもポインタへキャスト出来てしまうかのようです。キャストしたらその変数のアドレスを指すポインタになると。
**そんなわけがない**
いや確かにキャスト自体はできたりするよ？思った通りには動かないけどな！
このキャストが有効なのは、あくまで配列型はポインタ型に暗黙的型変換が可能という言語仕様によるもの[^1]です。一般の型がポインタ型にキャスト出来るわけではありません。


## まとめ
やっぱり侍エンジニア塾はgmですね。

[^1]: 最初はここに「配列変数は実質ポインタ」という様な誤った情報を書いておりましたので、修正させて頂きました。コメントにて指摘をして下さった方々にお礼を申し上げます。
はじめてのyukicoder vol.2


今回でチュートリアル問題を解いてみよう！が終わりました

全部で五問しかない上に既に三問も解いているので、

昨日一日だけで終わらせようと思えば終わらせられましたね・・・

しかも、今回のは入力の形式が違うだけで実質同じ問題というネ

それでも手こずるという体たらく

じゃーNo.9008からどーぞ

##No.9008
```9008.f90
integer(8) A
integer(8),allocatable :: x(:)
read(*,*) n
allocate (x(n))
read(*,*) (x(m),m=1,n)
A=0
do m=1,n
   A=A+x(m)
end do
write(*,*) A
end
```
言われた内容も単純、言っていることも単純、なのに手こずりました

というのも、私Fortranで横並び入力ほぼほぼしたことないんですよね・・・

それが仇になって非常に手こずりました

最初、反復で書いてたんですが一行の入力ができなくて(当たり前)、

次に反復やめて"read(*,*) x(n)"にしてたんですが、このままだとx(n)に数値代入されるので合計値が狂う

結果的に反復形？で何とかごまかしました

あとはIntegerを入れ忘れてチェックに引っかかるといういつものミスくらいでした<br><br><br>

この問題を私以外にFortranで解いている人がいたんですが、

私のより全然綺麗で最もっと精進しないとなぁーと思いました、まる
<br>
##No.9009
```9009.f90
integer(8) A
integer(8),allocatable :: x(:)
read(*,*) n
allocate (x(n))
A=0
do i=1,n
    read(*,*) x(i)
    A = A + x(i)
end do

write(*,*) A
end
```
こっちはいつもの縦入力で非常にえがった

特にいうことはないです

次回は★1の問題をメインに解いていきまーす

以上！
文字列配列 []string から要素を指定して削除する

```Go
// 文字列配列から指定したindexの要素を削除する
// 注意: runtime error: out of range 発生する恐れ有り
func unset(str []string, index int) []string {
	if index >= 0 {
		return append(str[:index], str[index+1:]...)
	} else {
		return append(str[:len(str)+index], str[len(str)+index+1:]...)
	}
}
```
ブラウザの JS のデバッグする時に Breakpoint を使うと便利

# 前提
- ソースコードに `debugger` とか書くのイチイチだるい時に使える方法です（いまさら）

# 環境
- Google Chrome 69.0.3497.100（Official Build）

# TL;DR
![gem_memories_stats_rails5.gif](https://qiita-image-store.s3.amazonaws.com/0/156176/b251623c-defa-856f-2bf3-cb1a25b8ab34.gif)

操作は簡単ですね。 Dev Tools を開いて、 Source タブをクリック。デバッグしたいコードの行数の部分をクリックすると、そこがブレイクポイントになります。あとはリロードすれば、上記の gif のように、該当のコード部分でストップさせることができます。今までなんで知らなかったんだろう。

# 参考文献
なし
Gnuplot (CentOS) フォントのインストール

# "Could not find/open font when opening font" と表示されて，フォントが使用できない場合の対処法

Gnuplotで図を作成する際に，TimesやArialのフォントが使いたいのに，"Could not find/open font when opening font"とメッセージが出てきて，粗いフォントになってしまう。

Timesを使うために，Microsoft TrueType fonts というものをダウンロードすればよいらしい。

以下に，centos5の例で説明。

## fontのダウンロード

以下のリンクからrpmファイルをダウンロード

[msttcorefonts-2.0-1.noarch.rpm](http://me.selah.ca/pub/centos5/msttcorefonts-2.0-1.noarch.rpm)

ファイルを置いたディレクトリ上で，スーパーユーザになって，以下のコマンドを実行。

```
$ su
# rpm -ivh msttcorefonts-2.0-1.noarch.rpm
```

以下のディレクトリが作成される。

`/usr/share/fonts/msttcorefonts`

```
[hnishi@centos5 ~]$ ls /usr/share/fonts/msttcorefonts
andalemo.ttf  ariali.ttf  comicbd.ttf  courbi.ttf  fonts.dir     georgia.ttf   tahoma.ttf   timesi.ttf    trebucbi.ttf  verdanab.ttf  verdanaz.ttf
arialbd.ttf   arial.ttf   comic.ttf    couri.ttf   georgiab.ttf  georgiaz.ttf  timesbd.ttf  times.ttf     trebucit.ttf  verdanai.ttf  webdings.ttf
arialbi.ttf   ariblk.ttf  courbd.ttf   cour.ttf    georgiai.ttf  impact.ttf    timesbi.ttf  trebucbd.ttf  trebuc.ttf    verdana.ttf
```

このttf拡張子のファイル群がフォント。

## 環境変数の設定

Gnuplotにフォントがあるディレクトリを教えてあげる。

bashの場合

`export GDFONTPATH=/usr/share/fonts/msttcorefonts/`

で設定する。
`~/.bashrc`に書き込んでおくと良い。
書きこんだら`source ~/.bashrc`で反映させること。

## gnuplotで描画

font名は.ttfのファイル名と同じにすれば良い。

```
$ gnuplot
set term png enhanced font "times, 20"
set output "test.png"
p "data.txt" w l
```

## 参考

- https://selah.ca/how-to-install-ms-truetype-fonts-on-centos-5/
- https://nvnote.com/gnuplot-could-not-find-open-font-when-opening-font/
Dialogflow + Slack

DialogDlowとSlackの連携方法について。
手順としてはチュートリアル的に実施すれば簡単に出来ます。

# チャットボット作成

## Dialogflow

https://console.dialogflow.com へアクセスします

### Create Agent

まず初めにエージェントを作成します

![dialogflow_01.png](https://qiita-image-store.s3.amazonaws.com/0/297616/d245c86a-ad75-23d7-ccc1-07e7da1c9e05.png)

- `CREATE AGENT` をクリック

![dialogflow_02.png](https://qiita-image-store.s3.amazonaws.com/0/297616/91c23bbe-fe78-8c9a-d107-e5a34b6bd2d4.png)

- エージェントの名前を入力
- デフォルトの言語を選択（今回は `japanease- - jp` を選択）
- `CREATE` をクリック

# Slackと連携

今回はSlack連携だけを目指すので、中身についてはデフォルトのサンプルを利用します。

## Dialogflow

### Integration

![dialogflow_03.png](https://qiita-image-store.s3.amazonaws.com/0/297616/d59cae06-5a8e-e79c-6159-627dc45d0342.png)

- 左のメニューから `Integration` をクリック
- Integrationではいくつかの連携ができることがわかりますが、今回は Web demo、とSlackについて

### Web Demo

![dialogflow_04.png](https://qiita-image-store.s3.amazonaws.com/0/297616/ecf4f727-a3b7-6b6a-5369-74b2334134be.png)

- Web demo のスイッチをONにする
- ダイアログに表示されているリンクをクリック

上記だけでチャットボットの確認をすることは可能ですが、コンソール下部のコードをHTMLに埋め込むことでもチャットボットの確認は可能です。
「やあ」と入力すると「こんにちは！」と返すことが確認できます。

### Slack

![dialogflow_05.png](https://qiita-image-store.s3.amazonaws.com/0/297616/9b3dd75f-8e60-02c5-4258-39c4a9bf08eb.png)

- Slack のスイッチをONにする
- `TEST IN SLACK` をクリック
- Slack間との認証を行うため、Slack側のダイアログが表示されるので `authorize` をクリック
- Launchの `Slack app` をクリックしSlackAPIを作成（アプリ名とワークスペースを入力し`Create app`をクリック）
- 作成したSlackAPIのアプリのCredentialsの情報を、Dialogflowに以下の設定を入力
    - Client ID
    - Client Secret
    - Verification Token
- `START` をクリック

## Slack

これで一応Slack間との連携は可能です。
Slackから Dialogflow のボットを呼び出してみてください。
以下は、Web demo同様に「やあ」と呼び出しています。

![dialogflow_06.png](https://qiita-image-store.s3.amazonaws.com/0/297616/5c4dc75c-b9fb-0a4a-0bd2-9d090e81fb80.png)
UltraDatastar60のFWアップデート方法

#はじめに
UltrastarData60のFWのアップデート方法について、メモがてら記載。

##　条件等
###　・PC条件
・　macbook High Sierra
・　Chrome +　RestletClient　インストール済
・　JBODはOOBEポートにすでにLANが繋がれDHCPでアクセスが成立していることが条件
###　・セキュリティ的な注意点
・JBODの管理者パスワードはしっかり変えとくこと
・JBODのOOBEは繋ぎっぱなしにしないこと。（悪用されたら、終わり。）

# 手順
###　JBOD状況の確認
1. JBOD状況をRestletClientのGETで確認する。　　`https://JBODのIPアドレス/redfish/v1/UpdateService/Actions/UpdateService.SimpleUpdate/Status`
![FWstatus](https://qiita-image-store.s3.amazonaws.com/0/166400/a9e55eb4-73c0-a4e1-6423-2289d5e14e4d.png)

2. ChromeのRestletClientを開いてGET　で `https://JBODのIPアドレス/redfish/v1/UpdateService/FirmwareInventory/モジュール名`　で現バージョンが古く、ダウンロードしたものが新しい事を確認する。

### tftp準備
1.　macのコンソールで　`sudo launchctl load -w /System/Library/LaunchDaemons/tftp.plist` を打ってtftpサーバを起動
2.　コンソール　`sudo lsof -i:69`　でプロセスが起動したか確認


### 最新FWダウンロード
1. https://support.hgst.com/download から最新FWにアクセス
2. hgst_mm_bundle_XXX-XXX_X.X.X.tar 　を落とす。注）Tが付いてるのはテスト版。
3. ChromeのRestletClientを開いてGET　で `https://JBODのIPアドレス/redfish/v1/UpdateService/FirmwareInventory/モジュール名`　で現バージョンが古く、ダウンロードしたものが新しい事を確認する。
4. macの　`/private/tftpboot/`にダウンロードしたFWデータを格納する。（cpコマンドとかmvコマンドとか）

###FWのアップデート
1. RestletClientのGETを　`https://JBODのIPアドレス/redfish/v1/UpdateService/Actions/UpdateService.SimpleUpdate`、下のUpdateFW.jsonを記載。２０２番が返ってくるのを確認する
2. RestletClientのGETで　`https://JBODのIPアドレス/redfish/v1/UpdateService/Actions/UpdateService.SimpleUpdate/Status`をして次のものになるまで待つ。
![GETJSON](https://qiita-image-store.s3.amazonaws.com/0/166400/77b56b23-6757-6216-1dce-9e036df5b498.png)

3. ９の状態になったらActivatonをしなければFWは適用されないので、POSTで次のものを送信する。`https://JBODのIPアドレス/redfish/v1/UpdateService/Actions/UpdateService.FWActivate`

4. JBODの状況が次の状況か確認する`https://JBODのIPアドレス/redfish/v1/UpdateService/Actions/UpdateService.SimpleUpdate/Status`
![FWstatus](https://qiita-image-store.s3.amazonaws.com/0/166400/a9e55eb4-73c0-a4e1-6423-2289d5e14e4d.png)

5.　最後に念のために　上がったか確認する。　`https://JBODのIPアドレス/redfish/v1/UpdateService/FirmwareInventory/モジュール名`
![更新確認](https://qiita-image-store.s3.amazonaws.com/0/166400/03dea8fe-6e9a-21df-60b2-394f9e23ee90.png)

````json:UpdateFW.json
{"TransferProtocol":"TFTP",
  "ImageURI": "tftp://自分のPCのIPアドレス/hgst_mm_bundle_XXX-XXX_X.X.X.tar.gz"}
````

### TFTPの終了
1. コンソールでtftpサーバをクローズ`sudo launchctl unload -w /System/Library/LaunchDaemons/tftp.plist`
2. クローズの確認のためコンソールで`sudo lsof -i:69` をする。




# 感想
さすがにしっかりAPI上はリファレンスが書かれてます。
ただ、ドキュメントリファレンスに乗っていないことが多いのでむしろ、ちょくで確認するのが一番かもしれません。
Chrome  web workerを使ってcanvasで絵を描く。

# Chrome  web workerを使ってcanvasで絵を描く。

※まだChrome69から実装された機能で他のブラウザでは動きません。

## 動機
描画の高速化を調べて色々ググっていると、MDNにOffscreenCanvasなるメソッドの[記事](https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas)を見つけて、WebWorkerを使えば何とかなるんじゃないかと考えていたのでこの記事はまさにど真ん中の記事でした。

早速実装にとりかかるとWebWorker初実装の私には、コールバックの嵐に見事に心が砕けてしまいました。
そこに救世主・・・・[Comlink](https://github.com/GoogleChromeLabs/comlink)が現れました。
### Comlinkとは
 コールバックやらイベントやらで呼ぶのではなく、その辺をよきに計らってくれてPromiseを返してくれるライブラリです。
コールバックよりは、async-awaitの方が読みやすいかなと使ってみることに。
githubを見てみると「Support OffscreenCanvas (fixes #165)」の文字が、これは期待度が高まります。

早速インストール

```bash
npm i comlink
```
```javascript:main.js
import * as Comlink from "comlink";
class Main {
    constructor() {
      this.createPng = Comlink.proxy(new Worker("worker.js"));
    }
    async createPng(){
        const instance = await new this.createPng();
        const canvas = document.createElement('canvas');
        const offscreen = canvas.transferControlToOffscreen();
        const url = await instance.createPng(offscreen);
        return url;
    }
    async show() {
       let imageData = await this.createPng(history, date);
       // 実際の描画処理。
    }

}
```
```javascript:woker.js
import * as Comlink from "comlink";
class MyClass {
 async createPng(offscreen) {
    let ctx = offscreen.getContext("2d");
    // ・・・描画処理
    // 完成したらpngURLに変換
    //toDataURLメソッドがないので、convertToBlob()で代用。　
    const blob = await offscreen.convertToBlob();
    const p = new Promise ((resove,reason) => {
      const reader = new FileReader();
      reader.onload = () =>{
        let dataUrl = reader.result;
        let base64 = dataUrl.split(',')[1];
        resove("data:image/png;base64, "+base64);
        
      }; 
      reader.readAsDataURL(blob);
    });
    return await p;
 }
}
Comlink.expose(MyClass, self);
```
## 動かない。全く動かない。
　インストールしたモジュールをみると、「Support OffscreenCanvas (fixes #165)」で追加された実装がないことが分かりました。
しかたなく、githubからzipを持ってきてファイルを置き換えることに。

## 動いた！
最初は、canvas と offscreen を使いまわす予定でしたが、ループ処理を入れると、offscreenのところでエラーが発生するので、worker側を呼び出す前に毎回作成するように変更しました。

## まとめ
Comlinkはいいですね。
[]byteからpngか判断

```go
func isPng(image []byte) bool {
	imageHead := image[0:8]
	var pngHead = []byte{0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A}
	return reflect.DeepEqual(imageHead, pngHead)
}
```
Jenkins でリモート Git レポジトリにアクセスできない macOS 固有の現象

さっき起きたトラブルの覚書

# 前提

* Jenkins で、リモートの Git レポジトリをワークスペースにクローンする設定を使っている
  * Git コマンドを手動で叩いてクローンするのではなくて、ジョブの設定の「ソースコード管理」でリモートの Git レポジトリを指定してある
* リモート Git レポジトリには HTTPS でアクセスしており、ユーザ名 & パスワード認証が必要
  * Jenkins にユーザ名 & パスワードを認証情報として登録し、それを使用するようにジョブの「ソースコード管理」で設定してある
* Jenkins を macOS マシンで実行している

# 問題

レポジトリのポーリングやクローンが失敗する。ユーザ名/パスワードが間違っている時と同じエラーメッセージが出る。[^1]

[^1]: GitHub のプライベートレポジトリの場合、ユーザ名/パスワードが間違っている時でも "Repository not found" のエラーになる。確かにレポジトリは存在しているはずなのになぜか not found になると思ったときは、認証エラーも疑うべし。

# 原因

* Jenkins がレポジトリにアクセスする時、 `GIT_ASKPASS` 環境変数を使用して Git に認証情報を渡すようになっている。
* Git のコンフィグで `credential.helper` が設定されていると `GIT_ASKPASS` 環境変数よりもそちらが優先される。
* macOS の Git はデフォルトでキーチェーンを使用するように `credential.helper` が設定されている

→ Jenkins から Git に認証情報が渡されない。 [^2]

[^2]: たまたま同じ認証情報がキーチェーンに入っていたりしない限りは

# 解決法

Jenkins のジョブを実行しているユーザアカウントにログインし、コマンド

``` sh
git config --global credential.helper ''
```
を実行する。

Jenkins 環境が複数のノードで構築されている場合は実際にポーリングやビルドを行う各ノードでこれを設定する必要がありそう。
私のパソコンのキーボード操作

私のパソコンの使い方に関して、お教えします。

パソコンを立ち上げたらまずはWindowsボタンとRボタンを同時に押して

検索窓を出し、そこでcmdと打ち、黒い画面を出します。

この黒い画面はコマンドプロンプトと言います。

そしてそのコマンドプロンプトでping -t IPアドレス

と書きエンターを押すとデフォルトゲートウェイと

自分のPCが断線していないかどうかというのを確認できます。

今の時代、無線が主流なので無線が落ちる、落ちないかの

確認という意味合いで使っています。

それ以外にも同一LAN内で自分の作成したウェブアプリケーションを

スマホで動かしたいときは

http://IPアドレス/フォルダ名/

と打ちます。

Apacheなどでvhostの設定をしていればIPアドレス名→vhost名

ということになったりします。

また、ブラウザを立ち上げてブラウザの操作は

CTRLとTabキーを使って画面を切り替えたり
別画面にしたいときはalt とtabキーを同時に押して
出したい画面を出したりということをしています。

また、Windowsボタンのあるタスクバーは

ピン止めしてあるタスクは

左から１・２・３という順番なので

Windowsボタンと数字キーを押すと

立ち上げることができますし

消したいときはctrlキーとwキーを

同時に押して消すことができます。

またコマンドプロンプトを立ち上げた状態で

ワードやエクセルを立ち上げたいときは

win word
excel
といった形で入力シエンターを押すと立ち上がります。

WindowsキーとRボタンを押してエクセルを立ち上げる場合も同様です。

WindowsボタンとRボタンを押してワードを立ち上げたい場合は

winwordと打つと立ち上がります。

また、ブラウザも左から１・２・３という並びなので

CTRLボタンと数字ボタンで切り替えることもできます。

パソコンを使っているけれど、ショートカットキーが上手く使えない

っていう方は、私のキーボード操作に関しての当記事を

拝見して試していただければと思います。

他にもブラウザを立ち上げるときは

ctrlボタンとtボタンを同時に押したり閉じるときはctrlボタンとwボタンで削除

印刷したい画面を出して印刷したいときはctlrとpだったりします。

新規画面を出したいときはctl Nを同時に押します。

コピーアンドペーストはctrl　ｃだったり、はりつけはctrl vだったり

戻すときはctrl zだったりします。

ドキュメント作成等での文字検索は

ctrl fで検索画面を出して該当文字を入力して検索したり

とします。

altボタンとwindowsボタンとctrlボタンが

自由自在に使えるだけでもパソコンライフは捗るでしょう。

また、ミスも少なくなっていくと思います。

wordやexcelのショートカットでも、altキーは役に立ちます。

また、音量や画面の明るさを変えるときはfnボタンとf5やf6などを押したり

音量はfnボタンとf12やf11だったりします。

機内モードにしたいときはfnボタンとf2ボタンだったりします。

最後に私の使っている端末の紹介です。

ASUS X541UでOSはWindows 10HOMEを使っています。

以上です。

皆様のパソコンライフが楽しくなればいいなと思い

記事を書かせていただきました。
MacbookでMicrosoft Sculpt Ergonomic Desktop キーボードを使う

## TL;DR

MacBook (Pro) で Microsoft Sculpt Ergonomic Desktop キーボード（+マウス）を使えるようにしてみたので設定メモ。

## 動機
MacBook Pro を色んなとこ持ってって作業したり寝っ転がって膝の上でカタカタやったりするのは快適だったんですが、机において文書書いたりコーディングしたりするとタイピングミスがすごく多くて作業効率が悪いことに気づき、外付けキーボードを買うことに。

以前仕事ではWindows＋MSエルゴノミックキーボードを愛用してたので、せっかくなので人間工学的なのを買おうとした、んですが……Mac用＋日本語配列だとロクなのがないので、意を決してMac非対応の MS Sculpt Ergonomic キーボード＋マウスのセットを試してみることにしました。

## ハードウェア構成
- MacBook Pro (13-inch, 2017, Four Thunderbolt 3 Ports)
- マイクロソフト Sculpt Ergonomic Desktop AES L5V-00030 キーボード＋マウス

## 使ったもの
- [Karabinar](https://pqrs.org/osx/karabiner/) ... macOSのキーバインド設定ソフト
- [Scroll Reverser for macOS](https://pilotmoon.com/scrollreverser/) ... スクロールの上下反転用ソフト

## キーボード設定
Karabinar の常駐アイコンをクリックして "Preferences..." メニューを選択。
ダイアログ画面で以下のように設定。 Target Devices の欄で "Microsoft ... " を選択してから行う。
<img width="1112" alt="スクリーンショット 2018-10-22 14.54.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/202213/355f47ad-f351-417f-a056-10b28b239fca.png">

## マウス設定
WindowsのマウススクロールとmacOSの「ナチュラル」スクロールは方向逆に動くので、これを外付けマウスとトラックパッドで使い分けたいと思い、ついでに設定しました。
やることは基本、Scroll Reverser を入れるだけです。

常駐アイコンをクリックすると、メニューとして「スクロールを逆にする」のトグルメニューが出てくるので、こちらでOn/Offを切り替えると、いちいち「システム環境設定」パネルを開かなくて良くなります。
<img width="182" alt="スクリーンショット 2018-10-22 14.59.55.png" src="https://qiita-image-store.s3.amazonaws.com/0/202213/8f5a8bc4-b0b8-1819-8c0a-90ff412c905d.png">

## ご注意
キーボード設定では、僕はShift, Control, Option, Commandの各キーは左手側しか使わないので、そっちの設定しかしていません。右手側の設定は別途追加する必要があると思います。
スリープ設定が勝手に上書きされてしまう場合の対処

会社のPCとかでスリープの設定をしても勝手に上書きとかされてしまうので、Jenkinsマシンとかはこれでスリープさせないようにする

```
$ sudo defaults write /Library/Preferences/SystemConfiguration/com.apple.PowerManagement SystemPowerSettings -dict SleepDisabled -bool YES
```
MySQLのバイナリログ削除タイミング

# バイナリログの運用について

バイナリログは更新系のログが記録されますが、放っておくと際限なく増えます
先日、不可解な更新クエリが大量に発生し、ディスク容量が90％を超えてしまったのでその時の諸々のまとめ

# 障害前基本設定

```
[mysqld]
expire_logs_days=14
```

# expire_logs_daysの動きについて

+ MySQL の再起動時 もしくは、バイナリログのローテート時に実行される
+ そのため、14日たてば自動的に削除されるわけではなく、少しずれる

# 障害時の挙動

+ 20MB/s でディスクが使われていった

# 若手メンバーからの質問

Q: `mysql-bin` を`rm` していいですか？
A: ダメです。`mysql` の中に入って`purge` しないとディスクは空きません
Q: `purge` ってなんすか？
A: こんなクエリを投げるのだよ

```sql
mysql> PURGE MASTER LOGS TO 'mysql-bin.429210';
Query OK, 0 rows affected (0.02 sec)

```

# 対応方針

+ 1ポジションで数百MBあったので、一気に`purge` するとサービス中のMySQLが落ちる可能性があるので、少しづつ実行する
+ ある程度`purge` が完了したら、`my.cnf` をいじって自動で`purge` されるようにする

## 作業内容

+ まず現在のポジションを確認する
    + ここまでは消して大丈夫！

```sql
mysql> SHOW MASTER STATUS\g;
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.434364 | 85145715 |              |                  | 
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)

```

+ 一番古いログのpositionを探す

```bash
ls -ltr /data/mysql/mysql-bin* | head -100
```

+ ひと思いに消す

```sql
mysql> PURGE MASTER LOGS TO 'mysql-bin.459210';
Query OK, 0 rows affected (0.02 sec)

```

# 障害後基本設定

```
[mysqld]
expire_logs_days=7
```
CEATEC2018 個人的まとめ

個人的にこの企業は面白い、要チェック！　という展示をピックアップして紹介していきます。
独断と偏見に基づく記事ですので、仕事の合間の暇つぶしにどうぞ。

# Darktrace
https://www.darktrace.com/ja/

ネットワークの不正アクセスを検知するシステム。
どうも機械学習によってネットワークのトラフィックを学習させることで、異常なアクセスを検知することができるよう。
既存の対策システムは特定のIPアドレス、国などを登録するブラックリスト（あるいはホワイトリスト）形式で不正アクセスを検知するそうですが、これは機械学習によって異常を検知するそうです。

CEATEC2018では特別展示にIoTが選ばれるなど、各企業はこぞって何から何までネットに繋げたがっています。
そんな世界では通信はより複雑になり、人間が異常なアクセスを定義するようでは対応できなくなるのかもしれません。

異常検知の精度についてはパンフレットやブースの説明では聞けなかったのでそこは要チェックとなりますが、より先進的な不正アクセス対策であることは間違い無いでしょう。

# Touch Focus
https://www.touchfocus.com/

ワンタッチでフォーカスしてくれる老眼鏡。
私は老眼鏡が必要な目を持っていませんが、この高齢化社会の時代には必要なものです。

サイボーグの定義というのは身体機能を機械などの人工物に代替させるものですが、そのプリミティブな一例としてメガネというものがあります。
古くからメガネはありますが、オートフォーカスが実装されることで人のピント調節機能を機械に代替することが可能になるわけです。
敬老の日のプレゼント候補となりますね。

# Trackener
https://www.trackener.com/

馬専用健康状態モニタリングシステム。
CEATEC2018では数々の健康状態モニタリングシステムが展示されていたが、馬専用とは思い切った選択だろう。
サイトからわかるように競技用の馬の健康状態を監視するもの。馬はその商業的価値から高額な生き物なので、このような監視システムを導入する価値はあるでしょう。

# コマツの遠隔操縦システム
https://internet.watch.impress.co.jp/docs/event/1148219.html

ドコモとコマツのコラボレーション展示で、夢の遠隔操縦ロボットの展示。
10Gbps以上の通信速度、エンドツーエンドで1ミリ秒の低遅延、99.999％の信頼性を目標とする5G通信で可能になることの一つとして展示されていた。

泥に汚れない土木産業従事者が生まれれば、人手不足解消に繋がるのかもしれない。

# ブレーカー付きType-Cケーブル
http://www.ssdenshi.co.jp/product/usb/

各種ケーブル製造のエスエス電子の製品。
実は既存のType-Cケーブルにはブレーカーのような過電流対策は施されていなかったそうで、このケーブルはブレーカー機構を内蔵した画期的な製品だそうです。

# 視覚障害者向けエアコンコントローラー
![三菱の変なコントローラー.JPG](https://qiita-image-store.s3.amazonaws.com/0/269942/256f0a55-a323-3066-2b9e-f0efde36285f.jpeg)

三菱電機の展示。
盲目の人でもエアコンが操作できるようなコントローラーとして作られたようです。インテリアとしての価値も高そうです。
左から電源ボタン、運転モード（暖房・冷房・除湿）、温度、風量、上下の風向き、タイマーという意味となっています。

そもそも目の見えない人にこれらの概念を理解する予備知識があるのかという問題はありますが、考えとしてはとても面白く、普通のリモコンと比べれば寄り添っているデザインと言えるでしょう。
Fortran入門　PythonからのFortran（90）

# はじめに

大学の課題で、Fortranを使ってプログラムを書け、と言われた。
Pythonからプログラムを始めた自分にとって、Fortranはワケワカメの世界...！

ググっても、わかりやすいチュートリアルが見つからず、ちょっと面倒。

てことで、普段Pythonを使っている人がFortranを始めるのに少しは役に立つ？記事になればと思って書きました。

# やりたいこと

以下のPythonプログラムをFortranで書き直したい。

```python

max_val = None
inpuit_val = None

initial = True

n_iter = 3

for i in range(n_iter):
    
    print("input :")
    input_val = input()

    if initial:
        max_val = input_val
        initial = False

    else:
        if input_val > max_val:
            max_val = input_val

print(max_val)

```

input()で３回数字を読み込んで、最大値をプリントするだけの、簡単なプログラム。
これをFortranにすると...？
    

# Fortran90バージョン

```fortran

      PROGRAM kadai
      IMPLICIT NONE

      real max_val
      real input_val

      logical initial

      integer n_iter
      integer i
      
      initial = .true.
      n_iter = 3

      do i=0, n_iter-1

          print *, 'input : '
          read *, input_val

          if (initial) then
              max_val = input_val
              initial = .false.
              
          else
              if (input_val > max_val) then
                  max_val = input_val
              endif
          endif

      end do
      
      print *, max_val

      stop
      end
```

ハマったのが、おそらく最初に全て宣言をした後に、値の代入をしなければエラーが出るということ。

```fortran

integer a
a = 10
integer b
```

とするとエラーとなるようだ。

Fortranめんどくさい！

# 最後に

また課題が出たら、Fortran記事を書くかもしれません。
次は配列の課題かな？
BitriseとDeployGateの無料版でiOSアプリ配布を自動化する

# 概要
- iOSアプリをGitHubにPushしたら自動的にビルドしてDeploygateで配布する
- BitriseとDeployGateは無料版でテスト配布用

## この記事通りにやれば作れる
- [Bitrise, GitHub, DeployGateを連携させ、全自動でアプリをビルドして配信するCI/CDシステムを作る](https://qiita.com/kyoro353/items/200d5b34b9f5805dd43a)
- 以下はこの記事見ながら設定した内容

## BitriseでAdd new app
- 対象のリポジトリなどを指定する

## BitriseのWorkflows設定
### GitHubにPush ⇒ Bitriseでビルド ⇒ DeployGateで配布 ⇒ Slackへ通知
- こんな感じのWorkflowにした
![workflow.png](https://qiita-image-store.s3.amazonaws.com/0/41208/187d8b87-d389-d1e7-2963-68dd95b8e674.png)

### DeployGate Uploadで設定した項目
- DeployGate API Key
 - DeployGate にアカウント作成、アプリを作成する
 - 対象アプリページのAPI Keyを設定する

- DeployGate Owner Name
 作成したアカウント名

- App file path
 $BITRISE_IPA_PATH

### Send a Slack messageで設定した項目
- Slack Webhook URL
 - Secretsで管理されるようになった。Webhook URLにkeyをつけて管理する。
 - [SlackのWebhook URL取得手順](https://qiita.com/vmmhypervisor/items/18c99624a84df8b31008)
- Text of the message to send.
 - 一連のビルド処理が成功した時にSlackへ通知するメッセージを記載する
- If Build Failed -> Text of message to send, if the build Failed
 - 一連のビルド処理が失敗した時にSlackへ通知するメッセージを記載する

## BitriseのCode Signing設定
- P12ファイルを設定する
 - [開発で使用しているMacで作成する](https://mushikago.com/i/?p=8200)
- Provisioning Profileを設定する
 - [Apple Developerで作成する](https://i-app-tec.com/ios/provisioning-profile.html)

## BitriseのEnv Vars設定
- 環境変数はデフォルトでセットされているはずだが、思うように動作しなかったら確認する

## BitriseのTriggers設定
- 特定リポジトリのPushイベントでビルドプロセスを起動させる場合
 - PUSHタブのPUSH BRANCHを対象のブランチにする。起動するWorkflowを指定する
- 不要なTriggerは削除する