Dificuldade em código Python

Antes de te mostrarem o código, cria um psudo-código ou um esquema do que pretendes com o programa para conseguires esquematizar todas as funcionalidades que vais ter de incluir, e apartir daí, vais começando a ver que função é que se encaixa na resolução do problema...

Cumps
 
Antes de te mostrarem o código, cria um psudo-código ou um esquema do que pretendes com o programa para conseguires esquematizar todas as funcionalidades que vais ter de incluir, e apartir daí, vais começando a ver que função é que se encaixa na resolução do problema...

Cumps
Eu fiz um esquema "simples" o problema é mete-lo para código
-Criar a lista para puder guardar lá os números.
-Criar um "range" de 1,1000
-Os números da lista fazerem fazerem uma "volta" ao range por exemplo: 9-1, 9-2.
-Verificar o que usou o maior número até 0, exemplo: 9-9 = 0 , usou o 9 então o primeiro, 10-10, usou 10, 10 > 9 então 10 fica em primeiro e 9 em segundo
A parte a a negrito é a pior, eu não sei como faço para meter os números em primeiro e segundo e isso.
Se calhar este esquema não é o melhor, mas por agora é o único em qual consigo pensar.

Não é nada. Já tens o pseudo-código, agora é só procurares como é que funcionam os ciclos for em Python e tudo o resto que precisares. Eu nunca programei em Python e com umas pesquisas no Google fiz o programa sem grandes problemas. Por isso tu também consegues. ;)
Eu basicamente usei input() para ler os valores, append() para os meter para uma lista, 2 ciclos for e 1 if. Talvez ajude como referência. ;)
Presumo que já tenhas algum conhecimento em algumas linguagens, eu comecei a pouco tempo(2 meses mais ou menos) por isso penso que seja mais difícil para mim do que para ti, mas obrigado pela a ajuda :)
 
Última edição:
@btuger: Vejo-me obrigado a lançar aqui um desafio antes de poderes continuar. Pelo que percebi, precisas mesmo disto para que possas fazer progressos.

Em qualquer algoritmo de ordenamento (ou pelo menos na maioria) é típico teres uma função que troca dois elementos de uma lista. Por exemplo, a minha lista é [1, 2, 3, 4, 5] e quero trocar os elementos nos índices 0 e 2, ficando portanto [3, 2, 1, 4, 5]. Isto porque nesses algoritmos de ordenamento tens uma série de trocas até chegares ao resultado final, que é a lista ordenada.

O desafio é completar o seguinte código:

Código:
def trocar_elementos_nos_indices(lista, primeiro_indice, segundo_indice):
    #Escreve aqui o código necessário para que esta função troque os elementos cujos índices são "primeiro_indice" e "segundo_indice"

lista = [1, 2, 3, 4, 5]
print "Antes:", lista
trocar_elementos_nos_indices(lista, 0, 1)
print "Depois:", lista
O resultado deverá ser:

Código:
Antes: [1,2,3,4,5]
Depois: [2,1,3,4,5]

EDIT: OK, acabei de implementar um insertion sort sem usar aquela função de troca. Peço desculpa pela confusão. Ainda assim, é um bom desafio para outros algoritmos, como o Bubble Sort.
 
Última edição:
@btuger: Vejo-me obrigado a lançar aqui um desafio antes de poderes continuar. Pelo que percebi, precisas mesmo disto para que possas fazer progressos.

Em qualquer algoritmo de ordenamento (ou pelo menos na maioria) é típico teres uma função que troca dois elementos de uma lista. Por exemplo, a minha lista é [1, 2, 3, 4, 5] e quero trocar os elementos nos índices 0 e 2, ficando portanto [3, 2, 1, 4, 5]. Isto porque nesses algoritmos de ordenamento tens uma série de trocas até chegares ao resultado final, que é a lista ordenada.

O desafio é completar o seguinte código:

Código:
def trocar_elementos_nos_indices(lista, primeiro_indice, segundo_indice):
    #Escreve aqui o código necessário para que esta função troque os elementos cujos índices são "primeiro_indice" e "segundo_indice"

lista = [1, 2, 3, 4, 5]
print "Antes:", lista
trocar_elementos_nos_indices(lista, 0, 1)
print "Depois:", lista
O resultado deverá ser:

Código:
Antes: [1,2,3,4,5]
Depois: [2,1,3,4,5]
EDIT: OK, acabei de implementar um insertion sort sem usar aquela função de troca. Peço desculpa pela confusão. Ainda assim, é um bom desafio para outros algoritmos, como o Bubble Sort.
Assim serve?
Código:
def elementos(lista):
    print 'Antes:', lista
    lista[0],lista[1] = lista[1], lista[0]
    print 'Depois:', lista

Por acaso até vi tirei ideia de fazer lista[0],lista[1] = lista[1], lista[0] através de um BubbleSort, não sabia que dava para fazer daquela maneira.
 
Confesso que não conhecia essa sintaxe: "lista,lista[j]=lista[j],lista". Efectivamente faz o pretendido. O código seria:

Código:
def trocar_elementos_nos_indices(lista, primeiro_indice, segundo_indice):
    lista[primeiro_indice],lista[segundo_indice] = lista[segundo_indice],lista[primeiro_indice]

lista = [1, 2, 3, 4, 5]
print "Antes:", lista
trocar_elementos_nos_indices(lista, 0, 1)
print "Depois:", lista
No entanto, estava mais a pensar nisto:

Código:
def trocar_elementos_nos_indices(lista, primeiro_indice, segundo_indice):
    temp = lista[primeiro_indice]
    lista[primeiro_indice] = lista[segundo_indice]
    lista[segundo_indice] = temp

lista = [1, 2, 3, 4, 5]
print "Antes:", lista
trocar_elementos_nos_indices(lista, 0, 1)
print "Depois:", lista
O Python pelos vistos dá-te o "luxo" de usares aquela sintaxe, mas aviso já que podes não te safar da mesma maneira noutras linguagens :) De qualquer maneira, tenta perceber o meu código. Porque é que eu faço:

Código:
temp = lista[primeiro_indice]
lista[primeiro_indice] = lista[segundo_indice]
lista[segundo_indice] = temp
?
 
De qualquer maneira, tenta perceber o meu código. Porque é que eu faço:
Código:
temp = lista[primeiro_indice]
lista[primeiro_indice] = lista[segundo_indice]
lista[segundo_indice] = temp
?
Guardaste o primeiro índice da lista na variável temp, depois substituíste o primeiro índice pelo segundo, depois substituíste o segundo índice por temp.

Era isto que estavas a perguntar ou era o código todo?
 
Guardaste o primeiro índice da lista na variável temp, depois substituíste o primeiro índice pelo segundo, depois substituíste o segundo índice por temp.

Era isto que estavas a perguntar ou era o código todo?

Não, era só isso. Bom, o desafio que eu queria realmente ter lançado antes, que tem a ver com o insertion sort é fazer a função insert:

Código:
#!/usr/bin/python
# -*- coding: utf-8 -*-
import random

def inserirElemento(lista, indice_do_elemento, posicao):
    #Inserir código aqui

lista = random.sample(xrange(100), 10)
print lista

indice_do_elemento = int(raw_input("Qual é o índice do elemento que pretende inserir? "))
print "Elemento escolhido:", lista[indice_do_elemento]

posicao = int(raw_input("Em que posição pretende inserir esse elemento? "))

inserirElemento(lista, indice_do_elemento, posicao)
print lista

Por exemplo, se a lista for [5, 4, 3, 2, 1] e eu quiser inserir o elemento de índice 4 (que é o 1) na posição 0 (ou seja, inseri-lo antes do 5), como é que eu faço? (o resultado deve dar, naturalmente, [1, 5, 4, 3, 2])
 
Não, era só isso. Bom, o desafio que eu queria realmente ter lançado antes, que tem a ver com o insertion sort é fazer a função insert:

Código:
#!/usr/bin/python
# -*- coding: utf-8 -*-
import random

def inserirElemento(lista, indice_do_elemento, posicao):
    #Inserir código aqui

lista = random.sample(xrange(100), 10)
print lista

indice_do_elemento = int(raw_input("Qual é o índice do elemento que pretende inserir? "))
print "Elemento escolhido:", lista[indice_do_elemento]

posicao = int(raw_input("Em que posição pretende inserir esse elemento? "))

inserirElemento(lista, indice_do_elemento, posicao)
print lista
Por exemplo, se a lista for [5, 4, 3, 2, 1] e eu quiser inserir o elemento de índice 4 (que é o 1) na posição 0 (ou seja, inseri-lo antes do 5), como é que eu faço? (o resultado deve dar, naturalmente, [1, 5, 4, 3, 2])
Tive a dar uma vista de olhos rápida e não percebi muito bem o código,porque é que isso nao está dentro da função?Se preferires mandar o ficheiro do codigo por PM podes mandar.

UPDATE:
Tive a ver aquilo do bubblesort e já consegui chegar a algum lado, tive a tentar e a ver e consegui fazer isto:

Código:
def bubblesort(lista,e):
    print lista
    while 1:
        for i in range(e - 1):
            if lista[i] > lista[i+1]:
                lista[i], lista[i+1] = lista[i+1], lista[i]
                print lista
Eu ao ver foi tentando entender o código, e tudo o que eu fiz no código eu entendi, só estou com uma dúvida nesta parte, embora eu pense que o meu raciocínio esteja certo.
lista, lista[i+1]. O lista[i+1] está a "avançar" nos números certo.
Exemplo:

lista = [4,5,3]
if lista > lista[i+1]:
lista, lista[i+1] = lista[i+1],lista

O lista vai ser o 4 e o lista[i+1] vai ser o 5 mas 4 < 5, então lista vai passar a 5 e o lista[i+1] vai passar a ser o 3 não é? O lista[i+1] faz andar mais um número na lista não é?

Parece estar confuso, espero que tenhas compreendido :p

Depois outro problema é neste código que vi.
Código:
def bubbleSort(L,n):
    flag = True
    while flag:
        flag = False
        for i in range(n-1):
            if L[i] > L[i+1]:
                L[i],L[i+1] = L[i+1],L[i]
                flag = True
Eu fiz o meu com while 1, mas vai dar erro porque ele vai estar sempre a repetir, e a tentar mudar os números de lugar quando eles já estão no sitio certo e então vai originar um erro, mas se virmos esse código vemos flag = True e depois False e depois True, e por causa disso não percebi muito bem, porque é que o flag = True vai fazer o programa parar?

Obrigado desde já e desculpa lá por estas dúvidas gigantescas :p
 
Última edição:
Boas. Vejo que andam por aí dificuldades, aqui fica o código como spoiler. Visto que vou estar fora mais uns dias, não vou poder esclarecer dúvidas acerca dele, mas certamente que outros o farão.
Este foi o meu primeiro script em Python, por isso se houver maneiras melhores de o fazer, não se admirem. :p
Só programo em C e C++ regularmente.

Código:
[spoiler=black]
a = []

while True:
	try:
		a.append(input());
	except EOFError:
		break

for i in range(1, len(a)):
	for k in range(len(a)-1, 0, -1):
		if a[k] < a[k-1]:
			tmp = a[k]
			a[k] = a[k-1]
			a[k-1] = tmp
print a
[/spoiler]
 
Eu ao ver foi tentando entender o código, e tudo o que eu fiz no código eu entendi, só estou com uma dúvida nesta parte, embora eu pense que o meu raciocínio esteja certo.
lista, lista[i+1]. O lista[i+1] está a "avançar" nos números certo.
Exemplo:

lista = [4,5,3]
if lista > lista[i+1]:
lista, lista[i+1] = lista[i+1],lista

O lista vai ser o 4 e o lista[i+1] vai ser o 5 mas 4 < 5, então lista vai passar a 5 e o lista[i+1] vai passar a ser o 3 não é? O lista[i+1] faz andar mais um número na lista não é?


Sim, o objectivo do bubble sort é precisamente esse. lista refere-se ao número na posição i (e como o i começa em 0, refere-se em primeiro lugar ao 4). Consequentemente, lista[i + 1] refere-se ao número que estiver imediatamente a seguir (o 5). O objectivo daquele if é dizer "se o número na posição i for maior que o número na posição i + 1, troca-os de lugar, porque para uma lista estar ordenada, os números menores têm que vir primeiro".

Eu fiz o meu com while 1, mas vai dar erro porque ele vai estar sempre a repetir, e a tentar mudar os números de lugar quando eles já estão no sitio certo e então vai originar um erro, mas se virmos esse código vemos flag = True e depois False e depois True, e por causa disso não percebi muito bem, porque é que o flag = True vai fazer o programa parar?

Em primeiro lugar, poderias ter feito com o while 1 à vontade. Pode parecer que vai repetir vezes e vezes sem conta, mas a instrução "break" serve para sair de um ciclo while, independentemente de a condição ser True ou False.

Em segundo lugar, talvez queiras olhar para esse código desta forma:
Código:
def bubbleSort(L,n):
    houve_troca = True
    while houve_troca:
        houve_troca = False
        for i in range(n-1):
            if L[i] > L[i+1]:
                L[i],L[i+1] = L[i+1],L[i]
                houve_troca = True

Aquela flag é precisamente para sinalizar se o bubble sort fez uma troca ou não. Começa a True (porque se não aquele while nunca executava). Dentro do while, colocamo-la a False (vamos assumir, temporariamente, que não vão existir trocas). A tua confusão está naquela última atribuição com o valor True. Repara, um ciclo while só termina se a condição for False (neste caso, se houve_troca == False).

Tu estás a dizer "ah, então nunca vai sair, porque passa sempre a True". Mas isso não é verdade. O houve_troca só passa a True se L > L[i + 1]!

O bubble sort faz várias passagens à lista, verificando se o elemento na posição i é maior que o elemento na posição i + 1. Mas o que é que achas que significa quando nenhum elemento na posição i é maior que o seguinte?
 
Sim, o objectivo do bubble sort é precisamente esse. lista refere-se ao número na posição i (e como o i começa em 0, refere-se em primeiro lugar ao 4). Consequentemente, lista[i + 1] refere-se ao número que estiver imediatamente a seguir (o 5). O objectivo daquele if é dizer "se o número na posição i for maior que o número na posição i + 1, troca-os de lugar, porque para uma lista estar ordenada, os números menores têm que vir primeiro".



Em primeiro lugar, poderias ter feito com o while 1 à vontade. Pode parecer que vai repetir vezes e vezes sem conta, mas a instrução "break" serve para sair de um ciclo while, independentemente de a condição ser True ou False.

Em segundo lugar, talvez queiras olhar para esse código desta forma:
Código:
def bubbleSort(L,n):
    houve_troca = True
    while houve_troca:
        houve_troca = False
        for i in range(n-1):
            if L[i] > L[i+1]:
                L[i],L[i+1] = L[i+1],L[i]
                houve_troca = True
Aquela flag é precisamente para sinalizar se o bubble sort fez uma troca ou não. Começa a True (porque se não aquele while nunca executava). Dentro do while, colocamo-la a False (vamos assumir, temporariamente, que não vão existir trocas). A tua confusão está naquela última atribuição com o valor True. Repara, um ciclo while só termina se a condição for False (neste caso, se houve_troca == False).

Tu estás a dizer "ah, então nunca vai sair, porque passa sempre a True". Mas isso não é verdade. O houve_troca só passa a True se L > L[i + 1]!


O bubble sort faz várias passagens à lista, verificando se o elemento na posição i é maior que o elemento na posição i + 1. Mas o que é que achas que significa quando nenhum elemento na posição i é maior que o seguinte?


Pois a minha confusão estava mesmo naquele True final, estava a criar-me confusão o porque de flag = True cancelar o while mas agora já percebi :)

Mas o que é que achas que significa quando nenhum elemento na posição i é maior que o seguinte?
Não percebi muito bem o que queres dizer, mas penso que a resposta seja que se nenhum elemento na posição i for maior que o seguinte ele vai permanecer naquela posição até aparecer um valor maior.

Agradeço a ajuda fornecida pelo Mr_Miguel que foi importantíssima para eu entender o Bubble Sort, e ao Psycop por ter aberto este tópico :)

Ups, outras dúvidas :P
Porque é que aqui : def bubbleSort(L,n): é preciso meter no n o número de elementos que a lista contêm?
Porque que é que tem de ser for i in range(n-1).
E posso usar isto também para descobrir qual o número maior entre 3 números ou existe um método melhor? Existir sei que existe mas não estou a ver como fazer mas sem usar aqueles ifs todos.
São dúvidas pequenas mas quero ficar a perceber mesmo tudo.
 
Última edição:
Não percebi muito bem o que queres dizer, mas penso que a resposta seja que se nenhum elemento na posição i for maior que o seguinte ele vai permanecer naquela posição até aparecer um valor maior.

Não era bem esse tipo de resposta que eu queria. Na realidade, quando nenhum elemento da lista é maior que o que está a seguir, é porque a lista já está ordenada. Por isso é que no bubble sort temos "enquanto tiverem havido trocas".

Porque é que aqui : def bubbleSort(L,n): é preciso meter no n o número de elementos que a lista contêm?

Se queres que eu te diga, acho que aquele n não faz muito sentido como parâmetro da função. A ideia do bubble sort é:

1. Fazer uma passagem pelo array todo
2. Fazer uma passagem pelo array todo excepto o último elemento (porque na passagem anterior o último elemento estará com certeza na posição correcta)
3. Fazer uma passagem pelo array todo excepto os dois últimos elementos (mesma razão)
4. (...) (fazer passagens até não existirem trocas de elementos)

A mim parece-me que o correcto seria:

Código:
def bubbleSort(L):
    n = len(L)
    houve_troca = True
    while houve_troca:
        houve_troca = False
        for i in range(n-1):
            if L[i] > L[i+1]:
                L[i],L[i+1] = L[i+1],L[i]
                houve_troca = True
        n = n - 1
Porque que é que tem de ser for i in range(n-1).
A razão pela qual subtrais 1 ao valor de n tem a ver com o facto de teres que aceder ao elemento na posição i + 1. Se fosse range(n), ias chegar a uma altura em que fazias L[n-1] > L[n], o que não é permitido, porque os índices só vão de 0 a n-1.
E posso usar isto também para descobrir qual o número maior entre 3 números ou existe um método melhor? Existir sei que existe mas não estou a ver como fazer mas sem usar aqueles ifs todos.
São dúvidas pequenas mas quero ficar a perceber mesmo tudo.

Depende do que entenderes por "melhor". Se tivesses a certeza que só ias trabalhar com 3 elementos, os ifs encadeados são provavelmente o método mais eficiente. Os algoritmos de ordenamento são mais genéricos (ou seja, funcionam para qualquer número de elementos). Fora esses dois métodos, não estou a ver mais nenhum que permite determinar qual dos números é o menor/maior.
 
Não era bem esse tipo de resposta que eu queria. Na realidade, quando nenhum elemento da lista é maior que o que está a seguir, é porque a lista já está ordenada. Por isso é que no bubble sort temos "enquanto tiverem havido trocas".



Se queres que eu te diga, acho que aquele n não faz muito sentido como parâmetro da função. A ideia do bubble sort é:

1. Fazer uma passagem pelo array todo
2. Fazer uma passagem pelo array todo excepto o último elemento (porque na passagem anterior o último elemento estará com certeza na posição correcta)
3. Fazer uma passagem pelo array todo excepto os dois últimos elementos (mesma razão)
4. (...) (fazer passagens até não existirem trocas de elementos)

A mim parece-me que o correcto seria:

Código:
def bubbleSort(L):
    n = len(L)
    houve_troca = True
    while houve_troca:
        houve_troca = False
        for i in range(n-1):
            if L[i] > L[i+1]:
                L[i],L[i+1] = L[i+1],L[i]
                houve_troca = True
        n = n - 1
A razão pela qual subtrais 1 ao valor de n tem a ver com o facto de teres que aceder ao elemento na posição i + 1 . Se fosse range(n), ias chegar a uma altura em que fazias L[n-1] > L[n], o que não é permitido, porque os índices só vão de 0 a n-1.

Depende do que entenderes por "melhor". Se tivesses a certeza que só ias trabalhar com 3 elementos, os ifs encadeados são provavelmente o método mais eficiente. Os algoritmos de ordenamento são mais genéricos (ou seja, funcionam para qualquer número de elementos). Fora esses dois métodos, não estou a ver mais nenhum que permite determinar qual dos números é o menor/maior.
Ah prontos, já fiquei esclarecido e realmente o código como meteste é melhor.
Obrigadão pela ajuda, foi bastante útil :)
 
Se calhar é uma dúvida estúpida mas não consigo fazer isto:
Faça um Programa que leia três números e mostre o maior e o menor deles.
Eu consigo fazer com que o programa amostre o número maior, mas ele depois não amostra o menor, eu fiz o código assim.

Código:
a = input('Numero: ')
b = input('Numero: ')
c = input('Numero: ')
if a > b and a > c:
    print a
elif a < b and a < c:
    print a
elif b > a and b > c:
    print b
elif b < a and b < c:
    print b
elif c > a and c > b:
    print c
elif c < a and c < b:
    print c

Gostava de saber o porquê do número menor não aparecer.
Obrigado desde já
 
Se calhar é uma dúvida estúpida mas não consigo fazer isto:
Eu consigo fazer com que o programa amostre o número maior, mas ele depois não amostra o menor, eu fiz o código assim.

Código:
a = input('Numero: ')
b = input('Numero: ')
c = input('Numero: ')
if a > b and a > c:
    print a
elif a < b and a < c:
    print a
elif b > a and b > c:
    print b
elif b < a and b < c:
    print b
elif c > a and c > b:
    print c
elif c < a and c < b:
    print c
Gostava de saber o porquê do número menor não aparecer.
Obrigado desde já


Boas,

Isso está errado, porque ao encontrar uma condição verdadeira, não avança para as condições de else.

Tens que dividir a parte do menor, e a parte do maior.

Cumprimentos
 
Porque repara o que tu estavas a fazer:

Quando uma das condições se verificava, ele iria processar o 'then', e nunca mais iria paras os 'else', visto que a condição estaria correcta. Portanto, depois de encontrar uma condição verdadeira, não fazia o resto das comparações.

Cumprimentos
 
Porque repara o que tu estavas a fazer:

Quando uma das condições se verificava, ele iria processar o 'then', e nunca mais iria paras os 'else', visto que a condição estaria correcta. Portanto, depois de encontrar uma condição verdadeira, não fazia o resto das comparações.

Cumprimentos
Eu depois também percebi isso, mais uma vez obrigado :)
 
Bem, precisava de mais ajuda. Alguém me pode explicar o self? É que eu já estive a ver e simplesmente não encaixa :p
Obrigado desde já
 
O self é de certa forma equivalente ao this do Java e C#. Tem utilidade se estiveres a criar classes. Caso nada disto faça sentido para ti, aconselho-te a ler algo relacionado com programação por objectos, como por exemplo, aqui.
 
Back
Topo