Este é um pequeno tutorial para aqueles que ainda não conhecem Python. Python é uma linguagem de programação multiplataforma de código aberto que possui vários recursos que o diferenciam de outras linguagens, tornado seu aprendizado muito acessível aos novos usuários:
Esse texto é uma introdução muito básica e não um tutorial completo. Mas esperamos que seja um ponto de partida e ajude a aprofundar seus conhecimento do FreeCAD e seus mecanismos. Recomendamos que você experimente os trechos de código abaixo em um interpretador Python.
Geralmente, quando se escreve programas de computador, você ira abrir um editor de texto ou editor de código para desenvolvimentos (que basicamente é um editor de texto com algumas ferramentas adicionais), escreve seu código, compila e executa. É comum acontecer um ou mais erros que impedem seu programa de funcionar, provavelmente um erro de digitação ou sintaxe, então seu programa não funcionará. Na maioria dos casos irá receber uma mensagem de erro dizendo o que deu errado. Então você volta ao seu editor de texto, corrige os erros, executa novamente, repetindo até que seu programa funcione como pretendido.
No Python, todo esse processo pode ser realizado de forma transparente dentro do interpretador Python. O interpretador é uma janela do Python com um prompt de comando, onde você pode simplesmente digitar código Python. Se você instalou o Python no seu computador (baixe-o no site do Python caso utilize Windows ou Mac, ou instale-o a partir do repositório de pacotes se utilizar GNU/Linux), terá um interpretador Python disponível no menu Iniciar. No entanto, como já mencionado, o FreeCAD também possui um interpretador Python integrado: o Console Python.
Console Python do FreeCAD
Se não o vir, clique em Exibir → Painéis → Console Python. O Console Python pode ser redimensionado e também desencaixado.
O interpretador exibe a versão do Python e, em seguida, o símbolo >>>, que representa o prompt de comando. Escrever código no interpretador é simples: cada linha corresponde a uma instrução. Ao pressionar Enter, a linha de código é executada (após ser compilada de forma instantânea e invisível). Por exemplo, tente escrever isto:
print("hello")
print() é um comando do Python que, obviamente, imprime algo na tela. Ao pressionar Enter, a operação é executada e a mensagem "hello" é impressa. Se você cometer um erro — por exemplo, vamos escrever:
print(hello)
O Python informará isso imediatamente. Nesse caso, o Python não sabe o que é hello. Os caracteres " " especificam que o conteúdo é uma *string* — jargão de programação para um trecho de texto. Sem eles, o comando print() não reconhece hello. Ao pressionar a seta para cima, você pode voltar à última linha de código e corrigi-la.
O interpretador Python também possui um sistema de ajuda integrado. Digamos que não entendamos o que deu errado com print(hello) e queiramos informações específicas sobre o comando:
help(print)
Você receberá uma descrição detalhada e completa de tudo o que o comando print() pode fazer.
Agora que você entende o interpretador Python, podemos prosseguir com as coisas mais sérias.
Com muita frequência, na programação, você precisa armazenar um valor associado a um nome. É aí que entram as variáveis. Por exemplo, digite isto:
a = "hello"
print(a)
Você provavelmente entendeu o que aconteceu aqui: salvamos a string "hello" com o nome a. Agora que a está definido, podemos usá-lo em qualquer lugar, por exemplo, no comando print(). Podemos usar o nome que quisermos; basta seguir algumas regras simples, como não usar espaços ou pontuação e não utilizar palavras-chave do Python. Por exemplo, podemos escrever:
hello = "my own version of hello"
print(hello)
Agora, hello não é mais indefinido. Variáveis podem ser modificadas a qualquer momento; é por isso que são chamadas de variáveis: seu conteúdo pode variar. Por exemplo:
myVariable = "hello"
print(myVariable)
myVariable = "good bye"
print(myVariable)
Alteramos o valor de myVariable. Também podemos copiar variáveis:
var1 = "hello"
var2 = var1
print(var2)
É aconselhável dar nomes significativos às suas variáveis. Depois de algum tempo, você não se lembrará do que a variável chamada a representa. Mas, se você a nomeou, por exemplo, como myWelcomeMessage, lembrará facilmente de sua finalidade. Além disso, seu código fica um passo mais próximo de ser autodocumentado.
A diferenciação entre maiúsculas e minúsculas é muito importante; myVariable não é o mesmo que myvariable. Se você digitasse print(myvariable), receberia um erro indicando que a variável não está definida.
É claro que programas em Python podem lidar com todos os tipos de dados, não apenas com strings de texto. Um ponto importante é que o Python precisa saber com que tipo de dado está lidando. Vimos no nosso exemplo de imprimir "hello" que o comando print() reconheceu a string "hello". Ao utilizar os caracteres " ", especificamos que o conteúdo seguinte é uma string de texto.
Podemos sempre verificar o tipo de dado de uma variável com o comando type():
myVar = "hello"
type(myVar)
Isso nos dirá que o conteúdo de myVar é uma 'str', abreviação de *string*. Também temos outros tipos de dados básicos, como números inteiros e de ponto flutuante (*float*):
firstNumber = 10
secondNumber = 20
print(firstNumber + secondNumber)
type(firstNumber)
O Python sabe que 10 e 20 são números inteiros, portanto são armazenados como 'int', e o Python pode realizar com eles todas as operações possíveis com números inteiros. Veja os resultados disto:
firstNumber = "10"
secondNumber = "20"
print(firstNumber + secondNumber)
Aqui, forçamos o Python a considerar que nossas duas variáveis não são números, mas sim trechos de texto. O Python consegue somar dois trechos de texto, embora, nesse caso, é claro, não realize nenhuma operação aritmética. Mas estávamos falando de números inteiros. Existem também os números de ponto flutuante (*float*). A diferença é que os números de ponto flutuante podem ter uma parte decimal, enquanto os números inteiros não:
var1 = 13
var2 = 15.65
print("var1 is of type ", type(var1))
print("var2 is of type ", type(var2))
Números inteiros e de ponto flutuante podem ser misturados sem problemas:
total = var1 + var2
print(total)
print(type(total))
Como var2 é um float, o Python decide automaticamente que o resultado também deve ser um float. No entanto, existem casos em que o Python não sabe qual tipo utilizar. Por exemplo:
varA = "hello 123"
varB = 456
print(varA + varB)
Isso resulta em um erro: varA é uma string e varB é um inteiro, e o Python não sabe o que fazer. No entanto, podemos forçar o Python a converter entre tipos:
varA = "hello"
varB = 123
print(varA + str(varB))
Agora que ambas as variáveis são strings, a operação funciona. Observe que convertemos varB em string no momento da impressão, mas não alteramos a própria varB. Se quiséssemos transformar varB permanentemente em uma string, precisaríamos fazer o seguinte:
varB = str(varB)
Também podemos usar int() e float() para converter para inteiro e ponto flutuante, se quisermos:
varA = "123"
print(int(varA))
print(float(varA))
Você deve ter notado que usamos o comando print() de várias maneiras. Imprimimos variáveis, somas, vários itens separados por vírgulas e até mesmo o resultado de outro comando do Python. Talvez você também tenha visto que estes dois comandos:
type(varA)
print(type(varA))
ter o mesmo resultado. Isso ocorre porque estamos no intérprete e tudo é impresso automaticamente. Quando escrevemos programas mais complexos que rodam fora do interpretador, eles não serão impressos automaticamente, então precisaremos usar o comando print(). Com isso em mente, vamos parar de usá-lo aqui. De agora em diante escreveremos simplesmente:
myVar = "hello friends"
myVar
Outro tipo de dado útil é a lista. Uma lista é uma coleção de outros dados. Para definir uma lista, usamos [ ]:
myList = [1, 2, 3]
type(myList)
myOtherList = ["Bart", "Frank", "Bob"]
myMixedList = ["hello", 345, 34.567]
Como você pode ver, uma lista pode conter qualquer tipo de dado. Você pode fazer muitas coisas com uma lista. Por exemplo, contar seus itens:
len(myOtherList)
Ou recupere um item:
myName = myOtherList[0]
myFriendsName = myOtherList[1]
Embora o comando len() retorne o número total de itens em uma lista, o primeiro item de uma lista está sempre na posição 0; portanto, em nossa myOtherList, "Bob" estará na posição 2. Podemos fazer muito mais com listas, como ordenar itens e remover ou adicionar itens.
Curiosamente, uma string de texto é muito semelhante a uma lista de caracteres em Python. Tente fazer isto:
myvar = "hello"
len(myvar)
myvar[2]
Geralmente, o que você pode fazer com listas também pode ser feito com strings. Na verdade, tanto listas quanto strings são sequências.
Além de strings, números inteiros, números de ponto flutuante e listas, existem outros tipos de dados nativos, como dicionários, e você pode até criar seus próprios tipos de dados usando classes.
Um uso importante das listas é a capacidade de percorrê-las e fazer algo com cada item. Por exemplo, veja isto:
alldaltons = ["Joe", "William", "Jack", "Averell"]
for dalton in alldaltons:
print(dalton + " Dalton")
Percorremos nossa lista (usando o termo técnico de programação "iterar") com o comando for in e realizamos uma ação com cada um dos itens. Observe a sintaxe especial: o comando for termina com :, indicando que o que se segue será um bloco contendo um ou mais comandos. No interpretador, logo após você inserir a linha de comando terminada em :, o prompt de comando mudará para ..., indicando que o Python sabe que há mais conteúdo por vir.
Como o Python saberá quantas das linhas seguintes precisam ser executadas dentro da operação for in? Para isso, o Python utiliza a indentação. As linhas seguintes devem começar com um ou mais espaços em branco, ou com uma ou mais tabulações. Enquanto a indentação permanecer a mesma, as linhas serão consideradas parte do bloco for in. Se você começar uma linha com 2 espaços e a seguinte com 4, ocorrerá um erro. Quando terminar, basta escrever outra linha sem indentação ou pressionar Enter para sair do bloco for in.
A indentação também auxilia na legibilidade do programa. Se você utilizar indentações amplas (por exemplo, usando tabulações em vez de espaços) ao escrever um programa extenso, terá uma visão clara de qual parte do código é executada dentro de outra. Veremos que outros comandos também utilizam blocos de código indentados.
O comando for in pode ser usado para muitas coisas que precisam ser feitas mais de uma vez. Ele pode, por exemplo, ser combinado com o comando range():
serie = range(1, 11)
total = 0
print("sum")
for number in serie:
print(number)
total = total + number
print("----")
print(total)
Se você tem executado os exemplos de código em um interpretador copiando e colando, perceberá que o bloco de texto anterior gera um erro. Em vez disso, copie até o final do bloco recuado — ou seja, até o final da linha total = total + number — e cole no interpretador. No interpretador, pressione Enter até que o prompt de três pontos desapareça e o código seja executado. Em seguida, copie as duas últimas linhas e pressione Enter novamente. O resultado final deverá aparecer.
Se você digitar help(range) no interpretador, verá:
range(...)
range(stop) -> list of integers
range(start, stop[, step]) -> list of integers
Aqui, os colchetes indicam um parâmetro opcional. No entanto, espera-se que todos sejam números inteiros. Abaixo, forçaremos o parâmetro de passo a ser um número inteiro usando int():
number = 1000
for i in range(0, 180 * number, int(0.5 * number)):
print(float(i) / number)
Outro exemplo de range():
alldaltons = ["Joe", "William", "Jack", "Averell"]
for n in range(4):
print(alldaltons[n], " is Dalton number ", n)
O comando range() também apresenta aquela peculiaridade curiosa de começar em 0 (caso você não especifique o número inicial) e de ter como último número um valor inferior ao número final especificado. Isso ocorre, naturalmente, para que ele funcione bem com outros comandos do Python. Por exemplo:
alldaltons = ["Joe", "William", "Jack", "Averell"]
total = len(alldaltons)
for n in range(total):
print(alldaltons[n])
Outro uso interessante de blocos recuados é com o comando if. Esse comando executa um bloco de código apenas se uma determinada condição for atendida; por exemplo:
alldaltons = ["Joe", "William", "Jack", "Averell"]
if "Joe" in alldaltons:
print("We found that Dalton!!!")
É claro que isso sempre imprimirá a frase, mas tente substituir a segunda linha por:
if "Lucky" in alldaltons:
Então, nada é impresso. Também podemos especificar uma instrução else:
alldaltons = ["Joe", "William", "Jack", "Averell"]
if "Lucky" in alldaltons:
print("We found that Dalton!!!")
else:
print("Such Dalton doesn't exist!")
Existem muito poucos comandos padrão do Python, e já conhecemos vários deles. Mas você pode criar seus próprios comandos. Na verdade, a maioria dos módulos adicionais que você pode incorporar à sua instalação do Python faz exatamente isso: eles adicionam comandos que você pode utilizar. Um comando personalizado no Python é chamado de função e é criado da seguinte maneira:
def printsqm(myValue):
print(str(myValue) + " square meters")
printsqm(45)
O comando def() define uma nova função; você atribui um nome a ela e, entre parênteses, define os argumentos que a função utilizará. Argumentos são dados que serão passados para a função. Por exemplo, observe o comando len(). Se você escrever apenas len(), o Python informará que é necessário um argumento. Isso é óbvio: você quer saber o tamanho de algo. Se você escrever len(myList), então myList é o argumento passado para a função len(). E a função len() é definida de modo a saber o que fazer com esse argumento. Fizemos a mesma coisa com a nossa função printsqm.
O nome myValue pode ser qualquer um, e será usado apenas dentro da função. É apenas um nome que você atribui ao argumento para poder utilizá-lo. Ao definir argumentos, você também indica à função quantos deles ela deve esperar. Por exemplo, se você fizer isto:
printsqm(45, 34)
haverá um erro. Nossa função foi programada para receber apenas um argumento, mas recebeu dois: 45 e 34. Vamos tentar outro exemplo:
def sum(val1, val2):
total = val1 + val2
return total
myTotal = sum(45, 34)
Aqui, criamos uma função que recebe dois argumentos, soma-os e retorna esse valor. Retornar algo é muito útil, pois podemos fazer algo com o resultado, como armazená-lo na variável myTotal.
Agora que você tem uma boa noção de como o Python funciona, precisará saber mais uma coisa: como trabalhar com arquivos e módulos.
Até agora, escrevemos instruções em Python linha a linha no interpretador. Esse método, obviamente, não é adequado para programas maiores. Normalmente, o código de programas Python é armazenado em arquivos com a extensão `.py`; trata-se de arquivos de texto simples que podem ser criados e editados com qualquer editor de texto (como o gedit, emacs ou vi no Linux, ou até mesmo o Bloco de Notas do Windows).
Existem várias maneiras de executar um programa em Python. No Windows, basta clicar com o botão direito no arquivo, abri-lo com o Python e executá-lo. No entanto, você também pode executá-lo a partir do próprio interpretador Python. Para isso, o interpretador precisa saber onde o seu programa está localizado. No FreeCAD, a maneira mais fácil é colocar o programa em uma pasta que o interpretador Python do FreeCAD reconheça por padrão, como a pasta Mod do usuário no FreeCAD:
Vamos adicionar uma subpasta chamada scripts nesse local e, em seguida, criar um arquivo como este:
def sum(a,b):
return a + b
print("myTest.py succesfully loaded")
Salve o arquivo como myTest.py na pasta scripts e, na janela do interpretador, escreva:
import myTest
sem a extensão .py. Isso executará o conteúdo do arquivo, linha por linha, exatamente como se o tivéssemos escrito no interpretador. A função de soma será criada e a mensagem será impressa. Arquivos que contêm funções, como o nosso, são chamados de módulos.
Quando escrevemos uma função sum() no interpretador, nós a executamos assim:
sum(14, 45)
Mas, quando importamos um módulo que contém uma função sum(), a sintaxe é um pouco diferente:
myTest.sum(14, 45)
Ou seja, o módulo é importado como um "contêiner", e todas as suas funções estão dentro desse contêiner. Isso é muito útil, pois podemos importar vários módulos e manter tudo bem organizado. Basicamente, quando você vê something.somethingElse, com um ponto no meio, isso significa que somethingElse está dentro de something.
Também podemos importar nossa função sum() diretamente para o espaço principal do interpretador:
from myTest import *
sum(12, 54)
Quase todos os módulos fazem isso: eles definem funções, novos tipos de dados e classes que você pode usar no interpretador ou em seus próprios módulos Python, pois nada impede que você importe outros módulos dentro do seu módulo!
Como sabemos quais módulos temos, quais funções eles contêm e como usá-los (ou seja, que tipo de argumentos eles exigem)? Já vimos que o Python possui uma função help(). Ao executar:
help("modules")
nos fornecerá uma lista de todos os módulos disponíveis. Podemos importar qualquer um deles e explorar seu conteúdo com o comando dir():
import math
dir(math)
Veremos todas as funções contidas no módulo math, bem como alguns elementos curiosos chamados __doc__, __file__ e __name__. Toda função em um módulo bem elaborado possui um __doc__ que explica como utilizá-la. Por exemplo, vemos que existe uma função sin() dentro do módulo math. Quer saber como usá-la?
print(math.sin.__doc__)
Pode não ser evidente, mas há dois caracteres de sublinhado em cada lado de doc.
E, finalmente, uma última dica: ao trabalhar em código novo ou existente, é melhor não utilizar a extensão de arquivo de macro do FreeCAD, .FCMacro, mas sim a extensão padrão .py. Isso ocorre porque o Python não reconhece a extensão .FCMacro. Se você utilizar .py, seu código poderá ser facilmente carregado com import, como já vimos, e também recarregado com importlib.reload():
import importlib
importlib.reload(myTest)
Existe, no entanto, uma alternativa:
exec(open("C:/PathToMyMacro/myMacro.FCMacro").read())
Esperamos que agora você tenha uma boa noção de como o Python funciona e possa começar a explorar o que o FreeCAD tem a oferecer. As funções Python do FreeCAD estão todas bem organizadas em diferentes módulos. Algumas delas já são carregadas (importadas) quando você inicia o FreeCAD. Experimente:
dir()