Beispiel #1
0
def minimum_quiz(file_num=-1, category=None, image=True):
    """最小正解数の問題を取得する

    Args:
        file_num (int, optional): ファイル番号. Defaults to -1.
        category (str, optional): カテゴリ. Defaults to None.
        image (bool, optional): イメージフラグ. Defaults to True.

    Returns:
        results [JSON]: 取得した問題
    """

    # 設定ファイルを呼び出してファイル番号からテーブル名を取得
    # (変なファイル番号の時はランダムに選ぶ)
    table_list = get_table_list()
    if (file_num < 0 or len(table_list) <= file_num):
        file_num = random.randint(0, len(table_list) - 1)
    table = table_list[file_num]['name']
    nickname = table_list[file_num]['nickname']

    # TODO イメージフラグの操作

    # MySQL への接続を確立する
    try:
        conn = get_connection()
    except Exception as e:
        return {
            "statusCode": 500,
            "message": 'Error: DB接続時にエラーが発生しました',
            "traceback": traceback.format_exc()
        }

    # テーブル名からSQLを作成して投げる
    try:
        with conn.cursor() as cursor:
            # 指定したテーブルの正解数が最も低い問題を調べる
            # カテゴリが指定されている場合は条件文を追加する
            where_statement = "WHERE"
            if (category is not None):
                where_statement += " category LIKE '%" + category + "%' "

            if (where_statement == "WHERE"):
                where_statement = ""

            sql = "SELECT quiz_num, quiz_sentense, answer, clear_count, fail_count, category, img_file FROM {0} ".format(
                table) + where_statement + " ORDER BY clear_count LIMIT 1"
            cursor.execute(sql)

            # MySQLから帰ってきた結果を受け取る
            # Select結果を取り出す
            results = cursor.fetchall()

        # 結果をJSONに変形して返す
        return {"statusCode": 200, "result": results}
    except Exception as e:
        return {
            "statusCode": 500,
            "message": 'Error: DB操作時にエラーが発生しました',
            "traceback": traceback.format_exc()
        }
Beispiel #2
0
def get_accuracy_rate_by_category(file_ind):
    """ファイル番号からカテゴリ毎の正解率を取得する関数

    Args:
        file_ind (int): ファイル番号

        Returns:
            result [JSON]: 取得した結果のリスト
    """

    # 設定ファイルを呼び出してファイル番号からテーブル名を取得
    # (変なファイル番号ならエラー終了)
    try:
        table_list = get_table_list()
        table = table_list[file_ind]['name']
        nickname = table_list[file_ind]['nickname']
    except IndexError:
        return {"statusCode": 500, "message": 'Error: ファイル番号が正しくありません'}

    # MySQL への接続を確立する
    try:
        conn = get_connection()
    except Exception as e:
        return {
            "statusCode": 500,
            "message": 'Error: DB接続時にエラーが発生しました',
            "traceback": traceback.format_exc()
        }

    # # SQLを作成して投げる
    try:
        with conn.cursor() as cursor:
            # 検索語句がカテゴリに含まれる
            # SQLを実行する
            sql_statement = "SELECT c_category,accuracy_rate FROM {0} ORDER BY accuracy_rate ".format(
                table + '_category_view')
            cursor.execute(sql_statement)

            # MySQLから帰ってきた結果を受け取る
            # Select結果を取り出す
            results = cursor.fetchall()
            # TODO Decimal -> strに直す効率良い方法、もしくは数値のままでもエラー出ずに返せる方法(DecimalのままだとAPIで取得時にエラーになる)
            for i in range(len(results)):
                ri = results[i]
                ri['accuracy_rate'] = str(ri['accuracy_rate'])
                results[i] = ri

        # 結果をJSONに変形して返す
        return {"statusCode": 200, "result": results}
    except Exception as e:
        return {
            "statusCode": 500,
            "message": 'Error: DB操作時にエラーが発生しました',
            "traceback": traceback.format_exc()
        }
Beispiel #3
0
def random_quiz(file_num=-1, image=True, rate=100.0, category=""):
    """問題を1問、ランダムに取得するAPI

    Args:
        file_num (int, optional): ファイル番号. Defaults to -1.
        image (bool, optional): 画像取得フラグ. Defaults to True.
        rate (float, optional): 取得する問題の正解率の最大値. Defaults to 100.0.
        category (str, optional): 取得する問題のカテゴリ Defaults to ''

    Returns:
        result (JSON): ランダムに取得した問題
    """
    # TODO image_flagの処理
    # TODO rateの処理

    # 設定ファイルを呼び出してファイル番号からテーブル名を取得
    # (変なファイル番号の時はランダムに選ぶ)
    table_list = get_table_list()
    if (file_num < 0 or len(table_list) <= file_num):
        file_num = random.randint(0, len(table_list) - 1)
    table = table_list[file_num]['name']
    nickname = table_list[file_num]['nickname']

    # MySQL への接続を確立する
    try:
        conn = get_connection()
    except Exception as e:
        return {
            "statusCode": 500,
            "message": 'Error: DB接続時にエラーが発生しました',
            "traceback": traceback.format_exc()
        }

    # WHERE文作成
    where_statement = 'WHERE'
    if (len(category) > 0):
        where_statement += (" category LIKE '%" + category + "%' ")

    if (where_statement == 'WHERE'):
        where_statement = ''

    # テーブル名からSQLを作成して投げる
    with conn.cursor() as cursor:
        # SQL作成して問題を取得する。結果のうちランダムに1つ取得する
        sql = "SELECT quiz_num, quiz_sentense, answer, clear_count, fail_count, category, img_file FROM {0} {1} ORDER BY RAND() LIMIT 1".format(
            table, where_statement)
        cursor.execute(sql)

        # MySQLから帰ってきた結果を受け取る
        # Select結果を取り出す
        results = cursor.fetchall()

    # 結果をJSONに変形して返す
    return {"statusCode": 200, "result": results}
Beispiel #4
0
def get_category(file_num):
    """ファイル番号からカテゴリを取得する関数

    Args:
        file_num (int): ファイル番号

        Returns:
            result [JSON]: 取得したカテゴリのリスト
    """

    # 設定ファイルを呼び出してファイル番号からテーブル名を取得
    # (変なファイル番号ならエラー終了)
    try:
        table_list = get_table_list()
        table = table_list[file_num]['name']
        nickname = table_list[file_num]['nickname']
    except IndexError:
        return {"statusCode": 500, "message": 'Error: ファイル番号が正しくありません'}

    # MySQL への接続を確立する
    try:
        conn = get_connection()
    except Exception as e:
        return {
            "statusCode": 500,
            "message": 'Error: DB接続時にエラーが発生しました',
            "traceback": traceback.format_exc()
        }

    # # SQLを作成して投げる
    with conn.cursor() as cursor:
        # 検索語句がカテゴリに含まれる
        # SQLを実行する
        sql_statement = "SELECT DISTINCT category FROM {0} ".format(table)
        cursor.execute(sql_statement)

        # MySQLから帰ってきた結果を受け取る
        # Select結果を取り出す
        results = cursor.fetchall()

        categories = set([])
        for ri in results:
            categories = categories | set(list(ri['category'].split(':')))

    # 結果をJSONに変形して返す
    return {"statusCode": 200, "result": list(categories)}
Beispiel #5
0
def edit_category_of_question(data):
    """問題にカテゴリを追加・削除する関数

    Args:
        data ([JSON]): JSONの配列
        要素は
        {
            "file_num" : ファイル番号(int)
            "quiz_num" : 問題番号(int)
            "category" : 追加・削除するカテゴリ
        }
    """

    # テーブルリスト取得
    table_list = get_table_list()

    # MySQL への接続を確立する
    try:
        conn = get_connection()
    except Exception as e:
        return {
            "statusCode": 500,
            "message": 'Error: DB接続時にエラーが発生しました',
            "traceback": traceback.format_exc()
        }

    try:
        # data内のクエリを1個1個見ていく
        for data_i in data:
            # ファイル番号を取得
            file_num = data_i['file_num']
            # 問題番号を取得
            quiz_num = data_i['quiz_num']
            # 追加・削除するカテゴリを取得
            query_category = data_i['category']

            # テーブル名取得
            table = table_list[file_num]['name']
            nickname = table_list[file_num]['nickname']

            with conn.cursor() as cursor:
                # まずは問題を取得
                sql = "SELECT quiz_num, quiz_sentense, answer, clear_count, fail_count, category, img_file FROM {0} WHERE quiz_num = {1}".format(
                    table, quiz_num)
                cursor.execute(sql)

                # MySQLから帰ってきた結果を受け取る
                # Select結果を取り出す
                results = cursor.fetchall()

                # カテゴリを取得
                category = results[0]['category']

                # カテゴリを修正する
                if (category is not None and query_category in category):
                    # クエリで出したカテゴリがすでにある場合はそれを削除する
                    category = category.replace(query_category, "")
                    category = category.replace("::", ":")
                    if (category == ":"):
                        category = ""
                    elif (len(category) > 1 and category[0] == ":"):
                        category = category[1:]
                    elif (len(category) > 1 and category[-1] == ":"):
                        category = category[:-1]
                else:
                    # クエリで出したカテゴリが含まれてない場合は追加する
                    if (category is None or category == ''):
                        category = query_category
                    else:
                        category = category + ":" + query_category

                # アップデート
                sql = "UPDATE {0} SET category = '{1}' WHERE quiz_num = {2} ".format(
                    table, category, quiz_num)
                cursor.execute(sql)

        #全て成功したらコミット
        conn.commit()
        conn.close()

        return {"statusCode": 200, "message": "All OK."}

    # DB操作失敗時はロールバック
    except Exception as e:
        message = 'Error: DB接続時にエラーが発生しました '
        try:
            conn.rollback()
        except:
            message += '( ロールバックにも失敗しました )'
        finally:
            return {
                "statusCode": 500,
                "message": message,
                "traceback": traceback.format_exc()
            }
Beispiel #6
0
def edit_quiz(file_num, quiz_num, question, answer, category, img_file):
    """入力データで問題を編集する関数

    Args:
        file_num (int): ファイル番号
        quiz_num (int): 問題番号
        question (str): 問題文
        answer (str): 答えの文
        category (str): カテゴリ
        img_file (str): 画像ファイル名

    Returns:
        [type]: [description]
    """

    # 入力内容確認
    if (question is None or len(question.strip())
            == 0) and (answer is None or len(answer.strip()) == 0) and (
                category is None or len(category.strip())
                == 0) and (img_file is None or len(img_file.strip()) == 0):
        return {"statusCode": 500, "message": 'Error: 入力内容がありません'}

    # 設定ファイルを呼び出してファイル番号からテーブル名を取得
    # (変なファイル番号ならエラー終了)
    try:
        table_list = get_table_list()
        table = table_list[file_num]['name']
        nickname = table_list[file_num]['nickname']
    except IndexError:
        return {"statusCode": 500, "message": 'Error: ファイル番号が正しくありません'}

    # MySQL への接続を確立する
    try:
        conn = get_connection()
    except Exception as e:
        return {
            "statusCode": 500,
            "message": 'Error: DB接続時にエラーが発生しました',
            "traceback": traceback.format_exc()
        }

    try:
        # 入力内容からSQLを作成して投げる
        # SQLを実行する
        with conn.cursor() as cursor:
            # テーブルに入力内容を更新する
            update_question = "" if question is None or len(question.strip(
            )) == 0 else " quiz_sentense = '{0}', ".format(question)
            update_answer = "" if answer is None or len(
                answer.strip()) == 0 else " answer = '{0}', ".format(answer)
            update_category = "" if category is None or len(category.strip(
            )) == 0 else " category = '{0}', ".format(category)
            update_img_file = " img_file = '' " if img_file is None else " img_file = '{0}' ".format(
                img_file)
            sql = "UPDATE {0} SET {1} {2} {3} {4} WHERE quiz_num = {5} ".format(
                table, update_question, update_answer, update_category,
                update_img_file, quiz_num)
            print(sql)
            cursor.execute(sql)

            result = "Success!! [{0}-{1}]:{2},{3},{4},{5}".format(
                nickname, str(quiz_num), question, answer, category, img_file)

        #全て成功したらコミット
        conn.commit()
        conn.close()

    # DB操作失敗時はロールバック
    except Exception as e:
        message = 'Error: DB接続時にエラーが発生しました '
        try:
            conn.rollback()
        except:
            message += '( ロールバックにも失敗しました )'
        finally:
            return {
                "statusCode": 500,
                "message": message,
                "traceback": traceback.format_exc()
            }

    # 結果(文字列)を返す
    return {"statusCode": 200, "result": result}
Beispiel #7
0
def add_quiz(file_num, input_data):
    """ファイル番号、問題番号、イメージ取得フラグから問題を取得する関数

    Args:
        file_num (int): ファイル番号
        input_data (str): 入力されたデータ(テスト問題,正解,カテゴリ,画像ファイル名)*x行

        Returns:
            result (JSON): 取得した問題
    """

    # 入力データを1行ずつに分割
    input_data = list(input_data.split('\n'))

    # 設定ファイルを呼び出してファイル番号からテーブル名を取得
    # (変なファイル番号ならエラー終了)
    try:
        table_list = get_table_list()
        table = table_list[file_num]['name']
        nickname = table_list[file_num]['nickname']
    except IndexError:
        return {"statusCode": 500, "message": 'Error: ファイル番号が正しくありません'}

    # MySQL への接続を確立する
    try:
        conn = get_connection()
    except Exception as e:
        return {
            "statusCode": 500,
            "message": 'Error: DB接続時にエラーが発生しました',
            "traceback": traceback.format_exc()
        }

    try:
        # データ全件数を確認
        count = 0
        with conn.cursor() as cursor:
            # 指定したテーブルの件数を調べる
            sql = "SELECT count(*) FROM {0}".format(table)
            cursor.execute(sql)
            results = cursor.fetchall()
            count = results[0]['count(*)']

        # 返るデータ
        result = []

        # 1行ずつ処理し、全て正常に行えた場合のみコミット、途中でエラーが発生した場合はロールバック
        for di in input_data:

            # 入力データ作成
            data_i = di.split(',')
            question = data_i[0]
            answer = data_i[1]
            category = data_i[2]
            img_file = data_i[3]

            # データのidを作成
            count += 1

            # テーブル名と問題番号からSQLを作成して投げる
            # (問題番号が範囲外なら終了)
            # SQLを実行する
            with conn.cursor() as cursor:
                # データを挿入する
                sql = "INSERT INTO {0} VALUES({1},'{2}','{3}',0,0,'{4}','{5}')".format(
                    table, count, question, answer, category, img_file)
                print(sql)
                cursor.execute(sql)

                result.append("Added!! [{0}-{1}]:{2},{3}".format(
                    nickname, str(count), question, answer))

        else:
            #全て成功したらコミット
            conn.commit()
            conn.close()

    # DB操作失敗時はロールバック
    except Exception as e:
        message = 'Error: DB接続時にエラーが発生しました '
        try:
            conn.rollback()
        except:
            message += '( ロールバックにも失敗しました )'
        finally:
            return {
                "statusCode": 500,
                "message": message,
                "traceback": traceback.format_exc()
            }

    # 結果(文字列)を返す
    return {"statusCode": 200, "result": result}
def update_category_master():
    """ファイル番号からカテゴリを取得する関数

    Args:
        なし

    Returns:
        なし
    """

    # 設定ファイルを呼び出してファイル番号からテーブル名を取得
    # (変なファイル番号ならエラー終了)
    try:
        table_list = get_table_list()
        table = [table_list[i]['name'] for i in range(len(table_list))]
        nickname = [table_list[i]['nickname'] for i in range(len(table_list))]
    except IndexError:
        return {"statusCode": 500, "message": 'Error: ファイル読み取りに失敗しました'}

    # MySQL への接続を確立する
    try:
        conn = get_connection()
    except Exception as e:
        return {
            "statusCode": 500,
            "message": 'Error: DB接続時にエラーが発生しました',
            "traceback": traceback.format_exc()
        }

    # # SQLを作成して投げる
    try:
        # 追加するカテゴリ数
        insert_categories = 0

        with conn.cursor() as cursor:
            # テーブル毎にカテゴリのリストを取得してマスタに更新
            for i in range(len(table)):
                # 問題テーブルからカテゴリのリストを取得
                sql_statement = "SELECT DISTINCT category FROM {0} ".format(
                    table[i])
                cursor.execute(sql_statement)
                results = cursor.fetchall()

                categories = set([])
                for ri in results:
                    categories = categories | set(
                        list(ri['category'].split(':')))

                # カテゴリマスタから既にあるカテゴリを取得
                sql_statement = "SELECT DISTINCT category FROM category WHERE file_name = '{0}' ".format(
                    table[i])
                cursor.execute(sql_statement)
                results = cursor.fetchall()
                already_exists_category = set(
                    [ri['category'] for ri in results])

                # マスタに入れるカテゴリリストを作る
                categories = list(categories - already_exists_category)
                insert_categories += len(categories)

                # カテゴリマスタにデータを入れる
                for ci in categories:
                    sql_statement = "INSERT INTO category VALUES('{0}','{1}') ".format(
                        table[i], ci)
                    cursor.execute(sql_statement)

        #全て成功したらコミット
        conn.commit()
        conn.close()
    # DB操作失敗時はロールバック
    except Exception as e:
        message = 'Error: DB接続時にエラーが発生しました '
        try:
            conn.rollback()
        except:
            message += '( ロールバックにも失敗しました )'
        finally:
            return {
                "statusCode": 500,
                "message": message,
                "traceback": traceback.format_exc()
            }

    # 結果をJSONに変形して返す
    return {
        "statusCode": 200,
        "message": "カテゴリマスタの更新が完了しました(新規カテゴリ数:{0})".format(insert_categories),
    }
Beispiel #9
0
def search_quiz(query, file_num, cond, category):
    """検索語句から問題を取得する関数

    Args:
        query (str): 検索語句
        file_num (int): ファイル番号
        cond(JSON): 検索条件のオプション
        category (str): カテゴリ

        Returns:
            result [JSON]: 取得した問題のリスト
    """

    # 設定ファイルを呼び出してファイル番号からテーブル名を取得
    # (変なファイル番号ならエラー終了)
    try:
        table_list = get_table_list()
        table = table_list[file_num]['name']
        nickname = table_list[file_num]['nickname']
        cond_question = cond.get('question', False)
        cond_answer = cond.get('answer', False)
    except IndexError:
        return {"statusCode": 500, "message": 'Error: ファイル番号が正しくありません'}

    # MySQL への接続を確立する
    try:
        conn = get_connection()
    except Exception as e:
        return {
            "statusCode": 500,
            "message": 'Error: DB接続時にエラーが発生しました',
            "traceback": traceback.format_exc()
        }

    # テーブル名と問題番号からSQLを作成して投げる
    with conn.cursor() as cursor:
        # 検索語句が問題文または解答文に含まれる
        # SQLを実行する
        sql_statement = "SELECT quiz_num, quiz_sentense, answer, clear_count, fail_count, category, img_file FROM {0} ".format(
            table, query)
        sql_statement += " WHERE "
        where_statement = []
        if (not cond_question and not cond_answer):
            where_statement.append(
                " (quiz_sentense LIKE '%{0}%' OR answer LIKE '%{0}%') ".format(
                    query))
        if (cond_question):
            # 問題にチェックあったときは語句が含まれている問題文を検索
            where_statement.append(
                " quiz_sentense LIKE '%{0}%' ".format(query))
        if (cond_answer):
            # 答えにチェックあったときは語句が含まれている解答文を検索
            where_statement.append(" answer LIKE '%{0}%' ".format(query))
        if (category != ""):
            # カテゴリを指定して検索
            where_statement.append(" category LIKE '%{0}%' ".format(category))

        sql_statement += ' AND '.join(where_statement)

        cursor.execute(sql_statement)

        # MySQLから帰ってきた結果を受け取る
        # Select結果を取り出す
        results = cursor.fetchall()

    # 結果をJSONに変形して返す
    return {"statusCode": 200, "result": results}
Beispiel #10
0
def select_quiz(file_num, quiz_num, image_flag):
    """ファイル番号、問題番号、イメージ取得フラグから問題を取得する関数

    Args:
        file_num (int): ファイル番号
        quiz_num (int): 問題番号
        image_flag (bool): イメージ取得フラグ

        Returns:
            result (JSON): 取得した問題
    """

    # 設定ファイルを呼び出してファイル番号からテーブル名を取得
    # (変なファイル番号ならエラー終了)
    try:
        table_list = get_table_list()
        table = table_list[file_num]['name']
        nickname = table_list[file_num]['nickname']
    except IndexError:
        return {"statusCode": 500, "message": 'Error: ファイル番号が正しくありません'}

    # MySQL への接続を確立する
    try:
        conn = get_connection()
    except Exception as e:
        return {
            "statusCode": 500,
            "message": 'Error: DB接続時にエラーが発生しました',
            "traceback": traceback.format_exc()
        }

    # テーブル名と問題番号からSQLを作成して投げる
    # (問題番号が範囲外なら終了)
    # SQLを実行する
    with conn.cursor() as cursor:
        # 指定したテーブルの件数を調べる
        sql = "SELECT count(*) FROM {0}".format(table)
        cursor.execute(sql)
        results = cursor.fetchall()
        for r in results:
            count = r['count(*)']

        # 問題番号が範囲外なら終了
        if (quiz_num < 1 or count < quiz_num):
            return {
                "statusCode":
                500,
                "message":
                'Error: {0}の問題番号は1~{1}の間で入力してください'.format(nickname, count)
            }

        sql = "SELECT quiz_num, quiz_sentense, answer, clear_count, fail_count, category, img_file FROM {0} WHERE quiz_num = {1}".format(
            table, quiz_num)
        cursor.execute(sql)

        # MySQLから帰ってきた結果を受け取る
        # Select結果を取り出す
        results = cursor.fetchall()

    # 結果をJSONに変形して返す
    return {"statusCode": 200, "result": results}
Beispiel #11
0
def answer_input(file_num,quiz_num,clear):
    """正解不正解データを受け取ってデータを登録する

    Args:
        answer_data (JSON): 解答データのJSON
            解答データは
            {
                "file_num": ファイル番号
                "quiz_num": 問題番号
                "clear": 正解ならTrue、不正解ならFalse
            }

    Returns:
        str: レコードのSQL、実行結果
    """

    # 結果
    result = ""

    # 設定ファイルを呼び出す
    table_list = get_table_list()

    # MySQL への接続を確立する
    try:
        conn = get_connection()
    except Exception as e:
        return {
            "statusCode": 500,
            "message": 'Error: DB接続時にエラーが発生しました',
            "traceback": traceback.format_exc()
        }
        
    try:
        # 設定ファイルを呼び出してファイル番号からテーブル名を取得
        # (変なファイル番号ならエラー終了)
        file_num = int(file_num)
        quiz_num = int(quiz_num)
        isclear = bool(clear)
        table = table_list[file_num]['name']
        nickname = table_list[file_num]['nickname']
    
        # テーブル名からSQLを作成して投げる
        with conn.cursor() as cursor:
            # 指定した問題の正解(不正解)数を取得する
            get_column_name = "clear_count" if isclear else "fail_count"
            sql = "SELECT " + get_column_name + " FROM {0} where quiz_num = {1}".format(table,quiz_num)
            cursor.execute(sql)
            results = cursor.fetchall()
            num = int(results[0][get_column_name])

            # 正解(不正解)数+1
            num += 1

            # SQL作成して更新する
            sql = "UPDATE {0} SET {1} = {2} WHERE quiz_num = {3}".format(table,get_column_name,num,quiz_num)
            cursor.execute(sql)

            # 結果を格納する
            result = "[" + nickname + "-" + str(quiz_num) + "]:" + ("正解" if isclear else "不正解") + " 登録OK"

        #全て成功したらコミット
        conn.commit()
        conn.close()

    # DB操作失敗時はロールバック
    except Exception as e:
        message = 'Error: DB接続時にエラーが発生しました '
        try:
            conn.rollback()
        except:
            message += '( ロールバックにも失敗しました )'
        finally:
            return {
                "statusCode": 500,
                "message": message,
                "traceback": traceback.format_exc()
            }

    # 結果を返す
    return {
        "statusCode": 200,
        "result": result
    }