よしたく blog

ほぼ週刊で記事を書いています

コードをきれいにするため、pycodestyleを使ってみた

f:id:yoshitaku_jp:20180728144033p:plain

プログラムコードはきれいにしておきたいですよね。そのために様々な言語で規約もあるかと思います。 Pythonを独学で書いている自分としてはサンプルコードを見て真似して感覚的に覚えていったりもしました。正しいものがあるなら、それを見て正しく書いていきたいし、自分の目視じゃなくてチェックもして欲しい!そんなときに便利なのがpycodestyleです!

github.com

これを使えば、自分が今書いてるコードがPEP8にそって書かれているかチェックしてくれます!

インストール

pip install pycodestyle

使い方

対象のhoge.pyファイルをチェックするときは下のように実行します!

pycodestyle hoge.py

試しに自分で作っているスクレイピングのツールを実行してみると…

yoshitaku$ pycodestyle scraping_netkeiba/getHtml.py 
scraping_netkeiba/getHtml.py:16:1: E302 expected 2 blank lines, found 1
scraping_netkeiba/getHtml.py:24:1: E302 expected 2 blank lines, found 1
scraping_netkeiba/getHtml.py:28:80: E501 line too long (107 > 79 characters)
scraping_netkeiba/getHtml.py:31:1: E302 expected 2 blank lines, found 1
scraping_netkeiba/getHtml.py:31:23: E231 missing whitespace after ','
scraping_netkeiba/getHtml.py:38:1: E302 expected 2 blank lines, found 1
scraping_netkeiba/getHtml.py:38:22: E231 missing whitespace after ','
scraping_netkeiba/getHtml.py:42:43: E712 comparison to True should be 'if cond is True:' or 'if cond:'
scraping_netkeiba/getHtml.py:44:33: E221 multiple spaces before operator
scraping_netkeiba/getHtml.py:44:46: E712 comparison to False should be 'if cond is False:' or 'if not cond:'
scraping_netkeiba/getHtml.py:59:38: E251 unexpected spaces around keyword / parameter equals
scraping_netkeiba/getHtml.py:59:80: E501 line too long (87 > 79 characters)
scraping_netkeiba/getHtml.py:61:80: E501 line too long (81 > 79 characters)
scraping_netkeiba/getHtml.py:73:38: E231 missing whitespace after ','
scraping_netkeiba/getHtml.py:75:53: E231 missing whitespace after ','
scraping_netkeiba/getHtml.py:80:44: E231 missing whitespace after ','
scraping_netkeiba/getHtml.py:80:55: E712 comparison to False should be 'if cond is False:' or 'if not cond:'
scraping_netkeiba/getHtml.py:80:80: E501 line too long (114 > 79 characters)
scraping_netkeiba/getHtml.py:80:95: E231 missing whitespace after ','
scraping_netkeiba/getHtml.py:83:48: E221 multiple spaces before operator
scraping_netkeiba/getHtml.py:89:48: E221 multiple spaces before operator
scraping_netkeiba/getHtml.py:92:49: E712 comparison to True should be 'if cond is True:' or 'if cond:'
scraping_netkeiba/getHtml.py:100:16: E221 multiple spaces before operator
scraping_netkeiba/getHtml.py:102:34: E231 missing whitespace after ','
scraping_netkeiba/getHtml.py:103:38: E231 missing whitespace after ','
scraping_netkeiba/getHtml.py:104:42: E231 missing whitespace after ','
scraping_netkeiba/getHtml.py:106:80: E501 line too long (81 > 79 characters)
scraping_netkeiba/getHtml.py:108:56: E231 missing whitespace after ','
scraping_netkeiba/getHtml.py:109:35: E712 comparison to False should be 'if cond is False:' or 'if not cond:'
scraping_netkeiba/getHtml.py:111:53: E221 multiple spaces before operator
scraping_netkeiba/getHtml.py:114:56: E221 multiple spaces before operator
scraping_netkeiba/getHtml.py:114:80: E501 line too long (81 > 79 characters)
scraping_netkeiba/getHtml.py:121:5: E722 do not use bare 'except'

辛い。 まぁ一つ一つ地道に直していこう。

なんとなく怒られている内容もわかりますが、エラー内容の一覧もあるのでご参照ください

Introduction — pycodestyle 2.4.0 documentation

DjangoでトップページにアプリのViewを表示する方法

f:id:yoshitaku_jp:20180711100334p:plain


はじめに

urls.pyの書き方を調整していたらハマったのでメモ。 DjangoでトップページにアプリのViewを表示したかったのに、設定値が足りなかったのかうまくいかず四苦八苦していました。正解パターンをブログに記しておこう。なんでできなかったんだ…

hoge_project/config/urls.pyの記述

プロジェクト全体のurls.pyでは、様々なurlを読み込んでいると思います。今回はfugaアプリのurlsを読み込む設定だけ追加で記述します。

urlpatterns = [
    path('admin/', admin.site.urls), #デフォルトで存在
    path('', include('fuga_app.urls')), #作成したアプリケーションを追加
]

hoge_project/fuga_app/urls.pyの記述

hoge_project/config/urls.pyで読み込んだファイルの設定です。

from django.conf.urls import include, url
from . import views

urlpatterns = [
    url('', views.index, name='index'),
]

これで、viewのindexに紐付いているやつが表示されるぞ。

おわり

Djangoの設定をHerokuの環境とローカルの環境で分ける方法

f:id:yoshitaku_jp:20180711100334p:plain

はじめに

Djangoで作ったWebアプリケーションをHerokuにアップロードしようとしたとき、Herokuの環境とローカルの環境で使っているDBが違ったので、設定を使い分けられたらいいなと思っていました。環境ごとに差異を出さず開発していくほうがいいと思いますが、今回はHerokuの環境とローカルの環境で設定をわける方法を知ったのでメモしておきます。

Herokuの環境へのデプロイ方法はこちら

yoshitaku-jp.hatenablog.com

local_setting.pyの作成

settings.pyがあるディレクトリにlocal_setting.pyを作成し、ローカルだけで使う設定を記述しておきます。HerokuではPostgreSQLが使われているので、settings.pyがいろいろ変更されているかと思います。ここではDjangoのプロジェクトを作った際のデフォルト設定をlocal_setting.pyに書いておきます。

import os

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'SECRET_KEY'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = ['*']

# Application definition
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    'ownercard',

    'django.contrib.auth',
    'django.contrib.sites',
    'allauth',
    'allauth.account',
    'allauth.socialaccount',
    'allauth.socialaccount.providers.twitter',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'config.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'config.wsgi.application'


# Database
# https://docs.djangoproject.com/en/2.1/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}


# Password validation
# https://docs.djangoproject.com/en/2.1/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


# Internationalization
# https://docs.djangoproject.com/en/2.1/topics/i18n/

LANGUAGE_CODE = 'ja'

TIME_ZONE = 'Asia/Tokyo'

USE_I18N = True

USE_L10N = True

USE_TZ = True

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.1/howto/static-files/

STATIC_ROOT = os.path.join(os.path.dirname(BASE_DIR), 'static')
STATIC_URL = '/static/'

STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'static'),
)
AUTHENTICATION_BACKENDS = (
    # Needed to login by username in Django admin, regardless of `allauth`
    'django.contrib.auth.backends.ModelBackend',

    # `allauth` specific authentication methods, such as login by e-mail
    'allauth.account.auth_backends.AuthenticationBackend',
)

settings.pyの修正

末尾にlocal_setting.pyを読み込む設定を追加します。try exceptの形にし、ファイルがなくても処理が進むようにしておくのが通例のようです。これは他の分野にも応用できそうなので覚えておこう。

#settings.pyの末尾に追加
try:
    from local_settings import *
except ImportError:
    pass

.gitignoreにlocal_setting.pyの追加

config/local_setting.py.gitignoreに追加しておかないと、ローカルの設定がアップロードされてしまいます。

これで、Herokuの環境とローカルの環境で設定の使い分けができます。

ローカル環境でのサーバ実行コマンド

実際にローカルサーバを起動するためにpython manage.py runserverコマンドを実行し、サーバを起動させます。

明示的に起動させるには下記のようにするといいようです。

python manage.py runserver --settings config.local_settings

#100DaysOfCode の60/100が過ぎました

f:id:yoshitaku_jp:20180730014526p:plain

目次

  1. はじめに
  2. 履歴
  3. まとめ

はじめに

無事にサボることなく60日目を迎えました。作業はやってるんだけど、つぶやくのは忘れている傾向にあるので気をつけていきたい。最近はコード書かないと気持ち悪くなってきたのでいい意味で習慣化できているなぁ

前回

yoshitaku-jp.hatenablog.com

履歴

まとめ

他にもポジティブに継続できる企画無いかなぁ

Pythonでunittestする

f:id:yoshitaku_jp:20180728144033p:plain

はじめに

Pythonはずっと独学でやってきたのですが、最近はどこに行っても恥ずかしくないようにお作法を学び始めています。 その一つがテストのやり方を抑えておこうというものです。 もちろん普段の業務ではテストしていますが、 個人的にPythonでガチャガチャ遊んでいるプログラムでもテストをやってソースコードをきれいに保ちたいと思いました。 今回はその過程で学んだことをまとめておきます。

Pythonでは最初からユニットテストフレームワークが組み込まれているのでunittestを使います。

26.4. unittest — ユニットテストフレームワーク — Python 3.6.5 ドキュメント

ディレクトリ構成

Pythonでは下記のようなテストディレクトリ構成にするのが一般的なようです。

.
├─dir
│ └─sample.py
└─tests
  └─test_sample.py

作成したプログラムとテスト用プログラムの2つを見ていきます。 しかし、ここで足し算プログラムなどやっても面白くないので、自分が実際に使ったプログラムで見てみます。

#dir/getHtml.pyの中身

def rtnBS(url):
    """
    htmlを引き渡し、bsObjを返す
    """
    html = urllib.request.urlopen(url)
    bsObj = BeautifulSoup(html, "html.parser")
    return bsObj

テスト実行のコマンド

#tests/test_getHtml.pyの中身

import unittest
from bs4 import BeautifulSoup

from dir.getHtml import rtnBS

class TestSample(unittest.TestCase):
    def test_rtnBS(self):
        url = 'https://www.yahoo.co.jp/'
        bsObj = rtnBS(url)
        beautifulsoup = BeautifulSoup()
        self.assertEqual(type(bsObj),type(beautifulsoup))

これはself.assertEqualで、取得したオブジェクトがbeautifulsoupかどうかをチェックしています。

実行する際のコマンドはtests/test_getHtml.pyです。

python -m unittest tests/test_getHtml.py

補足ですがdiscover testsに変更するとtestsディレクトリ配下のすべてのテストを実行できます。多くのテストケースを作った際はこちらに切り替えるべきでしょう

python -m unittest discover tests

Maker Faire Tokyo 2018に行ってきました

f:id:yoshitaku_jp:20180810005720j:plain


はじめに

8月4日にMaker Faire Tokyo 2018に行ってきました! ちょっと鮮度が落ちていますし、写真を上げるだけにしたいと思います…

出店者の方の興味深いブログとか toboli.hatenablog.com

もっとまとめてくださっている、からあげさんの記事が面白かったです! karaage.hatenadiary.jp

久々にIoTとか作品を作ってみたいなーと思いました。

ここから写真です

f:id:yoshitaku_jp:20180810005732j:plain

f:id:yoshitaku_jp:20180810005755j:plain f:id:yoshitaku_jp:20180810005744j:plain f:id:yoshitaku_jp:20180810005818j:plain

f:id:yoshitaku_jp:20180810005855j:plain f:id:yoshitaku_jp:20180810005831j:plain f:id:yoshitaku_jp:20180810005843j:plain f:id:yoshitaku_jp:20180810005916j:plain

f:id:yoshitaku_jp:20180810005933j:plain f:id:yoshitaku_jp:20180810010044j:plain

f:id:yoshitaku_jp:20180810010111j:plain f:id:yoshitaku_jp:20180810010137j:plain f:id:yoshitaku_jp:20180810010151j:plain f:id:yoshitaku_jp:20180810010202j:plain f:id:yoshitaku_jp:20180810010218j:plain f:id:yoshitaku_jp:20180810010241j:plain

f:id:yoshitaku_jp:20180810010254j:plain f:id:yoshitaku_jp:20180810010308j:plain

f:id:yoshitaku_jp:20180810010336j:plain f:id:yoshitaku_jp:20180810010349j:plain f:id:yoshitaku_jp:20180810010414j:plain

f:id:yoshitaku_jp:20180810010441j:plain f:id:yoshitaku_jp:20180810010453j:plain f:id:yoshitaku_jp:20180810010505j:plain

f:id:yoshitaku_jp:20180810010535j:plain f:id:yoshitaku_jp:20180810010548j:plain f:id:yoshitaku_jp:20180810010601j:plain f:id:yoshitaku_jp:20180810010639j:plain f:id:yoshitaku_jp:20180810010615j:plain f:id:yoshitaku_jp:20180810010627j:plain

f:id:yoshitaku_jp:20180810010748j:plain f:id:yoshitaku_jp:20180810010722j:plain f:id:yoshitaku_jp:20180810010735j:plain f:id:yoshitaku_jp:20180810010759j:plain f:id:yoshitaku_jp:20180810010812j:plain f:id:yoshitaku_jp:20180810010827j:plain f:id:yoshitaku_jp:20180810010841j:plain f:id:yoshitaku_jp:20180810010903j:plain

f:id:yoshitaku_jp:20180810011009j:plain f:id:yoshitaku_jp:20180810010951j:plain

f:id:yoshitaku_jp:20180810011021j:plain f:id:yoshitaku_jp:20180810011032j:plain

7月を振り返って

f:id:yoshitaku_jp:20180729002025p:plain

目次

  1. はじめに
  2. 7月やったこと
    • 週1回ブログを更新する
    • 毎月ひとつ新しいことをやるプロジェクト2018年7月版:中国語
    • FacebookInstagramをやめました
  3. まとめ
  4. 過去の振り返り

はじめに

7月の活動を振り返ってみます。先日6月を振り返ったばかりなのに… あと、読んでもらえるの嬉しいけど、読んでるよって言われるとなんか恥ずかしいですね。けど「全然わからない」って言われるとちょっと悔しいので、もっとわかりやすく表現できるようにしようとおもいました。たとえ話を混ぜたり。

週1回ブログを更新する

yoshitaku-jp.hatenablog.com

yoshitaku-jp.hatenablog.com

yoshitaku-jp.hatenablog.com

yoshitaku-jp.hatenablog.com

yoshitaku-jp.hatenablog.com

毎月ひとつ新しいことをやるプロジェクト2018年7月版:中国語

中国語を始めてみた。英語でさえ中途半端だけど、これからのドキュメントって中国語も増えるのかななんて思ったり、職場にも外国人の方が増えてきたので、面白いかななんて。まだキクタンの準4級を単語帳にまとめて音声を聞いているだけだけど。

FacebookInstagramをやめました

Instagramは写真をすべてアーカイブ化して、アカウントの利用を一時停止状態にしました。 一時停止状態だと、外側からはアカウントが消された状態に見えていて、自分がログインしたら再開状態に戻るらしいです。消したように見えて、IDだけは握り続けてるって感じなのかな。

FacebookiPhoneからアプリを消しました。ブラウザからはあまり入らない派。アカウントを消せない理由は、連絡手段としてのインフラとなってしまっていることですかね。

どちらもやめた理由としては、やっぱり無駄な時間に見ることが多すぎるから。一回スマホの電源を落として仕事をしたら、捗る捗る…。まぁこんなことは自分次第なのはわかってるけど、手の届く範囲にあるかないかっていうのはでかいと思う。ゲーム機もあるとやっちゃうし、ないならやらないし。スマホのアプリをインストールしないのもこれが理由ですし。 TwitterとLINEは無理ですね。捻出した時間が、こっちに行かないことを祈る。

と言いつつ、オクトパストラベラーやりたい。ドット絵が好き…

まとめ

  • 7月を振り返りました
  • もう一回、自分がどうなりたいか、そのために何をしなければいけないかを考えようと思った。

過去の振り返り

1月 yoshitaku-jp.hatenablog.com

2月 yoshitaku-jp.hatenablog.com

3月 yoshitaku-jp.hatenablog.com

4月 yoshitaku-jp.hatenablog.com

5月 yoshitaku-jp.hatenablog.com

6月 yoshitaku-jp.hatenablog.com

#100DaysOfCode の30/100が過ぎました

f:id:yoshitaku_jp:20180730014526p:plain

目次

  1. はじめに
  2. 履歴
  3. まとめ

はじめに

100日間コードを書き続けようって、ツイッターの企画?ハッシュタグ?があったので、面白くてのっています。botからも、いいね!がきて嬉しくなります。もちろん一般のユーザからも!そして、いい具合に習慣化されていて、GitHubの草を生やすのもめちゃくちゃ楽しくなってきました。これからも続けていきたいですね。

紹介してくださってありがとうございます!

kdnakt.hatenablog.com

色んな人がやっているみたいです

www.funclur.com

履歴

まとめ

全世界の人がやっているので、翻訳をかけて英語で呟いていましたが、疲れてしまったので30日目以降からは日本語で呟いています。また、まとまったら記事にしよう。ポジティブな企画に乗っかって自分のモチベーション維持に利用するのもいいかもしれません。

direnvを使って、source bin/activateを自動化する

f:id:yoshitaku_jp:20180728144033p:plain

目次

  1. はじめに
  2. tl;dr
  3. 手順
    1. インストール
    2. bashへhookを設定する
    3. .envrcの作成
    4. エラーが出たら
  4. まとめ

はじめに

Pythonの使って開発するときはvenvを使うことが多いと思います。venvを使って仮想的に開発環境を分けることによって、相互の環境で利用するライブラリをごちゃまぜにしないためです。venvが便利な半面、仮想環境を使うタイミングであったり、切り替えるタイミングであったりで、source bin/activateするのがめんどくさくなってきてしまいました。source bin/activateを自動化出来ないものか考えているうちに、便利なツールに巡り会えたのでブログに書いておきます。

以前巡り合った便利ツールはこちら

yoshitaku-jp.hatenablog.com

tl;dr

  • Go製のdirenvを使うよ
  • これでsource bin/activateを自動化できるよ

手順

インストール

MacならHomebrewを使ってbrew install direnvコマンドでインストールできます。

bashへhookを設定する

~/.bashrcへ、direnvを使うよという指示を与えておきます。 2行目以降は、仮想環境の名前を()付きで表示するために必要な設定です。

eval "$(direnv hook bash)"
show_virtual_env() {
  if [ -n "$VIRTUAL_ENV" ]; then
    echo "($(basename $VIRTUAL_ENV))"
  fi
}

PS1='$(show_virtual_env)'$PS1

設定を反映させる

source ~/.bashrc

.envrcの作成

.envrcを作成する前に、エディターを設定しておきます
export EDITOR=vim

source bin/activateしている、ディレクトリに移動して

direnv edit .

を実行、vimが起動します。

source bin/activate

を記述して完成。

cdコマンドで.envrcファイルのあるディレクトリに移動すると、 無事、自動的に仮想環境に入れる!

エラーが出たら

direnv: error .envrc is blocked. Rundirenv allowto approve its content.

はエラーにある通り、direnv allowを実行して、direnvの実行を許可しましょう。

まとめ

  • source bin/activateを自動化することが出来た
  • 地味にめんどくさかったから嬉しい

吉祥寺.pm15 に参加してきた!!!

f:id:yoshitaku_jp:20180728160331p:plain

目次

  1. はじめに
  2. TL;DR
  3. 発表資料
  4. まとめ

はじめに

2回目の参加になりました吉祥寺.pm。

kichijojipm.connpass.com

前回の14回も面白かったのですが、今回はそれをさらに超えてきましたね。参加者のバリエーションがすごすぎるでしょうと…。堅苦しくない感じで笑いもたくさん起き、こういう勉強会いいなぁって。これからも参加していきたいって気持ちになりました。

先にまとめてくださったので資料へのリンクがたどりやすかったです。ありがとうございます! kawahara-ci.hatenablog.com

TL;DR

  • キチピー最高だなぁ
  • 今回はあまりメモを取らないで、耳を傾けた
    • その場の空気感含め印象に残るので、個人的にはすごくあっていると思った
    • 発表の区切りごとにツイートして、メモしていくスタイルを今度は使ってみよう。
      • 資料を読み返しながらコメントを少し挟んだけど、疲れてしまった
  • 懇親会は不参加にして残念だったので、次は行きたい

発表資料

speakerdeck.com

  • 自身の領域外に存在するナレッジの獲得
    • 知らないことで、機会を失う
    • 知らないことで、課題を抱える
      • 知ることで本質に注力できる *発信するメリット
    • 検討・検証→言語化
    • 個人・個性の発露→体外な存在感の演出
    • フィードバックの獲得
      • 自身に対する直接的な成長機会 *社外に発信するメリット
    • 組織に依存しない主体の構築
    • 情報の鮮度の維持
    • 組織押しての個性の獲得
  • 勉強会活動は個人の成長を通じて組織の成長を助ける *チーム内テックトークの開催

大変参考になりました。自分の中のことをすごく整理してくれた感じ。チーム内テックトークいいですね。早速社内の人に声をかけてみています。


soudai.hatenablog.com

そーだいさんの話を聞いて身近に感じたので、早速Tポイントを募金した。 夏休みには、四国に行く予定なので、被災された地域周辺にも足を運んで、飲んだり食べたりして貢献していきたい。


speakerdeck.com 「技術者通しで交流するのは」が、ふむふむそうだよなぁと思いながら聞いていました。どこの場でも謙虚と尊敬を忘れないの大切です。


hkoba.github.io


slides.com


speakerdeck.com


speakerdeck.com


speakerdeck.com



speakerdeck.com


speakerdeck.com

まとめ

  • 次は、吉祥寺.pmと沖縄.pmが合同で六本木開催だそうです!(ちょっと何言ってるかわからない
  • Perl全然わからないのに参加しちゃってるけど、次も行っていいのだろうか…
  • これからも楽しみにしています!