3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

「今年の◯◯部、ログだけ読むとだいたいこんな性格」

3
Posted at

エンジニアは忘年会で何を武器にするべきか?

やっぱりPython を持っていきました

今年もはやいもので忘年会シーズン
忘年会が苦手な人でも、盛り上がれるようなアプリを作成しました

「何か技術ネタで笑いを取りたい」

部署別ログから “偏見WordCloud” を自動生成するAI

ログを見るだけで、その部署の性格が浮かび上がる

  • 総務 → 「申請」「確認」「期限」「書類」
  • 開発 → 「障害」「対応」「レビュー」「修正」
  • 営業 → 「商談」「提案」「予算」「数字」

人間性…じゃなくて “傾向” が全部出る

忘年会で披露すると、
会場「これ当たってるwwwwww」
の嵐になるやつです

実際に出てくるイメージ(※ダミーデータです)

スクリーンショット 2025-12-22 0.32.27.png

これだけで部署の1年が丸見えになる

🛠 アプリのポイント

  • CSV を複数まとめて読み込み
  • WordCloud を生成
  • 2列で比較表示(スクロール対応)
  • 日本語フォント対応
  • 画像は保存しない → 即比較
  • 忘年会のスクリーンにそのまま映せる

🧩 完成したフルコード

import tkinter as tk
from tkinter import filedialog, messagebox
from wordcloud import WordCloud
import csv
from PIL import Image, ImageTk
import os

# --- 日本語フォント(macOS向け) ---
JAPANESE_FONT = "/System/Library/Fonts/ヒラギノ角ゴシック W3.ttc"


# ---------- CSV読み込み ----------
def read_csv_words(csv_path):
    words = []
    with open(csv_path, "r", encoding="utf-8") as f:
        reader = csv.reader(f)
        for row in reader:
            for cell in row:
                if cell:
                    words.extend(cell.split())
    return words


# ---------- WordCloud画像生成(Pillow Image) ----------
def generate_wordcloud_image(word_list, scale=1.0):
    text = " ".join(word_list)

    width = int(600 * scale)
    height = int(350 * scale)

    wc = WordCloud(
        width=width,
        height=height,
        background_color="white",
        collocations=False,
        font_path=JAPANESE_FONT,
    )
    wc.generate(text)

    return wc.to_image()


# ---------- CSV複数選択 → 2列で画像表示(スクロール付き) ----------
def select_multiple_csv():
    file_paths = filedialog.askopenfilenames(
        title="CSVファイルを選択",
        filetypes=[("CSV Files", "*.csv")]
    )

    if not file_paths:
        messagebox.showwarning("警告", "CSVが選択されていません。")
        return

    try:
        scale = float(scale_entry.get())
        if scale <= 0:
            raise ValueError
    except ValueError:
        messagebox.showwarning("エラー", "縮尺は正の数を入力してください")
        return

    # --- 新ウィンドウ(比較用) ---
    win = tk.Toplevel()
    win.title("部署別 WordCloud)")

    # キャンバス + スクロール
    canvas = tk.Canvas(win)
    scrollbar = tk.Scrollbar(win, orient="vertical", command=canvas.yview)
    canvas.configure(yscrollcommand=scrollbar.set)

    scrollbar.pack(side="right", fill="y")
    canvas.pack(side="left", fill="both", expand=True)

    # 中身を入れるフレーム
    scroll_frame = tk.Frame(canvas)
    canvas.create_window((0, 0), window=scroll_frame, anchor="nw")

    # サイズ更新時にスクロール範囲調整
    def configure_scroll(event):
        canvas.configure(scrollregion=canvas.bbox("all"))

    scroll_frame.bind("<Configure>", configure_scroll)

    tk_images = []  # 参照保持用

    col = 0
    row = 0

    for path in file_paths:
        # ファイル名のみ
        file_name = os.path.splitext(os.path.basename(path))[0]

        words = read_csv_words(path)
        img = generate_wordcloud_image(words, scale=scale)

        tk_img = ImageTk.PhotoImage(img)
        tk_images.append(tk_img)

        frame = tk.Frame(scroll_frame, padx=15, pady=15)
        frame.grid(row=row, column=col, sticky="nw")

        # タイトル(ファイル名だけ)
        label_title = tk.Label(frame, text=file_name, font=("Arial", 14, "bold"))
        label_title.pack()

        # 画像表示
        label_img = tk.Label(frame, image=tk_img)
        label_img.pack()

        col += 1
        if col >= 2:
            col = 0
            row += 1

    win.tk_images = tk_images  # GC対策


# ---------- GUIメイン ----------
root = tk.Tk()
root.title("部署別 WordCloud")

label = tk.Label(root, text="部署CSVからWordCloud")
label.pack(pady=10)

# 縮尺設定
scale_frame = tk.Frame(root)
scale_frame.pack(pady=5)

tk.Label(scale_frame, text="縮尺(例: 1.0 / 0.8 / 1.5)").pack(side="left")
scale_entry = tk.Entry(scale_frame, width=5)
scale_entry.insert(0, "1.0")
scale_entry.pack(side="left", padx=5)

# ボタン
btn = tk.Button(root, text="CSVを選択", command=select_multiple_csv)
btn.pack(pady=20)

root.mainloop()

忘年会での鉄板トークスクリプト

“冒頭のネタ” はこれ


🔊 冒頭のマイク

みなさん今年もお疲れ様でした。
エンジニアらしく、社内Slackログを全部機械に読ませたところ、
「各部署の口癖は大体こんな感じ」らしいです。

※なお、このAIは”偏見学習”を積んでおりますので
「人間性」ではなく「傾向」です。
※怒らないでください。


会場:
「いや総務、書類って単語多すぎww」
「開発、障害って言いすぎだろwwwww」
「営業、数字って単語しかないやんwwww」

これで完全に場が温まります

技術ポイント

  • WordCloud 日本語対応(ヒラギノ角ゴ)
  • Tkinter Canvas + Frame スクロール
  • ImageTk.PhotoImage 参照保持
  • grid で 2 カラム配置
  • 拡大縮小 scale を入力して調整可能

まとめ:Pythonは忘年会の最強兵器

エンジニアの忘年会ほど
“技術ネタで笑いを取りやすい場” は無い

今年のログを WordCloud にして
「どの部署が一番陽キャか」
「どの単語が社内を支配したか」

こういう“偏見データ”はみんな大好き

最後にひとこと

形態素解析のほうが面白みがあるかも。。。

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?