-1

I been doing a project for a few weeks now and the final deadline has come for tommorow, I have completed all of the tasks I was set apart from one, I have been trying to do it for at least a few weeks now on my own but i just can get it wroking so if somone could help me out I would really apreciate it. The task was to create a program that saves data created to a txt file, this is my code so far;

import random

char1=str(input('Please enter a name for character 1: '))
strh1=((random.randrange(1,4))//(random.randrange(1,12))+10)
skl1=((random.randrange(1,4))//(random.randrange(1,12))+10)
print ('%s has a strength value of %s and a skill value of %s)'%(char1,strh1,skl1))


char2=str(input('Please enter a name for character 2: '))
strh2=((random.randrange(1,4))//(random.randrange(1,12))+10)
skl2=((random.randrange(1,4))//(random.randrange(1,12))+10)
print('%s has a strength value of %s and a skill value of %s'%(char1,strh1,skl1))

char1[1]="Strength now {} ".format(strh1)

char1[2]="Skill now {} ".format(skl1)

char2[1]="Strength now {} ".format(strh2)
print()

char2[2]="Skill now {}".format(skl2)
print()

myFile=open('CharAttValues.txt','wt')
for i in Char1:
    myFile.write (i)
    myFile.write ('\n')


for i in Char2:
    myFile.write (i)
    myFile.write('\n')
myFile.close()

Now I am trying to get this to write to a txt but its not working when ever i get to the end of the program where it is meant to save i get this error:

Traceback (most recent call last):
  File "E:\CA2 solution.py", line 14, in <module>
    char1[1]="Strength now {} ".format(strh1)
TypeError: 'str' object does not support item assignment

Im not sure how to get it to work and would really appreciate it if someone could help me to get it working in python 3.3.2 because my deadline is tomorrow and there will be bad consequences if i don't hand it in correctly, its just that i have been trying to figure it out on my own for while now and i don't have any time left so if someone could get it working I would really appreciate it, thanks so much for any help.

2 Answers2

0

What python thinks you are trying to change the 2nd character of char1 - which you can't do - and I am not sure you want to do that anyway - since char1 is already the name of your first character - see line 3 of your file.

I asume from the code that you are trying to make char1 to be actually data about character 1, if so maybe you want to use a dictionary to save the data - and that way you can use keys for the name, strength, and skill of the character - that is a very pythonic way to do things.

if you do use a dictionary, you will need to change your loops too.

Note : A better way to do this would be to have a character class - which holds all the data about a chracter, and has a specialised output method - but that I think is far beyond you for now.

Tony Suffolk 66
  • 9,358
  • 3
  • 30
  • 33
0

Here's a pretty severe rewrite; if you trace through it, you should learn lots ;-)

First, I thought your random-strength code was pretty opaque - it is not at all clear what sort of values it will produce - so I wrote a helper function:

from bisect import bisect_left
import random

def make_rand_distr(value_odds):
    """
    Create a discrete random-value generator
    according to a specified distribution

    Input:
        value_odds:  {x_value: odds_of_x, y_value: odds_of_y, ...}

    Output:
        function which, when called, returns one of
        (x_value or y_value or ...) distributed
        according to the given odds
    """
    # calculate the cumulative distribution
    total = 0.
    cum_prob = []
    values   = []
    for value,odds in value_odds.items():
        total += odds
        cum_prob.append(total)
        values.append(value)
    # create a new function
    def rand_distr():
        # generate a uniformly-distributed random number
        rnd = random.random() * total
        # use that to index into the cumulative distribution
        index = bisect_left(cum_prob, rnd)
        # then return the associated value
        return values[index]
    # return the new function
    return rand_distr

and used that to make more explicit strength and skill functions (the resulting value distribution is identical to your code's):

# When you call rand_strength(), you will get
#   Value   Odds
#    10    27/33
#    11     4/33
#    12     1/33
#    13     1/33
rand_strength = make_rand_distr({10: 27, 11: 4, 12: 1, 13: 1})
rand_skill    = make_rand_distr({10: 27, 11: 4, 12: 1, 13: 1})

(Note that this will let you easily create arbitrary distributions, ones which do not correspond to any obvious function);

then I wrote a Character class:

class Character:
    def __init__(self, ch):
        self.name     = input(
                            "Please enter a name for character {}: "
                            .format(ch)
                        ).strip()
        self.strength = rand_strength()
        self.skill    = rand_skill()

    def __str__(self):
        return (
            "{} has strength={} and skill={}"
            .format(self.name, self.strength, self.skill)
        )

    def __repr__(self):
        return (
            "{name}:\n"
            "  Strength now {strength}\n"
            "  Skill now {skill}\n"
            .format(
                name = self.name,
                strength = self.strength,
                skill = self.skill
            )
        )

and use it like so:

NUM_CHARS = 2
OUT_FILE  = "char_attr_values.txt"

def main():
    # create characters
    chars = [Character(ch) for ch in range(1, NUM_CHARS+1)]

    # display character stats
    for char in chars:
        print(char)     # calls char.__str__ implicitly

    # save character data to output file
    with open(OUT_FILE, "w") as outf:
        for char in chars:
            outf.write(repr(char))  # delegates to char.__repr__

if __name__=="__main__":
    main()
Hugh Bothwell
  • 55,315
  • 8
  • 84
  • 99