カフェでプログラミングしてる風（でも何もやってない）JSコード

先週トレンドに上がっていた[カフェでプログラミングしてる風（でも何もやってない）Java（クソ）コード](https://qiita.com/3S_Laboo/items/660883a0184dabaea65b)に便乗して、**JSを使って自分流にクソプログラムを作りました。**
普通コマンドラインをJSでやらないと思いますが、あえて試しにやってみました。

GitHubリポジトリ : https://github.com/Sparrow42/cafe-pro

# 元ネタからの改良点
- **カタカタと手を動かして**、プログラミングアピールができる
- 単調な動きでなく、**色々な単語が出現する**
- イテレーション数等をカスタマイズできる

# 実行結果
![My Project5.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403809/fdce291f-e881-e52b-b64b-5a02977efda3.gif)

流れは以下の通りです。
①文字を入力すると、プログレスバーを表示しながらインストールされる（？）
②英単語が次々にインストールされる
③無作為な英数字の羅列が表示される

言っていて何を言っているのか分からなくなります。。

# ソースコード

### 使用するモジュール
各種import等はこちら。コマンドラインに出力を行うのが``readline``というモジュールです。
``random-word-wikipedia``はWikipediaからランダムにタイトルの単語を引っ張ってこれるAPIです。

```JavaScript
const readline = require('readline')
const crypto = require('crypto');
const randomWordWikipedia = require('random-word-wikipedia');

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
})
```

### メイン実行
各種関数を非同期で実行します。３種類の関数として、
①質問形式＋プログレスバー（questionGauge）
②wiki単語＋プログレスバー（wikiWordGauge）
③英数字羅列（stringsList）
を用意しました。
for文のイテレーション数を変化させることで、動作回数を調整できます。プログレスバーや英数字羅列の長さもお好みで変えられます。

```javascript
//関数実行
const main = async () => {
    //質問回数
    const questionLoop = 2;
    //wiki単語プログレスバー回数
    const wikiWordLoop = 2;
    //プログレスバーの長さ
    const progressMax = 30;
    for(let i=0; i<questionLoop; i++){
        await questionGauge(progMax=progressMax); //①：質問形式＋プログレスバー
    }
    for (let i=0; i<wikiWordLoop; i++) {
        await wikiWordGauge(progMax=progressMax); //②：wiki単語＋プログレスバー    
    }
    await stringsList(strings=100, row=10); //③：英数字羅列
    console.log('Execution completed!');
    
    rl.close()
}

main()
```

次に３つの関数のコードを載せます。

### ①質問形式＋プログレスバー
「What do you execute?」という質問に何等かの入力をすると、入力のハッシュ値表示とプログレスバーが動作します。
![My Project7.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403809/b7ef6599-e846-a6ed-21c6-725887a93c5f.gif)

```javascript
//質問形式のプログレスバー
const questionGauge = (progMax) => {
  return new Promise((resolve, reject) => {

    rl.question('What do you execute? ', (answer) => {
        
        let iter = 0;
        console.log(crypto.createHash('md5').update(answer).digest('hex'));

        function gaugeDisp(iter, progMax){
            if( iter!=0 ){
                //行数分上に移動。
                readline.moveCursor(process.stdout,0,-1);
                //現在位置より下を消去する
                readline.clearScreenDown(process.stdout);
            }
            let percent = (iter / progMax) * 100;
    
            console.log(answer + " ["+"#".repeat(iter)+" ".repeat(progMax-iter)+"] - " + percent.toFixed(1) + "%");
            
            iter+=1;
            if(iter!=progMax+1){
                setTimeout( gaugeDisp, 100, iter, progMax );
            }else{
                resolve();
            }
        }

        gaugeDisp(iter, progMax);
        
    })
  })
}
```

### ②wiki単語＋プログレスバー
wiki単語をランダムに表示すると同時に、プログレスバーが動作します。以前作った[wikipediaのワードを使った連想ゲームアプリ](https://qiita.com/sparrow42/items/f160f4d520ea05b6d1a0)を応用しました。

![My Project8.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403809/da5655b4-3920-e350-c15e-ff22650f6a09.gif)


```javascript
//wiki単語＋プログレスバー
const wikiWordGauge = (progMax) => {
    return new Promise((resolve, reject) => {
        let iter = 0;![My Project8.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403809/239449a7-6acc-a18a-243e-fcb32538aa56.gif)

        
        randomWordWikipedia('en', 10).then((value) => {
        
            wikiWordArr = [];
            for(let i=0; i<progMax/10; i++){
                for(let j=0; j<10; j++){
                    wikiWordArr.push(value[j])
                }
            }
            
            function gaugeDisp(iter, progMax){
                if( iter!=0 ){
                    //行数分上に移動。
                    readline.moveCursor(process.stdout,0,-2);
                    //現在位置より下を消去する
                    readline.clearScreenDown(process.stdout);
                }
                let percent = (iter / progMax) * 100;
        
                console.log(value[0] + " ["+"#".repeat(iter)+" ".repeat(progMax-iter)+"] - " + percent.toFixed(1) + "%");
                console.log(wikiWordArr[iter]);
                

                iter+=1;
                if(iter!=progMax+1){
                    setTimeout( gaugeDisp, 100, iter, progMax );
                }else{
                    //行数分上に移動。
                    readline.moveCursor(process.stdout,0,-1);
                    //現在位置より下を消去する
                    readline.clearScreenDown(process.stdout);
                    console.log(wikiWordArr[iter-2]);
                    resolve();
                }
            }
    
            gaugeDisp(iter, progMax);
    
        });
    })
}
```

### ③英数字羅列
ランダムな英数字の文字列を出力します。

![My Project10.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403809/c6cead1c-7f07-1525-8349-80f6ba9d4635.gif)

```javascript

//英数字の羅列
const stringsList = (strings, row) => {
    return new Promise((resolve, reject) => {

        let iter = 0;
        function hashDisp() {
            // 生成する文字列の長さ
            var l = strings;
            // 生成する文字列に含める文字セット
            var c = "abcdefghijklmnopqrstuvwxyz0123456789";
            var cl = c.length;
            var r = "";
            for(var i=0; i<l; i++){
                r += c[Math.floor(Math.random()*cl)];
            }
            console.log(r);
            
            iter += 1;
            if(iter!=row){
                setTimeout( hashDisp, 100, iter, strings );
            }else{
                resolve();
            }
        }

        hashDisp();
    });
}
```

#終わりに
たまには流行りに乗ってみようということでやってみました。作り始めると他のことそっちのけで作ってしまうのは反省です。。
無駄なものでしたが、理解の乏しい非同期実行を学べたので意味はあったかなと思います。

カフェに行ったら是非使ってみてください。
最後までご覧いただきありがとうございました。