Update old scores without another iteration - python

I have a list of people that have an old and new score for a video game. The new scores of each player depend on the old scores of the other players. I could easily do this:
while not done calculating scores:
for each player:
player.new_score = calculate_score(player, players_scores) # this fn uses players' old scores
for each player:
player.old_score = player.new_score
but I'd rather not have another layer of complexity.
Since the new scores depend on old scores, I DON'T want to update the old scores in the same loop that I update new scores like this:
while not done calculating scores:
for each player:
player.new_score = calculate_score(player, players_scores) # this fn uses players' old scores
player.old_score = player.new_score
I was wondering if there's a way to execute the same set of instructions as the first block of code without having to iterate through the list of players again.

Related

list of lists - assigning values inside of list of lists to variables, changing values inside of list of lists due to local variable functions

Title probably doesn't make sense, i just don't know how to put describe the help I need in a single sentence. So,
I have a list of lists
team_list[[teamname, gamesplayed, gameswon, gameslost,health [teamname2,gamesplayed,gameswon, gameslost,health][teamname3,gamesplayed,gameswon, gameslost,health]]
each list inside the team_list variable has the teams name, how many games they've played, won, lost and the teams health (0-100). there are more teams in the list, but for simplicity i'll leave it at 3.
I want to create a function which takes the list of teams and position of the two teams that are about to go against each other, position being the index of the team name stored in the list of characters. This is what i have created
def match(team_list, teamname1_pos, teamname2_pos)
I want the function to take input from the user who will type in the name of 2 teams they want to verse each other
team1 = input('Please select team:')
team2 = input('Please select team:')
The user will know the name of the teams from another function inside this program. If the name of the team isn't found in the list, the user will need to re enter team name. If the name of the team is found in the list, assign team variable to that list. I have no idea on how i am supposed to write this in code
I also want the function to take input from the user who will select how many rounds they want the match to go for
battle_rounds = int(input('How many rounds would you like to go for?')
and a battle round counter to store how many rounds have been played so the battle stops once it hits that number
num_of_battles = 0
and a damage variable that is generated randomly which will effect the 2 teams health (index 4) chosen by the users
damage = random.randint(1,50)
The match must stop once one of the players health is at 0, or once the amount of rounds chosen by the user is reached. The values inside the list of list much change, eg if team 1 takes 50 damage (starts at 100 damage), but team2 takes 100 damage, both teams games played must be increased by 1, team 1 wins increased by 1, team 2s loses increased by 1, team 1s health reduced to 50 and teams 2s health reduced to 0.
I have come up with an algorithm for how I think it should work, i am just very confused on how to implement this into code:
while (number of matches have not been completed and both opponents health are >0)
randomly generate a damage value sustained from match and update team's health value by calling method update_health(damage1).
randomly generate a damage value sustained from battle and update team2's health value by calling method update_health(damage2).
display team1 round results, display team2 round results
determine the winner of the match - the team with the most health left at the end of all the match rounds is the winner.
display the winner to the screen and also report if a team has died as a result of match.
update team1's battle statistics.
update team2's battle statistics.
Any help, no matter how big or small is welcomed
Thank you if you have read this far.
Hello I would like to suggest using dictionary to solve the variable assigning problem.
team_dict= {"teamname": ["gamesplayed", "gameswon", "gameslost", "health"], "teamname2": ["gamesplayed", "gameswon", "gameslost", "health"],"teamname3": ["gamesplayed", "gameswon", "gameslost", "health"]}
since your data is more referential it would be more appropriate to use dictionaries. then loop over the keys to show the user the teams they can choose:
print(f"here are the teams you can choose from:")
for index,team in enumerate(team_dict,1):
print(f"{index}. {team}")
team1 = team_dict[input('Please select team:')]
team2 = team_dict[input('Please select team:')]
I hope that helped.

Dictionary Manupilation

We represent scores of batsmen across a sequence of matches in a two level dictionary as follows:
{'match1':{'player1':57, 'player2':38}, 'match2':{'player3':9, 'player1':42}, 'match3':{'player2':41, 'player4':63, 'player3':91}
Each match is identified by a string, as is each player. The scores are all integers. The names associated with the matches are not fixed (here they are 'match1','match2','match3'), nor are the names of the players. A player need not have a score recorded in all matches
Define a Python function "orangecap(d)" that reads a dictionary d of this form and identifies the player with the highest total score. Your function should return a pair (playername,topscore) where playername is a string, the name of the player with the highest score, and topscore is an integer, the total score of playername.
The input will be such that there are never any ties for highest total score.
For instance:
orangecap({'match1':{'player1':57, 'player2':38}, 'match2':{'player3':9, 'player1':42}, 'match3':{'player2':41, 'player4':63, 'player3':91}})
('player3', 100)
orangecap({'test1':{'Ashwin':84, 'Kohli':120}, 'test2':{'ashwin':59, 'Pujara':42}})
('Kohli', 120)
This is my code:
def orangecap(d):
s=[]
t=[]
for i in sorted(d.keys()):
for j in sorted(d[i].keys()):
flag=0
for k in range(len(s)):
if(s[k]==j):
t[k:k]+=[d[i][j]]
flag=1
break
if(flag==0):
s.append(j)
t.append(d[i][j])
m=max(t)
for i in range(len(t)):
if t[i]==m:
return (s[i],m)
You didn't quite get a question out there, in future try be specific in what you are asking or try https://codereview.stackexchange.com/ for general pointers etc.
First to note in python, as in all programming languages try to be as expressive as possible when naming variables, it will make it much easier for everyone (most often yourself) to work out what is going on (and wrong).
So in the question we are trying to work out the total scores for each player. In other words we are combining the dictionary for each match into a single dictionary, adding if we have a duplicate key. So
def orangecap(d):
# Make a new dict to count the totals
totals = {}
# Loop over every players score in every match.
for match in d.values():
for player in match:
# Check if player is in totals dictionary. If not add them.
if player not in totals:
totals[player] = 0
# Add players score in this match to there total score.
totals[player] += match[player]
#initialise highest_total as we will use it later for comparison.
highest_total = -1
#loop through totals to find highest score
for player in totals:
# if players score is greater than current highest, set highest_player
# to be current player, and set the highest total to players total
if totals[player] > highest_total:
highest_player = player
highest_total = totals[player]
# return the highest player and highest total
return highest_player, highest_total

Python Data Structure Selection

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()

Making a statistics program

I am trying to write a Python program that computes and prints the following :
the average score from a list of scores
the highest score from a list of scores
the name of the student who got the highest score.
The program starts by asking the user to enter the number of cases. For EACH case, the program should ask the user to enter the number of students. For each student the program asks the user to enter the student's name and marks. For EACH case the program reports the average marks, the highest marks and the name of the student who got the highest marks.
Also
If there are more than one person with the highest score in a CASE, the program should report the first occurrence only.
The average score and the highest score should have exactly 2 decimal places.
The output should be as in the sample program output.
What I have been trying so far is the following:
grade=[]
name_list=[]
cases=int(input('Enter number of cases: '))
for case in range(1,cases+1):
print('case',case)
number=int(input('Enter number of students: '))
for number in range (1,number+1):
name=str(input('Enter name of student: '))
name_list.append(name)
mark=float(input('Enter mark of student:'))
grade.append(mark)
highest= max (grade)
average=(sum(grade)/number)
high_name=grade.index(max(grade))
print('average',average)
print('Highest',highest)
print (high_name)
This is what i have deciphered so far. my biggest problem now is getting the name of the individual with the high score. Any thoughts and feedback is much appreciated. As with respect to the answer posted below, i am afraid the only thing i do not understand is the dictionary function but otherwise the rest does make sense to me.
This resembles an assignment, it is too specific on details.
Anyways, the official docs are a great place to get started learning Python.
They are quite legible and there's a whole bunch of helpful information, e.g.
range(start, end): If the start argument is omitted, it defaults to0
The section about lists should give you a head start.
numcases = int(input("How many cases are there? "))
cases = list()
for _ in range(numcases):
# the _ is used to signify we don't care about the number we're on
# and range(3) == [0,1,2] so we'll get the same number of items we put in
case = dict() # instantiate a dict
for _ in range(int(input("How many students in this case? "))):
# same as we did before, but skipping one step
name = input("Student name: ")
score = input("Student score: ")
case[name] = score # tie the score to the name
# at this point in execution, all data for this case should be
# saved as keys in the dictionary `case`, so...
cases.append(case) # we tack that into our list of cases!
# once we get here, we've done that for EVERY case, so now `cases` is
# a list of every case we have.
for case in cases:
max_score = 0
max_score_student = None # we WILL need this later
total_score = 0 # we don't actually need this, but it's easier to explain
num_entries = 0 # we don't actually need this, but it's easier to explain
for student in case:
score = case[student]
if score > max_score:
max_score = score
max_score_student = student
total_score += score
num_entries += 1
# again, we don't need these, but it helps to demonstrate!!
# when we leave this for loop, we'll know the max score and its student
# we'll also have the total saved in `total_score` and the length in `num_entries`
# so now we need to do.....
average = total_score/max_entries
# then to print we use string formatting
print("The highest score was {max_score} recorded by {max_score_student}".format(
max_score=max_score, max_score_student=max_score_student))
print("The average score is: {average}".format(average=average))

How to print different items depending on a random print in Python?

How to print different items depending on a random print in Python? Here is part of my script.
Mage = "Mage"
Warrior = "Warrior"
Thief = "Thief"
skilltree = (Mage, Warrior, Thief)
print random.choice (skilltree)
Now say it randomly chose Warrior. In my next script it would print 7 skills. But if it were to randomly choose Thief or Mage they would of been 7 completely different skills. So I want the 7 skills you get to depend on the randomly chosen skill tree.
You have done the hard part. Now you just need to map the skills to each category. For instance, using a dictionary:
skills = {'Mage': range(7), 'Warrior': range(7,14), 'Thief': range(14,21)}
choice = random.choice(skilltree)
print skills[choice]
This will print the list of skills you associated with the chosen skilltree. I used range just to illustrate, you could have a list of strings with the skills.
I will just illustrate a little bit further with Paulo's example in case you are not familiar with using a dictionary (and like he said using a dictionary is probably the best choice for a mapping).
MageSkills = ["Mskill1", "Mskill2"]
ThiefSkills = ["Tskill1", "Tskill2"]
WarriorSkills = ["Wskill1", "Wskill2"]
skills = {'Warrior': WarriorSkills, 'Mage': MageSkills, 'Thief': ThiefSkills}
choice = 'Warrior'
print(skills[choice])
The general concept of a solution has been outlined by others, but I think they're missing the key misunderstanding behind your question, which is how to persist something that you randomly chose and printed. As far as that goes, and for understanding this is what I would do:
import random
classes = ("Mage", "Warrior", "Thief")
skill_dictionary = {"Mage": ["Fireball", "Ice Blast"...], "Warrior": [...]} # etc
random_class = random.choice(classes) # Keep a version around for yourself
print random_class # print the version you just saved so you still have a copy
print skill_dictionary[random_class] #Then use the saved version to get the skill list
An important thought distinction to have here is separating getting the data from displaying it. First you randomly choose the data, and only after you already have it do you decide to show it to the user with your print statement.
The dictionary is just a key/value store (something that maps keys(your classes) to values (your skills)). It happens to fit this problem well, but you could implement this in other ways.

Categories

Resources