使用Redis构建简单的社交网站

news2024/11/15 19:54:31

文章目录

  • 第1关:创建用户与动态
  • 第2关:处理用户关系
  • 第3关:状态与信息流


第1关:创建用户与动态

编程要求
在Begin-End区域编写 create_user(login_name, real_name) 函数,实现创建新用户的功能,具体参数与要求如下:

方法参数login_name为用户登录名,real_name为用户真名;
用户登录名预处理的实现:将用户登录名转换成全小写格式;
重名检测的实现:查询哈希键users中是否存在与用户登录名同名的域,若存在,则不允许重新创建该用户,返回None;
分配用户编号的实现:对计数器user:id递增1,并将递增后的值作为新用户的编号;
存储用户信息的实现:使用事务一次性提交:
存储登录名的实现:将用户登录名记录到哈希键users当中,值为该用户编号;
存储详情的实现:按照如下示意将用户信息存储到哈希键user:{id}中:

返回创建结果的实现:返回新创建用户的编号。
编写 create_post(uid, content) 函数,实现创建新动态的功能,具体参数与要求如下:

方法参数uid为发布动态的用户编号,content为要发布的动态内容;
用户合法性检测的实现:查找用户编号对应详情信息哈希user:{uid}是否存在login_name域,若存在,则记录,若不存在,则不允许创建新动态,返回None;
分配动态编号的实现:对计数器post:id递增1,并将递增后的值作为新动态的编号;
存储动态信息的实现:按照如下示意将动态信息存储到哈希键post:{id}中:

更新用户动态数的实现:为该用户编号对应的详情信息哈希user:{uid}中的posts域的值加1;
返回创建结果的实现:返回新创建动态的编号。
测试说明
平台会对你编写的代码进行测试:

测试输入:无;
预期输出:

测试 create_user 方法…
第一次创建登录名为 TestUser 的用户
创建的用户ID为: 1
当前分配的用户ID为: 1
创建的用户信息为: {‘login_name’: ‘testuser’, ‘posts’: ‘0’, ‘real_name’: ‘Test User’, ‘followers’: ‘0’, ‘following’: ‘0’, ‘id’: ‘1’}
第二次创建登录名为 TestUser 的用户
创建的用户ID为: None
当前分配的用户ID为: 1
测试 create_post 方法…
为用户 1 创建一条动态
创建的动态ID为: 1
当前分配的动态ID为: 1
创建的动态信息为: {‘content’: ‘First POST!’, ‘uid’: ‘1’, ‘user_name’: ‘testuser’, ‘id’: ‘1’}
对应用户信息中更新为: {‘login_name’: ‘testuser’, ‘posts’: ‘1’, ‘real_name’: ‘Test User’, ‘followers’: ‘0’, ‘following’: ‘0’, ‘id’: ‘1’}
为不存在的用户 9 创建一条动态
创建的动态ID为: None
开始你的任务吧,祝你成功!

#!/usr/bin/env python
#-*- coding:utf-8 -*-

import re
import time
import redis

conn = redis.Redis()

# 创建新用户
def create_user(login_name, real_name):
    # 请在下面完成要求的功能
    #********* Begin *********#
    login_name = login_name.lower()
    if conn.hget("users", login_name):
        return None

    uid = conn.incr("user:id")
    pipe = conn.pipeline(True)
    pipe.hset("users", login_name, uid)
    pipe.hmset("user:%i"%(uid), {
        'login_name': login_name,
        'id': uid,
        'real_name': real_name,
        'followers': 0,
        'following': 0,
        'posts': 0,
        'last_signup': time.time(),
    })
    pipe.execute()

    return uid
    #********* End *********#

# 为用户创建新动态
def create_post(uid, content):
    # 请在下面完成要求的功能
    #********* Begin *********#
    pipe = conn.pipeline(True)
    pipe.hget("user:%i"%(uid), 'login_name')
    pipe.incr("post:id")
    login_name, pid = pipe.execute()

    if not login_name:
        return None

    pipe.hmset("post:%i"%(pid), {
        'id': pid,
        'uid': uid,
        'content': content,
        'posted': time.time(),
        'user_name': login_name,
    })
    pipe.hincrby("user:%i"%(uid), 'posts')
    pipe.execute()

    return pid
    #********* End *********#

在这里插入图片描述

第2关:处理用户关系

编程要求
在Begin-End区域编写 follow(uid, other_uid) 函数,实现关注用户的功能,具体参数与要求如下:

方法参数uid为当前用户编号,other_uid为被关注的用户编号;
避免重复关注的实现:如果被关注的用户编号已经在当前用户的关注列表following:{uid}中,则不重复关注,直接返回None;
建立关注关系的实现:使用事务一次性提交:
将被关注的用户编号加入到当前用户的关注列表following:{uid}中,分值为当前时间戳。
将当前用户编号加入到被关注用户的粉丝列表中followers:{other_uid},分值为当前时间戳。
修改统计数据的实现:若关系建立成功,则使用事务一次性提交:
将当前用户详情user:{uid}中的关注数following加1
将被关注用户详情user:{other_uid}中的粉丝数followers加1
返回执行结果的实现:返回True
编写 unfollow(uid, other_uid) 函数,实现取消关注的功能,具体参数与要求如下:

方法参数uid为当前用户编号,other_uid为被取消关注的用户编号;
避免重复取消关注的实现:如果被关注的用户编号已经不在当前用户的关注列表following:{uid}中,则不重复取消关注,直接返回None;
删除关注关系的实现:使用事务一次性提交:
从当前用户的关注列表following:{uid}中移除被取消关注用户编号。
从被取消关注用户的粉丝列表中followers:{other_uid}移除当前用户编号。
修改统计数据的实现:若关系删除成功,则使用事务一次性提交:
将当前用户详情user:{uid}中的关注数following减1
将被取消关注用户详情user:{other_uid}中的粉丝数followers减1
返回执行结果的实现:返回True
注意:
关注列表和粉丝列表均为有序集合,存储成员时,分值均为当前时间戳;
用户详情为上一关中创建的哈希结构。

测试说明
平台会对你编写的代码进行测试:

测试输入:

9
4
预期输出:

测试 follow 方法…
用户 9 关注 用户 4
关注结果: True
用户 9 的关注列表内容为: [‘4’]
用户 4 的粉丝列表内容为: [‘9’]
用户 9 的用户详情为: {‘login_name’: ‘test_user9’, ‘posts’: ‘0’, ‘real_name’: ‘Test user9’, ‘followers’: ‘0’, ‘following’: ‘1’, ‘id’: ‘9’}
用户 4 的用户详情为: {‘login_name’: ‘test_user4’, ‘posts’: ‘0’, ‘real_name’: ‘Test user4’, ‘followers’: ‘1’, ‘following’: ‘0’, ‘id’: ‘4’}
用户 9 再次关注 用户 4
关注结果: None
测试 unfollow 方法…
用户 9 取消关注 用户 4
取消关注结果: True
用户 9 的关注列表内容为: []
用户 4 的粉丝列表内容为: []
用户 9 的用户详情为: {‘login_name’: ‘test_user9’, ‘posts’: ‘0’, ‘real_name’: ‘Test user9’, ‘followers’: ‘0’, ‘following’: ‘0’, ‘id’: ‘9’}
用户 4 的用户详情为: {‘login_name’: ‘test_user4’, ‘posts’: ‘0’, ‘real_name’: ‘Test user4’, ‘followers’: ‘0’, ‘following’: ‘0’, ‘id’: ‘4’}
用户 9 再次取消关注 用户 4
取消关注结果: None
开始你的任务吧,祝你成功!

#!/usr/bin/env python
#-*- coding:utf-8 -*-

import re
import time
import redis

conn = redis.Redis()

# 关注用户
def follow(uid, other_uid):
    # 请在下面完成要求的功能
    #********* Begin *********#
    fkey1 = "following:%s"%(uid)
    fkey2 = "followers:%s"%(other_uid)

    if conn.zscore(fkey1, other_uid):
        return None

    now = time.time()
    pipe = conn.pipeline(True)
    pipe.zadd(fkey1, other_uid, now)
    pipe.zadd(fkey2, uid, now)
    following, followers = pipe.execute()

    pipe.hincrby("user:%s"%(uid), 'following', int(following))
    pipe.hincrby("user:%s"%(other_uid), 'followers', int(followers))
    pipe.execute()

    return True
    #********* End *********#

# 取消关注
def unfollow(uid, other_uid):
    # 请在下面完成要求的功能
    #********* Begin *********#
    fkey1 = "following:%s"%(uid)
    fkey2 = "followers:%s"%(other_uid)

    if not conn.zscore(fkey1, other_uid):
        return None

    pipe = conn.pipeline(True)
    pipe.zrem(fkey1, other_uid)
    pipe.zrem(fkey2, uid)
    following, followers = pipe.execute()

    pipe.hincrby("user:%s"%(uid), 'following', -int(following))
    pipe.hincrby("user:%s"%(other_uid), 'followers', -int(followers))
    pipe.execute()

    return True
    #********* End *********#

# 创建新用户
def create_user(login_name, real_name):
    login_name = login_name.lower()
    if conn.hget("users", login_name):
        return None

    uid = conn.incr("user:id")
    pipe = conn.pipeline(True)
    pipe.hset("users", login_name, uid)
    pipe.hmset("user:%i"%(uid), {
        'login_name': login_name,
        'id': uid,
        'real_name': real_name,
        'followers': 0,
        'following': 0,
        'posts': 0,
        'last_signup': time.time(),
    })
    pipe.execute()

    return uid

# 为用户创建新动态
def create_post(uid, content):
    pipe = conn.pipeline(True)
    pipe.hget("user:%i"%(uid), 'login_name')
    pipe.incr("post:id")
    login_name, pid = pipe.execute()

    if not login_name:
        return None

    pipe.hmset("post:%i"%(pid), {
        'id': pid,
        'uid': uid,
        'content': content,
        'posted': time.time(),
        'user_name': login_name,
    })
    pipe.hincrby("user:%i"%(uid), 'posts')
    pipe.execute()

    return pid

在这里插入图片描述

第3关:状态与信息流

编程要求
在Begin-End区域编写 get_home_timeline(uid) 函数,实现获得主页时间线的功能,具体参数与要求如下:

方法参数uid为要获取主页时间线的用户编号;
获取动态编号的实现:从存储用户主页时间线的有序集合home:{uid}中按照分值递减的顺序取出所有成员;
获取动态详情的实现:遍历动态编号,使用事务一次性获取每个动态编号对应动态详情哈希键post:{pid}的所有域-值对;
返回主页时间线的实现:返回事务执行的结果。
编写 post(uid, content) 函数,实现发布动态并将动态推送给粉丝的功能,具体参数与要求如下:

方法参数uid为要发布动态的用户编号,content为要发布的动态内容;
发布动态的实现:调用第一关中实现的create_post方法,并接收返回的动态编号,若发布失败,则取消发布,返回None;
获取发布时间的实现:从新发布的动态编号对应的动态详情哈希键post:{pid}中获取posted域;
更新个人主页的实现:将新发布的动态编号存储到个人主页有序集合键profile:{uid}中,分值为转为浮点数后的发布时间;
更新粉丝主页时间线的实现:遍历用户的粉丝列表followers:{uid},将新发布的动态编号存储到每个粉丝的主页时间线的有序集合home:{follower_id}中,分值为转为浮点数后的发布时间;
返回发布结果的实现:返回新发布的动态编号。
测试说明
平台会对你编写的代码进行测试:

测试输入:4;
预期输出:

用户 4 关注 用户 1
关注结果: True
测试 post 方法…
创建动态: 1
创建动态: 2
用户 1 的动态列表: [‘2’, ‘1’]
用户 4 的主页时间线动态编号: [‘2’, ‘1’]
测试 get_home_timeline 方法…
用户 4 的主页时间线: [{‘content’: ‘NEW post from user 1!!!’, ‘uid’: ‘1’, ‘user_name’: ‘test_user1’, ‘id’: ‘2’}, {‘content’: ‘This is the first post from user 1’, ‘uid’: ‘1’, ‘user_name’: ‘test_user1’, ‘id’: ‘1’}]
开始你的任务吧,祝你成功!

#!/usr/bin/env python
#-*- coding:utf-8 -*-

import re
import time
import redis

conn = redis.Redis()

# 获得主页时间线
def get_home_timeline(uid, page=1, count=30):
    # 请在下面完成要求的功能
    #********* Begin *********#
    post_ids = conn.zrevrange("home:%s"%(uid), 0, -1)

    pipe = conn.pipeline(True)
    for pid in post_ids:
        pipe.hgetall("post:%s"%(pid))

    return pipe.execute()
    #********* End *********#

# 发布动态并将动态推送给粉丝
def post(uid, content):
    # 请在下面完成要求的功能
    #********* Begin *********#
    pid = create_post(uid, content)
    if not pid:
        return None

    posted = conn.hget("post:%s"%(pid), "posted")
    conn.zadd("profile:%s"%(uid), pid, float(posted))
    followers = conn.zrange("followers:%s"%(uid), 0, -1)

    pipe = conn.pipeline(False)
    for follower in followers:
        pipe.zadd("home:%s"%(follower), pid, float(posted))
    pipe.execute()

    return pid
    #********* End *********#

# 关注用户
def follow(uid, other_uid):
    fkey1 = "following:%s"%(uid)
    fkey2 = "followers:%s"%(other_uid)

    if conn.zscore(fkey1, other_uid):
        return None

    now = time.time()
    pipe = conn.pipeline(True)
    pipe.zadd(fkey1, other_uid, now)
    pipe.zadd(fkey2, uid, now)
    following, followers = pipe.execute()

    posts = conn.zrevrange("profile:%s"%(other_uid), 0, 100, withscores=True)
    if posts:
        pipe.zadd("home:%s"%(uid), **dict(posts))

    pipe.hincrby("user:%s"%(uid), 'following', int(following))
    pipe.hincrby("user:%s"%(other_uid), 'followers', int(followers))
    pipe.execute()

    return True

# 取消关注
def unfollow(uid, other_uid):
    fkey1 = "following:%s"%(uid)
    fkey2 = "followers:%s"%(other_uid)

    if not conn.zscore(fkey1, other_uid):
        return None

    pipe = conn.pipeline(True)
    pipe.zrem(fkey1, other_uid)
    pipe.zrem(fkey2, uid)
    following, followers = pipe.execute()

    posts = conn.zrevrange("profile:%s"%(other_uid), 0, -1)
    if posts:
        pipe.zrem("home:%s"%(uid), *posts)

    pipe.hincrby("user:%s"%(uid), 'following', -int(following))
    pipe.hincrby("user:%s"%(other_uid), 'followers', -int(followers))
    pipe.execute()

    return True

# 创建新用户
def create_user(login_name, real_name):
    login_name = login_name.lower()
    if conn.hget("users", login_name):
        return None

    uid = conn.incr("user:id")
    pipe = conn.pipeline(True)
    pipe.hset("users", login_name, uid)
    pipe.hmset("user:%i"%(uid), {
        'login_name': login_name,
        'id': uid,
        'real_name': real_name,
        'followers': 0,
        'following': 0,
        'posts': 0,
        'last_signup': time.time(),
    })
    pipe.execute()

    return uid

# 为用户创建新动态
def create_post(uid, content):
    pipe = conn.pipeline(True)
    pipe.hget("user:%i"%(uid), 'login_name')
    pipe.incr("post:id")
    login_name, pid = pipe.execute()

    if not login_name:
        return None

    pipe.hmset("post:%i"%(pid), {
        'id': pid,
        'uid': uid,
        'content': content,
        'posted': time.time(),
        'user_name': login_name,
    })
    pipe.hincrby("user:%i"%(uid), 'posts')
    pipe.execute()

    return pid


在这里插入图片描述


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1315426.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

添加E1000网卡进行测试,只有VMXNET3性能的四分之一

正文共:1444 字 14 图,预估阅读时间:2 分钟 我们前面介绍了VMware ESXi 6.7中的适配器类型性能(VMWare ESXi中,不同的虚拟网卡性能竟然能相差三倍!),当时的配置项主要为E1000e和VMXN…

格式化Echarts的X轴显示,设置显示间隔

业务需求:x轴间隔4个显示,并且末尾显示23时 x轴为写死的0时-23时,使用Array.from data: Array.from({ length: 24 }).map((_, i) > ${i}时) 需要在axisLabel 里使用 interval: 0, // 强制显示所有刻度标签,然后通过 formatter …

Java集合(六)Hashtable、ConcurrentHashMap

文章目录 Hashtable一、Hashtable介绍1.1 Hashtable是什么1.2 Hashtable特点1.3 Hashtable常见方法 二、Hashtable源码分析2.1 节点2.2 构造方法2.3 获取元素2.4 存入元素2.5 判断是否包含某个key/value2.6 替换元素2.7 删除元素2.8 获取value集合2.9 哈希2.10 扩容 Concurrent…

ADUM1200ARZ数字隔离器:重新定义技术标准

ADUM1200ARZ数字隔离器成为技术进步领域的关键组件。其创新设计和多方面功能重新定义了数字隔离技术的格局,提供了满足不同工业需求的众多功能。让我们通过本文直观的了解ADUM1200ARZ的功能与技术标准。 窄体且符合ROHS:设定新基准 该数字隔离器采用窄体…

HNU-数据库系统-实验2-数据库安全性/完整性定义与检查

数据库系统 课程实验2数据库安全性/完整性定义与检查 计科210X 甘晴void 202108010XXX 目录 文章目录 数据库系统 课程实验2<br>数据库安全性/完整性定义与检查实验目的实验环境实验内容2.1数据库安全性2.1.1 自主存取控制实验1&#xff09;实验内容与要求2&#xff0…

verilog语法进阶-分布式ram原语

概述 官方提供的原语 RAM16X1S_1 #(.INIT(16h0000) // Initial contents of RAM) RAM16X1S_1_inst (.O(O), // RAM output.A0(A0), // RAM address[0] input.A1(A1), // RAM address[1] input.A2(A2), // RAM address[2] input.A3(A3), // RAM address[3…

数据结构-迷宫问题

文章目录 1、题目描述2、题目分析3、代码实现 1、题目描述 题目链接&#xff1a;迷宫问题 、 注意不能斜着走&#xff01; 2、题目分析 &#xff08;1&#xff09;0为可以走&#xff0c;1不能走且只有唯一一条通路 &#xff08;2&#xff09;我们可以通过判断上下左右来确定…

基于ssm电子资源管理系统源码和论文

idea 数据库mysql5.7 数据库链接工具&#xff1a;navcat,小海豚等 环境&#xff1a; jdk8 tomcat8.5 基于ssm电子资源管理系统源码和论文758 摘要 随着互联网技术的高速发展&#xff0c;人们生活的各方面都受到互联网技术的影响。现在人们可以通过互联网技术就能实现不出家门…

微信公众号怎样使用文章模版?怎样建立文章模版 公众号模版示例 如何使用

打开我们的微信公众平台并登陆&#xff0c;找到我们的管理->素材管理 如图所示 2 在新建图文素材的右边有三个点&#xff0c;我们把鼠标移动到此处并点击 我们会看到新建分享图文和管理图文模版 选中并点击管理图文模版 如图所示 3 我们会看到如下界面 如图所示 4 …

【C++入门到精通】 线程库 | thread类 C++11 [ C++入门 ]

阅读导航 引言一、thread类的简单介绍二、线程函数详细介绍1. start() 函数&#xff08;1&#xff09;头文件&#xff08;2&#xff09;函数原型 2. join() 函数&#xff08;1&#xff09;头文件&#xff08;2&#xff09;函数原型 3. detach() 函数&#xff08;1&#xff09;头…

列表优先于数组

在Java中&#xff0c;列表&#xff08;List&#xff09;通常优于数组&#xff0c;因为列表提供了更灵活的操作和动态调整大小的能力。下面是一个例子&#xff0c;展示了为什么在某些情况下使用列表比数组更好&#xff1a; import java.util.ArrayList; import java.util.List;…

交友网站的设计与实现(源码+数据库+论文+开题报告+说明文档)

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。这里根据疫情当下&#xff0c;你想解决的问…

1125矩阵乘法(C语言)

一&#xff1a;题目 二&#xff1a;思路分析 1.对于学习过线性代数的人来说&#xff0c;对应公式十分熟悉&#xff0c;而对于没接触过线性代数的人来说&#xff0c;我们地一步要做的是从题目所给的公式中找规律 2.这个题目&#xff0c;给了我们三个变量n&#xff0c;m&#xf…

图扑物联 | WEB组态可视化软件

什么是组态&#xff1f; 组态的概念来自于20世纪70年代中期出现的第一代集散控制系统&#xff08;Distributed Control System&#xff09;&#xff0c;可理解为“配置”、“设置”等&#xff0c;是指通过人机开发界面&#xff0c;用类似“搭积木”的简单方式来搭建软件功能&a…

运营微信视频号要注意哪些问题?

视频号运营的5个雷点你别踩! 今天和你说的视频号运营的5大雷点 你踩过没? 这5点虽然和野花似的 但也不能踩哦 雷点1:违规行为 雷点2:抄袭剽窃 雷点3:没有明确目标受众 雷点4:短视频质量过低 雷点5:缺少社交互动 相信不管是视频号还是别的平台都通用哈

QML中Image动态显示图片内容

1.定义一个ColorImageProvider类 #ifndef COLORIMAGEPROVIDER_H #define COLORIMAGEPROVIDER_H#include <QObject> #include <QImage> #include <QQuickImageProvider>#include <QTimer>class ColorImageProvider :public QObject, public QQuickImag…

26.Java安卓程序设计-基于SSM框架Android的网店系统设计与实现

1. 引言 1.1 背景 介绍网店系统的背景&#xff0c;说明为什么设计这个系统以及系统的重要性。 1.2 研究目的 阐述设计基于SSM框架的Android网店系统的目标和意义。 2. 需求分析 2.1 行业背景 分析网店行业的特点和需求&#xff0c;以及目前市场上同类系统的不足之处。 …

docker consul 容器的自动发现与注册

consul相关知识 什么是注册与发现 服务注册与发现是微服务架构中不可或缺的重要组件。起初服务都是单节点的&#xff0c;不保障高可用性&#xff0c;也不考虑服务的压力承载&#xff0c;服务之间调用单纯的通过接口访问。直到后来出现了多个节点的分布式架构&#xff0c;起初的…

基于ssm果蔬经营平台系统源码和论文

首先,论文一开始便是清楚的论述了系统的研究内容。其次,剖析系统需求分析,弄明白“做什么”,分析包括业务分析和业务流程的分析以及用例分析,更进一步明确系统的需求。然后在明白了系统的需求基础上需要进一步地设计系统,主要包罗软件架构模式、整体功能模块、数据库设计。本项…

Pygame游戏实战九:跳跃小游戏

介绍模块 本游戏使用的是由Pycharm中的pygame模块来实现的&#xff0c;也可以在python中运行。通过Pygame制作一个类似与跳跃游戏&#xff0c;但在游戏中并没有进行跳跃&#xff0c;而是通过键盘进行控制。 最小开发框架 详情请看此文章&#xff1a;Pygame游戏模块介绍二&am…