Difference between revisions of "Module6-New2"

From CSE330 Wiki
Jump to navigationJump to search
(Created page with "__NOTOC__ In Module 6, you will learn the fundamentals of Python, a popular scripting language, and Regular Expressions, which give you power in text processing. This article...")
 
Line 37: Line 37:
 
=== Learn Python and Regular Expressions ===
 
=== Learn Python and Regular Expressions ===
  
−
Up to this point in CSE 330, you have used only one programming language: PHP. In Module 4, you will learn a new language: Python.
+
Up to this point in CSE 3300, you have used two programming languages: PHP and JavaScript. In Module 6, you will learn a new language: Python.
  
 
Before starting this assignment review:
 
Before starting this assignment review:

Revision as of 15:41, 15 March 2026

In Module 6, you will learn the fundamentals of Python, a popular scripting language, and Regular Expressions, which give you power in text processing.

This article contains your assignments for Module 6.

Learning Goals

  • Regular Expressions
  • Python
  • MCP Fundamentals

Using the Wiki

Text enclosed by < and > should be replaced by content unique to you.

Example

$ sudo useradd -r -m -c "<My Full Name>" <usernameHere>

becomes

$ sudo useradd -r -m -c "Zach Cohn" zcohn

Reading

The following articles on the online class wiki textbook contain information that will help you complete the assignments.

Individual Assignments

Learn Python and Regular Expressions

Up to this point in CSE 3300, you have used two programming languages: PHP and JavaScript. In Module 6, you will learn a new language: Python.

Before starting this assignment review:

You should use Python version 3 or greater.

Write some Regular Expressions

Please write regular expressions that do each of the following:

  1. Match the substring "hello world"
  2. Match strings containing three or more consecutive vowels
  3. Match a flight code of format AA####

Save them as:

regex1.txt regex2.txt regex3.txt

Baseball Stats Counter

The St. Louis Cardinals are the most legendary baseball team in the national league.

In this exercise you will create a Python script that reads box scores from a file and computes the Cardinals' players' batting averages.

Input

Sample input files may be found here:

http://classes.engineering.wustl.edu/cse330/content/cardinals/

Output

Each line in the output should have the format:

XXX: #.###

Players should be sorted by batting average.

Baseball Stats MCP Extension

This project builds a custom MCP server that lets Claude Desktop explore St. Louis Cardinals batting data.

Goal

You will build a Python MCP server that:

  • reads Cardinals batting averages
  • lists team rosters
  • returns top hitters
  • allows player search
  • runs inside Docker
  • connects to Claude Desktop

Project Structure

cardinals-mcp/
├── Dockerfile
├── cardinals_server.py
├── requirements.txt
└── data/
    ├── cardinals-1930.txt
    └── cardinals-1940.txt

Step 1: Prerequisites

Install:

  • Docker Desktop
  • Claude Desktop

Step 2: Create the Files

cardinals_server.py
import os
import sys
import re
from datetime import datetime
from mcp.server.fastmcp import FastMCP

# Initialize MCP server
mcp = FastMCP("CardinalsMCP")

# Data file paths
DATA_DIR = os.path.join(os.path.dirname(__file__), "data")
CARDINALS_1930_FILE = os.path.join(DATA_DIR, "cardinals-1930.txt")
CARDINALS_1940_FILE = os.path.join(DATA_DIR, "cardinals-1940.txt")

# ==== Helper Functions (You DO NOT need to use these) ====

def load_cardinals_data():
    """Load Cardinals player data from both 1930 and 1940 files."""
    data = {"1930": [], "1940": []}
    
    for year, file_path in [("1930", CARDINALS_1930_FILE), ("1940", CARDINALS_1940_FILE)]:
        try:
            with open(file_path, 'r', encoding='utf-8') as f:
                content = f.read()
                data[year] = parse_player_data(content)
        except FileNotFoundError:
            logger.warning(f"Data file not found: {file_path}")
        except Exception as e:
            logger.error(f"Error loading {year} data: {e}")
    
    return data

def parse_player_data(content):
    """Parse player data from the simplified Cardinals text files."""
    players = []
    
    for line in content.split('\n'):
        line = line.strip()
        if not line or line.startswith('#'):
            continue
            
        if ':' in line:
            parts = line.split(':')
            if len(parts) == 2:
                name = parts[0].strip()
                try:
                    batting_avg = float(parts[1].strip())
                    players.append({
                        'name': name,
                        'batting_average': batting_avg
                    })
                except ValueError:
                    continue
    
    return players

def get_all_players(data):
    players=set()
    for year_data in data.values():
        for player in year_data:
            players.add(player['name'])
    return sorted(list(players))

def get_player_by_name(data, player_name):
    player_data=[]
    for year,year_data in data.items():
        for player in year_data:
            if player['name'].lower()==player_name.lower():
                player_data.append({
                    'year':year,
                    'name':player['name'],
                    'batting_average':player['batting_average']
                })
    return player_data

# ==== MCP Tools ====

@mcp.tool()
async def hello(name: str = "world") -> str:
    return f"Hello CSE 3300 Student, {name}!"

@mcp.tool()
async def get_player_stats(player: str = "") -> str:
    # TODO
  

@mcp.tool()
async def get_team_roster(year: str = "1930") -> str:
    # TODO
  

@mcp.tool()
async def get_top_players(year: str = "1930", limit: int = 10) -> str:
    # TODO


@mcp.tool()
async def search_players(search_term: str = "") -> str:
    # TODO

if __name__=="__main__":
    logger.info("Starting Cardinals Historical Data MCP server...")
    try:
        mcp.run(transport="stdio")
    except Exception as e:
        logger.error(f"Server error: {e}", exc_info=True)
        sys.exit(1)

Grading

We will be grading the following aspects of your work. There are 50 points total.

Assignments (including code) must be committed to Github by the end of class on the due date (commit early and often). Failing to commit by the end of class on the due date will result in a 0.

Upload your baseball code and a file with your Regular expressions.

  1. Regular Expressions (15 Points):
    • Your regex files should contain your regex (with no delimiters or flags) and nothing else.
    • Regular Expression 1 Correct and saved in a file named regex1.txt (5 points)
    • Regular Expression 2 Correct and saved in a file named regex2.txt (5 points)
    • Regular Expression 3 Correct and saved in a file named regex3.txt (5 points)
  1. Baseball Stats Counter (25 Points):
    • Solution is written entirely in Python and saved in a file named baseball.py (5 points)
      Note: Failing to write your code in Python 3 will result in losing, at a minimum, points for this category.
    • Correct usage of one or more regular expressions to parse and extract data from each line of the input file (5 points)
      Note: You should not be using str.split to extract data.
    • Script prints a usage message if a command line argument is not present (3 points)
      Note: For an example of a usage message, see https://en.wikipedia.org/wiki/Usage_message#Examples
    • Output is correct for all test cases (12 points)
      This includes sorting and rounding.
  1. Baseball Stats MCP Extension (10 Points):
    • Docker image builds successfully without errors (5 points)
      MCP server (`cardinals_server.py`) loads player data and returns correct results.
    • Includes at least 2 MCP tools (3 points)
      Each tool must function correctly and return expected output through Claude Desktop.
    • README includes 3 different example prompts used in Claude (2 points)
      Each example should show the prompt you asked and the MCP’s response.