Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Intensivão de Encoding

Elias Tandel
September 24, 2016

Intensivão de Encoding

Elias Tandel

September 24, 2016
Tweet

More Decks by Elias Tandel

Other Decks in Programming

Transcript

  1. Intensiv˜ ao de Encoding Ou: How I learned to stop

    worrying and love Python 3 Elias Tandel September 25, 2016 1
  2. Camadas de Abstra¸ c˜ ao E se eu quiser me

    comunicar com algu´ em do futuro? Ou que esteja longe? 3
  3. Sistemas de Escrita • alfab´ etico: Portuguˆ es • logossil´

    abico (logogr´ afico + sil´ abico): hieroglifos, sistemas chineses • abjad: Hebraico • etc. 4
  4. Sistemas de Escrita Mas meu computador s´ o entende n´

    umeros*; como fa¸ co pra guardar texto nele? 5
  5. Encoding! • encoding = codifica¸ c˜ ao • mapeia caracteres

    → n´ umeros → bits • muitas formas diferentes de fazer isso • cada forma ´ e um encoding diferente 7
  6. Exemplo • Direto: A = 1, B = 2, C

    = 3, ..., Z = 26 • Indireto: Z = 1, Y = 2, X = 3, ..., A = 26 8
  7. Exemplo • Direto: A = 1, B = 2, C

    = 3, ..., Z = 26 • Indireto: Z = 1, Y = 2, X = 3, ..., A = 26 • F O R A T E M E R 8
  8. Exemplo • Direto: A = 1, B = 2, C

    = 3, ..., Z = 26 • Indireto: Z = 1, Y = 2, X = 3, ..., A = 26 • F O R A T E M E R • 6 15 18 1 20 5 13 5 18 8
  9. Exemplo • Direto: A = 1, B = 2, C

    = 3, ..., Z = 26 • Indireto: Z = 1, Y = 2, X = 3, ..., A = 26 • F O R A T E M E R • 6 15 18 1 20 5 13 5 18 • 21 12 9 26 7 22 14 22 9 8
  10. Charsets - ASCII • American Standard Code for Information Interchange

    • Representa caracteres comuns no Inglˆ es + controle • 0 - 128 9
  11. Charsets - ISO-8859 • ISO-8859: Fam´ ılia de encodings de

    8 bits que expandem o ASCII: • iso-8859-1 / latin-1: Europa Ocidental (a gente! o/) 10
  12. Charsets - ISO-8859 • ISO-8859: Fam´ ılia de encodings de

    8 bits que expandem o ASCII: • iso-8859-1 / latin-1: Europa Ocidental (a gente! o/) • iso-8859-2 / latin-2: Europa Central • ... • iso-8859-11 : Tailandˆ es • ... • iso-8859-14 / latin-8 : Ga´ elico(s), Bret˜ ao etc. • ... 10
  13. Problema: • Texto que misture caracteres em charsets diferentes =

    caos • ` As vezes um charset para cada l´ ıngua / alfabeto etc. 11
  14. Unicode! • Unicode: Padr˜ ao internacional que tenta representar todos

    os caracteres (at´ e emojis!) • Vai de 0 a 4 294 967 296 (bem mais que 8 bits) 12
  15. Unicode! • Unicode: Padr˜ ao internacional que tenta representar todos

    os caracteres (at´ e emojis!) • Vai de 0 a 4 294 967 296 (bem mais que 8 bits) • Bem mais que encoding! Ligaduras, combina¸ c˜ oes de diacr´ ıticos, ordem de leitura etc. 12
  16. Unicode! • Caracteres s˜ ao a menor unidade de texto.

    • ”e”, ”´ e”, ”¸ c”, ”˜ a” e ”æ” s˜ ao caracteres 13
  17. Unicode! • Caracteres s˜ ao a menor unidade de texto.

    • ”e”, ”´ e”, ”¸ c”, ”˜ a” e ”æ” s˜ ao caracteres • Cada caracter tem um n´ umero associado chamado de code point 13
  18. Unicode! • Caracteres s˜ ao a menor unidade de texto.

    • ”e”, ”´ e”, ”¸ c”, ”˜ a” e ”æ” s˜ ao caracteres • Cada caracter tem um n´ umero associado chamado de code point • A tabela de code points ´ e ´ unica, mas as representa¸ c˜ oes bin´ arias s˜ ao diversas: • Normaliza¸ c˜ ao: ”´ e” vs ”e” + ”´ ” 13
  19. Unicode! • Caracteres s˜ ao a menor unidade de texto.

    • ”e”, ”´ e”, ”¸ c”, ”˜ a” e ”æ” s˜ ao caracteres • Cada caracter tem um n´ umero associado chamado de code point • A tabela de code points ´ e ´ unica, mas as representa¸ c˜ oes bin´ arias s˜ ao diversas: • Normaliza¸ c˜ ao: ”´ e” vs ”e” + ”´ ” • Unicode Transformation Formats 13
  20. Unicode Transformation Formats - UTF-32 • UTF-32 usa sempre 4

    bytes para representar qualquer code point 14
  21. Unicode Transformation Formats - UTF-32 • UTF-32 usa sempre 4

    bytes para representar qualquer code point • Vantagem: f´ acil ”pular” para qualquer caracter 14
  22. Unicode Transformation Formats - UTF-32 • UTF-32 usa sempre 4

    bytes para representar qualquer code point • Vantagem: f´ acil ”pular” para qualquer caracter • Desvantagem: Gasta mem´ oria ` a toa 14
  23. Unicode Transformation Formats - UTF-16 • UTF-16 usa 2 xor

    4 bytes para representar um code point 15
  24. Unicode Transformation Formats - UTF-16 • UTF-16 usa 2 xor

    4 bytes para representar um code point • Criado mais por quest˜ oes de compatibilidade 15
  25. Unicode Transformation Formats - UTF-16 • UTF-16 usa 2 xor

    4 bytes para representar um code point • Criado mais por quest˜ oes de compatibilidade • Hoje em dia usado s´ o por Java* e JS** 15
  26. Unicode Transformation Formats - UTF-8 • Criado por Rob Pike

    e Ken Thompson • UTF-8 usa de 1 a 4 bytes para representar um code point 16
  27. Unicode Transformation Formats - UTF-8 • Criado por Rob Pike

    e Ken Thompson • UTF-8 usa de 1 a 4 bytes para representar um code point • Vantagens: Economiza bastante espa¸ co e ´ e compat´ ıvel com ascii 16
  28. Unicode Transformation Formats - UTF-8 • Criado por Rob Pike

    e Ken Thompson • UTF-8 usa de 1 a 4 bytes para representar um code point • Vantagens: Economiza bastante espa¸ co e ´ e compat´ ıvel com ascii • Desvantagem: ”Pulos” s˜ ao O(n) 16
  29. Python! • Python 2: • unicode: tipo que representa sequˆ

    encias de caracteres • u’literal unicode’ 18
  30. Python! • Python 2: • unicode: tipo que representa sequˆ

    encias de caracteres • u’literal unicode’ • str: tipo que representa sequˆ encias de bytes • ’literal str’ 18
  31. Python! • Python 2: • unicode: tipo que representa sequˆ

    encias de caracteres • u’literal unicode’ • str: tipo que representa sequˆ encias de bytes • ’literal str’ • Python 3: • str: tipo que representa sequˆ encias de caracteres • ’literal str’ 18
  32. Python! • Python 2: • unicode: tipo que representa sequˆ

    encias de caracteres • u’literal unicode’ • str: tipo que representa sequˆ encias de bytes • ’literal str’ • Python 3: • str: tipo que representa sequˆ encias de caracteres • ’literal str’ • bytes: tipo que representa sequˆ encias de bytes • b’literal str’ 18
  33. Python! • Python 2: • valor.encode(): unicode → str •

    valor.decode(): str → unicode • Python 3: • valor.encode(): str → bytes • valor.decode(): bytes → str 19
  34. Ou seja, • encode / codificar: transformar caracteres em n´

    umeros • F O R A T E M E R → 6 15 18 1 20 5 13 5 18 20
  35. Ou seja, • encode / codificar: transformar caracteres em n´

    umeros • F O R A T E M E R → 6 15 18 1 20 5 13 5 18 • decode / decodificar: transformar n´ umeros em caracteres • F O R A T E M E R ← 21 12 9 26 7 22 14 22 9 20
  36. Remover Diacr´ ıticos • Problema: Remover diacr´ ıticos de um

    texto em portuguˆ es • Cora¸ c˜ ao → Coracao 21
  37. Remover Diacr´ ıticos • Problema: Remover diacr´ ıticos de um

    texto em portuguˆ es • Cora¸ c˜ ao → Coracao • Solu¸ c˜ ao: • 1) Normalizar NFKD • 2) Transformar para ascii ignorando os erros 21
  38. Remover Diacr´ ıticos - Python 2 e 3 from unicodedata

    import normalize def remove_diacritic(s): return (normalize(’NFKD’, s) .encode(’ascii’, ’ignore’) .decode(’ascii’)) 22
  39. UnicodeDecodeError • Problema: .decode() lan¸ ca UnicodeDecodeError • Causa: Vocˆ

    e est´ a tentando ler usando o encoding errado • Solu¸ c˜ ao: Descubra o encoding certo ou tente v´ arios at´ e achar 23
  40. UnicodeDecodeError - Python 2 e 3 def decode_me_maybe(encoded, encodings): for

    encoding in encodings: try: decoded = encoded.decode(encoding) except UnicodeDecodeError: pass else: return decoded else: raise UnicodeDecodeError encoded = get_encoded_string_from_unreliable_source() encodings = (’ascii’, ’iso-8859-1’, ’utf-32’, ’utf-16’, ’utf-8’) decoded = decode_me_maybe(encoded, encodings) 24
  41. UnicodeEncodeError - pt 1 • Problema: .encode() lan¸ ca UnicodeEncodeError

    • Causa: Existe um caracter que n˜ ao ´ e mapeado no encoding usado 25
  42. UnicodeEncodeError - pt 1 • Problema: .encode() lan¸ ca UnicodeEncodeError

    • Causa: Existe um caracter que n˜ ao ´ e mapeado no encoding usado • Solu¸ c˜ ao: Ache um encoding que suporte esse caracter (se poss´ ıvel) 25
  43. UnicodeEncodeError - pt 2 • Problema: file.write() lan¸ ca UnicodeEncodeError

    • Causa: • Vocˆ e est´ a usando Python 2 • Vocˆ e est´ a tentando escrever um objeto unicode 26
  44. UnicodeEncodeError - pt 2 • Problema: file.write() lan¸ ca UnicodeEncodeError

    • Causa: • Vocˆ e est´ a usando Python 2 • Vocˆ e est´ a tentando escrever um objeto unicode • Arquivos s˜ ao sequencias de bytes 26
  45. UnicodeEncodeError - pt 2 • Problema: file.write() lan¸ ca UnicodeEncodeError

    • Causa: • Vocˆ e est´ a usando Python 2 • Vocˆ e est´ a tentando escrever um objeto unicode • Arquivos s˜ ao sequencias de bytes • Ent˜ ao Python precisa fazer encode 26
  46. UnicodeEncodeError - pt 2 • Problema: file.write() lan¸ ca UnicodeEncodeError

    • Causa: • Vocˆ e est´ a usando Python 2 • Vocˆ e est´ a tentando escrever um objeto unicode • Arquivos s˜ ao sequencias de bytes • Ent˜ ao Python precisa fazer encode • Vocˆ e n˜ ao disse nada, Python assumiu ascii 26
  47. UnicodeEncodeError - pt 2 • Problema: file.write() lan¸ ca UnicodeEncodeError

    • Causa: • Vocˆ e est´ a usando Python 2 • Vocˆ e est´ a tentando escrever um objeto unicode • Arquivos s˜ ao sequencias de bytes • Ent˜ ao Python precisa fazer encode • Vocˆ e n˜ ao disse nada, Python assumiu ascii • Vide pt 1 26
  48. UnicodeEncodeError - pt 2 • Problema: file.write() lan¸ ca UnicodeEncodeError

    • Causa: • Vocˆ e est´ a usando Python 2 • Vocˆ e est´ a tentando escrever um objeto unicode • Arquivos s˜ ao sequencias de bytes • Ent˜ ao Python precisa fazer encode • Vocˆ e n˜ ao disse nada, Python assumiu ascii • Vide pt 1 26
  49. UnicodeEncodeError - pt 2 - Solu¸ c˜ ao 2 import

    codecs with codecs.open(’filename’, ’w’, ’utf-8’) as f: f.write(value) 28
  50. Windows-1252 • Problema: Windows-1252 vs ISO-8859-1 • Windows-1252 ´ e

    parte de outra familia que extende o ASCII • Windows-1252 ´ e quase igual ao latin-1 exceto por 32 caracteres • A galera n˜ ao sabe a diferen¸ ca e acha que s˜ ao a mesma coisa 29
  51. Windows-1252 • Problema: Windows-1252 vs ISO-8859-1 • Windows-1252 ´ e

    parte de outra familia que extende o ASCII • Windows-1252 ´ e quase igual ao latin-1 exceto por 32 caracteres • A galera n˜ ao sabe a diferen¸ ca e acha que s˜ ao a mesma coisa • ”Solu¸ c˜ ao”: • HTML5 recomenda que ISO-8859-1 seja tratado como windows-1252 29
  52. Windows-1252 • Problema: Windows-1252 vs ISO-8859-1 • Windows-1252 ´ e

    parte de outra familia que extende o ASCII • Windows-1252 ´ e quase igual ao latin-1 exceto por 32 caracteres • A galera n˜ ao sabe a diferen¸ ca e acha que s˜ ao a mesma coisa • ”Solu¸ c˜ ao”: • HTML5 recomenda que ISO-8859-1 seja tratado como windows-1252 • Trate do jeito certo em outras situa¸ c˜ oes 29
  53. Windows-1252 • Problema: Windows-1252 vs ISO-8859-1 • Windows-1252 ´ e

    parte de outra familia que extende o ASCII • Windows-1252 ´ e quase igual ao latin-1 exceto por 32 caracteres • A galera n˜ ao sabe a diferen¸ ca e acha que s˜ ao a mesma coisa • ”Solu¸ c˜ ao”: • HTML5 recomenda que ISO-8859-1 seja tratado como windows-1252 • Trate do jeito certo em outras situa¸ c˜ oes • Boa sorte 29
  54. Li¸ c˜ oes para a vida • Use Python 3

    • Use Python 3 • Na d´ uvida, use utf-8 30
  55. Li¸ c˜ oes para a vida • Use Python 3

    • Use Python 3 • Na d´ uvida, use utf-8 • Decodifique assim que poss´ ıvel 30
  56. Li¸ c˜ oes para a vida • Use Python 3

    • Use Python 3 • Na d´ uvida, use utf-8 • Decodifique assim que poss´ ıvel • Codifique s´ o quando necess´ ario 30
  57. Li¸ c˜ oes para a vida • Use Python 3

    • Use Python 3 • Na d´ uvida, use utf-8 • Decodifique assim que poss´ ıvel • Codifique s´ o quando necess´ ario • Seja consistente! (i.e. n˜ ao misture tipos de string) 30
  58. Li¸ c˜ oes para a vida • Use Python 3

    • Use Python 3 • Na d´ uvida, use utf-8 • Decodifique assim que poss´ ıvel • Codifique s´ o quando necess´ ario • Seja consistente! (i.e. n˜ ao misture tipos de string) • Use Python 3 30
  59. Li¸ c˜ oes para a vida • Use Python 3

    • Use Python 3 • Na d´ uvida, use utf-8 • Decodifique assim que poss´ ıvel • Codifique s´ o quando necess´ ario • Seja consistente! (i.e. n˜ ao misture tipos de string) • Use Python 3 30