OmniAICreator/Qiita-1.07M huggingface dataset:
初心者がJSDocを調べてみた

##免責事項
この記事は初心者視点でザックリとした説明をしています。正確性に欠ける可能性がございますが、ご了承ください。「明らかに違うよ」ということがありましたら、ご指摘くださると幸いです。

##環境
OS：最新版ではないMacOS

##目次
1. JSDocとは
2. JSDocの書き方

#1. JSDocとは
JSDocは、JavaScriptのソースコードにアノテーション（注釈）を追加するために使われるマークアップ言語です。

###なぜ使うか
複数人で開発を進める場合や、大規模なプログラムを開発する場合に、
変数のデータ型やオブジェクトの種類（配列、関数、コンストラクタ、クラスなど）をコメントとして記述することで、他の人がそれらを見分けることができ、開発の効率が上がります。

加えて、JSDocに対応しているエディターを使うとかなり開発効率が上がると思います。
JSDocに対応しているエディターVSCodeで、以下のように関数を作りJSDocをコメントとして書くと、
![スクリーンショット 2019-11-04 21.25.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374924/f97f3017-7505-1771-9641-947b96d1d41a.png)

以下のように別のファイルで関数にカーソルを合わせたときに、JSDocコメントが表示されます。
![スクリーンショット 2019-11-04 21.25.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374924/76fe6abb-0014-12e7-b6e4-150b256a20a5.png)


完璧な記述をする必要はありませんが、できるだけ推奨されている書き方で記述すると良いそうです。

#2. JSDocの書き方
"/\*\*"で初めて、"\*/"で終わります。
その間に記述がある分だけ"*"を書きましょう。

```JS
/**
 * [記述]
 */
```

###変数
@typeの後の{}内に変数の型（String, Number, Boolean）を書き、そのあとに変数の説明を書きます。

```JS
/**
 * @type {Number} 年齢
 */
let age = 23;
```

###配列
@typeの後の{}内にArrayと書き、そのあとに配列の説明を書きます。

```JS
/**
 * @type {Array} 年齢の配列
 */
let ageArray = [10, 22, 30];
```

###連想配列
最初に@typeで連想配列の説明を書きます。連想配列はオブジェクトの扱いなので、{}の中はobjectと書きます。
次に連想配列のオブジェクト内の@typeで連想配列のペアが何を意味しているのかを書きます。{}内は連想配列の値（value）の型を書きます。

```JS
/**
 * @type {Object} 会員情報の連想配列です
 */
const memberInfo = {
  /**
   * @type {Number} 会員番号
   */
  "id": 1,
  /**
   * @type {String} 会員名
   */
  "name": "taro imo"
}
```

###クラス（インスタンス）
はじめにクラス（インスタンス）の説明をします。
@constructorがコンストラクタであることを表します。（なくても良い）
@thisが何を指しているのか{}の中に書きます。
@paramで関数の引数の説明を書きます。{}の中には関数の引数の型を書きます。

```JS
/**
 * Personクラスのインスタンスを作成する。
 * @constructor
 * @this {Person}
 * @param {String} name 名前
 * @param {Number} age 年齢
 */
let Person = function(name, age) {
    this.name = name;
    this.age  = age;
    }

let taroImo = new Person('taroImo', 23);
console.log(taroImo.name); // taroImo
console.log(taroImo.age); // 23
```

###関数
まずコメントの最初に関数の説明を書きます。
次に@paramで関数の引数の説明を書きます。{}の中には関数の引数の型を書きます。
最後に@returnで返り値の説明を書きます。{}の中には返り値の型を書きます。
*関数内の変数のJSDocは省いています。

```JS
 /**
 * 10年後の年齢を返す
 * @param {Number} age 年齢
 * @return {Number} 10年後の年齢
 */
function tenYearsLater(age){
  let tenYearsLater = age + 10;
  return tenYearsLater;
}
```


#おわりに
この書き方が公式というわけではなく色々な書き方があり、人・企業・組織により書き方は違います。

##参考
「N予備校 プログラミングコース」
https://www.nnn.ed.nico/
「Wikipedia JSDoc」
https://ja.wikipedia.org/wiki/JSDoc
「JSDocでJavaScript のコメントを書こう」
https://sterfield.co.jp/designer/jsdoc-で-javascript-のコメントを書こう/
「Google JavaScript Style Guide」
https://google.github.io/styleguide/javascriptguide.xml?showone=Comments#Comments
BASIC から来た手続き型おじさんが、「手続き型」「関数型」「オブジェクト指向」について考える。

##はじめに

私は趣味で iPhone アプリを開発している51歳のアマ・プログラマーです。
プログラミングを始めたきっかけは36年前（中学生時代）に兄が「日立ベーシックマスターJr.」というパソコンを買ったことです。使用していた言語は BASIC という手続き型言語でした。当時はインターネットもメールもなく、パソコンといえば「自分でプログラムを書かなければ動かない、ただの箱」でパソコンを買った人は必然的に BASIC を習得していました。
Mac や Windows が出現してパソコンが「GUI でネットやメールをする道具」に変貌してからはプログラミングを止めていました。
40歳を過ぎた頃、ネットで iPhone アプリのプログラムを目にした時に感じたことは「for や if が使われている所は BASIC と似てるな。これなら自分でも書けるんじゃないか」ということです。以来 iPhone アプリ開発を趣味としています。
本稿では「手続き型」「関数型」「オブジェクト指向」についての私見を書いてみました。（対象言語は swift です）

##手続き型
「 if を使った条件分岐」と「 for を使った繰り返し」を組み合わせて全てのアルゴリズムを表現する方法です。BASIC ではどんな複雑なプログラムも if と for の組み合わせで書かれていました。逆にいうと if と for を組み合わせればどんな複雑なアルゴリズムも実現できる、ということです。（こういうのをチューリング完全というのでしょうか）
覚えることが少ないので習得のハードルが低く、35年前にNHK教育テレビで放映されていた BASIC 講座では**小学生からおじいさんまで**登場してプログラムを書いていました。

##関数型
簡単に言うと、map, filter, reduce を使って、なるべく if や for を使わないようにする手法です。（単純化しすぎでしょうか・・・）
UISearchController を使った tableView の検索で

```swift
func updateSearchResults(for searchController: UISearchController) {
        if let searchText = searchController.searchBar.text, !searchText.isEmpty {
           filteredArray = unfilteredArray.filter {
                  $0.lowercased().contains(searchText.lowercased())
            }
        }
        tableView.reloadData()
    }
```
のように filter を使うと、とても便利です。 
if や for の多重ネストが map や filter で1行に収まるとプログラムがすっきりします。

##オブジェクト指向
swift で iPhone アプリを開発する時は、オブジェクト指向を特に意識しなくても存分にオブジェクト指向の恩恵を受けています。
iPhone 画面上のパーツ（Label, Button, SegmentedControl）などはそれぞれ、UILabel, UIButton, UISegmentedControl などのクラスのインスタンスとして定義されます。
Label に
myLabel.text = "Hello, world!"
などのメッセージを送ると UILabel クラスの内部を知らなくても実行されます。
我々が UILabel クラスの内部を覗いたり、書き換えたりすることはありません。（こういうのを隠蔽・カプセル化というのでしょうか）
tableView から画面遷移するアプリでは1画面あたり1つのViewController クラスが割り当てられますが、クラス同士が干渉することがないので同じ変数名を複数の ViewController クラス内で使用しても問題がありません。

##おわりに
以上、アマ・プログラマーより私見を述べさせていただきました。
プロの方々から補足をいただければ幸甚です。
【JavaScript入門】変数宣言とStrictモード

## let命令
* 識別子を「ブロックスコープ」で定義する
* ブロックスコープで定義された識別子はそれを囲むブロックでしか有効にはならない
* ブロックは通常、ifやforなどのフロー制御に関係して使われるが、独立したブロックを用いることもできる

``` javascript
// 基本的な宣言
let msg;

// 複数の変数を宣言
let x, y;

// 初期値を設定
let greeting = 'こんにちは、世界！';

// 独立したブロック
{
    let z = 3;
    console.log(z);
}
console.log(`ブロックの外。x = ${z}`); // ReferenceError: x is not defined
```

## var
* varによって宣言された変数は「関数スコープ」をもつ（宣言された関数全体で有効になる）

### 巻き上げ（hoisting)

varを使って宣言した場合は、同じスコープの中であれば、たとえ宣言の前であっても有効になる。ただし巻き上げられるのは宣言だけであって、値の代入も巻き上げられるわけではない。したがって次のプログラムのように、宣言しただけではxの値はundefinedになる。

``` javascript
console.log(x);
var x = 3;
console.log(x);
```

varで宣言された変数のように、関数宣言もスコープの先頭に巻き上げられる。したがって、関数の宣言の前に呼び出すことができます。

``` javascript
f();
function f() {
    console.log('関数fが呼び出された');
}
```

ただし、変数に代入された関数式は巻き上げられない。

``` javascript
f();
var f = function() {
    console.log('関数fが呼び出された');
}
console.log(f);
f();
```

## let命令とvar命令の比較
* let命令は同名の変数を許可しない
* var命令は重複を許容する（宣言を繰り返してもエラーにならない）
* let命令はブロックスコープを認識する（より細かく変数の有効範囲を管理できる）
* var命令の場合、ブロックの中で新しい変数を宣言したとしても関数全体がスコープになってしまう
* letを使って変数を宣言すると、宣言をするまでは存在しない（巻き上げが起きない）

```javascript:script.js
let x = 3;
let x = 5; // Error
{
    let x = 5;
}
console.log(x); // 3

var y = 3;
var y = 5;
{
    var y = 5;
}
console.log(y); // 5
```

**ES2015を利用できる環境では、できるだけlet命令を優先して利用することが推奨される** 

## Strictモード

### 概要

* JavaScriptの落とし穴（暗黙的グローバル変数など）を検出して、エラーとして通知してくれるしくみ
* InternetExplorerではバージョン10以降でしか対応していない
* `'use strict';`は無害な文字列式で、非対応ブラウザーでは無視される
* 利用するメリット
 * 非Strictモードのコードよりも高速に動作する場合がある
 * 将来のJavaScriptで変更される点を禁止することで、今後の移行が簡単になる
 * JavaScriptの「べからず」を理解する手がかりになる

### 有効にする方法
1. スクリプトの先頭に`'use strict';`いう文を追加
 * 以降のスクリプト全体がStrictモードで解釈されるようになる
 * 複数のスクリプトを連結した場合、以降のすべてのコードに影響を及ぼす
 * 1つでも非Strictモードのコードが混在している場合には、正しく動作しない可能性がある

    ``` javascript
    'use strict'; // スクリプトの先頭に追加
    /*
      任意のコード
     */
    ``` 

2. 関数の本体先頭に「'use strict';」いう文を追加
 * 関数内のスクリプトがStrictモードで解釈されるようにnaru

    ``` javascript
    function hoge() {
        'use strict'; //関数の本体先頭に追加
    }
    ```

自分の書く関数についてはすべてstrictモードにしたいという場合、次のように全体のコードをひとつの関数としてラップしてしまう方法が使える。

```javascript:script.js
(function() {
  'use strict';
  /*
   * 自分のコードをここに書けば、すべてstrictモードで実行される。
   * この外にあるスクリプトには影響しない 
   */
})();
```

### Strictモードまとめ
* 新規の開発では、できるだけStrictモードを有効にすることが推奨される
* 一般的には、関数の本体先頭に書く記法が望ましい（有効範囲を限定できる）
* 即時関数のイディオムを利用すれば、自然と自前のコード全体にStrictモードを適用できる
創作＋機械学習LT会議事録

# 創作＋機械学習LT会議事録
先日11/3日に、[「創作＋機械学習LT会」](https://connpass.com/event/149734/)というイベントを主催し、盛況に終わりました。創作と機械学習をテーマにLTを行う会です。ここで言う創作は「小説、漫画、アニメ、イラスト、映画、音楽、ゲーム」等を指しています。私はこの分野に明るいわけではありませんが、興味がある人が多いはずの分野でイベントが無いのが寂しかったので本イベントを主催しました。今回はイベント主催が初だっだという事もあり、小規模に開催しました。参加者は８人で、全員発表を行いました。テーマも論文紹介寄り、研究寄り、アプリ開発寄り、哲学寄りと様々な観点のものがあったのが良かったです。テーマは以下の通りです。発表スライド（一部）は[創作＋機械学習LT会 - 資料一覧 - connpass](https://connpass.com/event/149734/presentation/)においてあります。

## midz 「小説の雰囲気に合った音楽の自動割当」
最初は私が発表しました。ゲームでは物語に合わせて音楽が流れるので、そのデータを使って、小説などの物語に合わせた音楽を自動選択するモデルを学習した話です。未知の音楽に対しての判定も可能にするために、モデルにはSiameseNetworkを使いました。

## wakadoriさん 「SNSにおける 二次元イラスト閲覧の自動化」
Twitterの良いね情報を使って、ユーザーが好むイラストをリコメンドしてくれるアプリを作る話。リコメンド方法の候補には、協調フィルタリングとコンテンツベースがあります。ユーザー数が少ない時はコンテンツベースが有利。実装はjavascript(photo.js等)を使った行う予定。
 
## Lentoさん「データに寄り添う着色の手法」
 線画着色の最新の手法について紹介されていました。pix2pixは、機械が生成した着色絵と本来の着色絵を識別するGANの仕組みで学習します。Style2paintは従来の着色技術の問題を解決するために、着色工程を二段階に分けました。一段回目では従来通りに着色し、二段階目では従来手法がよく陥る誤り（色の選択ミス、はみ出し、ぼやけ）の修正を行います。また、線画抽出は自動で行うが、線画の種類が１種類だと過学習を行ってしまうので、様々な方法で線画抽出を行う手法があるそうです。

## Jerry Chiさん「generating-fake-k-pop-faces」
AutoEncoderを利用してk-popのアイドルの顔をする実験を行っていました。icrawlerというツールを使うと、googleの画像検索結果を簡単にダウンロードできるそうです。ノードごとに、髪の毛担当、顔担当などが決まる結果が得られていました。data の正規化やノイズ除去で大きく精度が変わったそうです。

## まっくすさん「Rhythm is All You Need：コード進行を考慮したリアルタイム即興演奏生成」
背後で流れている音楽に合わせて、キーボードを叩くと、その音楽に合わせたメロディーを奏でてくれるシステムを作ったお話でした。学習はtheorytabと言われる、楽譜をデータ化したものを使用。モデルはBidirectionalGRU。過学習させた方が、学習データの定形メロディを記憶するため、良いメロディを奏でるそう。

## ゆきりんさん「働きたくないイタチと言葉がわかるロボット：人工知能をテーマにした小説の解説」
川添愛さんと言う、言語学、自然言語処理の専門家の方の書いた小説の紹介。文章は、同じ文でも、文脈や発話者の声色によって、意味が異なることがあるため、文章だけを見て意味を理解しようとする現在の機械学習モデルには限界がある。近年の自然言語処理分野の研究では、言語学の知見が使われなくなってきているなどの話がありました

## そねおさん「Make ch@tbot characterize：キャラクターの特徴を考慮したチャットボットの作成」
 idol m@sterの夢見り○むのLINEのチャットボットを作った話。発表者の意向により詳細は省きます。

## やすでぃーさん「漫画を定量化する試み」
 漫画の特徴量を使って、話者を推定した研究。特徴量は、セリフ文や、コマ割り、各コマのキャラクターの数、顔の面積の占有率など。キャラクターの描き方や記号、文字数などが特徴量として聞いている事がわかったが、決定的な特徴量はない。また、同じ作者でも、作品によってかなり精度が変わるので、特徴は、作者単位というより作品単位で決まっている可能性が高いとの事。

## 所感
LTという名目でしたが、皆２０分ほど発表していて充実した議論ができました。好評だったので、次回も開催したいと思います。次回の開催は４月頃を予定しています。今回は初開催だった事もあり、あまり大きな会場を用意できずに少人数で開催しましたが、都合が付けば次回はもう少し大きな規模で開催したいです。
フェルミ推定で日本のModern Fortran人口を推定してみた

Fortran Advent Calendar 2019よろしくお願いします。
ネタ記事でございます。

Modern Fortranが好きなので、もっと人口が増えてくれればいいなと思っているのですが、いったい現状で日本に何人のユーザーがいるのか気になったので推定してみました。

フェルミ推定を使って推定してみます。
記事の内容を思いついたときに作成したので、データが少しだけ古いのはご容赦を。

###Modern Fortranって？
Fortran2003以降の機能を利用し、オブジェクト指向プログラミング等を行うFortranの新しいスタイル。
古代言語ともいわれるFortran/FOATRANのユーザーは、（それゆえに？）比較的保守的なプログラマが多い（印象）。なので、Modern Fortranユーザーなんて、絶滅危惧種かもしれない。

###[フェルミ推定](https://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A7%E3%83%AB%E3%83%9F%E6%8E%A8%E5%AE%9A)とは？
物理学者、エンリコ・フェルミに由来する推定方法。
おおよその基礎となる（すぐに分かる）数量と単純な（割合の）計算から、ざざっと目安の数を算出する方法。
アメリカのシカゴに調律師は何人いる？などといった問いで有名。

###Modern Fortranを利用するプログラマの割合は？
幸いなことに、Qiitaではタグをフォローしている人数がわかります。
メジャーな言語（例えばpython）と比較すれば、Modern Fortranユーザーのおよその割合がわかるハズ。

タグをフォローしている人数です（2019/11/04日現在）
python：63625
Fortran：212
ModernFortran：8

Modern Fortran の8ってちょっと少なすぎじゃ、、、

python人口と比較すると、
Fortran人口は0.3%
Modern Fortran人口は0.0126%

###日本のプログラマの人口は？
日本のプログラマの人口は統計がとられているらしいです。下記の記事によると、
2016年度調査：88.6万人
まあ、ざっくり2019年現在で90万人と仮定します。
https://netvisionsystems.info/news/114

さらにそのプログラマの中で、pythonに興味がある人口を20%と仮定しましょう（大胆な仮定）。すなわち、python人口は90万×0.2で18万人ですね。

###というわけで、日本のModern Fortran人口を推定してみましょう
以上を踏まえて、フェルミ推定を行ってみました。
計算すると以下の通りです。

900,000×0.2×0.000126＝22.6



　　　　　＿人人 人人＿
　　　　　＞ ２３ 人  ＜
　　　　　￣Y^Y^Y^Y￣


というわけで、日本のModern Fortran人口は23人でした。ホントに絶滅危惧種だった。

###Modern Fortranを活性化させたい
[Modern Fortran勉強会](https://qiita.com/implicit_none/items/574cbb9440c851422efe)の記事など、QiitaにはModern Fortranについての記事がたくさんあります！初心者でもきっと取り組みやすいハズ。
私もModern Fortranユーザーを増やすべく、ぼちぼちと記事を増やしていく予定です！

あなたが日本で24人目のModern Fortranユーザーになるのを、心待ちにしています。

以上、お付き合いありがとうございました。
pandasで数値の変数を、閾値を決めてカテゴリカルに変換する

自分の備忘録として書いていこうと思います。

初記事からすごくピンポイントですが、機械学習の特徴量エンジニアリングとして、

・0~1は1,1~3は2
・3~10は3
・10~20は4　…………

　のように、特徴量を区分したい時ってあると思います。

すごく分かりやすい例だと、
[ビューフォート風力階級](https://ja.wikipedia.org/wiki/ビューフォート風力階級)

```Python:
beaufort = [(0, 0, 0.3), (1, 0.3, 1.6), (2, 1.6, 3.4), (3, 3.4, 5.5), (4, 5.5, 8), (5, 8, 10.8), (6, 10.8, 13.9), 
          (7, 13.9, 17.2), (8, 17.2, 20.8), (9, 20.8, 24.5), (10, 24.5, 28.5), (11, 28.5, 33), (12, 33, 200)]

for item in beaufort:
    train.loc[(train['wind_speed']>=item[1]) & (train['wind_speed']<item[2]), 'beaufort_scale'] = item[0]


```

このサンプルコードは非常にシンプルでかつ強力、使い回しもしやすいので、
自分の引き出しに入れておきます！！
Raspberry Pi で BME280 をモニタする（C++とソフトウェアI2C）

Raspberry Pi で、温度湿度気圧センサーの BME280 から、測定値を読み取ります。

というネタは、ネット上に溢れているのですが、困ったことに、ほとんどがPythonで書かれているため、C/C++で書かれたものが少なく、参考にならないとか、外部のI2Cライブラリに依存していて、そもそもI2Cハードウェアやライブラリを持たないようなマイコンチップで応用しづらい、などの不便さを感じました。そこで、この記事では、次のような方針でBME280から値を読み取ります。

- Amazonで820円で買える激安センサーを使用する
- C++で実装
- I2Cの信号線を自前制御

お手軽に購入できる、安いセンサーモジュールを使用します。

作例では Raspberry Pi を使用しましたが、メモリの少ないマイコンチップなどでの使用も想定し、C++で実装しています。AVRマイコンとavr-gccの様なプラットフォームにも簡単に移植できると思います。classを解体すればC言語にすることもできるでしょう。

最近の多くのマイコンチップにはI2Cの送受信ハードウェアが搭載されていますが、そういった機能が使えないチップを想定し、GPIOをダイレクト制御して、**ソフトウェアI2C**による通信を行います。

BME280から値を読み出す処理は、スイッチサイエンス社が公開している[Arduino用のサンプルプログラム](https://github.com/SWITCHSCIENCE/BME280)を元に開発し、ソフトウェアI2Cライブラリは、昔私が自作したものを使用しています。

**ソースコード：** https://github.com/soramimi/bme280

Raspberry Pi のヘッダから4本の線を引き出します。

- 1番ピン : 3.3V
- 3番ピン : SDA
- 5番ピン : SCL
- 6番ピン : GND

I2Cは電源以外に2本の信号線で双方向通信を行う規格です。Raspberry PiはハードウェアI2Cの機能を搭載していますが、それは使用せず、GPIOとして直接制御し、ソフトウェアI2Cを実現しています。

![a.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61222/717a308f-a5d5-dca6-1621-f6223695ecc0.jpeg)

センサー基板のシルク印刷の通りに線をつなぎます。VCCとSDOは3.3Vに接続します。CSBというピンは使いません。

![b.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61222/df75b4c3-4d88-a7fe-a951-b96c789ffeff.jpeg)

Raspberry Pi でC/C++を使ってGPIO制御するには、次のライブラリが使いやすいです。
http://www.airspayce.com/mikem/bcm2835/
Laravel プロジェクト作成まで

# PHP のインストール
```bash
brew install composer
```

# composer のインストール
```bash
brew install composer
```

# githubでプライベート・アクセス・トークンを作成

* github.com にログイン
* Setting > Developer settings に移動
* New Personal access tokens
* read:packages をチェック
* 作成されてプライベート・アクセス・トークンをコピー

# composer にプライベート・アクセス・トークンを設定
```bash
composer config --global github-oauth.github.com ${プライベート・アクセス・トークン}
```

# Laravel プロジェクト作成
```bash
composer create-project --prefer-dist laravel/laravel ${プロジェクト名}
```

# 参考文献
* [Laravel 6.0 Installation](https://readouble.com/laravel/6.0/en/installation.html)
* [ComposerでGitHubのリポジトリをHTTPSで追加したときの認証設定](https://qiita.com/fivestar/items/fc15e0bb379c791ff6b2)
SECCON CTF 2019 write-up

##概要
SECCON CTF 2019のうち、crypt問題のcoffee_breakのwrite-upを記載します。
##問題
The program "encrypt.py" gets one string argument and outputs ciphertext.
Example:

$ python encrypt.py "test_text"
gYYpbhlXwuM59PtV1qctnQ==

The following text is ciphertext with "encrypt.py".
FyRyZNBO2MG6ncd3hEkC/yeYKUseI/CxYoZiIeV2fe/Jmtwx+WbWmU1gtMX9m905
Please download "encrypt.py" from the following url.

encrypt.pyは以下のとおり。

```encrypt.py
import sys
from Crypto.Cipher import AES
import base64

def encrypt(key, text):
    s = ''
    for i in range(len(text)):
        s += chr((((ord(text[i]) - 0x20) + (ord(key[i % len(key)]) - 0x20)) % (0x7e - 0x20 + 1)) + 0x20)
    return s

key1 = "SECCON"
key2 = "seccon2019"
text = sys.argv[1]

enc1 = encrypt(key1, text)
cipher = AES.new(key2 + chr(0x00) * (16 - (len(key2) % 16)), AES.MODE_ECB)
p = 16 - (len(enc1) % 16)
enc2 = cipher.encrypt(enc1 + chr(p) * p)
print(base64.b64encode(enc2).decode('ascii'))
```

##解法

"encrypt.py"はテキスト文を暗号化するプログラムのようです。
暗号化されたテキストを復号すればflagが手に入りそうです。

まずはencrypt関数を復号する関数(decrypt関数)を作成することにしました。
encrypt関数は、引数で与えられたテキスト(text)を文字ごとに、文字コードへ変換→計算→文字へ
変換しています。
なので、足されたものを引いて、引かれたものを足せば元に戻りそうです。
encrypt関数とdecrypt関数のみを含んだプログラムで動作確認をしつつ作成した関数が以下になります。

```
def decrypt(key, encTxt):
        t= ''
        for j in range(len(encTxt)):
                t += chr((((ord(encTxt[j]) -0x20) - (ord(key[j % len(key)]) - 0x20)) % (0x7e - 0x20 + 1)) + 0x20)
        return t
```

"encrypt.py"の後半部分ですが、AESで暗号化しています。
AESは共通鍵暗号方式（暗号化と復号が同じ鍵を使用）なので、key2をそのまま流用可能です。
なお、pはブロックの端数を埋めるためのもの（パディング）です。
復号用の関数は以下のようになります。

```decrypt.py
import sys
from Crypto.Cipher import AES
import base64

def decrypt(key, encTxt):
        t= ''
        for j in range(len(encTxt)):
                t += chr((((ord(encTxt[j]) -0x20) - (ord(key[j % len(key)]) - 0x20)) % (0x7e - 0x20 + 1)) + 0x20)
        return t

key1 = "SECCON"
key2 = "seccon2019"
text = sys.argv[1]

dec1 = base64.b64decode(text)
cipher = AES.new(key2 + chr(0x00) * (16 - (len(key2) % 16)), AES.MODE_ECB)
dec2 = cipher.decrypt(dec1).decode("ascii")
print(decrypt(key1, dec2))
```
これを実行すると以下のようになります。

```
$ python decrypt.py FyRyZNBO2MG6ncd3hEkC/yeYKUseI/CxYoZiIeV2fe/Jmtwx+WbWmU1gtMX9m905
SECCON{Success_Decryption_Yeah_Yeah_SECCON}?AA56
```

flagが得られました。"}"以降の文字列はAES復号の際に付与されたパディングなので無視します。
picoCTF 2019 where-is-the-file - Points: 200

#問題

https://2019game.picoctf.com/problems

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/ce089f56-611a-80e7-346c-8d72808c8065.png)

#解いてみた

サーバに接続してllします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/16bd52a4-dbfb-9d4f-ab9d-c06f2d9ca775.png)

ファイルが一つあるのでcatしてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/c26f02af-a4b2-f135-16b5-ee6d3f19f15f.png)

ん？
答えでした。

lsだと出ないので隠しファイルを見つけ出す問題だったようです。
picoCTF 2019 whats-the-difference - Points: 200

#問題

https://2019game.picoctf.com/problems

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/8bc20917-792e-55dc-3f9f-28413c39783a.png)

#解いてみた

問題の2つのファイルをダウンロードしましたが、ファイルサイズが大きい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/e106ac37-8edd-1080-aad1-66a7037aa4bc.png)

二つの画像を見てみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/40b5e68e-3bd6-1526-938e-c3c9f7a1df6f.png)

猫です。
明らかな違いはあるもののどうやって言えばいいのか。
バイナリを比較してみますか。

Stirling使います。

比較機能があるのでそれを使うとたくさん出てきました。
そして一つ目を選択してみるとpicoの文字が。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/ca54eab7-1a2a-c801-2f0b-5a69103f1a19.png)

それぞれつなぎ合わせるとフラグでした。
RailsアプリをHerokuにデプロイする【備忘録】

# 環境
AWS Cloud9
Ruby 2.5.3
Rails 5.2.3

# はじめに
Qiita初投稿です。
毎回、忘れてしまうので自分への備忘録として。

# 前提として
Herokuにて登録していること
Gitを使用していること

公式サイト: [Heroku](https://dashboard.heroku.com/)

# とりあえずHerokuとは
PaaS(Platform as a Service)と呼ばれるサービスで、サーバコンピュータを提供してくれるサービスである

# Herokuへログイン
HerokuをCloud9のターミナルから操作するためのコマンドツール(heroku-cli)をインストールする。

```
$ wget https://cli-assets.heroku.com/heroku-linux-x64.tar.gz -O heroku.tar.gz
$ sudo mkdir -p /usr/local/lib/heroku
$ sudo tar --strip-components 1 -zxvf heroku.tar.gz -C /usr/local/lib/heroku
$ sudo ln -s /usr/local/lib/heroku/bin/heroku /usr/local/bin/heroku
```
ターミナル上で、Heroku にログインします。

```
$ heroku login -i

Enter your Heroku credentials.
Email: Herokuに登録したメールアドレスを入力
Password: Herokuに登録したパスワードを入力
```

# 自分の作ったプロジェクトフォルダへ移動する。

```
cd ~/environment/自分で作成したプロジェクトフォルダ
```
 
# Heroku アプリを作成する
ターミナルにてherokuコマンドが使えるようになるので操作する。

```
$ heroku create [Herokuアプリ名]
```
※例: test-sample-123
※すでにあるアプリ名があった場合重複はできない

# リモートリポジトリ heroku の確認

```
$ git remote -v
```

# Heroku用の設定
Herokuは標準はPostgreSQLなので開発環境でMySQL等、使用していた場合設定する

```ruby:Gemfile
group :production do
  gem 'pg', '>= 0.18', '< 2.0'
end
```
開発環境で読み込む必要がないので `--without production` を付ける

```
$ bundle install --without production
```
`database.yml` も下記のように修正する

``` yml:config/database.yml
production:
  adapter: postgresql
  encoding: unicode
  pool: 5
  database: message-board_production # 注意
  username: message-board # 注意
  password: <%= ENV['MESSAGE-BOARD_DATABASE_PASSWORD'] %> # 注意
```
注意: message-board、MESSAGE-BOARDはアプリ名で変わります。

Gitコミットを最新にする

```
$ git add .

$ git commit -m 'new heroku'
```

# 本番環境用にDBをマイグレーションする

```
$ heroku run rails db:migrate
```

# デプロイ開始

```
$ git push heroku master
```
プチコン4まとめ (7) RPGとかでよく見る選択メニューを作成してみる

[前回](https://qiita.com/yamachan360/items/cdf07b8fc4b75ff393ac) はかなり趣味に走ってしまい、「急に難易度上がった」「サンプル長っ！」などのご意見もいただき、ちょっとペースを戻したいとおもいます。

※ タイトルも短くしましたw

今回は、RPG などでよくみる、ポップアップ式の選択メニューを表示する関数を作成してみました。改造し易いようめっちゃシンプルなやつ。

ゲームのタイトル画面とか、ゲームオーバー時のコンティニュー時とか、アドベンチャーゲームの会話とか、RPG に限らずちょこまかと利用する機会があるかとおもいます。

# 今回のサンプル動画

![qiita.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/d094c9d0-ec32-43e1-a66c-f50adc7f7cca.gif)

# 今回のソースコード

![2019082413532000-B4374FDA41BFF09D976C1FEA83EFB230.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/ee94e2de-433c-99e7-8ab4-6f977f650c20.jpeg)
今回の実装のメインは RPG_MENU 関数のため、ソースコードのメイン部分はこの関数を呼び出して、結果を表示しているだけです。以下の部分。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/b4d83439-ed57-c8cf-fc0a-5f16710378b3.png)

# 拡張案

基本的な機能しか実装していませんので、いろんな拡張の方向性があります。

例えば表示する項目が多い場合、2列や3列など、複数列で表示するメニューがあると便利かもしれません。表示部分を拡張して、カーソルの動きに左右を追加すれば実装できそうです。

枠に使うキャラクター文字が関数にそのまま記述されている(ハードコードされている)ので、それを変えるだけで枠の見た目を変えられます。同様にカーソルも。最もお手軽な改造かもしれません。

また今回は通常のコンソールに表示しているので、元にゲーム側でコンソールを使用している場合に、その表示を壊してしまうかもしれません。

これには対応方法が2つあって、まず1つは、テキストスクリーンに表示するバージョンを用意すればokです。今は表示に `PRINT` 命令 (省略形は`?`) を使っているので、これを `TPRINT` に置き換えるだけで実装できます。表示するスクリーンIDをグローバル変数、もしくは引数で指定できるよう実装するのが良いでしょう。

もう1つの実装方法として、表示する前に、現在の表示内容をバックアップしておく、つまり文字変数などにいったん保持しておく方法があります。メニューを消す際に、保存しておいた元の表示内容でメニューを上書きすれば元通り、という訳です。

また細かい機能として、メニュー項目の「ディセーブル」つまり一時的な無効化の機能もあると便利かもしれません。例えばゲームをセーブできない場面では、メニューの「セーブ」項目が灰色で表示され、選択ボタンに反応しない、などです。

# より高度な拡張案

今回のメニューは、いわゆる「モーダル」な実装になっています。例えばアクションゲームを実行中に今回のメニューを呼び出すと、裏のアクションゲームは止まってしまいます。

メニューを表示している間もゲームを止めたくない、いわゆる「モードレス」なメニューの実装は、今回のようにお手軽ではなく、ゲームの実行エンジンに組み込む感じになります。少なくともゲームのメインループからのフック、つまり呼び出しを何らかの手段で実装する必要があります。

今回のサンプルの作り方から大きく逸脱するので、この「モードレス」なメニューに関してはまた別の機会に実装してみましょう。

# 今回の関数

今回のサンプルで作成＆利用している関数に関して　[プチコン4 公式リファレンス](https://sup4.smilebasic.com/doku.php?id=reference:%E3%81%99%E3%81%B9%E3%81%A6%E3%81%AE%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9) にあわせたカタチで説明してみます。

## LIST_WIDTH

LIST_WIDTH(文字列の配列)
文字列の配列を検査し、最も長い配列の文字数を返す。

**引数:**
文字列の配列: 検査対象となる

**返値:**
配列中で最も長い配列の文字数

**例:**
`R=LIST_WIDTH(["str1","str2"])`
`MENU$[]=["str1","str2","str3"]: R=LIST_WIDTH([MENU$)`

**今回の実装コード:**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/60530357-fa2d-5ccd-985b-a8d08e0e4813.png)

## RPG_MENU

RPG_MENU(X座標,Y座標,文字列の配列,カーソル初期位置)
シンプルなRPG風のメニューを出し、入力待ちをする。

**引数:**
X座標: メニューの表示位置 (X座標) の数値
Y座標: メニューの表示位置 (Y座標) の数値
文字列の配列: 表示するメニュー項目
カーソル初期位置: カーソルの初期位置を指定する数値 (1が最初のアイテム)

**返値:**
選択したアイテムの番号 (1が最初のアイテム)
キャンセルした場合には負の値になる

**例:**
`MENU$[]=["str1","str2","str3"]: R=RPG_MENU(4,4,MENU$,1)`

**今回の実装コード:**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/8d474d0c-7e96-a52c-09f8-a450c973d7c5.png)

# というわけで

内容を軽くすると言ったけど、軽すぎかな？などと思いつつ。ただ、これくらい単機能のほうがわかりやすいかな？とも思う次第です。

今後、今回ご紹介した関数、もしくはその拡張を利用したコードをご紹介することもあると思います。プログラミングは蓄積や、それによる手抜きも大事ですからね！

それではまた。
PHP2

```php:php
<?php
$item = 'test'; // 変数
echo $item;

$items = ['りんご' , 'ばなな']; // 配列

array_push($items, 'みかん'); // 配列に追加

unset($items[0]); // 配列から削除
$items = array_values($items); // 配列を詰める

foreach ($items as $item) {
	echo $item . '<br/>';
}

// 連想配列
$users = [
	1 => ['name' => '田中', 'age' => 10, 'skills' => ['HTML', 'CSS']],
	2 => ['name' => '佐藤', 'age' => 20, 'skills' => ['PHP', 'MySql']]
];

var_dump($users);

foreach ($users as $id => $user) {
  echo  'ID: ' . $id . ', 名前: ' . $user['name'] . ', 年齢: ' . $user['age'];
  echo ', スキル: ';
  foreach ($user['skills'] as $skill) {
	  echo $skill . ' ';
  }
  echo '<br/>';
}
?>
```
picoCTF 2019 vault-door-3 - Points: 200

#問題

https://2019game.picoctf.com/problems

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/591ad099-f018-51c8-1a22-0796b8f6f397.png)

#解いてみた

javaのソースコードを読み解く問題です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/be2f61f1-ce3c-37a5-a371-3763a9d4a9c0.png)

パット見、42行目にフラグの中身っぽいのが書かれているので、一応入力してみましたが、違いました。
パスワードを入力してcheckPasswordでチェックして正解ならそれがフラグという問題のようです。

こういうのは考えるより実行しながら答えに寄せていくほうがラクだし確実です。

Java実行環境(Webブラウザ)
http://ab77.jp/java/java.php

ここで実行させます。
6行目のところにべた書きするようにします。

最初の条件は32文字なのでそこだけ合わせて

```
1234567890abcdefghijklmnopqrstuvwxyzABCDE
```

と打ち込んで実行してみます。
41行目と42行目の間でsを出力するようにします。

```
90abcdefnmlkjihgCpArytwvuxszqBoD
```

こんな感じで出力されました。

```
90abcdefnmlkjihgCpArytwvuxszqBoD
↓
jU5t_a_sna_3lpm16g84c_u_4_m0r846
```

となるように

```
1234567890abcdefghijklmnopqrstuvwxyzABCDE
```

を並び替えれば終了です。

32文字全部を使ってるわけではないので空いているところにスペースを入れてみました。
が、それだとscanner.next()で区切り文字として判断されるようで、うまくいきませんでした。
なので!を入れて答えてみるとJava自体はうまくいきました。

がフラグとして答えると不正解でした。

空白の部分は何を入れればいいのか？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/0eead506-2cfc-7b4a-d7b5-a2d8227da5c6.png)

あぁ、この!のところはpicoCTF{}と文字数が一緒だったのでこれに変換して正解でした。
TypeScriptのaddEventListenerで「EventTargetの中にそんなプロパティないよ」と怒られる問題について

# どんな問題？
JSっぽくこんな風に書くと「**EventTargetの中にそんなプロパティないよ**」とTypeScript先生に怒られてしまいます。

```ts
const element = document.querySelector("#piyopiyo");
element!.addEventListener("click", (e) => {
    let target = e.target;
    console.log(target.innerText);
})

// エラー！
// Property 'innerText' does not exist on type 'EventTarget'.
```

# 解決方法
`as HTMLElement`でキャストすることで解決できます。これが一番簡単だと思います。

```ts
const element = document.querySelector("#piyopiyo");
element!.addEventListener("click", (e) => {
    let target = e.target as HTMLElement;    // <-- ココ！
    console.log(target.innerText);
})
```
**参考**
[javascript - error " Property 'innerText' does not exist on type 'EventTarget' "? - Stack Overflow](https://stackoverflow.com/questions/54886637/error-property-innertext-does-not-exist-on-type-eventtarget)

**他の解決方法のご紹介（interfaceの利用）**
[TypescriptでaddEventListener時のEventTarget型ではまった - Qiita](https://qiita.com/wamei/items/43753e03821964719f31)

## 原因
「**EventTargetはHTMLElementじゃないからダメ**」というお話みたいです。
JavaScriptの場合はEventTargetでもHTMLElementのプロパティをそのまま使えましたが、TypeScriptの場合は一度明示的にキャストする必要があるみたいです。

[TypescriptでaddEventListener時のEventTarget型ではまった - Qiita](https://qiita.com/wamei/items/43753e03821964719f31)
[EventTarget - Web API | MDN](https://developer.mozilla.org/ja/docs/Web/API/EventTarget)

# 参考リンク
- [javascript - error " Property 'innerText' does not exist on type 'EventTarget' "? - Stack Overflow](https://stackoverflow.com/questions/54886637/error-property-innertext-does-not-exist-on-type-eventtarget)
- [TypescriptでaddEventListener時のEventTarget型ではまった - Qiita](https://qiita.com/wamei/items/43753e03821964719f31)
- [TypeScriptのaddEventListenerで苦しんだところまとめ - Qiita](https://qiita.com/tobita0000/items/7341e11305eb25726dc0)
pipやJupyter Notebook使用する際のProxy設定

#はじめに
社内ネットワーク等Proxyサーバ経由する環境で以下に困っている方。
①pipでproxy経由する設定方法がわからない
②Jupyter Notebookでproxy経由する設定方法がわからない
③プロキシのURL設定値が分からない。(←個人的にココにはまりました)

#必須情報
プロキシの以下情報を把握していること。
・プロキシユーザ
・プロキシパスワード
・プロキシサーバホスト
・プロキシサーバポート

#①pipでproxy経由する設定方法
Anacondaプロンプトを起動し、以下を実行

```py
# プロキシURL設定
set HTTPS_PROXY=http://{プロキシユーザ}:{プロキシパスワード}@{プロキシサーバホスト}:{プロキシサーバポート}
# インストールライブラリ
set INSTALL_LIB_NAME=opencv-python

# pipコマンド
pip install --user %INSTALL_LIB_NAME% --proxy %HTTPS_PROXY%
```
#②Jupyter Notebookでproxy経由する設定方法
Anacondaプロンプトを起動し、以下を実行

```
ipython profile create
```
ipython_config.pyファイルが生成されるため、
以下のコマンドを実行し、編集を行う。
ファイルパスは環境によって異なるため、以下の値はあくまで参考程度に。

```
notepad C:\\Users\\USER\\.ipython\\profile_default\\ipython_config.py
```
編集箇所は任意だが、修正箇所が分かりやすいように、
一番最下部へ追加。

```py
import sys,os,os.path
os.environ['HTTP_PROXY']="http://{プロキシユーザ}:{プロキシパスワード}@{プロキシサーバホスト}:{プロキシサーバポート}"
os.environ['HTTPS_PROXY']="http://{プロキシユーザ}:{プロキシパスワード}@{プロキシサーバホスト}:{プロキシサーバポート}"
```

# ③プロキシのURL設定値
知っていればすぐなんですがね。。

```py
http://{プロキシユーザ}:{プロキシパスワード}@{プロキシサーバホスト}:{プロキシサーバポート}
```

#参考
https://qiita.com/dyoshiha/items/96dea238afe7bf0acd1b
【Ubuntu 18.04】pyenv+pipenvでPython環境構築

# はじめに
pyenvとpipenvを使った仮想環境管理環境（？）を作る. 
Python自体のバージョン管理をpyenvで行い, プロジェクト毎の仮想環境の構築やパッケージ管理をpipenvで行うようにする.

# 環境
- Ubuntu 18.04
- `apt install`が使える

# インストール
```install.sh
#!/bin/bash

# Install dependencies
echo "ユーザのパスワード" | sudo apt update && sudo apt install -y --no-install-recommends \
        build-essential \
        libffi-dev \
        libssl-dev \
        zlib1g-dev \
        libbz2-dev \
        libreadline-dev \
        libsqlite3-dev \
        git

# Download pyenv
git clone https://github.com/pyenv/pyenv.git ~/.pyenv

# Update .bash_profile
touch ~/.bash_profile
echo -e "# pyenv paths" >> ~/.bash_profile
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
echo 'eval "$(pyenv init -)"' >> ~/.bash_profile
source ~/.bash_profile
pyenv -v

# Install Python and set default
pyenv install 3.7.4
pyenv global 3.7.4

# Install pipenv
pip install pipenv
```

このシェルスクリプトを次のように実行することで, pyenv/python/pipenvのインストールが行われる. 

```
./install.sh
```
権限が無いと怒られたら, `chmod +rx install.sh`で読み取り・実行権限を与える.
勿論一行一行ターミナルに打って実行しても問題ない. 

# 使い方
hogeというプロジェクトを作り, Python3.6の仮想環境を立ち上げてみる.

まずpyenvで3.6バージョンのPythonをインストール.

```bash
$ pyenv install 3.6.9
```

続いてpipenvで仮想環境を作る.

```bash
$ mkdir hoge
$ cd hoge
$ pipenv install --python 3.6.9
```

```
Creating a virtualenv for this project…
Pipfile: /home/**/hoge/Pipfile
Using /home/**/.pyenv/versions/3.6.9/bin/python3 (3.6.9) to create virtualenv…
```
pyenvでインストールしたPython3.6.9が使われている.

`hoge/`下に`Pipfile`と`Pipfile.lock`があれば成功. 

- 仮想環境の有効化

```
$ pipenv shell
(hoge) user:~/hoge$ 
```

- 仮想環境にライブラリをインストール

```
$ pipenv install numpy
```
`pip install`の代わりに`pipenv install`を使う. 間違って`pip install`しても仮想環境外を汚すことは無いが, そのライブラリは `Pipfile/Pipfile.lock`で管理されないので気をつける. 

- 仮想環境から抜ける

```
$ exit
```

- 仮想環境の削除

```
$ pipenv --rm
```

# いいところ
- インストールが簡単＆構成が分かりやすい
- pipenvでライブラリをインストールすると`Pipfile/Pipfile.lock`も自動更新されるので, requirements.txtと違って更新忘れが無い
  - gitとの相性もいい
  - `pipenv install -r requirements.txt`で`requirements.txt`からパッケージ管理を引き継げる

# わるいところ
- 仮想環境の有効/無効化が面倒くさい. 使用感はvirtualenvと近いかも. 
- 間違えて`pip install`しそうになる.
- `Pipfile.lock`の作成に時間がかかる

# おまけ：仮想環境の置き場所
デフォルトでは, pipenvで作成した仮想環境は`~/.local/share/virtualenvs/`以下に置かれる. `pipenv --rm`を行うとこの仮想環境が削除されるのであるが, それを忘れてプロジェクトディレクトリだけ削除すると仮想環境自体は残り続ける. 

プロジェクト直下に仮想環境を作るには, 環境変数`$PIPENV_VENV_IN_PROJECT`を定義する必要がある.

```shell
echo -e "# pipenv property" >> ~/.bash_profile
echo 'export PIPENV_VENV_IN_PROJECT=1' >> ~/.bash_profile
source ~/.bash_profile
```

こうするとプロジェクト直下に仮想環境`.venv/`が置かれるようになり, プロジェクトディレクトリを削除すれば一緒に仮想環境も削除される. 

# 参考にしたサイト
- [ubuntu 18.04 に pyenv をインストールする話 - Qiita](https://qiita.com/pdv/items/1107bcdca7fa43de673d)
- [pipenv で任意の場所の仮想環境を使う - Qiita](https://qiita.com/tonluqclml/items/cd0d2a2cb0197cbaee42)
ReactHooksでuseReducerを使うときにswitchを使わない - JavsScript編

ReactHooksでのuseReducerの参考実装ではよくswitchが使われていると思います。↓みたいな感じ。

```js
function reducer(state, action) {
  switch (action.type) {
    case 'addTodo':
      const text = action.text.trim()
      return { ...state, text }
    default:
      throw new Error()
  }
}
```

switch文で書くことには挙動的にはなんの問題もありません。reducerはstate,actionを受け取ってstateと同じ型の値を返せばどのような実装でも構わないからです。
しかし、switch文を使った実装はネストが多くなり、reducerの実装が肥大化・複雑化しやすい不満があります。

この不満を解決するため、ReactのライブラリであるReduxには、具体的な変更ロジックと、適用する処理の選択ロジックを切り分ける方法が提案されています。
https://redux.js.org/recipes/reducing-boilerplate#generating-reducers
useReducerでもこの実装を適用することができます。この実装を適用すると↓のようになります。


```js
const todos = {
  addTodo: (state, action) => {
    const text = action.text.trim()
    return { ...state, text }
  }
}

function createReducer(handlers) {
  return (state, action) => {
    if(handlers.hasOwnProperty(action.type)) {
      return handlers[action.type](state, action)
    } else {
      throw new Error()
    }
  }
}
```

このように実装することで、変更ロジックとreducerによる選択ロジックを切り分けることができ、新たなactionタイプを定義するときもhandlersに追加を行うだけでよくなります。また、ぱっと見実装が多くなっていそうですが、`createReducer`は変更ロジックが一般化された実装になっているため、どのコンポーネントでもそのまま再利用することができます。よって、各コンポーネントで実装するのはhandlersのみになります。テストもhandlersの各関数に対してのみ行えば問題ありません。（handlersはただの関数群なので、引数のモックなども実装しやすいと思います）
switchを使った実装よりも可読性が高く、メンテナンスしやすい実装になっていると思います。

この実装、JavaScriptで実装するのであれば十分ですが、TypeScriptで書こうとすると
action.typeごとにpayloadの型も変わるため、型定義が煩雑＋可読性が低くなるという不満があります。 
https://dev.to/stephencweiss/usereducer-with-typescript-2kf
TypeScriptでuseReducerを用いる時にも自分なりの実装方法があるので、別の記事にでもまとめようと思います。

## 参考文献
- https://ja.reactjs.org/docs/hooks-reference.html#usereducer
- https://redux.js.org/recipes/reducing-boilerplate#generating-reducers
- https://qiita.com/rooooomania/items/cb14a0a6093456068857
- https://dev.to/stephencweiss/usereducer-with-typescript-2kf
RailsでAjaxを使う場合にredirect_to modelではなく@modelにする理由

# Postの操作を画面遷移からAjax操作に書き換える
Railsチュートリアル14章で、Ajax操作を実装したために上のコードを下のコードへと書き換える下りがある。

```ruby:app/controllers/relationships_controller.rb
 　　redirect_to user

```

```ruby:app/controllers/relationships_controller.rb
    respond_to do |format|
      format.html { redirect_to @user }
      format.js
    end
```

これは、Twitterのようなアプリを作成するとして特定のユーザーをフォローした後に、そのユーザーの画面を再表示するためにリダイレクトする処理となる。

### Railsチュートリアルでの説明
下のコードを実装したために、インスタンス変数が必要になるというのが理由と書かれているが、いまひとつ腑に落ちないのではないか

```erb:app/views/users/_follow.html.erb
<%= form_for(current_user.active_relationships.build, remote: true) do |f| %>
  <div><%= hidden_field_tag :followed_id, @user.id %></div>
  <%= f.submit "Follow", class: "btn btn-primary" %>
<% end %>
```
なぜならば、インスタンス変数が必要となる実装前のコードが以下のコードである。
「remote: true」が差分で、<span>@</span>userはその実装前から使われているではないか

```erb:app/views/users/_follow.html.erb
<%= form_for(current_user.active_relationships.build) do |f| %>
  <div><%= hidden_field_tag :followed_id, @user.id %></div>
  <%= f.submit "Follow", class: "btn btn-primary" %>
<% end %>
```

# Ajax通信でPostした場合と、通常の通信でPostした場合の差
Ajax通信は非同期通信である。

非同期通信がやっていることは、画面を遷移せずに裏でこっそりサーバー側に通信を送っていることとなる。
裏を返すと、非同期通信をしない場合は画面を遷移していることになる。

先ほどの画面の例だと

元々の
「クライアントが　フォローボタンを押す→
サーバーが　DB上でフォローする→userのモデルに対応する画面のページに遷移する」
処理が

「クライアントが　フォローボタンを押す→
サーバーが　DB上でフォローする→<span>@</span>userのモデルを画面に返してあげる」
処理に差し変わったということである

元の処理では画面遷移する=画面を0から組み立てるのでcontrollerのshowメソッドを経由する。
このshowメソッドは

```ruby:app/controllers/relationships_controller.rb
  def show
    @user = User.find(params[:id])
    @microposts = @user.microposts.paginate(page: params[:page])
    redirect_to root_url and return unless @user.activated
  end
```
というコードであり、こちらで@userを設定しているため
登録処理では@userを設定する必要がない

一方、Ajax処理を行うコードでは、リダイレクトでそのまま画面に戻っていくため
@userを登録処理内部で設定する必要が生じる
<〇〇::ActiveRecord_Associations_CollectionProxy:××××××××××××××××>が得られてしまった時の対策

データベースから特定の情報を抜き出してviewで見た時に以下が出てガッカリした時の対策を備忘録として記載します。

```
<〇〇::ActiveRecord_Associations_CollectionProxy:××××××××××××××××>
```


どうやらこれは取ってきたインスタンスの外側部分の表示で、肝心の中身ではないご様子。
（以下で言うとaaaの部分が表示されている?）

[例]
　　aaa = bbb.New(attribute)

<〇〇::Activ~>を生み出している変数に対してeachメソッドを当ててあげると中身だけが取り出される。
たとえばitem.imagesで出てきてしまった場合は

```
// haml で書いた場合
- item.images.each do |image|
 - result = image.image_url
= result
```
これでインスタンス内のimage_urlの値が取り出せる。


# もっといいやり方があればご教示ください。
日本語形態素解析「kuromoji」を使う

<a href="https://www.atilika.com/ja/kuromoji/">kuromoji Home Page</a>
<a href="https://github.com/atilika/kuromoji">kuromoji GitHub</a>

<h4>Gradle</h4>
build.gradle

```text

dependencies {
    compile group: 'com.atilika.kuromoji', name: 'kuromoji-ipadic', version: '0.9.0'
}
```

「-ipadic」は辞書です。

<h4>対応している辞書</h4>
<ul>
	<li>kuromoji-ipadic</li>
	<li>kuromoji-ipadic-neologd：future version</li>
	<li>kuromoji-jumandic</li>
	<li>kuromoji-naist-jdic</li>
	<li>kuromoji-unidic</li>
	<li>kuromoji-unidic-kanaaccent</li>
	<li>kuromoji-unidic-neologd</li>
</ul>
<h4>Example</h4>

```java
String text = "吾輩は猫である。";
Tokenizer tokenizer = new Tokenizer();
List<Token> tokenList = tokenizer.tokenize(text);
```
Rust入門に役に立つサイト・本

# [The Rust Programming Language](https://doc.rust-lang.org/book/title-page.html)
定番。
特に4章の「Understanding Ownership」は読むべき。
[日本語訳](https://doc.rust-jp.rs/book/second-edition/)も。

# [rustlings](https://github.com/rust-lang/rustlings)
コンパイルエラーが起きるサンプルコードを修正して、コンパイルが通るようにする学習用のソース。コンパイルエラーを自分で読みながらコンパイルが通るようにすることにより、コンパイルエラーの原因が少しずつわかるようになった。

# [Hands-On Data Structures and Algorithms with Rust](https://www.packtpub.com/application-development/hands-data-structures-and-algorithms-rust)
Rustでの基本的なデータ構造とアルゴリズムを実装する書籍。実際の例に従って説明が進んで行くのがいい。

# [New Rustacean](https://newrustacean.com/)
Podcast。RustのニュースやたまにRust開発者へのインタビューなど。

# [Rust container cheat sheet](https://docs.google.com/presentation/d/1q-c7UAyrUlM-eZyTo1pd8SZ0qwA_wYxmPZVOQkoDmH4/edit#slide=id.p)
Rustのコンテナのチートシート。図が分かりやすい。
Nuxt.js×Firebase Hosting×PWAでQiita記事共有時に、TwitterIDを取得して作者にメンションで感謝を伝えられるTweetサービスを作った🎉🎉

## Nuxt.js×Firebase HostingでPWAを作った🎉🎉🎉

<blockquote class="twitter-tweet"><p lang="und" dir="ltr"><a href="https://t.co/lse1BalZSL">https://t.co/lse1BalZSL</a></p>&mdash; ワツヨ@PWAのthanks-mentions (@watsuyo_2) <a href="https://twitter.com/watsuyo_2/status/1193057038932180993?ref_src=twsrc%5Etfw">November 9, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

開発コンセプトや想いはnoteにも書きました🙏🙏

作り手と受け手の新しい関係性を作るWebサービスを作った
https://note.mu/watuyo_2/n/nb47f9fa3fe81

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">PWAの「thanks-mentions」を作りました🎉🎉<br><br>Qiitaの記事を共有する際に、TwitterIDを取得して作者にメンションで感謝の気持ちを伝えられるTweetサービスです！<br><br>ぜひ使ってみてください！<br><br>UI改善、機能追加していきます！<a href="https://t.co/pGGYeHqFMQ">https://t.co/pGGYeHqFMQ</a> <a href="https://t.co/Vzf3HNWTxN">pic.twitter.com/Vzf3HNWTxN</a></p>&mdash; ワツヨ@PWAのthanks-mentions (@watsuyo_2) <a href="https://twitter.com/watsuyo_2/status/1191235378130276352?ref_src=twsrc%5Etfw">November 4, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

### サービス名
- **[thanks-mentions](https://thanks-mentions.web.app/)**

### 使用技術
- Nuxt.js
- Firebase Hositing
- Firebase Cloud Storage
- Stylus
- [QiitaAPI](https://qiita.com/api/v2/docs)

技術的な詳細は別記事で投稿予定。

### 概要
見返りが欲しいだけで記事を書いたり、ナレッジをシェアする訳ではありませんが、記事を共有する時にただ共有するのではなく、せめて感謝を伝えられたらと思いました。

自分の投稿した記事に対してメンション付きでお言葉をいただけるのめちゃくちゃ嬉しいし、共感してくださった方が可視化されることでそこで新たな関係性が生まれるのではないかと思い、今回のサービス作成に当たりました。
 
## PWAの使い方&ユーザーフロー

1. [thanks-mentions](https://thanks-mentions.web.app/)にアクセスします。
2. アクセスすると画面下部に `ホーム画面にthanks-mentionsを追加`というポップアップが出るのでタップしてホーム画面に追加します。
※推奨環境はAndroidのGoogle Chromeです。
![smartmockups_k2jzfghb.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253605/ff0db145-516d-4343-5f00-bb595dd3fb70.jpeg)

3. 共有したいQiitaの記事のページにある`共有ボタン`or`Chromeの共有`から[thanks-mentions](https://thanks-mentions.web.app/)のアイコンを選択します。下記の画像でいうと左下のアイコンになります。
![smartmockups_k2jzq8eb.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253605/a7fe6791-7c66-2a10-b94a-0de102839b44.jpeg)

4. そうすると下記のような画面に遷移し、記事のタイトルとURL、作者のTwitterIDを取得し表示されます。
   本ページでも内容を編集できます。内容を確認したら`共有ボタン`をタップします。
![share.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253605/37b071a0-0d86-b253-1f82-302294187011.jpeg)

5. 共有メニューからTwiiterアプリを選択し、Tweet画面に遷移します。あとはTweetをして、作者にメンションを飛ばすだけです！
![smartmockups_k2jzk7z0.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253605/e573efb0-f4e2-dd36-a59c-192e1fb4a714.jpeg)

## 技術的な話
別記事で投稿予定です！

## 終わりに
たくさんのQiitaユーザーの方に使っていただけたら嬉しいです。
いいね!、コメントをお待ちしてます🙏🏻🙏🏻
Twitter: [@watsutyo_2](https://twitter.com/watsuyo_2)でも受け付けてます🙏🏻🙏🏻
[ゼロから作るDeep Learning]sigmoidレイヤ・Reluレイヤの実装をしてみた

#はじめに
この記事は**ゼロから作るディープラーニング 6章誤差逆伝播法**を自分なりに理解して分かりやすくアウトプットしたものです。
文系の自分でも理解することが出来たので、気持ちを楽にして読んでいただけたら幸いです。
また、本書を学習する際に参考にしていただけたらもっと嬉しいです。


#sigmoidレイヤの実装

```python
class Sigmoid: # シグモイド関数のレイヤ実装
    def __init__(self):
        self.out = None # シグモイド関数の逆伝播処理では順伝播処理の出力信号が必要になる
        
    def forward(self, x):
        out = 1 / (1 + np.log(-x))
        self.out = out # 順伝播の出力保存
        
        return out
    
    def backward(self, dout):
        dx = dout * self.out * (1 - self.out) # シグモイド関数の逆伝播を求める処理
        
        return dx
```

順伝播処理は、sigmoid関数の公式通りに処理を行い、それをreturnで返す。
しかし、逆伝播処理で順伝播処理の結果を使用するので、インスタンス変数に保存しておく。

逆伝播処理では、普通にすると相当複雑になってしまうため、ここでは簡略式を使って微分を求める。
前の微分とインスタンス変数に保存した順伝播処理の結果を使ってsigmoidレイヤの入力値の微分を求める。


#Reluレイヤの実装

```python
class Relu: # Relu関数のレイヤ実装
    def __init__(self):
        self.mask = None # 入力信号の０以下がTrueで０より大きいものがFalseの配列が入る
        
    def forward(self, x):
        self.mask = (x <= 0)
        out = x.copy()
        out[self.mask] = 0 # 入力信号で０以下のものを０にする
        
        return out
    
    def backward(self, dout):
        dout[self.mask] = 0 # 順伝播が0の場合は逆伝播も０なのでここで０にする
        dx = dout # 他は前の微分を引き継ぐ
        
        return dx
```

順伝播処理は、ifを使わずに実装を行うためにまず、入力値で０を超えないものを全てTrueに０を超えるものをFalseにして、それをインスタンス変数に保存する。これはあとで使用する。

次に入力値の入った配列をコピーして、それにさっき保存したTrue,Falseの配列を使いTrueのものを全て０に変換する。そしてそれをreturnで返す。

逆伝播処理では、順伝播処理で保存したTrue,Falseの配列を使ってTrueを全て０に変換する。順伝播が０のものは逆伝播でも０のため。

そしてあとは前の微分を継承してreturnで返す。
EC2インスタンスへのSSH接続が失敗したのでインスタンスを停止→起動したら成功した件

##はじめに
AWSの勉強にあたり以下の本にてハンズオンをしていた際に微妙につまずいたのでメモです。

<a target="_blank"  href="https://www.amazon.co.jp/gp/product/4297106612/ref=as_li_tl?ie=UTF8&camp=247&creative=1211&creativeASIN=4297106612&linkCode=as2&tag=cocolonifty00-22&linkId=73946d7be8f19baed98f2aae78d4d1fe"><img border="0" src="//ws-fe.amazon-adsystem.com/widgets/q?_encoding=UTF8&MarketPlace=JP&ASIN=4297106612&ServiceVersion=20070822&ID=AsinImage&WS=1&Format=_SL250_&tag=cocolonifty00-22" ></a><img src="//ir-jp.amazon-adsystem.com/e/ir?t=cocolonifty00-22&l=am2&o=9&a=4297106612" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />
※すごくいい本です。

##環境

- OS:MacOS
- ソフト：ターミナル
- AMI：Amazon Linux 2
- セキュリティグループ：独自でHTTP/HTTPS/SSHのインバウンド許可

##事象
作成したてのインスタンスにsshログインを試みたところ、エラーが発生

```sh:xx.xx.xx.xxはパブリックIP。パブリックDNSに変えても同じ事象
$ ssh -i "/Users/xxxx/.ssh/myserverkey.pem" ec2-user@xx.xx.xx.xx
ec2-user@xx.xx.xx.xx: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
```

##結論
EC2を「停止」→「起動」したら解消しました。
停止を行うと、パブリックIPやパブリックDNSが変更されますので、新しいパブリックIPを指定したらすんなり接続できました。

##以下は、結論に至るまで考えうる原因（試してみて効果がなかったこと）

###キーの権限が不正
> SSH が機能するには、キーが公開されていないことが必要です。必要な場合は次のコマンドを使用します。

とのことなので、キーならびにキーの上位（ホームディレクトリ）まで権限の制限を行いました。

```sh
chmod 400 /Users/xxxx/.ssh/myserverkey.pem
chmod 600 /Users/xxxx/.ssh
chmod 600 /Users/xxxx
```
事象変わらず

###ログインユーザー間違い
AMIによってログインするユーザーの指定が異なります。
> Amazon Linux 2 または Amazon Linux AMI の場合は、ユーザー名は ec2-user です。
CentOS AMI の場合、ユーザー名は centos です。
Debian AMI の場合は、ユーザー名は admin または root です。
Fedora AMI の場合、ユーザー名は ec2-user または fedora です。
RHEL AMI の場合は、ユーザー名は ec2-user または root のどちらかです。
SUSE AMI の場合は、ユーザー名は ec2-user または root のどちらかです。
Ubuntu AMI の場合は、ユーザー名は ubuntu です。

EC2の「説明」の「AMI ID」をクリックし、作成した「Amazon Linux 2」で作成していることを確認
コマンドの実行において指定している「ec2-user」で問題ないため、原因ではないことを確認

###SSHがインバウンド許可されていない
独自でセキュリティグループを作っていたこともありインバウンドの設定を確認したがSSHは許可。
念の為、デフォルトのセキュリティーグループに切り替えてみたが、タイムアウトした。

```sh
$ ssh -i "/Users/xxxx/.ssh/myserverkey.pem" ec2-user@xx.xx.xx.xx
ssh: connect to host xx.xx.xx.xx port 22: Operation timed out
```
セキュリティグループやIPの打ち間違いといったコマンドミスも関係ないことを確認し、もとのセキュリティグループに戻す

###キーペアファイルが不正
何らかの理由でコピーが失敗しているようなことがあるようなので、新しいキーペアを作成してそちらを指定して同コマンドを実行したが、同じエラーになるため、関係がなさそう。
キーをおいているPCそのもののコピーの仕方などに問題がある可能性もあったのでWindowsでも試そうと思いましたが、未実施。

###EC2インスタンスがきちんと起動していない可能性
まずは、「インスタンスの状態」が「running」であることを再確認。
現状の状態は問題ないようなので、EC2インスタンスを「再起動」してみるが、事象変わらず。

はじめにに記載した、本に「再起動」と「停止→起動」は挙動が違うことを思い出して試してみたらうまくいきました。

##おわりに
検索やAWSのトラブルシューティングにヒットするものでは解決に至らなかったためちょっと困りました。
以前もAWSの勉強（挫折）を行なっている際、作成したEC2インスタンスがうまく起動されずにちょっと手間取っていたので、インスタンスの起動に疑いの目を向けられましたが、この起動の失敗率一体・・・。
また、起動時に割り当てられたIPに問題があったのか、問題があったのであれば何がどうだめだったのか、はたまたIPは関係がない部分でインスタンスに何らかの問題があったのか地味に根本原因がわかっていないので、わかる方いたら教えていただけると嬉しいです。
Oracle 管理 SQL メモ

# パスワードの無期限化
### 1. 対象のプロファイル確認
```sql
SELECT username, profile FROM dba_users WHERE username = '<ユーザー名>';
```
### 2. プロファイルのパスワード有効期限を確認
```sql
SELECT * FROM dba_profiles WHERE resource_name = 'PASSWORD_LIFE_TIME' AND profile = '<プロファイル名>';
```

### 3. プロファイルのパスワードを無期限に変更
```sql
ALTER PROFILE "<プロファイル名>" LIMIT PASSWORD_LIFE_TIME unlimited;
```

# ディレクトリ確認
### 1. ディレクトリ一覧
```sql
SELECT * FROM dba_directories;
```

### 2. ディレクトリの権限一覧
```sql
SELECT d.owner, d.directory_name, p.grantee, p.privilege, d.directory_path
    FROM dba_directories d, dba_tab_privs p
    WHERE d.owner = p.owner AND d.directory_name = p.table_name
    ORDER BY d.owner, d.directory_name;
```

# ユーザー情報
### 1. ユーザー情報確認
```sql
select * from dba_users WHERE username = '<ユーザー名>';
```

### 2. ユーザーに付与されているシステム権限情報確認
```sql
SELECT * FROM dba_sys_privs WHERE grantee = '<ユーザー名>';
```

### 3. ユーザーに付与されているロール情報確認
```sql
SELECT * FROM dba_role_privs WHERE grantee = '<ユーザー名>';
```

### 4. ユーザーに付与されているオブジェクト権限情報確認
```sql
SELECT * FROM dba_tab_privs WHERE grantee = '<ユーザー名>';
```

# 表領域情報確認
### 1. 表領域（テーブルスペース）情報確認
```sql
select * from dba_tablespaces;
```

### 2. データファイル情報確認
```sql
select * from dba_data_files;
```

### 3. テンポラリファイル情報確認
```sql
select * from dba_temp_files;
```
Python Openpyxlを使用したエクセルファイル列追加、行削除処理

# 概要

業務でちょっとエクセルファイルを加工する機会があったので、その時の処理のうち
エクセルファイルに列を追加したり、特定の条件の行を削除する処理をまとめてみました。
テンプレートや元になるデータにをちょっと加工する必要がある時に使えるかもしれません。


## 必要なもの

* python 3.7.2
* pandas
* numpy
* openpyxl

今回はexeはないです。

## 公開場所

[github](https://github.com/snowpff14/etcresource)で公開しています。

## 使い方

* inputディレクトリの `基準データ.xlsx` に対し各種操作を行います。
* inputディレクトリの `定義ファイル.xlsx` をもとに `基準データ.xlsx` の内容を修正します。

* 各項目配下のようになっています


|項番|シート名|カラム名|説明|
|---|:-------|:---------|:---------|
|1|追加列|項目名|基準データのカラム名に対応設定した値を<br>カラム名として追加する|
|2|追加列|追加列|基準データ指定した列に追加を行う A列から1始まりで設定する|
|3|追加列|追加データ|追加するデータを記載したシートを指定する。データは行の位置に対応する値を設定すること。|
|4|削除行|項目名|基準データのカラム名に対応設定した値を指定する。<br>削除する行の条件に使用するカラムを指定する。|
|5|削除行|条件|削除する行の条件を指定する。|


## ソースの説明

以下の処理が列追加処理の部分になります。
取得したファイルからカラム名、追加する位置を取得しさらにそのデータを記載しているシート
から追加するデータを取得しています。
`inser_cols`メソッドで指定した位置に列を追加しています。
データを取得し追加した列に値を設定しています。
また値を設定するときに罫線も引いています。

```python
        for columninfo in addColumnInfos:
            addColumnName=columninfo[1]
            addColumnPosition=columninfo[2]
            addColumnData=columninfo[3]
            addColmunDatas=inputWorkbook.parse(addColumnData)
            addDatas=np.asarray(addColmunDatas)
            baseSheet.insert_cols(addColumnPosition,1)
            baseSheet.cell(column=addColumnPosition,row=2,value=addColumnName).border=blackBorder
            for i,data in enumerate (addDatas):
                baseSheet.cell(column=addColumnPosition,row=i+3,value=data[1]).border=blackBorder

```
以下の処理が行削除の部分になります。
取得したファイルから削除する条件が指定されているカラム名、削除条件を取得します。
その後削除対象の行の位置を決定後(pandasのqueryで条件を求めています)
その位置にたいして　`delete_rows`メソッドで削除しています。
行を削除した場合は削除した分詰まっていくので行の位置を補正しています。


```python
        for columninfo in addColumnInfos:
            delTargetColumnName=columninfo[1]
            delRowCondition=columninfo[2]
            deleteRows=targetDeleteRowSheet.query(delTargetColumnName+'=="'+delRowCondition+'"')
            deleteIndexs=deleteRows.index

            log.info(deleteIndexs)
            for delcount,delindex in enumerate(deleteIndexs):
                
                baseSheet.delete_rows(startIndex+delindex-delcount)
```


## 活用方法

今回は適当に定義したファイルの条件をもとに削除する形をとっていますが、
例えば集計表の結果が０の行を削除する。
何らかの帳票に列を追加して提出用にするなどエクセルを加工する時の方法の一つとして使えるかもしれません。
Redmine 4.0.5 を RedMica 1.0.0 に移行する

# ●前提条件

- OS:CentOS 7
- Redmine
 - バージョン: 4.0.5
 - インストールディレクトリ: /opt/redmine
 - 動作パス: /redmine
- アプリケーションサーバ: unicorn

# 1.ディレクトリ退避＆作成
```
mv /opt/redmine /opt/redmine_org
mkdir /opt/redmine
```
※ディレクトリのオーナー／パーミッションは環境に合わせてください

# 2.ソース取得＆設定ファイルの移行
```
git clone https://github.com/redmica/redmica.git /opt/redmine
cd /opt
cp redmine_org/config/unicorn.rb  redmine/config/
cp redmine_org/config/database.yml  redmine/config/
cp redmine_org/config/configuration.yml  redmine/config/
cp redmine_org/Gemfile.local redmine/
cp redmine_org/config.ru redmine/
```
※config.ru はサブディレクトリで動かすために編集
※unicorn.rb はunicornを動かすために追加
該当しない場合はどちらも無視してください

# 3.添付ファイルコピー
```
cp -ra redmine_org/files/*  redmine/files/
```

# 4.プラグインコピー
```
cp -ra redmine_org/plugins/* redmine/plugins/
cp -ra redmine_org/public/plugin_assets/*  redmine/public/plugin_assets/
```

# 5.テーマコピー
```
cp -ra redmine_org/public/themes/{47redmine_theme,axiom,farend_basic,redmine-theme-connpass,redmine_theme_kodomo,circle,farend_fancy,redmine-theme-flat-master,gitmike}  redmine/public/themes/
```

※ご自身の環境に合わせてください
※alternate/classic/bleuclair(redmine_theme_farend_bleuclair) はRedMicaに含まれるため、除いています。


# 6. manifest.jsの作成

```
mkdir -p redmine/app/assets/config
vim redmine/app/assets/config/manifest.js
```

以下の内容で作成

```file:manifest.js
//= link_tree ../images
//= link_directory ../javascripts .js
//= link_directory ../stylesheets .css
```

# 7.gemインストール
```
cd redmine
bundle install --path vendor/bundle --without development test
```

# 8.master.key／credentials.yml.enc の作成
```
RAILS_ENV=production bundle exec rake secret
```

表示された値をコピーしておく。

```
EDITOR="vim" bundle exec rails credentials:edit
```

secret_key_base の値を上でコピーしたものに置き換える。



# 移行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63464/54412059-a150-8f0e-cf5f-1d83120bd3b0.png)