tanamonの稀に良く書く日記

KEEP CALM AND DRINK BEER

職務経歴書・公開版

最終更新日
  • 2024/03/13 (未完成です)

この職務経歴書の目的

  • カジュアル面談などでの利用を想定しています
  • 長いので興味あるところだけ見ていただけたらと思います
  • 社名・サービス名などは全公開している性質上隠していますが、会話などでは可能な範囲でお答えします

目次

基本情報

職務要約

  • 基本は受託開発のWebアプリケーション開発者ですが、社内で他の社員ができない仕事を(私も未経験のまま)よく任されてきました

  • 具体的には、新卒直後のカラオケ楽曲作成ソフト、アプリ保守チームの立ち上げ、他社の炎上プロジェクトの火消し、オンプレ/クラウド移行の判断資料作成、中国でのiPad業務アプリ作成、生成AI調査などは知識ゼロから開始して結果を残しています

  • 上流工程に関しては、要件が固まってない中から固める作業や、発注単位を軸にしたマイルストーンへの分割の提案などの最上流から行った経験があります

  • マネージメントに関しては、通常の受託開発案件や前述のようなイレギュラー業務の中で、主に4-8名程度までのメンバーに対しては長くやってきています

自己PR

  • 職歴の多くがプロジェクト開始時に未経験の状態から始まって結果を出しており、ゼロからイチまでの仕事が得意です
  • 当初は乗り気ではないプロジェクトでも、やっているうちにだんだん楽しくなる(仕事の中で楽しみを探し出す)ことができます

社歴

3社目(2004-現在)

  • 業態
    • Web受託開発(メインはJava
  • 社員
    • 入社時5名、その後50名弱まで拡大
  • 職務
    • 見積もり・要件・開発・設計・実装・テスト・マネージメント・技術選定・パフォーマンスチューニング・業務改善提案・保守運用チーム立ち上げ・市場調査など
    • (多岐にわたるため詳しくは後述)
  • 居住・勤務地
    • 沖縄県(2012-現在)
    • 愛知県(2010-2012)
    • 東京都(2004-2010)

2社目(2001-2004年)

  • 業態
    • 金融系ベンチャー、銀行を介した手形売買Webシステムの開発
  • 社員
    • 入社時5名、その後15名前後まで拡大
  • 職務
    • Linuxサーバー環境構築、Java開発環境構築、Javaプログラミング

1社目(2000-2001年)

主な職務経歴

  • 自分が主体的に動いた特徴的な業務のみピックアップしています

2023年

  • ↓詳細TODO 受託開発会社としての生成AIへの向き合い方についてのレポート作成
  • ドローンを活用した沖縄県内でのビジネスの実現可能性についてのレポート作成

2018年

  • 急速に普及してきた技術について調査

2015-2017年

  • (愛犬介護のため時短勤務期間)
    • サーバーのメンテナンスなど細かい仕事が中心

2012年

2010-2011年

  • ↓詳細 サーバーリプレイスについて、オンプレ維持か(出てきたばかりの)クラウド移行かの判断材料となる検証レポートの作成

2010年

  • Oracle社のMySQL買収後「OracleからMySQLに移行すると安くなる」という検証を行い、結果としてOracle DBがMySQLと同程度まで大幅値下げされた

2007年

  • 大手通販サイトでリリース後の品質問題が起きた現場の火消し対応
  • 大手自動車メーカーのPrototype.js全盛期に新興のjQueryを猛プッシュして導入させた

2005-2008年

  • ↓詳細 受託開発チームの体制作りを行った

2001-2004年

  • Linux/Oracleサーバーのインフラ構築・Java開発環境構築業務を行う

2001年

  • ↓詳細 携帯電話用のカラオケ楽曲作成ソフトの作成

2000年(職歴ではないですが)

  • 卒業制作でキー・マウス・ゴミ箱に入れるアクションを監視してキャラが勝手に育つゲームを作成(今起動するとウイルス判定される)

職務詳細

クラウド移行検証

概要

  • 所属 3社目
  • 商流 大手自動車メーカー → (SI子会社・発注だけ) → 自社
  • 時期 2010-2011年
  • 期間 1年
  • 人数 3-5人
  • 役割 調査・リーダー(force.comの途中から)

状況

  • 大手自動車メーカーで5年ごとに行っているサーバーの更新時期になった
  • 現状のまま自社データセンター内に置くか、近年出てきたAWSを初めとするクラウド環境に移行するかの判断を行いたい
  • クラウド選定の候補は以下の3社、これらと自社DC配置の比較をした結果を判断材料にしたい
    • Amazon Web Services
      • 最有力候補
    • Microsoft Azure
      • 付き合いがあるので比較することになった(当て馬)
    • Salesforce force.com
      • 完全に機能不足だが、商流上のSI子会社に資本を入れるという裏技で候補に入る
  • 社内でクラウドに詳しい人はいない
  • しかしこの案件を断ると来年の移行案件の受注が危うくなるため、会社としては断りたくない

force.com検証

課題

  • 当初、自社の私ではない人物が行くことになっていたが、直前で家庭の事情で行けなくなり、私が代理で担当することになった
  • また、SI子会社の意向で自社は私のみ、他2人が他社、リーダーも他社となった
  • もともとやる気があまりなかったのと、リーダーが他社でまとめるという体裁で単価を下げられたため、振られた仕事だけやろうと動いていたが、残り2週間になってもレポートが全くできてなかったことから私が(説得されて仕方なく)巻き取ることになった

行動

  • 今までやる気が出なかったのを「できないことをできると喧伝するforce.comのコンサルタントを見返したい」という気持ちでやる気を入れる
  • 検証してレポートにまとめるという仕事自体が初めてだったので、作文するより箇条書きで埋められるパワポで作成することを選択する
    • 目次を作って説明の順序立てを決め、
    • レポートの完成系を打ち合わせして、
    • 埋められるところを箇条書きで埋め、
    • 足りないところを分担して調べて埋めていった

結果

  • 結果として128pのレポートになった
  • ボリュームだけでなく内容も網羅的であったと評判だった
    • 特に「force.comへの移行は現実的ではない」という内容を数値根拠を基にコンサルタントの矛盾を詰めて撤回させることができた点を評価された
  • が、評判になりすぎて、次の検証に指名されることになった

Azure検証

TODO

課題

行動

結果

AWSの検証

TODO

課題

行動

結果


受託開発チームの体制づくり

概要

  • 所属 3社目
  • 商流 大手自動車メーカー → SI子会社 → 自社
  • 時期 2005-2009年
  • 期間 5年(断続的)
  • 人数 1人(開発案件と並行して実施、開発案件としては3-6人で時期により変動)
  • 役割 案件提案・発注単位の調整・スケジュール管理・ドキュメント様式変更・プロジェクトリーダー・保守運用チーム立ち上げ

状況

  • 転籍によりウォーターフォール型の受託開発の仕事を始めたが、どう考えても効率が悪いやり方をしているように見えた
  • 社内のメンバーに聞いても誰もこの状況を問題視していなかった
  • 効率が悪いことがストレスになっていたが、PL業務として客先に出向く必要が出たタイミングで勝手に動いて改善していくことに決めた

課題

  • あらゆる点で問題があったので、大きなものだけ記載

  • 納品物

    • 規定されたドキュメントが実用的ではなかった
      • Web向けの様式ではなくC/Sシステム用のものがベース
      • 誰もドキュメントを元に開発していない、検収をもらうための作業(今でいうブルシットワーク)となっていた
  • プログラム品質

    • テスト工程後のバグが多かった
    • さらにバグが多いことから、検収後に無償でバグではない修正作業まで行わされていた
    • 自動テストが全く無い
  • 開発環境の不統一

    • 開発者の環境によって動く動かないがよく発生していた
    • AさんとBさんとでFormatterの設定が違うのでdiffが機能しないなど
  • 仕事量の季節変動が激しい

    • 顧客は99%が同じなのに発注時期により忙しい・暇の差が激しかった
    • 特に冬が激務な一方、春は全く仕事が無い状態

行動

  • 個々の提案は短期的には追加作業が発生する上に納品物が減ることで受託開発としてはマイナスにしかならないため、まずは自分がPLとして受けた案件の隙間作業として進めた
  • 当初はウォーターフォールの標準開発手法から取り入れることを考えたが、実情に沿ってなかったので、現場の必要最低限を積み上げていくようにした

  • 納品物の改善

    • 一度決めた納品物を変えるのには相当の理由が必要で、誰もが及び腰だったが、新しいほうが便利という点を前面に出して改善していった
    • 発注元では企画チームが要件定義までレビュー、開発チームが設計書以降のレビューと分離していたので、基本設計書を両者が見れる形式への変更を提案した
    • 詳細設計書は誰も見てないことがわかったので廃止を提案した
    • その他、細かい要素の変更・削除の提案を随時していった
    • 改修時に既存ドキュメントも随時修正していくようにした
  • プログラム品質改善

    • 単体・結合テストのスコープを再定義した
      • 単体テストは基本設計書を元に作成し実装者スコープで担保、結合テストは要件定義書を元にチームスコープでの担保とし、他社システム連携がある場合は統合テストとした
    • テスト工程後のすり抜けバグは課題として記載し、次回以降のテスト項目として反映させるようにした
  • 開発環境の統一化

    • 開発環境構築の手順書作成(Formatter, Linterの設定など)
    • デプロイの自動化
  • アプリ保守サービスの立ち上げ

    • 検収後の無償作業がなぜ発生するのかを探った結果、少額の予算は決済手続きが面倒だからという結論に行き着いた
    • そのため、固定費(時間枠)で何でも作業するアプリ保守サービスの提案書を作成して受け入れられた
    • 工数は毎月レポートを出し、余るようであれば改善要望として提案して作業をできるようにした
    • また、自社の納品物以外でも工数が積めれば何でも作業する
  • 発注単位の改善

    • 要件工程でロードマップを作成するようにして、発注を分割(分割リリース)するように調整(説得)した
    • 発注単位が長いと資金繰り上の問題が起こるため、3-4ヶ月を最長とした

結果

  • 納品物

    • 改修後、SI子会社共通の納品物として再定義され、自社の納品物がサンプルとして提示されるようになったので、それなりに評価されるものができたのではと思われる
  • プログラム品質

    • 効果の検証をしていなかったため、世間一般程度になったという程度の認識でいた
    • 中国案件(2012)の際に他社が1000件以上バグを課題管理表に書く中で自社は3件のみで、「テストをしていないのではないか?」というレベルで疑問に持たれたことがあって初めて品質向上を実感した
  • アプリ保守

    • 他社開発のものでも受けつけるようにしたため、「不祥事で俳優の写真が使えなくなったから急いで差し替えて」といった作業ができるようになり、大変喜ばれた
  • 仕事量の季節変動

    • 春以外は少し改善された
      • 春:全く仕事が無い → (変化なし)
      • 夏:たまにある → そこそこある
      • 秋:多少ある → 忙しい
      • 冬:激務 → 忙しい
    • 春期の改善についてはクラウド検証(2010-2012)時期に行った
  • その他、想定していなかった良い副作用

    • アプリ保守で毎月固定費で入金があるため、資金繰りが良くなった
    • ロードマップがあるため、突発的な仕様追加を次の発注で辻褄を合わせるという調整ができるようになった

携帯電話用のカラオケ楽曲作成ソフトの作成

概要

  • 所属 1社目
  • 商流 携帯電話会社 → 楽曲作成会社 → 自社
  • 時期 2000-2001年
  • 期間 6ヶ月
  • 人数 1人 + リリース直前にバイト1人
  • 担当役割 要件・設計・開発・テスト・課題管理
  • 使用技術 Visual C++ (MFC), MIDI再生(自作), Crash検知DLL(自作)

状況

  • 新しい携帯端末の目玉機能として世界初のMIDIカラオケ機能を搭載したものを発売することが決定
  • 発売に合わせてカラオケ楽曲作成ソフトの開発が必要になった
  • 開発会社が見つからなかったようで、自社まで依頼が降りてきた時にはスケジュールはかなり押していたが、携帯端末の発売日はずらせない
  • さらに発売日までにソフトを利用した楽曲を最低1000曲用意する必要があった
  • 開発メンバーは自分のみで、追加は期待できない

課題

  • 自分の知識が不足だらけだった
    • そもそも社会人1年生
    • 他社と共同してソフトウェアを開発する方法がわからない
    • C++は入門書を読み終えたレベルで、Windows用のGUIプログラムを作った経験が無い
    • 使用技術、特にMIDIファイルの再生方法がわからない
  • 間に合わないような気がするが、どの程度オーバーするのかも(知識不足ゆえ)わからない
  • 会社の資金繰り上、検収が延期されるとまずい

行動

  • 手戻りを許容できる余力は無く、後工程の楽曲作成も同様だと想像できたので、主要機能の作成前に手戻りの回避策から着手した
    • ソフトのクラッシュ時に自動バックアップを取る仕組みを作った
    • ソフトの更新時に旧バージョンのファイルを自動更新するようにした
  • 並行して必要な機能の洗い出しを行い、工数をつけ、楽曲作成チームに欲しい順番を決めてもらった
  • 知識不足は書籍で賄うとして、本をタイトルだけ見て買い漁った
    • MIDI関連だけは適切なライブラリも情報も無かったためフル実装した
  • 資金繰りは(責務範囲外として)考えないようにした
  • とにかく残業した

結果

  • 携帯端末の発売日より前に主要機能は完成した
  • 楽曲も予定以上の1200曲以上作成できた
  • クラッシュ検知でバックアップを取る仕組みが高評価だった
    • 当初は先にそれ作るの?と懐疑的だったそうだが、手戻りの心配がなくなれば楽曲作成に人海戦術を用いる決断ができるとわかり効率が上がったとのこと

テクニカルスキル

開発(言語・フレームワーク

Python 6年(v3.7あたりから現在)

  • クローラー(Scrapy)の業務経験あり
  • 機械学習(TensorFlow)の業務経験あり
  • Web API(FastAPI, Flask)の業務経験あり
  • トレンドは追いかけている

Java 10年以上

  • 主にWebアプリの業務経験
  • Struts, Struts2, Seasar2, Springなど時代に合わせた経験あり
  • 自社フレームワークの改修や拡張ライブラリの作成経験もあり
    • 拡張ライブラリは取引先の自動車メーカーに売却した
  • ここ数年は使っていない

TypeScript/JavaScript 10年以上

  • JavaScriptjQuery登場初期から(これは流行ると思って)本格的に業務に利用
    • 勢いで取引先の自動車メーカーに提案して導入した
  • TypeScriptはReact登場以降に学習(業務経験は簡単なもののみ)
  • React, Next, Vue, Nuxtは入門書を読んだレベル(自己学習・業務経験なし)
  • トレンドは追いかけている

PHP 10年以上

Ruby

C/C++ 2年

  • Windowsアプリの開発経験あり
  • ただし1社目(2000-2001年)の使用技術なので知識は古い

スマホアプリ(iOS, Android

  • Kotlin, Swiftは入門書を読んだレベル(業務経験なし)

インフラ

Linux

  • 基本的な構築・運用はできる(業務経験あり)
  • 業務の必要に応じて学んでいるので、OOM Killerなどピンポイントにハマった部分は少しだけ詳しい

MySQL

  • 5.0から5.7まで業務経験あり(8は自己学習)
  • パフォーマンスチューニングの業務経験あり

Oracle Database

  • 8iから11gまで業務経験あり
  • パフォーマンスチューニングの業務経験あり

PostgreSQL

  • 入門書を読んだレベルでは理解しているが、業務経験はあまりない(構築とメンテナンス程度)

運用・保守

TODO

Pythonのloggingでエラーがあった場合だけ遡って出力する

クローラーみたいなものを作ってるとログがやたら出て困る。

今日動かしたやつは200MBを超えていた。そして開いたらVSCodeが不安定になった。

再起動したらこのメッセージ。いや、今まで散々Pythonでコード書いてたじゃない。何忘れてるの。

ログは見たいが出力量は減らしたい

ログが出すぎる問題への対処の基本はパッケージ単位で出力ログレベルを上げることだけど、クローラーのような、相手側のデータの都合でこちらの処理の成否が決まるようなプログラムは出力レベルを上げるとエラーを見てもわからないことが多い。必ず入る想定(例えばニュース記事のタイトル)のXPathの結果がNoneなのはなぜ?みたいなのは、UnitTestで先回りして品質を上げるのも難しい。

そうなると、ある程度ざっくりとした想定で作ったプログラムに処理の途中経過のログをDEBUGレベルなどで多めに出すようにしておいて、ひたすら動かして異常データを検出してから、それをテストケースにしながら修正する、という泥臭い作り方になる。当然ログ出力の量は増える。

とはいえ、ほぼ正常なログの中からエラーとなったデータを探すのは面倒なので、ログ出力のコードは書くが実際の出力はログレベルの以外の方法で抑制して欲しい、という要件が出てくる。

こういう、ある種のとんち的な要求に対する実装は検索で探しても見つからない(そもそも検索ワードがわからない)ので、最初から諦めてとりあえず自前で簡単なものを実装してみた。

コード

import logging.config

logger = logging.getLogger(__name__)


class MyMemoryHandler(logging.handlers.MemoryHandler):

    def emit(self, record):
        if self.capacity <= len(self.buffer):
            del self.buffer[0]
        super().emit(record)

    def shouldFlush(self, record):
        return (record.levelno >= self.flushLevel)

    def flush(self):
        # memo: logging.shutdown()からはshouldFlush()を経由せずに呼ばれるので再チェックがいる
        if self.buffer and self.shouldFlush(self.buffer[-1]):
            super().flush()


if __name__ == '__main__':
    if False:
        target_handler = logging.FileHandler(filename='./logtest.log', mode='w')
    else:
        target_handler = logging.StreamHandler()
        target_handler.setFormatter(logging.Formatter("%(asctime)s [%(levelname)s] (%(filename)s) %(message)s"))

    handler = MyMemoryHandler(capacity=3, flushLevel=logging.ERROR, target=target_handler)
    logging.basicConfig(level=logging.DEBUG, handlers=[handler])

    for n in range(25):
        if n % 10 == 9:
            logger.error(n, stack_info=True)
        else:
            logger.debug(n)

    logger.debug('end')  # 出力されない

loggingパッケージのMemoryHandlerからの拡張。このクラスは外部などに非同期でログ出力する用途で、ログ出力を同期から非同期に変えるために一度バッファリングするという目的のものだけど、今回の用途に合ってたので使った。

エラーの時に遡ったログと合わせてSlackに投げるみたいなのもできるので、このクラスのベースでいいと思う。

引数はこれら。

  • capacity: 貯めておくログの行数。flushLevel以上となったログを含むので、この値-1の分だけ遡る
  • flushLevel: ログを出力するトリガーとするエラーレベル
  • target: flushLevel以上のログが出た時に渡すhandler

ちなみに、del self.buffer[0]のところが計算量O(n)と遅いので、capacityはあまり巨大な値にしないほうがいいと思います。

実行結果

2019-07-15 03:39:05,150 [DEBUG] (logtest.py) 7
2019-07-15 03:39:05,150 [DEBUG] (logtest.py) 8
2019-07-15 03:39:05,150 [ERROR] (logtest.py) 9
Stack (most recent call last):
  File "logtest.py", line 35, in <module>
    logger.error(n, stack_info=True)
2019-07-15 03:39:05,150 [DEBUG] (logtest.py) 17
2019-07-15 03:39:05,150 [DEBUG] (logtest.py) 18
2019-07-15 03:39:05,150 [ERROR] (logtest.py) 19
Stack (most recent call last):
  File "logtest.py", line 35, in <module>
    logger.error(n, stack_info=True)

ERROR出力の時に2行遡って出力されます。

参考

緯度経度の省略はlat/lng、lat/lon、lat/longのどれが多数派なのか

タイトルのとおりなのですが、気になったので調べてみました。

ちなみに、調べる前はlat/lng派でした。

Google Trendsで比較

省略しないlatitude/longitudeを加えてGoogle Trendsで比較してみました。

f:id:tanamon:20190710175931p:plain https://trends.google.co.jp/trends/explore?date=today%205-y&q=lat%2Flon,lat%2Flng,lat%2Flong,latitude%2Flongitude

結果はlat/long >>> latitude/longitude > lat/lon >>> lat/lngでした。

lat/lngが少ないのが意外でした。けっこう使われてた記憶があるんですが、日本限定なんでしょうかね。

longは予約語に入っている言語もあるのですが、地図を一番使う環境のJavaScriptでは予約語になってないので、気にしないのが主流ということなんでしょうか。

というわけで、これからはlat/longを使おうと思います。

緯度経度と経度緯度

緯度経度を経度緯度と逆順で書く流派もあるので、ついでにその比率も調べてみました。

f:id:tanamon:20190710175936p:plain

latitude/longitude, longitude/latitude - Google トレンド

意外と拮抗していますが、やはり緯度経度の順番が多いようです。

この順番違いがバグを生むので、緯度経度の順番で統一して欲しいです。

GCEのf1-micro環境でPythonが動く環境を構築する

Google Compute Engineの無料枠のf1-micro環境でPythonの実行環境を構築した記録です。

OSはUbuntu 19.04にしました。

% gcloud compute ssh [INSTANCE_NAME]

$ cat /etc/os-release | grep VER
VERSION="19.04 (Disco Dingo)"
VERSION_ID="19.04"
VERSION_CODENAME=disco

スワップ領域が無い

アップデートや必要ライブラリを入れる前にスワップ領域を作ります。

f1-microはRAMが600MBしか無いくせに、初期状態ではスワップ領域が未設定なのです。

$ cat /proc/swaps
Filename                Type        Size    Used    Priority

そのままだとpipenv installでOutOfMemory Killerというシリアルキラーがわりと現れる世紀末環境なので、設定は必須です。

スワップ領域を作る

スワップ領域のサイズは、RAMが2GBまでの環境ではRAMの2倍が一般的らしい。

access.redhat.com

慣習に従って、1.2GBで作ります。

$ sudo dd if=/dev/zero of=/var/swapfile bs=1M count=1200
1200+0 records in
1200+0 records out
1258291200 bytes (1.3 GB, 1.2 GiB) copied, 43.4791 s, 28.9 MB/s

$ sudo chmod 600 /var/swapfile

$ sudo mkswap -L swap /var/swapfile
Setting up swapspace version 1, size = 1.2 GiB (1258287104 bytes)
LABEL=swap, UUID=1ec17506-09a4-4517-911d-c3e3e0f45428

$ sudo swapon /var/swapfile

$ cat /proc/swaps
Filename                Type        Size    Used    Priority
/var/swapfile                           file        1228796 0   -2

再起動時にスワップ領域が自動的にmountするようにする

このままだと再起動時に有効にならないので、fstabに書きます。

$ echo '/var/swapfile swap swap defaults 0 0' | sudo tee -a /etc/fstab
/var/swapfile swap swap defaults 0 0

確認のため再起動してみる。

$ exit

いったんsshを終了させて、gcloudコマンドで再起動します。

% gcloud compute instances stop [INSTANCE_NAME]
% gcloud compute instances start [INSTANCE_NAME]
% gcloud compute ssh [INSTANCE_NAME]

ログインできたらマウントの確認。

$ cat /proc/swaps
Filename                Type        Size    Used    Priority
/var/swapfile                           file        1228796 0   -2

マウントされていた。

Ubuntuのアップデート

$ sudo apt update

$ sudo apt upgrade -y

anyenvのインストール

aptで入れてもいいけど、OS配布版は古いバージョンになったりするので、anyenv + pyenvを使う。

今回はPythonしか使わないのでpyenvを直接入れてもいいけど、別の言語の時でも環境構築を同一手順にしたいのでanyenvから入れる。

github.com

github.com

$ git clone https://github.com/anyenv/anyenv ~/.anyenv

$ cat << \EOS >> ~/.bashrc
if [[ -d $HOME/.anyenv ]]; then
  export PATH="$HOME/.anyenv/bin:$PATH"
  eval "$(anyenv init -)"
fi
EOS

$ exec $SHELL -l
ANYENV_DEFINITION_ROOT(/home/user/.config/anyenv/anyenv-install) doesn't exist. You can initialize it by:
> anyenv install --init

$ anyenv install --init
Manifest directory doesn't exist: /home/user/.config/anyenv/anyenv-install
Do you want to checkout ? [y/N]: y
...
Completed!

$ anyenv --version
anyenv 1.1.1

pyenvのインストール

依存ライブラリを入れる。

公式サイトによると、以下のライブラリが必要らしい。

$ sudo apt-get install -y make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev
xz-utils tk-dev libffi-dev liblzma-dev python-openssl git

ログを見るとbuild-essential, make, wget, curlはすでにあった。gitもすでに使ってるのである。

Minimal版を想定したライブラリ構成だろうか。

$ anyenv install pyenv

$ exec $SHELL -l

$ pyenv --version
pyenv 1.2.12-4-g525dac36

Pythonのインストール

現在の最新版3.7.3を入れる。

$ pyenv install 3.7.3

$ pyenv global 3.7.3

$ python --version
Python 3.7.3

Pipenvのインストール

pipenvの作業ディレクトリはプロジェクト配下のほうが好きなのでPIPENV_VENV_IN_PROJECTの設定をしておく。

$ pip install pipenv
...
You are using pip version 19.0.3, however version 19.1.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.

$ pip install --upgrade pip

$ echo "export PIPENV_VENV_IN_PROJECT=true" >> ~/.bashrc

$ pipenv --version
pipenv, version 2018.11.26

pipが古いと言われたので、ついでに更新した。

(参考)aptでPythonを入れる場合

もし、aptで直接入れたい場合は、以下の手順で入れられる。

$ sudo apt install -y python3 python3-pip python3-venv

$ pip3 install pipenv

$ echo "export PIPENV_VENV_IN_PROJECT=true" >> ~/.bashrc