未経験者がプログラミングスクールに入る前にやっておくべき3つのこと

f:id:b1840943:20180719231420p:plain

 

僕が入学前にやっててよかったなーと思うことや、「何をしてたらいいですか?」と聞かれて考えたことをまとめました。未経験からエンジニアに転職したい人向けに書きます。あくまでスクールに通う前提の人向けです。

 

事前学習

どのプログラミングスクールも未経験者を対象にしているので、完了させるのが不可能なほど難しいカリキュラムということはありません。ですが、できるだけ早く転職を成功させることを目標として入学するはずなので、プログラミングの基礎的な部分に時間を取られることは避けたいです。

 

それにスクールに入ってから「やっぱりプログラミング好きじゃないかも…」とか「たぶんエンジニアに向いてないな…」ということにならないように、事前にある程度触っておいた方がいいでしょう。

 

おすすめはまずProgateをやってからRailsチュートリアルの黄金コースです。

 

Progate

以下の順番で学習していくといいと思います。大切なことは、理解しようとしないことです。とりあえず全体を把握することが大事なので、細かいところは「ほお〜、こんな感じか」ぐらいでどんどん先に進みましょう。

 

  1. HTML&CSS
  2. JavaScript
  3. jQuery(飛ばしていいかも)
  4. Ruby
  5. Ruby on Rails
  6. Git(とりあえずはいらないかも)

 

まずHTML&CSSはWEBページを支える最低限の技術なので、必ず押さえておく必要があります。ですが本当に必要最低限なので、WEBページを作れる以上のことは基本的にできません。そこでJavaScriptが登場します。JavaScriptは将来VueやReactを勉強するときの基礎にもなるので、やっておいて損はありません。というか絶対やってください。極論、JavaScriptさえできればなんでもできます。

 

jQueryはもしかしたら飛ばしてもいいかな…と思います。「jQueryは基礎だからやっておいて損はない」という意見を聞いたことがありますが、今VueやReactを勉強していて「jQueryやっててよかったー!!」という瞬間は特にないので、もうやらなくてもいいのかもしれません。反論は受け付けます。

 

だいたいどのスクールでもRailsを学ぶことになると思うので、RubyRailsは事前にやっておいた方がいいと思います。おまけでGitもどうぞ。

 

Railsチュートリアル

これを一周してるかしてないかで未経験エンジニアとしてランクが一つ変わる気がしてます。スクールに入ってからロケットスタートできること間違いなしです。

 

正直かなり時間かかったし、何回も挫折しそうになった(というか一回した)ので、あまり安直に未経験者にオススメはできませんが、Progate等である程度基礎がついている状態だったらぜひ一度挑戦してみてもらいたいです。

 

個人的によかったと思った点は、MVCの概念とGitの使い方を学べたところです。一周すればなんとなく「WEBアプリケーションってこんな感じで動いてんだー」っていうのがつかめるかなと思います。そこさえつかめればあとはわりと楽にスクールのカリキュラムが頭に入ってくるようになります。

 

貯金

f:id:b1840943:20180719231442j:plain

 

ある程度お金があるかどうかで転職活動がハードモードになったりイージーモードになったりします。もうすぐお金が尽きるという状態だと集中して勉強できないですよね。

 

ある程度生活のためのお金があれば、内定をもらっても「転職活動を継続する」という選択ができますが、お金がなかったらその余裕を持つのはなかなか難しいです。お金がなくなればなくなるほど、「早く転職して給料をもらわないと…!」という思考になっていくので、結果としてミスマッチが起こりやすくなります。

 

具体的には僕はざっくり100万あったらだいぶ余裕持って転職活動できるんじゃないかと思います。そこまでない状態だったとして「とにかく早くスクールに通うべき」か「まず貯金するべき」かは、僕はまず貯金してもいいかなと思います。

 

しっかりとエンジニアとしてのキャリアを見据えて、何をやりたいのかを明確にして、そこにハマる企業に転職するのがベストなので、そのためにはまず貯金して万全の状態でスタートを切る方がいいんじゃないかと僕は思います。中途半端にスタートするとそのあと全てが中途半端になる可能性が高いです。

 

スクールは必ず何週間は行かなきゃいけないというものではなく、早い人はさっさとカリキュラム終わらせて転職活動始めてすぐ卒業したりします。なのでしっかりと事前に自分で勉強してれば貯金のための期間はそこまでのタイムロスにはならないはずです。

 

情報発信の下準備

アウトプットすることは思っている以上に大事です。いろんなところで言われてることですが、実際に始める人はかなり少ない印象です。なおさらやれば目立つし、メリットしかないので絶対にやってください。Qiitaに書いたり、ノートにまとめたり、いろんな方法があると思いますが、オススメはTwitterとブログです。

 

 

なぜやるのか

アウトプットを前提にしていると、インプットと同時に頭の中でアウトプット用に編集するので、質が変わってきます。より噛み砕いて理解するようになるし、人に説明しやすくなります。体感では記憶の定着もいいです。

 

それに実際に文章にすることで自分がちゃんと理解していない部分に気づくことができるというメリットもあります。また公開することでフィードバックももらえるし、単純に文章力やプレゼン力が鍛えられるという利点もあります。

 

そういうメリットもあってか、アウトプットしているという点の面接官からの評価はすごいよかったなと感じました。大したこと書いてないのに。今でも「ほんとに大したこと書いてないな俺…」としばしばヘコむんですけどね。それでも評価してくれたのは「内容」よりもアウトプットしているという「行動」が重要なんだと思います。なのでとりあえずなんでもいいのでアウトプットしてみるのがいいでしょう。

 

準備は何をやればいいの

Twitterのアカウントやブログの開設をしましょう。自分がなぜエンジニアになろうと思ったのか、ブログにまとめてみるのもいいと思います。あとで振り返ることができるので、どれだけ自分が成長したのかを測れます。

 

あとどういう情報を発信していくのか、コンセプトもまとめておいたほうがいいと思います。わざわざ転職活動用にアカウントを作る必要はないと思いますが、全然関係ないツイートで埋まってるアカウントを面接官に見てもらってもあれなので、ある程度一貫性があった方がいいです。

 

なぜ下準備?

何を始めるにしても一番腰が重いのは一歩目です。ここを越えてしまえば二歩目、三歩目は自然と出ます。なのでスクールが始まる前に一歩目をもう踏み出してしまいましょう。

 

実際準備にそんなに時間はかからないはずなんですが、スクールが始まってしまうと忙しくなってなかなか気乗りしなくなってきます。たぶん入学前に何のアクションも起こさなかったら、卒業まで何もしないと思います。

 

なので今、やっちゃいましょう。

 

終わり

プログラミングスクールには人生を変える力があると思います。ですが、それは「入りさえすれば人生が変わる」というわけではなく、「人生を変えることができる環境を提供してくれる」だけです。結局自分がどうするか、です。

 

なので何も考えずにとりあえず入学するんじゃなくて、ちゃんと準備をして入るべきだと思います。これができてればあとからかなり楽になるはずです。辛いのは一歩目だけなので、ぜひやってみてください。

【CSS】はみ出した文字を「...」で省略する方法が簡単すぎた

f:id:b1840943:20180708122229p:plain

 

Pairsのクローンを作成していて、長すぎる文字を省略させたい部分があったので調べてみました。

jQueryでごにょごにょやるのかなー面倒くさいなーと思ってたらCSSでズバッと一撃で解決して感激したのでまとめます。

 

f:id:b1840943:20180614182531p:plain

 

長すぎるメッセージを送信した場合、最新のメッセージを表示している枠がどんどん大きくなってしまって時間を表示させる枠がおかしなことになっちゃう現象が発生しました。

本来はメッセージ本文の下に時間が入らないといけないことになってます。

 

これを解消するためにはjQueryで要素の幅とか文字数とか取得してあーだこーだやるのかなー…とか考えてたんですが、対象のCSS柴咲コウ 36歳って書いてるとこの下のaaaaaの部分)に以下の三つを追加するだけで解決しました。

 

.user_info02 {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

 

これを入れるだけで

 

f:id:b1840943:20180614183132p:plain

 

こうなりました。CSSで制御できると楽でいいですね。

 

ただ注意点としては、このやり方だと複数行表示させてから「...」で省略させることはできないみたいです。その場合やはりjQueryとか他のやり方を考えないといけないですね。

 

まあでもあんまり無いケースな気がするので、大抵はこのやり方だけでなんとかなりそうです。

 

参考サイト

dev.classmethod.jp

autoplayを設定してるのにvideoが動かない

f:id:b1840943:20180629111034p:plain

背景

背景動画が自動的に流れるデザインのページを作っていて、autoplayを設定しているのに自動で動いてくれませんでした。解決方法自体はすごい簡単でしたが、その情報までにたどり着くまでまったく解決の糸口が見つからなかったので、書いておこうと思います。

 

作っていたのはこのログインフォームです。

 

 

最初のコード

最初に書いたときはこんな感じにしてました。

 

<%= video_tag "married_couple.mp4", class: "landing_video", loop: true, autoplay: true %>

 

Railsアプリなので、erbで書いてます。これで表示自体はまったく問題なくできるんですが、なぜか自動再生がされないんですよね。なので動画なのに静止画のような状態になってしまってました。

 

もちろん、コントローラパネルを表示させて再生をクリックすれば再生はされます。ですがコントローラパネルを表示させると再生ボタンとかが動画にかかって見た目が悪いんですよね…。

 

改善コード

で、調べたところ以下のようなコードにすれば解決することがわかりました。

 

<%= video_tag "married_couple.mp4", class: "landing_video", loop: true, autoplay: true, muted: true %>

 

muted: trueを追加しただけです。これを追加するだけで自動再生されるようになりました。

 

推測ですが、音が出る動画を自動再生されるとUXが著しく損なわれるので禁止してるんじゃないかな…と思います。昔(15年ぐらい前)はありましたけどね。動画じゃないけどMIDIオルゴールとか変な音楽とか流れる個人ホームページ。たしかにうるせえとは思ってました。

 

終わり

これはHTML5自体が音が出るautoplayはサポートしてないってことかな??素晴らしいっすねそれは。いきなり音が流れたらウザいし。

 

そういえばFacebookも動画のautoplay時に音を鳴らす鳴らさないでもめてた記憶があるんですが、あれってどうなったんだろ?最近Facebookのフィードがだいぶさみしくなってきたので確認とれませんでした。

【9週目】未経験からTECH::EXPERTでプログラミングやってみた

f:id:b1840943:20180701230217p:plain

 

今週は僕の開発最終週だったので、仕上げを中心にやりました。グループで個々が機能を開発して、それをマージして一つのアプリとしてちゃんと動くのを見るとやっぱテンション上がりますね!

 

スタイリング

マージするとやっぱりスタイリングが崩れるところがどうしても出てくると思うんですね。Bootstrapを入れてたブランチと入れてないブランチをマージしたりするとBootstrapが悪さしたりとか。cssファイルをimportする順番のせいで上書きされちゃったりとか。そこの調整をしました。

 

主にサイドバーなんですが、一つは現在いるページへのボタン背景を変えました。

 

f:id:b1840943:20180701225838p:plain

 

jQueryで今ユーザーが見ているページを取得して、それとリンク先が合致すればクラスを追加してます。こんな感じですね。

 

$(function(){
  $('.gnavi_item a').each(function(){
    var $href = $(this).attr('href');
    if(location.href.match($href)) {
      $(this).addClass('is_current');
    } else {
      $(this).removeClass('is_current');
    }
  });
});

 

その他もろもろきれいにしました。かなり細かい部分ばっかりなんで省略します。

 

スクレイピング

実際に誰かにアプリを見せるときにユーザーが全然いなかったらさみしいですよね。なのでダミーユーザーを30人前後準備することになりました。

 

手動で一人一人フォームから登録していくこともできますが、エンジニアを称する人間がそんな人海戦術を是とするなんて言語道断だという結論になったので、スクレイピングで女性の画像を引っ張ってきてseedでデータベースに入れていくことにしました。

 

 

いや、ちゃんとやりましたよ…?

 

だいぶ前にカリキュラムで書いたコードを改変して使いました。今回はメイン画像を一枚、サブ画像を二枚取得します。取得先は女優さんがたくさん一覧で出ているページです。女優一覧ページの女優名にリンクが貼ってあり、そのリンク先にその女優の画像がぶわっと並んでる感じです。

 

require "mechanize"

def image_page_urls
  agent = Mechanize.new
  links = []

  current_page = agent.get("取りたい画像があるURL")
  elements = current_page.search('.image_list .imageBox a')

  # get_imageで取得できない画像もあるので、多めにfirst(n)に指定する
  elements.first(40).each do |ele|
    links << ele.get_attribute('href')
  end

  links.each_with_index do |link, i|
    get_image('取りたい画像があるhost' + link, i)
  end
end

def get_image(link, i)
  agent = Mechanize.new
  page = agent.get(link)

  begin
    main_image = page.search('#1_img')
    agent.get(main_image.first.attributes["src"]).save "/Users/kosaburokaneko/projects/techexpert/pairs_clone/app/assets/images/avatar/user#{i+1}.jpg"  
  rescue
    return # メイン画像が取れなかったらこの女優は諦める
  end
  
  begin
    sub_image1 = page.search("#{i+2}_img")
    agent.get(sub_image1.first.attributes["src"]).save "/Users/kosaburokaneko/projects/techexpert/pairs_clone/app/assets/images/avatar/user#{i+1}_sub1.jpg"
  rescue
    begin
      sub_image1 = page.search("#{i+3}_img")
      agent.get(sub_image1.first.attributes["src"]).save "/Users/kosaburokaneko/projects/techexpert/pairs_clone/app/assets/images/avatar/user#{i+1}_sub1.jpg"
    rescue
      begin
        sub_image1 = page.search("#{i+4}_img")
        agent.get(sub_image1.first.attributes["src"]).save "/Users/kosaburokaneko/projects/techexpert/pairs_clone/app/assets/images/avatar/user#{i+1}_sub1.jpg"
      rescue
        puts "取得できませんでした"
      end
    end
  end

  begin
    sub_image2 = page.search("#p1_#{i+5}_img")
    agent.get(sub_image2.first.attributes["src"]).save "/Users/kosaburokaneko/projects/techexpert/pairs_clone/app/assets/images/avatar/user#{i+1}_sub2.jpg"
  rescue
    begin
      sub_image2 = page.search("#p1_#{i+6}_img")
      agent.get(sub_image2.first.attributes["src"]).save "/Users/kosaburokaneko/projects/techexpert/pairs_clone/app/assets/images/avatar/user#{i+1}_sub2.jpg"
    rescue
      begin
        sub_image2 = page.search("#p1_#{i+7}_img")
        agent.get(sub_image2.first.attributes["src"]).save "/Users/kosaburokaneko/projects/techexpert/pairs_clone/app/assets/images/avatar/user#{i+1}_sub2.jpg"
      rescue
        puts "取得できませんでした"
      end
    end
  end
end

image_page_urls

 

なんでこんなbeginとrescueがこんなことになってるかというと、画像があったりなかったりするページだったので画像を取得できない可能性があったんですね。なのでもしメイン画像が取得できなかったらその女優は諦めて次の女優に移るというようにしてます。サブ画像については取得できなかったら次の画像を取りに行って、それを二回頑張って無理だったら諦めるという風にしてます。

 

あと取得画像の制限ももっと上手な方法があると思うんだよなあ…スクレイピングはほぼやったことがないんだけど、やっぱり取得成功してデータがもりもり増えるの見てるとなんか興奮するからもっと勉強したい。

 

で、取得できた画像はそれぞれ

  • メイン画像: user_1.jpg
  • サブ画像1: user_1_sub1
  • サブ画像2: user_1_sub2
  • メイン画像: user_2.jpg
  • サブ画像1: user_2_sub1
  • サブ画像2: user_2_sub2

という風にユーザー別に保存するようにしました。最近each_with_indexが大活躍してます。

 

保存した画像はcarrier_waveを使って保存する必要があって、それをユーザーと紐づかせなければいけません。なのでseed.rbには以下のように書きました。

 

32.times do
  password = Faker::Internet.password(8)

  User.create(
    name: Faker::Japanese::Name.last_name,
    gender: 2,
    email: Faker::Internet.free_email,
    password: password,
    birthday: Faker::Time.between(50.years.ago, 20.years.ago, :all).to_s[0, 10],
    nationality_id: 48,
    narrow_address_id: rand(1..48),
  )
end

32.times do |i|
  CapturedImage.create(
    content: File.open(Rails.root + "app/assets/images/avatar/user#{i+1}.jpg"),
    status: 0,
    user_id: "#{i+1}".to_i,
  )
  CapturedImage.create(
    content: File.open(Rails.root + "app/assets/images/avatar/user#{i+1}_sub1.jpg"),
    status: 1,
    user_id: "#{i+1}".to_i,
  )
  CapturedImage.create(
    content: File.open(Rails.root + "app/assets/images/avatar/user#{i+1}_sub2.jpg"),
    status: 1,
    user_id: "#{i+1}".to_i,
  )
end

 

Fakerで日本語使う方法がいまいちわからなかったので、ruby-faker-japaneseというgemで対応しました。それでユーザー登録に必要な情報をダミーで入れて32人作成してます。

 

下の段がcarrier_waveの部分ですが、contentの部分は先ほど保存した画像を開くように設定してます。ちなみにstatusが0はメイン画像で、1はサブ画像です。これでユーザーとユーザー画像がちゃんとひも付けされるようになりました。この二つのファイルがあれば何百人だろうが自動でできます。

 

終わり

というわけで、僕の役目は終わりました。あとはグループでこのアプリを発表するだけです。とうとうここまで来てしまいました。

 

グループでスクラム開発をできたこともそうですが、既存のサービスのクローンをつくるのはすごい勉強になりました。どういう技術が実際に使われてるのかとか、CSSの細かなテクニックとか、自分で開発するプロセスじゃなかなかたどり着けない、既存サービスを研究することで初めてわかったことがいくつもありました。

 

スクールのカリキュラムとして既存サービスをコピーするのか、オリジナルサービスをつくるのか、どちらがいいのかは難しいところだと思います。正直自分でやる前は「既存サービスのコピーなんて大した勉強になんないでしょ」と思ってましたが、全然そんなことありませんでした。むしろ今では一からサービスを作るよりも勉強になる部分がたくさんあると思うようになりました。

 

あまり経験がない中でオリジナルサービスを作ろうとするとどうしても技術的に背伸びしにくい気がするんですよね。技術的にがんばるというよりも、サービス全体として一つ作り上げる方に意識が向くというか。なので結果的に本当の自分の技術的ポテンシャルより一段落ちる気がしてます。

 

でも自分の個性とか出す場所としてはオリジナルサービスってすごくいいと思います。デザインにこだわってもいいし、アイディアで勝負もできるし。もちろん技術的にすごいサービスってとこを狙ってもいいですし。

 

でもいろいろ考えた上で、多くの人には既存サービスをコピーする方が転職には役立つんじゃないかと思います。転職目的では。大概WEBサービスのアイディアなんてすでに作られてるので、どうせそういうインパクト勝負ができないんだったらコピーした方が見た目もきれいだしいろんな話もできると思うんだよなあ。

【8週目】未経験からTECH::EXPERTでプログラミングやってみた

f:id:b1840943:20180623102157p:plain

ポイント機能

ポイントをクレジットカードで買うことができる機能を実装しました。と言っても決済機能を実際に実装するわけではなく、単にダミーのカード番号等を入力するとポイントが増える、といった動作をするという感じです。

 

f:id:b1840943:20180623103142g:plain

 

文章にするとシンプルなので実装開始前はわりと簡単かなと見積もってましたが、ちょっと悩んだ点がありました。ユーザーにフォームに値を入力してもらった後に確認画面に遷移するんですが、その確認画面でどうやって入力された値を表示させるかです。

 

今回決済機能は実装しないのでフォームに入力された値はデータベースには保存せず、入力されたかどうかだけフロント側でバリデーションをかけて確認画面に遷移させようと事前にチームで話し合いました。

 

データベースに保存された値を引っ張ってくるのはお茶の子さいさいですが、保存されない場合どうしよう…ということでparamsを使うことにしました。はっきり言ってセキュリティ的に絶対クソです。現場でこんなことしないのは現場知らない僕ですら感覚的にわかりました…がとりあえず実装しなければいけないということで、この方法でいくことにしました。

 

キャッシュ使ったりいろいろな方法があるということを後で知ったんですが、まあ経験が無い中でひねり出したということで大目に見たいと思います。

有料会員登録機能

これも実装したんですが、ポイントを買うときと基本的な動きは一緒です。フロント側でバリデーションかけて、全て入力されてれば有料会員になる、と言った流れです。

 

f:id:b1840943:20180623103408g:plain

 

特に引っかかったところは無いです!はっきりこう言い切れるのは初めてかも。

 

唯一あるとすれば実際に使われてるフォントを再現できなかったところかな…あれなんでできないんだろう。他と同じようにCSSで指定するだけじゃできないみたいなんだよな。

ログインフォームデザイン

Pairsってメアドでサインアップ or ログインできるようにはなってなくて、FacebookアカウントかSMS認証のどちらかしかありません。あとログアウトも基本的にできません。

 

まーーーこれは開発してると本当にめんどくさいポイントでした。なんで他のメンバーにdeviseでログイン機能を実装してもらい、メアドでできるようにしました。

 

ただインストールしてもらっただけなので、あの初期のデザインのままのログインフォームでしばらく放置されていました。今週もスプリントレビューがあったので、さすがに見た目をキレイにしないとマズいということでデザインしました。

 

 

レビューのときにメンターさんに褒められたので満足。デザインからやるのって難しいけど、やりがいはありますよね。

終わり

今週はぽんぽん機能実装できた週でした。多分一度やったことある部分が増えてきたってことだと思うので、いい傾向なんじゃないかと。

 

来週がチーム開発最終週になります。始まる前は予想してなかったんですけど、なんかPairsに愛着湧いてきてるんですよね。もっと良くしたいみたいな気持ちがポロポロ出てきます。

 

スプリントレビューでメンターさんが「自分がやりたい機能とかチャレンジングな機能を実装すれば絶対あとでいい思い出になる!」って言ってたのがすごく印象に残ってます。今は同感できるんですが、スクールに入る前はその感覚はわかんなかっただろうなあ…と思って。

 

というエモい終わり方で来週もがんばります。

【7週目】未経験からTECH::EXPERTでプログラミングやってみた

f:id:b1840943:20180617123321p:plain

非同期メッセージ機能完成

先週に引き続きメッセージ機能の実装です。

先週ツイートした時は高速Ctrl+Rで非同期に見せるという高度な技を使用していたので、今週は非同期通信を中心に実装しました。

 

 

メンバーがヘッダー、サイドバー、フッターを作ってくれていたので、renderでメッセージ画面を表示するようにしてます。見た目的にはほぼ完成したと言ってもいいんじゃないですかね。

勘違い

メッセージ機能自体を非同期化するのはカリキュラムでもやったことがあったのですんなりいったんですが、マッチしたユーザーの一覧の最新のメッセージを非同期更新するところでハマりました。

ハマったというか、勘違いしていてフロントのフレームワーク等がないと実装できないと思ってました。

 

ビューファイルはざっくりこういう構造になってました。マッチしたユーザーの一覧とメッセージエリアは部分テンプレートで切り出していた格好です。

f:id:b1840943:20180617115246p:plain

それで非同期でメッセージを更新しようとすると以下のようになります。

f:id:b1840943:20180617115656p:plain

ここまではOKです。

ここから_matched_usersの最新メッセージを更新しようとする場合、何を思ったか以下のように一度コントローラーを通さないとできないと思ってました。

f:id:b1840943:20180617115756p:plain

そもそも_message_areaで更新された最新メッセージの値を逆流させてコントローラーまで届くのか…? というところでつまずき、半分諦めてプルリク出そうかと思ってました。

 

と思ってたんですが、電車乗ってる時に勘違いに気付きました。上記のように考えてた原因はjQueryがそれぞれのビューに紐づいていると考えてたからなんですね。例えば、あるjQueryが記載されたファイルは_message_areaしか操作できない、といったように制限されてるとなぜか勘違いしてました。多分疲れてました。

実際は以下のように更新できました。

f:id:b1840943:20180617120519p:plain

いやーなんで勘違いしてたんだろう…部分テンプレートだからアクセスできないっていう風に考えてたっぽいんだけど…

 

無事実装完了したのでプルリク出してメンターさんからLGTMをもらったのでmasterブランチにマージしました。

ポイント機能

次はポイント機能を実装します。

どういう機能かというと、お金をポイントに交換することができてそのポイントで「いいね」を買ったり、メッセージ付き「いいね」を送れたりします。

その根幹となるポイント機能ですが、実際の決済機能は実装しません。ダミーのカード番号や有効期限が入力されていればポイントが購入できるようにします。

 

pairs_point from Kosaburo Kaneko on Vimeo.

 

今週はとりあえずビューだけを完成させました。ここのビューではモーダルが使われていてそこに結構時間使っちゃったんですが、それは別の記事にしようと思ってます。

ポイントを購入したらDBが更新されるバックエンドの動きを実装できれば完成…ですが毎回そんなすんなり行くことはないので、油断しないようにします。

終わり

いやほんとビュー作るのって時間がかかるんですよね…

時間かかるし、いくら時間かけても終わりがないし、いくら時間かけても機能自体は実装されないんですよね。フロントに注力しすぎて時間と労力かけた割には全然進んでないみたいな状況に陥る気持ちはわかるような気がします。

なのでフロントをある程度実装したらまず機能を作ることを先にやるように意識してます。それで全体の枠ができてそれでもフロントを修整したかったらするようにすればまあ進まないってことはないかなと思います。

【6週目】未経験からTECH::EXPERTでプログラミングやってみた

f:id:b1840943:20180610115741p:plain

最終週(最初のプロジェクトの)

仕上げ

現在同時進行で二つのプロジェクトが進んでいて、そのうちの一つは今週いっぱいで終了でした。アジャイルチーム開発を初めてやった案件なので、なんか思い入れがあります。

 

今週は軽微な修正とテストとデプロイがメインでした。軽微と言っても使う側から見ると軽微でも開発側から見るとけっこう手間かかったりするんですよね…。

 

  • AjaxでのレスポンスとHTMLでのレスポンスでコメント表示の見た目が違う
  • 各ポストにはタグ付けができ、作成されたタグの一覧を(きれいに)表示する
  • Newest / Popular機能
  • ポスト投稿時にアップロードする画像をプレビュー表示させる
  • アップロードした画像をポスト編集時に表示させる

 

このような点を今週は修正していきました。

ユーザーからすると当たり前に感じる機能ですが、いざ実装しようとすると「あれ?どうやってやるんだっけ?」ってなったりしました。一回実装したのに他でバグが出て泣く泣く削った機能もありましたが、なんとか最終形に持っていくことができてよかったです。

 

テスト

テストコードを書くのは自分が担当しました。正直あまり得意じゃないので、チャレンジしようと思って自分から名乗り出ました。やめとけばよかった。

 

  • 投稿機能
  • ポストへのコメント機能
  • ポストへのタグ付け機能
  • ポストへのLike機能

 

それぞれ「投稿ができる」「削除ができる」「編集ができる」ことをテストコードで保証しなければなりません。

 

カリキュラムで習った通りrspecでテストコード書き始めました。投稿と編集については問題はなかったんですが、どうしても削除のテストがうまくいきませんでした。

削除はログインしていないとできないようにしているので、deviseというgemを使ってログインをしてから削除をするという行動をテストで再現します。

そこの絡みかFactoryGirlなのかわかりませんが、email has been already takenというエラーをずっと回避できないままタイムアップでした。database_cleanerをインストールすればいいみたいな話もあったんですが、解決までには至らず…めっちゃ悔しいです。

 

テストってものを作り上げていくわけではないので、同じコードを書くにしても機能を実装してる時とかなり意識が違うなと感じます。好き嫌いが分かれると思いますが、個人的にはテストが通った時の気持ち良さはけっこう癖になる気がしてます。気がしてるだけですが。

Pairsクローン

メッセージ機能実装

Pairsを使ったことがあって相手からちゃんと返事が返ってくる人ならわかると思いますが、Pairsには素晴らしいメッセージ機能が備わってます。この機能を僕が担当することになりました。

 

実際開発者目線で見ると新たな発見がいろいろあります。今パッと思い返すだけで以下のような機能があります。

 

  • 自分と相手のメッセージで見た目を切り替える
  • 同じ日付のメッセージには重複して日付を表示させない
  • それぞれの相手との最新のメッセージをサイドバーに表示
  • 一通目以外は画像投稿ができる

 

などなど。

正直言って、めっっっっっっちゃ苦戦しました。

 

  • それぞれの相手との最新のメッセージをサイドバーに表示

 

これ!こいつ!これをRailsだけでどうやったらできるのか、かなり悩みました。ここはビューをどういう構造にするのかにも関わるので、影響が及ぶ範囲が大きくて大変でした。

 

 

夜ガチャガチャいじってて突然閃いた勢いでツイートしちゃいました。あと日付もeach_with_indexとか使ってごにょごにょやるとできるということに気づけました。ググっても出てこないんすよここら辺。そのうち記事にしようかなと思います。

 

難易度が上がれば上がるほどピンポイントでの解決法はGoogle先生も知らないことが増えるので、蓄えた知識と経験を応用させて解決しなきゃいけません。これができたことがすごく嬉しかったです。あーエンジニア面白いなーって改めて思いました。

 

スプリントレビュー

毎週月曜から土曜までを1スプリントとして区切っていて、土曜はメンターさんのレビューが入ります。Pairsでは初めてのスプリントレビューでした。

 

僕が作ったメッセージ機能をメンターさんに見せたところ、

 

メ「Ajaxですか?」 

僕「違います」

メ「Ajaxにしましょう」 

〜終了〜

 

 

裏側の苦労とかは別によくて、必要なのは機能なんですよ(泣)

基本的な機能は実装できてたから突っ込むところは特になかったのでこんな感じであっさり終わったんだろうという超ポジティブ思考でいきます。

 

f:id:b1840943:20180610115816j:plain

工数見積もり

見積もり失敗

第一スプリントが終了したのでチームで振り返りをしました。

結果的に僕が担当したメッセージ機能も完成はできず、各機能も部分的にしか実装することはできませんでした。それ自体はまあ、それはそれで仕方ないのですが、問題はこれが当初の見積もりと大幅な差があったことです。

 

先週各機能の見積もりをやったという話をしましたが、その時には第一スプリントで各自が担当した機能は全て完璧に実装完了して、プラスAWSにもデプロイした状態でスプリントレビューを迎えられるだろうという見積もりでした。

実は一度見積もりをみんなで出してみた後に「う〜ん、これって余裕がありすぎない?」という雰囲気になって開発する機能を追加したという経緯がありました。

 

なぜここまで見積もりと現実が乖離したかというと、各機能に必要な要素を把握しきれてなかったからだと思ってます。

僕が担当したメッセージ機能を例にとると、僕自身過去にメッセージ機能を開発した経験があったので、見積もり段階ですでに具体的な開発手段のイメージがついてました。

ですが、実際に開発を始めると

 

  • 同じ日付のメッセージには重複して日付を表示させない
  • それぞれの相手との最新のメッセージをサイドバーに表示

 

これらのような、「あ、これも実装しなきゃいけないじゃん。しかも実装した経験ないわ。」というものがポロポロ出てきました。なので結果的に当初の見積もりよりも実際の工数の方が多くなってしまったんですね。

 

対策

以下の二つの対策案にたどり着きました。

 

  • 見積もり精度を上げる
  • バッファーを見積もりに入れる

 

まずそもそも初回の見積もり時に把握できてなさすぎたことがあると思います。なんとなくメッセージ機能ってこうだよね、ぐらいの感覚で見積もってたのかなーと。見積もりにはもう少し時間をかけてチームとコミュニケーションをとりながら機能の全容を把握していってもいいと思いました。

 

ですがそれでも完璧に見積もるというのは不可能だと思います。

前職が機械メーカーだったので、納期を見積もってお客さんに出すのは日常茶飯事でしたが、最低でもプラス一週間は多めに出していました。だいたい海上輸送で機械を日本に持ってくるので、まず製造自体が遅れるリスクもあるし、海上輸送がどこかでストップしたり税関で止められるリスクもあるからです。

 

つまり予期しないことが発生することを見込んで、最悪そうなった場合でも支障なくプロジェクトを進められるように見積もりをしていました。まあ実際支障は出ますけど、最低限に抑えられるようにバッファーをかませていました。

 

なのでそのやり方をこっちにも持ち込もうと思います。

終わり

もう何百回も言ってる気がしますが、スクールに通う醍醐味はこのチーム開発だとつくづく思います。なんかもう得るものが大きいです。一人じゃ絶対に得られないものを得られます。

実際に転職する前に体験しておけばかなりスムーズに業務に移れるんじゃないかと思います。

 

書いてて思い出したことで、なぜ見積もりポーカーするときの数字がフィボナッチ数なのかという疑問があったんですが、いい記事をみつけたので貼っときます。

 

tango-ruby.hatenablog.com

 

絶対にPairs完成させたいと思います。