I had the following code that was working just fine and then I've updated to a new version of Python. What I don't understand is why it will only work up to 10 combinations. If you set variables combination_cap and range_to to higher than 10 the program just hangs. No error. Nothing.
Here's my code:
import itertools
import subprocess
import os
if os.name == 'nt':
def clear_console():
subprocess.call("cls", shell=True)
return
else:
def clear_console():
subprocess.call("clear", shell=True)
return
def generateCombinationRange():
combination_cap = 10
range_from = 1
range_to = 10
combination_list = list(itertools.combinations(range(1, int(combination_cap)+1), 6))
combination_list_lenght = len(combination_list)
output_file = open('F' + str(range_from) + 'T' + str(range_to) + 'OF' + str(combination_list_lenght) + '_comibnations.csv', 'w')
index = 0
for each_combination in combination_list:
index += 1
#print(''.join(str(each_combination)) + '\n')
if index >= range_from:
output_file.write(str(index) + ', '
+ str(each_combination[0]) + ', '
+ str(each_combination[1]) + ', '
+ str(each_combination[2]) + ', '
+ str(each_combination[3]) + ', '
+ str(each_combination[4]) + ', '
+ str(each_combination[5]) + '\n'
)
if index >= range_to:
output_file.close()
break
output_file.close()
generateCombinationRange()
The issue is the line list(itertools.combinations(range(1, int(combination_cap)+1), 6)). If the numbers are high, you're generating an enormous list that's going to chew through all of your RAM. What you should do is use it as a generator, so it only generates the numbers you actually use. This version will work with any set of values for combination_cap and range_to because it only stores one combination in memory at a time.
def generate_combination_range():
combination_cap = 100
range_from = 1
range_to = 100
output_file = open(
'F' + str(range_from) + 'T' + str(range_to) + 'OF' + '_comibnations.csv', 'w')
index = 0
for each_combination in itertools.combinations(range(1, int(combination_cap) + 1), 6):
index += 1
# print(''.join(str(each_combination)) + '\n')
if index >= range_from:
output_file.write(str(index) + ', '
+ str(each_combination[0]) + ', '
+ str(each_combination[1]) + ', '
+ str(each_combination[2]) + ', '
+ str(each_combination[3]) + ', '
+ str(each_combination[4]) + ', '
+ str(each_combination[5]) + '\n'
)
if index >= range_to:
output_file.close()
break
output_file.close()
Also, style note, it's generally prefered to use enumerate instead of manually managing an index. for index, each_combination in enumerate(itertools.combinations(range(1, int(combination_cap) + 1), 6)):
You are getting a Memory error:
Traceback (most recent call last):
File "C:\zila\zilawww\t.py", line 54, in <module>
generateCombinationRange()
File "C:\zila\zilawww\t.py", line 25, in generateCombinationRange
combination_list = list(itertools.combinations((range(1, int(combination_cap)+1)), 6))
MemoryError
Remove the "list"
combination_list = list(itertools.combinations(range(1, int(combination_cap)+1), 6))
To make it a generator and save the memory (you won't be able to use it on len though)
combination_gen = (itertools.combinations(range(1, int(combination_cap)+1), 6))
I took the time to incorporate your answer into my code and now I have the finished product. I would like to share the complete code with everyone who may be interested.
import subprocess
import os
import itertools
import math
if os.name == 'nt':
def clear_console():
subprocess.call("cls", shell=True)
return
else:
def clear_console():
subprocess.call("clear", shell=True)
return
#----------------------------------------------------------------------
def main_menu():
while True:
main_menu_selected_option = 0
# MAIN MENU - PARENT
while main_menu_selected_option not in range(1, 4):
try:
clear_console()
print ('')
print (' Combination Generator v1.0 - Menu')
main_menu_selected_option = int(input('''
1. All indexed combinations for combination cap.
2. All Prime indexed combinations for combination cap.
3. Extract range of indexed combinations for combination cap.
4. Extract Prime range of indexed combinations for combination cap.
Enter Option: '''))
except ValueError:
#print ('Not an integer!')
#clear_console()
#print ('')
#print (' Lotery Systems - Menu')
continue
else:
if main_menu_selected_option == 1:
menu_1()
else:
if main_menu_selected_option == 2:
menu_2()
else:
if main_menu_selected_option == 3:
menu_3()
else:
if main_menu_selected_option == 4:
menu_4()
else:
clear_console()
main_menu()
#----------------------------------------------------------------------
def menu_1():
combination_cap = 0
# 1ST MENU = CHILD.
while int(combination_cap) not in range(1, 42+1):
combination_cap = int(input('''
Enter combination Cap: '''))
print ('')
print (' Generating combinations for combination cap.')
print (' Please wait...')
menu_1_execute(combination_cap)
#----------------------------------------------------------------------
def menu_2():
combination_cap = 0
# 2ND MENU = CHILD.
while int(combination_cap) not in range(1, 42+1):
combination_cap = int(input('''
Enter combination Cap: '''))
print ('')
print (' Generating combinations for combination cap.')
print (' Please wait...')
menu_2_execute(combination_cap)
#----------------------------------------------------------------------
def menu_3():
combination_cap = 0
range_from = 0
range_to = 0
# 3RD MENU = CHILD.
while int(combination_cap) not in range(1, 42+1):
try:
combination_cap = int(input('''
Enter combination Cap: '''))
range_from = int(input('''
Enter from: '''))
range_to = int(input('''
Enter to: '''))
except ValueError:
#print ('Not an integer!')
#clear_console()
#print ('')
#print (' Lotery Systems - Menu')
continue
else:
if range_from < range_to:
print ('')
print (' Generating range of combinations for combination cap.')
print (' Please wait...')
menu_3_execute(combination_cap, range_from, range_to)
else:
continue
#----------------------------------------------------------------------
def menu_4():
combination_cap = 0
range_from = 0
range_to = 0
# 3RD MENU = CHILD.
while int(combination_cap) not in range(1, 42+1):
try:
combination_cap = int(input('''
Enter combination Cap: '''))
range_from = int(input('''
Enter from: '''))
range_to = int(input('''
Enter to: '''))
except ValueError:
#print ('Not an integer!')
#clear_console()
#print ('')
#print (' Lotery Systems - Menu')
continue
else:
if range_from < range_to:
print ('')
print (' Generating Prime range of combinations for combination cap.')
print (' Please wait...')
menu_4_execute(combination_cap, range_from, range_to)
else:
continue
#----------------------------------------------------------------------
def menu_1_execute(combination_cap):
index = 0
output_file = open('all_indexed_combinations.csv', 'w')
combination_generator = (itertools.combinations(range(1, int(combination_cap) + 1), 6))
for each_combination in combination_generator:
index += 1
output_file.write(str(index) + ', '
+ str(each_combination[0]) + ', '
+ str(each_combination[1]) + ', '
+ str(each_combination[2]) + ', '
+ str(each_combination[3]) + ', '
+ str(each_combination[4]) + ', '
+ str(each_combination[5]) + '\n'
)
#Stamp Combination Cap
output_file.write('Cap: ' + ', ' + str(combination_cap) + '\n')
#Stamp Combinations Total
output_file.write('Total: ' + ', ' + str(index) + '\n')
output_file.close()
os.rename('all_indexed_combinations.csv',str(index) + '_combinations.csv')
#----------------------------------------------------------------------
def menu_2_execute(combination_cap):
index = 0
prime_index = 0
output_file = open('all_prime_indexed_combinations.csv', 'w')
combination_generator = (itertools.combinations(range(1, int(combination_cap) + 1), 6))
for each_combination in combination_generator:
index += 1
if isPrime(index):
prime_index += 1
output_file.write(str(index) + ', '
+ str(each_combination[0]) + ', '
+ str(each_combination[1]) + ', '
+ str(each_combination[2]) + ', '
+ str(each_combination[3]) + ', '
+ str(each_combination[4]) + ', '
+ str(each_combination[5]) + '\n'
)
#Stamp Combination Cap
output_file.write('Cap: ' + ', ' + str(combination_cap) + '\n')
#Stamp Prime Combinations Total
output_file.write('Total: ' + ', ' + str(prime_index) + '\n')
output_file.close()
os.rename('all_prime_indexed_combinations.csv',str(prime_index) + '_prime_combinations.csv')
#----------------------------------------------------------------------
def menu_3_execute(combination_cap, range_from, range_to):
index = 0
output_file = open('Range_F' + str(range_from) + 'T' + str(range_to) + '_combinations.csv', 'w')
combination_generator = (itertools.combinations(range(1, int(combination_cap) + 1), 6))
for each_combination in combination_generator:
index += 1
if index >= range_from:
output_file.write(str(index) + ', '
+ str(each_combination[0]) + ', '
+ str(each_combination[1]) + ', '
+ str(each_combination[2]) + ', '
+ str(each_combination[3]) + ', '
+ str(each_combination[4]) + ', '
+ str(each_combination[5]) + '\n'
)
if index >= range_to:
output_file.close()
break
output_file.close()
#----------------------------------------------------------------------
def menu_4_execute(combination_cap, range_from, range_to):
index = 0
output_file = open('Prime_Range_F' + str(range_from) + 'T' + str(range_to) + '_combinations.csv', 'w')
combination_generator = (itertools.combinations(range(1, int(combination_cap) + 1), 6))
for each_combination in combination_generator:
index += 1
if index >= range_from:
if isPrime(index):
output_file.write(str(index) + ', '
+ str(each_combination[0]) + ', '
+ str(each_combination[1]) + ', '
+ str(each_combination[2]) + ', '
+ str(each_combination[3]) + ', '
+ str(each_combination[4]) + ', '
+ str(each_combination[5]) + '\n'
)
if index >= range_to:
output_file.close()
break
output_file.close()
#----------------------------------------------------------------------
def isPrime(n):
if n < 2:
return False
i = 2
for i in range(2, int(math.sqrt(n) + 1)):
if (n % i == 0):
return False
return True
#----------------------------------------------------------------------
#Initialize Application
main_menu()
Related
total begginner here.
I am trying to write a complete tic-tac-toe program based on the automate boring stuff exercise. I got it working before like this:
theBoard = {'top-L': ' ', 'top-M': ' ', 'top-R': ' ',
'mid-L': ' ', 'mid-M': ' ', 'mid-R': ' ',
'low-L': ' ', 'low-M': ' ', 'low-R': ' '}
def printBoard(board): #function to print board
print(board['top-L'] + '|' + board['top-M'] + '|' + board['top-R'])
print('-+-+-')
print(board['mid-L'] + '|' + board['mid-M'] + '|' + board['mid-R'])
print('-+-+-')
print(board['low-L'] + '|' + board['low-M'] + '|' + board['low-R'])
print('''
Hi! This is my tic-tac-toe text based game.
To make your move, write where you want to play:
top-L top-M top-R
mid-L mid-M mid-R
low-L low-M low-R
''')
turn= 'X' #starting
while True:
printBoard(theBoard)
print(f'Turn for {turn}. Where will you play?')
try:
move = input()
if theBoard[move] == ' ':
theBoard[move] = turn
if turn == 'X':
turn = 'O'
else:
turn = 'X'
else:
print('That move is not possible!')
continue
except KeyError:
print('''Wrong input.
To make your move, write where you want to play:
top-L top-M top-R
mid-L mid-M mid-R
low-L low-M low-R
''')
continue
if ((theBoard['top-L']==theBoard['top-M']==theBoard['top-R']) and theBoard['top-L']!=' ')\
or ((theBoard['mid-L']==theBoard['mid-M']==theBoard['mid-R']) and theBoard['mid-R']!=' ')\
or ((theBoard['low-L']==theBoard['low-M']==theBoard['low-R']) and theBoard['low-L']!=' ')\
or ((theBoard['top-L']==theBoard['mid-M']==theBoard['low-R']) and theBoard['top-L']!=' ')\
or ((theBoard['low-L']==theBoard['mid-M']==theBoard['top-R']) and theBoard['low-L']!=' ')\
or ((theBoard['top-L']==theBoard['mid-L']==theBoard['low-L']) and theBoard['top-L']!=' ')\
or ((theBoard['top-M']==theBoard['mid-M']==theBoard['low-M']) and theBoard['top-M']!=' ')\
or ((theBoard['top-R']==theBoard['mid-R']==theBoard['low-R']) and theBoard['top-R']!=' '):
break
if turn == 'X':
turn = 'O'
else:
turn = 'X'
print(f'Good Job {turn}, you won!')
This worked well and i turned to codereview for some improvements.
I stored the strings 'X' and 'O' as I discovered that those were considered magic strings and make my code less clean.
Next, I wanted to store all the win conditions in a variable called conditions. But when I do this my program will now not get out of the loop when I get a winning move. Why could this be?
theBoard = {'top-L': ' ', 'top-M': ' ', 'top-R': ' ',
'mid-L': ' ', 'mid-M': ' ', 'mid-R': ' ',
'low-L': ' ', 'low-M': ' ', 'low-R': ' '}
def printBoard(board):
print(board['top-L'] + '|' + board['top-M'] + '|' + board['top-R'])
print('-+-+-')
print(board['mid-L'] + '|' + board['mid-M'] + '|' + board['mid-R'])
print('-+-+-')
print(board['low-L'] + '|' + board['low-M'] + '|' + board['low-R'])
conditions = (((theBoard['top-L'] == theBoard['top-M'] == theBoard['top-R']) and theBoard['top-L'] != ' ') \
or ((theBoard['mid-L'] == theBoard['mid-M'] == theBoard['mid-R']) and theBoard['mid-R'] != ' ') \
or ((theBoard['low-L'] == theBoard['low-M'] == theBoard['low-R']) and theBoard['low-L'] != ' ') \
or ((theBoard['top-L'] == theBoard['mid-M'] == theBoard['low-R']) and theBoard['top-L'] != ' ') \
or ((theBoard['low-L'] == theBoard['mid-M'] == theBoard['top-R']) and theBoard['low-L'] != ' ') \
or ((theBoard['top-L'] == theBoard['mid-L'] == theBoard['low-L']) and theBoard['top-L'] != ' ') \
or ((theBoard['top-M'] == theBoard['mid-M'] == theBoard['low-M']) and theBoard['top-M'] != ' ') \
or ((theBoard['top-R'] == theBoard['mid-R'] == theBoard['low-R']) and theBoard['top-R'] != ' '))
print('''
Hi! This is my tic-tac-toe text based game.
To make your move, write where you want to play:
top-L top-M top-R
mid-L mid-M mid-R
low-L low-M low-R
''')
playerX = 'X'
playerO = 'O'
turn= playerX
while True:
printBoard(theBoard)
print(f'Turn for {turn}. Where will you play?')
try:
move = input()
if theBoard[move] == ' ':
theBoard[move] = turn
if turn == playerX:
turn = player0
else:
turn = playerX
else:
print('That move is not possible!')
continue
except KeyError:
print('''Wrong input.
To make your move, write where you want to play:
top-L top-M top-R
mid-L mid-M mid-R
low-L low-M low-R
''')
continue
if conditions == True:
printBoard(theBoard)
break
if turn == playerX:
turn = player0
else:
turn = playerX
print(f'Good Job {turn}, you won!')
That is because conditions is a bool value. It is calculated when it is set. That is to say - it not a function that makes its computations when it is called. In your case conditions is set to False and it will remain to be False. It is a constant.
Wrap it in a function like this:
def check():
conditions = (((theBoard['top-L'] == theBoard['top-M'] == theBoard['top-R']) and theBoard['top-L'] != ' ') \
or ((theBoard['mid-L'] == theBoard['mid-M'] == theBoard['mid-R']) and theBoard['mid-R'] != ' ') \
or ((theBoard['low-L'] == theBoard['low-M'] == theBoard['low-R']) and theBoard['low-L'] != ' ') \
or ((theBoard['top-L'] == theBoard['mid-M'] == theBoard['low-R']) and theBoard['top-L'] != ' ') \
or ((theBoard['low-L'] == theBoard['mid-M'] == theBoard['top-R']) and theBoard['low-L'] != ' ') \
or ((theBoard['top-L'] == theBoard['mid-L'] == theBoard['low-L']) and theBoard['top-L'] != ' ') \
or ((theBoard['top-M'] == theBoard['mid-M'] == theBoard['low-M']) and theBoard['top-M'] != ' ') \
or ((theBoard['top-R'] == theBoard['mid-R'] == theBoard['low-R']) and theBoard['top-R'] != ' '))
return conditions
And call this function instead of conditions in the if statement:
if check() == True:
printBoard(theBoard)
break
After F5 in Idle the input prompt appears, I enter a number the file is generated - everything works.
If I try to execute the script directly from the file a console is opened and closed with no result.
If I move the f = open("galaxies.txt","w+") before the outer most FOR loop the script doesn't work at all.
Any suggestions for a fix and reasons why it behaves like this?
import string, random
f = open("galaxies.txt","w+")
def inputNumber(message):
while True:
try:
howmany = int(input(message))
except ValueError:
print("Not an integer! Try again.")
continue
else:
return howmany
break
string.ascii_letters
type_galaxy = ['elliptical','spiral','irregular']
howmany = inputNumber('How many galaxies to generate? ')
for i in range(howmany):
planet_names = []
pos_0 = 'g' + random.choice(string.ascii_letters).upper() + random.choice(string.ascii_letters).upper() + random.choice(string.ascii_letters).upper() + '-' + random.choice(string.ascii_letters).upper() + str(random.randint(1, 9999))
gal_type = type_galaxy[random.randint(0,2)]
num_of_planets = random.randint(1,43)
for k in range(num_of_planets):
pos_1 = 'p' + random.choice(string.ascii_letters).upper() + random.choice(string.ascii_letters).upper() + '-' + random.choice(string.ascii_letters).upper() + str(random.randint(1, 99))
planet_names.append(pos_1)
if i < 1:
f.write('-----Galaxy '+pos_0+'----- \n')
else:
f.write('\n-----Galaxy '+pos_0+'----- \n')
f.write('Type: '+gal_type + ' \n')
f.write('There are '+str(num_of_planets)+' planets in the galaxy. Their names are: \n')
for x in planet_names:
f.write (x + ' and it has ' + str(random.randint(0,56)) + 'moons \n')
f.write('-----Thats all from Galaxy '+pos_0+'----- \n')
f.close()
Code:
triangle_char = input('Enter a character:\n')
triangle_height = int(input('Enter triangle height:\n'))
print('')
for i in range(triangle_height):
updatedChar = ' '.join([triangle_char]*i)
print(triangle_char + ' ' + updatedChar + ' ')
i += 1
The output is correct but I can't seem to get rid of the extra " " whitespace at the end of the first iteration.
Example Output:
% # How to remove this whitespace but keep the others
% %
% % %
Multiple updatedChar by i + 1 and print it without appending the sign again. You can also remove the i += 1, it has no effect
for i in range(triangle_height):
updated_char = ' '.join(triangle_char * (i + 1))
print(updated_char)
Output
%
% %
% % %
strip() should do what you want
triangle_char = input('Enter a character:\n')
triangle_height = int(input('Enter triangle height:\n'))
print('')
for i in range(triangle_height+1):
updatedChar = ' '.join([triangle_char]*i)
print((triangle_char + ' ' + updatedChar + ' ').strip())
i += 1
I am trying to create a simple board in a draw_board definition that will use size and several coordinates where I will place 1 character length characters in specified coordinates. I am in the beginning stages and want to just simply create the board itself using a 2d array.
This method below works when I change individual elements :
board = [['','','',''], ['','','',''], ['', '', '', ''], ['','','','']]
board[0][0] = 'a'
print(' 0 1 2 3')
print('0 ' + board[0][0] + ' ' + board[0][1] + ' ' + board[0][2] + ' ' + board[0][3])
print('1 ' + board[1][0] + ' ' + board[1][1] + ' ' + board[1][2] + ' ' + board[1][3])
print('2 ' + board[2][0] + ' ' + board[2][1] + ' ' + board[2][2] + ' ' + board[2][3])
print('3 ' + board[3][0] + ' ' + board[3][1] + ' ' + board[3][2] + ' ' + board[3][3])
However, I would not be able to change the size by just a variable and would need to edit the initialization of the board myself.
This method below is better and would work because I could easily change the size variable and get any size board I want...
size = 4
board = [['']*size]*size
board[0][0] = 'a'
print(' 0 1 2 3')
print('0 ' + board[0][0] + ' ' + board[0][1] + ' ' + board[0][2] + ' ' + board[0][3])
print('1 ' + board[1][0] + ' ' + board[1][1] + ' ' + board[1][2] + ' ' + board[1][3])
print('2 ' + board[2][0] + ' ' + board[2][1] + ' ' + board[2][2] + ' ' + board[2][3])
print('3 ' + board[3][0] + ' ' + board[3][1] + ' ' + board[3][2] + ' ' + board[3][3])
However, when I implement board[0][0] = 'a', it changes the entire column to 'a', which is not what I want. Any suggestions of how I could change this second method to make it work for just the desired coordinate?
Use
board = [['' for i in range(size)] for j in range(size)]
this is because when you use the * operator, you're creating more references to the same object, not more copies.
Here's more in depth information about the strategy used above, called list comprehensions
if group == 10G2:
file_name='10G2 Scores.txt'
fileObject = open(file_Name,'wb')
pickle.dump(+str(name) + ' got ' + str(finalscore) + ' percent from ' + str(totalquestions) + ' question(s), this is ' + str(score) + ' out of ' + str(totalquestions) + '.') ,fileObject)
fileObject.close()
This is part of a maths quiz and I am trying to write scores to a text file. It says there is a syntax error on the 10G2?
All of the variables have been defined and I have imported pickle
Thanks in advance. BTW, I'm doing GCSE computing.
This is my whole code:
#Maths Quiz
noq=0
score=0
import math
import pickle
import random
import time
import pickle
def write(name, finalscore, totalquestions, score, file_Object):
pickle.dump ((str(name) + ' got ' + str(finalscore) + ' percent from ' + str(totalquestions) + ' question(s), this is ' + str(score) + ' out of ' + str(totalquestions) + '.') ,file_Object)
return
group=input("What mentor group are you in?: ")
name=input("What is your name?: ")
print ("Hello " + name + ". How many questions would you like to do?:")
totalquestions=int(input(" "))
for i in range (0,(totalquestions)):
noq=noq+1
print ("Question " +str(noq))
numberone=random.randint(1, 10)
numbertwo=random.randint(1, 10)
answer=int(numberone) + int(numbertwo)
print ("What is " +str(numberone) + "+" + str(numbertwo) + "?:")
uanswer=int(input(""))
if answer==uanswer:
print("That is correct!!!")
score=score +1
print ("Your score is.....")
time.sleep(0.5)
print("" +str(score) + " out of " + str(i+1))
time.sleep(1)
else:
print ("Sorry, that is wrong!!!")
score=score
print ("Your score is.....")
time.sleep(0.5)
print ("" +str(score) + " out of " + str(i+1))
time.sleep(1)
time.sleep(0.5)
print ("Your final score is.....")
finalscore=score/totalquestions
finalscore=finalscore*100
time.sleep(3)
print ("" +str(finalscore)+ " percent")
#file write###############################################################################
if group == 10G2:
file_name='10G2 Scores.txt'
fileObject= open(file_Name,'w')
pickle.dump((+str(name) + ' got ' + str(finalscore) + ' percent from ' + str(totalquestions) + ' question(s), this is ' + str(score) + ' out of ' + str(totalquestions) + '.') ,fileObject)
fileObject.close()
elif group == 10G1:
file_name='10G1 Scores.txt'
fileObject = open(file_Name,'w')
pickle.dump((+str(name) + ' got ' + str(finalscore) + ' percent from ' + str(totalquestions) + ' question(s), this is ' + str(score) + ' out of ' + str(totalquestions) + '.') ,fileObject)
fileObject.close()
elif group == 10G3:
file_name='10G3 Scores.txt'
fileObject = open(file_Name,'w')
pickle.dump((+str(name) + ' got ' + str(finalscore) + ' percent from ' + str(totalquestions) + ' question(s), this is ' + str(score) + ' out of ' + str(totalquestions) + '.') ,fileObject)
fileObject.close()
elif group == 10G4:
file_name='10G4 Scores.txt'
fileObject = open(file_Name,'w')
write ()
fileObject.close()
elif group == 10G5:
file_name='10G5 Scores.txt'
fileObject = open(file_Name,'w')
write ()
fileObject.close()
elif group == 10G6:
file_name='10G6 Scores.txt'
fileObject = open(file_Name,'w')
write ()
fileObject.close()
elif group == 10G7:
file-name='10G7 Scores.txt'
fileObject = open(file_Name,'w')
write ()
fileObject.close()
Try changing this line
if group == 10G2:
to:
if group == '10G2':