第1关:创建用户与动态
任务描述
本关任务:实现创建新用户和创建新动态功能。
相关知识
为了完成本关任务,你需要掌握:1.redis
基本命令,2.python
基本命令。
redis基本命令
hget:从哈希中获取指定域的值。
conn = redis.Redis()
conn.hget("testhash", "field1")
执行结果:2
incr:将 key
中储存的数字值增一。
conn = redis.Redis()
conn.incr("testcount")
执行前:不存在 testcount
键。
执行后:
testcount
1
hset:将哈希中域 field
的值设为 value
。
conn = redis.Redis()
conn.hset("testhash", "field1", 2)
conn.hset("testhash", "field2", 4)
执行前:
{'field1': '1'}
执行后:
{'field1': '2', 'field2': '4'}
hmset:同时将多个域-值对设置到哈希表中。
conn = redis.Redis()
conn.hmset("test_hash", {
'id': 1,
'name': 'educoder',
'age': 2,
})
执行后:
{'age': '2', 'id': '1', 'name': 'educoder'}
hincrby:为哈希中指定域的值增加增量 increment
,用于统计。
conn = redis.Redis()
conn.hincrby("testhash", "field1", 1)
执行前:
{'field1': '1'}
执行后:
{'field1': '2'}
pipeline:将多条命令按照先后顺序放进一个队列中,一般配合execute一同使用,原子性(atomic
)地执行队列里的命令。
conn = redis.Redis()
pipe = conn.pipeline(True) # 事务开始
pipe.incr("counter")
pipe.incr("counter")
pipe.incr("counter")
pipe.execute() # 事务执行
执行结果:[1, 2, 3]
,通过下标即可获取对应命令的执行结果。
python基本命令
将字符串全小写化:
'Hello, Educoder'.lower()
执行结果:'hello, educoder'
返回当前时间的时间戳。
time.time()
使用格式化拼接字符串:
"My name is %s, I'm %i years old"%('educoder', 2)
执行结果:"My name is educoder, I'm 2 years old"
#!/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关:处理用户关系
#!/usr/bin/env python
#-*- coding:utf-8 -*-
import re
import time
import redis
conn = redis.Redis()
# 关注用户
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
第3关:状态与信息流
#!/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