djangoでappを始めよう

$ python -V
Python 3.8.0
$ django-admin startproject hanbai
$ python manage.py runserver 192.168.33.10:8000

### アプリケーションの作成
$ python manage.py startapp sales
$ git init

/sales/views.py

from django.shortcuts import render
from django.http import HttpResponse

def index(request):
	return HttpResponse("Hello Django!")

/hanbai/urls.py

from django.contrib import admin
from django.urls import path, include

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

/sales/urls.py

from django.urls import path
from . import views

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

urlパターンはpath(‘/’)とするとエラーになるので、path(”)とする必要があります。
これからfrontで作成したviewを組み込んで行きます。

初めての半田ゴテ

Arduinoやラズパイを触ると、無精に触りたくなります。
ということで、半田ごてセットを購入しました。

dav

机に直置きは怖いので、タオルの上で作業します。

dav

はんだ線を付けても全く溶解しなかったので不可解に思いましたが、ハンダゴテの金属が加熱するのに数分程度時間がかかるようで、少し時間をおいたらハンダ線が溶け始めました。

dav

なんやこの臭いは? 臭いが強烈
作業は室内より室外の方が向いているように思いました。

しかし半田ごてはやりたかったことの一つ。
まあ、一歩前進はしました。

トランジスタとは?

トランジスタとは電子回路において信号を増幅またはスイッチングすることができる半導体素子

– 信号を増幅する
– 回路をオンオフする
– NPNやPNPという順番で半導体を挟んでいる(Eエミッタ、Bベース、Cコネクタ)
– バイポーラ型トランジスタ、ユニポーラ型トランジスタ、フォトトランジスタ、サイリスタなどの種類がある

dav

### トランジスタの使い方
微弱な電流を流してコレクタ電流を増幅させる

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(8,OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
  Serial.println("HIGH");
  digitalWrite(8,HIGH);
  delay(2500);

  Serial.println("LOW");
  digitalWrite(8,LOW);
  delay(2500);
}
dav

コンデンサを使ってみよう

コンデンサは電気を蓄えたり放電したりする
金属板が絶縁体を挟み込んだ状態となっている
電圧を加えられると放電する
電圧を一定する働きがある
1.電荷を貯める(静電容量)
2.直流電流は通さず、交流電流を通す(充電と放電を繰り返す)
3.周波数が高い交流ほど通しやすい(抵抗の働きをする)

dav

コンデンサ、トランジスタを組み込んで配線を組みます

dav

int count = 0;
boolean discharge = false;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  digitalWrite(8, HIGH);
  digitalWrite(9, LOW);
  Serial.println("コンデンサの充電開始");
  delay(1000);

}

void loop() {
  // put your main code here, to run repeatedly:
  count++;

  Serial.print(count);
  Serial.print("秒");
  Serial.print(analogRead(A0) / 1024.0 * 5.0);
  Serial.print("V");
  Serial.print("(");
  Serial.print(analogRead(A0));
  Serial.println(")");

  if(count >= 35 && !discharge){
    digitalWrite(8, LOW);
    digitalWrite(9, HIGH);
    Serial.println("コンデンサの放電開始");
    count = 0; discharge = true;
  }
  delay(1000);
  
}

DatePickerでのstart〜endの制御

開始日を入力したら終了日は開始日以降にする
終了日を入力したら開始日は終了日以前しか入力できないようにする

<input type="text" name="start"> ~ <input type="text" name="end">
	<script>
			var format = 'yy/mm/dd';

			var start = $("[name=start]").datepicker({
				dateFormat: 'yy/mm/dd'
			}).on("change", function(){
				end.datepicker("option", "minDate", getDate(this));
			});

			var end = $("[name=end]").datepicker({
				dateFormat: 'yy/mm/dd'
			}).on("change", function(){
				start.datepicker("option", "maxDate", getDate(this));
			});

			function getDate(element){
				var date;
				try {
					date = $.datepicker.parseDate(format, element.value);
				} catch(error){
					date = null;
				}
				return date;
			}
	</script>

コントローラ(サーバ側)で制御するよりも、フロントで制御した方がユーザフレンドリーです。

Vue.jsでフォーム入力値の計算

– ユーザ入力がない場合はplaceholderを表示し、入力があった場合は、合計値をdisabledの入力フォームに表示させたい

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
</head>
<body>
	<h1>Test</h1>
	<div id="app">
		<p>{{message}}</p>
		<input type="number" v-model.number="input1_1" placeholder="1回目の得点を入力"> + <input type="number" v-model.number="input1_2" placeholder="2回目の得点を入力"> = <input type="text" v-model.number="add1" disabled id="total"  placeholder="合計点" >

	</div>
	<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
	<script>
		var app = new Vue({
			el: '#app',
			data: {
				message: 'Hello',
				input1_1:'',
				input1_2:'',
			},
			computed: {
				add1: function(){
					return this.input1_1 + this.input1_2
				}
			}
		})
	</script>
</body>
</html>

未入力

フォーム1のみ入力

フォーム1、フォーム2に入力

フォーム1のみ入力した場合でも、合計値にきちんと反映されています。
vue.jsのdataで、input1_1:”, としていますが、 input1_1:, とすると、動かなくなるので注意が必要です。

Vue.jsでユーザが入力フォームの行を追加出来るようにしたい1

見積登録画面で、費目の行を必要に応じてユーザが追加出来るようにしたい。

WF

Front(途中)

### Vue.jsでテスト実装
– Vue.jsはインラインで実装する
– 配列IDを持たせておき、ユーザが追加ボタンを押すと、フォームの行が追加され、inputフォームのnameには配列のIDを挿入する

<div class="row justify-content-center mt-3">
		<div class="col-8">
			<form class="row">
				<div id="app" class="col-12">
					<div class="row d-flex justify-content-between form-group mb-3">
						<input-field
							v-for="item in route_input"
							v-bind:todo="item"
							v-bind:key="item"
						></input-field>
					</div>
					<div class="row d-flex justify-content-around form-group">
						<div @click="add_route" class="btn btn-info col-2">追加</div>
					</div>
				</div>
			</form>
		</div>
	</div>

	<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
	<script>

		var data_array = ['1','2','3'];

		new Vue({
			el: '#app',
			data: {
				route_input: data_array,
			},
			methods: {
				add_route: function(){
					var add = this.route_input.length + 1;
					this.route_input.push(add)
				}
			},
			components: {
				'input-field':{
					template: `
							<div class="route_count col-12 mb-3 row d-flex justify-content-between">
								<input class="col-3 form-control" type="text" :value="todo.time" :name="'route&#91;' + todo + '&#93;&#91;time&#93;'">
								<input class="col-8 form-control" type="text" :value="todo.place" :name="'route&#91;' + todo + '&#93;&#91;place&#93;'">
							</div>`,
					props: ['todo']
				}
			}
		})
	</script>

見たところ行けそうな予感はある。
DBのカラムは10個ぐらいにしたいので、if add < 10 then add の処理も追加する必要があるか。ちょっと複雑だな。

Bootstrap4でSPでテーブルを横スクロールさせたい

SPでtableを表示した際に、tableの横幅が固定されるので、セル内の文字数がtheaderのセルよりも長くなった場合、縦長のテーブルになってしまう。

PC

SP

-> tableをtable-responsiveで囲み、セルにtext-nowrapを入れる

<div class="table-responsive">
				<table class="table table-striped">
					<thead >
						<tr>
							<th scope="col" class="font-weight-normal">ID</th>
							<th scope="col" class="font-weight-normal">見積日</th>
							<th scope="col" class="font-weight-normal">件名</th>
							<th scope="col" class="font-weight-normal">金額合計</th>
							<th scope="col" class="font-weight-normal">詳細</th>
							<th scope="col" class="font-weight-normal">見積書</th>
						</tr>
					</thead>
					<tbody>
						<tr>
							<td>1</td>
							<td class="text-nowrap">2020年8月9日(日)</td>
							<td class="text-nowrap">高温ヘリウム検査装置製造</td>
							<td>200,000,000</td>
							<td class="text-nowrap"><button>詳細</button> <button>編集</button></td>
							<td class="text-nowrap"><button>ダウンロード</button></td>
						</tr>
					</tbody>	
				</table>
			</div>

横スクロール出来るようになりました。

件名など入力時にバリデーションで文字数制限をしておけば、横スクロールが長くなりすぎる事はないでしょう。

quandlから日経225データを取得する

$ pip install quandl

ダブルインバース(1357)のデータを見てみる
>>> import quandl
>>> quandl.ApiConfig.api_key = ‘hogehoge’
>>> data = quandl.get(‘TSE/1357’)
>>> data
Open High Low Close Volume
Date
2014-07-16 5270.0 5280.0 5230.0 5260.0 43965.0
2014-07-17 5230.0 5270.0 5190.0 5260.0 52325.0
2014-07-18 5400.0 5440.0 5350.0 5350.0 125707.0
2014-07-22 5320.0 5320.0 5240.0 5270.0 71590.0
2014-07-23 5250.0 5290.0 5250.0 5290.0 19141.0
… … … … … …
2017-12-18 1285.0 1289.0 1267.0 1268.0 20980910.0
2017-12-19 1263.0 1274.0 1259.0 1272.0 8550773.0
2017-12-20 1277.0 1281.0 1266.0 1268.0 8632009.0
2017-12-21 1274.0 1290.0 1269.0 1274.0 10881922.0
2017-12-22 1275.0 1281.0 1268.0 1270.0 8738199.0

2017年末までのデータしか取得できない。

### 日経平均の取得
https://www.quandl.com/api/v3/datasets/CHRIS/CME_NK2/data.json?api_key=${api_key}

レスポンス結果
{“dataset_data”:{“limit”:null,”transform”:null,”column_index”:null,”column_names”:[“Date”,”Open”,”High”,”Low”,”Last”,”Change”,”Settle”,”Volume”,”Previous Day Open Interest”],”start_date”:”1990-09-26″,”end_date”:”2020-08-05″,”frequency”:”daily”,”data”:[[“2020-08-05”,22530.0,22555.0,22355.0,22395.0,-30.0,22390.0,22.0,6.0],[“2020-08-04”,null,22555.0,null,22435.0,135.0,22420.0,0.0,6.0],…// 省略

$ sudo apt-get install libpng-dev
$ sudo apt-get install libfreetype6-dev
$ sudo pip install matplotlib
$ sudo pip install ipython jupyter

$ python
Python 3.8.0 (default, Oct 28 2019, 16:14:01)
[GCC 8.3.0] on linux
Type “help”, “copyright”, “credits” or “license” for more information.
>>> import json
>>> json.dumps([‘foo’, {‘bar’: (‘baz’, None, 1.0, 2)}])
‘[“foo”, {“bar”: [“baz”, null, 1.0, 2]}]’

### quandlからデータ取得
app.py

# API
import requests
import json
import datetime as dt
# date
from dateutil.relativedelta import relativedelta
from pytz import timezone

# データ前処理、グラフ表示
import numpy as np
import pandas as pd
from IPython import get_ipython
ipy = get_ipython()
if ipy is not None:
    ipy.run_line_magic('matplotlib', 'inline')
import matplotlib.pyplot as plt

fig = plt.figure()

# エンドポイントを定義
url = 'https://www.quandl.com/api/v3/datasets/CHRIS/CME_NK2/data.json?api_key=hogehoge'

# json でデータ取得
catched_response = requests.get(url)
json_data = catched_response.json()


columns = json_data['dataset_data']['column_names']
values = json_data['dataset_data']['data']

df = pd.DataFrame(values, columns=columns)
df.loc[:,'Date'] = pd.to_datetime(df.loc[:,'Date'])
df.set_index('Date', inplace=True)

df.loc[:,'High'].interpolate(inplace=True)
df.loc[:,'Last'] = np.minimum(df.loc[:,'Last'].interpolate(),df.loc[:,'High'])

today = dt.datetime.now(timezone('Asia/Tokyo'))
t_year = today - relativedelta(years=1)
t_date = t_year.strftime('%Y-%m')

df_target = df.loc[:t_date,'Last'].sort_index()
df_target.plot()
df_target.rolling(window = 5).mean().plot()
df_target.rolling(window = 25).mean().plot()

fig.savefig("dist/img/225.png")

$ python app.py

トップページに嵌め込みます。

matplotlibのグラフはクーロンで日次でバッチ処理すれば良いですね。
景気動向指数の予定だったが、CIの各指標がAPIで公開されていないので、225のチャートで良しとするか。
致し方がない。