第二次结对编程作业
链接
具体分工
- 潘海东:后端,前端,博客撰写
- 方瑞雄:前端,博客撰写
演示视频
- 点击链接播放即可,可能需要一些广告
由于B站审核通过不了,只能发到优酷,委屈各位,但是还是希望大家先看一下我们的视频!
https://v.youku.com/v_show/id_XNDM5ODE4NzYwMA==.html?spm=a2h3j.8428770.3416059.1
-
强烈推荐我们提供体验版微信小程序,可以直接用微信扫码体验游戏,但是需要管理员通过,请提前联系管理员wx:phd02428 qq:1647790440(
哈哈哈,这二维码超级大)(一开始是想完全发布出去,只需要在微信搜索我们小程序的名字就可以直接使用,且不需要管理员的同意,但是由于题材比较特殊,可能涉及赌博就没办法通过审核,发布不了)请一定一定联系下管理员,不然就算是申请通过了,也不会收到通知的。
由于为了保证完整的背景图,取消掉了微信小程序原有的顶部导航栏,没有了返回按钮,因此这个小程序对苹果用户不友好,想返回上一个页面只能重新扫码进入小程序,安卓用户可以直接用返回键回到上一个页面。(之后会想办法更新添加返回按钮
没有之后,都是假的)赌徒,要么从头做人,要么一赌到底!
PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(min) | 实际耗时(min) |
---|---|---|---|
Planning | 计划 | 60 | 60 |
Estimate | 估计这个任务需要多少时间 | 60 | 80 |
Development | 开发 | 2160 | 2220 |
Analysis | 需求分析 (包括学习新技术) | 240 | 240 |
Design Spec | 生成设计文档 | 120 | 150 |
Design Review | 设计复审 | 60 | 60 |
Coding Standard | 代码规范 (为开发制定合适的规范) | 120 | 120 |
Design | 具体设计 | 240 | 200 |
Coding | 具体编码 | 960 | 1000 |
Code Review | 代码复审 | 120 | 150 |
Test | 测试 (自我测试,修改,提交修改) | 300 | 300 |
Reporting | 报告 | 210 | 270 |
Test Report | 测试报告 | 120 | 180 |
Size Measurement | 计算工作量 | 60 | 60 |
Postmortem & Process Improvement Plan | 事后总结 并提出过程改进计划 | 30 | 30 |
2430 | 2550 |
解题思路描述与设计实现说明
网络接口的使用
不懂接口的使用要写什么,要说明什么,就是直接使用永福写好的接口。助教姐姐说贴出代码,那我就贴出代码。(因为接口数量较多,会比较长,所以我就把代码折叠起来了)
这是隐藏起来的代码,点击就可以显示,下面也一样
//登陆,
wx.request({
url: 'https://api.shisanshui.rtxux.xyz/auth/login',
header:{
'content-type': 'application/json'
},
data:{
username: e.detail.value.username,
password: e.detail.value.password
},
method:"POST",
success(res) {
console.log(res.data)
console.log(res.data.data)
console.log(res.data.data.token)
var token = res.data.data.token
var userid = res.data.data.user_id
wx.navigateTo({
url: "/pages/mine/mine?token=" + token + "&userid=" + userid
})
}
})
//注册
wx.request({
url: 'https://api.shisanshui.rtxux.xyz/auth/register',
header: {
'content-type': 'application/json'
},
data: {
username: e.detail.value.username,
password: e.detail.value.password
},
method: "POST",
success(res) {
console.log(res.data)
wx.navigateTo({
url: "/pages/signin/signin"
})
}
})
//开局
wx.request({
url: 'https://api.shisanshui.rtxux.xyz/game/open',
header:{
"X-Auth-Token":that.data.id_token
},
method:"POST",
success(res){
console.log(res.data)
console.log(res.data.data.card)
that.setData({
getstring: res.data.data.card,
id: res.data.data.id
})
wx.request({
url: 'http://sssxfd.top:8080/card_division',
// url: 'http://172.26.76.171:7777/getcards',
method:"POST",
data:{
cardstring:that.data.getstring
// card: that.data.getstring
},
// header:{
// "Content-Type": "application/x-www-form-urlencoded",
// },
success(res){
console.log(res.data)
that.setData({
qian:res.data.card[0],
zhong:res.data.card[1],
hou:res.data.card[2],
card:res.data.card,
qian_image:res.data.card_image[0],
zhong_image: res.data.card_image[1],
hou_image: res.data.card_image[2],
})
console.log(that.data.hou_image)
}
})
}
})
//出牌
wx.request({
url: 'https://api.shisanshui.rtxux.xyz/game/submit',
method:"POST",
header:{
"Content-Type":"application/json",
"X-Auth-Token":that.data.id_token
},
data:{
id:that.data.id,
card:that.data.card
},
success(res){
console.log(res.data)
that.setData({
qian: "success",
zhong: "success",
hou: "success",
getstring:"success",
card:[],
qian_image:that.data.qian_image_1,
zhong_image:that.data.zhong_image_1,
hou_image:that.data.hou_image_1,
})
}
})
//对局记录
wx.request({
url: 'https://api.shisanshui.rtxux.xyz/history',
method:"GET",
header:{
"X-Auth-Token":that.data.id_token
},
data:{
player_id:that.data.user_id,
limit:100,
page:0
},
success(res){
console.log(res.data)
that.setData({
record_list:res.data.data
})
console.log(that.data.record_list)
// 没错了
}
})
//对局详情
wx.request({
url: 'https://api.shisanshui.rtxux.xyz/history/' + this.data.play_id,
method:"GET",
header:{
"X-Auth-Token":that.data.id_token
},
success(res){
console.log(res.data)
console.log(res.data.data.detail)
if(res.data.status != 3001){
that.setData({
play_list: res.data.data.detail,
})
}
console.log(that.data.play_list)
},
fail(res){
console.log(res)
}
})
//排行榜
wx.request({
url: 'https://api.shisanshui.rtxux.xyz/rank',
success(res){
console.log(res)
that.setData({
rank_list: res.data
})
console.log(that.data.rank_list)
}
})
代码组织与内部实现设计
-
前端代码组织
-
后端代码组织:
说明算法的关键与关键实现部分流程图
我的算法很简单(很直截了当,流程图都不需要分支),只能勉强保证后墩>中墩>前墩,能在不违反游戏规则的情况下出牌。核心思想是利用贪心算法每次在剩余卡牌中找出最大的5张牌。先在13张牌中找出组合最大的5张牌作为后墩,然后在剩余的8张卡牌中找出最大的5张作为中墩,最后剩余的3张卡牌作为前墩。
核心算法(找出当前剩余卡牌中最大的5张牌的)的实现也不难,就按照游戏规则(同花顺-->炸弹-->葫芦-->同花-->顺子-->三条-->两对-->对子-->散牌)的顺序依次寻找,一旦发现符合项就立即返回该项目,并结束函数。
PS:这几天在群里面看到其他同学说他们的py算法运行速度比较慢,要8-10s,我慌了,他们考虑的也太多了吧,算法复杂度也太复杂了吧,我的算法跑起来几乎不需要时间,秒出结果,可见我的算法是有多么智障了。
算法流程图:
关键代码解释
算法部分最难实现的部分是顺子的判断,因为顺子是最特殊的一种组合,既不是用花色来分组,也不是按牌面大小是否相同来分组。我使用了三个函数来实现对顺子卡牌的挑选。由于卡牌牌面是由花色和大小两个部分组成,且大小部分也不全为数字,不能接着判断出牌面大小,需要先进行预处理。我通过字典,先自定义了一个大小比对的变量,用它来完成对牌面大小的判断。
#去掉重复的牌,用来检查顺子
#挑出顺子1
def remove_same_card(card_list):
#print(card_list)
card_dict = {'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9,'10':10,'J':11,'Q':12,'K':13,'A':14} #大小比对
number_card_list = []
digital_card_list = []
for item in card_list:
number_card_list.append(item[1:])
number_card_list = sorted(set(number_card_list),key=number_card_list.index)
for item in number_card_list:
digital_card_list.append(card_dict[item])
#print(digital_card_list)
return digital_card_list
#单元测试
#print(remove_same_card(['&2', '*2', '$2', '#2', '*7', '*K', '#K', '*K', '#K', '*A','$A']))
#挑出顺子2
def select_digital(digital_card_list):
for i in range(len(digital_card_list)-4):
if(digital_card_list[i] == digital_card_list[i+4]+4):
#证明是顺子
return digital_card_list[i]
#只能证明存在顺子,但是得不到牌
return False
#挑出顺子3
def select_straight(card_list):
digital_card_list = remove_same_card(card_list)
digital = select_digital(digital_card_list)
if(digital == False):
return []
card_dict = {'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9,'10':10,'J':11,'Q':12,'K':13,'A':14} #大小比对
straight_card_list = []
for i in range(len(card_list)):
if(card_dict[card_list[i][1:]] == digital):
straight_card_list.append(card_list[i])
digital = digital - 1
if(len(straight_card_list) == 5):
break
return straight_card_list
#单元测试
#print(select_straight(['&A', '*K', '$Q', '#J', '*10', '*9', '#8', '*7', '#6', '*5','$4']))
性能分析与改进
性能改进
作业一开始,就本着以能够做出来为第一目标,因此没有考虑过性能改进(理不直气也壮)。但是在算法实现过程种还是有稍微考虑到一些性能问题。比如在挑选顺子的函数中,if(digital_card_list[i] == digital_card_list[i+4]+4):,直接利用牌面大小的差值来判断,可以省略很多的循环次数。
性能分析图
可以发现,在核心函数select_best()下消耗最高的函数是select_straight(),这函数是用来挑选出顺子的函数,因为在挑选顺子的过程中需要多次循环遍历列表,因此时间消耗比较高。
注:这些性能分析是在下面这些例子中跑出来的结果,前面的例子都是永福后端返回的随机卡牌,最后两个例子是人为构造的,为了测试顺子的卡牌组合。
main_function("*4 *3 &4 $Q *Q &10 &A *8 *6 *5 #4 *9 $J")
main_function("&5 $9 &K *7 #Q &J &7 &4 $5 $A *9 $8 #2")
main_function("&5 #J #A &8 &K $7 #3 *8 #8 #5 $6 *3 #2")
main_function("&10 &4 #Q *A *10 #K $4 $K #2 $J &K $3 $6")
main_function("#10 *6 $Q *K &Q #Q *10 *J &5 $3 $8 $K $J")
main_function("#K #4 *10 &Q $6 $J #8 *8 $5 &10 $3 &K $Q")
main_function("$9 $J &A #3 *9 #J *8 $6 #4 $K #7 &9 $7")
main_function("$10 $3 #6 &10 $4 #10 *J $2 &2 *10 $6 *6 $8")
main_function("#K &8 #10 $3 &A #9 *5 &6 *10 $6 #7 *J $J")
main_function("$6 #Q &4 #10 *J &3 *A *2 #J &K *10 $2 &Q")
main_function("#5 #K &2 $K *J &7 #6 *6 *Q *4 &5 &6 #9")
main_function("*9 *5 #4 &J *Q #3 *6 $J $K #7 #Q $Q *10")
main_function("#5 $2 &10 #8 &J *4 *Q $4 *3 &K &8 $Q #9")
main_function("$K #5 &5 *10 &4 #J &A $6 *4 #Q $2 #7 &K")
main_function("$8 &3 #9 $9 $J $Q *3 #6 #Q &K &J &2 #K")
main_function("*7 #3 *5 &3 #7 $8 &5 &J $4 &9 $Q $K *Q")
main_function("#A $2 #3 $4 #5 $6 #7 $8 #9 $10 #J $Q #K")
main_function("#A #2 #3 #4 #5 #6 #7 #8 #9 #10 #J #Q #K")
单元测试
所有功能都使用函数实现,写了很多函数,几乎每个函数在实现过程中都进行了充分的单元测试,虽然有些函数比较简单,但是在实现过程都有进行测试,舍不得去掉。因此下面我贴出了我的理牌算法部分的大部分代码,字符串接收等不涉及算法部分没有展示。(会比较长,一样隐藏了起来)
#把字符串转变成为卡牌 string to list
def stl(card_string):
card_list = []
card_list = card_string.split(' ')
return card_list
#单元测试
#print(stl("*2 *4 *3 *5 *6 $A *7 *8 *9 *10 *J *Q *K *A"))
#去掉选出来的卡牌
#需要保证card_list不发生变化
def cut_card(card_list,select_best):
t_list = card_list
t_list = sorted(set(card_list) - set(select_best),key=t_list.index) #保证顺序
return t_list
#单元测试
#print(cut_card(['*2', '*3', '*4', '*5', '*6', '*7', '*8', '*9', '*10', '*J', '*Q', '*K', '*A'],['*2', '*4', '*5', '*6', '*7', '*8', '*10', '*Q', '*K', '*A']))
#对卡牌进行排序
def seq(card_list):
card_dict = {'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9,'10':10,'J':11,'Q':12,'K':13,'A':14} #大小比对
card_dict_ordered = collections.OrderedDict()
#card_list = []
card_list_ordered = []
seq_card_list = []
#card_list = stl(card_string)
#card_list = ['*2', '*4', '*5', '*7','*6', '*8', '*10', '*Q', '*K', '*A','$A'] #测试
#card_list.reverse() #测试
#print(card_list) #测试
#a = '2' #测试
#print(card_dict[a])
for item in card_list:
str = item[1:]
value = card_dict[str]
card_dict_ordered[item] = value
card_dict_ordered=collections.Counter(card_dict_ordered).most_common()
for item in card_dict_ordered:
card_list_ordered.append(item[0])
#print(card_list_ordered) #测试
#print(card_dict_ordered) #测试
#print(type(card_dict_ordered)) #测试
seq_card_list = card_list_ordered
return seq_card_list
#单元测试
#print(seq(['*2', '*4', '*5', '*7','*6', '*8', '*10', '*Q', '*K', '*A','$A']))
#对卡牌花色进行挑选
def select_suit(card_list):
spade_list = [] #$
heart_list = [] #&
diamond_list = [] ##
club_list = [] #*
for item in card_list:
if(item[0] == '$'):
spade_list.append(item)
elif(item[0] == '&'):
heart_list.append(item)
elif(item[0] == '#'):
diamond_list.append(item)
else:
club_list.append(item)
return spade_list,heart_list,diamond_list,club_list
#单元测试
# spade_list,heart_list,diamond_list,club_list = select_suit(['&2', '*4', '$5', '#6', '*7', '*8', '#10', '*Q', '#K', '*A','$A'])
# print(spade_list)
# print(heart_list)
# print(diamond_list)
# print(club_list)
#分出炸弹、三条、对子、散牌
def select_pair(card_list):
c_list = card_list.copy()
c_list.append("^B") #重点
one = []
two = []
three = []
four = []
t_list = []
for i in range(len(c_list)-1):
t_list.append(c_list[i])
#print(t_list)
#print(c_list[i])
if(c_list[i][1:] != c_list[i+1][1:]):
if(len(t_list) == 1):
one.append(t_list)
elif(len(t_list) == 2):
two.append(t_list)
elif(len(t_list) == 3):
three.append(t_list)
else:
four.append(t_list)
t_list = []
#print(card_list)
#print(c_list)
return one,two,three,four
#单元测试
# one,two,three,four = select_pair(['&2', '*2', '$2', '#2', '*7', '*K', '#K', '*K', '#K', '*A','$A'])
# print(one)
# print(two)
# print(three)
# print(four)
#去掉重复的牌,用来检查顺子
#挑出顺子1
def remove_same_card(card_list):
#print(card_list)
card_dict = {'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9,'10':10,'J':11,'Q':12,'K':13,'A':14} #大小比对
number_card_list = []
digital_card_list = []
for item in card_list:
number_card_list.append(item[1:])
number_card_list = sorted(set(number_card_list),key=number_card_list.index)
for item in number_card_list:
digital_card_list.append(card_dict[item])
#print(digital_card_list)
return digital_card_list
#单元测试
#print(remove_same_card(['&2', '*2', '$2', '#2', '*7', '*K', '#K', '*K', '#K', '*A','$A']))
#挑出顺子2
def select_digital(digital_card_list):
for i in range(len(digital_card_list)-4):
if(digital_card_list[i] == digital_card_list[i+4]+4):
#证明是顺子
return digital_card_list[i]
#只能证明存在顺子,但是得不到牌
return False
#挑出顺子3
def select_straight(card_list):
digital_card_list = remove_same_card(card_list)
digital = select_digital(digital_card_list)
if(digital == False):
return []
card_dict = {'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9,'10':10,'J':11,'Q':12,'K':13,'A':14} #大小比对
straight_card_list = []
for i in range(len(card_list)):
if(card_dict[card_list[i][1:]] == digital):
straight_card_list.append(card_list[i])
digital = digital - 1
if(len(straight_card_list) == 5):
break
return straight_card_list
#单元测试
#print(select_straight(['&A', '*K', '$Q', '#J', '*10', '*9', '#8', '*7', '#6', '*5','$4']))
#判断是否存在特殊牌型
#放弃不写
# def if_is_special_card():
# special_card = []
# return special_card
#找出剩余手牌中最大的选项
#后敦和中敦都可以使用这个算法
#前敦不需要再一个函数了,去掉中墩和后敦之后剩下的就是前敦了
#主函数
def select_best(card_list):
card_dict = {'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9,'10':10,'J':11,'Q':12,'K':13,'A':14} #大小比对
# first_card_list = []
# second_card_list = []
# third_card_list = []
best_card_list = [] #要换成空列表
if(len(card_list) == 3):
best_card_list = card_list
print("乌龙") #测试 大概率为乌龙
return best_card_list #这个return不太行
#前期准备
spade_list,heart_list,diamond_list,club_list = select_suit(card_list)
one_list,two_list,three_list,four_list = select_pair(card_list)
#同花顺——》炸弹——》葫芦——》同花——》顺子——》三条——》两对——》对子——》散牌
#顺子不好搞定 解决了
#要重新考虑
#同花顺
if(len(spade_list) >= 5):
best_card_list = select_straight(spade_list)
elif(len(heart_list) >= 5):
best_card_list = select_straight(heart_list)
elif(len(diamond_list) >= 5):
best_card_list = select_straight(diamond_list)
else:
best_card_list = select_straight(club_list)
if(len(best_card_list) != 0): #这个不是很好
print("同花顺") #测试
return best_card_list
#炸弹
if(len(four_list) != 0):
best_card_list = four_list[0]
if(len(one_list) != 0):
best_card_list.append(one_list[-1][0])
print("炸弹") #测试
return best_card_list
elif(len(two_list) != 0):
best_card_list.append(two_list[-1][0])
print("炸弹") #测试
return best_card_list
else:
best_card_list.append(three_list[-1][0])
print("炸弹") #测试
return best_card_list
#葫芦
if(len(two_list) != 0 and len(three_list) != 0):
best_card_list = three_list[0] + two_list[-1]
print("葫芦") #测试
return best_card_list
elif(len(two_list) == 0 and len(three_list) >= 2):
best_card_list = three_list[0] + three_list[1][:1]
print("葫芦") #测试
return best_card_list
#同花
if(len(spade_list) >= 5):
best_card_list = spade_list[:5]
if(len(heart_list) >= 5):
if(len(best_card_list) != 0):
# print(1)
# print(best_card_list)
if(card_dict[best_card_list[0][1:]] < card_dict[heart_list[0][1:]]):
best_card_list = heart_list[:5]
else:
best_card_list = heart_list[:5]
if(len(diamond_list) >= 5):
if(len(best_card_list) != 0):
# print(2)
# print(best_card_list)
if(card_dict[best_card_list[0][1:]] < card_dict[diamond_list[0][1:]]):
best_card_list = diamond_list[:5]
else:
best_card_list = diamond_list[:5]
if(len(club_list) >= 5):
if(len(best_card_list) != 0):
# print(3)
# print(best_card_list)
if(card_dict[best_card_list[0][1:]] < card_dict[club_list[0][1:]]):
best_card_list = club_list[:5]
else:
best_card_list = club_list[:5]
if(len(best_card_list) != 0):
print("同花") #测试
return best_card_list
#顺子
best_card_list = select_straight(card_list)
if(len(best_card_list) != 0):
print("顺子") #测试
return best_card_list
#三条
if(len(three_list) != 0):
best_card_list = three_list[0] + one_list[0] + one_list[1]
print("三条") #测试
return best_card_list
#两对
if(len(two_list) >= 2):
best_card_list = two_list[0] + two_list[1] + one_list[0]
print("两对") #测试
return best_card_list
#对子
if(len(two_list) == 1):
best_card_list = two_list[0] + one_list[0] + one_list[1] + one_list[2]
print("对子") #测试
return best_card_list
#散牌
for item in one_list:
best_card_list = best_card_list + item
if(len(best_card_list) == 5):
break
print("乌龙") #测试
return best_card_list
def main_function(card_string):
#变量定义
#好像并不是很需要变量定义
card_list = []
card_string_list = []
#前中后
first_card_list = []
second_card_list = []
third_card_list = []
#四花色
# spade_list = [] #$
# heart_list = [] #&
# diamond_list = [] ##
# club_list = [] #*
#取排
#todo
#card_string = "#A $2 #3 $4 #5 $6 #7 $8 #9 $10 #J $Q #K" #测试
card_list = stl(card_string)
#理牌
#排序
card_list = seq(card_list)
#spade_list,heart_list,diamond_list,club_list = select_suit(card_list)
# #后敦
print("后敦")
third_card_list = select_best(card_list)
card_list = cut_card(card_list,third_card_list) #变成集合的过程中 还能保持有序吗?这是个问题 已经解决
third_card_list.reverse()
third_card_string = " ".join(third_card_list)
print(third_card_string)
#中敦
print("中敦")
second_card_list = select_best(card_list)
card_list = cut_card(card_list,second_card_list)
second_card_list.reverse()
second_card_string = " ".join(second_card_list)
print(second_card_string)
#前敦
print("前敦")
first_card_list = select_best(card_list)
first_card_list.reverse()
first_card_string = " ".join(first_card_list)
print(first_card_string)
#first_card_string,second_card_string,third_card_string
card_string_list.append(first_card_string)
card_string_list.append(second_card_string)
card_string_list.append(third_card_string)
print(card_string_list)
return card_string_list
#单元测试
#main_function()
# main_function("*4 *3 &4 $Q *Q &10 &A *8 *6 *5 #4 *9 $J")
# main_function("&5 $9 &K *7 #Q &J &7 &4 $5 $A *9 $8 #2")
# main_function("&5 #J #A &8 &K $7 #3 *8 #8 #5 $6 *3 #2")
# main_function("&10 &4 #Q *A *10 #K $4 $K #2 $J &K $3 $6")
# main_function("#10 *6 $Q *K &Q #Q *10 *J &5 $3 $8 $K $J")
# main_function("#K #4 *10 &Q $6 $J #8 *8 $5 &10 $3 &K $Q")
# main_function("$9 $J &A #3 *9 #J *8 $6 #4 $K #7 &9 $7")
# main_function("$10 $3 #6 &10 $4 #10 *J $2 &2 *10 $6 *6 $8")
# main_function("#K &8 #10 $3 &A #9 *5 &6 *10 $6 #7 *J $J")
# main_function("$6 #Q &4 #10 *J &3 *A *2 #J &K *10 $2 &Q")
# main_function("#5 #K &2 $K *J &7 #6 *6 *Q *4 &5 &6 #9")
# main_function("*9 *5 #4 &J *Q #3 *6 $J $K #7 #Q $Q *10")
# main_function("#5 $2 &10 #8 &J *4 *Q $4 *3 &K &8 $Q #9")
# main_function("$K #5 &5 *10 &4 #J &A $6 *4 #Q $2 #7 &K")
# main_function("$8 &3 #9 $9 $J $Q *3 #6 #Q &K &J &2 #K")
# main_function("*7 #3 *5 &3 #7 $8 &5 &J $4 &9 $Q $K *Q")
# main_function("#A $2 #3 $4 #5 $6 #7 $8 #9 $10 #J $Q #K")
# main_function("#A #2 #3 #4 #5 #6 #7 #8 #9 #10 #J #Q #K")
Github的代码签入记录
这是两周来的git签入记录,代码是一直再修改,但是没有每次都上传的git上。而且我们的前端是在微信开发者工具上开发的,就直接发布到微信平台上了,因此git上没有前端的迁入记录。
遇到的代码模块异常或结对困难及解决方法
在完成的过程遇到很很多很多的小问题,其中让我印象最深刻的,应该就是下面这两个了:
-
python中list的复制
在python中,要将list1赋值给list2,不能使用简单的等号赋值 list2 = list1,这样子事实上并没有产生一个新的变量list2,只是将list2指向了list1,类似c里面的指针。当对list2进行修改时,list1也会随之改变。需要使用列表函数copy()来完成列表的复制,list2 = list1.copy(),这样list2是完全独立于list1的新变量。
参考https://www.cnblogs.com/Black-rainbow/p/9577029.html
这虽然是一个很简单的问题,但是却很难发现,debug过程相当痛苦,一直不知道错误在哪里。也反映了对python语言的不了解,不熟悉。
-
ssl证书的安装
代码全部写完,一切本地测试正常之后,我就把小程序发布到了微信平台上,可以直接微信扫码使用小程序,结果却发现,所有请求都不能使用了,不只是我自己的后端请求,连永福提供的接口也都不能使用了。不能登录也不能注册,查找资料之后才发现,微信小程序中的request请求,会对域名的合法性需要进行校验。由于在本地环境下开发测试,默认不会对域名的合法性进行校验,所以我就很正常的请求使用我自己搭的后端服务器和永福的接口,也没有任何异常产生,但是发布之后,微信平台就会对小程序的request请求进行合法性检查,但是我自己的还有永福的接口都不符合规定,就全都不能使用了。
平台要求所有的http请求都需要带ssl证书认证的,也就是https请求,而我自己的后端并没有安装ssl证书,因此还需要去安装ssl证书。
参考:
https://blog.csdn.net/dyingstraw/article/details/82698639
https://blog.csdn.net/ziliwangmoe/article/details/81909151
然后还要再微信平台上添加域名信任白名单(下图),就可以正常使用了
评价队友
- 需要学习的地方:方瑞雄同学对任务的分解到位,减轻了本次作业的压力,与我共同完成了本次作业。
- 需要改进的地方:很早就上床睡觉了,不熬夜,不够努力。
学习进度条
周数 | 新增代码(行) | 累计代码(行) | 本周学习耗时(小时) | 累计学习耗时(小时) | 重要成长 |
---|---|---|---|---|---|
1 | 0 | 0 | 3 | 3 | 完成了原型的设计 |
2 | 400 | 400 | 15 | 18 | 完成了后端算法部分 |
3 | 500 | 900 | 25 | 43 | 完成了前端部分,根据作业要求做好前端与后端的对接,实现接口的调用,并完善代码与编写博客 |