Closed AngelLiang closed 6 years ago
首先不得不赞美作者几句,您的书籍和源码简直是棒极了!excellent!在闲暇时间阅读您的书籍,并配以github源码进行“食用”,感觉以前使用Flask编写项目时,一直紊乱的项目组织架构及代码设计思路逐渐理顺,恍然大悟的感觉油然而生,同时对您的钦佩之情也如滔滔江水绵延不绝。
当然,阅读您的源码时,遇到不太对劲的地方我会尝试修改或优化,然后提出来。如果无意让您感到吹毛求疵,还请见谅。
下面是这次的主题:「尽量使虚拟数据接近真实的数据」。当然,Faker生成的sentence和text都是毫无意义的,这个就无所谓了。我留意的是生成评论回复的虚拟数据。
Faker
先放上原始代码,位置在bluelog/fakes.py:
bluelog/fakes.py
def fake_comments(count=500): # ... # replies for i in range(salt): comment = Comment( author=fake.name(), email=fake.email(), site=fake.url(), body=fake.sentence(), timestamp=fake.date_time_this_year(), reviewed=True, replied=Comment.query.get(random.randint(1, Comment.query.count())), post=Post.query.get(random.randint(1, Post.query.count())) ) db.session.add(comment) db.session.commit()
以上代码功能上没有问题,但是不符合以下逻辑:
因此,对以上代码做了以下优化:
fake.date_time_between_dates()
def fake_comments(count=500): # ... # replies for i in range(salt): comment = Comment.query.get(random.randint(1, Comment.query.count())) reply = Comment( author=fake.name(), email=fake.email(), site=fake.url(), body=fake.sentence(), reviewed=True, # 确保回复的时间在评论的时间之后,并且不超过现在的时间 timestamp=fake.date_time_between_dates(comment.timestamp), replied=comment, # 关联评论 post=comment.post # 回复与评论是同一篇文章 ) db.session.add(reply) db.session.commit()
写到这里本来以为结束了。但转念一想似乎还有点问题:
fake.date_time_this_year()
关于第一点,同上面的修改方式一样了;
关于第二点,经过测试,我把本地时间调到2019年1月1日11点00分,生成的虚拟数据有的超过了该时间点,成了“未来的数据”。而且所有的虚拟数据的timestamp都集中在2019年1月1日,也不是很好。
经过我查阅相关资料,把fake.date_time_this_year()改为fake.past_datetime()就可以了,fake.past_datetime()默认是以一个月前的时间为起点随机生成时间,可以fake.past_datetime('-1y')这样调用,以一年前的时间为起点随机生成时间。
fake.past_datetime()
fake.past_datetime('-1y')
这样,需要修改的代码如下:
# ... def fake_posts(count=50): for i in range(count): post = Post( title=fake.sentence(), body=fake.text(2000), category=Category.query.get(random.randint(1, Category.query.count())), # timestamp=fake.date_time_this_year() # modify this timestamp=fake.past_datetime('-1y') ) db.session.add(post) db.session.commit() def fake_comments(count=500): for i in range(count): post = Post.query.get(random.randint(1, Post.query.count())) comment = Comment( author=fake.name(), email=fake.email(), site=fake.url(), body=fake.sentence(), # timestamp=fake.date_time_this_year(), # modify this timestamp=fake.date_time_between_dates(datetime_start=post.timestamp), reviewed=True, post=post ) db.session.add(comment) salt = int(count * 0.1) for i in range(salt): # unreviewed comments post = Post.query.get(random.randint(1, Post.query.count())) comment = Comment( author=fake.name(), email=fake.email(), site=fake.url(), body=fake.sentence(), # timestamp=fake.date_time_this_year(), # modify this timestamp=fake.date_time_between_dates(datetime_start=post.timestamp), reviewed=False, post=post ) db.session.add(comment) # from admin post = Post.query.get(random.randint(1, Post.query.count())) comment = Comment( author='Mima Kirigoe', email='mima@example.com', site='example.com', body=fake.sentence(), # timestamp=fake.date_time_this_year(), # modify this timestamp=fake.date_time_between_dates(datetime_start=post.timestamp), from_admin=True, reviewed=True, post=post ) db.session.add(comment) db.session.commit() # replies for i in range(salt): comment = Comment.query.get(random.randint(1, Comment.query.count())) reply = Comment( author=fake.name(), email=fake.email(), site=fake.url(), body=fake.sentence(), reviewed=True, # timestamp=fake.date_time_this_year(), # replied=Comment.query.get(random.randint(1, Comment.query.count())), # post=Post.query.get(random.randint(1, Post.query.count())) # 确保回复的时间在评论的时间之后,并且不超过现在的时间 timestamp=fake.date_time_between_dates(datetime_start=comment.timestamp), replied=comment, # 关联评论 post=comment.post # 回复与评论是同一篇文章 ) db.session.add(reply) db.session.commit() # ...
谢谢,很高兴你能认可这本书。如果有时间的话,欢迎在亚马逊或豆瓣写一个评价,帮助别人进一步了解这本书。
你说的提议很合理,不过我个人认为虚拟数据的主要目的只是用于展示或测试视觉效果,没必要花太多时间去追求内容逻辑的正确。在决定代码实现时,时间成本、需求相关性(必要性)和复杂度都是要纳入考虑的因素。
当然,你的改动的确让这个程序向“完美”更接近了一步,感谢你的反馈。我这几天有事,周三会把这个提议放到”可改进实现“里。如果方便的话,也可以尝试在“可改进实现文件”里修改并提交PR。
是的,从整个项目来看,我也是觉得设计重点及精力不应该放在虚拟数据这里。谢谢您的回复。
首先不得不赞美作者几句,您的书籍和源码简直是棒极了!excellent!在闲暇时间阅读您的书籍,并配以github源码进行“食用”,感觉以前使用Flask编写项目时,一直紊乱的项目组织架构及代码设计思路逐渐理顺,恍然大悟的感觉油然而生,同时对您的钦佩之情也如滔滔江水绵延不绝。
当然,阅读您的源码时,遇到不太对劲的地方我会尝试修改或优化,然后提出来。如果无意让您感到吹毛求疵,还请见谅。
下面是这次的主题:「尽量使虚拟数据接近真实的数据」。当然,
Faker
生成的sentence和text都是毫无意义的,这个就无所谓了。我留意的是生成评论回复的虚拟数据。先放上原始代码,位置在
bluelog/fakes.py
:以上代码功能上没有问题,但是不符合以下逻辑:
因此,对以上代码做了以下优化:
fake.date_time_between_dates()
确保评论回复在评论时间之后;写到这里本来以为结束了。但转念一想似乎还有点问题:
fake.date_time_this_year()
这个生成时间的方法,如果是在1月1日生成会不会有点问题。关于第一点,同上面的修改方式一样了;
关于第二点,经过测试,我把本地时间调到2019年1月1日11点00分,生成的虚拟数据有的超过了该时间点,成了“未来的数据”。而且所有的虚拟数据的timestamp都集中在2019年1月1日,也不是很好。
经过我查阅相关资料,把
fake.date_time_this_year()
改为fake.past_datetime()
就可以了,fake.past_datetime()
默认是以一个月前的时间为起点随机生成时间,可以fake.past_datetime('-1y')
这样调用,以一年前的时间为起点随机生成时间。这样,需要修改的代码如下: