0

I have read a few of the Stack answers on similar issues to mine. I have only found one answer that results in the output I want and that was an answer by the user arshajii in the following question:

Print list in table format in python

His answer was:

>>> l1 = ['a', 'b', 'c']
>>> l2 = ['1', '2', '3']
>>> l3 = ['x', 'y', 'z']
>>> for row in zip(l1, l2, l3):
...     print ' '.join(row)

a 1 x
b 2 y
c 3 z

The above is what I would like my format to be. I have tried his method but it doesn't work for my code. I have a feeling it's because the person that asked the question was talking about external files.... Can anyone help me rewrite this code into a non-external source format?

The optimal layout would result in the output being something like:

Letter a, Number 1, Letter x
Letter b, Number 2, Letter y
Letter c, Number 3, Letter z

With the letter and numbers actually being words printed (print "Letter ").

The below is the code I currently have:

    for list in zip ([rounds], [numberOfHits], [score]):
    print("Round " + str(rounds) + ": " + str(numberOfHits) + " shots. " + str(score)) .join(list)

But my output is:

Round [1, 1]: [6, 4] shots. 5 under par.

Rather than:

Round [1]: [6] shots. 3 under par.
Round [2]: [4] shots. 1 under par.

I keep getting the AttributeError: 'NoneType' object has no attribute 'join'. Anyone know why this is coming up?

Thank you in advance! Hopefully this is all understandable but if it isn't let me know.

(Please don't give me any solutions that require external programs. I am using PyCharm and would just like to stick to this type of coding before moving onto more advanced code.)

Amy
  • 1
  • 2
  • you're calling `print(....).join(list)`, print returns a `NoneType`. The `.join(list)` should be inside the print parens. – Sean Breckenridge May 18 '18 at 08:44
  • Its hard to know where the error is coming from if we don't know whats in `rounds`, `numberOfHits` and `score`. Can you post the code that defines those variables? Or print them out before your for loop, so we know the values. – Sean Breckenridge May 18 '18 at 08:53
  • @Sean Breckenridge I have edited my code to be: 'print ("Round " + str(rounds) + ": " + str(numberOfHits) + " shots. " + str(score).join (list))' But I get a "TypeError: sequence item 0: expected str instance, list found" error and I don't know why... – Amy May 18 '18 at 08:55
  • The 3 lists begin as empty lists and as the game progresses (this is what my program is - a game) the lists get filled. – Amy May 18 '18 at 08:58
  • I can add my code but it's quite lengthy as each list depends on what the user does. But i'll try and shorten it – Amy May 18 '18 at 08:58
  • Provide as little of it as needed to fully understand what each of the lists contain. I can't see any other way to figure out what the error is. – Sean Breckenridge May 18 '18 at 09:01
  • After the user has finished playing a round of the game I have: 'numberOfHits.append(hitsNumber) rounds.append(numberOfRounds)' before it goes onto the next function – Amy May 18 '18 at 09:01
  • the hits number is hitsNumber = hitsNumber + 1 and its the same concept with the numberOfRounds Both hitsNumber and numberOfRounds begin at 0 but the hitsNumber resets to 0 once a new game begins I know this isn't my code but maybe it helps you understand what I have done with my code – Amy May 18 '18 at 09:02

2 Answers2

0

I'll just predefine these variables with what I expect they would be, since I'm not sure what your code would contain:

import random

def calculate_score(par, hits):
    if par == hits:
        return "par"
    elif hits < par:
        return "{} under par".format(par - hits)
    else:
        return "{} over par".format(hits - par)

# score for each hole
numberOfHits = []
parForHole = []

for hole in range(18):
    # choose a random par
    par = random.randint(3,7)
    # choose a random number of hits that the user does
    user_score = random.randint(par - 2, par + 2)
    parForHole.append(par)
    numberOfHits.append(user_score)

for index, (hits, par) in enumerate(zip(numberOfHits, parForHole), 1):
    print("Round {round_number}: {hits} shots. {under_or_over}".format(
        round_number=index,
        hits=hits,
        under_or_over=calculate_score(par, hits)
    ))

To explain this a bit, enumerate assigns each index in a list a number. So instead of having a rounds list, you can just generate those at the end:

>>> list(enumerate([5,3,6,7], 1))
[(1, 5), (2, 3), (3, 6), (4, 7)]

.format is a nicer to way to create strings in python. You can create "replacement fields" and then assign values to them, like so:

>>> "Here is a {} string: {}".format("cool", "something")
'Here is a cool string: something'

Or you can name them:

>>> "Here is a {adjective} string: {description}".format(adjective="cool", description="something")
'Here is a cool string: something'

Heres what the output looks like:

Round 1: 3 shots. 2 under par
Round 2: 4 shots. par
Round 3: 6 shots. par
Round 4: 4 shots. 1 over par
Round 5: 5 shots. 1 under par
Round 6: 4 shots. par
Round 7: 3 shots. par
Round 8: 2 shots. 2 under par
Round 9: 6 shots. 2 over par
Round 10: 5 shots. par
Round 11: 6 shots. 1 over par
Round 12: 3 shots. par
Round 13: 3 shots. 2 under par
Round 14: 1 shots. 2 under par
Round 15: 6 shots. par
Round 16: 6 shots. 2 over par
Round 17: 2 shots. 1 under par
Round 18: 5 shots. 1 under par

Hopefully that explains everything, let me know if anything doesn't make sense.

Edit: Ah, I think I mistook Round with Hole. My bad, golf isn't my strong suit.

Sean Breckenridge
  • 1,932
  • 16
  • 26
  • Sorry. I don't have any practice with `return "{} under par".format(par - hits)` What I have is a final function that handles all of my values. The empty lists and .appends are located in other functions. My original code: – Amy May 18 '18 at 10:20
  • `def displayGameScores (playersName, rounds, hitsNumber, numberOfHits):` `print("Thanks for playing " + str(playersName + "."))` `if hitsNumber == 5:` `score = "On par"` `elif hitsNumber < 5:` `overParScore = hitsNumber - PAR` `score = str (overParScore) + " over par."` `else:` `underParScore = PAR - hitsNumber` `score = str (underParScore) + " under par."` `for list in zip([rounds], [numberOfHits]):` `print("Round " + str(rounds) + ": " + str(numberOfHits) + " shots. " + str(score))` – Amy May 18 '18 at 10:20
  • I don't know why the code isn't formatting on here :/ – Amy May 18 '18 at 10:22
  • I have however, given it a go through: – Amy May 18 '18 at 10:49
  • `def displayGameScores (playersName, rounds, hitsNumber, numberOfHits): print("Thanks for playing " + str(playersName + ".")) if hitsNumber == 5: return "On par" elif hitsNumber < 5: return "{} under par.".format (hitsNumber - PAR)` – Amy May 18 '18 at 10:50
  • `else: return "{} over par.".format (PAR - hitsNumber) for index, (hitsNumber) in enumerate(zip([numberOfHits], [rounds])): print("Round {rounds}: {hitsNumber} shots. {under_or_over}".format( rounds = index, hitsNumber = hitsNumber, under_or_over = displayGameScore (playersName, rounds, hitsNumber, numberOfHits) ))` – Amy May 18 '18 at 10:50
  • But i get an error stating that my numberOfHits and rounds are not defined. But before I added in your code they worked... – Amy May 18 '18 at 10:56
0
l1 = ["a","b","c"]
l2 = ["1","2","c"]
l3 = ["x","y","z"]
for x in range(0,3):
    print("Letter",l1[x],"Number",l2[x],"Letter",l3[x])

That will print in the format:

Letter a Number 1 Letter x
Letter b Number 2 Letter y
Letter c Number 3 Letter z
El-Chief
  • 383
  • 3
  • 15
  • hi, I have tried your code and replaced with my code and i get an print("round", rounds[x], ": ", numberOfHits[x], str(score)) IndexError: list index out of range – Amy May 18 '18 at 10:29
  • How long are the lists you are using? This code assumes every list is the same length. Make sure you change the range to fit how many values are in your list. – El-Chief May 18 '18 at 15:16