まるぼ実験場

アプリの開発日記を載せるサイトでしたが、ただの技術ブログになりました。

Pyaudioをループしたときに通知領域のマイクアイコンが荒ぶっていた問題が今更解決した

marubodiary.hateblo.jp
この大昔作ったネタアプリだが、最後に大問題を残したままなのだった。
・起動中に通知領域のマイクが荒ぶる問題
これの解決にようやく取り組む気になってそして解決したので、問題解決版のソースコードを書いておく。

結論

音声入力と画像描画を、スレッドに分けて処理した。

import pygame
from pygame.locals import *
import sys
import pyaudio
import numpy as np
import threading

#pyaudio初期化
chunk = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 44100

p = pyaudio.PyAudio()
stream = p.open(format = FORMAT,channels = CHANNELS, rate = RATE, input = True, frames_per_buffer = chunk)
# 閾値
threshold = 0.025
# 音データ格納用配列
x = np.empty(chunk)

#pygame初期化
pygame.init()
screen = pygame.display.set_mode((500,500))
pygame.display.set_caption("VTuber?")

#画像取得
#基本
bg = pygame.image.load("base.png").convert_alpha()
image_rect = bg.get_rect()
#目
me1 = pygame.image.load("me.png").convert_alpha()
me2 = pygame.image.load("me2.png").convert_alpha()
me3 = pygame.image.load("me3.png").convert_alpha()
#口
kuti1 = pygame.image.load("kuti.png").convert_alpha()
kuti2 = pygame.image.load("kuti2.png").convert_alpha()
#髪
kami = pygame.image.load("kami.png").convert_alpha()
#フォント
font = pygame.font.Font(None, 20) 

#タイマー変数
Timer = 0

#描画周期設定
Clock = pygame.time.Clock()
FPS = 30

	
def draw():
	while True:
		pygame.display.update()
		
		#時間経過
		Timer = pygame.time.get_ticks()
		# 画像生成
		ImageOut(screen, image_rect, bg, Select_Eye(Timer), Select_mouse(x, threshold), Select_Add())
		
		#デバッグ用
		#DebugGraph(screen, Timer)

		pygame.display.flip()
		Clock.tick(FPS)                     #画面更新

def streamread():
	global x
	while True:
		# 音データの取得
		data = stream.read(chunk)
		
		# ndarrayに変換
		x = np.frombuffer(data, dtype="int16") / 32768.0


def main():
	while True:
	# 終了用のイベント処理
		for event in pygame.event.get():
			# 閉じるボタンが押されたときの処理
			if event.type == QUIT:
				stream.close()
				p.terminate()
				pygame.quit()
				sys.exit()

#----------------
# パーツ選択
#----------------
def Select_Eye(Timer):
	
	# 瞬き(力技。。。もうちょい自然な見せ方があるはず
	if ((Timer % 2100) <= 160):
		put_me = me2        #目(閉じ)描画
	else:
		put_me = me1        #目描画
	
	#キー押下によって目の描画オブジェクトを変更する
	pressed_key = pygame.key.get_pressed()
	if pressed_key[K_q]:
		put_me = me3            #目(><)描画
	
	return put_me

def Select_mouse(x, threshold):
	#音声認識によって口の描画オブジェクトを変更する
	if x.max() > threshold:
		put_kuti = kuti1      #音声入力があるときの口描画
	else:
		put_kuti = kuti2      #何もないときの口描画
		
	return put_kuti
	
def Select_Add():
	#一番上に描画する画像(アクセサリーなど)
	put_add = kami      #髪描画
	
	return put_add
	
#----------------
# 描画
#----------------
def ImageOut(screen, image_rect, bg, me, kuti, add):
	screen.fill((0, 255, 0, 0))         # 画面の背景色(緑)
	screen.blit(bg, image_rect)         # ベース画像の描画
	screen.blit(me, image_rect)     # 目画像の描画
	screen.blit(kuti, image_rect)   # 口画像の描画
	screen.blit(add, image_rect)     # 上部画像の描画
	
	return

#----------------
# デバッグ用表示
#----------------
def DebugGraph(screen, Timer):
	print(Timer)
	
	return

#スレッド作成
thread1 = threading.Thread(target=draw)
thread2 = threading.Thread(target=streamread)
thread1.setDaemon(True)
thread2.setDaemon(True)
thread1.start()
thread2.start()

if __name__ == "__main__":
	main()

ChatGPTを使って一瞬で作ったJavaScriptタイピングゲーム

久しぶりにChatGPT使ったら応答がすげー早くなっててびっくりした。
次回作るゲームのたたき台にするためにこのコードを書いて貰ったんだけど、これだけでも結構遊べる気がした。日本語で指示しただけでこれができるとは、すごい……。
AIがイラストの方面で物議を醸しているところで、AIが作成したソースコードを丸々載せるって著作権的にはどうなんだろう……と思うところはあるんだけども、
こんな感じで、なにかしら作る時のベースになるコードをサクッと出させるのにAIを活用するのは良いなぁと思っていたり。

主に指示した仕様
JavascriptCanvasに描画
・方向キーも入力に使えるようにする
・お題を全20題からランダムに設定
・途中で入力に失敗した場合、最初からやり直しにさせる
・クリアしたらお題に手をつけてからクリアするまでの経過秒数をCanvas内に0.5秒間表示してから次のお題を出す

指示してない機能のコードを削らせることにちょっと気を遣ったかもしれない(^_^;

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Typing Game</title>
<style>
    canvas {
        border: 1px solid black;
    }
</style>
</head>
<body>
<canvas id="gameCanvas" width="400" height="200"></canvas>
<script>
    const canvas = document.getElementById('gameCanvas');
    const ctx = canvas.getContext('2d');

    const topics = ['apple', 'banana', 'cherry', 'orange', 'grape', 'melon', 'pear', 'strawberry', 'watermelon', 'pineapple', 'kiwi', 'mango', 'blueberry', 'peach', 'apricot', 'plum', 'fig', 'coconut', 'lime', 'lemon'];
    let currentTopicIndex = -1;
    let currentTopic = '';
    let inputText = 'input: ';
    let userInput = '';
    let startTime = null;

    function chooseRandomTopic() {
        currentTopicIndex = Math.floor(Math.random() * topics.length);
        currentTopic = topics[currentTopicIndex];
        userInput = '';
        startTime = new Date().getTime();
        draw();
    }

    function draw() {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        ctx.font = '20px Arial';
        ctx.fillText(inputText + currentTopic, 10, 30);
        ctx.fillText(inputText + userInput, 10, 60);
        if (userInput === currentTopic) {
            const elapsedTime = (new Date().getTime() - startTime) / 1000;
            ctx.fillText(`Clear! Time: ${elapsedTime.toFixed(1)} seconds`, 10, 90);
        }
    }

    function handleInput(event) {
        const key = event.key;
        const keyCode = event.keyCode;

        if (key.length === 1) {
            userInput += key;
        } else if (keyCode >= 37 && keyCode <= 40) { // Arrow keys
            userInput += handleArrowKeys(keyCode);
        }

        if (!currentTopic.startsWith(userInput)) {
            userInput = '';
        }

        if (userInput === currentTopic) {
            setTimeout(() => {
                chooseRandomTopic();
            }, 500); // 0.5秒後に次のお題に進む
        }

        draw();
    }

    function handleArrowKeys(keyCode) {
        switch (keyCode) {
            case 37: // Left arrow
                return '←';
            case 38: // Up arrow
                return '↑';
            case 39: // Right arrow
                return '→';
            case 40: // Down arrow
                return '↓';
            default:
                return '';
        }
    }

    document.addEventListener('keydown', handleInput);

    chooseRandomTopic();
</script>
</body>
</html>

サンプル
3ka.me

『パーフェクトPHP』Part3 6章のコードをSQLite仕様に書き直してみる

パーフェクトPHPは良い本なのだが、少々内容が古くなってしまっているため、調べながら読むのが良い。
6章Part3のひとこと掲示板のコードは、例示されているmysql関数が非推奨なので書き換える必要がある。
ついでに、SQLite3クラスを使う仕様に書き直してみた。コメントアウト部分は元コードを現在標準のmysqli関数仕様に書き直したもの(未テスト)
これは筆者が以前にPythonでWebアプリ作ったとき、MySQLを入れてから面倒なことになったので、メインのPC(Windows環境)で開発テスト段階のときはSQLiteを使うようにしているから。(規模が大きくなって必要になり次第、Linux環境のほうに別途環境を構築するようにしている。)
# 書籍からSQL文などの箇所を流用する形で書きたかったのでこうなったが、現代ではPDOを使う様にしたほうが流用しやすそうと思う。

(2024/04/07 ソースコードの間違いとインデントを見やすく修正。ついでにステートメント版を追加。)

データベース接続

//データベースに接続
/*
$link = mysqli_connect('localhost', 'root', '');
if(!$link){
    die('データベースに接続できません:'. mysqli_connect_error());
}

//データベースを選択する
mysqli_select_db($link, 'onbline_bbs');
*/
    
try{
    $link = new SQLite3('hitokoto.db');
}catch(Exception $e){
    die('データベースに接続できません:');
}

SQL作成・保存

なるべく書籍に近い書き方で。

//エラーが無ければ保存
if(count($err_msg) === 0){

 //SQL文作成
$sql = "INSERT INTO 'post' ('name' , 'comment', 'created_at') VALUES ('"
           //. mysqli_real_escape_string($link, $name) . "','"
              . $link->escapeString($name). "','"
           //. mysqli_real_escape_string($link, $comment) . "','"
              . $link->escapeString($comment) . "','"
              . date('Y-m-d H:i:s') . "')";
            
//保存する
//mysqli_query($link, $sql);
$link->query($sql);

//mysqli_close($link);
$link->close();

header('Location: http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
}

実際にはステートメント使う方が多いのかな?ということでステートメント使用版。

$sql = "INSERT INTO 'post' ('name' , 'comment', 'created_at') VALUES ( :name, :comment, :date )";
$date = date('Y-m-d H:i:s');

$stmt = $link->prepare($sql);
$stmt->bindParam(':name', $name, SQLITE3_TEXT);
$stmt->bindParam(':comment', $comment, SQLITE3_TEXT);
$stmt->bindParam(':date', $date, SQLITE3_TEXT);

//保存する
$stmt->execute();

$link->close();

HTMLの表示用要素取得部分

 // 投稿された内容を取得
$sql = "SELECT * FROM 'post' ORDER BY 'created_at' DESC";
//$result = mysqli_query($link, $sql);
$result = $link->query($sql);

$posts = array();
//if($result != false && mysqli_num_rows($result)):
     //while ($post = mysqli_fetch_assoc($result)){
if($result !== false && $result->numColumns()){
    while($post = $result->fetchArray()){
       $posts[] = $post;
    }
}
            
//取得結果を開放して接続を閉じる
//mysqli_free_result($result);
//mysqli_close($link);
$link->close();

余談

スタードメイン(無料サーバー)上でSQLiteが使えるかを上記コードにした状態でテストしてみたところ、
書き込み、読み込み共に問題無さそうだった。
夢が広がるね。

諭吉2枚中古ノートパソコンで遊ぶ ~Linuxによるデュアルトリプルブート~

ここからLinux転生編がスタート。

marubodiary.hateblo.jp

前回記事は中古パソコンを買ってちょっとカスタマイズした記録まで。

今回はLinuxをインストールしていきますが、一応まだサポート残ってるWindows10があるので残しておこうかなと。なるべく安全に(?)WindowsLinuxデュアルブート機にすることが今回の目標です。

基本的に同じストレージ内に複数OSを入れるデュアルブートはトラブルへの見舞われやすさ諸々を考えてあんまりやるべきではないのだが、こうやって色々実験するのに格安中古パソコンはうってつけってわけよ。

いやぁ、どこかの会社で要らなくなって市場に出されたと思われる元高級ノートパソコンでこうやって遊べるなんて、追放モノラノベみたいで楽しくなってきますねぇ!(何言ってんだこいつ)Linuxに転生してこれからも大活躍するんだ!

1.Linux mintをインストール

最初にインストールするOSはLinux mintにします。

無難にUbuntuのが良くない?Ubuntuはなんか飽きた。という理由でmintになりました。

f:id:kikyou_kiki:20231221104316j:image
まずはGpartedでLinuxの領域を確保します。

インストーラーでもその辺はいじれますが、それよりも使いやすくて分かりやすいパーティション管理ツールなのでこっち使うのがオススメ。

Windows10 約180GB

Linux mint 約80GB

にしておきました。

スワップ領域は……SSDなので無くてもいいかな……?


領域決めたらデスクトップにあるアイコンを押してインストールしていきます。

ex.Linuxブートローダーどうするの問題

ブートローダーはパソコンの電源を入れるとBIOS(UEFI)から呼ばれ、OSをブートするプログラム。(ざっくり説明)

インストール時にブートローダーの場所を指定する必要があるが、この選択はかなり重要だったりする。

特に何も指定しない場合、ディスクの先頭のEFIパーティションブートローダーをインストールしようとする。

OSを一つしか入れない状態ならもちろんそれでも問題ないのだが、Windowsがインストールされている所謂デュアルブート環境だと問題が発生する可能性がある。

Windowsがインストールされている環境では、この場所には既にWindowsブートローダー(Windowsブートマネージャ)が入っている。

この状態でLinuxブートローダーをインストールした場合、Windowsブートマネージャは消えるわけでは無いが、起動時に呼ばれるブートローダーがLinuxブートローダー(GRUB2)に置き換えられて、そこからWindowsブートマネージャを呼ぶ形に変更される。

一応それでもちゃんとデュアルブートは出来るが、Windows側がデュアルブートであることを認識しない(というか推奨していない?)ため、Linuxに構わずブートローダー部分をアプデで上書きしてしまうことがある。


ブートローダー書き換えによってOSが起動出来なくなるなど、かなり面倒いことになる可能性が考えられる。

なので、Linuxブートローダーはなるべく独立させたいのと、Windowsブートローダーはなるべく維持しておきたいのです。


f:id:kikyou_kiki:20231221104425j:image

f:id:kikyou_kiki:20231221104445j:image
ということでインストールの種類を「それ以外」、ブートローダーはWindowsブートローダーがある場所とは別の場所にインストールする方法にしたいと思います。

今回は、Linux mintは「/dev/sda4」、ブートローダーはLinuxになるパーティションの先頭にインストールするように指定しインストール。

f:id:kikyou_kiki:20231221104527j:image
再起動するとLinux mintブートローダー(GRUB2)のメニューが起動します。


これで完了……かと思いきや。

調べてみるとブートローダーの場所がおかしい。

f:id:kikyou_kiki:20231221104544j:image

dev/sda2、Windowsブートローダーの場所では……?ちゃんと/dev/sda4にしたはずなのに……どうして……

普通に使う分だと気にならないかもですが、筆者は気にしてるのでもうちょっと調べてみます。

f:id:kikyou_kiki:20231221104556j:image
Windows上から調べた。……思いっきり同居してますやん。

 

【Ubuntu】【上級者向け】Grubブートローダを削除する – 茱萸note

一旦別のLinux(あるいは先ほど作成したUSBのLinux)からブートローダーの情報を削除してからもう一度やり直してみる。


ちなみにこの間割愛するけど、GRUBの再インストールコマンドとかブートリペアツールやら別OSからごにょごにょとかも使ってみたけど何をやってもブートローダーがdev/sda2に戻ってきた様子だったよ、なんでや。


色々調べてみると、ブートローダーは先頭2TBまでのfat32フォーマットの領域からでないとUEFIが読み出せないという記述を見つけたので、

パーティションの切り出しからOSインストールをもう一回やり直す事にしました。

f:id:kikyou_kiki:20231221104755j:image
今度は専用のブート領域を作ってそこにインストールするよう指定する……。

f:id:kikyou_kiki:20231221104829j:imagef:id:kikyou_kiki:20231223095808j:image
……????


は????

 

Ubuntu 22.04 その191 - UEFIのブートローダーが選択されたデバイスにインストールされない不具合 - kledgeb

どうやら不具合があったらしい。
今のmintのバージョンはUbuntu22.04なので、もろですやん……。

との事で上記記事の対処法、インストール前にGpartedでWindowsブートローダー領域のフラグから「esp、boot」などのフラグを外してから専用のEFI領域にインストール。

再起動後はブートメニューが飛ばされてそのままLinux mint起動。(先ほどフラグを変えたため、他ブートローダーにいるWindowsの存在が認識されていないと思われる)


f:id:kikyou_kiki:20231223095821j:image

今度は成功したみたい。

でも今後のアップデートとかで戻ってきそうでコワイとこ。

(今更だけど、パーティション先頭にブートローダーかつEFIフラグオフでのインストールも試してみれば良かったかなぁ……)

2.manjaroをインストール

mintの項目が長くなりましたが、トリプルブートチャレンジ。

先ほどと同じくUSBにセットアップディスクを作ってブート……する前に、UEFIの設定でセキュアブートをが無効になってることを確認。

そう、これがWindows11だと、Linuxの一部のディストリビューションデュアルブートしたいときに、どうしてもセキュアブート対応で問題が出てくる。

そのためにWindows10の中古を選んでいた所がある。メインのパソコンはさっさと11にしてしまったのもあってね……。今後に期待。


f:id:kikyou_kiki:20231221104925j:image
さっきいじったブートローダーのフラグを元に戻して、残しておいた領域から80GBくらいをmanjaroで使うように設定する。

余りはNTFSでフォーマット……WindowsLinuxの両方から読めるデータ領域にするつもり。

それ以外の設定はウィザードに沿って進めていきます。

f:id:kikyou_kiki:20231221104936j:image

manjaroではブート領域を用意しないと怒られる。

f:id:kikyou_kiki:20231221104944j:image

さっきLinuxmintのブートローダーでだいぶん失敗したのでこうやって確認してくれるのは好印象。
manjaroはブートローダの場所も問題なく、すんなりインストール完了。f:id:kikyou_kiki:20231222021624j:image

再起動後のブートメニューには3つのOSがバッチリ載っていました。

最後をmanjaroにして本当に良かった……!(リアルにmintのブートローダー検証で役に立った)

f:id:kikyou_kiki:20231221105000j:image
Windowsからも確認。問題無さそうです。

3.ブートローダーをカスタマイズ(したかった)

ほんとはWindowsブートマネージャからLinuxを使えるようにしたかったのですが、設定するのはちょっと面倒そうなので最後にインストールしたmanjaroのブートローダーから使うようにしたほうが無難そう。

先ほど言ったように、後から入れたOSは既に入っているOSを検出してメニュー作ってくれているので、今後はmanjaro上からブートローダーの設定をするようにします。

順番とか表示時間とか。

https://w.atwiki.jp/linuxjapanwiki/pages/214.html#partition

Windowsブートマネージャを触る方法については、同じ手順やったけど、筆者の環境では失敗したのよね……(ブートマネージャにメニューは追加されるが起動出来ずエラー)

(ストレージがMBR形式のディスクなら、EasyBCDやMBMを使うのが綺麗でよさそう。)

まとめ

Windowsと色々なLinuxデュアルブートして遊びたいなら今のうちに10のパソコンを買うと楽かもしれない。

ブートローダ絡みで結構苦労した……その分仕組みとか復旧の仕方とか勉強になった。今はUbuntu(Linux mint)のインストーラーには注意しよう!!

諭吉2枚中古ノートパソコンの遊び方 ~諭吉1枚のDIY精神でSSDを添えて~

突然ですが中古Let's note買いました

f:id:kikyou_kiki:20231221102228j:image

  • 型式:CF-SZ6
  • CPU:i5-7300U
  • ストレージ:SSD256GB
  • メモリ:8GB
  • ドライブ:なし

2017年頃のモデル。梅田の某ショップで17800円でした。

モバイル性に特化したモデルで、筐体の軽さと非常に長いバッテリー持ちが特徴。

バッテリーはまだ純正新品が売られているみたいなので、入れ替えればまだまだ長く使えるのではないかと思う。

今ならサポート終了確定の第7世代CPU搭載Windows10がお安くなっているのではないかと中古パソコンショップ覗いてみて気に入ったのでゲット。

型番見るに法人向けのモデルらしい。売り場には同型機が複数台並んでいたりと、何処かの会社の備品更新で流れてきたような品揃えだった。

11対応か非対応か、RAMが16GBあるか出来るかどうかで大幅に値段変わってたのは面白かったな。

レッツノートと言えばザ・日本のビジネスパソコンって雰囲気。持ってるとMacとはまた違ったような出来る奴感が出る気がするブランド。
個人的にはThinkPadかLet's Note使いは強い人が多いイメージ(偏見)

キーボードも軽くて打ちやすく、沢山の機能がコンパクトにそつなくまとまってて個人的には好きだ。

サイズはA4とB5の間くらいで、小さめのバッグにも入る。そしてこのずっしり重そうな見た目で実はMacBook Airよりも軽いというのが良い!

中古パソコンにDIY的楽しさを見出している

前までは持ち運び用PCとしてMacBookを使っていたのもあってか、自分にはやっぱりこういう製品の方が肌に合う気がするなーと。

数あるWindows機の中から、自分好みの機体を選んで、中身や見た目を好きなようにカスタマイズして使う。

ノートパソコンは完成してる分拡張性で劣るが、手を入れられる所が少ない分、考えることが少なくて済むし、手に入れられる所にあえて手を入れることで愛着と満足感が得られる。(ソフトとハード、どっちを主に触りたいかの好みによるかと)

またOSはLinuxにする。このためにあえてサポート切れる10を探していたようなもの。

目的や好みに合わせて選べるディストリビューションの選択肢があるし、Linux系はカスタマイズ性に優れていたり、普段触っていてもついつい手段が目的化してしまうような所が恋しくなっていた。

 

新品で買ったり今メインで使ってるようなパソコンでやるには勇気がいるが、中古ならば気兼ねなくこういったチャレンジングな遊び方ができそうだ……と思ったのである。

ということで新連載(?)

ここ最近やってきたことの記録を記す。

これから使い倒して行くために、先にバックアップ兼パワーアップを施していきますよ〜

ミッション1、SSDを換装する

f:id:kikyou_kiki:20231221102251j:image

届いたパワーアップキット。

デフォルトのSSDは256GBとちょっと物足りないので、500GBのSSDに換装します。

1.買い揃えたもの

M2.SATA接続、2280サイズのSSD

今回はウェスタンデジタル製の500GBにした。

M2.SATA2280対応のSSDケース。HDE-12というものを用意した。

対応規格がM2.SATAで、最近主流?で形もよく似ているM2.NVMe規格と間違えないように注意やね。

2.内蔵SSDのクローンを作成する

クローン作るには専用のソフトを使うのがメジャーみたいですが、今回はウェスタンデジタルSSDにしたので、無料でクローンツールが使えます!

移行先が移行元のどちらかがウェスタンデジタル製の場合にのみ使えるようです。

 

まずは新しいSSDをパソコンにUSBで接続して、「新しいディスクを追加」からフォーマットします。

MBRとGPTの選択には注意。このパソコンの元々内蔵のSSDはGPT形式だったのでそれに合わせます。「ディスクの管理」で調べよう。

f:id:kikyou_kiki:20231221102347j:imageクローンツールを起動したら、OKぽちぽちして内蔵SSDを丸々クローンします。

Windows本体自体のバックアップになるのでいざという時に安心です。

これからのミッションでWindows自体消し飛ばしちゃうかもなので、これで安心。

念の為、新しいUSBメモリーも用意して、回復ドライブも作っておきます。

3.内蔵SSD交換

次は本体の内蔵SSDと新しいSSDを入れ替える……のですが。その前にある実験。

Windows10はUSB接続の外部メディアからは起動出来ないという噂。f:id:kikyou_kiki:20231221102410j:image

ここでさっき作ったSSDのUSBを挿しっぱなしにして再起動、F2連打でUEFI(BIOS)設定に入りUSBから起動してみます。f:id:kikyou_kiki:20231221102431j:image

おおう、心臓に悪いこの画面。
この状態で本当に入れ替えるだけで起動するのか?不安になりますがやってみます。


親の仇かってぐらいネジが多いっ!(←裏蓋ネジを回してる時の呟き)

 

入れ替え完了して電源入れる。

f:id:kikyou_kiki:20231221102442j:image
最初はこんな画面が表示されますが、「終了してWindows10に進みます」をクリック。

するとまるで何事もなかったかのように無事にWindows10が立ち上がりました。やった~

※問題無さそうならここでもう一回回復ドライブ作っておく。パーツ構成が変わったのでさっき作った回復ドライブは使えなくなってる可能性大。

まとめ

1kgに満たないノートパソコンは、いいぞ!

今サポート切れ予定のWindws10がお買い得。

 

キリの良いところで、次回に続きます~。

marubodiary.hateblo.jp

 

やりたいことリスト 2023

就職活動で面接練習をしてきた。

転職サイト眺めてると、自分に出来そうな仕事なんてないのかな……ってすごく弱気になってきていたけど、

自分の経歴を見た担当者が、伝え方をこのように工夫すると良い、とアドバイスくれたりしてくれて、

もっと自信を持てるのかもしれない、とちょっと元気出てきた。頑張りたい。

 

面接練習の時言われたのは、志望動機にやりたいことが見えて見えてこない、ということ。(貴社に入って〇〇の開発がしたい…みたいな。)

言われてみれば、自分としてはただ技術に触れたい、プログラミングが好きだから、人にものを伝える仕事がやりたいってところが先行してて、会社に入ってからやりたいこと、達成したいことはフワついた印象になってしまっていたのかもしれない。

あと、プログラミングがしたいのかデザインがしたいのかどっちなのか分からないとか。

はやく実務の環境で吸収することによって自身の成長をもっと感じたい、みたいなところかなぁ。

 

じゃあ自分がやりたいことって…?

正直、会社に入ってからの事って、まだ思いつかないのが正直なところ。

 

ではここで、仕事や趣味関係なく、いつか自分の力でやってみたい、と思っていることをリストアップしてみようと思う。

 

ポートフォリオサイトの完成

ホームページ自体はあるけど趣味性強すぎて同じ趣味の人以外にはあまり見せたくないのとデザインが(わざとではあるが)ダサいため。

 

・布教紹介チラシみたいなの作ってみたい

雑誌みたいなレイアウトにしてページ沢山作れたら本ができるな〜いつか作ってみたい。

 

・読んだことのある技術書レビュー

その本読んで何を吸収して何を作ったのか、みたいな感じでレビュー。

自分は何ができるのか、っていう棚卸しの意味でも良いかもしれないと思ってる。

 

アケコン(スティック)改造

最近思いついたネタ。

マイコン内部のメモリーにスティックのキーコンフィグ設定を保存できる専用アプリと機能を追加したい。

 

マイコンで家の照明とエアコンをオート化したい

力技スマートホーム化(笑)

エアコンや照明のリモコン赤外線を解析してラズパイとかのマイコンで送信出来るようにしたら出来そう、って思ってたりする。

消灯時間に照明落ちるようにしたり、冬場の朝に自動でエアコン運転させたりしたい。

 

・某cgiの改造

投稿ボタンや投稿ボックスが常に表示されてるようにしたい、アマゾン等の商品埋め込めるようにしたい。

ただあのCGI、内部のプログラムはアプデで書き換わってしまうので、現状触われるのはcssやテンプレートだけ。

 

・配送料計算機のデザイン改善

→一段落

 

・ふぁじいすいーぱー改修

グラフィックで止まってるのなんとかしたいよね……

 

マインスイーパーとパズルゲームを組み合わせたようなゲーム作りたい

相変わらずマインスイーパーにハマってるので。

原作では地雷に当たるとアウトだったけど、逆に地雷を起動させて障害を解消したらクリア、みたいな。

 

・ブラウザ上で遊べるローグライク的なゲーム作りたい

キャラメイク要素や、オンラインでメッセージ送ったり救援して…みたいな要素も入れたい。

 

cgi作って配布したい

ツールとして考えてるのはTodo管理アプリみたいなやつ。

ゲーム系なら、昔と違ってマネタイズの仕方とか広告での収益化とか色々考えられると思うんだ…

 

・デスクトップマスコットみたいなの作りたい

付箋紙アプリの亜種で、納期とか管理してくれる感じの…

仕事の管理とかしてくれたり、入力に応じてchatGPT経由でヒントくれたりしてくれたら最高なのに(妄想するだけ)

 

・キャラクターメールみたいなの欲しい

昔流行ったようなやつ。スマホとの相性良いとずーっと思ってるんだけどそもそもどうやって実現するのかわからず。あとキャライラストとか沢山用意するのが自分にはきつい。

 

・もっと絵上手くなりたい

伝えたいことを伝えるって意味ではもっと上手くなりたいなーと。

旅行によく行くので空気感を取り入れた風景イラストとか。

最近ロボアニメにハマったのでメカや工業製品とかにも興味。推しキャラの機体とセットで描けるようになりたい。

 

イラレでイラスト作品にチャレンジ

昔一目惚れした好きなイラストレーターさんがIllustratorで主線なしのイラストを描かれてて、それにすごく憧れてる。

昔のオンゲーの2Dアバターみたいなの好きだから作ってみたい。

続・アーケード風ジョイスティック自作

前回はアケコン品薄時代に対抗すべく、単品売りしているジョイスティックをPCに繋げて活用するという(斜め上な気がしなくもない)手法を提案したところだが、
marubodiary.hateblo.jp

今回はさらなる進化を遂げたのだった……。

外箱作りました

天板サイズは12cm*12cmの正方形、高さは7cm……のつもりだった。
ホームセンターのカットサービスで依頼したのに寸法ミスられて天板の長さが大体11cmになってた件について。まぁちょっと大きめに依頼してたから問題ないけども。

最初は全部ボンドでくっつけようと思っていたのだが、それだとメンテしたいときに困るくね?ということに気づいて、天板はマグネットでくっつけるように。工具なしで開けやすく、戻すときにもぴったり戻しやすくなった。

あと気休め程度かもだけど、箱の底面にもプレー中のズレ防止に滑り止めマットをカットして貼り付けた。

コマンド表も入れられる!?便利な多目的スペース

100均で見つけたA7サイズカードケースが丁度良い大きさだったので、それを前面に貼り付けただけである。
コマンド表やお好みのイラスト入れられたりと活用方法は色々あすはず。
既製品のアケコンの天板って絵を変えられるとかカスタマイズしやすいやつがあったりするし、そんな感じのイメージ……。
やってて思いついたけど、MDFを柱だけにして全側面をカードケースにしてみても面白かったかもしれない。

ArduinoをProMicroに

実は内部もちょっと弄ってたり。

LeonardoからProMicroにして基板のコストとサイズをダウン。
小型化して筐体の中に組み込みやすくなりました!!そして持ち運びにも便利(?)

ブレッドボードに空いていたスペースにトグルスイッチを追加して新機能も追加。
ソースコードの書き換えなしにWASD操作と方向キー操作をいつでも切り替えできるようになりました!すぐに1P2Pが切り替えられる!便利!!

トグルスイッチ追加版ソースコード
#include <Keyboard.h>

//セイミツ工業LS-32-01使用、ハーネスを右上とする
const int PIN_A = 2; //緑
const int PIN_B = 3; //黒 
const int PIN_C = 4; //赤
const int PIN_D = 5; //黄
const int PIN_SW = 7; //トグルスイッチ用

void setup() {
  // put your setup code here, to run once:
  pinMode(PIN_A, INPUT_PULLUP);
  pinMode(PIN_B, INPUT_PULLUP);
  pinMode(PIN_C, INPUT_PULLUP);
  pinMode(PIN_D, INPUT_PULLUP);
  pinMode(PIN_SW, INPUT_PULLUP);

  Keyboard.begin();
}

void loop() {
  // put your main code here, to run repeatedly:
  int val_a,val_b,val_c,val_d;
  int switchstate;
  
  val_a = digitalRead(PIN_A);
  val_b = digitalRead(PIN_B);
  val_c = digitalRead(PIN_C);
  val_d = digitalRead(PIN_D);
  switchstate = digitalRead(PIN_SW);

  if(switchstate == HIGH){
    val_b == 0 ? Keyboard.press(KEY_UP_ARROW) : Keyboard.release(KEY_UP_ARROW);
    val_a == 0 ? Keyboard.press(KEY_DOWN_ARROW) : Keyboard.release(KEY_DOWN_ARROW);
    val_d == 0 ? Keyboard.press(KEY_LEFT_ARROW) : Keyboard.release(KEY_LEFT_ARROW);
    val_c == 0 ? Keyboard.press(KEY_RIGHT_ARROW) : Keyboard.release(KEY_RIGHT_ARROW);
  }else if(switchstate == LOW){
    val_b == 0 ? Keyboard.press('w') : Keyboard.release('w');
    val_a == 0 ? Keyboard.press('s') : Keyboard.release('s');
    val_d == 0 ? Keyboard.press('a') : Keyboard.release('a');
    val_c == 0 ? Keyboard.press('d') : Keyboard.release('d');
  }
  
  delay(1);
}

ここまでの実制作期間は2日ほど。自分にしては珍しく勢いで作りきった!
こういうのは置いとけばおいとくほど面倒になってしまうたちなのでさっさと形にしてしまうに限る。一度作ってみることで分かることも多いので。
先述のプラスチックカードケースを全面に使うとかのアイデアもそのうちやってみたいなぁ。
格ゲー沼よりアケコン制作の沼に落ちかけてる
思えばこの人、肝心のソフトは買ってないのになんでコントローラーから先に作ってるんでしょうね……。