自己学做网站,万全孔家庄做网站,莱芜二手房出售信息最新房源,做一网站要学些什么1#xff0e;实现投票功能#xff0c;2#xff0e;创建文章数据#xff0c;3#xff0e;对文章进行排序。
实现投票功能
实现投票功能#xff0c;要注重文章的时效性与投票的公平性#xff0c;所以需要给投票功能加上一些约束条件#xff1a;
文章发布满一个星期后实现投票功能2创建文章数据3对文章进行排序。
实现投票功能
实现投票功能要注重文章的时效性与投票的公平性所以需要给投票功能加上一些约束条件
文章发布满一个星期后不再允许用户对该文章投票一个用户对一篇文章只能投一次票
所以我们需要使用
一个有序集合 time存储文章的发布时间一个集合 voted:*存储已投票用户名单 其中 * 是被投票文章的 ID一个有序集合 score存储文章的得票数 ONE_WEEK_IN_SECONDS 7 * 24 * 60 * 60def article_vote(r, user_id, article_id):# 使用 time.time() 获取当前时间# 减去一周的秒数从而获取一周前的Unix时间cutoff time.time() - ONE_WEEK_IN_SECONDSif r.zscore(time, article_id) cutoff:returnif r.sadd(voted: article_id, user_id):r.zincrby(score, article_id, 1)
当用户尝试投票时使用 ZSCORE 命令读取 time 有序集合得到这篇文章的发布时间再判断文章的发布时间是否超过一周。ZSCORE 命令的语法如下
r.zscore(key, member)
key 是有序集合的键名member 是有序集合中的某个成员
若未超过则使用 SADD 命令尝试将用户追加到这篇文章的已投票用户名单中如果添加成功则说明该用户未投过票。SADD 命令的语法是
r.sadd(key, member)
key 是集合的键名member 是要添加进集合的元素
由于集合中的元素是唯一的所以sadd函数会根据member是否存在在集合中做出不同返回
若该元素不存在在集合中返回 True若该元素已存在在集合中返回 False
所以返回为 True 时使用 ZINCRBY 命令来为文章的投票数加 1。zincrby 函数语法如下
r.zincrby(key, member, increment)
key 是有序集合的键名member 是有序集合中要增加分值的成员increment 是要增加的分值
创建文章数据
现在系统中还缺少文章数据所以我们要提供一个创建文章的函数并把文章数据存储到 Redis 中。创建文章的步骤如下
创建新的文章 ID将文章作者加入到这篇文章的已投票用户名单中存储文章详细信息到 Redis 中将文章的发布时间和初始投票数加入到 time 和 score 两个有序集合中
def post_article(r, user, title, link):# 创建新的文章ID使用一个整数计数器对 article 键执行自增# 如果该键不存在article 的值会先被初始化为 0# 然后再执行自增命令article_id str(r.incr(article))voted voted: article_idr.sadd(voted, user)r.expire(voted, ONE_WEEK_IN_SECONDS)now time.time()article article: article_idr.hmset(article, {title: title,link: link,poster: user,})r.zadd(score, article_id, 1)r.zadd(time, article_id, now)return article_id
将文章作者加入已投票用户名单中和之前一样这里不再赘述但在这里我们需要为这个已投票用户名单设置一个过期时间让它在一周后到期后自动删除减少 Redis 的内存消耗。为键设置过期时间的命令是
r.expire(key, seconds)
key 要设置过期时间的键名seconds 过期时间的长度单位秒
这里我们要设置的时间是一周所以我们可以使用上面定义好的全局变量 ONE_WEEK_IN_SECONDS。
接下来要存储文章详细信息了前面介绍过 hset 可以执行单个字段域的设置这里我们使用 hmset 一次性设置多个字段域其语法如下
r.hmset(key, {field: value, [field: value ...]})
我们可以使用 Python 的散列来一次性存储多个字段域到 Redis只需要将整个散列当作 key 对应的值通过 hmset 函数设置进去就行。
最后将初始投票数和创建时间设置到 score 和 time 中都可以通过 ZADD 命令来实现
r.zadd(key, member, score)
key 有序集合的键名member 要加入有序集合的成员score 该成员的分值
这里需要注意的是因为该篇文章的作者已经被加入到该文章已投票用户名单中为了保持数据一致性我们需要将文章的初始投票数设为 1。
对文章进行排序
实现了文章投票和创建文章功能接下来我们就需要将评分最高的文章和最新发布的文章从 Redis 中取出了。 首先我们要根据排序方式的不同 按评分排序则从 score 有序集合中取出一定量的文章 IDscore有序集合存放文章ID和对应的投票数按时间排序则从 time 有序集合中取出一定量的文章 IDtime有序集合存放文章ID和对应的发布时间 构成一个有序文章信息列表每个元素都 使用 HGETALL 命令取出每篇文章的全部信息
def get_articles(r, start, end, orderscore):ids r.zrevrange(order, start, end)articles []for id in ids:article_data r.hgetall(id)article_data[id] idarticles.append(article_data)return articles
这里因为需要对有序集合进行排序所以我们在取出文章 ID 时需要使用到 ZREVRANGE 命令以分值从大到小的排序方式取出文章 ID。ZREVRANGE 命令的语法是
r.zrevrange(key, start, stop)
key 有序集合的键名start 开始的数组下标stop 结束的数组下标
得到多个文章 ID 后我们还需要根据每一个文章 ID 获取文章的全部信息这时就需要使用到 HGETALL 命令它的语法如下
r.hgetall(key)
key 哈希的键名
我们取出文章的全部信息后还为文章信息添加了一个字段 id。这是因为文章 ID 在 Redis 中是作为键名存储的不在值当中所以我们需要附加这个字段到文章信息中。
实现这些方法后我们大体实现了一个文章投票的后端处理逻辑能够为文章投票并能根据投票结果改变文章的排序情况。
编程要求
根据提示在右侧Begin-End区域补充代码完成简化版文章投票网站的后端处理逻辑 在 article_vote() 函数中 该方法作用是对文章投票参数说明 rRedis 客户端 user_id投票用户 article_id被投票文章 已提供一周前 Unix 时间戳存放在变量 cutoff当满足以下条件时为文章投一票 该文章发布不超过一周 该用户没有为该文章投过票 在 post_article() 函数中 该方法作用是创建文章参数说明 rRedis 客户端 user发布用户 title文章标题 link文章链接 已提供 article_id新文章 ID voted新文章已投票用户名单存储键名 article新文章详细信息存储键名 now文章创建时间 按照 ID 递增的顺序依次创建文章保证发布文章的用户不能给自己的文章投票文章在发布一周后删除已投票用户名单存储文章详细信息到 Redis 中包括字段 文章标题 文章链接 发布用户 存储文章的发布时间和初始投票数 初始投票数为 1 在 get_articles() 函数中 该方法作用是对文章进行排序参数说明 rRedis 客户端start从排序为 start 的文章开始获取 end到排序为 end 的文章结束获取 order排序方式分为两种 time按时间排序score按投票数排序 已提供文章信息空列表articles 实现按时间/投票数排序 将排序后的文章及其全部信息组成一个列表 按照不同排序规则取出排序在参数提供的区间范围内的文章及每篇文章的全部信息包括文章 ID #!/usr/bin/env python
#-*- coding:utf-8 -*-
import time
ONE_WEEK_IN_SECONDS 7 * 24 * 60 * 60
def article_vote(r, user_id, article_id):cutoff time.time() - ONE_WEEK_IN_SECONDS# 请在下面完成要求的功能#********* Begin *********#if r.zscore(time, article_id) cutoff:returnif r.sadd(voted: article_id, user_id):r.zincrby(score, article_id, 1)#********* End *********#
def post_article(r, user, title, link):article_id str(r.incr(article))voted voted: article_idnow time.time()article article: article_id# 请在下面完成要求的功能#********* Begin *********#r.sadd(voted, user)r.expire(voted, ONE_WEEK_IN_SECONDS)r.hmset(article, {title: title,link: link,poster: user,})r.zadd(score, article_id, 1)r.zadd(time, article_id, now)#********* End *********#return article_id
def get_articles(r, start, end, orderscore):articles []# 请在下面完成要求的功能#********* Begin *********#ids r.zrevrange(order, start, end)for id in ids:article_data r.hgetall(id)article_data[id] idarticles.append(article_data)#********* End *********#return articles