import unittest from olmocr.bench.tests import ( parse_html_tables, parse_markdown_tables, ) class TestParseHtmlTables(unittest.TestCase): def test_basic_table(self): data = parse_html_tables("""
ArXiv Old
scans
math
Tables Old
scans
Headers
&
footers
Multi
column
Long
tiny
text
Base Overall
Mistral OCR API 77.2 67.5 60.6 29.3 93.6 71.3 77.1 99.4 72.0±1.1
""")[0] print(data) self.assertTrue(data.is_rectangular) self.assertEqual(data.cell_text[0, 0], "") self.assertEqual(data.cell_text[0, 1], "ArXiv") self.assertEqual(data.left_relations[0, 0], set()) self.assertEqual(data.up_relations[0, 0], set()) self.assertEqual(data.left_relations[0, 1], {(0, 0)}) self.assertEqual(data.up_relations[1, 0], {(0, 0)}) self.assertEqual(data.heading_cells, {(0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (0, 7), (0, 8), (0, 9)}) self.assertEqual(data.top_heading_relations(1, 3), {(0, 3)}) # If there are no left headings defined, then the left most column is considered the left heading print(data.left_heading_relations(1, 3)) self.assertEqual(data.left_heading_relations(1, 3), {(1, 0)}) def test_multiple_top_headings(self): data = parse_html_tables("""
Fruit Costs in Unittest land
Fruit Type Cost
Apples $1.00
Oranges $2.00
""")[0] print(data) self.assertEqual(data.cell_text[0, 0], "Fruit Costs in Unittest land") self.assertEqual(data.cell_text[1, 0], "Fruit Type") self.assertEqual(data.cell_text[1, 1], "Cost") self.assertEqual(data.cell_text[2, 0], "Apples") self.assertEqual(data.cell_text[2, 1], "$1.00") self.assertEqual(data.cell_text[3, 0], "Oranges") self.assertEqual(data.cell_text[3, 1], "$2.00") self.assertEqual(data.up_relations[1, 0], {(0, 0)}) self.assertEqual(data.up_relations[1, 1], {(0, 0)}) self.assertEqual(data.up_relations[2, 0], {(1, 0)}) self.assertEqual(data.up_relations[2, 1], {(1, 1)}) self.assertEqual(data.top_heading_relations(1, 0), {(0, 0)}) self.assertEqual(data.top_heading_relations(1, 1), {(0, 0)}) self.assertEqual(data.top_heading_relations(2, 0), {(0, 0), (1, 0)}) self.assertEqual(data.top_heading_relations(2, 1), {(0, 0), (1, 1)}) self.assertTrue(data.is_rectangular) def test_extra_colspans(self): data = parse_html_tables("""
Fruit Costs in Unittest land
Fruit Type Cost
Apples $1.00 Hi
Oranges $2.00
""")[0] self.assertFalse(data.is_rectangular) def test_extra_rowspans(self): data = parse_html_tables("""
Fruit Costs in Unittest land
Fruit Type Cost
Apples $1.00
Oranges $2.00
""")[0] self.assertFalse(data.is_rectangular) def test_extra_rowspans_okay(self): data = parse_html_tables("""
Fruit Costs in Unittest land
Fruit Type Cost
Apples $1.00
Oranges $2.00
a
""")[0] self.assertTrue(data.is_rectangular) def test_4x4_table_with_spans(self): """Test a 4x4 table with various row spans and column spans""" data = parse_html_tables("""
Header 1 Header 2-3 Header 4
Cell A (spans 2 rows) Cell B Cell C Cell D (spans 2 rows)
Cell E-F (spans 2 cols)
Cell G Cell H-I-J (spans 3 cols)
""")[0] print(data) self.assertTrue(data.is_rectangular) # Test header row self.assertEqual(data.cell_text[0, 0], "Header 1") self.assertEqual(data.cell_text[0, 1], "Header 2-3") self.assertNotIn((0, 2), data.cell_text) # colspan=2, so that next cell is empty self.assertEqual(data.cell_text[0, 3], "Header 4") # Test first body row self.assertEqual(data.cell_text[1, 0], "Cell A (spans 2 rows)") self.assertEqual(data.cell_text[1, 1], "Cell B") self.assertEqual(data.cell_text[1, 2], "Cell C") self.assertEqual(data.cell_text[1, 3], "Cell D (spans 2 rows)") # Test second body row self.assertNotIn((2, 0), data.cell_text) self.assertEqual(data.cell_text[2, 1], "Cell E-F (spans 2 cols)") # Test third body row self.assertEqual(data.cell_text[3, 0], "Cell G") self.assertEqual(data.cell_text[3, 1], "Cell H-I-J (spans 3 cols)") # Test heading cells self.assertEqual(data.heading_cells, {(0, 0), (0, 1), (0, 3)}) self.assertEqual(data.left_heading_relations(0, 0), set()) self.assertEqual(data.left_heading_relations(1, 0), set()) self.assertEqual(data.left_heading_relations(2, 0), set()) self.assertEqual(data.left_heading_relations(3, 0), set()) self.assertEqual(data.top_heading_relations(0, 0), set()) self.assertEqual(data.top_heading_relations(0, 1), set()) self.assertEqual(data.top_heading_relations(0, 2), set()) self.assertEqual(data.top_heading_relations(0, 3), set()) self.assertEqual(data.left_heading_relations(1, 1), {(1, 0)}) self.assertEqual(data.left_heading_relations(1, 2), {(1, 0)}) self.assertEqual(data.left_heading_relations(1, 3), {(1, 0)}) self.assertEqual(data.top_heading_relations(3, 1), {(0, 1), (0, 3)}) def test_complex_multi_level_headers(self): """Test a table with multiple levels of headers and complex spanning""" data = parse_html_tables("""
Main Category
Sub Category A Sub Category B
A1 A2 A3 B1 B2 B3
Row 1 10 20 30 40 50 60
Row 2 15 25 35 45 55 65
""")[0] print("\n=== Complex Multi-Level Headers Test ===") print(data) self.assertTrue(data.is_rectangular) # Test the three-level header structure self.assertEqual(data.cell_text[0, 0], "") # Empty corner cell self.assertEqual(data.cell_text[0, 1], "Main Category") self.assertEqual(data.cell_text[1, 1], "Sub Category A") self.assertEqual(data.cell_text[1, 4], "Sub Category B") self.assertEqual(data.cell_text[2, 1], "A1") self.assertEqual(data.cell_text[2, 2], "A2") self.assertEqual(data.cell_text[2, 3], "A3") self.assertEqual(data.cell_text[2, 4], "B1") self.assertEqual(data.cell_text[2, 5], "B2") self.assertEqual(data.cell_text[2, 6], "B3") # Test data rows self.assertEqual(data.cell_text[3, 0], "Row 1") self.assertEqual(data.cell_text[3, 1], "10") self.assertEqual(data.cell_text[4, 0], "Row 2") self.assertEqual(data.cell_text[4, 1], "15") # Test heading cells - all header rows should be marked as heading cells expected_heading_cells = { (0, 0), (0, 1), # First header row (1, 1), (1, 4), # Second header row (2, 1), (2, 2), (2, 3), (2, 4), (2, 5), (2, 6), # Third header row } self.assertEqual(data.heading_cells, expected_heading_cells) # Test top heading relations for data cells # Cell (3, 1) should have relations to all three levels of headers above it top_relations_3_1 = data.top_heading_relations(3, 1) self.assertIn((0, 1), top_relations_3_1) # Main Category self.assertIn((1, 1), top_relations_3_1) # Sub Category A self.assertIn((2, 1), top_relations_3_1) # A1 # Cell (3, 4) should relate to headers in the B column top_relations_3_4 = data.top_heading_relations(3, 4) self.assertIn((0, 1), top_relations_3_4) # Main Category self.assertIn((1, 4), top_relations_3_4) # Sub Category B self.assertIn((2, 4), top_relations_3_4) # B1 # Test left heading relations self.assertEqual(data.left_heading_relations(3, 1), {(3, 0)}) # Row 1 self.assertEqual(data.left_heading_relations(4, 1), {(4, 0)}) # Row 2 def test_left_headers_with_row_spans(self): """Test a table with left-side headers that have row spans""" data = parse_html_tables("""
Quarter 1 Quarter 2
Jan Feb Mar Apr May Jun
North Sales 100 110 120 130 140 150
Cost 50 55 60 65 70 75
Profit 50 55 60 65 70 75
South Sales 200 210 220 230 240 250
Cost 100 105 110 115 120 125
Profit 100 105 110 115 120 125
""")[0] print("\n=== Left Headers with Row Spans Test ===") print(data) self.assertTrue(data.is_rectangular) # Test top headers self.assertEqual(data.cell_text[0, 2], "Quarter 1") self.assertEqual(data.cell_text[0, 5], "Quarter 2") self.assertEqual(data.cell_text[1, 2], "Jan") self.assertEqual(data.cell_text[1, 3], "Feb") self.assertEqual(data.cell_text[1, 4], "Mar") # Test left headers with row spans self.assertEqual(data.cell_text[2, 0], "North") self.assertEqual(data.cell_text[2, 1], "Sales") self.assertEqual(data.cell_text[3, 1], "Cost") self.assertEqual(data.cell_text[4, 1], "Profit") self.assertEqual(data.cell_text[5, 0], "South") self.assertEqual(data.cell_text[5, 1], "Sales") # Test data values self.assertEqual(data.cell_text[2, 2], "100") self.assertEqual(data.cell_text[3, 2], "50") self.assertEqual(data.cell_text[5, 2], "200") # Test heading cells - should include both top headers and left headers # Top headers: rows 0-1, Left headers: column 0-1 in data rows self.assertIn((0, 2), data.heading_cells) # Quarter 1 self.assertIn((1, 2), data.heading_cells) # Jan self.assertIn((2, 0), data.heading_cells) # North (left header) self.assertIn((2, 1), data.heading_cells) # Sales (left header) self.assertIn((5, 0), data.heading_cells) # South (left header) # Test left heading relations with multiple levels # Data cell (2, 2) should have both North and Sales as left headers left_relations_2_2 = data.left_heading_relations(2, 2) self.assertIn((2, 0), left_relations_2_2) # North self.assertIn((2, 1), left_relations_2_2) # Sales # Data cell (3, 2) should have North (spans from row 2) and Cost as left headers left_relations_3_2 = data.left_heading_relations(3, 2) self.assertIn((2, 0), left_relations_3_2) # North (row span) self.assertIn((3, 1), left_relations_3_2) # Cost # Data cell (5, 3) should have South and Sales as left headers left_relations_5_3 = data.left_heading_relations(5, 3) self.assertIn((5, 0), left_relations_5_3) # South self.assertIn((5, 1), left_relations_5_3) # Sales # Test top heading relations top_relations_2_2 = data.top_heading_relations(2, 2) self.assertIn((0, 2), top_relations_2_2) # Quarter 1 self.assertIn((1, 2), top_relations_2_2) # Jan def test_nested_header_groups_with_col_spans(self): """Test a complex table with nested header groups and various column spans""" data = parse_html_tables("""
Region Store 2024 Sales Data
First Half Second Half
Q1 Q2 Q3 Q4
Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
West Store A 10 11 12 13 14 15 16 17 18 19 20 21
Store B 22 23 24 25 26 27 28 29 30 31 32 33
""")[0] print("\n=== Nested Header Groups with Col Spans Test ===") print(data) self.assertTrue(data.is_rectangular) # Test nested header structure self.assertEqual(data.cell_text[0, 0], "Region") self.assertEqual(data.cell_text[0, 1], "Store") self.assertEqual(data.cell_text[0, 2], "2024 Sales Data") self.assertEqual(data.cell_text[1, 2], "First Half") self.assertEqual(data.cell_text[1, 8], "Second Half") self.assertEqual(data.cell_text[2, 2], "Q1") self.assertEqual(data.cell_text[2, 5], "Q2") self.assertEqual(data.cell_text[2, 8], "Q3") self.assertEqual(data.cell_text[2, 11], "Q4") self.assertEqual(data.cell_text[3, 2], "Jan") self.assertEqual(data.cell_text[3, 7], "Jun") self.assertEqual(data.cell_text[3, 13], "Dec") # Test data rows self.assertEqual(data.cell_text[4, 0], "West") self.assertEqual(data.cell_text[4, 1], "Store A") self.assertEqual(data.cell_text[4, 2], "10") self.assertEqual(data.cell_text[5, 1], "Store B") self.assertEqual(data.cell_text[5, 2], "22") # Test all header cells are marked self.assertIn((0, 0), data.heading_cells) # Region self.assertIn((0, 1), data.heading_cells) # Store self.assertIn((0, 2), data.heading_cells) # 2024 Sales Data self.assertIn((1, 2), data.heading_cells) # First Half self.assertIn((2, 2), data.heading_cells) # Q1 self.assertIn((3, 2), data.heading_cells) # Jan # Test multiple top heading relations for a data cell # Cell (4, 2) - January data for Store A should have all 4 levels of headers top_relations_4_2 = data.top_heading_relations(4, 2) self.assertIn((0, 2), top_relations_4_2) # 2024 Sales Data self.assertIn((1, 2), top_relations_4_2) # First Half self.assertIn((2, 2), top_relations_4_2) # Q1 self.assertIn((3, 2), top_relations_4_2) # Jan # Cell (4, 7) - June data should relate to Q2 and First Half top_relations_4_7 = data.top_heading_relations(4, 7) self.assertIn((0, 2), top_relations_4_7) # 2024 Sales Data self.assertIn((1, 2), top_relations_4_7) # First Half self.assertIn((2, 5), top_relations_4_7) # Q2 self.assertIn((3, 7), top_relations_4_7) # Jun # Cell (4, 13) - December data should relate to Q4 and Second Half top_relations_4_13 = data.top_heading_relations(4, 13) self.assertIn((0, 2), top_relations_4_13) # 2024 Sales Data self.assertIn((1, 8), top_relations_4_13) # Second Half self.assertIn((2, 11), top_relations_4_13) # Q4 self.assertIn((3, 13), top_relations_4_13) # Dec # Test left heading relations # Store B row that says "22" should relate to just West left_relations_5_2 = data.left_heading_relations(5, 2) self.assertEqual(data.cell_text[5, 2], "22") self.assertIn((4, 0), left_relations_5_2) self.assertEqual(len(left_relations_5_2), 1) # But of the left headings themselves at the top, January, should have both Region and Store self.assertEqual(data.left_heading_relations(3, 2), {(0, 0), (0, 1)}) def test_large_real_table(self): html = """
Grupo Ocupacional Classe Ocupacional Superior Médio Baixo Interior Ínfimo Total
N (1.000s) % N (1.000s) % N (1.000s) % N (1.000s) % N (1.000s) % N (1.000s) %
Empregadores A-1 Empregadores (> 10) 608 67,3 185 20,4 86 9,6 16 1,8 8 0,9 903 100
A-2 Empregadores (<= 10) 1.555 36,9 1.107 26,3 1.036 24,7 341 8,1 171 4,1 4.213 100
Total 2.162 42,3 1.292 25,3 1.126 22,0 357 7,0 179 3,5 5.116 100
Profissionais C Profissionais Autônomos 1.643 21,7 1.513 20,0 2.073 27,4 1.225 16,2 1.108 14,7 7.562 100
D Profissionais Assalariados 4.438 13,3 6.030 18,0 11.550 34,5 7.027 21,0 4.389 13,1 33.434 100
Total 6.081 14,8 7.543 18,4 13.623 33,2 8.252 20,1 5.497 13,4 40.995 100
Massa Não-Agrícola F Trabalhadores Autônomos 657 3,5 1.754 9,2 5.561 29,2 5.271 27,7 5.788 30,4 19.030 100
G Trabalhadores Assalariados 282 0,7 1.657 4,3 10.363 27,1 13.002 34,0 12.968 33,9 38.272 100
I Trabalhadores Domésticos 10 0,1 104 1,6 977 14,7 1.810 27,3 3.733 56,3 6.633 100
Total 948 1,5 3.515 5,5 16.901 26,4 20.083 31,4 22.489 35,2 63.936 100
Massa Agrícola H-1 Proprietários Conta Própria 188 2,0 364 3,8 1.387 14,4 1.889 19,7 5.779 60,2 9.608 100
H-2 Trabalhadores Autônomos 5 0,5 14 1,5 72 7,6 152 16,1 703 74,3 946 100
H-3 Trabalhadores Assalariados 17 0,2 58 0,6 794 8,4 2.260 23,9 6.322 66,9 9.451 100
Total 210 1,0 436 2,2 2.253 11,3 4.301 21,5 12.805 64,0 20.005 100
Não-remunerados Não-remunerados Não-Agrícolas 13 6,8 16 8,1 28 14,0 22 10,9 119 60,2 198 100
Não-remunerados Agrícolas 5 0,1 13 0,3 59 1,6 352 9,4 3.302 88,5 3.731 100
Sem Ocupação Com Renda 1.567 6,0 2.330 8,9 5.395 20,7 6.821 26,2 9.964 38,2 26.078 100
Sem Ocupação Sem Renda 8.094 100 8.094 100
Ignorados 177 10,3 202 11,8 364 21,1 337 19,6 640 37,2 1.720 100
""" data = parse_html_tables(html)[0] self.assertTrue(data.is_rectangular) def test_non_rect(self): html = """\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
ModelAvg FLOP×1023Dev BenchmarksHeld-out Evals
MMLUARCCHSwagWinoGNQDROPAGIEvalGSM8KMMLUPRO
Open-weight models
Llama 2 13B51.01.655.767.383.974.938.445.641.528.123.9
Mistral 7B56.6n/a63.578.383.177.737.251.847.340.130.0
Llama 3.1 8B59.77.266.979.581.676.633.956.451.356.534.7
Mistral Nemo 12B64.9n/a69.585.285.681.539.769.254.762.136.7
Gemma 2 9B66.34.470.689.587.378.838.063.057.370.142.0
Qwen 2.5 7B67.28.274.489.589.774.229.955.863.781.545.8
Qwen 2.5 14B71.516.079.394.094.080.037.351.571.083.452.8
Models with partially available data
StableLM 2 12B60.22.962.481.984.577.737.655.550.962.029.3
Zamba 2 7B63.7n/c68.592.289.479.636.551.755.567.232.8
Fully-open models
Amber 7B32.50.524.744.974.565.518.726.121.84.811.7
OLMo 7B35.41.028.346.478.168.524.827.323.79.212.1
MAP Neo 7B47.92.158.078.472.869.228.939.445.812.525.9
OLMo 0424 7B49.81.054.366.980.173.629.650.043.927.722.1
DCLM 7B55.21.064.479.882.377.328.839.347.546.131.3
OLMo 2 7B61.21.863.779.883.877.236.960.850.467.531.0
OLMo 2 13B66.84.667.583.586.481.546.770.754.275.135.1
""" data = parse_html_tables(html)[0] self.assertFalse(data.is_rectangular) def test_two_non_rect(self): html = """## GAME-BY-GAME LEADERS \u00bb\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
DateOpponentPointsReboundsAssistsStealsBlocks
Nov. 11Fort WayneHannahs (23)Kingsley (9)Macon (5)Macon (4)Kingsley (7)
Nov. 14Southern IllinoisHannahs (19)Kingsley (7)Beard (6)Seven Players (1)Kingsley (3)
Nov. 18UT ArlingtonBarford (17)Three Players (6)Four Players (2)Barford (3)Kingsley (4)
Nov. 22at MinnesotaHannahs (20)Three Players (5)Three Players (3)Watkins (3)Kingsley (3)
Nov. 28Mount Saint Mary'sBarford (16)Kingsley (11)Hannahs (4)Hannahs (2)Kingsley (4)
Dec. 1Stephen F. AustinHannahs (15)Watkins (7)Macon (5)Beard (4)Jones (1)
Dec. 3Austin PeayMacon (14)Two Players (7)Kingsley (5)Two Players (2)Two Players (3)
Dec. 6HoustonTwo Players (17)Kingsley (9)Watkins (4)Beard (2)Two Players (2)
Dec. 10North Florida----------
Dec. 17Texas*----------
Dec. 20North Dakota State----------
Dec. 22Sam Houston State#----------
Dec. 29Florida*----------
Jan. 3at Tennessee*----------
Jan. 7at Kentucky*----------
Jan. 10Mississippi State*----------
Jan. 14Missouri*----------
Jan. 17at Texas A&M*----------
Jan. 21LSU*----------
Jan. 24at Vanderbilt*----------
Jan. 28at Oklahoma State%----------
Feb. 1Alabama*----------
Feb. 4at Missouri*----------
Feb. 7Vanderbilt*----------
Feb. 11at LSU*----------
Feb. 15at South Carolina*----------
Feb. 18Ole Miss*----------
Feb. 22Texas A&M*----------
Feb. 25at Auburn*----------
March 1at Florida*----------
March 4Georgia*----------
\n\n* Lone Star Shootout (Houston, Texas) | # at Verizon Arena (North Little Rock, Ark.) | % Big12/SEC Challenge | * SEC Game\n\n## MISCELLANEOUS TEAM STATS \u00bb\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
DateOpponentW/LPoints In PaintPts Off Turnovers2nd Chance PtsFast Break Pts
Ark.Opp.Diff.Ark.Opp.Diff.Ark.Opp.Diff.
Nov. 11Fort WayneW5222+301012+4921-12
Nov. 14Southern IllinoisW3028+22517+4910-1
Nov. 18UT ArlingtonW4228+14820-12118+3
Nov. 22at MinnesotaL4638+81126-151113-2
Nov. 28Mount Saint Mary'sW4834+141810+8136+7
Dec. 1Stephen F. AustinW3628+82924+5129+3
Dec. 3Austin PeayW5240+12258+172610+16
Dec. 6HoustonW383801519-4139+4
Dec. 10North Florida--------------------
Dec. 17Texas*--------------------
Dec. 20North Dakota State--------------------
Dec. 22Sam Houston State#--------------------
Dec. 29Florida*--------------------
Jan. 3at Tennessee*--------------------
Jan. 7at Kentucky*--------------------
Jan. 10Mississippi State*--------------------
Jan. 14Missouri*--------------------
Jan. 17at Texas A&M*--------------------
Jan. 21LSU*--------------------
Jan. 24at Vanderbilt*--------------------
Jan. 28at Oklahoma State%--------------------
Feb. 1Alabama*--------------------
Feb. 4at Missouri*--------------------
Feb. 7Vanderbilt*--------------------
Feb. 11at LSU*--------------------
Feb. 15at South Carolina*--------------------
Feb. 18Ole Miss*--------------------
Feb. 22Texas A&M*--------------------
Feb. 25at Auburn*--------------------
March 1at Florida*--------------------
March 4Georgia*--------------------
TOTALS7-1326210+78163126+3710496+8
13846+92
\n\n* Lone Star Shootout (Houston, Texas) | # at Verizon Arena (North Little Rock, Ark.) | % Big12/SEC Challenge | * SEC Game\n\n**The #Fastest40 Just Got Faster** \u2014 **13**""" data = parse_html_tables(html)[0] self.assertTrue(data.is_rectangular) data = parse_html_tables(html)[1] self.assertFalse(data.is_rectangular)