<gh_stars>0
#!/usr/bin/env python
"""Tools to analyse messages."""

from pypher import utils
from pypher import converter
from pypher import ocurs


def ocurs_chars(
	message: str, *, percent: bool = False, reverse: bool = False
) -> dict[str, int | float]:
	"""Count all ocurences of char in the message.

	Args:
		message (str): the message to process.
		percent (bool, optional): if the ocurences need to be
			specied as percent. Defaults to False.
		reverse (bool, optional): dict sort in reverse order.
			Defaults to False.

	Returns:
		dict[str, int | float]: the dict of all ocurences.
	"""
	chars = dict()
	for char in message:
		if char in chars:
			chars[char] += 1
		else:
			chars[char] = 1

	# It's beautiful (sort dict by value)
	chars = {key: value for key, value in sorted(chars.items(), key=(lambda item: item[1]), reverse=not reverse)}
	if percent:
		len_msg = len(message)
		chars = {key: round(value*100/len_msg, 2) for key, value in chars.items()}
	return chars

def ocurs_bigrammes(
	message: str, *, percent: bool = False, reverse: bool = False
) -> dict[str, int | float]:
	"""Count all ocurences of bigrammes (chunks of 2 chars) in the message.

	Args:
		message (str): the message to process.
		percent (bool, optional): if the ocurences need to be
			specied as percent. Defaults to False.
		reverse (bool, optional): dict sort in reverse order.
			Defaults to False.

	Returns:
		dict[str, int | float]: the dict of all ocurences.
	"""
	return ocurs_ngrammes(message, 2, percent=percent, reverse=reverse)

def ocurs_trigrammes(
	message: str, *, percent: bool = False, reverse: bool = False
) -> dict[str, int | float]:
	"""Count all ocurences of trigrammes (chunks of 3 chars) in the message.

	Args:
		message (str): the message to process.
		percent (bool, optional): if the ocurences need to be
			specied as percent. Defaults to False.
		reverse (bool, optional): dict sort in reverse order.
			Defaults to False.

	Returns:
		dict[str, int | float]: the dict of all ocurences.
	"""
	return ocurs_ngrammes(message, 3, percent=percent, reverse=reverse)

def ocurs_ngrammes(
	message: str, n: int, *, percent: bool = False, reverse: bool = False
) -> dict[str, int | float]:
	"""Count all ocurences of ngrammes (chunks of n chars) in the message.

	Args:
		message (str): the message to process.
		percent (bool, optional): if the ocurences need to be
			specied as percent. Defaults to False.
		reverse (bool, optional): dict sort in reverse order.
			Defaults to False.

	Returns:
		dict[str, int | float]: the dict of all ocurences.
	"""
	chunks = converter.split(message, n)
	ngrammes = dict()

	for chunk in chunks:
		if chunk in ngrammes:
			ngrammes[chunk] += 1
		else:
			ngrammes[chunk] = 1

	# It's beautiful (sort dict by value)
	ngrammes = {key: value for key, value in sorted(ngrammes.items(), key=(lambda item: item[1]), reverse=not reverse)}
	if percent:
		len_msg = len(message)
		ngrammes = {key: round(value*100/len_msg, 2) for key, value in ngrammes.items()}
	return ngrammes

def ocurs_words(
	message: str, *, percent: bool = False, reverse: bool = False
) -> dict[str, int | float]:
	"""Count all occurences of words in the message.

	Returns:
		dict[str, int | float]: the dict of all occurences.
	"""
	words = message.split(' ')
	word_ocurs = dict()

	for word in words:
		if word in word_ocurs:
			word_ocurs[word] += 1
		else:
			word_ocurs[word] = 1

	# It's beautiful (sort dict by value)
	word_ocurs = {key: value for key, value in sorted(word_ocurs.items(), key=(lambda item: item[1]), reverse=not reverse)}
	if percent:
		number_words = len(words)
		word_ocurs = {key: round(value*100/number_words, 2) for key, value in word_ocurs.items()}
	return word_ocurs


def ocurs_words_length(
	message: str, *, percent: bool = False, reverse: bool = False
) -> dict[int, int | float]:
	"""Count all occurences of words length in the message.

	Returns:
		dict[str, int | float]: the dict of all occurences.
	"""
	word_lengths = [len(word) for word in message.split(' ')]
	word_length_ocurs = dict()

	for word_length in word_lengths:
		if word_length in word_length_ocurs:
			word_length_ocurs[word_length] += 1
		else:
			word_length_ocurs[word_length] = 1

	# It's beautiful (sort dict by value)
	word_length_ocurs = {key: value for key, value in sorted(word_length_ocurs.items(), key=(lambda item: item[1]), reverse=not reverse)}
	if percent:
		number_word = len(word_lengths)
		word_length_ocurs = {key: round(value*100/number_word, 2) for key, value in word_length_ocurs.items()}
	return word_length_ocurs

def coincidence_index(message: str) -> float:
	"""Calculate the coincidence index of the message.
	This is the probability of chars repetition.

	Args:
		message (str): the message to process.

	Returns:
		float: the coincidence index.
	"""
	ocurs_alpha = ocurs_chars(message)
	len_message = len(message)
	if len_message == 0:
		return -1

	coincidence = 0
	for value in ocurs_alpha.values():
		coincidence += value * (value - 1)
	coincidence /= len_message * (len_message - 1)
	return coincidence

def cycle_chars(message: str, step: int, begin: int = 0) -> list[str]:
	"""Return all chars with a position multiple of step.

	Args:
		message (str): the message to process.
		step (int): the step of the cycle.
		begin (int, optional): offset for the begin. Defaults to 0.

	Returns:
		list[str]: the list of the chars.
	"""
	len_message = len(message)
	letters = list()
	for letter_index in range(begin, len_message, step):
		letters.append(message[letter_index])
	return letters

def frequency_match_score(message: str) -> int:
	"""Caculate the frequency match score.
	This is the number of commons chars in the 6 firsts and lasts chars of the ocurences of a language.

	Args:
		message (str): the message to process.

	Returns:
		int: the frequency match score.
	"""
	ocurs_alpha = list(ocurs_chars(message))
	most_ocurs = ocurs_alpha[0:6]
	least_ocurs = ocurs_alpha[20:26]
	most_ocurs_fr = list(ocurs.OCURS_FR)[0:6]
	least_ocurs_fr = list(ocurs.OCURS_FR)[20:26]

	score = 0
	for ocur in most_ocurs:
		if ocur in most_ocurs_fr:
			score += 1
	for ocur in least_ocurs:
		if ocur in least_ocurs_fr:
			score += 1
	return score

def has_lower_alpha(message: str) -> bool:
	"""Check if the message has alphas.

	Args:
		message (str): the message to analyse.

	Returns:
		bool: if the message check the condition.
	"""
	for letter in utils.LOWER_ALPHA + utils.LOWER_ACCENTS:
		if letter in message:
			return True
	return False

def has_upper_alpha(message: str) -> bool:
	"""Check if the message has alphas.

	Args:
		message (str): the message to analyse.

	Returns:
		bool: if the message check the condition.
	"""
	for letter in utils.UPPER_ALPHA + utils.UPPER_ACCENTS:
		if letter in message:
			return True
	return False

def has_alpha(message: str) -> bool:
	"""Check if the message has alphas.

	Args:
		message (str): the message to analyse.

	Returns:
		bool: if the message check the condition.
	"""
	for char in utils.ALPHA + utils.ACCENTS:
		if char in message:
			return True
	return False

def has_accents(message: str) -> bool:
	"""Check if the message has accents.

	Args:
		message (str): the message to analyse.

	Returns:
		bool: if the message check the condition.
	"""
	for accent in utils.ACCENTS:
		if accent in message:
			return True
	return False

def has_nums(message: str) -> bool:
	"""Check if the message has numbers.

	Args:
		message (str): the message to analyse.

	Returns:
		bool: if the message check the condition.
	"""
	for num in utils.NUMS:
		if num in message:
			return True
	return False

def has_puncts(message: str) -> bool:
	"""Check if the message has punctuations.

	Args:
		message (str): the message to analyse.

	Returns:
		bool: if the message check the condition.
	"""
	for punct in utils.PUNCTS:
		if punct in message:
			return True
	return False

def has_quotes(message: str) -> bool:
	"""Check if the message has quotes.

	Args:
		message (str): the message to analyse.

	Returns:
		bool: if the message check the condition.
	"""
	for quote in utils.QUOTES:
		if quote in message:
			return True
	return False

def has_brackets(message: str) -> bool:
	"""Check if the message has brackets.

	Args:
		message (str): the message to analyse.

	Returns:
		bool: if the message check the condition.
	"""
	for bracket in utils.BRACKETS:
		if bracket in message:
			return True
	return False

def has_spaces(message: str) -> bool:
	"""Check if the message has spaces.

	Args:
		message (str): the message to analyse.

	Returns:
		bool: if the message check the condition.
	"""
	for space in utils.SPACES:
		if space in message:
			return True
	return False
#!/usr/bin/env python
"""Tools to analyse messages."""

from pypher import utils
from pypher import converter
from pypher import ocurs


def ocurs_chars(
	message: str, *, percent: bool = False, reverse: bool = False
) -> dict[str, int | float]:
	"""Count all ocurences of char in the message.

	Args:
		message (str): the message to process.
		percent (bool, optional): if the ocurences need to be
			specied as percent. Defaults to False.
		reverse (bool, optional): dict sort in reverse order.
			Defaults to False.

	Returns:
		dict[str, int | float]: the dict of all ocurences.
	"""
	chars = dict()
	for char in message:
		if char in chars:
			chars[char] += 1
		else:
			chars[char] = 1

	# It's beautiful (sort dict by value)
	chars = {key: value for key, value in sorted(chars.items(), key=(lambda item: item[1]), reverse=not reverse)}
	if percent:
		len_msg = len(message)
		chars = {key: round(value*100/len_msg, 2) for key, value in chars.items()}
	return chars

def ocurs_bigrammes(
	message: str, *, percent: bool = False, reverse: bool = False
) -> dict[str, int | float]:
	"""Count all ocurences of bigrammes (chunks of 2 chars) in the message.

	Args:
		message (str): the message to process.
		percent (bool, optional): if the ocurences need to be
			specied as percent. Defaults to False.
		reverse (bool, optional): dict sort in reverse order.
			Defaults to False.

	Returns:
		dict[str, int | float]: the dict of all ocurences.
	"""
	return ocurs_ngrammes(message, 2, percent=percent, reverse=reverse)

def ocurs_trigrammes(
	message: str, *, percent: bool = False, reverse: bool = False
) -> dict[str, int | float]:
	"""Count all ocurences of trigrammes (chunks of 3 chars) in the message.

	Args:
		message (str): the message to process.
		percent (bool, optional): if the ocurences need to be
			specied as percent. Defaults to False.
		reverse (bool, optional): dict sort in reverse order.
			Defaults to False.

	Returns:
		dict[str, int | float]: the dict of all ocurences.
	"""
	return ocurs_ngrammes(message, 3, percent=percent, reverse=reverse)

def ocurs_ngrammes(
	message: str, n: int, *, percent: bool = False, reverse: bool = False
) -> dict[str, int | float]:
	"""Count all ocurences of ngrammes (chunks of n chars) in the message.

	Args:
		message (str): the message to process.
		percent (bool, optional): if the ocurences need to be
			specied as percent. Defaults to False.
		reverse (bool, optional): dict sort in reverse order.
			Defaults to False.

	Returns:
		dict[str, int | float]: the dict of all ocurences.
	"""
	chunks = converter.split(message, n)
	ngrammes = dict()

	for chunk in chunks:
		if chunk in ngrammes:
			ngrammes[chunk] += 1
		else:
			ngrammes[chunk] = 1

	# It's beautiful (sort dict by value)
	ngrammes = {key: value for key, value in sorted(ngrammes.items(), key=(lambda item: item[1]), reverse=not reverse)}
	if percent:
		len_msg = len(message)
		ngrammes = {key: round(value*100/len_msg, 2) for key, value in ngrammes.items()}
	return ngrammes

def ocurs_words(
	message: str, *, percent: bool = False, reverse: bool = False
) -> dict[str, int | float]:
	"""Count all occurences of words in the message.

	Returns:
		dict[str, int | float]: the dict of all occurences.
	"""
	words = message.split(' ')
	word_ocurs = dict()

	for word in words:
		if word in word_ocurs:
			word_ocurs[word] += 1
		else:
			word_ocurs[word] = 1

	# It's beautiful (sort dict by value)
	word_ocurs = {key: value for key, value in sorted(word_ocurs.items(), key=(lambda item: item[1]), reverse=not reverse)}
	if percent:
		number_words = len(words)
		word_ocurs = {key: round(value*100/number_words, 2) for key, value in word_ocurs.items()}
	return word_ocurs


def ocurs_words_length(
	message: str, *, percent: bool = False, reverse: bool = False
) -> dict[int, int | float]:
	"""Count all occurences of words length in the message.

	Returns:
		dict[str, int | float]: the dict of all occurences.
	"""
	word_lengths = [len(word) for word in message.split(' ')]
	word_length_ocurs = dict()

	for word_length in word_lengths:
		if word_length in word_length_ocurs:
			word_length_ocurs[word_length] += 1
		else:
			word_length_ocurs[word_length] = 1

	# It's beautiful (sort dict by value)
	word_length_ocurs = {key: value for key, value in sorted(word_length_ocurs.items(), key=(lambda item: item[1]), reverse=not reverse)}
	if percent:
		number_word = len(word_lengths)
		word_length_ocurs = {key: round(value*100/number_word, 2) for key, value in word_length_ocurs.items()}
	return word_length_ocurs

def coincidence_index(message: str) -> float:
	"""Calculate the coincidence index of the message.
	This is the probability of chars repetition.

	Args:
		message (str): the message to process.

	Returns:
		float: the coincidence index.
	"""
	ocurs_alpha = ocurs_chars(message)
	len_message = len(message)
	if len_message == 0:
		return -1

	coincidence = 0
	for value in ocurs_alpha.values():
		coincidence += value * (value - 1)
	coincidence /= len_message * (len_message - 1)
	return coincidence

def cycle_chars(message: str, step: int, begin: int = 0) -> list[str]:
	"""Return all chars with a position multiple of step.

	Args:
		message (str): the message to process.
		step (int): the step of the cycle.
		begin (int, optional): offset for the begin. Defaults to 0.

	Returns:
		list[str]: the list of the chars.
	"""
	len_message = len(message)
	letters = list()
	for letter_index in range(begin, len_message, step):
		letters.append(message[letter_index])
	return letters

def frequency_match_score(message: str) -> int:
	"""Caculate the frequency match score.
	This is the number of commons chars in the 6 firsts and lasts chars of the ocurences of a language.

	Args:
		message (str): the message to process.

	Returns:
		int: the frequency match score.
	"""
	ocurs_alpha = list(ocurs_chars(message))
	most_ocurs = ocurs_alpha[0:6]
	least_ocurs = ocurs_alpha[20:26]
	most_ocurs_fr = list(ocurs.OCURS_FR)[0:6]
	least_ocurs_fr = list(ocurs.OCURS_FR)[20:26]

	score = 0
	for ocur in most_ocurs:
		if ocur in most_ocurs_fr:
			score += 1
	for ocur in least_ocurs:
		if ocur in least_ocurs_fr:
			score += 1
	return score

def has_lower_alpha(message: str) -> bool:
	"""Check if the message has alphas.

	Args:
		message (str): the message to analyse.

	Returns:
		bool: if the message check the condition.
	"""
	for letter in utils.LOWER_ALPHA + utils.LOWER_ACCENTS:
		if letter in message:
			return True
	return False

def has_upper_alpha(message: str) -> bool:
	"""Check if the message has alphas.

	Args:
		message (str): the message to analyse.

	Returns:
		bool: if the message check the condition.
	"""
	for letter in utils.UPPER_ALPHA + utils.UPPER_ACCENTS:
		if letter in message:
			return True
	return False

def has_alpha(message: str) -> bool:
	"""Check if the message has alphas.

	Args:
		message (str): the message to analyse.

	Returns:
		bool: if the message check the condition.
	"""
	for char in utils.ALPHA + utils.ACCENTS:
		if char in message:
			return True
	return False

def has_accents(message: str) -> bool:
	"""Check if the message has accents.

	Args:
		message (str): the message to analyse.

	Returns:
		bool: if the message check the condition.
	"""
	for accent in utils.ACCENTS:
		if accent in message:
			return True
	return False

def has_nums(message: str) -> bool:
	"""Check if the message has numbers.

	Args:
		message (str): the message to analyse.

	Returns:
		bool: if the message check the condition.
	"""
	for num in utils.NUMS:
		if num in message:
			return True
	return False

def has_puncts(message: str) -> bool:
	"""Check if the message has punctuations.

	Args:
		message (str): the message to analyse.

	Returns:
		bool: if the message check the condition.
	"""
	for punct in utils.PUNCTS:
		if punct in message:
			return True
	return False

def has_quotes(message: str) -> bool:
	"""Check if the message has quotes.

	Args:
		message (str): the message to analyse.

	Returns:
		bool: if the message check the condition.
	"""
	for quote in utils.QUOTES:
		if quote in message:
			return True
	return False

def has_brackets(message: str) -> bool:
	"""Check if the message has brackets.

	Args:
		message (str): the message to analyse.

	Returns:
		bool: if the message check the condition.
	"""
	for bracket in utils.BRACKETS:
		if bracket in message:
			return True
	return False

def has_spaces(message: str) -> bool:
	"""Check if the message has spaces.

	Args:
		message (str): the message to analyse.

	Returns:
		bool: if the message check the condition.
	"""
	for space in utils.SPACES:
		if space in message:
			return True
	return False
#!/usr/bin/env python Tools to analyse messages. Count all ocurences of char in the message.  	Args: 		message (str): the message to process. 		percent (bool, optional): if the ocurences need to be 			specied as percent. Defaults to False. 		reverse (bool, optional): dict sort in reverse order. 			Defaults to False.  	Returns: 		dict[str, int | float]: the dict of all ocurences. # It's beautiful (sort dict by value) Count all ocurences of bigrammes (chunks of 2 chars) in the message.  	Args: 		message (str): the message to process. 		percent (bool, optional): if the ocurences need to be 			specied as percent. Defaults to False. 		reverse (bool, optional): dict sort in reverse order. 			Defaults to False.  	Returns: 		dict[str, int | float]: the dict of all ocurences. Count all ocurences of trigrammes (chunks of 3 chars) in the message.  	Args: 		message (str): the message to process. 		percent (bool, optional): if the ocurences need to be 			specied as percent. Defaults to False. 		reverse (bool, optional): dict sort in reverse order. 			Defaults to False.  	Returns: 		dict[str, int | float]: the dict of all ocurences. Count all ocurences of ngrammes (chunks of n chars) in the message.  	Args: 		message (str): the message to process. 		percent (bool, optional): if the ocurences need to be 			specied as percent. Defaults to False. 		reverse (bool, optional): dict sort in reverse order. 			Defaults to False.  	Returns: 		dict[str, int | float]: the dict of all ocurences. # It's beautiful (sort dict by value) Count all occurences of words in the message.  	Returns: 		dict[str, int | float]: the dict of all occurences. # It's beautiful (sort dict by value) Count all occurences of words length in the message.  	Returns: 		dict[str, int | float]: the dict of all occurences. # It's beautiful (sort dict by value) Calculate the coincidence index of the message. 	This is the probability of chars repetition.  	Args: 		message (str): the message to process.  	Returns: 		float: the coincidence index. Return all chars with a position multiple of step.  	Args: 		message (str): the message to process. 		step (int): the step of the cycle. 		begin (int, optional): offset for the begin. Defaults to 0.  	Returns: 		list[str]: the list of the chars. Caculate the frequency match score. 	This is the number of commons chars in the 6 firsts and lasts chars of the ocurences of a language.  	Args: 		message (str): the message to process.  	Returns: 		int: the frequency match score. Check if the message has alphas.  	Args: 		message (str): the message to analyse.  	Returns: 		bool: if the message check the condition. Check if the message has alphas.  	Args: 		message (str): the message to analyse.  	Returns: 		bool: if the message check the condition. Check if the message has alphas.  	Args: 		message (str): the message to analyse.  	Returns: 		bool: if the message check the condition. Check if the message has accents.  	Args: 		message (str): the message to analyse.  	Returns: 		bool: if the message check the condition. Check if the message has numbers.  	Args: 		message (str): the message to analyse.  	Returns: 		bool: if the message check the condition. Check if the message has punctuations.  	Args: 		message (str): the message to analyse.  	Returns: 		bool: if the message check the condition. Check if the message has quotes.  	Args: 		message (str): the message to analyse.  	Returns: 		bool: if the message check the condition. Check if the message has brackets.  	Args: 		message (str): the message to analyse.  	Returns: 		bool: if the message check the condition. Check if the message has spaces.  	Args: 		message (str): the message to analyse.  	Returns: 		bool: if the message check the condition.