I haven't programmed in a year so I am a little rusty. I really want to incorporate a link list but I am having trouble remembering how the code works, and having to implement it in Python isn't helping.
I only have the Node Class set up so far. Apparently, I cant use overloaded constructors which is annoying...
Basically i want to write a program that prompts a user to enter X number of bucket. Each bucket will have an X amount of different color balls. The user will specify how many balls for each color.
I welcome any help!
class Node:
def __init__(self, bucketNumber ,colorONE, colorTWO,
colorTHREE, colorFOUR, colorFIVE ):
self.bucket = bucketNumber # index
self.color1 = colorONE # quantity
self.color2 = colorTWO # quantity
self.color3 = colorTHREE # quantity
self.color4 = colorFOUR # quantity
self.color5 = colorFIVE # quantity
def printN(bucketNum):
for i in range(0,bucketNum):
print(nodes[i].bucket, nodes[i].color1, nodes[i].color2, nodes[i].color3, nodes[i].color4, nodes[i].color5)
colors = []
nodes = []
count = []
bucketNum = int(raw_input("The are 2-5 buckets with 2-5 ball colors. Enter number of Buckets:"))
colorNum = int(raw_input("Enter number of Colors:"))
for i in range(0,colorNum):
colors.append(raw_input("Enter color: " + str(i+1) ))
for i in range(0,bucketNum):
for j in range(0,colorNum):
count.append((raw_input("How many "+ colors[j] +" balls in bucket " + str(i+1))))
nodes.append( Node(i+1, count[0], count[1], count[2], count[3], count[4]) )
del count[ 0:len(count) ]
for i in range(0,colorNum):
print colors[i],
print " "
printN(bucketNum)
You don't seem to have a question, but note that there is probably no need to use a linked list, unless your list will have many insertions AND be large (because of python list memory allocation; and I wouldn't assume that this was a problem until it showed up in profiling), or if you will have many insertions and deletes at the ends of the list.
In that case, python provides collections.deque which is a linked sequence.
Related
I'm a newbie programmer working on an idea for a small game. I wanted my play space to be a grid for various reasons. Without a lot of good reason, I decided to create a class of GridSquare objects, each object having properties like size, an index to describe what (x,y) coordinates they represented, and some flags to determine if the grid squares were on land or empty space, for example. My grid is a dictionary of these objects, where each GridSquare is a key. The values in the dictionary are going to be various objects in the place space, so that I can easily look up which objects are on each grid square.
Just describing this I feel like a complete lunatic. Please bear in mind that I've only been at this a week.
My problem appears when I try to change the GridSquare objects. For example, I want to use a list to generate the land on each level. So I iterate over the list, and for each value I look through my grid squares using a for loop until I find one with the right index, and flip the GridSquare.land property. But I found that this caused a runtime error, since I was changing keys in a dictionary I was looping through. OK.
Now what I'm trying to do is to create a list of the keys I want to change. For each item in my level-generating list, I go through all the GridSquares in my grid dictionary until I find the one with the index I'm looking for, then I append that GridSquare to a list of old GridSquares that need updating. I then make another copy of the GridSquare, with some properties changed, in a list of altered GridSquares. Finally, I delete any keys from my grid dictionary which match my list of "old" GridSquares, and then add all of the altered ones into my grid dictionary.
The problem is that when I delete keys from my grid dictionary which match my list of "old" keys, I run into keyerrors. I can't understand what is happening to my keys before I can delete them. Using try/except, I can see that it's only a small number of the keys, which seems to vary kind of arbitrarily when I change parts of my code.
I would appreciate any insight into this behaviour.
Here is code for anyone still reading:
aspect_ratio = (4, 3)
screen_size = (1280, 720)
#defining a class of objects called GridSquares
class GridSquare:
def __init__(self, x, y):
self.index = (x, y)
self.land = 0
#creates a dictionary of grid squares which I hope will function as a grid......
grid = {}
for x_index in range(1, (aspect_ratio[0] + 1)):
for y_index in range (1, (aspect_ratio[1] + 1)):
new_square = GridSquare(x_index, y_index)
grid[new_square] = None
#these are lists to hold changes I need to make to the dictionary of grid squares
grid_changes = []
old_gridsquares = []
#this unweildly list is meant to be used to generate a level. Numbers represent land, spaces are empty space.
for number_no, number in enumerate(["1", "1", "1", "1",
" ", " ", " ", " ",
"1", "1", "1", "1"]):
#makes grid squares land if they are designated as such in the list
for gridsquare in grid.keys():
#this if statement is meant to convert each letter's position in the list into an index like the grid squares have.
if gridsquare.index == ((number_no + 1) % (aspect_ratio[0]), ((number_no + 1) // (aspect_ratio[0] + 1)) + 1):
#create a list of squares that need to be updated, and a list of squares to be deleted
old_gridsquares.append(gridsquare)
flagged_gridsquare = GridSquare((number_no + 1) % (aspect_ratio[0]), ((number_no + 1) // (aspect_ratio[0] + 1)) + 1)
flagged_gridsquare.land = 1
#this part is meant to set the flag for the gridsquare that indicates if it is on the far side or the near side,
#if it is land
if number == "1":
flagged_gridsquare.near = 1
grid_changes.append(flagged_gridsquare)
#deletes from grid any items with a key that matches the old squares, and adds updated versions.
for old_gridsquare in old_gridsquares:
try:
del grid[old_gridsquare]
except:
print(old_gridsquare.index)
print(old_gridsquare.land)
for grid_change in grid_changes:
grid[grid_change] = None
I am trying to make a part of a program that takes a users input, searches across several dictionaries to find a matching key, and then increase the corresponding entries value by 25.
Strength = {"Acrobatics":5, "Crafting":5, "Axe":5, "Blunt Weapon":5, "Long Blade":5}
Intelligence = {"Alchemy":5, "Conjuration":5, "Enchant":5, "Thievery":5}
Willpower = {"Alteration":5, "Destruction":5, "Mysticism":5, "Restoration":5}
Agility = {"Block":5, "Light Armor":5, "Marksman":5, "Sneak":5}
Speed = {"Athletics":5, "Hand to Hand":5, "Short Blade":5, "Unarmored":5}
Endurance = {"Heavy Armor":5, "Medium Armor":5, "Spear":5}
Personality = {"Illusion":5, "Mercantile":5, "Speechcraft":5}
# Skill dictionaries, will be printed to a seperate file after all things are done
skilldict = {"Strength":Strength, "Intelligence":Intelligence, "Willpower":Willpower, "Agility":Agility, "Speed":Speed, "Endurance":Endurance, "Personality":Personality}
for alphakey, alphaentry in skilldict.items():
if alphakey == usfavstat[0]:
for key, entry in alphaentry.items():
alphaentry[key] = entry + 5
for alphakey, alphaentry in skilldict.items():
# Grabs a key, entry combination from skilldict, named differently to not cause error down the line
if alphakey == usfavstat[1]:
# If the key is equal to the second favored stat, continue
for key, entry in alphaentry.items():
# This works?
# Nested for-loop grabbing a key, entry combination from a nested dict
alphaentry[key] = entry + 5
# Increases all values of entries by 5
mtemp = input("Enter major skills, seperated by a comma : ").title()
mtemp2 = mtemp.replace(" ", "")
majorskills = mtemp2.split(",")
# Stuff to increase corresponding skills by 25
I am unsure how to go about this. An example input would be "Acrobatics, Short Blade, Block, Speechcraft, Alteration". The desired output would have these skills at 30 in their respective dictionaries.
The for-loops with nested for-loops are irrelevant for this situation. I've included them to see if anyone would have a better means of achieving their goal, that being increasing all skills of an area by 5, based on user input in usfavstat, but this is secondary.
If there is information that would be beneficial to have, do comment and I'll add it if I can.
Here you go:
Strength = {"Acrobatics":5, "Crafting":5, "Axe":5, "Blunt Weapon":5, "Long Blade":5}
Intelligence = {"Alchemy":5, "Conjuration":5, "Enchant":5, "Thievery":5}
Willpower = {"Alteration":5, "Destruction":5, "Mysticism":5, "Restoration":5}
Agility = {"Block":5, "Light Armor":5, "Marksman":5, "Sneak":5}
Speed = {"Athletics":5, "Hand to Hand":5, "Short Blade":5, "Unarmored":5}
Endurance = {"Heavy Armor":5, "Medium Armor":5, "Spear":5}
Personality = {"Illusion":5, "Mercantile":5, "Speechcraft":5}
skill_dict = {"Strength":Strength, "Intelligence":Intelligence, "Willpower":Willpower, "Agility":Agility, "Speed":Speed, "Endurance":Endurance, "Personality":Personality}
user_input = input("Enter major skills, seperated by a comma: ").title()
major_skills = [skill.strip() for skill in user_input.split(",")]
for skill in skill_dict:
for major_skill in major_skills:
if skill_dict.get(skill).get(major_skill):
skill_dict[skill][major_skill] += 25
print(skill_dict)
I've re-named the variables a bit for my own convenience, but hope you get the idea.
By the way, I think mtemp2 = mtemp.replace(" ", "") is not a good idea in case you have some space-separated skills like Short Blade (since it becomes ShortBlade and fails), so I've replaced it with .strip() string method instead.
A little bit of context for this: I am going to be a junior in high school next year and I thought it would be cool to code some equations for things I would be doing in school. I have done equations for algebra (solving for x in the quadratic equation and such), and I thought it would be cool to create some code for chemistry. I'm trying to figure out how to balance equations, and I was thinking I could enter in all of the amounts and using a certain key (let's say space) it would continue to the next part of the chemical equation. Here is basically what I was thinking.
reac1_chem1 = input("Enter the first chemical: ")
reac1_amount1 = input("Enter the amount of " + reac1_chem1 + " atoms: )
reac1_chem2 = input("Enter the second chemical: ")
reac1_amount2 = input("Enter the amount of " + reac1_chem2 + " atoms: )
I want to continue this process until space is entered in as a chemical. How would I make this process infinite? Is creating variables the way to go or should I make a list? Any suggestions would be appreciated! Let me know if this was in any way confusing and I can try to clear it up for you. Thanks!
A dictionary would be great:
chemicals = dict()
index = 1
while True:
chemical = input(f"Enter chemical {index}: ")
if chemical == " ":
break
else:
chemicals[chemical] = input("Enter the amount: ")
index += 1
print(chemicals)
You could try to store the information in a dictionary of dictionaries, example as follows:
dct = {"ReactionNameOrID": {"ChemicalName1":"ATOMS", "ChemicalName":"ATOMS2"}}
You can then access the information like this:
dct.get("ReactionNameOrID").get("ChemicalName1")
#which will return: "ATOMS"
You could then use a class to store everything inside including the functions.
class Reactions():
#initialize the dictionary
def __init__(self):
self.dict_reactions = {}
#add a function to the class to add more reactions
def add_chemical(self):
reaction_name = input("Enter the reaction name/id: ")
dict_chemicals = input("Enter the chemicals + atoms as dictionary: ")
self.dict_reactions[reaction_name] = dict_chemicals
MyReactions = Reactions()
# Enter the reaction name/id: FirstReaction
# Enter the reaction name/id: {"H":100, "O":500}
MyReactions.add_chemical()
print(MyReactions.dict_reactions)
#{'FirstReaction': '{"H":100, "O":500}'}
I'm trying to dynamically generate cells. Each cell has a name, defined as a key of a dictionary. The value is an instance of a class, containing three parameters (strength, intelligence, energy).
import random
class Cell:
def __init__(self, energy, strength, intelligence):
self.energy = energy
self.strength = strength
self.intelligence = intelligence
cells = {}
k = 1
while k < 100:
key = "a" + str(k)
print("Generating cell: " + key)
cells[key] = Cell(random.randint(1, 100),random.randint(1, 100),random.randint(1, 100))
k += 1 #Generate cells
My problem is with names. This code was good enough for the first generation of cells, but when I need to make more, the new cells can override old ones due a name conflict.
Is there a way to generate random, but unique cell names to avoid such conflict? I tried to create new names starting with 'a' and the lowest number which doesn't already exist. However, cells die throughout my program. My approach would simply fill in the gaps, which would make it hard to determine which generation the cell is from.
You could use python's uuid library.
Simple example (out of context):
import uuid as uuidlib
uuid = str(uuidlib.uuid4())
In your case:
import uuid
import random
class Cell:
def __init__(self, energy, strength, intelligence):
self.energy = energy
self.strength = strength
self.intelligence = intelligence
cells = {}
k = 1
while k < 100:
key = str(uuid.uuid4())
print("Generating cell: " + key)
cells[key] = Cell(random.randint(1, 100),random.randint(1, 100),random.randint(1, 100))
k += 1 #Generate cells
You can try this function to generate random names
import random
def random_string(min_size, max_size):
import string
return ''.join(random.choices(string.ascii_uppercase + string.ascii_lowercase + string.digits, k=random.randint(min_size, max_size)))
random_string(7, 15)
This gives output like
'AvkyCzlN9ggPr' and if you run again it may give 'FBPXy5a4Ib'
Also you can add a version/generation field to your cell class in addition to energy, strength, intelligence. You can add a counter to get the current version and increment the version every time the cell is updated.
Based on what your requirements are you can then use it to remove old cells, or keep them as a version history.
To remove old cells, just override a dictionary value with random_string()
For eg:-
some_dict = {}
randomstr = random_string(7, 15)
some_dict[random_str] = some_cell(randomstr)
to override
some_updated_cell = some_cell.update() # decide to increment your version? upto you.
# If you keep the randomstr same it will override the dict key, else it will not override and you can make (randomstr +"-"+ str(version)) as the key of dict.
some_dict[some_updated_cell.get_randomstr] = some_updated_cell
to not overwrite and keep track of generation
version = 1 # build a method or autoincrement version.
key = randomstr + "-" + str(version)
then you can do key.split("-") to get the key and the version from 'AvkyCzlN9ggPr-1'.
Another alternative approach would be to use the dictionary values as a list of objects. So instead of replacing the dictionary value, you can append it to the list.
some_dict[randomstr] = []
some_dict[randomstr] = [*some_dict[randomstr], newObject]
And to access the latest generation just do
some_dict[random_str][-1] # to access the last element of list
If this does not solve your problem leave a comment and I'll update accordingly :)
Let's say I have a list of soccer players. For now, I only have four players. [Messi, Iniesta, Xavi, Neymar]. More players will be added later on. I want to keep track of the number of times these soccer players pass to each other during the course of a game. To keep track of the passes, I believe I'll need a data structure similar to this
Messi = {Iniesta: 4, Xavi: 5 , Neymar: 8}
Iniesta = {Messi: 4, Xavi: 10 , Neymar: 5}
Xavi = {Messi: 5, Iniesta: 10 , Neymar: 6}
Neymar = {Messi: 8, Iniesta: 5 , Xavi: 6}
Am I right to use a dictionary? If not, what data structure would be better suited? If yes, how do I approach this using a dictionary though? How do I address the issue of new players being included from time to time, and creating a dictionary for them as well.
As an example, If I get the first element in the list, List(i) in the first iteration is Messi, how do i use the value stored in it to create a dictionary with the name Messi. That is how do i get the line below.
Messi = [Iniesta: 4, Xavi: 5 , Neymar: 8]
It was suggested I try something like this
my_dynamic_vars = dict()
string = 'someString'
my_dynamic_vars.update({string: dict()})
Python and programming newbie here. Learning with experience as I go along. Thanks in advance for any help.
This is a fun question, and perhaps a good situation where something like a graph might be useful. You could implement a graph in python by simply using a dictionary whose keys are the names of the players and whose values are lists players that have been passed the ball.
passes = {
'Messi' : ['Iniesta', 'Xavi','Neymar', 'Xavi', 'Xavi'],
'Iniesta' : ['Messi','Xavi', 'Neymar','Messi', 'Xavi'],
'Xavi' : ['Messi','Neymar','Messi','Neymar'],
'Neymar' : ['Iniesta', 'Xavi','Iniesta', 'Xavi'],
}
To get the number of passes by any one player:
len(passes['Messi'])
To add a new pass to a particular player:
passes['Messi'].append('Xavi')
To count the number of times Messi passed to Xavi
passes['Messi'].count('Xavi')
To add a new player, just add him the first time he makes a pass
passes['Pele'] = ['Messi']
Now, he's also ready to have more passes 'appended' to him
passes['Pele'].append['Xavi']
What's great about this graph-like data structure is that not only do you have the number of passes preserved, but you also have information about each pass preserved (from Messi to Iniesta)
And here is a super bare-bones implementation of some functions which capture this behavior (I think a beginner should be able to grasp this stuff, let me know if anything below is a bit too confusing)
passes = {}
def new_pass(player1, player2):
# if p1 has no passes, create a new entry in the dict, else append to existing
if player1 not in passes:
passes[player1] = [player2]
else:
passes[player1].append(player2)
def total_passes(player1):
# if p1 has any passes, return the total number; otherewise return 0
total = len(passes[player1]) if player1 in passes else 0
return total
def total_passes_from_p1_to_p2(player1, player2):
# if p1 has any passes, count number of passes to player 2; otherwise return 0
total = passes[player1].count(player2) if player1 in passes else 0
return total
Ideally, you would be saving passes in some database that you could continuously update, but even without a database, you can add the following code and run it to get the idea:
# add some new passes!
new_pass('Messi', 'Xavi')
new_pass('Xavi', 'Iniesta')
new_pass('Iniesta', 'Messi')
new_pass('Messi', 'Iniesta')
new_pass('Iniesta', 'Messi')
# let's see where we currently stand
print total_passes('Messi')
print total_passes('Iniesta')
print total_passes_from_p1_to_p2('Messi', 'Xavi')
Hopefully you find this helpful; here's some more on python implementation of graphs from the python docs (this was a fun answer to write up, thanks!)
I suggest you construct a two dimensional square array. The array should have dimensions N x N. Each index represents a player. So the value at passes[i][j] is the number of times the player i passed to player j. The value passes[i][i] is always zero because a player can't pass to themselves
Here is an example.
players = ['Charles','Meow','Rebecca']
players = dict( zip(players,range(len(players)) ) )
rplayers = dict(zip(range(len(players)),players.keys()))
passes = []
for i in range(len(players)):
passes.append([ 0 for i in range(len(players))])
def pass_to(f,t):
passes[players[f]][players[t]] += 1
pass_to('Charles','Rebecca')
pass_to('Rebecca','Meow')
pass_to('Charles','Rebecca')
def showPasses():
for i in range(len(players)):
for j in range(len(players)):
print("%s passed to %s %d times" % ( rplayers[i],rplayers[j],passes[i][j],))
showPasses()