TECH PLAY

株式会社ラクス

株式会社ラクス の技術ブログ

941

はじめに こんにちは。aa_cryingです。早いもので、4月で入社して3年目になります。 2020/2/13-14 で実施された Developers Summit 2020 に参加してきましたので、 event.shoeisha.jp 今回はそのレポートとして、 聞いてきたセッションの内容の紹介と感想を残していこうと思います。 はじめに Developers Summit とは? セッション内容を紹介 【14-D-5】マルチクラウドに向けてNGINX活用促進する為に知っておいてほしいこと 【14-E-6】生涯イチ・エンジニアとして好きな技術でジャンプアップし続けよう - 夢のつづきはビッグデータで 【14-E-7】月間約10億件のクラッシュデータから見えたアプリ品質の実態! エンジニアが仕掛ける、『ONE TEAMで挑む、賢いアプリの品質管理』とは? 終わりに Developers Summit とは? 翔泳社 が主催されており、「技術者コミュニティとの連携から生まれた総合ITコンファレンス」というテーマで年に数回開催されています。 総合コンファレンス ということもあり、内容は技術寄りの話から、サービス運用の話、マインド的な話など多岐に渡っていました。 数あるセッションの中から3つのセッションを選び聞いてきたので、それらの紹介をしようと思います。 セッション内容を紹介 【14-D-5】マルチ クラウド に向けてNGINX活用促進する為に知っておいてほしいこと まず1つ目は技術寄りのセッションになります。こちらは マルチ クラウド ・ NGINX というワードに惹かれて選んだセッションですが、 思ったより技術寄りの内容でした。 まだスライドが公開されていませんので、内容を軽くご紹介しますが、 内容の趣旨としては「NGINXはこんなこともできます」という紹介でした。 DockerコンテナやJenkins等と連携してNGINXを利用することが出来ますよーと話や GKE ( Google Kubernetes Engine) や AKS (Azure Kubernetes Service) 上ではこういう活用が出来ますよーという話がありました。 2年目エンジニアの私には首をひねる内容が多かったですが、終了後に調べ、GKEや Kubernetes 等の技術について知り、興味を持つきっかけになりました。 新たに追加された機能である External Name についてはデモを交えて説明していただき理解できましたし、画期的なシステムだなと思いました。 External Nameを使用することで、部分的に (このバージョンのみ等)他の クラウド サービスを使用したりといったことが可能になるそうです。 また、マルチ クラウド で共通の設定をすることが可能なので、マルチ クラウド を管理するのが便利になりそうだなと思いました。 【14-E-6】生涯イチ・エンジニアとして好きな技術でジャンプアップし続けよう - 夢のつづきは ビッグデータ で 2つ目のセッションはマインド的な話でした。 こちらはスライドが公開されていましたので、詳細は以下をご覧いただければと思います。 speakerdeck.com 私の中では以下の話が印象に残りました。 常にホームランを打つという強い意志は大事だが、結果は三振だろうが気にしない。 (結果を出すためには失敗を恐れない) 「こうなりたい」ではなく、「なるんだ」という強い意志が大事。 まずは小さな夢・目標でいいから立てて、それを叶える・達成していくことでジャンプアップ(成長)できる。 心が折れないように趣味等で自分をケアすることが大事。 「結果を出すためには失敗を恐れない」ということの例えで アダム・ダン 率の話が出てきたりと、野球に例えて表現されるのが面白かったです。 33-4 も出てきました (笑) 好きな技術でジャンプアップ の前に、私はまず好きな技術を見つけるために様々な技術を学んでいきたいです。 【14-E-7】月間約10億件のクラッシュデータから見えたアプリ品質の実態! エンジニアが仕掛ける、『ONE TEAMで挑む、賢いアプリの品質管理』とは? こちらは スマホ アプリのサービス運用の話になります。 こちらもスライドが公開されていないため、内容を簡単に説明させていただきます。 登壇された方は スマホ アプリのエラー解析ツールである「SmartBeat」というツールの開発チームに属している 本ツールでは1ヶ月に10億件以上のエラーを検出している アプリのクラッシュが起こるとそれが★1レビューに繋がり、最終的にはユーザーが離れていってしまう アプリのクラッシュはアプリを使わなくなる理由の7割にものぼる データの消失が起きてしまったりすると大惨事に... なぜクラッシュするのか Android の場合 → 端末依存のクラッシュが多い 全ての Android 端末を集めてテストする、というのは難しい。 iOS の場合 → iOS のアップデートによりクラッシュの発生や再現が変わってくる クラッシュしないためには エラーの検知率を上げる (アラートメールや本ツールの使用等) すぐ直す・直さないの判断や、どこから直すかの判断を的確に行う 影響を最低限にとどめる工夫が大事 エラーが分かっておりすぐに直せない場合は早めにアナウンスする等 私が関わっている製品でもアプリを配信しているので、他人事ではないなと思い申し込みをしました。 また、私達のチームでは クラッシュしないためには に記載されている事項は的確に行われており、 サービス運用については上位者の皆さんにさすがの一言です。 終わりに このような大きなカンファレンスには初参加でしたが、学びやエンジニアとしてのモチベーション等得られるものが多く、また行きたいと思えました。 案内があった後すぐに動けず、題名や登壇者名から「気になる!」と思い申し込もうとしたら 既に満員 になってしまっているということが多かったのが心残りです。 次回以降は気になるセッションに参加できるよう、すぐに動きたいと思います。
id:logy0704 です。 もうすぐJava14がリリースされますね。 いくつかの変更が予定されていますが、その中でも今回はswitch文の変更についてご紹介しようと思います。 *1 そもそもswitch文って? 従来のswitch文の課題 fall through ブロック 文であること これからのswitch 矢印構文の導入 式として扱えるように 最後に 参考 そもそもswitch文って? Java を学んだことのある方ならば一度は触れたことがあるかと思います。 以下のような形式で複数分岐を表現することができ、特に Enum と組み合わせて使われることが多いです。 switch(case) { case1: hoge; break; case2: huga; break; default: piyo; } 従来のswitch文の課題 fall through switch文ではマッチしたラベル以降の分岐がすべて実行されてしまいます。 一つの分岐のみ実行したい場合にはbreak文を追加してあげる必要があります。 *2 ブロック switch文ではブロック全体が一つのスコープとみなされるため、変数名の競合や想定外の再代入が発生する可能性がありました。 *3 文であること switch文(switch statement)と表現されるように、これまではswitchは文としてのみ扱われてきました。 *4 そのため、条件によって変数を変化させたい場合、switch文をそのまま変数に設定することはできず、一度、switch文の中で変数に値を設定してから利用する必要がありました。 int hoge; switch(case) { case1: hoge = "huga"; break; case2: hoge = "piyo"; break; default: } System.out.println(hoge); これからのswitch これらの課題を解消するため、switchに変更が加えられました。 *5 ※ サンプルコードは https://openjdk.java.net/jeps/361 から引用させていただきました。 矢印構文の導入 ラムダ式 で見かけるような矢印を使った記法が導入されました。 switch (day) { case MONDAY, FRIDAY, SUNDAY -> System.out.println(6); case TUESDAY -> System.out.println(7); case THURSDAY, SATURDAY -> System.out.println(8); case WEDNESDAY -> System.out.println(9); } label -> 実行したい内容 という構文でそれぞれの条件分岐を表現することができます。 カンマ区切りで複数のラベルを並べることで、複数ケースにマッチする条件も表現できます。 この構文の場合、break文は必要とせず、一度条件にマッチした後、switchから離脱します。 見た目もスッキリするだけでなく、うっかりbreak文を書き忘れて想定外のバグが…なんてことがなくなりますね。 また、変数のスコープもそれぞれの矢印の右辺に閉じるため、変数名の重複等に気を使う必要がなくなりました。 式として扱えるように switchの結果を引数に渡したり、変数に格納することが出来るようになります。 static void howMany(int k) { System.out.println( switch (k) { case 1 -> "one" case 2 -> "two" default -> "many" } ); } 最後に switchの新たな記法についてご紹介しました。 Java14はLTSではないため、まだ導入される方は少ないかもしれませんが、将来的に利用できる記法として頭の片隅に置いておくと良いかもしれません。 参考 JEP 361: Switch Expressions Java SE 12の拡張switch文/式の完全ガイド エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ カジュアル面談お申込みフォーム どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。 以下フォームよりお申込みください。 forms.gle イベント情報 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! rakus.connpass.com *1 : Java12からプレビュー版として提供されていた内容ですが、フィードバックを経てJava14で正式導入されます。 *2 : あえてbreak文を書かないことで複数の条件にマッチさせるような書き方もできます。 *3 : 各ラベルごとにブロックを区切ってあげることで回避する方法が一応存在します。 *4 : Java における文の正確な定義については Oracle社公式ページ を参照してください。 *5 : 正確には課題の解消だけでなく、現在プレビュー中のパターンマッチング機能への布石としての側面もあるようです。
こんにちは!遅くなってしまいましたが、今回は1月21日に行われたビアバッシュのご紹介をします。 今回のビアバッシュは自由枠の発表とLTの構成となっております。 発表一覧 自由枠 情報管理アプリ「Notion」 へんな Scala ドメイン 駆動設計を支える アーキテクチャ テスト LT git switch & git restore PHPerKaigi2019の参加がきっかけで社内勉強会を主催するようになった話 発表内容 情報管理アプリ「Notion」 サンフランシスコにオフィスを構えるNotion社が開発した情報管理アプリ「Notion」について紹介してくださいました。 議事録などのテンプレートを用意することができるなど便利な機能がそろっています。 非常に柔軟でアイディア次第で何でもできるアプリですが、柔軟すぎるがゆえに迷うこともあるそうです。 へんな scala 今月も Scala が好きなエンジニアが Scala について語ってくださいました。本発表では Scala の処理系について紹介してくださいました。 Scala .js   Scala をJSにトランスパイルすることができます。 ScalaNative   Java スタンダードライブラリを一部使用することができます。 Ammonite   Scala で スクリプト を書くことができます。replだけでなく、shellも書くことができます。 Dotty   Scala の新しい処理系。 コンパイル 速度が速くなります。 Scala .net  NET用の実行ファイルを作成します。公式サポートされていましたが、2012年でサポートが終了しました。 ドメイン 駆動設計を支える アーキテクチャ テスト 2/16に開催されたOOC2020の先取りの発表をしてくださいました。 Java と アーキテクチャ テストツールの ArchUnit を用いた ドメイン 駆動な アーキテクチャ 設計を運用する方法についてのお話です。 また、 PHP の アーキテクチャ テストツールの紹介もしてくださいました。 こちらが実際にOOCで発表されたスライドなので気になる方はどうぞ。 speakerdeck.com git switch & git restore Git2.23の新機能で、gitのブランチを変更する「switch」とファイルを変更する「restore」コマンドについて紹介して頂きました。 「switch」と「restore」は「checkout」を分割した機能です。 ただ本人曰くcheckoutの方が打ちやすいらしいです PHPerKaigi2019の参加がきっかけで社内勉強会を主催するようになった話 若手エンジニアがPHPerKaigi2019に参加したことがきっかけで開催した社内勉強会についてのお話です。 勉強会を開催したきっかけや開催してよかったこと、気づいたことなどを語ってくださいました。 勉強会の開催を実行、継続する難しさを発表から感じました。 終わりに 今回のビアバッシュではGitの便利な機能など、業務の役に立ちそうなものや、 勉強会開催で得たものについての発表などためになる話を聞くことができました。 今後もビアバッシュの内容をブログに掲載しますので、どうぞお楽しみに!
はじめに こんにちは。新卒2年目のmrym_618です。 最近業務で Chrome 拡張の「Stylus」を使い、 CSS の設定とデザインの変更を行うことがありましたので、 今回はその使い方について紹介していきたいと思います。 はじめに Stylusとは インストール方法 CSSの設定方法 おわりに Stylusとは Stylusとは、特定の CSS をブラウザ側で設定するための Chrome 拡張機能 です。 インストール方法 インストール方法は、以下のサイトより chrome.google.com Chrome ウェブストアを開き、「 Chrome に追加」を押してインストールするだけです。 インストールが完了すると以下の画像のようなアイコンが表示されます。 CSS の設定方法 CSS を設定したいサイトを開いたままインストール完了後に表示されるようになったSのアイコンをクリックします。すると以下のようなダイアログが表示されますので、赤枠のように CSS を設定したいURLをクリックします。 すると、スタイルの編集画面が表示されますので、実際に適用したい CSS を記述します。 今回は、このサイトのタイトルと注釈の色を変更してみたいと思いますので、以下のように記述します。 .header-image-enable #blog-title #title a { color : #000000 ; } .header-image-enable #blog-title #blog-description { color : #000000 !important ; } CSS 設定後、Sアイコンで表示されるダイアログにチェックを入れることで CSS を適応することができます。 CSS の適応を無効にしたいときは、 チェックボックス のチェックを外すかすべてのスタイルをオフにするにチェックを入れることで無効にすることができます。 CSS を編集したい場合は、鉛筆マークを押すことで編集画面に遷移することができます。 おわりに 今回は、 CSS を設定することで自由にデザインの変更をできるStylusについて紹介しました。 Stylusを使い自分独自の CSS を設定することで、Webサイトを見やすくて使いやすいようにカスタマイズすることができますので、皆さんもぜひ試してみてください。 エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ カジュアル面談お申込みフォーム どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。 以下フォームよりお申込みください。 forms.gle イベント情報 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! rakus.connpass.com
はじめに こんにちは、 MasaKu です。 PHPer による PHPer のためのお祭り、 PHPerKaigi が今年も開催されました。 (弊社もスポンサーをさせていただいております) PHPerKaigi2020 phperkaigi.jp 今回は LT にチャレンジさせていただいたのですが、登壇にあたり様々な学びがありました。 本記事では、LT にチャレンジする上で学びにつながった以下のポイントについて記載していきたいと思います。 本記事で記載する内容 トーク テーマの選定 発表資料の作成 LT 発表 登壇資料 speakerdeck.com 参加にあたって 去年の PHPerKaigi2019 には一般参加という形で参加させていただいており、大変興味深い発表ばかりだったので、 「来年こそはぜひスピーカーに!」 と意気込んでおりました。 去年の参加レポートは こちら tech-blog.rakus.co.jp 実は昨年開催された PHPerKaigi2019 のプロポーザルにも挑戦していたのですが、残念ながら非採択という結果になってしまっていました。 そのため、今年の開催で トーク が採択された時は嬉しさ半分驚き半分といった気持ちでした。 なお、昨年度の トーク テーマは以下です。 Laravel + MongoDB でつなげる、つながるオープンデータ エンジニアとしての成長を加速させた3つの取り組み fortee.jp fortee.jp プロポーザル応募 今回のプロポーザル募集にあたり、話したい トーク テーマはすぐに思いつきました。 というのも、PHPerKaigi の参加がきっかけで社内で行った上映会からいろいろな活動を開始するようになったので、その経過報告をしようと考えていたからです。 社内のビアバッシュでも何度か発表したテーマでしたが、今回の PHPerKaigi2020 でも発表することができれば最高だなあと考えていたためです。 しかし、どのような展開で話していけば盛り上がるかという視点はサッパリだったので、 トーク の方向性についてはブレブレでした。 個人としてのモチベーションの変化を話すべきか 勉強会開催にあたってのノウハウを話すべきか テーマ検討で トーク を聞いてくださる方に受けそうなのはどちらか、自分として話しやすいのはどちらか、という視点でテーマ選定を行っていきました。 発表資料の準備 トーク が採択された後は発表資料の準備を始めましたが、弊社で定期的に開催している MeetUP という社内イベントで登壇した経験があったため、どのように話を構築していくと資料が作りやすいかというノウハウがあったため、資料作りはスムーズに進みました。 イベントページ rakus.connpass.com 登壇資料 speakerdeck.com 今回の登壇資料の作成は以下のような流れで進めました。 トーク テーマの再確認 伝えたいポイントを大きく書き出す そのポイントを一番盛り上げられそうな話の展開を考える 箇条書きレベルで話を整理してアウトラインを作成する アウトラインをレビューしてもらう レビュー結果を元にスライドを作成する 個人的に一番大切だと思うのは 4 番目の内容です。 箇条書きレベルで話がまとめられていると、それをスライド化するのは非常に容易です。 「それならスライドを作りながら内容を整理しても同じなのでは?」と思うかもしれません。 これは個人的な感覚ですが、 グラフィカルなアウトプットができてしまうと伝えたいポイントが見えにくくなる気がするので、まずは文字ベースのアウトプットを作成するのが良い と思っています。 逆に、文字ベースでも自分の話たい内容がきちんと整理できていればそれをスライド化するのは難しくなく、むしろ、図的な説明も可能になるので、自分としてもより納得できる説明を組み立てられるようになります。 発表練習 発表練習は個人でやるのも大切だと思いますが、やはりフィードバックをもらえる環境で実践するのが最適です。 幸いにも今回は発表練習をする機会が豊富だったので、実践的な練習を繰り返すことができました。 今回、発表練習を通して得た教訓としては、LT で登壇するう上で特に気をつけなければならないポイントは以下のように感じました。 ウケを狙うポイントはちゃんと意識すること 画面を読んでいるときはどこを読んでいるのかを分かるようにすること 5 分間フルで使い切ること 特に、 5分間をフルで使い切ること は大切だと感じました。 通常の発表の場合は話たい内容を時間内に収められるように簡潔に話すことが重要かと思いますが、様々なカンファレンスのLTを見て感じることとしては、 LT では 5 分間という時間を綺麗に使い切ることのほうが芸術点が高い ように感じておりました。 そのため、タイムキーパーの「終了です!」の一言と同時に発表をキレイに切れるように、最後のスライドに向けてどれくらいの時間を残すかということを意識して練習するようにしました。 登壇してみて PHPerKaigi2020 登壇風景 LT の会場には推定 200 人を超える参加者の方がいらっしゃったように思います(もっと多かったかも) このような大勢の前で発表した経験がこれまでなかったこともさることながら、カンファレンスでの登壇も初めてでしたので非常に緊張した 5 分間でした。 練習通りにできたところもあれば、自分で何を話しているのかすらわからなくなるような場面もありましたが、非常にいい経験になったと思っています。 会場内から笑いの声や拍手が聞こえてくると勇気づけられるような感覚があった ので、今後、こういったカンファレンスに出席する際は、 リアクション増しを意識 していきたいと思いました。 最後に いつかはスピーカーとして登壇したいと思っていたカンファレンスに出ることができてとても良い経験ができたと思っております。 発表内容について Twitter でたくさんのリアクションをいただいておりましたが、自分が想像していた以上に発表内容に共感していただけたようで嬉しかったです。 イベントを通して様々な方と交流することができたこともとても良い経験になったと思います。 今回の PHPerKaigi2020 での登壇をきっかけとして、また次のステップに向けて再チャレンジしていければと思います。 参考サイト PHPerKaigi 2019 PHPerKaigi 2020
こんにちは。新卒2年目のbadaikiです。業務でできることが徐々に増えていくなかで、まだまだ自分はできていないなと感じる日々を過ごしております。 はじめに オールペア法とは テストケース生成ツール PICT(Pairwise Independent Combinatorial Testing tool) pairwiser おわりに はじめに 前回ではテストの網羅率の向上、可視化するディシジョンテーブルについて記事を書きました。 tech-blog.rakus.co.jp ディシジョンテーブルは網羅率は高められるものの、ターゲットによってはすべてのケースを消化するだけでとんでもない 工数 がかかってしまうことがわかりました。 そこで今回はどうすればケース数を減らし、効率的にテストを実施できるかについて調べてみました。 以前私がテスト実施から参入した開発で、先輩社員がケースを作成したものを複数人で実施していくということがありました。条件がかなり複雑に絡み合う機能であったため、ケース数が爆発しているんだろうなーと予測していたのですが、いざケースを確認してみると予測していたケース数の1/3ほどのケース数で驚きました。聞くとオールペア法を活用していました。 オールペア法についてはケース数が減るよ。という知識しかなく、なぜ減らせるのか、漏れは起きないのかということまで理解できておりませんでしたので、この機に調べてみようと思いました。 オールペア法とは オールペア法(ペアワイズ法ともいう)とは組み合わせテストの技法の1つです。 組み合わせテストとは、多数の入力条件の値をいろいろと組み合わせて実施するテストです。しかし前項でも述べたように、全ての入力条件で値の組み合わせを考えると、膨大な数になり全てをテストするのは現実的ではありません。例えば3つの選択肢があるプルダウンが4つあり、その組み合わせだけで 3の4乗 = 81ケース となるわけです。81ケースと聞くとできそうな気がしますが、それぞれが4つの選択肢になるだけで256ケースと3倍以上に増えてしまいます。 以降ではプルダウンのような入力条件を因子、その値を水準と呼びます。 ある文献 *1 ではソフトウェアのバグの7割から9割が1つまたは2つの因子の組み合わせによって発生していることが記されています。以下がそれを示した表です。 要因数 組込み機器(医療系) ブラウザ( Netscape ) サーバ( Apache ) データベース 1 66 29 42 68 2 31 47 28 25 3 2 19 19 5 4 1 2 7 2 5 2 0 6 1 4 そこで2つの因子の組み合わせをつくり、すべての水準の組み合わせのケースを作成するのがオールペア法という技法です。 例えば、プルダウンが3つの組み合わせを考えてみます。 因子 水準 プルダウンA 0,1 プルダウンB 0,1 プルダウンC 0,1,2 これの全組み合わせは 2 * 2 * 3 = 12ケース 。 これをオールペア法で作成するには 1. まずそれぞれの因子のペア(AB、AC、BC)を作成し、水準の組み合わせの全パターンを作成します。 AB AC BC 00 00 00 01 01 01 10 02 10 11 10 11 11 12 2. 1で作成した水準の組み合わせをAB列から順に取り出します。 No A B C 1 0 0 2 0 1 3 1 0 4 1 1 3. 次にAC列、BC列と順に当てはまる行に割り付けていきます。このときに着目しているペア以外のペアも同じ組み合わせが現れないように割り付ける必要があり、これがケース数を最小にするために重要です。←これがややこしいです。例えばAC列の(10)を割り付けるとき、(1,0,0)の組み合わせではなく、(1,1,0)の組み合わせにします。AC列の(00)を割り付けるときに(0,0,0)の組み合わせが既に出来上がっており、BC列の(00)が2か所で作成されてしまうためです。 No A B C 1 0 0 0 2 0 1 1 3 1 0 1 4 1 1 0 5 0 0 2 6 1 1 2 このようにオールペア法で作成すると今回の例ではケース数が12ケースから6ケースと半分になりました。ただし、理屈がわかっても実際自分で作成しようとすると難しいです。。。加えて、実際のシステムでケース作成を行う場合には、A=0のときはB=0になるなどの制約条件があるとさらに複雑になってきます。上記の例は簡単な例でしたが、複雑になっていくと考えるを諦めてしまいそうですよね。実は制約条件も考慮して自動生成してくれるツールが提供されています! テストケース生成ツール オールペア法のテストケース生成ツールは多く提供されており、以下のサイトにまとめられていました。ここで紹介されているツールだけで現在51種類もあり、驚きました。この中で PICT と pairwiser について使い方を紹介したいと思います。 http://www.pairwise.org/tools.asp www.pairwise.org PICT(Pairwise Independent Combinatorial Testing tool) http://www.pairwise.org/tools.asp 特徴: 無料 Microsoft 社が開発 コマンドプロンプト で実行する 多機能 ダウンロードするとHTMLのマニュアルがついてくる(英語) 使い方: 1. パラメータを定義する PICTではモデルファイルと呼びますが、txtファイルで作成します。 基本的なモデルファイルは、末尾が : で終わるパラメータと、 ⁠, で区切られた値の並びとからなるモデル定義部のみで構成されます。 A: 0,1 B: 0,1 C: 0,1,2 2. 1で作成したファイルをpict.exeで実行する。 pict test.txt これだけです。 すると以下の結果が出力されます。 A B C 1 1 1 0 0 0 1 0 1 1 1 0 1 1 2 0 0 2 0 1 1 結果をリダイレクトする場合には以下で実行できます。 pict test.txt 1>result.txt 2>error.txt 1 は出力結果、 2 はエラーが発生したときにエラー内容が出力されます。 制約条件を設定する場合にはモデルファイルの末尾に制約条件を追記します。記述方法は独自の スクリプト言語 が用いられており,因子を [] で囲み,水準が文字列の場合は, " で囲み, ステートメント の末尾は ; で終わります。条件にはパラメータと値の関係を評価する関係式を用いて 条件付き制約 と必ず成立する 無条件制約 があります。 #パラメータ定義 A: 0,1 B: 0,1 C: 0,1,2 #制約条件定義 #条件付き制約 if [A] = 1 then [C] <> 2; #無条件制約 [A] <> [B] or [A] <> [C] or [B] <> [C]; 上記のモデルファイルで実行すると以下のケースが出力されます。制約条件通り、A=1の場合はC=2にはならず、A=B=Cになるケースは作成されません。 A B C 0 0 1 0 0 2 0 1 0 0 1 1 1 0 0 0 1 2 1 0 1 1 1 0 pairwiser Pairwiser - Pairwise Testing and Test Generation Tool 特徴: 無料(ユーザ登録が必要) INDUCTIVE社という ノルウェー の企業が開発しているWebアプリケーション カバレッジ などの解析が容易 生成したケースをエクセル形式でダウンロードできる pairwiser 使い方: 基本的に、左から右へタブに必須情報を入力してテストケースを生成します。それぞれのタブの「Save」ボタンを押さないとデータが保存されません。また、データが保存されていないタブよりも右側のタブの内容は更新が効かないようになっています。 Webアプリのため、直感的に操作がやりやすいです。 Define Parameters タブでパラメータ定義や制約条件を設定でき、 Generate Tests タブでケース作成ができます。 Generate Tests タブの上部にある Export to Excel ボタンをクリックすることで Excel ファイルもダウンロードすることができますので、業務でテストケースを Excel で書かれている場合にはそのまま活用することができて便利ですね! pairwiser 結果 また、公式ページには チュートリアル やヘルプもあるので、初めてさわる場合でも安心ですね! おわりに 前回のディシジョンテーブルに引き続き、今回は組み合わせテストのオールペア法について調べ、自動生成ツールを使ってみました。オールペア法について知ることで、なぜそのケース数で十分なのか、どのように作成されているのかが理解できました。また、自動生成ツールを用いることで制約条件など細かな設定も行え、ツールによっては Excel ファイルに変換してくれるなど、人手で行うよりもとても効率的にケース作成が可能だとわかりました。今後、条件が複雑に絡み合う機能のテストではオールペア法を用いて網羅性を保証しつつ、効率的に進めていこうと思います。 エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ カジュアル面談お申込みフォーム どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。 以下フォームよりお申込みください。 rakus.hubspotpagebuilder.com ラク スDevelopers登録フォーム https://career-recruit.rakus.co.jp/career_engineer/form_rakusdev/ イベント情報 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! ◆TECH PLAY techplay.jp ◆connpass rakus.connpass.com *1 : R.D.Kuhn et al.“⁠Software Fault Interactions and Implications for Software Testing,⁠”⁠ IEEE Transactions on Software Engineering, 30(6), June 2004
はじめに こんにちは。choreiiです。最近自チームで扱っている商材のフロントエンドのテストコードを大量に書く機会がありました。その中で大きくハマった3点について紹介します。 はじめに 環境 1. ライフサイクルフックをmock化(上書き)したい 2. テストによってcomputedを差し替えたい 3. localStorageをmock化したい まとめ 参考 環境 Vue:2.6.11 vue-test-utils:1.0.0-beta.29 Jest:23.6.0 1. ライフサイクルフックをmock化(上書き)したい 以下のようにbeforeMountで初期化処理を書いている場合、beforeMountをまるごとmock化(上書き)したくなる時があります。 <script> export default { beforeMount() { // コンポーネントで必要なデータの取得や初期化の処理 } , methods: { sampleMethods() { // 何らかの処理 } } } ; </script> methodsの内容を上書きする時は以下のようにすれば差し替えることができるので、ライフサイクルフックの場合も上書きできると考えていたのですができませんでした。 test( "test" , () => { const wrapper = shallowMount(Sample, { beforeMount() { // これで空の内容で上書きできるはず -> できない。。。 } methods: { sampleMethods() {} // 空の内容で上書きできる } } ); } ); vue-test-utilsのガイドには特に記載がなかったので手元で色々頑張ってみたのですが、下記のissueを発見。 github.com ライフサイクルフックは上書きできないので、処理を上書きしたい場合はbeforeMountの処理をmethodsに切り出して、その切り出した内容を上書きするのが良さそうです。 <script> export default { beforeMount() { this .initData(); // methodsに切り出し } , methods: { initData() { // コンポーネントで必要なデータの取得や初期化の処理 } , sampleMethods() { // 何らかの処理 } } } ; </script> test( "test" , () => { const wrapper = shallowMount(Sample, { methods: { initData() {} , // methodsの方で上書き sampleMethods() {} } } ); } ); ちなみに、shallowMount(mount)した後から、 setMethods を使っても上書きできます。 test( "test" , () => { const wrapper = shallowMount(Sample); wrapper.setMethods( { initData(): {} // 後から上書き } ) } ); 2. テストによってcomputedを差し替えたい 条件が少しだけ異なるテストを書く際に、毎回shallowMount(mount)を行うのはコード記述が増えるのであまりやりたくないです。methodsやcomputedだけを後から差し替える方法があれば完璧です。上記で述べたように、methodsは後から上書きすることができます。 describe( "test" , () => { const wrapper = shallowMount(Sample); test( "test1" , () => { wrapper.setMethods( { sampleMethods(): {} // test1用の処理 } ) } ); test( "test2" , () => { wrapper.setMethods( { sampleMethods(): {} // test2用の処理 } ) } ); } ); setMethods があるなら setComputed もあるだろうと考えていましたが、これまたvue-test-utilsのガイドには記載がありません。 ガイド記載のwrapperのメソッド抜粋 他にもset系のメソッドが用意されていながら、computedだけがありません。。。嫌な予感がしながら情報を探してみると下記のissueを発見(デジャヴ)。 github.com 昔は用意されていたものの、バグがテストをすり抜ける可能性があるので廃止されたようです。バグをなくすためと言われては仕方がないのでテストごとにshallowMount(mount)をするようにしています。 describe( "test" , () => { const render = ((sampleComputedStub), { const wrapper = shallowMount(Sample, { computed: { sampleComputed: sampleComputedStub } } ); } ); test( "test1" , () => { const wrapper = render( { // sampleComputedを上書きしたい処理 } ): } ); test( "test2" , () => { const wrapper = render( { // sampleComputedを上書きしたい処理 } ): } ); } ); 3. localStorageをmock化したい テストでlocalStorageをそのまま使うわけにはいかないので、mockに差し替える必要があります。 localStorageについては以下を参照 developer.mozilla.org jest.spyOn(localStorage, 'setItem' ); spyOnの使い方は間違えていないのに、以下のようなエラーがでてしまいました。 TypeError: object [ methodName ] .mockImplementation is not a function localStorageの中で、setItemが見つからないみたいです。またまた嫌な予感がしましたが今回は解決方法がありました。 stackoverflow.com 以下のように proto を使用するとアクセスできるようです。ただリンク先にも記載がある通り、 proto は非推奨とのことなのであまり多用するのはよろしくなさそう。今回はどうしてもjest.spyOnを使って呼び出し回数や呼び出し引数のテストを書きたかったので使用しています。 jest.spyOn(localStorage.__proto__, 'setItem' ); まとめ Vue/Jestの書き方は公式のガイドが充実しているので、ガイド通りに進めている間はスムーズに進みます。その反面、ガイドに載っていないことをやろうとすると情報がなかなか見つからず痛い目をみることが多かったです。 テストの主目的はプロダクトコードの品質担保なので、あまりテストの書き方を調べるのに時間をかけたくありません。今後は多少記述が増えたり冗長になったとしても、ガイドに従いながらテストを書き、どうしても実現できないことだけ別途調査することにします。 参考 Vue インスタンス — Vue.js ガイド | Vue Test Utils https://jestjs.io/docs/ja/23.x/getting-started エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ カジュアル面談お申込みフォーム どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。 以下フォームよりお申込みください。 rakus.hubspotpagebuilder.com ラク スDevelopers登録フォーム https://career-recruit.rakus.co.jp/career_engineer/form_rakusdev/ イベント情報 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! ◆TECH PLAY techplay.jp ◆connpass rakus.connpass.com
次週、都内ではPHPerKaigi 2020が開催されます! ラク スからは3名のエンジニアが登壇することとなりました! また、Silverスポンサーとしてイベント協賛をさせていただいております。 イベント概要 日時:2020 年 2 月 9 日 (日) ~ 11 日 (火) 会場: 練馬区 立 区民・産業プラザ Coconeri ホール( 練馬駅 から徒歩1分) 公式 HP: https://phperkaigi.jp/2020/ ハッシュタグ : #phperkaigi phperkaigi.jp セッションのご紹介 セッション内容とエンジニア3名からのコメントをご紹介します!  やなせ たかし/PHPerがこれから「型」とお付き合いしていくために(30分 トーク ) 日時:2 月 11 日 (火) 11:25 場所:Track A コメント: PHP 界隈でも最近何かと話題に上がる型システムのお話をします。   ・型システム でできること   ・動的型付き言語と静的型付き言語   ・ PHP と型 という内容を予定しています。 fortee.jp 加納悠史/ RFC の歩き方(LT) 日時:2 月 11 日 (火) 15:45 場所:Track A コメント: せっかく東京まで行くので、自身の発表含め最後まで楽しもうと思います。 発表では、興味を持った人でないと近寄りがたい、 PHP の RFC について紹介します。 fortee.jp MasaKu/PHPerKaigi2019への参加がきっかけで社内勉強会の主催するようになった話(LT) 日時:2 月 11 日 (火) 15:50 場所:Track A コメント: 昨年開催された PHPerkaigi2019 に参加させていただいた時から、「次回こそは登壇したい!」と思っていたので、CfPが採択された時は嬉しかったです。 良い発表ができるように、しっかりと準備して登壇に向かいたいと思います。 fortee.jp PHPerチャレンジ また、イベント中にはPHPerチャレンジという企画が開催されます。 会場や関連サイトに散らばった  #任意の文字列  形式のPHPer トーク ンを探して合計スコアを競う、というものです。 blog.phperkaigi.jp 本ブログを読んでいただいた皆様には、 ラク スからのPHPer トーク ンを受け取っていただければと思います! ラク スのPHPer トーク ンはこちらです! ↓ #RAKUSMeetup2020 それでは皆様、当日は弊社エンジニア陣の登壇にご期待ください! itoken1013でした!
こんにちは。昨年12月に入社しました。 logy0704です。 私の所属しているチームでは、 Java 開発においてメインの IDE として Intellij を使用しています。 私自身も Intellij を使い始めてから約半年ほど経過し、基本的な機能は使えるようになりました。 一方で、「今まであまり使ってこなかったけど、実はもっと便利な機能があるのでは?」と思い、 改めて公式ドキュメントを読んで知らない機能を探してみることにしました。 個人的に初めて目にした機能 Hippie completion Dependency structure matrix(Ultimate版のみ) Compare with clipboard Paste from history Check RegExp Shelves Analyze Java Stream operations 改めて公式ドキュメントを読んでみて 個人的に初めて目にした機能 Hippie completion 公式ドキュメント basic complitionやsmart completionは1ファイルで1回以上は必ず使うような必須機能ですが、 この機能を利用されたことのある方は少ないのではないでしょうか。 この機能では、今開いているファイルのテキストを分析し、単語の提案を行ってくれます。 Hippie completion 単なるコピーでは対応しきれないような、繰り返し登場する単語の入力補助に役立ちそうです。 Dependency structure matrix(Ultimate版のみ) 公式ドキュメント 依存関係をマトリクス形式で可視化することができます。 アーキテク トロール の方が、プロジェクトの分析を行う際のインプットとして利用できるのではないでしょうか。 Compare with clipboard 公式ドキュメント 予め クリップボード にコピーしておいたテキストと選択範囲のdiffをとることができます。 ファイル単位の比較だと余計なノイズが混じってしまうときに使えそうです。 compare with clipboard Paste from history 公式ドキュメント 直前にコピーしたものだけでなく履歴を遡って貼り付けを行うことができます。 同じような機能がWindows10でもOctober 2018 Updateから利用できるようになり、少し話題になりました。 Check RegExp 公式ドキュメント 正規表現 のテストができます。 目視だけでは確認の難しい 正規表現 を IDE 上で簡単にチェックできるのは非常に便利ですね。 Shelves 公式ドキュメント 作業中のファイルを一時的に退避させることができます。 git stashとよく似ていますが、退避、復元できる単位などに違いがあります。 Analyze Java Stream operations 公式ドキュメント StreamAPIの デバッグ を補助してくれる プラグイン です。 streamの中身の状態を可視化してくれるため、視覚的にもわかりやすい デバッグ が可能です。 改めて公式ドキュメントを読んでみて IntelliJ IDEA の公式ドキュメントをじっくり読んだのはこれが初めてでした。 それまではつまみ食い的に、都度、機能について検索していました。 しかし、一度全体に目を通しておくと、知らなかった機能に出会えたり、 その時は使わなくとも、別のタイミングで役に立つ機能の存在を思い出すこともあるかと思います。 今回は IDE が対象でしたが、普段利用している フレームワーク などにも同じことが言えるはずです。 皆さんも利用している製品の公式ドキュメントを一読すると、何か新しい発見が得られるかもしれません。
こんにちは。新卒2年目のy_kwmtです。今回は業務で取り扱っているChart.jsについて少し学習したので、 紹介していきたいと思います。 Chart.jsとは 折れ線グラフを描画する 棒グラフを描画する おわりに 参考にしたサイト Chart.jsとは グラフを簡単に描くことができる Javascript のライブラリです。 グラフは HTML5 の Canvas を使って描画することができます。 描画できるグラフ一覧 折れ線グラフ 棒グラフ レーダーチャート 円グラフ 散布図 公式サイト www.chartjs.org 公式ドキュメント www.chartjs.org 折れ線グラフを描画する 1/27~2/2の大阪の予想最高気温と予想最低気温をグラフにまとめてみました。 以下は ソースコード と実際に表示される画面です。 <!DOCTYPE html> < html lang = "ja" > < head > < meta charset = "utf-8" >   < title > グラフ </ title > </ head > < body > < h1 > 折れ線グラフ </ h1 > < canvas id = "graph" ></ canvas > < script src = "https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.js" ></ script > <!-- Chart.js読み込み --> < script > var ctx = document .getElementById ( "graph" ) ; var myLineChart = new Chart ( ctx, { type: 'line' , // 表示するグラフのタイプ data: { labels: [ '1月27日' , '1月28日' , '1月29日' , '1月30日' , '1月31日' , '2月1日' , '2月2日' ] , // 横軸 datasets: [ { label: '最高気温' , // 凡例 data: [ 11 , 17 , 14 , 12 , 9 , 10 , 11 ] , borderColor: "rgba(255,0,0,1)" , // グラフの色 backgroundColor: "rgba(0,0,0,0)" // 塗りつぶしなし } , { label: '最低気温' , // 凡例 data: [ 9 , 10 , 7 , 6 , 4 , 3 , 4 ] , borderColor: "rgba(0,0,255,1)" , // グラフの色 backgroundColor: "rgba(0,0,0,0)" // 塗りつぶしなし } ] , } , options: { title: { display: true , text: '気温(1月27日~2月2日)' // タイトル } , elements: { line: { tension: 0 , // ベジェ曲線を無効にする } } , scales: { // 軸設定 yAxes: [{ // y軸設定 ticks: { suggestedMax: 20 , // 最高値 suggestedMin: 0 , // 最低値 stepSize: 5 , // 間隔 callback: function ( value, index, values ) { return value + '度' } } }] } , } } ) ; </ script > </ body > </ html > 棒グラフを描画する 架空の店の売り上げをグラフにまとめてみました。 以下は ソースコード と実際に表示される画面です。 <!DOCTYPE html> < html lang = "ja" > < head > < meta charset = "utf-8" > </ head > < body > < h1 > 棒グラフ </ h1 > < canvas id = "graph" ></ canvas > < script src = "https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.js" ></ script > <!-- Chart.js読み込み --> < script > var ctx = document .getElementById ( "graph" ) ; var myLineChart = new Chart ( ctx, { type: 'bar' , // 表示するグラフのタイプ data: { labels: [ '1月27日' , '1月28日' , '1月29日' , '1月30日' , '1月31日' , '2月1日' , '2月2日' ] , // 横軸 datasets: [ { label: 'A店 売上高' , // 凡例 data: [ 200 , 190 , 160 , 195 , 215 , 180 , 170 ] , backgroundColor: "rgba(255,255,102,1)" // グラフの塗りつぶし } , { label: 'B店 売上高' , // 凡例 data: [ 160 , 150 , 130 , 170 , 155 , 140 , 170 ] , backgroundColor: "rgba(102,255,204,1)" // グラフの塗りつぶし } , { label: 'C店 売上高' , // 凡例 data: [ 120 , 130 , 135 , 115 , 150 , 130 , 120 ] , backgroundColor: "rgba(102,204,255,1)" // グラフの塗りつぶし } ] } , options: { title: { display: true , text: '支店別 売上高' // タイトル } , scales: { // 軸設定 yAxes: [{ // y軸設定 ticks: { suggestedMax: 240 , // 最高値 suggestedMin: 100 , // 最低値 stepSize: 30 , // 間隔 callback: function ( value, index, values ) { return value + '万円' } } }] } , } } ) ; </ script > </ body > </ html > おわりに 今回はChart.jsについて紹介させていただきました。 学習、資料作成の時間をあまりとることができず、今回は折れ線グラフと棒グラフのみの紹介となりました。 次回はグラフの表示非表示の切り替えなどグラフに対する操作をしたいと思っています。 参考にしたサイト liginc.co.jp qiita.com
はじめに Pythonの環境 実際に解いてみる RL回路 RC回路 さいごに はじめに こんにちは、crowd_kです。 プログラムを本格的に触り始めて、1年弱が経ちました。 というのも、私は「電気電子学科」出身であるためプログラミングは授業の一環でほんの少し触った程度しかありませんでした。 しかし、そんな授業で" Python "を少しだけ学んだことがあります。 内容は、" Python "を使って確率統計を解くというものでした。 紙を使って手計算すると、1問とくのに何十分もかけ、A4 の紙を1枚使い切ったり と大変だったものが" Python "を使って解くと簡単にあっさりと解けてしまい、とても驚いた記憶があります。 当時、「確率統計よりも厄介な(と感じる)、電気回路や電磁気を" Python "を使って解くことができたら便利ではないか」と思ったことがあります。 しかし、就活や卒業研究・論文 等で忙しかったため、実際にトライすることはありませんでした。 ふとそんなことを思い出し、" Python "の勉強になるのではと思ったので 簡単な電気回路を" Python "を使って解いて記事にまとめてみました。 Python の環境 まずは、 Python のインストールです。 「これから Python を勉強するなら3系が良い」という記事を多く見たので、3系を選択しました。 また、当時 Python を jupyter notebook で動かしていたので、そちらもあわせてインストール、 また同時に、 sympy もインストールしました。 pip install jupyter --user pip install sympy --user コマンドプロンプト で jupyter notebook と入力すれば、ブラウザで jupyter notebook が立ち上がります。 これでひとまず、準備は完了です。 実際に解いてみる まずはじめに、先ほどインストールした sympy をインポートしておきます。 import sympy as sym 今回はRL回路とRC回路の過渡応答について解いてみたいと思います。 RL回路とは、抵抗(R)とコイル(L)でできた電気回路のことで、RC回路は抵抗と コンデンサ ー(C)でできた回路のことです。 RL回路 まずは、変数を定義します。 変数の宣言は、 sympy.symbols で下のように定義できるようです。 R, L, t, V = sym.symbols( "R L t V" ) ここで、R=抵抗[Ω]、L=コイル[H]、t=時間[s]、V=電圧[V] を表します。 また、 sympy.Function 関数も定義することができるようです。 i = sym.Function( 'i' ) i=電流[A]です。 上記は、電流iは時間tによって変化することを表します。 上記の回路を解いていこうと思います。 一般的に以下のような式で表されます。 これを" python "を使って表していきたいと思います。 抵抗の電圧を表す式は単純で、以下のようになります。(すごく直感的に書くことができるので、楽です) R*i(t) 次に、コイルでの電圧ですが、Lと電流i(t)を時間tで 微分 したものの積で表されています。 sympy において 微分 は、 sympy.diff() と表すことができるので、 L*i(t).diff(t, 1 ) となります。 これらを使うと、RL回路の回路方程式は以下で表すことができることがわかります。 eq1 = sym.Eq(R*i(t) + L*i(t).diff(t, 1 ), V) eq1 について出力してみたら、下のようにうまくいきました。 今回は、R = 100、L = 100, V = 100000 として、解きたいと思います。(値は適当です) eq1 = sym.Eq( 100 *i(t) + 100 *i(t).diff(t, 1 ), 100000 ) 方程式を解くには、 sympy.solve を使います。 また、 微分方程式 を解く上で必要な初期値を引数として渡すことで、それを考慮した計算をしてくれるみたいです。(非常に便利) 今回は、t = 0のとき、(回路の電源を ON にする直前)の電流を 0 とします。 ans1 = sym.dsolve(eq1, ics = {i( 0 ): 0 }) 結果を出力すると、以下の式が得られました これで、解き終わりました。 これが何を表しているのか、グラフに書いてわかりやすくしようと思います。 from sympy.plotting import plot で、 plot を使って、表示してみます。 plot( 1000 - 1000 *exp(-t),(t, 0 , 10 )) 上のような結果が得られました。 i(t)は時間経過とともに徐々に1000[A]に近づいている(すぐには立ち上がらない)のがわかります。 抵抗のみなら、電源をONにしたと同時に電気が流れますが、コイルを挟むことで、ゆっくり立ち上がるようになります。 これは、コイルに流れる電流の変化したとき、その向きに対して逆向きの力を加えようとする性質からで、正しい答えが導き出せたと思います。 RC回路 同様に、RC回路を解いてみようと思います。 まずは、変数と関数の宣言です。 R, C, t, V = sym.symbols( "R C t V" ) i = sym.Function( 'i' ) R=抵抗[Ω]、C= コンデンサ ー[F]、t=時間[s]、V=電圧[V] としています。 RC回路の場合、上記のような式になります。 抵抗の電圧を示す式に関しては、RL回路と同様の考え方ができます。 しかし、 コンデンサ ーはコイルとは異となります。 コンデンサ ーの電圧は、Cの逆数と、電流i(t)をtで 積分 したものの積で表すことができます。 sympy では、 積分 を sympy.integrate と表すことができるので、 eq2 = sym.Eq(R*i(t) + sym.integrate( 1 /C * i(t), t), V) で、RC回路の回路方程式を表すことができます。 積分 がいると面倒なので、( この状態の方程式を解く方法がわからなかった )ひと工夫して解こうと思います。 それは、i(t)をtで 積分 したものを新たにq(t)として、解く方法です。 裏を返すと、以下のようにもなります。 これらを使うと、回路方程式は以下のようになりRL回路と同様に 微分 を含めた回路方程式になります。 これを、コードで書き直したものが下のものになります。 eq2 = sym.Eq(R*q(t).diff(t, 1 ) + 1 /C*q(t), V) これなら、RL回路と同様に方程式を解いてくれそうです。 R = 100、C = 0.01, V = 100 とし、初期条件にt=0のときのqを0に(スイッチを入れる前は電流が流れていないこととし、総 電荷 量も 0 になる)を当てはめると eq2 = sym.Eq( 100 *q(t).diff(t, 1 ) + 1 / 0.01 *q(t), 100 ) ans2 = sym.dsolve(eq2, ics = {q( 0 ): 0 }) となります。 ans2の実際の出力結果がこちら。 この答えは、i(t)をtで 積分 したq(t)を表しています。 i(t)に戻すために、両辺をtで 微分 します。 ans2_i = ( 1.0 - 1.0 *exp(- 1.0 *t)).diff(t, 1 )) 同様に、グラフに表してみたいと思います。 from sympy.plotting import plot plot(ans2_i, (t, 0 , 10 )) RC回路における電流i(t)の時間変化を表すグラフです。 立ち上がりは抵抗のみのときのように一瞬で立ち上がりますが、徐々に衰退しているのがわかります。 RL回路とは逆に時間経過とともに電流は流れなくなります。 コンデンサ ーは 電荷 をため込む性質(充電バッテリーのように)があります。 時間経過とともに電気をため込み、満タンになると電気が通らなくなります。 それがグラフで読み取ることができたので、こちらも正しい結果であると思います。 さいごに 本当ならこの流れでRLC回路も解いてみたかったのですが、解くことができませんでした。 積分 と 微分 が両方混ざった回路方程式になります。 なので、「 積分 を含んだ方程式を解く」または「二回 微分 を含む方程式を解く」 ことができる必要があります。 また、ベクトルの 内積 や 外積 、線 積分 や面 積分 といった計算が中心になる電磁気も、解けるようになったら面白そうです。 まだまだ勉強不足だと思うので、試行錯誤して今後チャレンジしていきたいです。 エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ カジュアル面談お申込みフォーム どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。 以下フォームよりお申込みください。 forms.gle イベント情報 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! rakus.connpass.com
あけましておめでとうございます!新卒1年目のrs_chankoです。 今回は Xcode を触ってみた話をしたいと思います。 はじめに Xcodeの所感 Swiftの所感 おわりに はじめに 就職してもう少しで一年、配属されて半年が経ちました。 自分のチームではアプリの開発も行っているのですが、 いかんせんあまり勤勉でなかった私は学生時代 Eclipse で Java を扱うのがほとんどでした…。 そこでこれからやるであろう アプリ開発 についてどうやって学習しようか考えていたのですが、 触ってみないことには始まらない!と思い立ち まずは Xcode とSwiftに慣れるためにサンプルプログラムを組んでみることにしました! ↓こちらが参考にしたサイトです。 developer.apple.com こちらは Apple 公式の チュートリアル 用ドキュメントです。 簡単な話、開発環境さえあればコピペぺたぺたすればアプリができてしまいます。 なので今回は実装方法などよりも、 GUI にあまり触れたことのない初心者が触ってみた感想について書いていこうと思います。 Xcode の所感 ストーリーボードによる直感的な操作 こちらが実際に作成したアプリの画面です。 これがなかなか直感的で分かりやすい。( GUI だしそれはそう) これを実行すると… こんな感じでシミュレータが起動します。 そのまま実際に動かした時の挙動を再現できるのも便利でした。 エディタの右側のメニュー上でUIパーツのサイズや配置場所の指定や、 他機能との接続をすることで、自動的に ソースコード が書き変わります。 画面を作成する段階で私は 全くSwiftを理解していませんでした が簡単に画面を作ることができました。 簡単で画面遷移があまり多くないアプリであればこのように直感的に操作ができると作ってみたくなりますね。 Unit Test Xcode は、クラス作成時にUnit Testのターゲットに選択するかのプロパティが存在します。 それさえ選択しておけば、 Java のように インスタンス 化したり…のような操作をせずに、 Testクラス内でクラス名.メソッドを呼ぶだけでテストを実行することができます。 こちらが実際に使ったメソッドです。 // MARK : Meal Class Tests // Confirm that the Meal initializer returns a Meal object when passed valid parameters. func testMealInitializationSucceeds () { // Zero rating let zeroRatingMeal = Meal. init (name : "Zero" , photo : nil , rating : 0 ) XCTAssertNotNil(zeroRatingMeal) // Highest positive rating let positiveRatingMeal = Meal. init (name : "Positive" , photo : nil , rating : 5 ) XCTAssertNotNil(positiveRatingMeal) } このように、簡単にテストケースを作成することができます。 お気軽にUnit Testができるのはとてもありがたいです。 戻るや確定のようなsubmit系ボタン こちらのような Cancel や Save のようなボタンは iOS のアプリでよく見かけますね。 こちらもSwiftのコードを書かなくても実装することができます。 Bar Button Item を使用して、属性タブのSystem Itemを変更することで挙動を選ぶことができます。 他の言語では○○に遷移するのような書き方をしていたので革新的な気持ちになりました! Swiftの所感 今時の言語 Swiftの特徴は 型推論 がされるところです。 Java でもJava10から 型推論 が導入されていますが、 Java8を使用している筆者からすると扱いやすくもあり扱いにくくもありと感じました。 コードはすっきりするものの、突如渡されたコードの変数の型を理解するためにコードを読まないといけないのか…とも感じました。 インタラクティブ 今回サンプルアプリの作成では使用しなかったのですが、 Xcode でSwiftのコードを書く際に Playgraund という機能を使うことができます。 このようにリアルタイムで コンパイル をして実行結果を表示してくれる機能があります。 実際に求めている結果が表示されているのかが確認できてとても便利です。 おわりに ただの感想文になってしまいましたが、 Xcode 、Swiftの所感でした。 今後は業務の開発でも触れていく(予定)なので、 プライベートで自分で何かしら開発をしてそれについて書けたらなと思います。 それではまたの機会に。 エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ カジュアル面談お申込みフォーム どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。 以下フォームよりお申込みください。 forms.gle イベント情報 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! rakus.connpass.com
こんにちは、新卒の mako _makokです。 今回はGo未経験者が外部の API を叩いてみた話になります。 はじめに この記事でやること 型を作る リクエスト connpass APIを叩いてみる 実行結果 最後に はじめに 自分でカスタマイズしたクエリを使用して勉強会情報を取得したいと考えました。 普段はこういったツールは個人的に Python で書くことが多いのですが、ある程度使い慣れた言語でリク エス トを投げてパースするだけだとすぐに実装が終わってしまうので、 勉強がてら興味があったGoで実装してみました。 本日はGoで 1. connpass API を叩き 2. レスポンスを構造体に詰め 3. 出力 するまでの手順や使用したツールについてお話ししようと思います。 この記事でやること やること レスポンスの json に対応した型の作成 httpクライアントの生成からGETリク エス トを送る Json を定義した型に変換する 型を作る 今回は以下のような型を定義しました。 package types import ( "time" ) type RequestParam struct { EventID int Keyword [] string KeywordOR [] string YM [] int YMD [] int NickName [] string OwnerNickname [] string SeriesID int Start int Order int Count int Format string } type ResultSet struct { ResultsReturned int `json:"results_returned"` Events []Event `json:"events"` ResultsStart int `json:"results_start"` ResultsAvailable int `json:"results_available"` } type Event struct { EventURL string `json:"event_url"` EventTypes string `json:"event_type"` OwnerNickname string `json:"owner_nickname"` Series Series `json:"series"` UpdatedAt time.Time `json:"updated_at"` Lat string `json:"lat"` StartedAt time.Time `json:"started_at"` HashTag string `json:"hash_tag"` Title string `json:"title"` EventID int `json:"event_id"` Lon string `json:"lon"` Waiting int `json:"waiting"` Limit int `json:"limit"` OwnerID int `json:"owner_id"` OwnerDisplayName string `json:"owner_display_name"` Description string `json:"description"` Address string `json:"address"` Catch string `json:"catch"` Accepted int `json:"accepted"` EndedAt time.Time `json:"ended_at"` Place string `json:"place"` } type Series struct { URL string `json:"url"` ID int `json:"id"` Title string `json:"title"` } レスポンスの型を書くのは単純作業ですし、タイプ量も少なくないので地味に面倒な作業ですが、Goの場合以下のツールで爆速で書くことができました。 JSON-to-Go: Convert JSON to Go instantly json を対応したstructとタグを作成してくれます。 今回の場合ですと、 https://connpass.com/api/v1/event/? keyword =python | jq ' . ' などして、整形した json をコピペするだけでtypeを生成してくれます。 JsonToGo リク エス ト ちょっとしたGETをするのであれば http.Get で良いですが、今回は勉強のためClientの設定なども行います。 標準ライブラリの net/http を使用します。 package httpwrapper import ( "io" "io/ioutil" "net/http" "net/url" "time" ) func DoRequest(method, path string , values url.Values, body io.Reader ) ([] byte , error ) { client := &http.Client { Timeout: 20 * time.Second, } req, err := http.NewRequest(method, path, body) if err != nil { return nil , err } req.URL.RawQuery = values.Encode(); resp, err := client.Do(req) if err != nil { return nil , err } defer resp.Body.Close() data, err := ioutil.ReadAll(resp.Body) if err != nil { return nil , err } return data, nil } 標準ライブラリしか使っていませんが、すごくすっきり書けて気持ちがいいです。 順番に説明していきます。すっきりしすぎてあまり説明することが無いような気がしますが、それも Golang の魅力かなと思いました。 タイムアウト 値の設定 client := &http.Client { Timeout: 20 * time.Second, } タイムアウト 値を20秒に設定します。 リク エス トの生成 req, err := http.NewRequest(method, path, body) コンスト ラク タを使用してRequestオブジェクトを生成しています。 パラメータの設定 req.URL.RawQuery = values.Encode(); values はmap型です。パラメータと値が マッピング されており、 Values.Encode() でURL エンコード を行います。 リク エス トの実行 resp, err := client.Do(req) (略) defer resp.Body.Close() defer を使用すると遅延実行することができます。 今回の場合ですと、DoRequest()が実行され終了する間際に resp.Body.Close() が走り、クローズ処理が行われます。 読み書きできる形にする data, err := ioutil.ReadAll(resp.Body) ioutil.ReadAll でレスポンスボディをバイトのスライスにして返します。 connpass API を叩いてみる package main import ( "fmt" "encoding/json" "log" "strconv" "net/url" "./httpwrapper" "./types" ) func main() { const endpoint = "https://connpass.com/api/v1/event/" keywordor := [] string { "JavaScript" , "TypeScript" , "Go" , "Java" , "Kotlin" , "Vue" , "React" , "Nuxt" , "Next" , "Spring Boot" } keyword := [] string { "東京" } count := 30 param := types.RequestParam{Keyword: keyword, KeywordOR: keywordor, Count: count} values := url.Values{ "keyword" : keyword, "keywordor" : param.KeywordOR, "count" : {strconv.Itoa(count)}} data, err := httpwrapper.DoRequest( "GET" , endpoint, values, nil ) if err != nil { log.Fatal(err) } var rs types.ResultSet if err := json.Unmarshal(data, &rs); err != nil { log.Fatal(err) } for i, event := range rs.Events { fmt.Println(strconv.Itoa(i + 1 ) + " Title: " + event.Series.Title) } } リク エス トを実行します。 結果を取得できた後は encoding/json の json .Unmarshalメソッド でパースできます。 var rs types.ResultSet if err := json.Unmarshal(data, &rs); err != nil { log.Fatal(err) } だいたいの json がこれでパースできます。 *1 なお、構造体を Json にパースする場合は json .Marshal を使用します。 実行結果 出力結果 最後に 今回はGoでconnpass API を叩いてみました。 今後はリク エス トの送信だけではなく、 RESTな API の作成したり、テスト等を書いて拡充していきたいと思います。 *1 : json の value に複数の型が混じった配列があるとエラーになります
はじめまして。 @penguin_no_045 です。 東京で12/1に開催された PHP Conference Japan 2019 でLT登壇してきました。 また、株式会社 ラク スは PHP Conference Japan 2019 のブロンズスポンサーとして協賛しています。 イベント概要 日時 : 2019年12月1日(日) 会場 : 東京都 大田区 南蒲田 1丁目20-20 大田区産業プラザ PiO 公式HP : https://phpcon.php.gr.jp/2019/ 登壇 社内最長老のシステムに PHPUnit で立ち向かう方法 speakerdeck.com 発表の要旨は、 レガシーシステム の PHP バージョンアップを PHPUnit でなんとかした というものです。いわゆるレガシーネタですが、 少ないリソースでどうやって大きなコードをテストしていくのかということについてお話しました。内容は発表資料を参照いただくことにして実際に行ったことを振り返ると、それにしてもかなり極端な手法を採用したように思います。 なぜこんな手法をとれたのかというと、今回の PHP バージョンアップによって文法的に正しい状態が維持されているかどうかだけに責務を絞ったからです。それだけが目的だったので、モックでもなんでも使用してとにかく カバレッジ を上げるという戦術を取ることができました。しかし品質担保の責務がもしあるならば、初めからこの手法は破綻しているでしょう。 お礼 発表準備に際してさまざまな方に資料のレビューや発表練習にお付き合いいただきました。 この場を借りてお礼を言いたいと思います。ありがとうございました! 印象に残ったセッション 改善失敗から学ぶ、レガシープロダクトに立ち向かうチーム作り。 speakerdeck.com まさに自分たちが通るであろう道を見せられた気がしました。改善を続けていく中で起こったことが紹介されています。実際、 カイゼン にチャレンジしたはいいけど、失敗したのでやめてしまった、なんていう話はたくさんあることでしょう。しかし失敗から学ぶことは多いはずですし、成功に結び付けることができればムダにはなりません。 カイゼン を続けているチームがいかに失敗し、その学びから カイゼン を回してきたのかを知ることができるセッションでした。 知見のない技術スタックをプロダクション導入するエンジニアの導入戦略 speakerdeck.com いつの日か既存サービスと同じ技術スタックが最適ではない機能やサービスを開発するときがくるかもしれません。このセッションでは、まさにそのような場面において組織の不安と向き合い、最適な技術を選定し、開発するために取った戦略を紹介されています。導入実績がない技術スタックには組織としても「不安」がつきまといます。その不安に対して向き合っていくための武器として、テスト・監視・コード検査を挙げ、それらをいかにして活用して、開発をすすめていくか。その実践内容がそれぞれの手法ごとに解説されています。 このセッションでは「知見のない技術スタック」と銘打っていますが、実際に機能選定で知見のない技術スタックを選定候補に上げるためには、別の「寝技」のようなものがあるように思います。また、このセッションで紹介されたプ ラク ティス事態は特別なものというわけではなく、日ごろから実践することでプロダクトの品質に大きく貢献できるのではないかと感じました。 感想 今回、登壇に際してたくさんの「はじめて」がありました。 1000人以上参加するイベントに参加 PHP 関連のイベント参加 登壇すること このようにはじめてづくしであったわりには発表自体はリラックスして行えたのではないかと 自画自賛 しておきます。 カンファレンスでは、 PHP に限らず広い領域のセッションがあったため、広範囲に刺激を受けることができました。 おしらせ PHPerKaigi 2020に登壇します! セッションタイトルは PHPerがこれから「型」とお付き合いしていくために です。 PHP で導入が進む型についてお話します。 プロポーザルは こちら をご覧ください。
こんにちは。新卒1年目エンジニアのrs_shoです。 投稿は3回目になります。 今回は実装の際に気を付けるべき汎用メソッドの落とし穴についてお話ししたいと思います。 はじめに そもそも何に困ったのか 解決するためにどういう案があるのか おわりに 参考資料 はじめに 皆さん、 java でコーディングする時によく使うUtilsの便利なメソッド、コーディングが楽ですよね。 実装する際によくStringUtilsやNumberUtilsなど、色々な汎用メソッドを多用して 楽にコーディングできるので、ついつい使ってしまいがち。。。 そういう僕も良く汎用メソッドを使って実装することが多々ありますが、今回はそのメソッドを使った際に 困ってしまったお話をしようと思います。 そもそも何に困ったのか 僕は今回 org.apache.commons.lang.math.NumberUtils の isNumber を使用して、数値の判定をする部分のコーディングをしていました。 入力された値が数値なのかを判定してくれるメソッドです。 実装していて、実装後のテスト時にあれ?変だな。。。と思いました。 NumberUtils.isNumber() は普通の数値以外に 8進数 16進数 指数表記(科学的表記法) 型修飾子のついた数値 など、通常の数値(10進数)として扱うには、変換が必要な数値まで通してしまうのです。(2進数は文字列判定らしいです) これでは計算などをするためにキャストしたりする時に NumberFormatException などが出て困りますね。。。 解決するためにどういう案があるのか この問題を解決するためには、いくつか案はありましたが、どれが一番正しいのか、かなり迷ってしまいました。 僕の主観でですが、考えた案をメリット・デメリットを含めてお伝えしたいと思います。 * 変換をして変換できなかったらエラーを出す(try-catch文) * メリット * 必要な数値だけ選んで取れるほか、エラーのカスタマイズが容易(数値の型指定やエラーをcatchの中で設定できる) * デメリット * エラーを握りつぶすことになる(実装ではなるべくしない方が望ましい。。。) * try-catch文はパフォーマンスが落ちる(調べた範囲でですが、色々なクラスに遷移するので遅い) * 自分でメソッドを作ってしまう * メリット * 自分で書くので、必要な処理だけ書ける * デメリット * 開発コストがかなりかかる(汎用メソッドを補うため、考慮すべき点が多すぎる) * 考慮漏れがある可能性大(自分でコードを書くため、考慮漏れが発生しやすい) * 正規表現で数値かどうかを判定する * メリット * 正規表現が扱えれば自由度が高い * デメリット * (あくまで主観ですが)可読性が悪い、コードが汚く見える * 判定する文字列が長ければ長いほどパフォーマンスが落ちる 色々調べた結果、どの実装にもメリット・デメリットがあり、実装の内容によりけりって感じですね。。。 ちなみに僕はtry-catchと 正規表現 を使用しました。 考慮漏れを防ぐためにも、ある程度組み合わせたほうが安全だと思います。 おわりに いかがでしたか。僕はこの問題に直面してからコーディングにものすごく時間を使いました。 みなさんのコーディングの助けになれば幸いです。 参考資料 基本的な正規表現一覧 | murashun.jp あえて言うほどではない 数値変換時の型チェック Java編
はじめに はじめまして。新卒1年目のtuq376sです。 気付けば入社してから季節は4つ目。毎日新しい壁にぶつかりながら、それでも随分とわかることが増えたなぁと思うくらいには成長できている気がします。 今回はそんな壁の中から、初めて シェルスクリプト を業務で触った時のことをまとめてみようかと思います。 はじめに 読めそうで読めなかったシェル 学んだこと 特殊パラメータ if文の条件式 testコマンド リダイレクト ファイルディスクリプタ さいごに 読めそうで読めなかったシェル シェルスクリプト に関するタスクを割り振ってもらったのは、少しずつ業務に携わり始めて、普段使っている Java の至極簡単な修正であれば1人でも頑張れるようになり始めたころ。 今まで触れたことがなかったとはいえ、 シェルスクリプト の概要は研修でも学んだし、改修する内容も既存に合わせて分岐を1つ増やすだけだったのでなんとかできそうだと思っていました。 一応新卒1年目とはいえエンジニアの端くれ、実際コードを見てどこをどうすればいいのかはすぐわかったのです。……けれど同時に、読めているのは雰囲気だけだなということにも気づきました。 いくら簡単なタスクとはいえ流石にそんな中途半端ができるわけもなく。ものの30分もしないうちに、まずは基礎の基礎を知ろうと思ったのでした。 学んだこと 特殊パラメータ シェルスクリプト を見てまず思ったのは$が多いということ。眺めていれば ${hghg} は変数で、 $1 や ${10} はこのプログラムへの引数だろうというのは見当がつきました。 けれどいくつか記号と組み合わさっているものについてはわからず、真っ先に調べることに。 どうやら特殊パラメータと呼ばれるもののようで、調べた中から自分でもぱっと理解して使えそうなものから覚えることにしました。 特殊パラメータ 内容 $@ 渡された引数全て。区切り文字は空白 $# 渡された引数の個数 $$ シェルのプロセスID $? フォアグラウンドで最後に終了したコマンドステータスの値 $! バックグラウンドで最後に終了したコマンドプロセスのID よく見る $HOME や $PATH のように予約された変数ということですね。 流石に記号だとどのような意味かは見ただけで推測できないので、わからなくなったら自分でここを見返そうかと思います。 if文の条件式 次にif文。これは雰囲気でも読めてしまうので書き方が違うだけだな……と思っていたのですが。 if [ ${a} -ne ${b} ]; then 処理 fi 条件式の中にコマンドのオプションらしきものを見て、これもわからないとなったわけです。 調べるとどうやらif文の条件式は本来testコマンドを使うようで、 [条件式] はtestコマンドの書き方の1つだとか。 testコマンドについても最低限しか知らなかったため、再度おさらいをすることになりました。 testコマンド 条件を判定し、真偽を返すコマンドです。 test 条件 または [ 条件 ] と表記します。 条件に使用するオプションは数多くありますが、一般的な数値処理と論理処理に関するものは以下になります。 オプション 意味 -eq == (equal) -ne != (not equal) -lt -le -gt > (greater than) -ge >= (greater than or equal) -a && (and) -o || (or) こちらは英語の省略系なので、わかっていれば毎度調べなおすこともなさそうですね。 リダイレクト さてもう1つ、読んでいて全然知らない……となったのはリダイレクトを行っている部分でした。 `コマンド` > ファイル名 2>&1 上記のような表記になじみがなかったのですが、これはファイル ディスクリプタ を利用して、標準出力と 標準エラー出力 を同じファイルに書き込んでいるらしい。 まずファイル ディスクリプタ とはなんだったっけ……ということでこれもまたおさらいしました。 ファイル ディスクリプタ ファイル ディスクリプタ とはOSがファイルを識別するために割り当てる管理番号のことで、各ファイルの名前や属性などが参照できるように結び付けられています。 普段ユーザがこの番号を意識することはありませんが、予約されている番号に関しては時々見かけることがあるようです。 番号 内容 0 標準入力 1 標準出力 2 標準エラー出力 内容を見ると、ああそれかとはなるのですが、普段見かけていないとすぐ忘れてしまいますね……。 これを踏まえてさっきの記述を解釈すると、 `コマンド` > ファイル名 2>&1 コマンドが実行され、標準出力をファイルにリダイレクト (標準出力をするときの ディスクリプタ 番号は省略可) 標準エラー出力 を標準出力へリダイレクト 標準出力はファイルにリダイレクトされているため、 標準エラー出力 もファイルへ書き出される ということのようです。もちろん上書きではなく追記を行う >> についても同じように使うことができます。 さいごに というわけで基本的な最低限を調べた私は、なんとかコードをきちんと理解したうえでタスクをこなすことができたのでした。 今回記事にまとめるにあたって、その時に調べたことをもう一度きちんと調べたのですが、そのおかげで 「読めるようで読めなかったシェル」も「読めないようでちょっとだけ読めるシェル」くらいには親しくなれたような気がしています。 これからも業務で触る機会はそこそこにありそうなので、少しずつ「読める!」と断言できるようになっていきたいなと思います。 そして、動作確認前に改めてコードを読み直してみたら思った以上に改修の必要な範囲が広くて顔を青くしたのはまた別のお話……。
@kawanamiyuu です。この記事は「 ドメイン駆動設計#1 Advent Calendar 2019 」の 6 日目の記事です。 1. はじめに 2. ドメインの依存関係に対するアーキテクチャテスト 2.1. 人事労務管理システムのドメイン 2.2. ドメインの依存関係 2.3. ドメインの依存関係に対するアーキテクチャテスト 3. レイヤーの依存関係に対するアーキテクチャテスト 3.1. シンプルなレイヤーアーキテクチャ 3.2. 依存関係を逆転したレイヤーアーキテクチャ 4. さいごに 1. はじめに 最近、技術イベントやまた社内でも「 ドメイン 駆動設計」や「クリーン アーキテクチャ 」についての話題をこれまでにも増してよく耳にするようになりました。 私も 楽楽労務 という実際のプロダクト開発で 1 年以上、 ドメイン 駆動設計に取り組んできました。 ドメイン 駆動設計 チョットデキル ような気がしてきたころ、このように思いました。 「 ドメイン 駆動設計って、『 オブジェクト指向設計 をちゃんとやる』ってことだよね?」 ドメイン 駆動設計もクリーン アーキテクチャ も、 オブジェクト指向設計 原則のうえに成り立つ設計プ ラク ティスであり、ただ、重要な視点として、 オブジェクト指向設計 原則の適用を検討する対象がクラスだけではありません。もう少し大きな単位、パッケージ・モジュール・レイヤー、まで視野を広げます。 依存関係が注意深く設計され、単一の責任を持ったモジュールやパッケージが、 ドメイン をかたちづくります レイヤーやパッケージの依存関係の逆転により、 ドメイン は自身の関心や責務を逸脱することなく ビジネスロジック の実現に集中できます ドメイン 駆動設計が オブジェクト指向 プログラミングによって実現されるということは、その アーキテクチャ も、私たちが慣れたいつもの方法 ─ ユニットテスト ─ で、テストすることができます。 ソースコード も アーキテクチャ も、一度つくって終わりではありません。プロダクト開発が続くかぎり、常に見直され改善されるべき対象です。 ...... 前置きが長くなりましたが、この記事では 依存関係 という切り口から、 アーキテクチャ の品質を継続的に維持・改善していくための手法として、 ArchUnit ( Java ) による アーキテクチャ テストを紹介します。 github.com ArchUnit って何?については昨年の アドベントカレンダー に投稿しています。 qiita.com 2. ドメイン の依存関係に対する アーキテクチャ テスト 今回は、私が開発を担当している人事 労務管理 システムを例にします。人事 労務管理 システムとは文字通り、企業の人事 労務 担当者の業務を 楽 にするための業務システムです。 このシステムが扱う業務の 1 つである、「従業員の入社関連業務」は以下のようなものです。 会社に従業員が入社したときに、従業員情報(氏名や住所といった個人情報、 基礎年金番号 といった 社会保険 に関する情報、など)を収集する 入社後、社内申請フローにより追加の個人情報が収集され、役所への 社会保険 等の提出書類(届出書という)を作成するための行政手続きフローが開始される 行政手続きフローを進めることで、(複数の)届出書が生成される 2.1. 人事 労務管理 システムの ドメイン 業務 ドメイン の境界が比較的わかりやすく、大きく 4 つに分けられます。 従業員 ドメイン ( employee ) 社内申請 ドメイン ( request ) 行政手続き ドメイン ( procedure ) 届出書 ドメイン ( report ) これらの ドメイン を Java プロジェクトのパッケージとして表現すると以下のようになります。 2.2. ドメイン の依存関係 ドメイン 同士の依存関係は次のとおりです。 「従業員 ドメイン 」(いわゆる 従業員マスタ を含む)は、人事 労務管理 システムという特性上あらゆる ドメイン から参照されます 「社内申請 ドメイン 」は、後続の業務であるの「行政手続き」を知っています 「行政手続き ドメイン 」は、その手続きで必要となる「届出書」を知っています 2.3. ドメイン の依存関係に対する アーキテクチャ テスト ドメイン の依存関係に対する アーキテクチャ テスト(以下の例は一部)は ArchUnit で次のように実装できます。 private static final JavaClasses CLASSES = new ClassFileImporter() .withImportOption(ImportOption.Predefined.DO_NOT_INCLUDE_TESTS) .importPackages( "com.example" ); @Test void 従業員ドメインは他のドメインに依存しない() { noClasses().that().resideInAPackage( "com.example.domain.employee.." ) .should() .dependOnClassesThat( new DescribedPredicate<>( "従業員ドメイン以外のドメイン" ) { @Override public boolean apply(JavaClass input) { if (! input.getPackageName().startsWith( "com.example" )) { // プロジェクト外(サードパーティライブラリ等)への依存はOK return false ; } return ! input.getPackageName().startsWith( "com.example.domain.employee" ); } }) .check(CLASSES); } @Test void 社内申請ドメインは届出書ドメインに依存しない() { noClasses().that().resideInAPackage( "com.example.domain.request.." ) .should() .dependOnClassesThat().resideInAPackage( "com.example.domain.report.." ) .check(CLASSES); } @Test void 行政手続きドメインは社内申請ドメインからのみ依存される() { classes().that().resideInAPackage( "com.example.domain.procedure.." ) .should() .onlyBeAccessed().byAnyPackage( "com.example.domain.request.." ) .check(CLASSES); } 3. レイヤーの依存関係に対する アーキテクチャ テスト ドメイン 駆動設計の文脈でよく登場する アーキテクチャ として、「レイヤー アーキテクチャ 」があります。ArchUnit でレイヤー アーキテクチャ に対するテストは以下のように実装できます。 ※この記事では省略しますが、オニオン アーキテクチャ (ヘキサゴナル アーキテクチャ )に対するテストも ArchUnit で実装できます。興味のある方は User Guide を参照ください。 3.1. シンプルなレイヤー アーキテクチャ 上位の層が下位の層に依存します。 @Test void シンプルなレイヤーアーキテクチャ() { layeredArchitecture() .layer( "ui" ).definedBy( "com.example.presentation.." ) .layer( "app" ).definedBy( "com.example.application.." ) .layer( "domain" ).definedBy( "com.example.domain.." ) .layer( "infra" ).definedBy( "com.example.infrastructure.." ) .whereLayer( "ui" ).mayNotBeAccessedByAnyLayer() .whereLayer( "app" ).mayOnlyBeAccessedByLayers( "ui" ) .whereLayer( "domain" ).mayOnlyBeAccessedByLayers( "ui" , "app" ) .whereLayer( "infra" ).mayOnlyBeAccessedByLayers( "ui" , "app" , "domain" ) .check(CLASSES); } 3.2. 依存関係を逆転したレイヤー アーキテクチャ ドメイン 層とインフラスト ラク チャ層の依存関係(依存の方向)を逆転させることで、 ドメイン 層はどの層にも依存せず、 ドメイン 層に閉じて ビジネスロジック の実現に専念できます。 @Test void 依存関係を逆転したレイヤーアーキテクチャ() { layeredArchitecture() .layer( "ui" ).definedBy( "com.example.presentation.." ) .layer( "app" ).definedBy( "com.example.application.." ) .layer( "domain" ).definedBy( "com.example.domain.." ) .layer( "infra" ).definedBy( "com.example.infrastructure.." ) .whereLayer( "ui" ).mayOnlyBeAccessedByLayers( "infra" ) .whereLayer( "app" ).mayOnlyBeAccessedByLayers( "infra" , "ui" ) .whereLayer( "domain" ).mayOnlyBeAccessedByLayers( "infra" , "app" ) .whereLayer( "infra" ).mayNotBeAccessedByAnyLayer() .check(CLASSES); } 4. さいごに ドメイン 駆動設計とは、特別な 銀の弾丸 的な設計手法ではなく、 オブジェクト指向設計 という基本的かつ重要なプログラミング原則のうえに成り立つ設計プ ラク ティスです クラスだけではなく、レイヤーやモジュール・パッケージといった粒度でも依存関係を注意深く設計し、依存関係を管理していくことが重要で、 ソースコード も アーキテクチャ も一度つくって終わりではなく、常に見直され改善されるべき対象であり、 アーキテクチャ も継続的にテストすることができます ドメイン 駆動設計、やっていきましょう! ...... tech-blog.rakus.co.jp
こんにちは、 @whiteFox_73 です。東京で11/30~12/1に開催された JSConf JP に登壇してきました。 また、株式会社 ラク スはJSConf JPの BRONZE スポンサーとしてイベントに協賛いたしました。 イベント概要 日時:2019年11月30日(土)~ 2019年12月1日(日) 会場:アーツ千代田 3331 公式 HP: https://jsconf.jp/2019/ jsconf.jp 登壇 正攻法はあるのか!?泥臭く戦ったNode.jsバージョンアップ一部始終(30分セッション) speakerdeck.com 初めての登壇がJSConf JPというのは緊張しましたが、無事発表することが出来ました。 発表内容としては、弊社サービス「 チャットディーラー 」で利用しているNode.jsをメジャーバージョンアップした方法やその際の苦労話を中心にお話しました。 実際の体験談的な発表は比較的少なめだったので、興味持ってもらえるか心配していたんですが、 発表後に Twitter を見たところ、共感してくれるコメントなどがありホッとしております。 全機能テストで複数回サイクル回すのあるよねー 営業日や平日・休日で挙動が異なるシステムなら尚更 この泥臭さ、弊社感あるw #jsconfjp #jsconfjp_b — ちゃんちゃん@雑食エンジニア (@fashioncrazy66) December 1, 2019 今回の発表資料を作るにあたっていくつか苦労したところがありました。 一つ目は当初話そうとしていた内容では30分枠に収める事ができず、資料のボリュームを落とすことになったところ。 ストーリー性を損なわずに削る作業が難しかったですが、一番伝えたかった 泥臭い 作業や、トラブルを経験して Node.jsの知見を得れた というところは伝えられたかと思います。 資料からは省きましたが当初の案では、 負荷試験 の話やNode.jsバージョンアップに伴うアプリ側の改修の話などがありました。 本番の資料は70枚ほどでしたが、延べ150枚ほど作った気がします(笑) 二つ目は発表内容の出来事は1年~半年前の出来事なので思い出すのに苦労したところ。 幸い、トラブルの過程などを自分用にまとめたドキュメントが作ってあったので何とか思い出せました。 やはり、こういった資料を作る際は時間が経つ前に書くべきと反省です。 印象に残ったセッション 興味を惹かれるセッションばかりでした。 参加した中でも特に印象に残ったセッションを中心に紹介します。 JavaScript AST プログラミング: 入門とその1歩先へ jsconf.jp ESLintなどを利用したことはありましたが、内部で使われている JavaScript ASTに関してはどういったものかよく知らなかったので参加しました。 JavaScript ASTは JSON で表現されるということもあり、理解しやすかったです。 ライブコーディングを見るのは初めてでしたが、普通の発表よりも自分ならどうしたいかイメージしやすくわかりやすいと感じました。 セッションを聞いて、チーム内だけのコーディング規約などは JavaScript ASTを利用して書き換えた方が早そうな気がしました。 簡単なものであればすぐ作れそうな所もポイント高い。 他には、自分が頻発させてしまう ケアレスミス とかにも利用できそうだなと。(笑) Streams API をちゃんと理解する speakerdeck.com セッションの最後の方に話されていましたが、この辺りの技術は今後重要になりそうです。 5Gなど通信技術が発達し大容量データのやり取りが増えそうなので、データを分割しないとクライアント側が耐えきれない…という状況は容易に想像ができる。 図が凄く見やすかったので見習いたい!! Minimum Hands-on Node.js speakerdeck.com 今までNode.jsは独学でやってきたのでhandsonに興味があったので参加しました。また、社内でこれからNode.jsを学習する人がいたので参考になればという思いもありました。 全体を通して凄く分かりやすかったので社内でも紹介したいと思います。 標準モジュールの学習するおススメの順番はNode.jsを触り始めた頃に知りたかった!!(笑) 途中で他社がどのように運用しているかなどの話を聞ける場面があり、今まで情報を得る機会が少なかったのでいろいろと勉強になりました。 handsonの 進捗管理 に調整さんを利用する発想はなかったので、面白い発見です。 感想 様々な方に発表練習や資料作成にお付き合い頂いたおかげで本番の発表に漕ぎつける事ができました。 ご協力いただいた皆様、本当にありがとうございました!! イベント中は技術的な質問をすることやされることが多々ありとても刺激になりました。 一つ後悔しているのは、海外のエンジニアと話ができる機会なのに英語が苦手であまり話せなかった事です…。 次の機会があれば話せるように頑張ります。(笑) 最後に、JSConf JPに参加したことで多くのエンジニアと知り合う事や貴重な体験ができました。 参加させてくれた会社とJSConf JPの運営の方々に感謝申し上げます。 おまけ 凄い共感して撮ってしまった。
はじめに はじめまして、新卒1年目エンジニアのthree_yagiです。 入社から早くも8か月が過ぎ、ようやく業務にも慣れてきました。業務において Linux を操作することが度々あり、はじめは何か操作しようとする度にコマンドなどを調べていましたが、最近は基本的な操作なら検索サイトを頼らなくても出来るようになってきました。 Linux の パーミッション については入社後の研修で Linux のマニュアルを読んで基礎から学習しました。最近、その パーミッション を意識する機会があったので、自身の復習も兼ねて基本をまとめてみました。また、意外と見落としがちなファイル削除時の パーミッション の注意点について紹介します。 目次 はじめに 目次 パーミッションとは パーミッションの見方 ファイルの削除権限 スティッキービット まとめ パーミッション とは Linux ではファイルと ディレクト リに対して、誰がどういった操作ができるかの権限を設定することができます。この設定を パーミッション といいます。 パーミッション は、「ファイルの所有者」「所有グループ」「その他ユーザー」という3種のユーザータイプに対してそれぞれ「読み取り」「書き込み」「実行」の権限を割り当てることができます。 パーミッション の見方 では実際に ls -l コマンドで パーミッション を確認してみましょう。 $ ls -l -rw-r--r-- 1 user group 0 12月 3 14:28 2019 test drwxr-xr-x 2 user group 4096 12月 3 14:28 2019 test_dir それぞれの行の先頭の10文字がそのファイル/ ディレクト リの パーミッション を表します。 はじめの1文字:ファイルの種別 "d": ディレクト リ "-":ファイル 2~10文字目:それぞれのユーザタイプにおける権限 最初の3文字分がファイルの所有者の権限 次の3文字が所有グループのユーザーの権限 最後の3文字がその他ユーザーに対する権限 権限の記号の意味と、権限を持つユーザーがファイル/ ディレクト リに対して行える操作を以下にまとめます。 記号 意味 ファイル ディレクト リ r 読み込み ファイルの内容を表示 ディレクト リ内のリスト表示 w 書き込み ファイルの上書き、変更 ディレクト リ内にファイル作成、削除 x 実行 実行ファイルの実行 ディレクト リ内に移動 上の実行例では、"test"ファイルは所有ユーザーはファイルを表示した上で編集を行えますが、所有グループのユーザーやそれ以外のユーザーはファイルの表示しかできません。 このように パーミッション を設定することでユーザーのタイプ別に操作を制限することができます。 次にファイル削除における パーミッション の注意点を説明します。 ファイルの削除権限 たとえば以下のような ディレクト リがあったとします。 drwxrwxrwx 2 user group 4096 12月 3 14:28 2019 free_dir すべてのユーザーが「読み取り」「書き込み」「実行」が可能な ディレクト リですね。 ではこの ディレクト リ内に以下のファイルが存在するとき、「その他のユーザー」はこのファイルを削除できるでしょうか。 -rw-r-x--- 1 user group 128 12月 3 14:28 2019 testfile 「その他のユーザー」はこのファイルに対して何の権限も持ちません。そのため削除できない。と考えてしまいそうになりますが、実際は削除できてしまいます。 上のrwxの表にでも示しているように、ファイルの削除は ディレクト リの書き込み権限で制御されています。そのため、 ディレクト リの書き込み権限を持つユーザーはファイルに対する権限を何も持たなくても削除ができてしまうのです。 ディレクト リの書き込み権限をなくせば削除を制限することができますが、同時にファイルの新規作成もできなくなってしまいます。 スティッキービット では、ファイルの作成を許可しつつ、削除を制限したいときはどうすればよいでしょうか。 その場合は、スティッキービットを使用します。 ディレクト リにスティッキービットを付与すると、その ディレクト リ内のファイルは所有者以外が削除できなくなります。 スティッキービットは以下のコマンドで付与できます。 $ chmod +t free_dir スティッキービットが付与された ディレクト リは ls -l コマンドで以下のように表示されます。 drwxrwxrwxt 2 user group 128 12月 3 16:42 2019 execute_dir パーミッション の最後に"t"が追加されていることがおわかりでしょうか。 この記号がスティッキービットを表しています。 この状態で所有者以外のユーザーが ディレクト リ内のファイルを削除しようとすると、下記のようなメッセージが表示され、ファイルが削除できなくなっていることがわかります。 $ rm testfile rm: remove write-protected 通常の空ファイル `testfile'? y rm: cannot remove `testfile': 許可されていない操作です ファイルの削除を制限する機会はそれなりにあると思うので、スティッキービットの設定方法は覚えておきましょう。 まとめ Linux における パーミッション とその注意点についてまとめてみました。 パーミッション の変更方法やumaskなど、まだまだまとめておきたいことはありますが、キリがなさそうなのでいったんここで締めようと思います。 パーミッション は Linux の基礎的な知識ではありますが、 Linux 上での様々な操作や処理にかかわってきます。 プログラムを実行したらエラーが出たけど原因がわからない…というときは一度 パーミッション をチェックしてみてもよいかもしれません。 エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ カジュアル面談お申込みフォーム どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。 以下フォームよりお申込みください。 rakus.hubspotpagebuilder.com ラク スDevelopers登録フォーム https://career-recruit.rakus.co.jp/career_engineer/form_rakusdev/ イベント情報 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! ◆TECH PLAY techplay.jp ◆connpass rakus.connpass.com
id:radiocat です。先日ご紹介したとおり私たちは大阪オフィスで『Web× PHP TechCafe』という新しいイベントをスタートさせました。今回はこの流れに至るまでのコミュニティ運営についてご紹介します。 tech-blog.rakus.co.jp もともとは『もくもく勉強会』としてスタートしたイベントでしたが、様々な試行錯誤や葛藤の末に今の形にたどり着きました。今回はその振り返りと新たなスタートの意味で 「 Web × PHP TechCafe Advent Calendar 2019 」の記事として書くことにしました。同じようなイベントやコミュニティに関わる方々の参考になれば幸いです。 チームの仲間に呼びかけてイベント立ち上げ スタートは2018年のオフィス移転でした。このとき、念願がかなってオフィス内に セミ ナールームとして活用できるスペースを作ってもらうことができました。 tech-blog.rakus.co.jp 特に目指すべきゴールなどは設定せず、ただやってみたいという思いで当時のチームメンバーに声をかけてスタートしました。実際に運営側として取り組んでみると、それまで参加側では気づけなかったことに色々と気づきました。スタートした最初の数ヶ月で当時気づいたことをいくつかご紹介します。 タイトルに大阪・梅田を入れる 我々は connpass を使って参加者を募集しています。人口比率的に東京を中心としたイベントが多いので、大阪・梅田で開催することをなるべくわかるようにしなければ、認知すらしてもらえませんでした。そこでタイトルに「大阪・梅田」という開催場所を入れるようにしました。これは関西や他の地方のコミュニティの多くで実践していることだと思います。 枠数と席の配置を考える 実際の参加者に対して多すぎず、少なすぎない枠を予測して設定するほうが良いとわかりました。余裕を持って確保しすぎるとガラガラな寂しい状態になり、枠を絞りすぎると参加を見送る人が出てくる可能性もあるので、毎回予測を立てながら最低限のスペースや席を確保してスタートし、エントリー状況を見守りながら最終的なスペースや席を決めています。私たちのイベントはただ黙々と勉強するだけではなく、参加者同士の交流も大切にしたいため特に気をつけています。 お菓子を置く 一般的に、食べ物の存在は交流しやすい雰囲気を生み出すとよく言われているので、お菓子を確保してご提供するようにしました。小さくスタートしたこともあり潤沢に準備はできていませんが、よくある懇親会のような大規模なものではないので、もくもく勉強会のお供や参加者の交流に必要な量としてはバランス良く成り立っていると感じています。 次回の募集を開始 毎月1回開催を決めており、気に入ってもらえた参加者のかたには次回も是非参加してもらいたいという思いで、開催当日には必ず次回の募集を開始し、開催を告知しています。 立ち上げ成功、運営体制の強化 約半年間の取り組みの結果、毎回一定の方々に参加してもらえるようになり、社内でも認知されてきたため、各チームからイベント運営のメンバーを選出してもらい正式な体制を作って運営できることになりました。 最初の3ヶ月の参加者数 社内ですでに実施していたMeetupなどの他のイベント運営とも連携して存在意義と活動範囲が拡大しました。 1年でモチベーション低下、マンネリ化 スタートしてから1年後、運営チームのふりかえりでモチベーションをタイムラインに表現してみたところ、全員が直近のモチベーションが下がり気味であることがわかりました。 原因についてディスカッションしたところ、いくつかの課題が見えてきました。 社内の参加者とのギャップ 社内では比較的いつでも使えるスペースなので、社内の参加者は毎月決められた日程に合わせてわざわざ自主的な勉強会をすることにあまり強い動機がなくなってきました。 参加者と運営側のギャップ 運営メンバーはイベントを運営しながら技術的な情報交換をしたり、エンジニア同士の交流を行うことも強い期待を持っていました。そのためもくもく勉強会の自習要素が高まると、運営者は場のセッティングなどが中心になりマンネリ感が高まってしまいます。 そろそろ新しいことをやりたい 集まった運営メンバーはそれなりに意欲を持って集まっているので、毎回同じように運営するだけの状況に疑問を感じ始めていました。何か新しい要素を取り入れてもっと活動範囲を広げれないかと考え始めていました。 PHP のエンジニアが交差するTechCafeへ これらの課題を踏まえて、運営していく我々にできることは何かをもう一度考えてみました。私たちの会社を当初からずっと支えてきたサービスは PHP で開発しており、 PHP に関しては組織体制上、その技術はほぼ大阪に集中しています。曲がりなりにも20年近くお客様へサービスを提供しており、 PHP に関してはある程度の強みを持てていると考えています。 ラク スと PHP について これを踏まえて、私たちはただ単に勉強する場をご提供するだけでなく、もっと能動的に学びとなる場をつくっていきたいと考えました。 TechCafeが支える領域 そして、その目的を 言語化 し「 PHP を軸としてエンジニアと技術が交差する憩いの場(カフェ)になる 」というコミュニティのコンセプトが生まれました。 Web× PHP TechCafeのコンセプト まだまだスタートしたばかりで、引き続き試行錯誤が続いていますが、いくつか新しく始めた取り組みを紹介します。 ディスカッション枠 先月は PHP 7.4の新機能について興味を持った人が集まってその仕様を把握したり、使い方やメリット・デメリットなどをディスカッションしました。思った以上に盛り上がって、次回も継続する予定です。なお、これらの情報はコミュニティ専用の Slack でも共有しています。 LT枠 また、5分のLT枠も作りました。特にテーマは決めず、普段参加して頂いている方の成果発表やアウトプットの機会として頂きたいと考えています。 コミュニティ間コラボ その他、関西で PHP を扱っている他のコミュニティともコラボして PHP 界隈を盛り上げていきたいと考えています。コミュニティ関係者のかたでご賛同いただけるかたがいらっしゃればぜひご連絡をください。 色々と新しいことに取り組み始めた段階で、ひとつひとつはまだまだ小さな取り組みですがこれから拡大していきたいと思います。 PHP 好きのみなさんよろしくおねがいします。