在MYSQL中存储3个值

时间:2015-12-12 15:56:16

标签: python mysql

我的问题是,我已经创建了一个数学测验,会向用户提出10个随机问题,然后它会在最后输出10分。我已经完成了这项任务的艺术,但我在最后一部分中挣扎最后一部分是我需要创建一些东西来存储每个用户的最后3个分数。我决定使用mysql但我的代码只允许我为每个用户存储1分。我使用python 3.4。这是代码

import random
import operator
import mysql.connector
cnx = mysql.connector.connect(user='root', password='password',
                             host='localhost',
                             database='mydb')

cursor = cnx.cursor()


ID = input("what is your ID?")


OPERATIONS = [
    (operator.add, "+"),
    (operator.mul, "x"),
    (operator.sub, "-")
    ]

NB_QUESTIONS = 10

def get_int_input(prompt=''):
    while True:
      try:
        return int(input(prompt))
      except ValueError:
        print("Sorry,but we need a number")

if __name__ == '__main__':
   name = input("What is your name?").title()
   Class=input("Which class do you wish to input results for 1,2 or 3?")                       
   print(name, ", Welcome to the Maths Test")

    score = 0
    for _ in range(NB_QUESTIONS):
        num1 = random.randint(1,10)
        num2 = random.randint(1,10)
        op, symbol = random.choice(OPERATIONS)
        print("What is", num1, symbol, num2)
        if get_int_input() == op(num1, num2):
            print("Correct")
            score += 1
        else:
            print("Incorrect")

print("Well done", name, "you scored", score, "/", NB_QUESTIONS)

print ("Thank you for doing this mathamatical quiz , goodbye ")


if "ID" in "Class1":
    if "score"  in "Score1":
        add_record = ("INSERT INTO Class1"
                      "(Score2)"
                      "VALUES(%s)")
        data_record = (score)


    if  "score"   in "Score2":
        add_record = ("INSERT INTO Class1"
                    "(Score3)"
                    "VALUES(%s)")
        data_record = (score)

    else:
        add_record = ("INSERT INTO Class1"
                     "(ID, Name, Score1) "
                      "VALUES (%s, %s, %s)")
        data_record = (ID, name, score)

cursor.execute(add_record, data_record)
cnx.commit()

cursor.close()
cnx.close()

在我的数据库中,我有列ID,名称,得分1,得分2,得分3 当我完成测验时,分数,名称和ID将被输入到表中。但是一旦具有相同ID的用户进行测验就会出现错误。我希望代码为每个用户存储3个分数但是有错误。错误是:

cursor.execute(add_record,data_record) NameError:name' add_record'未定义

感谢您阅读本文,也感谢您的帮助。我期待听到回复。

2 个答案:

答案 0 :(得分:0)

好的,我们将以最小的步骤逐步完成我的解决方案,以达到您的解决方案。注意:单个文件中的所有代码都适合我。

  

首先,我从Python在数据库中创建一个表。我不确定为什么你的平均列是INT类型,所以我改变了。另外,为简单起见,我的ID是INT。

import mysql.connector
cnx = mysql.connector.connect(user='root', password='password',
                             host='localhost',
                             database='mydb')
cursor = cnx.cursor()
# cursor.execute("DROP TABLE IF EXISTS Class1")
cursor.execute('''
    CREATE TABLE IF NOT EXISTS Class1
    ( ID INT PRIMARY KEY
    , Name VARCHAR(10) NOT NULL
    , Score1 INT
    , Score2 INT
    , Score3 INT
    , Average DECIMAL(9, 5)
    );
''')
cnx.commit()
  

接下来,我创建一个User类,以便保存所有重要信息,并包含转到&来自数据库。这样,您只需要单个User对象和单个方法即可。这种方法比您的多个INSERT查询更受欢迎。

class User:
    def __init__(self, _id, name, score1=None, score2=None, score3=None):
        self._id = _id
        self.name = name
        self.score1 = score1
        self.score2 = score2
        self.score3 = score3

    ''' set the score of the given or next available class '''
    def add_score(self, score, Class=None):
        if not Class or (Class < 0 or Class > 3):
            if all((self.score1, self.score2, self.score3)):
                return # can't update
            elif all((self.score1, self.score2)):
                Class = 3
            elif self.score1:
                Class = 2
            else:
                Class = 1

        if Class and 0 < Class <= 3: # if a position is given and valid
            setattr(self, 'score' + str(Class), score)

    def to_tuple(self):
        return (self._id, self.name, self.score1, self.score2, self.score3)

    ''' make it possible to see this object when printed '''
    def __repr__(self):
        return self.__class__.__name__+ str(self.to_tuple())

    ''' insert or update this user object in the database '''
    def insert_to_db(self, db):
        crsr = db.cursor()
        data = list(self.to_tuple())
        data.append(self.get_average_score())
        if User.get_by_id(self._id):
            data = data[1:]
            data.append(self._id)
            crsr.execute('''
                UPDATE Class1 SET
                    Name = %s,
                    Score1 = %s,
                    Score2 = %s,
                    Score3 = %s,
                    Average = %s
                WHERE ID = %s;
            ''', data)
        else:
            crsr.execute("INSERT INTO Class1 VALUES (%s,%s,%s,%s,%s,%s)", data)
        db.commit()
        crsr.close()

    @staticmethod
    def get_by_id(_id):
        cursor.execute("SELECT * FROM Class1 WHERE ID = %s", [_id])
        row = cursor.fetchone()
        return User.from_tuple(row)

    @staticmethod
    def get_by_name(name):
        cursor.execute("SELECT * FROM Class1 WHERE Name = %s", [name])
        row = cursor.fetchone()
        return User.from_tuple(row)

    ''' Get the average score from the object. No need to query the database '''
    def get_average_score(self):
        from statistics import mean
        scores = list(self.to_tuple())[2:4]
        scores = list(filter(None.__ne__, scores))
        return mean(scores) if len(scores) > 0 else 0

    @staticmethod
    def from_tuple(tup, min_elems=2, max_elems=6):
        user = None
        if tup:
            num_elems = len(tup)
            if num_elems < min_elems or num_elems > max_elems:
                raise Exception('invalid tuple given', tup)
            # know there is at least 2 elements here
            user = User(tup[0], tup[1])
            if num_elems >= 3:
                user.score1 = tup[2]
            if num_elems >= 4:
                user.score2 = tup[3]
            if num_elems >= 5:
                user.score3 = tup[4]
        return user

    @staticmethod
    def from_cursor(cursor):
        if cursor:
            return (User.from_tuple(row) for row in cursor.fetchall())
        return iter(()) # Return empty generator if cursor == None
  

接下来,定义一个测验方法,该方法返回参加测验的人的分数和名称。参数是可选的,并具有默认值。定义许多小方法以测试代码和逻辑是一个好习惯。

def quiz(num_questions=10, name=None):
    if not name:
        name = input("Enter your name: ").title()
    print(name, ", Welcome to the Maths Test")

    score = 0
    for _ in range(num_questions):
        num1 = random.randint(1,10)
        num2 = random.randint(1,10)
        op, symbol = random.choice(OPERATIONS)
        print("What is", num1, symbol, num2)
        if get_int_input() == op(num1, num2):
            print("Correct")
            score += 1
        else:
            print("Incorrect")
    return name, score
  

最后(和你的其他方法一起),这是将与程序一起运行的主要方法。这会提示输入ID,尝试在数据库中找到它,然后对现有用户进行测验并更新其分数,或者创建新用户,然后将用户插入数据库。

def main():
    user_id = get_int_input("Enter your ID: ")
    Class = get_int_input("Which class do you wish to input results for 1, 2, or 3? ")
    user = User.get_by_id(user_id)
    if not user:
        print("User with id %d not found" % user_id)
        print("Creating new user")
        name, score = quiz(NB_QUESTIONS)
        user = User(user_id, name)
    else:
        print("Found user %s" % user.name)
        _, score = quiz(NB_QUESTIONS, user)

    user.add_score(score, Class)
    print("\nWell done", user.name, "you scored", score, "/", NB_QUESTIONS)
    print("Thank you for doing this mathamatical quiz , goodbye ")

    user.insert_to_db(cnx) # Remember to update the user in the database
    cnx.close()

if __name__ == '__main__':
    main()

答案 1 :(得分:0)

如果“Class1”中的“ID”:

if "score"  in "Score1":
    add_record = ("INSERT INTO Class1"
                  "(Score2)"
                  "VALUES(%s)")
    data_record = (score)

if  "score"   in "Score2":
    add_record = ("INSERT INTO Class1"
                "(Score3)"
                "VALUES(%s)")
    data_record = (score)

else:
    add_record = ("INSERT INTO Class1"
                 "(ID, Name, Score1) "
                  "VALUES (%s, %s, %s)")
    data_record = (ID, name, score)
    cursor.execute(add_record, data_record)
    cnx.commit()

cursor.close() cnx.close()