Tips¶
Arduino(HiLetgo Leonardo Pro Micro)¶
シリアル通信でLED制御を行う(IDEからとC#から)¶
#define TX_LED 30
void setup() {
// put your setup code here, to run once:
pinMode(TX_LED, OUTPUT);
Serial.begin(9600);
}
void loop() {
// put your main code here, to run repeatedly:
if (Serial.available() > 0) {
int inputchar;
inputchar = Serial.read();
if(inputchar != -1) {
switch(inputchar) {
case 'a':
digitalWrite(TX_LED, LOW);
break;
case 'b':
digitalWrite(TX_LED, HIGH);
break;
}
}
}
}
動作確認はマイコンにプログラムを送った後、 IDE-ツール-シリアルポートから、シリアル通信に使うプログラムを起動。
そこでaを入力して送信するとLEDがついてbを入力して送信するとLEDが切れる。
因みに、私が使っているArduinoではRXの方を光らせようとしてもできなかった。 シリアル通信しているときにRXで設定されているLEDが光っていたため、 おそらくそういった関係で光らないのかもしれない。しらんけど。
それからC#からも制御を行うこともできた。下はそのコード。 usingのあたりは追加したもののみ載せてみた。
using System.Threading;
using System.IO.Ports;
namespace SampleSerialPort
{
class Program
{
static SerialPort serialPort;
static void Main(string[] args)
{
serialPort = new SerialPort();
serialPort.PortName = "COM4";
serialPort.BaudRate = 9600;
serialPort.DtrEnable = true;
serialPort.Open();
while (true)
{
string senddata = Console.ReadLine();
serialPort.Write(senddata);
Thread.Sleep(10);
}
}
}
}
これもIDEのツールに似ていて、 起動後にキーボードからaと入力するとLEDがついて、 bと入力するとLEDが消える。
COM4のところは私の環境ではArduinoと通信しているポートがCOM4のため。 それからDtrEnableについては私が使っているもので必須とのこと。 よくわからないけれど。 Thread.Sleepの値はテキトーなので変更してもいいかもしれない。 てか、いらないかも。
キーボード入力(複数)¶
#include "Keyboard.h"
void setup() {
// put your setup code here, to run once:
Keyboard.begin();
delay(1000);
for(int i = 0; i < 3; i++) {
Keyboard.press('a');
Keyboard.press('b');
Keyboard.press('c');
Keyboard.press('d');
Keyboard.press('e');
Keyboard.press('f');
delay(50);
Keyboard.releaseAll();
delay(50);
Keyboard.press('g');
Keyboard.press('h');
Keyboard.press('i');
Keyboard.press('j');
Keyboard.press('k');
delay(50);
Keyboard.releaseAll();
delay(200);
}
for(int i = 0; i < 3; i++) {
Keyboard.press(KEY_LEFT_CTRL);
//Keyboard.press(KEY_LEFT_ALT);
//Keyboard.press(KEY_LEFT_SHIFT);
delay(50);
Keyboard.press('1');
Keyboard.press('2');
Keyboard.press('3');
Keyboard.press('4');
Keyboard.press('5');
Keyboard.press('6');
delay(50);
Keyboard.releaseAll();
delay(200);
}
}
void loop() {
// put your main code here, to run repeatedly:
}
キーボード入力のキー複数版。
やはり同時入力は6キーまでらしく、delayで遅らせることでさらに増やせてるっぽい。
同時押しのほうはCtrlのあとすぐにdelayで遅らせて、 そのあと6キー同時入力する感じにしてみた。
時間取得¶
http://www.musashinodenpa.com/arduino/ref/index.php?f=0&pos=2524
上のサイトにあったサンプル。時間を取得できるらしい。
unsigned long time;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
}
void loop() {
// put your main code here, to run repeatedly:
time = millis();
Serial.println(time);
delay(1000);
}
動作確認はIDE-ツール-シリアルモニタを起動すると時間がでてくる。
キーボード入力¶
#include "Keyboard.h"
void setup() {
// put your setup code here, to run once:
Keyboard.begin();
delay(1000);
for(int i = 0; i < 3; i++) {
Keyboard.press('a');
delay(50);
Keyboard.releaseAll();
delay(200);
}
for(int i = 0; i < 3; i++) {
Keyboard.press(KEY_LEFT_CTRL);
//Keyboard.press(KEY_LEFT_ALT);
//Keyboard.press(KEY_LEFT_SHIFT);
Keyboard.press('1');
delay(50);
Keyboard.releaseAll();
delay(200);
}
}
void loop() {
// put your main code here, to run repeatedly:
}
LEDチカチカ¶
基盤にRX LEDとTX LEDという2つのLEDがついているのでそれらを光らせる。 ネットで調べると、 RXはD17、TXはD30をLOWにするとLEDが点灯するとのこと。
#define RX_LED 17
#define TX_LED 30
void setup() {
// put your setup code here, to run once:
pinMode(RX_LED, OUTPUT);
pinMode(TX_LED, OUTPUT);
}
void loop() {
// put your main code here, to run repeatedly:
digitalWrite(RX_LED, LOW);
delay(1000);
digitalWrite(RX_LED, HIGH);
digitalWrite(TX_LED, LOW);
delay(1000);
digitalWrite(TX_LED, HIGH);
}
これを書き込むと、2つのLEDが交互に点灯するようになる。
接続¶
Arduino IDEをインストール。 その後、PCとArduinoを接続。
私の使っているものは、 HiLetgo Leonardo Pro Microというもの使っていて、 IDE側ではLeonardoと認識するらしい。 なので、IDE-ツール-ボード-Arduino Leonardoを選択。
ポートも設定しないと書き込めないので、 IDE-ツール-シリアルポートからArduino Leonardoと表示されているものを選択。
これでIDEから書き込めるようになった。
Python¶
テンプレートエンジン Jinja2¶
インストール。
pip install Jinja2
テンプレートファイルは次の通り。sample_jinja.tpl.htmlという名前で これから作るpythonスクリプトと同じ階層に保存。
<html>
<body>
{# お名前の表示 #}
こんにちは {{ name }} さん
<hr />
<ul>
{# 持ち物の表示 #}
{% for item in items %}
<li>{{ item.name }} : {{ item.number }} {% if item.name == '鉛筆' %}本{% else %}個{% endif %}</li>
{% endfor %}
</ul>
</body>
</html>
Jinja2を読み込んで、テンプレートエンジンをもとにhtmlテキストを出力するプログラム。 FileSystemLoaderの最初の引数はテンプレートファイルが入っているディレクトリを指定。 get_templateはテンプレートファイルの名前を指定。
from jinja2 import Environment, FileSystemLoader
env = Environment(loader=FileSystemLoader('./', encoding='utf8'))
tpl = env.get_template('sample_jinja.tpl.html')
items = []
items.append({'name':'時計', 'number':1})
items.append({'name':'鉛筆', 'number':5})
items.append({'name':'ノート', 'number':1})
html = tpl.render({'name':'太郎', 'items':items})
print(html)
実行結果は次の通り。
$ python sample_jinja2template.py
<html>
<body>
こんにちは 太郎 さん
<hr />
<ul>
<li>時計 : 1 個</li>
<li>鉛筆 : 5 本</li>
<li>ノート : 1 個</li>
</ul>
</body>
</html>
テキストと数値、ループの処理とif文の処理のサンプル。if文は無理やり入れた感はあるけれど。
付けたしで、文字列のHTMLタグを有効にしたい場合は {{ tagstr | safe }}のように {{}}のなかでsafeを付ける。この例ではtagstrの中にhtmlタグが含まれている。
Jsonファイル読込¶
読込用のファイルは下の通り。sample_jsonfile.jsonという名前で保存した。 これから作るpythonスクリプトと同じ階層に。
{
"title": "users",
"data": null,
"user_list": [
{
"name": "Suzuki",
"age": 20,
"flag": true
},
{
"name": "Sato",
"age": 22,
"flag": false
}
]
}
プログラムは次の通り。
### Jsonファイル読込
import json
with open('./sample_jsonfile.json') as f:
jsn = json.load(f)
print('-------------------------------')
print('そのまま表示')
print(jsn)
print('-------------------------------')
print('キーを取得')
for jsn_key in jsn:
print(jsn_key)
print('-------------------------------')
print('値を取得')
for jsn_value in jsn.values():
print(jsn_value)
print('-------------------------------')
print('特定のキーの値を取得')
print(jsn["title"])
print(jsn["data"])
print(jsn["user_list"])
print('-------------------------------')
print('リストの子要素を取得')
for user in jsn["user_list"]:
print(user["name"])
print(user["age"])
print(user["flag"])
実行結果は次の通り。
$ python sample_readjson.py
-------------------------------
そのまま表示
{'title': 'users', 'data': None, 'user_list': [{'name': 'Suzuki', 'age': 20, 'flag': True}, {'name': 'Sato', 'age': 22, 'flag': False}]}
-------------------------------
キーを取得
title
data
user_list
-------------------------------
値を取得
users
None
[{'name': 'Suzuki', 'age': 20, 'flag': True}, {'name': 'Sato', 'age': 22, 'flag': False}]
-------------------------------
特定のキーの値を取得
users
None
[{'name': 'Suzuki', 'age': 20, 'flag': True}, {'name': 'Sato', 'age': 22, 'flag': False}]
-------------------------------
リストの子要素を取得
Suzuki
20
True
Sato
22
False
ファイルマッチング(glob)¶
import glob
result = glob.glob('*.py')
print(result)
カレントディレクトリのパターンにマッチングしたファイル名がそのままresult変数にリストとして格納される。
コマンドライン引数(argparse)(count)¶
import argparse
if __name__=='__main__':
parser = argparse.ArgumentParser()
parser.add_argument("square", type=int,
help="display a square of a given number")
parser.add_argument("-v", "--verbosity", help="increase output verbosity",
action="count", default=0)
args = parser.parse_args()
answer = args.square**2
if args.verbosity >= 2:
print("the square of {} equals {}".format(args.square, answer))
elif args.verbosity >= 1:
print("{}^2 == {}".format(args.square, answer))
else:
print(answer)
実行結果は次の通り。
$ python sample_argparse4.py 2 -vv
the square of 2 equals 4
$ python sample_argparse4.py 2 -v
2^2 == 4
$ python sample_argparse4.py 2
4
Vオプションの数で表示が変わる。
コマンドライン引数(argparse)(choices)¶
import argparse
if __name__=='__main__':
parser = argparse.ArgumentParser()
parser.add_argument("square", type=int,
help="display a square of a given number")
parser.add_argument("-v", "--verbosity", help="increase output verbosity",
type=str, choices=["zero", "one", "two"])
args = parser.parse_args()
answer = args.square**2
if args.verbosity == "two":
print("the square of {} equals {}".format(args.square, answer))
elif args.verbosity == "one":
print("{}^2 == {}".format(args.square, answer))
else:
print(answer)
実行結果は次の通り。
$ python sample_argparse3.py 2 --verbosity two
the square of 2 equals 4
$ python sample_argparse3.py 2 --verbosity one
2^2 == 4
$ python sample_argparse3.py 2 --verbosity zero
4
文字列でもいけた。公式のサンプルでは数値だったので。
コマンドライン引数(argparse)(action="store_true")¶
import argparse
if __name__=='__main__':
parser = argparse.ArgumentParser()
parser.add_argument("square", type=int,
help="display a square of a given number")
parser.add_argument("-v", "--verbose", help="increase output verbosity",
action="store_true") # store_trueはargs.verboseにTrue or Falseが格納されるようにする
args = parser.parse_args()
answer = args.square**2
if args.verbose:
print("verbosity turned on")
print("The square of {} equals {}".format(args.square, answer))
else:
print(answer)
実行結果は次の通り。
$ python sample_argparse2.py 2 --verbose
verbosity turned on
The square of 2 equals 4
$ python sample_argparse2.py 2
4
squareには整数が格納されるように、type=intで指定。
store_trueでtrueまたはfalseがargs.verboseに格納されている。
コマンドライン引数(argparse)¶
import argparse
if __name__=='__main__':
parser = argparse.ArgumentParser()
parser.add_argument("echo", help="echo")
args = parser.parse_args()
if args.echo:
print(args.echo)
実行結果は次の通り。
$ python sample_argparse.py abcde
abcde
parser = argparse.ArgumentParser()でパーサーの準備。parser.add_argument(...)でオプションの追加。 args = parser.parse_args()でargsに入力値を格納。 あとはif文でオプション毎の処理を追加していくというのが一連の流れ。
args.echoの中に引数の文字列が入っている。デフォルトでstr型。 --helpの文字列は自動で生成される。
コマンドライン引数¶
import sys
if __name__=='__main__':
argvs = sys.argv
argc = len(argvs)
print(argvs)
print(argc)
実行結果は次の通り。
$ python sample_argv.py aaa
['sample_argv.py', 'aaa']
2
sys.argvにリストで格納されている。
ファイルへ書き込む¶
write_text = '''
aaa
bbb
ccc
'''
with open('newfile.txt', mode='w', newline='\n', encoding='utf-8') as f:
f.write(write_text)
ここでは改行をLF(UNIX系)、文字コードをutf-8に指定している。 プログラムを実行した場所と同じところにnewfile.txtというファイルができていて、 なかを開くとwrite_textの内容が書き込まれている。
ファイルを読み込む¶
with open('sample_markdown.py') as f:
read_text = f.read()
print(read_text)
ここで読み込んでいるのは下のサンプルコード。読み込んだものをそのまま画面出力へ。
MarkdownをHTMLへ変換する¶
Pythonを使って、MarkdownをHTMLへ変換したときのメモです。
pip経由でmarkdownをインストール。
pip install markdown
extensions=['tables']という指定をしないと、表が作成されない。 他にもエクステンションが用意されているらしいので、調べる必要があるかもしれない。
import markdown
markdown_text = '''
# h1
## h2
本文
本文2行目
|タイトル1 |タイトル2 |
|--- |---|
|あああああ|アアアアア|
|いいいいい|イイイイイ|
|ううううう|ウウウウウ|
'''
md = markdown.Markdown(extensions=['tables'])
html_text = md.convert(markdown_text)
print(html_text)
実行結果は次の通り
<h1>h1</h1>
<h2>h2</h2>
<p>本文</p>
<p>本文2行目</p>
<table>
<thead>
<tr>
<th>タイトル1</th>
<th>タイトル2</th>
</tr>
</thead>
<tbody>
<tr>
<td>あああああ</td>
<td>アアアアア</td>
</tr>
<tr>
<td>いいいいい</td>
<td>イイイイイ</td>
</tr>
<tr>
<td>ううううう</td>
<td>ウウウウウ</td>
</tr>
</tbody>
</table>
仮想環境作成¶
Pythonの仮想環境を作るときのコマンド。パソコン環境はDebian(WSL)上にPython3をインストールしている。 同時にVirtualenvもインストール済み。
作業用のディレクトリを作成してその中へ移動後、次のコマンド。
virtualenv --no-site-packages .
source ./bin/activate
1行目はここに仮想環境を作るという意味。 2行目のコマンドを打つと、作った仮想環境のpythonのバイナリが実行できるようになる。
macbookを使っていたときは、1行目のコマンドは次のようにして、pythonのバージョンを指定していた。
virtualenv --no-site-packages -p python3.5 .
3.9.4¶
virtualenv -p python3.9 .
--no-site-packagesが廃止されたそうで。 デフォルトでそんな感じの動作をするようになったらしい。しらんけど。
ソースコードからインストール¶
3.9.4(mac)¶
./configure --prefix=/インストールフォルダ/ --with-openssl=/usr/local/opt/openssl/ --enable-optimizations
make
make install
インストールフォルダはuserのディレクトリ以下にテキトーにフォルダを作ってそこを指定 user/Python-3.9.4とか
with-opensslを指定する。パスはbrewでインストールしたopensslのパスを指定した。 opensslがうまくいっているかは、pythonをインストールしたあとにimport sslとして、 エラーがでなければok
./python3.9 -m pip install --upgrade pip
上はpipのアップグレード。インストールしたpython3.9のbinディレクトリに移動して、 そこで実行したもの。
C¶
strcmp¶
文字列の比較をする
- 第一引数 < 第二引数 の場合は-1 (第一引数が第二引数より先)
- 第一引数 > 第二引数 の場合は1 (第一引数が第二引数より後)
- 第一引数 == 第二引数 の場合は0
ソースは次の通り。
#include <stdio.h>
#include <string.h>
int
main(void) {
printf("%d\n", strcmp("aaa", "bbb"));
printf("%d\n", strcmp("bbb", "aaa"));
printf("%d\n", strcmp("ccc", "ccc"));
}
出力結果
-1
1
0
ロケール設定¶
ロケールの設定は、プログラムのコメントにも書いた通り、 locale -aの出力結果に含まれているものから転記する。
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
int
main(int argc, char *argv[]) {
struct lconv *conv;
/* setlocaleのロケール設定はlocale -aコマンドの中からそのまま転記 */
setlocale(LC_ALL, "ja_JP.utf8");
conv = localeconv();
printf("数値形式小数点文字: %s\n", conv->decimal_point);
printf("数値形式整数部セパレータ: %s\n", conv->thousands_sep);
printf("\n");
printf("国際通貨記号: %s\n", conv->int_curr_symbol);
printf("現地通貨記号: %s\n", conv->currency_symbol);
printf("\n");
printf("通貨形式小数点文字: %s\n", conv->mon_decimal_point);
printf("通貨形式整数部セパレータ: %s\n", conv->mon_thousands_sep);
printf("\n");
printf("負でない通貨値の符号: %s\n", conv->positive_sign);
printf("負の通貨値の符号: %s\n", conv->negative_sign);
printf("\n");
printf("国際通貨の少数桁数: %d\n", conv->int_frac_digits);
printf("通貨形式の少数桁数: %d\n", conv->frac_digits);
return EXIT_SUCCESS;
}
コンパイルは次の通り。
cc -Wall -O2 -std=c11 sample_2.c -o sample_2.out
実行結果は次の通り。
数値形式小数点文字: .
数値形式整数部セパレータ: ,
国際通貨記号: JPY
現地通貨記号: ¥
通貨形式小数点文字: .
通貨形式整数部セパレータ: ,
負でない通貨値の符号:
負の通貨値の符号: -
国際通貨の少数桁数: 0
通貨形式の少数桁数: 0
参考URL C言語関数辞典 - localeconv
Hello world¶
#include <stdio.h>
#include <stdlib.h>
int
main(int argc, char *argv[]) {
printf("Hello world!\n");
return EXIT_SUCCESS;
}
コンパイルは次の通り。
cc -Wall -O2 -std=c11 sample_1.c -o sample_1.out
Java¶
javapackager¶
javapackagerを使うとjarファイルからexe形式の実行ファイルを作ることができる。
これがなぜ必要かというと、現在のjavaはjreをユーザーにインストールさせず、 配布する側がコンパクトなjreを同梱させて配布するようにしているらしく、 そのため必要とのこと。なので、jreの配布ということもおこなっていないらしい。
なので、右下にjava updateの通知とかもでなくなる。
それで、このjavapackagerというツールを使って、jarファイルをexe化したので、 そのときに行ったコマンドをメモ。コマンドは次の通り。
自分用のわかりやすさのために複数行になっているけれど、実際は1行。
javapackager -deploy -native image -outdir dist
-srcdir . -srcfiles MyApp-jar-with-dependencies.jar
-appclass my.app.MyApp
-name MyApp -title MyApp -outfile MyApp.exe
nativeオプションでexeを指定するとインストーラーができあがるらしいが、 自分の環境で行うとwindows defenderのエラーが起きた。そのためimageで行った。 imageでは、そのまま実行ファイルがフォルダにできあがる。自分としては理想な形なのでこちらを採用。
outdirオプションで指定したフォルダ直下にMyAppというフォルダが出来上がり、その中に、 exeファイル等々が展開されている。その中のruntimeフォルダの中にjava.dllといったような、 重要そうなファイルもある。
最後にjarファイルの名前から推測できるかもしれないけれど、 自分がjarファイルを作るときは、mavenのプラグインを使って、 1つのjarにすべて詰め込む形で作っている。
JSON¶
書き方のサンプル¶
jsonファイルについてまとめます。
JSONはデータ定義言語のことです。サンプルとしては次のようになります。
{"name": "suzuki"}
決まりとしては次のようなものがあります。
- 文字コードはUTF-8固定
- エスケープ文字が使える。
- 文字列は""で囲む。''はNG。
- nullを使用
- 真偽値はtrue false
- {}を子要素としてもつことができる。階層構造。
- []で配列をつくることができる。
- 要素はカンマで区切る。ただ、最後の要素の後にカンマは付けられない。
上記を踏まえてもう一つサンプル。
{
"title": "users",
"data": null,
"user_list": [
{
"name": "Suzuki",
"age": 20,
"flag": true
},
{
"name": "Sato",
"age": 22,
"flag": false
}
]
}
"flag": falseのあとに,を付けたりするとエラーになる。上のリストの最後の文はこれを言いたかった!!
パソコン¶
Linux(debian)のデフォルトロケールの変更¶
私の環境はWSLというウィンドウズ上でDebianを使っていて、 次のコマンドでロケールを変更した。
sudo dpkg-reconfigure locales
コマンドを打つと、Configuring localesというCUIの設定画面に移る。 十字キーで移動して、スペースキーで選択。エンターキーで決定のような操作。 1つ目の画面はシステムで使えるロケールの設定で、 2つ目の画面はデフォルトのロケールの設定。
設定後は、次のコマンドでロケールの確認が行える。
locale -a
echo $LANG
1つ目は、システムで有効化されているロケールの一覧。 2つ目は、デフォルトのロケール。
画面再起動問題¶
自作パソコンで、CPU、マザーボード、メモリ、グラボを交換した後、 しばらく使っていると、画面が点滅するようになった。 デュアルディスプレイ環境でどちらの画面も点滅、 ディスプレイが再起動してる感じではなかった。
結果として、電源ユニットを容量が大きいものに交換したら治った。
おそらく、グラフィックボードにうまく電源が供給されていなくて、 それによってそのパーツが再起動のような状態になったと思う。 グラフィックは補助電源のようなものはないけれども、交換前は グラボをさしてないので、そのあたりで急に電源容量が増えたためそうなったと思う。
PostgreSQl¶
psqlログイン¶
psql -U postgres
データベースを指定する場合
psql -U postgres -d データベースの名前
psqlを終了させる¶
\q
psqlでデータベース一覧を確認¶
\l
データベース作成¶
create database testdb;
データベース削除¶
drop database testdb;