エムスリーテックブログ

エムスリーテックブログ

エムスリー(m3)のエンジニア・開発メンバーによる技術ブログです

関西と九州でエンジニアが働けるサテライトオフィスができました

はじめに

皆様こんにちは、こんばんは。 最近のアークナイツの盛り上がりがたまらない、VPoEの河合(@vaaaaanquish)です。

自分のキャリアを選ぶ次女。欲張りです。本文とは関係ありません

さて、タイトルの通り、エムスリーエンジニアリンググループは、関西と九州でエンジニアが働けるサテライトオフィスができました(というより出来てました!半年前に!笑)。 実際既に大阪、京都、福岡で働くエンジニアが在籍しており、サテライトオフィスのアピールも兼ねてと「サテライトオフィスブログリレー」を開催しています。

本記事では、VPoEとして私河合が「サテライトオフィス創設のねらい」について書いていきます。

  • はじめに
  • エムスリーの働く環境
  • サテライトオフィスのねらい
  • サテライトオフィスで働くエンジニアと技術
    • 型にこだわりのあるエンジニア
    • 遊びにこだわりのあるエンジニア
    • 成果にこだわりのあるエンジニア
  • おわりに
  • We are hiring !!
続きを読む

入社 4 ヶ月の私が初見コードでも開発のスタートダッシュを切る技術

  • はじめに
  • 前提となるマインドセット
  • 具体的な Tips
    • コードを読まずに理解する技術
      • とりあえず Clone する
      • インタフェースで理解する
      • テストコードで理解する
      • 慣習名で理解する
    • コードの詳細を理解する技術
      • デバッガを使う
      • とりあえずサンプルコードを書いてみる
      • 分からないなら聞く
    • 初見コードに安全に変更を加える技術
      • インタフェースを明らかにする
        • Stub としての実装を用意する
        • Design Doc を書く
      • テストを書く
  • まとめ
  • We are hiring !!
    • エンジニア採用ページはこちら
    • カジュアル面談もお気軽にどうぞ
    • インターンも常時募集しています

はじめに

京都オフィス在籍で、AI・機械学習チームの山本(@hiro_o918)です。 このブログはサテライトオフィスのメンバーで投稿されるブログリレー 3 日目の記事になります。 関西在住だとオフラインでのコミュニケーションに悩みがちなのですが、 サテライトオフィスがあることでリアルでチームメンバーと飲む会える機会が増えて、とても楽しいです。

2 日目は福岡オフィスの氏家さんによる「エムスリー福岡 Quine を作りました!」でした!

www.m3tech.blog

Quine という概念をこの会社に入社してから知ったのですが、なかなかギークな遊びだなと感じています。 ぜひ読んで見てください!

さて、実は中途入社して 4 ヶ月、先日初めての評価フィードバックがありました。 内心ドキドキしていましたが、自分でも前々から得意だと思っていた「初見のコードベースでも素早く目的の変更を行える」という点を実感してもらえている旨のフィードバックを頂くことが出来ました。 新しい環境に入った直後でもこのように言ってもらえたので、この点には少し自信を持っています。 定量的にも、次の記事にあるような社内 OSS の変更を入れたり、他チームのサーバーに対して新規に機能を追加したりと、 目的に対してそこまで迷わず変更を加えることができていたなと感じています。

www.m3tech.blog

なかなか大きな声で何かを得意と言う機会は少ないですが、フィードバックを受けて自分の中でもチョットデキルかもと思えているタイミングなのもあり、 今回は「初見のコードベースでも、素早く目的の変更を行える」と思えるように至るまでの経験や考え、Tips を共有したいと思います。

続きを読む

エムスリー福岡Quineを作りました!

突然ですが、次のM3柄のソースコードをPython(>=3.8)で実行し、実行結果を入力に何度か繰り返し実行してみてください! 結果はどうなるでしょうか?

exec("""m=lambda_x:"".join(x.split()).replace("~"+"~",chr(32))""".replace("_",chr(32)),globals());exec(s:=
m('''s="""exec(\\"\\"\\"m=lambda_x:"".join(x.split()).replace("~"+"~",chr(32))\\"\\"\\".replace("_",chr(32
)),globals());exec(s:=m(\'\'%r\'\'))"""%s;import~~base64~~as~~b6;import~~zlib;import~~re;from~~datetime~~i
mport~~datetime;tr=lambda~~x,y,z:~~(y~~if~~x~~else~~z);lme=lambda~~x:list(map(lambda~~x:tr(x=="1",1,0),x))
;di=zlib          .decompress(b6.b64decode("7Z          ZdcsMwCITfc5r4/pdr                O9PUAnYX9Oe0U/PQ
qQTig5Xk          6HFcZo8btQj1/DEVrqKezjahPAZF          AZSC4Ri/FufqQr                        EY1edilIqmKF
xhNeJGPV            FIzf82FDo8AMUPL/e26U+z/iIq          KySion8bqihg            zwgb            gm1CtbgLUD
6SoNTh/s            so+yHiCRaieAk10IWocyxQ+E            vG9o6VuQWFrF      1XQB1HNptjDGq/        3agblaFqX4
HFKHUtm4            KyMLPg/aii1Ra0KFy17AfJ4D            3OtwrlYcADDnuLwh6aED8VGYprkqC+RrJD      hwIS5yis9K
k4R1lsYa      9G      ULHvEkrPIBRMpm0M5SvX      mo      TEaIPRvbIvnHwDJlAWEqVk/w+iVMqFKJZy      y14tQPHACq
pLwAtRB7      Vf      hurYK2XbUWFJSUAWM4Ha      az      fq/6A6frQtCh1efU0HUPCGdqDUjW/ulcek      i1agKssyAW
OME7D6AW      QC      bkTxElhRn6hcIlTlIlRm      uV      hwBRJwDNX6y6i6KVSIsVeYSxA78rvSQl5/      BSo/gwj1Ss
mABhWTIT      k5yv      dw4ps1FuWDVFcngK      NMeS      9UC+lFsb1yfT2O6K6gbGF+57w23yjvHkf5      jl0TDzftg1
uzKA9A4p      rM7A      pnXSFAXGdc+1A+Un      6YkG      AZShhHtbXlXTEVmpX6pzGiR98WBEW0        Bp0PCrjdbtRf
RfW/LgZR      7IhX/d      OocBWll1xfjhIL    kkImUU      oV3CccZwLauTxxiooN                  vwIuRJGH1jgqBv
Wgpo5FO8      JSbkGx      MZvtFtAGo9lp      VNNwUs      DvR/ktLGzyPMr3V0Hl              5lD6OCsBu1BMDPkwJm
tQ3wXUiW      GwRSgL      4fJOo2I/TOBJ      1Lk/eB      aPu1E2QUyuehq4Vzpd                    BUUOuzrSPQc9
+gNq1Lre      hVc+pD8A      "),-15).      decode()      ;r=0;r=(r+1)if(r+1<4)else(0);d          ii=di[r*32
10:(r+1)      *3210];s      s=s.repl      ace("r=0      ;r=","r=%s;r="%r)+"#"*sum(lme(dii)        );print(
"".join(      [tr(c=="      1",ss.re      place(ch      r(32),"~"+"~")[sum(lme(dii)[:j])],tr      (c=="0",
chr(32),      c))for(j,c      )in(      enumerate(      dii))]));'''))######################      ########
########      ##########      ####      ##########      ####################################      ########
########      ############      ##    ############      ####################################      ########
########      ############            ############      ##################################        ########
########      ############            ############      ##################################      ##########
########      ##############        ##############      ##########        ############          ##########
########      ##############        ##############      ##########                            ############
########      ##############      ################      ############                      ################
##########################################################################################################
##########################################################################################################

タイトルで若干ネタバレしていますが、次のgifのように、「M3」→「福岡」→「積極」→「採用」→「M3」→ ... のように出力が変わっていったと思います。

「M3」を実行すると「福岡」が出力され、同じように「積極」「採用」と遷移していく

そう! 私が所属するエムスリー福岡オフィスではソフトウェアエンジニアを積極採用中です!

  • はじめに
    • 脱線: エムスリールーレットQuine
  • Quineとは
    • 整形Quine
    • クロスクワイン
  • 実際にクロスクワインを作ってみよう
    • まずは普通のQuineを作る(赤パート)
      • セイウチ演算子を使う
    • 圧縮したアスキーアートを展開 (青パート)
    • アスキーアートの遷移状態を保持し、実行のたびに遷移させる(ピンクパート)
  • 整形して出力する( 橙パート)
    • 空白や改行を処理する(紫パート、緑パート)
  • まとめ
  • We are hiring !!
    • エンジニア採用ページはこちら
    • カジュアル面談もお気軽にどうぞ
    • インターンも常時募集しています

はじめに

というわけで、こんにちは。AI・機械学習チームの氏家(@mowmow1259)です。 エムスリー福岡オフィスで1人目のエンジニアとして働いています。 この記事はサテライトオフィスブログリレーの2日目福岡担当です。 1日目は京都オフィスの北川さんによるgokartに型を導入する話でした。そちらも面白いので是非ご覧ください!

www.m3tech.blog

さて、冒頭でも紹介した通り、エムスリーでは京都・大阪、福岡でサテライトオフィスを開設しており、私が所属する福岡オフィスでも積極採用中です。 福岡オフィスでは、エムスリーとしての採用活動はもちろんのこと、福岡のソフトウェアエンジニア、MLエンジニア界隈も積極的に盛り上げていくべく、福岡でのイベントの参加はもちろん、主催もしていけたらなと思っております。

そんな折、先日もPython Meetup FukuokaがLINEヤフーさん主催で開かれ、私も聴講で参加させていただきました。 発表はもちろん、懇親会でも様々な方が熱量を持って交流していて、福岡の盛り上がりを感じました。 主催のLINEヤフーさん、素晴らしいイベントをありがとうございました。

lycorptech-jp.connpass.com

さて、Pythonといえば、AI・機械学習チームでもバッチの多くをPythonで書いている他、業務以外でもm3公式Xアカウント(@m3_engineering)で難読クイズを出していたり、Quine*1のような遊びもしていたりします。

www.m3tech.blog

この記事はとても面白く、私もこれをみてQuineで遊んでみたいなーと思っていたところにPython Meetup Fukuokaでモチベーションも上がったので、これを機に福岡にちなんだQuineを作ってみるか! から冒頭のQuineが出来上がりました。 とはいえ前回と同じQuineだと芸がないので、冒頭の通りアスキーアートを遷移させるように作って見ました。

ということで、この記事では、福岡は一ミリも関係なくなってしまいますが、せっかく作ったこのQuineの技術的な話をご紹介します!

脱線: エムスリールーレットQuine

本編に入る前に、ついでに作ったエムスリールーレットQuineもここにおいて供養しておきます。 形は先ほどのQuineとほぼ同じですが、こちらは実行のたびにエムスリーの3の文字がランダムに1-9の数字に切り替わります。 是非実行の結果をコメントで教えてください!

exec("""m=lambda_x:"".join(x.split()).replace("~"+"~",chr(32))""".replace("_",chr(32)),globals());exec(s:=
m('''s="""exec(\\"\\"\\"m=lambda_x:"".join(x.split()).replace("~"+"~",chr(32))\\"\\"\\".replace("_",chr(32
)),globa          ls());exec(s:=m(\'\'%r\'\'))          """%s;import~~base                64~~as~~b6;impor
t~~zlib;          import~~random;from~~datetim          e~~import~~dat                        etime;random
.seed(da            tetime.now().timestamp());          tr=lambda~~x            ,y,z            :~~(y~~if~
~x~~else            ~~z);lme=lambda~~x:list(            map(lambda~~      x:tr(x=="1",1,        0),x));di=
zlib.dec            ompress(b6.b64decode("7Z            tRcuQgDET/cxr2/pdLpSobg1BLArew8Vhf      CWp44MFTLT
P++rcsvi      5A      lb+w5COqBSikUFCRYZDG      Gm      UI5WlKWYQ6MiEUkvmKegrJqJ92qUxD9UoH      ZV8gnL87Sp
faWSLKm8      gO      qJH/XhRIH//jzH6o9ovI      H4      iAwlPYE4VcwjNQsYEGUPnxojZE6berDKwq      IpJQEhO6rz
yYppE90T      gE      z6710UaiViK91kBxjPRH      ox      ie/Y6o8+WBrkn07AtQOijBSCNQGkrLkFFW      jurZ7fUSUd
52oZUHHo      jm2X      0QCRUBUTx7MeOuKH      khTq      Py40VtiNL2TB+WCu89Ksrf6qTTA9nXua8i      KKSx1klGWW
qI4hnpj0      WxPP      sylLZ5iOVB6aLNEz      27hU      lFBS/gGc8usemoGrcAJZUpj/Tvixot        DwgoPIUYaCHq
+J/o2fVp      pqC0qP      tRTg98TIPKjxe1    IQrvnD      piKn3vJv6OKYAaLw9i                  Grpnx5rrUGeNtK
Whoo7M3V      Dznr1u      T0W1rUHUXHnQ      tp1ARS      ayBBVpoRjpyCp3Q+FN              EkTFPXtx406oaHlARO
EpWKFp7o      GKevY9      UZFhhlD58aI2      ROm3qw      yk6r+O3M0+h9JBUkU/                    PSChkMa/Gtei
5oz0i2rk      ekcrfwHK      3laU8qCo      MYmKZD1Y      yu+Y9EuZ9py9h6WfHtwJFffse6Gi5Q          ERhacQAZFR
9pdzCBX1      7FKFpph6      etD2Szs9      kL0e725f      1EmUtXeO8FV4J1JR9qYnnh54I9Ae6fvTJK        MwiPac3Q
d9DGqT8u      D4WxuBWB      5ot/AEKp      Kth9dgZJ      TWaqJGjTT6dNJQEnQB6n+G4tkRqs2kokIXsG      7xByahYg
PrsETU1H      2FB7BX0BcJ      h4J4      elCUqPPU0w      ML9Hh3+6JOotC+aQOqtJ0uxByUDfqVc8qDAC      j1hYCqyw
KUtapZI+      2v6TEoIUx8      92Ad      qpMR3z0gob      yJ+KDrUaNGGoAWokRjBkpdU84jfSDgo8CaMk      4PYJp/er
AMZSTZv/      hZhoJbIogamL      i5    4Ie72xd1EqXf      rjJcVWkiDVXUsFAT5YGW6qQ8z641p6D05qaV      ZaRRt71R
458VnqCX      Vz4t0cIsD9qh            OzS3PChdVEm2      Z4cgNmp8VZNGeuazmkKhS2HtwCkUWmrVzv        Lsm6AGyw
MGCk/hXq      imO8+z92LRwk            fJ+BNklAfgyj      /c3b6okyj9dpXhqMDeY6PMewqgpsqDNmHf      VxGUoekbOy
EHpXezUZ      NGGnVq2j8ENeXZ        N0BNlAdMlDORUt      Ds6KgeVqqw        UCc8e4tIQklY          J0189yCIGv
bsF6OEMP      Hdg2EUnkIItACl        dGSfHrRzbJpZqK      KEkLDKAwfT                            oPLjoahv"),-
15).deco      de();r=random.      randint(0,8);dii      =di[r*3103:(                      r+1)*3103];ss=s.
replace(chr(32),"~"+"~")+"#"*sum(lme(dii));print("".join([tr(c=="1",ss[sum(lme(dii)[:j])],tr(c=="0","@"+"@
",c))for(j,c)in(enumerate(dii))]).replace("@"+"@",chr(32)));'''))#########################################
##########################################################################################################

*1:それ自体が実行可能で、かつ出力した文字列が自分自身のソースコードとなるもの

続きを読む

Genericやらoverloadやらを使って、MLパイプラインツールgokartを型安全にしてみた

AI・機械学習チームの北川(@kitagry)です。 このブログはサテライトオフィスのメンバーで投稿されるブログリレー1日目の記事になります。1

サテライトオフィスブログリレーとある通り、4月から京都オフィスに在籍しています。 最近京都オフィスメンバーで居酒屋に行ったりしたのですが、やはり関西めっちゃ安い。。 みんなおいでよと思っているところです。

本ブログではエムスリー株式会社がOSSとして公開しているgokartというPythonツールの型を強化した話について書きます。 Python3.5から型ヒントの機能が追加され、現在最新のPython3.13に至るまでに徐々に機能が追加されています。 最近はGILの無効化など高速化に関する話題が上りがちですが、その一方で型についても徐々に充実してきています。 このブログではPythonで利用可能な型について言及しながら、gokartに型を導入した話について書きます。

本ブログは次のブログの続きでもあるのですが、このブログ単体でも読むことが出来ます。 mypy pluginが気になる方は是非次の記事も読んでみてください。

www.m3tech.blog

文脈とは何も関係ない、ただただデスクで寝ている猫


  1. タイトル一緒に考えて欲しいって言ったらいろんなタイトル案が出てきたのでここに供養します。Re:ゼロから始める型付け生活 ~ Dataframe型入出力 ~Python世界なのに型を持った俺が成り上がる話いまさら型を付けてくださいなんて言っても遅すぎる。Python界最下級ジョブ型付け師の俺が、狂った動的言語世界で安全スローライフする話型上手の若君Re:ゼロから始めるPython型付け生活
続きを読む

エムスリーが技術書典17で新刊を出します!

エムスリーエンジニアリンググループ AI・機械学習チームでソフトウェアエンジニアをしている中村(@po3rin) です。

技術書典17が2024/11/03に開催されます。(オンライン開催は11/02〜11/17)

今回エムスリーでは有志で新刊を携えて参戦します。過去最大の210ページの大ボリュームでお届けします。今回も多様な分野・技術について弊社スタッフが執筆いたしました。エムスリーのギークな面がふんだんに詰まった一冊となります。

オンラインでの購入は11/02以降、こちらからも可能です!

techbookfest.org

この記事では皆さんに新刊を手に取ってもらえるように、各章がどんな内容になっているのかを紹介します。

続きを読む

チームで培われたベストプラクティスをlintとして周知する

こんにちは。AI・機械学習チームの氏家(@mowmow1259)です。 エムスリー福岡オフィスの一人目のエンジニアとして福岡で働いています。 マクドナルドの月見バーガーが好きで、今年も発売開始当日に食べに行きました。

私が所属するAI・機械学習チームでは基本的に2週間から1ヶ月程度で新規プロダクトをリリースするなど、高速にプロダクトを開発しています。 その過程で、「この書き方は落とし穴があるから使わない方がいい」といった開発に際したベストプラクティスが溜まっていきます。 そういったベストプラクティスはレビューでの指摘や技術共有会*1でチームに浸透してきますが、レビュー負荷や新メンバーへの周知などに課題がありました。

この記事では、それを解決するためにベストプラクティスをLinterの独自ruleとして規定し、CIで自動検知することでチーム全体に周知する取り組みについて紹介します。

独自ruleによりLintされている例

  • ベストプラクティスの蓄積
  • ベストプラクティスの浸透の取り組み
  • ベストプラクティスの浸透の難しさ
  • Linterの独自ルールとして自動チェックする
    • 実装するベストプラクティス
    • Linterの選定
    • 独自ルールの記述
  • 各プロダクトへの導入
  • 導入の効果
  • まとめ
  • We are hiring !!
    • エンジニア採用ページはこちら
    • カジュアル面談もお気軽にどうぞ
    • インターンも常時募集しています

*1:AI・機械学習チームで週に一度行われている、面白い、共有したい技術の共有会です

続きを読む

プロダクトの成長を加速させる会議:エムスリーのプロダクトマネージャーが実践する「合宿」とは

こんにちは。エムスリー エンジニアリンググループ プロダクト支援チームでプロダクトマネージャーをしている中村です。

今回の記事では、プロダクト支援チームのプロダクトマネージャー陣が活用している「合宿」と呼ばれる会議をご紹介します。「合宿」と言っても、泊まりに行くわけではなく、オフィスの会議室に集まって2時間程度集中してプロダクトについて議論する場を指します。エムスリーのプロダクトマネージャー陣は、この「合宿」という場を活用し、プロダクトビジョンや戦略について議論を深めています。

  • はじめに
  • 「合宿」とは
  • 議論の流れ
    • ステップ1
    • ステップ2
    • ステップ3
  • 「合宿」の効果
  • まとめ
  • We are hiring!!
続きを読む