体重133キロからのプログラミング

体重はちょっと減って今125キロです。

g-notice ログを出力する

おはようございます。
早いもので、前回の記事から2ヶ月も空いてしまいました・・・。
年度末&年度始めということで結構忙しかったんですよね。
そしGWは11連休し、寝て起きて過ごしただけでした。

さて、最近またg-noticeの開発に着手していて、今回はnode.jsでのファイルへの書き込みなどを実装してみました。

ログ出力する

大抵のアプリケーションってログ出力してくれますよね。
正しく動いていることや、どこでつまづいたのかの目安になってめちゃ便利だなと感じたわけです。
なので、動きを真似て作ってみました。

const fs = require('fs');
const moment = require('moment');

class logger {

  info(msg) {
    // prefix
    const pref = '[INFO]'
    const log = this.createLog(pref, msg);
    // 書き込み
    fs.appendFile("log.log", log.log, (err) => {
      if (err) throw err;
      console.log(log.console);
    });
  }

  error(msg) {
    // prefix
    const pref = '[ERROR]'
    const log = this.createLog(pref, msg);
    // 書き込み
    fs.appendFile("log.log", log, (err) => {
      if (err) throw err;
      console.log(log);
    });
  }

  createLog(pref, msg) {
    // date
    const date = moment(new Date()).format('YYYY-MM-DD HH:mm:ss');
    const logStr = `${pref}${date}:${msg}\n`;
    const consoleLog = `${pref}${date}:${msg}`;

    const log = {
      log: logStr,
      console: consoleLog
    }
    return log;
  }

}

module.exports = logger;

f:id:poinorou:20210524221606p:plain 他クラスからはlog.info('HOGE')みたいに呼び出します。
ログはコンソールだけでなく、ファイルにも書き込んでメンテナンスの際に活用するんですよね。
作ってて思いましたが、絶対こういうライブラリあるわ。

おわりに

実はしれっとPDFのパース⇨DB書き込みまでは済んでるんですが、解説する気になれないレベルでごちゃついているので、明日の僕に任せるとします。
f:id:poinorou:20210524221342p:plain

g-notice テーブル設計

g-noticeのテーブル設計をする。
ガンプラの出荷予定日通知アプリ)

テーブル設計

バンダイ公式の出荷予定はこのような形式をしている。

f:id:poinorou:20210324184735p:plain
商品出荷予定

SR noというものは何なのか良くわからないので必要なさそう。
HGやMGといったスケールも入れたいので下記のようなテーブル設計とした。

id scale item_code name price shipment_date note_text updated_at
primary_key varchar int varchar int datetime text timestamp

スケールは4文字で十分だろうけど、新しいものが追加されるかもなので10文字くらいで。*1

上記を踏まえて、CREATE TABLE文は以下のようになる

CREATE TABLE g_notice.shipment (
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
scale VARCHAR(10),
item_code INT,
name VARCHAR(256),
price INT,
shipment_date DATETIME,
note_text TEXT,
updated_at TIMESTAMP NOT NULL
);

f:id:poinorou:20210405214927p:plain

一応商品名にはインデックスを張っておく。

ALTER TABLE shipment ADD INDEX name(name);

今後の予定

明日はExpressから上記DBへアクセスし、CRUD操作を行えるようにする。 *2
また、PDFをパースした際にどういった形になるのかわからないため、パースした内容を出力するところまでは早めにやっておきたい。

*1:ガンプラにはPG(1/60)、MG(1/100)、RG(1/144)、HG(1/144)の4種類のスケールが存在するがMGEXなど特殊なものもある

*2:ブログが次回更新される日を「明日」と呼ぶことにした

Express HelloWorld ~ Connect MySQLまで

何?

最近ガンプラにハマったけど転売がひどすぎる。
バンダイさんが公式で出荷予定を毎月pdfで公開して下さってるようなので、それを解析してLINEでどうのこうのするアプリを作成する。

要件

  • バンダイ公式の出荷予定pdfを解析するアプリケーション
    • 日に1度アクセスして解析
    • 解析結果をDBに保存
    • 納品前日と当日にLINEで通知
      • この辺の塩梅は後々調整する
      • 商品名送信すると納品日返すとかもやりたい
    • 納品日時を一覧表示するフロントも作る

スクレイピングを含むため、個人使用のみ。

Express Install ~ HelloWorld

  • install
$ npm init -y

※-yは対話モードをスキップするオプション

$ npm install express
  • app.js
const express = require('express')
const app = express()
const port = 3000

app.get('/', (req, res) => res.send('Hello World!'))

app.listen(port, () => console.log(`Example app listening on port ${port}!`))
$ node app.js

便利系

  • nodemon
    • nodeアプリケーションを更新すると直ちに反映してくれる。
$ npm install nodemon
$ npx nodemon app.js

MySQL

$ npm install mysql
  • app.js
.
.
.
const mysql = require('mysql');

const con = mysql.createConnection({
  host: 'localhost',
  user: 'root',
  password: ''
});

con.connect(function(err) {
  if (err) throw err;
  console.log('Connected');
});

MySQLが8系だとうまく繋げない場合があるようで、そういう時はパスワードを空に設定するといいっぽい。
参考にした記事では何の説明もなしに「以下を実行してください」みたいに書いてあって、結構怖くね?と思った。(僕は気にしないですが気にする人は気にしそう)

参考

https://reffect.co.jp/node-js/express-js-connect-mysql
CREATE TABLEもexpress上で実行するような手順になっているため、半月後にこの記事を読んで全てを忘れている僕は気をつけてください。
明日はテーブル設計していきまする。

ここまでのコード

https://github.com/JunpeiKatayama/g-notice

SESの研修が終わったのでどんな感じか伝えたい

筆者について

・SESに内定もらった
Railsチュートリアルを独学で2週した
・SESだとJavaPHPの案件がほとんどなので研修が必要だった
・研修終わった ←イマココ!

私自身も研修内容がどんなものなのか不安を抱えていましたので、SES企業の研修ってどんな感じなんだろう?という方向けに書いています。
また、研修先のスクールに掲載許可を得ていますが、具体的な社名・教材の詳しい内容についてはお伝えできません。

研修先について

IT企業の新入社員を対象として、JavaPHPなどの研修を行なっているスクールで研修を受けました。
動画教材をメインに、動画内容をテキストで補完していく形です。
講義形式ではなく、自習のような形で教材を進め、演習にチャレンジしてわからないところがあれば都度質問するといった感じでした。
ちなみにこういった研修には国から補助金が出るそうです。詳しくは知らないけど。

カリキュラム

Java基礎(2週間くらい)
JavaのClassの仕組みやオブジェクト志向の理解、外部ファイルやコンソールへの入出力・例外処理など。

SQL基礎(2日くらい)
MySQLコマンドあれこれ

JavaでのDB連携(2日くらい)
jdbcを用いてDBを操作。

ServletJSP(2週間くらい)
古の技術。

・Spring基礎(2週間くらい)
SpringBoot + Maven + thymeleaf + MyBatis

・模擬プロジェクト(2週間くらい)
SpringBootで好きなものを作る

感想

まず、スクールでの研修についてですが、効果に疑問を感じているSES企業は多く存在していて、自社でのみ研修を行う企業や、現場に入れて学ばせる企業など、会社によって対応は様々です。
そういった現実がある中、自分の研修先は果たしてどうだろうと心配でしたが、私にとっては「大当たり」でした。

独学で勉強をしていたため、勉強のやり方がある程度わかっていたので、家で勉強している感じで給料までもらえてしまうというフィーバーモードでした。

また、独学でSpringを勉強しようとしたことがある方はわかると思いますが、Springの歴史はとても長く、ビルドツールもたくさんあればHTML部分もJSPだったりthymeleafであったり選択肢が非常に多いため、これ!といった学習サイトが見つからず、情報の取捨選択が非常に難しいです。
私の研修先では教材がとてもわかりやすくまとめられており、レベル感もJava初心者に合ったものになっているため、非常に効率よく知識を吸収できました。
完全未経験でPCすら持っていない方も研修に参加されており、カリキュラム通りにこなせていたので、教材が優秀であったことがわかります。

Servletについて、カリキュラムを最初に見たとき、「こんな古の技術いるのか?」と思っていましたが、Springという歴史の長いフレームワークの誕生の背景を知ることができたため、個人的にはやってよかったと思います。(SpringもServlet生成してるわけだし)

講師の方は全員現役のエンジニアということもあり、ハマってしまっても根気強くコードを読んで原因を探ってくださり、デバッグの手法やエラーコードの解釈なども大変参考になりました。
スクール全体の雰囲気もよく、充実した2ヶ月でした。
優れた環境を用意してくれた研修先の企業様、ならびに弊社の経営陣に感謝。

最後に

最後の模擬プロジェクト演習で、プレゼンに使った資料を公開します(公開許可を得ています)
ソースコードについては、版権ものの画像がたくさん含まれているため、修正後に公開できればなと思います。

全てのアラサー駆け出しエンジニア(SES就職を目指す現実主義者系)に幸あれ

未経験からSESで内定を貰うまで

はじめに

まずは私が客観的にどれほどやばそうな人間なのか知ってもらうために経歴を書いておきます。

年齢:27歳(12月末で28になります)
体重:140kg
学歴:大学中退(当時付き合っていた彼女が病死、そのまま引きこもり半年) 職歴:飲食アルバイト⇨半年ニート⇨百貨店裏方アルバイト⇨コールセンターで契約社員⇨埼玉に引っ越して3月から今まで無職

失業保険の待機期間の3ヶ月を主にFF14をプレイしながら過ごし、IT系の職業訓練校の受験に落ちて、ようやくやばさに気づいて友人の助けを乞いながら独学で勉強開始。

主に勉強した言語:Ruby
勉強期間:2ヶ月

自分で書いていて地雷にしか見えない!やべー!

2ヶ月の勉強期間

Progateで勉強開始する。Rubyから触り始めた。 同時に、毎日勉強記録をつけるために当ブログを開設。
Qiitaは悪い意味で盛り上がりそうなのでやめておいた。

人生15日目 - 体重142キロからのプログラミング
なぜか勉強開始からわずか2週間で全能感を感じてWebアプリ(笑)を作り始めて魔物を生み出してしまう。
(HTMLとCSSについてはかなり勉強になった)
GitHub - peinorou/Hagire_App: hagire of unchi.
魔物のコードは上記から。ひどすぎる。尚この後ポートフォリオ(笑)として作ったものもひどいコードなのだが・・・。
ていうかそもそも他人のコードを一度も読んだことがない。

魔物を生み出してからようやく「Progateだけでは何かが足りていない・・・」と気づき、Railsチュートリアルを始める。
ここからRailsチュートリアル2週するまで、ほぼ人と交流することなく修行僧となる。
ここからいわゆる「写経」スタイルを開始。
RailsチュートリアルのコードをVScodeで手打ちして、さらに専用のノートも作成して手書きでも写した。
写経自体に効果があったかはわからないけど、自分のタイプミスの癖がわかったので気をつけることもできるようになったし、typoしてそうなところがだいたいわかるようになった。
Railsチュートリアルはとてもいい教材だけど、1週目ではテストがマジでわからなくて本当に辛かった。
テスト以外にもわからないことがめちゃくちゃ多くて、全く進捗が出ない日もあったし、とはいえ時間があまり残されていないのでそんな中でもやっていくしかなかった。
2週目もわからないことだらけだったが、演習含めてテストも全て通せるようになったのでとても気持ちよかった。

2週目終了直後から、「うんちの歯切れ報告サイト」を作り始める。
もともと友人と毎日うんちが出たかどうかを報告する謎の文化があった(頭おかしい)のだが、それをWebアプリケーションにしてみることにした。
無意味なものに全力を出すのが好きだったのでモチベーションを維持したまま開発を続けられた。
また、友人のアドバイスから、「プルリクエスト⇨GitHub上でマージ⇨masterをpull」という流れでやってみた。
企業に見せる可能性があるため、コードレビューなどもなしで全部一人でやった。
HAGIRE.
実際のサイトが上記のもの。
Railsチュートリアルの焼き直しのようになってしまったが、はじめてにしてはそれなりに動くものを作れた。
もともと友人しか使っていないものだし、出オチだったので最近は全く触っていない。

この後地獄のように思えた就職活動を始めたのだった。

就活

結果から言うと、全部で11社受けました。 いただいた内定は1つです。
2社書類で落ち、4社は面接で落ち、1社だけ最終面接まで受けさせていただきましたが、落ちました。 一番条件のよかった企業様より内定をいただいたため、選考中であった3社はこちらから選考の辞退を申し入れて現在に至ります。

面接で多かった質問

・将来どのようなエンジニアになりたいか教えてください
現場のことなんて全然知らないのに具体的なキャリアなんて描けねえ!と言うのが正直な感想でした。
自分で考えたものを作るのが楽しかったので、「自分のアイデアがサービスにできるといいな〜とは思います」と答えていました。

・ストレス解消方法を教えてください
ストレスに敏感な業界なため、結構な頻度で聞かれました。
「友人とVC繋ぎながらゲームしてます」と正直に答えました。

面接・逆質問編

こちらから質問する機会が必ずありますよね、あれ正直困りますよね?
2〜3社受けた時点で、仕事の内容に関する質問も尽きてしまったので、単純にその場で気になったことや、勉強方法などを質問していました。
Java勉強してるのですが、Webフレームワークがたくさんあって困っています」だとか、面接に落ちたとしても自分のためになる質問をするようにしていました。
これについて手応えとかは特になかったし、選考に影響したとも思えませんが・・・。
内定をいただいたところでも「JSPサーブレットの本買ったんですがもしかしてこれって古の技術ですか?」と質問しました。古の技術だった。ちくしょう・・・。

SES業界の印象

まず、SESの企業さん側も「SESは避けられている」という印象を持っていらっしゃるということがひしひしと伝わりました。
私はそもそも残された金銭的な猶予が少ないため、内定をいただける可能性が最も高いのはSESだろうということでほぼSESに絞って就職活動をしていました。
どこに行っても「残業がほとんどないこと」をかなりアピールされました。
SESばっかり受けてますと言うと驚かれる採用担当の方もいらっしゃいました。
また、応募者の想像する業務内容と、実際の業務内容で齟齬がないかどうかというのも必ず確認されます。
お話を聞いていると「いきなりコードを書ける」と思っている方が結構いらっしゃるようでした。
採用に力を入れている企業も多く、1時間〜1時間半ほどの長時間の面接も結構ありました。
色々な質問を真剣に答えてくださった企業の方々には本当に感謝しかない。
また、規模の小さいSESだとしても、取引先は大企業ばかりというところも結構あります。
引き抜きのある業界なので、そういった意味でもチャンスが転がっているなと思いました。
あと、当然だけど給料はそんなに高くないです。これはもうしょうがない。

結局ポートフォリオは必要なのか?

個人的な考えですが、資格などが無い場合はあったほうがいいと思います。
まあ「無いほうがいい」ってことは無いから「あったほうがいい」のは当然だけども・・・。
私の場合「うんちの歯切れ報告サイト」とかいうやばそうなものを作ってしまったので、最初は見せずにいましたが、職務履歴書にURLを記載してから明らかに面接の流れが変わりました。
「勉強している」といっても何ができるのかという具体的な指標があったほうがやはり企業側としても選考を進めやすいですよね。
「なんかやたら待たされるな・・・」と思っていたら、面接直前にお渡しした職務履歴書からURLを叩いてサイトを確認していただいていたということが多々ありましたので、転職サイトで申し込む際に備考欄にURLを載せておくだとか、メールで送っておくだとか、もっとお手間を取らせない方法があったなと後悔しています。

厳しいお言葉や、実際あったやばそうな会社

「年齢的にもギリギリだし、色々やってると思うけど、結果出してないよね」
この言葉は刺さりました。この日1日胃が痛かった。
今思い出してもテンション下がる。
でもこれも真剣に私のキャリアを考えてくださっているからこそ出た厳しい言葉なのかもしれない。

ここまでいいことばかり書いていましたが、もちろん「ネット上のSESのイメージ」がそのまま漂ってくるような会社もありました。
ただこればかりは実際に面接を受けたり、お話をしてみないとわからないことなのでなんとも言えないですが・・・。

まとめ

正直私自身の努力というよりは、支えてくれた仲間・家族・友人、また生活面・金銭面でも支えてくれたパートナーあっての内定だったと思います。
まだ実務始まってないから実際のところはわからないが、内定もらえると、嬉しい!
数ヶ月後、そこには変わり果てたデブが・・・ということになっていないようにしたい。
💎PoiyamaPoihey💎 (@poihey) | Twitter
もし何か質問があったり私のことが気になったら上記アカウントに気軽に連絡ください。
輝かしい未来を想像したりできる年齢でもないし、意識も全然高くないので勉強にはならないと思いますが、こんな奴でもIT業界で3食食っていけるんだということを証明してやります!!!

BubbleSortについて調べた

動機

就活をする中で、最終面接の課題になるという話だったので。

バブルソートとは

リストに於いて、隣り合う2つの要素を比較して条件に応じた交換を行う整列アルゴリズムのこと。
このソートを行うことで、値の小さい(大きい)ものが浮かび上がってくる様が、泡が浮かんでくる様を想起させるため「バブルソート」という。
最も基本的な交換法であるため、「基本交換法」「隣接交換法」、あるいは単に「交換法」と呼ばれることもある。

アルゴリズム

「算法」と訳されることもある。
問題を解く手順を定式化した形で表したもののこと。

バブルソートアルゴリズム分析

ここでは、リストを「昇順」に整列させる手順を扱う。
①先頭の要素”A"と隣り合う次の要素"B"を比較する
②要素”A"が”B”よりも大きいなら、”A”と”B”の値を交換する
③先頭の要素を”B"に移し、隣り合う”C"の値を比較/交換する
④上記をリストの終端まで繰り返す
⑤最も大きい値を持つ要素がリストの終端に浮かび上がる
⑥終端の値はリスト内での最大値のため、要素数をひとつ減らして①〜⑥を繰り返す。
https://www.codereading.com/algo_and_ds/algo/bubble_sort.htmlを参考

値が移動していくのではなく、比較の基点が移動していくイメージ。

Javaバブルソートを書く

import java.util.*;

public class Main {
    public static void main(String[] args) throws Exception {
        int[] array = {1,45,22,90,22};
        
        for(int i = 0; i < array.length; i++){
            System.out.print(array[i] + " ");
        }
        System.out.println("sort前");
        
        //bubble sortの処理
        for(int i = 0; i < array.length -1; i ++){
            for(int j = array.length -1; j > i; j--){
                if(array[j - 1] > array[j]){
                    int tmp = array[j - 1];
                    array[j - 1] = array[j];
                    array[j] = tmp;
                }
            }
        }
        
        //sort後を出力
        for(int i = 0; i < array.length; i++){
            System.out.print(array[i] + " ");
        }
    }
}
1 45 22 90 22 sort前
1 22 22 45 90 

コードは以下を参考にしました。
https://techacademy.jp/magazine/19444
自分で考えて近いところまでは行ったけど、うまくいかなかった。
webフレームワークばかり勉強していて、言語のことを全然理解できてなかったのが原因かも。反省。
いや、普通に数学的思考回路が弱すぎるのが原因だ・・・単に頭が悪い。
とりあえず考え方としては、
ループの回数:常に隣の値と比較して交換していくため、length-1回となる。
終端の値を除外する処理:forの中にforを入れて、1ループごとにj--する。

バブルソートの特徴

計算回数はn(n-1)/2回
n回目のスキャンでn番目に軽い(重い)値を浮かび上がらせる 計算量オーダーはO(n2)
ひとつずつ比較していくため処理は遅い 。
一方で並列処理との親和性が高く、コード次第で計算回数を減らすことができたり、単純な比較のため直感的に扱えるという利点もある。

計算量オーダー

実際にアルゴリズムを実装する前に計算時間を大まかに測ることのできる「ものさし」のようなもの。
簡単なものだと、O(n)、O(n2)などがある。
これは簡単に調べることができる。

【例】

//これはO(n)
for(int i = 0; i < n; i++){
...
}

//これはO(n^2)
for(int i = 0; i < n; i++){
    for(int j = 0; j < n; j ++){
...
    }
}

アルゴリズムとは本質的に「繰り返し処理」であるため、単純にfor文の数で計算量を求めることができるらしい(?)

ちなみに計算量オーダーは正しい計算量を示している訳ではない。
ランダウのO記法」を用いて表記している。

ランダウのO記法

3n2 + 5n + 100回の計算をするアルゴリズムがあるとする。
最高次数の項以外を落とす⇨3n2
⇨係数を落とす⇨n2
数学に明るくないので詳しい説明はできないが、nの値が大きくなればなるほど、他の数値は誤差になるということらしい。
アルゴリズムに関してはこの方の記事がとっても面白いです。(文系脳の私でも楽しく読めます)
https://qiita.com/drken/items/872ebc3a2b5caaa4a0d0

まとめ

アルゴリズム面白い
明日はバブルソートを用いたプログラムをいくつか書いてみたい

Javaを勉強し始めた

最近就活してます。体重は多分142キロを超えました、私です。
SESの求人に応募してまして、現在2社落ちていて、1社2次面接っていう感じです。
まあわかってはいたんですが、現場で働くにはまずJavaを覚える必要があります。
研修のあるところしか応募してませんが、Javaがどんなもんなのか触れてみようということで少し勉強してます。
自分で忘れないためにもRubyとの違いなどを書きとめていきます。

型宣言

Javaでは、型宣言を毎回行います。
「型」というのは「データ型」のことで、文字列ならString、数字ならintといったもののことです。

//Stirng型の変数hogeにhugaを代入。
String hoge = huga;

また、必ず命令文は「;」で終わらなければエラーになります。
また、以下のように戻り値・引数までにも型宣言をする必要があります。

public static String hoge(String huga) {
    return huga;
}

Rubyしかやったことがなかったので、一見するとただ読みづらいだけに見えましたが、後からコードを読んだ時に理解しやすく、コンパイルにも優しかったりと、業務上で役立つ仕組みになっています。
逆にRubyは表面に書いてある情報がとても少なく、コードはすっきりと読めますが、より堅牢な設計が求められます。

メソッドの呼び出し

メソッドの呼び出しもRubyと違います

//hello!を出力するhelloメソッドを定義
public static void hello() {
    System.out.println("hello!");
}
//helloメソッドを呼び出す
hello();

//入力された値を2倍にするメソッドを定義
public static int double(int value){
    return value * 2;
}

//doubleメソッドを呼び出す
double(2);

上記コードからわかるように、引数が不要な場合も()を用いて、引数が不要であることを示す必要があります。
また、Rubyは全てに戻り値がありますが、Javaにはありません。
「void」というのは「戻り値なし」を示しています。
この戻り値の定義は正直うまく噛み砕けていないのですが、「return」が含まれるメソッドには戻り値があるという理解で一旦保留しています。
クラスメソッドの呼び出しはRubyと似たような感じで、「クラス名.メソッド名();」で呼び出すことができます。

クラスフィールド

Railsでいう所のデータモデルのようなもの。

class Car {
        public String name;
        public int value;
        public String color;
        public double milage = 0;
}

Car.nameのようにして、属性の値を取り出せる。
尚実際にはCar.nameのように直接アクセスはせず、ゲッターと言われるメソッドを定義してアクセスする作法がある様子。
正直このあたりは言葉で説明できるほど理解できていない。

風邪ひいてしんどいので今日はこの辺で切り上げよう。
自分の学びのためだけにブログ書いてるけど、そろそろ発信していくことも意識していかないとなあ。