python 分类 投票_使用python+redis实现文章发布,投票,分组排名功能

本文介绍了如何使用Python和Redis构建一个投票网站,包括文章发布、投票功能,以及根据文章发布时间和票数计算评分的逻辑。文章在获得至少200张支持票后会被视为受欢迎,进入首页推荐前100位展示。同时,文章的评分会随时间递减,一周后无法再投票。代码示例展示了发布文章、投票、计算评分、获取文章等功能的实现。
摘要由CSDN通过智能技术生成

1.逻辑

实例来源于<>这本书。

构建一个投票网站,为这个网站设置一些数值和限制条件:如果一篇文章获得至少200张支持票,那么网站就认为这篇文章是用户喜欢的文章;假如这个网站发布1000篇文章,而其中50篇符合网站对有趣文章的要求,那么网站要把这50篇网站放到首页推荐前100位至少一天。为了产生一个能够随时间流逝而不断减少的评分,程序需要根据文章的发布时间和当前的时间来计算文章的评分,具体计算方法:将文章得到的支持票数乘以一个常量,然后加上文章的发布时间,得出的结果就是文章的评分。

文章发布时间使用Unix时间戳表示,计算评分时, 与支持票数量相乘的变量为432,这个常量是通过将一天的秒数(86400)除以文章展示一天所需的票数(200)得出的,文章没获得一张支持票,程序就需将文章的评分增加432分。

2.实现代码

#-*- coding: UTF-8 -*-

import redis

import time

ONE_WEEK_IN_SECONDS = 604800

VOTE_SCORE = 240.00

pool = redis.ConnectionPool(host = "127.0.0.1", port = 6379, password = '')

redis = redis.Redis(connection_pool = pool)

#发布文章

def post(articleData, redis = redis):

articleId = str(redis.incr('article:'))

'#保存文章'

article = 'article:' + articleId

redis.hmset(article, mapping = articleData)

'#将文章与发布时间通过一个有序集合进行关联'

redis.zadd('time',article, articleData['time'])

'#为自己投初始票'

vote(article, articleData['poster'])

'修改文章评分'

score(article, redis)

return article

#为文章投票

def vote(article, user, redis = redis):

global ONE_WEEK_IN_SECONDS

'#投票,和用户绑定'

voted = 'voted:' + article.partition(':')[-1]

articleData = redis.hgetall(article)

postTime = redis.zscore('time', article);

#一周之前的文章不能投票

tempTime = time.time() - ONE_WEEK_IN_SECONDS;

if postTime and postTime <= tempTime:

return False

#一个用户只能投一票,判断用户是否已经投过

if (redis.sismember(voted, user)):

return False

redis.sadd(voted, articleData[b'poster'])

redis.expire(voted, ONE_WEEK_IN_SECONDS)

#更新章的评分

def score(article, redis = redis):

global VOTE_SCORE

'#将文章与评分通过一个有序集合进行关联'

redis.zincrby('score', article, VOTE_SCORE)

redis.hincrby(article, 'votes', 1)

#按特定的方式(发布时间,评分)降序取出文章

def get_articles(order, page = 1, limit = 25, redis = redis):

start = (page - 1) * limit

end = start + limit - 1

articleIds = redis.zrange(order, start, end, desc = True)

articleList = {};

for id in articleIds:

articleData = redis.hgetall(id)

articleData['id'] = id

articleList[id] = articleData

return articleList

#设置,移除文章分组

def add_remove_group(article, add = [], remove = [], redis = redis):

for group in add:

groupKey = 'group:' + group

redis.sadd(groupKey, article)

for group in remove:

redis.srem(groupKey, article)

#按评分或时间排名取出分组下的文章

def get_group_articles(group, order, page = 25, limit = 25, redis = redis):

key = order + group

if (not redis.exists(key)):

redis.zinterstore(key,

['group:' + group, order],

aggregate = 'max'

)

redis.expire(key, 5)

return get_articles(key, page, limit)

3.发布文章

调用

article = post(articleData)

articleId = article.partition(':')[-1]

add_remove_group(article, add = ['redis'])

#获取文章

print('----------------------------------Article ID------------------------------')

print(articleId)

#获取文章

print('----------------------------------Article------------------------------')

print(redis.hgetall(article))

#获取文章发布时间

print('----------------------------------Voted Users------------------------------')

print(redis.smembers('voted:' + articleId))

#获取所有文章评分,并且按照分数排名

print('----------------------------------Rank------------------------------')

print(redis.zrange('score', 0, -1, desc=True, withscores=True))

#获取所有文章发布时间

print('----------------------------------Post Time------------------------------')

print(redis.zrange('time', 0, -1, desc=True, withscores=True))

输出结果

88

----------------------------------Article------------------------------

{b'poster': b'user:001', b'title': b'Ptython', b'content': b'hello world', b'votes': b'1', b'time': b'1596951581.718217'}

----------------------------------Voted Users------------------------------

{b'user:001'}

----------------------------------Rank------------------------------

[(b'article:87', 1596951443.171613), (b'article:86', 1596951389.8698218), (b'article:85', 1596951275.8035266), (b'article:84', 1596951174.1960804), (b'article:83', 1596951071.6917884), (b'article:10', 1596816080.909939), (b'article:9', 1596816058.8451862), (b'article:8', 1596816047.3071418), (b'article:7', 1596816011.8706625), (b'article:6', 1596815930.085024), (b'article:5', 1596815917.6721313), (b'article:4', 1596815862.928912), (b'article:3', 1596815838.7520182), (b'article:2', 1596814204.1336813), (b'article:1', 1596813938.6256502), (b'article:88', 240.0)]

----------------------------------Post Time------------------------------

[(b'article:88', 1596951581.718217), (b'article:87', 1596951203.171613), (b'article:86', 1596951149.8698218), (b'article:85', 1596951035.8035266), (b'article:84', 1596950934.1960804), (b'article:83', 1596950831.6917884), (b'article:82', 1596950758.6923993), (b'article:81', 1596950643.6892672), (b'article:80', 1596950633.143089), (b'article:10', 1596815840.909939), (b'article:9', 1596815818.8451862), (b'article:8', 1596815807.3071418), (b'article:7', 1596815771.8706625), (b'article:6', 1596815690.085024), (b'article:5', 1596815677.6721313), (b'article:4', 1596815622.928912), (b'article:3', 1596815598.7520182), (b'article:2', 1596813964.1336813), (b'article:1', 1596813698.6256502)]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值