kei_log

モダンな自社開発企業を目指すための学習ログ

ghq × fzf × g関数でGitリポジトリ高速ジャンプ

やりたいこと

ghq で管理しているGitリポジトリを、ターミナル上であいまい検索 → 一発で cd したい。

必要なツール

インストール

まずはbrewで必要なツールをインストールする

brew install ghq fzf
$(brew --prefix)/opt/fzf/install

関数定義

.zshrcに下記の関数を記載する

g() {
  local selected=$(ghq list | fzf)
  [ -n "$selected" ] && cd "$(ghq root)/$selected"
}

できたら設定内容を反映する

source ~/.zshrc

使い方

ただターミナル上で g と打つだけでよい!

g
  1. ghq listghq 管理しているリポジトリを取得
  2. fzf であいまい検索
  3. 選んだら、対象のリポジトリcd でジャンプできる

Happiness Chain Euforia 9ヶ月目の振り返り

1 月の学習の振り返りをしていきます!

1 月の学習時間

1 月中の学習時間はトータルで 81.0 時間 でした。 また、HappinessChain(HC)に入ってからの総学習時間は、676.0 時間となりました。

進捗状況

課題の進捗状況についてです。 1 月中に進めたカリキュラムは以下の通りです。

良かったところ

DjangoTwitter クローン作成)

1 月中に実装した機能は以下です。

  • ブックマーク機能
  • メッセージ機能
  • 通知機能

2 ヶ月程度かかりましたが、HC のロードマップの中ボスをようやく突破することができました! HC に入会してから最も達成感が得られる課題だったと思います。また、EC 課題も合わせると 4 ヶ月ほど Django フレームワークに触れてきて、簡単な Web アプリケーションであれば構築できる力は身についた実感があります。 この勢いでこの後のフロントエンド課題も一気に進めていこうと思います!🔥

JavaScript(中級課題)

さらに JavaScript の中級課題も一通り終えることができました! 課題の 1 つである JavaScript Primer は改めて、とても良書だと感じました。 読んだ感想については、下記ブログ記事でまとめています。

otaki0413.hatenablog.com

またアウトプット課題では、TODO リストを素の JavaScript のみで実装 することに取り組みました。 React など JS ライブラリを使って実装するのと比較して、直接的な DOM 操作が必要になるのは大変でした。ただ、基本的な JavaScript の仕組みを理解した上で実装できたので、改めて良い学びになったと思います。 実際に作成した TODO リストはこちらです。

https://otaki0413.github.io/js_todo/

改善点

学習量・学習ペースを上げる

これまでの学習時間は月 80 時間前後で安定していましたが、まだ学習時間をさらに増やせる余地があると感じました。 具体的には、月 100 時間 を目標に設定し、週 25 時間 を超える学習時間を確保することを意識します。そのために、以下の学習スケジュールを徹底します。

  • 平日: 2 時間 × 5 日 = 10 時間

  • 土日: 8 時間 × 2 日 = 16 時間

  • 合計: 週 26 時間 を目標

このスケジュールを継続し、学習ペースをさらに加速させていきます!

2 月の目標

  • 100 時間勉強する(週 26 時間のラインを超える)
  • JS 上級課題完了
  • React 課題 50%完了
  • 失業給付金の取得方法について調査する
  • ストレッチ毎日する
  • 土日はなるべくカフェに行く

『JavaScript Primer - 迷わないための入門書』を読み終えました!

本記事では「JavaScript Primer」を読み終えた感想を書いていきます。 結論、JavaScript の入門書としてこれ以上ない名著だと思います!

jsprimer.net

良かったところ

  • 著者が JavaScript 界隈における超有名人であること

    こちらで紹介されている、著者のazu さんオープンソース開発者として有名であり、これまで 500 以上もの npm パッケージの開発・メンテナンスに携わっている方です。また JavaScript の言語仕様である ECMAScript の仕様に日本人として関わっており、JavaScript に関する知見や周辺知識に置いては右に出る者はいないのではないでしょうか。さらに JSer.infoという、JavaScript の最新情報をブログ記事でも発信しています。このレベルの方が書いた書籍であるため、内容に関して非常に信頼をおけるものだと思います。

  • 本書自体が OSS であるため、最新の情報が取り入れられている

    ECMAScript のアップデートに追従して、継続的に内容が更新されています。 そのため最新の言語仕様を取り入れた、JavaScript の知識が手に入るのが強みです。
    リポジトリhttps://github.com/asciidwango/js-primer

悪かったところ

  • 探しましたが、見当たりませんでした。

学んだところ

  • プロトタイプオブジェクトの存在

    JavaScript には、文字列、数値、真偽値、配列、オブジェクトといったデータがあります。これらは広い意味でオブジェクトであり、Objectを継承することでObject.prototypeオブジェクトに定義されたメソッドなどにアクセスできることを学びました。MDN の記事で文字列操作のメソッドを見ていたときに、Object.prototype.toString()と書かれていたのはそういうことなのか、と気付きが得られたのも大きいです。
    参考:https://jsprimer.net/basic/prototype-object/

難しかったところ

  • TODO アプリの章 2 部の応用編で書かれている TODO アプリを作成するパートがかなり難しかったです。JS のコードでこれまでクラス構文を使う機会が少なかったのもありますが、TODO リストを構成するリストやアイテムをクラス化して、フォーム送信やクリックなどのイベントを管理するクラスを用意したりと、かなり丁寧ではあるものの理解しがたい箇所が多々ありました。ただし、アプリケーションの規模が大きくなることを想定した作りになっており、新たな知見も得られてよかったです。

おわりに

JavaScript はやっぱり好きな言語です! 本書は何度でも読み返せる名著なので、困ったときにはいつでも戻ってきたいと思いました。

Happiness Chain Euforia 8ヶ月目の振り返り

12 月の学習の振り返りをしていきます!

12 月の学習時間

12 月中の学習時間はトータルで 78.0 時間 でした。

また、HappinessChain(HC)に入ってからの総学習時間は、596.0 時間となりました。

進捗状況

課題の進捗状況についてです。 12 月中に進めたカリキュラムは以下の通りです。

良かったところ

DjangoTwitter クローン作成)

Twitter クローン課題に着手して約 2 ヶ月が経過しました。 12 月中には、以下の機能を実装しております。

  • プロフィール編集
  • ツイート作成
  • いいね
  • リツイート
  • ユーザーフォロー

また課題を進める中で、既存コードの冗長さが目立つ箇所があり、何度かリファクタリングも行っています。共通処理を mixin にまとめたり、重複するテンプレートを部分テンプレート化するなど、直接的な課題以外の学びも多く得られたと感じています。

長かった Twitter クローン課題のタスクも残りわずかですが、メッセージ機能と通知機能というラスボスが控えています。まだ実装イメージが着いていませんが、課題を通じて試行錯誤しながら進めていきたいと思います。

JavaScript(初級・中級課題)

最近は Python を触ることが多かったので、久しぶりに JavaScript に触れました。 比較的慣れている言語ということもあり、基本的な文法や構文のインプット学習は問題なく進められたと思います。 特にJavaScript Primerという教材は内容が丁寧に書かれているので、良い復習になっています。

さらにアウトプットとなるスクール課題では、JavaScript Primer で得た知識を活用することを意識したので、より理解が深まりました。レビューで CTO から 「とてもきれいなコードでした!」とコメントを頂き、大きな自信にも繋がりました。この調子で残りのアウトプット課題もクリアしていきたいと思います!

改善点

集中できないならカフェに行け

平日は基本的に家で学習していますが、土日は環境を変えたくなることがよくあります。 12 月に入ってから、近所のタリーズで学習するようにしたところ、自分でもわかるくらいに集中してプログラミングに長時間没頭できる感覚が得られました。受験期の学生に囲まれていることも少し関係しているかもしれませんが、やはり環境の力は偉大ですね。 ただし、この時期足元が寒いのが唯一の難点です。今後はひざ掛けを持参することで対策していきたいと思います。

1 月の目標

  • 80 時間勉強する(週 20 時間のラインを超える)
  • ストレッチ毎日する
  • Twitter クローン課題完了(100%)
  • JS課題完了(100%)
  • 土日はなるべくカフェに行こう

Happiness Chain Euforia 7ヶ月目の振り返り

11 月の学習の振り返りをしていきます!

11 月の学習時間

11 月中の学習時間はトータルで 72.0 時間 でした。

HC に入ってからの総学習時間は、529.0 時間となりました。

進捗状況

課題の進捗状況についてです。 11 月中に完了したカリキュラムは以下の通りです。

良かったところ

DjangoTwitterクローン作成)

Twitterクローン課題に着手して、1ヶ月程度経ちました。認証周りの実装が一通り完了し、トップページやプロフィールページの見た目部分の作成を主に進めました。前回のEC課題とは異なり、デザインは基本的に自分で実装する必要があり、時間はかかりますが楽しく進められています。今後は、メインとなる投稿やいいね・リツイート機能の実装に進む予定です。引き続き頑張りたいと思います!

11月で学んだ内容は以下の通りです。

改善点

忙しいを言い訳にしない

11月は比較的残業が多い月だった気がします。 毎日家に着くのが夜10時前くらいで、学習に取り組む意欲がなかなか沸かない日が多々ありました。その結果、何もしない日が続いてしまい、悪循環に陥ることも。 12 月は「少しでもいいから毎日机に向かう」という姿勢を大切にして、学習を継続することを目指します。

アウトプットをする

11月の目標だった「技術記事を最低1本書く」は達成できました。 しかし、投稿ネタが複数あったのに1本止まりなのは少し物足りない感じがします。 学んだことを言葉にして起こすのは、理解の定着につながると実感しているので、 12月は技術記事を2本書くことを目標にします!

12 月の目標

  • 80 時間勉強する(週 20 時間のラインを超える)
  • 技術記事を 2本書く
  • ストレッチ毎日する
  • Twitter クローン課題完了(100%)

Cloudinaryを使ったDjangoアプリで画像をリサイズしてみる

はじめに

現在、Djangoを使ったTwitterクローンを作成しています。画像ストレージにCloudinaryを使用しているのですが、アップロード画像のリサイズ方法に詰まったので、やり方をまとめておこうと思います。

前提条件

以下の環境を想定しています。

  • Djangoプロジェクトに Cloudinary が設定済み
  • django-cloudinary-storage を使用して画像アップロードを管理

Cloudinaryの設定やTweetモデルの定義は以下の通りです。

  • settings.py
MEDIA_URL = "/media/"
CLOUDINARY_STORAGE = {
    "CLOUD_NAME": env("CLOUDINARY_NAME"),
    "API_KEY": env("CLOUDINARY_API_KEY"),
    "API_SECRET": env("CLOUDINARY_API_SECRET"),
}
  • models.py
class Tweet(modes.Model):
    """ツイート情報の格納用モデル"""

    class Meta:
        db_table = "tweet"

    user = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
    content = models.TextField("ツイート内容", null=False, blank=False)
    image = models.ImageField("ツイート画像", upload_to="tweets/", blank=True)

上記設定で画像アップロードすると、Cloudinary上の/media/tweetsフォルダに格納されていきます。(下記イメージ) Cloudinaryのフォルダ階層の写真

Cloudinaryの配信URLについて

デフォルトの形式

公式によると、Cloudinaryのデフォルトの配信URLの形式は以下のようになります。

https://res.cloudinary.com/<cloud_name>/<asset_type>/<delivery_type>/<transformations>/<version>/<public_id>.<extension>

それぞれの要素について簡単にまとめます。

  • <cloud_name>:Cloudinaryのアカウント名
  • <asset_type>:配信するアセットタイプ(image,video,rawのいずれか)
  • <delivery_type>:配信タイプ(デフォルトはupload
  • <transformations>:変換パラメータ、カンマ区切りで指定する(※何も指定しないとオリジナルのファイルが配信される)
  • <public_id>:アセットの一意な識別子(フォルダ構造が入る)

ここで注目するべきは<transformations>の部分です。ここにトランスフォーメーション情報(リサイズやクロップ設定など)を追加することで動的に画像を変換できます。

リサイズした画像の例

例えば、<transformations>の部分にc_fill,w_150,h_150を付与することで、150×150pxにリサイズされた画像を配信できます。

https://res.cloudinary.com/<cloud_name>/image/upload/c_fill,w_150,h_150/v1/media/tweets/icecream_kckry7

他にも画像変換で用いるパラメータがあるため、気になる方は下記を参考にしてみてください。 dev.classmethod.jp

実際にリサイズ済みの動的なURLを作成する

Cloudinaryの配信URLの形式がわかったので、デフォルトのURLからリサイズ後のURLになるように変換する処理を作成していきます。

① 画像リサイズ用の関数をつくる

CloudinaryのリサイズURLを生成するget_resized_image_urlという関数を作成します。
引数にはトランスフォーメーション情報となる4つのパラメータを受け取れるようにしました。

ここで配信URLの形式をもう一度確認してみましょう。<transformations><asset_type>/<delicery_type>の後ろに記載する必要があることがわかります。

https://res.cloudinary.com/<cloud_name>/<asset_type>/<delivery_type>/<transformations>/<version>/<public_id>.<extension>

そのため、<asset_type>/<delicery_type>に該当する/image/upload/を起点にしてURLを一度分割してから、URLを再整形するやりかたを取っています。

def get_resized_image_url(
    image_url, width=None, height=None, crop="fill", gravity="auto"
):
    """
    Cloudinaryの画像URLをリサイズ用URLに変換する処理

    Args:
        image_url (str): 元の画像URL
        width (int): リサイズ後の幅(オプショナル)
        height (int): リサイズ後の高さ(オプショナル)
        crop (str): クロップ方法(デフォルトは"fill")
        gravity (str): クロップ位置(デフォルトは"auto")

    Returns:
        str: リサイズ後の画像URL
    """
    if not image_url:
        return None

    # URLを分割してリサイズ用のトランスフォーメーションを挿入
    parts = image_url.split("/image/upload/")
    if len(parts) != 2:
        # URLの形式が期待と異なる場合、元のURLを返す
        return image_url

    # 動的なリサイズ設定(引数のパラメータを含める)
    transformation_list = [f"c_{crop}", f"g_{gravity}"]
    if width is not None:
        transformation_list.append(f"w_{width}")
    if height is not None:
        transformation_list.append(f"h_{height}")

    # リサイズ設定用の文字列作成
    transformation_str = ",".join(transformation_list)

    # リサイズ後のURL整形
    resized_url = f"{parts[0]}/image/upload/{transformation_str}/{parts[1]}"
    return resized_url

② ビューからリサイズ済みのURLをテンプレートに渡す

リサイズ済みのURLを作成する関数ができたので、各ツイートの持つimageに対してURLの変換処理をかけていきます。私の場合は、150×150ピクセルの画像を表示するようにしました。

  • tweets/views.py
class TimelineView(ListView):
    model = Tweet
    template_name = "tweets/index.html"
    context_object_name = "tweet_list"

    def get_context_data(self, *args, **kwargs):
        context = super().get_context_data(*args, **kwargs)
        # 各ツイートに対してリサイズ済みの画像URLを設定
        for tweet in context["tweet_list"]:
            if tweet.image:
                tweet.resized_image_url = get_resized_image_url(
                    tweet.image.url, 150, 150
                )
        return context

  • templates/tweets/index.html
{% for tweet in tweet_list  %}
  <div>{{ tweet.user.username }}</div>
  <div>{{ tweet.content }}</div>
  <img src="{{ tweet.resized_image_url }}" alt="投稿画像}">
{% endfor %>

実際のアプリでの見た目↓

おわりに

Cloudinaryを使えば、画像を必要な形式、スタイル、寸法に変換できることが分かりました。画像を最適化することで、ファイルサイズを最小限に抑えながら配信できるので、今後使う機会があれば積極的に活用していこうと思います。 ここまで読んでいただきありがとうございます!

参考記事

https://cloudinary.com/documentation/image_transformations cloudinary.com

Happiness Chain Euforia 6ヶ月目の振り返り

10 月の学習の振り返りをしていきます!

10 月の学習時間

10 月中の学習時間はトータルで 81.0 時間 です。目標の 80 時間を達成できてよかったです!

また HC に入ってからの総学習時間は、457.0 時間となりました。

進捗状況

課題の進捗状況についてです。 10 月中に完了したカリキュラムは以下の通りです。

  • Django
    • EC サイト作成(100%):完了
    • Twitter クローン作成(10%)

良かったところ

Django(EC サイト作成)

先月時点で、EC サイトの進捗は 60%ほどであり、今月は残り 40%の機能開発を行いました。 主に取り組んだのは、チェックアウト機能とプロモーションコード機能の実装です。 これまでの課題を通して、Django の基礎知識が身に付いていたため、課題への取り掛かりはスムーズに進められたと思います。ただし、チェックアウト時のメール配信機能は外部サービスとの連携が必要で、目当ての情報に行き着くまでに時間を要しました。それでも自力で実装できたのは大きな成果です。

学んだ内容は以下の通りです。

  • フォームのバリデーション
  • クラスベースビューのメソッドオーバーライド
  • メール送信機能
  • フラッシュメッセージの表示
  • カスタムコマンドの使い方

DjangoTwitter クローン作成)

EC サイトが完成したため、10 月終盤からは Twitter クローン課題に着手しました。 課題の全体像を見た感じ、機能が盛り沢山なので大変そうだと思いながらも、以前より実装イメージが湧くので取り組むのが非常に楽しみです。 現在は 1 つ目のサインアップ・ログイン機能の実装を進めているのですが、けっこう時間がかかっています。django-allauth という認証ライブラリを使用しているのですが、公式ドキュメントや Github 上 のコードを参照し、内部実装をある程度理解することが必要だったからです。ライブラリを使うことでコード量は減りますが、中でどんな処理が行われているか把握しておくことで機能拡張したいときに役立つと実感できました。この調子で焦らず進めていきたいと思います。

改善点

アウトプットをする

技術記事を書く機会を増やしていこうと思います。 いま取り組んでいる Twitter クローン課題には学びが多いですが、自分の言葉で説明する習慣がないと、なかなか知識の定着に繋がらないと感じています。 まずは月に 1 つ技術記事を書くことを目標にします。

11 月の目標

  • 80 時間勉強する(週 20 時間のラインを超える)
  • 毎日 X 投稿
  • 毎日タイピング結果を投稿する
  • 毎日学習する
  • 技術記事を 最低 1 つ書く
  • ストレッチ毎日する
  • Twitter クローン課題 (80%)