Saturday 16 June 2018

Moving average function python


Spyder - o Python IDE Seg 16 de setembro de 2017 Hans Fangohr. University of Southampton, Reino Unido, 2017 Spyder desenvolveu-se em uma ferramenta bastante madura e muito produtiva aqui, eu tento fornecer um tutorial. Esta documentação é motivada por cursos de formação em Python e modelagem computacional para estudantes da Universidade de Southampton (ver nota histórica para mais detalhes). Esta entrada de blog foi integrada no Spyder como Tutorial. Uma vez que o Spyder tenha começado, a versão mais atualizada deste tutorial pode ser encontrada em Help - gt Spyder tutorial. Receba o arquivo do mundo da Olá na janela do editor do Spyder, baixe Baixe o hello. py e salve como hello. py. (Você baixou o arquivo clicando com o botão direito do mouse no link em seu navegador e selecione Salvar como destino ou Salvar como) e, em seguida, Abra o arquivo hello. py no menu Arquivo e selecione Abrir. Nós expressamos isso como File - gt Open em resumo. Clique em hello. py para ver o código-fonte no webbrowser e, em seguida, copie o código inteiro para navegar na janela do editor no spyder e cole o código. Em seguida, salve o arquivo como hello. py. Para executar o programa, selecione Executar - Gt Run (ou pressione F5) e confirme as configurações de execução, se necessário. Você deve ver saída como: ou (o caminho particular dependerá de onde você salvou o arquivo, mas isso é inserido automaticamente pela Spyder): em caso afirmativo, você acabou de executar o seu primeiro programa Python - bem feito. Antes de prosseguir, o console do IPython pode fazer um pouco mais do que o console padrão do Python e sugerimos que o use como console padrão aqui. Na sessão de interpretação do IPython que acabamos de começar, você pode usar Run-gtRun (como antes) para executar o hello. py e você deve ver: Python lê o arquivo linha por linha, ignorando comentários quando se trata da palavra-chave def, ele Sabe que uma função é DEFINIDA nesta e na próxima (uma ou mais) linhas. No arquivo hello. py, o Python cria um objeto de função com o nome hello. Todas as linhas sangrentas seguindo def hello (): pertencem ao corpo da função. Observe que o objeto de função apenas foi criado neste momento no arquivo, mas a função ainda não é chamada (ou seja, não é executada). Quando o Python encontrar comandos (que não sejam def. E algumas outras palavras-chave) que estão escritos na coluna mais à esquerda, executará estes imediatamente. No arquivo hello. py, esta é apenas a linha de leitura hello () que realmente chamará (ou seja, execute) a função com o nome hello. Se você remover a linha hello () do programa e executar o arquivo inteiro novamente (pressionando F5, ou selecionando run - gt run), nada será impresso (porque a função hello é definida, mas não chamada, ou seja, não executada) . Agora, você deve saber como executar um programa Python que você possui na janela do editor no Spyder usando o Console Python e o Console IPython mais sofisticado. Se você está apenas começando a aprender Python, este é provavelmente um bom ponto para retornar ao seu curso de livros de texto e veja exemplos mais básicos. A próxima seção fornece informações mais detalhadas sobre como você pode executar partes do código no editor no console Python e, assim, atualizar partes de suas definições no editor. Esta é uma técnica mais avançada, mas pode ser muito útil. (Você também pode estar interessado na opção de executar pedaços (chamados quotcellsquot) do código que são separados por delimitadores - veja Atalhos para funções úteis.) Depois de executar o programa hello. py, o objeto de função hello é definido E conhecido no prompt do Python. Podemos chamar a função do prompt do Python: Chame a função hello () do prompt do Python, ou seja, digite hello () na janela do Python Shell (o prompt do Python mostra como gtgtgt. Ou como In se usamos a sessão do IPython onde O ponto de interrogação pode ser qualquer número inteiro positivo.) E pressione a tecla de retorno. Você deve achar que a função hello () foi executada novamente, ou seja, o Hello World foi impresso novamente. A sua chamada de função no prompt do Python juntamente com a saída deve parecer assim: você pode ver como isso difere da execução do programa inteiro novamente. Quando executamos o programa inteiro (pressionando F5), o Python passa pelo arquivo, cria a função hello Objeto (substituindo o objeto anterior), chega ao programa principal e chama a função. Quando chamamos o hello () do prompt do Python, chamamos apenas os objetos da função hello que foram definidos no console (I) Python quando executámos o arquivo hello. py inteiro anteriormente (pressionando F5). Isso se tornará mais claro ao longo do tempo e também quando trabalharmos com exemplos um pouco maiores. Você pode querer retornar a este tutorial em um estágio um pouco posterior. O Python fornece uma função que exibe todos os objetos conhecidos (no espaço do nome atual). É chamado dir (). Quando você digita dir () no prompt, você obtém uma lista de objetos conhecidos. Ignore tudo começando com um sublinhado por enquanto. Você pode ver ola na lista (Se você conseguir uma longa lista de objetos definidos, então o Spyder pode ter feito algumas importações de conveniência para você. Para resolver isso, você deseja: Então execute o diretório dir) como sugerido acima. O objeto está visível no espaço do nome atual (como é oi neste exemplo), podemos usar a função de ajuda da seguinte forma para aprender sobre isso: Digite help (hello) no prompt do Python, você deve ver a saída como esta: Onde Python Tire as informações de algumas delas (como o número de argumentos de entrada e os nomes dessas variáveis ​​aqui não temos argumentos de entrada) Python pode encontrar através da inspeção de seus objetos, informações adicionais provêm da seqüência de documentação fornecida para o objeto de função hello. A cadeia de documentação é a primeira seqüência imediatamente abaixo da linha def hello ():. O ambiente Spyder também fornece um painel no canto superior direito (por padrão), que é o inspetor de objetos. Se você digitar hello na linha vazia na janela do inspetor de objetos, ele também fornecerá a seqüência de ajuda. Na janela do Editor, mude a função hello de modo que imprima Good Bye World em vez de Hello World. Pressione F5 (para executar o programa inteiro) e verifique se a saída do programa é agora: o que aconteceu quando você pressionou F5 é o seguinte: Python passou pelo arquivo hello. py e criou um novo objeto de função hello (substituindo a função Olá, já definimos antes) e então executámos a função. Precisamos começar com um estado claramente definido. Para fazer isso, mude a função hello () para trás, de modo que imprima o Hello World (ou seja, use o arquivo hello. py original) e, em seguida, pressione F5 para executar todo o programa e verifique se imprime o Hello World. Chame a função hello () do prompt de comando (conforme descrito em Chamar objetos de função existentes a partir da linha de comando). Você deve ver o Hello World impresso. Agora altere a definição da função para que ele imprima Laters World. E salve o arquivo (mas NÃO execute o programa, ou seja, NÃO pressione F5 ainda). Chame a função hello () do prompt de comando novamente. Você deve achar que o texto impresso lê Hello World. Como aqui Por que isso é assim Porque o objeto de função do Olá no intérprete do Python é o antigo que imprime o Olá Mundo. Até agora, mudamos o arquivo hello. py (e substituímos o Hello World por lá com Laters World) no editor, mas isso não afetou os objetos que foram criados anteriormente no intérprete do Python. Aqui estão duas possibilidades para usar nossa versão modificada da função hello: Opção 1: execute todo o arquivo hello. py novamente pressionando F5: isso cria um novo objeto de função hello (e anula o antigo). Você deve achar que, se você pressionar F5 e, em seguida, chame o hello () no prompt, o novo texto Laters World é impresso. Opção 2: selecione a região que você mudou (neste caso, a função inteira olá. A partir da linha def hello (): para baixo para retornar None. E depois selecione Run - gt Run selection. Isso atualizará o objeto hello no intérprete Sem ter que executar todo o arquivo hello. py: se agora digitar hello (). Vemos a resposta de atualização: a capacidade de executar partes do código para atualizar alguns objetos no intérprete (no exemplo acima, atualizamos a função Objeto hello), é de grande utilidade ao desenvolver e depurar códigos mais complexos, e quando criar objetosdata na sessão de interpretação levar tempo. Por exemplo, modificando apenas as funções (ou classesobjects, etc.) que estamos realmente desenvolvendo ou depurando, nós Pode seguir reutilizando as estruturas de dados, etc, que são definidas na sessão de interpretação. Para ensinar programação em Python e modelagem computacional, recomendamos (i) usar IPython em vez do intérprete normal de Python e (ii) não usar qualquer importação de conveniência. T Ele aceita o IPython como o padrão de fato e ajuda a entender melhor os espaços para nome. O Spyder tenta ajudar usuários mais avançados importando uma série de módulos para o espaço do nome principal. Digite scientific no prompt de comando para ver os detalhes. Esse comportamento pode mudar em versões futuras do Spyder. Embora essas importações de conveniência sejam muito úteis para programadores mais experientes, podem ser confusas (se não enganosas) para iniciantes. Recomendamos, portanto, desfazer essas importações para cumprir os nossos requisitos descritos acima e (i) mudar para um console IPython. E (ii) emitir o comando de reinicialização para redefinir o espaço do nome. Ambas as etapas são explicadas com mais detalhes na próxima seção. Na janela do console (canto inferior direito por padrão), você vê, por padrão, um prompt com três sinais maiores do que os sinais, ou seja, gtgtgt. Isso mostra que estamos usando o console - basicamente uma sessão de interpretação de Python normal (com alguma funcionalidade adicional da Spyder). Em vez disso, gostaríamos de usar um shell Interactive Python, um breve IPython do projeto ipython. Para fazer isso, selecione Interpreters - gt Abra um Console IPython. Você deve ver na janela consolse uma nova shell que apareça e o prompt IPython In 1: deve ser exibido. O espaço de nomes pode ser limpo no IPython usando o comando reset. Digite reset e pressione return, depois confirme com y: discutimos isso um pouco mais, mas você pode ignorar o seguinte se não estiver interessado: depois de emitir o comando reset, devemos ter apenas alguns objetos definidos no namespace dessa sessão . Podemos listar todos eles usando o comando dir (): Finalmente, se você quiser ignorar a etapa de confirmação do comando de reinicialização, use use reset - f em vez de redefinir. Além da sintaxe que é aplicada pela Python, há convenções adicionais sobre o layout do código-fonte, em particular o Guia de estilo para o código-fonte do Python conhecido como quopPEP8quot. Um grande comportamento do Spyders pode ser configurado através das suas Preferências. Onde este está localizado no menu depende do seu sistema operacional: No Windows e no Linux, vá para Ferramentas - gt Preferências No Mac OS, vá para Python - gt Preferences Ir para Preferências - gt Console IPython - gt Startup e selecione a caixa de seleção ao lado de Abra um console IPython na inicialização. Em seguida, clique no botão OK. A próxima vez que o Spyder começar, ele mostrará o console IPython automaticamente. Vá para Preferências - Gt Editor - gt Code IntrospectionAnalysis e selecione a caixa de seleção ao lado de Análise de estilo (PEP8) Para evitar qualquer magia quando o console é iniciado, vá para Preferências - gt Console - gt Configurações avançadas - gt PYTHONSTARTUP substituição e selecione o script PYTHONSTARTUP padrão (E reinicie o Spyder). (Esta magia, entre outras coisas, executa o comando de divisão de importação futura.) As configurações padrão podem mudar para isso na próxima versão principal. Para evitar a importação de todos os objetos de pylab e numpy no espaço de nome atual no IPython Console, vá para Preferências - gt IPython console - gt Graphics e desmarque a caixa de seleção ao lado de Automaticamente carregar módulos Pylab e NumPy e também desmarcar Ativar suporte. As configurações padrão podem mudar para isso na próxima versão principal. Por meio de Preferências - gt Console IPython - gt Configurações Avançadas - gt Use matemática simbólica podemos ativar o modo python simbólico IPythons. Isso permitirá uma saída de simpatiza bem renderizada (estilo latex) e também importará alguns objetos de simulação automaticamente quando o console do IPython for iniciado e relatar o que ele fez. Podemos então usar as variáveis ​​x. Y. Por exemplo, isto: F5 executa o buffer atual F9 executa o pedaço de código atualmente destacado: isso é muito útil para atualizar definições de funções (digamos) na sessão de interpretação sem ter que executar o arquivo inteiro novamente CTRL ltRETURNgt executa a célula atual ( Menu no menu Run - gt Run). Uma célula é definida como o código entre duas linhas que começam com a etiqueta acordada. SHIFT ltRETURNgt executa a célula atual e avança o cursor para a próxima célula (entrada do menu Run - gt Run cell and advance). As células são úteis para executar um grande segmento de fiéis em unidades menores. (É um pouco como uma célula em um notebook IPython, naquele pedaços de código podem ser executados de forma independente.) ALT lCURADOR UPgt move a linha atual. Se várias linhas estiverem destacadas, elas são movidas juntas. ALTlCCURSOR DOWNgt trabalha correspondentemente, movendo a (s) linha (s) para baixo. Clique com o botão direito do mouse em um método de função na fonte, abre um novo editor de janelas que mostra a definição dessa função. SHIFTCTRLALTM maximiza a janela atual (ou altera o tamanho de volta ao normal se pressionado em uma janela maximizada) SHIFTCTRLF ativa a pesquisa em todos os arquivos. No Mac OS X: CMD aumentará o tamanho da fonte no editor, CMD - diminui. Também funciona no Console IPython. O tamanho da fonte para o explorador de objetos, a consola Python etc pode ser configurado individualmente através de Preferências - gt Object explorer etc. Eu não consegui encontrar uma maneira de alterar o tamanho da fonte no variador explorador. CTRLSPACE autocomplete comandos, nomes de funções, nomes de variáveis, métodos muito úteis. CMDs (no Mac OS X) e CTRLs (caso contrário) na janela do editor salvam o arquivo que está sendo editado. Isso também força vários triângulos de aviso na coluna esquerda do editor a serem atualizados (caso contrário eles atualizam cada 2 a 3 segundos por padrão). CMDs (no Mac OS X) e CTRLs (caso contrário) na janela do console do IPython, salva a sessão atual do IPython como um arquivo HTML, incluindo as figuras que podem ser exibidas inline. Isso é útil como uma maneira rápida de gravar o que foi feito em uma sessão. (Não é possível carregar este registro guardado de volta à sessão - se você precisar de uma funcionalidade como essa, procure o Notebook IPython.) CMDi (no Mac OS X) e CTRLi (caso contrário) quando pressionado enquanto o cursor está em um objeto , Abre documentação desse objeto no inspetor de objetos. Estas são as configurações que definem como o código no editor é executado se selecionamos Run - gt Run ou pressione F5. Por padrão, a caixa de configurações aparecerá a primeira vez que tentamos executar um arquivo. Se quisermos alterar as configurações em qualquer outro momento, elas podem ser encontradas em Run - gt Configure ou pressionando F6. Existem três opções para o intérprete, do qual eu vou discutir os dois primeiros. Vamos assumir que temos um programa hello. py no editor que lê Esta é a sugestão padrão, e também geralmente uma boa escolha. Escolher Execute na configuração atual do intérprete de Python ou IPython em Run - gt Configure significa que quando a execução do hello. py estiver completa, podemos interagir com o intérprete no qual o programa foi executado e podemos usar o conveniente intérprete de IPython para isso (um pouco Do que o interpretador Python padrão). Podemos inspecionar e interagir com objetos que a execução do nosso programa criou, como eu e oi (). Isso geralmente é muito útil para codificação incremental, teste e depuração: podemos chamar hello () diretamente do prompt do interpretador e não precisamos executar o hello. py inteiro para isso (embora se mudarmos a função hello (). Nós precisamos Para executar o buffer, ou pelo menos a definição da função, para tornar a nova versão do hello () visível no intérprete, executando o buffer inteiro ou via Run - gt Run Selection.) No entanto, executando o código no editor no O intérprete atual também significa que o código que executa pode ver outros objetos (globais) que foram definidos na sessão de interpretação. Esta persistência de objetos é facilmente esqueceu-se e geralmente não é necessária quando se trabalha em pequenos programas (embora possa ser de grande valor ocasionalmente). Esses objetos podem vir da execução anterior do código, do trabalho interativo no intérprete ou de importações de conveniência, como a importação de pylab (o Spyder pode fazer algumas dessas importações de conveniência automaticamente). Essa visibilidade de objetos no espaço de nome global do intérprete para o código que executamos também pode resultar em erros de codificação se o código se basear inadvertidamente nesses objetos. Aqui está um exemplo: imagine que executamos o código hello. py. Posteriormente, a variável i é conhecida no intérprete como uma variável global. Nós editamos a fonte hello. py e excluímos acidentalmente a linha i 42, nós executamos o buffer contendo hello. py novamente. Neste ponto, a chamada de hello (i) não falhará porque o intérprete tem um objeto de nome que eu defini, embora isso não esteja definido na fonte de hello. py. Neste ponto, poderíamos poupar hello. py e (falsamente) pensamos que seria executado corretamente. No entanto, executá-lo em uma nova sessão de interpretação de python (ou via python hello. py. Say) resultaria em um erro, porque eu não está definido. O problema surge porque o código faz uso de um objeto (aqui i) sem criá-lo. Isso também afeta a importação de módulos: se tivéssemos importado o pylab no prompt do IPython, nosso programa verá isso quando executado nesta sessão de interpretação do IPython. Para saber como podemos verificar novamente se o nosso código não depende de objetos existentes, consulte Como verificar novamente se o seu código é executado corretamente. Escolhendo Execute no novo intérprete dedicado do Python em Run - gt Configure irá iniciar um novo intérprete do Python toda vez que o programa hello. py for executado. A maior vantagem desse modo em Execução no atual intérprete de Python ou IPython é que podemos ter certeza de que não existem objetos globais definidos neste intérprete que se originam da depuração e execução repetida do nosso código: sempre que executamos o código no editor , O intérprete python no qual o código é executado é reiniciado. Esta é uma opção segura, mas oferece menos flexibilidade e não pode usar o interpretador IPyton. Supondo que você escolheu seu código para executar no atual intérprete de Python ou IPython. Então você duas opções para verificar se o nosso código funciona por conta própria (ou seja, não depende de variáveis ​​indefinidas, módulos e comandos não importados etc.) Como alternativa, se você quiser ficar com o atual intérprete de IPython, você pode usar a reinicialização mágica de IPythons Comando que removerá todos os objetos (como eu no exemplo acima) do espaço de nomes atual e, em seguida, execute o código no editor. Uma vez que você tenha concluído um código, verifique se ele é executado de forma independente usando uma das opções explicadas em Como verificar novamente se o seu código é executado corretamente. Quando vários arquivos são abertos no editor, as abas correspondentes na parte superior da área da janela são organizadas em ordem alfabética do nome do arquivo da esquerda para a direita. À esquerda das guias, existe como ícone que mostra as abas de Pesquisa se o mouse estiver sobre ele. É útil saltar para um arquivo particular diretamente, se muitos arquivos estiverem abertos. As variáveis ​​de ambiente podem ser exibidas a partir da janela do console (janela inferior direita no layout padrão). Clique no ícone Opções (a dica de ferramenta é Opções) e, em seguida, selecione Variáveis ​​de ambiente. Toda a personalização salva no disco pode ser redefinida chamando o spyder da linha de comando com a opção --reset. Ou seja, um comando como spyder --reset. Clicar com o botão direito do mouse em matrizes no variável explorador dá opções para plotar e analisar isso ainda mais. O duplo clique em um objeto de dicionário abre uma nova janela que exibe o dicionário bem. Presumivelmente, há outras capacidades ocultas para alguns outros tipos de dados. Existem algumas convenções em relação às cadeias de documentação escritas em texto reestruturado. Se seguimos essas diretrizes, podemos obter cadeias de documentação formalmente formadas no Spyder. Por exemplo, para que nossa função média () pareça assim no Spyder Object Explorer: Precisamos formatar a seqüência de documentação da seguinte maneira. O que importa aqui, é que a palavra Parâmetros é usada e sublinhada. A linha a. O número mostra que o tipo do parâmetro a é o número. Na próxima linha, que é recuada, podemos escrever uma explicação mais extensa sobre o que esta variável representa, quais condições os tipos permitidos devem cumprir etc. O mesmo para todos os Parâmetros e também para o valor retornado. Muitas vezes, é uma boa idéia incluir um exemplo como mostrado. Ativando o modo de depuração (Debug - gt Debug) inicia o depurador IPython (ipdb) no console IPython. Isso é operado como normal, mas a janela de exibição do editor destaca a linha que está prestes a ser executada e o explorador de variáveis ​​exibe variáveis ​​no contexto atual do ponto de execução do programa. (Somente exibe variáveis ​​numéricas, ou seja, não objetos de função, etc.) Os comandos de chave dentro do depurador de IPython são batimentos de tecla individuais: s para entrar na instrução atual. Se esta é uma chamada de função, entre na função. N vá para a instrução Next. Se a instrução atual for uma função, não entre na função, mas execute-a completamente antes de retornar o controle ao prompt do depurador interativo. R complete todas as declarações na função atual e retorna dessa função antes de retornar o controle. P Imprimir permite exibir valores de variáveis, por exemplo p x irá imprimir o valor da variável x. Observe que no ipdb, você também pode alterar valores de variável. Por exemplo, para modificar um x valiable. Você pode dizer ipdb gt x 42 e o depurador continuará com x sendo ligado a 42. Você também pode chamar funções e fazer muitas outras coisas. Para sair do modo de depuração, você pode digitar sair ou selecionar no menu Debug - gt Depugging Control - gt Exit No console IPython, podemos chamar debug diretamente após uma exceção ter sido levantada: isso irá iniciar o modo de depuração IPython e permite Inspeção de variáveis ​​locais no ponto onde a exceção ocorreu como descrito acima. Isso é muito mais eficiente do que adicionar instruções de impressão ao código e executá-lo novamente. Se você usar isso, você também pode querer usar os comandos para cima e para baixo que navegam no ponto de inspeção para cima e para baixo da pilha. (Acima da pilha significa que as funções que chamaram a função atual para baixo são a direção oposta). Assumindo que usamos um console IPython com versão gt 1.0.0, podemos decidir se as figuras criadas com matplotlibpylab serão exibidas inline. Ou seja, dentro do console do IPython, ou se eles devem aparecer dentro de uma nova janela. A opção 1 é conveniente para salvar uma gravação da sessão interativa (seção Atalhos para funções úteis lista um atalho para salvar o console IPython em um arquivo html). A opção 2 permite ampliar de forma interativa a figura, manipulá-la um pouco e salvar a figura em diferentes formatos de arquivo através do menu. O comando para obter as figuras para aparecer em linha no console IPython é matplotlib inline. O comando para obter figuras aparecem em sua própria janela (o que tecnicamente é um desperdício de QT) é matplotlib qt. As preferências do Spyder podem ser usadas para personalizar o comportamento padrão (em particular, Preferências - gt IPython Console - gt Graphics - gt Ativar Suporte para alternar para plotar inline). Posts recentes CategoriasThis é um wrapper Python para TA-LIB com base em Cython em vez de SWIG. Na página inicial: a TA-Lib é amplamente utilizada pelos desenvolvedores de software que exigem a análise técnica dos dados do mercado financeiro. Inclui 150 indicadores como ADX, MACD, RSI, estocástico, Bandas Bollinger, etc. Reconhecimento de padrão de castiçal API de fonte aberta para CC, Java, Perl, Python e 100 Managed. NET. As ligações originais de Python usam SWIG que, infelizmente, são difíceis de instalar. E não são tão eficientes quanto poderiam ser. Portanto, este projeto usa Cython e Numpy para se conectar de forma eficiente e limpa a TA-Lib - produzindo resultados 2-4 vezes mais rápido do que a interface SWIG. Instale o TA-Lib ou Leia os Documentos Semelhantes ao TA-Lib, a interface da função fornece um invólucro leve dos indicadores expostos do TA-Lib. Cada função retorna uma matriz de saída e tem valores padrão para seus parâmetros, a menos que especificado como argumentos de palavras-chave. Normalmente, essas funções terão um período de lookback inicial (um número necessário de observações antes que uma saída seja gerada) configurado para NaN. Todos os exemplos a seguir usam a função API: Calcule uma média móvel simples dos preços de fechamento: Cálculo de bandas de bollinger, com média móvel exponencial tripla: Cálculo do momento dos preços de fechamento, com um período de tempo de 5: Inicialização da API Resumo Se você estiver Já familiarizado com o uso da função API, você deve se sentir em casa usando a API abstrata. Cada função leva a mesma entrada, passada como um dicionário de matrizes Numpy: as funções podem ser importadas diretamente ou instanciadas pelo nome: a partir daí, as funções de chamada são basicamente as mesmas que a função API: Saiba mais sobre o uso mais avançado do TA-Lib aqui . Indicadores suportados Podemos mostrar todas as funções de TA suportadas pelo TA-Lib, seja como uma lista ou como um orden ordenado por grupo (por exemplo, Estudos sobrepostos, Indicadores Momentum, etc.): Grupos de Função

No comments:

Post a Comment