




import numpy as np
def 		a_       (   __lowerCAmelCase      ,   __lowerCAmelCase="utf-8"      ,   __lowerCAmelCase="surrogatepass"							):
  lowerCAmelCase__								=			bin(int.from_bytes(text.encode(__lowerCAmelCase      ,   __lowerCAmelCase							)      ,   '''big'''							)							)[2:]
  return bits.zfill(8 * ((len(__lowerCAmelCase							) + 7) // 8)							)
def 		a_       (   __lowerCAmelCase      ,   __lowerCAmelCase="utf-8"      ,   __lowerCAmelCase="surrogatepass"							):
  lowerCAmelCase__								=			int(__lowerCAmelCase      ,   2							)
  return n.to_bytes((n.bit_length() + 7) // 8      ,   '''big'''							).decode(__lowerCAmelCase      ,   __lowerCAmelCase							) or "\0"
def 		a_       (   __lowerCAmelCase      ,   __lowerCAmelCase							):
  if size_par + len(__lowerCAmelCase							) <= 2**size_par - (len(__lowerCAmelCase							) - 1):
    raise ValueError('''size of parity don\'t match with size of data'''							)

  lowerCAmelCase__								=			[]
  lowerCAmelCase__								=			[]
  lowerCAmelCase__								=			[bin(__lowerCAmelCase							)[2:] for x in range(1      ,   size_par + len(__lowerCAmelCase							) + 1							)]

  # sorted information data for the size of the output data
  lowerCAmelCase__								=			[]
  # data position template + parity
  lowerCAmelCase__								=			[]
  # parity bit counter
  lowerCAmelCase__								=			0
  # counter position of data bits
  lowerCAmelCase__								=			0

  for x in range(1      ,   size_par + len(__lowerCAmelCase							) + 1							):
    # Performs a template of bit positions - who should be given,
    # and who should be parity
    if qtd_bp < size_par:
      if (np.log(__lowerCAmelCase							) / np.log(2							)).is_integer():
        data_out_gab.append('''P'''							)
        lowerCAmelCase__								=			qtd_bp + 1
      else:
        data_out_gab.append('''D'''							)
    else:
      data_out_gab.append('''D'''							)

    # Sorts the data to the new output size
    if data_out_gab[-1] == "D":
      data_ord.append(data[cont_data]							)
      cont_data += 1
    else:
      data_ord.append(__lowerCAmelCase							)

    # Calculates parity
  lowerCAmelCase__								=			0  # parity bit counter
  for bp in range(1      ,   size_par + 1							):
    # Bit counter one for a given parity
    lowerCAmelCase__								=			0
    # counter to control the loop reading
    lowerCAmelCase__								=			0
    for x in data_ord:
      if x is not None:
        try:
          lowerCAmelCase__								=			(bin_pos[cont_loop])[-1 * (bp)]
        except IndexError:
          lowerCAmelCase__								=			'''0'''
        if aux == "1" and x == "1":
          cont_bo += 1
      cont_loop += 1
    parity.append(cont_bo % 2							)

    qtd_bp += 1

  # Mount the message
  lowerCAmelCase__								=			0  # parity bit counter
  for x in range(0      ,   size_par + len(__lowerCAmelCase							)							):
    if data_ord[x] is None:
      data_out.append(str(parity[cont_bp]							)							)
      cont_bp += 1
    else:
      data_out.append(data_ord[x]							)

  return data_out
def 		a_       (   __lowerCAmelCase      ,   __lowerCAmelCase							):
  lowerCAmelCase__								=			[]
  # Parity bit counter
  lowerCAmelCase__								=			0
  # Counter p data bit reading
  lowerCAmelCase__								=			0
  # list of parity received
  lowerCAmelCase__								=			[]
  lowerCAmelCase__								=			[]

  for x in range(1      ,   len(__lowerCAmelCase							) + 1							):
    # Performs a template of bit positions - who should be given,
    #  and who should be parity
    if qtd_bp < size_par and (np.log(__lowerCAmelCase							) / np.log(2							)).is_integer():
      data_out_gab.append('''P'''							)
      lowerCAmelCase__								=			qtd_bp + 1
    else:
      data_out_gab.append('''D'''							)

    # Sorts the data to the new output size
    if data_out_gab[-1] == "D":
      data_output.append(data[cont_data]							)
    else:
      parity_received.append(data[cont_data]							)
    cont_data += 1

  # -----------calculates the parity with the data
  lowerCAmelCase__								=			[]
  lowerCAmelCase__								=			[]
  lowerCAmelCase__								=			[bin(__lowerCAmelCase							)[2:] for x in range(1      ,   size_par + len(__lowerCAmelCase							) + 1							)]

  #  sorted information data for the size of the output data
  lowerCAmelCase__								=			[]
  # Data position feedback + parity
  lowerCAmelCase__								=			[]
  # Parity bit counter
  lowerCAmelCase__								=			0
  # Counter p data bit reading
  lowerCAmelCase__								=			0

  for x in range(1      ,   size_par + len(__lowerCAmelCase							) + 1							):
    # Performs a template position of bits - who should be given,
    # and who should be parity
    if qtd_bp < size_par and (np.log(__lowerCAmelCase							) / np.log(2							)).is_integer():
      data_out_gab.append('''P'''							)
      lowerCAmelCase__								=			qtd_bp + 1
    else:
      data_out_gab.append('''D'''							)

    # Sorts the data to the new output size
    if data_out_gab[-1] == "D":
      data_ord.append(data_output[cont_data]							)
      cont_data += 1
    else:
      data_ord.append(__lowerCAmelCase							)

    # Calculates parity
  lowerCAmelCase__								=			0  # parity bit counter
  for bp in range(1      ,   size_par + 1							):
    # Bit counter one for a certain parity
    lowerCAmelCase__								=			0
    # Counter to control loop reading
    lowerCAmelCase__								=			0
    for x in data_ord:
      if x is not None:
        try:
          lowerCAmelCase__								=			(bin_pos[cont_loop])[-1 * (bp)]
        except IndexError:
          lowerCAmelCase__								=			'''0'''
        if aux == "1" and x == "1":
          cont_bo += 1
      cont_loop += 1
    parity.append(str(cont_bo % 2							)							)

    qtd_bp += 1

  # Mount the message
  lowerCAmelCase__								=			0  # Parity bit counter
  for x in range(0      ,   size_par + len(__lowerCAmelCase							)							):
    if data_ord[x] is None:
      data_out.append(str(parity[cont_bp]							)							)
      cont_bp += 1
    else:
      data_out.append(data_ord[x]							)

  lowerCAmelCase__								=			parity_received == parity
  return data_output, ack







def 		a_       (   __lowerCAmelCase      ,   __lowerCAmelCase							):
  lowerCAmelCase__								=			0
  for ele in arr:
    total_sum += product_sum(__lowerCAmelCase      ,   depth + 1							) if isinstance(__lowerCAmelCase      ,   __lowerCAmelCase							) else ele
  return total_sum * depth
def 		a_       (   __lowerCAmelCase							):
  return product_sum(__lowerCAmelCase      ,   1							)


if __name__ == "__main__":
      import doctest

      doctest.testmod()

