未熟学生エンジニアブログ

プログラミング・Web開発をする大学院生のブログ

「フレーズ英単語1800 センター対策編」サポートについて

お問い合わせ先

下記メールアドレスからお問い合わせください。本アプリはユーザーの皆様からの要望に答える形で新機能や単語の内容など、これからも改善を行なっていく予定です。ぜひお気軽にお問い合わせください。ご要望があれば、LINE@などのサービスも開始する予定です。

phraseeitango1800あっとまーくgmail.com

(「あっとまーく」を@に変えてください。迷惑メール対策のため、一部表記を変更しています。)

新しいiOSアプリのコンセプトメモ 2018 10月

コンセプト

  • 「夢を考えさせる」
  • 「自分のやりたいこと・夢を諦めない」
  • 「勇気を持って後悔なく踏み出す」
  • 「自分の背中を押す自信をつける」
  • 「実力=自信は努力によって身につく」
  • 「努力するモチベーションを作る」

これを実現するのが俺のアプリだ

これが俺の欲しかったアプリだ

これが俺の作りたいアプリだ

メッセージ性

  • 「自分のやりたいこと・夢を諦めない」
  • 「勇気を持って後悔なく踏み出す」
  • 「自分の背中を押す自信をつける」
  • 「実力=自信は努力によって身につく」
  • 「努力するモチベーションを作る」

テクニック

  • 「真似できる実例を示す」

追記 11/7

よくわからないテンションで書いていたので、

  • 問題点の洗い出し
  • アプリとしての機能を具体化

問題点

テクニック「真似できる実例を示す」に関して

  • 実例はできるだけノンフィクションが良い
    • 残念ながらノンフィクションには限界がある
    • 可能な範囲で自分のノンフィクション

自分が「真似できる実例を示す」ことは難しいかもしれない。やるとしても「掲示板機能などでWebから実例を示してくれる」ようにするくらいかな

具体化

  • 「学習アプリ」という形で
    • 「自分の背中を押す自信をつける」
    • 「実力=自信は努力によって身につく」

(書きかけ)Django製フリマサイト「ホクマ」ができるまで part6

今回は、 4.3 「ホクマ」でつかったDjangoパターンとサイトデザイン について話します。

「ホクマができるまで」シリーズについて

シリーズの目次はこちらにあります。今回は第6回です。

swiftfe0.hatenablog.com

この度「ホクマ」という北大生限定フリマWebサービスを作りました。(GitHub)

https://hufurima.comhufurima.com

その作り方について大雑把に解説していくことで、(基本個人)学生によるWebサービス開発の流れを説明していきたいと思います。

(ただし、ビジネス的な観点はあまり考えて作っていません。 収益化の方法などは書いていかない予定なので気をつけてください。

使った技術

f:id:swiftfe:20181006223428j:plain

サービス開発の流れ(簡単に)

今回は「 4.3 「ホクマ」でつかったDjangoパターンとサイトデザイン 」について書いていきます。

4.3 「ホクマ」でつかったDjangoパターンとサイトデザイン

前回は、以下のようなことについて書きました

  • フリマサイト「ホクマ」のモデル設計
  • インフラを含めた技術構成

今回は、以下のような話をします。割とこの辺りは重要なところかもしれません

  • その他Djangoについての細かいこと
  • サイトのデザインについて

4.3.1 Djangoについての細かいこと

ここでは、Djangoで使った細かいクラスやモジュールについて話します

4.3.2 サイトのデザインについて

正直、大部分は類似サービスである「nemche」様をパクりました。笑

safarichromeデベロッパーツールからhtmlとcssの構造をみて、それを真似ました。

また、bootstrap4を使ったのでCSSのコードも少なくスッキリしたコードになりました。

bootstrap4を使うと、以下のページのサイドバーから選んでいろんなサンプルが見れるので、基本はサンプルをコピペしてちょっと変えるだけで簡単にスタイルをつけることができます

getbootstrap.com

次回

次回は、以下の二つの話をする予定です

ついで: 僕のプログラミング歴について

以下の過去投稿にあります

swiftfe0.hatenablog.com

twitter.com

Djangoモデルからクラス図の自動生成

環境

macOS 10.14 Beta(18A384a) python 3.6.2

参考

stackoverflow.com

Graph models — django-extensions 2.1.3 documentation

tumblring.hdknr — Unknown command: graph_models - Django users |...

手順

適当にDjangoプロジェクトを作成

$ brew install graphviz $ pip install pygraphviz $ pip install django-extensions

settings.pyのINSTALLED_APPSに “django_extensions"を追加

$ python manage.py graph_models --pygraphviz -a -g -o my_project_visualized.png

すると、my_project_visualized.pngが生成されます。

結果

f:id:swiftfe:20181013023341p:plain

Django製フリマサイト「ホクマ」ができるまで part5

今回は、 4.2 「ホクマ」の機能構成・技術の話 について話します。

「ホクマができるまで」シリーズについて

シリーズの目次はこちらにあります。今回は第5回です。

swiftfe0.hatenablog.com

この度「ホクマ」という北大生限定フリマWebサービスを作りました。(GitHub)

hufurima.com

その作り方について大雑把に解説していくことで、(基本個人)学生によるWebサービス開発の流れを説明していきたいと思います。

(ただし、ビジネス的な観点はあまり考えて作っていません。 収益化の方法などは書いていかない予定なので気をつけてください。

使った技術

f:id:swiftfe:20181006223428j:plain

サービス開発の流れ(簡単に)

今回は「 4.2 「ホクマ」の機能構成・技術の話 」について書いていきます。

4.2 「ホクマ」の機能構成・技術の話

前回までは、開発初期の話をしました。具体的には以下のような話でした。

  • どんなものを作るかなんとなく決める
  • 具体的にどんなものを作るのかを考える・必須なことの列挙
  • ユーザーが操作する一連の流れをシンプルに作る
  • githubやweb上にある似たようなサービスを参考にしよう

今回は、もう少し開発が進んだ時点での話や、「ホクマ」の詳しい機能の構成や技術構成について話していきます。今回は、以下の二つの話をします

  • フリマサイト「ホクマ」のモデル設計(相当拙いものですが)
  • インフラを含めた技術構成

さらに次回で、以下の二つの話をする予定です

  • その他Djangoについての細かいこと
  • サイトのデザインについて

4.2.1 「ホクマ」のモデル設計

pygraphvizを使って、djangoのモデルのクラス図を自動生成してみました。

f:id:swiftfe:20181013023341p:plain

ごちゃごちゃしていてわかりませんね・・・一つずつ簡単に説明していきます

「ホクマ」で使ったモデルクラス

  • User: ユーザアカウント
  • Product: 商品
  • ProductImage: 商品の画像(複数あるため)
  • Chat: チャットルーム一つ
  • Talk: チャットメッセージ一通
  • UserRating: ユーザ評価
  • Notification: 通知(お知らせ)
  • TODO: TODO
    • RatingTodo: ユーザ評価を督促するTODO
    • ReportToRecieveTodo: 商品受け取りの報告を督促するTODO
  • Contact: お問い合わせ

そんなに多くないですね。ここだけ見ると、すぐに作れる人もいると思います。実際、そこまで複雑な機能が求められるかはユーザヒアリングをしないとわからないので、まずはこれくらいでいいのではないでしょうか。

一つずつ書いていきます。djangoのコードになっていますが、なんとなく構造はわかると思います

Userモデル

DjangoのAbstractBaseUserクラスを継承して作成しました。

class User(PermissionsMixin, AbstractBaseUser):
    username = models.CharField(
        ('username'),
        max_length=150,
        unique=True,
        help_text=(
            '英数字と@, ., +, -, _が使えます'),
        validators=[username_validator],
        error_messages={
            'unique': ("このユーザ名は既に登録されています"),
        },
    )
    email = models.EmailField(('email'), unique=True)
    intro = models.TextField(('intro'), max_length=200, blank=True)
    date_joined = models.DateTimeField(default=timezone.now, editable=False)
    is_active = models.BooleanField(default=False)
    icon = VersatileImageField('',upload_to='account',blank=True)
    EMAIL_FIELD = 'email'
    USERNAME_FIELD = 'username'

Productモデル

商品画像に関しては、ProductImageモデルが管理しています。Djangoは若干この関連付けが特殊jなような気がしてます。Productモデルは画像関係のカラムを持っていないんですね。しかし、実はこれでもProductインスタンスから、ProductImageを取り出すことができるんです。

詳しくは以下をどうぞ

多対一 (many-to-one) 関係 | Django documentation | Django

class Product(models.Model):
    seller = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='seller')
    title  = models.CharField('商品名', max_length=200, validators=[has_no_singlequote])
    description = models.TextField('説明文', max_length=2000)
    price = models.PositiveIntegerField('値段(円)', default=0)
    is_sold = models.BooleanField(default=False)
    created_date = models.DateTimeField(default=timezone.now)
    updated_date = models.DateTimeField(blank=True, null=True)
    wanting_users = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='wanting_users')
    buyer = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True, related_name='buyer')
    access_level = models.CharField('公開/非公開',
        max_length=10,
        choices=[(level.name, level.value) for level in AccessLevelChoice],
        default='public'
    )

    def update(self):
        self.updated_date = timezone.now()
        self.save()

    def __str__(self):
        return self.title

ProductImageモデル

class ProductImage(models.Model):
    image = VersatileImageField(
        '',
        upload_to='product', 
        blank=True,
        null=True
    )
    product = models.ForeignKey(Product, on_delete=models.CASCADE)

    def update(self):
        self.save()

    @property
    def thumbnail_url(self):
        if self.image and hasattr(self.image, 'url'):
            return self.image.thumbnail['600x600'].url

Chatモデル

商品の値段交渉や受け渡し方法の相談などをするためのチャットのためのモデルです。

ChatモデルとTalkモデルで分けています。

Chatモデルは以下の情報を持っています。チャットルームのような扱いです。

  • 商品(どの商品についてのチャットか)
  • 商品の売り手
  • 商品の買い手

Talkが実際のメッセージになります

class Chat(models.Model):
    product = models.ForeignKey(Product, on_delete=models.CASCADE, null=True) 
    product_seller = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True, related_name='product_seller') 
    product_wanting_user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True, related_name='product_wanting_user') 
    created_date = models.DateTimeField(default=timezone.now)
    updated_date = models.DateTimeField(blank=True, null=True)

    def update(self):
        self.updated_date = timezone.now()
        self.save()

Talkモデル

Talkモデルは以下の情報を持っています。実際のメッセージになります。

  • 話し手
  • チャットID(これでどのチャットルームで話されているか判定)
  • メッセージ本文
class Talk(models.Model):
    talker = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    chat = models.ForeignKey(Chat, on_delete=models.CASCADE, null=True)
    sentence = models.TextField(max_length=200)
    created_date = models.DateTimeField(default=timezone.now)
    updated_date = models.DateTimeField(blank=True, null=True)

    def update(self):
        self.updated_date = timezone.now()
        self.save()

UserRatingモデル

ユーザ評価のモデルです。

  • 商品ID
  • レビュアーID
  • レビュイーID
  • 評価値
class UserRating(models.Model):
    product = models.ForeignKey(Product, on_delete=models.CASCADE, null=True)
    rating_user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='rating_user')
    rated_user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='rated_user')
    rating = models.CharField(max_length=6)

Notificationモデル

お知らせ・通知のモデルです。商品が売れたりした時の通知などに使います。

  • 通知の受け手
  • 既読フラグ
  • 通知メッセージ本文
  • 通知にあるURL(このように分離しておくとHTMLとして表現しやすくなる)
class Notification(models.Model):
    reciever = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
    unread = models.BooleanField(default=True)
    message = models.TextField(max_length=256, null=True) 
    relative_url = models.TextField(max_length=256, null=True) 

TODOモデル(親クラス)

通知とほぼ同じなので省略

class Todo(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True)
    is_done = models.BooleanField(default=False)
    message = models.TextField(max_length=256, null=True) 
    relative_url = models.TextField(max_length=256, null=True) 
    created_date = models.DateTimeField(default=timezone.now)

    def done(self):
        self.is_done = True

    def update(self):
        self.save()

ReportToRecieveTodo

通知とほぼ同じなので省略

class ReportToRecieveTodo(Todo):
    product = models.ForeignKey(Product, on_delete=models.CASCADE, null=True)

    def set_template_message(self):
        self.message = '「'+self.product.title+'」の受け取りが完了しましたら、「商品を受け取りました」をクリックしてください'

RatingTodo

通知とほぼ同じなので省略

class RatingTodo(Todo):
    product = models.ForeignKey(Product, on_delete=models.CASCADE, null=True)

    def set_template_message(self):
        if self.user == self.product.seller:
            self.message = self.product.buyer.username+'との間での「'+self.product.title+'」の受け渡しの完了を確認しました。最後に購入者を評価してください。'
        else:
            self.message = self.product.seller.username+'との間での「'+self.product.title+'」の受け渡しの完了を確認しました。最後に出品者を評価してください。'

Contactモデル

問い合わせ(質問)についてのモデル。

  • 問い合わせ本文
  • メールアドレス
class Contact(models.Model):
    text = models.TextField(('お問い合わせ内容'), max_length=1000)
    email = models.EmailField(('メールアドレス'), default='')

4.2.2 インフラを含めた技術構成

技術構成図を再掲します。

f:id:swiftfe:20181006223428j:plain

だいたい以下のようにレイヤ分けされると思います。ここを詳しく話すと枝葉の話になるのでとりあえずここでは省略します。

ここについてはまた今度かきたいとおもいます。開発環境/QA環境/本番環境の3つに分けてdockerを使った開発について語ります多分。(11月)

  • アプリケーション
  • データベース
    • Postgres
  • Webサーバ
    • Nginx
    • Let's Encrypt(HTTPS対応)
  • その他
    • CentOS7
    • Docker
    • お名前.com(ドメイン取得)
    • ConohaVPS(配信サーバ)
  • メールサーバ

次回

次回は、以下の二つの話をする予定です

  • その他Djangoについての細かいこと
  • サイトのデザインについて

ついで: 僕のプログラミング歴について

以下の過去投稿にあります

swiftfe0.hatenablog.com

twitter.com

Django製フリマサイト「ホクマ」ができるまで part4

「ホクマができるまで」シリーズについて

シリーズの目次はこちらにあります。今回は第4回です。

swiftfe0.hatenablog.com

この度「ホクマ」という北大生限定フリマWebサービスを作りました。(GitHub)

hufurima.com

その作り方について大雑把に解説していくことで、(基本個人)学生によるWebサービス開発の流れを説明していきたいと思います。

(ただし、ビジネス的な観点はあまり考えて作っていません。 収益化の方法などは書いていかない予定なので気をつけてください。

使った技術

f:id:swiftfe:20181006223428j:plain

サービス開発の流れ(簡単に)

今回は「4.「ホクマ」を作り始める」について書いていきます。

4.「ホクマ」を作り始める

先に、「ホクマ」のレポジトリを挙げておきます。

github.com

コミットを見ると、初コミットは3月11日からでした。公式にリリースしたのは10月1日だったので、大体リリースまで7か月かかったことになりますね。

Commits · HUITCLUB/hokudai_furima · GitHub

しかし、実際の構想は2月中旬から始めていました。今回は、その構想段階からのお話をしていこうと思います。

4.1 「ホクマ」の構想を練り始める(コードを書く前)

コードを書く前に、まず「ホクマを作ろう!」と思い至った経緯から順に話していきます。

ちなみに、「ホクマ」は北大生限定のフリマWebサービスです。

hufurima.com

4.1.1 「ホクマ」を作った経緯

ホクマを作ろうと思い立ったのは、以下のような理由からでした。

  • 「何かDjangoで自分の代表作を作りたい」
  • 「北大生で、教科書を古本屋で買う人は多いが逆に売ると安くなってしまうので、高く売れるフリマサイトを作ればいけるのではないか」
  • 「北大生のためのサービスなら、使ってくれる人がいるだろう」(ユーザ数をある程度見込める)
  • 「サークルの後輩のロールモデルになりたい」

特に、何かWeb開発で何か自分の代表作を作らないと大学生活終われないと思ったのが大きいです。

正直今も昔もそこまでフリマにこだわってはいないのですが、ちょうど良いくらいの題材だったように思っています。

4.1.2 構想を固める

さて、作るもののコンセプトが決まったら、具体的にどんなものを作るのかを考えるフェーズに入ります。まずは、以下のように簡単に、必須なことだけを列挙しました。

  • 何を作るのか・どういう要素や機能があるか
    • 例: 出品・購入・アカウント登録・チャット
  • どうやって作るのか(どういう技術を使うのか)
    • 例: Django, Postgres, Nginx, Webサーバを立てて公開する方法
  • それは作れるか?
    • 決済はちょっときつそうー>手渡しでいいんじゃね?ー>待ち合わせしやすいようにチャット機能を強化しよう

特に、「それは作れるか?」の検討は重要です。とりあえず必須要素が作れるかは考えておかないと、後から無理そうだということになったときにきついです。

極端な例になりますが、「アニメ配信サービス」みたいなのを作ろうとしても、「配信するアニメデータ」は必須ですが、なかなか手に入らないと思います。これを考えずに配信サービスだけつくっても結局意味のないものになってしまいます。

4.1.3 とりあえずユーザー操作の流れに沿って作ってみる

次は、実際にユーザーが操作する流れに沿って作り始めてみました。とりあえず、ここでは細かいデザイン等は後回しで考えた方がいいと思います。コードも汚くなってしまいやすいので。

「ホクマ」の場合、以下の順番に開発していきました。

  1. アカウント登録機能
  2. 商品の出品・購入 1; 商品の検索
  3. チャット
  4. 細かいデザインや利用しやすい細かい気遣い

最初の段階では、開発に時間がかかるかもしれません。初期段階では時間をかけすぎないように、とりあえずシンプルに作ることが良いです。

CRUDができる簡単なものを最初は作れればOKです。

複雑な機能は後にした方がコードがシンプルになって読みやすく修正・拡張しやすいので、後々にも嬉しいです。

ユーザーが操作する流れに沿って作っていくことは割とモチベーションの維持につながります。まずは簡単な機能の積み重ねで一連の流れを作るだけでも、サービスの完成に近づいてくる実感を感じられるので、どんどんやる気が湧いてきます!

4.1.4 といっても、どうやってかけばわからないんですけど

これは僕もとても困りました。イメージとしては思いつくのですが、実際Djangoでどうやって書くのがベストなのか、安全なのかが全くわかりませんでした。

そういうときは、似たサービスをgithubやweb上からで探してみましょう。正直探すだけで1週間くらい使ったと思います。

「ホクマ」の場合、以下を参考にしました。

github.com

nemche

まとめ:「ホクマ」を作り始める

  • どんなものを作るかなんとなく決める
  • 具体的にどんなものを作るのかを考える・必須なことの列挙
  • ユーザーが操作する一連の流れをシンプルに作る
  • githubやweb上にある似たようなサービスを参考にしよう

次回

次回は、どうしようか未定です。Djangoの詳しい話や技術構成についての話に入っていこうと思います

ついで: 僕のプログラミング歴について

以下の過去投稿にあります

swiftfe0.hatenablog.com

twitter.com

Django製フリマサイト「ホクマ」ができるまで part3

「ホクマができるまで」シリーズについて

シリーズの目次はこちらにあります。今回は第2回です。

swiftfe0.hatenablog.com

この度「ホクマ」という北大生限定フリマWebサービスを作りました。(GitHub)

hufurima.com

その作り方について大雑把に解説していくことで、(基本個人)学生によるWebサービス開発の流れを説明していきたいと思います。

使った技術

f:id:swiftfe:20181006223428j:plain

サービス開発の流れ(簡単に)

  • 1 前提知識
  • 2 Djangoを始めた(Django Girls Tutorial)
  • 3 いろんなDjangoサイトを適当に作った
  • 4 「ホクマ」を作り始める
  • 5 開発を続けていくために
  • 6 開発ツールについて

今回は「2 Djangoを始めた(Django Girls Tutorial)」と「3 いろんなDjangoサイトを適当に作った」について書いていきます。

2 Djangoを始めた

part2で書いたように、Djangoを始めることになった僕ですが、以下のようにRailsの経験があり、Djangoにはある程度スッと入って行くことができました。

  • Railsの経験(同じような形式の言語違いのものを使ったことはあった)
  • 2週間もあればできるようなものしか作ったことがなかった
  • HTML・CSSがある程度読み書きできるようになっていた(jsはちょっとだけ)

しかし、実際にはRailsでのWeb開発からも半年ほど離れていたので、結局忘れていることも多かったです。Djangoを書きながら学び直していきました。

2. 1 Django Girls Tutorial

Djangoの入門は、[Django Grils Tutorial}(https://djangogirlsjapan.gitbooks.io/workshop_tutorialjp/content/)ではじめました。この他にDjango公式のチュートリアルもあるのですが、こちらのDjango Girls Tutorialは、

  • より初心者に優しい作り
  • windows, linux, macに対応
  • 実際にWebサイトの全世界公開までをサポート

と、非常に親切な内容です。とりあえずDjangoを使っていい感じのブログサイトを作れるという、かなりおすすめの内容になっています!(ただし、有志の作成なので、若干古くなってしまっているところがあり、そこが残念なところではあります。(英語版は新しい?))

僕はまずこのチュートリアルを動かすことで、Djangoの基本を知ることができました。

3 いろんなDjangoサイトを適当に作った

基本を抑えたら、そこをベースに色々いじって自分オリジナルのサイトを作っていきました。

Djangoの強みは、当たり前ですが、pythonのプログラムを自由に動かせるところです。python機械学習や画像処理系のライブラリが充実しているので、機械学習や画像処理の簡単なプログラムを動かしたりしてみました。

実際には、以下のようなアプリ(サイト)を作りました

  • アカウント登録機能付きブログサイト
  • OpenCVを使った画像アップロード・加工サイト
  • Seq2Seqという機械学習アルゴリズムを使ったチャットボットサイト

これらのサイトを自分で作るとなると、リファレンスやサンプルが必要になってきます。僕は以下のサイトでよく調べていました。

naritoブログさん

torina.top

narito.ninja

Django公式ドキュメント

Django ドキュメント | Django documentation | Django

上の「naritoブログ」さんは、日本語情報の少ないDjangoを調べて行く中でかなり使いました。最初に作った「アカウント登録機能付きブログサイト」はこの人のリポジトリを参考にしていました。(今確認したらリポジトリ消えていました・・・泣)

でも、読めるなら公式ドキュメントを読んでいくのがいいですね。Djangoは日本語情報が少ないので、公式ドキュメントの内容をちゃんと理解してないとエラーを解決できないことも割とあります。しかし、そのおかげで公式ドキュメントを読む大切さや、Django自体の理解(なんとなくコピペ的に使うのではなく、理解した上で使える)ができたので、決してマイナスではないですね。

日本語ドキュメントがないので、エラーが出た時など、ドキュメントから探しにくい情報は、Stack over flowなどの英語サイトを活用しましょう。英語情報への抵抗もDjangoのおかげで結構なくなりましたね。(僕はToeicは630点なので、まあ普通くらいの英語力だと思います)

最初の間は、一気に大きなものを作るというのではなく、小さなDjangoサイトをいくつか作ってみるのがいいと思います。 将来作りたいものにどんな機能が必要かな?と考えて、その機能を全部一緒のサイトで使うのではなく、いろんなサイトで少しずつ機能を使ってみて覚えて行くのがいいと思います。 具体的には、2、3週間で作れてしまうものがいいと思います。 挫折したらもったいないので、小さな完成を通して技術のストックを貯めていきましょう!

おまけとおさらい:Djangoのおすすめの勉強方法

  • まずはDjango Girls Tutorial または Django公式チュートリアルをやる(できれば公式をやるべき)
  • 公式ドキュメントやnaritoブログさんなどを読んで自分の作りたい機能を実装したサイトを何個か作ってみる
  • Dangoは日本語情報が少ないので、エラーなどはStack over flowなどの英語サイトを活用して解決しよう

次回

次回は、ついに「ホクマ」の作成を始める話に入っていきます!

ついで: 僕のプログラミング歴について

以下の過去投稿にあります

swiftfe0.hatenablog.com

twitter.com