表の最大列を取得する関数を作成する

毎月の試算表が列ごとに記されており、新しい月の試算表は表の最大(右)列のひとつ右の列に書き込まれていきます。

では表の最大列はどのように取得したらよいのでしょうか?

通常はmax_columnで取得できますが、表からはずれて右側に文字または書式が設定されている場合、その列を最大列と認識してしまいます。

すると書き込みはその右側の列に書き込まれてしまいます。

上の図では、表の最後は先月(4月)の書き込みがされているD列なので、当月(5月)分としてはE列に書き込みたいところです。
しかし、G4にグレー色の書式が設定されているため、G列を表の最後の列と認識してしまい、その右の列、つまりH列に5月分が書き込まれてしまっています。

表からはずれて文字入力や書式が設定されていても、表の最終列を認識するためそれに対応する関数を作成することにします。

最大列を取得する関数を作る

書式が設定されていてもデータがなければ空列とみなすように作成します。

def remove_right_none(lst): # 関数名
    count = len(lst) # ①
    for item in reversed(lst): # ②
        if item.value is None: # ③
            count = count – 1 # ③
        else:   # ④
            break # ④
    return count # ④

① 引数に指定されたlstの長さをカウントする
② 最後のセルからひとつづつitem変数に入る
③ そのセルが空白ならばカウントを1つ減らず
④ セルが空白でなければ処理は終了して、その時点のセルの数を返す(それが空白列を除いた最大列となる)

 

 

最大列を取得する関数ができたところで、さっそく使用してみます。

作成した remove_right_none( ) 関数を次のように利用します。

# ワークシートの取得
ws_2 = wb[“合計残高試算表_2”]

# 各行の最大列うち、最も大きい列を取得
data_column_num_2 = max([remove_right_none(row) for row in ws_2.rows])  

1.シートの行から1行づつ取り出しrow変数へ代入する。
2.そのrow(1行分)が関数の引数となりremove_right_none( )関数で処理され列数が返る。
3.すべての行につき関数で処理された後、max( )によりその中から1番大きい列数が最大列としてdata_column_num_2へ代入される。

これで表の最大列(上記図のD列)が取得されました。

 

 

集合関数を利用して事業区分を整える

子会社を吸収した関係で事業区分の再編を行っています。

親会社の事業区分は次の通りです。
事業区分   チーム区分
・事業C  ・チーム1
・事業C  ・チーム2
・事業D
・事業E

子会社の事業区分は次の通りです。
事業区分   チーム区分
・事業A  ・チーム1
・事業A  ・チーム2
・事業C  ・チーム1
・事業C  ・チーム2
・事業D
・事業G

親会社と子会社が合併した関係で事業区分につき整理したいと思います。
次の①、②、③の目的で整理してみます。

①和集合
親会社と子会社の事業区分をまとめます。
親会社と子会社では、同じ事業を行っていたものもあり、またC事業のようにチームは分かれますが同じ事業というものもありますので、事業区分がダブることなく親会社と子会社を合わせてどんな事業があるのかを把握します。

②積集合
親会社と子会社で同じ事業は何があるのかを整理します。

③差集合
子会社の行っていた事業のうち、親会社で行っていない事業は何があるのかを整理します。

それぞれの事業区分を抽出したら次のようなデータができました。
親会社(parent)=C ,E, D, C
子会社(sub)=G, D, C, C, A, A

アルファベット順になっていないため見にくいですが、気にすることなく次のコードを書いて整理します。
(pythonのnumpyモジュールを使用します)

import numpy as np

parent = [‘C’, ‘E’,’D’,’C’]
sub = [‘G’,’D’,’C’,’C’, ‘A’,’A’]

# ① 親会社(paretnt)と子会社(sub)の和集合を出力
print(np.union1d(parent,sub))

# ② 親会社(paretnt)と子会社(sub)の積集合を出力
print(np.intersect1d(parent, sub))

# ③子会社(sub)から親会社(parent)を引いた差集合を出力
print(np.setdiff1d(sub, parent))

すると次のように出力されました。

['A' 'C' 'D' 'E' 'G']
['C' 'D']
['A' 'G']



結果は次の通りとなります。

① 親会社と子会社の事業をまとめる(和集合)
[‘A’ ‘C’ ‘D’ ‘E’ ‘G’]

抽出したデータはアルファベット順になっていませんでしたが、結果はアルファベット順に返りました。
また、チームが複数あるC事業はひとつにまとめられています。

②親会社が行う事業と子会社が行う事業で同じもの(積集合)
[‘C’ ‘D’]

③子会社が行う事業で親会社が行っていなかった事業(差集合)
[‘A’ ‘G’]

以上統合における事業整理でした。

Pythonでパスワードを生成する

要件
文字や数値を入れた箱から、1つづつランダムに選び出し、それらを連結した文字列を作成する。

パスワードを生成する時などに使えます。

コード

import string
import secrets

def pass_gen(size=10):
chars = string.ascii_uppercase + string.ascii_lowercase + string.digits

return ”.join(secrets.choice(chars) for x in range(size))

print(pass_gen(6))

GAQK0FUENn

 

手順

1.chars変数に、パスワードで使用する文字・数字を代入します。

2.そのchars変数からひとつづつ文字・数値をランダムに抽出します。

3.抽出された文字・数値を結合してパスワードが出来上がります。

 

 

説明

1.chars変数に代入する文字・数値について

 ① string.ascii_uppercase
       大文字 ‘ABCDEFGHIJKLMNOPQRSTUVWXYZ’

    ② string.ascii_lowercase
       小文字 ‘abcdefghijklmnopqrstuvwxyz’

    ③ string.digits
       文字列 ‘0123456789’

    ほか
 記号を入れる場合は ’%&$#’ 
 ①と②を合わせたものは string.ascii_letters

 

2.パスワードの文字数について

print(pass_gen(6))
pass_gen( )の中にパスワードの文字数を指定します。
ここでは6つの文字数を指定しています。
数値を指定せずに、print (pass_gen( ) ) とすると、10の文字数のパスワードが出来上がります。
これは最初に、
def pass_gen(size=10):の箇所で
デフォルト値をsize=10としているためです。

 

3.文字の抽出および結合について

secrets.choice(chars) for x in range(size)で文字を抽出しています。
これを ”.join( ) の( )の中に入れることにより、ひとつづつ抽出された文字・数値が結合されます。

”.join( ) の 「” 」はシングルクォーテーションが2つで、文字を連結したい記号を中に入れます。
ここでは、文字を空白で連結したいので”としています。
(” はシングルクォーテーションが2つです)

もしもハイフン(‐)で結合する場合には”の間に「‐」を入れ
‘‐’.join(  ) とします。

カンマ(,)で文字を結合する場合には、”の間に「,」を入れ
‘,’.join(  )とします。

 

パスワードが生成されるイメージ

 

注意

secretsモジュールについて

先のコードでは、乱数を生成するのにsecretsモジュールを使用しています。
乱数を生成するにはrandomモジュールでも生成できますが、あくまでもシミュレーション向けの擬似乱数で,セキュリティや暗号学的に設計されていないようです。

セキュリティ向けの強い乱数を生成できるsecretsモジュールを用いるので、Python3.6以上を利用してください。

IDLEを利用する場合について

先のコードをIDLEのshell画面にコピペすると、次のエラーが出ます。

SyntaxError: multiple statements found while compiling a single statement

IDLEのShell画面では複数行に渡るペーストはできないようです。
複数行のペーストをする場合には、Shell画面のFile>New Fileで出てくる「エディター画面」の方を利用して下さい。

こちらはエディターで、Run>Run Moduleとしてみてください。
実行結果がShell画面の方へ出力されます。

jupyter notebookであればそのままコピペしても大丈夫です。
というより、IDLEのShell画面のみコピペ不可のようです。