|
什么是传染病动力学?numpy和matplotlib用python实现传染病模型SI模型SIS模型SIR模型SEIR模型 什么是传染病动力学?最近,在报道疫情的众多新闻中,相信大家也看到过一些来预测新型冠状病毒会导致感染肺炎的人数。你一定好奇,这个人数要怎么预测呢?预测人数又有什么用呢? 事实上,从学科方向来说,这类研究属于传染病动力学,就是用数学模型去描述传染病在人群中传播的规律,从而预测患病人数,进而指导政府制定措施和政策去控制传染病的传播。" `' T3 b4 u9 i+ B+ a7 O5 l7 ]! l
这类研究最早可追溯到18世纪Daniel Bernoulli对天花的研究,而我们今天所要介绍的SIR模型是1927年Kermack与McKendrick在为了研究伦敦黑死病而提出的,是传染病动力学中最基础的模型。 介绍了传染病模型的背景信息,不知道现在你对传染病模型更有兴趣,还是执着地对python更有兴趣呢?不论哪种,这篇文章会满足你所有的好奇心。 numpy和matplotlib首先,安装一下这节课我们需要使用的两个python包,numpy和matplotlib。& `, W+ z4 t) C+ s% }1 n
numpy-是python进行科学和矩阵运算最常用的包。 用numpy建立一维数组,存储和计算每天传染病人数的数据。
" S' J1 ]- i; l \, e5 b/ F& nimport numpy as np import matplotlib.pyplot as plt 用matplotlib绘制传染病人数随天数变化的曲线,给出模型预测人数变化的直观认识。 好啦,下面开始用python实现传染病模型吧。 用python实现传染病模型为了让大家能够更好地理解,我们先不直接说SIR模型,我们从最简单的开始。 SI模型首先想象这样一个场景,一个城市有 个人,假设没有人出生和死亡,忽然有一天有 个人感染了病毒成为了患者,如果每天每个患者能够有效传染 个人,那么第二天患病人数是多少呢?最简单的答案是: ,也就是说每天都会新增 个患者。那这样以来,在无限远的将来会有无穷多的人被感染,显然这是不合理的,那错在哪里?仔细思考,你一定发现了,已经患病的人就不能再被传染了,所以我们有必要把人群分为两类,易感者(S-susceptiable)和感染者(I-infective)(你猜的没错,这就是SIR中S和I的含义,R的含义之后介绍再讲)。为了之后方便计算我们记易感者和感染者在人群中的比例为 ,那么 。我们重新考虑上面的问题,顺便来个示意图: Image Name这样的话,每天新增的患者数为 ,也就是总传染人数乘以易感者所占的人群比例。
7 h9 ]1 k8 v2 r/ l7 b/ M7 x那么每天的感染者比例的增加量就是 。我们假设城市有一千万(N=10的7次方)人,每个患者每天接触感染每天0.8人(lamda=0.8),初始感染人数为45人(i0 = 45/N),我们来模拟70天(T=70)的情况。 # population
8 o+ _4 d4 m* W. L' K( qN = 1e79 o- t5 Z0 J4 A: w5 J
# simuation Time / Day
3 i% J' n7 q$ e n0 dT = 70; S5 ~5 p# }) Q {% O/ r
# susceptiable ratio; g! O, H. k! H4 t# ?5 t
s = np.zeros([T])
* E2 d8 Z# E2 F4 L4 K- ?# infective ratio. Z( t3 H# B: ?
i = np.zeros([T])
# B1 R( p. i0 G v6 c8 {9 W# contact rate
- N9 V$ v' Y$ K$ V3 ulamda = 0.8: t3 y% `5 R. c4 o5 A
' ~4 n& M+ {/ n" S' r1 w- c
# initial infective people
& t% d* w$ B! oi[0] = 45.0 / N
. O7 @2 T& G/ X9 t4 P& _( t3 U9 i( X+ Z4 e/ |* x
for t in range(T-1):7 \, [- X' |/ z7 Y& _8 U S
i[t + 1] = i[t] + i[t] * lamda * (1.0 - i[t])
4 g4 [: B) P# Z* R4 J/ `! m( U/ x' M7 b1 t
: d) i0 d4 I# Y5 b7 I
6 J f) h! u& Z( t- z+ q& @' r
相信其他语句大家都明白,新知识是这两行:
8 p- u' k: t9 R5 \8 g# M6 {) s% {9 m4 T9 }; m8 v
: s- q- Q! F: }$ C
s = np.zeros([T])+ g1 o, V- R1 t
i = np.zeros([T])% e0 o' r1 z/ Q2 J1 d) S, H
1 E) n) ~% a( S' L6 s5 S* f; y
这两句话的意思是一样的,就是利用numpy(已被我们重新命名为np)的函数(zeros())来建立一个所有元素都是零的数组,而给的参数决定了这个数组的维度。比如:$ w% ~" J5 |% D+ R" P9 Q7 p/ p
3 |* G6 w/ V3 p. t4 s) p6 [a = np.zeros([2,3])0 O j! \ D/ M. @1 P- V
a7 o) p1 n8 ~. m
% c* G- c- o$ sarray([[0., 0., 0.],9 ?5 t/ Z% d+ ?6 w- I" R2 N
[0., 0., 0.]])/ H4 b7 t# y, n& _" A( i
/ O# R+ a. X; j2 V7 s. O9 S# r: p+ q, _& j$ G% l8 @& D7 R
array([0., 0., 0., 0., 0.])
8 Q$ H; B0 q5 A0 W" B" n
% F M4 ]6 k! p% c2 T' k: H' N: u3 E) n) f/ R
类似的还有产生元素全部是1的数组的函数np.ones():5 P5 P2 ] N$ A! s: Z! K
& C+ Z2 G7 f0 f- B4 Qa = np.ones([5])
7 A' a6 b4 I) _7 d3 ^2 S$ y1 Aa' b, x z, u0 L
( d2 Z4 H9 j, L& `% B% D, ~array([1., 1., 1., 1., 1.])
; P2 W0 C) A" A) @, E: Q- E' I+ Q0 Q! P5 Y6 S, E* j
}& f& u1 e$ K. O; J7 Fa = np.ones([2,3])
. i' G9 U4 @' X% g' {a( E. E$ W- c7 E4 D l7 m1 I. ?5 d
" E( j a: r; J4 C8 l
6 z; G' m/ t1 D! Q4 Earray([[1., 1., 1.],8 Z t0 ?; l8 X" j+ q7 v, z) @, d
[1., 1., 1.]])1 }1 }% E$ B8 C; p1 c
, [' _/ G6 a4 A" F5 X4 e6 r% R$ h1 y6 S* g* [
plt.plot(i)7 c2 C V5 b0 j; B
* j. d C( z6 O! W( g E1 s, c$ }! Q
[<matplotlib.lines.Line2D at 0x7f0c2768d6d8>]2 ]: e9 z- @5 R# J6 L
1 p( u! a1 Y) I4 ?9 T3 L9 {, V4 t4 W- s, g& h1 q
$ n$ h0 h, [# m% T
5 n" ~( s' E3 b' z0 p2 ^# t8 e2 c8 J" A. h
实现SI模型的核心代码是第三个cell的第11,12行:6 g: f( A9 v. F+ X& L4 F; P, }
4 y3 a# R( K$ ]# Q0 }; [% Z0 \6 Lfor t in range(T-1):! n! H1 {* t' S
i[t + 1] = i[t] + i[t] * lamda * (1.0 - i[t]); G4 [6 O) b8 `1 w h+ G6 n6 Z
9 z6 ?+ J3 `: r' X就是我们建立的数学模型,利用python的for循环语句累加迭代的方式把每天的增加量叠加到感染者比例上。 运行代码完成计算,我们利用matplotlib的pyplot来画出感染者的随天数的变化曲线:
6 |- D1 \, E6 e' c" [6 W7 Z5 c: Efig, ax = plt.subplots(figsize=(8,4))
8 I0 P' E+ c6 H6 C) Uax.plot(i, c='r', lw=2)
+ w2 g0 W/ r# s5 s% i9 g% n5 b4 Qax.set_xlabel('Day',fontsize=20)
- I7 V, f; F* q) C# Wax.set_ylabel('Infective Ratio', fontsize=20)* h3 F J) i- A2 x
ax.grid(1)
* y" v' j b2 v& Zplt.xticks(fontsize=20)
* B, q# [$ g: |, o5 W: Iplt.yticks(fontsize=20);
4 ~- N: J% y: C6 Q3 ^
$ ~: ^8 E8 Q# i+ Z
+ D6 J& ?5 |! V( |# x+ R![]()
u1 Z$ J$ u$ S) `0 B) x( ?
: Q2 }% \/ h& a9 z0 Y3 {从这个结果看到,大约在25天左右,全部人群都会变成感染者,感染率 。+ w4 F; k9 j9 X$ ~4 C
在程序中我们假设每天每个患者传染0.8个人,你可以改变lamda的值,观察全部人群感染的天数的变化。* `( Z9 ]+ f6 }6 U
认真思考你会知道,lamda的现实意义就是该城市的卫生水平,衡量的是消毒,隔离这些措施执行得怎么样。回到传染病模型,按照SI模型计算的结果,我们全人类都会患病,这好可怕!原因是我们忽略了一个很重要的因素,那就是我们有奋斗在一线的医护人员,我们会被治愈!所以SI模型只适合研究具有高传染风险又不能被治愈的病(比如HIV)。 但是对于其他病,我们是可以靠医疗和自身免疫系统康复的,那么紧接着的一个问题就是,被治愈后还会再被传染上嘛?根据这个问题的回答不同,我们有了两个不同的模型,SIR 和 SIS。现在可以揭晓,SIR的R的含义了,就是移出者(Removed),现实含义就是指被治愈后不会再被感染的人。而SIS表示治愈后仍然还是易感者。下面我们用python来分别实现这两个模型。 SIS模型为了实现这个模型,我们需要引入新的一个参数,治愈率 。好啦,先上我们的新示意图: Image Name和SI模型做比较,区别就是计算感染者的增加数时要减去被治愈的人数。
$ e. I% P8 Y$ S3 \! [- ^8 E. j所以这时候每天的增加的感染者为: ,+ D) X- F) j% Q* p4 L/ v% q% B
增加的感染率为: 。
$ w3 J8 M( b, {" L模型完成啦,修改python代码:
( i5 F0 Q0 Q2 T. ]# susceptiable ratio
+ T4 r: z: w7 y3 L$ N& Q4 Xs = np.zeros([T])
5 ?9 G+ o7 y: ^$ b' y7 T: ^# infective ratio% R+ D$ u8 z6 z$ d& J
i = np.zeros([T])# {0 t- L9 p2 ?2 e$ F$ i4 p
! J5 [/ f, Y; E# k0 g$ F0 J# contact rate
9 a" J9 V. m8 u: I; x, rlamda = 1.06 M% `) c, @6 z+ B
# recover rate
- O# Z: O; A9 c9 x7 q5 sgamma = 0.5
& Y1 M, A0 ?# i2 t8 }2 _
7 o) c; I3 W2 W' t# initial infective people4 J W3 {" \5 A" G2 p
i[0] = 45.0 / N' J1 o4 H. d+ r
8 w% T( G( h% B. L- f8 O. F6 y
for t in range(T-1):
p0 C( B6 x7 K! E5 y; f0 `& t i[t + 1] = i[t] + i[t] * lamda * (1.0 - i[t]) - gamma*i[t]5 L9 J5 U1 _2 O8 t* X
4 X; k5 `5 l/ S( j
* }) h; L5 e& n7 E
& w- @6 d* P+ X& U% I# P. _! t运行代码,我们画出曲线(代码和SI模型的画图完全一样):$ `' I* i! d8 ?: x) |" y
# |* w2 C0 W. y& W7 c
fig, ax = plt.subplots(figsize=(8,4))
2 o6 G( B0 i. x/ y# W# w4 bax.plot(i, c='r', lw=2)/ o4 Y( R' h( f# i
ax.set_xlabel('Day',fontsize=20)
. ~+ T% {4 e: M5 e9 _6 A% u) uax.set_ylabel('Infective Ratio', fontsize=20) m* }( |1 W [" D7 l6 M" a
ax.grid(1)
' `0 k: d1 S$ @* gplt.xticks(fontsize=20)
7 M& f9 N% C* G( }/ w* W8 O- Z, aplt.yticks(fontsize=20);
' }8 j2 a5 T0 f
& j( h: A; l0 d3 H- k, S. `# L2 k6 k6 } 6 ~! h0 e' B$ j b1 S
& l" }6 \) F2 D
B' I. Z* L2 V) h0 U. @1 }0 ]
行代码,我们画出曲线(代码和SI模型的画图完全一样)
, m: l$ c6 w: m- A) P可以看到,达到最大感染率的时间退后10天左右,最后感染和治愈达到动态平衡,人群中有始终有一半的人感染着。所以,SIS模型适合研究具有传染性和反复性的流行病,比如常见流感。同样的,感兴趣的话,改变lamda和gamma的值,观察曲线的变化。和lamda不同的是,gamma的现实意义就是对这种疾病的治疗水平。 SIR模型加入了移出者,被治愈的病人不会再被传染,先上我们的新示意图: Image NameSIR 模型
# K( i( s3 d- c P' w注意到这里,人群被分成了三类,不再只有I和S,所以相比于之前的模型,我们需要找到新的约束关系。现在我们需要分别计算三种人每天的增加量了:
; ^( [0 I3 `9 p- 易感者:每天都在被传染,所以一直在减少,减少量为被传染的人数:
- 感染者:增加了被感染的人,减少了治愈的人:
- 移出者:增加了治愈的人:
; K# o7 b, |# U* Q
建模完成,修改python代码,并且假设人群普遍易感,新型疾病,初始没有移出者。 , P. g( e) g- X1 P& C
# population
- o! d3 V% I. N5 G" t2 rN = 1e7 + 10 + 5$ l; C# U/ V, }9 n2 H+ [+ ]
# simuation Time / Day" W( A' {! `0 b/ w P( X9 E$ M
T = 1708 Q- @/ {; E9 ]6 [) O) j0 {3 _/ z7 m
# susceptiable ratio) J. a* x; L; {+ Y5 ~, m7 ^: ^! C
s = np.zeros([T])
+ D) A9 x8 z9 W& d! z# infective ratio( u$ q. Y/ i, `& V" e! k
i = np.zeros([T])
& R, i# f9 B7 [5 Q8 E6 g# remove ratio
& M+ W! X8 Z V) {8 M. Wr = np.zeros([T])
2 l- \6 ]$ ^" G1 I5 P9 J) g0 H/ k* n+ P v/ M; O' m# Z. |
# contact rate
# A9 @7 m: ?. slamda = 0.2586
4 U$ t3 n7 S8 N; e# recover rate
0 m3 K V8 E3 D$ k& Fgamma = 0.0821, T9 \+ s5 J7 m
' X! X- q( J2 W; E% d8 B
# initial infective people
# n) J: P: r4 K2 q) Ji[0] = 10.0 / N
( O. J7 U" e! P) ]' |# Js[0] = 1e7 / N
% l( I o2 E8 }* u' m0 G& W6 I# Vfor t in range(T-1):& S; o# V8 @1 x, G& _
i[t + 1] = i[t] + i[t] * lamda * s[t] - gamma*i[t]8 c9 _8 s) R( }
s[t + 1] = s[t] - lamda * s[t] * i[t]
- L9 _) f2 q; e! C r[t + 1] = r[t] + gamma*i[t]
$ w8 A4 u, e' X! S4 Q8 y; i0 {9 }) y/ d$ s3 T$ t2 G) a, e
fig, ax = plt.subplots(figsize=(10,6))
E$ o+ Z1 |+ g/ H# O6 w' t* N6 eax.plot(s, c='b', lw=2, label='S')
+ j, o/ l7 ^2 xax.plot(i, c='r', lw=2, label='I')* o" O$ G& ?: e9 V" o1 K6 s
ax.plot(r, c='g', lw=2, label='R')
6 X$ s8 G' o) S! i t1 kax.set_xlabel('Day',fontsize=20)
0 [+ p6 U) m9 _+ t8 Dax.set_ylabel('Infective Ratio', fontsize=20)4 ^9 ?3 l+ S U- U' m$ N
ax.grid(1)
) L F# N/ ~4 }plt.xticks(fontsize=20)2 X6 L+ h5 w3 U$ m( C
plt.yticks(fontsize=20)
( x/ m, [1 `, j, y! Q) T( Yplt.legend();! A6 {: X* [3 B' N5 d
8 V& F" q' z- `. }
3 s2 o% G6 a* ?/ |3 A' y![]()
8 A6 T1 Q. I6 {
" r- b: V8 r- r4 q感染人数峰值发生在一个月左右,最大感染人数不到人群的20%, 但是最终人群的80%都会得此病(就是最终的移出者的比例)。SIR模型适合研究没有潜伏期的急性传染病,治疗后能够痊愈并具有抗病性。 到这里,虽然不准确,我们也可以先用SIR模型来分析一下此次疫情,武汉新型冠状病毒的传染病动力学! 模型有了,其实就是确定参数的问题。一开始就有人做了这个工作: Image Name于教授给的参数是参考了非典的, ,初始易感人数为一千万, 初始感染10人,初始移出者5人,那么我们的城市总人数 , 带入我们的模型得到结果:重现于教授的模型
/ @+ Z: T- x6 U( v高峰和尾声日期的推测基本相符。
* n# G- y8 ?/ k1 {! ^# susceptiable ratio. u# e3 f! Q! Z! `8 v* \
s = np.zeros([T]), L P0 m. X, S; ~, ^; [
# infective ratio
! O4 x, S) V3 Vi = np.zeros([T]). A" Q7 Z5 {' ^% {" N5 _% T
# removed ratio
: ]4 H. _4 m: h9 S9 x: Hr = np.zeros([T])
* d2 Q! I# l6 @& z# `4 ^! n5 T L- O$ b4 B
# birth ratio
" H6 v1 _4 W6 Db = 20.0 / N) ]# k8 d% O; c- m) X
# death ratio
" S! B' d* W: i2 b2 jd = 10.0 / N
' z) d# L$ c& m5 Z- ?7 H% P3 `+ R: v9 W" m/ S! u% q3 A
# contact rate: C" i3 _8 U, D0 D; \
y = 1.50 ?1 n, Z% o7 q8 o5 ~$ \
# recover rate
& L A" b" l. b- M: v# r! r4 @u = 0.8 # 1 / infective_period$ A2 E$ Z) ^- \2 s9 R' f- h5 @ ]
: \* z& B: b, x. m6 q
# sigma = y / u: r1 W+ F' F, ~. d0 n+ v: ^
$ A1 Q. t6 H8 o7 X: r5 b( d# initial infective people
) D ~$ o+ T I* ^! pi[0] = 45.0 / N4 B! ?+ U) H S/ O% n& |
s[0] = 1 - i[0]
+ X$ d5 f& d1 r4 \! W# ifor t in range(T-1):
+ V7 J' I2 L" J) [" y% i# c i[t+1] = i[t] + i[t] * y * s[t] - u*i[t] - d*i[t]; T. g' O! W/ z* l& k
s[t+1] = s[t] - y * s[t] * i[t] + b - d*s[t]
* k u! P' ~- \5 x! n- y6 A7 | r[t+1] = r[t] + u*i[t] - d*r[t]( _+ n$ \. `1 _: ~! a1 l
1 @. r+ a) _+ ^
plt.plot(i)! H8 @4 g7 h! e
plt.plot(s)( `; ^* f( f5 J! ?( x" @
plt.plot(r) ~# z8 A3 ^, _2 s/ V9 L6 q% x
plt.plot(np.diff(i),ls='--')4 u R A4 \8 m$ i
' @; b/ ~, E) b, I0 J
7 h- D. z) D# p: k. K[<matplotlib.lines.Line2D at 0x7f77796e8518>]. m) X1 T3 d* W* {7 H; _ M9 s6 h& H
1 K- C1 Z0 f5 r1 b0 l
![]()
4 I; W0 g3 z& V: _) h
% }0 M( f0 l1 _. a2 NSEIR模型但是,SIR模型和实际情况的出入会比较大,因为忽略了太多因素了,比如说潜伏期,比如说政策调控,药物,出生死亡等等。下面我们可以和前面一样,把潜伏期考虑进去,新增一个人群,叫潜伏者E(exposed): Image NameSEIR模型; [- z2 W0 q. N
同样的我们需要计算各人群每天的增加量: S:每天减少: 9 ^: s2 }5 C; p& Y+ G
E:每天增加传染,减少发病:
5 }6 @1 A# h z9 V* ZI:每天增加发病,减少治愈:
. r9 C; W. F! BR:每天增加治愈: & j$ s( C D+ _0 r4 H: z4 b
建模完成,修改我们的python程序,这里的 可以理解为潜伏期的倒数。给的4天。新型冠状病毒给目前临床的潜伏期是3-14天。) j2 G, j0 @1 C7 n- `% U% ]% R
# population- G( ^( g1 W' a" |
N = 1e7 + 10 + 5% C; P) X8 v' E5 g' I6 k
# simuation Time / Day
' q' E, T; Z- w7 W2 v0 S8 \8 DT = 170
* ]/ Y U# J( h1 ]0 n% p3 Y# susceptiable ratio
: m% \/ v: W- x! m% s9 C0 n9 [ @0 us = np.zeros([T])+ N+ F# e) G5 U
# exposed ratio1 t7 q, Y1 `7 D V w C
e = np.zeros([T])1 L8 V0 @* e7 d* R1 Y1 v& X
# infective ratio
' F& w' C4 f, b* }( z0 M. Ji = np.zeros([T])+ x# g3 t L8 P8 Q i* k
# remove ratio% V$ P+ E" v0 x$ Z4 y2 Q# ` _) @
r = np.zeros([T])
2 V, l2 [- o2 \& {7 }* Q5 H6 W5 p* ]6 _2 Q% Q( X! O
# contact rate
& n( l4 o$ a6 _lamda = 0.5
3 E2 j% h/ x% t, o# @ [# recover rate# l7 U/ [7 b1 B/ P' z
gamma = 0.0821
; B3 W2 L3 o$ s# exposed period
# ]* T. C4 D( u% l! \1 tsigma = 1 / 42 n$ L0 z2 ^$ A0 i# p9 b8 a
' ~* o: P$ V U( [0 b
# initial infective people
) d5 N# U' |5 ]i[0] = 10.0 / N
8 a* P/ M! L- S0 W' x( Rs[0] = 1e7 / N6 S! ^( d5 y( a$ H
e[0] = 40.0 / N( p; Z/ S& O: S7 [" f- X- q8 W5 G
for t in range(T-1):
$ Z G9 I4 h; D4 l' _# y/ E s[t + 1] = s[t] - lamda * s[t] * i[t]6 \+ r7 s5 s3 D5 [
e[t + 1] = e[t] + lamda * s[t] * i[t] - sigma * e[t]
! r3 f( \5 m# l9 C4 p i[t + 1] = i[t] + sigma * e[t] - gamma * i[t]
) U Z6 R7 ?* e9 m! E r[t + 1] = r[t] + gamma * i[t]
8 \/ A K( }, J+ V) Q3 ^2 E9 x! K
) C) i$ g w2 w- Yfig, ax = plt.subplots(figsize=(10,6))
: P, i$ V# B1 f8 k6 F# ]; `ax.plot(s, c='b', lw=2, label='S')
- w6 `! H# J" q2 _ax.plot(e, c='orange', lw=2, label='E')9 J+ W' G, S5 A: {, X- T4 a3 E
ax.plot(i, c='r', lw=2, label='I') i9 J# n1 Q% [, d. x- o% X( g
ax.plot(r, c='g', lw=2, label='R')
! i8 {/ i) {+ f2 z5 pax.set_xlabel('Day',fontsize=20)
4 l. F/ T* T/ N5 d) k9 [7 fax.set_ylabel('Infective Ratio', fontsize=20)
6 W' ^, p% P$ uax.grid(1)* B! r# N, r! c, C
plt.xticks(fontsize=20)3 d: L, {6 y$ {" p: E0 g( J
plt.yticks(fontsize=20)7 A7 R+ @1 a0 D6 _; W% {+ v
plt.legend();
# L9 A5 j- x% S# n3 f1 z
3 J0 D$ ?4 W2 W' S- M6 r
6 N2 x9 p. d% l# i( f; O+ g1 j % v. o0 p9 @2 e& C8 N2 k, [
. e/ S- X; U |
按照模型的结果,此次疫情可能真的要持续到 三四月份。这个接触率 真的非常影响表现,模型给的是个常数,但是由于政府措施的原因,这应该是个变化的值。
' w9 y) r- }+ q( J5 X1 l) N还有治愈率 也是。没有完美的模型,但是随着考虑因素的增多,就会越来越接近实际情况,从而指导政府的疫情方针政策的制定。" c$ J( Y# L) L% [5 C- N
! d; M7 H8 h Q- l' `" V9 {! b/ L' G+ d
7 t. {' s( L. a% Z% Z
$ ^# C3 j5 \0 k
|