久保、文章書きます

書きたいことを好き勝手書きます。備忘録的な感じです。

【Python】Excelのフォーマットを一括で整えるツールをGUIで作った

だいぶお久しぶりです。
生きてます。

今回はPythonのライブラリである「PySimpleGUI」というものの存在を知ったので使ってみました。

作るもの

せっかくなら今まで仕事をしてきて自動化できたら楽だなと思っていることを実現するためのツールを作成しようと思いました。
仕事上、大量のExcelファイルの受け渡しを行う機会がそれなりにあり、その度に1つ1つのファイルのフォーマットを確認することが時間の無駄なので自動化しようと思います。

  • 先頭シートをアクティブシートにする
  • 全シートのアクティブセルをA1にする
  • 全シートの表示倍率を100%にする

仕事上、上記の内容をフォルダ内のExcelに対して一括で設定できれば楽になると考えました。
また、「3のうち2つだけ設定したい」といったような場合も考慮し、GUIで対応する設定内容を選択できるようにしたいと思いました。



使用ライブラリ

・PySimpleGUI
 →簡単にGUI作れるライブラリ
github.com


・openpyxl
 →PythonExcelファイルを操作するためのライブラリ
github.com

ソースコード

import PySimpleGUI as psg
import os
import openpyxl

# レイアウト設定
layout = [
    [psg.Text("Excelファイルを一括更新する親フォルダを選択してください")],
    [psg.Text("フォルダ"), psg.InputText(key="folder"), psg.FolderBrowse()],
    [psg.Checkbox("アクティブシートを先頭シートにする", key="activeSheet")],
    [psg.Checkbox("全シートのアクティブセルをA1にする", key="activeCell")],
    [psg.Checkbox("全シートの表示倍率を100%にする", key="zoom100")],
    [psg.Button("実行", size=(7, 1), key="execution")],
    [psg.Button("終了", key="exit")],
]

window = psg.Window("Excelフォーマット一括設定", layout)

while True:
    event, value = window.read()
    # 実行ボタン押下時のイベントを定義
    if event == "execution":
        # 処理前にエラーチェックを実施
        # ERROR:対象フォルダが選択されていない場合
        if not value["folder"]:
            failMsg = "【ERROR】フォルダを選択してください"
            psg.popup(failMsg)
            continue

        # ERROR:対象フォルダが存在しない場合
        if not os.path.exists(value["folder"]):
            failMsg = "【ERROR】フォルダが存在しません"
            psg.popup(failMsg)
            continue

        # ERROR:対象がフォルダではない場合
        if not os.path.isdir(value["folder"]):
            failMsg = "【ERROR】フォルダを選択する必要があります"
            psg.popup(failMsg)
            continue

        # ERROR:処理内容のチェックボックスが1つも選択されていない場合
        if (
            value["activeSheet"] == False
            and value["activeSheet"] == False
            and value["zoom100"] == False
        ):
            failMsg = "【ERROR】処理内容を選んでください"
            psg.popup(failMsg)
            continue

        # 指定されたフォルダ内のファイル分だけ繰り返し
        for root, dirs, files in os.walk(value["folder"]):
            for file in files:
                ext = os.path.splitext(file)[1]
                ext = ext.lower()
                # 拡張子が.xlsxのファイルのみ処理対象とする
                if ".xlsx" in ext:
                    # 絶対パス組み立て
                    abs = value["folder"] + "/" + file
                    # 対象ファイル読み込み
                    wb = openpyxl.load_workbook(abs)

                    # 先頭シートをアクティブシートにする処理
                    if value["activeSheet"] == True:
                        # シートの選択状態を解除
                        for ws in wb.worksheets:
                            ws.sheet_view.tabSelected = False
                        wb.active = wb.worksheets[0]
                        # 保存
                        wb.save(abs)

                    # 全シートのアクティブセルをA1にする処理
                    if value["activeCell"] == True:
                        cell_no = "A1"
                        for ws in wb.worksheets:
                            sv = ws.sheet_view
                            sv.selection[0].activeCell = cell_no
                            sv.selection[0].sqref = cell_no
                            sv.selection[0].activeCellId = None
                        # 保存
                        wb.save(abs)

                    # 全シートの表示倍率を100%にする処理
                    if value["zoom100"] == True:
                        zoom_scale = 100
                        for ws in wb.worksheets:
                            sv = ws.sheet_view
                            sv.zoomScale = zoom_scale
                            sv.zoomScaleNormal = zoom_scale
                        # 保存
                        wb.save(abs)

        # 処理完了時の表出メッセージを組み立て
        exeMsgs = list()
        if value["activeSheet"] == True:
            exeMsgs.append("・アクティブシートを先頭シートにする")
        if value["activeCell"] == True:
            exeMsgs.append("・全シートのアクティブセルをA1にする")
        if value["zoom100"] == True:
            exeMsgs.append("・全シートの表示倍率を100%にする")

        compMsg = "以下の処理が完了しました"
        for exeMsg in exeMsgs:
            compMsg = compMsg + "\n" + exeMsg

        psg.popup(compMsg)
        break

    elif event is None:
        break

    if event == "exit":
        break

作ったもの

対象のフォルダを選択して、そのフォルダ内のExcelファイルに対してラジオボタンで選択した操作を行います。



以上のような設定がバラバラのシートを用意して、全てのラジオボックスにチェックを入れて実行すると。。



フォーマットが統一されました!!
(画像では分かりづらいですがSheet1がアクティブシートになった状態で保存されています。)




最後に

「PySimpleGUI」の簡単さに驚きました。
GUIの実装はかなり面倒なイメージがあったのですが、ほんの数行で書けてしまいました。

Excelのフォーマットは様々な人が関わっているプロジェクトでは必ずと言っていいほどバラバラになってしまいがちなので、このツールの

今後、時間があればexe化するところまでやってみたいと思いました。


おわり

AWS認定 クラウドプラクティショナーを取得した話 感想とか

先日、AWS認定 クラウドラクティショナーの試験を受けて無事に資格を取得しました。
適当にまとめてみたいと思います。

AWS クラウドラクティショナーってなに?

aws.amazon.com

みんな大好きAWSの認定資格です。
一番簡単なもので、入門編って感じの試験です。
取得することで、クラウドに関する基礎知識やAWSの基礎の部分を身につけられます。

クラウドの概要だったり、AWS基本的なサービスの概要だったり、料金体系だったり、カバーしている範囲は結構広いです。
学習してみた印象としては、 "広く浅く" というイメージを受けました。

なぜ受けようと思ったのか

昨年末からアサインした案件でAWSを利用していたのですが、全く触ったこともなく不安だった為です。
周りは結構 "できる方達" だったので少しでも追いつけるように、せっかくだから体系的に学んでみようと思ったのがきっかけです。

結果

f:id:kekekkusu:20200409220039j:plain

1000点満点中900点で合格でした。(700点以上で合格)
新宿のテストセンターで受験したのですが、試験が終わった直後に画面に "合格 "と書かれていてホッしました。

勉強方法

主に3つのコンテンツを使用しました

試験対策テキスト

www.amazon.co.jp

クラウドラクティショナーの試験範囲の内容がしっかりまとめられていて読みやすかったです。
各章の最後に練習問題がついており、難易度も本番と同等程度だったと思います。
買ってよかったです。ありがとうございました。

Udemy この問題だけで合格可能!AWS 認定クラウドラクティショナー 模擬試験問題集(7回分455問)

https://www.udemy.com/course/aws-4260/
膨大な量の問題集です。
基礎と応用に別れていて、基礎の方は結構易しめで応用になると割と難しいです。
実際の試験の難易度はこの問題集の基礎と応用の間ぐらいだったかなと感じました。 応用の最後の方はよくわからなくても合格はできると思います。 逆に言うと、応用の方を問題なく解けるようになったら安心して試験を受けていいと思います。

Kindleの模擬問題集

https://www.amazon.co.jp/dp/B081D4ZJ5G

試験日の少し前に存在を知り問題を解きました。
難易度は本番と同等程度だったと思います。
見つけてよかった。。。

受けてみての感想とか

一応3月中を目標としていたので無事取得できて安心しました。
実際に業務でAWSに触りつつ、勉強を進めたので、サービスのイメージがつきやすかったです。
正直、サービスに触らなくても合格自体はできるとは思いますが、触りながら知識の吸収をするのがやはり効率がいいです。
今後は気が向いたらソリューションアーキテクト アソシエイトを目指したいです。
実際に構築したりするにはやはりアソシエイトレベルの知識が必要な気がします。。。

でもやっぱり開発がしたいので、勉強は続けますが、一旦はAWSの資格からは離れそうです。

おわり

使ったAWSサービスを何となく自分用にまとめた話①

最近AWSに触れているので色々忘れないように自分用に簡単にまとめたいと思います。 触っているのは結構メジャーなサービスばっかりです。。。

EC2(Amazon Elastic Compute Cloud)

仮想サーバーを立てられます。
一番名前を聞くサービスな気がします。
GUIからボタンを数回押すだけで気軽に立てることができます。
立てる際に様々なインスタンスタイプ(スペック)から選択します。
AutoScallingといってこっちで指定した条件で自動的にインスタンスを増やしたり減らしたりとかできます。時間帯とか負荷に応じてとか。
sshで接続して色々できます。色々。
色んなOSが選べます。

S3(Simple Storage Service)

ストレージサービスです。
用途はいっぱいありますね。
EC2と並んで代表的なサービスだと思います。
静的ファイルを置いてそのまま配信とかもできます。
また、バケット(入れ物、ディレクトリみたいな感じ)を作る際にあらかじめ容量を決める必要がありません。容量に制限はありません。
アップロードの際は容量がでかいとマルチパートアップロードといって分割して並列アップロードしたりしてくれます。
AWSサービスのログをS3に保存するとかいう用途もあります。
S3のデータは99.999999999%の耐久性があります。(イレブンナイン)
Amazonスゲー

RDS(Relational Database Service)

データベースサービスです。
AWSには他にもDBサービスがあるのですがこれが一番メジャーです。
DBの種類を選んでボタンポチポチしてればすぐに立てられます。
レプリカの作成ももちろん画面から作成できたりします。
使えるDBの種類は以下です。

最近Auroraを触ったのですが、MySQLPostgreSQLどっちに互換があるものを選ぶかで機能が結構変わって驚きました。

Lambda

ラムダと読みます。個人的に名前がかっこよくて好きです。
プログラムの実行環境を提供します。
サーバーを必要とせずにプログラムを実行させることができます。
AWSの◯◯のサービスのイベントをトリガーとしてプラグラムを実行する」みたいなことができます。 (S3への画像ファイルのアップロードをトリガーとしてアップロードされた画像を特定のサイズにリサイズするとか) PythonとかNode.jsとかで書けます。他にも色んな言語に対応してます。

CloudFront

CDN(Content Delivery Network)です。
以上。

CloudWatch

AWSサービスのログを監視したり保存します。
言うまでもなくめちゃくちゃ使います。

ECS(Elastic Container Service)

コンテナ管理サービスです。
EC2インスタンス上でDockerコンテナを実行したり停止したり管理したりするサービスです。
一番取っ掛かりづらさを感じたのはこれでした。(Dockerに対しての僕の知識の浅さが大きいですが。。。)
用語が結構複雑です。タスクとかクラスタとかサービスとか、1つ1つの用語がパッと見で何をするものなのかが分かりづらかったです。
これに関してはもっと理解を深めたいと思っているのでもっと掘り下げて書ける機会があればいいと思います。

おわりに

とりあえずメジャーどころなサービスを書き出しました。
他にも触っているAWSサービスは色々あるので自分の中で整理するためにも時間があるときにまとめていきたいです。
AWSクラウドラクティショナーの勉強も本格的に進めていきたいです。
サービスに対する知識は何となくついているとは思うのですが、料金とかサポートあたりは正直普段あまり意識しないので力を入れて勉強しないといけないと思いました。
セキュリティ、ネットワークの分野は正直苦手意識が強いので克服したいです。 今回のサービスの紹介でもセキュリティ、ネットワークは避けてしまいました。

おわり

Github Pagesを利用して自分のサイトを公開した話

Github Pagesとは

静的ページをGithubにプッシュするだけで公開することができるというサービスです。(つい先日存在を知りました。)

公開の流れ

  1. リポジトリを作成する
  2. 作成したリポジトリをクローンする
  3. クローンしたリポジトリに公開したいモジュールを置く
  4. プッシュする
  5. GithubPagesの公開設定をする

簡単な手順はこんな感じです。
ググれば公開方法については結構記事がいっぱい出てきました。

実際に公開してみた

静的ページであれば簡単に公開することができるのでプロフィールサイト等に向いていると思ったので僕も作ってみました。

k-kub0.github.io

とりあえず公開したのですが、内容の更新、デザインの修正も追々行なっていきたいと思います。(書くことが思ったよりも無かった)

デザインって難しい

おわり

obnizを買ってLチカさせた話

obnizを買おうと思ったきっかけ

  • LEDとか光ってるのかっこいい
  • IoT楽しそう!!  

でもハードウェアが関わってくると難しそうだな~

そんな漠然とした気持ちで色々調べていると良さげなものを見つけてしまいました。

obniz

obniz.io


発音は"オブナイズ"です。

特徴としては


組み込み系の知識が全くない僕にとって
JavaScriptで開発できるというのはとても魅力的です。
Pythonとかでも書けるらしいです。すごい。


似たような製品に見えるラズパイ等とは根本的な仕組みから違っており、
obnizボード自体にプログラムを書き込むわけではありません。
obnizはクラウド上にあるプログラムをAPI経由で実行します。
このあたりがWeb寄りの人間からすると非常にとっつきやすいですね。

 

購入 実際に動かしてみた


Amazonで注文して翌日に届きました。5000円弱です。

https://www.amazon.co.jp/dp/B07X1K5392

 


思っていたよりもだいぶ小さいです。

f:id:kekekkusu:20191010004952j:plain

f:id:kekekkusu:20191010005023j:plain



microUSBケーブルを接続すると電源が入りました。
クジラみたいなのが出てきました。かわいい。

f:id:kekekkusu:20191010005105j:plain



ボード上でWi-Fi設定をします。
クラウド上のAPIを介して制御するのでボードがWi-Fi接続されているというのは前提条件です。

f:id:kekekkusu:20191010010928j:plain

 


設定が完了するとボードの固有IDが表示されます。
クラウドからこの固有IDを参照して制御するみたいです。

f:id:kekekkusu:20191010011150j:plain

 


固有IDを入力して開発者コンソールに入る。

f:id:kekekkusu:20191010005308p:plain

 


するとすでにサンプルコードが打ちこまれています。
内容はこんな感じ↓

<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
  <script src="https://obniz.io/js/jquery-3.2.1.min.js"></script>
  <script src="https://unpkg.com/obniz@2.3.0/obniz.js" crossorigin="anonymous"></script>
</head>
<body>

<div id="obniz-debug"></div>
<h3>Connect From Your Browser</h3>
<button class="btn btn-primary" id="on">LED ON</button>
<button class="btn btn-primary" id="off">LED OFF</button>
<div id="print"></div>

<div>
  <input type="text" id="text" value="Hello World">
  <button class="btn btn-primary" id="showtime">Print on obniz</button>
</div>

<div>Demo Pin Assign</div>
<ul>
  <li>io0: LED anode</li>
  <li>io1: LED cathode</li>
  <li>Switch State will be printed on browser</li>
</ul>

<script>
var obniz = new Obniz("XXXX-XXXX");

obniz.onconnect = async function () {
  var led = obniz.wired("LED", { anode:0, cathode:1 } );

  obniz.display.clear();
  obniz.display.print("Hello World");
  
  obniz.switch.onchange = function(state) {
    $('#print').text(state);
    obniz.display.clear();
    obniz.display.print(state);
  }

  $("#showtime").on("click", function(){
    obniz.display.clear();
    obniz.display.print($("#text").val());
  });

  $('#on').click(function () {
      led.on();
      obniz.display.clear();
      obniz.display.print("ON");
  });

  $('#off').click(function () {
      led.off();
      obniz.display.clear();
      obniz.display.print("OFF");
  });
}

</script>
</body>
</html>



実行してみるとobnizの画面に、おなじみのHello World

f:id:kekekkusu:20191010005341j:plain

 


日本語もちゃんと表示されます。

f:id:kekekkusu:20191010005407j:plain




なんとこの初期のサンプルコードでLチカまでできるということで実際にやってみました。

抵抗が接続されているLEDをつないでONのボタンを押すと...光りました。
OFFのボタンを押すと消えます。こんなに簡単でいいのか。

 


コードを見てみるとボタンアクションあたりは
jQueryで書かれてるみたいです。




所感

誇張抜きで10分あればLチカまでたどりつきます。やばい。
また、公式サイトにはチュートリアル的なレッスンや作成事例が多く載っていて、
初学者にとても優しいな~と思いました。

obniz.io

blog.obniz.io



Web寄りのエンジニアであっても技術的にとっつきやすいのがとても魅力的に感じました。

基盤がむき出しなのは少し気になりました。
気を付けて扱わないといけませんね。

電子工作など全く触れてきていない為、部品等をほぼ持っていないので
そのうち適当に調達して遊び倒そうと思います。
"IoTっぽい"ことができるように頑張ります。



おわり