|
什么是传染病动力学?numpy和matplotlib用python实现传染病模型SI模型SIS模型SIR模型SEIR模型 什么是传染病动力学?最近,在报道疫情的众多新闻中,相信大家也看到过一些来预测新型冠状病毒会导致感染肺炎的人数。你一定好奇,这个人数要怎么预测呢?预测人数又有什么用呢? 事实上,从学科方向来说,这类研究属于传染病动力学,就是用数学模型去描述传染病在人群中传播的规律,从而预测患病人数,进而指导政府制定措施和政策去控制传染病的传播。9 ?4 Q& J0 M4 H+ W: f/ B# A
这类研究最早可追溯到18世纪Daniel Bernoulli对天花的研究,而我们今天所要介绍的SIR模型是1927年Kermack与McKendrick在为了研究伦敦黑死病而提出的,是传染病动力学中最基础的模型。 介绍了传染病模型的背景信息,不知道现在你对传染病模型更有兴趣,还是执着地对python更有兴趣呢?不论哪种,这篇文章会满足你所有的好奇心。 numpy和matplotlib首先,安装一下这节课我们需要使用的两个python包,numpy和matplotlib。1 B% L4 ^$ W8 F9 r, c B
numpy-是python进行科学和矩阵运算最常用的包。 用numpy建立一维数组,存储和计算每天传染病人数的数据。
. a( U5 d. C# C: r! a2 Cimport numpy as np import matplotlib.pyplot as plt 用matplotlib绘制传染病人数随天数变化的曲线,给出模型预测人数变化的直观认识。 好啦,下面开始用python实现传染病模型吧。 用python实现传染病模型为了让大家能够更好地理解,我们先不直接说SIR模型,我们从最简单的开始。 SI模型首先想象这样一个场景,一个城市有 个人,假设没有人出生和死亡,忽然有一天有 个人感染了病毒成为了患者,如果每天每个患者能够有效传染 个人,那么第二天患病人数是多少呢?最简单的答案是: ,也就是说每天都会新增 个患者。那这样以来,在无限远的将来会有无穷多的人被感染,显然这是不合理的,那错在哪里?仔细思考,你一定发现了,已经患病的人就不能再被传染了,所以我们有必要把人群分为两类,易感者(S-susceptiable)和感染者(I-infective)(你猜的没错,这就是SIR中S和I的含义,R的含义之后介绍再讲)。为了之后方便计算我们记易感者和感染者在人群中的比例为 ,那么 。我们重新考虑上面的问题,顺便来个示意图: Image Name这样的话,每天新增的患者数为 ,也就是总传染人数乘以易感者所占的人群比例。3 |! }! f L A8 c. m
那么每天的感染者比例的增加量就是 。我们假设城市有一千万(N=10的7次方)人,每个患者每天接触感染每天0.8人(lamda=0.8),初始感染人数为45人(i0 = 45/N),我们来模拟70天(T=70)的情况。 # population
& A9 {- b% I+ Q/ m L9 zN = 1e74 j8 g. n2 A9 w E* j& I
# simuation Time / Day6 a$ a/ i3 C; S& |( }- M, @
T = 70
9 S$ s( z% B! Z- H) T* N7 Y# susceptiable ratio( i4 N4 k3 H: Y! L8 U% a3 K. B* u
s = np.zeros([T])% i1 w7 e! W; ?: w* K* e
# infective ratio! e2 Q$ ?" T. k9 p$ O) M
i = np.zeros([T])* ^" d& L9 v" i+ M& q2 X
# contact rate7 p( ?3 e. Z4 Y/ S* f+ G- `
lamda = 0.85 G4 X3 Y: t; V$ s5 U" m
4 {2 ]4 ~" y1 H, x! Z; I3 c7 F% {# initial infective people! p% ?& V" E' Y7 T, X
i[0] = 45.0 / N
. J% R( g6 m8 @% A4 [/ o
( B0 h' W) U" I6 ]for t in range(T-1):
/ P2 w8 G- X7 d- x- q i[t + 1] = i[t] + i[t] * lamda * (1.0 - i[t])9 D& K) T! s) f9 Q
: i, }* o* q/ J$ t! P# R
; w: X1 n7 g7 u8 c3 X0 G' h
: g7 v1 L) y( V; j相信其他语句大家都明白,新知识是这两行:
" M8 @! I* F1 ~4 r0 j- S0 [% V! B# s# s6 ]2 C# O
. _7 T% r) U5 X m
s = np.zeros([T])
# ^5 d# g; J6 R3 ti = np.zeros([T])
9 H3 t5 L' s; m7 {' }+ X- S0 X9 E7 J, A, d. u$ _7 p/ G
这两句话的意思是一样的,就是利用numpy(已被我们重新命名为np)的函数(zeros())来建立一个所有元素都是零的数组,而给的参数决定了这个数组的维度。比如:$ `4 b2 ]3 g( p4 j* f
( M: ^1 j l8 G, y. _, b# K) O5 {a = np.zeros([2,3])
8 ^' B D7 z0 E# ]a. i5 L( _. Y9 R" X
1 G' u, Q& L2 Y- J$ sarray([[0., 0., 0.],
( z- T$ U+ I5 ~& c: ? [0., 0., 0.]])4 c D4 j, L# v3 b
8 u! ]. X. Q, d0 E6 D& D$ }
$ i% w2 J& Q% x5 Z barray([0., 0., 0., 0., 0.])
+ N- ^% u( m! k q' b6 r7 Q, p# ]7 O/ ^! y p
# p; W# f. [. k+ D6 b类似的还有产生元素全部是1的数组的函数np.ones():
+ m9 ]: s: @# @
2 A( u S7 z3 A& C9 Va = np.ones([5])8 p+ D9 e; W! z; u. W8 W
a
1 S/ j0 U! c) A; R! @, p1 [7 |) d" a' L
array([1., 1., 1., 1., 1.])( f- n4 s- j1 @1 d0 P
& ~6 {2 W; N* e
1 m( u' L6 n9 Y- ^1 C9 g5 m0 n( ]' h
a = np.ones([2,3])! i) ^1 s3 v3 `2 f
a
( q: r& t! K) }+ G
1 a+ ~, B, w# l8 }, f# Y) P; X; G ^2 t3 z, t+ Z
array([[1., 1., 1.],
. j" e: N! D0 p" G2 } [1., 1., 1.]])
& M3 m- J$ W( }$ v# l- \( u" c: n5 j. ], O
( u3 B( X$ Q) S2 uplt.plot(i) Z) X$ W# B: W0 `
, } f+ j$ O# K+ w7 g, O0 y7 H
" W( w4 l U: \' S( K[<matplotlib.lines.Line2D at 0x7f0c2768d6d8>]
0 I% l, W( u3 H7 G3 Q! x
4 A5 g% x$ ?. k( m. @& X% o2 o
; ?1 b/ J- t, q1 B4 L- s 5 R# [, l6 R- w* e e* t
0 j" I4 l0 o) m: X! @$ _
3 E& [5 P+ p* s2 u实现SI模型的核心代码是第三个cell的第11,12行:' ^% n3 U' c! t+ V8 S' d
8 {+ e" r$ d- K+ h* cfor t in range(T-1):
! ~7 O- S3 u/ i1 W0 M9 O i[t + 1] = i[t] + i[t] * lamda * (1.0 - i[t])
- ^* G3 a! a( {: b) W* b" D$ q+ [8 ]0 x& S! `
就是我们建立的数学模型,利用python的for循环语句累加迭代的方式把每天的增加量叠加到感染者比例上。 运行代码完成计算,我们利用matplotlib的pyplot来画出感染者的随天数的变化曲线: 3 u" s" G+ ]* j. _
fig, ax = plt.subplots(figsize=(8,4))
?* m& T( }6 Y4 o' i5 F. i2 Jax.plot(i, c='r', lw=2)
; [( o" E" A# `- U1 x1 }ax.set_xlabel('Day',fontsize=20)
; l+ i! w" n& X/ S" n& Wax.set_ylabel('Infective Ratio', fontsize=20). c9 Y+ F$ r+ Q# K' U
ax.grid(1)
3 G" G/ P4 V P4 S% _/ y; xplt.xticks(fontsize=20)
$ G+ n4 T- a$ G0 ^plt.yticks(fontsize=20);( |) A; P- u, N! k8 w
9 j, t6 P* Z* Z( z( k5 J, {
` ?$ S% j2 V- T1 N 7 c0 S- |2 M0 Y9 E7 ?
7 I& B5 `2 q9 U, G
从这个结果看到,大约在25天左右,全部人群都会变成感染者,感染率 。8 a# k, _, t6 _! a6 T. I
在程序中我们假设每天每个患者传染0.8个人,你可以改变lamda的值,观察全部人群感染的天数的变化。
: h, k v9 I. ^7 f7 z K3 m {认真思考你会知道,lamda的现实意义就是该城市的卫生水平,衡量的是消毒,隔离这些措施执行得怎么样。回到传染病模型,按照SI模型计算的结果,我们全人类都会患病,这好可怕!原因是我们忽略了一个很重要的因素,那就是我们有奋斗在一线的医护人员,我们会被治愈!所以SI模型只适合研究具有高传染风险又不能被治愈的病(比如HIV)。 但是对于其他病,我们是可以靠医疗和自身免疫系统康复的,那么紧接着的一个问题就是,被治愈后还会再被传染上嘛?根据这个问题的回答不同,我们有了两个不同的模型,SIR 和 SIS。现在可以揭晓,SIR的R的含义了,就是移出者(Removed),现实含义就是指被治愈后不会再被感染的人。而SIS表示治愈后仍然还是易感者。下面我们用python来分别实现这两个模型。 SIS模型为了实现这个模型,我们需要引入新的一个参数,治愈率 。好啦,先上我们的新示意图: Image Name和SI模型做比较,区别就是计算感染者的增加数时要减去被治愈的人数。
. e" [" t$ d v5 e所以这时候每天的增加的感染者为: ,
' ^, `0 W; K9 y( T增加的感染率为: 。
- o1 t# w0 t$ T% F9 M模型完成啦,修改python代码:* L9 P/ x- U3 E4 |
# susceptiable ratio
4 O1 O @# r" e2 Y7 X. k/ `- Es = np.zeros([T])
+ Z9 B: H5 ~: ~0 J" i# infective ratio
6 C! C1 H6 b3 C3 E" E+ \i = np.zeros([T])
+ ]3 _ q2 M) e4 b+ P
, ]4 z0 B& ^! l' A# contact rate
: w# _' w) u. q1 j" ylamda = 1.06 z9 R4 p5 S0 W- q/ D/ m
# recover rate
& E i7 A a! L# q7 [0 ^ egamma = 0.5 6 T. O0 A" d5 w: U3 t' m
. P8 m4 Y% J7 Y* E! V
# initial infective people4 m3 h6 Q9 K/ v' @9 I# B" {% o
i[0] = 45.0 / N/ A* Q3 c. P% n) j+ ]. I
/ l6 r8 l: I; V8 R0 l0 tfor t in range(T-1):
$ K8 N5 G. R. F3 J, r; E i[t + 1] = i[t] + i[t] * lamda * (1.0 - i[t]) - gamma*i[t]- H( R9 I- d* }& Y' Q, z/ c
0 h4 L! J4 O9 O/ q, T7 w4 Y8 J/ n7 {: U8 R6 P
% z! A7 P }2 C Y9 |4 [$ `3 @! K运行代码,我们画出曲线(代码和SI模型的画图完全一样):
* g" q T2 p# _5 W$ A
, w/ ?% T7 R4 D5 F; b$ H& rfig, ax = plt.subplots(figsize=(8,4))
0 G! F# }. ~7 Q: hax.plot(i, c='r', lw=2)* I* g% w+ N' c) D/ Z6 D9 Y
ax.set_xlabel('Day',fontsize=20)$ P8 B: j" U _
ax.set_ylabel('Infective Ratio', fontsize=20)
9 @2 j1 R0 Q6 Q, Sax.grid(1)! X9 c$ b. y; ~) o
plt.xticks(fontsize=20)
M3 f j T! r9 Q o4 Gplt.yticks(fontsize=20);. `/ L# N& p6 C q1 {* x6 t( z1 [
; l3 R. B5 Y; R2 F9 G0 w0 m
![]()
- ^& v" L: h) Y. J+ K/ d+ [* i! @2 m# V
" o8 L* [) k7 G& ^* R
行代码,我们画出曲线(代码和SI模型的画图完全一样)
2 B9 B0 B9 d. ]. _可以看到,达到最大感染率的时间退后10天左右,最后感染和治愈达到动态平衡,人群中有始终有一半的人感染着。所以,SIS模型适合研究具有传染性和反复性的流行病,比如常见流感。同样的,感兴趣的话,改变lamda和gamma的值,观察曲线的变化。和lamda不同的是,gamma的现实意义就是对这种疾病的治疗水平。 SIR模型加入了移出者,被治愈的病人不会再被传染,先上我们的新示意图: Image NameSIR 模型
- {' {# G" B( G0 R: d6 y注意到这里,人群被分成了三类,不再只有I和S,所以相比于之前的模型,我们需要找到新的约束关系。现在我们需要分别计算三种人每天的增加量了: " q. F7 ^4 a3 t5 K" w8 q% A* I4 y
- 易感者:每天都在被传染,所以一直在减少,减少量为被传染的人数:
- 感染者:增加了被感染的人,减少了治愈的人:
- 移出者:增加了治愈的人: y6 k- H8 m* i, |
建模完成,修改python代码,并且假设人群普遍易感,新型疾病,初始没有移出者。 . L' s& t9 h; P1 W0 z
# population% [# [# R& }- X0 e* ^4 X+ w& p
N = 1e7 + 10 + 5
% Z. z) a8 L1 Y0 y" ]0 s9 v, @# simuation Time / Day5 n7 K& E" K$ C+ f7 Y3 _$ s
T = 170 |4 t2 F" r3 l6 g1 [: `
# susceptiable ratio o. h) V9 E$ D3 _. i
s = np.zeros([T])
`4 o1 Q- P$ X% M" j5 d# infective ratio
! ~! C, b* p5 Ni = np.zeros([T])
- w, j6 ^7 K! W# remove ratio
; @! E; H5 ~/ Ir = np.zeros([T])
- I5 c1 Q: S! Y' j) a3 G- ^9 \# ~, M/ F1 W, z, ?3 m1 B6 P& U
# contact rate
( o8 m3 d* s# @2 {lamda = 0.2586, k; F: o( E8 H, n( o6 p2 e
# recover rate& l" H( Q. t/ q* t( @8 S/ h9 f
gamma = 0.0821- T8 x8 W1 S' ]% ^* V$ p( k- a
3 z# g" V' Z* J* a/ a% v( P
# initial infective people4 q4 F3 n9 H. z7 d% n; a
i[0] = 10.0 / N& {/ E/ x' O8 b) M1 c' e: T0 n! R
s[0] = 1e7 / N
# q% |$ `+ ^! \0 ?1 H* Tfor t in range(T-1):) O# j. E. N0 j( Y8 ?* D8 t6 P$ d
i[t + 1] = i[t] + i[t] * lamda * s[t] - gamma*i[t]: w8 U* ~2 Q& ?% a1 @: B
s[t + 1] = s[t] - lamda * s[t] * i[t]: U8 ?) f- i0 q
r[t + 1] = r[t] + gamma*i[t]
0 q$ J3 Z/ s) }$ s
* `1 n6 Q0 [4 F: rfig, ax = plt.subplots(figsize=(10,6))9 U8 O' l4 ?: y! n5 ^4 e& P
ax.plot(s, c='b', lw=2, label='S')
' t7 T0 h0 ~' U2 @ bax.plot(i, c='r', lw=2, label='I')1 g9 e" N* S) N+ h H9 N4 L
ax.plot(r, c='g', lw=2, label='R')' P- h% y$ ]& Y1 t
ax.set_xlabel('Day',fontsize=20)5 _- k6 u M& [# J% y: {6 S( i/ {
ax.set_ylabel('Infective Ratio', fontsize=20)% \, f* c# m. w# Z3 I. n" y
ax.grid(1)
" w7 q7 M j# m+ d. Lplt.xticks(fontsize=20)
8 O" \; a0 I! v, H! e# Eplt.yticks(fontsize=20)0 w! k! a# S( j. p- `( u# s
plt.legend();: R" G( ~7 n; h% W9 _
$ j. d C# _) I( p+ b
5 @0 }. B7 y% c* o ' e! b, R8 m# Z0 B9 q( Z3 C7 ~9 G2 E
+ p& y4 }1 J0 G: u
感染人数峰值发生在一个月左右,最大感染人数不到人群的20%, 但是最终人群的80%都会得此病(就是最终的移出者的比例)。SIR模型适合研究没有潜伏期的急性传染病,治疗后能够痊愈并具有抗病性。 到这里,虽然不准确,我们也可以先用SIR模型来分析一下此次疫情,武汉新型冠状病毒的传染病动力学! 模型有了,其实就是确定参数的问题。一开始就有人做了这个工作: Image Name于教授给的参数是参考了非典的, ,初始易感人数为一千万, 初始感染10人,初始移出者5人,那么我们的城市总人数 , 带入我们的模型得到结果:重现于教授的模型2 K% G: R3 Y1 X4 i5 m# l$ a
高峰和尾声日期的推测基本相符。
! Q3 g3 i v2 t# susceptiable ratio4 [2 G( C+ n5 e3 R9 w' ~1 s
s = np.zeros([T])
& h& f/ f; ?. I; c5 ^, _ \# infective ratio Q9 j( {1 C( {
i = np.zeros([T]) N& s- I% t5 Z
# removed ratio
4 j" |+ ]2 D# t8 l* x1 qr = np.zeros([T])
3 K4 P5 o6 a* m$ u( p7 J2 }- l. h
5 C$ C" n- o/ _6 Z4 ]. S6 [5 k# birth ratio
6 `) S9 p3 N" w' l2 e6 f5 P7 [' ^b = 20.0 / N
* R6 b! P( h! @# death ratio
: g8 p9 v" P$ L% L7 m) _/ j& \, id = 10.0 / N
$ A, c* ?4 |9 |1 C6 f1 [8 N/ l
' y* Z p" M* I# M! c$ {) c% c# contact rate g+ j+ W4 w9 k6 h+ ~, Q
y = 1.58 q; H' s6 O7 @( O
# recover rate
1 |7 i2 _ h/ w3 k4 ru = 0.8 # 1 / infective_period. O' s" C9 {( @; _
3 z/ q* T- r! Q! r j" [, Q, V
# sigma = y / u
% c7 h; A' n f4 v3 e8 m* {% Z i$ p2 r
# initial infective people7 m$ M" P6 m5 R0 r1 S( ]
i[0] = 45.0 / N
% b1 y. o" S" c$ ^7 q Js[0] = 1 - i[0]
* k$ v6 c( K$ _% z, c' Mfor t in range(T-1):
Q8 r, l3 ~6 W% Y3 N0 y3 o, | i[t+1] = i[t] + i[t] * y * s[t] - u*i[t] - d*i[t]( ^! H% W- T |. k0 g: c' [
s[t+1] = s[t] - y * s[t] * i[t] + b - d*s[t]
* b. S, s, ]9 O/ E& d r[t+1] = r[t] + u*i[t] - d*r[t]
7 o# ^. N, C0 k$ m3 J& R: o# P+ X0 g0 z9 {
plt.plot(i)
" i4 Z3 D/ h# L5 ]2 G% @$ m/ cplt.plot(s). Z/ B$ b& z$ m- ~) H* N
plt.plot(r); l0 U; q$ K+ c9 n- A; o/ Q; y
plt.plot(np.diff(i),ls='--')
- U0 E: S2 \# ~; S
2 p) ?3 [! {( `" a1 l# \
! p' p8 b3 x5 O) {[<matplotlib.lines.Line2D at 0x7f77796e8518>]
9 M: h" v$ }% @1 [1 M! w, i" g% S& a ~- P2 k
![]()
9 x: i7 z k6 R, \: k3 V/ h, ^
* |- _: c# S# `: K7 ZSEIR模型但是,SIR模型和实际情况的出入会比较大,因为忽略了太多因素了,比如说潜伏期,比如说政策调控,药物,出生死亡等等。下面我们可以和前面一样,把潜伏期考虑进去,新增一个人群,叫潜伏者E(exposed): Image NameSEIR模型 w0 l% j3 |8 x$ t- b# E
同样的我们需要计算各人群每天的增加量: S:每天减少: 6 J% z, v! z; P, s1 Z, D: ^( j
E:每天增加传染,减少发病:
. `5 ~6 r5 p% E' y3 g6 UI:每天增加发病,减少治愈: 7 C* t% D X) f1 X
R:每天增加治愈: & ]4 k! v0 g% y% m; y
建模完成,修改我们的python程序,这里的 可以理解为潜伏期的倒数。给的4天。新型冠状病毒给目前临床的潜伏期是3-14天。
8 u4 s" R; J' }. K/ H# population- R) S% S4 L0 {
N = 1e7 + 10 + 5
' b1 m" y" B7 _- ^# simuation Time / Day2 J- H' s& X5 }4 {
T = 170
: o3 m' Z5 p$ E$ d2 q) m, q# susceptiable ratio5 x ^, Y' C! J, {
s = np.zeros([T])
; a) I r" Q; A( t! v* s$ [8 e$ S# exposed ratio
3 K2 w' F* r7 ]* `2 ee = np.zeros([T])7 ~/ W9 ^$ D# y8 D) j
# infective ratio
. V2 F2 @1 x6 l$ l% H7 b/ Si = np.zeros([T])
, h9 U7 s l8 B1 l3 I+ k, m7 y# remove ratio
" z; z& p; m' @+ {r = np.zeros([T])
' C$ L c) T9 X1 Z' C; n: @4 l O& Z$ a, r; B' P+ [
# contact rate9 k b( D( i) c1 J5 ^- w1 k
lamda = 0.5
* c5 ?1 d8 q/ s# recover rate
$ }' | @6 j+ C6 e5 k& Bgamma = 0.0821; T1 a) z/ Y0 t" ]
# exposed period
1 o: y/ @- e4 `& osigma = 1 / 4
- M; ` ?$ y+ q+ k: A
5 V. |; z) d9 q9 H# initial infective people
; l+ e( O: H+ m( G. Di[0] = 10.0 / N; y7 Z3 @; G) ^! d
s[0] = 1e7 / N
0 R# o# r3 x* z. Ge[0] = 40.0 / N1 j9 O7 m# n7 A4 t6 T7 K+ H
for t in range(T-1):
# M8 u: e' E* ~ s[t + 1] = s[t] - lamda * s[t] * i[t]
( Z/ U) v/ ]7 A1 a e[t + 1] = e[t] + lamda * s[t] * i[t] - sigma * e[t]
( ?( U" ^# i; S" z% @7 N% _ i[t + 1] = i[t] + sigma * e[t] - gamma * i[t]
" v1 G9 h* |: h- X, T r[t + 1] = r[t] + gamma * i[t]8 u+ W, i% Q3 |9 Z& |
& N0 r6 U+ N" }4 q `
7 ~( r. ~' b! h# b7 L' g& h: F
fig, ax = plt.subplots(figsize=(10,6))' d( r r4 P6 M! {2 K! F# ~
ax.plot(s, c='b', lw=2, label='S')
) l; o4 X0 Z3 y; y: d" V Tax.plot(e, c='orange', lw=2, label='E')6 r3 [4 p" I3 K3 V! Z
ax.plot(i, c='r', lw=2, label='I')
) |# M4 a2 ]% S* n9 _0 `+ g8 K2 ~. Gax.plot(r, c='g', lw=2, label='R')5 F, W3 N" \1 v7 V5 k& k4 k4 n, T, Q
ax.set_xlabel('Day',fontsize=20)
- w" h5 V3 l5 c( E1 u/ nax.set_ylabel('Infective Ratio', fontsize=20)/ p; S3 ~& R7 W+ d
ax.grid(1)3 x5 j* w: S) t- e6 B
plt.xticks(fontsize=20)
& v5 ]; T3 W! E, vplt.yticks(fontsize=20)
0 o3 O6 M: @3 p( v+ L: ]6 vplt.legend();) ]: o% s! L0 P* _+ z! P( t
* K5 s6 F2 X9 {
2 c4 t& a7 Z* F8 Q( G " [9 B) s7 y- V; A
2 b1 w+ ?& R* f3 M按照模型的结果,此次疫情可能真的要持续到 三四月份。这个接触率 真的非常影响表现,模型给的是个常数,但是由于政府措施的原因,这应该是个变化的值。
" h- w0 t' E2 r% z还有治愈率 也是。没有完美的模型,但是随着考虑因素的增多,就会越来越接近实际情况,从而指导政府的疫情方针政策的制定。$ J0 Z. n' s- ~$ q
$ Q" r- e ~! Q$ ]/ \; E3 M& `4 o8 f1 T/ j# c( X, E) r. t
3 k1 l3 e- c+ {# i c1 d6 G% M' p5 n
|