#author("2024-02-16T02:12:11+00:00","","")
#author("2024-02-16T02:14:05+00:00","","")
[[中市引継ぎ.nakaichi]]


**ディレクトリ [#j7864f1b]
  📁 app
    📄 app.py
    📁 Kamoku
      📁 ME
        📄 chromedriver.exe
        📄 KeyWord.csv
        📁 Kyouzai
          📄 desktop.ini
          📁 kyouzai1
            📄 kyouzaiDB.csv
            📄 review_prac.csv
            📄 review_score.csv
            📄 video_kyouzai.csv
            📄 video_Review.csv
            📄 video_score.csv
          📁 kyouzai10
            📄 kyouzaiDB.csv
            📄 review_prac.csv
            📄 review_score.csv
            📄 video_kyouzai.csv
            📄 video_Review.csv
            📄 video_score.csv
          📁 kyouzai2
            📄 kyouzaiDB.csv
            📄 review_prac.csv
            📄 review_score.csv
            📄 video_kyouzai.csv
            📄 video_Review.csv
            📄 video_score.csv
          📁 kyouzai3
            📄 kyouzaiDB.csv
            📄 review_prac.csv
            📄 review_score.csv
            📄 video_kyouzai.csv
            📄 video_Review.csv
            📄 video_score.csv
          📁 kyouzai4
            📄 kyouzaiDB.csv
            📄 review_prac.csv
            📄 review_score.csv
            📄 video_kyouzai.csv
            📄 video_Review.csv
            📄 video_score.csv
          📁 kyouzai5
            📄 kyouzaiDB.csv
            📄 review_prac.csv
            📄 review_score.csv
            📄 video_kyouzai.csv
            📄 video_Review.csv
            📄 video_score.csv
          📁 kyouzai6
            📄 kyouzaiDB.csv
            📄 review_prac.csv
            📄 review_score.csv
            📄 video_kyouzai.csv
            📄 video_Review.csv
            📄 video_score.csv
          📁 kyouzai7
            📄 kyouzaiDB.csv
            📄 review_prac.csv
            📄 review_score.csv
            📄 video_kyouzai.csv
            📄 video_Review.csv
            📄 video_score.csv
          📁 kyouzai8
            📄 kyouzaiDB.csv
            📄 review_prac.csv
            📄 review_score.csv
            📄 video_kyouzai.csv
            📄 video_Review.csv
            📄 video_score.csv
          📁 kyouzai9
            📄 kyouzaiDB.csv
            📄 review_prac.csv
            📄 review_score.csv
            📄 video_kyouzai.csv
            📄 video_Review.csv
            📄 video_score.csv
          📄 make_database.py
          📄 video_kyouzai0.csv
          📄 video_kyouzai1.csv
          📄 video_kyouzai10.csv
          📄 video_kyouzai2.csv
          📄 video_kyouzai3.csv
          📄 video_kyouzai4.csv
          📄 video_kyouzai5.csv
          📄 video_kyouzai6.csv
          📄 video_kyouzai7.csv
          📄 video_kyouzai8.csv
          📄 video_kyouzai9.csv
          📄 website_0.csv
          📄 website_1.csv
          📄 website_10.csv
          📄 website_2.csv
          📄 website_3.csv
          📄 website_4.csv
          📄 website_5.csv
          📄 website_6.csv
          📄 website_7.csv
          📄 website_8.csv
          📄 website_9.csv
        📄 sakusei_sele.py
        📄 video_sakusei.py
        📄 クロームドライバーは常に最新のものを入れておく
      📄 重いのでMEのキーワード10のみ入っている
    📁 lib
      📁 bindings
        📄 utils.js
      📁 tom-select
        📄 tom-select.complete.min.js
        📄 tom-select.css
      📁 vis-9.1.2
        📄 vis-network.css
        📄 vis-network.min.js
    📄 Recom.py
    📁 static
      📄 data.py
      📄 days.html
      📄 mainpage.css
      📄 style.css
      📄 subject.html
      📁 subjects
        📁 1111
          📄 BH.html
          📄 CE.html
          📄 CH.html
          📄 CJ.html
          📄 EE.html
          📄 EH.html
          📄 EJ.html
          📄 GH.html
          📄 HH.html
          📄 JE.html
          📄 JH.html
          📄 JJ.html
          📄 KH.html
          📄 ME.html
          📄 MH.html
          📄 MJ.html
          📄 PH.html
          📄 SE.html
          📄 SH.html
          📄 SJ.html
    📄 study.csv
    📁 subject
      📄 BH.csv
      📄 BH_check.csv
      📄 CE.csv
      📄 CE_check.csv
      📄 CH.csv
      📄 CH_check.csv
      📄 CJ.csv
      📄 CJ_check.csv
      📄 EE.csv
      📄 EE_check.csv
      📄 EH.csv
      📄 EH_check.csv
      📄 EJ.csv
      📄 EJ_check.csv
      📄 GH.csv
      📄 GH_check.csv
      📄 graph.py
      📄 HH.csv
      📄 HH_check.csv
      📄 JE.csv
      📄 JE_check.csv
      📄 JH.csv
      📄 JH_check.csv
      📄 JJ.csv
      📄 JJ_check.csv
      📄 KH.csv
      📄 KH_check.csv
      📁 lib
        📁 bindings
          📄 utils.js
        📁 tom-select
          📄 tom-select.complete.min.js
          📄 tom-select.css
        📁 vis-9.1.2
          📄 vis-network.css
          📄 vis-network.min.js
      📄 ME.csv
      📄 ME_check.csv
      📄 MH.csv
      📄 MH_check.csv
      📄 MJ.csv
      📄 MJ_check.csv
      📁 ori
        📄 BH.csv
        📄 BH=butsuri h
        📄 CE.csv
        📄 CE=soCiety e
        📄 CH.csv
        📄 CH=chigaku h
        📄 CJ.csv
        📄 CJ=soCiety j
        📄 EE.csv
        📄 EE=english e
        📄 EH.csv
        📄 EH=english h
        📄 EJ.csv
        📄 EJ=english j
        📄 GH.csv
        📄 GH=geography h
        📄 HH.csv
        📄 HH=history h
        📄 JE.csv
        📄 JE=japanaese e
        📄 JH.csv
        📄 JH=japanese h
        📄 JJ.csv
        📄 JJ=japanaese j
        📄 kate.py
        📄 KH.csv
        📄 KH=kagaku h
        📄 ME.csv
        📄 ME=math e
        📄 MH.csv
        📄 MH=math h
        📄 MJ.csv
        📄 MJ=math j
        📄 PH Public h
        📄 PH.csv
        📄 rikai_html_sakusei1.py
        📄 rikai_html_sakusei2.py
        📄 rikai_html_sakusei3.py
        📄 SE.csv
        📄 SE=science e
        📄 SH.csv
        📄 SH=seibutsu h
        📄 SJ.csv
        📄 SJ=science j
        📄 ここで作った理解度ページをtemplateにもっていく
      📄 PH.csv
      📄 PH_check.csv
      📄 SE.csv
      📄 SE_check.csv
      📄 SH.csv
      📄 SH_check.csv
      📄 SJ.csv
      📄 SJ_check.csv
    📁 templates
      📁 1111
        📄 1111.html
      📄 graph.html
      📁 Kyouzai
        📁 ME
          📄 1.html
          📄 10.html
          📄 2.html
          📄 3.html
          📄 4.html
          📄 5.html
          📄 6.html
          📄 7.html
          📄 8.html
          📄 9.html
      📄 login.html
      📁 ME
        📄 1.html
        📄 10.html
        📄 2.html
        📄 3.html
        📄 4.html
        📄 5.html
        📄 6.html
        📄 7.html
        📄 8.html
        📄 9.html
      📄 nyuu.html
      📄 rikai.html
      📄 rikai1.html
      📄 rikai2.html
      📄 rikai3.html
    📁 userdata
      📁 1111
        📄 1111_press.csv
        📄 BH_float.csv
        📄 BH_ratio.csv
        📄 BH_sten.csv
        📄 CE_float.csv
        📄 CE_ratio.csv
        📄 CE_sten.csv
        📄 CH_float.csv
        📄 CH_ratio.csv
        📄 CH_sten.csv
        📄 CJ_float.csv
        📄 CJ_ratio.csv
        📄 CJ_sten.csv
        📄 EE_float.csv
        📄 EE_ratio.csv
        📄 EE_sten.csv
        📄 EH_float.csv
        📄 EH_ratio.csv
        📄 EH_sten.csv
        📄 EJ_float.csv
        📄 EJ_ratio.csv
        📄 EJ_sten.csv
        📄 GH_float.csv
        📄 GH_ratio.csv
        📄 GH_sten.csv
        📄 HH_float.csv
        📄 HH_ratio.csv
        📄 HH_sten.csv
        📄 JE_float.csv
        📄 JE_ratio.csv
        📄 JE_sten.csv
        📄 JH_float.csv
        📄 JH_ratio.csv
        📄 JH_sten.csv
        📄 JJ_float.csv
        📄 JJ_ratio.csv
        📄 JJ_sten.csv
        📄 KH_float.csv
        📄 KH_ratio.csv
        📄 KH_sten.csv
        📄 ME_float.csv
        📄 ME_ratio.csv
        📄 ME_sten.csv
        📄 MH_float.csv
        📄 MH_ratio.csv
        📄 MH_sten.csv
        📄 MJ_float.csv
        📄 MJ_ratio.csv
        📄 MJ_sten.csv
        📄 PH_float.csv
        📄 PH_ratio.csv
        📄 PH_sten.csv
        📄 SE_float.csv
        📄 SE_ratio.csv
        📄 SE_sten.csv
        📄 SH_float.csv
        📄 SH_ratio.csv
        📄 SH_sten.csv
        📄 SJ_float.csv
        📄 SJ_ratio.csv
        📄 SJ_sten.csv
      📄 1111.csv
    📄 users.csv
    📁 __pycache__
      📄 Recom.cpython-310.pyc
      📄 Recom.cpython-39.pyc


**app.py [#f3582cdd]

    from flask import Flask, render_template, request, redirect, url_for, session,abort
    import csv
    import os
    from os import name
    import pandas as pd
    import tkinter as tk
    from tkinter import messagebox
    import numpy as np
    from datetime import datetime, timedelta, date
    import networkx as nx
    from pyvis.network import Network
    from flask import flash



    ############################################################
    ###################多分自作モジュール
    ############################################################

    from Recom import Similarity, Informative, Concentration, Credibility, kousinn,\
                    video_kousinn, video_Credibility, Video_Concentration

    # サーバーでの実行時に必要なパス
    file_path = "/var/www/html/nakaichi/"



    app = Flask(__name__)
    app.secret_key = 'your_secret_key'  # セッションの安全性のためのキーを設定

    @app.route('/')
    def home():
        return render_template('login.html')




    ###############################################################################################
    #######################################ログイン
    ###############################################################################################
    @app.route('/login', methods=['POST'])
    def login():
        username = request.form.get('username')
        password = request.form.get('password')

        if not username or not password:
            return render_template('login.html', login_message='ユーザー名とパスワードを入力してください')

        with open('users.csv', 'r', encoding='utf-8') as file:
            reader = csv.reader(file)
            for row in reader:
                if row[0] == username and row[1] == password:
                    # ログインが成功したらセッションにユーザー情報を保存
                    session['username'] = username
                    session['password'] = password
                    session['name'] = row[2]
                    return redirect(url_for('dashboard'))

        return render_template('login.html', login_message='ユーザー名またはパスワードが正しくありません')




    ###############################################################################################
    #######################################新規登録
    ###############################################################################################
    @app.route('/register', methods=['POST'])
    def register():
        new_username = request.form.get('new_username')
        new_password = request.form.get('new_password')
        new_name = request.form.get('new_name')

        if not new_username or not new_password or not new_name:
            return render_template('login.html', registration_message='全ての項目を入力してください')

        # ユーザーIDが数字で構成されているか確認
        if not new_username.isdigit():
            return render_template('login.html', registration_message='ユーザーIDは数字である必要があります')

        with open('users.csv', 'r', encoding='utf-8') as file:
            reader = csv.reader(file)
            for row in reader:
                if row[0] == new_username:
                    return render_template('login.html', registration_message='このユーザー名はすでに使用されています')

        with open('users.csv', 'a', newline='', encoding='utf-8') as file:
            writer = csv.writer(file)
            writer.writerow([new_username, new_password, new_name])

        return render_template('login.html', registration_message='新しいユーザーが登録されました')




    ###############################################################################################
    #######################################カテゴリ選択
    ###############################################################################################



    # CSVファイルからデータを読み込む関数
    def read_unit_data(file_path):
        df = pd.read_csv(file_path, sep=",", dtype={"単元番号": str, "単元名": str})
        df = df.dropna(subset=["単元番号", "単元名"])  # NaNを含む行を削除
        unit_numbers = df["単元番号"].tolist()
        unit_names = df["単元名"].tolist()
        return unit_numbers, unit_names

    # カテゴリと略称のデータ
    categories_data = {
        "category": ["小学校国語", "小学校算数", "小学校英語", "小学校理科", "小学校社会",
                    "中学国語", "中学数学", "中学英語", "中学理科", "中学社会",
                    "高校国語", "高校数学", "高校英語",
                    "高校物理", "高校科学", "高校生物", "高校地学",
                    "高校地理", "高校歴史", "高校公共"],
        "path": ["JE", "ME", "EE", "SE", "CE", "JJ", "MJ", "EJ", "SJ", "CJ", "JH", "MH", "EH", "BH", "KH", "SH", "CH", "GH", "HH", "PH"]
    }

    # カテゴリデータから単元データを取得
    unit_data = {}
    for i, category in enumerate(categories_data["category"]):
        unit_numbers, unit_names = read_unit_data(f"subject/ori/{categories_data['path'][i]}.csv")
        unit_data[category] = {"unit_numbers": unit_numbers, "unit_names": unit_names}

    # DataFrameを作成
    categories = pd.DataFrame({
        "category": categories_data["category"],
        "subjects": [unit_data[category]["unit_names"] for category in categories_data["category"]],
        "units": [unit_data[category]["unit_numbers"] for category in categories_data["category"]],
        "path": categories_data["path"]
    })

    # 結果を表示
    # print(categories)


    ###############################################################################################
    #######################################教材の画面に飛ぶ
    ###############################################################################################


    @app.route('/Kyouzai/<category>/<unit>')
    def kyouzai_start(category, unit):

        path = categories[categories['category'] == category]['path'].values[0]
        # print(path)
        
        template_path = f'Kyouzai/{path}/{unit}.html'
        
        return render_template(template_path)


    @app.route('/Kyouzai/<path>/<unit>')
    def redirect_to_template(path, unit):
        # Redirect to the corresponding HTML template
        return redirect(url_for('kyouzai_start', category=path, unit=unit))




    ###############################################################################################
    #######################################2ページ目右上
    ###############################################################################################
    @app.route('/save_total_hours', methods=['POST'])
    def save_total_hours():
        total_hours_data = request.form.get('total_hours_data')

        if total_hours_data:
            with open('study.csv', 'a', newline='', encoding='utf-8') as file:
                file.write(total_hours_data)

            return 'Total hours data saved successfully', 200
        else:
            return 'Error saving total hours data', 400


    @app.route('/check_duplicate_username', methods=['GET'])
    def check_duplicate_username():
        username_to_check = request.args.get('username')
        
        with open('study.csv', 'r', encoding='utf-8') as file:
            reader = csv.reader(file)
            for row in reader:
                if row[0] == username_to_check:
                    return 'true'

        return 'false'

    @app.route('/delete_and_save_total_hours', methods=['POST'])
    def delete_and_save_total_hours():
        username = request.form.get('username')
        total_hours_data = request.form.get('total_hours_data')

        # ユーザー名が同じ行が存在するか確認
        with open('study.csv', 'r', encoding='utf-8') as file:
            reader = csv.reader(file)
            data = list(reader)

        with open('study.csv', 'w', newline='', encoding='utf-8') as file:
            writer = csv.writer(file)
            for row in data:
                if row[0] != username:
                    writer.writerow(row)

            # 新しいデータを追加
            writer.writerow(total_hours_data.split(','))

        return 'Data deleted and saved successfully', 200


    ###############################################################################################
    #######################################2ページ目左下
    ###############################################################################################
    @app.route('/write_fullcalendar_data', methods=['POST'])
    def write_fullcalendar_data():
        username = request.form.get('username')
        csv_data = request.form.get('csv_data')

        # userdataディレクトリが存在しない場合は作成
        user_data_dir = 'userdata'
        if not os.path.exists(user_data_dir):
            os.makedirs(user_data_dir)

        # CSVファイルにイベントデータを書き込み
        with open(f'{user_data_dir}/{username}.csv', 'w', newline='', encoding='utf-8') as file:
            file.write(csv_data)

        return 'FullCalendar data written to CSV successfully', 200


    @app.route('/read_fullcalendar_data', methods=['GET'])
    def read_fullcalendar_data():
        username = request.args.get('username')

        # userdataディレクトリが存在しない場合は、データがまだ存在しないとみなして空のCSVデータを返す
        user_data_dir = 'userdata'
        if not os.path.exists(user_data_dir):
            return '', 200

        # CSVファイルからFullCalendarデータを読み込み
        try:
            with open(f'{user_data_dir}/{username}.csv', 'r', encoding='utf-8') as file:
                csv_data = file.read()
            return csv_data, 200
        except FileNotFoundError:
            return '', 200


    ###############################################################################################
    #######################################2ページ目左上
    ###############################################################################################
    @app.route('/dashboard')
    def dashboard():
        # セッションからユーザー情報を取得
        username = session.get('username')
        password = session.get('password')
        name = session.get('name')

        # ユーザーがログインしていない場合はログインページにリダイレクト
        if not username or not password or not name:
            return redirect(url_for('home'))

        user_info = {'id': 1, 'username': username, 'password': password, 'name': name}
        return render_template('nyuu.html', user_info=user_info)

    ###############################################################################################
    #######################################2ページ目右下
    ###############################################################################################


    #main_page関数を押すと更新されてしまうのでやっつけ別ルート
    @app.route('/mainpage')
    def mainpage():
        username = session.get('username')

        # ユーザーのHTMLファイルが存在するか確認
        template_path = f'templates/{username}/{username}.html'
        if not os.path.exists(template_path):
            abort(404, description='先にスケジュールを作成してください')

        return render_template(f'{username}/{username}.html')

    #ついで
    @app.route('/graphpage')
    def graphpage():
        username = session.get('username')
        template_path =f'static/subjects/{username}/ME.html'#MEじゃなくてもいいどうせ全部作るからなんでもいい
        if not os.path.exists(template_path):
            abort(404, description='グラフが作成されていません')
        return render_template('graph.html', username=username)


    @app.route('/main_page')
    def main_page():
        # ユーザー名を取得
        username = session.get('username')
        
        # userdata/{username}.csvが存在するか確認
        user_csv_path = f"userdata/{username}.csv"
        if not os.path.exists(user_csv_path):
            abort(404, description='予定データが存在しません')


        for idx, row in categories.iterrows():
            category = row["category"]
            path = row['path']
            input_ori_filename = f"subject/ori/{path}.csv"
            input_schedule_filename = f"subject/{path}_check.csv"
            output_directory = f"userdata/{username}"
            output_filename = f"{output_directory}/{path}_sten.csv"

            # 出力ディレクトリが存在しない場合は作成する
            if not os.path.exists(output_directory):
                os.makedirs(output_directory)

            target_unit_numbers = get_target_unit_numbers(input_schedule_filename, username)
            # print(f"\n{category} カテゴリの処理中:")
            # print("対象ユニット番号:", target_unit_numbers)

            process_csv(category, input_ori_filename, output_filename, target_unit_numbers)
            
        for idx, row in categories.iterrows():
            category = row["category"]
            path = row["path"]
            process_category(category, path)

        events_data = event_close_read_csv(f"userdata/{username}.csv")
        
        closest_event, days_until_event = find_closest_event(events_data)

        if closest_event:
            print(f"最も近いイベント '{closest_event['Title']}' までの残り日数: {days_until_event}日")

        start_date = datetime.today().date()
        exam_days = days_until_event
        study_hours_file = "study.csv"

        generate_study_schedule(categories, start_date, exam_days, study_hours_file)

        # pathを使ってCSVファイルを取り込む
        schedule_csv_files = [f'userdata/{username}/{path}_ratio.csv' for path in categories['path']]
        df_combined = read_and_concat_csv_files(schedule_csv_files)

        # HTMLを生成
        generate_html(df_combined)

        # レンダリングするHTMLを指定
        return render_template(f'{username}/{username}.html')




    @app.route('/rikai_page1')
    def rikai_page1():
        return render_template('rikai1.html')

    @app.route('/rikai2_page')
    def rikai_page2():
        return render_template('rikai2.html')

    @app.route('/rikai3_page')
    def rikai_page3():
        return render_template('rikai3.html')

    ###########################################################################################################
    ################################グラフページ##########################################
    ###########################################################################################################
    @app.route('/graph_page')
    def graph_page():
        username = session.get('username')

        for index, row in categories.iterrows():
            path = row['path']
            category = row['category']

            # ユーザーのcsvファイルが存在するか確認
            template_path = f"userdata/{username}/{path}_float.csv"
            if not os.path.exists(template_path):
                abort(404, description='先にスケジュールを作成してください')



            df_rikaim = pd.read_csv(f"subject/{path}.csv")
            df_graph = pd.read_csv(f"subject/ori/{path}.csv")
            df_check = pd.read_csv(f"subject/{path}_check.csv")
            df_float = pd.read_csv(f"userdata/{username}/{path}_float.csv")

            header_units =  df_graph['単元番号'].tolist()
            user_data = df_rikaim[df_rikaim["username"] == {username}].iloc[:, 1:].values.flatten().tolist()
            print(df_check)
            # usernameが存在するか確認
            if username in df_check["username"].values:
                group1_nodes = df_check[df_check["username"] == username].iloc[0, 1:].astype(str).tolist()
                for i in range(len(group1_nodes)):
                    if group1_nodes[i] == 1:
                        group1_nodes[i] = df_check.columns[i + 1]
            #1を無理やり単元番号に変更するだけのバカみたいなシステム

            elif int(username) in df_check["username"].values:
                #ユーザー名がintがたになった時の処理(こっちメイン)
                int_username = int(username)
                user_row = df_check[df_check["username"] == int_username].iloc[0, 1:]
                group1_nodes = user_row[1:].astype(str).tolist()
                group1_nodes = [int(float(x)) for x in group1_nodes]
                # print(group1_nodes)

                for i in range(len(group1_nodes)):
                    if group1_nodes[i] == 1:
                        group1_nodes[i] = df_check.columns[i + 1]

            else:
            # エラーメッセージを表示して処理を中断
                abort(404, description="理解度を入力してください")


            
            group2_nodes = df_float[df_float["CRITICAL"] == "YES"]["CODE"].astype(str).tolist()
            # print(group2_nodes)



            # '単元番号'列の値がheader_unitsに存在しない場合は-1で埋める
            missing_units = set(header_units) - set(df_rikaim.columns[1:])
            user_data += [-1] * len(missing_units)

            user_scores = {}
            for index, row in df_rikaim.iterrows():
                user_number = row.get("username", -1)
                user_scores[user_number] = {str(i): row.get(str(i), -1) for i in header_units}
            # print(user_scores)

            nodes_data = df_graph["単元名"].tolist()
            node_numbers = df_graph["単元番号"].tolist()
            conditions = df_graph["前単元"].tolist()

            G = nx.DiGraph()
            node_names = {node_numbers[i]: f"{node_numbers[i]} - {nodes_data[i]}" for i in range(len(node_numbers))}
            color_mapping = {
                0: 'crimson',
                1: 'orange',
                2: 'khaki',
                3: 'palegreen',
                4: 'forestgreen',
                -1: 'deepskyblue',
            }

            for i in range(len(nodes_data)):
                condition = conditions[i]

                if pd.isna(condition) or condition == 99999:
                    continue
                else:
                    if isinstance(condition, float):
                        condition = int(condition)
                    
                    dependent_nodes = [str(condition)] if isinstance(condition, int) else [str(int(c)) for c in condition.split(',')]

                    for dependent_node in dependent_nodes:
                        dependent_node = int(dependent_node)
                        if dependent_node in node_numbers:
                            G.add_edge(node_names[dependent_node], node_names[node_numbers[i]])

            net = Network(notebook=True)

            for node in G.nodes:
                node_number = int(node.split(" - ")[0])
                if node_number in node_numbers:
                    index = node_numbers.index(node_number)
                    if user_number in user_scores and str(node_number) in user_scores[user_number]:
                        color = color_mapping.get(user_scores[user_number][str(node_number)])
                    link = f'/Kyouzai/{category}/{node_number}'

                    if str(node_number) in group2_nodes:
                        net.add_node(node, color=color, originalColor=color, title=f'<a href="{link}" target="_blank">{node.split(" - ")[1]}</a>', shape='star', size=40)
                    elif str(node_number) in group1_nodes:
                        net.add_node(node, color=color, originalColor=color, title=f'<a href="{link}" target="_blank">{node.split(" - ")[1]}</a>', size=35)
                    else:
                        net.add_node(node, color=color, originalColor=color, title=f'<a href="{link}" target="_blank">{node.split(" - ")[1]}</a>', size=20)

            for edge in G.edges:
                net.add_edge(edge[0], edge[1], arrows='to')
            
            # ディレクトリのパス
            directory_path = f'static/subjects/{username}/'

            # ディレクトリが存在しない場合に作成
            if not os.path.exists(directory_path):
                os.makedirs(directory_path)

            # その後、net.show()を呼び出す
            net.show(f'static/subjects/{username}/{path}.html')

            search_script = """
            <script>
            function searchNodes() {
                var searchText = document.getElementById('searchBox').value;
                var nodes = network.body.data.nodes.get();
                var foundNodes = nodes.filter(function(node) {
                    return node.label.includes(searchText);
                });
                if (foundNodes.length > 0) {
                    var foundNodeIds = foundNodes.map(function(node) {
                        return node.id;
                    });
                    network.selectNodes(foundNodeIds);
                    network.focus(foundNodeIds[0], {animation: true});
                    network.body.data.nodes.update(foundNodeIds.map(function(nodeId) {
                        return {id: nodeId, color: 'gray'};
                    }));
                } else {
                    alert('ノードが見つかりませんでした。');
                }
            }

            function resetSearch() {
                document.getElementById('searchBox').value = '';
                network.unselectAll();
                network.body.data.nodes.update(nodes.map(function(node) {
                    return {id: node.id, color: node.originalColor};
                }));
            }
            </script>

            <div style="position: absolute; top: 10px; right: 10px;">
                <input type="text" id="searchBox" placeholder="単元を検索">
                <button onclick="searchNodes()">検索</button>
                <button onclick="resetSearch()">リセット</button>
            </div>
            """



            with open(f'static/subjects/{username}/{path}.html', 'a', encoding='utf-8') as html_file:
                html_file.write(search_script)

        return render_template('graph.html', username=username)


    ###########################################################################################################
    ################################テスト範囲を対象にして対象単元を指定##########################################
    ###########################################################################################################

    def get_target_unit_numbers(input_filename, user_number):
        target_unit_numbers = set()
        
        with open(input_filename, 'r', encoding='utf-8') as input_file:
            reader = csv.reader(input_file)
            headers = next(reader)


            for row in reader:
                if row[0] == user_number:  # ユーザー番号の列に対応するインデックス
                    for header, value in zip(headers[1:], row[1:]):
                        if value == '1':
                            target_unit_numbers.add(header)

        return target_unit_numbers

    def process_csv(category, input_filename, output_filename, target_unit_numbers):
        with open(input_filename, 'r', encoding='utf-8') as input_file, \
            open(output_filename, 'w', encoding='utf-8', newline='') as output_file:
            
            # print(f"Input File: {input_filename}")
            # print(f"Output File: {output_filename}")
            # print(f"Target Unit Numbers: {target_unit_numbers}")
            
            reader = csv.DictReader(input_file)
            
            fieldnames = ['単元名', '単元番号', '指導時数', '前単元']
            writer = csv.DictWriter(output_file, fieldnames=fieldnames)
            writer.writeheader()
            previous_unit_numbers = set()
            code_contents = target_unit_numbers
            all_unit_numbers = set(code_contents)
            # print(all_unit_numbers)

            writer.writerow({
                '単元名': 'Start',
                '単元番号': '0',
                '指導時数': '0',
                '前単元': ''
            })

            for row in reader:
                unit_number = row['単元番号']

                # target_unit_numbersに含まれない単元番号の行は無視する
                if unit_number not in target_unit_numbers:
                    continue

                unit_name = row['単元名']
                teaching_hours = row['指導時数']
                previous_units = row['前単元']

                # NaNの場合は '0' を挿入
                if previous_units.lower() == 'nan':
                    previous_units = '0'
                else:
                    # カンマで分割し、かつ存在しない単元番号に対応する前単元の要素も削除
                    previous_units = ','.join(num for num in previous_units.split(',') if num in target_unit_numbers)

                # 前単元が一つも存在しない場合(NaNまたはすべてが含まれない場合)のみ '0' を挿入
                if not previous_units:
                    previous_units = '0'

                # print(f"Used: {unit_number}: {unit_name}, Teaching Hours: {teaching_hours}, Previous Units: {previous_units}")

                writer.writerow({
                    '単元名': unit_name,
                    '単元番号': unit_number,
                    '指導時数': teaching_hours,
                    '前単元': previous_units
                })

                previous_unit_numbers.update(previous_units.split(','))

            valid_previous_units = previous_unit_numbers.intersection(target_unit_numbers)
            end_previous_units = ','.join(sorted(target_unit_numbers - valid_previous_units))

            # print(f"End Unit: Previous Units: {end_previous_units}")

            writer.writerow({
                '単元名': 'End',
                '単元番号': '999',
                '指導時数': '0',
                '前単元': end_previous_units
            })






    ###############################################################################################
    #######################################CPM計算(youtube産)
    ###############################################################################################


    #print stars
    def stars(number):
        for i in range(number):
            print("*", end = "")
        print("")

    #error messages
    def errorCodeMsg():
        print("Error in input file : CODE ")
        quit()
        

    def errorPredMsg():
        print("Error in input file : PREDECESSORS ")
        quit()

    def errorDaysMsg():
        print("Error in input file : DAYS ")
        quit()

    # Scans if the code in predecessors and successors are
    # in the list of task codes:
    def getTaskCode(mydata, code):
        x = 0
        flag = 0
        for i in mydata['CODE']:
            if(i == code):
                flag = 1
                break
            
            x+=1
        
        if(flag == 1):
            return x
        else:
            errorCodeMsg()



    # Critical Path Method Forward Pass Function
    # EF -> Earliest Finish
    # ES -> Earliest Start

    def forwardPass(mydata):
        ntask = mydata.shape[0]
        ES = np.zeros(ntask, dtype=np.int32)
        EF = np.zeros(ntask, dtype=np.int32)
        temp = []  # hold temporary codes

        for i in range(ntask):
            if mydata['PREDECESSORS'][i] is None:
                ES[i] = 0
                try:
                    EF[i] = ES[i] + mydata['DAYS'][i]
                except Exception as e:
                    print(f"Error in task {i+1}: {e}")
                    errorDaysMsg()

            else:
                for j in mydata['PREDECESSORS'][i]:
                    index = getTaskCode(mydata, j)
                    # Check the video for the missing line here

                    if index == i:
                        print(f"Error in task {i+1}: {errorPredMsg()}")
                    else:
                        temp.append(EF[index])

                ES[i] = max(temp)
                try:
                    EF[i] = ES[i] + mydata['DAYS'][i]
                except Exception as e:
                    print(f"Error in task {i+1}: {e}")
                    errorDaysMsg()

                # reset temp
                temp = []

        # Update dataFrame:
        mydata['ES'] = ES
        mydata['EF'] = EF

        return mydata



    # Critical Path Method Backward Pass function
    # LS -> Latest Start
    # LF -> Latest Finish

    def backwardPass(mydata):
        ntask = mydata.shape[0]
        temp = []
        LS = np.zeros(ntask, dtype=np.int32)
        LF = np.zeros(ntask, dtype=np.int32)
        SUCCESSORS = np.empty(ntask, dtype = object)

        #create successor column:
        
        # create successor column:
        for i in range(ntask-1, -1, -1):
            if(mydata['PREDECESSORS'][i] != None):
                for j in mydata['PREDECESSORS'][i]:
                    index = getTaskCode(mydata, j)
                    if(SUCCESSORS[index] != None):
                        SUCCESSORS[index].append(mydata['CODE'][i])
                    else:
                        SUCCESSORS[index] = [mydata['CODE'][i]]

        # incorporate the column to the data frame:
        mydata["SUCCESSORS"] = SUCCESSORS

        

        #compute for  EF and LS:

        for i in range(ntask-1, -1, -1):
            if(mydata['SUCCESSORS'][i] == None):
                LF[i] = np.max(mydata['EF'])
                LS[i] = LF[i] - mydata['DAYS'][i]
            else:
                for j in mydata['SUCCESSORS'][i]:
                    index = getTaskCode(mydata,j)
                    temp.append(LS[index])

                LF[i] = min(temp)
                LS[i] = LF[i] - mydata['DAYS'][i]

                #reset temp list:
                temp = []


        #incorporate LF and LS to data frame :

        mydata['LS'] = LS
        mydata['LF'] = LF

        return mydata

    #compute for SLACK and CRITICAL state
    def slack(mydata):
        ntask = mydata.shape[0]
        
        SLACK = np.zeros(shape = ntask, dtype=np.int32)
        CRITICAL = np.empty(shape = ntask,dtype = object)

        for i in range(ntask):
            SLACK[i] = mydata['LS'][i] - mydata['ES'][i] 
            if(SLACK[i] == 0):
                CRITICAL[i] = "YES"
            else:
                CRITICAL[i] = "NO"

        #incorporate SLACK and CRITICAL to data frame

        mydata['SLACK'] = SLACK
        mydata['CRITICAL'] = CRITICAL


        #re arrange columns in dataframe:
        mydata = mydata.reindex(columns = ['DESCR', 'CODE','PREDECESSORS',
                    'SUCCESSORS','DAYS','ES','EF','LS','LF','SLACK','CRITICAL'])

        return mydata

    #wrapper function:

    def computeCPM(mydata):

        mydata = forwardPass(mydata)
        mydata = backwardPass(mydata)
        mydata = slack(mydata)
        return mydata

    #print function

    # def printTask(mydata):
    #     print("CRITICAL PATH METHOD CALCULATOR")
    #     stars(90)
    #     print("ES = Earliest Start; EF = Earliest Finish; LS = Latest Start, LF = Latest Finish")
    #     stars(90)
    #     print(mydata)
    #     stars(90)


    def process_category(category, path):
        # ori.csv からデータを読み込む

        username = session.get('username')
        df_ori = pd.read_csv(f'userdata/{username}/{path}_sten.csv', delimiter=',')

        # データの整形
        data = {
            'DESCR': df_ori['単元名'],
            'CODE': df_ori['単元番号'].astype(str),  # 数値から文字列に変換
            'PREDECESSORS': df_ori['前単元'].apply(lambda x: None if pd.isna(x) else [str(int(float(i))) for i in str(x).split(',')]),
            'DAYS': df_ori['指導時数']
        }

        # データフレームを作成
        df = pd.DataFrame(data)

        # CPM計算を実行
        result_data = computeCPM(df)

        # クリティカルなノードのみを取得
        critical_nodes = result_data[result_data['CRITICAL'] == 'YES']

        # 結果を格子枠線のある表で表示
        # print(f"\n{category} - CPM計算結果:")
        # print(result_data.to_markdown(index=False, tablefmt='grid'))

        # クリティカルパス上の経路を表示
        # print(f"\n{category} - Critical Path Route:")
        for index, row in critical_nodes.iterrows():
            print(f"({row['CODE']}) -> ", end="")

        # 結果をCSVファイルに保存
        result_data.to_csv(f'userdata/{username}/{path}_float.csv', index=False)
        # print(f"\n{category} - 結果を {username}_{path}.csv に保存しました。")



    ###############################################################################################
    #######################################納期計算
    ###############################################################################################



    def event_close_read_csv(file_path):
        data = []
        with open(file_path, newline='', encoding='utf-8') as csvfile:
            reader = csv.DictReader(csvfile)
            for row in reader:
                data.append(row)
        return data

    def find_closest_event(events_data):
        closest_event = None
        closest_days_until_event = float('inf')

        for event in events_data:
            start_date = event['Start']
            days_until_event = days_until_next_event(start_date)

            if days_until_event < closest_days_until_event:
                closest_days_until_event = days_until_event
                closest_event = event

        return closest_event, closest_days_until_event

    def days_until_next_event(start_date):
        today = datetime.today().date()
        start_date = datetime.strptime(start_date, '%Y-%m-%d').date()
        
        days_until_event = (start_date - today).days
        
        if days_until_event < 0:
            return float('inf')  # イベントは既に過去の日付です
        
        return days_until_event



    ###############################################################################################
    #######################################スケジュール作成関数#######################################
    ###############################################################################################




    def generate_study_schedule(categories, start_date, exam_days, study_hours_file):
        study_hours_df = pd.read_csv(study_hours_file, index_col=0)
        username = session.get('username')


        # 圧縮率とpathをunit_press_fileにヘッダーとして書き込む
        unit_press_file = f"userdata/{username}/{username}_press.csv"
        with open(unit_press_file, 'w', encoding='utf-8') as file:
            file.write("科目名,圧縮率\n") # ヘッダーを追加
        
        for idx, row in categories.iterrows():
            category = row["category"]
            path = row["path"]
        
            unit_ratios_file = f"userdata/{username}/{path}_float.csv"
            selected_columns = ["CODE", "DAYS", "LS", "DESCR"]
            unit_ratios_df = pd.read_csv(unit_ratios_file, usecols=selected_columns)
            unit_ratios_df = unit_ratios_df.sort_values(by="LS")
            unit_ratios_df = unit_ratios_df.reset_index(drop=True)
        
            total_study_time = 0
            study_schedule = []
        
            for day in range(exam_days):
                current_date = start_date + timedelta(days=day)
                day_of_week = current_date.strftime("%a")
        
                try:
                    study_hours = study_hours_df.loc[username, day_of_week]
                except KeyError:
                    try:
                        # "username" 列に存在しない場合、整数列で同じ値を探して代用
                        index_for_integer = study_hours_df.index.get_loc(int(username))
                        study_hours = study_hours_df.iloc[index_for_integer][day_of_week]
                    except KeyError:
                        # エラーメッセージを表示して処理を中断
                        print(f"エラー: {username} のスタディ時間が設定されていません。")
                        abort(404, description="勉強時間を設定してください")
                total_study_time += study_hours
        
                study_schedule.append({
                    "Day": day + 1,
                    "Date": current_date.strftime("%Y-%m-%d"),
                    "Day of Week": day_of_week,
                    "Study Hours": study_hours,
                    "Total Study Time": total_study_time,
                })
        
            unit_ratios_dict = dict(zip(unit_ratios_df["CODE"], unit_ratios_df["DAYS"]))
            unit_study_time = {unit: total_study_time * int(ratio) / sum(map(int, unit_ratios_dict.values())) for unit, ratio in unit_ratios_dict.items()}



            study_schedule = []
        
            for day in range(exam_days):
                current_date = start_date + timedelta(days=day)
                day_of_week = current_date.strftime("%a")
                try:
                    study_hours = study_hours_df.loc[username, day_of_week]

                except KeyError:
                    # "username" 列に存在しない場合、整数列で同じ値を探して代用
                    index_for_integer = study_hours_df.index.get_loc(int(username))
                    study_hours = study_hours_df.iloc[index_for_integer][day_of_week]
        
                unit_to_study = list(unit_ratios_df["CODE"])
                unit_to_study.sort(key=lambda x: unit_ratios_df[unit_ratios_df["CODE"] == x]["LS"].values[0])
        
                for unit in unit_to_study:
                    if unit not in unit_study_time:
                        continue
        
                    if study_hours > unit_study_time[unit]:
                        study_schedule.append({
                            "Day": day + 1,
                            "Date": current_date.strftime("%Y-%m-%d"),
                            "Day of Week": day_of_week,
                            "Unit": unit,
                            "Study Hours": unit_study_time[unit],
                            "Description": unit_ratios_df[unit_ratios_df["CODE"] == unit]["DESCR"].values[0],
                        })
        
                        study_hours -= unit_study_time[unit]
                        del unit_study_time[unit]
                    else:
                        study_schedule.append({
                            "Day": day + 1,
                            "Date": current_date.strftime("%Y-%m-%d"),
                            "Day of Week": day_of_week,
                            "Unit": unit,
                            "Study Hours": study_hours,
                            "Description": unit_ratios_df[unit_ratios_df["CODE"] == unit]["DESCR"].values[0],
                        })
        
                        unit_study_time[unit] -= study_hours
                        
                        break
        
            csv_output_file = f"userdata/{username}/{path}_ratio.csv"
            study_schedule_df = pd.DataFrame(study_schedule)
            total_ratio = unit_ratios_df["DAYS"].sum()

            total_ratio = unit_ratios_df["DAYS"].sum()

            total_ratio = unit_ratios_df["DAYS"].sum()
            unit_total_time = 0

            unit_total_time = {unit: 0 for unit in unit_ratios_df["CODE"]}
            for schedule in study_schedule:
                unit_total_time[schedule["Unit"]] += schedule["Study Hours"]

            if total_ratio == 0:
                # If the total ratio is 0, set all Study Hours to 0
                study_schedule_df["Study Hours"] = 0
            else:
                # Calculate compression ratio and perform further calculations
                total_study_time = sum(unit_total_time.values())
                compression_ratio = total_ratio / total_study_time
                # Additional calculations as needed...

            
            study_schedule_df.to_csv(csv_output_file, index=False)
        
            # print(f"\nCSVファイル {csv_output_file} に書き込まれた内容:")
            # print(study_schedule_df)
        
        
            total_ratio = unit_ratios_df["DAYS"].sum()
            # print(sum(unit_total_time.values()))
            total_study_time = sum(unit_total_time.values())
            compression_ratio = total_ratio / total_study_time
        
            # print(f"\n{category} - 各単元ごとの合計時間:")
            # for unit, total_time in unit_total_time.items():
            #     print(f"{unit}: {total_time} 時間")
        
            # print(f"\n{category} - 理想勉強時間: {total_ratio}")
            # print(f"\n{category} - 合計勉強時間: {total_study_time} 時間")
            # print(f"\n{category} - 圧縮率: {compression_ratio}")

            # 圧縮率とpathをunit_press_fileに追記
            with open(unit_press_file, 'a', encoding='utf-8') as file:
                file.write(f"{category},{compression_ratio}\n")





    ###############################################################################################
    #######################################html作成関数
    ###############################################################################################

    def read_and_concat_csv_files(csv_files):
        dfs = []
        for file in csv_files:
            df = pd.read_csv(file)
            df = df[df['Study Hours'] != 0]
            # print(df)
            df['Source'] = file
            dfs.append(df)

        combined_df = pd.concat(dfs, ignore_index=True)
        return combined_df

    def generate_html(schedule_data):
        username = session.get('username')
        html_content = f"""
    <!DOCTYPE html>
    <html lang="ja">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="stylesheet" href="../static/mainpage.css">
    </head>
    <body>
        <div id="calendar-container">
            <div id="month-year-selector">
                <span id="current-month"></span>
                <button onclick="previousMonth()">前月</button>
                <button onclick="nextMonth()">次月</button>
                <select id="month-selector" onchange="changeMonth()">
                    <option value="0">1月</option>
                    <option value="1">2月</option>
                    <option value="2">3月</option>
                    <option value="3">4月</option>
                    <option value="4">5月</option>
                    <option value="5">6月</option>
                    <option value="6">7月</option>
                    <option value="7">8月</option>
                    <option value="8">9月</option>
                    <option value="9">10月</option>
                    <option value="10">11月</option>
                    <option value="11">12月</option>
                </select>
                <select id="year-selector" onchange="changeYear()">
                    <!-- 2020年から2050年までの範囲を指定 -->
                </select>
            </div>
            <table id="calendar">
                <thead>
                    <tr>
                        <th>日</th>
                        <th>月</th>
                        <th>火</th>
                        <th>水</th>
                        <th>木</th>
                        <th>金</th>
                        <th>土</th>
                    </tr>
                </thead>
                <tbody id="calendar-body"></tbody>
            </table>
        </div>
        <div id="schedule-data" style="display: none;">
    {generate_schedule_data(schedule_data)}
        </div>
        <div class="details">
            <h3>勉強する単元</h3>
            <div class="details" id="date-details">
                <!-- 日付ごとの詳細スケジュールがここに表示されます -->
            </div>
        </div>
        <link rel="stylesheet" href="../static/mainpage.js">
    """



    ###スクリプトインデントエラーめっちゃ出すから嫌い
    ###jsコード全然読み込まないの何とかしろ
        

        html_content2="""
        <script>
    var currentMonth;
    var currentYear;

    document.addEventListener("DOMContentLoaded", function () {
        currentMonth = new Date().getMonth();
        currentYear = new Date().getFullYear();
        updateCalendar(currentMonth, currentYear);
        populateYearSelector();
    });

    function updateCalendar(month, year) {
        var calendarContainer = document.getElementById('calendar-body');
        var monthYearText = document.getElementById('current-month');
        var calendar = document.getElementById('calendar');
        var daysInMonth = new Date(year, month + 1, 0).getDate();
        var firstDay = new Date(year, month, 1).getDay();
        var lastDay = new Date(year, month, daysInMonth).getDay();

        monthYearText.innerText = year + "年 " + (month + 1) + "月";
        calendar.innerHTML = '';

        // Create header row
        var headerRow = document.createElement('tr');
        ["日", "月", "火", "水", "木", "金", "土"].forEach(function (day) {
            var th = document.createElement('th');
            th.innerText = day;
            headerRow.appendChild(th);
        });
        calendar.appendChild(headerRow);

        // Create calendar rows
        var row = document.createElement('tr');
        var dayCount = 1;

        for (var i = 0; i < firstDay; i++) {
            var td = document.createElement('td');
            td.className = 'off';
            row.appendChild(td);
        }

        for (var day = 1; day <= daysInMonth; day++) {
            var td = document.createElement('td');
            var dateStr = year + "-" + (month + 1).toString().padStart(2, '0') + "-" + day.toString().padStart(2, '0');
            var schedule = getScheduleForDate(dateStr);

            if (dateStr === getCurrentDate()) {
                td.className = 'today';
            }

            td.innerText = day;
            td.onclick = function () {
                showDetails(dateStr, schedule);
            };

            row.appendChild(td);

            if ((firstDay + dayCount) % 7 === 0) {
                calendar.appendChild(row);
                row = document.createElement('tr');
            }

            dayCount++;
        }

        for (var i = lastDay + 1; i < 7; i++) {
            var td = document.createElement('td');
            td.className = 'off';
            row.appendChild(td);
        }

        calendar.appendChild(row);

        // 日付がクリックされたときのイベントを追加
        calendar.addEventListener('click', function (event) {
            if (event.target.tagName === 'TD' && event.target.innerText !== '') {
                var selectedDate = year + "-" + (month + 1).toString().padStart(2, '0') + "-" + event.target.innerText;
                showDetails(selectedDate, getScheduleForDate(selectedDate));
            }
        });
    }

    function populateYearSelector() {
        var yearSelector = document.getElementById('year-selector');
        for (var year = 2020; year <= 2050; year++) {
            var option = document.createElement('option');
            option.value = year;
            option.innerText = year;
            yearSelector.appendChild(option);
        }
        yearSelector.value = currentYear;
    }

    function previousMonth() {
        currentMonth--;
        if (currentMonth < 0) {
            currentMonth = 11;
            currentYear--;
        }
        updateCalendar(currentMonth, currentYear);
    }

    function nextMonth() {
        currentMonth++;
        if (currentMonth > 11) {
            currentMonth = 0;
            currentYear++;
        }
        updateCalendar(currentMonth, currentYear);
    }

    function changeMonth() {
        currentMonth = parseInt(document.getElementById('month-selector').value);
        updateCalendar(currentMonth, currentYear);
    }

    function changeYear() {
        currentYear = parseInt(document.getElementById('year-selector').value);
        updateCalendar(currentMonth, currentYear);
    }

    function getScheduleForDate(date) {
        // 初期化: 空のオブジェクトの配列
        var scheduleInfoArray = [];

        // 'schedule-data'というIDを持つHTML要素を取得
        var scheduleData = document.getElementById('schedule-data');

        // 'schedule-data'要素が存在する場合の処理
        if (scheduleData) {
            // 'schedule-data'の子要素(日付ごとのデータ)を配列に変換
            var dateIndices = Array.from(scheduleData.children).reduce(function (indices, element, index) {
                // 配列内の各要素の中から、指定された日付に対応する要素のインデックスを取得
                if (element.getAttribute('data-date') === date) {
                    indices.push(index);
                }
                return indices;
            }, []);

            // 指定された日付に対応するデータが見つかった場合
            if (dateIndices.length > 0) {
                dateIndices.forEach(function (dateIndex) {
                    // 該当する日付のデータからスケジュール情報とデータソースを取得
                    var scheduleInfo = {
                        schedule: scheduleData.children[dateIndex].getAttribute('data-schedule'),
                        source: scheduleData.children[dateIndex].getAttribute('data-source')
                    };
                    scheduleInfoArray.push(scheduleInfo);
                });
            }
        }


        console.log(scheduleInfoArray)
        // 取得したスケジュール情報とデータソースを含むオブジェクトの配列を返す
        return scheduleInfoArray;
    }

    function getCurrentDate() {
        var today = new Date();
        return today.getFullYear() + "-" + (today.getMonth() + 1).toString().padStart(2, '0') + "-" + today.getDate().toString().padStart(2, '0');
    }

    function showDetails(date, scheduleInfoArray) {
        var details = document.getElementById('date-details');
        details.innerHTML = '';  // 前の内容をクリア

        var sourceDictionary = createSourceDictionary();

        if (scheduleInfoArray.length > 0) {
            scheduleInfoArray.forEach(function (scheduleInfo) {
                var scheduleItems = scheduleInfo.schedule.split(', ');
                for (var i = 0; i < scheduleItems.length; i += 2) {
                    var unit = scheduleItems[i];
                    var description = scheduleItems[i + 1];
                    var sourceName = sourceDictionary[scheduleInfo.source] || scheduleInfo.source;

                    var span = document.createElement('span');
                    // リンク先を変更
                    span.innerHTML = `<a href="Kyouzai/${sourceName}/${unit}" target="_blank">${unit}:${description}(${sourceName})</a>`;
                    details.appendChild(span);
                }
            });
        }
    }



    function createSourceDictionary() {
        // ユーザー名を取得
        var username = "{{ session['username'] }}";  // Flaskテンプレートエンジンの場合

        // データソースとその対応する情報を辞書に登録
        var sourceDictionary = {
    [`userdata/${username}/JE_ratio.csv`]: "小学校国語",
    [`userdata/${username}/ME_ratio.csv`]: "小学校算数",
    [`userdata/${username}/EE_ratio.csv`]: "小学校英語",
    [`userdata/${username}/SE_ratio.csv`]: "小学校理科",
    [`userdata/${username}/CE_ratio.csv`]: "小学校社会",
    [`userdata/${username}/JJ_ratio.csv`]: "中学国語",
    [`userdata/${username}/MJ_ratio.csv`]: "中学数学",
    [`userdata/${username}/EJ_ratio.csv`]: "中学英語",
    [`userdata/${username}/SJ_ratio.csv`]: "中学理科",
    [`userdata/${username}/CJ_ratio.csv`]: "中学社会",
    [`userdata/${username}/JH_ratio.csv`]: "高校国語",
    [`userdata/${username}/MH_ratio.csv`]: "高校数学",
    [`userdata/${username}/EH_ratio.csv`]: "高校英語",
    [`userdata/${username}/BH_ratio.csv`]: "高校物理",
    [`userdata/${username}/KH_ratio.csv`]: "高校科学",
    [`userdata/${username}/SH_ratio.csv`]: "高校生物",
    [`userdata/${username}/CH_ratio.csv`]: "高校地学",
    [`userdata/${username}/GH_ratio.csv`]: "高校地理",
    [`userdata/${username}/HH_ratio.csv`]: "高校歴史",
    [`userdata/${username}/PH_ratio.csv`]: "高校公共"
    };

        return sourceDictionary;
    }


    </script>
    """

        press_file = f"userdata/{username}/{username}_press.csv"

        # CSVファイルをDataFrameに読み込む
        if os.path.exists(press_file):
            press_df = pd.read_csv(press_file)

            # path列が0の行を除外
            press_df = press_df[press_df['圧縮率'] != 0]
        else:
            press_df = pd.DataFrame()


        press_html = press_df.to_html(classes='table table-bordered table-striped',index=False)+"※圧縮率が高いほど無理のある勉強スケジュールになっている"





        directory_path = f"templates/{username}"
        if not os.path.exists(directory_path):
            os.makedirs(directory_path)

        with open(f"templates/{username}/{username}.html", "w", encoding="utf-8") as file:
            file.write(html_content+html_content2+press_html)







    def generate_schedule_data(schedule_data):
        # 与えられたデータを日付とソースでグループ化し、各グループにformat_schedule関数を適用
        grouped_data = schedule_data.groupby(['Date', 'Source']).apply(format_schedule)
        
        # HTML形式の文字列を初期化
        schedule_html = ""
        
        # グループデータが存在しない場合、"max baka"というエラーメッセージを含むHTML文字列を生成
        if grouped_data.empty:
            return '<div>Error: max baka</div>\n'
        #エラー回避用バカ
        
        # 各グループごとにHTMLタグを生成
        for (date, source), schedule in grouped_data.items():
            # 各データをHTMLの属性として追加
            schedule_html += f'<div data-date="{date}" data-schedule="{schedule}" data-source="{source}"></div>\n'
        
        # 生成したHTML文字列を返す
        return schedule_html


    def format_schedule(group):
        formatted_schedule = ', '.join([f'{unit}, {description}' for _, (unit, description) in group[['Unit', 'Description']].iterrows()])
        return formatted_schedule




    ###############################################################################################
    #######################################理解度ページ
    ###############################################################################################



    # subjectフォルダが存在しない場合は作成
    subject_folder = "subject"
    if not os.path.exists(subject_folder):
        os.makedirs(subject_folder)

    @app.route('/submit', methods=['POST'])
    def submit():
        if request.method == 'POST':
            username = session['username']
            # フォームデータを取得
            data = request.form
            check_data = {key: data[key] for key in data if '_checkbox' in key}
            # ユーザーごとにsubjectフォルダ内のCSVにデータを保存する例
            save_data_to_subject_csv(username, data)
            
            # チェックボックスのデータを保存
            checkbox_save(username, check_data)

            # 成功したらどこかにリダイレクトするか、適切なレスポンスを返す
            return render_template('rikai.html')



    def save_data_to_subject_csv(user_id, data):
        # カテゴリごとの科目

        # 各科目ごとのCSVファイルパス
        subject_csv_paths = {row["category"]: f"{subject_folder}/{row['path']}.csv" for _, row in categories.iterrows()}

        # 各科目ごとにデータを整形
        for _, row in categories.iterrows():
            category = row["category"]
            subjects = row["subjects"]
            units = row["units"]

            formatted_data = {"username": user_id}
            for subject, unit in zip(subjects, units):
                # カテゴリに属する科目のみを処理
                key = f"{category.lower()}_{subject.lower()}"
                if key in data:
                    formatted_data[unit.lower()] = data[key]

            csv_path = subject_csv_paths[category]

            # ヘッダーをunitsに変更して新しい行を作成
            new_row = pd.DataFrame([formatted_data], columns=["username"] + units)
            # print(csv_path)
            # print(new_row)

            # 新しい行に NaN が含まれているか確認
            if new_row.isnull().values.any():
                print("新しい行にNaNが含まれているため中断します。")
            else:
                # NaN が含まれていない場合の処理を続行
                # print("新しい行にNaNは含まれていません。")
                # ここで新しい行を他の処理に渡すなどの操作を続ける

                # 既存のCSVデータを読み込む
                existing_data = pd.DataFrame(columns=["username"] )
                if os.path.exists(csv_path) and os.path.getsize(csv_path) > 0:
                    existing_data = pd.read_csv(csv_path, encoding='utf-8-sig')

                

                # print("全データ")
                # print(existing_data)
                # 同じ"username"を持つ行を削除
                existing_data = existing_data[existing_data['username'].astype(str) != formatted_data['username']]
                #print("かぶってないデータ")
                #print(existing_data)
                # 既存のデータを更新または新規追加
                existing_data = pd.concat([existing_data,new_row], ignore_index=True)

                # CSVファイルに書き込む
                existing_data.to_csv(csv_path, index=False, encoding='utf-8')




    def checkbox_save(username, check_data):
        for index, row in categories.iterrows():
            category = row['category']
            subjects = row['subjects']
            path = row['path']
            units = row['units']

            csv_filename = f"{subject_folder}/{path}_check.csv"

            # print(check_data)
            

            # 新しい行の作成
            new_row = [username] + [0 if check_data.get(f"{category}_{subject}_checkbox") is None else 1 for subject in subjects]
            # print(new_row)

            # 既存のCSVデータを読み込む
            existing_data = pd.DataFrame(columns=["username"] + units)
            if os.path.exists(csv_filename) and os.path.getsize(csv_filename) > 0:
                existing_data = pd.read_csv(csv_filename, encoding='utf-8-sig')

            #print("全データ")
            #print(existing_data)

            # 同じ"username"を持つ行を削除
            existing_data = existing_data[existing_data['username'].astype(str) != username]
            #print("かぶってないデータ")
            #print(existing_data)

            # 既存のデータを更新または新規追加
            existing_data = pd.concat([existing_data, pd.DataFrame([new_row], columns=["username"] + units)], ignore_index=True)

            # CSVファイルに書き込む
            existing_data.to_csv(csv_filename, index=False, encoding='utf-8-sig')







    ###############################################################################################
    #######################################メインページ右
    ###############################################################################################

    @app.route('/subject_select')
    def subject_select():
        return render_template('main.html', currentEmbed='subjects/link_network.html', currentHeaderText='数学')


    ###############################################################################################
    #######################################教材ページ
    ###############################################################################################


    @app.route("/kyouzai")
    def kyouzai():

        unit_name = request.args.get('unit_name')
        unit = request.args.get('unit')
        key_number = int(request.args.get('key_number'))
        # CSVファイルのパスを作成
        
        csv_path = f"Kamoku/{unit_name}/KeyWord.csv"

        # データフレームの読み込み
        df_key = pd.read_csv(csv_path, encoding="cp932", names=['key'])
        keyword = [df_key.loc[i, 'key'] for i in range(len(df_key))]

        # kyouzaiDB データ処理
        kyouzaiDB = pd.read_csv(f'Kamoku/{unit_name}/Kyouzai/kyouzai{key_number}/kyouzaiDB.csv', encoding="cp932")
        review_df = pd.read_csv(f"Kamoku/{unit_name}/Kyouzai/kyouzai{key_number}/review_prac.csv", encoding="cp932")

        kyouzai_title_list, kyouzai_url_list, mihyouka_kyouzai_title_list, mihyouka_kyouzai_url_list, length, score_list = [], [], [], [], [], []
        index = list(kyouzaiDB.query(f'Credibility_score.isnull()', engine='python').index)
        number = kyouzaiDB['Hpnumber']
        

        for i in range(3):
            kyouzai_title_list.append(kyouzaiDB.iloc[i, 0])
            kyouzai_url_list.append(kyouzaiDB.iloc[i, 1])
            mihyouka_kyouzai_title_list.append(kyouzaiDB.iloc[index[i], 0])
            mihyouka_kyouzai_url_list.append(kyouzaiDB.iloc[index[i], 1])
            length.append(len(list(review_df.query(f'Hpnumber == "{number[i]}"').index)))
            score_list.append(kyouzaiDB.iat[i, 3])

        # videoDB データ処理
        youtubeDB = pd.read_csv(f'Kamoku/{unit_name}/Kyouzai/kyouzai{key_number}/video_kyouzai.csv', encoding='cp932')
        video_review_df = pd.read_csv(f'Kamoku/{unit_name}/Kyouzai/kyouzai{key_number}/video_Review.csv', encoding='cp932')
        video_update_df = pd.read_csv(f'Kamoku/{unit_name}/Kyouzai/kyouzai{key_number}/video_kyouzai.csv',encoding='cp932')
        

        video_title_list, video_url_list, video_id_list, mihyouka_video_title_list, mihyouka_video_url_list, mihyouka_video_id_list, video_length, video_score_list = [], [], [], [], [], [], [], []
        video_index = list(youtubeDB.query(f'Credibility_score.isnull()', engine='python').index)
        yo = youtubeDB['Youtubenumber']

        for i in range(3):
            video_title_list.append(youtubeDB.iat[i, 0])
            video_url_list.append(youtubeDB.iat[i, 1])
            video_id_list.append(youtubeDB.iat[i, 3])
            mihyouka_video_title_list.append(youtubeDB.iat[video_index[i], 0])
            mihyouka_video_url_list.append(youtubeDB.iat[video_index[i], 1])
            mihyouka_video_id_list.append(youtubeDB.iat[video_index[i], 3])
            video_length.append(len(list(video_review_df.query(f'Youtubenumber == "{yo[i]}"').index)))
            video_score_list.append(video_update_df.iat[i, 4])

            

        return render_template(f"/{unit_name}/{key_number}.html", title=keyword[key_number-1],
                            ###########キーワードは0から始まってしまうので-1する
                            kyouzai_title1=kyouzai_title_list[0], kyouzai_url1=kyouzai_url_list[0],
                            kyouzai_title2=kyouzai_title_list[1], kyouzai_url2=kyouzai_url_list[1],
                            kyouzai_title3=kyouzai_title_list[2], kyouzai_url3=kyouzai_url_list[2],
                            mihyouka_title1=mihyouka_kyouzai_title_list[0], mihyouka_url1=mihyouka_kyouzai_url_list[0],
                            mihyouka_title2=mihyouka_kyouzai_title_list[1], mihyouka_url2=mihyouka_kyouzai_url_list[1],
                            mihyouka_title3=mihyouka_kyouzai_title_list[2], mihyouka_url3=mihyouka_kyouzai_url_list[2],
                            length1=length[0], length2=length[1], length3=length[2],
                            video_title1=video_title_list[0], video_url1=video_url_list[0], video_id1=video_id_list[0],
                            video_title2=video_title_list[1], video_url2=video_url_list[1], video_id2=video_id_list[1],
                            video_title3=video_title_list[2], video_url3=video_url_list[2], video_id3=video_id_list[2],
                            mihyouka_video_title1=mihyouka_video_title_list[0], mihyouka_video_url1=mihyouka_video_url_list[0],
                            mihyouka_video_title2=mihyouka_video_title_list[1], mihyouka_video_url2=mihyouka_video_url_list[1],
                            mihyouka_video_title3=mihyouka_video_title_list[2], mihyouka_video_url3=mihyouka_video_url_list[2],
                            mihyouka_video_id1=mihyouka_video_id_list[0], mihyouka_video_id2=mihyouka_video_id_list[1],
                            mihyouka_video_id3=mihyouka_video_id_list[2],
                            video_length1=video_length[0], video_length2=video_length[1], video_length3=video_length[2],
                            score1=score_list[0], score2=score_list[1], score3=score_list[2],
                            video_score1=video_score_list[0], video_score2=video_score_list[1], video_score3=video_score_list[2])





    @app.route('/Review',methods = ["post"])
    def Review():
        
        unit_name = request.form.get('unit_name')
        unit = request.form.get('unit')
        key_number = int(request.form.get('key_number'))
        

        df_key = pd.read_csv(f"Kamoku/{unit_name}/KeyWord.csv",encoding="cp932",names= ['key'])
        keyword = []
        for i in range(len(df_key)):
            keyword.append(df_key.loc[i,'key'])

        kyouzaiDB = pd.read_csv(f'Kamoku/{unit_name}/Kyouzai/kyouzai{key_number}/kyouzaiDB.csv', encoding="cp932")
        number = int(request.form['number'])
        print(f"入力番号{number}")
        HPnumber = kyouzaiDB.iloc[number,2]
        print(f"順位{HPnumber}")
        HPtitle = kyouzaiDB.iloc[number,0]
        print(f"タイトル{HPtitle}")
        HPurl = kyouzaiDB.iloc[number,1]
        evaluation = int(request.form['evaluation'])
        text = request.form['text']
        

        #レビューした学籍番号を取得
        studentnumber = session["username"]


        #レビューした日付と時間を取得する
        dt = datetime.now()
        dtt = dt.replace(microsecond=0)
        #date = dtt.strftime("%Y/%#m/$#d %H:%M") 
        date = dtt.strftime("%Y/%#m/%#d %H:%M")
        #上で取得したデータを review_list に保存する
        
        review_list = [HPtitle, HPurl, HPnumber, studentnumber, evaluation, text, date]
        print(review_list)


        with open(f"Kamoku/{unit_name}/Kyouzai/kyouzai{key_number}/review_prac.csv","a",encoding="cp932",newline='') as f:
            writer = csv.writer(f,delimiter=',')
            writer.writerow(review_list)

        df = pd.read_csv(f"Kamoku/{unit_name}/Kyouzai/kyouzai{key_number}/review_prac.csv",encoding="cp932")
        saveDB = f"Kamoku/{unit_name}/Kyouzai/kyouzai{key_number}/kyouzaiDB.csv"

        S_score_norm = Similarity(df)
        I_score_norm = Informative(df)
        C_score_norm = Concentration(df)  
        Credibility_score, Ave_score = Credibility(S_score_norm, I_score_norm, C_score_norm, HPnumber, df)
        review_score = [HPtitle, HPurl, HPnumber, studentnumber, evaluation, text, date, Credibility_score, Ave_score]


        with open(f"Kamoku/{unit_name}/Kyouzai/kyouzai{key_number}/review_score.csv", "a", encoding="cp932",newline='') as f:
            writer = csv.writer(f,delimiter=',')
            writer.writerow(review_score)

        #Youtube
        youtubeDB = pd.read_csv(f'Kamoku/{unit_name}/Kyouzai/kyouzai{key_number}/video_kyouzai.csv',encoding="cp932")
        video_review_df = pd.read_csv(f'Kamoku/{unit_name}/Kyouzai/kyouzai{key_number}/video_Review.csv',encoding='cp932')
        video_title_list = []
        video_url_list = []
        video_id_list = []
        mihyouka_video_title_list = []
        mihyouka_video_url_list = []
        mihyouka_video_id_list = []
        video_length = []
        video_index = list(youtubeDB.query(f'Credibility_score.isnull()',engine='python').index)
        yo = youtubeDB['Youtubenumber']
        for i in range(3):
            video_title_list.append(youtubeDB.iat[i,0])
            video_url_list.append(youtubeDB.iat[i,1])
            video_id_list.append(youtubeDB.iat[i,3])
            mihyouka_video_title_list.append(youtubeDB.iat[video_index[i],0])
            mihyouka_video_url_list.append(youtubeDB.iat[video_index[i],1])
            mihyouka_video_id_list.append(youtubeDB.iat[video_index[i],3])
            video_length.append(len(list(video_review_df.query(f'Youtubenumber == "{yo[i]}"').index)))


        kyouzai_title_list, kyouzai_url_list, mihyouka_kyouzai_title_list, mihyouka_kyouzai_url_list, length =\
            kousinn(kyouzaiDB, Credibility_score, HPnumber,df,saveDB)
        kousinn_df = pd.read_csv(f"Kamoku/{unit_name}/Kyouzai/kyouzai{key_number}/kyouzaiDB.csv",encoding="cp932")
        score_list = []
        for i in range(3):
            score_list.append(kousinn_df.iat[i,3])

        video_kousinn_df = pd.read_csv(f'Kamoku/{unit_name}/Kyouzai/kyouzai{key_number}/video_kyouzai.csv',encoding='cp932')
        video_score_list = []
        for i in range(3):
            video_score_list.append(video_kousinn_df.iat[i,4])

        return render_template(f"/{unit_name}/{key_number}.html",title = keyword[key_number-1],
        kyouzai_title1 = kyouzai_title_list[0],kyouzai_url1 = kyouzai_url_list[0],
        kyouzai_title2 = kyouzai_title_list[1],kyouzai_url2 = kyouzai_url_list[1],
        kyouzai_title3 = kyouzai_title_list[2],kyouzai_url3 = kyouzai_url_list[2],
        mihyouka_title1 = mihyouka_kyouzai_title_list[0], mihyouka_url1 = mihyouka_kyouzai_url_list[0],
        mihyouka_title2 = mihyouka_kyouzai_title_list[1], mihyouka_url2 = mihyouka_kyouzai_url_list[1],
        mihyouka_title3 = mihyouka_kyouzai_title_list[2], mihyouka_url3 = mihyouka_kyouzai_url_list[2],
        length1 = length[0], length2=length[1], length3=length[2],
        video_title1 = video_title_list[0],video_url1 = video_url_list[0],video_id1 = video_id_list[0],
        video_title2 = video_title_list[1],video_url2 = video_url_list[1],video_id2 = video_id_list[1],
        video_title3 = video_title_list[2],video_url3 = video_url_list[2],video_id3 = video_id_list[2],
        mihyouka_video_title1 = mihyouka_video_title_list[0],mihyouka_video_url1 = mihyouka_video_url_list[0],
        mihyouka_video_title2 = mihyouka_video_title_list[1],mihyouka_video_url2 = mihyouka_video_url_list[1],
        mihyouka_video_title3 = mihyouka_video_title_list[2],mihyouka_video_url3 = mihyouka_video_url_list[2],
        mihyouka_video_id1 = mihyouka_video_id_list[0],mihyouka_video_id2 = mihyouka_video_id_list[1],mihyouka_video_id3S = mihyouka_video_id_list[2],
        video_length1 = video_length[0],video_length2=video_length[1],video_length3=video_length[2],
        score1 = score_list[0],score2 = score_list[1],score3 = score_list[2],
        video_score1 = video_score_list[0],video_score2 = video_score_list[1],video_score3 = video_score_list[2]
        )


    @app.route("/mihyouka_Review", methods=["POST"])
    def mihyouka_Review():

        unit_name = request.form.get('unit_name')
        unit = request.form.get('unit')
        key_number = int(request.form.get('key_number'))


        ##キーワード取得のための部分##
        df_key = pd.read_csv(f"Kamoku/{unit_name}/KeyWord.csv",encoding="cp932",names= ['key'])
        keyword = []
        for i in range(len(df_key)):
            keyword.append(df_key.loc[i,'key'])
        ############################

        kyouzaiDB = pd.read_csv(f'Kamoku/{unit_name}/Kyouzai/kyouzai{key_number}/kyouzaiDB.csv', encoding="cp932")
        number = int(request.form['number'])
        #index = list(kyouzaiDB.reset_index().query(f'Credibility_score == "{np.nan}"').index)
        index = list(kyouzaiDB.reset_index().query(f'Credibility_score.isnull()').index)
        HPnumber = kyouzaiDB.iloc[index[number],2]
        HPtitle = kyouzaiDB.iloc[index[number],0]
        HPurl = kyouzaiDB.iloc[index[number],1]
        evaluation = int(request.form['evaluation'])
        text = request.form['text']

        studentnumber = session["username"]

        dt = datetime.now()
        dtt = dt.replace(microsecond=0)
        date = dtt.strftime("%Y/%#m/%#d %H:%M")
        review_list = [HPtitle,HPurl,HPnumber,studentnumber,evaluation,text,date]

        with open(f"Kamoku/{unit_name}/Kyouzai/kyouzai{key_number}/review_prac.csv","a",encoding="cp932",newline='') as f:
            writer = csv.writer(f,delimiter=',')
            writer.writerow(review_list)
        #評価によって並べ替える
        df = pd.read_csv(f"Kamoku/{unit_name}/Kyouzai/kyouzai{key_number}/review_prac.csv",encoding="cp932")
        saveDB = f"Kamoku/{unit_name}/Kyouzai/kyouzai{key_number}/kyouzaiDB.csv"


        #Youtube
        youtubeDB = pd.read_csv(f'Kamoku/{unit_name}/Kyouzai/kyouzai{key_number}/video_kyouzai.csv', encoding="cp932")
        video_review_df = pd.read_csv(f'Kamoku/{unit_name}/Kyouzai/kyouzai{key_number}/video_Review.csv',encoding='cp932')

        video_title_list = []
        video_url_list = []
        video_id_list = []
        mihyouka_video_title_list = []
        mihyouka_video_url_list = []
        mihyouka_video_id_list = []
        video_length = []
        video_index = list(youtubeDB.query(f'Credibility_score.isnull()',engine='python').index)
        yo = youtubeDB['Youtubenumber']

        for i in range(3):
            video_title_list.append(youtubeDB.iat[i,0])
            video_url_list.append(youtubeDB.iat[i,1])
            video_id_list.append(youtubeDB.iat[i,3])
            mihyouka_video_title_list.append(youtubeDB.iat[video_index[i],0])
            mihyouka_video_url_list.append(youtubeDB.iat[video_index[i],1])
            mihyouka_video_id_list.append(youtubeDB.iat[video_index[i],3])
            video_length.append(len(list(video_review_df.query(f'Youtubenumber == "{yo[i]}"').index)))


        S_score_norm = Similarity(df)
        I_score_norm = Informative(df)
        C_score_norm = Concentration(df)
        Credibility_score,Ave_score = Credibility(S_score_norm,I_score_norm,C_score_norm,HPnumber,df)
        review_score = [HPtitle,HPurl,HPnumber,studentnumber,evaluation,text,date,Credibility_score,Ave_score]

        with open(f"Kamoku/{unit_name}/Kyouzai/kyouzai{key_number}/review_score.csv", "a", encoding="cp932",newline='') as f:
            writer = csv.writer(f,delimiter=',')
            writer.writerow(review_score)

        kyouzai_title_list,kyouzai_url_list,mihyouka_kyouzai_title_list,mihyouka_kyouzai_url_list,length =\
            kousinn(kyouzaiDB,Credibility_score,HPnumber,df,saveDB)

        kousinn_df = pd.read_csv(f"Kamoku/{unit_name}/Kyouzai/kyouzai{key_number}/kyouzaiDB.csv",encoding="cp932")
        score_list = []
        for i in range(3):
            score_list.append(kousinn_df.iat[i,3])
        
        video_kousinn_df = pd.read_csv(f'Kamoku/{unit_name}/Kyouzai/kyouzai{key_number}/video_kyouzai.csv',encoding='cp932')
        video_score_list = []
        for i in range(3):
            video_score_list.append(video_kousinn_df.iat[i,4])  

        return render_template(f"/{unit_name}/{key_number}.html",title = keyword[key_number-1],
        kyouzai_title1 = kyouzai_title_list[0],kyouzai_url1 = kyouzai_url_list[0],
        kyouzai_title2 = kyouzai_title_list[1],kyouzai_url2 = kyouzai_url_list[1],
        kyouzai_title3 = kyouzai_title_list[2],kyouzai_url3 = kyouzai_url_list[2],
        mihyouka_title1 = mihyouka_kyouzai_title_list[0],mihyouka_url1 = mihyouka_kyouzai_url_list[0],
        mihyouka_title2 = mihyouka_kyouzai_title_list[1],mihyouka_url2 = mihyouka_kyouzai_url_list[1],
        mihyouka_title3 = mihyouka_kyouzai_title_list[2],mihyouka_url3 = mihyouka_kyouzai_url_list[2],
        length1 = length[0],length2=length[1],length3=length[2],
        video_title1 = video_title_list[0],video_url1 = video_url_list[0],video_id1 = video_id_list[0],
        video_title2 = video_title_list[1],video_url2 = video_url_list[1],video_id2 = video_id_list[1],
        video_title3 = video_title_list[2],video_url3 = video_url_list[2],video_id3 = video_id_list[2],
        mihyouka_video_title1 = mihyouka_video_title_list[0],mihyouka_video_url1 = mihyouka_video_url_list[0],
        mihyouka_video_title2 = mihyouka_video_title_list[1],mihyouka_video_url2 = mihyouka_video_url_list[1],
        mihyouka_video_title3 = mihyouka_video_title_list[2],mihyouka_video_url3 = mihyouka_video_url_list[2],
        mihyouka_video_id1 = mihyouka_video_id_list[0],mihyouka_video_id2 = mihyouka_video_id_list[1],mihyouka_video_id3S = mihyouka_video_id_list[2],
        video_length1 = video_length[0],video_length2=video_length[1],video_length3=video_length[2],
        score1 = score_list[0],score2 = score_list[1],score3 = score_list[2],
        video_score1 = video_score_list[0],video_score2 = video_score_list[1],video_score3 = video_score_list[2]
        )

    @app.route('/video',methods =["post"])
    def video():

        unit_name = request.form.get('unit_name')
        unit = request.form.get('unit')
        key_number = int(request.form.get('key_number'))

        df_key = pd.read_csv(f"Kamoku/{unit_name}/KeyWord.csv",encoding="cp932",names= ['key'])
        keyword = []
        for i in range(len(df_key)):
            keyword.append(df_key.loc[i,'key'])

        youtubeDB = pd.read_csv(f'Kamoku/{unit_name}/Kyouzai/kyouzai{key_number}/video_kyouzai.csv',encoding='cp932')
        number = int(request.form['number'])
        Youtubenumber = youtubeDB.iloc[number,2]
        Youtubetitel = youtubeDB.iloc[number,0]
        Youtubeurl = youtubeDB.iloc[number,1]
        Youtubeid = youtubeDB.iloc[number,3]
        evaluation = int(request.form['evaluation'])
        text = request.form['text']
        
        #レビューした学籍番号を取得
        studentnumber = session["username"]


        dt = datetime.now()
        dtt = dt.replace(microsecond=0)
        #date = dtt.strftime("%Y/%#m/$#d %H:%M") 
        date = dtt.strftime("%Y/%#m/%#d %H:%M")
        video_review = [Youtubetitel,Youtubeurl,Youtubenumber,studentnumber,evaluation,text,date,Youtubeid]

        with open(f'Kamoku/{unit_name}/Kyouzai/kyouzai{key_number}/video_Review.csv','a',encoding="cp932",newline='') as f:
            writer = csv.writer(f,delimiter=',')
            writer.writerow(video_review)
        
        video_df = pd.read_csv(f'Kamoku/{unit_name}/Kyouzai/kyouzai{key_number}/video_Review.csv',encoding='cp932')
        save_videoDB = f"Kamoku/{unit_name}/Kyouzai/kyouzai{key_number}/video_kyouzai.csv"

        S_score_norm = Similarity(video_df)
        I_score_norm = Informative(video_df)
        C_score_norm = Concentration(video_df)
        Credibility_score, Ave_score = video_Credibility(S_score_norm,I_score_norm,C_score_norm,Youtubenumber,video_df)
        review_score = [Youtubetitel,Youtubeurl,Youtubenumber,studentnumber,evaluation,text,date,Credibility_score,Ave_score]
        
        with open(f'Kamoku/{unit_name}/Kyouzai/kyouzai{key_number}/video_score.csv', 'a',encoding="cp932",newline='') as f:
            writer = csv.writer(f,delimiter=',')
            writer.writerow(review_score)
        
        ##HP##
        kyouzaiDB = pd.read_csv(f'Kamoku/{unit_name}/Kyouzai/kyouzai{key_number}/kyouzaiDB.csv', encoding="cp932")
        review_df = pd.read_csv(f"Kamoku/{unit_name}/Kyouzai/kyouzai{key_number}/review_prac.csv",encoding='cp932')
        kyouzai_title_list = []
        kyouzai_url_list = []
        mihyouka_kyouzai_title_list = []
        mihyouka_kyouzai_url_list = []
        length = []
        index = list(kyouzaiDB.query(f'Credibility_score.isnull()',engine='python').index)
        a = kyouzaiDB['Hpnumber']

        for i in range(3):
            kyouzai_title_list.append(kyouzaiDB.iloc[i,0])
            kyouzai_url_list.append(kyouzaiDB.iloc[i,1])
            mihyouka_kyouzai_title_list.append(kyouzaiDB.iloc[index[i],0])
            mihyouka_kyouzai_url_list.append(kyouzaiDB.iloc[index[i],1])
            length.append(len(list(review_df.query(f'Hpnumber == "{a[i]}"').index)))
        
        
        kousinn_df = pd.read_csv(f'Kamoku/{unit_name}/Kyouzai/kyouzai{key_number}/kyouzaiDB.csv',encoding='cp932')
        score_list = []
        for i in range(3):
            score_list.append(kousinn_df.iat[i,3])

        video_title_list,video_url_list,mihyouka_video_title_list,mihyouka_video_url_list,video_id_list,mihyouka_video_id_list,video_length =\
            video_kousinn(youtubeDB,Credibility_score,Youtubenumber, video_df, save_videoDB)
        video_kousinn_df = pd.read_csv(f'Kamoku/{unit_name}/Kyouzai/kyouzai{key_number}/video_kyouzai.csv',encoding='cp932')
        video_score_list = []
        for i in range(3):
            video_score_list.append(video_kousinn_df.iat[i,4])

        return render_template(f"/{unit_name}/{key_number}.html",title = keyword[key_number-1],
        kyouzai_title1 = kyouzai_title_list[0],kyouzai_url1 = kyouzai_url_list[0],
        kyouzai_title2 = kyouzai_title_list[1],kyouzai_url2 = kyouzai_url_list[1],
        kyouzai_title3 = kyouzai_title_list[2],kyouzai_url3 = kyouzai_url_list[2],
        mihyouka_title1 = mihyouka_kyouzai_title_list[0],mihyouka_url1 = mihyouka_kyouzai_url_list[0],
        mihyouka_title2 = mihyouka_kyouzai_title_list[1],mihyouka_url2 = mihyouka_kyouzai_url_list[1],
        mihyouka_title3 = mihyouka_kyouzai_title_list[2],mihyouka_url3 = mihyouka_kyouzai_url_list[2],
        length1 = length[0],length2=length[1],length3=length[2],
        video_title1 = video_title_list[0],video_url1 = video_url_list[0],video_id1 = video_id_list[0],
        video_title2 = video_title_list[1],video_url2 = video_url_list[1],video_id2 = video_id_list[1],
        video_title3 = video_title_list[2],video_url3 = video_url_list[2],video_id3 = video_id_list[2],
        mihyouka_video_title1 = mihyouka_video_title_list[0],mihyouka_video_url1 = mihyouka_video_url_list[0],
        mihyouka_video_title2 = mihyouka_video_title_list[1],mihyouka_video_url2 = mihyouka_video_url_list[1],
        mihyouka_video_title3 = mihyouka_video_title_list[2],mihyouka_video_url3 = mihyouka_video_url_list[2],
        mihyouka_video_id1 = mihyouka_video_id_list[0],mihyouka_video_id2 = mihyouka_video_id_list[1],mihyouka_video_id3 = mihyouka_video_id_list[2],
        video_length1 = video_length[0],video_length2=video_length[1],video_length3=video_length[2],
        score1 = score_list[0],score2 = score_list[1],score3 = score_list[2],
        video_score1 = video_score_list[0],video_score2 = video_score_list[1],video_score3 = video_score_list[2])





    @app.route('/mihyouka_video',methods =["post"])
    def mihyouka_video():

        unit_name = request.form.get('unit_name')
        unit = request.form.get('unit')
        key_number = int(request.form.get('key_number'))

        df_key = pd.read_csv(f"Kamoku/{unit_name}/KeyWord.csv",encoding="cp932",names= ['key'])
        keyword = []
        for i in range(len(df_key)):
            keyword.append(df_key.loc[i,'key'])

        youtubeDB = pd.read_csv(f'Kamoku/{unit_name}/Kyouzai/kyouzai{key_number}/video_kyouzai.csv',encoding='cp932')
        number = int(request.form['number'])
        video_index = list(youtubeDB.query(f'Credibility_score.isnull()',engine='python').index)
        Youtubenumber = youtubeDB.iloc[video_index[number],2]
        Youtubetitel = youtubeDB.iloc[video_index[number],0]
        Youtubeurl = youtubeDB.iloc[video_index[number],1]
        Youtubeid = youtubeDB.iloc[video_index[number],3]
        evaluation = int(request.form['evaluation'])
        text = request.form['text']

        studentnumber = session["username"]


        dt = datetime.now()
        dtt = dt.replace(microsecond=0)
        date = dtt.strftime("%Y/%#m/%#d %H:%M")

        video_review = [Youtubetitel,Youtubeurl,Youtubenumber,studentnumber,evaluation,text,date,Youtubeid]
        with open(f'Kamoku/{unit_name}/Kyouzai/kyouzai{key_number}/video_Review.csv', 'a',encoding="cp932",newline='') as f:
            writer = csv.writer(f,delimiter=',')
            writer.writerow(video_review)

        video_df = pd.read_csv(f"Kamoku/{unit_name}/Kyouzai/kyouzai{key_number}/video_Review.csv", encoding="cp932")
        save_videoDB = f"Kamoku/{unit_name}/Kyouzai/kyouzai{key_number}/video_kyouzai.csv"
        
        S_score_norm = Similarity(video_df)
        I_score_norm = Informative(video_df)
        C_score_norm = Concentration(video_df)
        Credibility_score,Ave_score = video_Credibility(S_score_norm,I_score_norm,C_score_norm,Youtubenumber,video_df)
        review_score = [Youtubetitel,Youtubeurl,Youtubenumber,studentnumber,evaluation,text,date,Credibility_score,Ave_score]
        
        with open(f'Kamoku/{unit_name}/Kyouzai/kyouzai{key_number}/video_score.csv', 'a',encoding="cp932",newline='') as f:
            writer = csv.writer(f,delimiter=',')
            writer.writerow(review_score)
        
        ##HP##
        kyouzaiDB = pd.read_csv(f'Kamoku/{unit_name}/Kyouzai/kyouzai{key_number}/kyouzaiDB.csv', encoding="cp932")
        review_df = pd.read_csv(f'Kamoku/{unit_name}/Kyouzai/kyouzai{key_number}/review_prac.csv',encoding='cp932')
        kyouzai_title_list = []
        kyouzai_url_list = []
        mihyouka_kyouzai_title_list = []
        mihyouka_kyouzai_url_list = []
        length = []
        index = list(kyouzaiDB.query(f'Credibility_score.isnull()',engine='python').index)
        a = kyouzaiDB['Hpnumber']

        for i in range(3):
            kyouzai_title_list.append(kyouzaiDB.iloc[i,0])
            kyouzai_url_list.append(kyouzaiDB.iloc[i,1])
            mihyouka_kyouzai_title_list.append(kyouzaiDB.iloc[index[i],0])
            mihyouka_kyouzai_url_list.append(kyouzaiDB.iloc[index[i],1])
            length.append(len(list(review_df.query(f'Hpnumber == "{a[i]}"').index)))
        
        
        kousinn_df = pd.read_csv(f'Kamoku/{unit_name}/Kyouzai/kyouzai{key_number}/kyouzaiDB.csv',encoding='cp932')
        score_list = []
        for i in range(3):
            score_list.append(kousinn_df.iat[i,3])
        
        video_title_list,video_url_list,mihyouka_video_title_list,mihyouka_video_url_list,video_id_list,mihyouka_video_id_list,video_length =\
            video_kousinn(youtubeDB,Credibility_score,Youtubenumber, video_df, save_videoDB)
        video_kousinn_df = pd.read_csv(f'Kamoku/{unit_name}/Kyouzai/kyouzai{key_number}/video_kyouzai.csv',encoding='cp932')
        video_score_list = []
        for i in range(3):
            video_score_list.append(video_kousinn_df.iat[i,4])

        return render_template(f"/{unit_name}/{key_number}.html",title = keyword[key_number-1],
        kyouzai_title1 = kyouzai_title_list[0],kyouzai_url1 = kyouzai_url_list[0],
        kyouzai_title2 = kyouzai_title_list[1],kyouzai_url2 = kyouzai_url_list[1],
        kyouzai_title3 = kyouzai_title_list[2],kyouzai_url3 = kyouzai_url_list[2],
        mihyouka_title1 = mihyouka_kyouzai_title_list[0],mihyouka_url1 = mihyouka_kyouzai_url_list[0],
        mihyouka_title2 = mihyouka_kyouzai_title_list[1],mihyouka_url2 = mihyouka_kyouzai_url_list[1],
        mihyouka_title3 = mihyouka_kyouzai_title_list[2],mihyouka_url3 = mihyouka_kyouzai_url_list[2],
        length1 = length[0],length2=length[1],length3=length[2],
        video_title1 = video_title_list[0],video_url1 = video_url_list[0],video_id1 = video_id_list[0],
        video_title2 = video_title_list[1],video_url2 = video_url_list[1],video_id2 = video_id_list[1],
        video_title3 = video_title_list[2],video_url3 = video_url_list[2],video_id3 = video_id_list[2],
        mihyouka_video_title1 = mihyouka_video_title_list[0],mihyouka_video_url1 = mihyouka_video_url_list[0],
        mihyouka_video_title2 = mihyouka_video_title_list[1],mihyouka_video_url2 = mihyouka_video_url_list[1],
        mihyouka_video_title3 = mihyouka_video_title_list[2],mihyouka_video_url3 = mihyouka_video_url_list[2],
        mihyouka_video_id1 = mihyouka_video_id_list[0],mihyouka_video_id2 = mihyouka_video_id_list[1],mihyouka_video_id3 = mihyouka_video_id_list[2],
        video_length1 = video_length[0],video_length2=video_length[1],video_length3=video_length[2],
        score1 = score_list[0],score2 = score_list[1],score3 = score_list[2],
        video_score1 = video_score_list[0],video_score2 = video_score_list[1],video_score3 = video_score_list[2]
        )







    ###############################################################################################
    #######################################共用
    ###############################################################################################
    @app.route('/logout')
    def logout():
        # セッションからユーザー情報を削除し、ログアウト
        session.pop('username', None)
        session.pop('password', None)
        session.pop('name', None)
        return redirect(url_for('home'))

    if __name__ == '__main__':
        app.run(debug=True)


トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS