---
title: '海大高培-Python By Liao-Hsiu-I'
disqus: hackmd
---
海大高培-Python By Liao-Hsiu-I
===
[TOC]
(9/19)(第一堂)
---
### 生成網路-影像風格轉換
```python=
from __future__ import absolute_import, division, print_function, unicode_literals
import tensorflow as tf
import IPython.display as display
import matplotlib.pyplot as plt
import matplotlib as mpl
import numpy as np
import PIL.Image
import time
import functools
import cv2
mpl.rcParams['figure.figsize'] = (12,12)
mpl.rcParams['axes.grid'] = False
def tensor_to_image(tensor):
numy_array = np.squeeze(np.array(tensor*255, dtype=np.uint8))
return numy_array
def gram_matrix(input_tensor):
result = tf.linalg.einsum('bijc,bijd->bcd', input_tensor, input_tensor)
input_shape = tf.shape(input_tensor)
num_locations = tf.cast(input_shape[1]*input_shape[2], tf.float32)
return result/(num_locations)
def train_step(obj, image):
with tf.GradientTape() as tape:
outputs = obj.extractor(image)
loss = obj.loss(outputs)+obj.total_variation_weight*tf.image.total_variation(image)
grad = tape.gradient(loss, image)
obj.opt.apply_gradients([(grad, image)])
image.assign(tf.clip_by_value(image, clip_value_min=tf.constant(0.0), clip_value_max=tf.constant(1.0)))
class style_transfer:
def __init__(self,style_layers=None,content_layers=None):
vgg = tf.keras.applications.VGG19(include_top=False, weights='imagenet')
if style_layers is None:
style_layers = ['block1_conv1','block2_conv1','block3_conv1', 'block4_conv1', 'block5_conv1']
if content_layers is None:
content_layers = ['block5_conv2']
self.style_layers = style_layers.copy()
self.content_layers=content_layers.copy()
self.num_style_layers = len(self.style_layers)
self.num_content_layers = len(self.content_layers)
outputs = [vgg.get_layer(name).output for name in style_layers+content_layers]
self.model = tf.keras.Model([vgg.input],outputs)
self.model.trainable = False
def loss(self,outputs):
gram_outputs = [gram_matrix(o) for o in outputs[:self.num_style_layers]]
style_loss = tf.add_n([tf.reduce_mean((out-tar)**2) for out,tar in zip(gram_outputs,self.style_target)])
style_loss *= self.style_weight / self.num_style_layers
content_loss = tf.add_n([tf.reduce_mean((out-tar)**2) for out,tar in zip(outputs[self.num_style_layers:],self.content_target)])
content_loss *= self.content_weight / self.num_content_layers
loss = style_loss + content_loss
return loss
def extractor(self,image):
processed_input = tf.keras.applications.vgg19.preprocess_input(image*255.0)
outputs = self.model(processed_input)
return outputs
def transfer(self,content_image,style_image,style_weight=1.0e-2,content_weight=1.0e4,total_variation_weight=30,epochs=10,step_per_epoch=100):
self.content_weight = content_weight
self.style_weight = style_weight
self.total_variation_weight = total_variation_weight
style_output = self.extractor(style_image)
content_output = self.extractor(content_image)
self.style_target = [gram_matrix(s) for s in style_output[:self.num_style_layers]]
self.content_target = content_output[self.num_style_layers:]
self.opt = tf.optimizers.Adam(learning_rate=0.02, beta_1=0.99, epsilon=1e-1)
image = tf.Variable(content_image)
for step in range(epochs):
for _ in range(step_per_epoch):
train_step(self, image)
display.clear_output(wait=True)
display.display(PIL.Image.fromarray(tensor_to_image(image)))
print("Train step: {}".format(step+1))
return tensor_to_image(image)
```
```python=
#載入content image
content_url = 'https://i1.wp.com/boo2k.com/wp-content/uploads/2018/08/IMG_3349-1.jpg?resize=860%2C573&ssl=1'
content_image_file = tf.keras.utils.get_file('content.jpg',origin=content_url,cache_subdir='datasets')
content_image = cv2.imread(content_image_file)
content_image = tf.image.convert_image_dtype(content_image[:,:,::-1],tf.float32)
content_image = tf.image.resize(content_image,(content_image.shape[0]//4,content_image.shape[1]//4))
#content_image = np.array(PIL.Image.open('tree.jpg')).astype('float32')/255.0
#載入style image
style_url = 'https://tse2.mm.bing.net/th?id=OIP.1KA-xMf_qquuwP0mL22OSAHaF7&pid=Api&P=0&w=202&h=162'
style_image_file = tf.keras.utils.get_file('style.jpg',origin=style_url,cache_subdir='datasets')
style_image = cv2.imread(style_image_file)
style_image = tf.image.convert_image_dtype(style_image[:,:,::-1],tf.float32)
style_image = tf.image.resize(style_image,(style_image.shape[0]//4,style_image.shape[1]//4))
#style_image = np.array(PIL.Image.open('Vassily_Kandinsky,_1913_-_Composition_7.jpg')).astype('float32')/255.0
plt.figure(figsize=(12,6))
plt.subplot(1, 2, 1)
plt.imshow(content_image)
plt.title('Content Image')
plt.axis(False)
plt.subplot(1, 2, 2)
plt.imshow(style_image)
plt.title('Style Image')
plt.axis(False)
plt.show()
```
```python=
transfer = style_transfer()
image = transfer.transfer(content_image[tf.newaxis,:],style_image[tf.newaxis,:],epochs=15)
```
```python=
plt.figure(figsize=(18,6))
plt.subplot(1, 3, 1)
plt.imshow(content_image)
plt.title('Content Image')
plt.axis(False)
plt.subplot(1, 3, 2)
plt.imshow(style_image)
plt.title('Style Image')
plt.axis(False)
plt.subplot(1, 3, 3)
plt.imshow(image)
cv2.imwrite('stylied_image.png',image[:,:,::-1])
plt.title('Stylized Image')
plt.axis(False)
plt.show()
```
(11/21)
---
### code 1 noPronoun
#### 仙貝知識
```python=
len(test_sentence) # test_sentence 這個 list 的長度
for i in range(5):
print(i)
test_sentence[0] # test_sentence 裡面的第一個字串, 編號從 0 開始
result = change_text(test_sentence[0]) # 呼叫 change_text function 並且得到回傳值、儲存在 result 裡面
newtext = test_sentence[0] + "\t" + result # 將字串拼接在一起, 其中 "\t" 是 TAB 定位符號
print(newtext)
newtext
```
#### 正文
function def_1
```python=
def change_text(sentence):
sentence = sentence.replace('你', '汝') # 會把字串中的「你」都改成「汝」
sentence = sentence.replace('我', '吾') # 會把字串中的「我」都改成「吾」
sentence = sentence.replace('妳', '汝們') # 會把字串中的「妳」都改成「汝們」
sentence = sentence.replace('您', '偉大的人') # 會把字串中的「您」都改成「偉大的人」
sentence = sentence.replace('祢', '神') # 會把字串中的「祢」都改成「神」
sentence = sentence.replace('他', 'he') # 會把字串中的「他」都改成「he」
sentence = sentence.replace('她', 'she') # 會把字串中的「她」都改成「she」
sentence = sentence.replace('祂', '神神') # 會把字串中的「祂」都改成「神神」
sentence = sentence.replace('它', 'item') # 會把字串中的「牠」都改成「item」
sentence = sentence.replace('牠', 'cat') # 會把字串中的「牠」都改成「cat」
# 請在此處加上其他代名詞取代規則 (10分)
return sentence
```
list_1 datas
```python=
test_sentence = [ # 這是一個 list, 裡面都是字串
"你好",
"你說你想要逃",
"妳是我的眼",
"我們不說你我他",
"我你妳您祢他她祂它牠"
]
```
#### 執行
```python=
for i in range(len(test_sentence)):
result = change_text(test_sentence[i])
print(test_sentence[i] + "\t" + result)
while True:
sentence = input('請輸入句子 (over 代表結束遊戲):')
if sentence == 'over': break
sentence = change_text(sentence)
print(sentence)
print('下回見')
```
### code 2 myEliza.ipynb
#### 仙貝知識
```python=
k = test_sentence[0].find("死") # 在「我覺得我生活一片黯淡」句子中找 "死" 的出現位置k
k = test_sentence[3].find("死") # 在「那個死傢伙」句子中找 "死" 的出現位置k
sampleText = "死傢伙"
k = sampleText.find("死")
k # 句子開頭位置從 0 開始
sentence = input("請輸入:") # 從鍵盤打字,可以指定前面的提示訊息sentence
```
```python=
k = 1
while True: # 無窮迴圈
if k > 5: break # 直到符合某條件就跳出迴圈
print(k)
k += 1 # 這行是把 k 的值加 1
```
#### 正文
function def_1
```python=
def create_response(sentence):
if sentence.find("死") >= 0:
return "生命很寶貴,來電1995讓我陪你聊聊"
elif sentence.find("自殺")>=0:
return "張老師在你身邊"# 若在此處加上其他回覆可加分 (10分)
else:
sentence = sentence.replace('你', '吾')# 為了把「你」「我」互換,請先在此把「你」改成「吾」
sentence = sentence.replace('我', '你')# 交換人稱
sentence = sentence.replace('吾', '我')# 再把「吾」改成「我」 (10分)
if sentence[0:2] == '因為':
sentence = sentence[2:]
sentence = '為什麼說' + sentence
return sentence
```
```python=
test_sentence = [
"我覺得我生活一片黯淡",
"因為我另一半不愛我了",
"他跑去跟別人約會了",
"那個死傢伙",
"你好像聽不太懂我講的話"
]
```
#### 執行
```python=
print('Eliza\t今天覺得怎麼樣??')
for i in range(len(test_sentence)):
print("You\t" + test_sentence[i])
result = create_response(test_sentence[i])
print("Eliza\t" + result)
print("Eliza\t今天覺得怎麼樣??")
while True:
sentence = input("You\t")
if sentence == "881~": break
sentence = create_response(sentence)
print("Eliza\t" + sentence)
print("Eliza\t881~")
```
### code 3 simpleChatbot
#### 仙貝知識
```python=
#解釋上述程式各行意義,先解釋 dictionary 是可以由 key 找 value 值的做法
print(dialogue["早安"])
myKey = "你好嗎"
print(dialogue[myKey])
# if key in dialogue 這可以查找 dialogue 是否有這個 key 出現
myKey = "你好嗎" # 有收錄
print("YES") if myKey in dialogue else print("NO")
myKey = "你好嗎?" # 沒收錄
print("YES") if myKey in dialogue else print("NO")
# random.randrange(n) 會回傳一個 0 ~ (n-1) 的亂數
for i in range(10):
print(random.randrange(100))
k = random.randrange(len(random_response)) # 拿到一個亂數,值在 random_response 長度範圍內
print(k) # 每次執行,結果都會不一樣
random_response[k]
```
#### 正文
import
```python=
import random # 加入可提供亂數的模組
random.seed() # 亂數產生器需要先初始化
```
function def_1
```python=
def get_response(sentence):
if sentence in dialogue:
return dialogue[sentence]
else:
k = random.randrange(len(random_response))
return random_response[k]
```
list_1 datas
```python=
dialogue = { # 這是一種 dictionary, 每組資料都是 key : value , 查詢 key 可拿到 value
"早安": "早安",
"午安": "午安",
"你好嗎": "我很好,謝謝!",# 加上兩組以上的應答 (10分)
"你好": "你好!",
"再見": "再見~"
}
random_response = ['嗯嗯', '呵呵', 'OSO']
```
list_2 datas
```python=
test_sentence = [
"早安",
"你好嗎",
"最近好嗎",
"什麼",
"你好奇怪",
"再見"
]
```
#### 執行
```python=
for i in range(len(test_sentence)):
print("You\t" + test_sentence[i])
result = get_response(test_sentence[i])
print("Chatbot\t" + result)
while True:
sentence = input("You\t")
result = get_response(sentence)
print("Chatbot\t" + result)
if sentence == '再見': break
```
### code 4 voiceCommand
#### 仙貝知識
```python=
#解釋上述程式各行意義; commandSet 是一個 list of dictionary
print(commandSet[0]["pattern"])
print(commandSet[0]["command"])
# regular expression 常用來寫比對字串的句型,但其實不太適合用來處理自然語言, 太多變化且要有詞的概念
print(re.search("[說講]", "說說看")) # [AB] 表示 A B 出現其中一個
print(re.search("[說講]", "演講"))
print(re.search("[說講]", "看看"))
print(re.search("[說講]笑話", "說笑話"))
print(re.search("[說講]笑話", "可以講笑話嗎"))
print(re.search("[說講]笑話", "說個笑話來聽"))
print(re.search("[說講].*笑話", "說個笑話來聽")) # .* 表示中間可夾任意長度文字
print(re.search("(打開|開).*門", "能幫我打開廚房的門嗎?")) # (A|B) 也是 A B 任出現一個,但可多個字
print(re.search("(打開|開).*門", "我要開房間門"))
print(re.search("(打開|開).*門", "芝麻開門"))#開始專門訓練=>false
```
#### 正文
import
```python=
import re
```
list_1 datas
```python=
commandSet = [ # 這是一個 list of dictionary
#每加一種新功能可加 5 分,最多加到 20 分
{"pattern" : "[說講].*定義", "command" : "tell the defination"},
{"pattern" : "[說講].*原因", "command" : "tell the reason"},
{"pattern" : "[說講].*我喜歡你", "command" : "I love you"},
{"pattern" : "[說講].*故事", "command" : "tell a story"},
{"pattern" : "[說講].*笑話", "command" : "tell a joke"},
{"pattern" : "聽.*音樂", "command" : "listen to music"},
{"pattern" : "打開.*電視", "command" : "turn on the TV"},
{"pattern" : "打開.*冷氣", "command" : "turn on the air conditioner"},
{"pattern" : "(打開|開).*門", "command" : "open the door"}
]
unknownCommand = "我聽不懂您的指令"
```
list_2 datas
```python=
test_sentence = [
"你會講笑話嗎?",
"說個笑話來聽聽",
"你覺得我是個笑話嗎?",
"能幫我打開廚房的門嗎?",
"我要開房間門",
"打開客廳的冷氣好了",
"你好像聽不太懂我講的話"
]
```
#### 執行
```python=
for i in range(len(test_sentence)):
print(test_sentence[i])
noMatch = True
for j in range(len(commandSet)):
if re.search(commandSet[j]["pattern"], test_sentence[i]) is not None:
print("執行動作:" + commandSet[j]["command"])
noMatch = False # 比對到指令就把 noMatch 改成 False
break # 並且 break 跳出迴圈、不用再比後面的指令
if noMatch:
print(unknownCommand)
print("您好,要我做什麼事?")
sentence = input()
noMatch = True
for i in range(len(commandSet)):
if re.search(commandSet[i]["pattern"], sentence) is not None:
print("執行動作:" + commandSet[i]["command"])
noMatch = False
break
if noMatch:
print(unknownCommand)
```
### code 5 mySiri
import
```python=
import re # 加入 regular expression 比對的功能
import random
```
function def_1
```python=
def tell_a_joke(sentence):
jokes = [
"易經的媽媽叫什麼\n\n\n\n\n液晶螢幕",
"小明吃麻婆豆腐,麻婆告他性騷擾",
"死掉的腎臟,猜一本中國小說?\n\n\n\n\n答案:西遊記(台語:死腰子)"
] # https://w199584.pixnet.net/blog/post/16756643
print(jokes[0]) # 現在一直印出第一個笑話
print(jokes[random.randrange(len(jokes))] )# 若改成亂數選一則笑話印出,加 15 分 (可參考 simpleChotbot)
```
google_res def_1
```python=
def find_restaurant(sentence):
print("找到的餐廳:")
for i in range(len(restaurant)):
if (sentence.find(restaurant[i]["type"]) >= 0):
print("\t" + restaurant[i]["name"])
```
google_res def_2
```python=
def find_rating(sentence):
for i in range(len(restaurant)):
if (sentence.find(restaurant[i]["name"]) >= 0):
print(restaurant[i]["name"] + "評價" + str(restaurant[i]["rate"]) + "顆星")
```
google_res def_3
```python=
def find_buffet(sentence):
print("自助區:")
for i in range(len(restaurant)):
if (sentence.find(restaurant[i]["buffet"]) >= 0):
print("\t" + restaurant[i]["name"])
```
function def_2
```python=
def phone_call(sentence):
k = sentence.find('給')
if k >= 0:
print("現在要打電話給" + sentence[k+1:]) # 目前是印出對方的名字
# 模仿 restaurant[] 建立電話簿 phone_book 記錄人名、電話。
# 可以用上面找到的人名查出他的電話號碼。完成此功能加 15 分
```
google_name def_1
```python=
def find_phone(sentence): #sentence=人名
print("人名:")
for i in range(len(phone_book)):
if (sentence.find(phone_book[i]["name"]) >= 0):
print(phone_book[i]["name"] + "的電話是" + phone_book[i]["phone_num"])
```
list_1 datas
```python=
restaurant = [
{"name":"麥當當", "type":"速食店", "rate":3.5, "service":"free black tea"},
{"name":"大家牛排", "type":"牛排館", "rate":3.8, "service":"free milk"},
{"name":"超好吃", "type":"牛排館", "rate":4.7, "service":"free green tea"},
{"name":"肯爺爺", "type":"速食店", "rate":3.5, "service":"free cola"},
{"name":"貴貴世家", "type":"牛排館", "rate":3.2, "service":"free coffee"}
]
# 若餐廳能新增其他欄位 (例如價位...) 並增加相對應的查詢功能 (和 find_restaurant() 一樣) 加 20 分
```
list_2 datas
```python=
phone_book = [
{"name":"BECKETT", "phone_num":"0934975931"},
{"name":"ROSEMARY", "phone_num":"0970954407"},
{"name":"MILBURN", "phone_num":"0914186333"},
{"name":"MERTON", "phone_num":"0915273181"},
]
```
list_3 datas
```python=
commandSet = [ # 這是一個 list of dictionary
{"pattern" : "(打電話|撥號)給", "command" : phone_call},
{"pattern" : "[說講].*笑話", "command" : tell_a_joke},
{"pattern" : "幫我找(這)?(附近的)?", "command" : find_restaurant},
{"pattern" : ".*(的)?評價如何", "command" : find_rating}
]
unknownCommand = "我聽不懂您的指令"
```
#### 執行
```python=
test_sentence = [
"你會講笑話嗎?",
"說個笑話來聽聽",
"打電話給林志玲",
"撥號給老爸",
"幫我找速食店",
"幫我找這附近的牛排館",
"大家牛排評價如何"
]
for i in range(len(test_sentence)):
print(test_sentence[i])
noMatch = True
for j in range(len(commandSet)):
if re.search(commandSet[j]["pattern"], test_sentence[i]) is not None:
func = commandSet[j]["command"]
func(test_sentence[i])
noMatch = False # 比對到指令就把 noMatch 改成 False
break # 並且 break 跳出迴圈、不用再比後面的指令
if noMatch:
print(unknownCommand)
print("您好,要我做什麼事?")
sentence = input()
noMatch = True
for i in range(len(commandSet)):
if re.search(commandSet[i]["pattern"], sentence) is not None:
func = commandSet[i]["command"]
func(sentence)
noMatch = False
break
if noMatch:
print(unknownCommand)
```
## (12/5)
### 語音指令介面_段詞
```python=
!pip install -U DistilTag
```
```python=
import DistilTag
DistilTag.download()
```
```python=
from DistilTag import DistilTag
tagger = DistilTag() # 這是一個可進行中文斷詞及詞性標記的系統
```
```python=
import re # 加入 regular expression 比對的功能
unknownCommand = "\t回答:我聽不懂您的指令"
```
```python=
command_set_wseg = [ # 修改上回的指令集,考慮斷詞邊界
{"pattern" : "\\b[說講]\\b.*\\b笑話\\b", "command" : "tell a joke"},
{"pattern" : "\\b打開\\b.*\\b冷氣\\b", "command" : "turn on the air conditioner"},
{"pattern" : "\\b(打開|開)\\b.*\\b門\\b", "command" : "open the door"}
]
test_sentence_raw = [ # 句子沒有斷詞
"你會講笑話嗎?",
"這是演講聽到的笑話",
"能幫我打開廚房的門嗎?",
"我要開始專門訓練課程了",
"打開客廳的冷氣好了",
"你好像聽不太懂我講的話"
]
for i in range(len(test_sentence_raw)):
print("You: " + test_sentence_raw[i])
tagged = tagger.tag(test_sentence_raw[i])# 先對句子斷詞
sent_tagged = ""
for j in tagged[0]:
print(j)
sent_tagged = sent_tagged + str(j[0]) +" "
# 請在此處使用 tagger 將 test_sentence_raw[i] 斷詞、拼接成 sent_tagged
# (20 分)
print("\t" + sent_tagged)
noMatch = True
for j in range(len(command_set_wseg)):
matchStr = re.search(command_set_wseg[j]["pattern"], sent_tagged)
if matchStr is not None:
print("\t符合字串:[" + matchStr.group() + "]\n\t執行動作:" + command_set_wseg[j]["command"])
noMatch = False # 比對到指令就把 noMatch 改成 False
break # 並且 break 跳出迴圈、不用再比後面的指令
if noMatch:
print(unknownCommand)
```
```python=
hw_sentence = [
"你會講笑話嗎?",
"康橋的靈性全在一條河上;康河,我敢說,是全世界最秀麗的一條水。",
"用一轉身離開,用一輩子去忘記。",
"這一次的曲調卻是柔和之至,宛如一人輕輕歎息。",
"「他喜歡你這般打扮做鬼臉,那還用說。你是他的大玩偶。」",
"學院分配儀式是非常重要的,因為你在霍格華茲的時候,你的學院就像你的家一樣。"
]
for i in range(len(hw_sentence)):
print("You: " + hw_sentence[i])
tagged = tagger.tag(hw_sentence[i])# 先對句子斷詞
sent_tagged = ""
for j in tagged[0]:
print(j)
print(j[0])
sent_tagged = sent_tagged + j[0] +" "
# 請在此處使用 tagger 將 hw_sentence[i] 斷詞、拼接成 sent_tagged
# (20 分)
print("\t" + sent_tagged)
# 對各個句子斷詞,將斷詞結果貼到 TronClass 測驗卷中
# 例如第一個句子會成為「你 會 講 笑話 嗎 ?」
```
### 搜尋拍賣文章
```python=
# 假設拍賣網站的文章都已斷好詞如下
saleDoc = [
["英倫", "風", "羅馬", "布", "材質", "休閒", "長褲", "棉褲"],
["學院", "風", "劍", "領", "休閒", "西服", "英倫", "雅痞", "棉質", "針織", "外套", "韓", "版", "修身", "外套", "西裝", "韓劇", "都敏俊", "同", "款"],
["舒適", "休閒", "素面", "中性", "百", "搭", "休閒", "鞋", "5", "色"],
["防風", "外套", "防水", "透氣", "防曬", "輕薄", "騎士", "外套"],
["經典", "不", "敗", "夏季", "薄", "款", "牛仔", "襯衫", "輕薄", "外套", "微", "刷色", "深藍", "/", "淺藍"],
["小", "曼", "超", "愛", "款", "🎉", "特價", "🉐", "韓國", "打", "版", "一字", "涼", "拖鞋", "(", "二", "色", ")"],
["氣質", "穿", "搭", "台灣", "手工", "尖頭", "氣質", "繞", "踝", "平底鞋"],
["Vans", "專櫃", "代購", "經典", "款", "學生", "最愛", "帆布鞋"],
["人氣", "冠軍", "👑", "👑", "百", "搭", "單品", "❤", "不", "咬", "腳", "金屬", "簡約", "軟", "底", "平底鞋"],
["藤麻", "編織", "金屬", "皮革", "懶人", "鞋", "/", "平底鞋"],
]
```
```python=
query_str = "氣質 外套 鞋 牛仔" # 查詢字串
query = query_str.split(" ") # 依空白切出各查詢詞
query
```
```python=
doc_score = []
for i in range(len(saleDoc)):
score = 0
for q in query:
if q in saleDoc[i]: #多次出現仍+1
score = score + 1
if score > 0:
t = [score, saleDoc[i]] #[分數,類型]
doc_score.append(t)
doc_score.sort(reverse = True) #按分數高低排列
doc_score
```
```python=
synset = [ #同義詞
["舒適", "休閒"],
["氣質", "優雅", "經典", "雅痞"],
["拖鞋","平底鞋"],
["皮革","鞋"]
]
def is_synonym(x, y):
for sy in synset:
if x in sy and y in sy and x != y: return True
return False
def has_synonym_in_doc(token, doc):
for w in doc:
if is_synonym(token, w): return True
return False
```
```python=
doc_score = []
for i in range(len(saleDoc)):
score = 0
for q in query:
if q in saleDoc[i] or has_synonym_in_doc(q, saleDoc[i]):
score = score + 1
if score > 0:
t = [score, saleDoc[i]]
doc_score.append(t)
doc_score.sort(reverse = True)
doc_score
```