


'''simple docstring'''




import argparse
import logging
import os

import datasets
import tensorflow as tf

from transformers import AutoTokenizer


_lowerCAmelCase  :		List[Any]		     =	logging.getLogger(__name__)

def 			__UpperCamelCase    (    )    ->      Any:




	"""simple docstring"""





	lowerCAmelCase					:    str      							= argparse.ArgumentParser(
	    description='Prepare TFRecord shards from pre-tokenized samples of the wikitext dataset.'				)
	parser.add_argument(
	    '--dataset_name'					,   type=_A					,   default='wikitext'					,   help='Name of the training. Explore datasets at: hf.co/datasets.'					,   )
	parser.add_argument(
	    '--dataset_config'					,   type=_A					,   default='wikitext-103-raw-v1'					,   help='Configuration name of the dataset.'				)
	parser.add_argument(
	    '--tokenizer_name_or_path'					,   type=_A					,   default='sayakpaul/unigram-tokenizer-wikitext'					,   help='Tokenizer identifier. Can be a local filepath or a Hub identifier.'					,   )
	parser.add_argument(
	    '--shard_size'					,   type=_A					,   default=10_00					,   help='Number of entries to go in a single shard.'					,   )
	parser.add_argument('--split'					,   type=_A					,   default='train'					,   choices=['train', 'test', 'validation']				)
	parser.add_argument(
	    '--limit'					,   default=_A					,   type=_A					,   help='Limit the number of shards (used for debugging).'					,   )
	parser.add_argument(
	    '--max_length'					,   type=_A					,   default=5_12					,   help='Maximum sequence length. For training on TPUs, it helps to have a maximum'
	    ' sequence length that is a multiple of 8.'					,   )
	parser.add_argument(
	    '--output_dir'					,   default='tf-tpu'					,   type=_A					,   help='Output directory where the TFRecord shards will be saved. If the'
	    ' path is appended with `gs://` (\'gs://tf-tpu\', for example) then the TFRecord'
	    ' shards will be directly saved to a Google Cloud Storage bucket.'					,   )

	lowerCAmelCase					:    Any      							= parser.parse_args()
	return args

def 			__UpperCamelCase    (    _A    :				Optional[int]				)    ->      int:




	"""simple docstring"""





	def fn(_A    :				Tuple				):
		return tokenizer(examples['text']				)

	return fn

def 			__UpperCamelCase    (    _A    :				int				)    ->      int:




	"""simple docstring"""





	lowerCAmelCase					:    Tuple      							= []
	for i in range(len(tokenized_data['input_ids']				)				):
		lowerCAmelCase					:    Optional[Any]      							= {
		    'input_ids': tf.train.Feature(intaa_list=tf.train.IntaaList(value=tokenized_data['input_ids'][i]				)				),
		    'attention_mask': tf.train.Feature(
		        intaa_list=tf.train.IntaaList(value=tokenized_data['attention_mask'][i]				)				),
		}
		lowerCAmelCase					:    Any      							= tf.train.Features(feature=_A				)
		lowerCAmelCase					:    List[str]      							= tf.train.Example(features=_A				)
		lowerCAmelCase					:    Tuple      							= example.SerializeToString()
		records.append(_A				)
	return records

def 			__UpperCamelCase    (    _A    :				int				)    ->      Union[str, Any]:




	"""simple docstring"""





	lowerCAmelCase					:    Union[str, Any]      							= datasets.load_dataset(args.dataset_name					,   args.dataset_config					,   split=args.split				)

	if args.limit is not None:
		lowerCAmelCase					:    Optional[Any]      							= min(len(_A				)					,   args.limit				)
		lowerCAmelCase					:    Dict      							= dataset.select(range(_A				)				)
		print(F"Limiting the dataset to {args.limit} entries."				)

	lowerCAmelCase					:    str      							= AutoTokenizer.from_pretrained(args.tokenizer_name_or_path				)

	# Handle output directory creation.
	# For serializing into a Google Cloud Storage Bucket, one needs to first
	# create a bucket.
	if "gs" not in args.output_dir:
		if not os.path.exists(args.output_dir				):
			os.makedirs(args.output_dir				)
		lowerCAmelCase					:    Any      							= os.path.join(args.output_dir					,   args.split				)
		if not os.path.exists(_A				):
			os.makedirs(_A				)
	else:
		lowerCAmelCase					:    List[Any]      							= os.path.join(args.output_dir					,   args.split				)

	# Tokenize the whole dataset at once.
	lowerCAmelCase					:    Any      							= tokenize_function(_A				)
	lowerCAmelCase					:    Optional[int]      							= dataset.map(_A					,   batched=_A					,   num_proc=4					,   remove_columns=['text']				)

	# We need to concatenate all our texts together, and then split the result
	# into chunks of a fixed size, which we will call block_size. To do this, we
	# will use the map method again, with the option batched=True. When we use batched=True,
	# the function we pass to map() will be passed multiple inputs at once, allowing us
	# to group them into more or fewer examples than we had in the input.
	# This allows us to create our new fixed-length samples. The advantage of this
	# method is that we don't lose a whole lot of content from the dataset compared to the
	# case where we simply tokenize with a pre-defined max_length.

	def group_texts(_A    :				str				):
		# Concatenate all texts.
		lowerCAmelCase					:    Optional[int]      							= {k: sum(examples[k]					,   []				) for k in examples.keys()}
		lowerCAmelCase					:    str      							= len(concatenated_examples[list(examples.keys()				)[0]]				)
		# We drop the small remainder, though you could add padding instead if the model supports it
		# In this, as in all things, we advise you to follow your heart 🫀
		lowerCAmelCase					:    List[Any]      							= (total_length // args.max_length) * args.max_length
		# Split by chunks of max_len.
		lowerCAmelCase					:    str      							= {
		    k: [t[i : i + args.max_length] for i in range(0					,   _A					,   args.max_length				)]
		    for k, t in concatenated_examples.items()
		}
		return result

	lowerCAmelCase					:    List[Any]      							= dataset_tokenized.map(_A					,   batched=_A					,   batch_size=10_00					,   num_proc=4				)

	lowerCAmelCase					:    Union[str, Any]      							= 0
	lowerCAmelCase					:    Tuple      							= 0
	for shard in range(0					,   len(_A				)					,   args.shard_size				):
		lowerCAmelCase					:    Optional[Any]      							= grouped_dataset[shard : shard + args.shard_size]
		lowerCAmelCase					:    List[str]      							= len(dataset_snapshot['input_ids']				)
		lowerCAmelCase					:    Union[str, Any]      							= os.path.join(_A					,   F"dataset-{shard_count}-{records_containing}.tfrecord"				)
		lowerCAmelCase					:    List[Any]      							= get_serialized_examples(_A				)

		with tf.io.TFRecordWriter(_A				) as out_file:
			for i in range(len(_A				)				):
				lowerCAmelCase					:    Union[str, Any]      							= serialized_examples[i]
				out_file.write(_A				)
			print('Wrote file {} containing {} records'.format(_A					,   _A				)				)

		shard_count += 1
		total_records += records_containing

	with open(F"split-{args.split}-records-count.txt"					,   'w'				) as f:
		print(F"Total {args.split} records: {total_records}"					,   file=_A				)


if __name__ == "__main__":
				_lowerCAmelCase  :		List[Any]		     =	parse_args()
				main(args)




'''simple docstring'''




from typing import Any



class  lowerCAmelCase				:



	def __init__(					self ,					snake_case__    ):
		lowerCAmelCase					:    Optional[int]      							= data
		lowerCAmelCase					:    Optional[Any]      							= None



	def __repr__(					self    ):
		return f"Node({self.data})"



class  lowerCAmelCase				:



	def __init__(					self    ):
		lowerCAmelCase					:    Dict      							= None



	def __iter__(					self    ):
		lowerCAmelCase					:    Optional[Any]      							= self.head
		while node:
			yield node.data
			lowerCAmelCase					:    Optional[int]      							= node.next



	def __len__(					self    ):
		return sum(1 for _ in self    )



	def __repr__(					self    ):
		return "->".join([str(snake_case__    ) for item in self]    )



	def __getitem__(					self ,					snake_case__    ):
		if not 0 <= index < len(self    ):
			raise ValueError('list index out of range.'    )
		for i, node in enumerate(self    ):
			if i == index:
				return node
		return None



	def __setitem__(					self ,					snake_case__ ,					snake_case__    ):
		if not 0 <= index < len(self    ):
			raise ValueError('list index out of range.'    )
		lowerCAmelCase					:    Any      							= self.head
		for _ in range(snake_case__    ):
			lowerCAmelCase					:    List[str]      							= current.next
		lowerCAmelCase					:    int      							= data



	def 				lowercase     (					self ,					snake_case__    ):
		self.insert_nth(len(self    ) ,					snake_case__    )



	def 				lowercase     (					self ,					snake_case__    ):
		self.insert_nth(0 ,					snake_case__    )



	def 				lowercase     (					self ,					snake_case__ ,					snake_case__    ):
		if not 0 <= index <= len(self    ):
			raise IndexError('list index out of range'    )
		lowerCAmelCase					:    List[str]      							= Node(snake_case__    )
		if self.head is None:
			lowerCAmelCase					:    int      							= new_node
		elif index == 0:
			lowerCAmelCase					:    List[Any]      							= self.head  # link new_node to head
			lowerCAmelCase					:    List[Any]      							= new_node
		else:
			lowerCAmelCase					:    List[Any]      							= self.head
			for _ in range(index - 1    ):
				lowerCAmelCase					:    Union[str, Any]      							= temp.next
			lowerCAmelCase					:    Any      							= temp.next
			lowerCAmelCase					:    str      							= new_node



	def 				lowercase     (					self    ):  # print every node data
		print(self    )



	def 				lowercase     (					self    ):
		return self.delete_nth(0    )



	def 				lowercase     (					self    ):  # delete from tail
		return self.delete_nth(len(self    ) - 1    )



	def 				lowercase     (					self ,					snake_case__ = 0    ):
		if not 0 <= index <= len(self    ) - 1:  # test if index is valid
			raise IndexError('List index out of range.'    )
		lowerCAmelCase					:    List[str]      							= self.head  # default first node
		if index == 0:
			lowerCAmelCase					:    Tuple      							= self.head.next
		else:
			lowerCAmelCase					:    Dict      							= self.head
			for _ in range(index - 1    ):
				lowerCAmelCase					:    Tuple      							= temp.next
			lowerCAmelCase					:    Dict      							= temp.next
			lowerCAmelCase					:    Tuple      							= temp.next.next
		return delete_node.data



	def 				lowercase     (					self    ):
		return self.head is None



	def 				lowercase     (					self    ):
		lowerCAmelCase					:    List[Any]      							= None
		lowerCAmelCase					:    Any      							= self.head

		while current:
			# Store the current node's next node.
			lowerCAmelCase					:    List[str]      							= current.next
			# Make the current node's next point backwards
			lowerCAmelCase					:    int      							= prev
			# Make the previous node be the current node
			lowerCAmelCase					:    int      							= current
			# Make the current node the next node (to progress iteration)
			lowerCAmelCase					:    Optional[Any]      							= next_node
		# Return prev in order to put the head at the end
		lowerCAmelCase					:    List[Any]      							= prev


def 			__UpperCamelCase    (    )    ->      None:




	"""simple docstring"""





	lowerCAmelCase					:    Tuple      							= LinkedList()
	assert linked_list.is_empty() is True
	assert str(_A				) == ""

	try:
		linked_list.delete_head()
		raise AssertionError  # This should not happen.
	except IndexError:
		assert True  # This should happen.

	try:
		linked_list.delete_tail()
		raise AssertionError  # This should not happen.
	except IndexError:
		assert True  # This should happen.

	for i in range(10				):
		assert len(_A				) == i
		linked_list.insert_nth(_A					,   i + 1				)
	assert str(_A				) == "->".join(str(_A				) for i in range(1					,   11				)				)

	linked_list.insert_head(0				)
	linked_list.insert_tail(11				)
	assert str(_A				) == "->".join(str(_A				) for i in range(0					,   12				)				)

	assert linked_list.delete_head() == 0
	assert linked_list.delete_nth(9				) == 10
	assert linked_list.delete_tail() == 11
	assert len(_A				) == 9
	assert str(_A				) == "->".join(str(_A				) for i in range(1					,   10				)				)

	assert all(linked_list[i] == i + 1 for i in range(0					,   9				)				) is True

	for i in range(0					,   9				):
		lowerCAmelCase					:    Optional[Any]      							= -i
	assert all(linked_list[i] == -i for i in range(0					,   9				)				) is True

	linked_list.reverse()
	assert str(_A				) == "->".join(str(_A				) for i in range(-8					,   1				)				)

def 			__UpperCamelCase    (    )    ->      None:




	"""simple docstring"""





	lowerCAmelCase					:    Optional[int]      							= [
	    -9,
	    1_00,
	    Node(77_34_51_12				),
	    'dlrow olleH',
	    7,
	    55_55,
	    0,
	    -1_92.5_55_55,
	    'Hello, world!',
	    77.9,
	    Node(10				),
	    None,
	    None,
	    12.20,
	]
	lowerCAmelCase					:    Dict      							= LinkedList()

	for i in test_input:
		linked_list.insert_tail(_A				)

	# Check if it's empty or not
	assert linked_list.is_empty() is False
	assert (
	    str(_A				) == "-9->100->Node(77345112)->dlrow olleH->7->5555->0->"
	    "-192.55555->Hello, world!->77.9->Node(10)->None->None->12.2"
	)

	# Delete the head
	lowerCAmelCase					:    Optional[Any]      							= linked_list.delete_head()
	assert result == -9
	assert (
	    str(_A				) == "100->Node(77345112)->dlrow olleH->7->5555->0->-192.55555->"
	    "Hello, world!->77.9->Node(10)->None->None->12.2"
	)

	# Delete the tail
	lowerCAmelCase					:    List[str]      							= linked_list.delete_tail()
	assert result == 12.2
	assert (
	    str(_A				) == "100->Node(77345112)->dlrow olleH->7->5555->0->-192.55555->"
	    "Hello, world!->77.9->Node(10)->None->None"
	)

	# Delete a node in specific location in linked list
	lowerCAmelCase					:    List[str]      							= linked_list.delete_nth(10				)
	assert result is None
	assert (
	    str(_A				) == "100->Node(77345112)->dlrow olleH->7->5555->0->-192.55555->"
	    "Hello, world!->77.9->Node(10)->None"
	)

	# Add a Node instance to its head
	linked_list.insert_head(Node('Hello again, world!'				)				)
	assert (
	    str(_A				)
	    == "Node(Hello again, world!)->100->Node(77345112)->dlrow olleH->"
	    "7->5555->0->-192.55555->Hello, world!->77.9->Node(10)->None"
	)

	# Add None to its tail
	linked_list.insert_tail(_A				)
	assert (
	    str(_A				)
	    == "Node(Hello again, world!)->100->Node(77345112)->dlrow olleH->"
	    "7->5555->0->-192.55555->Hello, world!->77.9->Node(10)->None->None"
	)

	# Reverse the linked list
	linked_list.reverse()
	assert (
	    str(_A				)
	    == "None->None->Node(10)->77.9->Hello, world!->-192.55555->0->5555->"
	    "7->dlrow olleH->Node(77345112)->100->Node(Hello again, world!)"
	)

def 			__UpperCamelCase    (    )    ->      List[Any]:




	"""simple docstring"""





	from doctest import testmod

	testmod()

	lowerCAmelCase					:    Optional[Any]      							= LinkedList()
	linked_list.insert_head(input('Inserting 1st at head '				).strip()				)
	linked_list.insert_head(input('Inserting 2nd at head '				).strip()				)
	print('\nPrint list:'				)
	linked_list.print_list()
	linked_list.insert_tail(input('\nInserting 1st at tail '				).strip()				)
	linked_list.insert_tail(input('Inserting 2nd at tail '				).strip()				)
	print('\nPrint list:'				)
	linked_list.print_list()
	print('\nDelete head'				)
	linked_list.delete_head()
	print('Delete tail'				)
	linked_list.delete_tail()
	print('\nPrint list:'				)
	linked_list.print_list()
	print('\nReverse linked list'				)
	linked_list.reverse()
	print('\nPrint list:'				)
	linked_list.print_list()
	print('\nString representation of linked list:'				)
	print(_A				)
	print('\nReading/changing Node data using indexing:'				)
	print(F"Element at Position 1: {linked_list[1]}"				)
	lowerCAmelCase					:    Tuple      							= input('Enter New Value: '				).strip()
	print('New list:'				)
	print(_A				)
	print(F"length of linked_list is : {len(_A				)}"				)


if __name__ == "__main__":
				main()
