Python Svenska Tecken, (hjälp en nybörjare)

Permalänk
Medlem

Python Svenska Tecken, (hjälp en nybörjare)

Hej!

Jag har stött på ett problem i Python där jag inte kan läsa in svenska tecken.
Använder Python 3.5 och PyCharm 2016.2.3.
Något saknas i min kod antar jag ? Jag har förvisso lagt till "encoding=utf-8", borde de inte bli svenska tecken då ?

Min kod: (webscraping, följer en tutorial)

import urllib.request import re try: url = 'http://www.sweclockers.com/' resp = urllib.request.urlopen(url) respData = resp.read() saveFile = open('data.txt', 'w', encoding='utf-8') saveFile.write(str(respData)) saveFile.close() except Exception as e: print(str(e))

Permalänk

Prova att lägga detta högst upp i din källkod:

#!/usr/bin/env python # -*- coding: utf-8 -*-

Permalänk
Hedersmedlem
Skrivet av n413:

import urllib.request import re try: url = 'http://www.sweclockers.com/' resp = urllib.request.urlopen(url) respData = resp.read() saveFile = open('data.txt', 'w', encoding='utf-8') saveFile.write(str(respData)) saveFile.close() except Exception as e: print(str(e))

Din respData kommer som en byte-ström, dvs råa "ettor och nollor" som nu visserligen råkar representera tecken, men vilka tecken det faktiskt representerar är inte klart förrän man applicerar en teckenkodning på den ström man har fått. SweClockers sänder ut UTF-8, så du skulle kunna omvandla din byte-ström till ett internt strängobjekt genom att avkoda strömmen som just UTF-8:

response = urllib.request.urlopen(url) raw_response_data = resp.read() # Detta är ett `bytes`-objekt response_data = raw_response_data.decode('utf-8') # Detta är nu ett strängobjekt

Ett strängobjekt i Python 3 är i praktiken teckenkodningsoberoende när det väl har skapats. Den behöver inte längre veta om att den kom från UTF-8 eller någon annan teckenkodning — den vet nu vilka faktiska tecken som den ska representera (i praktiken lagras den i en modern CPython-tolk som den mest kompakta representationen av UCS-4, UCS-2 och Latin-1 som klarar av innehållet, men det är en implementationsdetalj).

Detta teckenkodningsagnostiska objekt kan du nu sedan hantera transparent i olika sammanhang. Om du vill skriva ut strängen till en terminal så kommer den först fråga terminalen "Vilken teckenkodning gillar du?", koda strömmen enligt denna teckenkodning och skicka ut motsvarande bitström. Vill du skriva till en fil så kommer Python ta reda på vilken teckenkodning du valt att öppna filen med och på samma sätt koda strängen till motsvarande bitström och banka ner den på disk.

Så, ditt response_data-objekt är efter avkodning med UTF-8 nu ett strängobjekt. Om du skapar en fil och väljer teckenkodningen att vara UTF-8 så kommer Python ta strängobjektet, koda det enligt UTF-8-reglerna och skriva det till filen:

#!/usr/bin/env python3 import re import urllib.request URL = 'http://www.sweclockers.com/' FILENAME = 'data.txt' def main(): response = urllib.request.urlopen(URL) raw_response_data = response.read() response_data = raw_response_data.decode('utf-8') with open(FILENAME, 'w', encoding='utf-8') as f: f.write(response_data) if __name__ == '__main__': main()

Varför denna "round trip" till strängobjektet med avkodning/kodning när SweClockers skickar ut UTF-8 direkt? Tja, om det inte finns några prestandamässiga problem så är det ofta en bra reflex att omvandla alla inkommande strängar till ett "korrekt" strängobjekt som man utan större fara kan skicka runt i sin kod utan att behöva minnas vilken teckenkodning som gällde. Tumregeln är att avkoda inkommande data tidigt, och koda det så nära utmatning som möjligt.

Vill man utnyttja att man vet att dokumentets teckenkodning är UTF-8 och man vill banka den direkt till disk så kan man öppna filen i binärläge och skriva bytes-objektet rakt ned till filen:

#!/usr/bin/env python3 import re import urllib.request URL = 'http://www.sweclockers.com/' FILENAME = 'data.txt' def main(): response = urllib.request.urlopen(URL) response_data = response.read() with open(FILENAME, 'wb') as f: f.write(response_data) if __name__ == '__main__': main()

Med det sagt så är det generellt enklare att behandla strängar som strängar snarare än byteströmmar, om inte annat för sin egen sinnesfrids skull.

Jag tog mig friheten att skriva om koden en smula. I stället för att lägga generell kod på den globala nivån så deklarerade jag en main()-funktion som jag kallar på genom besvärjelsen if __name__ == '__main__':, osv. Detta är en konvention som du kommer se mer eller mindre överallt i Python-världen. Anledningen har att göra med import av moduler kontra att köra dem som egna skript, samt att undvika att förorena den globala namnrymden. Det tar inte många knapptryckningar att fixa, undviker problem med odeklarerade funktioner pga deras ordning i filen, med mera, så det är bra att vänja sig vid. Se What does `if __name__ == “__main__”:` do? [StackOverflow].

Jag använde även en kontexthanterare ("context manager") för open-anropet genom nyckelordet with. Detta har följden att filen alltid hanteras korrekt på så sätt att den stängs automatiskt när den trillar ur scope, i stället för att du måste ta ansvar för att explicit kalla close() (i praktiken kallas detta ändå när filen trillar ur scope i "vanliga" Python-tolkar, men det är inte garanterat, och framför allt är det inte garanterat när det händer). Mindre kod att skriva, mer robust kod.

Att lära sig:

  • Vad är ett bytes-objekt? Vad är ett str-objekt?

  • Vad innebär det att avkoda ("decode") något? Vad innebär det att koda ("encode") något? Vilka operationer applicerar på bitströmmar respektive strängar?

  • Vad är en kontexthanterare? Varför vill man använda dessa?

Sista punkten är lite överkurs, men det kan vara trevligt att ha sett det någon gång, då du definitivt kommer se with fler gånger om du fortsätter med Python.

Skrivet av Formel117:

Prova att lägga detta högst upp i din källkod:

#!/usr/bin/env python # -*- coding: utf-8 -*-

Detta anger tolken till Python 2 enligt en vanlig konvention på *nix-system, samt deklarerar att Python-filens teckenkodning är UTF-8. Det rör inte den data som tas emot eller skrivs till fil.

Om filen börjar köras med Python 2 kommer det också bli problem med urllib-importen (motsvarigheten till urllib.request.open är i Python 2 snarare urllib2.urlopen) samt att open i Python 2 inte tar någon encoding-parameter.

Stavning.
Visa signatur

Nu med kortare användarnamn, men fortfarande bedövande långa inlägg.

Permalänk
Medlem

@phz: Tack för ett utomordentlig svar!!! Bästa svar jag läst på länge

Jag ska göra min läxa och läsa på om punkterna du listat. Tack! Dock lyckades jag faktiskt tidigare hitta lösningen på just de problemet efter letande (2-3 kvällar) på diverse ställen/tutorials etc, slutligen hittade jag svaret i Python library. Inkommande ström behövde tillägget decode('utf-8). Det tar så väldans tid att lära sig programmera på egen hand.
Jag upplever det oerhört svårt att kliva över den där tröskeln innan man kan börja göra något vettigt på egen hand, utan att hela tiden fastna på nya saker

Nu har jag problemet igen. Tidigare problemet var enklare att förstå, det här problemet känns mer ologiskt.

Jag hämtar nu data från dagens industri istället och försöker läsa in lite statistik, det går ju sådär...

Problemet/ frågan: Hur kommer det sig att stat_1 respektive stat_2 ger så olika output när dess regular expression är desamma vid ett tillfälle i loopen. (stat_1 är"hårdkodat"/statiskt det andra, stat_2, hämtar sitt "regex" från listan "namnbanker")

import re import urllib.request URL = 'http://trader.di.se/index.php/quote/maklarstat/1061816' FILENAME = 'data.txt' def main(): response = urllib.request.urlopen(URL) raw_response_data = response.read() response_data = raw_response_data.decode('utf-8') with open(FILENAME, 'w', encoding='utf-8') as f: f.write(response_data) namnBanker = re.findall(r'18px" style="text-align:left">(.*)</td>', str(response_data)) taBortradtecken = re.split(r'\n|\t', str(response_data)) i = 0 for namn in range(0, 2): regex = str("r'") + str(namnBanker[i]) + str("(.*?)d>'") pat = re.compile(regex, re.MULTILINE) stat_1 = re.findall(r'Svenska Handelsbanken AB(.*?)d>(.*?)class', str(taBortradtecken)) stat_2 = re.findall(pat, str(taBortradtecken)) print("\n--------------------------------------------------\n") print("stat 1: " + str(stat_1)) print("stat 2 : " + str(stat_2)) i += 1 if __name__ == '__main__': main()

PS. dessutom verkar "flaggan" re.MULTILINE totalt verkningslöst, så därför skapade jag ytterligare en sträng "taBortradtecken" (dvs \n och \s) för att kunna använda ett regular expression som löper över flera rader.

Permalänk
Hedersmedlem
Skrivet av n413:

Det tar så väldans tid att lära sig programmera på egen hand.
Jag upplever det oerhört svårt att kliva över den där tröskeln innan man kan börja göra något vettigt på egen hand, utan att hela tiden fastna på nya saker

Det är bara att köra på, men det är nog viktigt att låta inlärningen ta sin tid så att man verkligen förstår varje problem man stöter på, så att man samlar byggstenar för att ständigt förbättra sin förståelse. Stressar man för mycket för att "bara få något gjort" så kommer man efter projektet ha lärt sig mycket mindre än om man tagit sig tid, och därmed lättare fastna i samma mönster i nästa projekt, och i nästa, … .

Skrivet av n413:

Hur kommer det sig att stat_1 respektive stat_2 ger så olika output när dess regular expression är desamma vid ett tillfälle i loopen. (stat_1 är"hårdkodat"/statiskt det andra, stat_2, hämtar sitt "regex" från listan "namnbanker")

regex = str("r'") + str(namnBanker[i]) + str("(.*?)d>'") pat = re.compile(regex, re.MULTILINE) stat_1 = re.findall(r'Svenska Handelsbanken AB(.*?)d>(.*?)class', str(taBortradtecken)) stat_2 = re.findall(pat, str(taBortradtecken))

Uttrycken är inte lika. Prefixet r till en sträng som avgränsas med exempelvis apostrofer är ett kompilatordirektiv som säger till att det i strängen som följer inte ska tolkas några escape-sekvenser, men strängen i sig kommer i ett sådant fall inte innehålla r''.

När du konstruerar ditt regex för stat_2 så konstruerar du strängen (för banknamn "ABG Sundal Collier Norge ASA"):

r'ABG Sundal Collier Norge ASA(.*?)d>'

men mönstret för ditt stat_1 är strängen:

ABG Sundal Collier Norge ASA(.*?)d>

vilket är vad du vill ha. I andra fallet betyder prefixet r i koden bara att du inte vill att Python skulle tolka backslash-sekvenser i strängen som escape-tecken (detta är vanligt (och starkt förespråkat) att alltid göra för bland annat mönster till reguljära uttryck).

Se 2.4.1. Lexical analysis → String and Bytes literals i dokumentationen.

Citat:

PS. dessutom verkar "flaggan" re.MULTILINE totalt verkningslöst, så därför skapade jag ytterligare en sträng "taBortradtecken" (dvs \n och \s) för att kunna använda ett regular expression som löper över flera rader.

re.MULTILINE aktiverar sökning över flera rader, men ditt metatecken . ("punkt") matchar fortfarande bara "vanliga" tecken, och vandrar inte över en radbrytning. Ett sätt att kunna göra vad du verkar försöka göra är att även sätta flaggan re.DOTALL för att låta punkten även matcha radbörjan/radslut.

Du kombinerar multipla flaggor till re-modulen genom "bitvis OR"-operatorn, vilket i Python är | ("pipe"). Exempel:

result = re.search(pattern, haystack, re.MULTILINE|re.DOTALL)

Se

i manualen.

Visa signatur

Nu med kortare användarnamn, men fortfarande bedövande långa inlägg.

Permalänk
Medlem

import numpy
första_pris = float(input('Mata in första_pris: '))
sista_pris = float(input('Mata in sista_pris : '))
steg_langd = float(input('Mata in steg_langd: '))
momsprocent = float(input('Mata in momsprocent : '))
#första_pris = 0
print (' Pris Moms Pris_med_moms ')
print ('-----------------------------------')
for pris in numpy.arange(första_pris,sista_pris,steg_langd):
if första_pris <= sista_pris:
temp_första_pris = första_pris
första_pris = första_pris + steg_langd
moms = första_pris * (momsprocent/100)
pris_med_moms = pris + moms
#första_pris = första_pris + 1
print(f" {temp_första_pris:0.2f} {moms:0.2f} {pris_med_moms:0.2f}")
print('\n')

else:
#första_pris = första_pris
sista_pris = sista_pris + steg_langd
moms = sista_pris * (momsprocent/100)
pris_med_moms = sista_pris + moms
#sista_pris = sista_pris + 1
print(f" {sista_pris:0.2f} {moms:0.2f} {pris_med_moms:0.2f}")
print('\n')

Jag har skrivit koden ovan men det funkade inte som jag ville. Jag är en nybörjare, jag fick både problem med if raden och else stod utanför "for". Tack för hjälpen

Permalänk
Medlem
Skrivet av merdan:

import numpy
första_pris = float(input('Mata in första_pris: '))
sista_pris = float(input('Mata in sista_pris : '))
steg_langd = float(input('Mata in steg_langd: '))
momsprocent = float(input('Mata in momsprocent : '))
#första_pris = 0
print (' Pris Moms Pris_med_moms ')
print ('-----------------------------------')
for pris in numpy.arange(första_pris,sista_pris,steg_langd):
if första_pris <= sista_pris:
temp_första_pris = första_pris
första_pris = första_pris + steg_langd
moms = första_pris * (momsprocent/100)
pris_med_moms = pris + moms
#första_pris = första_pris + 1
print(f" {temp_första_pris:0.2f} {moms:0.2f} {pris_med_moms:0.2f}")
print('\n')

else:
#första_pris = första_pris
sista_pris = sista_pris + steg_langd
moms = sista_pris * (momsprocent/100)
pris_med_moms = sista_pris + moms
#sista_pris = sista_pris + 1
print(f" {sista_pris:0.2f} {moms:0.2f} {pris_med_moms:0.2f}")
print('\n')

Jag har skrivit koden ovan men det funkade inte som jag ville. Jag är en nybörjare, jag fick både problem med if raden och else stod utanför "for". Tack för hjälpen

Känns som om detta kanske borde vara en egen tråd men... det blir enklare om du berättar vad det är du försöker göra? Det kommer också vara enklare att hjälpa dig om du lägger [code][/code] taggar runt din kod så att indenteringen syns.

Troligen är det just indenteringen, indragen, du har problem med. Se till att else: står på samma indenteringsnivå som if, annars blir det en for-else istället och det verkar inte vara vad du vill ha.

Varför gör du massa kollar så att sista priset inte är större än första priset? Du har en lista med alla dina priser i, skapat av numpy.arange() som du sedan stegar dig igenom ett pris i taget med for-loopen. Det borde bara vara att skriva ut pris, moms och pris_med_moms och skippa allting annat.

Kan det vara så att detta började sitt liv som en while-loop? Det ser lite ut så.

Visa signatur

Primär: R9 3900X | ASUS X570-F Gaming | NH-D15 | 64GB@3200MHz | RTX 3080 10GB | Seasonic 850W | Fractal Define R6 |
Gamla bettan: i5 750@3.8GHz | 8GB | HD5770 | Corsair VS 550W | FD R2 |

Permalänk
Medlem

Jag vill mata in första och sista pris som gränser och skriva ut efter varje steg_langd pris med moms. Det som ska skrivas ut i sista delen är att första värdet skulle vara större än det sista. jag gjorde samma sak med while men kunde inte lyckas. När jag kör programmet på första while skrivs sista raden två gånger och jag förstår inte varför. t.ex steg_längd är 0.1, momsprocent är 10, första värdet är 10 och sista värdet är 11.
Sista raden blir två gånger 11, 2.75 och 13.75 och jag förstår inte varför programmet skriver sista raden. Tack

första_pris = float(input('Mata in första_pris: '))
sista_pris = float(input('Mata in sista_pris : '))
steg_langd = float(input('Mata in steg_langd: '))
momsprocent = float(input('Mata in momsprocent : '))
print (' Pris Moms Pris_med_moms ')
print ('-----------------------------------')
while första_pris <= sista_pris:
temp_första_pris = första_pris
första_pris = första_pris + steg_langd
moms = temp_första_pris * (momsprocent/100)
pris_med_moms = temp_första_pris + moms
print(f" {temp_första_pris:0.2f} {moms:0.2f} {pris_med_moms:0.2f}")
print('\n')
while första_pris > sista_pris:
temp_sista_pris = sista_pris
sista_pris = sista_pris + steg_langd
moms = temp_sista_pris * (momsprocent/100)
pris_med_moms = temp_sista_pris + moms
print(f" {temp_sista_pris:0.2f} {moms:0.2f} {pris_med_moms:0.2f}")
print('\n')

Permalänk
Medlem
Skrivet av merdan:

Jag vill mata in första och sista pris som gränser och skriva ut efter varje steg_langd pris med moms. Det som ska skrivas ut i sista delen är att första värdet skulle vara större än det sista. jag gjorde samma sak med while men kunde inte lyckas. När jag kör programmet på första while skrivs sista raden två gånger och jag förstår inte varför. t.ex steg_längd är 0.1, momsprocent är 10, första värdet är 10 och sista värdet är 11.
Sista raden blir två gånger 11, 2.75 och 13.75 och jag förstår inte varför programmet skriver sista raden. Tack

första_pris = float(input('Mata in första_pris: '))
sista_pris = float(input('Mata in sista_pris : '))
steg_langd = float(input('Mata in steg_langd: '))
momsprocent = float(input('Mata in momsprocent : '))
print (' Pris Moms Pris_med_moms ')
print ('-----------------------------------')
while första_pris <= sista_pris:
temp_första_pris = första_pris
första_pris = första_pris + steg_langd
moms = temp_första_pris * (momsprocent/100)
pris_med_moms = temp_första_pris + moms
print(f" {temp_första_pris:0.2f} {moms:0.2f} {pris_med_moms:0.2f}")
print('\n')
while första_pris > sista_pris:
temp_sista_pris = sista_pris
sista_pris = sista_pris + steg_langd
moms = temp_sista_pris * (momsprocent/100)
pris_med_moms = temp_sista_pris + moms
print(f" {temp_sista_pris:0.2f} {moms:0.2f} {pris_med_moms:0.2f}")
print('\n')

Noterade att det verkar gå att se någon form av indentering när jag citerar så tror jag förstår vad som pågår.

Du kör först en while-loop som skriver ut saker tills första_pris är större än sista_pris. Den loopen skriver ut det sista värdet i ditt exempel också eftersom första_pris == sista_pris och då kör loopen ett varv till innan den avslutar. Du behöver inte göra mer efter den loopen är klar men i din kod kör du en loop till som börjar där den första slutade och kör en runda till, därför får du dubbla utskrifter.

Du säger att momsen att betala på 11 kr när momsen är 10% är 2.75 men 10% av 11 är 1.10 så någonting är galet där, eller så har jag helt glömt hur moms fungerar...

För att slippa en del extravariabler inuti loopen kan du lägga ändringen av variabeln du jämför med i slutet enligt nedan.

while första_pris <= sista_pris: moms = första_pris * (momsprocent/100) pris_med_moms = första_pris + moms print(f" {första_pris:0.2f} {moms:0.2f} {pris_med_moms:0.2f}") print('\n') första_pris = första_pris + steg_langd

Vill du göra det ännu lite snyggare kan du skriva

första_pris += steg_langd

istället för

första_pris = första_pris + steg_langd

då dessa betyder samma sak.

Eftersom du använder dig av f-strings kan du, om du vill, t.o.m. lägga in beräkningar direkt inuti dina {} men då krävs nog en extravariabel utanför loopen för att det ska bli lite mer läsbart.

Jag kopierade din lösning och gjorde några småfixar i spoilern nedan, tror den gör ungefär vad du vill och kanske går att utgå ifrån. Ser att pygments spårade ur lite på f-strings men det bjuder jag på.

#Ta input från användaren första_pris = float(input('Mata in första_pris: ')) sista_pris = float(input('Mata in sista_pris : ')) steg_langd = float(input('Mata in steg_langd: ')) momsprocent = float(input('Mata in momsprocent : ')) #Ändra momsprocent till moms eftersom det är enklare att räkna med decimalformen #Momsen för ett givet pris är nu pris * moms moms = momsprocent / 100 #Lägg även till förändringsfaktor som variabel för att öka läsbarheten #Förändringsfaktor är t.ex. 1.10 när momsen är 10% och priset att betala #blir då pris * förändringsfaktor = pris att betala med momspåslag förändringsfaktor = 1 + moms #Skriv ut kolumnnamnen för tabellen print (' Pris Moms Pris_med_moms ') print ('-----------------------------------') #Eftersom vi inte vet i förväg hur många utskrifter som ska göras används en while-loop #while-loopen kör så länge första_pris inte är större än sista_pris. while första_pris <= sista_pris: print(f"{första_pris:0.2f} {första_pris*moms:0.2f} {första_pris*förändringsfaktor:0.2f}\n") första_pris += steg_langd

Dold text
Visa signatur

Primär: R9 3900X | ASUS X570-F Gaming | NH-D15 | 64GB@3200MHz | RTX 3080 10GB | Seasonic 850W | Fractal Define R6 |
Gamla bettan: i5 750@3.8GHz | 8GB | HD5770 | Corsair VS 550W | FD R2 |

Permalänk
Medlem

första_pris = float(input('Mata in första_pris: '))
sista_pris = float(input('Mata in sista_pris : '))
steg_langd = float(input('Mata in steg_langd: '))
momsprocent = float(input('Mata in momsprocent : '))

#Ändra momsprocent till moms eftersom det är enklare att räkna med decimalformen
#Momsen för ett givet pris är nu pris * moms
moms = momsprocent / 100

#Lägg även till förändringsfaktor som variabel för att öka läsbarheten
#Förändringsfaktor är t.ex. 1.10 när momsen är 10% och priset att betala
#blir då pris * förändringsfaktor = pris att betala med momspåslag
förändringsfaktor = 1 + moms

#Skriv ut kolumnnamnen för tabellen
print (' Pris Moms Pris_med_moms ')
print ('-----------------------------------')

#Eftersom vi inte vet i förväg hur många utskrifter som ska göras används en while-loop
#while-loopen kör så länge första_pris inte är större än sista_pris.
while första_pris <= sista_pris:
print(f"{första_pris:0.2f} {första_pris*moms:0.2f} {första_pris*förändringsfaktor:0.2f}\n")
första_pris += steg_langd
while första_pris > sista_pris:
print (f"{sista_pris:0.2f} {sista_pris*moms:0.2f} {sista_pris*förändringsfaktor:0.2f}\n")
sista_pris += steg_langd

Mina utmattningar blir inte som jag vill ( Se nedan; varför får jag två lika rad i slutet, de som är 15.00). Tack så mycket

10.00 1.00 11.00

10.50 1.05 11.55

11.00 1.10 12.10

11.50 1.15 12.65

12.00 1.20 13.20

12.50 1.25 13.75

13.00 1.30 14.30

13.50 1.35 14.85

14.00 1.40 15.40

14.50 1.45 15.95

15.00 1.50 16.50

15.00 1.50 16.50

@Daz:

Permalänk
Medlem
Skrivet av merdan:

Mina utmattningar blir inte som jag vill ( Se nedan; varför får jag två lika rad i slutet, de som är 15.00). Tack så mycket

Det händer för att du har lagt till en while-loop till i slutet av koden jag postade. Vad är det du tycker saknas i utmatningen från koden jag postade som gör att en loop till behövs? Har du testat att köra koden utan ändringar för att se hur den fungerar?

Visa signatur

Primär: R9 3900X | ASUS X570-F Gaming | NH-D15 | 64GB@3200MHz | RTX 3080 10GB | Seasonic 850W | Fractal Define R6 |
Gamla bettan: i5 750@3.8GHz | 8GB | HD5770 | Corsair VS 550W | FD R2 |

Permalänk
Medlem

Jag har lagt en while loop till eftersom jag vill att det ska funka om första pris är större än sista pris men den här gången beräkningar ska utgå från sista priset. Se nedan:

print (f"{sista_pris:0.2f} {sista_pris*moms:0.2f} {sista_pris*förändringsfaktor:0.2f}\n")
sista_pris += steg_langd

uppgiften är så. Man ska göra beräkningar för först att: första priset <= sista priset och även första priset > sista priset
Tack för hjälpen, ursäkta att det är inte så tydligt.

@Daz:

Permalänk
Medlem
Skrivet av merdan:

Jag har lagt en while loop till eftersom jag vill att det ska funka om första pris är större än sista pris men den här gången beräkningar ska utgå från sista priset. Se nedan:

print (f"{sista_pris:0.2f} {sista_pris*moms:0.2f} {sista_pris*förändringsfaktor:0.2f}\n")
sista_pris += steg_langd

uppgiften är så. Man ska göra beräkningar för först att: första priset <= sista priset och även första priset > sista priset
Tack för hjälpen, ursäkta att det är inte så tydligt.

@Daz:

Där ser man, problemet kvarstår dock att om båda looparna körs efter varandra så kommer du att få dubbla utskrifter. Du behöver göra någon slags urval för att bestämma vilken loop som ska köras i det fallet. Måste du specifikt ha två loopar eller är det ok att göra något i stil med nedan?

start = min(första_pris, sista_pris) stop = max(första_pris, sista_pris while start <= stop: <kod här> start += steg_langd

Vad handlar kapitlet ni jobbar med om? Vad är det egentligen för krav som ska uppfyllas?

Visa signatur

Primär: R9 3900X | ASUS X570-F Gaming | NH-D15 | 64GB@3200MHz | RTX 3080 10GB | Seasonic 850W | Fractal Define R6 |
Gamla bettan: i5 750@3.8GHz | 8GB | HD5770 | Corsair VS 550W | FD R2 |

Permalänk
Medlem

Tack för hjälpen, jag tror att jag löste problemet. Det som vi kör handlar om while, for, if/else. När jag byte plats på while loop funkade.
@Daz:

Permalänk
Medlem
Skrivet av merdan:

Tack för hjälpen, jag tror att jag löste problemet. Det som vi kör handlar om while, for, if/else. När jag byte plats på while loop funkade.
@Daz:

Får du inte samma fel med dubbelutskrifter om du anger ett mindre värde på sista_pris till en början när du byter plats på looparna?

Visa signatur

Primär: R9 3900X | ASUS X570-F Gaming | NH-D15 | 64GB@3200MHz | RTX 3080 10GB | Seasonic 850W | Fractal Define R6 |
Gamla bettan: i5 750@3.8GHz | 8GB | HD5770 | Corsair VS 550W | FD R2 |

Permalänk
Medlem

Nej Jag fick faktisk inte samma fel. Jag vet inte varför men det funkade. Tackar.
@Daz:

Permalänk
Medlem

Ju, jag fick samma fel, nu testade jag igen. Jag vet inte hur jag kan lösa problemet.

@Daz:

Permalänk
Medlem

I den uppgiften jag har, står det att båda villkor ska vara uppfyllda det vill säga man ska mata in första pris större eller lika med sista pris och sista pris större än första pris t.ex.
mata in första pris: 10
mata in sista pris: 12
mata in steglängd: 0.1
momsprocent: 10

mata in första pris: 12
mata in sista pris: 10
mata in steglängd: 0.1
momsprocent: 10

Dessutom finns det olika momsprocent och steglängd (koden ska funka för dem också), steglängd 0.1, 0.3 m.m och procent 13, 25 m.m.
Tackar.

@Daz:

Permalänk
Medlem

Tack för hjälpen, den sista inlägg funkade faktisk och gjorde vad jag ville. Tusen tack:)
@Daz:

Permalänk
Medlem

listor

Mata in antalet dagar: 8
Mata in undre gräns: 14
Mata in övre gräns: 29

Temperaturer:
Tid Dag 1 Dag 2 Dag 3 Dag 4 Dag 5 Dag 6 Dag 7 Dag 8
07:00 17.4 21.9 20.4 27.5 27.0 22.1 24.8 28.5
12:00 28.6 17.0 25.6 24.7 27.3 27.5 23.4 19.4
19:00 24.0 24.8 20.0 15.3 26.2 23.1 18.7 28.5
02:00 24.4 19.4 17.1 25.2 28.3 25.9 17.3 15.7

Hej!

Jag behöver hjälp med en uppgift som ska skriva ut slumpvis temperatur med övre- och undergräns för antal veckodagar som jag matade in. Ett körexempel har jag skickar, se ovan. Jag är jättetacksam om du guidar mig.

Hälsningar
Merd

@Daz:

Permalänk
Medlem

Hej!

Jag ber om ursäkt eftersom jag stör dig.
Skulle du kunna hjälpa mig med ovan skrivna koden för att jag inte kunde fixa.

import numpy
from random import randint
from random import uniform

dagar = int(input ("Mata in vecko dagar: "))
ovre_grans = float(input ("Mata in övregräns: "))
undre_grans = float(input ("Mata in undergräns: "))
listor_tid = ["07:00", "12:00", "19:00", "02:00"]

listor_temp = []
dagar_temp = []
maxValueDay= 0
maxValue = 0
tempMaxValue = 0

newDict = dict()
mapDict = dict()

summa = 0
medeltemp = 0

if undre_grans <= ovre_grans:
print('\n')
print("Tid", " ", end ='\t')
for k in numpy.arange(dagar):
print("Dag", k+1, " ", end =' ')
print('\n')
for j in listor_tid:
print(j, end ='\t')
for i in numpy.arange(dagar):
temp_random = round(uniform (undre_grans, ovre_grans),1)
print(temp_random,end='\t')
print('\n')
if tempMaxValue <= temp_random:
tempMaxValue = temp_random
newDict[i+1] = tempMaxValue
mapDict[(i+1, j)] = temp_random

print('\n')

maxValueDay = max(newDict,key=newDict.get)
maxValue = newDict[maxValueDay]
for j in listor_tid:
summa = summa + mapDict[(maxValueDay, j)]
medeltemp = summa /4
print("Varmaste dagen: ", "Dag",maxValueDay,"has max temperature value as:",maxValue)
print("Medeltemperatur är: ", f"{medeltemp:0.1f}")

Uppgiften är att mata in antal dagar och ta random temperatur för 4 olika tider sedan ta varmaste dag och medeltemperatur för det. Till sist skriva ut temperaturer för den varmaste dagen. Min kod fungerar inte för medeltemperatur och den skriver inte ut temperaturen för varmaste dagen.

Mata in antalet dagar: 6
Mata in undre gräns: 10
Mata in övre gräns: 31

Temperaturer:
Tid Dag 1 Dag 2 Dag 3 Dag 4 Dag 5 Dag 6
07:00 30.6 18.5 29.0 11.7 11.5 28.9
12:00 21.9 26.2 17.3 23.0 17.4 29.8
19:00 15.3 16.5 11.1 28.7 11.8 22.0
02:00 17.1 24.4 16.0 26.1 30.8 21.4

Varmaste dagen: Dag 6, medeltemp: 25.5
Kl 07:00 12:00 19:00 02:00
28.9 29.8 22.0 21.4

@Daz:

Permalänk
Medlem

Hjälp med kod

Hej!

Jag ber om ursäkt eftersom jag stör dig.
Skulle du kunna hjälpa mig med koden som är skriven nedan för att jag inte kunde fixa.

import numpy
from random import randint
from random import uniform

dagar = int(input ("Mata in vecko dagar: "))
ovre_grans = float(input ("Mata in övregräns: "))
undre_grans = float(input ("Mata in undergräns: "))
listor_tid = ["07:00", "12:00", "19:00", "02:00"]

listor_temp = []
dagar_temp = []
maxValueDay= 0
maxValue = 0
tempMaxValue = 0

newDict = dict()
mapDict = dict()

summa = 0
medeltemp = 0

if undre_grans <= ovre_grans:
print('\n')
print("Tid", " ", end ='\t')
for k in numpy.arange(dagar):
print("Dag", k+1, " ", end =' ')
print('\n')
for j in listor_tid:
print(j, end ='\t')
for i in numpy.arange(dagar):
temp_random = round(uniform (undre_grans, ovre_grans),1)
print(temp_random,end='\t')
print('\n')
if tempMaxValue <= temp_random:
tempMaxValue = temp_random
newDict[i+1] = tempMaxValue
mapDict[(i+1, j)] = temp_random

print('\n')

maxValueDay = max(newDict,key=newDict.get)
maxValue = newDict[maxValueDay]
for j in listor_tid:
summa = summa + mapDict[(maxValueDay, j)]
medeltemp = summa /4
print("Varmaste dagen: ", "Dag",maxValueDay,"has max temperature value as:",maxValue)
print("Medeltemperatur är: ", f"{medeltemp:0.1f}")

Uppgiften är att mata in antal dagar och ta random temperatur för 4 olika tider sedan ta varmaste dag och medeltemperatur för det. Till sist skriva ut temperaturer för den varmaste dagen. Min kod fungerar inte för medeltemperatur och den skriver inte ut temperaturen för varmaste dagen.

Mata in antalet dagar: 6
Mata in undre gräns: 10
Mata in övre gräns: 31

Temperaturer:
Tid Dag 1 Dag 2 Dag 3 Dag 4 Dag 5 Dag 6
07:00 30.6 18.5 29.0 11.7 11.5 28.9
12:00 21.9 26.2 17.3 23.0 17.4 29.8
19:00 15.3 16.5 11.1 28.7 11.8 22.0
02:00 17.1 24.4 16.0 26.1 30.8 21.4

Varmaste dagen: Dag 6, medeltemp: 25.5
Kl 07:00 12:00 19:00 02:00
28.9 29.8 22.0 21.4

Permalänk
Medlem
Skrivet av merdan:

Hej!

Jag ber om ursäkt eftersom jag stör dig.
Skulle du kunna hjälpa mig med koden som är skriven nedan för att jag inte kunde fixa.

import numpy
from random import randint
from random import uniform

dagar = int(input ("Mata in vecko dagar: "))
ovre_grans = float(input ("Mata in övregräns: "))
undre_grans = float(input ("Mata in undergräns: "))
listor_tid = ["07:00", "12:00", "19:00", "02:00"]

listor_temp = []
dagar_temp = []
maxValueDay= 0
maxValue = 0
tempMaxValue = 0

newDict = dict()
mapDict = dict()

summa = 0
medeltemp = 0

if undre_grans <= ovre_grans:
print('\n')
print("Tid", " ", end ='\t')
for k in numpy.arange(dagar):
print("Dag", k+1, " ", end =' ')
print('\n')
for j in listor_tid:
print(j, end ='\t')
for i in numpy.arange(dagar):
temp_random = round(uniform (undre_grans, ovre_grans),1)
print(temp_random,end='\t')
print('\n')
if tempMaxValue <= temp_random:
tempMaxValue = temp_random
newDict[i+1] = tempMaxValue
mapDict[(i+1, j)] = temp_random

print('\n')

maxValueDay = max(newDict,key=newDict.get)
maxValue = newDict[maxValueDay]
for j in listor_tid:
summa = summa + mapDict[(maxValueDay, j)]
medeltemp = summa /4
print("Varmaste dagen: ", "Dag",maxValueDay,"has max temperature value as:",maxValue)
print("Medeltemperatur är: ", f"{medeltemp:0.1f}")

Uppgiften är att mata in antal dagar och ta random temperatur för 4 olika tider sedan ta varmaste dag och medeltemperatur för det. Till sist skriva ut temperaturer för den varmaste dagen. Min kod fungerar inte för medeltemperatur och den skriver inte ut temperaturen för varmaste dagen.

Mata in antalet dagar: 6
Mata in undre gräns: 10
Mata in övre gräns: 31

Temperaturer:
Tid Dag 1 Dag 2 Dag 3 Dag 4 Dag 5 Dag 6
07:00 30.6 18.5 29.0 11.7 11.5 28.9
12:00 21.9 26.2 17.3 23.0 17.4 29.8
19:00 15.3 16.5 11.1 28.7 11.8 22.0
02:00 17.1 24.4 16.0 26.1 30.8 21.4

Varmaste dagen: Dag 6, medeltemp: 25.5
Kl 07:00 12:00 19:00 02:00
28.9 29.8 22.0 21.4

Code-taggar är din vän, är omöjligt att läsa någonting utan dom när det är så många if, for etc.

Känns som att dela upp det hela i funktioner hade varit en bra idé för att t.ex. ha en funktion som sköter medeltalsberäkningen. Har ni lärt er sånt ännu?

Är det ett krav att använda numpy.arange? Känns lite overkill när det, antar jag, alltid är en int som matas in av användaren.

Ser ut som att du alltid bara jämför tempMaxValue mot den sista temp_random varje dag men är lite svårt att se utan code-taggar.

Visa signatur

Primär: R9 3900X | ASUS X570-F Gaming | NH-D15 | 64GB@3200MHz | RTX 3080 10GB | Seasonic 850W | Fractal Define R6 |
Gamla bettan: i5 750@3.8GHz | 8GB | HD5770 | Corsair VS 550W | FD R2 |

Permalänk
Medlem

Tack

Vi har lärt oss att använda funktioner. men hur många funktioner ska jag använda, hur ska jag tänka?.
Jag tror att du har förstått mitt problem.
Tack för hjälpen, jag ska försöka själv och kolla om jag kan fixa problemet.

@Daz:

Permalänk
Medlem
Skrivet av merdan:

Vi har lärt oss att använda funktioner. men hur många funktioner ska jag använda, hur ska jag tänka?.
Jag tror att du har förstått mitt problem.
Tack för hjälpen, jag ska försöka själv och kolla om jag kan fixa problemet.

@Daz:

En tanke är väl att dela upp det hela i tydliga funktioner som gör exakt en sak eller fyller ett enskilt syfte. Exempelvis kan det vara att beräkna medeltemperaturen givet datan du får fram.

En annan sak som går att få ut till en funktion är t.ex. att du frågar användaren om saker och det går att bryta ut. Ett exempel är nedan för att samla in antalet dagar.

def collect_days(): asking = True while asking: try: dagar = int(input("Mata in antal veckodagar: ")) asking = False except ValueError: print("Måste vara ett heltal") return dagar

sedan kan man enkelt skriva

dagar = collect_days()

vilket ser snyggare ut i t.ex. en main().

Visa signatur

Primär: R9 3900X | ASUS X570-F Gaming | NH-D15 | 64GB@3200MHz | RTX 3080 10GB | Seasonic 850W | Fractal Define R6 |
Gamla bettan: i5 750@3.8GHz | 8GB | HD5770 | Corsair VS 550W | FD R2 |

Permalänk
Medlem

Tack för hjälpen, jag ska prova detta.
Hälsningar
Merdan
@Daz:

Permalänk
Medlem

Median

import numpy
import statistics
from random import randint
from random import uniform

dagar = int(input ("Mata in vecko dagar: "))
ovre_grans = float(input ("Mata in övregräns: "))
undre_grans = float(input ("Mata in undergräns: "))
listor_tid = ["07:00", "12:00", "19:00", "02:00"]

listor_temp = []
dagar_temp = []
listor_value = []
maxValueDay= 0
maxValue = 0
newDict = dict()
mapDict = dict()

if undre_grans <= ovre_grans:
print('\n')
print("Tid", " ", end ='\t')
for k in numpy.arange(dagar):
print("Dag", k+1, " ", end =' ')
print('\n')

def mapDailyData(listor_tid, dagar):
tempMaxValue =0
mediantemp = 0
for j in listor_tid:
print(j, end='\t')
for i in numpy.arange(dagar):
temp_random = round(uniform(undre_grans, ovre_grans), 1)
print(temp_random, end='\t')
if tempMaxValue <= temp_random:
tempMaxValue = temp_random
newDict[i+1] = tempMaxValue
mapDict[(i+1,j)]=temp_random

print('\n')
#def median_temp(mapDict, temp_random, listor_tid):
# mediantemp = 0

mapDailyData(listor_tid,dagar)
maxValueDay = max(newDict, key=newDict.get)

def medel_temp(mapDict, maxValueDay, listor_tid):
medeltemp = 0
summa = 0
maxValue = 0
for j in listor_tid:
summa = summa + mapDict[(maxValueDay, j)]
maxValue = mapDict[maxValueDay,j]
listor_value.append(maxValue)
medeltemp = summa/4
return medeltemp

medelTemp = medel_temp(mapDict,maxValueDay,listor_tid)

print("Varmaste dagen är: ", "Dag" , maxValueDay)
print("Medeltemperatur är: ", f"{medelTemp:0.1f}")
print("Varmaste dagen värdena: ", listor_value)

Hej! Det som jag gjorde funkar som jag vill men jag behöver även hitta medianen för alla temp_random värdena. Jag har inte lyckats med det. Om du kan hjälpa mig är jag jätte tacksam. Tack så mycket.

@Daz: