From 529a70e01b1f6d784ef0192850b9b5765b0787b2 Mon Sep 17 00:00:00 2001 From: Kimiyuki Onaka Date: Tue, 19 Mar 2019 21:05:51 +0900 Subject: [PATCH] #380: fix AtCoderProblem.get_input_format() --- onlinejudge/service/atcoder.py | 22 +++++++------ tests/service_atcoder.py | 57 ++++++++++++++++++++++++++++++++-- 2 files changed, 68 insertions(+), 11 deletions(-) diff --git a/onlinejudge/service/atcoder.py b/onlinejudge/service/atcoder.py index f8a11f50..dce0f281 100644 --- a/onlinejudge/service/atcoder.py +++ b/onlinejudge/service/atcoder.py @@ -496,15 +496,19 @@ def get_input_format(self, session: Optional[requests.Session] = None) -> Option # parse soup = bs4.BeautifulSoup(resp.content.decode(resp.encoding), utils.html_parser) - for h3 in soup.find_all('h3'): - if h3.string in ('入力', 'Input'): - tag = h3 - for _ in range(3): - tag = utils.next_sibling_tag(tag) - if tag is None: - break - if tag.name in ('pre', 'blockquote'): - return tag.decode_contents(formatter='html') + for h3 in soup.find_all('h3', text=re.compile(r'^(入力|Input)$')): + if h3.parent.name == 'section': + section = h3.parent + else: + section = h3.find_next_sibling('section') + if section is None: + section = soup.find(class_='io-style') + if section is None: + log.warning('
tag not found. something wrong') + return None + pre = section.find('pre') + if pre is not None: + return pre.decode_contents(formatter=None) return None def get_available_languages(self, session: Optional[requests.Session] = None) -> List[Language]: diff --git a/tests/service_atcoder.py b/tests/service_atcoder.py index f5768254..15f3d5f2 100644 --- a/tests/service_atcoder.py +++ b/tests/service_atcoder.py @@ -177,6 +177,26 @@ def test_get_source_code(self): class AtCoderProblemGetInputFormatTest(unittest.TestCase): def test_normal(self): + """ + .. code-block:: html + +
+
+
+

入力

+

入力は以下の形式で標準入力から与えられる。

+
+                            N
+                        
+
+
+
+ ... +
+ ... +
+ """ + self.assertEqual(AtCoderProblem.from_url('https://beta.atcoder.jp/contests/agc001/tasks/agc001_d').get_input_format(), 'N M\r\nA_1 A_2 ... A_M\r\n') self.assertEqual(AtCoderProblem.from_url('https://beta.atcoder.jp/contests/agc002/tasks/agc002_d').get_input_format(), '\r\nN M\r\na_1 b_1\r\na_2 b_2\r\n:\r\na_M b_M\r\nQ\r\nx_1 y_1 z_1\r\nx_2 y_2 z_2\r\n:\r\nx_Q y_Q z_Q\r\n') self.assertEqual(AtCoderProblem.from_url('https://beta.atcoder.jp/contests/agc003/tasks/agc003_d').get_input_format(), 'N\r\ns_1\r\n:\r\ns_N\r\n') @@ -186,8 +206,41 @@ def test_normal(self): self.assertEqual(AtCoderProblem.from_url('https://beta.atcoder.jp/contests/arc083/tasks/arc083_a').get_input_format(), 'A B C D E F\r\n') def test_old_problem(self): - # https://github.com/kmyk/online-judge-tools/issues/380 - pass + """ + :note: https://github.com/kmyk/online-judge-tools/issues/380 + + .. code-block:: html + +

入力

+
+ 入力は以下の形式で与えられる。 +
+                    N
+                
+
+ """ + + self.assertEqual(AtCoderProblem.from_url('https://atcoder.jp/contests/arc001/tasks/arc001_1').get_input_format(), '\r\nN\r\nc_1c_2c_3…c_N\r\n') + self.assertEqual(AtCoderProblem.from_url('https://atcoder.jp/contests/arc002/tasks/arc002_3').get_input_format(), '\r\nN\r\nc_{1}c_{2}...c_{N}\r\n') + self.assertEqual(AtCoderProblem.from_url('https://atcoder.jp/contests/arc034/tasks/arc034_4').get_input_format(), '\r\nA B C\r\na_1 a_2 .. a_A\r\nb_1 b_2 .. b_B\r\n') + + def test_dwacon_problem(self): + """ + :note: https://github.com/kmyk/online-judge-tools/issues/142 + + .. code-block:: html + +

入力

+

入力は以下の形式で標準入力から与えられる。

+
+
+                    N
+                
+
+ """ + + self.assertEqual(AtCoderProblem.from_url('https://atcoder.jp/contests/dwacon2018-final/tasks/dwacon2018_final_a').get_input_format(), '\r\nH M S\r\nC_1 C_2\r\n') + self.assertEqual(AtCoderProblem.from_url('https://atcoder.jp/contests/dwacon2018-final/tasks/dwacon2018_final_b').get_input_format(), '\r\nN K\r\nv_1 ... v_N\r\n') if __name__ == '__main__':