なーたのおぼえがき

なーたのおぼえがき

つくったものとか

Google Apps Sctriptで作る参考文献管理ツール② 検索編

こんにちは。暖かくなってきましたね。燕もそろそろ古巣に帰ってくる時期ですし、本当に春って感じ。この間帰宅途中に花桃を見ました。やっぱり綺麗ですね。私は割とソメイヨシノよりも大島桜や山桜が好きなタイプなので、桜並木で綺麗と言われる淡い桜色の集合を見ると「ソメイヨシノー!!」って思います。梅とか桃も花綺麗ですよね、美味しいし。
ちょこちょこお散歩していて思うのですが、花の蜜を好む小鳥たちを見かけない気がしています。道路を彩る桜の花びら、基本的に花びらだけで丸ごと落ちていること、少ないですよね…?
まあそれは地域の特色かもしれないのでおいといて。

別段難しくもないやつを作ったからという理由でまとめるシリーズ(今考えた)第2弾、参考文献管理ツールの検索部分です。れっつごー

はじめに

これは第2弾です。
第1弾は登録編
clairdeluna-eve.hatenablog.com

動機は共通。つまりテンションです。

ツールの動きと外装

外装はこんな感じ
f:id:Clairdeluna_eve:20220409181635p:plain
備品と違ってカード型のレイアウトを採用してみました。なので実装がtableではなくdivの中にaタグ。アイコンは変わらずgoogle material iconを使ってます。便利便利。

動きにも特筆することはなく、検索窓に検索語を入れてアイコンクリックで検索される感じ。中身に関しては備品検索と同じ。
カードをクリックすると該当のページやファイルに直接アクセスできます。以上。

詰まったとこ

唯一タイムゾーンに翻弄された…いや、タイムゾーンではないか。時間周りの仕様(多分)?
解決策は簡単で、getValuesではなくgetDisplayValuesを使ってデータを取得しました。

発覚の状況

システム-データ間の関係がこんな感じ。GASはjsを含む表示まで含めたものだと思ってください。
f:id:Clairdeluna_eve:20220409184035p:plain

実際に使いながらデバッグをしていたところ、登録日の表示(外装では薄い灰色の日付)がスプレッドシートの日付と異なっていることに気づきました。

調べたこと・全体の状況

こういう、1日2日程度の日付の前後はタイムゾーンであろうという予想のもと仕様を確認。
で、Google Apps Scriptくんですが、デフォルトタイムゾーン設定がAmerica/New_York。スプレッドシートくんはAsia/Tokyo。
該当の登録日はGASでnew Dateから取得して書き込み、スプレッドシートでは日付型として認識されています。
スプレッドシートでは問題なく、記憶と同一の日付が表示されていました。
つまり登録部分では問題は特になし。とはいえ一応タイムゾーン設定はAsia/Tokyoへ変更。
参考は
walking-elephant.blogspot.com

次に検索の部分。
受け渡し前の生データを表示させると
f:id:Clairdeluna_eve:20220409192503p:plain
うん、知ってた。さっきと同様の手順でタイムゾーンをAsia/Tokyoへ変更。
タイムゾーンが原因ならばこれで問題なくなるはず。と思って実行したけどあれー?
1日ずれたまま。あれー??
console.logで受け渡し前と表示するデータを書き出してみると、やっぱり表示するデータが一日ずれてる。

原因と思しきこと

もしかして、jsのタイムゾーンが実行環境に依存するから…?
推測でしかないのだけど、先ほどの手順で変更できるタイムゾーン設定は.gsのみで、普通にサーバで実行されたjsのタイムゾーンは元のAmerica/New_York、とか。

対処

1つ1つのデータに対してUtilities.formatDateでタイムゾーンを直して表示するのは無駄すぎるのでスプレッドシートの表示データをそのまま持ってこれるgetDisplayValuesを使って、表示用のデータを取得。文字列として日付型を取得して表示に回した。
無事にスプレッドシートと同じデータが表示されてハッピー。

おわりに

時間の表示以外に詰まったとこがないのでめちゃくちゃ虚無い中身になった。備忘録といえばそうなのでまあいいか。

大学も来週から講義が始まるけど、起きられるかとかその辺だけがとにかく心配。夜更かしには気をつけねば…
ということでこの辺でー

Google Apps Sctriptで作る参考文献管理ツール① 登録編

割と短期スパンでこんにちは。もう3月末とか正気ですかね…?ついこの間、春休みが始まったばかりのような気すらするのにあっという間に新学期です。冬眠してたんですかね、あまりにも時間が過ぎ去ってる。

さて、今回は先日の備品登録・検索システムを眺めていて「これ、何か別の作る時に使えそうだよなあ」と思っていました。
そして後日、割とたくさんの文献を読む必要があり、いつものように1つ1つメモを書いていたんですが突然面倒になって…?!ということで、文献とWebサイトをメモとともに管理できるようにツールを作ります。
では、いってみよー

はじめに

動機

「参考情報の管理めんどくさーー!!」って思ったから。論文を見る・参考になるWebサイトを見るといった場合に大体メモを書くんですが、とっても面倒だし検索できないし、何より紙媒体で書いているので忘れる・失くすということが割と多発。
大体こんな感じで書いてる。
f:id:Clairdeluna_eve:20220329011735j:plain
8cm四方くらいなのでそりゃあどっかこっか紛れるし消える。1文献1〜2枚で書くのですぐ増える。
つまり動機は「これ、どうにかならんかな…」です。

ここで書くこと

簡単にいうと、めっちゃくちゃ詰まった部分です。GASの仕様的な部分が割と大きいかもしれない。
ツールとしてやっている動作はすごく単純なものばかりで備忘録しなくてもいい程度のものなので。

環境と使ったライブラリ

Mac book pro
GAS
swiper

ツールの動きと外装

外装

外装はこんな感じ。
PC画面でのレイアウト
f:id:Clairdeluna_eve:20220329015501p:plain
スマホでのレイアウト
f:id:Clairdeluna_eve:20220329020002j:plain
登録する対象は、論文やファイルとWebサイトに分けています。論文やファイルはファイルそのものとタイトル、発行年、キーワード、概要、新規性・特徴、メモ。Webページはサイト名・記事タイトル、URL、キーワード、概要、参考になった情報、メモ。それぞれはタブで切り替え可能になっていて、スワイプにも対応してます。

ツールの動き

論文・ファイル

ファイルを選択、タイトルや内容について入力して送信すると、Google Driveの指定のフォルダに選択されたファイルを「発行年_タイトル」とリネームしアップロード。入力した情報はSpreadSheetに格納・蓄積される、という流れになってます。
内部的には

  1. ユーザがフォームへファイルやテキストを入力する
  2. submit時にgoogle.script.runでGASの自作関数を呼び出し、this.parentNodeでフォームの情報を直接渡す
  3. ファイルが選択されていない場合は処理しない
  4. ファイルオブジェクトをcreatefileに渡し、アップロード処理をする
  5. ファイルをリネームし、URLを取得
  6. 入力データ含め全てをSpreadSheetに書き込む
  7. 通常のsubmit関数を実行し、データを送信
  8. doPost関数がindex.htmlを返却

という処理。誰でも思いつくようなのをぽちぽちやっただけって感じです。

Webサイト

入力したらそのまま何もせずにSpreadSheetに投げ込む。以上。マジでなんもしてないので書けることもない。ないったらないない。

詰まったところ

ファイルが送信できない

知識不足でやっちゃったやつ。
初めてちゃんと認識したんだけど、MIME typeの設定つまりHTTPヘッダーのcontent typeの設定がmultipart/form-dataだとファイルを送信できるらしい。ただ、ちょっと仕様が理解できなかったのとファイルエンコードのやり方がわからなかったので、google.script.runで引数としてformの要素を投げて処理する形で実装しました。

発覚の状況

f:id:Clairdeluna_eve:20220330035120p:plain
実行したら「Exception: パラメータ(String)が DriveApp.Folder.createFile のメソッドのシグネチャと一致しません。」と出た。この時点では「あれ?POSTでフォームデータ送ってるはずなんだけど指定間違ったかな?」と思ってた。他の送信する要素が全部文字列だったので、そっちと指定ミスしたかなと。でもコードを確認したら指定のミスはしてなかった。もしかして…?とtypeofをかけてconsole.logでファイルオブジェクト(が送信されてると思い込んでた)要素を指定して出力。その結果、Stringだった。でもって受け取った情報をそのまま出力させたらファイル名だった。
f:id:Clairdeluna_eve:20220330040249p:plain
なるほどね〜??

原因

GASがPOSTするときのデフォルトcontent-typeがapplication/jsonだったため、ファイル自体の送信ができていなかった。

解決策

通常、content-typeを明示的にmultipart/form-dataに設定するすることでBace64やバイナリデータとしてファイルを取得できる。取得したファイルのバイナリデータなどはエンコードすることでファイルオブジェクトとして利用できる。
が、私にはちょっとエンコード周りのやり方がわからなかったので、別の方法で解決しました。

<!-- index.html -->
<form method="post" action="https://script.google.com/a/macros/xxx/xxx/exec" onsubmit="return false;">
<!-- 中略 -->
 <input type="submit" class="submitbutton" value="記録" onclick="google.script.run.postFile(this.parentNode);submit()">
</form>
// コード.gs
function postFile(ref){
 let fileObj=Folder.createFile(ref.file);
}

submitした時にGASの関数であるpostFileを呼び出してフォームのデータをそのまま渡す、渡されたデータをGASが処理する、と言う形です。その後に通常のsubmit処理がされる(Webサイト側の送信後の処理とindex.htmlの返却はdoPostに書いてる)。
この方式にするとちゃんとオブジェクトが取得できる。
f:id:Clairdeluna_eve:20220330195917p:plain
その後は普通にファイルオブジェクトとして扱えば良い。

PC用のCSSスマホにも反映される

GASの仕様に翻弄されたもの。
なんとなーくmediaクエリ設定したのにちゃんと表示されなくない?とは思ってたので、試行錯誤してた分ものすごく気力を吸い取られた。

発覚の状況

基本的にモバイルファーストで作ることが多いんだけど、PCのレイアウト完全に変えたい時は通常、headにviewportの設定をかけて、mediaクエリでブレイクポイントを決めて変更する感じだと思います。

<head>
<meta name=”viewport” content=”width=device-width, initial-scale=1>
</head>
@media screen and (min-width:480px){
//スタイル
}

これをちゃんとかけても、外装で紹介したようなPC・タブレットだとクリック可能な感じのメニュー部分が2カラム、スマホだとメニューも1カラムみたいにならず、片方のレイアウトを組むともう片方も変わる組む変わる組む変わる…の繰り返し。mediaクエリ、効いてなくない…?

原因

GASではmetaタグをindex.html内に記述しても解釈されない。

解決策

.gs内でHTMLサービスをevaluateした時にaddMetaTagでmetaタグを記述する。マジでこれだけ。ほんと、ドキュメントに最初目を通した時に気づかなかったのがすごく悲しい。

おわりに

単純な仕組みの割に知識不足で詰まったのでなんとも言えない気持ちになりました。まあ今度からは疑えるはずなので、はずなので…
次は検索部分についてかなあ…まだ作り途中だからちょっと先になるけど
では、このへんでー

Google Apps Sctriptで作る備品検索・登録システム

もうだいぶ春めいてきましたね。公園の芝生も柔らかい色になってきて、黒いアスファルトにちらほらと転がっていく花びらもいる。花粉さえなければ、程よく肌寒く日差しの暖かい過ごしやすい良い季節です。
卒業シーズンでもありますが、大学院へ進学するのであんまり実感がわかない…。先輩や友人が卒業していくので、「門出だね!」とは思いますが、所詮それまで。気軽に遊べなくなるんだろうなあとちょっと寂しい気持ちはあります。

さて今回は題目の通り、Google Apps Script(以下、GAS)で作る検索・登録システム。前々から「研究室の備品をどうにか管理したい」「何があるんだかなんもわからん」みたいな状況だったので、春休みであれこれとデータ化とかをしたかったわけです。卒論もあり、私の後回し癖もあり結構終盤での(暫定)完成。実作業時間は1日ないくらいですが、思っていたよりも苦戦したので、どうせまた同じとこで躓くでしょという気持ちもありまとめてみることにしました。

前提

要件

制約
  • 開発に工数が多くかからない
  • 1人で作りきれる
  • お金かからない
  • ものすごくダメな感じの人でもとりあえず使える
  • メンテナンスしなくてもいい

以上の制約を踏まえての要件定義!

機能
  • 1枚のページで登録・検索ができる
  • 検索結果はテーブル(表)で示す
  • 基本PCで見ることを想定しているが、スマホでも見られる
非機能
  • 全データ要求以外のレスポンスは3秒以内
  • ローカルに依存せず、クラウド上で完結する
  • 外部ライブラリなどを極力使わない
  • 研究室の人以外が見れないようにする

環境

あれこれの制約によって自動的に環境が絞られてこんな感じ

とっても普通な感じのGAS動作環境です。作業環境はMac Book Pro。

GASってなーに

Googleが提供してるサーバ用意しなくてもWebアプリケーションとかマクロ的な処理が作れる便利なやつ。基本構文はおおよそjavascript。この辺はいろんな人が解説してるので、ざっとだけ。

フロントがHTML・CSSjavascript、サーバサイドがGAS、データベースがSpreadSheet。利点はサーバを用意しなくていいこととGoogle提供のアプリケーションが簡単に使えること、欠点は書き方というか処理の流れに癖があってなんて??ってなるとこが度々あること。いわゆる業務効率化的なものにめちゃくちゃ良いタイプのやつ。トリガー実行とかあるから定期的に同じ処理をする人とか。

今回は普通にWebアプリケーションを作ってくよ。じゃーいってみよー

データ作り

なんと言っても検索システムにはデータが必要。ということで、研究室の掃除兼備品確認を1週間と少しかけてやりました。その結果データ数は474レコード。お掃除の方は友人のお手伝いって感じだったけど、大変だった。
手作業で取ったデータのカラム数は4。

備品名 これは何ですよという情報。型番書いてたり商品名だったり
使用中の個数 消耗品とかで開いてるのとか、個人が占有してるもの
未使用の個数 消耗品で開いてないやつ、誰も使ってないやつ
備考 キーボードの接続方法とか紛失してるものとか

こんな感じ。これを元に検索システムで使えるデータの構造を考えていきます。

まず検索システムである以上「人ってどうやってもの探す?」ということを考えざるを得ないわけです。例えば、ノートパソコン。「Lenovoの」「HPの」というメーカー名、「Let's note」「LIFEBOOK」などのシリーズ名で呼ばれるし、検索したときに欲しい情報には「OSが何か」「型番は?」「いくつあるの」なんてのもある。消耗品だったら「今何があるのか」はもちろん、「こういう種類のやつって何があるの」というアバウトな検索だってあり得る。工具とかなら「壊れていないか」「どういうものなのか(電源はバッテリー?)」も必要。とか色々考えた結果、カラム数は11になった。

名称 検索の時とかに使える、用途的な説明
メーカー名 どこが作ったものか
型番 メーカーが付与した物品を示すコード。検索で出るものを書く
大分類 事務機器・情報機器などの大雑把な分類
中分類 大分類よりも細かな分類。どういう用途のものか
小分類 中分類よりもものの特性に基づいた分類。何に使うのか
種別 消耗品か、備品か、ケーブルか。絞り込みであると便利
状態 破損、廃棄などものそのものの状態
詳細 備考といってもいい。デバイスの対応OSとか付属品紛失とか
使用中 個人が占有している/開封済みの消耗品の個数
全数 使用中の個数も含めた存在個数

こんな感じ!最初はこれに所在や学校の管理下にあるかも入れていたのだけど、別に必要でないよね、ということでリストラ。
例としてプリンタの互換インクだと

名称 Canonプリンタインク シアン C
メーカー名 Astere
型番 371 XL
大分類 事務機器類
中分類 印刷・製本類
小分類 印刷
種別 消耗
状態 -
詳細 互換インク
使用中 1
全数 2

これで1レコードになる。で、これを474レコード分作成するとデータの出来上がり。文章にすると一瞬だけどこれだけで数日かかってるので割と大変だった。

ということで、続いてはシステム構成的な部分に入っていきまーす

開発準備

作り終わったデータはExcelの形式(.xlsx)だったのでDriveにアップロード。メニューのファイルからSpreadSheetに変換して保存、拡張機能からGASを選んだら環境構築終了!

必要な部品を書く

サーバサイド

GASでWebアプリケーションを作るときに必ず必要な部品がいくつかあって、ベストプラクティスに則って書いていきます。
普通に公式を参照します。
developers.google.com
doGet関数、HTMLにcssjavascriptとかを持ってくるためのinclude関数を書きます。下の方に「レスポンシブなUIのためにテンプレートHTMLじゃなくて非同期実行してよね!」と書いてありますが今回の実装では普通にテンプレートHTMLで書きました。なんでかっていうとformタグを使ってPOSTして検索かけて返り値を持ってくる実装にしたんだけど、非同期実行が面倒だったから。ぶん回した方が速かったのもある。
で、結果的にdoGetとincludeとdoPostを書いて必ず必要なものは終了。

//getリクエストに対する処理
function doGet() {
  let template = HtmlService.createTemplateFromFile("index");
  template.myData = [];
  return template.evaluate();
}
//htmlファイル内でincludeができるようにする
function include(filename) {
  return HtmlService.createHtmlOutputFromFile(filename).getContent();
}
//postされた時の処理。レスポンスはkey-value型
function doPost(e) {
  console.log(e.parameter);
  let search=e.parameter
}
フロント

Webサイトに必要な普通のあれこれをやっていきます。ひとまずGAS特有の.htmlと.gs(GASの拡張子)以外作れない仕様に従って、index.html、style.html、script.htmlを作る。
さっき作ったinclude関数を使ってindex.html内にstyle.htmlとscript.htmlを読み込んでいくんだけど、これはいわゆる埋め込みの形をとる。

<!-- index.html -->
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <?!= include('style'); ?>
  </head>
  <body>
    <?!= include('script'); ?>
  </body>
</html>

なのでこの場合、style.htmlは

<!-- style.html -->
<style>
 <!-- 内容 -->
</style>

でなければ解釈できないし、script.htmlも当然scriptタグから書き始めないといけない。でもまあここまで書いてしまえば後は普通にWebアプリケーションを書いていけばいい。

検索に必要なデータの形式を考える

まあ行き当たりばったりだと当然辛いので、どういう形式で検索データとするか、どうやってレスポンスさせるかを考えていきます。
カラムの情報をデータの状態に着目してまとめるとこんな感じ。

名称 文字列 傾向がない
メーカー名 文字列 ある程度偏りがある。空白を許容
型番 文字列。多くの場合英数 法則性がない。空白を許容
大分類 文字列 データが決まっている
中分類 文字列 データが決まっている。大分類に伴って変化
小分類 文字列 データが決まっている。中分類に伴って変化
種別 文字列 データが決まっている
状態 文字列 データが決まっている
詳細 文字列 傾向がない。空白を許容
使用中 数値 空白を許容
全数 数値 空白を許容

とりあえずここで、検索するときのパターンを考えてみます。考えられるのは2つ。

  1. 明確に探しているものがわかる
  2. ぼんやりとこんなものだった気がする

この2つのどちらもが検索で見つけられるようにすればいい。
1. は何を探しているか明確にわかっているから全部のカラムが並んでいても迷わない。それに対して2. はぼんやりとしかわからないから並んでいると困る。
逆に、2. はキーワードだけで検索できたら嬉しいけど、1. はキーワード検索だけだと必要のないものも引っかかってくる可能性が高い。
なるほどーー??つまりキーワード検索と詳細検索を作ればいいんだな!そういうことです。
キーワードの方はいいとして、詳細検索はどうするか。
データの状態から、メーカー名・種別・状態は独立したドロップダウンメニューで、名称と型番はtextboxで部分一致検索すれば充足できそうです。分類は大分類に伴って中分類が、中分類に伴って小分類が変化する、つまりは木構造的にカテゴリデータがあるのでいわゆる連動するタイプのプルダウンの方が親切。
つまりこういうこと

キーワード 詳細検索
名称 自由入力
メーカー名 プルダウン
型番 自由入力
大分類 プルダウン
中分類 連動プルダウン
小分類 連動プルダウン
種別 - プルダウン
状態 - プルダウン
詳細 -
使用中 - -
全数 - -

ということでデータ形状が決まったので、これの通りに作っていきます。

結果表示の方法について考える

元々がテーブルつまり表だし、物品の詳細的な情報ページを持たないので普通にhtmlのtableタグを使って表で構成しようと思います。で、そうなるとGASから二次元配列的にデータをもらってきたい。レガシーにhtmlへデータ渡してぶん回すとして、そのデータをどうやって持ってくるか、という問題があります。
今回はシステムの非機能要件としてレスポンスまでのターンアラウンドタイムの上限が3秒。そして試しにデータを全件取得、表示したときの時間は18秒。といって探してたらこんな記事が。
pineplanter.moo.jp
なるほど、Query関数。
support.google.com
どうもSQLライクにかけるっぽいし、SpreadSheetの組み込みなら手元で扱うときはテキストで良い。計算資源と待ち時間的にも良さそうなので使ってみることに。結局早かったんで採用しました。
ざっとサーバサイドの話もすると、

  1. フロントのHTMLからformのデータをPOST
  2. JSONでパラメータを取得
  3. パラメータでQuery関数の条件式を生成
  4. SpreadSheetのQueryシートのA1にsetValue
  5. 出力された結果をgetDataRangeでgetValues
  6. HTMLへ直接渡して、template HTMLの生成
  7. 回される配列、生成されるtableタグのtd要素

こんな感じの実装。

検索システムの実装

というわけでいよいよたくさん書くターン、とはいっても今回は構造がシンプルなのでそんなにたくさんはないです。

フロントを先に作る

今回はHTMLのformからデータを受け取ってーという処理なので先にフロントをいい感じに作ります。

作りました。

とってもシンプル。虫眼鏡アイコンはGoogle Material Icon、つまりGoogle Web Fontから持ってきてペイってした。
fonts.google.com
で、このページはこんな感じの構成。

それぞれのformの中にnameがtype、valueが識別子になるようにhidden要素が入っていて、GASのdoPostが受け取るパラメータによって処理を変える。

キーワード検索ボックス

HTML5から導入されたのか、前からあって気づかなかったのかわからないけどinputタグのtypeにsearchというのがあった。特徴的な部分としてはいわゆる検索ボックスあるある、「×押したら全部消える」がデフォルト機能っぽい感じになるみたい。
ここのcssは割とどうしようか悩んだ。虫眼鏡アイコンを内側に置くか外側に置くか、みたいな割としょうもないことだけど。参考にした記事はこれ。
qiita.com
とてもわかりやすかった。感謝。

アコーディオンメニュー

そしてHTML5すごい話なんだけど、アコーディオンメニュー(クリックしたらびよーんってでてくるやつ)が要素2つで実装できる。すごい。

 <!-- 詳細検索の時のフォーム -->
    <details>
      <summary>詳細検索</summary>
      <form method="post" action="https://script.google.com/a/macros/xxx/s/xxxxx/exec">
        <input type="hidden" name="type" value="shousai">
        <label>名称<br><input type="text" name="name"></label><br>
        
        <!-- 省略 -->
        
        <input type="submit" value="検索" class="detsubmit">
      </form>
    </details>
    <!-- 詳細検索の時のフォーム終了 -->

この、detailsとsummaryを書くだけでアコーディオンメニューができる。面倒なcssでdisplay:hidden;がとかそういう実装が一切いらない。これからも消えないでほしい。

ドロップダウンメニュー

詳細検索のドロップダウンメニューは実装ベースで3種類。

  1. HTMLのsection要素に全て手打ちしたもの
  2. GASからSpreadSheetのデータを受け取ってHTMLを生成したもの
  3. 連動のために連想配列javascriptで宣言してjavascriptで生成したもの


1. は特になんというわけでもなく単純なやつ。数が少ないのと、増えても1種とかなのでこの実装。編集も難しくないので、メンテ負担も少ないはず。
2. はSpreadSheetにfilterとuniqueで一意のメーカー名データを取ってきて、GASが取得、javascriptから呼び出したら値をポイってしてくるのでそれを加工するだけのお手軽な感じです。
3. はライブラリの使用制約によって、いわゆる便利ツールの使用が制限されてるのでjsで実装。
参考ページ
blog.ver001.com
木構造的になってるカテゴリのせいで非常に数が多くて割としんどかった。

装飾

面倒ではあるが、スマホ対応も考えていたので要素やフォントのサイズ指定はほぼほぼ割合でしてる。ただ、スマホってユーザビリティ的な面を勝手に考慮してくれるので、テキストボックスへの入力時に自動ズームがかかってしまう問題が発生しました。
調べた結果、ユーザのズームを明示的に禁止する方法とフォントサイズを上げる方法があるっぽかったんだけど…。どれも全く効果なくて、なんかもう良くない…?ってなったので解決しないまま放置してる。

サーバサイド

実は全く特別なことはやってなくて、特に苦労もしなかったから書くことがないという。
流れだけそれぞれまとめておきます

メーカー名ドロップダウン
  1. 空白以外の行をFilterで取得し、Unique関数に通して、Sortで文字コード昇順に並べ替え
  2. GASでgetMakerName関数を作り、getRangeで場所を指定しメーカー名の一覧をgetValueで取得
  3. javaScriptのwindow.onloadでgoogle.script.runからgetMakerName関数を呼び出し
  4. javaScriptで自作したプルダウンを作るmaker関数に返り値を渡して実行
  5. document.getElementByNameでプルダウンの作成先を取得
  6. データの終端までoptionタグのvalue等に値を設定しながらappendChild
検索結果表示
  1. フロントのHTMLからformのデータをPOST
  2. JSONでパラメータを取得
  3. パラメータでQuery関数の条件式を生成
  4. SpreadSheetのQueryシートのA1にsetValue
  5. 出力された結果をgetDataRangeでgetValues
  6. HTMLへ直接渡して、template HTMLの生成
  7. 回される配列、生成されるtableタグのtd要素
getPost関数でのQuery関数の条件式生成

Postに渡された送信データのkey:typeがキーワード検索の指定

  1. 取得したキーワードにtoLowerCaseをかけて、小文字に変換
  2. 名称・メーカー名・型番・分類・詳細の列にLower関数をかけて、列名 contains 'キーワード' の条件式を作る
  3. 条件格納用の変数へ文字列結合してA1へsetValueする
  4. Query関数の結果を取得

Postに渡された送信データのkey:typeが詳細検索の指定

  1. 取得した各パラメータに値が格納されている時に、対応する列と部分一致か完全一致の条件を作って文字列結合する
  2. 条件の結合はANDで行う
  3. 終端が必ずAND演算子になってしまうので最後のカラムの1つ先の列を指定して、列名=''で条件を終了させる
  4. 条件格納用の変数へ文字列結合してA1へsetValueする
  5. Query関数の結果を取得

Postに渡された送信データのkey:typeが備品登録の指定

  1. データ格納用の空配列を宣言して、取得したデータを順にkey指定しながらpush
  2. getRangeで最終行の次の行をgetLastRow()+1で示し範囲を指定してデータをsetValueする

全て終了後、Queryの結果を引き渡しindex.htmlの生成結果をreturnする。

以上!!マジで特別なこと何もやってない。

おしまい

全件データを取得しない限りちゃんと3秒以内におさまったのでよし。ちょっと良くない実装とかあるかもしれないけど、単純に何も考えたくなーいと放り出しかねないので気にしないことにします。なんとなーくテストはやったけどぜーったいバグあるじゃんね。こわいこわい。

ということで、またそのうちにー

読んだ本と新年ことはじめ

新年明けましておめでとうございます。今年もまた良き年だといいな。
先日、母の知り合いというご夫妻とお会いして「読んだ本とかやったことをどこかにまとめておくと良い」と聞きまして。影響を受けやすい質なのでちょろっと書いてみよ、みたいな気持ちで開きました、お久しぶりですね。
最近は卒論ばかりに注力しているので、形態素解析とか自然言語処理周りが個人的に検索の主流ワード。卒論のあれこれで調べた形態素解析の仕組みが面白かったのでそのうちまとめたいな、という気持ちはあります。
というわけで、今日読んだ本の話。

1冊目はサンキュータツオ氏の『もっとヘンな論文』。
www.amazon.co.jp
先日友人と学校帰りの寄り道で買った本。軽妙な語り口で面白い研究の紹介をするという内容で、この論文等をどうやって見つけてきたのかの方が気になりました。
紹介されていたのは番外編を除くと10本。本体読みたくて探した結果、見れないものもあった。国立情報学研究所のciniiのページがあったり論文が見られるやつはそれらを載せておきます。リンク貼るためにJSTAGEの規約読んだけどリンク自由であってるよね?書いてある通りにDOI使ったけど…ダメそうだったら誰か教えて欲しいです。

向井 裕美子「プロ野球選手と結婚するための方法論に関する研究」
あちこちからリンクを辿ったけどPDFのURLは404を吐く。所属ゼミのページからも飛べなかったので今は入手不可なのかな…?割と詳細な分析をしているみたいで、手に入ったら読んでみたいところ。画面越しにみる人間もエキセントリックな感じではなく、普通の出会いをしているんですね、ちょっとつまんない…。拐かして黄泉竈食ひさせちゃうタイプのやばやば神話婚姻譚に慣れきってしまった可能性は否定できないけど。現代社会でエキセントリックな出会い方ってなんだろう。

三柴 友太「「追いかけてくるもの」研究--諸相と変容」
ci.nii.ac.jp
紙媒体でしか出てない可能性が高い。Google Scholarでもダメだった。でもこの「昔話伝説研究」という雑誌は面白そうなタイトルばかり並んでいたのでちょっと気になる…
mukaden.amebaownd.com

吉川 純子「縄文時代におけるクリ果実の大きさの変化」
doi.org
結論の「縄文人、いろんな大きさの栗食べてた」めちゃくちゃ好き。でもここまでしないとわかんないんだよなと思うと、史学ってやっぱおもしれー!の気持ちと人間って面倒!の気持ちが混在しちゃう。

東﨑 雅樹「竹取の翁の年齢について」
ci.nii.ac.jp
またもや見れないやつ。「翁は軽率だしとても誇張するタイプ」という分析が好きすぎる。手を叩いて笑っちゃう。物語って割に若く賢い娘・青年とちょっと抜けてる爺様・婆様(の形状をした異形も含む)の対比はありがちだと思います。浮世絵とかでも美女と野獣の構図、いわゆる横浜浮世絵の西洋人と芸妓さんみたいな対比構造って美女役が際立つよね。

佐々木 正人「「起き上がるカブトムシ」の観察 環境-行為系の創発
doi.org
ファーブル昆虫記みたいだ!と思った。読んでてちょっと不思議だったんだけど、起き上がる時に翅を使って動きつけたりしないんだね。ひっくり返っちゃった蛾とか蝶って翅をバタバタさせて元に戻る気がします。あとセミファイナルのイメージが強いのか蝉も。

寄藤 晶子「曖昧さが残る場所-競艇場エスノグラフィー」
genpoo.kir.jp
紙媒体系。競艇場に行ったことないから空気感が共有できなかったけど、サンキュータツオ氏の語りが面白かった。フィールドワーク系する人って筆力すごい感じなのかもしれない。サンプルがすごく偏ってるとは思うけど。

大門 正幸「「過去生の記憶」を持つ子供について : 日本人児童の事例」
doi.org
全然関係ないんだけど、論文に幼児が剥き終わった後のニンニクの山が画像として載ってるのが面白すぎる。事例強度尺度(SOCS)なるものがあるのも面白い。ソックスって読むんですかね。

有馬 義貴ほか「マンガの社会学 : 鍼灸・柔道整復の社会認知」
ci.nii.ac.jp
これも本筋とは関係ないんだけど、健康プロデュース雑誌って?と思ったらそういう学科が大学にあるんですね…?漫画で何らかの通俗的な認識を探るような研究って割とみるから内容的にはあまり目新しくない感じではありました。登場シーンの列挙をしている部分を引用していたけど表現が結構好きだったので本体そのうち読みたい。

池間 里代子「花札図像学的考察」
id.nii.ac.jp
図像学とは?と思った。美術史研究の1手法で彫刻や絵画の主題・象徴を識別・比較・分類するもの、らしい。分類学に近いのかな…?
kotobank.jp
対比構造や慮りであの美しい柄が生まれたのって、何となく趣があっていいですね。とても好き。

山田 廸生「「坊っちゃん」と瀬戸内航路」
ci.nii.ac.jp
海事史研究は会員にならないとPDF読めない仕様なので歯噛みしてたらなんかあげてるとこあった。日本クルーズ&フェリー学会。グレーなのかな…怖いな、ということでタイトルを検索すれば出るので…。正直論文の内容や後日譚よりも漱石研究年表怖すぎるという感想です。夏目金之助氏がみたらかなり怖がるでしょ。脳がホルマリンにつけられた挙句、大事に保管されてるかと思えば、自分の足跡をとても詳細に本にまとめられてる。想像しただけで怖いな…。

結局、主として取り上げられていて読める論文は4本くらいだったけど面白かった。全体的に本がツッコミ入れながら論文紹介をするというスタンスだったので、人伝に論文とか書籍の内容聞くのが嫌な人じゃない限り楽しめる気がします。番外編として紹介されてる論文も、内容をちゃんと汲み取りながら興味惹かれるような書き方をされていて実際論文も面白かったので興味ある人はぜひ読んでみて欲しいですね、面白かったので。とはいえこれ続編らしいのだけど。

久々に卒研関係ない本読んだのでとっても楽しかったです。友人との寄り道で買った本はあと1冊あるのでそれも今週で読んじゃう予定。このミス17回のやつなので楽しみ。友人もミステリー好きらしくこのミスいくつか買ってたからそのうちどうだったか聞きたいですね。積読ってどうしてついつい増やした挙句にスタックで読んでしまうのか不思議な感じですよね、個人差ありますけど。まだ読めてない積読あるのに金曜に買ったものを読んでしまったという謎の罪悪感がとってもいい読書のスパイスです。卒論終わったらどこかで集中して本読む時間取りたいな。

それではこの辺でおーしまい。

最近何もやっていないという話

びっくりするくらい久しぶりにはてなにアクセスしたら前の記事が5月とかいう状況でした。驚きの事態になっていたので近況報告的な感じです。

春休みに入りまして、最近ちょっと技術云々から離れています。いろいろ作るの面倒だなとか解決した事案とかも特にないので書くことないだけともいうけど。
その代わり随分前から気になっていた簿記のお勉強を始めた。たまに聞く、有価証券取引とか約束手形ってこうなってるんだとかそういう方向の気づきはたくさんあるのでめちゃくちゃたのしいです。
でも、最初に買ったテキスト(ブックオフで200円くらい)と相性が悪すぎました。もともと受験のためのお勉強とか試験のためのお勉強みたいなのに向かないので。所謂、合格テキスト系のやつ。よくわからん例、謎のイラスト、例で説明が終わりというタイプだったのでびっくりするくらい合わなかった。結果的に中央経済社のこれ買いました。
www.hanmoto.com
詳細に書いてあって理解が進むので楽しい。自分に合うテキストは本当に重要なので学校の教材合わない人って地獄だろうなあと思うなど。


他は何もしてないです。百人一首百首タイピングとか、般若心経タイピングとかそういう虚無い奴は遊び程度にやってたりはしますけど。あとは春休みだし復習してたりとかそのくらい。
オンラインになってびっくりするくらいGPA上がったけど、別に理解度が上がってるわけじゃあないですからね。復習は大事。動画になったりメモがタイピングになったりしたことでむしろ頭から抜けてる気もするので、休み中にちゃんとやり直す必要性は大です。といっても休み入ってそれなりの日数経ってても終わってないわけですが。頭の出来が残念。

そのうちなんかやり始めるか簿記のあれそれまとめるかもしれないけどとりあえず近況報告は終わりです。ちゃんと何かまとめたい気持ちはある。気持ちしかないともいう。
おしまい。

Google colaboratoryをpdfに変換して出力する

気候がやばいですね。上がったり下がったりで体調の死。
COVID-19の影響で大学がオンラインになりました。引きこもり最高。
でも一人でやっているとモチベーションがご逝去なさるので学友とzoomつないだまま講義受けてます。これはこれで楽しい。

さて本題。オンライン講義が始まって「Google colaboratoryつーかうよ」といわれました。レポートはPDF形式で提出、作り方は好きにしーてね。
どうせ実行結果とコードを貼るしそのままcolabでやっていいよとのことだったのですが、書き出しできなくない??という内容以外で詰まるという地獄。
ちまちま調べて暫定手順が決まったので備忘録。あとできなくてひーん(泣)ってしてる人いるかもしれないしちらっとまとめてみます。
先生から指示があったらそっちに切り替えたい…

前提条件

  • 使用するのはGoogle colaboratory(.ipynbファイルで説明)
  • ローカルに何か入れるのは面倒なので無し
  • HTMLがそれなりにわかっている人向け(わからなくても問題はないが体裁を整えるのに必要)

とりあえずここではGoogle driveのマイドライブ直下に「Colab Notebooks」というフォルダがありその中にPDFにしたいファイルが格納されているという状況から始めます。
えーとつまり
 MyDrive > Colab Notebooks >PDFにしたいファイル.ipynb
という状況。

それではいってみよー

全体の流れ

  1. 新しいファイルを作成
  2. apt-getでnbconvertと環境を入れる
  3. nbconvertで変換する
  4. 体裁を整える

新しい .ipynbファイルを作成する

まず、PDFにしたいファイルがあるよね。
f:id:Clairdeluna_eve:20200520083300p:plain
どこからでもいいんだけど新しいColabのファイルを作成します。
PDFにしたいファイルを開いていたら左上の「ファイル」>「ノートブックを新規作成」。
そうするとまっさらなファイルができます。
f:id:Clairdeluna_eve:20200520083654p:plain

環境の導入

Google colaboratoryは「!」を前につけることでunix系コマンドが使えるよ。
ここに

!apt-get install texlive texlive-xetex texlive-latex-extra pandoc
!pip install pypandoc

と入力して実行。
見てわかる通りTexだったりPandocをインストールしています。
ちょっと時間かかるけど終わったら

from google.colab import drive
drive.mount('/content/drive')

これを入力して実行。
ColabとDriveの連携をさせる処理。左のタブからドライブマウントしてたらいらないかもしれにゃ。
ちょっとしたら止まって入力スペースみたいなのが出てくる。そしたらその上にある「Go to this URL in a browser」の行のリンクをクリックして認証フェーズへ。
連携したいGoogleアカウント(PDFにしたいファイルが入っているドライブのアカウント)でログイン。そうしたら認証コードが出てくるのでコピーして入力スペースに貼ったらEnter。するとマウントできたよ実行おーわりってなる。

変換

画像はなんかあるらしいけど詳しく知らない。

日本語も画像も含まれていないファイル
!cp drive/My\ Drive/Colab\ Notebooks/[PDFにしたいファイル名].ipynb ./
!jupyter nbconvert --to PDF "[PDFにしたいファイル名].ipynb"

を実行するとしばらくだぁーーって文字が流れて変換プロセスを教えてくれます。
で、実行終了した後最後から二行目に「PDF successfully created」と出ていたら変換が成功しています。エラー吐かれたらメッセージよく読んで原因排除してもっかいやってね。
f:id:Clairdeluna_eve:20200520085632p:plain
左側のタブの囲ってるとこに[PDFにしたいファイル].pdfって出てくるのでダウンロードすればOK。

日本語の含まれているファイル

日本語の含まれているファイルは上の方法でじかに変換すると
f:id:Clairdeluna_eve:20200520090614p:plain
こんな感じに文字化けします。理由は出力に使用するテンプレートでascii-onlyつまり英数だけねって設定があるから。ローカルに環境作ってて変換するならテンプレートファイル作れば一瞬で終わるんだけど、残念ながら他人のサーバに投げているので設定が見れない(というか見る方法がよくわかってないので知っていたら教えてください)。
そこで

!cp drive/My\ Drive/Colab\ Notebooks/[PDFにしたいファイル名].ipynb ./
!jupyter nbconvert --to HTML "[PDFにしたいファイル名].ipynb"

と変換先をHTMLファイルにして実行します。
そうするとPDFではなくHTMLで出力されるよ。実行が終わったら
f:id:Clairdeluna_eve:20200520085632p:plain
左側のタブの囲ってるとこに[PDFにしたいファイル].htmlって出てくるのでダウンロード。

体裁を整える

ダウンロードしたhtmlファイルをエディタとブラウザで開いていい感じに整えてください。
このhtmlファイルは構成としてはCSS→HTMLという流れで記載されているよ。
HTML5の形式ではあるけど、sectionやarticle等の意味のあるタグ、figureなどの可読性を高めていくやつは全く含まれず、ありとあらゆるをdivで囲う地獄みたいなやつです。コード部分はspanやpreで構成されているのでコードの可読性は捨てて、画像サイズとかを(推奨はされないけど)styleやwidthなどで編集するのがいいと思うよ。CSSも数千行に及ぶので見ない方がいい。
あと実行結果が図の場合BASE-64(おそらく)で書かれているので面白いよ。

HTMLわからん勢のための例

基本的にHTML内にCSSというかスタイルを書くのは推奨されていないけど、今回はやむを得ないという認識でいてね。
idやclass、srcがあるものはその後ろに「style=""」と記載してダブルクオートの中にスタイルを書いていきます。基本的に「プロパティ:値;」という形式だよ。

画像サイズ

<img src="画像のソース" width="300px" height="300px"> 

文字の配置(上から中央ぞろえ、右寄せ、左寄せ)

<h1 id="文字列" style="text-align:center;">見出し<h1>
<p id="文字列" style="text-align:right;">文章<p>
<p id="文字列" style="text-align:left;">文章<p>

各タグ

h1 一番大きな見出し
h2 二番目に大きな見出し
div ここからここまで一つの塊ですよという印
p 内容などの文
span インライン要素というグループ化の単位
img 画像。srcは画像の場所やそのものを指す

詳しくは調べるといいよ。

PDFにする

体裁を整え終わったらWebサイトを印刷する手順を取ります。(画像はChrome)
f:id:Clairdeluna_eve:20200520094412p:plain
印刷ダイアログを開いて
f:id:Clairdeluna_eve:20200520094641p:plain
送信先から「PDFに保存」、そして右下の「保存」をクリック。
ちゃんとプレビューを確認して、変なずれとかあったらHTMLに戻って体裁を整えてね。
ファイル名とかパスが入っているのが嫌な人は印刷ダイアログの詳細設定から余白をなしにすると消えます。

別の方法(2020/5/22追記)

Google colaboratoryの画面から直にPDFに直せます。
f:id:Clairdeluna_eve:20200520083300p:plain
f:id:Clairdeluna_eve:20200520094412p:plainf:id:Clairdeluna_eve:20200520094641p:plain
この流れ。でも文字だのなんだのが見切れたりおさまらなかったりする。これでやってみて問題なければこっちのほうが楽だけど、ページ送りが大変なことになってしまうので個人的にはHTMLに書きだす方をおすすめしたい。できる状態はほとんど変わらないよ。

以上
Wordみたいにきれいな文書にはならないけど、そのままできるのはいいよね。レポート書きなおすのがだるだるだったのでレイアウト?知ったことか!というノリです。
きれいに吐き出させる方法ないのかなー…


ローカルにいーれよって人はこのへん
cartman0.hatenablog.com
github.com

参考にしたのは
hellorusk.net

やっと生活が落ち着いた

よく考えたら10月から放置していたのを思い出して書いています。
さっきIPAから春試験中止のお知らせ来てましたね。
今春は午前1免除切れるのもあってセキスペ…じゃなくて、情報安全確保支援士?を申し込んでいたのでちょっと残念。
自己採点高めでいけそうだったのでふむ…という感じ。
まあ合格できるかは別問題なだけど。

2月頭に引っ越してやっといろいろできる環境になったものの、生活がまったく落ち着かないし生活習慣ぐっだぐだだったので特に目新しいこともできていない現状。
新居では無線の他に机周り(というかPC用)に有線を引くのに敷設作業とか家中のコード配線考えたりとかで地味に面倒でした。
書籍が増えすぎて困ってるのもある。といいつつこの間の翔泳社のキャンペーンで電子本買ったり、近くの本屋探索のついでに3冊くらい増えたりしてるけど。
やっとスペースができたし、来月くらいにはVR導入したいなぁと検討中。ゲーミングにはたぶんPCスペックが足りないし、そのほか部屋事情もあるのでQuestかな?

ここ数か月は支援士の勉強他にも一応、心理学に基づく話し方系の本とか読んでます。質問上手話し上手になりたい…どちらかというとカウンセリングできるようになりたいとか思ってたり。身近にカウンセラーさんとか知り合いのキャリアコンサルタントさんとかいたけど、読んでいるとあの動作はそういう?とか聞き方でこうしたがってたのかとかわかって面白い。けどできるようになってしまったらたぶんもうちゃんと受けられなくなりそ…

COVID-19の影響があってもなくても外にはあまり出ないのでハッピー引きこもりライフ。ただしそろそろ大学始まる。
入学式は中止になってるみたいだけど、健康診断とかガイダンスどうするんだろう?