Let's face it, Polygon is horrible

Revision en2, by purplesyringa, 2021-05-20 21:18:43

image

Polygon is not world's greatest evil. Polygon doesn't even have a particular defect that makes it horrible. You can't say what's exactly wrong with Polygon. Polygon seems to work, it seems like every feature is supported, but if you touch it here it will fall apart, and if you touch it there a problem (pun not intended) will appear. Or not, depending on your luck. Polygon is like PHP. For those who haven't read the famous rant, I'll cite it for you:

I can't even say what's wrong with PHP, because-- okay. Imagine you have uh, a toolbox. A set of tools. Looks okay, standard stuff in there.

You pull out a screwdriver, and you see it's one of those weird tri-headed things. Okay, well, that's not very useful to you, but you guess it comes in handy sometimes.

You pull out the hammer, but to your dismay, it has the claw part on both sides. Still serviceable though, I mean, you can hit nails with the middle of the head holding it sideways.

You pull out the pliers, but they don't have those serrated surfaces; it's flat and smooth. That's less useful, but it still turns bolts well enough, so whatever.

And on you go. Everything in the box is kind of weird and quirky, but maybe not enough to make it completely worthless. And there's no clear problem with the set as a whole; it still has all the tools.

Now imagine you meet millions of carpenters using this toolbox who tell you “well hey what's the problem with these tools? They're all I've ever used and they work fine!” And the carpenters show you the houses they've built, where every room is a pentagon and the roof is upside-down. And you knock on the front door and it just collapses inwards and they all yell at you for breaking their door.

That's what's wrong with PHP.

Open polygon.codeforces.com and sign in. We see a table with a bunch of problems. Say I want to open all my problems and check the translations, or something else, it doesn't matter. I open all the problems in new tabs, that is, I ctrl-click the Continue link. What happens? -- right, half of the problems are opened and the other half shows me 'You should select a working copy before visit edit pages' in red. Interestingly, if you don't open all the tabs at once but open them one by one with a two seconds interval between that, Polygon won't raise errors.

Do you know why this happens? This is not documented so we can only speculate that, but I've got a theory. In fact, this happens on Codeforces too. Originally, (most parts of) Polygon and Codeforces were Java applets/programs. The user launched the program which stored information about the current session, showed the necessary menus, and so on. Then Mike decided to switch to HTML5, but he didn't want to rewrite the code a bit, so he used a giiiiant hack. Namely, each browser session is tied to a session on the server, and the information about which page the user is currently on and what he can do on that page is stored on the server. Therefore, if you open two tabs on Codeforces or Polygon, the server doesn't understand what page you are on and what's the state of your session. When you open two problems on Polygon concurrently, Polygon tries to perform two problem-read actions on a single session which fails as expected. On Codeforces, this comes out when you try to open some deleted post--Codeforces redirects you to the last page you viewed.

Whatever, let's open some problem. We see a huge menu with lots of options. Clear as mud. Let's run through the list of pages at the top menu.

Statement. For some reason we see 'Encoding: UTF-8'. The question is, actually, why the heck would we use anything other than UTF-8 in the 21st century? I'm 90% sure that at least one of Codeforces scripts will fail if the encoding is not in UTF-8. This option is probably for other judges, but anyway if you using anything other than UTF-8 the problem won't be universal, it will work on some judges and crash on others. The next one is my favorite table layout with a bunch of fields for all occasions, and a few more fields hidden behind checkboxes. Of course all these fields are in latex, while everything else on Codeforces uses Markdown. So you have to switch between one format and another, even though Markdown can easily be transformed into latex (not the other way round though). Even worse, there are no standards and there is no documentation. For example, it is not clear how to insert a picture. Could you guess this? \begin{center} \includegraphics[scale=0.15]{example.png} \end{center} Okay, it seems to work, you probably understand what it means and the options make sense. But let's face it, it takes quite a while to write out and even then you'll be wondering if there's an easier way to resize the images or something. In Markdown, ![](example.png) is much shorter and much more obvious. We could even (ab)use Markdown syntax to add legends: ![legend](example.png). Another point that would be nice to improve is to agree on is how to spell out big-O notation. Half of the problemsetters use \mathcal{O}, another half simply uses O which looks different. Finally there is a checkbox 'Render fomulas using MathJax' at the end (and what if you don't render fomulas via MathJax? Will they be rendered on the server, or not at all?) Yeah, I also so much enjoy links that are not such: 'Edit with Preview' is a button, not a link, so you won't be able to open it in another tab.

Okay, let's move on. Then we have 'Files'. Wait, weren't the ones in the Statement tab files too?.. In fact, Polygon has several groups of files of different types. There are those that are added to the statements. Then there are Resource Files that seem to contain something related to statements: problem.tex, statements.ftl, tutorial.tex. Screw you, these are Freemarker templates, not statements, because Mike decided to call them that. This probably makes sense once you consider the files are named so in packages, but that's absolutely unintuitive before you get a grasp of the internals of Polygon. Then there are Source Files -- finally code! testlib.h, however, lies in Resource Files. Isn't it related to code too? Nah it's fine; it's not even surprising, because Source Files a) does not contain all sources, b) contains not only sources. Oh, one more point: 'Language' is not just about programming languages, but about compilers too. For C and C++, GCC is hardcoded, clang is not supported (but MSVC is. But only for C++). And after the list of files go Attachments. I have no idea what it is and what directory they go to, and whether there is a problem that uses them at all.

Then we have checkers. I won't really focus on them, the only thing that confuses me is the std:: prefix, which is used exactly once throughout the entire Polygon in a single line in this tab. Even in the 'select' list, nothing starts with std::. There is also no way to glance at the source code of the checker you are interested in, because they are not hosted in any repository on GitHub or elsewhere. Further there is a list of checker tests. For each test you specify the input and output data and the expected verdict. It's unclear why anyone would want to ensure that the verdict is CRASHED though.

Validators. There are no std validators here, although it would seem that simple ones could be written, or even generated from a simple description or even from the statement. Figuring out why validator tests have testgroups is left as an exercise for the reader.

Tests, finally! Tests are, obviosly, a set of input and output stored in files. Then Polygon supports test generators, the configs for which have to be stored somewhere. For this there is a so-called Script. You write commands to launch generators there, for example gen_seq 9901 10000 1 100 > 5. The > indicates that the number after it is the number of the test. Here, naturally, a question arises -- we configured the content of the test and its ID, but it would be nice to also indicate the testgroup and the score. How to do this? This must be specified separately in the configuration of each test, but what if you have a lot of tests? Nah, you won't like it. There is a hack, which, as far as I know, is not documented anywhere, but polygon-cli uses it in some situations. Test configuration can be embedded into this very script in a special format, but no one knows how to do it, there is no documentation (just as for the entire polygon). Whatever, let's say we have an ICPC-style contest and groups and points are not needed, but there are a lot of tests. You probably don't want to generate them by hand or write a giant script manually. In this case, you can make a (drum roll) script template! That is, you write code in Freemarker language that generates a script which is a list of commands for generating tests, which is then interpreted by a polygon. But! no developer wants to spend time designing good architecture, so your Freemarker template doesn't simply run, instead it runs and then gets replaced with its output. That is, you write a beautiful template, click 'Run script' -- and your entire template is replaced with a huge genereated script. Found a typo and want to fix your template? -- screw you, you'd better saved it somewhere. By the way, in addition to generators, Polygon allows you to upload your tests from an archive. Of course, as soon as the number of tests becomes greater than 200-300, Polygon passes away, that is, the archive is half loaded and half loading-in-progress-maybe, the tests are being added in background, and you cannot stop this process, you have to wait. Then the interface itself starts to hang, you have to delete your entire working copy in order to work on the task further (maybe the tests are handled in $$$\mathcal{O}(n^2)$$$? lol).

Stress. I won't comment on this one because I did not use it.

Solution files. I have only one question here: aren't Solution files also Source files, why are they stored separately at all? Really, why is everything stored separately and you always have to recall what is to be accessed from which tab?

Invocations. First, they don't always work. That is, you click 'Want to run solutions?', choose something, run the program and then you see that the invocation has not appeared on the list. You try again -- it doesn't work. Then you give up and try to rejudge an older solution, and it works. You return and 'Want to run solutions?' magically starts to work. But then Rejudge of the old invocation breaks. Yet it works on another solution. Screw you, you will never understand what's wrong. Then you can see the actual results of Invocations. Polygon shows us: solution tag (that is, the expected verdict), number and group of tests, verdict, running time, memory used (0 kilobytes, how's that?), input, output, correct answer, error stream, checker comment, code output and source. A paradise for a problemsetter, huh? Screw you. For input, output, correct answer, error stream, and checker comment, Polygon only shows the first 255 bytes (why not 256? Probably Polygon is partially written in Pascal, haha). This means that you won't be able to debug the solution on the server in any way.

Issues. Jira or GitHub issues on steroids but the other way round. They look awful, but at least they work, thanks for that.

Packages. There are so-called packages and a button to create a package -- standard or full. Which of the two types is needed for Codeforces? I think it's 'full', but you can't figure that out before creating the first package, because the difference between standard and full packages is only described in the list of packages when you hover over the link to the generated package, and this list is empty at first.

Now let's take a look at Polygon version control system. The system seems to be copied either from cvs or from git, I don't know. It has linear history. There are revisions. A list of changes in each revision and a comment to the revision are stored. There is a button that says 'Commit Changes', which obviously commits changes. And then there is a button saying 'Update working copy' which does who knows what. Apparently it is akin to git reset --hard, that is, it replaces the local version with the upstream version. Naturally, 'Currently Polygon doesn't support conflicts resolving.' is written in small font, so if you had a bunch of changes and accidentally clicked the wrong button, I'm sorry for you. That hints that you'd better save as often as possible just like you press Ctrl+S every minute, right? Nah, screw you. Polygon VCS doesn't support branches, everyone works on trunk, so if two people work on a problem you are doomed. If you're working at once and commit at once, you will have to merge everything manually, if you notice conflicts at all. Yeah, and if you commit an erroneous version, another person may accidentally update to it. It is also possible to generate a package for an erroneous version accidentally.

And then a question arises: what is a package? The problem is that the paths to the files mentioned in the changelog are missing from the package. How to download or upload files at those paths is unclear too. Why is that? Apparently Mike was too lazy to generate an adequate structure and had NIH syndrome, so he came up with his own format. So now there is Polygon format that is only used by Polygon internally (and which we only see in the changelog), and there is the classic problem.xml format. You want to manually correct polygon data? Screw you, use its UI. Want to add a couple of lines to problem.xml? Screw you, use Mike's converter, which generates a package in 5 minutes, and then you have to check the generated package in the same amount of time. Want to upload a problem in problem.xml format to Polygon? Screw you.

I'll stop here. Polygon also has infrastructural and security problems, problems with trust and Codeforces integration, problems with automation and API, and much more, but that's a whole 'nother story.


Polygon is much better than every other problem preparation tool. Which does not imply it is not horrible. We have to choose the least evil, but that doesn't mean we don't deserve a better tool.

Agreed?

Tags #polygon, #problem

History

 
 
 
 
Revisions
 
 
  Rev. Lang. By When Δ Comment
ru6 Russian purplesyringa 2021-05-20 21:19:01 48
en2 English purplesyringa 2021-05-20 21:18:43 48
en1 English purplesyringa 2021-05-20 20:59:59 14371 Initial revision for English translation
ru5 Russian purplesyringa 2021-05-20 20:21:29 24
ru4 Russian purplesyringa 2021-05-20 20:20:43 0 (опубликовано)
ru3 Russian purplesyringa 2021-05-20 20:12:26 16
ru2 Russian purplesyringa 2021-05-20 20:11:54 91
ru1 Russian purplesyringa 2021-05-20 20:10:59 14422 Первая редакция (сохранено в черновиках)