小梅の日記帳

覚書き、メモ、等々残していくつもりです。

djangoで作成したソースをjupyterで動作させる

やたらとpathがとおらなかったのでメモ。

まず確認すべき事。

①仮想環境上でpip install jupyterしたかどうか。
指定した環境でインストールしていないことで、違う場所を見ているのかもしれない。

②pathの確認
jupyter上のpathとdjango上のpathを比較する。
djangoのテストコードとかでpathを出力してみる。
jupyterのセル上でも同様にpathを出力してみる。

import sys
pprint(sys.path)

from pprint import pprint
print(sys.path)

このどっちか実行。

djangoで作成したソースをjupyterで動作させる

やたらとpathがとおらなかったのでメモ。

まず確認すべき事。

①仮想環境上でpip install jupyterしたかどうか。
指定した環境でインストールしていないことで、違う場所を見ているのかもしれない。

②pathの確認
jupyter上のpathとdjango上のpathを比較する。
djangoのテストコードとかでpathを出力してみる。
jupyterのセル上でも同様にpathを出力してみる。

import sys
pprint(sys.path)

from pprint import pprint
print(sys.path)

このどっちか実行。

1分値データから30分平均へデータを変換する方法

1分毎のデータを用意します。

import pandas as pd
import numpy as np

df = pd.DataFrame({'value': range(1,62,1)},
                  index=pd.date_range('2018-08-01 12:00', '2018-08-01 13:00', freq='T'))

データはこんな感じになります

          value
2018-08-01 12:00:00 1
2018-08-01 12:01:00 2
2018-08-01 12:02:00 3
2018-08-01 12:03:00 4
2018-08-01 12:04:00 5
2018-08-01 12:05:00 6
2018-08-01 12:06:00 7
2018-08-01 12:07:00 8
2018-08-01 12:08:00 9
2018-08-01 12:09:00 10
2018-08-01 12:10:00 11
2018-08-01 12:11:00 12
2018-08-01 12:12:00 13
2018-08-01 12:13:00 14
2018-08-01 12:14:00 15
2018-08-01 12:15:00 16
2018-08-01 12:16:00 17
2018-08-01 12:17:00 18
2018-08-01 12:18:00 19
2018-08-01 12:19:00 20
2018-08-01 12:20:00 21
2018-08-01 12:21:00 22
2018-08-01 12:22:00 23
2018-08-01 12:23:00 24
2018-08-01 12:24:00 25
2018-08-01 12:25:00 26
2018-08-01 12:26:00 27
2018-08-01 12:27:00 28
2018-08-01 12:28:00 29
2018-08-01 12:29:00 30
... ...
2018-08-01 12:31:00 32
2018-08-01 12:32:00 33
2018-08-01 12:33:00 34
2018-08-01 12:34:00 35
2018-08-01 12:35:00 36
2018-08-01 12:36:00 37
2018-08-01 12:37:00 38
2018-08-01 12:38:00 39
2018-08-01 12:39:00 40
2018-08-01 12:40:00 41
2018-08-01 12:41:00 42
2018-08-01 12:42:00 43
2018-08-01 12:43:00 44
2018-08-01 12:44:00 45
2018-08-01 12:45:00 46
2018-08-01 12:46:00 47
2018-08-01 12:47:00 48
2018-08-01 12:48:00 49
2018-08-01 12:49:00 50
2018-08-01 12:50:00 51
2018-08-01 12:51:00 52
2018-08-01 12:52:00 53
2018-08-01 12:53:00 54
2018-08-01 12:54:00 55
2018-08-01 12:55:00 56
2018-08-01 12:56:00 57
2018-08-01 12:57:00 58
2018-08-01 12:58:00 59
2018-08-01 12:59:00 60
2018-08-01 13:00:00 61

ここで30分毎の平均値へ変換したいとします。

df.resample(rule='30Min').mean()
                                 value
2018-08-01 12:00:00 15.5
2018-08-01 12:30:00 45.5
2018-08-01 13:00:00 75.5
2018-08-01 13:30:00 105.5
2018-08-01 14:00:00 121.0

30分毎の平均値の時系列データへ変換することができました。

念の為値の確認をしてみます。

a = np.arange(1,31)
array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17,
       18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30])
np.average(a)
15.5

値は合致しました。 pandas強い。

次は、欠測値が含まれる場合を考えてみようかな。

Kindleか本か

ipadでPDFに書き込みながら勉強するのがとてもやりやすくて気に入っている。

今日はKindleDRMを解除してPDF化するというのをやってみた。

注意しないといけないのが、Kindleのバージョン1.25以降はデバッグされていて、DRMの解除はできないということ。

すんなり行くかと思ったのに数時間ハマってしまった。。。

バージョン1.24で解除すれば問題なく実行できる。

Kindle for PCはWindows版かMac版でしかダウンロード出来ないので、今後はWindowsのノートからDRM解除してGoogleDriveへ保存してipadと連携しようかなと思う。

メインのUbuntuへWineというのを入れてexeを実行出来るようにして見たけどHOMEが汚されてあんまり良くなかった。

何でsudo apt-get purge モジュール名してもホームのドットファイルとか消し去ってくれないのか、、、

気持ち悪いからこれから全部インストールしなおしてみよ。

あと、ドットファイルはなるべくgithubへ上げて今後管理しやすいようにした。

異なるボタンによるPOSTのテストについて

tutorial/urls.py

"""tutorial URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/2.2/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('tutorial/', include('tutorial_app.urls')),
]

tutorial_app/url.py

from tutorial_app.views import SampleFormView, SampleTemplateView
from django.urls import path

urlpatterns = [
  #ここで、class_Viewを用いるときには、as_viewという表現を用いる。
  path('template_index', SampleTemplateView.as_view()),
  path('sample_template', SampleFormView.as_view()),
]

models.py

from django.db import models

class Product(models.Model):
    code = models.CharField('商品番号', max_length=30, unique=True)
    name = models.CharField('商品名', max_length=100)

    def __str__(self):
      return "{0}{1}".format(self.code, self.name)

forms.py

from django import forms
from django.core import validators
from . import models

class ProductForm(forms.Form):
  name = forms.ModelChoiceField(
      models.Product.objects,
      label='商品',
      to_field_name='code'
  )

  product = forms.CharField(
      required=False,
      validators=[validators.MaxLengthValidator(10)])

  # clean_product関数
  def clean_product(self):
    product = self.cleaned_data['product']
    if len(product) > 5:
      raise forms.ValidationError("productのエラー")
    return product

  # clean関数
  def clean(self):
    clean_data = super().clean()
    return clean_data

views.py

from django.views.generic import FormView, TemplateView
from tutorial_app.forms import ProductForm
from tutorial_app.models import Product


class SampleFormView(FormView):
  form_class = ProductForm
  template_name = "tutorial_app/sample.html"
  success_url = "sample_template"

  def form_valid(self, form):
    print(form)
    return super().form_valid(form)

  def post(self, request, *args, **kwargs):
    if request.POST.get('action')=='送信1':
      print('送信1')
    if request.POST.get('action')=='送信2':
      print('送信2')

    return super().post(request, *args, **kwargs)

class SampleTemplateView(TemplateView):
  template_name = "index.html"

sample.html

<html>
<body>
<form action="" method="post">
  {% csrf_token %}
  {% if form.errors %}
    {% for errors in form.errors.values %}
      {% for error in errors %}
        {{ error }}<br>
      {% endfor %}
    {% endfor %}
  {% endif %}

  {% for field in form %}
    <div>
      {{ field.label_tag }}
    </div>

    <div>
      {{ field }}
    </div>
  {% endfor %}
  <button type="submit" name="action" value="送信1">送信1</button>
  <button type="submit" name="action" value="送信2">送信2</button>
</form>
</body>
</html>

このようなテストが書ける。

from django.test import TestCase
from django.test.client import Client

class SubmitTests(TestCase):
    def test_submit(self):
        c = Client(enforce_csrf_checks=False)
        response1 = c.post('/tutorial/sample_template', {'name': '1', 'product': '車', 'action': '送信2'})
        response2 = c.post('/tutorial/sample_template', {'name': '2', 'product': '馬', 'action': '送信1'})
        self.assertEqual(response1.status_code, 200)

ここで、Clientメソッドは、Client()でもデフォルトでscrfがオフになっているのでcsrfについては設定する必要はない。 異なるボタンに反応させるには、dic型でボタンの名前と値を指定すれば良いとわかった。

djangoproject.jp