Min första "riktiga" kodsnutt i Python, tips ock kritik sökes

Trädvy Permalänk
Medlem
Plats
Falun
Registrerad
Sep 2008

Min första "riktiga" kodsnutt i Python, tips ock kritik sökes

Jag håller på att försöka lära mig lite Python, dels för att det är ett roligt språk och dels för att jag ska läsa scriptprogrammering i februari nästa år, så jag tänkte kasta ut den första "riktiga" koden jag lyckats knacka ihop och mottager gärna tips samt konstruktiv kritik. Jag har ingen tidigare erfarenhet av programmering förutom visual basic som jag läste på gymnasiet för 7 år sedan, läser även C# för tillfället.

Håll till godo!

Jag vet att den är "slafsig" i brist på bättre uttryck, men det är ju också därför jag postar.

Jag letar speciellt efter bra tips på hur man kan begränsa input till en given grupp karaktärer som accepteras som korrekta input's, dvs bara 0 - 9 accepteras.

__author__ = 'Zoap' def function(): import math yes = "y" or "Y" no = "n" or "N" inv = "Invalid input" invx = "Number to search for must be a number!" invs = "Length must be a number!" space = "No spacing allowed!" number_list = [] print() print("This program allows you to search for the number of possible combinations of a pin number of length x, " "given that you know one of the digits") print() x = str(input("Input number to search for: ")) if x == '': print() print(invx) function() return elif ' ' in x: print() print(space) function() return else: print() def function2(): s = str(input("Input length of pin code: ")) stop = int((math.pow(10, int(s)))) if s == '': print() print(invs) print() function2() return elif ' ' in s: print() print(space) print() function2() return elif int(s) > 7: print() print("Length can not be more than 7 digits!") print() function2() return elif stop < int(x): print() print("Length of pin makes the number to search for bigger than the possible number of variations!") print() function2() return else: # For every integer in range add int to list and convert to string for i in range(0, (stop + 1)): number_list.append(str(i)) print() # For every str in list containing x, count x x_numbers = [a for a in number_list if x] # Percent of total numbers in range containing digit x percent = len(x_numbers) / (stop / 100) if int(x) >= 10: print("There are a total of " + str(len(x_numbers)) + " numbers between 0 and " + str(stop) + " containing the number " + x) print() print("That is a total of " + str("%.2f" % percent) + "%" " of all numbers between 0 and " + str(stop)) elif int(len(x_numbers)) == 1: print("There are a total of " + str(len(x_numbers)) + " number between 0 and " + str(stop) + " containing the digit " + x) print() print("That is a total of " + str("%.2f" % percent) + "%" " of all numbers between 0 and " + str(stop)) else: print("There are a total of " + str(len(x_numbers)) + " numbers between 0 and " + str(stop) + " containing the digit " + x) print() print("That is a total of " + str("%.2f" % percent) + "%" " of all numbers between 0 and " + str(stop)) def function3(): print() choice = input("Run again? y/n: ") if choice == yes: print() function() return elif choice == no: exit() else: print() print(inv) function3() return while True: function3() while True: function2() while True: function()

"Life is a sexually transmitted disease and the mortality rate is 100%." - R. D. Laing

Trädvy Permalänk
Medlem
Plats
Götet, typ
Registrerad
Okt 2004
Skrivet av Zoap:

Jag håller på att försöka lära mig lite Python, dels för att det är ett roligt språk och dels för att jag ska läsa scriptprogrammering i februari nästa år, så jag tänkte kasta ut den första "riktiga" koden jag lyckats knacka ihop och mottager gärna tips samt konstruktiv kritik. Jag har ingen tidigare erfarenhet av programmering förutom visual basic som jag läste på gymnasiet för 7 år sedan, läser även C# för tillfället.

Håll till godo!

Jag vet att den är "slafsig" i brist på bättre uttryck, men det är ju också därför jag postar.

Jag letar speciellt efter bra tips på hur man kan begränsa input till en given grupp karaktärer som accepteras som korrekta input's, dvs bara 0 - 9 accepteras.

__author__ = 'Zoap' def function(): import math yes = "y" or "Y" no = "n" or "N" inv = "Invalid input" invx = "Number to search for must be a number!" invs = "Length must be a number!" space = "No spacing allowed!" number_list = [] print() print("This program allows you to search for the number of possible combinations of a pin number of length x, " "given that you know one of the digits") print() x = str(input("Input number to search for: ")) if x == '': print() print(invx) function() return elif ' ' in x: print() print(space) function() return else: print() def function2(): s = str(input("Input length of pin code: ")) stop = int((math.pow(10, int(s)))) if s == '': print() print(invs) print() function2() return elif ' ' in s: print() print(space) print() function2() return elif int(s) > 7: print() print("Length can not be more than 7 digits!") print() function2() return elif stop < int(x): print() print("Length of pin makes the number to search for bigger than the possible number of variations!") print() function2() return else: # For every integer in range add int to list and convert to string for i in range(0, (stop + 1)): number_list.append(str(i)) print() # For every str in list containing x, count x x_numbers = [a for a in number_list if x] # Percent of total numbers in range containing digit x percent = len(x_numbers) / (stop / 100) if int(x) >= 10: print("There are a total of " + str(len(x_numbers)) + " numbers between 0 and " + str(stop) + " containing the number " + x) print() print("That is a total of " + str("%.2f" % percent) + "%" " of all numbers between 0 and " + str(stop)) elif int(len(x_numbers)) == 1: print("There are a total of " + str(len(x_numbers)) + " number between 0 and " + str(stop) + " containing the digit " + x) print() print("That is a total of " + str("%.2f" % percent) + "%" " of all numbers between 0 and " + str(stop)) else: print("There are a total of " + str(len(x_numbers)) + " numbers between 0 and " + str(stop) + " containing the digit " + x) print() print("That is a total of " + str("%.2f" % percent) + "%" " of all numbers between 0 and " + str(stop)) def function3(): print() choice = input("Run again? y/n: ") if choice == yes: print() function() return elif choice == no: exit() else: print() print(inv) function3() return while True: function3() while True: function2() while True: function()

Jag är ingen supererfaren programmerare, men det var ett par saker jag tänkte på direkt.
Jag tycker inte du ska göra en metod som kör alltihopa som du gjort utan ha det i separata metorer i första nivån och sedan kickar du igång dem antingen i main eller rakt av bara i scriptet.

Kalla inte metoder eller functioner för function, function1 function2 etc det är en väldigt dålig idé. Ge dem namn so mär goda ledtrådar till vad de utför.

Se till så att metoder inte gör för mycket saker, det är lättast att först hur ett program jobbar om man ser varje steg på ett bra sätt.

Kom ihåg detta: Dina program ska vara lätta att läsa, dels för att andra kan behöva läsa dem, men i nuläget även för att DU ska läsa dem. Om ett halvår kommer du på att du vill göra något på ett vis du gjorde i ett gammalt script, då är det bra om du kan fatta vad som hänt för det har du inte i huvudet hela tiden utan glömmer efter ett par månader så då ska du börja från scratch och måste fatta ditt gamla script.

Om du vill ha en enter före lite text kan du skriva \n i texten: print("\nHello world")

/M

Trädvy Permalänk
Medlem
Plats
Luleå
Registrerad
Sep 2009

Hade som ovan delat upp programmet i olika funktioner.
Av givna anledningar och även att det blir smidigare för dig att loopa vid felaktig input.
Nu är jag inget ess på det här men kanske hjälper dig något.

i stil med:

def menutext(): #only made for cleaner mainfunc. print"loads of menu text" def somemathfunction(n): #magic happens math def main(): while True: menutext() try: knownNumber = int(raw_input("Please enter your known digit: ") if knownNumber == 4 : #or similar. do some func ... else: handle the error and print error message.

| i7 920 C0 @ 3,63| GTX 580 + EK CU| CM 690 | EK HF Acetal |Samsung 830 120+TG 120 | AX850 | Asus Rampage 3 Formula|12GB Corsair |
FoldingRig1: i5 2320, 8GB ram, Win7
FoldingRig2: i7 920, 12GB ram, Win7
http://folding.extremeoverclocking.com/user_summary.php?s=&u=530039

Trädvy Permalänk
Medlem
Plats
Falun
Registrerad
Sep 2008

Nu har jag "förfinat" koden lite grann iaf, skalat av ca 20 rader onödig kod och optimerat urvalen för mina inputs så att programmet inte kraschar pga felaktiga inputs, jag känner ganska starkt för att optimera kod så att den ska vara så foolproof som möjligt i användarens händer.

Ta gärna och krascha den och återkom med vad som behöver lösas.

Tar samtidigt tillfället i akt och frågar om det är någon som vet om det går att formatera strings i Python liknande formateringen i C#?
Exempel: 100000 formaterat i c# med hjälp av {0:N0} ger 100 000 istället.

Pastebin

"Life is a sexually transmitted disease and the mortality rate is 100%." - R. D. Laing

Trädvy Permalänk
Medlem
Plats
Uppsala
Registrerad
Dec 2008

@Zoap:

Det funkar som du skrivit, men vanligtvis brukar man lägga sina funktioner på "global" nivå. Det blir mer överskådligt då. Jag förstår att du i exempelvis i PinLength vill ha tillgång till x från Search, men då kan det vara bättre att skicka x som parameter.

def PinLength(x): ... def Search(): x = ... PinLength(x)

Det har fördelen att man kan anropa funktionen från flera olika ställen, med olika parametrar.

Sedan har du nog missförstått hur operatorn or kan användas. Din test

yes = "Y" or "y" .... if choice is yes:

kommer inte bete som som du hoppas att den skall göra. Testa att göra tilldelningen av yes i interpretatorn och skriv ut resultatet.

Trädvy Permalänk
Medlem
Plats
Falun
Registrerad
Sep 2008

Postade min kod på en annan sida och fick supermycket bra feedback, koden är nu jämte version 1 som jag började tråden med mycket bättre. Finns fortfarande saker att göra dock, ska nog lägga alla strings i en dict och använda output_style() för att hämta och skriva ut dessa.

Newbiecode v1.3

"Life is a sexually transmitted disease and the mortality rate is 100%." - R. D. Laing

Trädvy Permalänk
Medlem
Plats
Uppsala
Registrerad
Dec 2008

@Zoap:

Dina loopar är onödigt kompllcerade. Du kan göra return mitt i funktionen och bli av med en del kontrollkod. Sedan undar jag varför du stoppar alla texter i en variabel innan de skrivs ut? Lite kortare kan det se ut så här:

def run_again(): while True: output_style("Run again? y/n: ") choice = input() if choice in ["y", "Y"]: return True elif choice in ["n", "N"]: return False else: output_style("Invalid input")

Trädvy Permalänk
Medlem
Plats
Falun
Registrerad
Sep 2008
Skrivet av Ingetledigtnamn:

Du kan göra return mitt i funktionen och bli av med en del kontrollkod. Sedan undar jag varför du stoppar alla texter i en variabel innan de skrivs ut?

Varför jag stoppade in texterna i variabler berodde på okunskap helt enkelt, som sagt så har jag ju tänkt bygga en dictionary senare med all text så att all text är mer centraliserad och därmed enklare att göra förändringar och då kommer ju alla variabler försvinna iaf, aka löser det senare.

Citat:

Dina loopar är onödigt kompllcerade.

Än en gång okunskapen som speglar sig, jag antar att jag inte riktigt kommit in i tänket än, ska titta över dem och experimentera lite.

"Life is a sexually transmitted disease and the mortality rate is 100%." - R. D. Laing