プログラミングBlog

勉強会㉖

Hands-on and Lightning Talks

開催日時 2021年6月19日(土) 7:00-9:00
今週はBIツール、アプリ開発についての話、Promiseのライブコーディングを行いました。

本日の内容

発表者 テーマ 資料 時間
Kobori BIツールの話 40分
Toku Activity開発の進捗とPromiseライブコーディング Activity 60分
Nakagawa 共同アプリ開発の話 20分

BIツールの話

BIツールとは??

ja.wikipedia.org

企業の基幹システムで生成されたデータを、ユーザ自身が抽出・加工するためのアプリケーションソフトウェアである

なぜBIツール??

システムの内製化を進めるため、BIツールを導入したい。
システムを外注することによるコストが高いため、内製化を図ることでコスト削減をしたい。

どんなものを作る??

フロント + バックエンド → データを集計したものをグラフで可視化。
フロント側はC# デスクトップアプリケーション
ミドルウェアに関しては外部で読み込んだものを使用
ツール開発者ベースでのレポート作成ではなくユーザー主体で行いたい

個人アプリ開発Activityの進捗

ローカルで使用できる学習支援、デスクトップアプリケーション。
タイマーで設定した時間が終了した時にダイアログを出力する。 ログと簡易的なメモ。
ブックマーク機能をつけることで、参考サイトに素早くアクセス。
学習時間が可視化できるようActivityGraph搭載。
まだ未完成なため日々アップデータ中。
github.com

共同アプリ開発の進捗

ログイン機能
slack提携機能 トークンと連携させる
markdown.js マークダウン機能
highlight.js 言語ごとにハイライトをつける機能

Promiseライブコーディング

主に学んだのは5つの基本構文
* resolve reject then catch finally
* 関数の中で呼び出す
* ループの中で使う。

var sample = function (requestData) {
    return  new Promise((resolve, reject) => {
        if (requestData[0] === 1) {
            resolve(requestData[0]);
        } else {
            reject(requestData[0]);
        }
    });
}

var data = [1, 2, 3];

while (data.length > 0) {
    console.log(data);
    sample(data).then((success) => {
        console.log("resolve" + success);
    }).catch((error) => {
        console.log("reject" + error);
    }).finally((execute) => {
        console.log("finally");
    });
    data.shift();
}

ループの場合、Promiseの挙動に注意。

すべてのループ処理が終了した後にthen,catch,finallyの部分が走るため、Promise(){}の部分でデータを削除する(ループ終了処理)を書く。
そうしないとthen以下で記述しても処理が走らないため、無限ループに陥る。

勉強会㉕

Hands-on and Lightning Talks

開催日時 2021年6月12日(土) 7:00-9:00
今週は非同期、同期のお勉強と後半はPaizaのアルゴリズム問題を解きました。

本日の内容

JavaScriptの非同期、同期の例外処理

非同期、同期の例外処理
やったことはtrycatchとコールバック関数でのエラーハンドリングを行い、非同期と同期で動きの変化をみながら、後半はpromiseを少し書いてみる。
ファイル読み込みを想定して、成功時と失敗時にどんな動きをするかを確かめながら行いました。
狙いとしては、現場でのjavascriptのESによって書き方が変わってくる(まだまだIEが現役)なためいきなりpromiseから入るのではなく基礎から学ぶ。
そうすることで、どんな書き方にでも対応できるようにする。
実際にコールバック地獄を体験したり、少しですがpromiseも書いてみました。
非同期処理はメールやチャットなどのリアルタイム処理に使われるそうなので、開発してみたいですね!

paizaのアルゴリズム問題

文字列の長さ
簡単なので、lengthなどの長さを返却するようなプロパティは使用しない縛りでやってみました。

JavaScript

文字列を文字の配列に変換。
文字配列の数だけ繰り返しcountUpを呼び出す。
クロージャを利用することで内部に定義したcountがインクリメントされます。
最後に文字の数だけ呼び出されたcountを表示させる。

execute01();

// 文字の数
// length,countは使ってはいけない縛り。
function execute01() {
    // 標準入力
    process.stdin.resume();
    process.stdin.setEncoding('utf8');

    var lines = [];
    var reader = require('readline').createInterface({
        input: process.stdin,
        output: process.stdout
    });

    reader.on('line', (line) => {
        lines.push(line);
    });

    reader.on('close', () => {
        console.log(strLength(lines[0]));
    });
}

// 文字列の長さを調べる
function strLength(str) {
    str.split('').forEach(value => countUp());
    var count1 = countUp()
    return count1;
}

// 呼び出されるとインクリメント
function counter() {
    var count = 0;
    return function () {
        return count++;
    }
}

// クロージャ
var countUp = counter();

Python

文字列を文字の配列に変換する。
文字配列の最後の要素(文字の末尾)を取得した後に文字の末尾で文字の検索を行う。
値のインデックス番号 + 1が長さとなる。

input_line = input()
array = list(input_line)
print(input_line.rfind(array[-1]) + 1)

paizaの注意事項

レベルアップ問題集

なお、このコーナー内の問題については、ユーザー同士で解答を教え合ったり、コードを公開したりするのは自由としています。 授業や研修にもご利用いただけますので、ぜひ教材などにもお使いください。

コーディングスキルチェック受験での禁止行為

JavaScript 非同期同期 例外処理

実行環境

Node - v 14.16.0

例外の基本

try{}で囲ってる箇所に例外が起こりえるような処理を書いて、 もし例外が発生したらcatch{}の中に書いた処理を実行する。
finallyは実行してほしいような処理がある場合使う。

try {
    // 例外が発生するかもしれない処理
} catch (error) {
    // 例外発生時の処理
} finally {
    // 必ず実行される処理
}

例外の基本の書き方ですが、ファイルを読込処理をしていた時に 例外が拾えずはまったのでもう一度復習。

コールバックについて

非同期

ファイルを読み込むためにfsモジュールを使います。

const fs = require('fs');

fs.readFile('./saplme.txt');

このままだとエラーとなります。
TypeError [ERR_INVALID_CALLBACK]: Callback must be a function. Received undefined
仕様が変更されてfsモジュール使用時にコールバック関数がMustになっているため追加します。

const fs = require('fs');

fs.readFile('./sample.txt', (error, txt) => {
    if (error) {
        console.log(error);
    } else {
        console.log(txt.toString());
    }
});

第一引数はerrorが起こった場合、エラーオブジェクトが入ります。
第二引数は読み込めた場合、読み込んだ内容が入ります。
無事にtxtファイルの中身sampleが表示されました。

sample!

次にtrycatchで囲んだ後に例外を発生させてみましょう。
先ほどのsample.txtを削除して読み込めなくします。
その後にthrowでcatchさせるようにします。

テキストファイルが読み込めなかった場合。

const fs = require('fs');

try {
    fs.readFile('./sample.txt', (error, txt) => {
        if (error) {
            console.log('callback');
            throw error.message;
        } else {
            console.log(txt.toString());
        }
    });
} catch (err) {
    console.log('catch');
    console.log(err.message);
}
callback  
ENOENT: no such file or directory, open 'C:\repos\javasc\sample.txt'
(Use `node --trace-uncaught ...` to show where the exception was thrown)

結果からわかるようにコールバック関数を用いたエラーハンドリングでは、trycatchを外側に書くと拾うことはできないようです。
次はコールバック関数の中でtrycatchで拾うようにしてみます。

const fs = require('fs');

try {
    fs.readFile('./sample.txt', (error, txt) => {
        try{
        if (error) {
            console.log('callback');
            throw error;
        } else {
            console.log(txt.toString());
        }
    }catch(innnerError){
        console.log("innnerCatch")
        console.log(innnerError.message);
    }
    });
} catch (err) {
    console.log('catch');
    console.log(err.message);
}

無事拾うことができました。
可読性がひどいのでtrycatchではなくコールバック関数でエラーハンドリングすべきですね!

callback
innnerCatch
ENOENT: no such file or directory, open 'C:\repos\javasc\sample.txt'

同期

const fs = require('fs');

try {
    var txt = fs.readFileSync('./sample.txt');
    console.log(txt.toString());
} catch (err) {
    console.log(err.message);
}

trycatchは同期的に動くため、同期処理の場合はcatchできるようです。

catch
ENOENT: no such file or directory, open './sample.txt'

結論

  • 非同期の場合はコールバック関数でのエラーハンドリング
  • 同期の場合はtrycatchでのエラーハンドリング

勉強会㉔

Hands-on and Lightning Talks

開催日時 2021年6月5日(土) 7:00-9:00
今週は転職活動情報共有会とネットワークのお勉強をしました。

カジュアル面談の話

求人媒体:LAPRAS
lapras.com
Github提携により企業側からアウトプットが見やすい。
個人開発をしていて、それを見た企業から今回スカウトメールが来た。
技術スタックはRails + vue.js
相手は経験者だと思っていたようなので、未経験という言葉はあまり使わない方が良い。
技術に関して発信を続けていくと今回のような面談に繋がるの第三者に見えるようなアウトプット大事。

リファラル採用の話

外注するとコストが高くなるため自社にシフトを進めている企業
業種は保険
立ち上げて数年のため、人手が足りていない
インフラ + アプリケーションエンジニアを募集
離職率4%と少なめ。
JAVAをメインとしている
スピード感が足りていないため、払しょくできるような人材を探している。
リファラル採用だと、その会社の雰囲気がよりわかるのでお互いミスマッチがおこりにくいためおすすめ。

共有フォルダ作成方法

window + R → ipconfig

検索窓表示 → IPv4を表示
f:id:Tokuty:20210605085405p:plain

共有フォルダ作成

f:id:Tokuty:20210605102415p:plain
右クリック → 詳細な共有 → このフォルダーを共有する → アクセス許可する

エクスプローラーに共有先のIPアドレスを打ち込む。

認証情報を求められるのでユーザー名とパスワードを打ち込む。
f:id:Tokuty:20210522111409p:plain

勉強会㉓

Hands-on and Lightning Talks

開催日時 2021年5月29日(土) 7:00-9:00
本日の発表者はKoboriさん。

発表者 テーマ 資料 時間
Kobori RPAとAS/400IBM i)の話 Youtubeの広告スキップ 90分

テーマの感想

RPAとAS/400IBM i)の感想

RPAを簡単に説明すると業務の自動化のこと。
WinActorというツールを使用。
主な機能としては、データの計算、出力、整形の自動化。
コード書けるとより理解がしやすい。理由の一つがフローチャート形式でプログラムを組んでいく。
FAX-OCRなどのAPI連携も可能。組み合わせることで簡単に機能を作成できる。
課題はIT知識が無い方が担当しているため、結局サポート頼りとなってしまう。
新規機能を作成しようにも学習コストがかかるため、専門の方を頼ることになる。
ある程度の知識は必要。コストも意外とかかる。

Youtubeの広告スキップ

google拡張機能を使用。
言語はJavaScriptで書く。DOMを使用して、タグから情報を抜き取る。
常駐化することで広告スキップを自動で行う。
拡張機能で他にもできることがありそう。

勉強会㉒

Hands-on and Lightning Talks

開催日時 2021年5月22日(土) 7:00-9:00
本日の発表者はNakagawaさんとイナバさんの2人!

発表者 テーマ 資料 時間
Nakagawa 案件面談の話 30分
イナバ サーバー認証の話(Windows) 20分

各テーマ詳細

案件面談の話

東京の案件事情
面談の結果などなど。

サーバー認証の話

業務の話なので詳しくは書けませんが、出てきた言葉を抜粋。
* Windows認証
* ワークグループ
* Security Account Manager(SUM
* コンピューターの管理
* ローカルユーザーとグループ
* アクティブディレクトリー
* SSO

長テーブルのうなぎ屋 JavaScript編

PaizaのBランク問題に挑戦。
簡単に解ける言ってる人多いですが、普通に難しかったです。

レベルアップ問題集

なお、このコーナー内の問題については、ユーザー同士で解答を教え合ったり、コードを公開したりするのは自由としています。 授業や研修にもご利用いただけますので、ぜひ教材などにもお使いください。

コーディングスキルチェック受験での禁止行為

入力される値

  • 座席数
  • グループ数
  • グループの人数
  • 着席開始座席番号

期待結果

  • 最後のグループが座りに来た後、無事に座席に着席出来ている人数を1行で出力してください。

処理の流れ

  • グループ数分、座席に座る処理
  • 座席が埋まっていた場合の処理
  • 最大座席数を超えた場合に一番目から座る処理

考え方

先にグループの人数と着席開始座席番号を格納した2つの配列を作ります。
次にグループの数だけ繰り返し処理を行う。
このときにまずは以下の要件を満たすように先客がいた場合は帰宅する処理を書きます。   

ただしお客さんは江戸っ子なので、それら座席のうち、いずれか一つでも既に先客に座られている座席があった場合、 一人も座らずにグループ全員で怒って帰ってしまいます。江戸っ子は気が早いんでぃ。

もし、先客がいなかった場合は着席開始座席番号から順に座席に座ってもらいます。
最大座席数を超えた場合に一番目から座る処理も忘れずに。
最後に座席に残った人数を表示させて処理終了。

// 標準入力
process.stdin.resume();
process.stdin.setEncoding('utf8');

var lines = [];
var reader = require('readline').createInterface({
    input: process.stdin,
    output: process.stdout
});

reader.on('line', (line) => {
    var nums = line.split(" ")
    for (var i = 0; i < nums.length; i++) {
        lines.push(parseInt(nums[i]));
    }
});

reader.on('close', () => {
    // 座席
    var seats = new Array(lines[0]).fill(0);

    // 人数と開始番号
    var NumberOfPeopleAndStartNumber = lines.splice(2, lines[1] * 2);

    // 人数
    var peoples = NumberOfPeopleAndStartNumber.filter(function (value, index) {
        if (index % 2 === 0) {
            return value;
        }
    });

    // 開始番号
    var startNumbers = NumberOfPeopleAndStartNumber.filter(function (value, index) {
        if (index % 2 === 1) {
            return value;
        }
    }).map((a) => a - 1);

    // グループ数分座席に座る処理
    for (var i = 0; i < NumberOfPeopleAndStartNumber.length / 2; i++) {
        var sitting = false;
        // 座席の確認
        for (var x = 0; x < peoples[i]; x++) {
            if (seats[startNumbers[i]] + x > seats.length) {
                if (seats[0] === 1) {
                    sitting = true;
                    break;
                }
            } else {
                if (seats[startNumbers[i] + x] === 1) {
                    sitting = true;
                    break;
                }
            }
        }

        // 座先確定
        if (!sitting) {
            for (var y = 0; y < peoples[i]; y++) {
                if (seats[startNumbers[i]] + y > seats.length) {
                    seats[0] = 1;
                } else {
                    seats[startNumbers[i] + y] = 1;
                }
            }
        }
    }
    // 座席に座っている人数
    console.log(seats.reduce((sum, num) => sum + num, 0));
});