
import os
import tempfile
from pathlib import Path
from unittest import TestCase

import pyarrow as pa
import pytest

from datasets.arrow_dataset import Dataset
from datasets.arrow_reader import ArrowReader, BaseReader, FileInstructions, ReadInstruction, make_file_instructions
from datasets.info import DatasetInfo
from datasets.splits import NamedSplit, Split, SplitDict, SplitInfo

from .utils import assert_arrow_memory_doesnt_increase, assert_arrow_memory_increases


class 					a_					(_a      ):




       def 							__UpperCamelCase    (       self				,				snake_case_				,				snake_case_=False					):
         _lowerCAmelCase    :					Dict							=   (
             filename_skip_take["""filename"""],
             filename_skip_take["""skip"""] if """skip""" in filename_skip_take else None,
             filename_skip_take["""take"""] if """take""" in filename_skip_take else None,
         )
         open(os.path.join(snake_case_					)				,				"""wb"""					).close()
         _lowerCAmelCase    :					Any							=   pa.Table.from_pydict({"""filename""": [Path(snake_case_					).name] * 1_0_0}					)
         if take == -1:
           _lowerCAmelCase    :					Union[str, Any]							=   len(snake_case_					) - skip
         if skip is not None and take is not None:
           _lowerCAmelCase    :					Any							=   pa_table.slice(snake_case_				,				snake_case_					)
         return pa_table



class 					a_					(_a      ):




       def 							__UpperCamelCase    (       self					):
         _lowerCAmelCase    :					Any							=   """my_name"""
         _lowerCAmelCase    :					List[str]							=   SplitInfo(name="""train"""				,				num_examples=1_0_0					)
         _lowerCAmelCase    :					List[Any]							=   SplitInfo(name="""test"""				,				num_examples=1_0_0					)
         _lowerCAmelCase    :					int							=   [train_info, test_info]
         _lowerCAmelCase    :					Union[str, Any]							=   SplitDict()
         split_dict.add(snake_case_					)
         split_dict.add(snake_case_					)
         _lowerCAmelCase    :					Optional[Any]							=   DatasetInfo(splits=snake_case_					)

         with tempfile.TemporaryDirectory() as tmp_dir:
           _lowerCAmelCase    :					List[Any]							=   ReaderTest(snake_case_				,				snake_case_					)

           _lowerCAmelCase    :					int							=   """test[:33%]"""
           _lowerCAmelCase    :					Union[str, Any]							=   Dataset(**reader.read(snake_case_				,				snake_case_				,				snake_case_					)					)
           self.assertEqual(dset["""filename"""][0]				,				f'{name}-test'					)
           self.assertEqual(dset.num_rows				,				3_3					)
           self.assertEqual(dset.num_columns				,				1					)

           _lowerCAmelCase    :					Any							=   ["""train""", """test[:33%]"""]
           _lowerCAmelCase    :					List[Any]							=   [Split.TRAIN, ReadInstruction.from_spec("""test[:33%]"""					)]
           for instructions in [instructionsa, instructionsa]:
             _lowerCAmelCase    :					Union[str, Any]							=   [reader.read(snake_case_				,				snake_case_				,				snake_case_					) for instr in instructions]
             _lowerCAmelCase    :					Tuple							=   (Dataset(**snake_case_					) for dataset_kwargs in datasets_kwargs)
             self.assertEqual(train_dset["""filename"""][0]				,				f'{name}-train'					)
             self.assertEqual(train_dset.num_rows				,				1_0_0					)
             self.assertEqual(train_dset.num_columns				,				1					)
             self.assertIsInstance(train_dset.split				,				snake_case_					)
             self.assertEqual(str(train_dset.split					)				,				"""train"""					)
             self.assertEqual(test_dset["""filename"""][0]				,				f'{name}-test'					)
             self.assertEqual(test_dset.num_rows				,				3_3					)
             self.assertEqual(test_dset.num_columns				,				1					)
             self.assertIsInstance(test_dset.split				,				snake_case_					)
             self.assertEqual(str(test_dset.split					)				,				"""test[:33%]"""					)
             del train_dset, test_dset




       def 							__UpperCamelCase    (       self					):
         _lowerCAmelCase    :					str							=   """my_name"""
         _lowerCAmelCase    :					List[str]							=   SplitInfo(name="""train"""				,				num_examples=1_0_0_0				,				shard_lengths=[1_0_0] * 1_0					)
         _lowerCAmelCase    :					Optional[int]							=   [train_info]
         _lowerCAmelCase    :					Any							=   SplitDict()
         split_dict.add(snake_case_					)
         _lowerCAmelCase    :					Any							=   DatasetInfo(splits=snake_case_					)

         with tempfile.TemporaryDirectory() as tmp_dir:
           _lowerCAmelCase    :					Union[str, Any]							=   ReaderTest(snake_case_				,				snake_case_					)

           _lowerCAmelCase    :					List[Any]							=   """train[:33%]"""
           _lowerCAmelCase    :					Dict							=   Dataset(**reader.read(snake_case_				,				snake_case_				,				snake_case_					)					)
           self.assertEqual(dset["""filename"""][0]				,				f'{name}-train-00000-of-00010'					)
           self.assertEqual(dset["""filename"""][-1]				,				f'{name}-train-00003-of-00010'					)
           self.assertEqual(dset.num_rows				,				3_3_0					)
           self.assertEqual(dset.num_columns				,				1					)







       def 							__UpperCamelCase    (       self					):
         _lowerCAmelCase    :					Union[str, Any]							=   SplitInfo(name="""train"""				,				num_examples=1_0_0					)
         _lowerCAmelCase    :					Union[str, Any]							=   SplitInfo(name="""test"""				,				num_examples=1_0_0					)
         _lowerCAmelCase    :					List[str]							=   SplitDict()
         split_dict.add(snake_case_					)
         split_dict.add(snake_case_					)
         _lowerCAmelCase    :					Union[str, Any]							=   DatasetInfo(splits=snake_case_					)

         with tempfile.TemporaryDirectory() as tmp_dir:
           _lowerCAmelCase    :					Dict							=   ReaderTest(snake_case_				,				snake_case_					)

           _lowerCAmelCase    :					Tuple							=   [
               {"""filename""": os.path.join(snake_case_				,				"""train"""					)},
               {"""filename""": os.path.join(snake_case_				,				"""test"""					), """skip""": 1_0, """take""": 1_0},
           ]
           _lowerCAmelCase    :					Dict							=   Dataset(**reader.read_files(snake_case_				,				original_instructions="""train+test[10:20]"""					)					)
           self.assertEqual(dset.num_rows				,				1_1_0					)
           self.assertEqual(dset.num_columns				,				1					)
           del dset



@pytest.mark.parametrize("""in_memory"""					, [False, True]						)
def 		_UpperCAmelCase			(					_lowerCamelCase  :    Optional[int]					, _lowerCamelCase  :    Optional[Any]					, _lowerCamelCase  :    Union[str, Any]						)      ->  List[Any]:
  _lowerCAmelCase    :					Dict							=   arrow_file
  with assert_arrow_memory_increases() if in_memory else assert_arrow_memory_doesnt_increase():
    _lowerCAmelCase    :					Optional[int]							=   ArrowReader.read_table(_lowerCamelCase					, in_memory=_lowerCamelCase						)
  assert table.shape == dataset.data.shape
  assert set(table.column_names						) == set(dataset.data.column_names						)
  assert dict(table.to_pydict()						) == dict(dataset.data.to_pydict()						)  # to_pydict returns OrderedDict


@pytest.mark.parametrize("""in_memory"""					, [False, True]						)
def 		_UpperCAmelCase			(					_lowerCamelCase  :    int					, _lowerCamelCase  :    List[Any]					, _lowerCamelCase  :    Tuple						)      ->  Dict:
  _lowerCAmelCase    :					Union[str, Any]							=   arrow_file
  _lowerCAmelCase    :					Any							=   ArrowReader(""""""					, _lowerCamelCase						)
  with assert_arrow_memory_increases() if in_memory else assert_arrow_memory_doesnt_increase():
    _lowerCAmelCase    :					Optional[int]							=   reader.read_files([{"""filename""": filename}]					, in_memory=_lowerCamelCase						)
  assert dataset_kwargs.keys() == {"arrow_table", "info", "split"}
  _lowerCAmelCase    :					Tuple							=   dataset_kwargs["""arrow_table"""]
  assert table.shape == dataset.data.shape
  assert set(table.column_names						) == set(dataset.data.column_names						)
  assert dict(table.to_pydict()						) == dict(dataset.data.to_pydict()						)  # to_pydict returns OrderedDict


def 		_UpperCAmelCase			(					)      ->  int:
  assert ReadInstruction("""train"""					, to=10					, unit="""abs"""						).to_spec() == "train[:10]"
  assert ReadInstruction("""train"""					, from_=-80					, to=10					, unit="""%"""						).to_spec() == "train[-80%:10%]"

  _lowerCAmelCase    :					Dict							=   """train+test"""
  assert ReadInstruction.from_spec(_lowerCamelCase						).to_spec() == spec_train_test

  _lowerCAmelCase    :					List[str]							=   """train[2:10]"""
  assert ReadInstruction.from_spec(_lowerCamelCase						).to_spec() == spec_train_abs

  _lowerCAmelCase    :					Union[str, Any]							=   """train[15%:-20%]"""
  assert ReadInstruction.from_spec(_lowerCamelCase						).to_spec() == spec_train_pct

  _lowerCAmelCase    :					Union[str, Any]							=   """train[:10%](closest)"""
  assert ReadInstruction.from_spec(_lowerCamelCase						).to_spec() == "train[:10%]"

  _lowerCAmelCase    :					List[str]							=   """train[:10%](pct1_dropremainder)"""
  assert ReadInstruction.from_spec(_lowerCamelCase						).to_spec() == spec_train_pct_rounding

  _lowerCAmelCase    :					Any							=   """train[:10%](pct1_dropremainder)+test[-10%:](pct1_dropremainder)"""
  assert ReadInstruction.from_spec(_lowerCamelCase						).to_spec() == spec_train_test_pct_rounding


def 		_UpperCAmelCase			(					)      ->  List[Any]:
  _lowerCAmelCase    :					List[str]							=   """dummy"""
  _lowerCAmelCase    :					Optional[Any]							=   [SplitInfo(name="""train"""					, num_examples=1_00						)]
  _lowerCAmelCase    :					str							=   """train[:33%]"""
  _lowerCAmelCase    :					Dict							=   """arrow"""
  _lowerCAmelCase    :					int							=   """prefix"""

  _lowerCAmelCase    :					List[Any]							=   make_file_instructions(_lowerCamelCase					, _lowerCamelCase					, _lowerCamelCase					, _lowerCamelCase					, _lowerCamelCase						)
  assert isinstance(_lowerCamelCase					, _lowerCamelCase						)
  assert file_instructions.num_examples == 33
  assert file_instructions.file_instructions == [
      {"filename": os.path.join(_lowerCamelCase					, f'{name}-train.arrow'						), "skip": 0, "take": 33}
  ]

  _lowerCAmelCase    :					int							=   [SplitInfo(name="""train"""					, num_examples=1_00					, shard_lengths=[10] * 10						)]
  _lowerCAmelCase    :					Optional[Any]							=   make_file_instructions(_lowerCamelCase					, _lowerCamelCase					, _lowerCamelCase					, _lowerCamelCase					, _lowerCamelCase						)
  assert isinstance(_lowerCamelCase					, _lowerCamelCase						)
  assert file_instructions.num_examples == 33
  assert file_instructions.file_instructions == [
      {"filename": os.path.join(_lowerCamelCase					, f'{name}-train-00000-of-00010.arrow'						), "skip": 0, "take": -1},
      {"filename": os.path.join(_lowerCamelCase					, f'{name}-train-00001-of-00010.arrow'						), "skip": 0, "take": -1},
      {"filename": os.path.join(_lowerCamelCase					, f'{name}-train-00002-of-00010.arrow'						), "skip": 0, "take": -1},
      {"filename": os.path.join(_lowerCamelCase					, f'{name}-train-00003-of-00010.arrow'						), "skip": 0, "take": 3},
  ]



@pytest.mark.parametrize("""name, expected_exception"""					, [(None, TypeError), ("""""", ValueError)]						)
def 		_UpperCAmelCase			(					_lowerCamelCase  :    int					, _lowerCamelCase  :    Dict						)      ->  int:
  _lowerCAmelCase    :					Optional[int]							=   [SplitInfo(name="""train"""					, num_examples=1_00						)]
  _lowerCAmelCase    :					List[str]							=   """train"""
  _lowerCAmelCase    :					Optional[Any]							=   """arrow"""
  _lowerCAmelCase    :					Dict							=   """prefix_path"""
  with pytest.raises(_lowerCamelCase						):
    _lowerCAmelCase    :					str							=   make_file_instructions(_lowerCamelCase					, _lowerCamelCase					, _lowerCamelCase					, _lowerCamelCase					, _lowerCamelCase						)




'''simple docstring'''

def 		_UpperCAmelCase			(					_lowerCamelCase  :    int = 1_00						)      ->  int:
  _lowerCAmelCase    :					Dict							=   [[0 for _ in range(_lowerCamelCase						)] for _ in range(m + 1						)]
  for i in range(m + 1						):
    _lowerCAmelCase    :					List[str]							=   1

  for n in range(m + 1						):
    for k in range(1					, _lowerCamelCase						):
      memo[n][k] += memo[n][k - 1]
      if n > k:
        memo[n][k] += memo[n - k - 1][k]

  return memo[m][m - 1] - 1


if __name__ == "__main__":
     print(solution(int(input("""Enter a number: """).strip())))


