collapse

* Posts Recentes

Amplificador - Rockboard HA 1 In-Ear por almamater
[Ontem às 19:13]


O que é isto ? por KammutierSpule
[26 de Março de 2024, 19:35]


Bateria - Portátil por almamater
[25 de Março de 2024, 22:14]


Emulador NES em ESP32 por dropes
[13 de Março de 2024, 21:19]


Escolher Osciloscópio por jm_araujo
[06 de Fevereiro de 2024, 23:07]


TP4056 - Dúvida por dropes
[31 de Janeiro de 2024, 14:13]


Leitura de dados por Porta Serie por jm_araujo
[22 de Janeiro de 2024, 14:00]


Distancia Cabo por jm_araujo
[08 de Janeiro de 2024, 16:30]


Meu novo robô por josecarlos
[06 de Janeiro de 2024, 16:46]


Laser Engraver - Alguém tem? por almamater
[16 de Dezembro de 2023, 14:23]

Autor Tópico: TCL ("ticle")  (Lida 12331 vezes)

0 Membros e 1 Visitante estão a ver este tópico.

Online KammutierSpule

  • Mini Robot
  • *
  • Mensagens: 1.481
Re: TCL ("ticle")
« Responder #15 em: 22 de Maio de 2015, 14:48 »
E se quiseres eliminar as palavras repetidas?

Offline Njay

  • Mini Robot
  • *
  • Mensagens: 3.598
    • Tróniquices
Re: TCL ("ticle")
« Responder #16 em: 22 de Maio de 2015, 20:14 »
A 1ª coisa que me veio à cabeça foi usar um array de TCL, que é uma tabela de dispersão (hashtable). Varria a lista de palavras e criava elementos dummy em que os nomes (como em TCL se chamam às chaves) são as palavras. Ao inserir no array uma palavra que já existe, esta vai sobrepôr a palavra já existente. No final, é obter uma lista só com os nomes do array (subcomando names do comando array) e contar o número de elementos dessa lista. Ficaria então assim:

...
# Partir o texto pelos espaços, guardando o resultado (uma lista, de palavras) na variável words
set words  [split $txt " "]
# Percorrer a lista de palavras, criando no array word_table entradas em que os nomes são as
# palavras. Palavras repetidas sobrepõem-se, ficando apenas uma ocorrência da palavra no array.

foreach word $words  {
    # Criar a entrada de nome $word no array word_table (quando a variável não existe,
    # o set cria-a). Como neste caso não interessa o que guardamos no array, metemos
    # strings vazias (não ocupa mem)

    set word_table($word)  ""
}
# Obter a lista dos nomes do array
set words  [array names word_table]
# E escrever no ecran o número de palavras únicas
puts "[llenght $words] palavras"


Mas depois lembrei-me que o comando para ordenar listas tem um parâmetro para deitar fora os elementos repetidos :) . Então aí ficaria assim:

...
# Partir o texto pelos espaços, guardando o resultado (uma lista, de palavras) na variável words
set words  [split $txt " "]
# Ordenar a lista de palavras deitando fora as repetidas
# (lsort recebe uma lista e retorna uma nova lista)

set words  [lsort -unique $words]
# E escrever no ecran o número de palavras únicas
puts "[llenght $words] palavras"


No final ainda ficamos com a lista de palavras ordenada. Se quisermos imprimi-la no ecran, uma palavra por linha, podemos usar o comando join. Esta comando aceita uma lista e uma string separadora, e cria uma string com todos os elementos da lista separados pela string separadora. Para meter uma palavra por linha, temos que as separar por um fim de linha, daí:

# Escrever no ecran a lista de palavras únicas, uma palavra por linha
puts [join $words "\n"]


É comum escrever-se de uma forma um pouco mais compacta, juntando na mesma linha até 2 ou 3 comandos (agora completo e usando a função que criámos lá atrás, para carregar um ficheiro de texto):

# Carregar um ficheiro e escrever no ecran o número de palavras únicas
set txt  [LoadTextFile [lindex $argv 0]]
regsub -all "\\s\\s+" $txt " " txt
set words  [lsort -unique [split $txt " "]]
puts "[llenght $words] palavras"


Aqui adicionei uma linha extra, com o comando regsub, uma expressão regular para substituir conjuntos de 2 ou mais espaços consecutivos por apenas um espaço. Isto é para evitar criar palavras vazias, pois se o split apanhar por exemplo 2 espaços consecutivos, ele parte a string entre os espaços e cria uma entrada vazia (string vazia, "") a representar o que se encontra entre esses espaços. Há outras formas de eliminar estas palavras vazias, que até são bastante mais eficientes; mas eu gosto de expressões regulares :)

Então, e mais desafios para fazer em TCL?
« Última modificação: 02 de Setembro de 2018, 05:23 por Njay »

Online KammutierSpule

  • Mini Robot
  • *
  • Mensagens: 1.481
Re: TCL ("ticle")
« Responder #17 em: 23 de Maio de 2015, 20:58 »
Alright, sinceramente, nao consigo perceber nada da linguagem :), sou mau em linguagens, so sei C/C++

Ha ai uma coisa que nao entendo, se estas a usar hashtable, porque precisas de ordenar e eleminar, se e' so para saber quantas palavras existem, entao era so retornar o tamanho da tabela.

A ideia de usar uma hashtable 'e boa, em C++ podia-se usar map para isso, e dessa maneira ate dava para contar as ocorrencias de cada palavra.
Neste caso nao importa a ordem.

Offline Njay

  • Mini Robot
  • *
  • Mensagens: 3.598
    • Tróniquices
Re: TCL ("ticle")
« Responder #18 em: 24 de Maio de 2015, 01:25 »
Apresentei 2 métodos diferentes. O 1º usa uma tabela de dispersão (hash), que em TCL é um array (o nome formal deste tipo de dados é "array associativo"). De facto há um subcomando, "size", do comando array, que retorna o número de elementos do array, não sei porquê não me lembrei na altura, e podemos assim poupar uma linha, substituindo

...
# Obter a lista dos nomes do array
set words  [array names word_table]
# E escrever no ecran o número de palavras únicas
puts "[llenght $words] palavras"


por

...
# E escrever no ecran o número de palavras únicas
puts "[array size word_table] palavras"


No código original eu estava a obter uma lista com todas as chaves do array e depois imprimia o tamanho dessa lista, mas de facto, é estúpido :) .

O 2º usa o comando de ordenação de listas, que tem um parâmetro para eliminar os repetidos; ao ordenar a lista de palavras com eliminação de repetidos, fico com uma lista sem palavras repetidas (o que é retornado do comando lsort, list sort):

set words  [lsort -unique $words]

Isto ordena a lista e elimina os repetidos; a lista de entrada está na variável words e o resultado é atribuído à mesma variável words. Não estamos interessados na ordenação, aqui estamos apenas a aproveitar o facto do comando de ordenação de listas também eliminar os repetidos.

TCL é um bocado como lisp (na verdade acho-os conceptualmente parecidos), muda a tua maneira de ver o mundo ;) .

O que é que te faz mais confusão?

Uma variável array de TCL, que é na prática uma tabela de dispersão, acede-se tendo o nome do array sufixado pela chave entre parentesis. Daí que word_table(TCL) é o nome do elemento de chave "TCL" do array word_table. Repara que eu disse "o nome"; se quiseres aceder ao valor é preciso usar o $ tal como no acesso às restantes variáveis, como em $word_table(TCL).
Se quisermos usar a chave que está numa variável, é só passar o valor dessa variável como chave. Exemplos:

set array(TCL)  "FIXE"   ;# cria a chave "TCL" no array "array"
set key  "TCL"           ;# cria a variável "key" com o valor "TCL"
puts "array($key)"       ;# imprime "array(TCL)"
puts "$array($key) é o mesmo que $array(TCL)"   ;# imprime "FIXE é o mesmo que FIXE"


Nota: Para se colocar um comentário a seguir a um comando na mesma linha é necessário colocar um ;

Repara como eu usei "array" como nome de uma variável, apesar de ser também o nome de um comando. Em TCL podes fazer isso, porque para o TCL, comandos são a 1ª palavra da linha ou a 1ª palavra a seguir ao [ , daí que não há ambiguidade.
« Última modificação: 24 de Maio de 2015, 01:40 por Njay »

Online KammutierSpule

  • Mini Robot
  • *
  • Mensagens: 1.481
Re: TCL ("ticle")
« Responder #19 em: 24 de Maio de 2015, 10:16 »
ok nice.

Essa linguagem, 'e dificil de seguir sem conhecer a syntax.
Ai torna-se complicado a cena dos $, porque estas a aceder ao conteudo das variaveis dentro da propria string que vais imprimir.
Por exemplo
"puts "[llenght $words] palavras"

e' dificil entender o que desses caracteres sao para imprimir e o que sao comandos ai pelo meio sem conhecer a syntax.

...Se calhar vou antes aprender um pouco da linguagem: http://en.wikipedia.org/wiki/Brainfuck
:P

Offline Njay

  • Mini Robot
  • *
  • Mensagens: 3.598
    • Tróniquices
Re: TCL ("ticle")
« Responder #20 em: 24 de Maio de 2015, 11:02 »
A substituições. Muito bom :) . Quando tens algo dentro de [] isso é visto pelo TCL como um comando. Se olhares bem vais ver que uma linha onde tens vários [], inclusivé uns dentro de outros, tem como que uma hierarquia/árvore bem definida, e é preciso executar 1º os comandos que são mais "interiores", trabalhando "de dentro para fora", pois os comandos "de fora" dependem dos de "dentro", que são ou contribuem para o seus argumentos. No exemplo que deste,

puts "[llenght $words] palavras"

é preciso 1º invocar o comando llenght (mais "interior"), pois o argumento para o comando puts (o mais "exterior") depende dele. E para invocar o comando llenght é preciso ir buscar o valor da variável words, portanto é, nesta linha toda, aquilo que o interpretador de TCL faz 1º
Assumindo que a variável words tem a lista {um dois três} (uma lista em TCL define-se separando os elementos por espaço e envolvendo tudo em {}), o interpretador de TCL faz o seguinte para executar a linha:

puts "[llenght $words] palavras"
   (vai substituir, na linha, $words pelo valor da variável)
puts "[llenght {um dois três}] palavras"
   (vai substituir, na linha, a chamada ao comando llenght pelo seu retorno)
puts "3 palavras"


Acredito que te faça confusão ver chamadas a funções no meio duma string, especialmente se só conheces linguagens "duras" como o C. É uma questão de hábito. Se isto for bem usado é até pode ser mais fácil de entender, estás a "ir buscar" o que é para imprimir no sitio exacto onde é para imprimir. Mas se quiseres muito, também tens o comando format que gera uma string usando a mesma sintaxe de "format specifiers" do C ;)

puts [format "%d palavras" [llenght $words]]

Quanto ao brainfuck, bom, gostos não se discutem, lol . É uma espécie de assembly, não me parece muito dificil construir um CPU com esse instruction set.
« Última modificação: 24 de Maio de 2015, 11:06 por Njay »

Online KammutierSpule

  • Mini Robot
  • *
  • Mensagens: 1.481
Re: TCL ("ticle")
« Responder #21 em: 24 de Maio de 2015, 17:01 »
Quanto ao brainfuck, bom, gostos não se discutem, lol . É uma espécie de assembly, não me parece muito dificil construir um CPU com esse instruction set.

Era uma piada!

Offline dropes

  • Mini Robot
  • *
  • Mensagens: 2.189
Re: TCL ("ticle")
« Responder #22 em: 24 de Maio de 2015, 20:04 »
Quanto ao brainfuck, bom, gostos não se discutem, lol . É uma espécie de assembly, não me parece muito dificil construir um CPU com esse instruction set.

Era uma piada!

Programar só com 8 comandos, então os comentários são lindos, 1000 x assembly  :o

Offline Njay

  • Mini Robot
  • *
  • Mensagens: 3.598
    • Tróniquices
Re: TCL ("ticle")
« Responder #23 em: 24 de Maio de 2015, 21:37 »
LOL... eu sei que era uma piada. brainfuck é uma "curiosidade cientifica".

Offline Njay

  • Mini Robot
  • *
  • Mensagens: 3.598
    • Tróniquices
Re: TCL ("ticle")
« Responder #24 em: 02 de Setembro de 2015, 14:34 »
Tb dá para brainfluckar um bocado em TCL, por exemplo :) :

set \  \ \ \ \
puts ${ }indentado\ a\ 4 espaços


ou

proc \  n { string repeat \  $n }
puts "[\  8]indentado a 8 espaços"

proc \" * { return \"${*}\" }
puts [\" entreaspas]


TCL é tão "básico" que podemos criar funções (procs) ou variáveis com o nome que quisermos, inclusive com o nome "1 espaço" ou " (1 aspa) como nos casos acima, ou mesmo com o nome de "keywords" da linguagem pois não há ambiguidade na utilização. A \ serve para fazer escape ou para indicar que o caracter branco que se segue não é da categoria "espaços separadores" mas é para ser interpretado como um "item sólido".
Mas vamos desligar o complicador e esquecer estes casos patológicos que ninguém usa :) (os fãs de Perl é que devem gostar :) )

E expressões regulares, quem conhece e usa que levante o braço. Não são uma exclusividade do TCL, existem noutras linguagens, mas é onde mais as uso. Expressões regulares são a 2ª coisa mais útil logo a seguir a saber programar, :D :D
« Última modificação: 02 de Setembro de 2015, 17:51 por Njay »

Offline dropes

  • Mini Robot
  • *
  • Mensagens: 2.189
Re: TCL ("ticle")
« Responder #25 em: 02 de Setembro de 2015, 15:17 »
Também acredito que quem não saiba programar não vá pegar em TCL (na de conceito).
Pela lógica, o que acho reduzido após as limitações, até que tem alguma piada.
Usado pelos fãs dos PLDs para criar uCs, seria possível criar um que interprete TLC apenas com portas lógicas.
Ainda este mês estive com um PLC só com TTLs + um GAL pelo meio, aquilo fez-me uma confusão desgraçada da imensidão de ICs, estava avariado e o técnico perguntou-me se sabia diagnosticar aquilo... LOL pistas queimadas e tal é para esquecer.

StarRider

  • Visitante
Re: TCL ("ticle")
« Responder #26 em: 03 de Setembro de 2015, 22:35 »

Hum ... pois expressões regulares e p-code não obrigado  ;D

Sou daqueles que ainda nos dias de hoje faz contas de cabeça ao numero
de ciclos por cada llinha/rotina que programo, e mesmo em sistemas não
embebed não sou nada adepto de linguagens interpretadas ou semi complidas
que correm em interpretadores de p-code.

Abraços,
PA