diadia

興味があることをやってみる

がん検診の受け方、使い方

がん検診の受け方、使い方を読んだ

がんは人類の解決すべき問題の一つだと感じている。がんを解決することでもっと大きく世界が広がっていくと思う。 ただ人類ががんに対してどこまで研究を進めてきているか知らないと思ったので、今後がんについての本も意識的に読んでみようと思う。

メモ

タバコは肺がんの原因だと思っていたけど、その他の多くのがんの原因になる。アルコール、アセトアルデヒド、酢酸という流れでアルコールは代謝される。この流れのうちアルコール、アセトアルデヒドは発がん性がある。飲酒もまたおおくのがんの原因となることが知られている。一般的にしられているのは肝臓がんだけれども膵がんのリスクも高くなる。

centos7にepelを入れる

centos7にepelをいれる

以下のコマンドでepelをいれることができる。

sudo yum install epel-release

epelをいれる理由

centos7では保守的なリポジトリなので使いたいソフトウェアが入っていないことが多い。centos7に相性の良いリポジトリの一つがepelである。これをインストールすることでyumでもともとできなかったソフトウエアをインストールすることができるようになる。

django ログインユーザしか見れない構造の作り方

ユーザログインしているときだけ見える構造を構築する方法

実装例

views.py

def hoge():
    context = { }
        return render(request, "index.html",context )

#又はclass-based-viewを使う場合には、
class Diary(ListView):
    model = diaries
    template_name = "index.html"

index.html

{% if request.user.is_authenticated %}
もしユーザーなら見られる
{% else %}
this is test
{% endif %}

注意点はdjango2.0以前はis_authenticated() だったけど以降はis_authenticatedになったっぽい。

ディレクトリの指定

現状のパス問題点

ディレクトリの操作、ファイルの操作に関して個別具体的なパスで記述している。そのためスクリプトを移動してしまうと途端に関連するスクリプトにファイルを読み込めなくなってしまう。具体性を排除して、汎用的なファイル操作ができるようにしたい。

操作確認

C:\Users\user\program\dir_test.pyで試してみる。

test1

print(os.getcwd())

結果

C:\Users\user\program

test2

print(__name__)

結果

__main__

test3

print(__file__)

結果

dir_test.py

この__file__はモジュールファイルのパスを文字列として保存してあるらしい。byみんなのpython

test4

print(os.path.abspath(__file__))

結果

C:\Users\user\program\dir_test.py

test5

print(os.path.dirname(os.path.abspath(__file__)))

結果

C:\Users\user\program

os.path.dirname(os.path.abspath(__file__))とos.getcwd()の結果が同じだった。でこれはカレントディレクトリを示す。

カレントディレクトリに新たにディレクトリを作る場合

os.mkdir("dir1")

カレントディレクトリにdir1を作成することができた。mkdir(パス)なのでmkdir(フルパス)にするには以下のようにする。

os.mkdir(os.path.join(os.path.dirname(os.path.abspath(__file__)),"dir2"))

新たに作ったディレクトリに画像ファイルを保存する

まず新たに作ったディレクトリのパスを取得する。それにつなげてurllib.request.retrieve()を用いる。
新たに作ったディレクトリのパスは以下のように書く。

os.path.dirname(os.path.abspath(__file__))

画像urlは以下のものにする。https://www.google.co.jp/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png。だから画像のダウンロード自体は以下になる。

import urllib.request
url ="https://www.google.co.jp/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png"
save_name = "image.png"
urllib.request.retrieve(url,save_name)

これらを合わせるとこうなる。

import urllib.request
url ="https://www.google.co.jp/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png"
save_name = "image.png"
save_name = os.path.join(os.path.dirname(os.path.abspath(__file__)),"dir2",save_name)
urllib.request.retrieve(url,save_name)

指定のディレクトリの画像ファイルすべて削除する

指定のディレクトリ今回は"image"のファイルすべてを削除する

for t in os.listdir("image"):
    file = os.path.join(os.path.dirname(os.path.abspath(__file__)),"image",t)
    os.remove(file)

ちなみに以下の方法だと正確にフルパスを検出できずに、削除する事ができなかった。

for t in os.listdir("image"):
    print(os.path.abspath(t))
    os.remove(os.path.abspath(t))

関連メモ

ディレクトリ、ファイルの削除

ディレクトリ、ファイルの削除

ファイル、ディレクトリの削除

一時的に画像ファイルを作成し、利用後削除したいとする。画像ファイルを作りっぱなしだと容量がかさばってしまうからだ。osモジュールで作成したディレクトリやファイルを削除することができる。

files = os.listdir()
for t in files:
    os.remove(t)

os.listdirで指定したパスのディレクトリに有るファイルをリストで返す。パスを書いていない場合は、カレントディレクトリのファイルをリストにして返す。ファイルはos.remove(パス)で削除する。

関連メモ

ディレクトリの指定

opencvのエラー

エラー内容1

Traceback (most recent call last):
  File "opencv_practice.py", line 10, in 
    cv2.imshow("resized",image1)
cv2.error: OpenCV(4.0.0) d:\build\opencv\opencv-4.0.0\modules\highgui\src\window
.cpp:358: error: (-215:Assertion failed) size.width>0 && size.height>0 in functi
on 'cv::imshow'

コード

import numpy as np
import cv2

image0 = cv2.imread("test_0.jpg")
cv2.imshow("resized",image0)
cv2.waitKey(0)
cv2.destroyAllWindows()

参考にしたurl:Python2.7.6でOpenCV Errorが発生します ここのyohjp様のコメントが役に立ちました。自分の場合は拡張子をつけてないためcv2.imshow()ではなく、その前のcv2.imread()の段階で誤りだと気づいた。しょうもないミスだけれども同じことを繰り返さないために記録しておく。

エラー内容2

ディレクトリに有る画像ファイルをリスト化し、それをcv2.imshow()で表示させる際に画像表示のウィンドウが応答なしとなってしまう。

これも記述ミスだった。cv2.waitkey()と書いていたが、これが間違い。ただしくは大文字小文字に気をつける。

cv2.waitKey()

git リモート、ブランチ、マージあたりのこと

リモートについて

fetchするリモートやpushするリモートを表示するためには以下のコマンドをつかう。

$ git remote
#リモートリポジトリのurlを表示させる場合には以下
$ git remote -v

リモートリポジトリを追加する場合には以下のコマンドを用いる。

$ git remote [リモートリポジトリ名]

リモートリポジトリからコードを取得する

方法は2種類有る。一つはfetchを使ったあとにmergeする方法。もう一つはpullする方法。基本的にfetchとmergeを使った組み合わせでコードを取得するのが望ましいようだ。なぜならpullの場合は現在編集しているブランチにコードを上書きしてしまう。具体的に言えば、ローカルAブランチのコードをリモートAブランチのコードで更新するのが望ましいのに、ローカルAブランチコードをリモートBブランチのコードで更新してしまうという事が起こりえないからだ。

fetch

$ git fetch [リモート名]
ex. git remote origin

fetchはリモートリポジトリからローカルリポジトリにソースを取ってくるだけらしい。ローカルリポジトリには、以下の場所にコードが保存される。remotes/リモートリポジトリ名/ブランチ名

pull

$ git pull [リモート名] [ブランチ名]
ex. git pull origin master

上記のコマンドは省略する事もできる。

$ git pull

リモートリポジトリの情報表示

git remoteで情報を表示することができたが、以下のコマンドでより詳しく表示させることができる。

$ git remote show [リモートリポジトリ名]
ex. git remote show origin

表示される項目

  • fetch,pushのurl
  • リモートブランチ
  • git pullの挙動
  • git pushの挙動

リモートリポジトリ名の変更とリモートリポジトリの削除

リモートリポジトリ名の変更

$ git remote rename [旧リモート名] [新リモート名]
ex. git remote rename check1 check2

リモートリポジトリの削除

$ git remote rm [リモート名]

ブランチについて

ブランチを新規作成する

$ git branch [ブランチ名]
ex. git branch detail

ブランチを作成するだけではブランチの切り替えまでは行われない。

ブランチの一覧を表示する

$ git branch
git branch -a

-aをつけるとリモートリポジトリまで表示することができるが、つけなければローカルリポジトリのブランチが表示される。

djangoにクローン機能を実装する

djangoウェブアプリケーションで表示される情報を定期的に更新したい

現状のプロダクトでは、postgresqlcsvのデータをコピーしただけなのでデータは変更されない。ブログのようなアプリケーションならこれで十分だけれども、定期的に情報を更新したいものには対応できない。例えば、株価、為替、天気のような情報だ。これが問題だった。情報を更新するには何が必要か調べたのでメモしておく。

情報更新に必要な要素

情報収集する際に"django クローン"で調べるといろいろ情報が出てきた。それをもとに必要な要素が確定した。

  • データオブジェクトの更新
  • 更新トリガーを作る
  • 更新する頻度の設定

データオブジェクトの更新

データオブジェクトの更新は、views.pyの中でデータオブジェクトを抽出し、当該オブジェクトのデータを変更して、save()すれば良い。変更内容はスクレイピングなどを利用して更新したい情報を取得する。

更新トリガーを作る

更新トリガーはdjango-admin コマンドの実装を参考にした。 https://docs.djangoproject.com/ja/2.1/howto/custom-management-commands/

python manage.py hogehoge

という自作のコマンドを作成することができ、これによりコマンド入力の際にviews.pyを走らせることができるようになる。

更新する頻度の設定

これはサーバのクローンを利用する。crontabコマンドを使うと定期的に指定した日時で何らかの指示を実行してくれる。

具体的な実装手続き

django-extensionsの採用

djanogo-extensionsを利用するとcommand作成に必要なディレクトリやファイルの構造を自動で作成してくれる。だからviews.pyでどんな挙動にするかを記述することに専念することができる。

django-extensionsのインストール

こちらを参考にさせていただきました。
https://tokibito.hatenablog.com/entry/20150827/1440602095

$ pip install django-extensions

settings.pyを編集する。注意点はpipインストールしたモジュール名はdjango-extensionsだけれども、追加する内容はdjango_extensionsで異なる。ハイフンとアンダーバーの違いに注意すること。間違うとコマンド作成時に以下のエラーになります。

ModuleNotFoundError: No module named 'django-extensions'

話は戻ってsettings.pyの編集。

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django_extensions',  # この行を追加
)

特殊メソッドについて

 

特殊メソッドとは

特殊メソッドは、みんなのpythonによると

新しく作ったクラスに特殊メソッドを定義すると、インスタンスに対して演算子などを使った操作を行えるようになります。

と書いてある。あまりピンとこなかったが今回本当に小さいことだけれど分かったことがあるのでメモする。

djangoと特殊メソッドの関係

djangoではadminのページでデータオブジェクト(インスタンス)を見れるが、その表示はContent object(1),Content object(2)である。そしてこの表示を具体的なデータオブジェクトの表示へ変える事ができる。その際に使うのが、特殊メソッドの一つの__str__メソッドである。以下のように使うと今回の場合データオブジェクトの表示をタイトル表示に変えられる。

def __str__(self):
    return self.title

こういう事ができるのは学び始めて早い段階でわかったのだけれども、なぜmodels.pyでこのコードが書かれるのか分からず、記憶頼りにコーディングしていた。それについてのメモだ。特殊メソッドは、まずインスタンス(データオブジェクト)に対して使う。また新しく作ったクラスに特殊メソッドを定義する形で使う。
一方models.pyでは新たにクラスを作る。でもそのデータオブジェクトの表示は、adminページでContent object(1)のような表示になっている。データオブジェクトはインスタンスのことなので、特殊メソッドを使うとデータオブジェクトを操作することができる。その使い方は新たに作ったクラスに対して定義(def)する形で使う。__str__メソッドはデータオブジェクトの表示を変える操作である。そういうわけでクラスを新たに定義するmodels.pyにおいてクラス定義した中に特殊メソッドを定義して使う。これで記憶量をコンパクトにできる。

    class Content(models.Model):
        title = models.CharField(max_length=120)
        text  = models.TextField()
        date  = models.DatetimeField()
        
        def __str__(self):
            return self.title
    

migrate後にテーブルを削除

python manage.py makemigrations/migrateした後にpostgresqlのテーブルの一部またはデータベースを削除してみた。そこからもう一度python manage.py makemigrations/migrateしてみたけど新たにテーブルを作成することができなかった。no change detected という結果のみになった。新しくテーブルを作るにはどうすればいいのか?キャッシュとかが関係しているのか?

pycacheがどこにあるか

pycacheがどこにあるか探してみた。一つはdjangoプロジェクトの本体アプリケーション内に存在する。具体的にはsettings.pyやwsgi.pyがあるディレクトリに__pycache__として存在している。__pycache__には__init__.cpython-36.pyc,settings.cpython-36.pyc,wsgi.cpython-36.py,urls.cpython-36.pycが入っていた。
その他にhomeディレクトリに.cacheがある。その中にはpip,abrtがあった。

 その他にはアプリディレクトリのmigrationsディレクトリの中に__pycache__があった。

[application_name]
    |
    |--__pycache__ --------__init__.cpython-36.pyc
    |--__init__.py     |---settings.cpython-36.pyc
    |--settings.py     |---wsgi.cpython-36.pyc
    |--wsgi.py         |---urls.cpython-36.pyc

scpの使い方

scpを使うとローカルからサーバにファイルを送ることができる。使い方をまとめてみる。

基本的な構文

scp [オプション] コピー元 コピー先

コピー元、コピー先の書き方

[ユーザ名@]ホスト名またはIPアドレス:ファイルのパス

だからローカルのカレントディレクトリのtest.txtをサーバのtmpファイルに送る場合は以下のような感じになる。

scp test.txt ****@*.*.*.*:/tmp

こんな感じになる。

オプションについて

オプションは以下のものがある。

  • -P
  • -p
  • -r
  • -i

sshのポート番号を変更していれば-Pを用いる。
秘密の鍵を設定している場合は-iを用いる。

本番用と開発用のsettings.pyを分けるときの技術

settings.pyを本番用と開発用に準備する

本番用と開発用にsettings.pyを両方持っていることは便利。それは一度デプロイしたプロダクトを拡張したいときに、プロダクトのsettings.pyの設定を本番用の環境から開発用の環境の設定に書き換える必要があるからだ。面倒くさいことだし、この変更操作中に例えば記述ミスで誤った設定にしてしまったら、バグ解消に時間がかかってしまう。そこで本番用の環境と開発用の環境を分けておくことが一つの方法だ。ちなみに以下が本番と開発間の変更すべき項目である。

DEBUG =   # FalseまたはTrue
DATABASES = {} #sqlit3または任意の
ALLOWED_HOSTS 
    

やり方

  • python3.6
  • django2.1
  • nginxを使用
  • postgresqlを使用
  • gunicornを使用

そこで従来のsettingとは別に例えば、production_settings.pyを本番環境用に準備する。

#オリジナルのsettings.pyがあるディレクトリにて
$ mkdir production_settings.py 

settings.pyの内容をコピーしてproduction_settings.pyに貼り付ける。その後以下の項目に書き換える。static_url以下は追記する。

DEBUG = True
# 自分の場合はpostgresqlを使う
DATABASES = {
    'default': {
        'ENGINE'   : 'django.db.backends.postgresql_psycopg2',
        'NAME'     : "project", #postgresqlで作成したデータベース名(この場合だとCREATE DATABASE project ;)
        'USER'     : "*****",
        "PASSWORD" : "*****",
        "HOST"     : "localhost",
        "PORT"     : "",
    }
}

ALLOWED_HOSTS = ['*.*.*.*']
STATIC_URL = '/static/'
STATIC_ROOT = '/usr/share/nginx/html/static'
MEDIA_URL = '/media/'
MEDIA_ROOT = '/usr/share/nginx/html/media'

変更したらいつもどおりのgunicornのコマンドを入力する。ただしその前に一つコマンドをかませる。そういうわけでコマンドは以下のようになる。

export DJANGO_SETTINGS_MODULE=[アプリ名].production_settings
gunicorn --bind 127.0.0.1:8000 [アプリ名].wsgi:application

もっと便利な他のやり方もある

上記の方法はexportの内容が消えてしまう?のかgunicornコマンドを入力する前にexportする必要が出てくる。ちょっと面倒くさい。wsgi.pyファイルやmanage.pyファイルを編集することで解決する方法も有るようだが、まだ技術が追いついていない。できるようになったら追記しておく。