{"id":2019,"date":"2020-11-19T11:45:52","date_gmt":"2020-11-19T14:45:52","guid":{"rendered":"https:\/\/www.ufrgs.br\/gespla\/?p=2019"},"modified":"2021-03-09T13:10:17","modified_gmt":"2021-03-09T16:10:17","slug":"quatro-niveis-de-programacao-em-pesquisa","status":"publish","type":"post","link":"https:\/\/www.ufrgs.br\/gespla\/2020\/11\/19\/quatro-niveis-de-programacao-em-pesquisa\/","title":{"rendered":"Quatro n\u00edveis de programa\u00e7\u00e3o em pesquisa"},"content":{"rendered":"<p>por <strong>Ipor\u00e3 Possantti<\/strong>, Engenheiro Ambiental, Mestre e doutorando em Recursos H\u00eddricos e Saneamento Ambiental (IPH\/UFRGS).<\/p>\n<p>Em diversas \u00e1reas de pesquisa, novas ferramentas s\u00e3o desenvolvidas na forma de c\u00f3digos de computador. N\u00e3o \u00e9 diferente na \u00e1rea de recursos h\u00eddricos, principalmente em hidrologia e planejamento, onde modelos de otimiza\u00e7\u00e3o, simula\u00e7\u00e3o e processamento de dados s\u00e3o largamente empregados. Nesse post \u00e9 feita uma proposta de classifica\u00e7\u00e3o dessas ferramentas. O objetivo \u00e9 criar uma terminologia pr\u00e1tica. Exemplos s\u00e3o dados com Python.<\/p>\n<p><!--more--><\/p>\n<p><strong>Leia e execute os c\u00f3digos desse post no Google Colab<\/strong><\/p>\n<p>Esse post foi originalmente escrito para o <a href=\"http:\/\/colab.research.google.com\/\" target=\"_blank\" rel=\"noopener noreferrer\">Google Colab<\/a>. Nessa plataforma, se voc\u00ea acessar pela sua conta google, \u00e9 poss\u00edvel executar os c\u00f3digos diretamente no navegador, sem nenhuma configura\u00e7\u00e3o.<\/p>\n<p>Link para visualizar o post no Google Colab:<\/p>\n<p><a href=\"https:\/\/colab.research.google.com\/drive\/1sL9SWgZWpSlJxN6ZSZXXD3zqf9v0BzTh?usp=sharing\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/colab.research.google.com\/drive\/1sL9SWgZWpSlJxN6ZSZXXD3zqf9v0BzTh?usp=sharing<\/a><\/p>\n<p>&nbsp;<\/p>\n<h1>Pesquisa e programa\u00e7\u00e3o de c\u00f3digos<\/h1>\n<p>Em diversas \u00e1reas de pesquisa, novas ferramentas s\u00e3o desenvolvidas na forma de c\u00f3digos de computador. N\u00e3o \u00e9 diferente na \u00e1rea de recursos h\u00eddricos, principalmente em hidrologia e planejamento, onde modelos de otimiza\u00e7\u00e3o, simula\u00e7\u00e3o e processamento de dados s\u00e3o largamente empregados.<\/p>\n<p>Nesse post \u00e9 feita uma proposta de classifica\u00e7\u00e3o dessas ferramentas. O objetivo \u00e9 criar uma terminologia pr\u00e1tica. Exemplos s\u00e3o dados com Python.<\/p>\n<h1>N\u00edvel 1: <em>hard coding<\/em><\/h1>\n<p>\u00c9 a forma mais simples de programar um c\u00f3digo de processamento. Os dados est\u00e3o diretamente escritos junto com o c\u00f3digo de processamento, atribu\u00eddos a vari\u00e1veis, e n\u00e3o existem n\u00edveis hier\u00e1rquicos de c\u00f3digos, como as fun\u00e7\u00f5es. Qualquer modifica\u00e7\u00e3o deve ser feita de forma exaustiva no c\u00f3digo inteiro. Por isso, <em>hard coding<\/em> (&#8220;programa\u00e7\u00e3o dura&#8221;). Os resultados s\u00e3o impressos na tela do computador. Assim, existem duas se\u00e7\u00f5es: a se\u00e7\u00e3o de processamento e a se\u00e7\u00e3o de impress\u00e3o em tela.<\/p>\n<div id=\"attachment_2022\" style=\"width: 706px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.ufrgs.br\/gespla\/wp-content\/uploads\/2020\/10\/hard.jpg\" target=\"_blank\" rel=\"noopener noreferrer\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-2022\" class=\"wp-image-2022 size-large\" src=\"https:\/\/www.ufrgs.br\/gespla\/wp-content\/uploads\/2020\/10\/hard-1024x512.jpg\" alt=\"\" width=\"696\" height=\"348\" srcset=\"https:\/\/www.ufrgs.br\/gespla\/wp-content\/uploads\/2020\/10\/hard-1024x512.jpg 1024w, https:\/\/www.ufrgs.br\/gespla\/wp-content\/uploads\/2020\/10\/hard-300x150.jpg 300w, https:\/\/www.ufrgs.br\/gespla\/wp-content\/uploads\/2020\/10\/hard-768x384.jpg 768w, https:\/\/www.ufrgs.br\/gespla\/wp-content\/uploads\/2020\/10\/hard.jpg 1104w\" sizes=\"(max-width: 696px) 100vw, 696px\" \/><\/a><p id=\"caption-attachment-2022\" class=\"wp-caption-text\">Esquema de um c\u00f3digo n\u00edvel 1. Elabora\u00e7\u00e3o do autor.<\/p><\/div>\n<p>Um exemplo simples, em Python:<\/p>\n<figure>\n<pre class=\"prettyprint\" data-lang=\"scss\"><strong>[in:]<\/strong>\r\n<em># processamento<\/em>\r\ns = 1 + 2\r\n<em># impress\u00e3o em tela<\/em>\r\n<strong>print<\/strong>(s)\r\n\r\n<strong>[out:]<\/strong>\r\n&gt;&gt;&gt; 3\r\n<\/pre>\n<\/figure>\n<h1>N\u00edvel 2: <em>soft coding<\/em><\/h1>\n<p>Aqui surgem as <strong>fun\u00e7\u00f5es<\/strong>. As fun\u00e7\u00f5es executam <em>opera\u00e7\u00f5es unit\u00e1rias<\/em>, que podem ser convocadas em muitas partes do c\u00f3digo. Assim, uma modifica\u00e7\u00e3o na defini\u00e7\u00e3o fun\u00e7\u00e3o \u00e9 automaticamente atualizada em todas as partes do c\u00f3digo que ela \u00e9 convocada. Os dados ainda s\u00e3o escritos no c\u00f3digo, mas s\u00e3o passados como <strong>par\u00e2metros<\/strong> das fun\u00e7\u00f5es. Dessa maneira, uma terceira se\u00e7\u00e3o \u00e9 adicionada: a se\u00e7\u00e3o que define as fun\u00e7\u00f5es<\/p>\n<div id=\"attachment_2025\" style=\"width: 706px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.ufrgs.br\/gespla\/wp-content\/uploads\/2020\/10\/soft.jpg\" target=\"_blank\" rel=\"noopener noreferrer\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-2025\" class=\"wp-image-2025 size-large\" src=\"https:\/\/www.ufrgs.br\/gespla\/wp-content\/uploads\/2020\/10\/soft-1024x589.jpg\" alt=\"\" width=\"696\" height=\"400\" srcset=\"https:\/\/www.ufrgs.br\/gespla\/wp-content\/uploads\/2020\/10\/soft-1024x589.jpg 1024w, https:\/\/www.ufrgs.br\/gespla\/wp-content\/uploads\/2020\/10\/soft-300x173.jpg 300w, https:\/\/www.ufrgs.br\/gespla\/wp-content\/uploads\/2020\/10\/soft-768x442.jpg 768w, https:\/\/www.ufrgs.br\/gespla\/wp-content\/uploads\/2020\/10\/soft.jpg 1132w\" sizes=\"(max-width: 696px) 100vw, 696px\" \/><\/a><p id=\"caption-attachment-2025\" class=\"wp-caption-text\">Esquema de um c\u00f3digo n\u00edvel 2, quando fun\u00e7\u00f5es passam a fazer opera\u00e7\u00f5es unit\u00e1rias, aumentando a efici\u00eancia de programa\u00e7\u00e3o. Elabora\u00e7\u00e3o do autor.<\/p><\/div>\n<p>No exemplo anterior, o processamento poderia fazer uso de uma fun\u00e7\u00e3o que soma dois n\u00fameros quaisquer, passados como par\u00e2metros. Essa fun\u00e7\u00e3o \u00e9 convocada no c\u00f3digo de processamento:<\/p>\n<figure>\n<pre class=\"prettyprint\" data-lang=\"scss\"><strong>[in:]<\/strong>\r\n<em># defini\u00e7\u00e3o de fun\u00e7\u00e3o:<\/em>\r\ndef <strong>somar<\/strong>(n1, n2):\r\n<em>\"\"\"\r\n  uma fun\u00e7\u00e3o que soma dois n\u00fameros, passados como par\u00e2metros\r\n  :param n1: primeiro n\u00famero\r\n  :param n2: segundo n\u00famero\r\n  :return : soma dos dois n\u00fameros\r\n  \"\"\"<\/em>\r\n  def_s = n1 + n2\r\n  <strong>return<\/strong> def_s\r\n \r\n<em># processamento<\/em>\r\na = 1\r\nb = 2\r\ns = <strong>somar<\/strong>(n1=a, n2=b)\r\n<em># impress\u00e3o em tela<\/em>\r\n<strong>print<\/strong>(s)\r\n\r\n<strong>[out:]<\/strong>\r\n&gt;&gt;&gt; 3\r\n<\/pre>\n<\/figure>\n<h1>N\u00edvel 3: <em>Input, Process, Output<\/em> (IPO)<\/h1>\n<p>O terceiro n\u00edvel consiste na separa\u00e7\u00e3o completa daquilo que \u00e9 dado e aquilo que \u00e9 c\u00f3digo. Isso requer a importa\u00e7\u00e3o de dados que est\u00e3o armazenados em arquivos e a exporta\u00e7\u00e3o de dados para arquivos. Essas opera\u00e7\u00f5es de <strong><em>input<\/em><\/strong> e <strong><em>output<\/em><\/strong> (I\/O) podem ser feitas por fun\u00e7\u00f5es novas ou mesmo fun\u00e7\u00f5es de bibliotecas espec\u00edficas para isso (como a <code>&lt;pandas&gt;<\/code>, em Python). Isso adiciona pelo menos mais duas se\u00e7\u00f5es: uma se\u00e7\u00e3o de importa\u00e7\u00e3o e outra de exporta\u00e7\u00e3o, resultando na estrutura <strong>IPO<\/strong> &#8211; <em>input, process, output<\/em>.<\/p>\n<div id=\"attachment_2023\" style=\"width: 706px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.ufrgs.br\/gespla\/wp-content\/uploads\/2020\/10\/io.jpg\" target=\"_blank\" rel=\"noopener noreferrer\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-2023\" class=\"wp-image-2023 size-large\" src=\"https:\/\/www.ufrgs.br\/gespla\/wp-content\/uploads\/2020\/10\/io-1024x486.jpg\" alt=\"\" width=\"696\" height=\"330\" srcset=\"https:\/\/www.ufrgs.br\/gespla\/wp-content\/uploads\/2020\/10\/io-1024x486.jpg 1024w, https:\/\/www.ufrgs.br\/gespla\/wp-content\/uploads\/2020\/10\/io-300x142.jpg 300w, https:\/\/www.ufrgs.br\/gespla\/wp-content\/uploads\/2020\/10\/io-768x365.jpg 768w, https:\/\/www.ufrgs.br\/gespla\/wp-content\/uploads\/2020\/10\/io.jpg 1411w\" sizes=\"(max-width: 696px) 100vw, 696px\" \/><\/a><p id=\"caption-attachment-2023\" class=\"wp-caption-text\">Esquema de um c\u00f3digo n\u00edvel 3, quando os dados s\u00e3o completamente separados do c\u00f3digo. Elabora\u00e7\u00e3o do autor.<\/p><\/div>\n<p>Voltando ao nosso exemplo, considere que existe um arquivo de texto chamado input.txt que possui os n\u00famero que queremos somar. Os dados est\u00e3o organizados separados por &#8220;;&#8221; da sequinte forma (A e B s\u00e3o os r\u00f3tulos dos n\u00fameros):<\/p>\n<figure>\n<pre class=\"prettyprint\" data-lang=\"scss\">;A ;B\r\n0;1;2\r\n<\/pre>\n<\/figure>\n<p>O c\u00f3digo abaixo cria o arquivo de entrada para nosso exemplo:<\/p>\n<figure>\n<pre class=\"prettyprint\" data-lang=\"scss\"><strong>[in:]<\/strong>\r\n<strong>import<\/strong> pandas <strong>as<\/strong> pd\r\ndct = {'A': 1, 'B': 2}\r\ndf = pd.<strong>DataFrame<\/strong>(dct, index={'': 0})\r\ndf.<strong>to_csv<\/strong>('.\/input.txt', sep=';')\r\n<\/pre>\n<\/figure>\n<p>Para o c\u00f3digo funcionar, a formata\u00e7\u00e3o dos dados no arquivo de entrada precisa ser previamente conhecida. Isso requer um certo grau de documenta\u00e7\u00e3o, tanto na forma de coment\u00e1rios no c\u00f3digo como em documentos armazenados em reposit\u00f3rio na internet, como o <a href=\"https:\/\/github.com\/\" target=\"_blank\" rel=\"noopener noreferrer\">GitHub<\/a>.<\/p>\n<p>O valor da soma, por sua vez, dever\u00e1 ser exportado para um arquivo de texto tamb\u00e9m, chamado output.txt. Dever\u00e1 ter a mesma formata\u00e7\u00e3o do arquivo de entrada, mas com um campo adicional chamado &#8220;S&#8221;.<\/p>\n<p>Usando <code>&lt;pandas&gt;<\/code>, o problema fica assim:<\/p>\n<figure>\n<pre class=\"prettyprint\" data-lang=\"scss\"><strong>[in:]<\/strong>\r\n<strong>import<\/strong> pandas <strong>as<\/strong> pd  <em># importar biblioteca pandas<\/em>\r\n \r\n<em># defini\u00e7\u00e3o de fun\u00e7\u00e3o:<\/em>\r\ndef <strong>somar<\/strong>(n1, n2):\r\n    <em>\"\"\"\r\n    uma fun\u00e7\u00e3o que soma dois n\u00fameros, passados como par\u00e2metros\r\n    :param n1: primeiro n\u00famero\r\n    :param n2: segundo n\u00famero\r\n    :return : soma dos dois n\u00fameros\r\n    \"\"\"<\/em>\r\n    def_s = n1 + n2\r\n    <strong>return<\/strong> def_s\r\n \r\n<em># importar dados de input.txt<\/em>\r\ninput_file =  '.\/input.txt'\r\n<strong>print<\/strong>('Importar dados de: {}'.format(input_file))\r\nindf = pd.<strong>read_csv<\/strong>(input_file, sep=';')  <em># obter DataFrame\r\n<\/em>a = indf['A'][0] <em># obter o primeiro valor da coluna 'A '\r\n<\/em>b = indf['B'][0]  <em># obter o primeiro valor da coluna 'B '\r\n<\/em><strong>print<\/strong>('Primeiro n\u00famero: {}'.format(a))\r\n<strong>print<\/strong>('Segundo n\u00famero: {}'.format(b))\r\n<strong>print<\/strong>('&gt;&gt; OK')\r\n \r\n<em># processamento<\/em>\r\ns = <strong>somar<\/strong>(n1=a, n2=b)\r\n<strong>print<\/strong>('\\nSoma: {} + {} = {}\\n'.format(a, b, s))\r\n \r\n<em># exportar dados para output.txt<\/em>\r\noutput_file = '.\/output.txt'\r\n<strong>print<\/strong>('Exportar dados para: {}'.format(output_file))\r\noutdf = pd.<strong>DataFrame<\/strong>({\"A\": a, \"B\": b, \"S\": s}, index={\"\": 0})  <em># criar DataFrame<\/em>\r\noutdf.<strong>to_csv<\/strong>(output_file, sep=';', index=False)  <em># exportar para<\/em> \r\n<strong>print<\/strong>('&gt;&gt; OK')\r\n\r\n<strong>[out:]<\/strong>\r\n&gt;&gt;&gt; Importar dados de: .\/input.txt\r\n&gt;&gt;&gt; Primeiro n\u00famero: 1\r\n&gt;&gt;&gt; Segundo n\u00famero: 2\r\n&gt;&gt;&gt; &gt;&gt; OK\r\n&gt;&gt;&gt; Soma: 1 + 2 = 3\r\n&gt;&gt;&gt; Exportar dados para: .\/output.txt\r\n&gt;&gt;&gt; &gt;&gt; OK\r\n<\/pre>\n<\/figure>\n<h1>N\u00edvel 4: Aplica\u00e7\u00e3o<\/h1>\n<p>Na maioria dos casos de pesquisa, o n\u00edvel 3 de programa\u00e7\u00e3o j\u00e1 \u00e9 suficiente: importa, processa e exporta (o modelo input, process, output &#8211; IPO). Mas \u00e9 poss\u00edvel direcionar o c\u00f3digo para um p\u00fablico maior, pensando no modelo de aplica\u00e7\u00e3o.<\/p>\n<p>Uma aplica\u00e7\u00e3o tem os seguinte objetivo:<\/p>\n<p><strong>Ampliar a quantidade de usu\u00e1rios da ferramenta.<\/strong><\/p>\n<p>Portanto, para ter sucesso, uma aplica\u00e7\u00e3o precisa deixar tudo extremamente f\u00e1cil e intuitivo. Todas as funcionalidades devem estar bem documentadas e manuais com exemplos pr\u00e1ticos devem ser disponibilizados, de prefer\u00eancia em uma p\u00e1gina da internet que hospeda o projeto da aplica\u00e7\u00e3o.<\/p>\n<p>O modelo de aplica\u00e7\u00e3o demanda alguma forma de intera\u00e7\u00e3o com o usu\u00e1rio da aplica\u00e7\u00e3o, seja per uma interface de terminal (TUI) ou mesmo por uma interface gr\u00e1fica (GUI). A interface consiste no frontend da aplica\u00e7\u00e3o. Com essa interface, o usu\u00e1rio determina comandos ou manualmente indica arquivos para serem processados. O usu\u00e1rio precisa ser considerado de forma gen\u00e9rica, leigo, que n\u00e3o precisa entender como o programa funciona.<\/p>\n<p>Uma vez autorizado pelo usu\u00e1rio, o processamento \u00e9 feito pelo backend da aplica\u00e7\u00e3o. Assim, uma aplica\u00e7\u00e3o consiste em uma forma interativa de acionar os c\u00f3digos IPO por um usu\u00e1rio &#8220;leigo&#8221;.<\/p>\n<div id=\"attachment_2027\" style=\"width: 514px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.ufrgs.br\/gespla\/wp-content\/uploads\/2020\/10\/UI.jpg\" target=\"_blank\" rel=\"noopener noreferrer\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-2027\" class=\"wp-image-2027 \" src=\"https:\/\/www.ufrgs.br\/gespla\/wp-content\/uploads\/2020\/10\/UI-300x125.jpg\" alt=\"\" width=\"504\" height=\"210\" srcset=\"https:\/\/www.ufrgs.br\/gespla\/wp-content\/uploads\/2020\/10\/UI-300x125.jpg 300w, https:\/\/www.ufrgs.br\/gespla\/wp-content\/uploads\/2020\/10\/UI-768x321.jpg 768w, https:\/\/www.ufrgs.br\/gespla\/wp-content\/uploads\/2020\/10\/UI.jpg 1011w\" sizes=\"(max-width: 504px) 100vw, 504px\" \/><\/a><p id=\"caption-attachment-2027\" class=\"wp-caption-text\">Esquema de um c\u00f3digo n\u00edvel 4. Esse n\u00edvel requer um frontend para a intera\u00e7\u00e3o com o usu\u00e1rio, que \u00e9 considerado leigo em programa\u00e7\u00e3o. Elabora\u00e7\u00e3o do autor.<\/p><\/div>\n<h2>TUI: interface baseada em terminal de comandos<\/h2>\n<p>Uma TUI (Terminal-based User Interface) pode ser programada de forma bem simples com Python. Primeiramente \u00e9 preciso definir um &#8220;la\u00e7o infinito&#8221; que \u00e9 apenas quebrado com um comando de sa\u00edda fornecida pelo usu\u00e1rio.<\/p>\n<div id=\"attachment_2026\" style=\"width: 642px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.ufrgs.br\/gespla\/wp-content\/uploads\/2020\/10\/tui.jpg\" target=\"_blank\" rel=\"noopener noreferrer\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-2026\" class=\"wp-image-2026 size-full\" src=\"https:\/\/www.ufrgs.br\/gespla\/wp-content\/uploads\/2020\/10\/tui.jpg\" alt=\"\" width=\"632\" height=\"469\" srcset=\"https:\/\/www.ufrgs.br\/gespla\/wp-content\/uploads\/2020\/10\/tui.jpg 632w, https:\/\/www.ufrgs.br\/gespla\/wp-content\/uploads\/2020\/10\/tui-300x223.jpg 300w\" sizes=\"(max-width: 632px) 100vw, 632px\" \/><\/a><p id=\"caption-attachment-2026\" class=\"wp-caption-text\">Esquema de uma TUI, interface baseada em terminal. Elabora\u00e7\u00e3o do autor.<\/p><\/div>\n<p>Um exemplo em Python:<\/p>\n<figure>\n<pre class=\"prettyprint\" data-lang=\"scss\"><strong>[in:]<\/strong>\r\n<em># a TUI como um fun\u00e7\u00e3o<\/em>\r\ndef <strong>tui<\/strong>():\r\n    <em># entra no la\u00e7o infinito:<\/em>\r\n    <strong>while True<\/strong>:                 \r\n        <em># mensagem de inicializa\u00e7\u00e3o:\r\n<\/em>        <strong>print<\/strong>('\\n&gt;&gt; Ol\u00e1! Essa \u00e9 uma interface de terminal')\r\n        <em># fun\u00e7\u00e3o input() permite o usu\u00e1rio inserir texto no c\u00f3digo\r\n<\/em>        command = <strong>input<\/strong>('\\n&gt;&gt; Voce deseja fechar o programa? (s \/ n): ')\r\n        <em># condi\u00e7\u00f5es de parada<\/em> \r\n        <strong>if<\/strong> command.upper() == 'S':          \r\n            <em># mensagem para sa\u00edda<\/em>\r\n            <strong>print<\/strong>('\\n&gt;&gt; Ok, fechando o programa...')\r\n            <strong>break<\/strong>  <em># quebra o la\u00e7o<\/em>\r\n        <strong>else<\/strong>:\r\n            <strong>print<\/strong>('\\n&gt;&gt; Ok, continuamos aqui!')\r\n \r\n<em># fun\u00e7\u00e3o da interface \u00e9 convocada:<\/em>\r\n<strong>tui<\/strong>()\r\n\r\n<strong>[out:]<\/strong>\r\n&gt;&gt; Ol\u00e1! Essa \u00e9 uma interface de terminal\r\n&gt;&gt; Voce deseja fechar o programa? (s \/ n): d\r\n&gt;&gt; Ok, continuamos aqui!\r\n&gt;&gt; Ol\u00e1! Essa \u00e9 uma interface de terminal\r\n&gt;&gt; Voce deseja fechar o programa? (s \/ n): s\r\n&gt;&gt; Ok, fechando o programa...\r\n\r\n<\/pre>\n<\/figure>\n<h2>Valida\u00e7\u00e3o das entradas do usu\u00e1rio<\/h2>\n<p>O problema das interfaces \u00e9 que precisam lidar com as falhas humanas. As entradas dos usu\u00e1rios precisam ser validadas.<\/p>\n<p>Por exemplo, suponha que uma interface pe\u00e7a para o usu\u00e1rio digitar o caminho de um arquivo. Se o arquivo digitado n\u00e3o existir, por uma falha de digita\u00e7\u00e3o, o programa inteiro ir\u00e1 travar. \u00c9 preciso bolar protocolos de valida\u00e7\u00e3o diversos para garantir que os usu\u00e1rios consigam usar o programa. Nesse caso do caminho do arquivo, deve-se obviamente checar se o arquivo existe antes de continuar o programa. Se n\u00e3o existir, a interface deve retornar uma mensagem de erro para o usu\u00e1rio.<\/p>\n<h2>TUI com menus<\/h2>\n<p>Uma forma que eu acho particularmente simples e \u00fatil de desenvolver uma TUI \u00e9 com o uso de menus.<\/p>\n<p>Considere uma aplica\u00e7\u00e3o que \u00e9 uma calculadora simples: soma, subtrai, multiplica e divide. A TUI apresenta para o usu\u00e1rio um menu das opera\u00e7\u00f5es dispon\u00edveis. O usu\u00e1rio precisa digitar uma &#8220;chave&#8221; para acionar cada opera\u00e7\u00e3o. Com base na &#8220;chave&#8221; entrada, a opera\u00e7\u00e3o \u00e9 acionada, por meio de uma ou mais fun\u00e7\u00f5es que requerem do usu\u00e1rio que entre com os n\u00fameros. Precisam ser n\u00fameros, n\u00e3o textos. A TUI tamb\u00e9m precisa oferecer uma op\u00e7\u00e3o de &#8220;sair&#8221; do programa, para quando o usu\u00e1rio estiver j\u00e1 entediado.<\/p>\n<p>O c\u00f3digo para essa aplica\u00e7\u00e3o tem 211 linhas, por isso ser\u00e1 omitido aqui. Mas voc\u00ea pode <a href=\"https:\/\/colab.research.google.com\/drive\/1sL9SWgZWpSlJxN6ZSZXXD3zqf9v0BzTh?usp=sharing\" target=\"_blank\" rel=\"noopener noreferrer\">conferir e executar o c\u00f3digo no Google Colab<\/a>.<\/p>\n<p>Quando executada, essa aplica\u00e7\u00e3o tem a seguinte cara:<\/p>\n<figure>\n<pre class=\"prettyprint\" data-lang=\"scss\"><strong>[out:]<\/strong>\r\n************ CALCULADORA ************\r\n\r\n************ Menu ************\r\n\r\n Options                 Keys\r\n      Adi\u00e7\u00e3o...............0\r\n      Subtra\u00e7\u00e3o............1\r\n      Multiplica\u00e7\u00e3o........2\r\n      Divis\u00e3o..............3\r\n Exit program..............e\r\n\r\n&gt;&gt;&gt; Enter a menu key: 0\r\n&gt;&gt;&gt; OK\r\n\r\n******* Adi\u00e7\u00e3o *******\r\n\r\nDigite o primeiro n\u00famero!\r\nEntre um n\u00famero inteiro positivo: 2\r\n&gt;&gt;&gt; OK\r\nDigite o segundo n\u00famero!\r\nEntre um n\u00famero inteiro positivo: 3\r\n&gt;&gt;&gt; OK\r\n2 + 3 = 5\r\n\r\n************ CALCULADORA ************\r\n\r\n************ Menu ************\r\n\r\nOptions                 Keys\r\n      Adi\u00e7\u00e3o...............0\r\n      Subtra\u00e7\u00e3o............1\r\n      Multiplica\u00e7\u00e3o........2\r\n      Divis\u00e3o..............3\r\n Exit program..............e\r\n\r\n&gt;&gt;&gt; Enter a menu key: e\r\n&gt;&gt;&gt; OK\r\n&gt;&gt; Ok, fechando o programa...\r\n<\/pre>\n<\/figure>\n<h2>GUI: interface gr\u00e1fica<\/h2>\n<p>As interfaces gr\u00e1ficas de usu\u00e1rio (GUI) inserem no modelo de aplica\u00e7\u00e3o os objetos chamados widgets. Os widgets s\u00e3o classes e representam os itens program\u00e1veis da interface gr\u00e1fica, como as janelas, os bot\u00f5es, os r\u00f3tulos, os campos, as caixas de sele\u00e7\u00e3o, etc, etc.<\/p>\n<p>Exemplo de alguns widgets em uma GUI:<\/p>\n<div id=\"attachment_2028\" style=\"width: 459px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.ufrgs.br\/gespla\/wp-content\/uploads\/2020\/10\/widgets.jpg\" target=\"_blank\" rel=\"noopener noreferrer\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-2028\" class=\"wp-image-2028 \" src=\"https:\/\/www.ufrgs.br\/gespla\/wp-content\/uploads\/2020\/10\/widgets-300x257.jpg\" alt=\"\" width=\"449\" height=\"385\" srcset=\"https:\/\/www.ufrgs.br\/gespla\/wp-content\/uploads\/2020\/10\/widgets-300x257.jpg 300w, https:\/\/www.ufrgs.br\/gespla\/wp-content\/uploads\/2020\/10\/widgets.jpg 607w\" sizes=\"(max-width: 449px) 100vw, 449px\" \/><\/a><p id=\"caption-attachment-2028\" class=\"wp-caption-text\">Widgets de uma GUI. Fonte: Wikipedia.<\/p><\/div>\n<h2>Bibliotecas para GUI em Python<\/h2>\n<p>Em Python, existem diversas bibliotecas (pacotes) que oferecem widgets para GUI. O pacote &#8220;padr\u00e3o de f\u00e1brica&#8221; que vem junto quando se instala python para desktop \u00e9 o TkInter.<\/p>\n<p>Um tutorial simples para o TkInter:<\/p>\n<p><a href=\"https:\/\/www.dummies.com\/programming\/python\/using-tkinter-widgets-in-python\/\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/www.dummies.com\/programming\/python\/using-tkinter-widgets-in-python\/<\/a><\/p>\n<p>Lista completa de bibliotecas de GUI para Python:<\/p>\n<p><a href=\"https:\/\/wiki.python.org\/moin\/GuiProgramming\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/wiki.python.org\/moin\/GuiProgramming<\/a><\/p>\n<p>&nbsp;<\/p>\n<h2>Uma solu\u00e7\u00e3o pr\u00e1tica: GUIs que se parecem formul\u00e1rios<\/h2>\n<p>As GUI n\u00e3o precisam ser complexas. O InVEST, \u00e9 um software de mapeamento de servi\u00e7os ambientais e capital natural da Stanford University (<a href=\"https:\/\/naturalcapitalproject.stanford.edu\/software\/invest\">https:\/\/naturalcapitalproject.stanford.edu\/software\/invest<\/a> ) que oferece GUIs bem simplificadas para cada modelo.<\/p>\n<p>As GUIs se parecem com formul\u00e1rios onde o usu\u00e1rio aponta os arquivos de entrada e nomeia os arquivos de sa\u00edda. Um bot\u00e3o de execu\u00e7\u00e3o \u00e9 ativado assim que todas as entradas obrigat\u00f3rias s\u00e3o preenchidas.<\/p>\n<div id=\"attachment_2021\" style=\"width: 600px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.ufrgs.br\/gespla\/wp-content\/uploads\/2020\/10\/gui_INVEST.jpg\" target=\"_blank\" rel=\"noopener noreferrer\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-2021\" class=\"wp-image-2021 \" src=\"https:\/\/www.ufrgs.br\/gespla\/wp-content\/uploads\/2020\/10\/gui_INVEST.jpg\" alt=\"\" width=\"590\" height=\"575\" srcset=\"https:\/\/www.ufrgs.br\/gespla\/wp-content\/uploads\/2020\/10\/gui_INVEST.jpg 673w, https:\/\/www.ufrgs.br\/gespla\/wp-content\/uploads\/2020\/10\/gui_INVEST-300x292.jpg 300w\" sizes=\"(max-width: 590px) 100vw, 590px\" \/><\/a><p id=\"caption-attachment-2021\" class=\"wp-caption-text\">GUI do InVEST (modelo de produ\u00e7\u00e3o anual de \u00e1gua). Fonte: impress\u00e3o de tela do InVEST.<\/p><\/div>\n<p>No QGIS (<a href=\"https:\/\/www.qgis.org\">https:\/\/www.qgis.org<\/a> ) a abordagem \u00e9 id\u00eantica, os geoalgoritmos possuem um <em>frontend<\/em> na forma de GUIs simplificadas, que se parecem formul\u00e1rios.<\/p>\n<div id=\"attachment_2024\" style=\"width: 574px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.ufrgs.br\/gespla\/wp-content\/uploads\/2020\/10\/qgis.jpg\" target=\"_blank\" rel=\"noopener noreferrer\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-2024\" class=\"wp-image-2024 \" src=\"https:\/\/www.ufrgs.br\/gespla\/wp-content\/uploads\/2020\/10\/qgis.jpg\" alt=\"\" width=\"564\" height=\"598\" srcset=\"https:\/\/www.ufrgs.br\/gespla\/wp-content\/uploads\/2020\/10\/qgis.jpg 692w, https:\/\/www.ufrgs.br\/gespla\/wp-content\/uploads\/2020\/10\/qgis-283x300.jpg 283w\" sizes=\"(max-width: 564px) 100vw, 564px\" \/><\/a><p id=\"caption-attachment-2024\" class=\"wp-caption-text\">GUI do QGIS para executar geoalgoritmo de interpola\u00e7\u00e3o. Fonte: impress\u00e3o de tela do QGIS.<\/p><\/div>\n<p>Quem sabe esse seja o melhor um grupo de pesquisa possa oferecer sem se transformar uma empresa de <em>software<\/em>!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>por Ipor\u00e3 Possantti, Engenheiro Ambiental, Mestre e doutorando em Recursos H\u00eddricos e Saneamento Ambiental (IPH\/UFRGS). Em diversas \u00e1reas de pesquisa, novas ferramentas s\u00e3o desenvolvidas na forma de c\u00f3digos de computador. N\u00e3o \u00e9 diferente na \u00e1rea de recursos h\u00eddricos, principalmente em hidrologia e planejamento, onde modelos de otimiza\u00e7\u00e3o, simula\u00e7\u00e3o e processamento de dados s\u00e3o largamente empregados.<\/p><\/div>\n<div class=\"blog-btn\"><a href=\"https:\/\/www.ufrgs.br\/gespla\/2020\/11\/19\/quatro-niveis-de-programacao-em-pesquisa\/\" class=\"home-blog-btn\">Ler mais<\/a><\/p>\n","protected":false},"author":3,"featured_media":2040,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_uag_custom_page_level_css":"","ngg_post_thumbnail":0,"footnotes":""},"categories":[14,39],"tags":[42,40,41],"class_list":["post-2019","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-conceitos","category-ferramentas","tag-ferramentas","tag-programacao","tag-python"],"uagb_featured_image_src":{"full":["https:\/\/www.ufrgs.br\/gespla\/wp-content\/uploads\/2020\/10\/capa2.jpg",1728,947,false],"thumbnail":["https:\/\/www.ufrgs.br\/gespla\/wp-content\/uploads\/2020\/10\/capa2-150x150.jpg",150,150,true],"medium":["https:\/\/www.ufrgs.br\/gespla\/wp-content\/uploads\/2020\/10\/capa2-300x164.jpg",300,164,true],"medium_large":["https:\/\/www.ufrgs.br\/gespla\/wp-content\/uploads\/2020\/10\/capa2-768x421.jpg",696,382,true],"large":["https:\/\/www.ufrgs.br\/gespla\/wp-content\/uploads\/2020\/10\/capa2-1024x561.jpg",696,381,true],"1536x1536":["https:\/\/www.ufrgs.br\/gespla\/wp-content\/uploads\/2020\/10\/capa2.jpg",1536,842,false],"2048x2048":["https:\/\/www.ufrgs.br\/gespla\/wp-content\/uploads\/2020\/10\/capa2.jpg",1728,947,false]},"uagb_author_info":{"display_name":"Ipor\u00e3 Possantti","author_link":"https:\/\/www.ufrgs.br\/gespla\/author\/ipora-possantti\/"},"uagb_comment_info":0,"uagb_excerpt":"por Ipor\u00e3 Possantti, Engenheiro Ambiental, Mestre e doutorando em Recursos H\u00eddricos e Saneamento Ambiental (IPH\/UFRGS). Em diversas \u00e1reas de pesquisa, novas ferramentas s\u00e3o desenvolvidas na forma de c\u00f3digos de computador. N\u00e3o \u00e9 diferente na \u00e1rea de recursos h\u00eddricos, principalmente em hidrologia e planejamento, onde modelos de otimiza\u00e7\u00e3o, simula\u00e7\u00e3o e processamento de dados s\u00e3o largamente empregados.Ler&hellip;","_links":{"self":[{"href":"https:\/\/www.ufrgs.br\/gespla\/wp-json\/wp\/v2\/posts\/2019"}],"collection":[{"href":"https:\/\/www.ufrgs.br\/gespla\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.ufrgs.br\/gespla\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.ufrgs.br\/gespla\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/www.ufrgs.br\/gespla\/wp-json\/wp\/v2\/comments?post=2019"}],"version-history":[{"count":12,"href":"https:\/\/www.ufrgs.br\/gespla\/wp-json\/wp\/v2\/posts\/2019\/revisions"}],"predecessor-version":[{"id":2492,"href":"https:\/\/www.ufrgs.br\/gespla\/wp-json\/wp\/v2\/posts\/2019\/revisions\/2492"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.ufrgs.br\/gespla\/wp-json\/wp\/v2\/media\/2040"}],"wp:attachment":[{"href":"https:\/\/www.ufrgs.br\/gespla\/wp-json\/wp\/v2\/media?parent=2019"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.ufrgs.br\/gespla\/wp-json\/wp\/v2\/categories?post=2019"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.ufrgs.br\/gespla\/wp-json\/wp\/v2\/tags?post=2019"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}