<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>protohackers Archives - ClickedyClick</title>
	<atom:link href="https://gergely.imreh.net/blog/tag/protohackers/feed/" rel="self" type="application/rss+xml" />
	<link>https://gergely.imreh.net/blog/tag/protohackers/</link>
	<description>Life in real, complex and digital.</description>
	<lastBuildDate>Sat, 24 Sep 2022 09:33:30 +0000</lastBuildDate>
	<language>en-GB</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	
	<item>
		<title>Programming challenge: Protohackers 3</title>
		<link>https://gergely.imreh.net/blog/2022/09/programming-challenge-protohackers-3/</link>
					<comments>https://gergely.imreh.net/blog/2022/09/programming-challenge-protohackers-3/#respond</comments>
		
		<dc:creator><![CDATA[Gergely Imreh]]></dc:creator>
		<pubDate>Sat, 24 Sep 2022 09:33:28 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[protohackers]]></category>
		<category><![CDATA[python]]></category>
		<guid isPermaLink="false">https://gergely.imreh.net/blog/?p=2720</guid>

					<description><![CDATA[<p>Incursion into server programming with Python and failing in a productive way.</p>
<p>The post <a href="https://gergely.imreh.net/blog/2022/09/programming-challenge-protohackers-3/">Programming challenge: Protohackers 3</a> appeared first on <a href="https://gergely.imreh.net/blog">ClickedyClick</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p><a href="https://protohackers.com/">Protohackers</a> is a server programming challenge, where various network protocols are set as a problem. It has started not so long ago, and <a href="https://protohackers.com/problem/3">the No 3. challenge</a> was just released yesterday, aiming at creating a simple (&#8220;Budget&#8221;) multi-user chat server. I thought I <s>sacrifice a decent part of my weekend</s> give it a honest try. This is the short story of trying, failing, then getting more knowledge out than I&#8217;ve expected.</p>



<p>Definitely wanted to tackle it using Python as that&#8217;s my current utility language that I want to know most about. Since the aim of Protohackers, I think, is to go from scratch, I set to use only the standard library. With some poking around documentation I ended up choosing <a href="https://docs.python.org/3/library/socketserver.html#module-socketserver">SocketServer</a> as the basis of the work. It seemed suitable, but there was a severe dearth of non-dummy code and deeper explanation. In a couple of hours I did make some progress, though, that already felt exciting:</p>



<ul class="wp-block-list"><li>Figured out (to some extent) the purpose of the server / handler parts in practice</li><li>Made things multi-user with data shared across connections</li><li>Grokked a bit the lifecycle of the requests, but definitely not fully, especially not how disconnections happen.</li></ul>



<p>Still it was working to some extent, I <em>could</em> make a server that functioned for a certain definition of &#8220;functioned&#8221;, as the logs attest:</p>



<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="1024" height="232" src="https://gergely.imreh.net/blog/wp-content/uploads/2022/09/budget-chat-server-logs-1024x232.png" alt="Console log of server messages while trying my Budget Chat Server implementation." class="wp-image-2724" srcset="https://gergely.imreh.net/blog/wp-content/uploads/2022/09/budget-chat-server-logs-1024x232.png 1024w, https://gergely.imreh.net/blog/wp-content/uploads/2022/09/budget-chat-server-logs-500x113.png 500w, https://gergely.imreh.net/blog/wp-content/uploads/2022/09/budget-chat-server-logs-768x174.png 768w, https://gergely.imreh.net/blog/wp-content/uploads/2022/09/budget-chat-server-logs-1200x272.png 1200w, https://gergely.imreh.net/blog/wp-content/uploads/2022/09/budget-chat-server-logs.png 1386w" sizes="(max-width: 1024px) 100vw, 1024px" /><figcaption>Server logs from trying my Budget Chat Server</figcaption></figure>



<span id="more-2720"></span>



<p>On the other hand, ended up in a relative dead-end, as some message ordering issues kicked in, and reliably failed the test here, not knowing much what to try next just yet:</p>



<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="836" src="https://gergely.imreh.net/blog/wp-content/uploads/2022/09/protohackers-3-failure-1024x836.png" alt="" class="wp-image-2721" srcset="https://gergely.imreh.net/blog/wp-content/uploads/2022/09/protohackers-3-failure-1024x836.png 1024w, https://gergely.imreh.net/blog/wp-content/uploads/2022/09/protohackers-3-failure-500x408.png 500w, https://gergely.imreh.net/blog/wp-content/uploads/2022/09/protohackers-3-failure-768x627.png 768w, https://gergely.imreh.net/blog/wp-content/uploads/2022/09/protohackers-3-failure-1536x1254.png 1536w, https://gergely.imreh.net/blog/wp-content/uploads/2022/09/protohackers-3-failure-1200x980.png 1200w, https://gergely.imreh.net/blog/wp-content/uploads/2022/09/protohackers-3-failure.png 1568w" sizes="(max-width: 1024px) 100vw, 1024px" /><figcaption>Testing my in-progress solution, and failing.</figcaption></figure>



<p>Since it&#8217;s a learning exercise and definitely not a competition on my part, I started to procrastinate. Not long before I&#8217;ve looked at the status of the <a href="https://protohackers.com/leaderboard">leaderboard</a>. Funnily enough, looking at the top entries, they were linking to the repositories where their solutions were! <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4a1.png" alt="💡" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h2 class="wp-block-heading">Shoulders of Giants</h2>



<p>Here&#8217;s my surprise and delight started, though. Within the first 7 entries there were 3 with Python implementations that included code! Even better, they actually covered 3 completely different ways of solving the task. Jackpot, really!</p>



<ol class="wp-block-list"><li>The <a href="https://github.com/pyxyne/protohackers/blob/9c4b26ecf0b274755856d5e1e3104bfa774a12f9/p3_chat.py">first solution</a> used pure <a href="https://docs.python.org/3/library/socket.html">sockets</a>, which is quite versatile if I&#8217;d want to go all-in on low-level networking in the future. It had quite a lot of helper code, though which makes it look like a pretty decent effort to duplicate.</li><li>The <a href="https://github.com/simon816/Protohackers-solutions/blob/f10c0f606a3688e7486d70a4914cd22e4d781e07/3/server.py">second solution</a> went with <a href="https://docs.python.org/3/library/socketserver.html">SocketServer</a> just like I&#8217;ve tried, and that is nice to dig in a bit more, given how small the whole code is. The main thing here was that I should have understood from the problem description this being a <a href="https://docs.python.org/3/library/socketserver.html#socketserver.StreamRequestHandler">Streaming</a> TCP connection case. Looks like streaming is the part that takes care of a lot of details, including the connection/disconnection that plagued me. Bam!</li><li>The <a href="https://github.com/LiraNuna/protohackers/blob/566b90aa7e17929f7d87a4fa9468cdb332bdf4ce/3%20-%20budget-chat/budget-chat.py">third solution</a> then used <a href="https://docs.python.org/3/library/asyncio.html?highlight=asyncio">asyncio</a>, to take it in a different direction again. It&#8217;s amazing how simple it all is when the relevant components and abstractions are understood.</li></ol>



<p>Which one is the most tempting solution to follow (and/or learn from)? Pure sockets are likely just a fallback option when there&#8217;s nothing else. On the SocketServer vs asyncio front however there was some useful <a href="https://stackoverflow.com/a/40177631">StackOverflow</a> discussion, even if a bit dated, coming from 2016. It pointed at the different use of threading and event loops. I guess this would make this answer a bit unsatisfying, but quite realistic: <em>learn both and know when either is applicable for your use case</em>. </p>



<h2 class="wp-block-heading">What did we learn?</h2>



<p>In the end I haven&#8217;t finished my code yet. Reading the existing solutions influences me and just adapting what others did and submit would feel like cheating (to myself). The way to resolve this is setting your own goals on top of the original challenge. Here I picked the following, and achieving these would complete things for me:</p>



<ul class="wp-block-list"><li>Use proper project structure and try out <a href="https://pdm.fming.dev/latest/">PDM</a></li><li>Figure out how to set up the project &amp; code to be testable with <a href="https://docs.pytest.org/en/7.1.x/">pytest</a> (basically grok testing of programs that run servers)</li></ul>



<p>The combination of these focuses on something akin to &#8220;going to production&#8221;, besides obviously writing the actual code, which is very much relevant to my interests.</p>



<p>So far I haven&#8217;t seen many examples of testing SocketServer, though <a href="https://github.com/python/cpython/blob/c5b750dc0b4d4e58047c9d93c635fa26b06562f7/Lib/test/test_socketserver.py">there&#8217;s Python&#8217;s own test suit</a> that could be a starting place. It has a lot of super useful helper functions (such as finding an unused port to run the server on), but overall seems a lot of boilerplate too. For asyncio I haven&#8217;t looked around yet. It being &#8220;cooler&#8221; there might be more discussion around it, but it&#8217;s by no means a given. Would be interesting to combine this with a Basic Chat client as well.</p>



<p>Another impression from today&#8217;s effort is that Python modules are documented to very varying levels. Their complexity definitely jumps when I try to go from dummy stuff to anything useful. For example here understanding the proper role and interaction of the Server and Handler parts of this multi-user environment.</p>



<p>I&#8217;m also acutely aware that my networking knowledge is very patchy regardless of doing networking-adjacent stuff for decades. It&#8217;s a very useful frontier to tackle when I have a chance.</p>



<p>Finally, <a href="https://ngrok.com/">ngrok</a> is still very cool tool, nice to be able to sit in a cafe and safely exposing a server to the internet.</p>
<p>The post <a href="https://gergely.imreh.net/blog/2022/09/programming-challenge-protohackers-3/">Programming challenge: Protohackers 3</a> appeared first on <a href="https://gergely.imreh.net/blog">ClickedyClick</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://gergely.imreh.net/blog/2022/09/programming-challenge-protohackers-3/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>

<!--
Performance optimized by W3 Total Cache. Learn more: https://www.boldgrid.com/w3-total-cache/?utm_source=w3tc&utm_medium=footer_comment&utm_campaign=free_plugin

Object Caching 20/27 objects using APC
Page Caching using Disk: Enhanced 
Lazy Loading (feed)

Served from: gergely.imreh.net @ 2026-04-10 19:23:06 by W3 Total Cache
-->