Академический Документы
Профессиональный Документы
Культура Документы
1
Python Aplicado a Problemas de Gestão de
Recursos Humanos
Universidade de Lisboa
cgoncalves@iscsp.ulisboa.pt
2
Índice
1. Introdução à Linguagem Python .................................................................................. 3
Exercício 1................................................................................................................... 20
Alínea a. .................................................................................................................. 20
Alínea b. .................................................................................................................. 20
Alínea c. .................................................................................................................. 21
Alínea d. .................................................................................................................. 21
Exercício 2................................................................................................................... 21
Exercício 3................................................................................................................... 23
Alínea a. .................................................................................................................. 23
Alínea c. .................................................................................................................. 23
Exercício 4................................................................................................................... 25
Exercício 5................................................................................................................... 25
Exercício 6................................................................................................................... 26
Bibliografia...................................................................................................................... 27
3
1. Introdução à Linguagem Python
A linguagem Python foi adoptada pelo MIT no curso de Engenharia Eléctrica e Ciência
da Computação (http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/),
no ensino da programação1 e da Inteligência Artificial. Esta linguagem tem também sido utilizada
pela Google e pela NASA, assim como por um conjunto crescente de empresas, conforme
ilustrado no website:
https://www.python.org/about/success/#business
1
Embora as linguagens C++ e Java também sejam ensinadas.
4
níveis cognitivos. Assim, em termos computacionais, existem elementos de Inteligência Artificial
(IA) incorporados na programação orientada a objectos.
Um objecto corresponde a uma instância de uma classe, quando definimos uma classe,
definimos os atributos de instância e os procedimentos computacionais integrados nos
chamados métodos de instância, um método de instância descreve uma unidade coerente de
computação que define o comportamento das instâncias de uma dada classe, correspondendo
a um algoritmo: sempre que o método é invocado, o algoritmo é executado pelo computador
para a instância correspondente.
Podemos, então, definir a classe das unidades fabris tal que cada uma das dez unidades
5
fabris corresponde a uma instância particular. Os atributos de instância correspondem às
variáveis estatísticas. Embora não seja uma condição imposta pela linguagem, adoptaremos a
convenção da Oracle, tal que:
Nomes das Classes: a primeira letra de cada palavra que compõe o nome de
uma classe é definida como maiúscula, sendo as restantes letras definidas como
minúsculas, assim, para o problema em causa temos a classe designada por
UnidadeFabril;
Nomes dos Métodos: a primeira letra é definida como minúscula, quando um
método é composto por várias palavras têm de aparecer juntas, sem espaços,
no nome do método, a convenção é: para a primeira palavra que compõe o
nome do método as letras são minúsculas, enquanto que a primeira letra, para
cada uma das restantes palavras que compõem o nome de um método, é
definida como maiúscula (por exemplo, avaliaProdutividade ou
avaliaTrabalhadoresDaUnidade), o nome do método deverá expressar o tipo de
actividade de análise que é realizada e o interesse da mesma para a gestão da
empresa.
class UnidadeFabril:
def __init__(self,local,numTrab,pecaHora,formacao,acidentes,operarios,antiguidade):
self.local = local # Localização da Unidade (Portugal ou Espanha)
self.numTrab = numTrab # Número de trabalhadores
self.pecaHora = pecaHora # Número de peças produzidas por hora
self.formacao = formacao # Número de horas de formação
self.acidentes = acidentes # Número de acidentes de trabalho
self.operarios = operarios # Número de operários
self.antiguidade = antiguidade # Antiguidade máxima dos operários
6
operarios: número de operários;
antiguidade: antiguidade máxima.
Em termos tradicionais, uma base de dados tem uma estrutura semelhante a uma
tabela, em que a cada linha corresponde um membro da população sob análise e a cada coluna
corresponde uma variável estatística. O quadro seguinte contém um exemplo desta estrutura
tradicional de base de dados, para o caso sob análise.
Nº de Peça / Nº de
Local Formação Acidentes Antiguidade
Trabalhadores hora Operários
Unidade 1 Portugal 200 20 2000 20 150 20
Unidade 2 Portugal 250 10 1200 10 120 15
Unidade 3 Portugal 300 25 2000 20 250 30
Unidade 4 Portugal 210 15 1500 30 110 20
Unidade 5 Portugal 220 16 1600 25 110 20
Unidade 6 Portugal 230 16 2000 15 150 25
Unidade 7 Espanha 250 25 2000 20 160 15
Unidade 8 Espanha 250 26 1100 14 160 16
Unidade 9 Espanha 210 17 1200 10 150 17
Unidade 10 Espanha 210 14 1200 20 150 20
Em Python, a cada unidade irá corresponder uma instância, assim, temos o seguinte
processo de instanciação, conforme passamos a explicar:
Unidade1 = UnidadeFabril('Portugal',200,20,2000,20,150,20)
Unidade2 = UnidadeFabril('Portugal',250,10,1200,10,120,15)
Unidade3 = UnidadeFabril('Portugal',300,25,2000,20,250,30)
Unidade4 = UnidadeFabril('Portugal',210,15,1500,30,110,20)
Unidade5 = UnidadeFabril('Portugal',220,16,1600,25,110,20)
Unidade6 = UnidadeFabril('Portugal',230,16,2000,15,150,25)
Unidade7 = UnidadeFabril('Espanha',250,25,2000,20,160,15)
Unidade8 = UnidadeFabril('Espanha',250,26,1100,14,160,16)
Unidade9 = UnidadeFabril('Espanha',210,17,1200,10,150,17)
Unidade10 = UnidadeFabril('Espanha',210,15,1200,20,150,20)
O sinal “=” não corresponde a um sinal de “igual” matemático mas sim ao símbolo de
atribuição, cada linha de código acima dá ao computador a instrução para criar um objecto,
atribuindo-lhe, como valor, uma instância da classe UnidadeFabril com determinados valores,
assim a primeira linha de código pode ser lida do seguinte modo:
7
valores para os atributos:
o local: Portugal;
o numTrab: 200;
o pecaHora: 20;
o formacao: 2000;
o acidentes: 20;
o operarios: 150;
o antiguidade: 20.
Vamos assumir, então, que a empresa pretende avaliar cada unidade fabril segundo
critérios definidos a partir de objectivos relacionados com a produtividade, a formação e os
acidentes. Podemos, então, definir três métodos de instância:
avaliaProdutividade
avaliaFormacao
avaliaAcidentes
avaliaUnidade
8
adicionais definidos como parâmetros externos (inputs do método2).
Comunica:
Divisão inferior a 1 'não atingiu o objectivo de Devolve resultado do rácio
produtividade'
Comunica:
Divide peça/hora por
Divisão igual a 1 'atingiu o objectivo de Devolve resultado do rácio
objectivo
produtividade'
Comunica:
Divisão superior a 1 'superou o objectivo de Devolve resultado do rácio
produtividade'
2
Os inputs de um método, para problemas de gestão, geralmente correspondem a variáveis
estratégicas que estão sob o controlo da empresa, podendo ser alteradas pela gestão da empresa (a
definição de um objectivo quantitativo pela gestão da empresa constui um exemplo).
o agente comunica que a unidade fabril que lhe corresponde não atingiu o objectivo de
9
produtividade.
Quando o rácio é igual a 1, o resultado obtido coincide com o objectivo, logo, o agente
comunica que a unidade que lhe corresponde atingiu o objectivo de produtividade.
Em qualquer das alternativas, o agente devolve o resultado do rácio, podendo esse valor
ser utilizado pelo agente para efeitos de cálculo futuro, como iremos ver mais adiante.
def avaliaProdutividade(self,objectivo):
avaliacao = self.pecaHora / objectivo
if avaliacao < 1:
print(self.nome, 'não atingiu o objectivo de produtividade')
elif avaliacao == 1:
print(self.nome, 'atingiu o objectivo de produtividade')
else:
print(self.nome, 'superou o objectivo de produtividade')
return avaliacao
Se o conteúdo da variável avaliacao for inferior a 1 (if avaliacao < 1:), então, imprime
na consola do Python o conteúdo do atributo nome (o nome da unidade fabril)
seguido da mensagem não atingiu o objectivo de produtividade (print(self.nome,
'não atingiu o objectivo de produtividade'));
Se o conteúdo da variável avaliacao for igual a 1 (elif avaliacao == 1:), então, imprime
10
na consola do Python o conteúdo do atributo nome (o nome da unidade fabril)
seguido da mensagem atingiu o objectivo de produtividade (print(self.nome, 'atingiu
o objectivo de produtividade'));
Se o conteúdo da variável avaliacao for superior a 1 (else:), então, imprime na
consola do Python o conteúdo do atributo nome (o nome da unidade fabril) seguido
da mensagem superou o objectivo de produtividade (print(self.nome, 'superou o
objectivo de produtividade')).
A estrutura condicional SE (if) – DE OUTRO MODO (else), é tal que o agente realiza um
determinado conjunto de acções se uma dada condição se verifica, de outro modo (isto é, nos
restantes casos em que a condição não se verifica) realiza outro conjunto de acções.
No caso acima, a estrutura é mais complexa, pois existem três ramos, o primeiro está
marcado com a expressão if (SE), o segundo ramo (segunda alternativa) está marcado com a
expressão elif que significa else if (DE OUTRO MODO, SE). Deste modo, quando a primeira
condição não se verifica, se a segunda se verifica, então, o agente realiza as acções
correspondentes à segunda condição.
avaliacao, o que permite incorporar o método no cálculo posterior da avaliação final da unidade
11
fabril.
O método seguinte inclui o cálculo do rácio horas de formação por operário e a avaliação
face ao objectivo.
def avaliaFormacao(self,objectivo):
racio = self.formacao / self.operarios
avaliacao = racio / objectivo
if avaliacao < 1:
print(self.nome, 'horas de formação por trabalhador inferiores ao objectivo')
elif avaliacao == 1:
print(self.nome, 'horas de formação por trabalhador iguais ao objectivo')
else:
print(self.nome, 'horas de formação por trabalhador superiores ao objectivo')
return avaliacao
def avaliaAcidentes(self,objectivo):
racio = self.acidentes / self.operarios
avaliacao = racio / objectivo
if avaliacao < 1:
print(self.nome, 'superou o objectivo de acidentes por operário')
elif avaliacao == 1:
print(self.nome, 'atingiu o objectivo de acidentes por operário')
else:
print(self.nome, 'não atingiu o objectivo de acidentes por operário')
return 1 / avaliacao
3
Outros objectivos de formação podem ser trabalhados, implicando a alteração ou mesmo
introdução de novos métodos para as instâncias da classe UnidadeFabril.
12
Embora com uma base análoga aos restantes métodos analisados até ao momento,
existem algumas diferenças neste método, no que se refere à relação entre o rácio e o objectivo,
pois quanto menor o rácio melhor a performance, ao contrário do que acontecia no caso do
método anterior.
Assim, se o valor da avaliação for inferior a 1, isso significa que o rácio de acidentes por
operário é inferior ao objectivo definido pela empresa o que implica uma boa performance, logo,
considera-se que a unidade fabril superou o objectivo em termos de número de acidentes por
operário. Se o valor da avaliação for igual a 1, então, a unidade fabril atingiu o objectivo.
Contudo, se o valor da avaliação for superior a 1, isso significa que a unidade fabril tem mais
acidentes por operário do que o objectivo definido pela empresa, o que significa uma má
performance em termos de acidentes, logo, considera-se, neste caso, que a empresa não atingiu
o objectivo em termos de acidentes por operário.
Dado que a avaliação segue no sentido inverso dos restantes elementos sob avaliação,
ou seja, quanto maior o valor pior é a performance da unidade fabril, a instrução “return”
devolve o valor inverso da avaliação, será esse o valor a ser utilizado na ponderação final da
avaliação da unidade fabril.
def avaliaUnidade(self,objectivos,pesos):
prod = self.avaliaProdutividade(objectivos[0])
form = self.avaliaFormacao(objectivos[1])
acid = self.avaliaAcidentes(objectivos[2])
avaliacao = pesos[0] * prod + pesos[1] * form + pesos[2] * acid
print('Valor Final:', avaliacao,'\n')
O método avaliaUnidade recebe como inputs uma lista de objectivos e uma lista de
pesos associados a cada dimensão sob avaliação. O método executa a avaliação da
produtividade e guarda o valor devolvido por esta avaliação numa variável local “prod”, o
mesmo é feito para a avaliação da formação (guardada na variável “form”) e dos acidentes
(guardada na variável “acid”), a avaliação final resulta de uma média ponderada de cada uma
das avaliações em que cada avaliação é multiplicada pelo peso respectivo, o método imprime,
então, o resultado final da avaliação da unidade e muda de linha deixando um espaço (comando
newline: '\n').
O método trabalha com um tipo de objecto primitivo em Python designado por lista.
13
Uma lista é representada, na linguagem Python, como uma sequência de valores separada por
vírgulas e delimitada por parêntesis rectos. Assim, por exemplo, uma lista dos nomes João,
Maria e José, seria representada em Python como [João,Maria,José]. Se atribuirmos esta lista a
uma variável chamada “amigos”, podemos escrever:
amigos = [João,Maria,José]
No caso do método avaliaUnidade, existem duas listas que são fornecidas ao agente
artificial, uma lista de objectivos, em termos de valores definidos como objectivos a serem
cumpridos pelas unidades fabris, e uma lista de pesos, que corresponde ao valor atribuído pela
empresa a cada dimensão de avaliação. A lista de objectivos é utilizada na fase de avaliação de
cada dimensão enquanto que a lista de pesos é utilizada na avaliação final da unidade fabril.
Utilizando estes elementos, cada agente tem a estrutura cognitiva necessária para
avaliar cada unidade, assim que tenha os valores correspondentes. Considere-se, então, que a
empresa definiu os seguintes objectivos para as unidades fabris:
10 peças/hora produzidas;
20 horas de formação por operário;
No máximo 5 acidentes por cada 100 operários (rácio de 0.05).
A lista de pesos é, então, dada por pesos = [0.35,0.35,0.3], o código final em linguagem
Python é apresentado no website http://pythonfiddle.com/avaliacao-de-desempenho/.
Executando o código, verifica-se que as unidades 1, 3, 7 e 8 apresentam um resultado final
superior a 1, ou seja, a classificação média é positiva. Contudo, nenhuma destas quatro unidades
cumpriu os objectivos de formação e de acidentes por operário, o que ocorre também com as
14
restantes unidades fabris.
A GRH é, deste modo, suportada por métodos de trabalho dos dados dirigidos a uma
resposta feita à medida. Desde que as condições do problema se mantenham inalteradas, as
mesmas classes e os mesmos métodos podem ser implementados, trata-se de um problema de
generalidade algorítmica.
Se outros critérios de avaliação tivessem sido definidos pela empresa, o programa a ser
escrito teria sido distinto. Assim, existe a possibilidade de construir “fatos à medida” do gestor,
em que o sistema artificial analisa os dados e sintetiza a informação que é mais útil ao gestor na
sua actividade. O “discurso” da máquina pode inclusive ser adaptado ao discurso do gestor,
15
estatístico e o nível de discurso de gestão.
Por seu turno, é possível também desenvolver sistemas multiproblema, isto é, sistemas
que são capazes de resolver diferentes problemas de gestão e, sem modificação de código,
suportar o gestor no seu trabalho. O sistema artificial a ser desenvolvido depende do tipo de
problema de gestão a ser trabalhado.
Assim, tudo aquilo que, na Gestão Empresarial (e das organizações em geral), pode ser
convertido em algoritmo poderá ser resolvido por uma máquina, por seu turno, tudo aquilo que
na gestão possa ser resolvido por uma máquina, mais eficientemente e eficazmente do que por
um humano, tenderá a ser resolvido por uma máquina (devido à própria acção humana de
desenhar tecnologias que substituam a componente humana nessa tarefa). Note-se que a
máquina não substitui, neste caso, o gestor, mas, sim, apoia-o no processo de tomada de
decisão, realizando parte da tarefa do gestor, tornando a tarefa mais fácil, logo, mais rápida.
Importa relevar, contudo, que a máquina poderá nem sempre substituir com mais
eficiência o ser humano numa dada actividade, principalmente se a actividade a ser realizada
pela máquina for algoritmicamente complexa (conceito de complexidade algorítmica), neste
caso, a capacidade humana para capturar totalidades poderá conduzir a uma solução mais
eficiente dado que pode ir para além do algoritmo, não sendo confinada a segui-lo.
Se alguma vez uma máquina for capaz de intuir soluções de modo não-algorítmico,
16
então, poderá também ultrapassar a barreira dos limites à computação, trata-se, contudo, de
uma estrutura tecnológica distinta da que temos presentemente, embora, em termos de Ciência
da Computação, não possamos rejeitar esta possibilidade, isto é, não podemos afirmar ser
impossível construir tecnologia não-algorítmica (ou com níveis de actividade não-algorítmicos).
de trabalho permanente (os registos dos valores nos atributos de instância), assim como é
17
possível introduzir memória de trabalho temporária (as variáveis locais).
Deste modo, o programa é abordado a partir de uma dinâmica cognitiva, o que suporta
um trabalho mais eficaz no sentido em que uma dinâmica cognitiva humana algoritmizável
pode, por paralelismo, ser programada na máquina.
18
3. Uma empresa definiu um sistema de controlo de acidentes de trabalho que emite um
aviso de excesso de acidentes se o número anual de acidentes ultrapassar um limite
definido como número máximo aceitável pela empresa. Com base nesta informação,
responda às seguintes questões:
a. Defina a classe apropriada para o caso (nome da classe e atributos).
b. Defina um método de instância que expresse, em código Python, o sistema de
controlo definido pela empresa, para os seguintes dois casos:
i. A empresa apenas pretende que o sistema forneça o alerta sem
apresentar qual o número de acidentes.
ii. A empresa pretende que o número de acidentes seja fornecido pelo
sistema em qualquer circunstância.
c. Expresse o método de instância para o código das alíneas b.i. e b.ii. em árvore
de decisão, e analise as diferenças em termos de Gestão de Recursos Humanos.
4. Modifique a árvore da questão anterior para o caso em que a empresa pretende que o
sinal de alerta tenha o seguinte código de cores:
a. Alerta Amarelo: se o número de acidentes com nível de gravidade elevada se
situar entre 25% (inclusive) e 50% (exclusive) do número total de acidentes;
b. Alerta Laranja: se o número de acidentes com nível de gravidade elevada se
situar entre 50% (inclusive) e 75% (exclusive) do número total de acidentes;
c. Alerta Vermelho: se o número de acidentes com nível de gravidade elevada for
superior ou igual a 75% do número total de acidentes.
6. A tabela seguinte contém dados de produtividade média para dez sucursais de uma
empresa, no ano de 2014, construa um programa em Python que classifique as sucursais
em função do objectivo de produtividade média (comum às 10 sucursais), tal que se
houverem sucursais que tenham atingido ou superado o objectivo de produtividade,
aquela que tiver a produtividade mais elevada recebe um prémio de produtividade e
execute o código para as 10 sucursais. Considere, na resolução, um objectivo de
produtividade média de 225 Euros/hora.
Sucursais Produtividade
19
Média
(Euros/h)
Sucursal 1 230
Sucursal 2 150
Sucursal 3 260
Sucursal 4 220
Sucursal 5 120
Sucursal 6 110
Sucursal 7 225
Sucursal 8 250
Sucursal 9 270
Sucursal 10 220
20
Exercício 1.
Alínea a.
Dado que se pretende avaliar os vendedores, o nome da classe é definido como
“Vendedores”, o atributo sob avaliação é o atributo “vendas”, para além desse atributo,
introduzimos também os atributos código do vendedor e nome, de onde resulta a seguinte
definição de classe:
Alínea b.
Conforme definido pela empresa, temos uma estrutura condicional, assim:
Temos, assim, o seguinte código em Python, com a definição da classe (alínea anterior)
e do método de instância:
O método recebe como inputs a média das vendas realizadas por cada vendedor e a
proporção definida pela empresa e avalia a condicional tal que: se as vendas de um vendedor
forem superiores à média, então, atribui um prémio decorrente da multiplicação da proporção
4
Na resolução dos exercícios utilizamos, por uma questão de efeito comparativo, a versão 2 do
Python.
definida pela empresa pelas vendas realizadas por esse vendedor e imprime a informação de
21
que o vendedor deverá receber o prémio.
Alínea c.
Calcula prémio
Comunica: codigo
nome recebe
prémio de <valor
do prémio> euros
Alínea d.
A resolução encontra-se disponível no website:
https://sites.google.com/site/mqgestao/programas-em-python/caso-vendedores
http://pythonfiddle.com/vendedores
Exercício 2.
Temos, agora, de definir uma segunda condicional, tal que, se o prémio exceder o
prémio máximo definido pela empresa (novo input do método), então, atribui-se o prémio
máximo ao vendedor, caso contrário o vendedor recebe o prémio proporcional às suas vendas.
22
.
Calcula prémio
Exercício 3.
23
Alínea a.
Dado que se pretende avaliar o número total anual de acidentes de trabalho, o nome
da classe é definido como “Acidentes”, definida com um único atributo o número de
acidentes, assim, escrevemos:
Alínea b.i.
Face ao critério definido pela empresa, o seguinte código em Python, com a definição
da classe (alínea anterior) e do método de instância, fornece uma solução para o problema:
Alínea b.ii.
Dado que a empresa pretende que o número de acidentes seja fornecido pelo sistema
em qualquer circustância o código tem de ser modificado para:
Alínea c.
Para o caso da alínea b.ii. a árvore é dada por:
24
.
Número de
Acidentes > Limite
Comunica: Alerta:
Excesso de
Acidentes de
Trabalho!
Comunica: Número
de acidentes de
trabalho: <número>
Número de
Acidentes > Limite
Comunica: Alerta:
Excesso de
Acidentes de
Trabalho!
Exercício 4.
25
Comunica: Número
de acidentes de
trabalho:
<número>
Número de
Acidentes > Limite
Comunica: Alerta:
Excesso de
Acidentes de
Trabalho!
Calcula
percentagem de
acidentes com
gravidade elevada
25% ≤
50 ≤ Percentagem < Percentagem ≥
Percentagem <
75% 75%
50%
Exercício 5.
Exercício 6.
26
O programa, em Python é dado pelo código seguinte:
Bibliografia
27
Borny, T. 2015, Interview: Neil Jacobstein Discusses Future of Jobs, Universal
Basic Income and the Ethical Dangers of AI,
http://singularityhub.com/2015/03/23/future-of-work-interview-with-neil-
jacobstein/.
Cassel, L. and Gauld, A. 2015, Python® Projects, Wrox.
Downey, Allen B. 2012, Think Python, O'Reilly Media. Introdução ao Python
disponível no formato Wiki: http://en.wikibooks.org/wiki/Think_Python.
Goertzel, B. 2014, Ten Years to the Singularity, If We Really Really Try…and
other Essays on AGI and its Implications, humanity+ Press.
Gonçalves, 2014, Singularidade Tecnológica e a Terceira Revolução Industrial,
https://www.academia.edu/9763186/Singularidade_Tecnol%C3%B3gica_e_a_
Terceira_Revolu%C3%A7%C3%A3o_Industrial.