mirrored 19 minutes ago
0
Your Nameupdate docs 4618714
<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="generator" content="pdoc 15.0.4"/>
    <title>vimgolf_gym.log_parser API documentation</title>

    <style>/*! * Bootstrap Reboot v5.0.0 (https://getbootstrap.com/) * Copyright 2011-2021 The Bootstrap Authors * Copyright 2011-2021 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md) */*,::after,::before{box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;background-color:#fff;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}hr{margin:1rem 0;color:inherit;background-color:currentColor;border:0;opacity:.25}hr:not([size]){height:1px}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2}h1{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){h1{font-size:2.5rem}}h2{font-size:calc(1.325rem + .9vw)}@media (min-width:1200px){h2{font-size:2rem}}h3{font-size:calc(1.3rem + .6vw)}@media (min-width:1200px){h3{font-size:1.75rem}}h4{font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){h4{font-size:1.5rem}}h5{font-size:1.25rem}h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[data-bs-original-title],abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:.875em}mark{padding:.2em;background-color:#fcf8e3}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#0d6efd;text-decoration:underline}a:hover{color:#0a58ca}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em;direction:ltr;unicode-bidi:bidi-override}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:#d63384;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:.875em;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:1em;font-weight:700}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:#6c757d;text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,tfoot,th,thead,tr{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]::-webkit-calendar-picker-indicator{display:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + .3vw);line-height:inherit}@media (min-width:1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:textfield}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::file-selector-button{font:inherit}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none!important}</style>
    <style>/*! syntax-highlighting.css */pre{line-height:125%;}span.linenos{color:inherit; background-color:transparent; padding-left:5px; padding-right:20px;}.pdoc-code .hll{background-color:#ffffcc}.pdoc-code{background:#f8f8f8;}.pdoc-code .c{color:#3D7B7B; font-style:italic}.pdoc-code .err{border:1px solid #FF0000}.pdoc-code .k{color:#008000; font-weight:bold}.pdoc-code .o{color:#666666}.pdoc-code .ch{color:#3D7B7B; font-style:italic}.pdoc-code .cm{color:#3D7B7B; font-style:italic}.pdoc-code .cp{color:#9C6500}.pdoc-code .cpf{color:#3D7B7B; font-style:italic}.pdoc-code .c1{color:#3D7B7B; font-style:italic}.pdoc-code .cs{color:#3D7B7B; font-style:italic}.pdoc-code .gd{color:#A00000}.pdoc-code .ge{font-style:italic}.pdoc-code .gr{color:#E40000}.pdoc-code .gh{color:#000080; font-weight:bold}.pdoc-code .gi{color:#008400}.pdoc-code .go{color:#717171}.pdoc-code .gp{color:#000080; font-weight:bold}.pdoc-code .gs{font-weight:bold}.pdoc-code .gu{color:#800080; font-weight:bold}.pdoc-code .gt{color:#0044DD}.pdoc-code .kc{color:#008000; font-weight:bold}.pdoc-code .kd{color:#008000; font-weight:bold}.pdoc-code .kn{color:#008000; font-weight:bold}.pdoc-code .kp{color:#008000}.pdoc-code .kr{color:#008000; font-weight:bold}.pdoc-code .kt{color:#B00040}.pdoc-code .m{color:#666666}.pdoc-code .s{color:#BA2121}.pdoc-code .na{color:#687822}.pdoc-code .nb{color:#008000}.pdoc-code .nc{color:#0000FF; font-weight:bold}.pdoc-code .no{color:#880000}.pdoc-code .nd{color:#AA22FF}.pdoc-code .ni{color:#717171; font-weight:bold}.pdoc-code .ne{color:#CB3F38; font-weight:bold}.pdoc-code .nf{color:#0000FF}.pdoc-code .nl{color:#767600}.pdoc-code .nn{color:#0000FF; font-weight:bold}.pdoc-code .nt{color:#008000; font-weight:bold}.pdoc-code .nv{color:#19177C}.pdoc-code .ow{color:#AA22FF; font-weight:bold}.pdoc-code .w{color:#bbbbbb}.pdoc-code .mb{color:#666666}.pdoc-code .mf{color:#666666}.pdoc-code .mh{color:#666666}.pdoc-code .mi{color:#666666}.pdoc-code .mo{color:#666666}.pdoc-code .sa{color:#BA2121}.pdoc-code .sb{color:#BA2121}.pdoc-code .sc{color:#BA2121}.pdoc-code .dl{color:#BA2121}.pdoc-code .sd{color:#BA2121; font-style:italic}.pdoc-code .s2{color:#BA2121}.pdoc-code .se{color:#AA5D1F; font-weight:bold}.pdoc-code .sh{color:#BA2121}.pdoc-code .si{color:#A45A77; font-weight:bold}.pdoc-code .sx{color:#008000}.pdoc-code .sr{color:#A45A77}.pdoc-code .s1{color:#BA2121}.pdoc-code .ss{color:#19177C}.pdoc-code .bp{color:#008000}.pdoc-code .fm{color:#0000FF}.pdoc-code .vc{color:#19177C}.pdoc-code .vg{color:#19177C}.pdoc-code .vi{color:#19177C}.pdoc-code .vm{color:#19177C}.pdoc-code .il{color:#666666}</style>
    <style>/*! theme.css */:root{--pdoc-background:#fff;}.pdoc{--text:#212529;--muted:#6c757d;--link:#3660a5;--link-hover:#1659c5;--code:#f8f8f8;--active:#fff598;--accent:#eee;--accent2:#c1c1c1;--nav-hover:rgba(255, 255, 255, 0.5);--name:#0066BB;--def:#008800;--annotation:#007020;}</style>
    <style>/*! layout.css */html, body{width:100%;height:100%;}html, main{scroll-behavior:smooth;}body{background-color:var(--pdoc-background);}@media (max-width:769px){#navtoggle{cursor:pointer;position:absolute;width:50px;height:40px;top:1rem;right:1rem;border-color:var(--text);color:var(--text);display:flex;opacity:0.8;z-index:999;}#navtoggle:hover{opacity:1;}#togglestate + div{display:none;}#togglestate:checked + div{display:inherit;}main, header{padding:2rem 3vw;}header + main{margin-top:-3rem;}.git-button{display:none !important;}nav input[type="search"]{max-width:77%;}nav input[type="search"]:first-child{margin-top:-6px;}nav input[type="search"]:valid ~ *{display:none !important;}}@media (min-width:770px){:root{--sidebar-width:clamp(12.5rem, 28vw, 22rem);}nav{position:fixed;overflow:auto;height:100vh;width:var(--sidebar-width);}main, header{padding:3rem 2rem 3rem calc(var(--sidebar-width) + 3rem);width:calc(54rem + var(--sidebar-width));max-width:100%;}header + main{margin-top:-4rem;}#navtoggle{display:none;}}#togglestate{position:absolute;height:0;opacity:0;}nav.pdoc{--pad:clamp(0.5rem, 2vw, 1.75rem);--indent:1.5rem;background-color:var(--accent);border-right:1px solid var(--accent2);box-shadow:0 0 20px rgba(50, 50, 50, .2) inset;padding:0 0 0 var(--pad);overflow-wrap:anywhere;scrollbar-width:thin; scrollbar-color:var(--accent2) transparent; z-index:1}nav.pdoc::-webkit-scrollbar{width:.4rem; }nav.pdoc::-webkit-scrollbar-thumb{background-color:var(--accent2); }nav.pdoc > div{padding:var(--pad) 0;}nav.pdoc .module-list-button{display:inline-flex;align-items:center;color:var(--text);border-color:var(--muted);margin-bottom:1rem;}nav.pdoc .module-list-button:hover{border-color:var(--text);}nav.pdoc input[type=search]{display:block;outline-offset:0;width:calc(100% - var(--pad));}nav.pdoc .logo{max-width:calc(100% - var(--pad));max-height:35vh;display:block;margin:0 auto 1rem;transform:translate(calc(-.5 * var(--pad)), 0);}nav.pdoc ul{list-style:none;padding-left:0;}nav.pdoc > div > ul{margin-left:calc(0px - var(--pad));}nav.pdoc li a{padding:.2rem 0 .2rem calc(var(--pad) + var(--indent));}nav.pdoc > div > ul > li > a{padding-left:var(--pad);}nav.pdoc li{transition:all 100ms;}nav.pdoc li:hover{background-color:var(--nav-hover);}nav.pdoc a, nav.pdoc a:hover{color:var(--text);}nav.pdoc a{display:block;}nav.pdoc > h2:first-of-type{margin-top:1.5rem;}nav.pdoc .class:before{content:"class ";color:var(--muted);}nav.pdoc .function:after{content:"()";color:var(--muted);}nav.pdoc footer:before{content:"";display:block;width:calc(100% - var(--pad));border-top:solid var(--accent2) 1px;margin-top:1.5rem;padding-top:.5rem;}nav.pdoc footer{font-size:small;}</style>
    <style>/*! content.css */.pdoc{color:var(--text);box-sizing:border-box;line-height:1.5;background:none;}.pdoc .pdoc-button{cursor:pointer;display:inline-block;border:solid black 1px;border-radius:2px;font-size:.75rem;padding:calc(0.5em - 1px) 1em;transition:100ms all;}.pdoc .alert{padding:1rem 1rem 1rem calc(1.5rem + 24px);border:1px solid transparent;border-radius:.25rem;background-repeat:no-repeat;background-position:.75rem center;margin-bottom:1rem;}.pdoc .alert > em{display:none;}.pdoc .alert > *:last-child{margin-bottom:0;}.pdoc .alert.note{color:#084298;background-color:#cfe2ff;border-color:#b6d4fe;background-image:url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2224%22%20height%3D%2224%22%20fill%3D%22%23084298%22%20viewBox%3D%220%200%2016%2016%22%3E%3Cpath%20d%3D%22M8%2016A8%208%200%201%200%208%200a8%208%200%200%200%200%2016zm.93-9.412-1%204.705c-.07.34.029.533.304.533.194%200%20.487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703%200-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381%202.29-.287zM8%205.5a1%201%200%201%201%200-2%201%201%200%200%201%200%202z%22/%3E%3C/svg%3E");}.pdoc .alert.tip{color:#0a3622;background-color:#d1e7dd;border-color:#a3cfbb;background-image:url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2224%22%20height%3D%2224%22%20fill%3D%22%230a3622%22%20viewBox%3D%220%200%2016%2016%22%3E%3Cpath%20d%3D%22M2%206a6%206%200%201%201%2010.174%204.31c-.203.196-.359.4-.453.619l-.762%201.769A.5.5%200%200%201%2010.5%2013a.5.5%200%200%201%200%201%20.5.5%200%200%201%200%201l-.224.447a1%201%200%200%201-.894.553H6.618a1%201%200%200%201-.894-.553L5.5%2015a.5.5%200%200%201%200-1%20.5.5%200%200%201%200-1%20.5.5%200%200%201-.46-.302l-.761-1.77a2%202%200%200%200-.453-.618A5.98%205.98%200%200%201%202%206m6-5a5%205%200%200%200-3.479%208.592c.263.254.514.564.676.941L5.83%2012h4.342l.632-1.467c.162-.377.413-.687.676-.941A5%205%200%200%200%208%201%22/%3E%3C/svg%3E");}.pdoc .alert.important{color:#055160;background-color:#cff4fc;border-color:#9eeaf9;background-image:url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2224%22%20height%3D%2224%22%20fill%3D%22%23055160%22%20viewBox%3D%220%200%2016%2016%22%3E%3Cpath%20d%3D%22M2%200a2%202%200%200%200-2%202v12a2%202%200%200%200%202%202h12a2%202%200%200%200%202-2V2a2%202%200%200%200-2-2zm6%204c.535%200%20.954.462.9.995l-.35%203.507a.552.552%200%200%201-1.1%200L7.1%204.995A.905.905%200%200%201%208%204m.002%206a1%201%200%201%201%200%202%201%201%200%200%201%200-2%22/%3E%3C/svg%3E");}.pdoc .alert.warning{color:#664d03;background-color:#fff3cd;border-color:#ffecb5;background-image:url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2224%22%20height%3D%2224%22%20fill%3D%22%23664d03%22%20viewBox%3D%220%200%2016%2016%22%3E%3Cpath%20d%3D%22M8.982%201.566a1.13%201.13%200%200%200-1.96%200L.165%2013.233c-.457.778.091%201.767.98%201.767h13.713c.889%200%201.438-.99.98-1.767L8.982%201.566zM8%205c.535%200%20.954.462.9.995l-.35%203.507a.552.552%200%200%201-1.1%200L7.1%205.995A.905.905%200%200%201%208%205zm.002%206a1%201%200%201%201%200%202%201%201%200%200%201%200-2z%22/%3E%3C/svg%3E");}.pdoc .alert.caution{color:#842029;background-color:#f8d7da;border-color:#f5c2c7;background-image:url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2224%22%20height%3D%2224%22%20fill%3D%22%23842029%22%20viewBox%3D%220%200%2016%2016%22%3E%3Cpath%20d%3D%22M11.46.146A.5.5%200%200%200%2011.107%200H4.893a.5.5%200%200%200-.353.146L.146%204.54A.5.5%200%200%200%200%204.893v6.214a.5.5%200%200%200%20.146.353l4.394%204.394a.5.5%200%200%200%20.353.146h6.214a.5.5%200%200%200%20.353-.146l4.394-4.394a.5.5%200%200%200%20.146-.353V4.893a.5.5%200%200%200-.146-.353zM8%204c.535%200%20.954.462.9.995l-.35%203.507a.552.552%200%200%201-1.1%200L7.1%204.995A.905.905%200%200%201%208%204m.002%206a1%201%200%201%201%200%202%201%201%200%200%201%200-2%22/%3E%3C/svg%3E");}.pdoc .alert.danger{color:#842029;background-color:#f8d7da;border-color:#f5c2c7;background-image:url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2224%22%20height%3D%2224%22%20fill%3D%22%23842029%22%20viewBox%3D%220%200%2016%2016%22%3E%3Cpath%20d%3D%22M5.52.359A.5.5%200%200%201%206%200h4a.5.5%200%200%201%20.474.658L8.694%206H12.5a.5.5%200%200%201%20.395.807l-7%209a.5.5%200%200%201-.873-.454L6.823%209.5H3.5a.5.5%200%200%201-.48-.641l2.5-8.5z%22/%3E%3C/svg%3E");}.pdoc .visually-hidden{position:absolute !important;width:1px !important;height:1px !important;padding:0 !important;margin:-1px !important;overflow:hidden !important;clip:rect(0, 0, 0, 0) !important;white-space:nowrap !important;border:0 !important;}.pdoc h1, .pdoc h2, .pdoc h3{font-weight:300;margin:.3em 0;padding:.2em 0;}.pdoc > section:not(.module-info) h1{font-size:1.5rem;font-weight:500;}.pdoc > section:not(.module-info) h2{font-size:1.4rem;font-weight:500;}.pdoc > section:not(.module-info) h3{font-size:1.3rem;font-weight:500;}.pdoc > section:not(.module-info) h4{font-size:1.2rem;}.pdoc > section:not(.module-info) h5{font-size:1.1rem;}.pdoc a{text-decoration:none;color:var(--link);}.pdoc a:hover{color:var(--link-hover);}.pdoc blockquote{margin-left:2rem;}.pdoc pre{border-top:1px solid var(--accent2);border-bottom:1px solid var(--accent2);margin-top:0;margin-bottom:1em;padding:.5rem 0 .5rem .5rem;overflow-x:auto;background-color:var(--code);}.pdoc code{color:var(--text);padding:.2em .4em;margin:0;font-size:85%;background-color:var(--accent);border-radius:6px;}.pdoc a > code{color:inherit;}.pdoc pre > code{display:inline-block;font-size:inherit;background:none;border:none;padding:0;}.pdoc > section:not(.module-info){margin-bottom:1.5rem;}.pdoc .modulename{margin-top:0;font-weight:bold;}.pdoc .modulename a{color:var(--link);transition:100ms all;}.pdoc .git-button{float:right;border:solid var(--link) 1px;}.pdoc .git-button:hover{background-color:var(--link);color:var(--pdoc-background);}.view-source-toggle-state,.view-source-toggle-state ~ .pdoc-code{display:none;}.view-source-toggle-state:checked ~ .pdoc-code{display:block;}.view-source-button{display:inline-block;float:right;font-size:.75rem;line-height:1.5rem;color:var(--muted);padding:0 .4rem 0 1.3rem;cursor:pointer;text-indent:-2px;}.view-source-button > span{visibility:hidden;}.module-info .view-source-button{float:none;display:flex;justify-content:flex-end;margin:-1.2rem .4rem -.2rem 0;}.view-source-button::before{position:absolute;content:"View Source";display:list-item;list-style-type:disclosure-closed;}.view-source-toggle-state:checked ~ .attr .view-source-button::before,.view-source-toggle-state:checked ~ .view-source-button::before{list-style-type:disclosure-open;}.pdoc .docstring{margin-bottom:1.5rem;}.pdoc section:not(.module-info) .docstring{margin-left:clamp(0rem, 5vw - 2rem, 1rem);}.pdoc .docstring .pdoc-code{margin-left:1em;margin-right:1em;}.pdoc h1:target,.pdoc h2:target,.pdoc h3:target,.pdoc h4:target,.pdoc h5:target,.pdoc h6:target,.pdoc .pdoc-code > pre > span:target{background-color:var(--active);box-shadow:-1rem 0 0 0 var(--active);}.pdoc .pdoc-code > pre > span:target{display:block;}.pdoc div:target > .attr,.pdoc section:target > .attr,.pdoc dd:target > a{background-color:var(--active);}.pdoc *{scroll-margin:2rem;}.pdoc .pdoc-code .linenos{user-select:none;}.pdoc .attr:hover{filter:contrast(0.95);}.pdoc section, .pdoc .classattr{position:relative;}.pdoc .headerlink{--width:clamp(1rem, 3vw, 2rem);position:absolute;top:0;left:calc(0rem - var(--width));transition:all 100ms ease-in-out;opacity:0;}.pdoc .headerlink::before{content:"#";display:block;text-align:center;width:var(--width);height:2.3rem;line-height:2.3rem;font-size:1.5rem;}.pdoc .attr:hover ~ .headerlink,.pdoc *:target > .headerlink,.pdoc .headerlink:hover{opacity:1;}.pdoc .attr{display:block;margin:.5rem 0 .5rem;padding:.4rem .4rem .4rem 1rem;background-color:var(--accent);overflow-x:auto;}.pdoc .classattr{margin-left:2rem;}.pdoc .decorator-deprecated{color:#842029;}.pdoc .decorator-deprecated ~ span{filter:grayscale(1) opacity(0.8);}.pdoc .name{color:var(--name);font-weight:bold;}.pdoc .def{color:var(--def);font-weight:bold;}.pdoc .signature{background-color:transparent;}.pdoc .param, .pdoc .return-annotation{white-space:pre;}.pdoc .signature.multiline .param{display:block;}.pdoc .signature.condensed .param{display:inline-block;}.pdoc .annotation{color:var(--annotation);}.pdoc .view-value-toggle-state,.pdoc .view-value-toggle-state ~ .default_value{display:none;}.pdoc .view-value-toggle-state:checked ~ .default_value{display:inherit;}.pdoc .view-value-button{font-size:.5rem;vertical-align:middle;border-style:dashed;margin-top:-0.1rem;}.pdoc .view-value-button:hover{background:white;}.pdoc .view-value-button::before{content:"show";text-align:center;width:2.2em;display:inline-block;}.pdoc .view-value-toggle-state:checked ~ .view-value-button::before{content:"hide";}.pdoc .inherited{margin-left:2rem;}.pdoc .inherited dt{font-weight:700;}.pdoc .inherited dt, .pdoc .inherited dd{display:inline;margin-left:0;margin-bottom:.5rem;}.pdoc .inherited dd:not(:last-child):after{content:", ";}.pdoc .inherited .class:before{content:"class ";}.pdoc .inherited .function a:after{content:"()";}.pdoc .search-result .docstring{overflow:auto;max-height:25vh;}.pdoc .search-result.focused > .attr{background-color:var(--active);}.pdoc .attribution{margin-top:2rem;display:block;opacity:0.5;transition:all 200ms;filter:grayscale(100%);}.pdoc .attribution:hover{opacity:1;filter:grayscale(0%);}.pdoc .attribution img{margin-left:5px;height:35px;vertical-align:middle;width:70px;transition:all 200ms;}.pdoc table{display:block;width:max-content;max-width:100%;overflow:auto;margin-bottom:1rem;}.pdoc table th{font-weight:600;}.pdoc table th, .pdoc table td{padding:6px 13px;border:1px solid var(--accent2);}</style>
    <style>/*! custom.css */</style></head>
<body>
    <nav class="pdoc">
        <label id="navtoggle" for="togglestate" class="pdoc-button"><svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'><path stroke-linecap='round' stroke="currentColor" stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/></svg></label>
        <input id="togglestate" type="checkbox" aria-hidden="true" tabindex="-1">
        <div>            <a class="pdoc-button module-list-button" href="../vimgolf_gym.html">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-box-arrow-in-left" viewBox="0 0 16 16">
  <path fill-rule="evenodd" d="M10 3.5a.5.5 0 0 0-.5-.5h-8a.5.5 0 0 0-.5.5v9a.5.5 0 0 0 .5.5h8a.5.5 0 0 0 .5-.5v-2a.5.5 0 0 1 1 0v2A1.5 1.5 0 0 1 9.5 14h-8A1.5 1.5 0 0 1 0 12.5v-9A1.5 1.5 0 0 1 1.5 2h8A1.5 1.5 0 0 1 11 3.5v2a.5.5 0 0 1-1 0v-2z"/>
  <path fill-rule="evenodd" d="M4.146 8.354a.5.5 0 0 1 0-.708l3-3a.5.5 0 1 1 .708.708L5.707 7.5H14.5a.5.5 0 0 1 0 1H5.707l2.147 2.146a.5.5 0 0 1-.708.708l-3-3z"/>
</svg>                &nbsp;vimgolf_gym</a>


            <input type="search" placeholder="Search..." role="searchbox" aria-label="search"
                   pattern=".+" required>



            <h2>API Documentation</h2>
                <ul class="memberlist">
            <li>
                    <a class="class" href="#AbstractLogParser">AbstractLogParser</a>
                            <ul class="memberlist">
                        <li>
                                <a class="function" href="#AbstractLogParser.feed_line">feed_line</a>
                        </li>
                </ul>

            </li>
            <li>
                    <a class="class" href="#LogWatcher">LogWatcher</a>
                            <ul class="memberlist">
                        <li>
                                <a class="function" href="#LogWatcher.__init__">LogWatcher</a>
                        </li>
                        <li>
                                <a class="variable" href="#LogWatcher.log_file">log_file</a>
                        </li>
                        <li>
                                <a class="variable" href="#LogWatcher.parser_class">parser_class</a>
                        </li>
                        <li>
                                <a class="variable" href="#LogWatcher.parser">parser</a>
                        </li>
                        <li>
                                <a class="variable" href="#LogWatcher.last_filesize">last_filesize</a>
                        </li>
                        <li>
                                <a class="variable" href="#LogWatcher.last_position">last_position</a>
                        </li>
                        <li>
                                <a class="function" href="#LogWatcher.update">update</a>
                        </li>
                        <li>
                                <a class="function" href="#LogWatcher.simple_update">simple_update</a>
                        </li>
                        <li>
                                <a class="function" href="#LogWatcher.naive_update">naive_update</a>
                        </li>
                        <li>
                                <a class="function" href="#LogWatcher.advanced_update">advanced_update</a>
                        </li>
                </ul>

            </li>
            <li>
                    <a class="class" href="#VimGolfLogWatcher">VimGolfLogWatcher</a>
                            <ul class="memberlist">
                        <li>
                                <a class="function" href="#VimGolfLogWatcher.__init__">VimGolfLogWatcher</a>
                        </li>
                        <li>
                                <a class="variable" href="#VimGolfLogWatcher.parser">parser</a>
                        </li>
                        <li>
                                <a class="variable" href="#VimGolfLogWatcher.update_style">update_style</a>
                        </li>
                        <li>
                                <a class="function" href="#VimGolfLogWatcher.default_update">default_update</a>
                        </li>
                        <li>
                                <a class="variable" href="#VimGolfLogWatcher.success">success</a>
                        </li>
                        <li>
                                <a class="function" href="#VimGolfLogWatcher.get_best_success_result">get_best_success_result</a>
                        </li>
                        <li>
                                <a class="function" href="#VimGolfLogWatcher.get_last_success_result">get_last_success_result</a>
                        </li>
                        <li>
                                <a class="variable" href="#VimGolfLogWatcher.results">results</a>
                        </li>
                        <li>
                                <a class="variable" href="#VimGolfLogWatcher.success_results">success_results</a>
                        </li>
                </ul>

            </li>
            <li>
                    <a class="class" href="#VimGolfLogParser">VimGolfLogParser</a>
                            <ul class="memberlist">
                        <li>
                                <a class="function" href="#VimGolfLogParser.__init__">VimGolfLogParser</a>
                        </li>
                        <li>
                                <a class="variable" href="#VimGolfLogParser.results">results</a>
                        </li>
                        <li>
                                <a class="function" href="#VimGolfLogParser.feed_line">feed_line</a>
                        </li>
                        <li>
                                <a class="variable" href="#VimGolfLogParser.success_results">success_results</a>
                        </li>
                        <li>
                                <a class="variable" href="#VimGolfLogParser.success">success</a>
                        </li>
                        <li>
                                <a class="function" href="#VimGolfLogParser.get_last_success_result">get_last_success_result</a>
                        </li>
                        <li>
                                <a class="function" href="#VimGolfLogParser.get_best_success_result">get_best_success_result</a>
                        </li>
                </ul>

            </li>
    </ul>



        <a class="attribution" title="pdoc: Python API documentation generator" href="https://pdoc.dev" target="_blank">
            built with <span class="visually-hidden">pdoc</span><img
                alt="pdoc logo"
                src="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20role%3D%22img%22%20aria-label%3D%22pdoc%20logo%22%20width%3D%22300%22%20height%3D%22150%22%20viewBox%3D%22-1%200%2060%2030%22%3E%3Ctitle%3Epdoc%3C/title%3E%3Cpath%20d%3D%22M29.621%2021.293c-.011-.273-.214-.475-.511-.481a.5.5%200%200%200-.489.503l-.044%201.393c-.097.551-.695%201.215-1.566%201.704-.577.428-1.306.486-2.193.182-1.426-.617-2.467-1.654-3.304-2.487l-.173-.172a3.43%203.43%200%200%200-.365-.306.49.49%200%200%200-.286-.196c-1.718-1.06-4.931-1.47-7.353.191l-.219.15c-1.707%201.187-3.413%202.131-4.328%201.03-.02-.027-.49-.685-.141-1.763.233-.721.546-2.408.772-4.076.042-.09.067-.187.046-.288.166-1.347.277-2.625.241-3.351%201.378-1.008%202.271-2.586%202.271-4.362%200-.976-.272-1.935-.788-2.774-.057-.094-.122-.18-.184-.268.033-.167.052-.339.052-.516%200-1.477-1.202-2.679-2.679-2.679-.791%200-1.496.352-1.987.9a6.3%206.3%200%200%200-1.001.029c-.492-.564-1.207-.929-2.012-.929-1.477%200-2.679%201.202-2.679%202.679A2.65%202.65%200%200%200%20.97%206.554c-.383.747-.595%201.572-.595%202.41%200%202.311%201.507%204.29%203.635%205.107-.037.699-.147%202.27-.423%203.294l-.137.461c-.622%202.042-2.515%208.257%201.727%2010.643%201.614.908%203.06%201.248%204.317%201.248%202.665%200%204.492-1.524%205.322-2.401%201.476-1.559%202.886-1.854%206.491.82%201.877%201.393%203.514%201.753%204.861%201.068%202.223-1.713%202.811-3.867%203.399-6.374.077-.846.056-1.469.054-1.537zm-4.835%204.313c-.054.305-.156.586-.242.629-.034-.007-.131-.022-.307-.157-.145-.111-.314-.478-.456-.908.221.121.432.25.675.355.115.039.219.051.33.081zm-2.251-1.238c-.05.33-.158.648-.252.694-.022.001-.125-.018-.307-.157-.217-.166-.488-.906-.639-1.573.358.344.754.693%201.198%201.036zm-3.887-2.337c-.006-.116-.018-.231-.041-.342.635.145%201.189.368%201.599.625.097.231.166.481.174.642-.03.049-.055.101-.067.158-.046.013-.128.026-.298.004-.278-.037-.901-.57-1.367-1.087zm-1.127-.497c.116.306.176.625.12.71-.019.014-.117.045-.345.016-.206-.027-.604-.332-.986-.695.41-.051.816-.056%201.211-.031zm-4.535%201.535c.209.22.379.47.358.598-.006.041-.088.138-.351.234-.144.055-.539-.063-.979-.259a11.66%2011.66%200%200%200%20.972-.573zm.983-.664c.359-.237.738-.418%201.126-.554.25.237.479.548.457.694-.006.042-.087.138-.351.235-.174.064-.694-.105-1.232-.375zm-3.381%201.794c-.022.145-.061.29-.149.401-.133.166-.358.248-.69.251h-.002c-.133%200-.306-.26-.45-.621.417.091.854.07%201.291-.031zm-2.066-8.077a4.78%204.78%200%200%201-.775-.584c.172-.115.505-.254.88-.378l-.105.962zm-.331%202.302a10.32%2010.32%200%200%201-.828-.502c.202-.143.576-.328.984-.49l-.156.992zm-.45%202.157l-.701-.403c.214-.115.536-.249.891-.376a11.57%2011.57%200%200%201-.19.779zm-.181%201.716c.064.398.194.702.298.893-.194-.051-.435-.162-.736-.398.061-.119.224-.3.438-.495zM8.87%204.141c0%20.152-.123.276-.276.276s-.275-.124-.275-.276.123-.276.276-.276.275.124.275.276zm-.735-.389a1.15%201.15%200%200%200-.314.783%201.16%201.16%200%200%200%201.162%201.162c.457%200%20.842-.27%201.032-.653.026.117.042.238.042.362a1.68%201.68%200%200%201-1.679%201.679%201.68%201.68%200%200%201-1.679-1.679c0-.843.626-1.535%201.436-1.654zM5.059%205.406A1.68%201.68%200%200%201%203.38%207.085a1.68%201.68%200%200%201-1.679-1.679c0-.037.009-.072.011-.109.21.3.541.508.935.508a1.16%201.16%200%200%200%201.162-1.162%201.14%201.14%200%200%200-.474-.912c.015%200%20.03-.005.045-.005.926.001%201.679.754%201.679%201.68zM3.198%204.141c0%20.152-.123.276-.276.276s-.275-.124-.275-.276.123-.276.276-.276.275.124.275.276zM1.375%208.964c0-.52.103-1.035.288-1.52.466.394%201.06.64%201.717.64%201.144%200%202.116-.725%202.499-1.738.383%201.012%201.355%201.738%202.499%201.738.867%200%201.631-.421%202.121-1.062.307.605.478%201.267.478%201.942%200%202.486-2.153%204.51-4.801%204.51s-4.801-2.023-4.801-4.51zm24.342%2019.349c-.985.498-2.267.168-3.813-.979-3.073-2.281-5.453-3.199-7.813-.705-1.315%201.391-4.163%203.365-8.423.97-3.174-1.786-2.239-6.266-1.261-9.479l.146-.492c.276-1.02.395-2.457.444-3.268a6.11%206.11%200%200%200%201.18.115%206.01%206.01%200%200%200%202.536-.562l-.006.175c-.802.215-1.848.612-2.021%201.25-.079.295.021.601.274.837.219.203.415.364.598.501-.667.304-1.243.698-1.311%201.179-.02.144-.022.507.393.787.213.144.395.26.564.365-1.285.521-1.361.96-1.381%201.126-.018.142-.011.496.427.746l.854.489c-.473.389-.971.914-.999%201.429-.018.278.095.532.316.713.675.556%201.231.721%201.653.721.059%200%20.104-.014.158-.02.207.707.641%201.64%201.513%201.64h.013c.8-.008%201.236-.345%201.462-.626.173-.216.268-.457.325-.692.424.195.93.374%201.372.374.151%200%20.294-.021.423-.068.732-.27.944-.704.993-1.021.009-.061.003-.119.002-.179.266.086.538.147.789.147.15%200%20.294-.021.423-.069.542-.2.797-.489.914-.754.237.147.478.258.704.288.106.014.205.021.296.021.356%200%20.595-.101.767-.229.438.435%201.094.992%201.656%201.067.106.014.205.021.296.021a1.56%201.56%200%200%200%20.323-.035c.17.575.453%201.289.866%201.605.358.273.665.362.914.362a.99.99%200%200%200%20.421-.093%201.03%201.03%200%200%200%20.245-.164c.168.428.39.846.68%201.068.358.273.665.362.913.362a.99.99%200%200%200%20.421-.093c.317-.148.512-.448.639-.762.251.157.495.257.726.257.127%200%20.25-.024.37-.071.427-.17.706-.617.841-1.314.022-.015.047-.022.068-.038.067-.051.133-.104.196-.159-.443%201.486-1.107%202.761-2.086%203.257zM8.66%209.925a.5.5%200%201%200-1%200c0%20.653-.818%201.205-1.787%201.205s-1.787-.552-1.787-1.205a.5.5%200%201%200-1%200c0%201.216%201.25%202.205%202.787%202.205s2.787-.989%202.787-2.205zm4.4%2015.965l-.208.097c-2.661%201.258-4.708%201.436-6.086.527-1.542-1.017-1.88-3.19-1.844-4.198a.4.4%200%200%200-.385-.414c-.242-.029-.406.164-.414.385-.046%201.249.367%203.686%202.202%204.896.708.467%201.547.7%202.51.7%201.248%200%202.706-.392%204.362-1.174l.185-.086a.4.4%200%200%200%20.205-.527c-.089-.204-.326-.291-.527-.206zM9.547%202.292c.093.077.205.114.317.114a.5.5%200%200%200%20.318-.886L8.817.397a.5.5%200%200%200-.703.068.5.5%200%200%200%20.069.703l1.364%201.124zm-7.661-.065c.086%200%20.173-.022.253-.068l1.523-.893a.5.5%200%200%200-.506-.863l-1.523.892a.5.5%200%200%200-.179.685c.094.158.261.247.432.247z%22%20transform%3D%22matrix%28-1%200%200%201%2058%200%29%22%20fill%3D%22%233bb300%22/%3E%3Cpath%20d%3D%22M.3%2021.86V10.18q0-.46.02-.68.04-.22.18-.5.28-.54%201.34-.54%201.06%200%201.42.28.38.26.44.78.76-1.04%202.38-1.04%201.64%200%203.1%201.54%201.46%201.54%201.46%203.58%200%202.04-1.46%203.58-1.44%201.54-3.08%201.54-1.64%200-2.38-.92v4.04q0%20.46-.04.68-.02.22-.18.5-.14.3-.5.42-.36.12-.98.12-.62%200-1-.12-.36-.12-.52-.4-.14-.28-.18-.5-.02-.22-.02-.68zm3.96-9.42q-.46.54-.46%201.18%200%20.64.46%201.18.48.52%201.2.52.74%200%201.24-.52.52-.52.52-1.18%200-.66-.48-1.18-.48-.54-1.26-.54-.76%200-1.22.54zm14.741-8.36q.16-.3.54-.42.38-.12%201-.12.64%200%201.02.12.38.12.52.42.16.3.18.54.04.22.04.68v11.94q0%20.46-.04.7-.02.22-.18.5-.3.54-1.7.54-1.38%200-1.54-.98-.84.96-2.34.96-1.8%200-3.28-1.56-1.48-1.58-1.48-3.66%200-2.1%201.48-3.68%201.5-1.58%203.28-1.58%201.48%200%202.3%201v-4.2q0-.46.02-.68.04-.24.18-.52zm-3.24%2010.86q.52.54%201.26.54.74%200%201.22-.54.5-.54.5-1.18%200-.66-.48-1.22-.46-.56-1.26-.56-.8%200-1.28.56-.48.54-.48%201.2%200%20.66.52%201.2zm7.833-1.2q0-2.4%201.68-3.96%201.68-1.56%203.84-1.56%202.16%200%203.82%201.56%201.66%201.54%201.66%203.94%200%201.66-.86%202.96-.86%201.28-2.1%201.9-1.22.6-2.54.6-1.32%200-2.56-.64-1.24-.66-2.1-1.92-.84-1.28-.84-2.88zm4.18%201.44q.64.48%201.3.48.66%200%201.32-.5.66-.5.66-1.48%200-.98-.62-1.46-.62-.48-1.34-.48-.72%200-1.34.5-.62.5-.62%201.48%200%20.96.64%201.46zm11.412-1.44q0%20.84.56%201.32.56.46%201.18.46.64%200%201.18-.36.56-.38.9-.38.6%200%201.46%201.06.46.58.46%201.04%200%20.76-1.1%201.42-1.14.8-2.8.8-1.86%200-3.58-1.34-.82-.64-1.34-1.7-.52-1.08-.52-2.36%200-1.3.52-2.34.52-1.06%201.34-1.7%201.66-1.32%203.54-1.32.76%200%201.48.22.72.2%201.06.4l.32.2q.36.24.56.38.52.4.52.92%200%20.5-.42%201.14-.72%201.1-1.38%201.1-.38%200-1.08-.44-.36-.34-1.04-.34-.66%200-1.24.48-.58.48-.58%201.34z%22%20fill%3D%22green%22/%3E%3C/svg%3E"/>
        </a>
</div>
    </nav>
    <main class="pdoc">
            <section class="module-info">
                    <h1 class="modulename">
<a href="./../vimgolf_gym.html">vimgolf_gym</a><wbr>.log_parser    </h1>

                        <div class="docstring"><p>Log parser for VimGolf executor</p>
</div>

                        <input id="mod-log_parser-view-source" class="view-source-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">

                        <label class="view-source-button" for="mod-log_parser-view-source"><span>View Source</span></label>

                        <div class="pdoc-code codehilite"><pre><span></span><span id="L-1"><a href="#L-1"><span class="linenos">  1</span></a><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-2"><a href="#L-2"><span class="linenos">  2</span></a><span class="sd">Log parser for VimGolf executor</span>
</span><span id="L-3"><a href="#L-3"><span class="linenos">  3</span></a><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-4"><a href="#L-4"><span class="linenos">  4</span></a>
</span><span id="L-5"><a href="#L-5"><span class="linenos">  5</span></a><span class="kn">import</span><span class="w"> </span><span class="nn">copy</span>
</span><span id="L-6"><a href="#L-6"><span class="linenos">  6</span></a><span class="kn">import</span><span class="w"> </span><span class="nn">json</span>
</span><span id="L-7"><a href="#L-7"><span class="linenos">  7</span></a><span class="kn">import</span><span class="w"> </span><span class="nn">os</span>
</span><span id="L-8"><a href="#L-8"><span class="linenos">  8</span></a><span class="kn">from</span><span class="w"> </span><span class="nn">abc</span><span class="w"> </span><span class="kn">import</span> <span class="n">ABC</span><span class="p">,</span> <span class="n">abstractmethod</span>
</span><span id="L-9"><a href="#L-9"><span class="linenos">  9</span></a><span class="kn">from</span><span class="w"> </span><span class="nn">typing</span><span class="w"> </span><span class="kn">import</span> <span class="n">Type</span>
</span><span id="L-10"><a href="#L-10"><span class="linenos"> 10</span></a>
</span><span id="L-11"><a href="#L-11"><span class="linenos"> 11</span></a><span class="kn">from</span><span class="w"> </span><span class="nn">vimgolf_gym.dataclasses</span><span class="w"> </span><span class="kn">import</span> <span class="n">VimGolfEnvResult</span>
</span><span id="L-12"><a href="#L-12"><span class="linenos"> 12</span></a>
</span><span id="L-13"><a href="#L-13"><span class="linenos"> 13</span></a>
</span><span id="L-14"><a href="#L-14"><span class="linenos"> 14</span></a><span class="k">class</span><span class="w"> </span><span class="nc">AbstractLogParser</span><span class="p">(</span><span class="n">ABC</span><span class="p">):</span>
</span><span id="L-15"><a href="#L-15"><span class="linenos"> 15</span></a>    <span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="o">...</span>
</span><span id="L-16"><a href="#L-16"><span class="linenos"> 16</span></a>    <span class="nd">@abstractmethod</span>
</span><span id="L-17"><a href="#L-17"><span class="linenos"> 17</span></a>    <span class="k">def</span><span class="w"> </span><span class="nf">feed_line</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">line</span><span class="p">:</span> <span class="nb">str</span><span class="p">):</span> <span class="o">...</span>
</span><span id="L-18"><a href="#L-18"><span class="linenos"> 18</span></a>
</span><span id="L-19"><a href="#L-19"><span class="linenos"> 19</span></a>
</span><span id="L-20"><a href="#L-20"><span class="linenos"> 20</span></a><span class="c1"># We keep track of the log file attributes.</span>
</span><span id="L-21"><a href="#L-21"><span class="linenos"> 21</span></a><span class="c1"># Specifically, the file size.</span>
</span><span id="L-22"><a href="#L-22"><span class="linenos"> 22</span></a><span class="c1"># If the file size changes, we will reparse the log.</span>
</span><span id="L-23"><a href="#L-23"><span class="linenos"> 23</span></a><span class="c1"># In more advanced usage, we could seek to given point and parse from there, avoiding reparsing from the beginning.</span>
</span><span id="L-24"><a href="#L-24"><span class="linenos"> 24</span></a><span class="k">class</span><span class="w"> </span><span class="nc">LogWatcher</span><span class="p">:</span>
</span><span id="L-25"><a href="#L-25"><span class="linenos"> 25</span></a>    <span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">log_file</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">parser_class</span><span class="p">:</span> <span class="n">Type</span><span class="p">[</span><span class="n">AbstractLogParser</span><span class="p">]):</span>
</span><span id="L-26"><a href="#L-26"><span class="linenos"> 26</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-27"><a href="#L-27"><span class="linenos"> 27</span></a><span class="sd">        Initialize the log watcher with a log file and a parser class.</span>
</span><span id="L-28"><a href="#L-28"><span class="linenos"> 28</span></a>
</span><span id="L-29"><a href="#L-29"><span class="linenos"> 29</span></a><span class="sd">        Args:</span>
</span><span id="L-30"><a href="#L-30"><span class="linenos"> 30</span></a><span class="sd">            log_file (str): The path to the log file.</span>
</span><span id="L-31"><a href="#L-31"><span class="linenos"> 31</span></a><span class="sd">            parser_class (Type[AbstractLogParser]): A class that implements the AbstractLogParser interface.</span>
</span><span id="L-32"><a href="#L-32"><span class="linenos"> 32</span></a>
</span><span id="L-33"><a href="#L-33"><span class="linenos"> 33</span></a><span class="sd">        Attributes:</span>
</span><span id="L-34"><a href="#L-34"><span class="linenos"> 34</span></a><span class="sd">            log_file (str): The path to the log file.</span>
</span><span id="L-35"><a href="#L-35"><span class="linenos"> 35</span></a><span class="sd">            parser_class (Type[AbstractLogParser]): The class of the parser.</span>
</span><span id="L-36"><a href="#L-36"><span class="linenos"> 36</span></a><span class="sd">            parser (AbstractLogParser): An instance of the parser class.</span>
</span><span id="L-37"><a href="#L-37"><span class="linenos"> 37</span></a><span class="sd">            last_filesize (int): The size of the log file when it was last checked.</span>
</span><span id="L-38"><a href="#L-38"><span class="linenos"> 38</span></a><span class="sd">            last_position (int): The last read position in the log file.</span>
</span><span id="L-39"><a href="#L-39"><span class="linenos"> 39</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="L-40"><a href="#L-40"><span class="linenos"> 40</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">log_file</span> <span class="o">=</span> <span class="n">log_file</span>
</span><span id="L-41"><a href="#L-41"><span class="linenos"> 41</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">parser_class</span> <span class="o">=</span> <span class="n">parser_class</span>
</span><span id="L-42"><a href="#L-42"><span class="linenos"> 42</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">parser</span> <span class="o">=</span> <span class="n">parser_class</span><span class="p">()</span>
</span><span id="L-43"><a href="#L-43"><span class="linenos"> 43</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">last_filesize</span> <span class="o">=</span> <span class="mi">0</span>
</span><span id="L-44"><a href="#L-44"><span class="linenos"> 44</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">last_position</span> <span class="o">=</span> <span class="mi">0</span>  <span class="c1"># Track the last read position</span>
</span><span id="L-45"><a href="#L-45"><span class="linenos"> 45</span></a>
</span><span id="L-46"><a href="#L-46"><span class="linenos"> 46</span></a>    <span class="k">def</span><span class="w"> </span><span class="nf">update</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">style</span><span class="o">=</span><span class="s2">&quot;advanced&quot;</span><span class="p">):</span>
</span><span id="L-47"><a href="#L-47"><span class="linenos"> 47</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-48"><a href="#L-48"><span class="linenos"> 48</span></a><span class="sd">        Update the log watcher using one of three strategies.</span>
</span><span id="L-49"><a href="#L-49"><span class="linenos"> 49</span></a>
</span><span id="L-50"><a href="#L-50"><span class="linenos"> 50</span></a><span class="sd">        The ``advanced`` strategy is the default. It checks the file size</span>
</span><span id="L-51"><a href="#L-51"><span class="linenos"> 51</span></a><span class="sd">        and only reads new content if the file size has changed. If the file</span>
</span><span id="L-52"><a href="#L-52"><span class="linenos"> 52</span></a><span class="sd">        size is smaller than the last recorded size, it resets the parser and</span>
</span><span id="L-53"><a href="#L-53"><span class="linenos"> 53</span></a><span class="sd">        reads the entire file.</span>
</span><span id="L-54"><a href="#L-54"><span class="linenos"> 54</span></a>
</span><span id="L-55"><a href="#L-55"><span class="linenos"> 55</span></a><span class="sd">        The ``simple`` strategy reads the entire log file every time it is</span>
</span><span id="L-56"><a href="#L-56"><span class="linenos"> 56</span></a><span class="sd">        called. This is simple, but slow for large log files.</span>
</span><span id="L-57"><a href="#L-57"><span class="linenos"> 57</span></a>
</span><span id="L-58"><a href="#L-58"><span class="linenos"> 58</span></a><span class="sd">        The ``naive`` strategy reads the entire log file every time it is</span>
</span><span id="L-59"><a href="#L-59"><span class="linenos"> 59</span></a><span class="sd">        called, but it does not reset the parser. This is faster than the</span>
</span><span id="L-60"><a href="#L-60"><span class="linenos"> 60</span></a><span class="sd">        ``simple`` strategy, but it does not handle the case where the log</span>
</span><span id="L-61"><a href="#L-61"><span class="linenos"> 61</span></a><span class="sd">        file is truncated.</span>
</span><span id="L-62"><a href="#L-62"><span class="linenos"> 62</span></a>
</span><span id="L-63"><a href="#L-63"><span class="linenos"> 63</span></a><span class="sd">        Args:</span>
</span><span id="L-64"><a href="#L-64"><span class="linenos"> 64</span></a><span class="sd">            style (str, optional): The update strategy to use. Must be one of </span>
</span><span id="L-65"><a href="#L-65"><span class="linenos"> 65</span></a><span class="sd">                ``advanced``, ``simple``, or ``naive``. Defaults to ``advanced``.</span>
</span><span id="L-66"><a href="#L-66"><span class="linenos"> 66</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="L-67"><a href="#L-67"><span class="linenos"> 67</span></a>        <span class="k">if</span> <span class="n">style</span> <span class="o">==</span> <span class="s2">&quot;advanced&quot;</span><span class="p">:</span>
</span><span id="L-68"><a href="#L-68"><span class="linenos"> 68</span></a>            <span class="bp">self</span><span class="o">.</span><span class="n">advanced_update</span><span class="p">()</span>
</span><span id="L-69"><a href="#L-69"><span class="linenos"> 69</span></a>        <span class="k">elif</span> <span class="n">style</span> <span class="o">==</span> <span class="s2">&quot;simple&quot;</span><span class="p">:</span>
</span><span id="L-70"><a href="#L-70"><span class="linenos"> 70</span></a>            <span class="bp">self</span><span class="o">.</span><span class="n">simple_update</span><span class="p">()</span>
</span><span id="L-71"><a href="#L-71"><span class="linenos"> 71</span></a>        <span class="k">elif</span> <span class="n">style</span> <span class="o">==</span> <span class="s2">&quot;naive&quot;</span><span class="p">:</span>
</span><span id="L-72"><a href="#L-72"><span class="linenos"> 72</span></a>            <span class="bp">self</span><span class="o">.</span><span class="n">naive_update</span><span class="p">()</span>
</span><span id="L-73"><a href="#L-73"><span class="linenos"> 73</span></a>        <span class="k">else</span><span class="p">:</span>
</span><span id="L-74"><a href="#L-74"><span class="linenos"> 74</span></a>            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
</span><span id="L-75"><a href="#L-75"><span class="linenos"> 75</span></a>                <span class="s2">&quot;Unrecognized update option: </span><span class="si">%s</span><span class="s2"> (should be in advanced, simple, naive)&quot;</span>
</span><span id="L-76"><a href="#L-76"><span class="linenos"> 76</span></a>                <span class="o">%</span> <span class="n">style</span>
</span><span id="L-77"><a href="#L-77"><span class="linenos"> 77</span></a>            <span class="p">)</span>
</span><span id="L-78"><a href="#L-78"><span class="linenos"> 78</span></a>
</span><span id="L-79"><a href="#L-79"><span class="linenos"> 79</span></a>    <span class="k">def</span><span class="w"> </span><span class="nf">simple_update</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span id="L-80"><a href="#L-80"><span class="linenos"> 80</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-81"><a href="#L-81"><span class="linenos"> 81</span></a><span class="sd">        Read the entire log file and reset the parser if the file size has changed.</span>
</span><span id="L-82"><a href="#L-82"><span class="linenos"> 82</span></a>
</span><span id="L-83"><a href="#L-83"><span class="linenos"> 83</span></a><span class="sd">        The ``simple`` strategy reads the entire log file every time it is</span>
</span><span id="L-84"><a href="#L-84"><span class="linenos"> 84</span></a><span class="sd">        called. This is simple, but slow for large log files.</span>
</span><span id="L-85"><a href="#L-85"><span class="linenos"> 85</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="L-86"><a href="#L-86"><span class="linenos"> 86</span></a>        <span class="n">current_size</span> <span class="o">=</span> <span class="p">(</span>
</span><span id="L-87"><a href="#L-87"><span class="linenos"> 87</span></a>            <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">getsize</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">log_file</span><span class="p">)</span> <span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">log_file</span><span class="p">)</span> <span class="k">else</span> <span class="mi">0</span>
</span><span id="L-88"><a href="#L-88"><span class="linenos"> 88</span></a>        <span class="p">)</span>
</span><span id="L-89"><a href="#L-89"><span class="linenos"> 89</span></a>        <span class="k">if</span> <span class="n">current_size</span> <span class="o">!=</span> <span class="bp">self</span><span class="o">.</span><span class="n">last_filesize</span><span class="p">:</span>
</span><span id="L-90"><a href="#L-90"><span class="linenos"> 90</span></a>            <span class="bp">self</span><span class="o">.</span><span class="n">naive_update</span><span class="p">()</span>
</span><span id="L-91"><a href="#L-91"><span class="linenos"> 91</span></a>            <span class="bp">self</span><span class="o">.</span><span class="n">last_filesize</span> <span class="o">=</span> <span class="n">current_size</span>
</span><span id="L-92"><a href="#L-92"><span class="linenos"> 92</span></a>
</span><span id="L-93"><a href="#L-93"><span class="linenos"> 93</span></a>    <span class="k">def</span><span class="w"> </span><span class="nf">naive_update</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span id="L-94"><a href="#L-94"><span class="linenos"> 94</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-95"><a href="#L-95"><span class="linenos"> 95</span></a><span class="sd">        Reset the parser and read the entire log file.</span>
</span><span id="L-96"><a href="#L-96"><span class="linenos"> 96</span></a>
</span><span id="L-97"><a href="#L-97"><span class="linenos"> 97</span></a><span class="sd">        This is slow for large log files, but it is simple and handles</span>
</span><span id="L-98"><a href="#L-98"><span class="linenos"> 98</span></a><span class="sd">        the case where the log file is truncated.</span>
</span><span id="L-99"><a href="#L-99"><span class="linenos"> 99</span></a>
</span><span id="L-100"><a href="#L-100"><span class="linenos">100</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="L-101"><a href="#L-101"><span class="linenos">101</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">parser</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">parser_class</span><span class="p">()</span>
</span><span id="L-102"><a href="#L-102"><span class="linenos">102</span></a>        <span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">log_file</span><span class="p">):</span>
</span><span id="L-103"><a href="#L-103"><span class="linenos">103</span></a>            <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">log_file</span><span class="p">,</span> <span class="s2">&quot;r&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
</span><span id="L-104"><a href="#L-104"><span class="linenos">104</span></a>                <span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">f</span><span class="o">.</span><span class="n">readlines</span><span class="p">():</span>
</span><span id="L-105"><a href="#L-105"><span class="linenos">105</span></a>                    <span class="bp">self</span><span class="o">.</span><span class="n">parser</span><span class="o">.</span><span class="n">feed_line</span><span class="p">(</span><span class="n">line</span><span class="p">)</span>
</span><span id="L-106"><a href="#L-106"><span class="linenos">106</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">last_filesize</span> <span class="o">=</span> <span class="p">(</span>
</span><span id="L-107"><a href="#L-107"><span class="linenos">107</span></a>            <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">getsize</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">log_file</span><span class="p">)</span> <span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">log_file</span><span class="p">)</span> <span class="k">else</span> <span class="mi">0</span>
</span><span id="L-108"><a href="#L-108"><span class="linenos">108</span></a>        <span class="p">)</span>
</span><span id="L-109"><a href="#L-109"><span class="linenos">109</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">last_position</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">last_filesize</span>
</span><span id="L-110"><a href="#L-110"><span class="linenos">110</span></a>
</span><span id="L-111"><a href="#L-111"><span class="linenos">111</span></a>    <span class="k">def</span><span class="w"> </span><span class="nf">advanced_update</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span id="L-112"><a href="#L-112"><span class="linenos">112</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-113"><a href="#L-113"><span class="linenos">113</span></a><span class="sd">        Read only the new content from the log file.</span>
</span><span id="L-114"><a href="#L-114"><span class="linenos">114</span></a>
</span><span id="L-115"><a href="#L-115"><span class="linenos">115</span></a><span class="sd">        The ``advanced`` strategy reads only the new content from the log file,</span>
</span><span id="L-116"><a href="#L-116"><span class="linenos">116</span></a><span class="sd">        starting from the last recorded position. This is fast for large log</span>
</span><span id="L-117"><a href="#L-117"><span class="linenos">117</span></a><span class="sd">        files, but it requires keeping track of the last recorded position.</span>
</span><span id="L-118"><a href="#L-118"><span class="linenos">118</span></a>
</span><span id="L-119"><a href="#L-119"><span class="linenos">119</span></a><span class="sd">        If the file size has decreased, it resets the parser and reads the</span>
</span><span id="L-120"><a href="#L-120"><span class="linenos">120</span></a><span class="sd">        entire file.</span>
</span><span id="L-121"><a href="#L-121"><span class="linenos">121</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="L-122"><a href="#L-122"><span class="linenos">122</span></a>        <span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">log_file</span><span class="p">):</span>
</span><span id="L-123"><a href="#L-123"><span class="linenos">123</span></a>            <span class="k">return</span>
</span><span id="L-124"><a href="#L-124"><span class="linenos">124</span></a>
</span><span id="L-125"><a href="#L-125"><span class="linenos">125</span></a>        <span class="n">current_size</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">getsize</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">log_file</span><span class="p">)</span>
</span><span id="L-126"><a href="#L-126"><span class="linenos">126</span></a>
</span><span id="L-127"><a href="#L-127"><span class="linenos">127</span></a>        <span class="c1"># If file size decreased (file was truncated), do a full reset</span>
</span><span id="L-128"><a href="#L-128"><span class="linenos">128</span></a>        <span class="k">if</span> <span class="n">current_size</span> <span class="o">&lt;</span> <span class="bp">self</span><span class="o">.</span><span class="n">last_filesize</span><span class="p">:</span>
</span><span id="L-129"><a href="#L-129"><span class="linenos">129</span></a>            <span class="bp">self</span><span class="o">.</span><span class="n">naive_update</span><span class="p">()</span>
</span><span id="L-130"><a href="#L-130"><span class="linenos">130</span></a>            <span class="k">return</span>
</span><span id="L-131"><a href="#L-131"><span class="linenos">131</span></a>
</span><span id="L-132"><a href="#L-132"><span class="linenos">132</span></a>        <span class="c1"># If file size increased, read only the new content</span>
</span><span id="L-133"><a href="#L-133"><span class="linenos">133</span></a>        <span class="k">if</span> <span class="n">current_size</span> <span class="o">&gt;</span> <span class="bp">self</span><span class="o">.</span><span class="n">last_filesize</span><span class="p">:</span>
</span><span id="L-134"><a href="#L-134"><span class="linenos">134</span></a>            <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">log_file</span><span class="p">,</span> <span class="s2">&quot;r&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
</span><span id="L-135"><a href="#L-135"><span class="linenos">135</span></a>                <span class="n">f</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">last_position</span><span class="p">)</span>
</span><span id="L-136"><a href="#L-136"><span class="linenos">136</span></a>                <span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
</span><span id="L-137"><a href="#L-137"><span class="linenos">137</span></a>                    <span class="n">line</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">readline</span><span class="p">()</span>
</span><span id="L-138"><a href="#L-138"><span class="linenos">138</span></a>                    <span class="k">if</span> <span class="ow">not</span> <span class="n">line</span><span class="p">:</span>  <span class="c1"># End of file</span>
</span><span id="L-139"><a href="#L-139"><span class="linenos">139</span></a>                        <span class="k">break</span>
</span><span id="L-140"><a href="#L-140"><span class="linenos">140</span></a>                    <span class="bp">self</span><span class="o">.</span><span class="n">parser</span><span class="o">.</span><span class="n">feed_line</span><span class="p">(</span><span class="n">line</span><span class="p">)</span>
</span><span id="L-141"><a href="#L-141"><span class="linenos">141</span></a>
</span><span id="L-142"><a href="#L-142"><span class="linenos">142</span></a>                <span class="c1"># Update tracking variables</span>
</span><span id="L-143"><a href="#L-143"><span class="linenos">143</span></a>                <span class="bp">self</span><span class="o">.</span><span class="n">last_filesize</span> <span class="o">=</span> <span class="n">current_size</span>
</span><span id="L-144"><a href="#L-144"><span class="linenos">144</span></a>                <span class="bp">self</span><span class="o">.</span><span class="n">last_position</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">tell</span><span class="p">()</span>
</span><span id="L-145"><a href="#L-145"><span class="linenos">145</span></a>
</span><span id="L-146"><a href="#L-146"><span class="linenos">146</span></a>
</span><span id="L-147"><a href="#L-147"><span class="linenos">147</span></a><span class="k">class</span><span class="w"> </span><span class="nc">VimGolfLogWatcher</span><span class="p">(</span><span class="n">LogWatcher</span><span class="p">):</span>
</span><span id="L-148"><a href="#L-148"><span class="linenos">148</span></a>    <span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">log_file</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">update_style</span><span class="o">=</span><span class="s2">&quot;advanced&quot;</span><span class="p">):</span>
</span><span id="L-149"><a href="#L-149"><span class="linenos">149</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-150"><a href="#L-150"><span class="linenos">150</span></a><span class="sd">        Initialize a VimGolfLogWatcher with a log file and an update style.</span>
</span><span id="L-151"><a href="#L-151"><span class="linenos">151</span></a>
</span><span id="L-152"><a href="#L-152"><span class="linenos">152</span></a><span class="sd">        The VimGolfLogWatcher is a LogWatcher that is specialized for</span>
</span><span id="L-153"><a href="#L-153"><span class="linenos">153</span></a><span class="sd">        reading VimGolf logs.</span>
</span><span id="L-154"><a href="#L-154"><span class="linenos">154</span></a>
</span><span id="L-155"><a href="#L-155"><span class="linenos">155</span></a><span class="sd">        Args:</span>
</span><span id="L-156"><a href="#L-156"><span class="linenos">156</span></a><span class="sd">            log_file (str): The path to the log file.</span>
</span><span id="L-157"><a href="#L-157"><span class="linenos">157</span></a><span class="sd">            update_style (str, optional): The update strategy to use. Must be one of </span>
</span><span id="L-158"><a href="#L-158"><span class="linenos">158</span></a><span class="sd">                ``advanced``, ``simple``, or ``naive``. Defaults to ``advanced``.</span>
</span><span id="L-159"><a href="#L-159"><span class="linenos">159</span></a>
</span><span id="L-160"><a href="#L-160"><span class="linenos">160</span></a><span class="sd">        Returns:</span>
</span><span id="L-161"><a href="#L-161"><span class="linenos">161</span></a><span class="sd">            [return_type]: [description of return value]</span>
</span><span id="L-162"><a href="#L-162"><span class="linenos">162</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="L-163"><a href="#L-163"><span class="linenos">163</span></a>        <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">log_file</span><span class="o">=</span><span class="n">log_file</span><span class="p">,</span> <span class="n">parser_class</span><span class="o">=</span><span class="n">VimGolfLogParser</span><span class="p">)</span>
</span><span id="L-164"><a href="#L-164"><span class="linenos">164</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">parser</span><span class="p">:</span> <span class="n">VimGolfLogParser</span>
</span><span id="L-165"><a href="#L-165"><span class="linenos">165</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">update_style</span> <span class="o">=</span> <span class="n">update_style</span>
</span><span id="L-166"><a href="#L-166"><span class="linenos">166</span></a>
</span><span id="L-167"><a href="#L-167"><span class="linenos">167</span></a>    <span class="k">def</span><span class="w"> </span><span class="nf">default_update</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span id="L-168"><a href="#L-168"><span class="linenos">168</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-169"><a href="#L-169"><span class="linenos">169</span></a><span class="sd">        Call the update method with the default update style.</span>
</span><span id="L-170"><a href="#L-170"><span class="linenos">170</span></a>
</span><span id="L-171"><a href="#L-171"><span class="linenos">171</span></a><span class="sd">        This method is a convenience wrapper around the update method,</span>
</span><span id="L-172"><a href="#L-172"><span class="linenos">172</span></a><span class="sd">        calling it with the default update style specified in the</span>
</span><span id="L-173"><a href="#L-173"><span class="linenos">173</span></a><span class="sd">        constructor.</span>
</span><span id="L-174"><a href="#L-174"><span class="linenos">174</span></a>
</span><span id="L-175"><a href="#L-175"><span class="linenos">175</span></a><span class="sd">        See the update method for more details.</span>
</span><span id="L-176"><a href="#L-176"><span class="linenos">176</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="L-177"><a href="#L-177"><span class="linenos">177</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">style</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">update_style</span><span class="p">)</span>
</span><span id="L-178"><a href="#L-178"><span class="linenos">178</span></a>
</span><span id="L-179"><a href="#L-179"><span class="linenos">179</span></a>    <span class="nd">@property</span>
</span><span id="L-180"><a href="#L-180"><span class="linenos">180</span></a>    <span class="k">def</span><span class="w"> </span><span class="nf">success</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span id="L-181"><a href="#L-181"><span class="linenos">181</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-182"><a href="#L-182"><span class="linenos">182</span></a><span class="sd">        Check if the vimgolf challenge has been solved successfully.</span>
</span><span id="L-183"><a href="#L-183"><span class="linenos">183</span></a>
</span><span id="L-184"><a href="#L-184"><span class="linenos">184</span></a><span class="sd">        This property checks if the vimgolf challenge has been solved</span>
</span><span id="L-185"><a href="#L-185"><span class="linenos">185</span></a><span class="sd">        successfully. It updates the log watcher if necessary before</span>
</span><span id="L-186"><a href="#L-186"><span class="linenos">186</span></a><span class="sd">        checking the success status.</span>
</span><span id="L-187"><a href="#L-187"><span class="linenos">187</span></a>
</span><span id="L-188"><a href="#L-188"><span class="linenos">188</span></a><span class="sd">        Returns:</span>
</span><span id="L-189"><a href="#L-189"><span class="linenos">189</span></a><span class="sd">            bool: True if the challenge has been solved successfully, False otherwise.</span>
</span><span id="L-190"><a href="#L-190"><span class="linenos">190</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="L-191"><a href="#L-191"><span class="linenos">191</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">default_update</span><span class="p">()</span>
</span><span id="L-192"><a href="#L-192"><span class="linenos">192</span></a>        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">parser</span><span class="o">.</span><span class="n">success</span>
</span><span id="L-193"><a href="#L-193"><span class="linenos">193</span></a>
</span><span id="L-194"><a href="#L-194"><span class="linenos">194</span></a>    <span class="k">def</span><span class="w"> </span><span class="nf">get_best_success_result</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span id="L-195"><a href="#L-195"><span class="linenos">195</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-196"><a href="#L-196"><span class="linenos">196</span></a><span class="sd">        Return the best success result in the log watcher.</span>
</span><span id="L-197"><a href="#L-197"><span class="linenos">197</span></a>
</span><span id="L-198"><a href="#L-198"><span class="linenos">198</span></a><span class="sd">        This method returns the best success result in the log watcher,</span>
</span><span id="L-199"><a href="#L-199"><span class="linenos">199</span></a><span class="sd">        updating the log watcher if necessary before returning the result.</span>
</span><span id="L-200"><a href="#L-200"><span class="linenos">200</span></a>
</span><span id="L-201"><a href="#L-201"><span class="linenos">201</span></a><span class="sd">        Returns:</span>
</span><span id="L-202"><a href="#L-202"><span class="linenos">202</span></a><span class="sd">            VimGolfEnvResult: The best success result in the log watcher, or None if </span>
</span><span id="L-203"><a href="#L-203"><span class="linenos">203</span></a><span class="sd">            there is no success result.</span>
</span><span id="L-204"><a href="#L-204"><span class="linenos">204</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="L-205"><a href="#L-205"><span class="linenos">205</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">default_update</span><span class="p">()</span>
</span><span id="L-206"><a href="#L-206"><span class="linenos">206</span></a>        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">parser</span><span class="o">.</span><span class="n">get_best_success_result</span><span class="p">()</span>
</span><span id="L-207"><a href="#L-207"><span class="linenos">207</span></a>
</span><span id="L-208"><a href="#L-208"><span class="linenos">208</span></a>    <span class="k">def</span><span class="w"> </span><span class="nf">get_last_success_result</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span id="L-209"><a href="#L-209"><span class="linenos">209</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-210"><a href="#L-210"><span class="linenos">210</span></a><span class="sd">        Return the last success result in the log watcher.</span>
</span><span id="L-211"><a href="#L-211"><span class="linenos">211</span></a>
</span><span id="L-212"><a href="#L-212"><span class="linenos">212</span></a><span class="sd">        This method returns the last success result in the log watcher,</span>
</span><span id="L-213"><a href="#L-213"><span class="linenos">213</span></a><span class="sd">        updating the log watcher if necessary before returning the result.</span>
</span><span id="L-214"><a href="#L-214"><span class="linenos">214</span></a>
</span><span id="L-215"><a href="#L-215"><span class="linenos">215</span></a><span class="sd">        Returns:</span>
</span><span id="L-216"><a href="#L-216"><span class="linenos">216</span></a><span class="sd">            VimGolfEnvResult: The last success result in the log watcher, or None if </span>
</span><span id="L-217"><a href="#L-217"><span class="linenos">217</span></a><span class="sd">            there is no success result.</span>
</span><span id="L-218"><a href="#L-218"><span class="linenos">218</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="L-219"><a href="#L-219"><span class="linenos">219</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">default_update</span><span class="p">()</span>
</span><span id="L-220"><a href="#L-220"><span class="linenos">220</span></a>        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">parser</span><span class="o">.</span><span class="n">get_last_success_result</span><span class="p">()</span>
</span><span id="L-221"><a href="#L-221"><span class="linenos">221</span></a>
</span><span id="L-222"><a href="#L-222"><span class="linenos">222</span></a>    <span class="nd">@property</span>
</span><span id="L-223"><a href="#L-223"><span class="linenos">223</span></a>    <span class="k">def</span><span class="w"> </span><span class="nf">results</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span id="L-224"><a href="#L-224"><span class="linenos">224</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-225"><a href="#L-225"><span class="linenos">225</span></a><span class="sd">        The results of the vimgolf challenge environment.</span>
</span><span id="L-226"><a href="#L-226"><span class="linenos">226</span></a>
</span><span id="L-227"><a href="#L-227"><span class="linenos">227</span></a><span class="sd">        This property returns the results of the vimgolf challenge environment,</span>
</span><span id="L-228"><a href="#L-228"><span class="linenos">228</span></a><span class="sd">        updating the log watcher if necessary before returning the results.</span>
</span><span id="L-229"><a href="#L-229"><span class="linenos">229</span></a>
</span><span id="L-230"><a href="#L-230"><span class="linenos">230</span></a><span class="sd">        Returns:</span>
</span><span id="L-231"><a href="#L-231"><span class="linenos">231</span></a><span class="sd">            list[VimGolfEnvResult]: The results of the vimgolf challenge environment, or an empty list if</span>
</span><span id="L-232"><a href="#L-232"><span class="linenos">232</span></a><span class="sd">            there are no results.</span>
</span><span id="L-233"><a href="#L-233"><span class="linenos">233</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="L-234"><a href="#L-234"><span class="linenos">234</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">default_update</span><span class="p">()</span>
</span><span id="L-235"><a href="#L-235"><span class="linenos">235</span></a>        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">parser</span><span class="o">.</span><span class="n">results</span>
</span><span id="L-236"><a href="#L-236"><span class="linenos">236</span></a>
</span><span id="L-237"><a href="#L-237"><span class="linenos">237</span></a>    <span class="nd">@property</span>
</span><span id="L-238"><a href="#L-238"><span class="linenos">238</span></a>    <span class="k">def</span><span class="w"> </span><span class="nf">success_results</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span id="L-239"><a href="#L-239"><span class="linenos">239</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-240"><a href="#L-240"><span class="linenos">240</span></a><span class="sd">        The successful results of the vimgolf challenge environment.</span>
</span><span id="L-241"><a href="#L-241"><span class="linenos">241</span></a>
</span><span id="L-242"><a href="#L-242"><span class="linenos">242</span></a><span class="sd">        This property returns the successful results of the vimgolf challenge</span>
</span><span id="L-243"><a href="#L-243"><span class="linenos">243</span></a><span class="sd">        environment, updating the log watcher if necessary before returning the</span>
</span><span id="L-244"><a href="#L-244"><span class="linenos">244</span></a><span class="sd">        results.</span>
</span><span id="L-245"><a href="#L-245"><span class="linenos">245</span></a>
</span><span id="L-246"><a href="#L-246"><span class="linenos">246</span></a><span class="sd">        Returns:</span>
</span><span id="L-247"><a href="#L-247"><span class="linenos">247</span></a><span class="sd">            list[VimGolfEnvResult]: The successful results of the vimgolf challenge environment, or an</span>
</span><span id="L-248"><a href="#L-248"><span class="linenos">248</span></a><span class="sd">            empty list if there are no successful results.</span>
</span><span id="L-249"><a href="#L-249"><span class="linenos">249</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="L-250"><a href="#L-250"><span class="linenos">250</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">default_update</span><span class="p">()</span>
</span><span id="L-251"><a href="#L-251"><span class="linenos">251</span></a>        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">parser</span><span class="o">.</span><span class="n">success_results</span>
</span><span id="L-252"><a href="#L-252"><span class="linenos">252</span></a>
</span><span id="L-253"><a href="#L-253"><span class="linenos">253</span></a>
</span><span id="L-254"><a href="#L-254"><span class="linenos">254</span></a><span class="k">class</span><span class="w"> </span><span class="nc">VimGolfLogParser</span><span class="p">(</span><span class="n">AbstractLogParser</span><span class="p">):</span>
</span><span id="L-255"><a href="#L-255"><span class="linenos">255</span></a>    <span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span id="L-256"><a href="#L-256"><span class="linenos">256</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-257"><a href="#L-257"><span class="linenos">257</span></a><span class="sd">        Initialize the VimGolfLogParser.</span>
</span><span id="L-258"><a href="#L-258"><span class="linenos">258</span></a>
</span><span id="L-259"><a href="#L-259"><span class="linenos">259</span></a><span class="sd">        The VimGolfLogParser is initialized with an empty list of results.</span>
</span><span id="L-260"><a href="#L-260"><span class="linenos">260</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="L-261"><a href="#L-261"><span class="linenos">261</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">results</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="n">VimGolfEnvResult</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
</span><span id="L-262"><a href="#L-262"><span class="linenos">262</span></a>
</span><span id="L-263"><a href="#L-263"><span class="linenos">263</span></a>    <span class="k">def</span><span class="w"> </span><span class="nf">feed_line</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">line</span><span class="p">:</span> <span class="nb">str</span><span class="p">):</span>
</span><span id="L-264"><a href="#L-264"><span class="linenos">264</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-265"><a href="#L-265"><span class="linenos">265</span></a><span class="sd">        Feed a line to the parser.</span>
</span><span id="L-266"><a href="#L-266"><span class="linenos">266</span></a>
</span><span id="L-267"><a href="#L-267"><span class="linenos">267</span></a><span class="sd">        The line should be a JSON-formatted string. The parser will attempt to</span>
</span><span id="L-268"><a href="#L-268"><span class="linenos">268</span></a><span class="sd">        parse the line as a JSON object, and if it is a dictionary, it will</span>
</span><span id="L-269"><a href="#L-269"><span class="linenos">269</span></a><span class="sd">        check if the dictionary has an &quot;event_type&quot; key with value</span>
</span><span id="L-270"><a href="#L-270"><span class="linenos">270</span></a><span class="sd">        &quot;vimgolf_result&quot;. If so, it will attempt to parse the value of the</span>
</span><span id="L-271"><a href="#L-271"><span class="linenos">271</span></a><span class="sd">        &quot;event_data&quot; key as a VimGolfEnvResult object and append it to the</span>
</span><span id="L-272"><a href="#L-272"><span class="linenos">272</span></a><span class="sd">        results list.</span>
</span><span id="L-273"><a href="#L-273"><span class="linenos">273</span></a>
</span><span id="L-274"><a href="#L-274"><span class="linenos">274</span></a><span class="sd">        If the line is not a valid JSON object, or if the JSON object does not</span>
</span><span id="L-275"><a href="#L-275"><span class="linenos">275</span></a><span class="sd">        have the correct structure, the line will be ignored.</span>
</span><span id="L-276"><a href="#L-276"><span class="linenos">276</span></a>
</span><span id="L-277"><a href="#L-277"><span class="linenos">277</span></a><span class="sd">        Args:</span>
</span><span id="L-278"><a href="#L-278"><span class="linenos">278</span></a><span class="sd">            line (str): The line of text to feed to the parser.</span>
</span><span id="L-279"><a href="#L-279"><span class="linenos">279</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="L-280"><a href="#L-280"><span class="linenos">280</span></a>        <span class="k">try</span><span class="p">:</span>
</span><span id="L-281"><a href="#L-281"><span class="linenos">281</span></a>            <span class="n">data</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">line</span><span class="o">.</span><span class="n">strip</span><span class="p">())</span>
</span><span id="L-282"><a href="#L-282"><span class="linenos">282</span></a>            <span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> <span class="o">==</span> <span class="nb">dict</span><span class="p">:</span>
</span><span id="L-283"><a href="#L-283"><span class="linenos">283</span></a>                <span class="k">if</span> <span class="n">data</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;event_type&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> <span class="o">==</span> <span class="s2">&quot;vimgolf_result&quot;</span><span class="p">:</span>
</span><span id="L-284"><a href="#L-284"><span class="linenos">284</span></a>                    <span class="n">event_data</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;event_data&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
</span><span id="L-285"><a href="#L-285"><span class="linenos">285</span></a>                    <span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">event_data</span><span class="p">)</span> <span class="o">==</span> <span class="nb">dict</span><span class="p">:</span>
</span><span id="L-286"><a href="#L-286"><span class="linenos">286</span></a>                        <span class="n">parsed_result</span> <span class="o">=</span> <span class="n">VimGolfEnvResult</span><span class="o">.</span><span class="n">parse_obj</span><span class="p">(</span><span class="n">event_data</span><span class="p">)</span>
</span><span id="L-287"><a href="#L-287"><span class="linenos">287</span></a>                        <span class="bp">self</span><span class="o">.</span><span class="n">results</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">parsed_result</span><span class="p">)</span>
</span><span id="L-288"><a href="#L-288"><span class="linenos">288</span></a>        <span class="k">except</span> <span class="n">json</span><span class="o">.</span><span class="n">JSONDecodeError</span><span class="p">:</span>
</span><span id="L-289"><a href="#L-289"><span class="linenos">289</span></a>            <span class="o">...</span>
</span><span id="L-290"><a href="#L-290"><span class="linenos">290</span></a>
</span><span id="L-291"><a href="#L-291"><span class="linenos">291</span></a>    <span class="nd">@property</span>
</span><span id="L-292"><a href="#L-292"><span class="linenos">292</span></a>    <span class="k">def</span><span class="w"> </span><span class="nf">success_results</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span id="L-293"><a href="#L-293"><span class="linenos">293</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-294"><a href="#L-294"><span class="linenos">294</span></a><span class="sd">        The successful results of the vimgolf challenge environment.</span>
</span><span id="L-295"><a href="#L-295"><span class="linenos">295</span></a>
</span><span id="L-296"><a href="#L-296"><span class="linenos">296</span></a><span class="sd">        This property returns the successful results of the vimgolf challenge</span>
</span><span id="L-297"><a href="#L-297"><span class="linenos">297</span></a><span class="sd">        environment, which are the results in the results list where the</span>
</span><span id="L-298"><a href="#L-298"><span class="linenos">298</span></a><span class="sd">        correct attribute is True.</span>
</span><span id="L-299"><a href="#L-299"><span class="linenos">299</span></a>
</span><span id="L-300"><a href="#L-300"><span class="linenos">300</span></a><span class="sd">        Returns:</span>
</span><span id="L-301"><a href="#L-301"><span class="linenos">301</span></a><span class="sd">            list[VimGolfEnvResult]: The successful results of the vimgolf challenge environment, or an</span>
</span><span id="L-302"><a href="#L-302"><span class="linenos">302</span></a><span class="sd">            empty list if there are no successful results.</span>
</span><span id="L-303"><a href="#L-303"><span class="linenos">303</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="L-304"><a href="#L-304"><span class="linenos">304</span></a>        <span class="k">return</span> <span class="p">[</span><span class="n">it</span> <span class="k">for</span> <span class="n">it</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">results</span> <span class="k">if</span> <span class="n">it</span><span class="o">.</span><span class="n">correct</span><span class="p">]</span>
</span><span id="L-305"><a href="#L-305"><span class="linenos">305</span></a>
</span><span id="L-306"><a href="#L-306"><span class="linenos">306</span></a>    <span class="nd">@property</span>
</span><span id="L-307"><a href="#L-307"><span class="linenos">307</span></a>    <span class="k">def</span><span class="w"> </span><span class="nf">success</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span id="L-308"><a href="#L-308"><span class="linenos">308</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-309"><a href="#L-309"><span class="linenos">309</span></a><span class="sd">        Check if the vimgolf challenge has been solved successfully.</span>
</span><span id="L-310"><a href="#L-310"><span class="linenos">310</span></a>
</span><span id="L-311"><a href="#L-311"><span class="linenos">311</span></a><span class="sd">        This property checks if the vimgolf challenge has been solved</span>
</span><span id="L-312"><a href="#L-312"><span class="linenos">312</span></a><span class="sd">        successfully. It returns True if there are any successful results in</span>
</span><span id="L-313"><a href="#L-313"><span class="linenos">313</span></a><span class="sd">        the results list, and False otherwise.</span>
</span><span id="L-314"><a href="#L-314"><span class="linenos">314</span></a>
</span><span id="L-315"><a href="#L-315"><span class="linenos">315</span></a><span class="sd">        Returns:</span>
</span><span id="L-316"><a href="#L-316"><span class="linenos">316</span></a><span class="sd">            bool: True if the challenge has been solved successfully, False otherwise.</span>
</span><span id="L-317"><a href="#L-317"><span class="linenos">317</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="L-318"><a href="#L-318"><span class="linenos">318</span></a>        <span class="k">return</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">success_results</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">0</span>
</span><span id="L-319"><a href="#L-319"><span class="linenos">319</span></a>
</span><span id="L-320"><a href="#L-320"><span class="linenos">320</span></a>    <span class="k">def</span><span class="w"> </span><span class="nf">get_last_success_result</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span id="L-321"><a href="#L-321"><span class="linenos">321</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-322"><a href="#L-322"><span class="linenos">322</span></a><span class="sd">        Return the last success result in the log watcher.</span>
</span><span id="L-323"><a href="#L-323"><span class="linenos">323</span></a>
</span><span id="L-324"><a href="#L-324"><span class="linenos">324</span></a><span class="sd">        This method returns the last success result in the log watcher,</span>
</span><span id="L-325"><a href="#L-325"><span class="linenos">325</span></a><span class="sd">        which is the last result in the success_results list.</span>
</span><span id="L-326"><a href="#L-326"><span class="linenos">326</span></a>
</span><span id="L-327"><a href="#L-327"><span class="linenos">327</span></a><span class="sd">        Returns:</span>
</span><span id="L-328"><a href="#L-328"><span class="linenos">328</span></a><span class="sd">            VimGolfEnvResult: The last success result in the log watcher, or None if there is no</span>
</span><span id="L-329"><a href="#L-329"><span class="linenos">329</span></a><span class="sd">            success result.</span>
</span><span id="L-330"><a href="#L-330"><span class="linenos">330</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="L-331"><a href="#L-331"><span class="linenos">331</span></a>        <span class="n">success_results</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">success_results</span>
</span><span id="L-332"><a href="#L-332"><span class="linenos">332</span></a>        <span class="k">if</span> <span class="n">success_results</span><span class="p">:</span>
</span><span id="L-333"><a href="#L-333"><span class="linenos">333</span></a>            <span class="k">return</span> <span class="n">success_results</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
</span><span id="L-334"><a href="#L-334"><span class="linenos">334</span></a>
</span><span id="L-335"><a href="#L-335"><span class="linenos">335</span></a>    <span class="k">def</span><span class="w"> </span><span class="nf">get_best_success_result</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span id="L-336"><a href="#L-336"><span class="linenos">336</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;Return the result with the lowest score&quot;&quot;&quot;</span>
</span><span id="L-337"><a href="#L-337"><span class="linenos">337</span></a>        <span class="n">success_results</span> <span class="o">=</span> <span class="n">copy</span><span class="o">.</span><span class="n">deepcopy</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">success_results</span><span class="p">)</span>
</span><span id="L-338"><a href="#L-338"><span class="linenos">338</span></a>        <span class="k">if</span> <span class="n">success_results</span><span class="p">:</span>
</span><span id="L-339"><a href="#L-339"><span class="linenos">339</span></a>            <span class="n">success_results</span><span class="o">.</span><span class="n">sort</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="n">x</span><span class="o">.</span><span class="n">score</span><span class="p">)</span>
</span><span id="L-340"><a href="#L-340"><span class="linenos">340</span></a>            <span class="k">return</span> <span class="n">success_results</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
</span></pre></div>


            </section>
                <section id="AbstractLogParser">
                            <input id="AbstractLogParser-view-source" class="view-source-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<div class="attr class">
            
    <span class="def">class</span>
    <span class="name">AbstractLogParser</span><wbr>(<span class="base">abc.ABC</span>):

                <label class="view-source-button" for="AbstractLogParser-view-source"><span>View Source</span></label>

    </div>
    <a class="headerlink" href="#AbstractLogParser"></a>
            <div class="pdoc-code codehilite"><pre><span></span><span id="AbstractLogParser-15"><a href="#AbstractLogParser-15"><span class="linenos">15</span></a><span class="k">class</span><span class="w"> </span><span class="nc">AbstractLogParser</span><span class="p">(</span><span class="n">ABC</span><span class="p">):</span>
</span><span id="AbstractLogParser-16"><a href="#AbstractLogParser-16"><span class="linenos">16</span></a>    <span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="o">...</span>
</span><span id="AbstractLogParser-17"><a href="#AbstractLogParser-17"><span class="linenos">17</span></a>    <span class="nd">@abstractmethod</span>
</span><span id="AbstractLogParser-18"><a href="#AbstractLogParser-18"><span class="linenos">18</span></a>    <span class="k">def</span><span class="w"> </span><span class="nf">feed_line</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">line</span><span class="p">:</span> <span class="nb">str</span><span class="p">):</span> <span class="o">...</span>
</span></pre></div>


            <div class="docstring"><p>Helper class that provides a standard way to create an ABC using
inheritance.</p>
</div>


                            <div id="AbstractLogParser.feed_line" class="classattr">
                                        <input id="AbstractLogParser.feed_line-view-source" class="view-source-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<div class="attr function">
                    <div class="decorator decorator-abstractmethod">@abstractmethod</div>

        <span class="def">def</span>
        <span class="name">feed_line</span><span class="signature pdoc-code condensed">(<span class="param"><span class="bp">self</span>, </span><span class="param"><span class="n">line</span><span class="p">:</span> <span class="nb">str</span></span><span class="return-annotation">):</span></span>

                <label class="view-source-button" for="AbstractLogParser.feed_line-view-source"><span>View Source</span></label>

    </div>
    <a class="headerlink" href="#AbstractLogParser.feed_line"></a>
            <div class="pdoc-code codehilite"><pre><span></span><span id="AbstractLogParser.feed_line-17"><a href="#AbstractLogParser.feed_line-17"><span class="linenos">17</span></a>    <span class="nd">@abstractmethod</span>
</span><span id="AbstractLogParser.feed_line-18"><a href="#AbstractLogParser.feed_line-18"><span class="linenos">18</span></a>    <span class="k">def</span><span class="w"> </span><span class="nf">feed_line</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">line</span><span class="p">:</span> <span class="nb">str</span><span class="p">):</span> <span class="o">...</span>
</span></pre></div>


    

                            </div>
                </section>
                <section id="LogWatcher">
                            <input id="LogWatcher-view-source" class="view-source-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<div class="attr class">
            
    <span class="def">class</span>
    <span class="name">LogWatcher</span>:

                <label class="view-source-button" for="LogWatcher-view-source"><span>View Source</span></label>

    </div>
    <a class="headerlink" href="#LogWatcher"></a>
            <div class="pdoc-code codehilite"><pre><span></span><span id="LogWatcher-25"><a href="#LogWatcher-25"><span class="linenos"> 25</span></a><span class="k">class</span><span class="w"> </span><span class="nc">LogWatcher</span><span class="p">:</span>
</span><span id="LogWatcher-26"><a href="#LogWatcher-26"><span class="linenos"> 26</span></a>    <span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">log_file</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">parser_class</span><span class="p">:</span> <span class="n">Type</span><span class="p">[</span><span class="n">AbstractLogParser</span><span class="p">]):</span>
</span><span id="LogWatcher-27"><a href="#LogWatcher-27"><span class="linenos"> 27</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="LogWatcher-28"><a href="#LogWatcher-28"><span class="linenos"> 28</span></a><span class="sd">        Initialize the log watcher with a log file and a parser class.</span>
</span><span id="LogWatcher-29"><a href="#LogWatcher-29"><span class="linenos"> 29</span></a>
</span><span id="LogWatcher-30"><a href="#LogWatcher-30"><span class="linenos"> 30</span></a><span class="sd">        Args:</span>
</span><span id="LogWatcher-31"><a href="#LogWatcher-31"><span class="linenos"> 31</span></a><span class="sd">            log_file (str): The path to the log file.</span>
</span><span id="LogWatcher-32"><a href="#LogWatcher-32"><span class="linenos"> 32</span></a><span class="sd">            parser_class (Type[AbstractLogParser]): A class that implements the AbstractLogParser interface.</span>
</span><span id="LogWatcher-33"><a href="#LogWatcher-33"><span class="linenos"> 33</span></a>
</span><span id="LogWatcher-34"><a href="#LogWatcher-34"><span class="linenos"> 34</span></a><span class="sd">        Attributes:</span>
</span><span id="LogWatcher-35"><a href="#LogWatcher-35"><span class="linenos"> 35</span></a><span class="sd">            log_file (str): The path to the log file.</span>
</span><span id="LogWatcher-36"><a href="#LogWatcher-36"><span class="linenos"> 36</span></a><span class="sd">            parser_class (Type[AbstractLogParser]): The class of the parser.</span>
</span><span id="LogWatcher-37"><a href="#LogWatcher-37"><span class="linenos"> 37</span></a><span class="sd">            parser (AbstractLogParser): An instance of the parser class.</span>
</span><span id="LogWatcher-38"><a href="#LogWatcher-38"><span class="linenos"> 38</span></a><span class="sd">            last_filesize (int): The size of the log file when it was last checked.</span>
</span><span id="LogWatcher-39"><a href="#LogWatcher-39"><span class="linenos"> 39</span></a><span class="sd">            last_position (int): The last read position in the log file.</span>
</span><span id="LogWatcher-40"><a href="#LogWatcher-40"><span class="linenos"> 40</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="LogWatcher-41"><a href="#LogWatcher-41"><span class="linenos"> 41</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">log_file</span> <span class="o">=</span> <span class="n">log_file</span>
</span><span id="LogWatcher-42"><a href="#LogWatcher-42"><span class="linenos"> 42</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">parser_class</span> <span class="o">=</span> <span class="n">parser_class</span>
</span><span id="LogWatcher-43"><a href="#LogWatcher-43"><span class="linenos"> 43</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">parser</span> <span class="o">=</span> <span class="n">parser_class</span><span class="p">()</span>
</span><span id="LogWatcher-44"><a href="#LogWatcher-44"><span class="linenos"> 44</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">last_filesize</span> <span class="o">=</span> <span class="mi">0</span>
</span><span id="LogWatcher-45"><a href="#LogWatcher-45"><span class="linenos"> 45</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">last_position</span> <span class="o">=</span> <span class="mi">0</span>  <span class="c1"># Track the last read position</span>
</span><span id="LogWatcher-46"><a href="#LogWatcher-46"><span class="linenos"> 46</span></a>
</span><span id="LogWatcher-47"><a href="#LogWatcher-47"><span class="linenos"> 47</span></a>    <span class="k">def</span><span class="w"> </span><span class="nf">update</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">style</span><span class="o">=</span><span class="s2">&quot;advanced&quot;</span><span class="p">):</span>
</span><span id="LogWatcher-48"><a href="#LogWatcher-48"><span class="linenos"> 48</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="LogWatcher-49"><a href="#LogWatcher-49"><span class="linenos"> 49</span></a><span class="sd">        Update the log watcher using one of three strategies.</span>
</span><span id="LogWatcher-50"><a href="#LogWatcher-50"><span class="linenos"> 50</span></a>
</span><span id="LogWatcher-51"><a href="#LogWatcher-51"><span class="linenos"> 51</span></a><span class="sd">        The ``advanced`` strategy is the default. It checks the file size</span>
</span><span id="LogWatcher-52"><a href="#LogWatcher-52"><span class="linenos"> 52</span></a><span class="sd">        and only reads new content if the file size has changed. If the file</span>
</span><span id="LogWatcher-53"><a href="#LogWatcher-53"><span class="linenos"> 53</span></a><span class="sd">        size is smaller than the last recorded size, it resets the parser and</span>
</span><span id="LogWatcher-54"><a href="#LogWatcher-54"><span class="linenos"> 54</span></a><span class="sd">        reads the entire file.</span>
</span><span id="LogWatcher-55"><a href="#LogWatcher-55"><span class="linenos"> 55</span></a>
</span><span id="LogWatcher-56"><a href="#LogWatcher-56"><span class="linenos"> 56</span></a><span class="sd">        The ``simple`` strategy reads the entire log file every time it is</span>
</span><span id="LogWatcher-57"><a href="#LogWatcher-57"><span class="linenos"> 57</span></a><span class="sd">        called. This is simple, but slow for large log files.</span>
</span><span id="LogWatcher-58"><a href="#LogWatcher-58"><span class="linenos"> 58</span></a>
</span><span id="LogWatcher-59"><a href="#LogWatcher-59"><span class="linenos"> 59</span></a><span class="sd">        The ``naive`` strategy reads the entire log file every time it is</span>
</span><span id="LogWatcher-60"><a href="#LogWatcher-60"><span class="linenos"> 60</span></a><span class="sd">        called, but it does not reset the parser. This is faster than the</span>
</span><span id="LogWatcher-61"><a href="#LogWatcher-61"><span class="linenos"> 61</span></a><span class="sd">        ``simple`` strategy, but it does not handle the case where the log</span>
</span><span id="LogWatcher-62"><a href="#LogWatcher-62"><span class="linenos"> 62</span></a><span class="sd">        file is truncated.</span>
</span><span id="LogWatcher-63"><a href="#LogWatcher-63"><span class="linenos"> 63</span></a>
</span><span id="LogWatcher-64"><a href="#LogWatcher-64"><span class="linenos"> 64</span></a><span class="sd">        Args:</span>
</span><span id="LogWatcher-65"><a href="#LogWatcher-65"><span class="linenos"> 65</span></a><span class="sd">            style (str, optional): The update strategy to use. Must be one of </span>
</span><span id="LogWatcher-66"><a href="#LogWatcher-66"><span class="linenos"> 66</span></a><span class="sd">                ``advanced``, ``simple``, or ``naive``. Defaults to ``advanced``.</span>
</span><span id="LogWatcher-67"><a href="#LogWatcher-67"><span class="linenos"> 67</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="LogWatcher-68"><a href="#LogWatcher-68"><span class="linenos"> 68</span></a>        <span class="k">if</span> <span class="n">style</span> <span class="o">==</span> <span class="s2">&quot;advanced&quot;</span><span class="p">:</span>
</span><span id="LogWatcher-69"><a href="#LogWatcher-69"><span class="linenos"> 69</span></a>            <span class="bp">self</span><span class="o">.</span><span class="n">advanced_update</span><span class="p">()</span>
</span><span id="LogWatcher-70"><a href="#LogWatcher-70"><span class="linenos"> 70</span></a>        <span class="k">elif</span> <span class="n">style</span> <span class="o">==</span> <span class="s2">&quot;simple&quot;</span><span class="p">:</span>
</span><span id="LogWatcher-71"><a href="#LogWatcher-71"><span class="linenos"> 71</span></a>            <span class="bp">self</span><span class="o">.</span><span class="n">simple_update</span><span class="p">()</span>
</span><span id="LogWatcher-72"><a href="#LogWatcher-72"><span class="linenos"> 72</span></a>        <span class="k">elif</span> <span class="n">style</span> <span class="o">==</span> <span class="s2">&quot;naive&quot;</span><span class="p">:</span>
</span><span id="LogWatcher-73"><a href="#LogWatcher-73"><span class="linenos"> 73</span></a>            <span class="bp">self</span><span class="o">.</span><span class="n">naive_update</span><span class="p">()</span>
</span><span id="LogWatcher-74"><a href="#LogWatcher-74"><span class="linenos"> 74</span></a>        <span class="k">else</span><span class="p">:</span>
</span><span id="LogWatcher-75"><a href="#LogWatcher-75"><span class="linenos"> 75</span></a>            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
</span><span id="LogWatcher-76"><a href="#LogWatcher-76"><span class="linenos"> 76</span></a>                <span class="s2">&quot;Unrecognized update option: </span><span class="si">%s</span><span class="s2"> (should be in advanced, simple, naive)&quot;</span>
</span><span id="LogWatcher-77"><a href="#LogWatcher-77"><span class="linenos"> 77</span></a>                <span class="o">%</span> <span class="n">style</span>
</span><span id="LogWatcher-78"><a href="#LogWatcher-78"><span class="linenos"> 78</span></a>            <span class="p">)</span>
</span><span id="LogWatcher-79"><a href="#LogWatcher-79"><span class="linenos"> 79</span></a>
</span><span id="LogWatcher-80"><a href="#LogWatcher-80"><span class="linenos"> 80</span></a>    <span class="k">def</span><span class="w"> </span><span class="nf">simple_update</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span id="LogWatcher-81"><a href="#LogWatcher-81"><span class="linenos"> 81</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="LogWatcher-82"><a href="#LogWatcher-82"><span class="linenos"> 82</span></a><span class="sd">        Read the entire log file and reset the parser if the file size has changed.</span>
</span><span id="LogWatcher-83"><a href="#LogWatcher-83"><span class="linenos"> 83</span></a>
</span><span id="LogWatcher-84"><a href="#LogWatcher-84"><span class="linenos"> 84</span></a><span class="sd">        The ``simple`` strategy reads the entire log file every time it is</span>
</span><span id="LogWatcher-85"><a href="#LogWatcher-85"><span class="linenos"> 85</span></a><span class="sd">        called. This is simple, but slow for large log files.</span>
</span><span id="LogWatcher-86"><a href="#LogWatcher-86"><span class="linenos"> 86</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="LogWatcher-87"><a href="#LogWatcher-87"><span class="linenos"> 87</span></a>        <span class="n">current_size</span> <span class="o">=</span> <span class="p">(</span>
</span><span id="LogWatcher-88"><a href="#LogWatcher-88"><span class="linenos"> 88</span></a>            <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">getsize</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">log_file</span><span class="p">)</span> <span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">log_file</span><span class="p">)</span> <span class="k">else</span> <span class="mi">0</span>
</span><span id="LogWatcher-89"><a href="#LogWatcher-89"><span class="linenos"> 89</span></a>        <span class="p">)</span>
</span><span id="LogWatcher-90"><a href="#LogWatcher-90"><span class="linenos"> 90</span></a>        <span class="k">if</span> <span class="n">current_size</span> <span class="o">!=</span> <span class="bp">self</span><span class="o">.</span><span class="n">last_filesize</span><span class="p">:</span>
</span><span id="LogWatcher-91"><a href="#LogWatcher-91"><span class="linenos"> 91</span></a>            <span class="bp">self</span><span class="o">.</span><span class="n">naive_update</span><span class="p">()</span>
</span><span id="LogWatcher-92"><a href="#LogWatcher-92"><span class="linenos"> 92</span></a>            <span class="bp">self</span><span class="o">.</span><span class="n">last_filesize</span> <span class="o">=</span> <span class="n">current_size</span>
</span><span id="LogWatcher-93"><a href="#LogWatcher-93"><span class="linenos"> 93</span></a>
</span><span id="LogWatcher-94"><a href="#LogWatcher-94"><span class="linenos"> 94</span></a>    <span class="k">def</span><span class="w"> </span><span class="nf">naive_update</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span id="LogWatcher-95"><a href="#LogWatcher-95"><span class="linenos"> 95</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="LogWatcher-96"><a href="#LogWatcher-96"><span class="linenos"> 96</span></a><span class="sd">        Reset the parser and read the entire log file.</span>
</span><span id="LogWatcher-97"><a href="#LogWatcher-97"><span class="linenos"> 97</span></a>
</span><span id="LogWatcher-98"><a href="#LogWatcher-98"><span class="linenos"> 98</span></a><span class="sd">        This is slow for large log files, but it is simple and handles</span>
</span><span id="LogWatcher-99"><a href="#LogWatcher-99"><span class="linenos"> 99</span></a><span class="sd">        the case where the log file is truncated.</span>
</span><span id="LogWatcher-100"><a href="#LogWatcher-100"><span class="linenos">100</span></a>
</span><span id="LogWatcher-101"><a href="#LogWatcher-101"><span class="linenos">101</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="LogWatcher-102"><a href="#LogWatcher-102"><span class="linenos">102</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">parser</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">parser_class</span><span class="p">()</span>
</span><span id="LogWatcher-103"><a href="#LogWatcher-103"><span class="linenos">103</span></a>        <span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">log_file</span><span class="p">):</span>
</span><span id="LogWatcher-104"><a href="#LogWatcher-104"><span class="linenos">104</span></a>            <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">log_file</span><span class="p">,</span> <span class="s2">&quot;r&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
</span><span id="LogWatcher-105"><a href="#LogWatcher-105"><span class="linenos">105</span></a>                <span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">f</span><span class="o">.</span><span class="n">readlines</span><span class="p">():</span>
</span><span id="LogWatcher-106"><a href="#LogWatcher-106"><span class="linenos">106</span></a>                    <span class="bp">self</span><span class="o">.</span><span class="n">parser</span><span class="o">.</span><span class="n">feed_line</span><span class="p">(</span><span class="n">line</span><span class="p">)</span>
</span><span id="LogWatcher-107"><a href="#LogWatcher-107"><span class="linenos">107</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">last_filesize</span> <span class="o">=</span> <span class="p">(</span>
</span><span id="LogWatcher-108"><a href="#LogWatcher-108"><span class="linenos">108</span></a>            <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">getsize</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">log_file</span><span class="p">)</span> <span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">log_file</span><span class="p">)</span> <span class="k">else</span> <span class="mi">0</span>
</span><span id="LogWatcher-109"><a href="#LogWatcher-109"><span class="linenos">109</span></a>        <span class="p">)</span>
</span><span id="LogWatcher-110"><a href="#LogWatcher-110"><span class="linenos">110</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">last_position</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">last_filesize</span>
</span><span id="LogWatcher-111"><a href="#LogWatcher-111"><span class="linenos">111</span></a>
</span><span id="LogWatcher-112"><a href="#LogWatcher-112"><span class="linenos">112</span></a>    <span class="k">def</span><span class="w"> </span><span class="nf">advanced_update</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span id="LogWatcher-113"><a href="#LogWatcher-113"><span class="linenos">113</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="LogWatcher-114"><a href="#LogWatcher-114"><span class="linenos">114</span></a><span class="sd">        Read only the new content from the log file.</span>
</span><span id="LogWatcher-115"><a href="#LogWatcher-115"><span class="linenos">115</span></a>
</span><span id="LogWatcher-116"><a href="#LogWatcher-116"><span class="linenos">116</span></a><span class="sd">        The ``advanced`` strategy reads only the new content from the log file,</span>
</span><span id="LogWatcher-117"><a href="#LogWatcher-117"><span class="linenos">117</span></a><span class="sd">        starting from the last recorded position. This is fast for large log</span>
</span><span id="LogWatcher-118"><a href="#LogWatcher-118"><span class="linenos">118</span></a><span class="sd">        files, but it requires keeping track of the last recorded position.</span>
</span><span id="LogWatcher-119"><a href="#LogWatcher-119"><span class="linenos">119</span></a>
</span><span id="LogWatcher-120"><a href="#LogWatcher-120"><span class="linenos">120</span></a><span class="sd">        If the file size has decreased, it resets the parser and reads the</span>
</span><span id="LogWatcher-121"><a href="#LogWatcher-121"><span class="linenos">121</span></a><span class="sd">        entire file.</span>
</span><span id="LogWatcher-122"><a href="#LogWatcher-122"><span class="linenos">122</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="LogWatcher-123"><a href="#LogWatcher-123"><span class="linenos">123</span></a>        <span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">log_file</span><span class="p">):</span>
</span><span id="LogWatcher-124"><a href="#LogWatcher-124"><span class="linenos">124</span></a>            <span class="k">return</span>
</span><span id="LogWatcher-125"><a href="#LogWatcher-125"><span class="linenos">125</span></a>
</span><span id="LogWatcher-126"><a href="#LogWatcher-126"><span class="linenos">126</span></a>        <span class="n">current_size</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">getsize</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">log_file</span><span class="p">)</span>
</span><span id="LogWatcher-127"><a href="#LogWatcher-127"><span class="linenos">127</span></a>
</span><span id="LogWatcher-128"><a href="#LogWatcher-128"><span class="linenos">128</span></a>        <span class="c1"># If file size decreased (file was truncated), do a full reset</span>
</span><span id="LogWatcher-129"><a href="#LogWatcher-129"><span class="linenos">129</span></a>        <span class="k">if</span> <span class="n">current_size</span> <span class="o">&lt;</span> <span class="bp">self</span><span class="o">.</span><span class="n">last_filesize</span><span class="p">:</span>
</span><span id="LogWatcher-130"><a href="#LogWatcher-130"><span class="linenos">130</span></a>            <span class="bp">self</span><span class="o">.</span><span class="n">naive_update</span><span class="p">()</span>
</span><span id="LogWatcher-131"><a href="#LogWatcher-131"><span class="linenos">131</span></a>            <span class="k">return</span>
</span><span id="LogWatcher-132"><a href="#LogWatcher-132"><span class="linenos">132</span></a>
</span><span id="LogWatcher-133"><a href="#LogWatcher-133"><span class="linenos">133</span></a>        <span class="c1"># If file size increased, read only the new content</span>
</span><span id="LogWatcher-134"><a href="#LogWatcher-134"><span class="linenos">134</span></a>        <span class="k">if</span> <span class="n">current_size</span> <span class="o">&gt;</span> <span class="bp">self</span><span class="o">.</span><span class="n">last_filesize</span><span class="p">:</span>
</span><span id="LogWatcher-135"><a href="#LogWatcher-135"><span class="linenos">135</span></a>            <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">log_file</span><span class="p">,</span> <span class="s2">&quot;r&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
</span><span id="LogWatcher-136"><a href="#LogWatcher-136"><span class="linenos">136</span></a>                <span class="n">f</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">last_position</span><span class="p">)</span>
</span><span id="LogWatcher-137"><a href="#LogWatcher-137"><span class="linenos">137</span></a>                <span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
</span><span id="LogWatcher-138"><a href="#LogWatcher-138"><span class="linenos">138</span></a>                    <span class="n">line</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">readline</span><span class="p">()</span>
</span><span id="LogWatcher-139"><a href="#LogWatcher-139"><span class="linenos">139</span></a>                    <span class="k">if</span> <span class="ow">not</span> <span class="n">line</span><span class="p">:</span>  <span class="c1"># End of file</span>
</span><span id="LogWatcher-140"><a href="#LogWatcher-140"><span class="linenos">140</span></a>                        <span class="k">break</span>
</span><span id="LogWatcher-141"><a href="#LogWatcher-141"><span class="linenos">141</span></a>                    <span class="bp">self</span><span class="o">.</span><span class="n">parser</span><span class="o">.</span><span class="n">feed_line</span><span class="p">(</span><span class="n">line</span><span class="p">)</span>
</span><span id="LogWatcher-142"><a href="#LogWatcher-142"><span class="linenos">142</span></a>
</span><span id="LogWatcher-143"><a href="#LogWatcher-143"><span class="linenos">143</span></a>                <span class="c1"># Update tracking variables</span>
</span><span id="LogWatcher-144"><a href="#LogWatcher-144"><span class="linenos">144</span></a>                <span class="bp">self</span><span class="o">.</span><span class="n">last_filesize</span> <span class="o">=</span> <span class="n">current_size</span>
</span><span id="LogWatcher-145"><a href="#LogWatcher-145"><span class="linenos">145</span></a>                <span class="bp">self</span><span class="o">.</span><span class="n">last_position</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">tell</span><span class="p">()</span>
</span></pre></div>


    

                            <div id="LogWatcher.__init__" class="classattr">
                                        <input id="LogWatcher.__init__-view-source" class="view-source-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<div class="attr function">
            
        <span class="name">LogWatcher</span><span class="signature pdoc-code multiline">(<span class="param">	<span class="n">log_file</span><span class="p">:</span> <span class="nb">str</span>,</span><span class="param">	<span class="n">parser_class</span><span class="p">:</span> <span class="n">Type</span><span class="p">[</span><span class="n"><a href="#AbstractLogParser">AbstractLogParser</a></span><span class="p">]</span></span>)</span>

                <label class="view-source-button" for="LogWatcher.__init__-view-source"><span>View Source</span></label>

    </div>
    <a class="headerlink" href="#LogWatcher.__init__"></a>
            <div class="pdoc-code codehilite"><pre><span></span><span id="LogWatcher.__init__-26"><a href="#LogWatcher.__init__-26"><span class="linenos">26</span></a>    <span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">log_file</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">parser_class</span><span class="p">:</span> <span class="n">Type</span><span class="p">[</span><span class="n">AbstractLogParser</span><span class="p">]):</span>
</span><span id="LogWatcher.__init__-27"><a href="#LogWatcher.__init__-27"><span class="linenos">27</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="LogWatcher.__init__-28"><a href="#LogWatcher.__init__-28"><span class="linenos">28</span></a><span class="sd">        Initialize the log watcher with a log file and a parser class.</span>
</span><span id="LogWatcher.__init__-29"><a href="#LogWatcher.__init__-29"><span class="linenos">29</span></a>
</span><span id="LogWatcher.__init__-30"><a href="#LogWatcher.__init__-30"><span class="linenos">30</span></a><span class="sd">        Args:</span>
</span><span id="LogWatcher.__init__-31"><a href="#LogWatcher.__init__-31"><span class="linenos">31</span></a><span class="sd">            log_file (str): The path to the log file.</span>
</span><span id="LogWatcher.__init__-32"><a href="#LogWatcher.__init__-32"><span class="linenos">32</span></a><span class="sd">            parser_class (Type[AbstractLogParser]): A class that implements the AbstractLogParser interface.</span>
</span><span id="LogWatcher.__init__-33"><a href="#LogWatcher.__init__-33"><span class="linenos">33</span></a>
</span><span id="LogWatcher.__init__-34"><a href="#LogWatcher.__init__-34"><span class="linenos">34</span></a><span class="sd">        Attributes:</span>
</span><span id="LogWatcher.__init__-35"><a href="#LogWatcher.__init__-35"><span class="linenos">35</span></a><span class="sd">            log_file (str): The path to the log file.</span>
</span><span id="LogWatcher.__init__-36"><a href="#LogWatcher.__init__-36"><span class="linenos">36</span></a><span class="sd">            parser_class (Type[AbstractLogParser]): The class of the parser.</span>
</span><span id="LogWatcher.__init__-37"><a href="#LogWatcher.__init__-37"><span class="linenos">37</span></a><span class="sd">            parser (AbstractLogParser): An instance of the parser class.</span>
</span><span id="LogWatcher.__init__-38"><a href="#LogWatcher.__init__-38"><span class="linenos">38</span></a><span class="sd">            last_filesize (int): The size of the log file when it was last checked.</span>
</span><span id="LogWatcher.__init__-39"><a href="#LogWatcher.__init__-39"><span class="linenos">39</span></a><span class="sd">            last_position (int): The last read position in the log file.</span>
</span><span id="LogWatcher.__init__-40"><a href="#LogWatcher.__init__-40"><span class="linenos">40</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="LogWatcher.__init__-41"><a href="#LogWatcher.__init__-41"><span class="linenos">41</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">log_file</span> <span class="o">=</span> <span class="n">log_file</span>
</span><span id="LogWatcher.__init__-42"><a href="#LogWatcher.__init__-42"><span class="linenos">42</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">parser_class</span> <span class="o">=</span> <span class="n">parser_class</span>
</span><span id="LogWatcher.__init__-43"><a href="#LogWatcher.__init__-43"><span class="linenos">43</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">parser</span> <span class="o">=</span> <span class="n">parser_class</span><span class="p">()</span>
</span><span id="LogWatcher.__init__-44"><a href="#LogWatcher.__init__-44"><span class="linenos">44</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">last_filesize</span> <span class="o">=</span> <span class="mi">0</span>
</span><span id="LogWatcher.__init__-45"><a href="#LogWatcher.__init__-45"><span class="linenos">45</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">last_position</span> <span class="o">=</span> <span class="mi">0</span>  <span class="c1"># Track the last read position</span>
</span></pre></div>


            <div class="docstring"><p>Initialize the log watcher with a log file and a parser class.</p>

<h6 id="arguments">Arguments:</h6>

<ul>
<li><strong>log_file (str):</strong>  The path to the log file.</li>
<li><strong>parser_class (Type[AbstractLogParser]):</strong>  A class that implements the AbstractLogParser interface.</li>
</ul>

<h6 id="attributes">Attributes:</h6>

<ul>
<li><strong>log_file (str):</strong>  The path to the log file.</li>
<li><strong>parser_class (Type[AbstractLogParser]):</strong>  The class of the parser.</li>
<li><strong>parser (AbstractLogParser):</strong>  An instance of the parser class.</li>
<li><strong>last_filesize (int):</strong>  The size of the log file when it was last checked.</li>
<li><strong>last_position (int):</strong>  The last read position in the log file.</li>
</ul>
</div>


                            </div>
                            <div id="LogWatcher.log_file" class="classattr">
                                <div class="attr variable">
            <span class="name">log_file</span>

        
    </div>
    <a class="headerlink" href="#LogWatcher.log_file"></a>
    
    

                            </div>
                            <div id="LogWatcher.parser_class" class="classattr">
                                <div class="attr variable">
            <span class="name">parser_class</span>

        
    </div>
    <a class="headerlink" href="#LogWatcher.parser_class"></a>
    
    

                            </div>
                            <div id="LogWatcher.parser" class="classattr">
                                <div class="attr variable">
            <span class="name">parser</span>

        
    </div>
    <a class="headerlink" href="#LogWatcher.parser"></a>
    
    

                            </div>
                            <div id="LogWatcher.last_filesize" class="classattr">
                                <div class="attr variable">
            <span class="name">last_filesize</span>

        
    </div>
    <a class="headerlink" href="#LogWatcher.last_filesize"></a>
    
    

                            </div>
                            <div id="LogWatcher.last_position" class="classattr">
                                <div class="attr variable">
            <span class="name">last_position</span>

        
    </div>
    <a class="headerlink" href="#LogWatcher.last_position"></a>
    
    

                            </div>
                            <div id="LogWatcher.update" class="classattr">
                                        <input id="LogWatcher.update-view-source" class="view-source-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<div class="attr function">
            
        <span class="def">def</span>
        <span class="name">update</span><span class="signature pdoc-code condensed">(<span class="param"><span class="bp">self</span>, </span><span class="param"><span class="n">style</span><span class="o">=</span><span class="s1">&#39;advanced&#39;</span></span><span class="return-annotation">):</span></span>

                <label class="view-source-button" for="LogWatcher.update-view-source"><span>View Source</span></label>

    </div>
    <a class="headerlink" href="#LogWatcher.update"></a>
            <div class="pdoc-code codehilite"><pre><span></span><span id="LogWatcher.update-47"><a href="#LogWatcher.update-47"><span class="linenos">47</span></a>    <span class="k">def</span><span class="w"> </span><span class="nf">update</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">style</span><span class="o">=</span><span class="s2">&quot;advanced&quot;</span><span class="p">):</span>
</span><span id="LogWatcher.update-48"><a href="#LogWatcher.update-48"><span class="linenos">48</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="LogWatcher.update-49"><a href="#LogWatcher.update-49"><span class="linenos">49</span></a><span class="sd">        Update the log watcher using one of three strategies.</span>
</span><span id="LogWatcher.update-50"><a href="#LogWatcher.update-50"><span class="linenos">50</span></a>
</span><span id="LogWatcher.update-51"><a href="#LogWatcher.update-51"><span class="linenos">51</span></a><span class="sd">        The ``advanced`` strategy is the default. It checks the file size</span>
</span><span id="LogWatcher.update-52"><a href="#LogWatcher.update-52"><span class="linenos">52</span></a><span class="sd">        and only reads new content if the file size has changed. If the file</span>
</span><span id="LogWatcher.update-53"><a href="#LogWatcher.update-53"><span class="linenos">53</span></a><span class="sd">        size is smaller than the last recorded size, it resets the parser and</span>
</span><span id="LogWatcher.update-54"><a href="#LogWatcher.update-54"><span class="linenos">54</span></a><span class="sd">        reads the entire file.</span>
</span><span id="LogWatcher.update-55"><a href="#LogWatcher.update-55"><span class="linenos">55</span></a>
</span><span id="LogWatcher.update-56"><a href="#LogWatcher.update-56"><span class="linenos">56</span></a><span class="sd">        The ``simple`` strategy reads the entire log file every time it is</span>
</span><span id="LogWatcher.update-57"><a href="#LogWatcher.update-57"><span class="linenos">57</span></a><span class="sd">        called. This is simple, but slow for large log files.</span>
</span><span id="LogWatcher.update-58"><a href="#LogWatcher.update-58"><span class="linenos">58</span></a>
</span><span id="LogWatcher.update-59"><a href="#LogWatcher.update-59"><span class="linenos">59</span></a><span class="sd">        The ``naive`` strategy reads the entire log file every time it is</span>
</span><span id="LogWatcher.update-60"><a href="#LogWatcher.update-60"><span class="linenos">60</span></a><span class="sd">        called, but it does not reset the parser. This is faster than the</span>
</span><span id="LogWatcher.update-61"><a href="#LogWatcher.update-61"><span class="linenos">61</span></a><span class="sd">        ``simple`` strategy, but it does not handle the case where the log</span>
</span><span id="LogWatcher.update-62"><a href="#LogWatcher.update-62"><span class="linenos">62</span></a><span class="sd">        file is truncated.</span>
</span><span id="LogWatcher.update-63"><a href="#LogWatcher.update-63"><span class="linenos">63</span></a>
</span><span id="LogWatcher.update-64"><a href="#LogWatcher.update-64"><span class="linenos">64</span></a><span class="sd">        Args:</span>
</span><span id="LogWatcher.update-65"><a href="#LogWatcher.update-65"><span class="linenos">65</span></a><span class="sd">            style (str, optional): The update strategy to use. Must be one of </span>
</span><span id="LogWatcher.update-66"><a href="#LogWatcher.update-66"><span class="linenos">66</span></a><span class="sd">                ``advanced``, ``simple``, or ``naive``. Defaults to ``advanced``.</span>
</span><span id="LogWatcher.update-67"><a href="#LogWatcher.update-67"><span class="linenos">67</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="LogWatcher.update-68"><a href="#LogWatcher.update-68"><span class="linenos">68</span></a>        <span class="k">if</span> <span class="n">style</span> <span class="o">==</span> <span class="s2">&quot;advanced&quot;</span><span class="p">:</span>
</span><span id="LogWatcher.update-69"><a href="#LogWatcher.update-69"><span class="linenos">69</span></a>            <span class="bp">self</span><span class="o">.</span><span class="n">advanced_update</span><span class="p">()</span>
</span><span id="LogWatcher.update-70"><a href="#LogWatcher.update-70"><span class="linenos">70</span></a>        <span class="k">elif</span> <span class="n">style</span> <span class="o">==</span> <span class="s2">&quot;simple&quot;</span><span class="p">:</span>
</span><span id="LogWatcher.update-71"><a href="#LogWatcher.update-71"><span class="linenos">71</span></a>            <span class="bp">self</span><span class="o">.</span><span class="n">simple_update</span><span class="p">()</span>
</span><span id="LogWatcher.update-72"><a href="#LogWatcher.update-72"><span class="linenos">72</span></a>        <span class="k">elif</span> <span class="n">style</span> <span class="o">==</span> <span class="s2">&quot;naive&quot;</span><span class="p">:</span>
</span><span id="LogWatcher.update-73"><a href="#LogWatcher.update-73"><span class="linenos">73</span></a>            <span class="bp">self</span><span class="o">.</span><span class="n">naive_update</span><span class="p">()</span>
</span><span id="LogWatcher.update-74"><a href="#LogWatcher.update-74"><span class="linenos">74</span></a>        <span class="k">else</span><span class="p">:</span>
</span><span id="LogWatcher.update-75"><a href="#LogWatcher.update-75"><span class="linenos">75</span></a>            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
</span><span id="LogWatcher.update-76"><a href="#LogWatcher.update-76"><span class="linenos">76</span></a>                <span class="s2">&quot;Unrecognized update option: </span><span class="si">%s</span><span class="s2"> (should be in advanced, simple, naive)&quot;</span>
</span><span id="LogWatcher.update-77"><a href="#LogWatcher.update-77"><span class="linenos">77</span></a>                <span class="o">%</span> <span class="n">style</span>
</span><span id="LogWatcher.update-78"><a href="#LogWatcher.update-78"><span class="linenos">78</span></a>            <span class="p">)</span>
</span></pre></div>


            <div class="docstring"><p>Update the log watcher using one of three strategies.</p>

<p>The <code>advanced</code> strategy is the default. It checks the file size
and only reads new content if the file size has changed. If the file
size is smaller than the last recorded size, it resets the parser and
reads the entire file.</p>

<p>The <code>simple</code> strategy reads the entire log file every time it is
called. This is simple, but slow for large log files.</p>

<p>The <code>naive</code> strategy reads the entire log file every time it is
called, but it does not reset the parser. This is faster than the
<code>simple</code> strategy, but it does not handle the case where the log
file is truncated.</p>

<h6 id="arguments">Arguments:</h6>

<ul>
<li><strong>style (str, optional):</strong>  The update strategy to use. Must be one of 
<code>advanced</code>, <code>simple</code>, or <code>naive</code>. Defaults to <code>advanced</code>.</li>
</ul>
</div>


                            </div>
                            <div id="LogWatcher.simple_update" class="classattr">
                                        <input id="LogWatcher.simple_update-view-source" class="view-source-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<div class="attr function">
            
        <span class="def">def</span>
        <span class="name">simple_update</span><span class="signature pdoc-code condensed">(<span class="param"><span class="bp">self</span></span><span class="return-annotation">):</span></span>

                <label class="view-source-button" for="LogWatcher.simple_update-view-source"><span>View Source</span></label>

    </div>
    <a class="headerlink" href="#LogWatcher.simple_update"></a>
            <div class="pdoc-code codehilite"><pre><span></span><span id="LogWatcher.simple_update-80"><a href="#LogWatcher.simple_update-80"><span class="linenos">80</span></a>    <span class="k">def</span><span class="w"> </span><span class="nf">simple_update</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span id="LogWatcher.simple_update-81"><a href="#LogWatcher.simple_update-81"><span class="linenos">81</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="LogWatcher.simple_update-82"><a href="#LogWatcher.simple_update-82"><span class="linenos">82</span></a><span class="sd">        Read the entire log file and reset the parser if the file size has changed.</span>
</span><span id="LogWatcher.simple_update-83"><a href="#LogWatcher.simple_update-83"><span class="linenos">83</span></a>
</span><span id="LogWatcher.simple_update-84"><a href="#LogWatcher.simple_update-84"><span class="linenos">84</span></a><span class="sd">        The ``simple`` strategy reads the entire log file every time it is</span>
</span><span id="LogWatcher.simple_update-85"><a href="#LogWatcher.simple_update-85"><span class="linenos">85</span></a><span class="sd">        called. This is simple, but slow for large log files.</span>
</span><span id="LogWatcher.simple_update-86"><a href="#LogWatcher.simple_update-86"><span class="linenos">86</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="LogWatcher.simple_update-87"><a href="#LogWatcher.simple_update-87"><span class="linenos">87</span></a>        <span class="n">current_size</span> <span class="o">=</span> <span class="p">(</span>
</span><span id="LogWatcher.simple_update-88"><a href="#LogWatcher.simple_update-88"><span class="linenos">88</span></a>            <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">getsize</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">log_file</span><span class="p">)</span> <span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">log_file</span><span class="p">)</span> <span class="k">else</span> <span class="mi">0</span>
</span><span id="LogWatcher.simple_update-89"><a href="#LogWatcher.simple_update-89"><span class="linenos">89</span></a>        <span class="p">)</span>
</span><span id="LogWatcher.simple_update-90"><a href="#LogWatcher.simple_update-90"><span class="linenos">90</span></a>        <span class="k">if</span> <span class="n">current_size</span> <span class="o">!=</span> <span class="bp">self</span><span class="o">.</span><span class="n">last_filesize</span><span class="p">:</span>
</span><span id="LogWatcher.simple_update-91"><a href="#LogWatcher.simple_update-91"><span class="linenos">91</span></a>            <span class="bp">self</span><span class="o">.</span><span class="n">naive_update</span><span class="p">()</span>
</span><span id="LogWatcher.simple_update-92"><a href="#LogWatcher.simple_update-92"><span class="linenos">92</span></a>            <span class="bp">self</span><span class="o">.</span><span class="n">last_filesize</span> <span class="o">=</span> <span class="n">current_size</span>
</span></pre></div>


            <div class="docstring"><p>Read the entire log file and reset the parser if the file size has changed.</p>

<p>The <code>simple</code> strategy reads the entire log file every time it is
called. This is simple, but slow for large log files.</p>
</div>


                            </div>
                            <div id="LogWatcher.naive_update" class="classattr">
                                        <input id="LogWatcher.naive_update-view-source" class="view-source-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<div class="attr function">
            
        <span class="def">def</span>
        <span class="name">naive_update</span><span class="signature pdoc-code condensed">(<span class="param"><span class="bp">self</span></span><span class="return-annotation">):</span></span>

                <label class="view-source-button" for="LogWatcher.naive_update-view-source"><span>View Source</span></label>

    </div>
    <a class="headerlink" href="#LogWatcher.naive_update"></a>
            <div class="pdoc-code codehilite"><pre><span></span><span id="LogWatcher.naive_update-94"><a href="#LogWatcher.naive_update-94"><span class="linenos"> 94</span></a>    <span class="k">def</span><span class="w"> </span><span class="nf">naive_update</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span id="LogWatcher.naive_update-95"><a href="#LogWatcher.naive_update-95"><span class="linenos"> 95</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="LogWatcher.naive_update-96"><a href="#LogWatcher.naive_update-96"><span class="linenos"> 96</span></a><span class="sd">        Reset the parser and read the entire log file.</span>
</span><span id="LogWatcher.naive_update-97"><a href="#LogWatcher.naive_update-97"><span class="linenos"> 97</span></a>
</span><span id="LogWatcher.naive_update-98"><a href="#LogWatcher.naive_update-98"><span class="linenos"> 98</span></a><span class="sd">        This is slow for large log files, but it is simple and handles</span>
</span><span id="LogWatcher.naive_update-99"><a href="#LogWatcher.naive_update-99"><span class="linenos"> 99</span></a><span class="sd">        the case where the log file is truncated.</span>
</span><span id="LogWatcher.naive_update-100"><a href="#LogWatcher.naive_update-100"><span class="linenos">100</span></a>
</span><span id="LogWatcher.naive_update-101"><a href="#LogWatcher.naive_update-101"><span class="linenos">101</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="LogWatcher.naive_update-102"><a href="#LogWatcher.naive_update-102"><span class="linenos">102</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">parser</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">parser_class</span><span class="p">()</span>
</span><span id="LogWatcher.naive_update-103"><a href="#LogWatcher.naive_update-103"><span class="linenos">103</span></a>        <span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">log_file</span><span class="p">):</span>
</span><span id="LogWatcher.naive_update-104"><a href="#LogWatcher.naive_update-104"><span class="linenos">104</span></a>            <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">log_file</span><span class="p">,</span> <span class="s2">&quot;r&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
</span><span id="LogWatcher.naive_update-105"><a href="#LogWatcher.naive_update-105"><span class="linenos">105</span></a>                <span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">f</span><span class="o">.</span><span class="n">readlines</span><span class="p">():</span>
</span><span id="LogWatcher.naive_update-106"><a href="#LogWatcher.naive_update-106"><span class="linenos">106</span></a>                    <span class="bp">self</span><span class="o">.</span><span class="n">parser</span><span class="o">.</span><span class="n">feed_line</span><span class="p">(</span><span class="n">line</span><span class="p">)</span>
</span><span id="LogWatcher.naive_update-107"><a href="#LogWatcher.naive_update-107"><span class="linenos">107</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">last_filesize</span> <span class="o">=</span> <span class="p">(</span>
</span><span id="LogWatcher.naive_update-108"><a href="#LogWatcher.naive_update-108"><span class="linenos">108</span></a>            <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">getsize</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">log_file</span><span class="p">)</span> <span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">log_file</span><span class="p">)</span> <span class="k">else</span> <span class="mi">0</span>
</span><span id="LogWatcher.naive_update-109"><a href="#LogWatcher.naive_update-109"><span class="linenos">109</span></a>        <span class="p">)</span>
</span><span id="LogWatcher.naive_update-110"><a href="#LogWatcher.naive_update-110"><span class="linenos">110</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">last_position</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">last_filesize</span>
</span></pre></div>


            <div class="docstring"><p>Reset the parser and read the entire log file.</p>

<p>This is slow for large log files, but it is simple and handles
the case where the log file is truncated.</p>
</div>


                            </div>
                            <div id="LogWatcher.advanced_update" class="classattr">
                                        <input id="LogWatcher.advanced_update-view-source" class="view-source-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<div class="attr function">
            
        <span class="def">def</span>
        <span class="name">advanced_update</span><span class="signature pdoc-code condensed">(<span class="param"><span class="bp">self</span></span><span class="return-annotation">):</span></span>

                <label class="view-source-button" for="LogWatcher.advanced_update-view-source"><span>View Source</span></label>

    </div>
    <a class="headerlink" href="#LogWatcher.advanced_update"></a>
            <div class="pdoc-code codehilite"><pre><span></span><span id="LogWatcher.advanced_update-112"><a href="#LogWatcher.advanced_update-112"><span class="linenos">112</span></a>    <span class="k">def</span><span class="w"> </span><span class="nf">advanced_update</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span id="LogWatcher.advanced_update-113"><a href="#LogWatcher.advanced_update-113"><span class="linenos">113</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="LogWatcher.advanced_update-114"><a href="#LogWatcher.advanced_update-114"><span class="linenos">114</span></a><span class="sd">        Read only the new content from the log file.</span>
</span><span id="LogWatcher.advanced_update-115"><a href="#LogWatcher.advanced_update-115"><span class="linenos">115</span></a>
</span><span id="LogWatcher.advanced_update-116"><a href="#LogWatcher.advanced_update-116"><span class="linenos">116</span></a><span class="sd">        The ``advanced`` strategy reads only the new content from the log file,</span>
</span><span id="LogWatcher.advanced_update-117"><a href="#LogWatcher.advanced_update-117"><span class="linenos">117</span></a><span class="sd">        starting from the last recorded position. This is fast for large log</span>
</span><span id="LogWatcher.advanced_update-118"><a href="#LogWatcher.advanced_update-118"><span class="linenos">118</span></a><span class="sd">        files, but it requires keeping track of the last recorded position.</span>
</span><span id="LogWatcher.advanced_update-119"><a href="#LogWatcher.advanced_update-119"><span class="linenos">119</span></a>
</span><span id="LogWatcher.advanced_update-120"><a href="#LogWatcher.advanced_update-120"><span class="linenos">120</span></a><span class="sd">        If the file size has decreased, it resets the parser and reads the</span>
</span><span id="LogWatcher.advanced_update-121"><a href="#LogWatcher.advanced_update-121"><span class="linenos">121</span></a><span class="sd">        entire file.</span>
</span><span id="LogWatcher.advanced_update-122"><a href="#LogWatcher.advanced_update-122"><span class="linenos">122</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="LogWatcher.advanced_update-123"><a href="#LogWatcher.advanced_update-123"><span class="linenos">123</span></a>        <span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">log_file</span><span class="p">):</span>
</span><span id="LogWatcher.advanced_update-124"><a href="#LogWatcher.advanced_update-124"><span class="linenos">124</span></a>            <span class="k">return</span>
</span><span id="LogWatcher.advanced_update-125"><a href="#LogWatcher.advanced_update-125"><span class="linenos">125</span></a>
</span><span id="LogWatcher.advanced_update-126"><a href="#LogWatcher.advanced_update-126"><span class="linenos">126</span></a>        <span class="n">current_size</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">getsize</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">log_file</span><span class="p">)</span>
</span><span id="LogWatcher.advanced_update-127"><a href="#LogWatcher.advanced_update-127"><span class="linenos">127</span></a>
</span><span id="LogWatcher.advanced_update-128"><a href="#LogWatcher.advanced_update-128"><span class="linenos">128</span></a>        <span class="c1"># If file size decreased (file was truncated), do a full reset</span>
</span><span id="LogWatcher.advanced_update-129"><a href="#LogWatcher.advanced_update-129"><span class="linenos">129</span></a>        <span class="k">if</span> <span class="n">current_size</span> <span class="o">&lt;</span> <span class="bp">self</span><span class="o">.</span><span class="n">last_filesize</span><span class="p">:</span>
</span><span id="LogWatcher.advanced_update-130"><a href="#LogWatcher.advanced_update-130"><span class="linenos">130</span></a>            <span class="bp">self</span><span class="o">.</span><span class="n">naive_update</span><span class="p">()</span>
</span><span id="LogWatcher.advanced_update-131"><a href="#LogWatcher.advanced_update-131"><span class="linenos">131</span></a>            <span class="k">return</span>
</span><span id="LogWatcher.advanced_update-132"><a href="#LogWatcher.advanced_update-132"><span class="linenos">132</span></a>
</span><span id="LogWatcher.advanced_update-133"><a href="#LogWatcher.advanced_update-133"><span class="linenos">133</span></a>        <span class="c1"># If file size increased, read only the new content</span>
</span><span id="LogWatcher.advanced_update-134"><a href="#LogWatcher.advanced_update-134"><span class="linenos">134</span></a>        <span class="k">if</span> <span class="n">current_size</span> <span class="o">&gt;</span> <span class="bp">self</span><span class="o">.</span><span class="n">last_filesize</span><span class="p">:</span>
</span><span id="LogWatcher.advanced_update-135"><a href="#LogWatcher.advanced_update-135"><span class="linenos">135</span></a>            <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">log_file</span><span class="p">,</span> <span class="s2">&quot;r&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
</span><span id="LogWatcher.advanced_update-136"><a href="#LogWatcher.advanced_update-136"><span class="linenos">136</span></a>                <span class="n">f</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">last_position</span><span class="p">)</span>
</span><span id="LogWatcher.advanced_update-137"><a href="#LogWatcher.advanced_update-137"><span class="linenos">137</span></a>                <span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
</span><span id="LogWatcher.advanced_update-138"><a href="#LogWatcher.advanced_update-138"><span class="linenos">138</span></a>                    <span class="n">line</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">readline</span><span class="p">()</span>
</span><span id="LogWatcher.advanced_update-139"><a href="#LogWatcher.advanced_update-139"><span class="linenos">139</span></a>                    <span class="k">if</span> <span class="ow">not</span> <span class="n">line</span><span class="p">:</span>  <span class="c1"># End of file</span>
</span><span id="LogWatcher.advanced_update-140"><a href="#LogWatcher.advanced_update-140"><span class="linenos">140</span></a>                        <span class="k">break</span>
</span><span id="LogWatcher.advanced_update-141"><a href="#LogWatcher.advanced_update-141"><span class="linenos">141</span></a>                    <span class="bp">self</span><span class="o">.</span><span class="n">parser</span><span class="o">.</span><span class="n">feed_line</span><span class="p">(</span><span class="n">line</span><span class="p">)</span>
</span><span id="LogWatcher.advanced_update-142"><a href="#LogWatcher.advanced_update-142"><span class="linenos">142</span></a>
</span><span id="LogWatcher.advanced_update-143"><a href="#LogWatcher.advanced_update-143"><span class="linenos">143</span></a>                <span class="c1"># Update tracking variables</span>
</span><span id="LogWatcher.advanced_update-144"><a href="#LogWatcher.advanced_update-144"><span class="linenos">144</span></a>                <span class="bp">self</span><span class="o">.</span><span class="n">last_filesize</span> <span class="o">=</span> <span class="n">current_size</span>
</span><span id="LogWatcher.advanced_update-145"><a href="#LogWatcher.advanced_update-145"><span class="linenos">145</span></a>                <span class="bp">self</span><span class="o">.</span><span class="n">last_position</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">tell</span><span class="p">()</span>
</span></pre></div>


            <div class="docstring"><p>Read only the new content from the log file.</p>

<p>The <code>advanced</code> strategy reads only the new content from the log file,
starting from the last recorded position. This is fast for large log
files, but it requires keeping track of the last recorded position.</p>

<p>If the file size has decreased, it resets the parser and reads the
entire file.</p>
</div>


                            </div>
                </section>
                <section id="VimGolfLogWatcher">
                            <input id="VimGolfLogWatcher-view-source" class="view-source-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<div class="attr class">
            
    <span class="def">class</span>
    <span class="name">VimGolfLogWatcher</span><wbr>(<span class="base"><a href="#LogWatcher">LogWatcher</a></span>):

                <label class="view-source-button" for="VimGolfLogWatcher-view-source"><span>View Source</span></label>

    </div>
    <a class="headerlink" href="#VimGolfLogWatcher"></a>
            <div class="pdoc-code codehilite"><pre><span></span><span id="VimGolfLogWatcher-148"><a href="#VimGolfLogWatcher-148"><span class="linenos">148</span></a><span class="k">class</span><span class="w"> </span><span class="nc">VimGolfLogWatcher</span><span class="p">(</span><span class="n">LogWatcher</span><span class="p">):</span>
</span><span id="VimGolfLogWatcher-149"><a href="#VimGolfLogWatcher-149"><span class="linenos">149</span></a>    <span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">log_file</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">update_style</span><span class="o">=</span><span class="s2">&quot;advanced&quot;</span><span class="p">):</span>
</span><span id="VimGolfLogWatcher-150"><a href="#VimGolfLogWatcher-150"><span class="linenos">150</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="VimGolfLogWatcher-151"><a href="#VimGolfLogWatcher-151"><span class="linenos">151</span></a><span class="sd">        Initialize a VimGolfLogWatcher with a log file and an update style.</span>
</span><span id="VimGolfLogWatcher-152"><a href="#VimGolfLogWatcher-152"><span class="linenos">152</span></a>
</span><span id="VimGolfLogWatcher-153"><a href="#VimGolfLogWatcher-153"><span class="linenos">153</span></a><span class="sd">        The VimGolfLogWatcher is a LogWatcher that is specialized for</span>
</span><span id="VimGolfLogWatcher-154"><a href="#VimGolfLogWatcher-154"><span class="linenos">154</span></a><span class="sd">        reading VimGolf logs.</span>
</span><span id="VimGolfLogWatcher-155"><a href="#VimGolfLogWatcher-155"><span class="linenos">155</span></a>
</span><span id="VimGolfLogWatcher-156"><a href="#VimGolfLogWatcher-156"><span class="linenos">156</span></a><span class="sd">        Args:</span>
</span><span id="VimGolfLogWatcher-157"><a href="#VimGolfLogWatcher-157"><span class="linenos">157</span></a><span class="sd">            log_file (str): The path to the log file.</span>
</span><span id="VimGolfLogWatcher-158"><a href="#VimGolfLogWatcher-158"><span class="linenos">158</span></a><span class="sd">            update_style (str, optional): The update strategy to use. Must be one of </span>
</span><span id="VimGolfLogWatcher-159"><a href="#VimGolfLogWatcher-159"><span class="linenos">159</span></a><span class="sd">                ``advanced``, ``simple``, or ``naive``. Defaults to ``advanced``.</span>
</span><span id="VimGolfLogWatcher-160"><a href="#VimGolfLogWatcher-160"><span class="linenos">160</span></a>
</span><span id="VimGolfLogWatcher-161"><a href="#VimGolfLogWatcher-161"><span class="linenos">161</span></a><span class="sd">        Returns:</span>
</span><span id="VimGolfLogWatcher-162"><a href="#VimGolfLogWatcher-162"><span class="linenos">162</span></a><span class="sd">            [return_type]: [description of return value]</span>
</span><span id="VimGolfLogWatcher-163"><a href="#VimGolfLogWatcher-163"><span class="linenos">163</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="VimGolfLogWatcher-164"><a href="#VimGolfLogWatcher-164"><span class="linenos">164</span></a>        <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">log_file</span><span class="o">=</span><span class="n">log_file</span><span class="p">,</span> <span class="n">parser_class</span><span class="o">=</span><span class="n">VimGolfLogParser</span><span class="p">)</span>
</span><span id="VimGolfLogWatcher-165"><a href="#VimGolfLogWatcher-165"><span class="linenos">165</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">parser</span><span class="p">:</span> <span class="n">VimGolfLogParser</span>
</span><span id="VimGolfLogWatcher-166"><a href="#VimGolfLogWatcher-166"><span class="linenos">166</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">update_style</span> <span class="o">=</span> <span class="n">update_style</span>
</span><span id="VimGolfLogWatcher-167"><a href="#VimGolfLogWatcher-167"><span class="linenos">167</span></a>
</span><span id="VimGolfLogWatcher-168"><a href="#VimGolfLogWatcher-168"><span class="linenos">168</span></a>    <span class="k">def</span><span class="w"> </span><span class="nf">default_update</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span id="VimGolfLogWatcher-169"><a href="#VimGolfLogWatcher-169"><span class="linenos">169</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="VimGolfLogWatcher-170"><a href="#VimGolfLogWatcher-170"><span class="linenos">170</span></a><span class="sd">        Call the update method with the default update style.</span>
</span><span id="VimGolfLogWatcher-171"><a href="#VimGolfLogWatcher-171"><span class="linenos">171</span></a>
</span><span id="VimGolfLogWatcher-172"><a href="#VimGolfLogWatcher-172"><span class="linenos">172</span></a><span class="sd">        This method is a convenience wrapper around the update method,</span>
</span><span id="VimGolfLogWatcher-173"><a href="#VimGolfLogWatcher-173"><span class="linenos">173</span></a><span class="sd">        calling it with the default update style specified in the</span>
</span><span id="VimGolfLogWatcher-174"><a href="#VimGolfLogWatcher-174"><span class="linenos">174</span></a><span class="sd">        constructor.</span>
</span><span id="VimGolfLogWatcher-175"><a href="#VimGolfLogWatcher-175"><span class="linenos">175</span></a>
</span><span id="VimGolfLogWatcher-176"><a href="#VimGolfLogWatcher-176"><span class="linenos">176</span></a><span class="sd">        See the update method for more details.</span>
</span><span id="VimGolfLogWatcher-177"><a href="#VimGolfLogWatcher-177"><span class="linenos">177</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="VimGolfLogWatcher-178"><a href="#VimGolfLogWatcher-178"><span class="linenos">178</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">style</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">update_style</span><span class="p">)</span>
</span><span id="VimGolfLogWatcher-179"><a href="#VimGolfLogWatcher-179"><span class="linenos">179</span></a>
</span><span id="VimGolfLogWatcher-180"><a href="#VimGolfLogWatcher-180"><span class="linenos">180</span></a>    <span class="nd">@property</span>
</span><span id="VimGolfLogWatcher-181"><a href="#VimGolfLogWatcher-181"><span class="linenos">181</span></a>    <span class="k">def</span><span class="w"> </span><span class="nf">success</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span id="VimGolfLogWatcher-182"><a href="#VimGolfLogWatcher-182"><span class="linenos">182</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="VimGolfLogWatcher-183"><a href="#VimGolfLogWatcher-183"><span class="linenos">183</span></a><span class="sd">        Check if the vimgolf challenge has been solved successfully.</span>
</span><span id="VimGolfLogWatcher-184"><a href="#VimGolfLogWatcher-184"><span class="linenos">184</span></a>
</span><span id="VimGolfLogWatcher-185"><a href="#VimGolfLogWatcher-185"><span class="linenos">185</span></a><span class="sd">        This property checks if the vimgolf challenge has been solved</span>
</span><span id="VimGolfLogWatcher-186"><a href="#VimGolfLogWatcher-186"><span class="linenos">186</span></a><span class="sd">        successfully. It updates the log watcher if necessary before</span>
</span><span id="VimGolfLogWatcher-187"><a href="#VimGolfLogWatcher-187"><span class="linenos">187</span></a><span class="sd">        checking the success status.</span>
</span><span id="VimGolfLogWatcher-188"><a href="#VimGolfLogWatcher-188"><span class="linenos">188</span></a>
</span><span id="VimGolfLogWatcher-189"><a href="#VimGolfLogWatcher-189"><span class="linenos">189</span></a><span class="sd">        Returns:</span>
</span><span id="VimGolfLogWatcher-190"><a href="#VimGolfLogWatcher-190"><span class="linenos">190</span></a><span class="sd">            bool: True if the challenge has been solved successfully, False otherwise.</span>
</span><span id="VimGolfLogWatcher-191"><a href="#VimGolfLogWatcher-191"><span class="linenos">191</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="VimGolfLogWatcher-192"><a href="#VimGolfLogWatcher-192"><span class="linenos">192</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">default_update</span><span class="p">()</span>
</span><span id="VimGolfLogWatcher-193"><a href="#VimGolfLogWatcher-193"><span class="linenos">193</span></a>        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">parser</span><span class="o">.</span><span class="n">success</span>
</span><span id="VimGolfLogWatcher-194"><a href="#VimGolfLogWatcher-194"><span class="linenos">194</span></a>
</span><span id="VimGolfLogWatcher-195"><a href="#VimGolfLogWatcher-195"><span class="linenos">195</span></a>    <span class="k">def</span><span class="w"> </span><span class="nf">get_best_success_result</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span id="VimGolfLogWatcher-196"><a href="#VimGolfLogWatcher-196"><span class="linenos">196</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="VimGolfLogWatcher-197"><a href="#VimGolfLogWatcher-197"><span class="linenos">197</span></a><span class="sd">        Return the best success result in the log watcher.</span>
</span><span id="VimGolfLogWatcher-198"><a href="#VimGolfLogWatcher-198"><span class="linenos">198</span></a>
</span><span id="VimGolfLogWatcher-199"><a href="#VimGolfLogWatcher-199"><span class="linenos">199</span></a><span class="sd">        This method returns the best success result in the log watcher,</span>
</span><span id="VimGolfLogWatcher-200"><a href="#VimGolfLogWatcher-200"><span class="linenos">200</span></a><span class="sd">        updating the log watcher if necessary before returning the result.</span>
</span><span id="VimGolfLogWatcher-201"><a href="#VimGolfLogWatcher-201"><span class="linenos">201</span></a>
</span><span id="VimGolfLogWatcher-202"><a href="#VimGolfLogWatcher-202"><span class="linenos">202</span></a><span class="sd">        Returns:</span>
</span><span id="VimGolfLogWatcher-203"><a href="#VimGolfLogWatcher-203"><span class="linenos">203</span></a><span class="sd">            VimGolfEnvResult: The best success result in the log watcher, or None if </span>
</span><span id="VimGolfLogWatcher-204"><a href="#VimGolfLogWatcher-204"><span class="linenos">204</span></a><span class="sd">            there is no success result.</span>
</span><span id="VimGolfLogWatcher-205"><a href="#VimGolfLogWatcher-205"><span class="linenos">205</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="VimGolfLogWatcher-206"><a href="#VimGolfLogWatcher-206"><span class="linenos">206</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">default_update</span><span class="p">()</span>
</span><span id="VimGolfLogWatcher-207"><a href="#VimGolfLogWatcher-207"><span class="linenos">207</span></a>        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">parser</span><span class="o">.</span><span class="n">get_best_success_result</span><span class="p">()</span>
</span><span id="VimGolfLogWatcher-208"><a href="#VimGolfLogWatcher-208"><span class="linenos">208</span></a>
</span><span id="VimGolfLogWatcher-209"><a href="#VimGolfLogWatcher-209"><span class="linenos">209</span></a>    <span class="k">def</span><span class="w"> </span><span class="nf">get_last_success_result</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span id="VimGolfLogWatcher-210"><a href="#VimGolfLogWatcher-210"><span class="linenos">210</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="VimGolfLogWatcher-211"><a href="#VimGolfLogWatcher-211"><span class="linenos">211</span></a><span class="sd">        Return the last success result in the log watcher.</span>
</span><span id="VimGolfLogWatcher-212"><a href="#VimGolfLogWatcher-212"><span class="linenos">212</span></a>
</span><span id="VimGolfLogWatcher-213"><a href="#VimGolfLogWatcher-213"><span class="linenos">213</span></a><span class="sd">        This method returns the last success result in the log watcher,</span>
</span><span id="VimGolfLogWatcher-214"><a href="#VimGolfLogWatcher-214"><span class="linenos">214</span></a><span class="sd">        updating the log watcher if necessary before returning the result.</span>
</span><span id="VimGolfLogWatcher-215"><a href="#VimGolfLogWatcher-215"><span class="linenos">215</span></a>
</span><span id="VimGolfLogWatcher-216"><a href="#VimGolfLogWatcher-216"><span class="linenos">216</span></a><span class="sd">        Returns:</span>
</span><span id="VimGolfLogWatcher-217"><a href="#VimGolfLogWatcher-217"><span class="linenos">217</span></a><span class="sd">            VimGolfEnvResult: The last success result in the log watcher, or None if </span>
</span><span id="VimGolfLogWatcher-218"><a href="#VimGolfLogWatcher-218"><span class="linenos">218</span></a><span class="sd">            there is no success result.</span>
</span><span id="VimGolfLogWatcher-219"><a href="#VimGolfLogWatcher-219"><span class="linenos">219</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="VimGolfLogWatcher-220"><a href="#VimGolfLogWatcher-220"><span class="linenos">220</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">default_update</span><span class="p">()</span>
</span><span id="VimGolfLogWatcher-221"><a href="#VimGolfLogWatcher-221"><span class="linenos">221</span></a>        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">parser</span><span class="o">.</span><span class="n">get_last_success_result</span><span class="p">()</span>
</span><span id="VimGolfLogWatcher-222"><a href="#VimGolfLogWatcher-222"><span class="linenos">222</span></a>
</span><span id="VimGolfLogWatcher-223"><a href="#VimGolfLogWatcher-223"><span class="linenos">223</span></a>    <span class="nd">@property</span>
</span><span id="VimGolfLogWatcher-224"><a href="#VimGolfLogWatcher-224"><span class="linenos">224</span></a>    <span class="k">def</span><span class="w"> </span><span class="nf">results</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span id="VimGolfLogWatcher-225"><a href="#VimGolfLogWatcher-225"><span class="linenos">225</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="VimGolfLogWatcher-226"><a href="#VimGolfLogWatcher-226"><span class="linenos">226</span></a><span class="sd">        The results of the vimgolf challenge environment.</span>
</span><span id="VimGolfLogWatcher-227"><a href="#VimGolfLogWatcher-227"><span class="linenos">227</span></a>
</span><span id="VimGolfLogWatcher-228"><a href="#VimGolfLogWatcher-228"><span class="linenos">228</span></a><span class="sd">        This property returns the results of the vimgolf challenge environment,</span>
</span><span id="VimGolfLogWatcher-229"><a href="#VimGolfLogWatcher-229"><span class="linenos">229</span></a><span class="sd">        updating the log watcher if necessary before returning the results.</span>
</span><span id="VimGolfLogWatcher-230"><a href="#VimGolfLogWatcher-230"><span class="linenos">230</span></a>
</span><span id="VimGolfLogWatcher-231"><a href="#VimGolfLogWatcher-231"><span class="linenos">231</span></a><span class="sd">        Returns:</span>
</span><span id="VimGolfLogWatcher-232"><a href="#VimGolfLogWatcher-232"><span class="linenos">232</span></a><span class="sd">            list[VimGolfEnvResult]: The results of the vimgolf challenge environment, or an empty list if</span>
</span><span id="VimGolfLogWatcher-233"><a href="#VimGolfLogWatcher-233"><span class="linenos">233</span></a><span class="sd">            there are no results.</span>
</span><span id="VimGolfLogWatcher-234"><a href="#VimGolfLogWatcher-234"><span class="linenos">234</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="VimGolfLogWatcher-235"><a href="#VimGolfLogWatcher-235"><span class="linenos">235</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">default_update</span><span class="p">()</span>
</span><span id="VimGolfLogWatcher-236"><a href="#VimGolfLogWatcher-236"><span class="linenos">236</span></a>        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">parser</span><span class="o">.</span><span class="n">results</span>
</span><span id="VimGolfLogWatcher-237"><a href="#VimGolfLogWatcher-237"><span class="linenos">237</span></a>
</span><span id="VimGolfLogWatcher-238"><a href="#VimGolfLogWatcher-238"><span class="linenos">238</span></a>    <span class="nd">@property</span>
</span><span id="VimGolfLogWatcher-239"><a href="#VimGolfLogWatcher-239"><span class="linenos">239</span></a>    <span class="k">def</span><span class="w"> </span><span class="nf">success_results</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span id="VimGolfLogWatcher-240"><a href="#VimGolfLogWatcher-240"><span class="linenos">240</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="VimGolfLogWatcher-241"><a href="#VimGolfLogWatcher-241"><span class="linenos">241</span></a><span class="sd">        The successful results of the vimgolf challenge environment.</span>
</span><span id="VimGolfLogWatcher-242"><a href="#VimGolfLogWatcher-242"><span class="linenos">242</span></a>
</span><span id="VimGolfLogWatcher-243"><a href="#VimGolfLogWatcher-243"><span class="linenos">243</span></a><span class="sd">        This property returns the successful results of the vimgolf challenge</span>
</span><span id="VimGolfLogWatcher-244"><a href="#VimGolfLogWatcher-244"><span class="linenos">244</span></a><span class="sd">        environment, updating the log watcher if necessary before returning the</span>
</span><span id="VimGolfLogWatcher-245"><a href="#VimGolfLogWatcher-245"><span class="linenos">245</span></a><span class="sd">        results.</span>
</span><span id="VimGolfLogWatcher-246"><a href="#VimGolfLogWatcher-246"><span class="linenos">246</span></a>
</span><span id="VimGolfLogWatcher-247"><a href="#VimGolfLogWatcher-247"><span class="linenos">247</span></a><span class="sd">        Returns:</span>
</span><span id="VimGolfLogWatcher-248"><a href="#VimGolfLogWatcher-248"><span class="linenos">248</span></a><span class="sd">            list[VimGolfEnvResult]: The successful results of the vimgolf challenge environment, or an</span>
</span><span id="VimGolfLogWatcher-249"><a href="#VimGolfLogWatcher-249"><span class="linenos">249</span></a><span class="sd">            empty list if there are no successful results.</span>
</span><span id="VimGolfLogWatcher-250"><a href="#VimGolfLogWatcher-250"><span class="linenos">250</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="VimGolfLogWatcher-251"><a href="#VimGolfLogWatcher-251"><span class="linenos">251</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">default_update</span><span class="p">()</span>
</span><span id="VimGolfLogWatcher-252"><a href="#VimGolfLogWatcher-252"><span class="linenos">252</span></a>        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">parser</span><span class="o">.</span><span class="n">success_results</span>
</span></pre></div>


    

                            <div id="VimGolfLogWatcher.__init__" class="classattr">
                                        <input id="VimGolfLogWatcher.__init__-view-source" class="view-source-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<div class="attr function">
            
        <span class="name">VimGolfLogWatcher</span><span class="signature pdoc-code condensed">(<span class="param"><span class="n">log_file</span><span class="p">:</span> <span class="nb">str</span>, </span><span class="param"><span class="n">update_style</span><span class="o">=</span><span class="s1">&#39;advanced&#39;</span></span>)</span>

                <label class="view-source-button" for="VimGolfLogWatcher.__init__-view-source"><span>View Source</span></label>

    </div>
    <a class="headerlink" href="#VimGolfLogWatcher.__init__"></a>
            <div class="pdoc-code codehilite"><pre><span></span><span id="VimGolfLogWatcher.__init__-149"><a href="#VimGolfLogWatcher.__init__-149"><span class="linenos">149</span></a>    <span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">log_file</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">update_style</span><span class="o">=</span><span class="s2">&quot;advanced&quot;</span><span class="p">):</span>
</span><span id="VimGolfLogWatcher.__init__-150"><a href="#VimGolfLogWatcher.__init__-150"><span class="linenos">150</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="VimGolfLogWatcher.__init__-151"><a href="#VimGolfLogWatcher.__init__-151"><span class="linenos">151</span></a><span class="sd">        Initialize a VimGolfLogWatcher with a log file and an update style.</span>
</span><span id="VimGolfLogWatcher.__init__-152"><a href="#VimGolfLogWatcher.__init__-152"><span class="linenos">152</span></a>
</span><span id="VimGolfLogWatcher.__init__-153"><a href="#VimGolfLogWatcher.__init__-153"><span class="linenos">153</span></a><span class="sd">        The VimGolfLogWatcher is a LogWatcher that is specialized for</span>
</span><span id="VimGolfLogWatcher.__init__-154"><a href="#VimGolfLogWatcher.__init__-154"><span class="linenos">154</span></a><span class="sd">        reading VimGolf logs.</span>
</span><span id="VimGolfLogWatcher.__init__-155"><a href="#VimGolfLogWatcher.__init__-155"><span class="linenos">155</span></a>
</span><span id="VimGolfLogWatcher.__init__-156"><a href="#VimGolfLogWatcher.__init__-156"><span class="linenos">156</span></a><span class="sd">        Args:</span>
</span><span id="VimGolfLogWatcher.__init__-157"><a href="#VimGolfLogWatcher.__init__-157"><span class="linenos">157</span></a><span class="sd">            log_file (str): The path to the log file.</span>
</span><span id="VimGolfLogWatcher.__init__-158"><a href="#VimGolfLogWatcher.__init__-158"><span class="linenos">158</span></a><span class="sd">            update_style (str, optional): The update strategy to use. Must be one of </span>
</span><span id="VimGolfLogWatcher.__init__-159"><a href="#VimGolfLogWatcher.__init__-159"><span class="linenos">159</span></a><span class="sd">                ``advanced``, ``simple``, or ``naive``. Defaults to ``advanced``.</span>
</span><span id="VimGolfLogWatcher.__init__-160"><a href="#VimGolfLogWatcher.__init__-160"><span class="linenos">160</span></a>
</span><span id="VimGolfLogWatcher.__init__-161"><a href="#VimGolfLogWatcher.__init__-161"><span class="linenos">161</span></a><span class="sd">        Returns:</span>
</span><span id="VimGolfLogWatcher.__init__-162"><a href="#VimGolfLogWatcher.__init__-162"><span class="linenos">162</span></a><span class="sd">            [return_type]: [description of return value]</span>
</span><span id="VimGolfLogWatcher.__init__-163"><a href="#VimGolfLogWatcher.__init__-163"><span class="linenos">163</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="VimGolfLogWatcher.__init__-164"><a href="#VimGolfLogWatcher.__init__-164"><span class="linenos">164</span></a>        <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">log_file</span><span class="o">=</span><span class="n">log_file</span><span class="p">,</span> <span class="n">parser_class</span><span class="o">=</span><span class="n">VimGolfLogParser</span><span class="p">)</span>
</span><span id="VimGolfLogWatcher.__init__-165"><a href="#VimGolfLogWatcher.__init__-165"><span class="linenos">165</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">parser</span><span class="p">:</span> <span class="n">VimGolfLogParser</span>
</span><span id="VimGolfLogWatcher.__init__-166"><a href="#VimGolfLogWatcher.__init__-166"><span class="linenos">166</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">update_style</span> <span class="o">=</span> <span class="n">update_style</span>
</span></pre></div>


            <div class="docstring"><p>Initialize a VimGolfLogWatcher with a log file and an update style.</p>

<p>The VimGolfLogWatcher is a LogWatcher that is specialized for
reading VimGolf logs.</p>

<h6 id="arguments">Arguments:</h6>

<ul>
<li><strong>log_file (str):</strong>  The path to the log file.</li>
<li><strong>update_style (str, optional):</strong>  The update strategy to use. Must be one of 
<code>advanced</code>, <code>simple</code>, or <code>naive</code>. Defaults to <code>advanced</code>.</li>
</ul>

<h6 id="returns">Returns:</h6>

<blockquote>
  <p>[return_type]: [description of return value]</p>
</blockquote>
</div>


                            </div>
                            <div id="VimGolfLogWatcher.parser" class="classattr">
                                <div class="attr variable">
            <span class="name">parser</span><span class="annotation">: <a href="#VimGolfLogParser">VimGolfLogParser</a></span>

        
    </div>
    <a class="headerlink" href="#VimGolfLogWatcher.parser"></a>
    
    

                            </div>
                            <div id="VimGolfLogWatcher.update_style" class="classattr">
                                <div class="attr variable">
            <span class="name">update_style</span>

        
    </div>
    <a class="headerlink" href="#VimGolfLogWatcher.update_style"></a>
    
    

                            </div>
                            <div id="VimGolfLogWatcher.default_update" class="classattr">
                                        <input id="VimGolfLogWatcher.default_update-view-source" class="view-source-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<div class="attr function">
            
        <span class="def">def</span>
        <span class="name">default_update</span><span class="signature pdoc-code condensed">(<span class="param"><span class="bp">self</span></span><span class="return-annotation">):</span></span>

                <label class="view-source-button" for="VimGolfLogWatcher.default_update-view-source"><span>View Source</span></label>

    </div>
    <a class="headerlink" href="#VimGolfLogWatcher.default_update"></a>
            <div class="pdoc-code codehilite"><pre><span></span><span id="VimGolfLogWatcher.default_update-168"><a href="#VimGolfLogWatcher.default_update-168"><span class="linenos">168</span></a>    <span class="k">def</span><span class="w"> </span><span class="nf">default_update</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span id="VimGolfLogWatcher.default_update-169"><a href="#VimGolfLogWatcher.default_update-169"><span class="linenos">169</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="VimGolfLogWatcher.default_update-170"><a href="#VimGolfLogWatcher.default_update-170"><span class="linenos">170</span></a><span class="sd">        Call the update method with the default update style.</span>
</span><span id="VimGolfLogWatcher.default_update-171"><a href="#VimGolfLogWatcher.default_update-171"><span class="linenos">171</span></a>
</span><span id="VimGolfLogWatcher.default_update-172"><a href="#VimGolfLogWatcher.default_update-172"><span class="linenos">172</span></a><span class="sd">        This method is a convenience wrapper around the update method,</span>
</span><span id="VimGolfLogWatcher.default_update-173"><a href="#VimGolfLogWatcher.default_update-173"><span class="linenos">173</span></a><span class="sd">        calling it with the default update style specified in the</span>
</span><span id="VimGolfLogWatcher.default_update-174"><a href="#VimGolfLogWatcher.default_update-174"><span class="linenos">174</span></a><span class="sd">        constructor.</span>
</span><span id="VimGolfLogWatcher.default_update-175"><a href="#VimGolfLogWatcher.default_update-175"><span class="linenos">175</span></a>
</span><span id="VimGolfLogWatcher.default_update-176"><a href="#VimGolfLogWatcher.default_update-176"><span class="linenos">176</span></a><span class="sd">        See the update method for more details.</span>
</span><span id="VimGolfLogWatcher.default_update-177"><a href="#VimGolfLogWatcher.default_update-177"><span class="linenos">177</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="VimGolfLogWatcher.default_update-178"><a href="#VimGolfLogWatcher.default_update-178"><span class="linenos">178</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">style</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">update_style</span><span class="p">)</span>
</span></pre></div>


            <div class="docstring"><p>Call the update method with the default update style.</p>

<p>This method is a convenience wrapper around the update method,
calling it with the default update style specified in the
constructor.</p>

<p>See the update method for more details.</p>
</div>


                            </div>
                            <div id="VimGolfLogWatcher.success" class="classattr">
                                        <input id="VimGolfLogWatcher.success-view-source" class="view-source-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<div class="attr variable">
            <span class="name">success</span>

                <label class="view-source-button" for="VimGolfLogWatcher.success-view-source"><span>View Source</span></label>

    </div>
    <a class="headerlink" href="#VimGolfLogWatcher.success"></a>
            <div class="pdoc-code codehilite"><pre><span></span><span id="VimGolfLogWatcher.success-180"><a href="#VimGolfLogWatcher.success-180"><span class="linenos">180</span></a>    <span class="nd">@property</span>
</span><span id="VimGolfLogWatcher.success-181"><a href="#VimGolfLogWatcher.success-181"><span class="linenos">181</span></a>    <span class="k">def</span><span class="w"> </span><span class="nf">success</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span id="VimGolfLogWatcher.success-182"><a href="#VimGolfLogWatcher.success-182"><span class="linenos">182</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="VimGolfLogWatcher.success-183"><a href="#VimGolfLogWatcher.success-183"><span class="linenos">183</span></a><span class="sd">        Check if the vimgolf challenge has been solved successfully.</span>
</span><span id="VimGolfLogWatcher.success-184"><a href="#VimGolfLogWatcher.success-184"><span class="linenos">184</span></a>
</span><span id="VimGolfLogWatcher.success-185"><a href="#VimGolfLogWatcher.success-185"><span class="linenos">185</span></a><span class="sd">        This property checks if the vimgolf challenge has been solved</span>
</span><span id="VimGolfLogWatcher.success-186"><a href="#VimGolfLogWatcher.success-186"><span class="linenos">186</span></a><span class="sd">        successfully. It updates the log watcher if necessary before</span>
</span><span id="VimGolfLogWatcher.success-187"><a href="#VimGolfLogWatcher.success-187"><span class="linenos">187</span></a><span class="sd">        checking the success status.</span>
</span><span id="VimGolfLogWatcher.success-188"><a href="#VimGolfLogWatcher.success-188"><span class="linenos">188</span></a>
</span><span id="VimGolfLogWatcher.success-189"><a href="#VimGolfLogWatcher.success-189"><span class="linenos">189</span></a><span class="sd">        Returns:</span>
</span><span id="VimGolfLogWatcher.success-190"><a href="#VimGolfLogWatcher.success-190"><span class="linenos">190</span></a><span class="sd">            bool: True if the challenge has been solved successfully, False otherwise.</span>
</span><span id="VimGolfLogWatcher.success-191"><a href="#VimGolfLogWatcher.success-191"><span class="linenos">191</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="VimGolfLogWatcher.success-192"><a href="#VimGolfLogWatcher.success-192"><span class="linenos">192</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">default_update</span><span class="p">()</span>
</span><span id="VimGolfLogWatcher.success-193"><a href="#VimGolfLogWatcher.success-193"><span class="linenos">193</span></a>        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">parser</span><span class="o">.</span><span class="n">success</span>
</span></pre></div>


            <div class="docstring"><p>Check if the vimgolf challenge has been solved successfully.</p>

<p>This property checks if the vimgolf challenge has been solved
successfully. It updates the log watcher if necessary before
checking the success status.</p>

<h6 id="returns">Returns:</h6>

<blockquote>
  <p>bool: True if the challenge has been solved successfully, False otherwise.</p>
</blockquote>
</div>


                            </div>
                            <div id="VimGolfLogWatcher.get_best_success_result" class="classattr">
                                        <input id="VimGolfLogWatcher.get_best_success_result-view-source" class="view-source-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<div class="attr function">
            
        <span class="def">def</span>
        <span class="name">get_best_success_result</span><span class="signature pdoc-code condensed">(<span class="param"><span class="bp">self</span></span><span class="return-annotation">):</span></span>

                <label class="view-source-button" for="VimGolfLogWatcher.get_best_success_result-view-source"><span>View Source</span></label>

    </div>
    <a class="headerlink" href="#VimGolfLogWatcher.get_best_success_result"></a>
            <div class="pdoc-code codehilite"><pre><span></span><span id="VimGolfLogWatcher.get_best_success_result-195"><a href="#VimGolfLogWatcher.get_best_success_result-195"><span class="linenos">195</span></a>    <span class="k">def</span><span class="w"> </span><span class="nf">get_best_success_result</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span id="VimGolfLogWatcher.get_best_success_result-196"><a href="#VimGolfLogWatcher.get_best_success_result-196"><span class="linenos">196</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="VimGolfLogWatcher.get_best_success_result-197"><a href="#VimGolfLogWatcher.get_best_success_result-197"><span class="linenos">197</span></a><span class="sd">        Return the best success result in the log watcher.</span>
</span><span id="VimGolfLogWatcher.get_best_success_result-198"><a href="#VimGolfLogWatcher.get_best_success_result-198"><span class="linenos">198</span></a>
</span><span id="VimGolfLogWatcher.get_best_success_result-199"><a href="#VimGolfLogWatcher.get_best_success_result-199"><span class="linenos">199</span></a><span class="sd">        This method returns the best success result in the log watcher,</span>
</span><span id="VimGolfLogWatcher.get_best_success_result-200"><a href="#VimGolfLogWatcher.get_best_success_result-200"><span class="linenos">200</span></a><span class="sd">        updating the log watcher if necessary before returning the result.</span>
</span><span id="VimGolfLogWatcher.get_best_success_result-201"><a href="#VimGolfLogWatcher.get_best_success_result-201"><span class="linenos">201</span></a>
</span><span id="VimGolfLogWatcher.get_best_success_result-202"><a href="#VimGolfLogWatcher.get_best_success_result-202"><span class="linenos">202</span></a><span class="sd">        Returns:</span>
</span><span id="VimGolfLogWatcher.get_best_success_result-203"><a href="#VimGolfLogWatcher.get_best_success_result-203"><span class="linenos">203</span></a><span class="sd">            VimGolfEnvResult: The best success result in the log watcher, or None if </span>
</span><span id="VimGolfLogWatcher.get_best_success_result-204"><a href="#VimGolfLogWatcher.get_best_success_result-204"><span class="linenos">204</span></a><span class="sd">            there is no success result.</span>
</span><span id="VimGolfLogWatcher.get_best_success_result-205"><a href="#VimGolfLogWatcher.get_best_success_result-205"><span class="linenos">205</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="VimGolfLogWatcher.get_best_success_result-206"><a href="#VimGolfLogWatcher.get_best_success_result-206"><span class="linenos">206</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">default_update</span><span class="p">()</span>
</span><span id="VimGolfLogWatcher.get_best_success_result-207"><a href="#VimGolfLogWatcher.get_best_success_result-207"><span class="linenos">207</span></a>        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">parser</span><span class="o">.</span><span class="n">get_best_success_result</span><span class="p">()</span>
</span></pre></div>


            <div class="docstring"><p>Return the best success result in the log watcher.</p>

<p>This method returns the best success result in the log watcher,
updating the log watcher if necessary before returning the result.</p>

<h6 id="returns">Returns:</h6>

<blockquote>
  <p>VimGolfEnvResult: The best success result in the log watcher, or None if 
  there is no success result.</p>
</blockquote>
</div>


                            </div>
                            <div id="VimGolfLogWatcher.get_last_success_result" class="classattr">
                                        <input id="VimGolfLogWatcher.get_last_success_result-view-source" class="view-source-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<div class="attr function">
            
        <span class="def">def</span>
        <span class="name">get_last_success_result</span><span class="signature pdoc-code condensed">(<span class="param"><span class="bp">self</span></span><span class="return-annotation">):</span></span>

                <label class="view-source-button" for="VimGolfLogWatcher.get_last_success_result-view-source"><span>View Source</span></label>

    </div>
    <a class="headerlink" href="#VimGolfLogWatcher.get_last_success_result"></a>
            <div class="pdoc-code codehilite"><pre><span></span><span id="VimGolfLogWatcher.get_last_success_result-209"><a href="#VimGolfLogWatcher.get_last_success_result-209"><span class="linenos">209</span></a>    <span class="k">def</span><span class="w"> </span><span class="nf">get_last_success_result</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span id="VimGolfLogWatcher.get_last_success_result-210"><a href="#VimGolfLogWatcher.get_last_success_result-210"><span class="linenos">210</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="VimGolfLogWatcher.get_last_success_result-211"><a href="#VimGolfLogWatcher.get_last_success_result-211"><span class="linenos">211</span></a><span class="sd">        Return the last success result in the log watcher.</span>
</span><span id="VimGolfLogWatcher.get_last_success_result-212"><a href="#VimGolfLogWatcher.get_last_success_result-212"><span class="linenos">212</span></a>
</span><span id="VimGolfLogWatcher.get_last_success_result-213"><a href="#VimGolfLogWatcher.get_last_success_result-213"><span class="linenos">213</span></a><span class="sd">        This method returns the last success result in the log watcher,</span>
</span><span id="VimGolfLogWatcher.get_last_success_result-214"><a href="#VimGolfLogWatcher.get_last_success_result-214"><span class="linenos">214</span></a><span class="sd">        updating the log watcher if necessary before returning the result.</span>
</span><span id="VimGolfLogWatcher.get_last_success_result-215"><a href="#VimGolfLogWatcher.get_last_success_result-215"><span class="linenos">215</span></a>
</span><span id="VimGolfLogWatcher.get_last_success_result-216"><a href="#VimGolfLogWatcher.get_last_success_result-216"><span class="linenos">216</span></a><span class="sd">        Returns:</span>
</span><span id="VimGolfLogWatcher.get_last_success_result-217"><a href="#VimGolfLogWatcher.get_last_success_result-217"><span class="linenos">217</span></a><span class="sd">            VimGolfEnvResult: The last success result in the log watcher, or None if </span>
</span><span id="VimGolfLogWatcher.get_last_success_result-218"><a href="#VimGolfLogWatcher.get_last_success_result-218"><span class="linenos">218</span></a><span class="sd">            there is no success result.</span>
</span><span id="VimGolfLogWatcher.get_last_success_result-219"><a href="#VimGolfLogWatcher.get_last_success_result-219"><span class="linenos">219</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="VimGolfLogWatcher.get_last_success_result-220"><a href="#VimGolfLogWatcher.get_last_success_result-220"><span class="linenos">220</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">default_update</span><span class="p">()</span>
</span><span id="VimGolfLogWatcher.get_last_success_result-221"><a href="#VimGolfLogWatcher.get_last_success_result-221"><span class="linenos">221</span></a>        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">parser</span><span class="o">.</span><span class="n">get_last_success_result</span><span class="p">()</span>
</span></pre></div>


            <div class="docstring"><p>Return the last success result in the log watcher.</p>

<p>This method returns the last success result in the log watcher,
updating the log watcher if necessary before returning the result.</p>

<h6 id="returns">Returns:</h6>

<blockquote>
  <p>VimGolfEnvResult: The last success result in the log watcher, or None if 
  there is no success result.</p>
</blockquote>
</div>


                            </div>
                            <div id="VimGolfLogWatcher.results" class="classattr">
                                        <input id="VimGolfLogWatcher.results-view-source" class="view-source-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<div class="attr variable">
            <span class="name">results</span>

                <label class="view-source-button" for="VimGolfLogWatcher.results-view-source"><span>View Source</span></label>

    </div>
    <a class="headerlink" href="#VimGolfLogWatcher.results"></a>
            <div class="pdoc-code codehilite"><pre><span></span><span id="VimGolfLogWatcher.results-223"><a href="#VimGolfLogWatcher.results-223"><span class="linenos">223</span></a>    <span class="nd">@property</span>
</span><span id="VimGolfLogWatcher.results-224"><a href="#VimGolfLogWatcher.results-224"><span class="linenos">224</span></a>    <span class="k">def</span><span class="w"> </span><span class="nf">results</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span id="VimGolfLogWatcher.results-225"><a href="#VimGolfLogWatcher.results-225"><span class="linenos">225</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="VimGolfLogWatcher.results-226"><a href="#VimGolfLogWatcher.results-226"><span class="linenos">226</span></a><span class="sd">        The results of the vimgolf challenge environment.</span>
</span><span id="VimGolfLogWatcher.results-227"><a href="#VimGolfLogWatcher.results-227"><span class="linenos">227</span></a>
</span><span id="VimGolfLogWatcher.results-228"><a href="#VimGolfLogWatcher.results-228"><span class="linenos">228</span></a><span class="sd">        This property returns the results of the vimgolf challenge environment,</span>
</span><span id="VimGolfLogWatcher.results-229"><a href="#VimGolfLogWatcher.results-229"><span class="linenos">229</span></a><span class="sd">        updating the log watcher if necessary before returning the results.</span>
</span><span id="VimGolfLogWatcher.results-230"><a href="#VimGolfLogWatcher.results-230"><span class="linenos">230</span></a>
</span><span id="VimGolfLogWatcher.results-231"><a href="#VimGolfLogWatcher.results-231"><span class="linenos">231</span></a><span class="sd">        Returns:</span>
</span><span id="VimGolfLogWatcher.results-232"><a href="#VimGolfLogWatcher.results-232"><span class="linenos">232</span></a><span class="sd">            list[VimGolfEnvResult]: The results of the vimgolf challenge environment, or an empty list if</span>
</span><span id="VimGolfLogWatcher.results-233"><a href="#VimGolfLogWatcher.results-233"><span class="linenos">233</span></a><span class="sd">            there are no results.</span>
</span><span id="VimGolfLogWatcher.results-234"><a href="#VimGolfLogWatcher.results-234"><span class="linenos">234</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="VimGolfLogWatcher.results-235"><a href="#VimGolfLogWatcher.results-235"><span class="linenos">235</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">default_update</span><span class="p">()</span>
</span><span id="VimGolfLogWatcher.results-236"><a href="#VimGolfLogWatcher.results-236"><span class="linenos">236</span></a>        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">parser</span><span class="o">.</span><span class="n">results</span>
</span></pre></div>


            <div class="docstring"><p>The results of the vimgolf challenge environment.</p>

<p>This property returns the results of the vimgolf challenge environment,
updating the log watcher if necessary before returning the results.</p>

<h6 id="returns">Returns:</h6>

<blockquote>
  <p>list[VimGolfEnvResult]: The results of the vimgolf challenge environment, or an empty list if
  there are no results.</p>
</blockquote>
</div>


                            </div>
                            <div id="VimGolfLogWatcher.success_results" class="classattr">
                                        <input id="VimGolfLogWatcher.success_results-view-source" class="view-source-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<div class="attr variable">
            <span class="name">success_results</span>

                <label class="view-source-button" for="VimGolfLogWatcher.success_results-view-source"><span>View Source</span></label>

    </div>
    <a class="headerlink" href="#VimGolfLogWatcher.success_results"></a>
            <div class="pdoc-code codehilite"><pre><span></span><span id="VimGolfLogWatcher.success_results-238"><a href="#VimGolfLogWatcher.success_results-238"><span class="linenos">238</span></a>    <span class="nd">@property</span>
</span><span id="VimGolfLogWatcher.success_results-239"><a href="#VimGolfLogWatcher.success_results-239"><span class="linenos">239</span></a>    <span class="k">def</span><span class="w"> </span><span class="nf">success_results</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span id="VimGolfLogWatcher.success_results-240"><a href="#VimGolfLogWatcher.success_results-240"><span class="linenos">240</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="VimGolfLogWatcher.success_results-241"><a href="#VimGolfLogWatcher.success_results-241"><span class="linenos">241</span></a><span class="sd">        The successful results of the vimgolf challenge environment.</span>
</span><span id="VimGolfLogWatcher.success_results-242"><a href="#VimGolfLogWatcher.success_results-242"><span class="linenos">242</span></a>
</span><span id="VimGolfLogWatcher.success_results-243"><a href="#VimGolfLogWatcher.success_results-243"><span class="linenos">243</span></a><span class="sd">        This property returns the successful results of the vimgolf challenge</span>
</span><span id="VimGolfLogWatcher.success_results-244"><a href="#VimGolfLogWatcher.success_results-244"><span class="linenos">244</span></a><span class="sd">        environment, updating the log watcher if necessary before returning the</span>
</span><span id="VimGolfLogWatcher.success_results-245"><a href="#VimGolfLogWatcher.success_results-245"><span class="linenos">245</span></a><span class="sd">        results.</span>
</span><span id="VimGolfLogWatcher.success_results-246"><a href="#VimGolfLogWatcher.success_results-246"><span class="linenos">246</span></a>
</span><span id="VimGolfLogWatcher.success_results-247"><a href="#VimGolfLogWatcher.success_results-247"><span class="linenos">247</span></a><span class="sd">        Returns:</span>
</span><span id="VimGolfLogWatcher.success_results-248"><a href="#VimGolfLogWatcher.success_results-248"><span class="linenos">248</span></a><span class="sd">            list[VimGolfEnvResult]: The successful results of the vimgolf challenge environment, or an</span>
</span><span id="VimGolfLogWatcher.success_results-249"><a href="#VimGolfLogWatcher.success_results-249"><span class="linenos">249</span></a><span class="sd">            empty list if there are no successful results.</span>
</span><span id="VimGolfLogWatcher.success_results-250"><a href="#VimGolfLogWatcher.success_results-250"><span class="linenos">250</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="VimGolfLogWatcher.success_results-251"><a href="#VimGolfLogWatcher.success_results-251"><span class="linenos">251</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">default_update</span><span class="p">()</span>
</span><span id="VimGolfLogWatcher.success_results-252"><a href="#VimGolfLogWatcher.success_results-252"><span class="linenos">252</span></a>        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">parser</span><span class="o">.</span><span class="n">success_results</span>
</span></pre></div>


            <div class="docstring"><p>The successful results of the vimgolf challenge environment.</p>

<p>This property returns the successful results of the vimgolf challenge
environment, updating the log watcher if necessary before returning the
results.</p>

<h6 id="returns">Returns:</h6>

<blockquote>
  <p>list[VimGolfEnvResult]: The successful results of the vimgolf challenge environment, or an
  empty list if there are no successful results.</p>
</blockquote>
</div>


                            </div>
                            <div class="inherited">
                                <h5>Inherited Members</h5>
                                <dl>
                                    <div><dt><a href="#LogWatcher">LogWatcher</a></dt>
                                <dd id="VimGolfLogWatcher.log_file" class="variable"><a href="#LogWatcher.log_file">log_file</a></dd>
                <dd id="VimGolfLogWatcher.parser_class" class="variable"><a href="#LogWatcher.parser_class">parser_class</a></dd>
                <dd id="VimGolfLogWatcher.last_filesize" class="variable"><a href="#LogWatcher.last_filesize">last_filesize</a></dd>
                <dd id="VimGolfLogWatcher.last_position" class="variable"><a href="#LogWatcher.last_position">last_position</a></dd>
                <dd id="VimGolfLogWatcher.update" class="function"><a href="#LogWatcher.update">update</a></dd>
                <dd id="VimGolfLogWatcher.simple_update" class="function"><a href="#LogWatcher.simple_update">simple_update</a></dd>
                <dd id="VimGolfLogWatcher.naive_update" class="function"><a href="#LogWatcher.naive_update">naive_update</a></dd>
                <dd id="VimGolfLogWatcher.advanced_update" class="function"><a href="#LogWatcher.advanced_update">advanced_update</a></dd>

            </div>
                                </dl>
                            </div>
                </section>
                <section id="VimGolfLogParser">
                            <input id="VimGolfLogParser-view-source" class="view-source-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<div class="attr class">
            
    <span class="def">class</span>
    <span class="name">VimGolfLogParser</span><wbr>(<span class="base"><a href="#AbstractLogParser">AbstractLogParser</a></span>):

                <label class="view-source-button" for="VimGolfLogParser-view-source"><span>View Source</span></label>

    </div>
    <a class="headerlink" href="#VimGolfLogParser"></a>
            <div class="pdoc-code codehilite"><pre><span></span><span id="VimGolfLogParser-255"><a href="#VimGolfLogParser-255"><span class="linenos">255</span></a><span class="k">class</span><span class="w"> </span><span class="nc">VimGolfLogParser</span><span class="p">(</span><span class="n">AbstractLogParser</span><span class="p">):</span>
</span><span id="VimGolfLogParser-256"><a href="#VimGolfLogParser-256"><span class="linenos">256</span></a>    <span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span id="VimGolfLogParser-257"><a href="#VimGolfLogParser-257"><span class="linenos">257</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="VimGolfLogParser-258"><a href="#VimGolfLogParser-258"><span class="linenos">258</span></a><span class="sd">        Initialize the VimGolfLogParser.</span>
</span><span id="VimGolfLogParser-259"><a href="#VimGolfLogParser-259"><span class="linenos">259</span></a>
</span><span id="VimGolfLogParser-260"><a href="#VimGolfLogParser-260"><span class="linenos">260</span></a><span class="sd">        The VimGolfLogParser is initialized with an empty list of results.</span>
</span><span id="VimGolfLogParser-261"><a href="#VimGolfLogParser-261"><span class="linenos">261</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="VimGolfLogParser-262"><a href="#VimGolfLogParser-262"><span class="linenos">262</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">results</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="n">VimGolfEnvResult</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
</span><span id="VimGolfLogParser-263"><a href="#VimGolfLogParser-263"><span class="linenos">263</span></a>
</span><span id="VimGolfLogParser-264"><a href="#VimGolfLogParser-264"><span class="linenos">264</span></a>    <span class="k">def</span><span class="w"> </span><span class="nf">feed_line</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">line</span><span class="p">:</span> <span class="nb">str</span><span class="p">):</span>
</span><span id="VimGolfLogParser-265"><a href="#VimGolfLogParser-265"><span class="linenos">265</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="VimGolfLogParser-266"><a href="#VimGolfLogParser-266"><span class="linenos">266</span></a><span class="sd">        Feed a line to the parser.</span>
</span><span id="VimGolfLogParser-267"><a href="#VimGolfLogParser-267"><span class="linenos">267</span></a>
</span><span id="VimGolfLogParser-268"><a href="#VimGolfLogParser-268"><span class="linenos">268</span></a><span class="sd">        The line should be a JSON-formatted string. The parser will attempt to</span>
</span><span id="VimGolfLogParser-269"><a href="#VimGolfLogParser-269"><span class="linenos">269</span></a><span class="sd">        parse the line as a JSON object, and if it is a dictionary, it will</span>
</span><span id="VimGolfLogParser-270"><a href="#VimGolfLogParser-270"><span class="linenos">270</span></a><span class="sd">        check if the dictionary has an &quot;event_type&quot; key with value</span>
</span><span id="VimGolfLogParser-271"><a href="#VimGolfLogParser-271"><span class="linenos">271</span></a><span class="sd">        &quot;vimgolf_result&quot;. If so, it will attempt to parse the value of the</span>
</span><span id="VimGolfLogParser-272"><a href="#VimGolfLogParser-272"><span class="linenos">272</span></a><span class="sd">        &quot;event_data&quot; key as a VimGolfEnvResult object and append it to the</span>
</span><span id="VimGolfLogParser-273"><a href="#VimGolfLogParser-273"><span class="linenos">273</span></a><span class="sd">        results list.</span>
</span><span id="VimGolfLogParser-274"><a href="#VimGolfLogParser-274"><span class="linenos">274</span></a>
</span><span id="VimGolfLogParser-275"><a href="#VimGolfLogParser-275"><span class="linenos">275</span></a><span class="sd">        If the line is not a valid JSON object, or if the JSON object does not</span>
</span><span id="VimGolfLogParser-276"><a href="#VimGolfLogParser-276"><span class="linenos">276</span></a><span class="sd">        have the correct structure, the line will be ignored.</span>
</span><span id="VimGolfLogParser-277"><a href="#VimGolfLogParser-277"><span class="linenos">277</span></a>
</span><span id="VimGolfLogParser-278"><a href="#VimGolfLogParser-278"><span class="linenos">278</span></a><span class="sd">        Args:</span>
</span><span id="VimGolfLogParser-279"><a href="#VimGolfLogParser-279"><span class="linenos">279</span></a><span class="sd">            line (str): The line of text to feed to the parser.</span>
</span><span id="VimGolfLogParser-280"><a href="#VimGolfLogParser-280"><span class="linenos">280</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="VimGolfLogParser-281"><a href="#VimGolfLogParser-281"><span class="linenos">281</span></a>        <span class="k">try</span><span class="p">:</span>
</span><span id="VimGolfLogParser-282"><a href="#VimGolfLogParser-282"><span class="linenos">282</span></a>            <span class="n">data</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">line</span><span class="o">.</span><span class="n">strip</span><span class="p">())</span>
</span><span id="VimGolfLogParser-283"><a href="#VimGolfLogParser-283"><span class="linenos">283</span></a>            <span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> <span class="o">==</span> <span class="nb">dict</span><span class="p">:</span>
</span><span id="VimGolfLogParser-284"><a href="#VimGolfLogParser-284"><span class="linenos">284</span></a>                <span class="k">if</span> <span class="n">data</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;event_type&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> <span class="o">==</span> <span class="s2">&quot;vimgolf_result&quot;</span><span class="p">:</span>
</span><span id="VimGolfLogParser-285"><a href="#VimGolfLogParser-285"><span class="linenos">285</span></a>                    <span class="n">event_data</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;event_data&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
</span><span id="VimGolfLogParser-286"><a href="#VimGolfLogParser-286"><span class="linenos">286</span></a>                    <span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">event_data</span><span class="p">)</span> <span class="o">==</span> <span class="nb">dict</span><span class="p">:</span>
</span><span id="VimGolfLogParser-287"><a href="#VimGolfLogParser-287"><span class="linenos">287</span></a>                        <span class="n">parsed_result</span> <span class="o">=</span> <span class="n">VimGolfEnvResult</span><span class="o">.</span><span class="n">parse_obj</span><span class="p">(</span><span class="n">event_data</span><span class="p">)</span>
</span><span id="VimGolfLogParser-288"><a href="#VimGolfLogParser-288"><span class="linenos">288</span></a>                        <span class="bp">self</span><span class="o">.</span><span class="n">results</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">parsed_result</span><span class="p">)</span>
</span><span id="VimGolfLogParser-289"><a href="#VimGolfLogParser-289"><span class="linenos">289</span></a>        <span class="k">except</span> <span class="n">json</span><span class="o">.</span><span class="n">JSONDecodeError</span><span class="p">:</span>
</span><span id="VimGolfLogParser-290"><a href="#VimGolfLogParser-290"><span class="linenos">290</span></a>            <span class="o">...</span>
</span><span id="VimGolfLogParser-291"><a href="#VimGolfLogParser-291"><span class="linenos">291</span></a>
</span><span id="VimGolfLogParser-292"><a href="#VimGolfLogParser-292"><span class="linenos">292</span></a>    <span class="nd">@property</span>
</span><span id="VimGolfLogParser-293"><a href="#VimGolfLogParser-293"><span class="linenos">293</span></a>    <span class="k">def</span><span class="w"> </span><span class="nf">success_results</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span id="VimGolfLogParser-294"><a href="#VimGolfLogParser-294"><span class="linenos">294</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="VimGolfLogParser-295"><a href="#VimGolfLogParser-295"><span class="linenos">295</span></a><span class="sd">        The successful results of the vimgolf challenge environment.</span>
</span><span id="VimGolfLogParser-296"><a href="#VimGolfLogParser-296"><span class="linenos">296</span></a>
</span><span id="VimGolfLogParser-297"><a href="#VimGolfLogParser-297"><span class="linenos">297</span></a><span class="sd">        This property returns the successful results of the vimgolf challenge</span>
</span><span id="VimGolfLogParser-298"><a href="#VimGolfLogParser-298"><span class="linenos">298</span></a><span class="sd">        environment, which are the results in the results list where the</span>
</span><span id="VimGolfLogParser-299"><a href="#VimGolfLogParser-299"><span class="linenos">299</span></a><span class="sd">        correct attribute is True.</span>
</span><span id="VimGolfLogParser-300"><a href="#VimGolfLogParser-300"><span class="linenos">300</span></a>
</span><span id="VimGolfLogParser-301"><a href="#VimGolfLogParser-301"><span class="linenos">301</span></a><span class="sd">        Returns:</span>
</span><span id="VimGolfLogParser-302"><a href="#VimGolfLogParser-302"><span class="linenos">302</span></a><span class="sd">            list[VimGolfEnvResult]: The successful results of the vimgolf challenge environment, or an</span>
</span><span id="VimGolfLogParser-303"><a href="#VimGolfLogParser-303"><span class="linenos">303</span></a><span class="sd">            empty list if there are no successful results.</span>
</span><span id="VimGolfLogParser-304"><a href="#VimGolfLogParser-304"><span class="linenos">304</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="VimGolfLogParser-305"><a href="#VimGolfLogParser-305"><span class="linenos">305</span></a>        <span class="k">return</span> <span class="p">[</span><span class="n">it</span> <span class="k">for</span> <span class="n">it</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">results</span> <span class="k">if</span> <span class="n">it</span><span class="o">.</span><span class="n">correct</span><span class="p">]</span>
</span><span id="VimGolfLogParser-306"><a href="#VimGolfLogParser-306"><span class="linenos">306</span></a>
</span><span id="VimGolfLogParser-307"><a href="#VimGolfLogParser-307"><span class="linenos">307</span></a>    <span class="nd">@property</span>
</span><span id="VimGolfLogParser-308"><a href="#VimGolfLogParser-308"><span class="linenos">308</span></a>    <span class="k">def</span><span class="w"> </span><span class="nf">success</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span id="VimGolfLogParser-309"><a href="#VimGolfLogParser-309"><span class="linenos">309</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="VimGolfLogParser-310"><a href="#VimGolfLogParser-310"><span class="linenos">310</span></a><span class="sd">        Check if the vimgolf challenge has been solved successfully.</span>
</span><span id="VimGolfLogParser-311"><a href="#VimGolfLogParser-311"><span class="linenos">311</span></a>
</span><span id="VimGolfLogParser-312"><a href="#VimGolfLogParser-312"><span class="linenos">312</span></a><span class="sd">        This property checks if the vimgolf challenge has been solved</span>
</span><span id="VimGolfLogParser-313"><a href="#VimGolfLogParser-313"><span class="linenos">313</span></a><span class="sd">        successfully. It returns True if there are any successful results in</span>
</span><span id="VimGolfLogParser-314"><a href="#VimGolfLogParser-314"><span class="linenos">314</span></a><span class="sd">        the results list, and False otherwise.</span>
</span><span id="VimGolfLogParser-315"><a href="#VimGolfLogParser-315"><span class="linenos">315</span></a>
</span><span id="VimGolfLogParser-316"><a href="#VimGolfLogParser-316"><span class="linenos">316</span></a><span class="sd">        Returns:</span>
</span><span id="VimGolfLogParser-317"><a href="#VimGolfLogParser-317"><span class="linenos">317</span></a><span class="sd">            bool: True if the challenge has been solved successfully, False otherwise.</span>
</span><span id="VimGolfLogParser-318"><a href="#VimGolfLogParser-318"><span class="linenos">318</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="VimGolfLogParser-319"><a href="#VimGolfLogParser-319"><span class="linenos">319</span></a>        <span class="k">return</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">success_results</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">0</span>
</span><span id="VimGolfLogParser-320"><a href="#VimGolfLogParser-320"><span class="linenos">320</span></a>
</span><span id="VimGolfLogParser-321"><a href="#VimGolfLogParser-321"><span class="linenos">321</span></a>    <span class="k">def</span><span class="w"> </span><span class="nf">get_last_success_result</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span id="VimGolfLogParser-322"><a href="#VimGolfLogParser-322"><span class="linenos">322</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="VimGolfLogParser-323"><a href="#VimGolfLogParser-323"><span class="linenos">323</span></a><span class="sd">        Return the last success result in the log watcher.</span>
</span><span id="VimGolfLogParser-324"><a href="#VimGolfLogParser-324"><span class="linenos">324</span></a>
</span><span id="VimGolfLogParser-325"><a href="#VimGolfLogParser-325"><span class="linenos">325</span></a><span class="sd">        This method returns the last success result in the log watcher,</span>
</span><span id="VimGolfLogParser-326"><a href="#VimGolfLogParser-326"><span class="linenos">326</span></a><span class="sd">        which is the last result in the success_results list.</span>
</span><span id="VimGolfLogParser-327"><a href="#VimGolfLogParser-327"><span class="linenos">327</span></a>
</span><span id="VimGolfLogParser-328"><a href="#VimGolfLogParser-328"><span class="linenos">328</span></a><span class="sd">        Returns:</span>
</span><span id="VimGolfLogParser-329"><a href="#VimGolfLogParser-329"><span class="linenos">329</span></a><span class="sd">            VimGolfEnvResult: The last success result in the log watcher, or None if there is no</span>
</span><span id="VimGolfLogParser-330"><a href="#VimGolfLogParser-330"><span class="linenos">330</span></a><span class="sd">            success result.</span>
</span><span id="VimGolfLogParser-331"><a href="#VimGolfLogParser-331"><span class="linenos">331</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="VimGolfLogParser-332"><a href="#VimGolfLogParser-332"><span class="linenos">332</span></a>        <span class="n">success_results</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">success_results</span>
</span><span id="VimGolfLogParser-333"><a href="#VimGolfLogParser-333"><span class="linenos">333</span></a>        <span class="k">if</span> <span class="n">success_results</span><span class="p">:</span>
</span><span id="VimGolfLogParser-334"><a href="#VimGolfLogParser-334"><span class="linenos">334</span></a>            <span class="k">return</span> <span class="n">success_results</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
</span><span id="VimGolfLogParser-335"><a href="#VimGolfLogParser-335"><span class="linenos">335</span></a>
</span><span id="VimGolfLogParser-336"><a href="#VimGolfLogParser-336"><span class="linenos">336</span></a>    <span class="k">def</span><span class="w"> </span><span class="nf">get_best_success_result</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span id="VimGolfLogParser-337"><a href="#VimGolfLogParser-337"><span class="linenos">337</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;Return the result with the lowest score&quot;&quot;&quot;</span>
</span><span id="VimGolfLogParser-338"><a href="#VimGolfLogParser-338"><span class="linenos">338</span></a>        <span class="n">success_results</span> <span class="o">=</span> <span class="n">copy</span><span class="o">.</span><span class="n">deepcopy</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">success_results</span><span class="p">)</span>
</span><span id="VimGolfLogParser-339"><a href="#VimGolfLogParser-339"><span class="linenos">339</span></a>        <span class="k">if</span> <span class="n">success_results</span><span class="p">:</span>
</span><span id="VimGolfLogParser-340"><a href="#VimGolfLogParser-340"><span class="linenos">340</span></a>            <span class="n">success_results</span><span class="o">.</span><span class="n">sort</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="n">x</span><span class="o">.</span><span class="n">score</span><span class="p">)</span>
</span><span id="VimGolfLogParser-341"><a href="#VimGolfLogParser-341"><span class="linenos">341</span></a>            <span class="k">return</span> <span class="n">success_results</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
</span></pre></div>


            <div class="docstring"><p>Helper class that provides a standard way to create an ABC using
inheritance.</p>
</div>


                            <div id="VimGolfLogParser.__init__" class="classattr">
                                        <input id="VimGolfLogParser.__init__-view-source" class="view-source-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<div class="attr function">
            
        <span class="name">VimGolfLogParser</span><span class="signature pdoc-code condensed">()</span>

                <label class="view-source-button" for="VimGolfLogParser.__init__-view-source"><span>View Source</span></label>

    </div>
    <a class="headerlink" href="#VimGolfLogParser.__init__"></a>
            <div class="pdoc-code codehilite"><pre><span></span><span id="VimGolfLogParser.__init__-256"><a href="#VimGolfLogParser.__init__-256"><span class="linenos">256</span></a>    <span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span id="VimGolfLogParser.__init__-257"><a href="#VimGolfLogParser.__init__-257"><span class="linenos">257</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="VimGolfLogParser.__init__-258"><a href="#VimGolfLogParser.__init__-258"><span class="linenos">258</span></a><span class="sd">        Initialize the VimGolfLogParser.</span>
</span><span id="VimGolfLogParser.__init__-259"><a href="#VimGolfLogParser.__init__-259"><span class="linenos">259</span></a>
</span><span id="VimGolfLogParser.__init__-260"><a href="#VimGolfLogParser.__init__-260"><span class="linenos">260</span></a><span class="sd">        The VimGolfLogParser is initialized with an empty list of results.</span>
</span><span id="VimGolfLogParser.__init__-261"><a href="#VimGolfLogParser.__init__-261"><span class="linenos">261</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="VimGolfLogParser.__init__-262"><a href="#VimGolfLogParser.__init__-262"><span class="linenos">262</span></a>        <span class="bp">self</span><span class="o">.</span><span class="n">results</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="n">VimGolfEnvResult</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
</span></pre></div>


            <div class="docstring"><p>Initialize the VimGolfLogParser.</p>

<p>The VimGolfLogParser is initialized with an empty list of results.</p>
</div>


                            </div>
                            <div id="VimGolfLogParser.results" class="classattr">
                                <div class="attr variable">
            <span class="name">results</span><span class="annotation">: list[<a href="dataclasses.html#VimGolfEnvResult">vimgolf_gym.dataclasses.VimGolfEnvResult</a>]</span>

        
    </div>
    <a class="headerlink" href="#VimGolfLogParser.results"></a>
    
    

                            </div>
                            <div id="VimGolfLogParser.feed_line" class="classattr">
                                        <input id="VimGolfLogParser.feed_line-view-source" class="view-source-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<div class="attr function">
            
        <span class="def">def</span>
        <span class="name">feed_line</span><span class="signature pdoc-code condensed">(<span class="param"><span class="bp">self</span>, </span><span class="param"><span class="n">line</span><span class="p">:</span> <span class="nb">str</span></span><span class="return-annotation">):</span></span>

                <label class="view-source-button" for="VimGolfLogParser.feed_line-view-source"><span>View Source</span></label>

    </div>
    <a class="headerlink" href="#VimGolfLogParser.feed_line"></a>
            <div class="pdoc-code codehilite"><pre><span></span><span id="VimGolfLogParser.feed_line-264"><a href="#VimGolfLogParser.feed_line-264"><span class="linenos">264</span></a>    <span class="k">def</span><span class="w"> </span><span class="nf">feed_line</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">line</span><span class="p">:</span> <span class="nb">str</span><span class="p">):</span>
</span><span id="VimGolfLogParser.feed_line-265"><a href="#VimGolfLogParser.feed_line-265"><span class="linenos">265</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="VimGolfLogParser.feed_line-266"><a href="#VimGolfLogParser.feed_line-266"><span class="linenos">266</span></a><span class="sd">        Feed a line to the parser.</span>
</span><span id="VimGolfLogParser.feed_line-267"><a href="#VimGolfLogParser.feed_line-267"><span class="linenos">267</span></a>
</span><span id="VimGolfLogParser.feed_line-268"><a href="#VimGolfLogParser.feed_line-268"><span class="linenos">268</span></a><span class="sd">        The line should be a JSON-formatted string. The parser will attempt to</span>
</span><span id="VimGolfLogParser.feed_line-269"><a href="#VimGolfLogParser.feed_line-269"><span class="linenos">269</span></a><span class="sd">        parse the line as a JSON object, and if it is a dictionary, it will</span>
</span><span id="VimGolfLogParser.feed_line-270"><a href="#VimGolfLogParser.feed_line-270"><span class="linenos">270</span></a><span class="sd">        check if the dictionary has an &quot;event_type&quot; key with value</span>
</span><span id="VimGolfLogParser.feed_line-271"><a href="#VimGolfLogParser.feed_line-271"><span class="linenos">271</span></a><span class="sd">        &quot;vimgolf_result&quot;. If so, it will attempt to parse the value of the</span>
</span><span id="VimGolfLogParser.feed_line-272"><a href="#VimGolfLogParser.feed_line-272"><span class="linenos">272</span></a><span class="sd">        &quot;event_data&quot; key as a VimGolfEnvResult object and append it to the</span>
</span><span id="VimGolfLogParser.feed_line-273"><a href="#VimGolfLogParser.feed_line-273"><span class="linenos">273</span></a><span class="sd">        results list.</span>
</span><span id="VimGolfLogParser.feed_line-274"><a href="#VimGolfLogParser.feed_line-274"><span class="linenos">274</span></a>
</span><span id="VimGolfLogParser.feed_line-275"><a href="#VimGolfLogParser.feed_line-275"><span class="linenos">275</span></a><span class="sd">        If the line is not a valid JSON object, or if the JSON object does not</span>
</span><span id="VimGolfLogParser.feed_line-276"><a href="#VimGolfLogParser.feed_line-276"><span class="linenos">276</span></a><span class="sd">        have the correct structure, the line will be ignored.</span>
</span><span id="VimGolfLogParser.feed_line-277"><a href="#VimGolfLogParser.feed_line-277"><span class="linenos">277</span></a>
</span><span id="VimGolfLogParser.feed_line-278"><a href="#VimGolfLogParser.feed_line-278"><span class="linenos">278</span></a><span class="sd">        Args:</span>
</span><span id="VimGolfLogParser.feed_line-279"><a href="#VimGolfLogParser.feed_line-279"><span class="linenos">279</span></a><span class="sd">            line (str): The line of text to feed to the parser.</span>
</span><span id="VimGolfLogParser.feed_line-280"><a href="#VimGolfLogParser.feed_line-280"><span class="linenos">280</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="VimGolfLogParser.feed_line-281"><a href="#VimGolfLogParser.feed_line-281"><span class="linenos">281</span></a>        <span class="k">try</span><span class="p">:</span>
</span><span id="VimGolfLogParser.feed_line-282"><a href="#VimGolfLogParser.feed_line-282"><span class="linenos">282</span></a>            <span class="n">data</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">line</span><span class="o">.</span><span class="n">strip</span><span class="p">())</span>
</span><span id="VimGolfLogParser.feed_line-283"><a href="#VimGolfLogParser.feed_line-283"><span class="linenos">283</span></a>            <span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> <span class="o">==</span> <span class="nb">dict</span><span class="p">:</span>
</span><span id="VimGolfLogParser.feed_line-284"><a href="#VimGolfLogParser.feed_line-284"><span class="linenos">284</span></a>                <span class="k">if</span> <span class="n">data</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;event_type&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> <span class="o">==</span> <span class="s2">&quot;vimgolf_result&quot;</span><span class="p">:</span>
</span><span id="VimGolfLogParser.feed_line-285"><a href="#VimGolfLogParser.feed_line-285"><span class="linenos">285</span></a>                    <span class="n">event_data</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;event_data&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
</span><span id="VimGolfLogParser.feed_line-286"><a href="#VimGolfLogParser.feed_line-286"><span class="linenos">286</span></a>                    <span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">event_data</span><span class="p">)</span> <span class="o">==</span> <span class="nb">dict</span><span class="p">:</span>
</span><span id="VimGolfLogParser.feed_line-287"><a href="#VimGolfLogParser.feed_line-287"><span class="linenos">287</span></a>                        <span class="n">parsed_result</span> <span class="o">=</span> <span class="n">VimGolfEnvResult</span><span class="o">.</span><span class="n">parse_obj</span><span class="p">(</span><span class="n">event_data</span><span class="p">)</span>
</span><span id="VimGolfLogParser.feed_line-288"><a href="#VimGolfLogParser.feed_line-288"><span class="linenos">288</span></a>                        <span class="bp">self</span><span class="o">.</span><span class="n">results</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">parsed_result</span><span class="p">)</span>
</span><span id="VimGolfLogParser.feed_line-289"><a href="#VimGolfLogParser.feed_line-289"><span class="linenos">289</span></a>        <span class="k">except</span> <span class="n">json</span><span class="o">.</span><span class="n">JSONDecodeError</span><span class="p">:</span>
</span><span id="VimGolfLogParser.feed_line-290"><a href="#VimGolfLogParser.feed_line-290"><span class="linenos">290</span></a>            <span class="o">...</span>
</span></pre></div>


            <div class="docstring"><p>Feed a line to the parser.</p>

<p>The line should be a JSON-formatted string. The parser will attempt to
parse the line as a JSON object, and if it is a dictionary, it will
check if the dictionary has an "event_type" key with value
"vimgolf_result". If so, it will attempt to parse the value of the
"event_data" key as a VimGolfEnvResult object and append it to the
results list.</p>

<p>If the line is not a valid JSON object, or if the JSON object does not
have the correct structure, the line will be ignored.</p>

<h6 id="arguments">Arguments:</h6>

<ul>
<li><strong>line (str):</strong>  The line of text to feed to the parser.</li>
</ul>
</div>


                            </div>
                            <div id="VimGolfLogParser.success_results" class="classattr">
                                        <input id="VimGolfLogParser.success_results-view-source" class="view-source-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<div class="attr variable">
            <span class="name">success_results</span>

                <label class="view-source-button" for="VimGolfLogParser.success_results-view-source"><span>View Source</span></label>

    </div>
    <a class="headerlink" href="#VimGolfLogParser.success_results"></a>
            <div class="pdoc-code codehilite"><pre><span></span><span id="VimGolfLogParser.success_results-292"><a href="#VimGolfLogParser.success_results-292"><span class="linenos">292</span></a>    <span class="nd">@property</span>
</span><span id="VimGolfLogParser.success_results-293"><a href="#VimGolfLogParser.success_results-293"><span class="linenos">293</span></a>    <span class="k">def</span><span class="w"> </span><span class="nf">success_results</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span id="VimGolfLogParser.success_results-294"><a href="#VimGolfLogParser.success_results-294"><span class="linenos">294</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="VimGolfLogParser.success_results-295"><a href="#VimGolfLogParser.success_results-295"><span class="linenos">295</span></a><span class="sd">        The successful results of the vimgolf challenge environment.</span>
</span><span id="VimGolfLogParser.success_results-296"><a href="#VimGolfLogParser.success_results-296"><span class="linenos">296</span></a>
</span><span id="VimGolfLogParser.success_results-297"><a href="#VimGolfLogParser.success_results-297"><span class="linenos">297</span></a><span class="sd">        This property returns the successful results of the vimgolf challenge</span>
</span><span id="VimGolfLogParser.success_results-298"><a href="#VimGolfLogParser.success_results-298"><span class="linenos">298</span></a><span class="sd">        environment, which are the results in the results list where the</span>
</span><span id="VimGolfLogParser.success_results-299"><a href="#VimGolfLogParser.success_results-299"><span class="linenos">299</span></a><span class="sd">        correct attribute is True.</span>
</span><span id="VimGolfLogParser.success_results-300"><a href="#VimGolfLogParser.success_results-300"><span class="linenos">300</span></a>
</span><span id="VimGolfLogParser.success_results-301"><a href="#VimGolfLogParser.success_results-301"><span class="linenos">301</span></a><span class="sd">        Returns:</span>
</span><span id="VimGolfLogParser.success_results-302"><a href="#VimGolfLogParser.success_results-302"><span class="linenos">302</span></a><span class="sd">            list[VimGolfEnvResult]: The successful results of the vimgolf challenge environment, or an</span>
</span><span id="VimGolfLogParser.success_results-303"><a href="#VimGolfLogParser.success_results-303"><span class="linenos">303</span></a><span class="sd">            empty list if there are no successful results.</span>
</span><span id="VimGolfLogParser.success_results-304"><a href="#VimGolfLogParser.success_results-304"><span class="linenos">304</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="VimGolfLogParser.success_results-305"><a href="#VimGolfLogParser.success_results-305"><span class="linenos">305</span></a>        <span class="k">return</span> <span class="p">[</span><span class="n">it</span> <span class="k">for</span> <span class="n">it</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">results</span> <span class="k">if</span> <span class="n">it</span><span class="o">.</span><span class="n">correct</span><span class="p">]</span>
</span></pre></div>


            <div class="docstring"><p>The successful results of the vimgolf challenge environment.</p>

<p>This property returns the successful results of the vimgolf challenge
environment, which are the results in the results list where the
correct attribute is True.</p>

<h6 id="returns">Returns:</h6>

<blockquote>
  <p>list[VimGolfEnvResult]: The successful results of the vimgolf challenge environment, or an
  empty list if there are no successful results.</p>
</blockquote>
</div>


                            </div>
                            <div id="VimGolfLogParser.success" class="classattr">
                                        <input id="VimGolfLogParser.success-view-source" class="view-source-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<div class="attr variable">
            <span class="name">success</span>

                <label class="view-source-button" for="VimGolfLogParser.success-view-source"><span>View Source</span></label>

    </div>
    <a class="headerlink" href="#VimGolfLogParser.success"></a>
            <div class="pdoc-code codehilite"><pre><span></span><span id="VimGolfLogParser.success-307"><a href="#VimGolfLogParser.success-307"><span class="linenos">307</span></a>    <span class="nd">@property</span>
</span><span id="VimGolfLogParser.success-308"><a href="#VimGolfLogParser.success-308"><span class="linenos">308</span></a>    <span class="k">def</span><span class="w"> </span><span class="nf">success</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span id="VimGolfLogParser.success-309"><a href="#VimGolfLogParser.success-309"><span class="linenos">309</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="VimGolfLogParser.success-310"><a href="#VimGolfLogParser.success-310"><span class="linenos">310</span></a><span class="sd">        Check if the vimgolf challenge has been solved successfully.</span>
</span><span id="VimGolfLogParser.success-311"><a href="#VimGolfLogParser.success-311"><span class="linenos">311</span></a>
</span><span id="VimGolfLogParser.success-312"><a href="#VimGolfLogParser.success-312"><span class="linenos">312</span></a><span class="sd">        This property checks if the vimgolf challenge has been solved</span>
</span><span id="VimGolfLogParser.success-313"><a href="#VimGolfLogParser.success-313"><span class="linenos">313</span></a><span class="sd">        successfully. It returns True if there are any successful results in</span>
</span><span id="VimGolfLogParser.success-314"><a href="#VimGolfLogParser.success-314"><span class="linenos">314</span></a><span class="sd">        the results list, and False otherwise.</span>
</span><span id="VimGolfLogParser.success-315"><a href="#VimGolfLogParser.success-315"><span class="linenos">315</span></a>
</span><span id="VimGolfLogParser.success-316"><a href="#VimGolfLogParser.success-316"><span class="linenos">316</span></a><span class="sd">        Returns:</span>
</span><span id="VimGolfLogParser.success-317"><a href="#VimGolfLogParser.success-317"><span class="linenos">317</span></a><span class="sd">            bool: True if the challenge has been solved successfully, False otherwise.</span>
</span><span id="VimGolfLogParser.success-318"><a href="#VimGolfLogParser.success-318"><span class="linenos">318</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="VimGolfLogParser.success-319"><a href="#VimGolfLogParser.success-319"><span class="linenos">319</span></a>        <span class="k">return</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">success_results</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">0</span>
</span></pre></div>


            <div class="docstring"><p>Check if the vimgolf challenge has been solved successfully.</p>

<p>This property checks if the vimgolf challenge has been solved
successfully. It returns True if there are any successful results in
the results list, and False otherwise.</p>

<h6 id="returns">Returns:</h6>

<blockquote>
  <p>bool: True if the challenge has been solved successfully, False otherwise.</p>
</blockquote>
</div>


                            </div>
                            <div id="VimGolfLogParser.get_last_success_result" class="classattr">
                                        <input id="VimGolfLogParser.get_last_success_result-view-source" class="view-source-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<div class="attr function">
            
        <span class="def">def</span>
        <span class="name">get_last_success_result</span><span class="signature pdoc-code condensed">(<span class="param"><span class="bp">self</span></span><span class="return-annotation">):</span></span>

                <label class="view-source-button" for="VimGolfLogParser.get_last_success_result-view-source"><span>View Source</span></label>

    </div>
    <a class="headerlink" href="#VimGolfLogParser.get_last_success_result"></a>
            <div class="pdoc-code codehilite"><pre><span></span><span id="VimGolfLogParser.get_last_success_result-321"><a href="#VimGolfLogParser.get_last_success_result-321"><span class="linenos">321</span></a>    <span class="k">def</span><span class="w"> </span><span class="nf">get_last_success_result</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span id="VimGolfLogParser.get_last_success_result-322"><a href="#VimGolfLogParser.get_last_success_result-322"><span class="linenos">322</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="VimGolfLogParser.get_last_success_result-323"><a href="#VimGolfLogParser.get_last_success_result-323"><span class="linenos">323</span></a><span class="sd">        Return the last success result in the log watcher.</span>
</span><span id="VimGolfLogParser.get_last_success_result-324"><a href="#VimGolfLogParser.get_last_success_result-324"><span class="linenos">324</span></a>
</span><span id="VimGolfLogParser.get_last_success_result-325"><a href="#VimGolfLogParser.get_last_success_result-325"><span class="linenos">325</span></a><span class="sd">        This method returns the last success result in the log watcher,</span>
</span><span id="VimGolfLogParser.get_last_success_result-326"><a href="#VimGolfLogParser.get_last_success_result-326"><span class="linenos">326</span></a><span class="sd">        which is the last result in the success_results list.</span>
</span><span id="VimGolfLogParser.get_last_success_result-327"><a href="#VimGolfLogParser.get_last_success_result-327"><span class="linenos">327</span></a>
</span><span id="VimGolfLogParser.get_last_success_result-328"><a href="#VimGolfLogParser.get_last_success_result-328"><span class="linenos">328</span></a><span class="sd">        Returns:</span>
</span><span id="VimGolfLogParser.get_last_success_result-329"><a href="#VimGolfLogParser.get_last_success_result-329"><span class="linenos">329</span></a><span class="sd">            VimGolfEnvResult: The last success result in the log watcher, or None if there is no</span>
</span><span id="VimGolfLogParser.get_last_success_result-330"><a href="#VimGolfLogParser.get_last_success_result-330"><span class="linenos">330</span></a><span class="sd">            success result.</span>
</span><span id="VimGolfLogParser.get_last_success_result-331"><a href="#VimGolfLogParser.get_last_success_result-331"><span class="linenos">331</span></a><span class="sd">        &quot;&quot;&quot;</span>
</span><span id="VimGolfLogParser.get_last_success_result-332"><a href="#VimGolfLogParser.get_last_success_result-332"><span class="linenos">332</span></a>        <span class="n">success_results</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">success_results</span>
</span><span id="VimGolfLogParser.get_last_success_result-333"><a href="#VimGolfLogParser.get_last_success_result-333"><span class="linenos">333</span></a>        <span class="k">if</span> <span class="n">success_results</span><span class="p">:</span>
</span><span id="VimGolfLogParser.get_last_success_result-334"><a href="#VimGolfLogParser.get_last_success_result-334"><span class="linenos">334</span></a>            <span class="k">return</span> <span class="n">success_results</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
</span></pre></div>


            <div class="docstring"><p>Return the last success result in the log watcher.</p>

<p>This method returns the last success result in the log watcher,
which is the last result in the success_results list.</p>

<h6 id="returns">Returns:</h6>

<blockquote>
  <p>VimGolfEnvResult: The last success result in the log watcher, or None if there is no
  success result.</p>
</blockquote>
</div>


                            </div>
                            <div id="VimGolfLogParser.get_best_success_result" class="classattr">
                                        <input id="VimGolfLogParser.get_best_success_result-view-source" class="view-source-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<div class="attr function">
            
        <span class="def">def</span>
        <span class="name">get_best_success_result</span><span class="signature pdoc-code condensed">(<span class="param"><span class="bp">self</span></span><span class="return-annotation">):</span></span>

                <label class="view-source-button" for="VimGolfLogParser.get_best_success_result-view-source"><span>View Source</span></label>

    </div>
    <a class="headerlink" href="#VimGolfLogParser.get_best_success_result"></a>
            <div class="pdoc-code codehilite"><pre><span></span><span id="VimGolfLogParser.get_best_success_result-336"><a href="#VimGolfLogParser.get_best_success_result-336"><span class="linenos">336</span></a>    <span class="k">def</span><span class="w"> </span><span class="nf">get_best_success_result</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span><span id="VimGolfLogParser.get_best_success_result-337"><a href="#VimGolfLogParser.get_best_success_result-337"><span class="linenos">337</span></a><span class="w">        </span><span class="sd">&quot;&quot;&quot;Return the result with the lowest score&quot;&quot;&quot;</span>
</span><span id="VimGolfLogParser.get_best_success_result-338"><a href="#VimGolfLogParser.get_best_success_result-338"><span class="linenos">338</span></a>        <span class="n">success_results</span> <span class="o">=</span> <span class="n">copy</span><span class="o">.</span><span class="n">deepcopy</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">success_results</span><span class="p">)</span>
</span><span id="VimGolfLogParser.get_best_success_result-339"><a href="#VimGolfLogParser.get_best_success_result-339"><span class="linenos">339</span></a>        <span class="k">if</span> <span class="n">success_results</span><span class="p">:</span>
</span><span id="VimGolfLogParser.get_best_success_result-340"><a href="#VimGolfLogParser.get_best_success_result-340"><span class="linenos">340</span></a>            <span class="n">success_results</span><span class="o">.</span><span class="n">sort</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="n">x</span><span class="o">.</span><span class="n">score</span><span class="p">)</span>
</span><span id="VimGolfLogParser.get_best_success_result-341"><a href="#VimGolfLogParser.get_best_success_result-341"><span class="linenos">341</span></a>            <span class="k">return</span> <span class="n">success_results</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
</span></pre></div>


            <div class="docstring"><p>Return the result with the lowest score</p>
</div>


                            </div>
                </section>
    </main>
<script>
    function escapeHTML(html) {
        return document.createElement('div').appendChild(document.createTextNode(html)).parentNode.innerHTML;
    }

    const originalContent = document.querySelector("main.pdoc");
    let currentContent = originalContent;

    function setContent(innerHTML) {
        let elem;
        if (innerHTML) {
            elem = document.createElement("main");
            elem.classList.add("pdoc");
            elem.innerHTML = innerHTML;
        } else {
            elem = originalContent;
        }
        if (currentContent !== elem) {
            currentContent.replaceWith(elem);
            currentContent = elem;
        }
    }

    function getSearchTerm() {
        return (new URL(window.location)).searchParams.get("search");
    }

    const searchBox = document.querySelector(".pdoc input[type=search]");
    searchBox.addEventListener("input", function () {
        let url = new URL(window.location);
        if (searchBox.value.trim()) {
            url.hash = "";
            url.searchParams.set("search", searchBox.value);
        } else {
            url.searchParams.delete("search");
        }
        history.replaceState("", "", url.toString());
        onInput();
    });
    window.addEventListener("popstate", onInput);


    let search, searchErr;

    async function initialize() {
        try {
            search = await new Promise((resolve, reject) => {
                const script = document.createElement("script");
                script.type = "text/javascript";
                script.async = true;
                script.onload = () => resolve(window.pdocSearch);
                script.onerror = (e) => reject(e);
                script.src = "../search.js";
                document.getElementsByTagName("head")[0].appendChild(script);
            });
        } catch (e) {
            console.error("Cannot fetch pdoc search index");
            searchErr = "Cannot fetch search index.";
        }
        onInput();

        document.querySelector("nav.pdoc").addEventListener("click", e => {
            if (e.target.hash) {
                searchBox.value = "";
                searchBox.dispatchEvent(new Event("input"));
            }
        });
    }

    function onInput() {
        setContent((() => {
            const term = getSearchTerm();
            if (!term) {
                return null
            }
            if (searchErr) {
                return `<h3>Error: ${searchErr}</h3>`
            }
            if (!search) {
                return "<h3>Searching...</h3>"
            }

            window.scrollTo({top: 0, left: 0, behavior: 'auto'});

            const results = search(term);

            let html;
            if (results.length === 0) {
                html = `No search results for '${escapeHTML(term)}'.`
            } else {
                html = `<h4>${results.length} search result${results.length > 1 ? "s" : ""} for '${escapeHTML(term)}'.</h4>`;
            }
            for (let result of results.slice(0, 10)) {
                let doc = result.doc;
                let url = `../${doc.modulename.replaceAll(".", "/")}.html`;
                if (doc.qualname) {
                    url += `#${doc.qualname}`;
                }

                let heading;
                switch (result.doc.kind) {
                    case "function":
                        if (doc.fullname.endsWith(".__init__")) {
                            heading = `<span class="name">${doc.fullname.replace(/\.__init__$/, "")}</span>${doc.signature}`;
                        } else {
                            heading = `<span class="def">${doc.funcdef}</span> <span class="name">${doc.fullname}</span>${doc.signature}`;
                        }
                        break;
                    case "class":
                        heading = `<span class="def">class</span> <span class="name">${doc.fullname}</span>`;
                        if (doc.bases)
                            heading += `<wbr>(<span class="base">${doc.bases}</span>)`;
                        heading += `:`;
                        break;
                    case "variable":
                        heading = `<span class="name">${doc.fullname}</span>`;
                        if (doc.annotation)
                            heading += `<span class="annotation">${doc.annotation}</span>`;
                        if (doc.default_value)
                            heading += `<span class="default_value"> = ${doc.default_value}</span>`;
                        break;
                    default:
                        heading = `<span class="name">${doc.fullname}</span>`;
                        break;
                }
                html += `
                        <section class="search-result">
                        <a href="${url}" class="attr ${doc.kind}">${heading}</a>
                        <div class="docstring">${doc.doc}</div>
                        </section>
                    `;

            }
            return html;
        })());
    }

    if (getSearchTerm()) {
        initialize();
        searchBox.value = getSearchTerm();
        onInput();
    } else {
        searchBox.addEventListener("focus", initialize, {once: true});
    }

    searchBox.addEventListener("keydown", e => {
        if (["ArrowDown", "ArrowUp", "Enter"].includes(e.key)) {
            let focused = currentContent.querySelector(".search-result.focused");
            if (!focused) {
                currentContent.querySelector(".search-result").classList.add("focused");
            } else if (
                e.key === "ArrowDown"
                && focused.nextElementSibling
                && focused.nextElementSibling.classList.contains("search-result")
            ) {
                focused.classList.remove("focused");
                focused.nextElementSibling.classList.add("focused");
                focused.nextElementSibling.scrollIntoView({
                    behavior: "smooth",
                    block: "nearest",
                    inline: "nearest"
                });
            } else if (
                e.key === "ArrowUp"
                && focused.previousElementSibling
                && focused.previousElementSibling.classList.contains("search-result")
            ) {
                focused.classList.remove("focused");
                focused.previousElementSibling.classList.add("focused");
                focused.previousElementSibling.scrollIntoView({
                    behavior: "smooth",
                    block: "nearest",
                    inline: "nearest"
                });
            } else if (
                e.key === "Enter"
            ) {
                focused.querySelector("a").click();
            }
        }
    });
</script></body>
</html>