30 svar
395 visningar
GräddMaja behöver inte mer hjälp
GräddMaja 23
Postad: 8 maj 2022 13:43

primtalssåll

Jag behöver hjälp med att få till ett primtalssåll som lägger till primtalen i en lista, med felhantering. Vad gör jag för fel när jag inte får till primtal? utan att den enbart skriver ut alla tal i det intervall som jag anger.

Tacksam för hjälp :)

CurtJ 1201
Postad: 8 maj 2022 13:48

Vad jag ser gör du ingen kontroll om talet är ett primtal innan du lägger in det i listan.

GräddMaja 23
Postad: 8 maj 2022 14:27
CurtJ skrev:

Vad jag ser gör du ingen kontroll om talet är ett primtal innan du lägger in det i listan.

Jag provade att lägga i en kontrollen i listan, men får felmeddelande om rad två "är_primtal=True" vad beror det på?

CurtJ 1201
Postad: 8 maj 2022 17:10

Vad säger felmeddelandet då?

GräddMaja 23
Postad: 8 maj 2022 17:41
CurtJ skrev:

Vad säger felmeddelandet då?

invalid syntax

CurtJ 1201
Postad: 8 maj 2022 18:04 Redigerad: 8 maj 2022 18:08

Om det är raden är_primtal=True så gissar jag att du kör python2 eller tidigare. Då är bara ASCII tillåtet, dvs inga svenska tecken. Annars är det ok syntax.

Däremot är jag mer fundersam på din initiering av primtalslista. Den syntaxen känner inte jag igen som giltig. Den fungerar fram till "talet for talet in range(...)" men ger då alla tal mellan start och stoppvärde och det är nog inte det du vill.

Du har ju plockat ut primtalen i den inledande loopen. Om du i stället för att skriva ut primtalet lägger in det i en lista så har du ju en färdig lista/array efter den loopen.

Innan for-loopen definierar du en lista (array) med t ex "primes=[]"

och i stället för print(talet) gör du "primes.append(talet)" så har du din lista av primtal.

Det finns effektivare metoder att leta primtal men det är kanske inte det du ska fokusera på i den här uppgiften. 

GräddMaja 23
Postad: 8 maj 2022 20:17
CurtJ skrev:

Om det är raden är_primtal=True så gissar jag att du kör python2 eller tidigare. Då är bara ASCII tillåtet, dvs inga svenska tecken. Annars är det ok syntax.

Däremot är jag mer fundersam på din initiering av primtalslista. Den syntaxen känner inte jag igen som giltig. Den fungerar fram till "talet for talet in range(...)" men ger då alla tal mellan start och stoppvärde och det är nog inte det du vill.

Du har ju plockat ut primtalen i den inledande loopen. Om du i stället för att skriva ut primtalet lägger in det i en lista så har du ju en färdig lista/array efter den loopen.

Innan for-loopen definierar du en lista (array) med t ex "primes=[]"

och i stället för print(talet) gör du "primes.append(talet)" så har du din lista av primtal.

Det finns effektivare metoder att leta primtal men det är kanske inte det du ska fokusera på i den här uppgiften. 

Jag kör med python 3.10

Mitt fokus i uppgiften är att leta primtal i en sekvens och dessa primtal ska läggas i en lista och presenteras med hur många primtal som hittas. Jag ska även ha med felkod.

Jag har försökt få till det så som du förklarar, men det har inte gått så bra. Skulle du ha några fler bra tips så tar jag gladeligen emot det.

CurtJ 1201
Postad: 8 maj 2022 20:31

Kan du visa koden du har nu? Och felutskriften så kan jag leda dig

GräddMaja 23
Postad: 8 maj 2022 20:45

Jag har nu kommit så här långt, så tänker att det gäller att få till felhanteringen.

Skulle även kunna få det snyggare, men det är ju inget måste :)

CurtJ 1201
Postad: 8 maj 2022 20:50

Nja, det är inte primtal du skriver ut utan alla  udda.

Börja med att deklarera din primtalslista som en tom lista innan loopen

När du, i loopen, konstaterat att det är ett primtal så lägger du in den i listan

Sen kan du skriva ut den som du gör.

Felhanteringen du kan behöva är att hantera värden som matas in som inte är heltal.

Jag lägger till koden jag menar (utan inmatning/felhantering) men försök själv först

Visa spoiler
primtalslista = []
for talet in range(start_värde, stop_värde):
    är_primtal = True
    for k in range(2, talet):
        if talet % k == 0:
            är_primtal = False
    if är_primtal:
        primtalslista.append(talet)

print(primtalslista, len(primtalslista))
GräddMaja 23
Postad: 8 maj 2022 21:24
CurtJ skrev:

Nja, det är inte primtal du skriver ut utan alla  udda.

Börja med att deklarera din primtalslista som en tom lista innan loopen

När du, i loopen, konstaterat att det är ett primtal så lägger du in den i listan

Sen kan du skriva ut den som du gör.

Felhanteringen du kan behöva är att hantera värden som matas in som inte är heltal.

Jag lägger till koden jag menar (utan inmatning/felhantering) men försök själv först

Visa spoiler
primtalslista = []
for talet in range(start_värde, stop_värde):
    är_primtal = True
    for k in range(2, talet):
        if talet % k == 0:
            är_primtal = False
    if är_primtal:
        primtalslista.append(talet)

print(primtalslista, len(primtalslista))

Tack, jag hade lagt primtalslista.append(talet) på fel ställe naturligtvis.

Nu när jag försöker få till felhanteringen så förstör det i koden jag skrivit istället för att hjälpa.

CurtJ 1201
Postad: 8 maj 2022 21:31

Kan du visa?

GräddMaja 23
Postad: 8 maj 2022 21:46
CurtJ skrev:

Kan du visa?

Jag var snabb och plockade bort det i koden, jag använde mig av Try: och exceptValueError.

GräddMaja 23
Postad: 8 maj 2022 21:48

Jag bara funderar på om det räcker med den for loop som jag har, det börjar vara snurrigt nu :)

CurtJ 1201
Postad: 8 maj 2022 21:58 Redigerad: 8 maj 2022 22:00

 

Jag skulle nog lägga felhanteringen av indateringen utanför din primtalsloop så du inte krånglar till det för mycket.

En väsentlig del av felhantering i de flesta språk som jag känner till handlar om att ta hand om de undantag (exceptions) som runtime-miljön kastar. Det gör man med en konstruktion som kapslar in kod om man vill fånga exceptions från och tala om vad koden ska göra OM ett fel kastas. I python ser den ut såhär

try: 
	kod som ska kontrolleras
except: 
	kod som exekverar om ett fel kastas

I ditt fall vill du nog att inmatningen ska göras om ifall ett fel kastas så då kan du ju kapsla in ovanstående med en slinga som körs tills inmatningen är korrekt - exempelvis

while (inmatningen är felaktig): 
    try: 
        läs in data
        tala om att inmatningen gick bra
    except: 
        Skriv ut någon varningstext till användaren


Leta reda på dina primtal givna dina indata.. 

	

Vill man så kan man va specifik med vilka fel man vill fånga men det behövs knappast i det här fallet.

GräddMaja 23
Postad: 8 maj 2022 22:20

Jag får verkligen inte till det, är säkert för trött. Så här ser det ut nu:

Det är dags å sova!

CurtJ 1201
Postad: 8 maj 2022 22:23

try: except: ska du ha runt koden som kan kasta fel och det är, i ditt fall, när du konverterar inmatningen till heltal med instruktionen int() . Din primtalsloop kan inte kasta fel så där behövs inget. Försök följa pseudokoden i #15

CurtJ 1201
Postad: 8 maj 2022 22:29

Mitt förslag om du vill

Visa spoiler
# initiera felvillkoret för att komma in i while-loopen
fail_input = True

# så länge inte rätt inmatning gjorts
while (fail_input):
    # Hantera fel i konverteringen till int. Användaren ska bara mata in heltal
    try:
        start_värde = int(input("välj startvärde:"))
        stop_värde = int(input("välj stoppvärde:"))
        # allt gick bra, bryt slingan
        fail_input = False
    except:
        # Varna användaren
        print("Endast heltal")


# skapa primtalslistan
primtalslista = []

# gå igenom alla möjliga tal
for talet in range(start_värde, stop_värde):
    
    är_primtal = True
    for k in range(2, talet):
        if talet % k == 0:
            är_primtal = False
    if är_primtal:
        # Primtal, lägg in i listan
        primtalslista.append(talet)

print(primtalslista, len(primtalslista))
GräddMaja 23
Postad: 8 maj 2022 22:30
CurtJ skrev:

Mitt förslag om du vill

Visa spoiler
# initiera felvillkoret för att komma in i while-loopen
fail_input = True

# så länge inte rätt inmatning gjorts
while (fail_input):
    # Hantera fel i konverteringen till int. Användaren ska bara mata in heltal
    try:
        start_värde = int(input("välj startvärde:"))
        stop_värde = int(input("välj stoppvärde:"))
        # allt gick bra, bryt slingan
        fail_input = False
    except:
        # Varna användaren
        print("Endast heltal")


# skapa primtalslistan
primtalslista = []

# gå igenom alla möjliga tal
for talet in range(start_värde, stop_värde):
    
    är_primtal = True
    for k in range(2, talet):
        if talet % k == 0:
            är_primtal = False
    if är_primtal:
        # Primtal, lägg in i listan
        primtalslista.append(talet)

print(primtalslista, len(primtalslista))

Ja naturligtvis, tusen tack!

GräddMaja 23
Postad: 9 maj 2022 22:01

Lite påbackning då jag behöver använda funktioner för att få till det. Har ni någon ide om vad jag behöver göra här?

CurtJ 1201
Postad: 9 maj 2022 22:49

En funktion är ett stycket kod som man av olika skäl vill separera från övrig kod. Det kan va att man vill kunna anropa den från olika ställen i sin kod och om man då gör en funktion av den så behöver man bara skriva den en gång. En annan anledning är att strukturera sin kod i mindre delar för att lättare testa och underhålla koden.

Som du skriver så deklarerar man en funktion med def och ett kolon efter parentesen och följande rader i funktionen ska vara indenterade. En funktion kan ta noll eller fler parametrar som man använder för att skicka in data till funktionen. Man kan också deklarera globala variabler som då är tillgängliga i funktionen men jag tycker sällan det är en bra idé, det blir otydligt vad funktionen behöver och det blir krångligare att testa för att nämna några skäl. Jag deklarerar alltid allt som behövs som parametrar.

En funktion kan returnera värden också och det görs med en return-instruktion i slutet på metoden. Return-instruktionen tar ett argument och det argumentet är det som anroparen av metoden kan få som returvärde när metoden har anropats. Man kan tänka sig en metod returnera ett heltalsvärde som i

def add (a, b): 
    sum = a + b
    return sum

integer_sum = add (14, 25)

Behöver man returnera fler värden så kan returvärdet vara en lista eller en tuple som i

def sum_prod (a, b): 
    sum = a + b
    prod = a*b
    return (a, b)

(sum, prod) = sum_prod(14,25)

 

Om vi nu går till din kod så kan man som du gör lägga inmatningen i en funktion som då returnerar start och stoppvärdet. Vi behöver ingen parameter så den kan se ut såhär. Den motsvarar din funktion "inmatning"

def get_limits():

    # här läser du in start- och stoppvärde från användaren 
    # t ex som i mitt exempel i #18	

    return (startvalue, stopvalue)

Jag föredrar engelska för identifierare men det är en smaksak. Alla har olika preferenser

Du definierar sen leta_primtal och där har du så riktigt skickat in start och stoppvärden från inmatningen som parametrar. Den funktionen ska inte returnera något utan skriva ut resultatet. Det borde kunna se ut så här givet get_limits() ovan

def print_primes(start_value, stop_value):
    
     # här kommer koden som du har i din funktion. 

Du har sen definierat en main() som anropar båda och den skulle i vårt fall med funktionerna ovan kunna se ut såhär

def main():
    (start, stop) = get_limits()
    find_primes(start, stop)

och sen anropar du main som du gör i huvudflödet. Man skulle kunna hoppa över main och göra koden i main i huvudflödet i stället men det är också en smaksak.

print_primes eller som du kallar den let_primtal fungerar nog som den är skriven men get_limits() (inmatning()) måste du se över. Titta på mitt förslag i #18

Fråga om du behöver mer hjälp

GräddMaja 23
Postad: 9 maj 2022 23:28

Kommit lite längre men:

Vad gör jag åt detta?

CurtJ 1201
Postad: 9 maj 2022 23:31

Du har inte använt mitt exempel. Titta på det så ser du att try: alltid måste ha en except: eller finally: med. Det finns andra konstigheter i den metoden också, t ex "for i in range (x>0):  ... Jämför med #18 och försök förstå vad den koden gör så blir det llättare för dig

GräddMaja 23
Postad: 9 maj 2022 23:45

Om jag fattar dig rätt så är det såhär du menar?!

Jag får ju fortfarande felkod, så får fortsätta i morgon :) Tack för din hjälp!

CurtJ 1201
Postad: 9 maj 2022 23:48 Redigerad: 9 maj 2022 23:52

Du returnerar inget från inmatning(). Titta på #21 och försök förstå hur funktioner fungerar.  Sen är din funktion inmatning() fortfarande konstig. Det här är mitt exempel från #18 som du kan utgå från i din inmatning()

# initiera felvillkoret för att komma in i while-loopen
fail_input = True

# så länge inte rätt inmatning gjorts
while (fail_input):
    # Hantera fel i konverteringen till int. Användaren ska bara mata in heltal
    try:
        start_värde = int(input("välj startvärde:"))
        stop_värde = int(input("välj stoppvärde:"))
        # allt gick bra, bryt slingan
        fail_input = False
    except:
        # Varna användaren
        print("Endast heltal")

så blir det lättare.

GräddMaja 23
Postad: 10 maj 2022 09:05 Redigerad: 10 maj 2022 09:11

Nu har jag löst flera saker, men hur får jag till att det inte är negativa tal, det får ju inte vara möjligt att skriva in  t.ex -2

CurtJ 1201
Postad: 10 maj 2022 09:27 Redigerad: 10 maj 2022 09:32

När du har läst in värdena kan du kontrollera att de är större än 0 och om de inte är det ser du till att while-slingar körs ett varv till, t ex genom att du sätter fail_input  till True

Vill du va riktigt vass så kan du göra det runtime-miljön gör om du försöker konvertera ett heltal som inte är ett heltal. Det kallas att "throw an exception" (kasta undantag låter konstigt) Det gör du med instuktionen

raise ValueError ('Endast positiva heltal'))

och se till att göra det innan du sätter fail_input till False

GräddMaja 23
Postad: 10 maj 2022 10:37

Vet inte om jag är ute å cyklar "haha" men tycker jag har gjort det jag ska men det kan jag ju inte eftersom den fortfarande skriver ut -2. Vad gör jag för fel?

CurtJ 1201
Postad: 10 maj 2022 13:32 Redigerad: 10 maj 2022 13:36

Ditt villkor  innehåller två logiska värden - start_värde och stopp_värde > 1.

Det fösta värdet är alltid sant och det andra är sant om värdet är större än 1. Dessa två värden kombineras med or vilket innebär att det räcker om det ena är sant och eftersom start_värde alltid är sant så blir villkorssatsen alltid sann.

Du borde konstruera den som den här, notera att jag sätter värden större än 0, inte 1

if start_värde > 0 and stopp_värde > 0:
	return (...)

Eftersom du nu returnerar när du fått korrekta värden behöver du inte sätta fail_input längre. Den är ju True så länge du inte ändrar den och det gör du ju aldrig. Du skulle kunna ta bort den helt och ersätta while-loopen med

while(True):
GräddMaja 23
Postad: 10 maj 2022 16:22
CurtJ skrev:

Ditt villkor  innehåller två logiska värden - start_värde och stopp_värde > 1.

Det fösta värdet är alltid sant och det andra är sant om värdet är större än 1. Dessa två värden kombineras med or vilket innebär att det räcker om det ena är sant och eftersom start_värde alltid är sant så blir villkorssatsen alltid sann.

Du borde konstruera den som den här, notera att jag sätter värden större än 0, inte 1

if start_värde > 0 and stopp_värde > 0:
	return (...)

Eftersom du nu returnerar när du fått korrekta värden behöver du inte sätta fail_input längre. Den är ju True så länge du inte ändrar den och det gör du ju aldrig. Du skulle kunna ta bort den helt och ersätta while-loopen med

while(True):

Toppen! Tack för att du hjälpt mig, det är svårt när man inte har någon att bolla med annars.

CurtJ 1201
Postad: 10 maj 2022 17:35

Här på PA finns många förmågor som mer än gärna delar med sig av sina kunskaper.

Lycka till med programmeringen.

Svara
Close