upload_csv

import pandas as pd
from db_utils import save_csv_file_name

# CSVファイルをデータベースに保存する関数
def save_csv_to_db(conn, csv_file):
    df = pd.read_csv(csv_file)
    df.to_sql('data_table', conn, if_exists='append', index=False)
   
    # CSVファイル名を保存
    file_name = csv_file.name
    save_csv_file_name(conn, file_name)

main

import streamlit as st
from upload_csv import save_csv_to_db
from delete_data import delete_data
from update_data import update_data
from db_utils import get_data_from_db, init_db, get_csv_file_list
from delete_csv import delete_csv_file
import sqlite3

def main():
    # タイトルのフォントサイズを大きく
    st.markdown("<h1 style='text-align: center; font-size: 32px;'>CSVファイルをSQLiteDBで管理するアプリ</h1>", unsafe_allow_html=True)

    # リフレッシュボタンを右上に配置、位置をさらに下げる
    st.markdown("""
        <style>
        .refresh-button {
            position: fixed;
            top: 80px;  /* ボタンの位置を3cmほど下げる */
            right: 20px;
            background-color: red;
            color: white;
            border: none;
            padding: 10px 20px;
            border-radius: 5px;
            cursor: pointer;
            z-index: 100;
        }
        </style>
        <button class="refresh-button" onclick="location.reload();">DB更新</button>
        """, unsafe_allow_html=True)

    # データベース接続の初期化
    conn = init_db()

    # CSVファイルのアップロード機能
    st.markdown("<h5 style='font-size: 12px;'>CSVファイルのアップロード</h5>", unsafe_allow_html=True)
    csv_file = st.file_uploader("CSVファイルを選択してください", type="csv")
    if csv_file is not None:
        save_csv_to_db(conn, csv_file)
        st.success("CSVファイルが正常にアップロードされました!")

    # データの表示
    st.markdown("<h5 style='font-size: 12px;'>データベースの内容</h5>", unsafe_allow_html=True)
    df = get_data_from_db(conn)
    st.dataframe(df)

    # CSVファイルの削除機能
    st.markdown("<h5 style='font-size: 15px;'>CSVファイルの削除</h5>", unsafe_allow_html=True)  # 3ポイント大きく
    csv_files = get_csv_file_list(conn)  # データベースからCSVファイル名のリストを取得
    files_to_delete = st.multiselect("削除するCSVファイルを選択してください", csv_files)

    if st.button("選択されたCSVファイルを削除"):
        for file_name in files_to_delete:
            if delete_csv_file(conn, file_name):
                st.success(f"CSVファイル '{file_name}' が正常に削除されました!")
            else:
                st.error(f"CSVファイル '{file_name}' が見つかりませんでした。")

    # 行データの削除機能
    st.markdown("<h5 style='font-size: 12px;'>行データの削除</h5>", unsafe_allow_html=True)
    row_id_to_delete = st.number_input("削除する行IDを入力してください", min_value=1, step=1)
    if st.button("行を削除"):
        delete_data(conn, row_id_to_delete)
        st.success(f"行 {row_id_to_delete} が正常に削除されました!")

    # 行データの更新機能
    st.markdown("<h5 style='font-size: 12px;'>行データの更新</h5>", unsafe_allow_html=True)
    row_id_to_update = st.number_input("更新する行IDを入力してください", min_value=1, step=1)
    new_col1 = st.text_input("col1の新しい値")
    new_col2 = st.text_input("col2の新しい値")
    new_col3 = st.text_input("col3の新しい値")
    if st.button("行を更新"):
        update_data(conn, row_id_to_update, new_col1, new_col2, new_col3)
        st.success(f"行 {row_id_to_update} が正常に更新されました!")

    conn.close()

if __name__ == '__main__':
    main()

delete_csv

import os
from db_utils import delete_csv_file_record

# CSVファイルを削除する関数
def delete_csv_file(conn, file_name, folder_path='csv_files'):
    # ファイルを削除
    file_path = os.path.join(folder_path, file_name)
    if os.path.exists(file_path):
        os.remove(file_path)
        delete_csv_file_record(conn, file_name)
        return True
    else:
        return False


db_utils

import sqlite3
import pandas as pd

# データベースの初期化
def init_db():
    conn = sqlite3.connect('data.db')
    cursor = conn.cursor()
    # データテーブルを作成
    cursor.execute('''
    CREATE TABLE IF NOT EXISTS data_table (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        col1 TEXT,
        col2 TEXT,
        col3 TEXT
    )
    ''')
    # CSVファイル名を保存するテーブルを作成
    cursor.execute('''
    CREATE TABLE IF NOT EXISTS csv_files (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        file_name TEXT
    )
    ''')
    conn.commit()
    return conn

# CSVファイル名を保存する関数
def save_csv_file_name(conn, file_name):
    cursor = conn.cursor()
    cursor.execute("INSERT INTO csv_files (file_name) VALUES (?)", (file_name,))
    conn.commit()

# CSVファイル名のリストを取得する関数
def get_csv_file_list(conn):
    cursor = conn.cursor()
    cursor.execute("SELECT file_name FROM csv_files")
    files = cursor.fetchall()
    return [file[0] for file in files]

# CSVファイル名を削除する関数
def delete_csv_file_record(conn, file_name):
    cursor = conn.cursor()
    cursor.execute("DELETE FROM csv_files WHERE file_name = ?", (file_name,))
    conn.commit()

# データベースからデータを取得する関数
def get_data_from_db(conn):
    query = "SELECT * FROM data_table"
    df = pd.read_sql(query, conn)
    return df

"use client";
import React from "react";

function MainComponent() {
  const [message, setMessage] = useState(null);
  const [error, setError] = useState(null);
  const [isLoading, setIsLoading] = useState(false);
  const [isDeleting, setIsDeleting] = useState(false);
  const [isUpdating, setIsUpdating] = useState(false);
  const [uploadedData, setUploadedData] = useState(null);
  const handleFileSelect = async (file) => {
    setIsLoading(true);
    setError(null);
    setMessage(null);

    try {
      const reader = new FileReader();
      reader.onload = async (e) => {
        const fileData = e.target.result;

        const response = await fetch("/api/handle-file-upload", {
          method: "POST",
          headers: {
            "Content-Type": "application/json",
          },
          body: JSON.stringify({ fileData }),
        });

        const result = await response.json();

        if (result.error) {
          setError(result.error);
        } else {
          setMessage(result.message);
          setUploadedData(result.data);
        }
        setIsLoading(false);
      };

      reader.readAsDataURL(file);
    } catch (err) {
      setError("ファイルのアップロード中にエラーが発生しました");
      setIsLoading(false);
    }
  };

  const handleUpdate = async () => {
    setIsUpdating(true);
    setError(null);
    setMessage(null);

    try {
      const response = await fetch("/api/update-data", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({ data: uploadedData }),
      });

      const result = await response.json();

      if (result.error) {
        setError(result.error);
      } else {
        setMessage("データが正常に更新されました");
      }
    } catch (err) {
      setError("データの更新中にエラーが発生しました");
    } finally {
      setIsUpdating(false);
    }
  };

  const handleDelete = async (fileId) => {
    setIsDeleting(true);
    setError(null);
    setMessage(null);

    try {
      const response = await fetch("/api/delete-uploaded-file", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({ fileId }),
      });

      const result = await response.json();

      if (result.error) {
        setError(result.error);
      } else {
        setMessage("ファイルが正常に削除されました");
        setUploadedData(null);
      }
    } catch (err) {
      setError("ファイルの削除中にエラーが発生しました");
    } finally {
      setIsDeleting(false);
    }
  };

  return (
    <div className="flex flex-col min-h-screen bg-gray-50">
      <h1 className="text-4xl font-roboto text-gray-700 text-center pt-8 mb-8">
        CSVファイル管理
      </h1>

      <div className="flex-grow flex flex-col w-full max-w-2xl mx-auto px-8">
        <div className="mt-4">
          {isLoading && (
            <div className="text-blue-600 font-roboto flex items-center justify-center">
              <i className="fas fa-spinner fa-spin mr-2"></i>
              アップロード処理中...
            </div>
          )}

          {error && (
            <div className="text-red-500 font-roboto flex items-center justify-center">
              <i className="fas fa-exclamation-circle mr-2"></i>
              {error}
            </div>
          )}

          {message && (
            <div className="text-green-500 font-roboto flex items-center justify-center">
              <i className="fas fa-check-circle mr-2"></i>
              {message}
            </div>
          )}
        </div>

        {uploadedData && (
          <div className="mt-6">
            <div className="flex items-center justify-between mb-4">
              <h2 className="text-xl font-roboto text-gray-700">
                アップロード結果
              </h2>
              <DeleteButton
                onDelete={() => handleDelete("uploaded-file-id")}
                isLoading={isDeleting}
                itemId="uploaded-file-id"
              >
                DBからCSVファイルを削除
              </DeleteButton>
            </div>
            <div className="bg-gray-50 p-4 rounded-lg">
              <p className="font-roboto text-gray-600 text-center">
                {uploadedData.length}件のデータが正常にアップロードされました
              </p>
            </div>
          </div>
        )}
      </div>

      <div className="fixed bottom-0 left-0 right-0 flex justify-center gap-4 pb-8 bg-gradient-to-t from-gray-50 to-transparent pt-8">
        <div className="flex items-center gap-4">
          <FileUploadButton
            onFileSelect={handleFileSelect}
            isLoading={isLoading}
          />
          <DeleteButton
            onDelete={() => handleDelete("uploaded-file-id")}
            isLoading={isDeleting}
            itemId="uploaded-file-id"
          >
            DBからCSVファイルを削除
          </DeleteButton>
          <button
            onClick={handleUpdate}
            disabled={isUpdating}
            className="inline-flex items-center px-4 py-2 text-sm font-roboto text-white bg-green-600 hover:bg-green-700 rounded-lg transition-colors duration-200 disabled:bg-gray-400 disabled:cursor-not-allowed"
          >
            {isUpdating ? (
              <i className="fas fa-spinner fa-spin mr-2"></i>
            ) : (
              <i className="fas fa-sync-alt mr-2"></i>
            )}
            DBを更新
          </button>
        </div>
      </div>
    </div>
  );
}

export default MainComponent;

映画 "Jagten" ──── 最後に主人公を撃ったのは誰だったのか?

www.youtube.com

 

まずは外見から

・右利きである。

・服は襟付きである。

・服はおなかから下に向かってへこんでいる。

→ この服は、例えばコートのような形状ではない。

・服の外郭に、「毛素材」の雰囲気を感じる。

→ この服はおそらく、例えばセーターのような、ニット素材でできている。

・右手中指が、(他の指と比較して)少し出っ張っている。

→ 指輪を装着している可能性がある。

・容姿の輪郭から、つば付き帽子の着用が疑われる。

 

次に行動から

・主人公から見て右手前にある木に着弾している

・尻もちをつき、チェックメイトがかかった主人公に向かって、2発目を撃たない

・逆光ながら、主人公と目が合っている

→ 殺意がない可能性が高い。殺意があるならば、尻もちをつき身動きの取れない主人公に2発目を撃ちこむはずである。したがって、一発目は「わざと」木に向けて発砲していると考えるべきである。主人公を殺さず、かつ真横の木を射止めるほどの能力があることから、初心者や素人ではなく、例えば猟友会に所属している熟達した猟手である。

そして、これは厳密には「殺人未遂事件」であり、被害者と目が合ってしまっているので通報・逮捕される可能性も十分に考えられる。逮捕が頭をよぎるならば2発目を発砲してもおかしくはないが、狙撃手は2発目を撃つ構えを見せただけで、実際には発砲しなかった。それは、「お前を殺すことなどいつでもできる」「死にたくなければこの村から出ていけ」というメッセージがあるとともに、主人公が「通報などしない」性格であることを知っていた、ということが考えられる。したがって、狙撃手は主人公の性格を知っている程度には近しい人物であろう。

大阪大学経済学研究科経済学専攻【大学院入試】

私事ですが、大阪大学経済学研究科経済学専攻の大学院入試を受験し、合格しました。

今回は、阪大経研院試の情報について記しています。

なお、僕が受験したのは経済学専攻で、経営学専攻でないため、経営学専攻の情報はわずかであることをご承知いただきたく思います。

なお、受験そのものの詳細については、以下の阪大経研のHPをご参照ください。

 

大阪大学経済学研究科 / 経済学部 入試情報

https://www.econ.osaka-u.ac.jp/admissions/g_notice.html

  • ①試験情報
  • ②試験当日の雰囲気
    • 2019年8月17日:筆記試験
    • 2019年8月31日:口述試験
  • ③阪大経研の院試勉強法
    • 必ず過去問を取り寄せる
    • ミクロ
    • マクロ
    • 英語
    • 研究計画書
続きを読む

Piano Man (Billy Joel) 和訳

 

Piano ManBilly Joel によって1973年11月2日にリリースされた最初のシングルで、Billy Joel の代表曲として今なお高い人気を誇る楽曲です。本楽曲は日本でも浸透しており、最近では「消えた天才」(TBSテレビ) や、2019年3月29日放送の「アナザースカイ」(日本テレビ) *1で挿入曲として使用されています。

 

なお、本楽曲は2016年3月24日、歴史的に重要であるとの理由から、米議会図書館の「国立録音登録簿(National Recording Registry)」*2に永久保存されました。

 

曲は3/4拍子*3のリズムで

イントロ前:ジャズ風のソロピア

イントロ :ピアノ, ハーモニカ, ベース, ドラム

Aメロ   :ピアノ, ベース, ドラム

サビ   :ピアノ, ベース, ドラム, アコーディオン, マンドリン

の楽器が使用されています。

*1:中条あやみさんの卒業スペシャル回

*2:国立録音登録簿は毎年、「文化的、歴史的、美学的に大きな意義を持つ」と判断される25作品を選定し、後世のために最高品質のオリジナル音源を保存している。

*3:Waltz Time ともいう。

続きを読む