25
Engenharia de Software
UNIVATES
2
Engenharia de Software
UNIVATES
1
Engenharia de Software
UNIVATES
62
Engenharia de Software
UNIVATES
19
Engenharia de Software
UNIVATES
Texto de pré-visualização
Code Challenge Ganho de Capital Contexto O objetivo deste exercício é implementar um programa de linha de comando CLI que calcula o imposto a ser pago sobre lucros ou prejuízos de operações no mercado financeiro de ações Por favor leia as instruções abaixo e sintase à vontade para fazer perguntas caso ache necessário Exemplo de uso do Ganho de Capital Como o programa deve funcionar Entrada Seu programa vai receber listas uma por linha de operações do mercado financeiro de ações em formato JSON através da entrada padrão stdin Cada operação desta lista contém os seguintes campos Nome Significado operation Se a operação é uma operação de compra buy ou venda sell unitcost Preço unitário da ação em uma moeda com duas casas decimais quantity Quantidade de ações negociadas Segue um exemplo da entrada formatado aqui para legibilidade O input real terá uma lista em cada linha operationbuy unitcost1000 quantity 10000 operationsell unitcost2000 quantity 5000 operationbuy unitcost2000 quantity 10000 operationsell unitcost1000 quantity 5000 As operações estarão na ordem em que elas ocorreram ou seja a segunda operação na lista aconteceu depois da primeira e assim por diante Cada linha é uma simulação independente seu programa não deve manter o estado obtido em uma linha para as outras A última linha da entrada será uma linha vazia Saída Para cada linha da entrada o programa deve retornar uma lista contendo o imposto pago para cada operação recebida Os elementos desta lista devem estar codificados em formato JSON e a saída deve ser retornada através da saída padrão stdout O retorno é composto pelo seguinte campo Nome Significado Nome Significado tax O valor do imposto pago em uma operação Este é um exemplo da saída tax 00 tax 100000 tax 00 tax 00 A lista retornada pelo programa deve ter o mesmo tamanho da lista de operações processadas na entrada Por exemplo se foram processadas três operações buy buy sell o retorno do programa deve ser uma lista com três valores que representam o imposto pago em cada operação Regras do Ganho de Capital O programa deve lidar com dois tipos de operações buy e sell e ele deve seguir as seguintes regras O percentual de imposto pago é de 20 sobre o lucro obtido na operação Ou seja o imposto vai ser pago quando há uma operação de venda cujo preço é superior ao preço médio ponderado de compra Para determinar se a operação resultou em lucro ou prejuízo você pode calcular o preço médio ponderado então quando você compra ações você deve recalcular o preço médio ponderado utilizando essa fórmula novamediaponderada quantidadedeacoesatual mediaponderada atual quantidadedeacoescompradas valordecompra quantidadedeacoesatual quantidadedeacoescompradas Por exemplo se você comprou 10 ações por R 2000 vendeu 5 depois comprou outras 5 por R 1000 a média ponderada é 5 x 2000 5 x 1000 5 5 1500 Você deve usar o prejuízo passado para deduzir múltiplos lucros futuros até que todo prejuízo seja deduzido Prejuízos acontecem quando você vende ações a um valor menor do que o preço médio ponderado de compra Neste caso nenhum imposto deve ser pago e você deve subtrair o prejuízo dos lucros seguintes antes de calcular o imposto Você não paga nenhum imposto e não deve deduzir o lucro obtido dos prejuízos acumulados se o valor total da operação custo unitário da ação x quantidade for menor ou igual a R 2000000 Use o valor total da operação e não o lucro obtido para determinar se o imposto deve ou não ser pago E não se esqueça de deduzir o prejuízo dos lucros seguintes Nenhum imposto é pago em operações de compra Você pode assumir que nenhuma operação vai vender mais ações do que você tem naquele momento Exemplos do Ganho de Capital Caso 1 Operação Custo unitário Quantidade Imposto Pago Explicação buy 1000 100 0 Comprar ações não paga imposto Operação Custo unitário Quantidade Imposto Pago Explicação sell 1500 50 0 Valor total menor do que R 20000 sell 1500 50 0 Valor total menor do que R 20000 Entrada operationbuy unitcost1000 quantity 100 operationsell unitcost1500 quantity 50 operationsell unitcost1500 quantity 50 Saída tax 00tax 00tax 00 Caso 2 Operação Custo unitário Quantidade Imposto Pago Explicação buy 1000 10000 0 Comprar ações não paga imposto sell 2000 5000 10000 Lucro de R 50000 20 do lucro corresponde a R 10000 e não possui prejuízo anterior sell 500 5000 0 Prejuízo de R 25000 não paga imposto Entrada operationbuy unitcost1000 quantity 10000 operationsell unitcost2000 quantity 5000 operationsell unitcost500 quantity 5000 Saída tax 00tax 100000tax 00 Case 1 Case 2 Quando a aplicação recebe duas linhas elas devem ser lidadas como duas simulações independentes O programa não deve carregar o estado obtido do processamento da primeira entrada para as outras execuções Input operationbuy unitcost1000 quantity 100 operationsell unitcost1500 quantity 50 operationsell unitcost1500 quantity 50 operationbuy unitcost1000 quantity 10000 operationsell unitcost2000 quantity 5000 operationsell unitcost500 quantity 5000 Output tax 00tax 00tax 00 tax 00tax 100000tax 00 Caso 3 Operação Custo unitário Quantidade Imposto Pago Explicação buy 1000 10000 0 Comprar ações não paga imposto sell 500 5000 0 Prejuízo de R 25000 não paga imposto sell 2000 3000 1000 Lucro de R 30000 Deve deduzir prejuízo de R 25000 e paga 20 de R 5000 em imposto R 1000 Entrada operationbuy unitcost1000 quantity 10000 operationsell unitcost500 quantity 5000 operationsell unitcost2000 quantity 3000 Saída tax 00tax 00tax 10000 Caso 4 Operação Custo unitário Quantidade Imposto Pago Explicação buy 1000 10000 0 Comprar ações não paga imposto buy 2500 5000 0 Comprar ações não paga imposto sell 1500 10000 0 Considerando preço médio ponderado de R 15 1010000 255000 15000 não teve lucro nem prejuízo Entrada operationbuy unitcost1000 quantity 10000 operationbuy unitcost2500 quantity 5000 operationsell unitcost1500 quantity 10000 Saída tax 00tax 00tax 00 Caso 5 Operação Custo unitário Quantidade Imposto Pago Explicação buy 1000 10000 0 Comprar ações não paga imposto buy 2500 5000 0 Comprar ações não paga imposto sell 1500 10000 0 Considerando preço médio ponderado de R 15 não teve lucro nem prejuízo sell 2500 5000 10000 Considerando preço médio ponderado de R 15 lucro de R 50000 paga 20 de R 50000 em imposto R 10000 Entrada operationbuy unitcost1000 quantity 10000 operationbuy unitcost2500 quantity 5000 operationsell unitcost1500 quantity 10000 operationsell unitcost2500 quantity 5000 Saída tax 00tax 00tax 00tax 100000 Caso 6 Operação Custo unitário Quantidade Imposto Pago Explicação buy 1000 10000 0 Comprar ações não paga imposto sell 200 5000 0 Perda de R 40000 valor total é menor do que R 20000 mas devemos deduzir o prejuízo independe disso Operação Custo unitário Quantidade Imposto Pago Explicação sell 2000 2000 0 Lucro de R 20000 se deduzir o prejuízo seu lucro é zero Você ainda tem R 20000 de prejuízo para deduzir dos próximos lucros sell 2000 2000 0 Lucro de R 20000 se deduzir o prejuízo seu lucro é zero Agora não tem mais prejuízo para deduzir dos próximos lucros sell 2500 1000 3000 Lucro de R 15000 e sem prejuízos paga 20 de R 15000 em imposto R 3000 Entrada operationbuy unitcost1000 quantity 10000 operationsell unitcost200 quantity 5000 operationsell unitcost2000 quantity 2000 operationsell unitcost2000 quantity 2000 operationsell unitcost2500 quantity 1000 Saída tax 00tax 00tax 00tax 00tax 30000 Case 7 Operação Custo unitário Quantidade Imposto Pago Explicação buy 1000 10000 0 Comprar ações não paga imposto sell 200 5000 0 Prejuizo de R 40000 valor total é menor que R 20000 mas deduzimos os prejuízos independente disso sell 2000 2000 0 Lucro de R 20000 se deduzir o prejuízo seu lucro é zero Você ainda tem R 20000 de prejuízo para deduzir dos próximos lucros sell 2000 2000 0 Lucro de R 20000 se deduzir o prejuízo seu lucro é zero Agora não tem mais prejuízo para deduzir dos próximos lucros sell 2500 1000 3000 Lucro de R 15000 e sem prejuízos paga 20 de R 15000 em imposto R 3000 Operação Custo unitário Quantidade Imposto Pago Explicação buy 2000 10000 0 Todas as ações anteriores foram vendidas Comprar novas ações muda a média ponderada para o valor pago por elas R 20 sell 1500 5000 0 Prejuizo de R 25000 sell 3000 4350 3700 Lucro de R 43500 se deduzir o prejuízo de R 25000 ficou restando R 18500 de lucro Paga 20 de R 18500 em imposto R 3700 sell 3000 650 0 Lucro de R 6500 sem prejuizo para deduzir mas o valor total e menor que R 20000 então não paga imposto Input operationbuy unitcost1000 quantity 10000 operationsell unitcost200 quantity 5000 operationsell unitcost2000 quantity 2000 operationsell unitcost2000 quantity 2000 operationsell unitcost2500 quantity 1000 operationbuy unitcost2000 quantity 10000 operationsell unitcost1500 quantity 5000 operationsell unitcost3000 quantity 4350 operationsell unitcost3000 quantity 650 Output tax 00tax 00tax 00tax 00tax 30000 tax 00tax 00tax 37000tax 00 Case 8 Operação Custo unitário Quantidade Imposto Explicação buy 1000 10000 0 Comprar ações não paga imposto sell 5000 10000 80000 Lucro de R 400000 paga 20 de R 400000 em imposto R 80000 buy 2000 10000 0 Comprar ações não paga imposto sell 5000 10000 60000 Lucro de R 300000 paga 20 de R 300000 em imposto R 60000 Input operationbuy unitcost1000 quantity 10000 operationsell unitcost5000 quantity 10000 operationbuy unitcost2000 quantity 10000 operationsell unitcost5000 quantity 10000 Output tax 00tax 800000tax 00tax 600000 Case 9 Operation Unit Cost Quantity Tax Explanation buy 500000 10 0 Compra de ações não gera impostos sell 400000 5 0 Perda de R 5000 total da operação é igual a R 20000 mas devemos acumular esse prejuízo de qualquer forma buy 1500000 5 0 Compra de ações não gera impostos buy 400000 2 0 Compra de ações não gera impostos buy 2300000 2 0 Compra de ações não gera impostos sell 2000000 1 0 Total da operação R 20000 não gera impostos e não deve modificar as perdas acumuladas sell 1200000 10 1000 Lucro de R 10000 deduzindo a perda acumulada de R 5000 temos outros R 5000 de lucro O imposto devido é de 20 dos R 5000 de lucro R 1000 sell 1500000 3 2400 Lucro de R 12000 e nenhuma perda acumulada Imposto de 20 sobre os R 12000 de lucro R 2400 Input operation buy unitcost 500000 quantity 10 operation sell unitcost 400000 quantity 5 operation buy unitcost 1500000 quantity 5 operation buy unitcost 400000 quantity 2 operation buy unitcost 2300000 quantity 2 operation sell unitcost 2000000 quantity 1 operation sell unitcost 1200000 quantity 10 operation sell unitcost 1500000 quantity 3 Output tax 00tax 00tax 00tax 00tax 00 tax 00tax 10000tax 24000 Estado da aplicação O programa não deve depender de nenhum banco de dados externo e o estado interno da aplicação deve ser gerenciado em memória explicitamente por alguma estrutura que achar adequada O estado da aplicação deve estar vazio sempre que a aplicação for inicializada Arredondando Decimais Para numeros decimais o programa deve arredondar os valores para a segunda casa decimal Por exemplo Se houver a compra de 10 ações por R 2000 e 5 ações por R 1000 o preço médio ponderado é 10 x 2000 5 x 1000 15 1667 Lidando com erros Você pode assumir que não ocorrerão erros na conversão do JSON de entrada Na avaliação da sua solução nós não vamos utilizar entradas que contenham erros estejam mal formatadas ou que quebrem o contrato Formato de saída dos números A maiora das bibliotecas de algumas linguages que lidam diretamente com JSON tendem a retirar os zeros à direita dos números decimais Se isto acontecer na sua linguagem escolhida prefira retornar os números Int Long Float Double BigDecimal etc com menos digitos do que transformálos em outros tipos de dados strings e afins Nossas Expectativas Nós no Nubank valorizamos as seguintes qualidades Simplicidade esperase da solução um projeto pequeno e de fácil entendimento Elegância esperase da solução facilidade de manutenção uma separação clara das responsabilidades e uma estrutura de código bem organizada Operacional esperase da solução a resolução do problema seus casos de borda ou extremos e a capacidade de extensão para futuras decisões de design Qualidade à medida que você estrutura seu código recomendamos e esperamos que você realize testes para garantir que ele esteja funcionando corretamente Testes bem escritos ajudam a garantir que sua solução seja robusta e sustentável Boas práticas recomendamos e esperamos que além de testes unitários hajam testes que cubram a sua solução de ponta a ponta ou seja desde a entrada até a saída da aplicação Uma forma de fazer isto é adicionando testes de integração Validação com testes Esperamos que as soluções apresentadas sejam validadas com testes adequados A ausência de testes pode impactar a avaliação da qualidade da sua solução já que consideramos testes como uma parte essencial do desenvolvimento Desta forma procuraremos avaliar Uso adequado de trasparência referencial quando aplicável Testes de unidade e integração de qualidade Documentação onde for necessário Instruções sobre como executar o código Por último porém não menos importante Você pode utilizar bibliotecas de código aberto open source que acredite serem adequadas para ajudar na solução do desafio por exemplo analisadores de json Por favor tente limitar o uso de frameworks e boilerplate code desnecessários O desafio espera uma aplicação de linhas de comando independente Por favor evite adicionar infraestrutura desnecessária eou dependências externas É esperado que você seja capaz de identificar as ferramentas necessárias para resolver o problema apresentado sem adicionar camadas extras de complexidade Notas gerais Esse desafio poderá ser estendido por você e por outra pessoa engenheira do Nubank durante uma outra etapa do processo O Ganho de Capital deve receber as operações através da entrada padrão stdin e retornar o resultado do processamento através da saída padrão stdout ao invés de uma API REST Preparando seu desafio para envio Você deve entregar o código fonte de sua solução para nós em um arquivo comprimido zip contendo o código e toda documentação possível Favor não incluir arquivos desnecessários como binários compilados bibliotecas etc Não faça o upload da sua solução em nenhum repositório público como GitHub BitBucket etc Se estiver builds conteinerizados não faça o upload da sua imagem no em hubs públicos como DockerHub Sloppyio etc Remova informações pessoais IMPORTANTE Por favor remova toda informação que possa lhe identificar nos arquivos do desafio antes de enviar a solução Atenção especial para os seguintes pontos Arquivos da solução como código testes namespaces binários comentários e nomes dos arquivos Comentários automáticos que seu editor de código pode ter adicionado aos arquivos Documentação do código como annotations metadata e READMEMD Informações de autoria do código e configuração do versionador de código Se você planeja utilizar git como sistema de controle de versões execute o seguinte comando na raíz do repositório para exportar a solução anonimizada git archive formatzip outputcapitalgainszip HEAD Adicione um README Sua solução deve conter um arquivo de README com Uma explicação sobre as decisões técnicas e arquiteturais do seu desafio Uma justificativa para o uso de frameworks ou bibliotecas caso sejam usadas Instruções sobre como compilar e executar o projeto Instruções sobre como executar os testes da solução Notas adicionais que você considere importantes para a avaliação Ambiente de execução O processo de build e execução da aplicação deve ser possível num sistema operacional Unix ou Mac Builds conteinerizadas são bem vindas FAQ P Como eu leio da entrada padrão stdin Ela precisa estar em um arquivo tipo inputtxt Eu preciso pedir para o usuário colocar o nome do arquivo no terminal R Esse é geralmente o tipo de leitura mais simples em qualquer aplicação de linha de comando por exemplo ConsoleReadLine em C ou input em Python Sua solução deve esperar que o usuário escreva cada linha no terminal e pressione enter Isso também permite que um arquivo seja passado à aplicação por Input Redirection Por examplo capitalgains inputtxt Adicionalmente nós não esperamos que a sua solução imprima qualquer explicação ao usuário de qual input esperado do tipo Agora insira as operações de entrada Você pode assumir que o usuário sabe qual entrada seu programa espera e em qual ordem A única saída esperada é o JSON com as respostas dos impostos P Pode haver um evento de compra após eventos de venda Nesse caso o preço médio de compra deve ser recalculado usando a nova compra R Sim o preço médio ponderado de compra deve sempre considerar todos os eventos de compra anteriores até o evento de venda atual Por favor veja o Caso 7 para um exemplo prático
25
Engenharia de Software
UNIVATES
2
Engenharia de Software
UNIVATES
1
Engenharia de Software
UNIVATES
62
Engenharia de Software
UNIVATES
19
Engenharia de Software
UNIVATES
Texto de pré-visualização
Code Challenge Ganho de Capital Contexto O objetivo deste exercício é implementar um programa de linha de comando CLI que calcula o imposto a ser pago sobre lucros ou prejuízos de operações no mercado financeiro de ações Por favor leia as instruções abaixo e sintase à vontade para fazer perguntas caso ache necessário Exemplo de uso do Ganho de Capital Como o programa deve funcionar Entrada Seu programa vai receber listas uma por linha de operações do mercado financeiro de ações em formato JSON através da entrada padrão stdin Cada operação desta lista contém os seguintes campos Nome Significado operation Se a operação é uma operação de compra buy ou venda sell unitcost Preço unitário da ação em uma moeda com duas casas decimais quantity Quantidade de ações negociadas Segue um exemplo da entrada formatado aqui para legibilidade O input real terá uma lista em cada linha operationbuy unitcost1000 quantity 10000 operationsell unitcost2000 quantity 5000 operationbuy unitcost2000 quantity 10000 operationsell unitcost1000 quantity 5000 As operações estarão na ordem em que elas ocorreram ou seja a segunda operação na lista aconteceu depois da primeira e assim por diante Cada linha é uma simulação independente seu programa não deve manter o estado obtido em uma linha para as outras A última linha da entrada será uma linha vazia Saída Para cada linha da entrada o programa deve retornar uma lista contendo o imposto pago para cada operação recebida Os elementos desta lista devem estar codificados em formato JSON e a saída deve ser retornada através da saída padrão stdout O retorno é composto pelo seguinte campo Nome Significado Nome Significado tax O valor do imposto pago em uma operação Este é um exemplo da saída tax 00 tax 100000 tax 00 tax 00 A lista retornada pelo programa deve ter o mesmo tamanho da lista de operações processadas na entrada Por exemplo se foram processadas três operações buy buy sell o retorno do programa deve ser uma lista com três valores que representam o imposto pago em cada operação Regras do Ganho de Capital O programa deve lidar com dois tipos de operações buy e sell e ele deve seguir as seguintes regras O percentual de imposto pago é de 20 sobre o lucro obtido na operação Ou seja o imposto vai ser pago quando há uma operação de venda cujo preço é superior ao preço médio ponderado de compra Para determinar se a operação resultou em lucro ou prejuízo você pode calcular o preço médio ponderado então quando você compra ações você deve recalcular o preço médio ponderado utilizando essa fórmula novamediaponderada quantidadedeacoesatual mediaponderada atual quantidadedeacoescompradas valordecompra quantidadedeacoesatual quantidadedeacoescompradas Por exemplo se você comprou 10 ações por R 2000 vendeu 5 depois comprou outras 5 por R 1000 a média ponderada é 5 x 2000 5 x 1000 5 5 1500 Você deve usar o prejuízo passado para deduzir múltiplos lucros futuros até que todo prejuízo seja deduzido Prejuízos acontecem quando você vende ações a um valor menor do que o preço médio ponderado de compra Neste caso nenhum imposto deve ser pago e você deve subtrair o prejuízo dos lucros seguintes antes de calcular o imposto Você não paga nenhum imposto e não deve deduzir o lucro obtido dos prejuízos acumulados se o valor total da operação custo unitário da ação x quantidade for menor ou igual a R 2000000 Use o valor total da operação e não o lucro obtido para determinar se o imposto deve ou não ser pago E não se esqueça de deduzir o prejuízo dos lucros seguintes Nenhum imposto é pago em operações de compra Você pode assumir que nenhuma operação vai vender mais ações do que você tem naquele momento Exemplos do Ganho de Capital Caso 1 Operação Custo unitário Quantidade Imposto Pago Explicação buy 1000 100 0 Comprar ações não paga imposto Operação Custo unitário Quantidade Imposto Pago Explicação sell 1500 50 0 Valor total menor do que R 20000 sell 1500 50 0 Valor total menor do que R 20000 Entrada operationbuy unitcost1000 quantity 100 operationsell unitcost1500 quantity 50 operationsell unitcost1500 quantity 50 Saída tax 00tax 00tax 00 Caso 2 Operação Custo unitário Quantidade Imposto Pago Explicação buy 1000 10000 0 Comprar ações não paga imposto sell 2000 5000 10000 Lucro de R 50000 20 do lucro corresponde a R 10000 e não possui prejuízo anterior sell 500 5000 0 Prejuízo de R 25000 não paga imposto Entrada operationbuy unitcost1000 quantity 10000 operationsell unitcost2000 quantity 5000 operationsell unitcost500 quantity 5000 Saída tax 00tax 100000tax 00 Case 1 Case 2 Quando a aplicação recebe duas linhas elas devem ser lidadas como duas simulações independentes O programa não deve carregar o estado obtido do processamento da primeira entrada para as outras execuções Input operationbuy unitcost1000 quantity 100 operationsell unitcost1500 quantity 50 operationsell unitcost1500 quantity 50 operationbuy unitcost1000 quantity 10000 operationsell unitcost2000 quantity 5000 operationsell unitcost500 quantity 5000 Output tax 00tax 00tax 00 tax 00tax 100000tax 00 Caso 3 Operação Custo unitário Quantidade Imposto Pago Explicação buy 1000 10000 0 Comprar ações não paga imposto sell 500 5000 0 Prejuízo de R 25000 não paga imposto sell 2000 3000 1000 Lucro de R 30000 Deve deduzir prejuízo de R 25000 e paga 20 de R 5000 em imposto R 1000 Entrada operationbuy unitcost1000 quantity 10000 operationsell unitcost500 quantity 5000 operationsell unitcost2000 quantity 3000 Saída tax 00tax 00tax 10000 Caso 4 Operação Custo unitário Quantidade Imposto Pago Explicação buy 1000 10000 0 Comprar ações não paga imposto buy 2500 5000 0 Comprar ações não paga imposto sell 1500 10000 0 Considerando preço médio ponderado de R 15 1010000 255000 15000 não teve lucro nem prejuízo Entrada operationbuy unitcost1000 quantity 10000 operationbuy unitcost2500 quantity 5000 operationsell unitcost1500 quantity 10000 Saída tax 00tax 00tax 00 Caso 5 Operação Custo unitário Quantidade Imposto Pago Explicação buy 1000 10000 0 Comprar ações não paga imposto buy 2500 5000 0 Comprar ações não paga imposto sell 1500 10000 0 Considerando preço médio ponderado de R 15 não teve lucro nem prejuízo sell 2500 5000 10000 Considerando preço médio ponderado de R 15 lucro de R 50000 paga 20 de R 50000 em imposto R 10000 Entrada operationbuy unitcost1000 quantity 10000 operationbuy unitcost2500 quantity 5000 operationsell unitcost1500 quantity 10000 operationsell unitcost2500 quantity 5000 Saída tax 00tax 00tax 00tax 100000 Caso 6 Operação Custo unitário Quantidade Imposto Pago Explicação buy 1000 10000 0 Comprar ações não paga imposto sell 200 5000 0 Perda de R 40000 valor total é menor do que R 20000 mas devemos deduzir o prejuízo independe disso Operação Custo unitário Quantidade Imposto Pago Explicação sell 2000 2000 0 Lucro de R 20000 se deduzir o prejuízo seu lucro é zero Você ainda tem R 20000 de prejuízo para deduzir dos próximos lucros sell 2000 2000 0 Lucro de R 20000 se deduzir o prejuízo seu lucro é zero Agora não tem mais prejuízo para deduzir dos próximos lucros sell 2500 1000 3000 Lucro de R 15000 e sem prejuízos paga 20 de R 15000 em imposto R 3000 Entrada operationbuy unitcost1000 quantity 10000 operationsell unitcost200 quantity 5000 operationsell unitcost2000 quantity 2000 operationsell unitcost2000 quantity 2000 operationsell unitcost2500 quantity 1000 Saída tax 00tax 00tax 00tax 00tax 30000 Case 7 Operação Custo unitário Quantidade Imposto Pago Explicação buy 1000 10000 0 Comprar ações não paga imposto sell 200 5000 0 Prejuizo de R 40000 valor total é menor que R 20000 mas deduzimos os prejuízos independente disso sell 2000 2000 0 Lucro de R 20000 se deduzir o prejuízo seu lucro é zero Você ainda tem R 20000 de prejuízo para deduzir dos próximos lucros sell 2000 2000 0 Lucro de R 20000 se deduzir o prejuízo seu lucro é zero Agora não tem mais prejuízo para deduzir dos próximos lucros sell 2500 1000 3000 Lucro de R 15000 e sem prejuízos paga 20 de R 15000 em imposto R 3000 Operação Custo unitário Quantidade Imposto Pago Explicação buy 2000 10000 0 Todas as ações anteriores foram vendidas Comprar novas ações muda a média ponderada para o valor pago por elas R 20 sell 1500 5000 0 Prejuizo de R 25000 sell 3000 4350 3700 Lucro de R 43500 se deduzir o prejuízo de R 25000 ficou restando R 18500 de lucro Paga 20 de R 18500 em imposto R 3700 sell 3000 650 0 Lucro de R 6500 sem prejuizo para deduzir mas o valor total e menor que R 20000 então não paga imposto Input operationbuy unitcost1000 quantity 10000 operationsell unitcost200 quantity 5000 operationsell unitcost2000 quantity 2000 operationsell unitcost2000 quantity 2000 operationsell unitcost2500 quantity 1000 operationbuy unitcost2000 quantity 10000 operationsell unitcost1500 quantity 5000 operationsell unitcost3000 quantity 4350 operationsell unitcost3000 quantity 650 Output tax 00tax 00tax 00tax 00tax 30000 tax 00tax 00tax 37000tax 00 Case 8 Operação Custo unitário Quantidade Imposto Explicação buy 1000 10000 0 Comprar ações não paga imposto sell 5000 10000 80000 Lucro de R 400000 paga 20 de R 400000 em imposto R 80000 buy 2000 10000 0 Comprar ações não paga imposto sell 5000 10000 60000 Lucro de R 300000 paga 20 de R 300000 em imposto R 60000 Input operationbuy unitcost1000 quantity 10000 operationsell unitcost5000 quantity 10000 operationbuy unitcost2000 quantity 10000 operationsell unitcost5000 quantity 10000 Output tax 00tax 800000tax 00tax 600000 Case 9 Operation Unit Cost Quantity Tax Explanation buy 500000 10 0 Compra de ações não gera impostos sell 400000 5 0 Perda de R 5000 total da operação é igual a R 20000 mas devemos acumular esse prejuízo de qualquer forma buy 1500000 5 0 Compra de ações não gera impostos buy 400000 2 0 Compra de ações não gera impostos buy 2300000 2 0 Compra de ações não gera impostos sell 2000000 1 0 Total da operação R 20000 não gera impostos e não deve modificar as perdas acumuladas sell 1200000 10 1000 Lucro de R 10000 deduzindo a perda acumulada de R 5000 temos outros R 5000 de lucro O imposto devido é de 20 dos R 5000 de lucro R 1000 sell 1500000 3 2400 Lucro de R 12000 e nenhuma perda acumulada Imposto de 20 sobre os R 12000 de lucro R 2400 Input operation buy unitcost 500000 quantity 10 operation sell unitcost 400000 quantity 5 operation buy unitcost 1500000 quantity 5 operation buy unitcost 400000 quantity 2 operation buy unitcost 2300000 quantity 2 operation sell unitcost 2000000 quantity 1 operation sell unitcost 1200000 quantity 10 operation sell unitcost 1500000 quantity 3 Output tax 00tax 00tax 00tax 00tax 00 tax 00tax 10000tax 24000 Estado da aplicação O programa não deve depender de nenhum banco de dados externo e o estado interno da aplicação deve ser gerenciado em memória explicitamente por alguma estrutura que achar adequada O estado da aplicação deve estar vazio sempre que a aplicação for inicializada Arredondando Decimais Para numeros decimais o programa deve arredondar os valores para a segunda casa decimal Por exemplo Se houver a compra de 10 ações por R 2000 e 5 ações por R 1000 o preço médio ponderado é 10 x 2000 5 x 1000 15 1667 Lidando com erros Você pode assumir que não ocorrerão erros na conversão do JSON de entrada Na avaliação da sua solução nós não vamos utilizar entradas que contenham erros estejam mal formatadas ou que quebrem o contrato Formato de saída dos números A maiora das bibliotecas de algumas linguages que lidam diretamente com JSON tendem a retirar os zeros à direita dos números decimais Se isto acontecer na sua linguagem escolhida prefira retornar os números Int Long Float Double BigDecimal etc com menos digitos do que transformálos em outros tipos de dados strings e afins Nossas Expectativas Nós no Nubank valorizamos as seguintes qualidades Simplicidade esperase da solução um projeto pequeno e de fácil entendimento Elegância esperase da solução facilidade de manutenção uma separação clara das responsabilidades e uma estrutura de código bem organizada Operacional esperase da solução a resolução do problema seus casos de borda ou extremos e a capacidade de extensão para futuras decisões de design Qualidade à medida que você estrutura seu código recomendamos e esperamos que você realize testes para garantir que ele esteja funcionando corretamente Testes bem escritos ajudam a garantir que sua solução seja robusta e sustentável Boas práticas recomendamos e esperamos que além de testes unitários hajam testes que cubram a sua solução de ponta a ponta ou seja desde a entrada até a saída da aplicação Uma forma de fazer isto é adicionando testes de integração Validação com testes Esperamos que as soluções apresentadas sejam validadas com testes adequados A ausência de testes pode impactar a avaliação da qualidade da sua solução já que consideramos testes como uma parte essencial do desenvolvimento Desta forma procuraremos avaliar Uso adequado de trasparência referencial quando aplicável Testes de unidade e integração de qualidade Documentação onde for necessário Instruções sobre como executar o código Por último porém não menos importante Você pode utilizar bibliotecas de código aberto open source que acredite serem adequadas para ajudar na solução do desafio por exemplo analisadores de json Por favor tente limitar o uso de frameworks e boilerplate code desnecessários O desafio espera uma aplicação de linhas de comando independente Por favor evite adicionar infraestrutura desnecessária eou dependências externas É esperado que você seja capaz de identificar as ferramentas necessárias para resolver o problema apresentado sem adicionar camadas extras de complexidade Notas gerais Esse desafio poderá ser estendido por você e por outra pessoa engenheira do Nubank durante uma outra etapa do processo O Ganho de Capital deve receber as operações através da entrada padrão stdin e retornar o resultado do processamento através da saída padrão stdout ao invés de uma API REST Preparando seu desafio para envio Você deve entregar o código fonte de sua solução para nós em um arquivo comprimido zip contendo o código e toda documentação possível Favor não incluir arquivos desnecessários como binários compilados bibliotecas etc Não faça o upload da sua solução em nenhum repositório público como GitHub BitBucket etc Se estiver builds conteinerizados não faça o upload da sua imagem no em hubs públicos como DockerHub Sloppyio etc Remova informações pessoais IMPORTANTE Por favor remova toda informação que possa lhe identificar nos arquivos do desafio antes de enviar a solução Atenção especial para os seguintes pontos Arquivos da solução como código testes namespaces binários comentários e nomes dos arquivos Comentários automáticos que seu editor de código pode ter adicionado aos arquivos Documentação do código como annotations metadata e READMEMD Informações de autoria do código e configuração do versionador de código Se você planeja utilizar git como sistema de controle de versões execute o seguinte comando na raíz do repositório para exportar a solução anonimizada git archive formatzip outputcapitalgainszip HEAD Adicione um README Sua solução deve conter um arquivo de README com Uma explicação sobre as decisões técnicas e arquiteturais do seu desafio Uma justificativa para o uso de frameworks ou bibliotecas caso sejam usadas Instruções sobre como compilar e executar o projeto Instruções sobre como executar os testes da solução Notas adicionais que você considere importantes para a avaliação Ambiente de execução O processo de build e execução da aplicação deve ser possível num sistema operacional Unix ou Mac Builds conteinerizadas são bem vindas FAQ P Como eu leio da entrada padrão stdin Ela precisa estar em um arquivo tipo inputtxt Eu preciso pedir para o usuário colocar o nome do arquivo no terminal R Esse é geralmente o tipo de leitura mais simples em qualquer aplicação de linha de comando por exemplo ConsoleReadLine em C ou input em Python Sua solução deve esperar que o usuário escreva cada linha no terminal e pressione enter Isso também permite que um arquivo seja passado à aplicação por Input Redirection Por examplo capitalgains inputtxt Adicionalmente nós não esperamos que a sua solução imprima qualquer explicação ao usuário de qual input esperado do tipo Agora insira as operações de entrada Você pode assumir que o usuário sabe qual entrada seu programa espera e em qual ordem A única saída esperada é o JSON com as respostas dos impostos P Pode haver um evento de compra após eventos de venda Nesse caso o preço médio de compra deve ser recalculado usando a nova compra R Sim o preço médio ponderado de compra deve sempre considerar todos os eventos de compra anteriores até o evento de venda atual Por favor veja o Caso 7 para um exemplo prático