Reputation: 1100
I'm quite new to programming and I'm just learning Python. The code I've written below is for a program that let's you input a grade over a scale (14/20 or 70 over 100 for example), and then gives you a grade from A to E. Basically what I want to know is if there is a way to "take out" the integers of the list rather than taking them one by one and multiply them by 10, 100 and so on.
I summarize : I want grade ["14 sur 20"] to become a = 14 and b =20 without having to write all the code I wrote.
PS : I guess my code is way too long, but I'm new to Python and I don't have enough knowledge yet to make it shorter, so don't be too hard ;)
import os
grade = input ("Entrez votre note :")
deter = []
redet = []
i = z = a = b = x = 0
while i < len(grade):
if grade[i] == "s" and grade[i+1] == "u" and grade [i+2] == "r" : #checking if the grade is written as " x sur y"
while z < i-1 : #building a list for the grade
deter.append (grade[z])
z += 1
z += 5 #jumping to the scale
while z < len(grade) : #building a list for the scale
redet.append (grade[z])
z += 1
elif grade[i] == "/" : #means grade is written as "x/y"
while z < i : #building a list for the grade
deter.append (grade[z])
z += 1
z += 1 #jumping to the scale
while z < len(grade) : #building a list for the scale
redet.append (grade[z])
z += 1
i += 1
redet = list (map(float, redet)) #converting to integers
deter = list (map(float, deter))
if len(deter)>1 :
y = 10**(len(deter)-1)
else:
y = 1
while x < len(deter) : #making variables
a = a + deter[x]*y
x += 1
y /= 10
x = 0
if len(redet)>1 :
y = 10**(len(redet)-1)
else :
y = 1
while x < len(redet) : #making variables
b = b + redet[x]*y
x += 1
y /= 10
grade = a/b
if grade >= 0.8 :
print("A")
elif grade >= 0.6 :
print("B")
elif grade >= 0.5 :
print("C")
elif grade >= 0.4 :
print("D")
elif grade <= 0.4 :
print("E")
os.system ("pause")
Upvotes: 2
Views: 1158
Reputation: 879611
You could use re.split to split strings like 14 sur 20
or 14/20
into two pieces.
And you could use bisect.bisect to convert the scores into letter grades.
import bisect
import re
def lettergrade(score, breakpoints = [40, 50, 60, 80], grades = 'EDCBA'):
"""
>=80 -> A
>=60 -> B
>=50 -> C
>=40 -> D
else -> E
"""
i = bisect.bisect(breakpoints, score)
return grades[i]
grade = input("Entrez votre note : ")
a, b = map(int, re.split(r'sur|/', grade))
print(lettergrade(100.0*a/b))
An explanation of the regex pattern:
`re.split(r'sur|/', grade)` splits the string `grade` into a list of strings. It splits on the regex pattern `r'sur|/'`. This regex pattern matches the literal string `sur` or the forward-slash `/`. The `|` is the regex syntax for "or".
The r
in front of 'sur|/'
is Python syntax which causes Python to interpret 'sur|/'
as a raw string. This affects the way backslashes are interpreted. The docs for the re module explain its use this way:
Regular expressions use the backslash character (
'\'
) to indicate special forms or to allow special characters to be used without invoking their special meaning. This collides with Python’s usage of the same character for the same purpose in string literals; for example, to match a literal backslash, one might have to write'\\\\'
as the pattern string, because the regular expression must be\\
, and each backslash must be expressed as\\
inside a regular Python string literal.The solution is to use Python’s raw string notation for regular expression patterns; backslashes are not handled in any special way in a string literal prefixed with
'r'
. Sor"\n"
is a two-character string containing'\'
and'n'
, while"\n"
is a one-character string containing a newline. Usually patterns will be expressed in Python code using this raw string notation.
For the full story on raw strings, see the language reference doc.
Although in this case the raw string r'sur|/'
is the same as ordinary string 'sur|/'
, it is perhaps a good practice to always make regex patterns with raw strings. It does not hurt in this case, and it definitely helps in other cases.
Since re.split
returns a list of strings, map(int, ...)
is used to convert the strings into ints
:
In [37]: grade = '14 sur 20'
In [38]: re.split(r'sur|/', grade)
Out[38]: ['14 ', ' 20']
In [39]: map(int, re.split(r'sur|/', grade))
Out[39]: [14, 20]
Upvotes: 5
Reputation: 17981
def printLetterGrade(rawGrade):
grade = rawGrade/20
if grade >= 0.8 :
print("A")
elif grade >= 0.6 :
print("B")
elif grade >= 0.5 :
print("C")
elif grade >= 0.4 :
print("D")
elif grade <= 0.4 :
print("E")
rawGrade = int(input ("Entrez votre note entre 1 et 20:"))
printLetterGrade(rawGrade)
IIRC the french grading scale always has 20 as the base, so just tell them to input their grade and no base, then you can accept the input that you wanted in the first place.
Upvotes: 0
Reputation: 113988
a,b = map(int,input ("Entrez votre note :").lower().split("sur"))
Assuming that the input matches what you say it will, that should work fine.
Upvotes: 0
Reputation: 137594
This might be useful:
>>> s = "15 over 20"
>>> s.split()
['15', 'over', '20']
>>> [int(x) for x in s.split()]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: 'over'
>>> [int(x) for x in s.split() if x.isdigit()]
[15, 20]
Upvotes: 0