2020年5月18日月曜日

[Web開發] RxJS 鎖鏈戰記


開始接觸Angular 9,沒想到前提是必須了解RxJS跟TypeScript。過程中也遇到許多難以理解的部分。
加上RxJS本身的精神就是連鎖處理,聯想到S社的手遊チェインクロニクル,簡稱チェインクロ,戲稱chain苦勞,於是有了這個標題。

本篇先談RxJS的部分。TypeScript的定義部分就不討論,加上TypeScript的定義,複雜度會直線上升。
希望看到的各位不再chain苦勞。

2020年3月31日火曜日

python基本規格測試

 之前寫的python規格測試用的東西。可以用jupyter丟進去觀察結果。


#!/usr/bin/env python3

# -*- coding: utf8 -*-
# 除了迴圈/if判斷/函式定義/class定義需要冒號":"之外,行尾不需終結符號
# 註解建議使用linux script style : 井號後面加上空格再開始寫
# 可以跳行的長字串: 使用三個雙引號定義(""")
#     第一個沒有被指定變數的長字串會被當成 class的 docstring (可用變數名稱 __doc__ 存取)
# 靠縮排4格來定義下一層的指令(函數,迴圈,判斷式的後續動作等等)

import sys # for console arguments

""" 這是長字串
第二行 """

longStr2 = """ 這是長字串2
 2的第二行 """

print("arg0=" + sys.argv[0])
print(longStr2)
print(__doc__)

__doc__ =""" 這是長字串3
3的第二行 """
print(__doc__)


print('unicode -------------------------------------')
strTmp= '一二三四' # 變數不需宣告,也會持續存在。重複使用時的初始值必須考慮。可以用del指令刪除變數。

# 注意,一個變數被assign初始之後,不要再assign不同的資料結構,容易出現不明問題。

i = -1
j = 6
print(strTmp[i:j])  # 多碼字不是以byte計算,以一個文字為單位。
print(strTmp[1])


# 使用陣列index做存取,在超過陣列範圍的情況下,會產生outbound index exception, 但是套用array slice則不會。
#    slice可以為負值,不管起終點都是指從陣列尾倒數。
# 字串物件其中的字不可被修改,只能經過處理產生新的



# 序列資料結構: list  [obj1, obj2, ...] ,可以單獨置換list元素,可以slice指定置換list元素,可以接合兩個list
# slice的置換可以只給1個元素"z",也可以丟list["y","z"],起點跟終點相同的話,視同插入。

print('list -------------------------------------')
arJ =  [3,4]
arI = [0,1,2] + arJ
print(arI)
print(len(arI))
arI[0:0] = "x"  #在陣列頭插入
print(arI)
arI[0:1] = "y"  #在陣列頭置換
print(arI)
arI[2:4] = ["a", "b"]  #在陣列中置換。
print(arI)
arI[2:3] = ["y", "z"]  #在陣列中置換。注意:若是slice的起終點的差,小於置入陣列的大小,視為插入。
print(arI)
arI[0:1] = arI  #在陣列頭插入自己,結果是會重複內容
print(arI)


# 多層list, 不可使用slice方式置入
arI[2] = arJ
print(arI)


# 迴圈, 條件表示式,需在尾巴加上":"

print('while loop -------------------------------------')
i = 0
j = 0
while (i < 10):
    j = j + i
    i = i + 1


print(j)

pass # pass: 不做任何事情。 在一定要有命令行的地方可以發揮作用。



# 序列資料結構 touple: 小括號"()"表示。只有一層可以不寫小括號,直接用逗號定義內容,
#     但是第二層之後必須有括號(obj1, int2, ...) ,應該是故意要跟function call相同
# 建立之後不可改變內容,但是裡面的元素可以改變內容。性質與list類似。元素內容有順序,可重複元素。
# 可使用index存取: touple[0]
# 建立0個元素的內容: 固定指令()
# 建立只有一個元素的內容,必須在後面加上逗號。 (obj, ) 原因猜測是會跟function call parameter重複定義



print('touple -------------------------------------')
x = "x"
y = "y"
z = "z"

touple = (x, y, z)  # touple packing
a, b, c = touple  # 可以拆解。 注意變數數量必須跟touple的元素數量相同, 太多或太少都會出ValueError
print(touple)
print(touple[0])
print(a + b + c)



print('set -------------------------------------')
# 序列資料結構 set: 以大括號"{}"表示。 而且跟list一樣必須寫。
# 元素順序由系統自行決定不可自訂(操作前是固定的,操作後不保證會不會變動)
# 元素內容可變,但不可重複。放入重複元素會以後蓋前的方式運作。
# 無法循序存取,只能遍歷。有基本的add / remove / pop / clear操作
# 建立0個元素的內容: 固定指令set(),不可使用{},會建立另一種資料結構:dict。
# 無刪除元素指令

a = set('abracadabra')  # 注意: 以set()初始化字串的話,結果會是一個單字串的set
b = set('alacazam')
print(a)
print(b)



# 序列資料結構 dictionary : 同樣以大括號"{}"表示,但是定義內容以key: value的方式定義。 運作方式類似java的map, objective c也有dictionary。
# key必須為不可變的物件,像是字串,數字,boolean。也可以用touple定義,但是此時的touple不可包含可變元素。
# 元素有順序,內容可變,要列舉可以用list(dic)取得key list,也可以用dict.items()取得key-value iterable
# 無法直接取得value list。使用 in 運算子只能比對key。
# key: value必須同時存在,key值不會重複,跟set一樣,設定重複的值會以後蓋前的方式運作。
# 比對兩個dict相同,不會管key值順序。



print('dict -------------------------------------')
tel = {'jack': 4098, 'sape': 4139, 'sape': 4140}
print(tel)
tel['guido'] = 4127  # 可使用list運算存取。
print(tel)
del tel['sape'] # 可以用del指令刪除key(value也會消失)。刪除不存在的key會出現KeyError。
print(tel)


tel = dict([('sape', 4139), ('guido', 4127), ('jack', 4098)]) # 可以靠touple定義key: value值
print(tel)
tel2 = dict(zip(['one', 'two', 'three'], [1, 2, 3])) # zip(): 把兩個同元素數量的序列以順序合併成touple組合
print(tel2)






# for : 只能對陣列型物件操作。 要寫一般的數字跑法的話,可以使用range(起始, 終點, step)產生iterable物件。
# 或是使用此法產生數字陣列: list(range(起始, 終點, step))
# for的list操作,建議使用slice功能產生copy,避免即時操作list導致iterate成為無窮迴圈
# for/while else : 疊代跑完沒被break的話就執行。若是要設計find流程好用。
# 其他技巧: 可以用dict.items()取得key-value iterable
# 可以用enumerate()取得index-value touple(iterable)
# 二階迴圈可以靠zip()實作

print('for loop -------------------------------------')
i = 0
for ar in range(10): # 只會跑0 ~ n-1的部份
    i = i + ar

print(i)
print(ar)  # 回傳值為9 (也就是n-1)。 參數會持續存在。



for f in enumerate(a):  # 印出來會是touple組合。
    print('enumerate {0}= {1}'.format(f[0], f[1]))


index = [0, 1, 2]
value = ['a', 'b', 'c']

for i, v in zip(index, value):  # 二階迴圈可以靠zip()實作
    print('index[{0}]= {1}'.format(i, v))

   

   

   

# function : 不可控制外部變數,除非以global做特別宣告。 參數加上預設值代表option參數(caller給不足參數的話就會使用預設值)
# 沒給預設值的參數,caller必須給值,要不然執行會錯誤。可以不照參數順序給,但是要使用<parameter name>=value的方式指定
# 使用<parameter name>=value的方式指定,不可重複給同一個參數值
# option參數也可以不照順序給,同樣使用<parameter name>=value的方式指定
# option參數的預設值假如是物件的話,操作過的結果會被保留。若是有重複call的動作要注意。解決方案如下面的程式碼的參數z。
# 函式的參數可以帶函式(因為函式本身就是一個物件)。
# 函式物件的物件定義: function.__self__ --- 一個帶著函式方法fucntion()的物件。
# 函式物件的函式定義: function.__func__(self, param1, param2, ...) --- 等同於class method。
# 參數名帶*號,會收集傳進來的所有照順序給的參數(除了已指定的之外)。
# 參數名帶**號,會收集傳進來的所有<parameter name>=value的方式指定的參數(除了已指定的之外)。
# 傳入順序參數時,可以利用list傳入。 但是要在參數名前面加上*號
# lambda function: 單行的無名function可以不需寫def來定義。參數可以參照上層。
print('function -------------------------------------')

def plusplus(n, x=1, y= ["zzzzz"], z = None):
    if z is None:
        z=[]

    n = n + 1  # python沒有累加算符(++)
    x= x + 1
    print(x)
    y.append("a")   # 操作的結果會被保留
    print(y)
    return n        # 不指定回傳值(包含只寫了return)的話,caller會接到None這個物件。


print(plusplus(i))
print(plusplus(i))
print(plusplus(*[i, 2]))
print(plusplus(i, y=['yyyyy'])) # lambda function
print(i)


def funcplus(a,b):
    return a(b)



print('function parameter -------------------------------------')
print(funcplus(plusplus, 1))


# 判斷式if : 可以用 in (datatype1, objet2, list3, ...) 的方式比對一個個obj。這種touple表示的物件,因為只比對第一層的obj表列,並不會比對陣列內部內容
print('if else elif -------------------------------------')
if (arI) in (45, arI):  # in也是比較運算子。其他的比較運算子: == && < > <= >=
    print("here")
else:
    print("there")

if ([4, 3]) in arI[:]:  # in直接丟一個list物件進去的場合,不同的list, 只要順序跟內容相同,就會被找到
    print("revarray")

if (arJ) in arI[:]:  # 不只是同一個list,不同的list, 只要順序跟內容相同,也會被找到
    print("array")

if ([3, 4]) in arI[:]:  # 不只是同一個list,不同的list, 只要順序跟內容相同,也會被找到
    print("newarray")

print(arI in (45, arI)) # 簡易比較的寫法。其他語言也有



# 資料型態: None (一般語言的null,注意大小寫,是系統預設的物件)
# NaN : 非數字,是系統預設的物件
# boolean : True / False (注意大小寫)
# assign 的動作只能出現在左端,不能出現在比較式內。
# None的比對敘述: if a is None:


# 模組: import 之後會跑一次模組檔案的內容,也就是所謂的初始動作。
# as : 別名
# 模組內參數存取:modname.itemname
# 模組只會初始化一次,而且永久有效。所以要是import過之後改了模組,在不重啟python執行器的狀況下要更新模組,
# 可以 import importlib,再執行 importlib.reload(modulename) 。

# 如何讓模組判斷現在是當成主程式在跑:  if __name__ == "__main__"   這樣方便單獨測試。

# 模組路徑: 1. 主模組執行的同一個目錄 2. PYTHONPATH
# 如何增加模組搜尋路徑: sys.path.append('<路徑>')

print('import -------------------------------------')

import requests as http

print(dir())  # 這樣可以印出目前有用到的所有method跟變數。



headers = {
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
    "Accept-Language": "zh-TW,zh;q=0.8,en-US;q=0.6,en;q=0.4",
    "Accept-Encoding": "gzip, deflate",
    "User-Agent": "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.89 Safari/537.36",
}

url = "https://udn.com/news/story/7338/4091931"



# print(sys.path)
# try:

# r = http.get(
#    url, verify=False, headers=headers, timeout=(10, 30)
#    )  # ,proxies=proxies)
# except:
# print(r.text)


# 例外處理 : try / except 一個try可以有多個except, 若是except沒指定,會傳到上層的try / except。 都沒捕捉的話就拋出系統錯誤,停止執行
# except可以一次捕捉多個。  格式: except (RuntimeError, TypeError, NameError):
# raise : 丟出例外
# 在例外處理中再丟出例外,就是給上一層處理。
print('try except -------------------------------------')




print('class -------------------------------------')
# class定義方式: class ClassName(Extend from class1, Extend from class2, ...):
# self : 物件本身 (就是java/c++的this)
# class的初始化: 定義函數 __init__(self, arg0, arg1,...)
# new一個class(產生一個class物件): ClassName(arg0, arg1,...)
# 物件函式與class函式的關係: 假設x為MyClass的物件, x.f() 等同於 MyClass.f(x) 。python不分class method或是object method...
# class內定義參數的話,所有從同一個class產生或是繼承的物件共享該參數。
# class method要操作物件的參數,必須以self操作。
# object.__class__ : 判斷該object是哪種class(就是傳回該物件的class定義結構)。
#    預設的class比對方法: isinstance(obj, <classname>)
#    是不是繼承class的比對: issubclass(object.__class__, <classname>)

# class內部參數: __name__ ,會給class的可讀名稱
# 定義一般函式,要給class/object 當作method用的話,第一個參數必須是self。

# 繼承可以指定模組內的某個class。
# 繼承來的class function可以改寫(因為沒有特別的阻擋機制)
# class function改寫後要call baseclass的函式也是可以的。就直接執行class method即可。
#   例:BaseClassName.methodname(self, arguments)
#   要注意,假如是class中的class,就不能這樣做。

# 空的class :  在class定義後加上一行"pass"。 就可以拿來放任何東西,不過這樣做比較難掌握其內容。(是可以靠dir()來列舉...)


class MyClass(int):
    def __init__(self):
        self.lArray = []
       
    def add(self, x):
        self.lArray.append(x)


myClass = MyClass()
print(issubclass(myClass.__class__, int))
print(myClass.__class__ is MyClass)
print(myClass.lArray.__class__.__name__)
print(myClass.add.__self__)
myClass.add.__func__(myClass, "a")
print(myClass.lArray)


print('namespace -------------------------------------')

# Namespace: global --- 此參數定義之後,會影響模組的最上層的區域。
#            nonlocal --- 此參數定義之後,會影響下了該定義的階層的上一層。
# 不建議依賴系統的動態變數解析。(乖乖的傳參數的意思)

def scope_test(): # 第二層
    def do_local(): # 第三層
        spam = "local spam"  # do_local 內部的spam

    def do_nonlocal():
        nonlocal spam # spam 定義在上一層。
        spam = "nonlocal spam" # 此例上一層已定義spam = "test spam", 所以執行此動作的話,第二層的spam會被定義為"nonlocal spam"

    def do_global():
        global spam # spam定義在此模組的第一層
        spam = "global spam" # 這時第一層的spam才被賦值

    spam = "test spam" # 第二層的spam定義。不會影響第一層
    do_local()
    print("After local assignment:", spam)
    do_nonlocal()
    print("After nonlocal assignment:", spam)
    do_global()
    print("After global assignment:", spam)

scope_test()
print("In global scope:", spam)  # 第一層




# iterator
# 只要該物件/class有實作__iter__(self), __next__(self),丟出StopIteration的動作的話,就可以被迴圈用來迭代。
# python原生函式: iterator = iter(obj) --- 獲得該物件的迭代器。
# python原生函式: next(iterator) --- 執行一次迭代。通常會回傳迭代物件
# 下面是一個簡單的可迭代class的實作。
class Reverse:
    """Iterator for looping over a sequence backwards."""
    def __init__(self, data):
        self.data = data
        self.index = len(data)

    def __iter__(self):
        return self

    def __next__(self):
        if self.index == 0:
            raise StopIteration
        self.index = self.index - 1
        return self.data[self.index]
   
print('iterator -------------------------------------')
rev = Reverse('spam')
iter(rev)
for char in rev:
    print(char)

   
   
# generator : 不需定義class就可以產生可迭代物件的方法。
# 只要函式定義裡面使用yield關鍵字(作用是回傳物件),就自動成為可迭代的動作。
def GenReverse(data):
    for index in range(len(data)-1, -1, -1):
        yield data[index]

print('generator -------------------------------------')
genReverse = GenReverse('abc')
print(next(genReverse))
print(next(genReverse))
print(next(genReverse))

2019年12月7日土曜日

[禁止酒駕]2019/11/15~18 台北國際酒展

禁止酒駕,未成年請勿飲酒
禁止酒駕,未成年請勿飲酒
禁止酒駕,未成年請勿飲酒
禁止酒駕,未成年請勿飲酒
禁止酒駕,未成年請勿飲酒
禁止酒駕,未成年請勿飲酒
禁止酒駕,未成年請勿飲酒
禁止酒駕,未成年請勿飲酒
禁止酒駕,未成年請勿飲酒
禁止酒駕,未成年請勿飲酒











































今年的11月,是酒鬼的11月。連續三場大型酒展的第三場。 試酒試到爽。
每一年都覺得似乎差不多,不過總有些新發現, 也至少會排一天。看狀況增加參觀日數。
這次個人覺得很有料。也因此參加了兩天。

參展前的準備:雞二。每週一次也吃不膩。

場內狀況。





這兩支是擺在玻璃瓶廠的攤位,應該算是瓶子的sample。
孤陋寡聞,查了資料才知道是澎湖第一酒廠的產品。 有機會再試。

新參展的攤位帶了四套AMARONE+RIPASSO。給試的門檻有點高所以就只試了一兩支。


corte merci ripasso:
聞: 明顯的新鮮莓果香,古早糖香,些許肉桂。
喝:酸2, 新鮮果香,莓果,清爽,甘草,圓潤,單寧有,味道飽滿。
corte merci amarone:
聞:果香,稻草香。
喝: 酸1,單寧中等,清爽,甘草,回甘,紅葡萄皮味。放久之後果香會增強。
這系列是清爽型。還是比較喜歡強勁型的...

Ripa della Volta valpolicella:  valpolicella產區的分級是valpolicella < ripasso < amarone。
聞:果香,紅葡萄皮
喝:酸2,中等丹寧,清爽


Ripa della Volta ripasso :  也是清爽型的。
聞:苺果香,帶些稻草香。
喝:酸2, 甘草,單寧強勁,清爽。

 純展示。畢竟都不便宜。

這兩支都是非加烈製法的高酒精度甜酒。
moscarel de setubal:
聞:麝香葡萄味,帶些氧化的桂圓氣味。
喝:甜度比可樂弱些,酸度有。 李子,蜜餞,味道強度中等。
moscel roxo:
聞: 麝香葡萄味,帶些氧化的桂圓氣味,花香,古早糖香。
喝: 甜度接近可樂,酸度明顯,有清爽感,草香,薄荷涼感,味道強度中等。
第一隻比較一般常見的麝香葡萄甜酒的感覺,第二隻就蠻喜歡的。

planeta passito :
聞:檸檬為主要風味。鳳梨,糖香,梅李
喝:甜度接近可樂,酸度明顯。 入口先有酸度,然後是稻桿,梅李。杯底蜜餞,微微的果醋味,糖香。


carlos .i:40%雪莉白蘭地。
聞:葡萄梗,雪莉酒花,氧化雪莉酒。
喝:刺激感,飽滿的雪莉酒花味,味道強度中等,有水感

parse rum 3y:
聞:木香,糖蜜蒸餾香。
喝:飽滿木香,苦澀。
這系列的桶味強勁,應該是用新桶。

parse rum 8y: 木桶苦澀味較圓潤。

 這隻就沒試了。

加賀香檬(50%):
聞:明顯的香檬味。酒精味少許。
喝:刺激感強,飽滿的香檬味,微苦。杯底有米味。尾韻香檬味蠻長。
檸檬蒸餾酒來說是做得不錯的一隻。想要求沒有米味大概是有點難...
還是得靠基酒浸泡之後再蒸餾。

純士忌(58%):
聞:氧化木桶味,
喝:刺激感強,有酸澀感,氧化木桶味。
多種穀類混合發酵蒸餾,可以感受到各種威士忌的影子。桶味太搶眼...

這系列是用威士忌原酒,以在威士忌的製作上少見的萃取法製作。
blue lionfish (62%):
聞: 主麥草香,木醋味。
喝:強烈的橡木香氣,苦澀。
blue lionfish (90%):
聞: 只剩草香,酒精味。
喝:強烈的麥草香,強烈的苦澀感,後味是強烈的麥草香,麥味。

62%的比較剛好。可以得到比威士忌原酒更強勁的味道。
90%就有點過頭了...

這隻92%高粱也是使用萃取法製作。喝起來的感覺就是濃縮高粱...
超過60%的都不建議大量喝,會傷人體。用沾的就夠了。


holy 米 new make(68%): 
聞:草香,酸醋味,爆米花味,些許油臭味。
喝:飽滿的花草香,酸澀,尾韻甘甜。
可以想成是米酒。米做蒸餾之後可能比較適合做成vodka。畢竟日本已經有一隻「白」可以做參考。甘甜感會是其他的穀物vodka比較少見的。

holy new make(55%):
聞:草香,麥香,爆米花味,釀造醋味,發酵臭味。
喝:麥香,糖香,酸澀,尾韻有不錯的爆米花味
酒廠在鶯歌,現在可以登記參觀,有機會來去看看。

holy rum(42%):
聞:波本桶香,麥香,草香,
喝:台灣的亞熱帶氣候久放之後獨有的強烈果酸感,跟木桶雜味...
沒有新酒可以試,用新桶的話味道說不定會比較純淨。

vecchio amaro del capo: 算是藥草酒。
聞:主味橘子,香草,甘草,糖香。
喝:甜度接近可樂。橘子,香草,甘草,糖香,八角
有著藥草酒少見的橘子味。還蠻喜歡的。

byejoe(40%):美國製清香型高粱酒。
聞: 的確是高粱味。酒精味。清香型。
喝:釀造的酸感。
完全是基本款的感覺。

riga black original(45%): 藥草酒。
聞:焦糖香,果香
喝:強烈的甘草味跟甘草香,酸味,澀味,不錯的回甘。
也是之前不知道,試了之後被感動到的一隻。個人還是喜歡經典款。




jawbox 貝爾法斯特 gin(43%): 標準琴酒。
聞: 基礎琴酒味。

london lima gin(42.8%): pisco為底的琴酒。
聞: 香草,葡萄,苦味。
喝:強烈的香草,香菜味,些許胡椒,刺激感強。杯底葡萄香很棒。
可惜價格偏高,要不然也是會當場出手的一隻。

1770 peated, ex-sherry, virgin oak(46%):
聞: 花香,煙燻偏炭。
喝: 明顯的碳味,帶出煙燻味,中度煙燻,烏梅,澀感。



酒區逛得差不多了。到四樓看一下咖啡區的狀況。
基本上這個展的主體是咖啡展。佔了一整個南港展館的四樓。有不少國家來參展。

原來現在的雙層玻璃杯可以做到這樣...

還可以分色。

還可以單雙分層。不過上層感覺保溫效果就差了點。


連咖啡壺都可以做成雙層的。這個真的相當有興趣。咖啡保溫也很有用。

usb致冷的冷萃器。

 這次參展的最大衝擊:人頭馬君度有做烘焙用酒。

根本就是把市售版本打趴了... 氣味飽滿。
不過要注意的是這是寶特瓶裝。瓶身是不是比較容易產生影響就不確定。

rum因為平常就是喝高酒精度的,沒留下太多印象

這隻就是強烈推薦喜歡植物學家的人一定要試看看的。60% ,超越海軍強度的版本會給你更強烈的感受。

君度橙酒(60%): 應該是拿40%版本再蒸餾一次的結果。
聞:香精等級,極強烈的橙皮味橙油味。
喝:除了極強的氣味之外,強烈橙油帶來的刺激跟辣感。
這隻的確就不適合純飲。拿來做橙味調酒也會比一般的Triple sec要再更強勁。
場內試吃橙味的蛋糕也覺得是天然的橘子味,很棒。

amaretto 60%:
聞: 高級天然的杏仁香。
喝:就像是在吃大量的乾杏仁。 杏仁的天然苦味,杏仁皮味,杏仁油感跟澀感。
也是前所未有的體驗。之前在國際食品展看到甜點烘焙用的食材原料酒,也沒有一隻是這種強烈又天然的味道的品項。

manzana verdes(18%)
聞:飽滿的青蘋果香。
喝:甜度比可樂低些,有酸度。舒服天然的青蘋果香跟酸味。


這隻的味道是基本款。味道強度也不差。




二日目,把第一天看到比較在意的酒款試一試。


BRACHETTO D'ACQUI(甜紅酒):
聞:明顯的古早糖香。新鮮梅子。
喝:甜度接近可樂, 有酸度, 微澀,梅子,清爽,味道強度中等。




monti garbi ripasso:
聞: 古老木頭,烏梅。
喝:酸度強勁, 枯葉,古老木頭,中等單寧,苦澀,圓潤,回甘。味道強度結實。
令人印象深刻的一隻。

這兩隻Grappa(40%)都是溫和不刺激,適合入門。喝習慣強酒的筆者覺得偏弱...


sotto sopra:黑莓酒
聞: 古早糖香。莓果香。
喝: 甜度接近可樂,酸度強勁, 單寧中等,果香,清爽。

tenura ripasso :
聞: 古早糖香。紅葡萄皮,莓果。
喝:有酸度, 強勁單寧,澀,稻草味。
還不錯的一隻。

vieni icewine graspa(43%):
聞:葡萄渣,果香。
喝: 強烈的渣味,刺激感明顯。

prism icewine:
聞:梅子,蜜熟鳳梨。
喝:比可樂甜上不少, 酸度強勁, 梅子,香氣弱。不膩。


palatine hills 2007卡本內冰酒:
聞:烏龍茶香,糖香,烏梅香,
喝: 甜度接近可樂, 帶苦澀,甘草,茶香,紅葡萄皮。
印象深刻的一隻。

本次的新認識:澳洲的Ruthenglen產區。
rutherglan topaque(17.5%):麝香葡萄加烈酒。
聞:甘草,蜂蜜,中藥,葡萄乾。
喝:甜度明顯,有酸度, 蜂蜜,甘草。味道強度中等

rutherglan muscat(17.5%):
聞: 玫瑰花香,蜂蜜,甘草,中藥。
喝: 甜度接近可樂, 甘草,葡萄乾,蜂蜜。 味道強度中等
味道比較有中藥感的加烈甜酒。令人印象深刻。

法緹玉荷包(30%):
聞: 明顯的新鮮荔枝香。
喝: 甜度接近可樂, 飽滿的新鮮荔枝果汁香氣。
跟乃姬30%很像的做法。感覺酒體比較輕...

brookfields vionier late harvest 2016:
聞: 蜂蜜檸檬,糖香。
喝: 甜度接近可樂,酸度強勁, 蜂蜜檸檬,帶苦,梅子味。清爽,味道強度中等。

蘋果苦艾酒。清爽型。

接著回到4樓試一下海地展區的酒。第一天太晚到結果已經收攤了。

vieux labbe special(40%): 三年的rum。
聞:明顯的糖香,新木桶香。
喝:明顯的桶味,帶酸味,甘甜。刺激感明顯。



vieux signature blend:
聞:紅糖香,苦味。
喝: 氧化桶味,糖香,苦味。

vieux 10y:
喝:桶味,苦味,甘草味,巧克力。刺激感有。
款式整體偏苦味。在懷疑是不是舌頭快不行了...


最後一攤:永遠的白水芳華。喝了之後其他攤也不用去了。試試新產品。
玉米酒(酒精度送驗中,約60%):
聞:玉米蒸餾味。
喝:波本威士忌味。多了白水獨有的銅蒸味。

黑麥酒(酒精度送驗中,約60%):
聞:rye(裸麥威士忌)味。
喝: rye味,酸,烘麥味。


天恩黑糯糙米(59.5%):
聞:草味,黑糯米香,
喝:黑糯米香,甘甜。烤地瓜味。