Are there better ways to write if statements in python? - python

So ive been writing Python for a bit now. I've decided to make an app to help my sister with multiplication tables. Im writing the code that will randomly pick from my 10 lists of the diffrent questions (I know there are better ways to write it but it gave me abilities i wanted to use with SQL). lists are by Table (Tone,Ttwo,Tthree, etc.) inside Tone would be ['1*1','1*2',...] then as seen in the if statement it calls by calling the list and problem with randomly generated numbers.
def pick_question():
Table = random.randint(0,9)
Col = random.randint(0,9)
if Table == 0:
if Col == 0:
return Tone[0]
elif Col == 1:
return Tone[1]
elif Col == 2:
return Tone[2]
elif Col == 3:
return Tone[3]
elif Col == 4:
return Tone[4]
elif Col == 5:
return Tone[5]
elif Col == 6:
return Tone[6]
elif Col == 7:
return Tone[7]
elif Col == 8:
return Tone[8]
elif Col == 9:
return Tone[9]
elif Table == 1:
if Col == 0:
return Ttwo[0]
elif Col == 1:
return Ttwo[1]
elif Col == 2:
return Ttwo[2]
elif Col == 3:
return Ttwo[3]
elif Col == 4:
return Ttwo[4]
elif Col == 5:
return Ttwo[5]
elif Col == 6:
return Ttwo[6]
elif Col == 7:
return Ttwo[7]
elif Col == 8:
return Ttwo[8]
elif Col == 9:
return Ttwo[9]
obviously it would keep going but it was already quite long. was wondering if there was anyway to make this not hae to be so repetitive and look better...

def pick_question():
Table = random.randint(0,9)
Col = random.randint(0,9)
return [Tone,Ttwo][Table][Col]
I guess what you are trying to write is
import random
Tone = [f"1*{i}" for i in range(1,10)]
Ttwo = [f"2*{i}" for i in range(1,10)]
Tthree = [f"3*{i}" for i in range(1,10)]
Tfour = [f"4*{i}" for i in range(1,10)]
Tfive = [f"5*{i}" for i in range(1,10)]
Tsix = [f"6*{i}" for i in range(1,10)]
Tseven = [f"7*{i}" for i in range(1,10)]
Teight = [f"8*{i}" for i in range(1,10)]
Tnine = [f"9*{i}" for i in range(1,10)]
Questions = [
Tone,
Ttwo,
Tthree,
Tfour,
Tfive,
Tsix,
Tseven,
Teight,
Tnine,
]
def pick_question():
Table = random.randint(0,8)
Col = random.randint(0,8)
return Questions[Table][Col]
print(pick_question())
but I guess what you are trying to do is this:
import random
A=random.randint(1,9)
B=random.randint(1,9)
print(f"{A}*{B}=?")
C=input()
try:
assert A*B==int(C)
print("You are RIGHT!")
except:
print(f"Your are WRONG, right answer is: {A*B}")
Good luck with python! it's an amazing language! :)

Just use a one-dimensional list:
def pick_question():
Table = random.randint(0,9)
Col = random.randint(0,9)
if Table == 0:
return Tone[Col]
elif Table == 1:
return Ttwo[Col]
This will do the trick.
Or even better, a two-dimensional list:
def pick_question():
Table = random.randint(0,9)
Col = random.randint(0,9)
List = [Tone, Ttwo]
return List[Table][Col]

I quite like this solution with dictionaries and the get method:
route = input()
branch = {'y': code1, 'n': code2}.get(route)
This shortens your code and will be easier to read.

Rather than write the inner if structures, why not just
return Tone[Col]
?
In fact, you can create a list with the Tone, Ttwo, etc. inside it and then write
return outer_list[Table][Col]
def pick_question(list_with_tone_ttwo):
table = random.randint(0,9)
col = random.randint(0,9)
return list_with_tone_ttwo[table][col]
EDIT: added full function

Related

Not printing letters one by one on one single line [duplicate]

This question already has an answer here:
Why doesn't print output show up immediately in the terminal when there is no newline at the end?
(1 answer)
Closed last month.
dict = {}
def colors(col):
if col == "red":
return "\033[31m"
elif col == "green":
return "\033[32m"
elif col == "yellow":
return "\033[33m"
elif col == "blue":
return "\033[34m"
elif col == "magenta":
return "\033[35m"
def seperator(x):
colors1 = ["red","green","yellow","blue","magenta"]
for char in x:
y = random.choice(colors1)
print(f"{colors(y)}{char}",end="")
time.sleep(0.2)
seperator("MokeBeast")
I am trying to make python print the letters of this string with a 0.2 delay between each one on one single line.
I was expecting it to print out my string like this:
M (wait 0.2sec) o (wait 0.2sec) k (wait 0.2sec) e (wait 0.2sec) B (wait 0.2sec) e (wait 0.2sec) etc...
What keeps happening is that it does not print the letter one by one, instead it waits all those delays and then prints the string all in one like this: MokeBeast
How can I fix this?
You have to flush the standard output after each print to ensure they appear in between the waits:
import time
import sys
import random
dict = {}
def colors(col):
if col == "red":
return "\033[31m"
elif col == "green":
return "\033[32m"
elif col == "yellow":
return "\033[33m"
elif col == "blue":
return "\033[34m"
elif col == "magenta":
return "\033[35m"
def seperator(x):
colors1 = ["red","green","yellow","blue","magenta"]
for char in x:
y = random.choice(colors1)
print(f"{colors(y)}{char}",end="")
sys.stdout.flush() # <--- use this
time.sleep(0.2)
seperator("MokeBeast")

how i break the while loop in func "loop of user"?

I need to break the while loop, I try to do it with status statment and it didn't work to me.
Any suggestions what are the easiest ways to break a while loop?
This is my code:
def loop_of_user(my_details):
"""_summary_
the function do a variety of actions on the the variable my_detailes
:my_details (dict): dictionary of detailes on mariha
"""
num = int(input())
if num == 1:
print(my_details["first_name"])
elif num == 2:
print(my_details["birth_date"][3:5])
elif num == 3:
print(len(my_details["hobbies"]))
elif num == 4:
print(my_details["hobbies"][-1])
elif num == 5:
my_details["hobbies"].append("cooking")
print(my_details["hobbies"])
elif num == 6:
print(tuple_birth_date(my_details["birth_date"]))
elif num == 7:
my_details ["age"] = calculate_age(my_details["birth_date"])
print(my_details["age"])
else:
return "break"
def main():
mariah_details = {"first_name" : "mariah", "last_name" : "carey", "birth_date" : "27.03.1970", "hobbies" : ["sing", "compose", "act"]}
status = ""
while status != "break":
loop_of_user(mariah_details)
if __name__ == "__main__":
main()
The I try to use in satatus like you see and write "break" in the else satement and it not working, it still in the loop and won't break.
I will love some help here.
You can put the while loop inside the function loop_of_user instead and call the function loop_of_user() explicitly.
def loop_of_user(my_details):
"""_summary_
the function do a variety of actions on the the variable my_detailes
:my_details (dict): dictionary of detailes on mariha
"""
while True:
num = int(input())
if num == 1:
print(my_details["first_name"])
elif num == 2:
print(my_details["birth_date"][3:5])
elif num == 3:
print(len(my_details["hobbies"]))
elif num == 4:
print(my_details["hobbies"][-1])
elif num == 5:
my_details["hobbies"].append("cooking")
print(my_details["hobbies"])
elif num == 6:
print(tuple_birth_date(my_details["birth_date"]))
elif num == 7:
my_details["age"] = calculate_age(my_details["birth_date"])
print(my_details["age"])
else:
break
def main():
mariah_details = {"first_name": "mariah", "last_name": "carey", "birth_date": "27.03.1970",
"hobbies": ["sing", "compose", "act"]}
loop_of_user(mariah_details)
if __name__ == "__main__":
main()

Simplify for loop in python

I am using python and asking for help on how to simplify the code below. Thanks.
for i in range(1,9):
if i == 1:
wt_1 = gwt_2018[gwt_2018.WkNum == i]
elif i == 2:
wt_2 = gwt_2018[gwt_2018.WkNum == i]
elif i == 3:
wt_3 = gwt_2018[gwt_2018.WkNum == i]
elif i == 4:
wt_4 = gwt_2018[gwt_2018.WkNum == i]
elif i == 5:
wt_5 = gwt_2018[gwt_2018.WkNum == i]
elif i == 6:
wt_6 = gwt_2018[gwt_2018.WkNum == i]
elif i == 7:
wt_7 = gwt_2018[gwt_2018.WkNum == i]
else i == 8:
wt_8 = gwt_2018[gwt_2018.WkNum == i]
Do you need something like this?
l = [wt_1, wt_2, wt_3, wt_4, wt_5, wt_6, wt_7, wt_8]
for index, i in enumerate(l):
i = gwt_2018[gwt_2018.WkNum == index+1]
Is that mandatory to have 'wt_i' as variable name for all i's ?
I would use a dictionary instead:
wt = {}
for i in range(1,9):
wt[i] = gwt_2018[gwt_2018.WkNum == i]
I found the solution [a link] (Create multiple dataframe using for loop in python 2.7)
gbl = globals()
for i in range(1,54):
gbl['df_'+str(i)] = gwt_2018[gwt_2018.WkNum == i]

How to check for 3 in a row in tic tac toe game

I am making a tic tac toe game and trying to create a function that checks if 3 of the same spots in a row have the same input 'x' or '0'. I am having trouble with the three_in_row function I am trying to make to trigger game over. I am trying to figure out how to do this in a simple way so all rows or columns will be triggers if 3 X's or 0's are played... Here's what I have so far. This is in python 2.7.13
(this is only part of the code I think should be relevant)
def setup_board(size):
board = []
for row in range(size):
board.append([])
for col in range(size):
board[row].append(empty)
return board
def three_in_row(b):
b[0][0] and b[0][1] and b[0][2] == 'x'
def game_over(b):
if three_in_row(b) == True:
print "Congratulations You Win!"
else:
return False
def tic_tac_toe():
b = setup_board(3)
run_game(b)
In my opinion, it might make more sense to store X's as +1 and O's as -1, so that you can easily do arithmetic to check if the game is over.
For example:
def three_in_row(b):
xWin = check_winner(b,3)
oWin = check_winner(b,-3)
return xWin | oWin
def check_winner(b, valToCheck):
foundWin = any(sum(r) in {valToCheck} for r in b) # check rows
# now check columns
for i in range(3):
foundWin = foundWin | (sum([b[j][i] for j in range(3)]) == valToCheck)
# now check diagonals
foundWin = foundWin | (sum([b[i][i] for i in range(3)]) == valToCheck)
foundWin = foundWin | (sum([b[i][2-i] for i in range(3)]) == valToCheck)
return foundWin
Thanks to Blender for the following more succinct method:
def three_in_row(b):
return any(sum(r) in {3, -3} for r in b)
def line_match(game):
for i in range(3):
set_r = set(game[i])
if len(set_r) == 1 and game[i][0] != 0:
return game[i][0]
return 0
#transposed column function for future use
#def column(game):
# trans = numpy.transpose(game)
# for i in range(3):
# set_r = set(trans[i])
# if len(set_r) == 1 and trans[i][0] != 0:
# return list(set_r)[0]
def diagonal_match(game):
if game[1][1] != 0:
if game[1][1] == game[0][0] == game[2][2]:
return game[1][1]
elif game[1][1] == game[0][2] == game[2][0]:
return game[1][1]
return 0
The correct syntax for the checks is either:
b[0][0] == 'x' and b[0][1] == 'x' and b[0][2] == 'x'
or (more succinctly):
b[0][0] == b[0][1] == b[0][2] == 'x'
You are also missing a return just before your check, like:
return b[0][0] == b[0][1] == b[0][2] == 'x'
Anyways, your code does not iterate over all the rows. A possible correction would be:
def three_in_row(b):
for row in rage(0, 3):
if b[row][0] == b[row][1] == b[row][2] == 'x':
return True
return False
Doing a three_in_column(b) should be fairly easy (changing b[row][n] in b[n][column]), so is also manually checking the two diagonals.

List index out of range when coding a valid move for board game

Hey everyone im new here and im trying to make a game called HiQ now i got the board drawn and everything and i can click on one of the pieces, but when i do the piece does change color and i get an error in the shell as well (listed below) im not sure why im getting this and i was hoping you guys could give me better insight. Ill provide my code below as well and it is coded in python 3, thank you
builtins.IndexError: list index out of range
boardcirc =[[0,0,0,1,1,1,0,0,0],
[0,0,0,1,1,1,0,0,0],
[0,0,0,1,1,1,0,0,0],
[1,1,1,1,1,1,1,1,1],
[1,1,1,1,2,1,1,1,1],
[1,1,1,1,1,1,1,1,1],
[0,0,0,1,1,1,0,0,0],
[0,0,0,1,1,1,0,0,0],
[0,0,0,1,1,1,0,0,0]]
def HiQ():
splash_screen()
make_board()
def make_board():
make_sqr()
make_circ()
get_click()
def get_click():
global count, boardcirc
while 1!=0:
count = count - 1
displaymessage("Pieces: " + str(count))
where = win.getMouse()
col = where.x//90
row = where.y//90
valid_move(row,col)
make_move(row,col)
def valid_move(row,col):
if boardcirc[row][col] == 0:
return False
if boardcirc[row-1][col] == 1 and boardcirc[row-2][col] == 1:
return True
if boardcirc[row+1][col] == 1 and boardcirc[row+2][col] == 1:
return True
if boardcirc[row][col-1] == 1 and boardcirc[row][col-2] == 1:
return True
if boardcirc[row][col+1] == 1 and boardcirc[row][col+2] == 1:
return True
def make_move(row,col):
while valid_move(row,col) == True:
col = (col*85)+42
row = (row*85)+42
circ = Circle(Point(col,row),35)
circ.setFill("white")
circ.draw(win)
thats everything that applies to the error
For your valid_move(row,col), you can't have all those if statements.
Instead of doing this, use elif's after the initial if statement, and don't forget to write an else statement
if boardcirc[row][col] == 0:
return False
if boardcirc[row-1][col] == 1 and boardcirc[row-2][col] == 1:
return True
elif boardcirc[row+1][col] == 1 and boardcirc[row+2][col] == 1:
return True
elif boardcirc[row][col-1] == 1 and boardcirc[row][col-2] == 1:
return True
elif boardcirc[row][col+1] == 1 and boardcirc[row][col+2] == 1:
return True
else:
return False

Categories