見出し画像

非エンジニアがGWの5日間で1つのサービスを個人開発してみた話

こんにちは、YOUTRUSTでPdMを務める竹中です!

今回は表題の通り、
GWのチャレンジとして、「まったくエンジニアリングの知識がない自分が個人開発として1つのサービスを作ってみた!」という内容になります。

せっかくなので、自分向けの学び記録として、また非エンジニアで個人開発に取り組んでみたい!という方向けに取り組んだ内容や手順をまとめてみたいと思います。


A. 個人開発の目的

①PdMとしてエンジニアリングの知識を実際に体験することで身に付けたかった

現在YOUTRUSTでPdMを務めているのですが、元々ビジネスサイドにいたこともあり、エンジニアリングのイメージがまったくついていませんでした。

昔から自分はそうなのですが、座学よりも何でもやってみて体得するタイプでした。エンジニアリングについても先輩エンジニアに聞いてみたり、日々の業務の中で少しずつ調べてみるものの、正直まったくエンジニアリングのイメージがつかず、、、
であれば、「まとまった時間が取れるGWにやってみよう!」ということで取り組むことにしました!


②自分の思いついたアイデアを形にしてみたかった

偶然にも自分は個人開発として、取り組んでみたい開発内容が既に決まっていました。

そのアイデアを友達や知人に壁打ちする中で、「悪くはなさそうだぞ?」という所感があり、日に日に自分で形にしたいという気持ちが強くなっていました。

もちろんそのアイデアを友達のエンジニアに依頼することも考えましたが、①の目的もあったので「どうせならば自分でやってみよう!」ということで個人開発をしてみることを決めました。


B. 開発したサービス

結論から言うと、最初のアイデア自体は実現できずMVPに近い形でリリースをすることになりました。(悔しい…)

当初実現したかったサービス

自分が歌える曲を選択すると同じ音域範囲内で歌える曲をレコメンドしてくれるサービスを作ろうとしていました。

皆さんには「歌ったことはないが歌えそうで知っている曲」にチャレンジして失敗した経験は何度かないでしょうか?
自分の音域で無理せずに、カラオケで歌える曲は大体1人につき2~3曲くらいはあるものです。
しかし、その曲が枯渇したりその曲を知らない人とカラオケに行く場面だったりで、何を歌うか悩んでしまう、、、!というシーンは多いと思います。

そんな中で、「自分が歌える曲(十八番的な曲)」を選択することで、その曲の音域内で歌える曲を知ることができれば、困ったシーンに合わせた曲を選択できるのでは?と考えました。

曲を発見するという行為において、他のサービスにはない新しいアプローチなのでは?と考え、これを実現できるサービスの開発に取り組み始めました。


最終的にリリースしたサービス:「音域分かる君」

最終的には
本当に本当に紆余曲折ありまして(後述予定)、
1つの曲を選択するとその曲の最高音と最低音を教えてくれる、というサービスのリリースに至りました。

実際のサービスは下記です!
※デプロイされたURLはサーバーの関係で、興味がある人に個別に送付する形とさせてください。


(GW中に公開するという期日をあえて絶対にずらしたくなかったので、CSSで見た目をリッチにする取り組みには時間が足りず、手が伸びませんでした…!悔しい…!)


リリースしたサービスの詳細

  • 曲名やアーティスト名で検索

  • キーワードと部分一致する曲を一覧に表示

  • 1つの音楽を選択する

  • その音楽を音域解析ツールにかけて、音域を出力する

  • 出力された音域に応じて「高い」「低い」等の評価を行う


C. サービス開発に伴う前提情報

下記の言語と環境で開発を行いました!

言語

  • HTML

  • CSS

  • JavaScript

  • Ruby

  • Ruby on Rails

  • Python

  • PostgreSQL

環境/外部サービス

  • Cloud9

  • Heroku

  • Spotify Web API

  • Essentia


D. 個人開発に向けた事前準備

GW最初の2日間は、ひたすら開発に必要な基礎知識を勉強していました。

個人開発の手順の勉強

手順は下記を参考にさせていただきつつ、基本的にはChatGPTに手順を教えていただきながら進めました。


開発で利用する予定の言語の基礎勉強

HTML/CSS/JavaScriptはProgateで1周ずつ学習しました。


Ruby/Ruby on Railsは下記のUdemyで学習しました。
この講座にある通り、RubyやRailsの基礎はもちろんQ&Aサイトの作成など一連のサービス開発の流れを体験することができたのは大きかったです。



E. 個人開発で実際に取り組んだ手順

1. プログラミング言語の学習(25時間くらい)

上記で記載したため、省略

2. 開発したいサービスの要件定義(1時間くらい)

現職がPdMなので無駄に凝った仕様書を作成しました…!
当初の計画していたサービスが破綻したので、何も公開しませんが、どの画面にどんな文言を置くか、どの画面にどう遷移するか、それぞれの条件など、開発に必要な情報を記載していました。

3. 開発環境の構築&Railsプロジェクトの作成(3時間くらい)

ローカルではなくCloud9環境を利用することに決めたので、いわゆる開発環境の構築ほどは時間は必要なかったです。

また上述したRailsの入門講座を受講する過程で、Cloud9のセットアップも含まれていたので、その内容を再度受講しながら個人開発用のセットアップも実施しました。

ChatGPTにひたすらどこに何を打てば良いのか、こんなエラーが出たがどうすれば良いのか?を聞き続けて、何とか実装を進める土台作りができました。

とはいえ、一番数々のエラーを目にした過程だった記憶があります…!

4. 音楽APIの選定&API連携(1時間以内)

ChatGPTに相談しつつ、各種サービスのAPIドキュメントを読む中で、最終的に「Spotify Web API」に決めました。

Spotifyユーザーだったのと、馴染みがあったのと音楽情報が多様だったためこちらに決めました。

英語が苦手なので、APIのドキュメントはほぼ日本語版に変換して読んでいました笑

5. 音域解析ツールの選定と導入(5時間くらい)

ここで1つ目の挫折だったのですが、「音域」という情報は各種音楽APIでは提供されていないようでした…!
(このAPIにはあるよ!など詳しい方がいれば教えてください…)

完全な事前リサーチ不足ですが、APIに含まれている情報だと思っていたので、特定の音楽から音域解析を行い、音域情報を取得するというアプローチが必要になってしまいました。


結果的に、Spotify Web APIから取得した音楽を「Essentia」という音域解析ツールを通して、音域情報に変換するという方針で進めることになりました。

※ちなみにこの時点で未学習だったPythonが必要になったことはかなり絶望的でした…!
Pythonのインストールなどもここで実施しました。


6. SpotifyAPIから音楽の取得(1.5時間くらい)

4で接続したAPIからRuby/Rails/Pythonを活用して音域情報を取得するコードを作成しました。

現在とは異なりますが、この時点ではこんな感じです。(ChatGPTに聞いた)

if __name__ == "__main__":
    access_token = "YOUR_ACCESS_TOKEN"  # 実際のアクセストークンに置き換えてください
    track_name = "Hello"
    artist_name = "Adele"
    preview_url = search_track(access_token, track_name, artist_name)
    print("Preview URL:", preview_url)

このアプローチによってSpotify APIからプレビューURLの取得ができるようになりました。

※ただしあくまでここではターミナル内で1つの曲を取り出す、という実装のみです


7. SpotifyAPIから取得した音楽をEssentiaで音域解析(4時間)

このセクションは取得できたプレビューURLをEssentiaで解析して、音域情報を取得するというアプローチでした。

主にPythonで解析を行うコードを作成し、指定された曲の最高音と最低音を出力してもらいました。

EssentiaのPitchMelodiaアルゴリズムをPythonに適用して、ターミナル上ですが下記のような出力を実現しました!
音域: 最低ピッチ = 117.22 Hz, 最高ピッチ = 529.34

(ここでやっとそれっぽい出力ができたのですごい嬉しかったです)

この後、ヘルツを「ドレミファソラシド」に変換する処理を入れました。
何気にここが難関でエラーと2時間近く格闘した記憶があります。
音域: 最低音 = ミ2, 最高音 =ド5

8. 検索画面の実装(10時間)

まずはconfig/routes.rbでルーティングの設定を行い、controllerの作成、viewの作成と着実に進めていきました。

まだこの時点では実現したい理想の仕様のままだったので、検索画面→検索結果画面→レコメンド画面という流れの検索→検索結果の表示を進めていきました。

一番最初に表示できた初期の検索画面

検索画面は各種サービスで実現する手段であり、すぐに実現すると思っていたのですが、甘かったです…!

MVCの概念も正確には理解していない状況だったため、どこに何を作成して、どんなアクションを実装していけば良いのかかなり手探りで進めていくことになりました。

PostgreSQLが起動しないだの、ec2-userが存在しないだの、データベースができていないだの、たくさんたくさん躓きました。

ChatGPT先生のキャップ上限を2回くらいこの実装過程で超えた気がします。


やっと表示された検索結果画面


9. 検索画面とAPIの連携(2時間くらい)

キーワードで検索すると、SpotifyのAPIを叩いて、検索結果を表示するという実装を進めていきました。

APIの連携はターミナル上では完了していたので、ここはそれほど苦労せずに進めることができました。

最初に検索結果が表示された画面

テーブル形式のUIにしてみたり、しました。

テーブル形式UI


10. 仕様変更に伴い、スコープ(ゴール)の調整(1.5時間くらい)

ここは苦しい過程でした。

ここで、元々進めていた「好きな曲を選択すると、同じ音域で歌える曲をレコメンドしてくれる」という仕様を実装するには、
数百万~数千万近い曲の音域を解析した結果をデータベースに保存しておいて、検索した結果と突合しなければいけない…!という事実に気がつきました…!

データベースの量が尋常ではないこと、コスト的にサーバーとして抱えていられないこと、などなど様々な観点からこの仕様は見直すことになりました。

次に目指した方針が、
「2つの曲を選択すると、その曲の音域比較をしてくれる」という内容でした。

例えば下記のように歌える曲と歌ってみたい曲を選択して、音域の比較をしてくれれば簡易的に当初のペインの解決になると思い、この方針で実装を進めることになりました。

曲Bの音域の範囲内に曲Aの音域がある場合、「“{Aの曲名}が歌えないならば、{Bの曲名}も歌えないはず!残念!”」「“{Aの曲名}が歌えなくても、{Bの曲名}は歌えるかも!チャレンジ!”」と表示
Aの最高音程がBの範囲内にある場合は、「“{Aの曲名}が歌えても{Bの曲名}の高音はしんどいかも!”」と表示


11. 2つの曲を選択できる&それぞれの音域を比較する、実装(6時間くらい)

1つ目の選択を保持して、もう1つの曲を選択するという実装を進めていくことになりました。

1つ目の選択をローカルストレージに保存し、再度検索をかけてもう1つの曲を選択するという流れです。


結論、この仕様も期日と実装難易度の観点で見送ることになりました…!

どうしても検索を実行する度に、保持されていた検索結果が消えてしまうという罠に陥り、自分の力では解決が全くできませんでした。

またこの時点で残り1.5日しか実装時間が残っておらず、期日から逆算すると絶対に間に合わないと感じて、苦渋の決断ですが、さらにスコープを削ることになりました。

12. 2回目の大きな仕様変更&ここまでの仕様の負債解消(6時間くらい)

ここで最終的にリリースした仕様に落ち着きました。
1つの曲を選択するとその曲の最高音と最低音を教えてくれて、その高さも伝えてくれる、という内容です。


ここまでの実装で進めていた分析処理や検索画面の不具合の解消を進めました。

ここでYOUTRUSTの先輩エンジニアの寺井さんに半日張り付いていただき、竹中&ChatGPTで作成していたコードの不具合の修正やデータベースの作成などを進めていくことになりました。

(寺井さんは30万人近いユーザーが利用する席替えアプリの個人開発をされた方でもあります!)

具体的に相談した事項としては、「分析ボタン」をクリックすると分析結果画面に遷移せずに、検索画面にリダイレクトされるという事案です。
ただのルーティング設定の問題ではなく、複数の条件分岐のどこかの過程で検索画面にリダイレクトされる問題が起きており、その原因を特定することからスタートしました。

binding.irb」を活用してデバッグを進める方法を教えていただき、1つ1つ改善を進めました。


最終的には分析画面に正しく遷移できるようになりました。


13. 分析結果画面に、選択していた曲の音域解析結果を表示する(4時間くらい)

ここでも問題が発生するのですが、7で実装した音域解析はSpotifyから取得できる30秒のプレビューURLから抽出するという内容でした。

つまり、曲全体の音域を出すわけではなく、30秒程度のプレビューから音域を取得する、というクオリティの調整が必要になってしまいました。期日が1日もなかったので、クオリティを妥協して実装を進めました。

Pythonを活用して1つの曲から音域を抽出できるように実装をしました。


大好きな槇原敬之の音域を解析できるようになりました


これで検索〜分析結果の表示まで一連の流れを実装することができました。


14. デプロイメント(2時間くらい)

人生初のデプロイを実行しました。

GitとHeroku(デプロイサーバー)というサービスを活用して、デプロイを行いました!

思ったよりしっかり時間がかかりました…!難しい…!


15. 軽微な修正をいくつか追加で実装(5時間くらい)

下記のようないくつか追加実装を行いました!

  • プレビューURLがNULLの場合に、「その音楽の音域は取得できませんでした。他の曲でお試しください。」と表示

    • 新しい曲だとプレビューURLが入っていないことがあるためその対策

  • 分析結果画面から検索画面に戻ることができるように

  • 細かい文言の調整

  • 音域を表示するだけではなく、音域に対して「高い」「低い」という評価を追加


最後の「高い」「低い」という評価はいくつか実際の音域情報から竹中にて、各音域の高さを定義した対応表を作成して、それをデータベースに読み込ませました!


F. 学んだこと

  • 実装の一通りの過程を体験できた

    • 今回はすべての過程を自分で体験したので、実装の中にどんな過程があるのかを理解できたのは大きかったなと思っています

  • 実装可能な仕様を先んじて調査するのはすごく重要

    • PdMをする中でも感じていたことですが、エンジニアに実装上の実現可能性を確認しておくのは本当に重要だなと…!

    • その調査をできていなかったことによって、何度もスコープを変更することになりました

  • 開発は常にQCDのトレードオフ

    • 今回は個人開発なので極端な例ですが、Dの納期を最優先にQもCも何度も下方修正しました

    • 何を優先するか、誰に何を届けたいのか、すべてはこのゴールに対するトレードオフだなと改めて痛感しました

  • エラーは失敗というよりNAが明確になる救い

    • エラーは出ないが期待している挙動にならない方が個人的にはきつかった…

    • どこを修正すればどう変わるのか?のイメージがクリアではなかったので、とにかくエラーには救われました

  • スペルミスは命取り

    • 「question」と記載すべきところを「qustion」になっていたという内容で2時間もロスをしたことがありました



G. 今後の展望

GW中、という期日の関係でいくつも悔しいポイントがあるので、ここは最後までやりきりたいなと思っています。

まだ一部ローカルでは動いているが、デプロイ後の本番環境では動いていないという事態があるのでその修正と、着手できなかったデザインの実装までは今後進めたいなと思っています。


元々実現したかったことについては、技術の選定からスタートしてどこかのタイミングで再チャレンジしたいなと思っています。


ここまで長い文章を読んでいただいてありがとうございました。

この記事が参加している募集

新生活をたのしく

この記事が気に入ったらサポートをしてみませんか?