比赛地址https://www.shiyanlou.com/contests/lou3/challenges
一、存储学习记录(Python+Sqlite+sqlalchemy)
介绍
我们开发了一个 Python 程序,通过 SQLAlchemy 向实验楼的 sqlite 数据库中写入用户,课程和学习记录数据。但这个程序在你的实验环境中无法运行,请修复其中的 bug,让程序可以正确执行。
解答步骤
1. 下载程序到指定位置:
wget http://labfile.oss.aliyuncs.com/contestlou3/studydemo.py
2. 运行程序
首次运行程序
python studydemo.py
提示缺少sqlalchemy包,我们先安装此包
3.安装sqlalchemy包
sudo pip sqlalchemy
再次运行程序
python studydemo.py
提示engine = create_engine(‘sqlite://shiyanlou.db’)语句中url非法,
4.修改程序
根据提示信息可知冒号后的斜杠数与后方路径有关,改为三个斜杠后继续运行
vi studydemo.py
错误提示表之间的relationship有问题,最简单的解决方法是将User和Course中的relationship语句直接注释掉,再次运行
5. 运行成功,提交结果
二、跟踪课程更新
介绍
我们开发了一个课程类 Course,存储课程名称,是否公开,实验数量信息。然后实现了一个训练营课程类 BootcampCourse,继承 Course 类,并增加价格信息,训练营课程默认公开。程序中创建了两个训练营课程,然后更新两个课程的实验数量和价格,最后与先前备份的课程信息进行对比输出。这个程序在你的实验环境中无法运行,请修复其中的 bug,让程序可以正确执行并返回预期的信息。
解答步骤
下载程序
wget http://labfile.oss.aliyuncs.com/contestlou3/coursedemo.py
运行程序
python coursedemo.py
错误提示:TypeError: super() argument 1 must be type, not classobj,
经搜索这是一个python2常见的问题,让父类继承object即可
修改程序
class Course:
改为
class Course(object):
再次运行
提示
TypeError:typename() takes exactly 1 argument(0 given)
发现父类info方法调用typename()方法缺少参数,我们将参数加上即可
print self.typename(), self.name
改为
print self.typename(self), self.name
再次运行程序
错误提示:
AttributeError: 'BootcampCourse' object has no attribute 'name'
发现子类构造函数__init__()中没有声明定义属性name,在其中添加以下代码
self.name = name
self.public = True
self.price = price
再次运行程序
错误提示:
TypeError: 'int' object is not callable
这里有两个问题存在,一是子类中没有声明定义属性lab_count,二是调用count方法出错,我们修改为以下所示代码
def __init__(self, name, lab_count, price):
self.name = name
self.lab_count = lab_count
self.public = True
self.price = price
def update(self, lab_count, price):
self.lab_count = lab_count
self.price = price
def info(self):
super(BootcampCourse, self).info()
print 'Lab count:', self.lab_count
print 'Public:', self.public
print 'Price:', self.price
再次运行程序,输出了结果,可以提交了
提交结果
提交以后发现没有通过,检查程序输出信息发现新数据和老数据是一模一样的,且都为新数据,程序中用到了copy.copy()进行数据拷贝,这个是浅拷贝,需要改为深拷贝,我们改为copy.deepcopy()即可。然后再进行提交。
虽然提交通过了,但是我发现每一门课程信息后多了一行None,
然后发现main中调用info函数时用了print,这个地方其实不需要print,直接调用即可,因为信息打印是在方法中进行的