quarta-feira, 10 de dezembro de 2014

TCL - Multiplas condições em um IF

Olá galera,


Recentemente um estagiário meu estava sofrendo com o alinhamento de várias condições em um IF. Este caso me lembrou que eu já passei por isso e portanto decidi colocar aqui para vocês para que não "sofram" como nós.


O seguinte bloco de código não funciona:

if {{$number == 1 && $name == "hello"} || {$number == 0&&$name == "yes"}} {
    #faça algo
}

O interpretador envia mensagem de erro: IS EXPECTED TO BE A BOOLEAN.

O motivo é que os { } e os ( ) não podem ser colocados em paralelo. Mas no caso dos ( ) eles são reconhecidos como array (ex. $ar(2) ), por tanto, interpretado como array de booleanos.

Utilizem o seguinte bloco de código:

if {(($number == 1)&&($name == "hello")) || (($number == 0)&&($name == "yes"))} {
    #faça algo
}


Até a próxima, Emanuel

sexta-feira, 28 de novembro de 2014

TCL/TK - Acesso ao sistema de arquivos

Tcl possui diversos comandos que permitem acessar o sistema de arquivos de um computador. Muitos desses comandos, possuem opções que só estam disponíveis em um determinado sistema operacional.
Para uma maior portabilidade de seu programa, é recomendável utilizar apenas as opções indepentes de sistema operacional.

ComandoDescrição
fila atimeRetorna o tempo em segundos, a partir 01/01/1970, desde o último acesso ao arquivo. 
file attributesRetorna ao define os atributos de um arquivo. As opções são diferentes para o UNIX, o Windows e o MacOS. 
file copyCopia um ou mais arquivos para outro. 
file deleteRemove um arquivo. 
file dirnameRetorna o caminho completo de um arquivo. 
file executableRetorna 1 se o arquivo for um programa executável pelo usuário, 0 caso contrário.
file existsRetorna 1 se o arquivo existir( e se o usuário puder ler o seu diretório ), 0 caso contrário. 
file extensionRetorna a extensão de um arquivo. 
file isdirectoryRetorna 1 se o arquivo for um diretório, 0 caso contrário. 
file isfileRetorna 1 se o arquivo for um arquivo regular, 0 caso contrário. 
file joinUne nome de arquivo e diretórios, usando o separador correto para o sistema operacional. 
file lstatO mesmo que file stat, mas usando a chamada lstat do kernel. 
file mkdirCria um ou mais diretórios. Pode criar uma árvore inteira. 
file mtimeRetorna o tempo em segundos, a partir 01/01/1970, desde a última modificação no arquivo. 
file nativenameRetorna o nome específico do arquivo para o sistema operacional corrente.
file ownedRetorna 1 se o arquivo pertencer ao usuário, 0 caso contrário. 
file pathtypeRetorna o tipo do caminho: absolute, relative ou volumerelative. 
file readableRetorna 1 se o arquivo puder ser lido pelo usuário, 0 caso contrário. 
file readlinkRetorna o valor do link sinbólico. 
file renameRenomeia um arquivo. 
file rootnameRetorna o nome do arquivo sem a extensão. 
file sizeRetorna o tamanho do arquivo. 
file splitRetorna o caminho de um arquivo em uma lista. Cada subdiretório como um elemento da lista. 
file statRetorna os resultados da chamada à função stat do kernel em uma lista, cujos elementos são: atime, ctime, dev, gid, ino, mode, mtime, nlink, size, type e uid. 
file tailRetorna o nome do arquivo, sem o caminho. 
file typeRetorna o tipo do arquivo: file, directory, characterSpecial, blockSpecial, fifo, link ou socket. 
file volumeRetorna a lista dos drivers locais no Windows, dos drivers locais e de rede no MacOS e apenas "/" no UNIX. 
file writableRetorna 1 se o usuário puder escrever no arquivo, 0 caso contrário. 


Exemplo 


No Windows, não utilize "\" para separar diretórios e nomes de arquivos, use "/", pois Tcl interpreta o caractere "\" como um caractere especial. Se desejar poderá usar "\\".

TCL/TK - Funções e procedimentos

Procedimento é uma subrotina ou porção de código, que é executado a partir de um nome que o referencia. Uma função é um procedimento que retorna um valor.
Para entender melhor o que é uma função, vejamos o seguinte exemplo: 
Desejamos calcular o quadrado de um número dado e imprimi-lo na tela: 
proc quadrado {numero} {
      return [expr $numero * $numero]
}
puts [quadrado 2]
Retornará 4 pois 2 vezes 2 é igual a 4.  

Criando procedimentos e funções

Criamos procedimentos e funções através do comando proc. A sintaxe de proc e a seguinte:
proc nome {[argumento1] [argumento2]... [argumentoN]} {
     [upvar nível variável_acima variável_local]
     [global [variavel1] [variavel2]... [variavelN]
     instruções... 
     [return [valor]]
}

Onde nome é o nome do procedimento ou função, argumento1, argumento2, argumentoN são argumentos ou valores opcionais passados ao procedimento ou função, variavel1, variavel2, variavelN são variaveis globais( ou seja variáveis vistas em todo o programa ), instruções são as instruções que serão executadas no procedimento ou função e valor é um valor que opcionalmente será retornado ao procedimento que chamou a função. O comando upvar será estudado mais adiante.

Argumentos

Argumentos são valores passados para a função ou procedimento. No caso do exemplo visto acima, do cálculo do quadrado de um número, número é o argumento passado à função quadrado. Argumentos podem ter valores default, ou padrão. Assim, caso nenhum valor seja passado para a função, um valor padrao será usado como argumento. Para definir um valor padrão para um argumento devemos colocar o nome do argumento e o valor padrão entre chaves {}, assim:
proc quadrado {{numero 0}} {
     return [expr $numero * $numero]
}

Caso existam vários argumentos, cada argumento que possuir um valor padrão deverá vir entre chaves, assim:
proc nome {{argumento1 valor1} {argumento2 valor2}... {argumentoN valorN}} { ... }
Em muitos casos é importante fornecer valores padrões para os argumentos de uma função. Isso evitará erros de tempo de execução. Assim, estude bem suas funções e procedimentos. 

Escopo das variáveis

Variáveis podem ser visíveis em todo o programa, ou somente em partes dele. A isso se dá o nome de escopo. Quando uma variável não pode ser vista em determinada parte do programa, se diz que ela está fora do escopo da função ou procedimento.  
De um modo geral, variáveis criadas no interior de uma função ou procedimento, serão visíveis somente no interior da função ou procedimento onde foi criada. Para tornar uma variável visível em todo o programa, usa-se o comando global. Exemplo:
global código, nome, e-mail
Torna as variáveis código, nome e e-mail disponíveis para todo o programa. 
Entretanto, para utilizar as variáveis acima dentro de uma outra função, você terá que repetir o mesmo comando acima dentro da função onde deseja utilizar as variáveis. 
Muitas vezes entretanto, desejamos utilizar uma variável criada em um nível acima da nossa função, e não uma variável global. Nestes casos podemos utilizar o comando upvar, para criar um ponteiro para a nossa variável um ou mais níveis acima. Exemplo: 
upvar 1 registro reg
Faz com que a variável reg referencie a variável registro que está na função chamadora( um nível acima ). Caso nível seja precedido pelo sinal #, nível será tratado como um valor absoluto. Assim #0 estará se referindo ao nível mais alto no programa. 

Retornando valores

É possivel retornar valores de funções através do comando return, como visto no exemplo de introdução desta aula. Contudo, isso não é obrigatório. 

Criando biblioteca de funções

Bibliotecas de funções são arquivos contendo declarações de diversas funções que queremos reaproveitar em nossos programas. Não há nenhum formato especial para arquivos de bibliotecas.  
Para carregar uma biblioteca utilizamos o comando source. A sintaxe de source é:
source arquivo.tcl
Carregará a biblioteca
O comando source também pode ser usado para carregar programas inteiros em Tcl. Ao carregar um arquivo, source compilará e executará os comandos no arquivo.

Criando pacotes

Uma forma elegante de distribuir bibliotecas é colocando-as em pacotes. Um pacote é criado colocando um comando package provide no início do arquivo. A sintaxe de packageprovide é: 
package provide nome versão
Onde nome é o nome do pacote( biblioteca ) que se está provendo e versão é o número da versão do pacote. 
Para carregar um pacote coloque no ínicio de seu programa:
package require nome versão 
Onde nome é o nome do pacote( biblioteca ) que se está solicitando e versão é o número da versão do pacote. 
Para instalar um pacote em seu computador, crie um diretório, dentro do diretório das bibliotecas do Tcl, com o nome do pacote seguido da versão. Em seguida entre no diretório e execute o comando: 
pkg_mkindex .
Isso criará um índice que Tcl utilizará para encontrar o pacote. Examine o diretório do Tcl em seu computador para entender melhor os nomes dos diretórios de pacotes. 
O diretório das bibliotecas do Tcl no Windows é: 
C:\Arquivos de Programas\Tcl\lib\ 
E no Linux, normalmente é: 
/usr/lib/

Namespaces

Namespaces são a nova forma de encapsular variáveis e funções em bibliotecas e programas em Tcl. Trata-se de um tema avançado e difícil de entender para o iniciante.

quinta-feira, 27 de novembro de 2014

TCL/TK - Adicionando um simbolo N vezes no fim da string.

Boa tarde,



Estava com essa dúvida outro dia no trabalho, pesquisei no manual da linguagem e achei a seguinte solução.

Segue exemplos do código:

puts novastr [format "|%-25s|" hello]

Saída: |hello                        |



set novastr [format "|%-*s|" $qtd $str]



Outras opções que um amigo me enviou:

set novastr $str[string repeat " " [expr {25 - [string length $str]}]]
e
for {set novastr $str} {[string length $novastr] < 25} {} {
    append novastr " "
}


Att, Emanuel Moraes

quarta-feira, 19 de novembro de 2014

TCL/TK - Controle de fluxo

Com frequência, em programação, nossos programas precisam escolher entre certas direções determinadas, de acordo com certas condições pre-estabelecidas. A isso se chama controle de fluxo de execução do programa. Tcl oferece mecanismos avançados para que o programador possa controlar o fluxo de execução de seus programas. Mais adiante estudaremos cada um dos recursos que Tcl oferece para que controle de fluxo de execução de programas. Mas antes vamos entender um pouco mais o que é fluxo de execução.

Analisaremos a seguinte situação: Precisamos  imprimir todos os números ímpares de 0 a 100. O algorítimo do nosso programa ficaria assim:

N = 0
enquanto N < 100 faça {
     se resto(N, 2) <> 0 então {
          imprima N
     }
     incremente N
}

Na primeira linha do nosso programa, iniciamos a variável N como 0. Em seguida entramos em um laço de repetição( uma parte do programa que se repete enquanto uma condição dada permanecer verdadeira ) enquanto N for menor que 100.
No interior do laço de repetição, verificamos se o número N é ímpar( um número é impar se o resto da divisão do número por dois for diferente de zero ). Se for ímpar, imprimimos o número. Incrementamos( somamos mais um ) ao número e repetimos o laço. Cada repetição do laço se chama interação.
Vejamos agora como ficaria cada parte do programa em Tcl:
set N 0 
while {$N < 100} {
     if {[expr fmod($N,2)]} {
          puts $N
     }
     incr N
}

if... then...elseif...else... 

A expressão if...then...elseif...else... permite controlar o fluxo de execução do programa de acordo com diferentes condições dadas. A sintaxe é:
if expr1 corpo1 elseif expr2 corpo2... else corpoN 
Onde expr1, expr2, exprN são diferentes condições a serem testadas e corpo1, corpo2, corpoN são porções de código que devem ser executadas caso a condição correspondente seja verdadeira. A expressão else somente é executada caso todas as outras expressões sejam avaliadas como falsas. 
Exemplo:
if {$x == 0} {
     puts "X é igual a 0"
} elseif {$x < 0} {
     puts "X é menor que 0"
} else {
     puts "X é maior que 0"

while...

A expressão while... permite executar um laço de repetição enquanto uma expressão for avaliada como verdadeira. A sintaxe de while é:
while expr1 corpo
Onde expr1 é a expressão que deve ser avaliada como verdadeira( 1, true ou yes ) para que o laço seja repetido. E corpo é o fragmento de código que será executado a cada repetição do laço.
Pode-se interromper a execução de um laço a qualquer momento através do comando break.
Para pular para a próxima interação de um laço, saltando todas as instruções restantes, podemos utilizar o comando continue.
Exemplo:
set x 0
while {$x < 10} {
     puts $x;
}

for...

A expressão for... permite executar um laço de repetição enquanto uma expressão for avaliada como verdadeira. A sintaxe de for é: 
for início teste próximo corpo 
O onde início contém o código de inicialização da variável usada no teste, teste contém uma expressão que deve ser avaliada como verdadeira para que o laço se repita, próximo contém um fragmento de código que é avaliado a cada repetição, e que normalmente é utilizado para incrementar a variável e corpo contém o fragmento de código que se deseja executar a cada interação do laço.  
Pode-se interromper a execução de um laço a qualquer momento através do comando break.
Para pular para a próxima interação de um laço, saltando todas as instruções restantes, podemos utilizar o comando continue. 
Exemplo:
for {set x 1} {$x < 10} {incr x} {
     puts $s
}

foreach...

A expressão foreach... oferece um meio de interagir por todos os elementos de uma lista, de forma simplificada. foreach é muito usada no processamento de informações retornadas por consultas SQL. 
A sintaxe de foreach é: 
foreach variável lista corpo 
Onde variável é o nome de uma variável que irá conter, a cada interação, o valor de um elemento da lista. lista é a lista que será percorrida e corpo é o fragmento de código que será executado a cada interação. 
Pode-se interromper a execução de um laço a qualquer momento através do comando break. 
Para pular para a próxima interação de um laço, saltando todas as instruções restantes, podemos utilizar o comando continue.
Exemplo:
set lista {vermelho alaranjado amarelo verde azul anil violeta}
foreach cor $lista {
     puts $cor
}

switch... 

O comando switch é provavelmente o meio mais poderoso para se controlar o fluxo de execução de um programa em Tcl. switch permite que se compare o valor de uma string com diversos valores dados e se execute a porção de código correspondente. switch suporta expressões regulares e é muito usado em comandos definidos pelo usuário para avaliar as opções passadas para o comando.
A sintaxe de switch é: 
 
switch [-exact] [-regexp] [-glob] string {
     valor1 corpo1
     valor2 corpo2
     valorN corpoN
}

Onde as opções entre cochetes [] são opcionais, string é a string que será comparada com os valores definidos, valor1, valor2, valorN são os valores que serão comparados com a string e corpo1, corpo2, corpoN são os fragmentos de código que serão executados caso o valor correspondente coincida com a string passada para o comando.
Exemplo:
set x "arquivo"
switch x {
     arquivo {puts "Você selecionou a opção arquivo"}
     editar {puts "Você selecionou a opção editar"}
     ajuda {puts "Você selecionou a opção ajuda"}
}

exit...

O comando exit encerra a execução do programa e retorna um valor para o shell.
A sintaxe de exit é: 
exit valor
Onde valor é o valor que será retornado ao shell. 
Exemplo:
set lista {vermelho alaranjado amarelo verde azul anil violeta}
foreach cor $list {
     puts $cor
}
exit 0

TCL/TK - Estrutura de dados

Tcl suporta dois tipos de estruturas de dados: vetores associativos e listas. A seguir estudaremos cada uma dessas estruturas, assim como os recursos que Tcl oferece para manipulá-las.

Vetores associativos

Vetores são variáveis capazes de armazenar vários valores ao mesmo tempo. Sendo que cada valor é referenciado por um índice, de modo semelhante a uma matriz.
Vetores podem ter uma, duas ou múltiplas dimensões. No entanto, é mais comun trabalhar com vetores com até 5 dimensões. Neste caso, na resolução de sistemas de equações com múltiplas variáveis.
Observe o exemplo de um vetor típico:
Suponhamos que queiramos armazenar os nomes dos dias da semana em um vetor: 
dia(1) = "domingo"
dia(2) = "segunda-feira"
dia(3) = "terça-feira"
dia(4) = "quarta-feira"
dia(5) = "quinta-feira"
dia(6) = "sexta-feira"
dia(7) = "sábado"
Em Tcl faríamos:
set dia(1) "domingo"
set dia(2) "segunda-feira"
set dia(3) "terça-feira"
set dia(4) "quarta-feira"
set dia(5) "quinta-feira"
set dia(6) "sexta-feira"
set dia(7) "sábado"

E para lermos o nome do dia armazenado na posição 2:
puts $dia(2)
Se você já conhece outras linguagens de programação, deve estar se perguntando se Tcl começa os números dos índices com zero(0) ou um(1). A resposta é: Tcl não começa. De fato, Tcl trabalha com vetores associativos. Dessa forma os índices pode ser números, letras, palavras ou qualquer combinação de caracteres.
Suponha que você queira armazenar os dados de um cliente em um vetor cliente. Podemos armazenar o nome do cliente no elemento nome do vetor, enquanto o telefone seria armazenado no elemento telefone, e o e-mail no elemento e-mail:
set cliente(nome) "Roberto Luiz Souza Monteiro"
set cliente(telefone) "+55-71-9121-7576"
set cliente(e-mail) "souzamonteiro@souzamonteiro.com"
Para acessarmos o nome do cliente faríamos:
puts $cliente(nome)
E na verdade, é assim que trabalham os bancos de dados em Tcl: atribuindo o registro corrente a um vetor associativo. Para entender melhor como funcionam vetores associativos em bancos de dados, veja o código fonte da biblioteca TDO - Tcl Database Access Objects, disponível em http://www.souzamonteiro.com/tdo.shtml.
Tcl oferece as seguintes funções para tratamento de vetores:

FunçãoDescrição
array anymoreVerifica, e retorna 1, se ainda existirem elementos a serem pesquisados no vetor. 
array donesearchTermina uma busca em um vetor.
arrays existVerifica, e retorna 1, se o vetor existir. 
array getRetorna uma lista onde cada elemento ímpar corresponde ao nome do elemento no vetor, e cada elemento par corresponde ao valor do elemento. 
array namesRetorna uma lista com os nomes de cada elemento no vetor. 
array nextelementRetorna o nome do próximo elemento no vetor.
array setAtribui a cada elemento no vetor, o valor correspondente ao existente na lista fornecida. 
array sizeRetorna o número de elementos no vetor. 
array starsearchRetorna um ponteiro para uma busca sequencial em um vetor.
parrayExibe, na saída padrão, os nomes e os valores de todos os elementos no vetor, que correspondam ao padrão especificado. 


Exemplos
 
Suponha o vetor dos dias da semana:
set dia(1) "domingo"
set dia(2) "segunda-feira"
set dia(3) "terça-feira"
set dia(4) "quarta-feira"
set dia(5) "quinta-feira"
set dia(6) "sexta-feira"
set dia(7) "sábado"

array get
puts [array get dia]
Retornará: 
4 quarta-feira 5 quinta-feira 1 domingo 6 sexta-feira 2 segunda-feira 7 sábado 3 terça-feira

array names
puts [array names dia]
Retornará:
4 5 1 6 2 7 3

array size
puts [array size dia]
Retornará:
7

parray
puts [parray dia]
Retornará:
dia(1) = domingo
dia(2) = segunda-feira
dia(3) = terça-feira
dia(4) = quarta-feira
dia(5) = quinta-feira
dia(6) = sexta-feira
dia(7) = sábado

Listas

Listas são provavelmente as estruturas de dados mais poderosas. De fato, Tcl oferece muitos recursos para manipulação de listas. Mas o que são listas? 
Listas são estruturas capazes de armazenar coleções de dados, de forma estruturada. Uma lista pode conter outras listas aninhadas e é possivel ordenar e pesquisar listas do mesmo modo como se faria em um banco de dados, e com a mesma eficiência.
Veja o seguinte exemplo: 
Suponha um banco de dados de clientes, onde cada registro conteria o nome, o telefone e o e- mail de cada cliente. Tcl poderia armazenar o banco de dados em uma lista, onde cada registro sera armazenado em um elemento da lista como uma segunda lista, e nesta segunda lista cada elemento corespoderia a um campo no banco de dados: 

{
     {nome telefone e-mail}
     {"Roberto Luiz Souza Monteiro" "+55-71-9121-7576" "souzamonteiro@souzamonteiro.com"}
     {"Katia Souza Monteiro" "+55-71-242-8798" "katia@souzamonteiro.com"}
     {"Regina C. S. de Andrade" "+55-71-386-0627" "regina@souzamonteiro.com"}
}  

Sabendo que o primeiro elemento na lista corresponde à lista de nomes dos campos na tabela, cada elemento seguinte, corresponde a uma linha, ou registro, na tabela. E de fato, no banco de dados TclVSdb, os dados são armazenados dessa forma nas tabelas do banco de dados.

Tcl oferece as seguintes funções para tratamento de listas: 

FunçãoDescrição
concatConcatena várias lista para formar uma nova lista. 
joinConverte uma lista em uma string, separando os elementos da lista com o separador indicado. 
lappendAdiciona um elemento ao final da lista.
lindexRetorna o valor do elemento indicado na lista.
linsertInsere um elemento em uma lista. Na verdade retorna uma nova lista. 
listCria uma lista, a partir dos elementos fornecidos como argumentos. 
llengthRetorna o tamanho de uma lista. 
lrangeRetorna uma lista contendo os elementos dentro da faixa especificada. 
lreplaceSubstitui valores em uma lista. Na verdade retorna uma nova lista. 
lsearchExecuta uma busca em uma lista. Suporta expressões regulares. 
lsortOrdena uma lista. Suporta várias opções. Na verdade retorna uma nova lista.
splitConverte uma string em uma lista, considerando um caractere especificado na string, como o separador dos elementos. 


Exemplos 


quinta-feira, 13 de novembro de 2014

TCL/TK - Expressões regulares

Expressões regulares são um poderoso meio para realizar pesquisas em strings. A tabela a seguir, apresenta os operadores utilizados em Tcl para realizar buscas em strings, vetores e listas:

OperadorDescrição
expreg|expregCompara ambas as expressões. 
expreg*Compara zero ou mais ocorrências de expreg. 
expreg+Compara uma ou mais ocorrências de expreg.
expreg?Compara zero ou uma ocorrência de expreg. 
.Compara um único caractere. 
^Compara o início da string. 
$Compara o fim da string.
\cCompara o caractere c mesmo que ele seja especial. 
[abc]Compara o conjunto de caracteres.
[^abc]Compara os caracteres que não estejam no conjunto. 
[a-z]Compara a faixa de caracteres. 
[^a-z]Compara os caracteres que não estejam na faixa. 
()Agrupa expressões.


Exemplos
puts [regexp {[1-5]} "12345678"]
Retorna 1, pois um dos números de 1 a 5 está incluído na string.  

puts [regexp {[1-5]} "6789"]
Retorna 0, pois nenhum dos números de 1 a 5 está incluído na string. 

set x ""
regexp -nocase {[^def]} "abcdef" x
puts $x
Retorna abc, pois regexp atribuirá à string todos os caracteres que não correspondam à expressão fornecida.   

Expressões regulares são muito usadas em bancos de dados SQL e programas CGI que procuram informações em páginas HTML.  

quarta-feira, 5 de novembro de 2014

TCL/TK - Strings

Em Tcl existe apenas um tipo de dado: strings. Strings são cadeias de caracteres, que podem ser delimitadas por aspas duplas("), aspas simples(') ou chaves({}). O delimitador da string determina se haverá ou não substituição.
Para atribuir uma string a uma variável, utilizamos o comando set:
set x "Esta é uma string"
Para ler o conteúdo da variável colocamos um caractere $ antes do nome da variável:
puts $x
Tcl oferece diversos comandos e funções para tratar strings:

Comando/funçãoDescrição
appendConcatena várias strings.
binary formatRetorna uma representação binária de uma string, de acordo com um formato especificado. 
binary scanEstrai valores de uma string binária, para uma variável, de acordo com o formato especificado. 
formatRetorna uma string formatada, de modo semelhante ao comando sprintf do ANSI C. 
regexpRetorna 1 se a expressão regular corresponde à string. 
regsubSubstitue a primeira porção da string que corresponde à expressão regular. 
scanExtrai valores de uma string, em uma variável, de modo semelhante ao comando sscanf do ANSI C. 
string compareCompara duas strings. 
string firstEncontra a primeira ocorrencia de uma string em outra. 
string indexRetorna o caractere na posição especificada.
string isVerifica se os dados em uma string são de um determinado tipo. 
string lastEncontra a última ocorrência de uma string em outra. 
string lengthRetorna o tamanho da string. 
string matchVerifica se uma string corresponde a outra dada. 
string rangeRetorna um trecho de uma string.
string tolowerConverte uma string em minúsculas. 
string toupperConverte uma string em maiúsculas. 
string trimRemove os espaços em branco à direita e à esquerda de uma string. 
string trimleftRemove os espaços em branco à esquerda de uma string. 
string trimrightRemove os espaços em branco à direita de uma string.
string wordendRetorna o caractere logo após o último caractere na palavra especificada na string. 
string wordstartRetorna o primeiro caractere na palavra especificada na string. 
substRealiza uma substituição em uma string. 


Para uma descrição detalhada de todas as funções string, consulte a documentação on-line, ou o Tcl/Tk Reference Guide, ou ainda o Tcl/Tk Electronic Reference. 

TCL/TK - Comentários

Comentários em Tcl começam com o caractere sustenido(#). Comentários podem vir em qualquer parte do programa, contudo, se vierem no final de uma linha de código, deve ser precedidos do um caractere ponto-e-vírgula(;):
puts "Esta linha contém um comentário\n"; # Este é um comentário
puts "Esta linha contém um comentário incorreto\n" # Este comentário não foi precedido do sial (;) e gerará um erro
# Este comentário é válido
puts "OK!" 

TCL/TK - Pontuação

Todos os comandos em Tcl devem ser terminados por um ponto-e-vírgula ou por uma nova linha:
puts "Esta é uma linha\n"; puts "Esta é uma outra linha\n"
é equivalente a:
puts "Esta é uma linha\n"
puts "Esta é uma outra linha\n" 

TCL/TK - Bloco de comandos

Pode-se agrupar comandos em blocos, colocando-se todos os comando entre chaves:

if {$x == 1}  {
     set y 1
     set z 2
}

O comando anterior execurá o bloco {set y 1; set z 2} caso o conteúdo da variável x seja 1. 

sexta-feira, 22 de agosto de 2014

TCL/TK - Operadores

Os operadores matemáticos e lógicos suportados por Tcl são os seguintes, em ordem de precedência:  

OperadorSignificado
- ~ !Negativo, Não bit a bit, Negação lógica 
* / %Multiplicação, divisão, parte inteira da divisão 
<< >>Deslocamento de bits à esquerda, Deslocamento de bits à direita 
< > <= >=Menor, Maior, menor ou igual, maior ou igual 
== != Igual( comparação lógica ), diferente 
&E (AND) bit a bit 
^OU EXCLUSIVO( XOR ) bit a bit 
|OU( OR ) bit a bit 
&&E lógico( AND ) 
||OU lógico( OR ) 
x ? y : zSe x então y, caso contrário, z 


Tcl também suporta as seguintes funções matemáticas através do comando expr:

FunçãoSignificado
absMódulo
acosArco-cosseno
asinArco-seno
atanArco-tangente
atan2Arco-tangente
ceilArredonda para maior
cosCosseno
coshCosseno hyperbólico
doubleTransforma em um número de dupla precisão
expCalcula o número e elevado a x
floorArredonda para menor
fmodCalcula o resto de uma divisão
hypodCalcula a hypotenusa de um triângulo retângulo
intConverte em inteiro
logCalcula o logarítimo natural de x
log10Calcula o logarítimo na base 10 de x
powx elevado a y
randGera um número aleatório
roundArredonda um número
sinSeno
sinhSeno hyperbólico
sqrtRaiz quadrada
tanTangente
tanhTangente hyperbólico


Para realizar uma operação matemática basta passar a expressão para o comando expr: puts [expr 2 + 3 * (1 + sin(32))] Exibirá no console: 6.65428004373  

quinta-feira, 21 de agosto de 2014

TCL/TK - Introdução

A linguagem Tcl/Tk foi desenvolvida pelo Dr. John K. Ousterhout e sua equipe da Universidade da California, tendo sido mantida pela Sun Microsystems e posteriormente pela Scriptics e atualmente pela Ajuba Solutions.

A linguagem Tcl é essencialmente uma linguagem de script, podendo ser compilada para criar um executável em formato binário. Tk é o seu Tool Kit, sua biblioteca gráfica.

O uso mais comum para o Tcl é na criação de programa para os sistemas UNIX, Windows e Mac. Entretanto vem crescendo o número de empresas que utilizam a linguagem Tcl em seus servidores de Web, entre elas a America On-Line( AOL ).

Tcl é uma linguagem poderosa, aliando um eficiente compilador JIT, a uma sintaxe extremamente simples. O compilador Tcl é tão eficiente, que há pouca diferença em velocidade, entre um programa Tcl interpretado e sua versão compilada. 

Variáveis

Em Tcl só existe um tipo de dado: strings, ou cadeias de caracteres. Contudo, alguns comandos, especialmente os que realizam cálculos, interpretam seus arqumentos como valores numéricos ou booleanos. Nesse caso os dados estarão nos seguintes formatos:

TipoExemplo
Inteiro123( decimal ), 0xFF( hexadecimal), 0377( octal ) 
Ponto flutuante1.2, 2., 3e5, 1.23e+5 
Booleano( lógico )true, false, 0, 1, yes, no 


Uma variável pode ter qualquer nome. Para atribuir um valor a uma variável utiliza-se o comando set: set x 0 O comando anterior atribui o valor 0( zero ) à variável x. Para ler o valor de uma variável basta colocar o caractere $, antes do nome da variável: puts $x Exibe o valor da variável x no console. Você não precisa declarar variáveis, elas são criadas à medida em que são referenciadas. 1

quinta-feira, 24 de julho de 2014

Criar um menu de Recent Files no Qt.

Olá pessoal,



Ando ocupado no emprego, mas como desenvolvi alguns programas para facilitar as coisas no trabalho, estou postando dicas que usei nesses programas. Segue mais um abaixo ;-)


A biblioteca do Qt anda muito bem, gosto muito desse framework. Estava lendo algumas notícias relacionadas a desenvolvimento e me deparei com um componente chamado QSettings, na hora me veio a ideia de utiliza-lo, pesquisei na net e descobri algumas pessoas já fazendo uso. Segue abaixo meu código:

Primeiro, o QSettings usa arquivos .ini para guardar informações do formulário e recuperá-los. Por tanto criei uma lista dos ultimos arquivos abertos:

QAction *separatorAct;
enum { MaxRecentFiles = 10 };

QAction *recentFileActs[MaxRecentFiles];


Segundo, criei duas funções para guardar e recuperar essas info do arquivo .ini:

Recuperar:
void MainWindow::updateRecentFileActions()
{
    QSettings settings("demosetting.ini", QSettings::IniFormat);
    QStringList files = settings.value("recentFileList").toStringList();
    //qDebug() << "carregando de settings: " << files;
    int numRecentFiles = qMin(files.size(), (int)MaxRecentFiles);

    for (int i = 0; i < numRecentFiles; i++) {
        QString text = QString("&%1 %2").arg(i).arg(files[i]);
        recentFileActs[i]->setText(text);
        recentFileActs[i]->setData(files[i]);
        recentFileActs[i]->setVisible(true);
    }

}

Guardar:
void MainWindow::setCurrentFile(const QString &fileName)
{
    //curFile = fileName;
    setWindowFilePath(fileName);

    QSettings settings("demosetting.ini", QSettings::IniFormat);
    QStringList files = settings.value("recentFileList").toStringList();
    files.removeAll(fileName);
    files.prepend(fileName);
    while (files.size() > MaxRecentFiles)
        files.removeLast();

    settings.setValue("recentFileList", files);
    //qDebug() << "salvando em " << settings.fileName() << ": " << files;

}

E o código para adicionar o menu "Recent files":

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // recent files
    QMenu *r = this->menuBar()->addMenu("Recent files");

    for (int i = 0; i < MaxRecentFiles; i++) {
        recentFileActs[i] = new QAction(this);
        recentFileActs[i]->setVisible(false);
        connect(recentFileActs[i], SIGNAL(triggered()), this, SLOT(openRecentFile()));
    }
    for (int i = 0; i < MaxRecentFiles; ++i)
        r->addAction(recentFileActs[i]);
    updateRecentFileActions();
    separatorAct = r->addSeparator();

}

void MainWindow::openRecentFile()
{
    QAction *action = qobject_cast<QAction *>(sender());
    if (action)
        loadFile(action->data().toString());

}

Implementem a função loadFile() ou substitua a chamada pela sua função e lembrando que estou usando o Qt versão 5.2 (no Qt Creator 3.1.1).
Espero ter ajudado novamente.

Até a próxima

Abç, Emanuel