I'm trying to code the question in the image above but I only know how to use if else and for, while loop.
Can't figure out how to use a loop for this so I tried if else, but ended up with 100+ lines just doing height < 155.
Can it be done using a loop?
This is my code, I stopped at height<155 due to the length:
height = float(input('Enter height measurement (cm): '))
chest = float(input('Enter Chest Measurement (cm): '))
waist = float(input('Enter waist measurement (cm): '))
if height < 155:
if chest < 80:
if waist < 70:
print('You are size 1 (best fit)')
elif chest >= 80 and chest < 88:
if waist <70:
print('You are size 2 (Regular fit)')
elif waist >= 76 and waist < 84:
print('You are size 3 (Relaxed fit)')
elif waist >= 84 and waist < 92:
print('You are size 4 (Relaxed fit)')
elif waist >= 92 and waist < 100:
print('You are size 5 (Relaxed fit)')
elif waist >= 100 and waist < 108:
print('You are size 6 (Relaxed fit)')
elif waist >= 108 and waist < 116:
print('You are size 7 (Relaxed fit)')
elif waist >= 116:
print('You are size 8 (Relaxed fit)')
elif chest >= 88 and chest < 96:
if waist < 70:
print('You are size 3 (Regular fit)')
elif waist >= 84 and waist < 92:
print('You are size 4 (Relaxed fit)')
elif waist >= 92 and waist < 100:
print('You are size 5 (Relaxed fit)')
elif waist >= 100 and waist < 108:
print('You are size 6 (Relaxed fit)')
elif waist >= 108 and waist < 116:
print('You are size 7 (Relaxed fit)')
elif waist >= 116:
print('You are size 8 (Relaxed fit)')
elif chest >= 96 and chest < 104:
if waist < 70:
print('You are size 4 (Regular fit)')
elif waist >= 92 and waist < 100:
print('You are size 5 (Relaxed fit)')
elif waist >= 100 and waist < 108:
print('You are size 6 (Relaxed fit)')
elif waist >= 108 and waist < 116:
print('You are size 7 (Relaxed fit)')
elif waist >= 116:
print('You are size 8 (Relaxed fit)')
elif chest >= 104 and chest < 112:
if waist < 70:
print('You are size 5 (Regular fit)')
elif waist >= 100 and waist < 108:
print('You are size 6 (Relaxed fit)')
elif waist >= 108 and waist < 116:
print('You are size 7 (Relaxed fit)')
elif waist >= 116:
print('You are size 8 (Relaxed fit)')
elif chest >= 112 and chest < 120:
if waist < 70:
print('You are size 6 (Regular fit)')
elif waist >= 108 and waist < 116:
print('You are size 7 (Relaxed fit)')
elif waist >= 116:
print('You are size 8 (Relaxed fit)')
elif chest >= 120 and chest < 128:
if waist < 70:
print('You are size 7 (Regular fit)')
elif waist >= 116:
print('You are size 8 (Relaxed fit)')
elif chest >= 128:
if waist >=116:
print('You are size 8 (Regular fit)')
else:
print('You are size 8 (Relaxed fit)')
When you look at the table, you can see a regular pattern. For instance, the height ranges are all of size 5 (155-160, 160-165, ...), except the "catch-all" at either extreme.
So you can calculate the corresponding size with a formula. For instance for height, we can first subtract 145 and then divide by 5. Then convert anything that is less than 1 to 1, and anything that is greater than 8 to 8.
For the chest measure, the steps are 8 wide. Similarly for the waist measure, the steps are 8 wide, but there is one exception: the waist range for size 2 is 70-76 and thus only spans 6 units, not 8. It would have been nice if that range had been 68-76. So there is special care needed to deal with that irregularity, so that 68 and 69 will translate to waist size 1 and not to size 2.
Secondly, the fit can be derived as follows:
Sort the three sizes (for height, chest and waist) and get the greatest value: that is the size to report. Then find the first occurrence of that size in the sorted list of sizes. If it is found at index 0, then the fitting is "best"; if it is found at index 1, the fitting is "regular", and if found at index 2, then it is "relaxed".
Here is the code for it:
height = float(input('Enter height measurement (cm): '))
chest = float(input('Enter Chest Measurement (cm): '))
waist = float(input('Enter waist measurement (cm): '))
height_size = min(8, max(1, int(height - 145) // 5))
chest_size = min(8, max(1, int(chest - 64) // 8))
waist_size = min(8, max(1, int(waist - 52) // 8))
if waist < 70:
waist_size = 0 # Deal with an irregularity for waist measures 69 and 68.
sizes = sorted([height_size, chest_size, waist_size])
size = sizes[-1] # Greatest
fitting = ["best", "regular", "relaxed"][sizes.index(size)]
print(f"You are size {size} ({fitting} fit)")
Related
I have three 2D arrays SandArray,ClayArray, and SiltArray. I also have a function described here. Below is my code, when I run the script I get a ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
def TextureClass(sand, clay, silt):
#if sand + clay > 100 or sand < 0 or clay < 0:
# raise Exception('Inputs adds over 100% or are negative')
if silt + 1.5*clay < 15:
textural_class = 'sand'
elif silt + 1.5*clay >= 15 and silt + 2*clay < 30:
textural_class = 'loamy sand'
elif (clay >= 7 and clay < 20 and sand > 52 and silt + 2*clay >= 30) or (clay < 7 and silt < 50 and silt + 2*clay >= 30):
textural_class = 'sandy loam'
elif clay >= 7 and clay < 27 and silt >= 28 and silt < 50 and sand <= 52:
textural_class = 'loam'
elif (silt >= 50 and clay >= 12 and clay < 27) or (silt >= 50 and silt < 80 and clay < 12):
textural_class = 'silt loam'
elif silt >= 80 and clay < 12:
textural_class = 'silt'
elif clay >= 20 and clay < 35 and silt < 28 and sand > 45:
textural_class = 'sandy clay loam'
elif clay >= 27 and clay < 40 and sand > 20 and sand <= 45:
textural_class = 'clay loam'
elif clay >= 27 and clay < 40 and sand <= 20:
textural_class = 'silty clay loam'
elif clay >= 35 and sand > 45:
textural_class = 'sandy clay'
elif clay >= 40 and silt >= 40:
textural_class = 'silty clay'
elif clay >= 40 and sand <= 45 and silt < 40:
textural_class = 'clay'
else:
textural_class = 'na'
return textural_class
Texture = TextureClass(SandArray,ClayArray,SiltArray)
Texture should be an array with the same shape as SandArray, ClayArray, and SiltArray but with the textural_class str as its values.
Is it possible to have an output array of text from a function having conditions and using arrays as its input arguments and if so, what am I missing?
Edit:
Having tried texture = np.array(list(map(TextureClass,SandArray,ClayArray,SiltArray))) I still get the same ValueError
I'm not really that knowledgeable in numpy, but, from what I searched in other questions, you could use vectorize to wrap your function.
Here's an example: How to apply a function / map values of each element in a 2d numpy array/matrix?
Using my previous approach of mostly built-in python-code:
You could zip the three arrays (either inside or outside your function, but I'd do it outside), then loop over the zipped arrays.
The zip() function returns a zip object, which is an iterator of tuples where the first item in each passed iterator is paired together, and then the second item in each passed iterator are paired together etc.
If the passed iterators have different lengths, the iterator with the least items decides the length of the new iterator.
Emphasis on the fact that it's assumed the three arrays have the same length. And, in this case, you'd need to bi-dimensionally zip:
So, instead of Texture = TextureClass(SandArray,ClayArray,SiltArray), you could use:
soilCompositions = (zip(sands, clays, silts) for sands, clays, silts in zip(SandArray, ClayArray, SiltArray))
Textures = ((TextureClass(sand, clay, silt) for sand, clay, silt in soilCompositionRow) for soilCompositionRow in soilCompositions)
Notice that I used generator comprehension, but you could just as easy use list comprehension instead:
soilCompositions = (zip(sands, clays, silts) for sands, clays, silts in zip(SandArray, ClayArray, SiltArray))
Textures = [[TextureClass(sand, clay, silt) for sand, clay, silt in soilCompositionRow] for soilCompositionRow in soilCompositions]
Applying a function to each element of a matrix requires np.vectorize. The documentation is available here. An example of a similar questions can be found here:How to apply a function / map values of each element in a 2d numpy array/matrix?.
I think this question is unique in that it shows the range of functions that np.vectorize works on. My original issue was whether or not np.vectorize would work for a conditional function like the one in my question.
def TextureClass(sand, clay, silt):
#if sand + clay > 100 or sand < 0 or clay < 0:
# raise Exception('Inputs adds over 100% or are negative')
if silt + 1.5*clay < 15:
textural_class = 'sand'
elif silt + 1.5*clay >= 15 and silt + 2*clay < 30:
textural_class = 'loamy sand'
elif (clay >= 7 and clay < 20 and sand > 52 and silt + 2*clay >= 30) or (clay < 7 and silt < 50 and silt + 2*clay >= 30):
textural_class = 'sandy loam'
elif clay >= 7 and clay < 27 and silt >= 28 and silt < 50 and sand <= 52:
textural_class = 'loam'
elif (silt >= 50 and clay >= 12 and clay < 27) or (silt >= 50 and silt < 80 and clay < 12):
textural_class = 'silt loam'
elif silt >= 80 and clay < 12:
textural_class = 'silt'
elif clay >= 20 and clay < 35 and silt < 28 and sand > 45:
textural_class = 'sandy clay loam'
elif clay >= 27 and clay < 40 and sand > 20 and sand <= 45:
textural_class = 'clay loam'
elif clay >= 27 and clay < 40 and sand <= 20:
textural_class = 'silty clay loam'
elif clay >= 35 and sand > 45:
textural_class = 'sandy clay'
elif clay >= 40 and silt >= 40:
textural_class = 'silty clay'
elif clay >= 40 and sand <= 45 and silt < 40:
textural_class = 'clay'
else:
textural_class = 'na'
return textural_class
vector_func = np.vectorize(TextureClass)
textures = vector_func(SandArray, ClayArray, SiltArray)
Lab:Seasons assignment
Write a program that takes a date as input and outputs the date's season. The input is a string to represent the month and an int to represent the day.
Ex: If the input is:
April
11
the output is:
Spring
In addition, check if the string and int are valid (an actual month and day).
Ex: If the input is:
Blue
65
the output is:
Invalid
The dates for each season are:
Spring: March 20 - June 20
Summer: June 21 - September 21
Autumn: September 22 - December 20
Winter: December 21 - March 19
my code so far:
input_month = input()
input_day = int(input())
months = ('January', 'February', 'March', 'April', 'May', 'June','July', 'August', 'September', 'October', 'November', 'December')
if not (input_month in months):
print ('Invalid')
elif input_month == 'January':
if not (0 < input_day <= 31):
print('Invalid')
else:
print('Winter')
elif input_month == 'February':
if not (0 < input_day <= 29):
print('Invalid')
else:
print('Winter')
elif input_month == 'March':
if (0 < input_day < 20):
print('Winter')
elif (20 <= input_day <= 31):
print('Spring')
else:
print('Invalid')
elif input_month == 'April':
if not (0 < input_day <= 30):
print('Invalid')
else:
print('Spring')
elif input_month == 'May':
if not (0 < input_day <= 31):
print('Invalid')
else:
print('Spring')
elif input_month == 'June':
if (0 < input_day <= 20):
print('Spring')
elif (20 < input_day <= 30):
print('Summer')
else:
print('Invalid')
elif input_month == 'July' or 'August':
if not (0 < input_day <= 31):
print('Invalid')
else:
print('Summer')
elif input_month == 'September':
if not(0 < input_day <= 30):
print("Invalid")
elif (0 < input_day <= 21):
print ("Summer")
else:
print ("Autumn")
elif input_month == 'October':
if not (0 < input_day <= 31):
print('Invalid')
else:
print('Autumn')
elif input_month == 'November':
if not (0 < input_day <= 30):
print('Invalid')
else:
print('Autumn')
elif input_month == 'December':
if (0 < input_day <= 20):
print('Autumn')
elif (20 < input_day <= 31):
print('Winter')
else:
print('Invalid')
I am getting errors for September 31 and November 7th and I can't figure out why?
This is my first question in Stackoverflow. So please do offer advice if I'm breaking any house rules.
I have started learning Z3Py only recently. I found myself in a situation where I know the following about an Int->Int function A that I want to describe and leave it for Z3Py to solve:
The summation of A(x) = 10000 where 0<x<100
A(x) > 10 where 0<x<100
A(x) = 0 where x>= 100
A(3) = 190
A(12) = 1200
How can these constraints be described in Z3Py (Or Z3)?
There could be multiple ways to code this example in z3py. With the constraints as you listed, you can use a symbolic array, an uninterpreted function or use separate variables for each of the 100 elements.
Using arrays
The simplest for this case would be the use of arrays: That is, model the Int -> Int function as an array:
from z3 import *
A = Array('A', IntSort(), IntSort())
s = Solver()
total = 0
for i in range(100):
s.add(A[i] > 10)
total = total + A[i]
s.add(total == 10000)
s.add(A[ 3] == 190)
s.add(A[12] == 1200)
k = Int('k')
s.add(ForAll(k, (Implies(Or(k < 0, k >= 100), A[k] == 0))))
if s.check() == sat:
m = s.model()
for i in range(100):
v = m.evaluate(A[i]).as_long()
print("%3d: %d" % (i, v))
When run, this prints:
0: 131
1: 19
2: 436
3: 190
4: 12
5: 11
6: 19
7: 24
8: 11
9: 13
10: 133
11: 134
12: 1200
13: 39
14: 132
15: 134
16: 134
17: 134
18: 30
19: 132
20: 132
21: 38
22: 16
23: 132
24: 22
25: 132
26: 134
27: 27
28: 134
29: 76
30: 130
31: 15
32: 132
33: 134
34: 31
35: 123
36: 35
37: 58
38: 123
39: 64
40: 49
41: 20
42: 139
43: 24
44: 134
45: 11
46: 132
47: 132
48: 22
49: 11
50: 134
51: 134
52: 134
53: 132
54: 132
55: 11
56: 134
57: 11
58: 11
59: 132
60: 11
61: 71
62: 134
63: 58
64: 132
65: 132
66: 134
67: 134
68: 39
69: 74
70: 132
71: 134
72: 134
73: 11
74: 18
75: 134
76: 16
77: 132
78: 17
79: 132
80: 132
81: 132
82: 15
83: 132
84: 132
85: 134
86: 15
87: 132
88: 134
89: 18
90: 132
91: 132
92: 132
93: 132
94: 12
95: 132
96: 22
97: 121
98: 24
99: 11
You can sum up the values printed to ensure it indeed gives you 10000.
Using uninterpreted functions
You can also model A as an uninterpreted function. The changes required is really trivial to the above:
from z3 import *
A = Function('A', IntSort(), IntSort())
s = Solver()
total = 0
for i in range(100):
s.add(A(i) > 10)
total = total + A(i)
s.add(total == 10000)
s.add(A( 3) == 190)
s.add(A(12) == 1200)
k = Int('k')
s.add(ForAll(k, (Implies(Or(k < 0, k >= 100), A(k) == 0))))
if s.check() == sat:
m = s.model()
for i in range(100):
v = m.evaluate(A(i)).as_long()
print("%3d: %d" % (i, v))
This prints:
0: 11
1: 11
2: 11
3: 190
4: 11
5: 11
6: 11
7: 11
8: 11
9: 11
10: 11
11: 11
12: 1200
13: 11
14: 11
15: 11
16: 11
17: 11
18: 11
19: 11
20: 11
21: 11
22: 11
23: 11
24: 11
25: 11
26: 11
27: 11
28: 11
29: 11
30: 11
31: 11
32: 11
33: 11
34: 11
35: 11
36: 11
37: 11
38: 11
39: 11
40: 11
41: 11
42: 11
43: 11
44: 11
45: 11
46: 11
47: 11
48: 11
49: 11
50: 11
51: 11
52: 11
53: 11
54: 11
55: 11
56: 11
57: 11
58: 11
59: 11
60: 11
61: 11
62: 11
63: 11
64: 11
65: 11
66: 11
67: 11
68: 11
69: 11
70: 11
71: 11
72: 11
73: 11
74: 7543
75: 11
76: 11
77: 11
78: 11
79: 11
80: 11
81: 11
82: 11
83: 11
84: 11
85: 11
86: 11
87: 11
88: 11
89: 11
90: 11
91: 11
92: 11
93: 11
94: 11
95: 11
96: 11
97: 11
98: 11
99: 11
The model is quite different in this case, but it's easy to see that it has A(3) = 190, A(12) = 1200, A(74) = 7543, and all other entries are set to 11; giving you a total of 190 + 1200 + 7543 + 11 * 97 = 10000.
Using separate variables
Yet a third method would be to allocate 100 integer elements in a python array, and assert the constraints on individual elements separately. This would lead to the simplest model, as it would not use any quantification. Of course, this would model the fact that elements outside the range 0..99 are 0 implicitly, so only use this if this constraint does not need to be explicitly mentioned. Again, the coding is almost identical:
from z3 import *
A = [Int('A_%d' % i) for i in range(100)]
s = Solver()
total = 0
for i in range(100):
s.add(A[i] > 10)
total = total + A[i]
s.add(total == 10000)
s.add(A[ 3] == 190)
s.add(A[12] == 1200)
if s.check() == sat:
m = s.model()
for i in range(100):
v = m.evaluate(A[i]).as_long()
print("%3d: %d" % (i, v))
I'm eliding the output of this for brevity. Note how we're using A as a python list in this case, instead of a symbolic array directly supported by z3py itself.
Summary
At the end of the day, the constraints you've described are simple enough that it can use all these three techniques. Which one is the best depends on what other constraints you'd want to model. (In particular, you'd want to avoid anything that makes heavy use of quantifiers, like ForAll above since SMT solvers don't do all that well for quantifiers in general. This problem is simple enough so it doesn't pose an issue, but when your constraints get complicated, it can increase solving times or lead the solver to answer unknown.)
Hope this gets you started. Best of luck!
Below you'll find a straight-forward SMT encoding of your problem, except for the summation requirement.
(set-option :smt.mbqi true) ; also try false (e-matching instead of MBQI)
(declare-fun A (Int) Int)
(assert
(=
10000
(+
(A 1)
(A 2)
(A 3)
; ...
(A 99))))
; A(x) > 10 where 0<x<100
(assert (forall ((x Int))
(implies
(and (< 0 x) (< x 100))
(> (A x) 10))))
; A(x) = 0 where x>= 100
(assert (forall ((x Int))
(implies
(>= x 100)
(> (A x) 10))))
; A(3) = 190
(assert (= (A 3) 190))
; A(12) = 1200
(assert (= (A 12) 1200))
(check-sat)
A few remarks:
All SMT functions are total; if you want to encode a partial function, you'll have to explicitly model the function's domain, and make definitional axioms conditional on whether or not an argument is in the domain. Z3 will still give you a total model for the function, though.
Arbitrary summation is non-trivial to encode in SMT, since there is no sum comprehension operator. Your case is simpler, though, since your sum ranges over a statically known number of elements (0 < x < 100).
I'd not be surprised if Z3py offers a convenient source syntax to generate sums over statically-known many elements
why does my code return wrong ticket prices? I am supposed to add a time factor as well, but can't get even this to work. This is what I am supposed to do:
"""
Price of one bus ticket
time 6-17, price 2.7, age 16-64
time 18-22, price 3.5, age 16-64
time 23 and 0-5, price 4, age 16-64
for ages 0-2 ticket is free at all times
time 6-17, price 1.7, ages 3-15 and 65 -->
time 18-22, price 2.5, ages 3-15 and 65 -->
time 23 and 0-5, price 3.0, ages 3-15 and 65 -->
"""
def calculate_ticket_price(age):
ticket_price = 0
while True:
if age >= 0 or age <= 2:
ticket_price = 1.0
if age <= 15 or age >= 3 or age >= 65:
ticket_price = 1.5
if age > 15 or age < 65:
ticket_price = 2.7
return float(ticket_price)
def main():
age = 5
price = calculate_ticket_price(age)
print(price)
if __name__ == '__main__':
main()
I think it’ll return the wrong price cause you’re using or where you need an and.
Your first if statement should be:
if ((age >= 0) and (age <= 2)):
Your second if statement should be:
if (((age <= 15) and (age >= 3)) or (age >= 65)):
Then your third one:
if ((age > 15) and (age < 65)):
def calculate_ticket_price(age, time):
while True:
if time >= 6 or time <= 17 and age > 15 or age < 65:
ticket_price = 2.7
elif time >= 18 or time <= 22 and age > 15 or age < 65:
ticket_price = 3.5
elif time >= 23 or time >= 0 or time <= 5 and age > 15 or age < 65:
ticket_price = 4.0
elif time >= 6 or time <= 17 and age <= 15 or age >= 3 or age >= 65:
ticket_price = 1.7
elif time >= 18 or time <= 22 and age <= 15 or age >= 3 or age >= 65:
ticket_price = 2.5
elif time >= 23 or time >= 0 or time <= 5 and age <= 15 or age >= 3 or age >= 65:
ticket_price = 3.0
else:
ticket_price = 0.0
return float(ticket_price)
def main():
age = 5
time = 12
price = calculate_ticket_price(age, time)
print(price)
if __name__ == '__main__':
main()
Made these edits. Should there be and between every >=, <= etc..?
You're using or when I think you want to be using and. For example, this condition:
if age >= 0 or age <= 2:
is going to be true for any positive number, since the first part will always match.
You also want to be using elif so that only one of these blocks will happen. Your last condition:
if age > 15 or age < 65:
ticket_price = 2.7
is going to happen any time the age is under 65 or over 15 (which is going to be every number), so I'd expect that your function just always returns 2.7.
A simpler way to write this function that follows the simple age-only rules you're trying to implement would be:
def calculate_ticket_price(age: int) -> float:
if age <= 2:
return 0.0 # infant price
elif age <= 15:
return 1.5 # youth price
elif age <= 65:
return 2.7 # adult price
else:
return 1.5 # senior price
In this very simple example, only the first condition that matches will return a value, so testing both sides of the range isn't necessary.
You can also check for an age to be within a particular range by writing an expression like 2 < age <= 15, or age > 2 and age < 15, or even age in range(2, 16).
Note that putting everything inside a while loop serves no purpose at all -- avoid having lines of code that don't do anything useful, since they're just one more place for bugs to appear. :)
As far as having the function account for both age and time, I notice that the fare table amounts to giving youth/seniors the same $1 discount regardless of what time it is, so I might simplify it down like this rather than have a different condition for each age/time combination:
def calculate_ticket_price(time: int, age: int) -> float:
# Infants ride free
if age <= 2:
return 0.0
# Youth and seniors get a $1.00 discount
discount = 1.0 if age <= 15 or age >= 65 else 0.0
if 6 <= time <= 17:
return 2.7 - discount
if 18 <= time <= 22:
return 3.5 - discount
if 0 <= time <= 5 or time == 23:
return 4.0 - discount
raise ValueError(f"invalid time {time}!")
I'm currently running Python 3.5 on Mac and I can't seem to find a way to be more efficient with my code.
In all I'm currently making a wheel of fortune game (or basically hangman), and I have it so that when the user clicks on a letter it checks if the letter is in the word etc.
Is there a better way than writing 26 if statements and checking coordinates each time? Is there a more efficient way of checking for coordinates using if statements?
while True:
mouse = win.getMouse()
if 35 < mouse.x < 65 and 85 < mouse.y < 115:
ans = "a"
break
elif 65 < mouse.x < 95 and 85 < mouse.y < 115:
ans = "b"
break
elif 95 < mouse.x < 125 and 85 < mouse.y < 115:
ans = "c"
break
elif 125 < mouse.x < 155 and 85 < mouse.y < 115:
ans = "d"
break
elif 155 < mouse.x < 185 and 85 < mouse.y < 115:
ans = "e"
break
elif 185 < mouse.x < 215 and 85 < mouse.y < 115:
ans = "f"
break
elif 215 < mouse.x < 245 and 85 < mouse.y < 115:
ans = "g"
break
elif 245 < mouse.x < 275 and 85 < mouse.y < 115:
ans = "h"
break
elif 275 < mouse.x < 305 and 85 < mouse.y < 115:
ans = "i"
break
elif 305 < mouse.x < 335 and 85 < mouse.y < 115:
ans = "j"
break
elif 35 < mouse.x < 65 and 115 < mouse.y < 145:
ans = "k"
break
elif 65 < mouse.x < 95 and 115< mouse.y < 145:
ans = "l"
break
elif 95 < mouse.x < 125 and 115 < mouse.y < 145:
ans = "m"
break
elif 125 < mouse.x < 155 and 115 < mouse.y < 145:
ans = "n"
break
elif 155 < mouse.x < 185 and 115 < mouse.y < 145:
ans = "o"
break
elif 185 < mouse.x < 215 and 115 < mouse.y < 145:
ans = "p"
break
elif 215 < mouse.x < 245 and 115 < mouse.y < 145:
ans = "q"
break
elif 245 < mouse.x < 275 and 115 < mouse.y < 145:
ans = "r"
break
elif 275 < mouse.x < 305 and 115 < mouse.y < 145:
ans = "s"
break
elif 305 < mouse.x < 335 and 115 < mouse.y < 145:
ans = "t"
break
elif 35 < mouse.x < 65 and 145 < mouse.y < 175:
ans = "u"
break
elif 65 < mouse.x < 95 and 145 < mouse.y < 175:
ans = "v"
break
elif 95 < mouse.x < 125 and 145 < mouse.y < 175:
ans = "w"
break
elif 125 < mouse.x < 155 and 145 < mouse.y < 175:
ans = "x"
break
elif 155 < mouse.x < 185 and 145 < mouse.y < 175:
ans = "y"
break
elif 185 < mouse.x < 215 and 145 < mouse.y < 175:
ans = "z"
break
As simple solution using a calculation vs. multiple if statements:
import string
while True:
mouse = win.getMouse()
x, xr = divmod(mouse.x-35, 30)
y, yr = divmod(mouse.y-85, 30)
if not(0 <= x < 10 and 0 <= y < 3): # Guard values
continue
if xr == 0 or yr == 0: # Gridlines?
continue
try:
ans = string.ascii_lowercase[10*y+x]
break
except IndexError:
pass
e.g. mouse(x=102, y=143) would return 'm'
You could use the following code to avoid the big if statement.
def check_pos(x, y):
table = 'abcdefghijklmnopqrstuvwxyz'
idx = (x - (35-30)) / 30
idy = (y - (85-30)) / 30
# each row has 10 cells
offset = idx + (idy -1) * 10
if 1 <= offset <= 26:
return table[offset-1]
import string
alpha=string.ascii_lowercase
mouse = win.getMouse()
for idx,i in enumerate(range(35,335,30)):
if mouse.x>i and mouse.x<i+30:
if mouse.y>85 and mouse.y<115:
ans=alpha[idx]
break
elif mouse.y>115 and mouse.y<145:
ans=alpha[idx + 10]
break
elif mouse.y>145 and mouse.y<175:
ans=alpha[idx+20]
break