• Projeto 0 - Base Python

Camada Física da Computação - Aula 1 - exemplos de operações básicas

1) Nesta atividade você irá aprimorar seus conhecimentos em relação à representação dos dados que iremos transmitir. Seu primeiro passo será converter números na representação decimal em outras bases. Você conseguiria converter os números 12, 16, 34 e 255 para a base binária? Tente fazer a transformação.

#suas respostas

2) Agora vamos fazer o inverso. Qual é o valor em decimal para o número b00010010 (a letr b indica que a representação está em base binária, na verdade um byte de 8 bits)

#sua resposta

3) Podemos fazer estas transformações através de códigos. Utilize a função do python bin(numDec), que transforma um numero decimal em binário, e também a funcao int('numBin',2), que transforma o binario em decimal inteiro, e confira seus resultados ateriores!

#seu codigo
print('solucoes anteriores 12={}, 16={}, 34={}, 255={}' .format(bin(12),bin(16),bin(34),bin(255)))
solucoes anteriores 12=0b1100, 16=0b10000, 34=0b100010, 255=0b11111111

4) Vamos agora considerar a base numérica de 16 símbolos, que chamamos de hexadecimal. Nesse caso, usamos "0x" antes de um número para indicar que está na base hexadecinal. Lembre-se da explicação do seu professor ou revise o material de aula se precisar e escreva os números 8, 15, 16 e 255 em base hexadecimal.

# sua resposta aqui.

5) Verifique o codigo abaixo. A função bytes([]) do python para tranformar números decimais em hexadecimais e confira seu resultado.

print('respostas anteriores:  8={}, 15={}, 16={}, 255={}' .format(bytes([8]),bytes([15]),bytes([16]),bytes([255])))

print('ou ainda: respostas anteriores:  8={}' .format((8).to_bytes(2, byteorder='big')))
print('ou ainda: respostas anteriores:  8={}' .format((8).to_bytes(3, byteorder='little')))
print('ou ainda: respostas anteriores:  1024={}' .format((1024).to_bytes(5, byteorder='big')))
print('ou ainda: respostas anteriores:  1024={}' .format((1024).to_bytes(5, byteorder='little')))
respostas anteriores:  8=b'\x08', 15=b'\x0f', 16=b'\x10', 255=b'\xff'
ou ainda: respostas anteriores:  8=b'\x00\x08'
ou ainda: respostas anteriores:  8=b'\x08\x00\x00'
ou ainda: respostas anteriores:  1024=b'\x00\x00\x00\x04\x00'
ou ainda: respostas anteriores:  1024=b'\x00\x04\x00\x00\x00'

6) Quantos bits seriam necessários para representar 0xFF em binário?

#sua resposta

7) Agora vamos entender como um valor hexadecimal pode se convertido em um int. Para isso você deverá "printar" os valores abaixo e fazer algo investigativo! Tente descobrir como funciona a função "int.from_bytes", que tranforma vários bytes em um int.

valor1 = int.from_bytes(b'\x00\x1C', byteorder='little')    
valor2 = int.from_bytes(b'\x00\x1C', byteorder='big') 
valor3 = int.from_bytes(b'\x1C\x00', byteorder='little')  
valor4 = int.from_bytes(b'\x00\x1A', byteorder='big', signed=True)  
valor5 = int.from_bytes(b'\x7F\xFF', byteorder='big', signed=True)  
valor6 = int.from_bytes(b'\x80\x00', byteorder='big', signed=True)
valor7 = int.from_bytes(b'\xAB\xC5', byteorder='big', signed=True)  
valor8 = int.from_bytes(b'\xFF\xFF', byteorder='big', signed=True)  
valor9 = int.from_bytes(b'\xFF\xFF\A3\67', byteorder='big')  
print('valor1={}   \n valor2={} \n valor3={} \n valor4={}  \n valor5={} \n valor6={}  \n valor7={}  \n valor8={} \n valor9 {}' .format(valor1, valor2, valor3,valor4, valor5, valor6,valor7,valor8,valor9))
valor1=7168   
 valor2=28 
 valor3=28 
 valor4=26  
 valor5=32767 
 valor6=-32768  
 valor7=-21563  
 valor8=-1 
 valor9 281472229520183

Repare que os parametros "little" e "big" definem a ordem de leitura dos bytes (esquerda para direita ou direita para esquerda). estamos acostumados a ter os digitos mais significativos na esquerda, então normalmente usamos o parâmetro "big". 
O parâmetro "signed" quando "true" reparte os possíveis valores formados pelos n Bytes sendo convertidos em duas metades. A primeira sendo crescente e positiva. A segunda sendo o complemento e negativo. Por exemplo: se estamos falando de 2 bytes, temos 65536 possíveis valores. Se usamos "signed=False" os números irão de 0 a 65535. Se usarmos "signed=True" a conversão se dará naturalmente de 0 a 32768 e a partir de então, o valor torna-se negativo, como se fosse subtraido -65536 de cada conversão. Isso permite valores positivos e negativos de -32768 a + 32768.

8) Você deve ter percebido no item 7 que para cada 8 bits são necessários 2 dígitos do Hexadecimal. Ou seja, um byte! Muitas vezes quando queremos expressar o conteúdo de um byte de memória (8 bits) é conveniente expressá-lo em hexadecimal, sendo apenas 2 dígitos, por exemplo 0x6B. Agora vamos fazer uma lista de bytes! Há 2 maneiras! Você pode criar uma lista correspondente de decimais e fazendo algo como listaBytes.append(bytes(int)). Alternativamente, em caso de pequenas listas você pode escrever cada um dos bytes. Para escrever o byte A4, por exemplo, você deve escrever b'\xA4'. P Código abaixo implementa 3 diferentes listas de bytes. tente entender o que foi feito.

#seu código
#lista1 de 0x00 a 0x1F
#lista2 de 0x09 a 0x10
#lista3 de 0x20 a 0x7F

# solução lista 1
listaBytes=[]
for x in range(0,12):
    listaBytes.append(bytes([x]))
print('lista1: {} ' .format(listaBytes))

#solução lista 2
listaBytes=[]
listaBytes=[b'\x09',b'\x0A',b'\x0B',b'\x0C',b'\x0D'b'\x0E'b'\x0F',b'\x10']
print(' \n lista2: {} ' .format(listaBytes))

#solução lista 3
listaBytes=[]
for x in range(int.from_bytes(b'\x30', byteorder='big'),int.from_bytes(b'\x3F', byteorder='big')):
    listaBytes.append(bytes([x]))
print('\n lista3: {} ' .format(listaBytes))

lista4 = listaBytes + listaBytes
print('\n lista4: {} ' .format(listaBytes))
lista1: [b'\x00', b'\x01', b'\x02', b'\x03', b'\x04', b'\x05', b'\x06', b'\x07', b'\x08', b'\t', b'\n', b'\x0b'] 

 lista2: [b'\t', b'\n', b'\x0b', b'\x0c', b'\r\x0e\x0f', b'\x10'] 

 lista3: [b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', b':', b';', b'<', b'=', b'>'] 

 lista4: [b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', b':', b';', b'<', b'=', b'>'] 

Você deve estar se perguntando sobre o porquê de vários caracteres terem aparecidos no print! Já ouviu a respeito de tabela ASCII, certo? É uma tabela que associa um caractere a um byte, possibilitando armazenar nossos textos em forma de bytes e também conver os bytes novamente para nosso idioma (não é qualquer um que lê em bytes). A função "print" do Python faz automaticamnete essa conversão de byte para caractere quando o byte a ser "printado" está entre 0x20 e 0x7F. Faça o teste com um print do byte, por exemplo, 0x4D. Esse byte, segundo a tabela (você pode encontrar a tabela ascii on line), é associado ao caractere "M". A função "print" sempre retornará o caractere associado ao seu respectivo byte quando este estiver entre 0x20 e 0x7F! Importante: Repare que esta associação vale para interface, ou seja, armazenar caracteres ou ler caracteres armazenados. Já quando queremos armazenar simplesmente um número em uma variável, por exemplo, 132, não precisamos armazenar um byte para cada caractere! Apenas precisamos de um único byte: 0x84 (equivale a 132)! A associação de 1 byte para cada caractere é apenas para nossa interface (prints e varíaveis contendo caracteres, como chars e strings).

Por fim, você também poderá usar bytes organizados em forma de "array", através do bytearray. Veja o exemplo abaixo.

prime_numbers = [2, 3, 5, 7]

# convert list to bytearray
byte_array1 = bytearray(prime_numbers)
byte_array2 = bytearray(prime_numbers)
byte_array = byte_array1 + byte_array2
print(byte_array)
bytearray(b'\x02\x03\x05\x07\x02\x03\x05\x07')

listaBytes=[]
for x in range(0,12):
    listaBytes.append(bytes([x]))
print('lista1: {} ' .format(listaBytes))

a1 = bytearra

 soma em bytes: b'\x00\x00\x00\x00\x01\xa6\xda\x01\xa6\xda' 

 soma em bytes: bytearray(b'\x00\x00\x00\x00\x01\xa6\xda\x01\xa6\xda')