1

This is my first SO question.

I am teaching myself to code using Python (and subsequently django). I am working on developing a website that allows local sailing regattas to create groups and track their results. Although this will eventually be a django project using a database, I wanted to write a simple script to 'sketch' the logic.

Objective: I would like a user to be able to create a Race Group, add boats to this group, and print various items.

Current Code: I have written the basic script that allows users to add boats to an existing race group:

#basic program logic to add boats to an existing race group;

#existing race group:

shediac = {
    'location':'Shediac NB',
    'year':2020,
    'boats': boats
}

#default boat list to pass into the race group

 boats=[
    {'name':'name1','owner':'owner1','handicap':0.00},  
]

#loop to take user input when adding new entries

answer=input('do you want to add a boat?: Y/N').upper()

while answer == 'Y':

    name = input('enter the boat name: ')
    owner = input('enter the boat owner''s name: ')
    handicap = input('enter the boat handicap: ')

    boats.append({
        'name': name,
        'handicap': handicap,
        'owner': owner,
        })

    # get user input again to retest for the while loop
    answer=input('do you want to add a boat?: Y/N').upper()

#prompt user to select information to display:

while true: 

what = input('what do you want to view: NAMES / OWNERS / HANDICAP / EXIT: 
').lower()

    if what == 'names':
        for boat in shediac['boats']:
            print(boat['name'])
    elif what == 'owners':
        for boat in shediac['boats']:
            print(boat['owner'])
    elif what == 'handicap':
        for boat in shediac['boats']:
            print(boat['handicap'])
    else:
        print('see you next time')

Challenge:

  1. How do I get a user to create a new race group

  2. How do I take the user input to generate the name of the new race group

I am using a dictionary for each race group, and passing in a list of boats (dictionaries containing various key value pairs). The existing code works to add boat entries to the existing race group (dictionary).

If my approach is entirely wrong, I welcome any better solutions! My primary interest is understanding how to approach such a problem.

Thanks.

Mateen Ulhaq
  • 24,552
  • 19
  • 101
  • 135
JulienEast
  • 27
  • 7
  • What's a `RaceGroup`? Something with a location, year, and boats? You should probably put that in a [`dataclass`](https://stackoverflow.com/a/52283085/365102). (See first code snippet.) Or just a regular class if you're on Python 3.7 or earlier. – Mateen Ulhaq Jan 17 '20 at 02:48
  • Welcome to Stack Overflow! Check out the [tour] and [ask]. Your code doesn't run. You need to provide a [mre]. As well, part of your question has already been asked here: [How do I create a variable number of variables?](https://stackoverflow.com/q/1373164/4518341) In short, you should use a dict - a nested dict in your case. The only part you would need to figure out is how to take user input for a nested dict. – wjandrea Jan 17 '20 at 02:57
  • Thanks! will read up on these items. Thinking about it now, my question could be simply how to get a user to generate a name for a new dictionary. – JulienEast Jan 17 '20 at 03:03

1 Answers1

0

While storing things inside dictionaries is fine, it's sometimes clearer to have dedicated types:

from dataclasses import dataclass
from typing import List

@dataclass
class Boat:
    name: str
    owner: str
    handicap: float

@dataclass
class RaceGroup:
    location: str
    year: int
    boats: List[Boat]

Next up, define a some input methods. Here's a method that returns a Boat:

def input_boat() -> Boat:
    name = input("enter the boat name: ")
    owner = input("enter the boat owner's name: ")
    handicap = float(input("enter the boat handicap: "))
    return Boat(name, owner, handicap)

Now for a method that returns a list of Boats. We can reuse input_boat here inside a loop:

def input_boat_list() -> List[Boat]:
    boats = []
    while True:
        response = input('do you want to add a boat? [Y/N]: ').upper()
        if response == "N":
            return boats
        if response == "Y":
            boat = input_boat()
            boats.append(boat)

Here's a method that returns a RaceGroup:

def input_race_group() -> RaceGroup:
    location = input("enter the location: ")
    year = input("enter the year: ")
    boats = input_boat_list()
    return RaceGroup(location, year, boats)

Programming is easier and code becomes clearer when you break things up into subproblems!


We can now use the "library" of functions that we've created above in our main program:

default_boat_list = [
    Boat(name="name1", owner="owner1", handicap=0.00),  
]

shediac = RaceGroup(
    location="Shediac NB",
    year=2020,
    boats=list(default_boat_list),
    # list(...) creates a "shallow" copy of our earlier list
}

race_groups = [shediac]

while True:
    response = input('do you want to add a race group? [Y/N]: ').upper()
    if response == "N":
        break
    if response == "Y":
        race_group = input_race_group()
        race_group.boats = default_boat_list + race_group.boats
        race_groups.append(race_group)

print(race_groups)
Mateen Ulhaq
  • 24,552
  • 19
  • 101
  • 135
  • Thanks for the thorough response - I will read up on dataclass objects as they seem to be quite useful in this situation. – JulienEast Jan 18 '20 at 16:03