### Install and Build Documentation Source: https://github.com/hassanemam/pyp6xer/blob/master/docs/BUILD_GUIDE.md Installs project dependencies and builds the HTML documentation using make commands. ```bash pip install -r docs/requirements.txt make docs ``` -------------------------------- ### Install PyP6Xer from Source Source: https://github.com/hassanemam/pyp6xer/blob/master/docs/source/troubleshooting.md Installs PyP6Xer by cloning the repository and installing it in editable mode. This is useful for developers who want to modify the library. ```bash git clone https://github.com/HassanEmam/PyP6Xer.git cd PyP6Xer pip install -e . ``` -------------------------------- ### GitHub Actions Workflow for Documentation Source: https://github.com/hassanemam/pyp6xer/blob/master/docs/BUILD_GUIDE.md An example GitHub Actions workflow to automatically build and deploy documentation on code pushes or pull requests. ```yaml name: Build Documentation on: [push, pull_request] jobs: docs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Setup Python uses: actions/setup-python@v2 with: python-version: '3.11' - name: Install dependencies run: pip install -r docs/requirements.txt - name: Build docs run: make docs - name: Deploy to GitHub Pages uses: peaceiris/actions-gh-pages@v3 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./docs/build/html ``` -------------------------------- ### Install PyP6Xer from PyPI Source: https://github.com/hassanemam/pyp6xer/blob/master/docs/source/troubleshooting.md Installs the PyP6Xer library using pip, the Python package installer. This is the recommended method for most users. ```bash pip install PyP6XER ``` -------------------------------- ### Install gh-pages Tool Source: https://github.com/hassanemam/pyp6xer/blob/master/PUBLISHING_GUIDE.md Bash commands to install the gh-pages tool globally using npm or pip for manual deployment to GitHub Pages. ```bash npm install -g gh-pages # OR use Python version pip install ghp-import ``` -------------------------------- ### Verify PyP6Xer Installation Source: https://github.com/hassanemam/pyp6xer/blob/master/docs/source/troubleshooting.md Tests the PyP6Xer installation by importing the library and attempting to read a sample XER file. It prints a success message or an error if the installation failed. ```python import xerparser from xerparser.reader import Reader # Test with a sample XER file try: xer = Reader("sample.xer") print("PyP6Xer installed successfully!") print(f"Projects found: {len(xer.projects)}") except Exception as e: print(f"Installation issue: {e}") ``` -------------------------------- ### Sphinx Configuration Example (conf.py) Source: https://github.com/hassanemam/pyp6xer/blob/master/docs/BUILD_GUIDE.md Illustrates key settings within Sphinx's conf.py for auto-generating API documentation using AutoAPI and setting the theme. ```python # -- Project information ----------------------------------------------------- project = '/hassanemam/pyp6xer' copyright = 'Year, Author' author = 'Author' # -- General configuration --------------------------------------------------- # Add any Sphinx extension module names here, as strings. extensions = [ 'sphinx.ext.autodoc', 'sphinx.ext.napoleon', 'sphinx.ext.intersphinx', 'autoapi.extension', ] # AutoAPI configuration autoapi_type = 'python' autoapi_dirs = ['../src'] # Adjust to your source directory # -- Options for HTML output ------------------------------------------------- # The theme to use for HTML and HTML Help pages. html_theme = 'sphinx_rtd_theme' ``` -------------------------------- ### Troubleshooting Build Failures Source: https://github.com/hassanemam/pyp6xer/blob/master/PUBLISHING_GUIDE.md Bash commands to help resolve common build failures by installing dependencies, cleaning the build, and rebuilding documentation. ```bash # Check build logs in GitHub Actions # Common fixes: pip install -r docs/requirements.txt make clean make docs ``` -------------------------------- ### Exception Example for Missing Filename Source: https://github.com/hassanemam/pyp6xer/blob/master/docs/source/troubleshooting.md Shows an exception that is raised when attempting to write an XER file without providing a filename. ```text Exception: You have to provide the filename ``` -------------------------------- ### Install PyP6Xer Source: https://github.com/hassanemam/pyp6xer/blob/master/docs/source/getting_started.md Instructions for installing the PyP6Xer library using pip from PyPI or from source. ```bash pip install PyP6XER ``` ```bash git clone https://github.com/HassanEmam/PyP6Xer.git cd PyP6Xer pip install -e . ``` -------------------------------- ### Serve Documentation Locally Source: https://github.com/hassanemam/pyp6xer/blob/master/docs/BUILD_GUIDE.md Builds and serves the documentation locally for review, typically on http://localhost:8000. ```bash make serve ``` -------------------------------- ### Build and Deploy Documentation (Manual) Source: https://github.com/hassanemam/pyp6xer/blob/master/PUBLISHING_GUIDE.md Bash commands to build documentation using 'make docs' and deploy it to the 'gh-pages' branch using 'ghp-import'. ```bash # Build documentation make docs # Deploy to gh-pages branch ghp-import -n -p -f docs/build/html ``` -------------------------------- ### Debug XER Loading and File Information Source: https://github.com/hassanemam/pyp6xer/blob/master/docs/source/troubleshooting.md Loads an XER file with detailed debug information, including file size, loading time, and counts of projects, activities, resources, and relationships. It also includes error handling and prints tracebacks for debugging. Requires `os` and `time` modules. ```python import logging import os import time # Set up logging for debugging logging.basicConfig(level=logging.DEBUG) def debug_xer_loading(filename): """Load XER with debug information.""" print(f"Loading XER file: {filename}") try: # Check file size file_size = os.path.getsize(filename) print(f"File size: {file_size:,} bytes") # Load and report progress start_time = time.time() xer = Reader(filename) # Assuming Reader is defined elsewhere load_time = time.time() - start_time print(f"Loaded in {load_time:.2f} seconds") print(f"Projects: {len(xer.projects)}") print(f"Activities: {len(xer.activities)}") print(f"Resources: {len(xer.resources)}") print(f"Relationships: {len(xer.relations)}") return xer except Exception as e: print(f"Error loading XER: {e}") import traceback traceback.print_exc() return None # Usage # xer = debug_xer_loading("project.xer") ``` -------------------------------- ### Install PyP6XER Source: https://github.com/hassanemam/pyp6xer/blob/master/docs/source/quick_reference.md Installs the PyP6XER library using pip. This is the first step to using the library for parsing XER files. ```bash pip install PyP6XER ``` -------------------------------- ### Basic Activity Information Source: https://github.com/hassanemam/pyp6xer/blob/master/docs/source/getting_started.md Provides an example of iterating through the first few activities of a project to display their names, IDs, duration, status, completion percentage, and scheduled start/finish dates. ```python for activity in project.activities[:5]: # First 5 activities print(f"\nActivity: {activity.task_name}") print(f" ID: {activity.task_code}") print(f" Duration: {activity.target_drtn_hr_cnt} hours") print(f" Status: {activity.status_code}") print(f" % Complete: {activity.phys_complete_pct}%") print(f" Start: {activity.act_start_date}") print(f" Finish: {activity.act_end_date}") ``` -------------------------------- ### Local Documentation Testing Source: https://github.com/hassanemam/pyp6xer/blob/master/PUBLISHING_GUIDE.md Bash commands to build and serve documentation locally for testing before deployment. ```bash # Always test locally first make docs make serve # Open http://localhost:8000 to verify ``` -------------------------------- ### Sphinx Custom Domain Configuration Source: https://github.com/hassanemam/pyp6xer/blob/master/PUBLISHING_GUIDE.md Python code snippet for Sphinx configuration file (conf.py) to include a CNAME file for custom domain setup. ```python html_extra_path = ['_static/CNAME'] ``` -------------------------------- ### Handle FileNotFoundError Source: https://github.com/hassanemam/pyp6xer/blob/master/docs/source/troubleshooting.md Provides solutions for the FileNotFoundError, which occurs when the specified XER file cannot be found. It demonstrates checking file existence and using absolute paths. ```python import os # Check if file exists if os.path.exists("project.xer"): xer = Reader("project.xer") else: print("File not found. Check the file path.") # Use absolute path xer = Reader(r"C:\\path\\to\\your\\project.xer") ``` -------------------------------- ### Theme Troubleshooting Source: https://github.com/hassanemam/pyp6xer/blob/master/PUBLISHING_GUIDE.md Provides basic troubleshooting steps for theme-related issues in Sphinx documentation. ```bash # Clear browser cache # Check conf.py theme settings # Verify CSS files are loading ``` -------------------------------- ### Install PyP6XER Source: https://github.com/hassanemam/pyp6xer/blob/master/docs/source/index.md Installs the PyP6XER library using pip. This is the first step to using the library for parsing Primavera P6 XER files. ```bash pip install PyP6XER ``` -------------------------------- ### Project Dependencies Source: https://github.com/hassanemam/pyp6xer/blob/master/PUBLISHING_GUIDE.md Lists the required Python packages for building the project documentation using Sphinx. ```python sphinx>=8.0.0 sphinx-rtd-theme>=3.0.0 sphinx-autoapi>=3.0.0 myst-parser>=4.0.0 sphinx-copybutton>=0.5.0 ``` -------------------------------- ### Load Multiple XER Files Source: https://github.com/hassanemam/pyp6xer/blob/master/docs/source/examples.md Demonstrates how to load multiple XER files from a directory using glob and the Reader class. Includes basic error handling for file loading. ```python from xerparser.reader import Reader import glob # Load all XER files in a directory xer_files = [] for filename in glob.glob("*.xer"): try: xer = Reader(filename) xer_files.append(xer) print(f"Loaded: {filename}") except Exception as e: print(f"Failed to load {filename}: {e}") ``` -------------------------------- ### Generate Project Summary Report Source: https://github.com/hassanemam/pyp6xer/blob/master/docs/source/examples.md A Python function to generate a detailed summary report for a given project loaded from an XER file. It includes basic project information, schedule dates, and activity statistics (not started, in progress, completed). ```python def project_summary(xer_file): """Generate a comprehensive project summary.""" for project in xer_file.projects: print(f"\n{'='*50}") print(f"PROJECT SUMMARY: {project.proj_short_name}") print(f"{'='*50}") # Basic info print(f"Project Name: {project.proj_name}") print(f"Project Manager: {project.proj_mgr}") print(f"Status: {project.status_code}") # Dates print(f"\nSCHEDULE:") print(f"Data Date: {project.last_recalc_date}") print(f"Planned Start: {project.plan_start_date}") print(f"Planned Finish: {project.plan_end_date}") # Activity statistics activities = project.activities total_activities = len(activities) not_started = len([a for a in activities if a.status_code == "TK_NotStart"]) in_progress = len([a for a in activities if a.status_code == "TK_Active"]) completed = len([a for a in activities if a.status_code == "TK_Complete"]) print(f"\nACTIVITIES:") print(f"Total: {total_activities}") print(f"Not Started: {not_started}") print(f"In Progress: {in_progress}") print(f"Completed: {completed}") # Progress calculation if total_activities > 0: completion_pct = (completed / total_activities) * 100 print(f"Completion: {completion_pct:.1f}%") # Usage xer = Reader("project.xer") project_summary(xer) ``` -------------------------------- ### Network Analysis with PyP6Xer Source: https://github.com/hassanemam/pyp6xer/blob/master/docs/source/examples.md Analyzes the network structure of a project, including counting activities, relationships, identifying start and end activities, and summarizing relationship types. It processes activities and relationships from the XER file. ```python def network_analysis(xer_file): """Analyze the project network structure.""" activities = xer_file.activities.get_list() relationships = xer_file.relations.get_list() # Count relationship types relationship_types = {} for rel in relationships: rel_type = rel.pred_type relationship_types[rel_type] = relationship_types.get(rel_type, 0) + 1 # Find activities with no predecessors (start activities) activity_ids = {a.task_id for a in activities} successor_ids = {r.task_id for r in relationships} start_activities = activity_ids - successor_ids # Find activities with no successors (end activities) predecessor_ids = {r.pred_task_id for r in relationships} end_activities = activity_ids - predecessor_ids print(f"NETWORK ANALYSIS") print(f"{ '='*30}") print(f"Total Activities: {len(activities)}") print(f"Total Relationships: {len(relationships)}") print(f"Start Activities: {len(start_activities)}") print(f"End Activities: {len(end_activities)}") print(f"\nRelationship Types:") for rel_type, count in relationship_types.items(): print(f" {rel_type}: {count}") # Usage network_analysis(xer) ``` -------------------------------- ### Read the Docs Configuration Source: https://github.com/hassanemam/pyp6xer/blob/master/PUBLISHING_GUIDE.md YAML configuration file for Read the Docs to define build environment, Python version, dependencies, and Sphinx configuration. ```yaml version: 2 build: os: ubuntu-22.04 tools: python: "3.11" python: install: - requirements: docs/requirements.txt - method: pip path: . sphinx: configuration: docs/source/conf.py builder: html fail_on_warning: false ``` -------------------------------- ### Optimize Large Project Processing with Lookups Source: https://github.com/hassanemam/pyp6xer/blob/master/docs/source/troubleshooting.md Optimizes the processing of large projects by creating lookup dictionaries for activities and resources, enabling faster data access. This reduces the time complexity of searching for specific items within the project data. ```python import time def optimize_large_project_processing(xer): """Optimize processing for large projects.""" start_time = time.time() # Create lookup dictionaries for faster access activity_lookup = {a.task_id: a for a in xer.activities} resource_lookup = {r.rsrc_id: r for r in xer.resources} print(f"Created lookups in {time.time() - start_time:.2f} seconds") # Use lookups instead of iterating def find_activity(task_id): return activity_lookup.get(task_id) def find_resource(rsrc_id): return resource_lookup.get(rsrc_id) return activity_lookup, resource_lookup # Usage # activity_lookup, resource_lookup = optimize_large_project_processing(xer) ``` -------------------------------- ### Create Efficient Lookups Source: https://github.com/hassanemam/pyp6xer/blob/master/docs/source/troubleshooting.md Generates lookup dictionaries for fast access to activities, resources, and assignments based on project, WBS, resource type, and assignment relationships. This function takes a `xer` object as input and returns a dictionary containing these pre-processed lookups. ```python def create_efficient_lookups(xer): """Create efficient lookup structures.""" lookups = { 'activities_by_project': {}, 'activities_by_wbs': {}, 'resources_by_type': {}, 'assignments_by_activity': {}, 'assignments_by_resource': {} } # Group activities by project for activity in xer.activities: proj_id = activity.proj_id if proj_id not in lookups['activities_by_project']: lookups['activities_by_project'][proj_id] = [] lookups['activities_by_project'][proj_id].append(activity) # Group activities by WBS for activity in xer.activities: wbs_id = activity.wbs_id if wbs_id not in lookups['activities_by_wbs']: lookups['activities_by_wbs'][wbs_id] = [] lookups['activities_by_wbs'][wbs_id].append(activity) # Group resources by type for resource in xer.resources: rsrc_type = resource.rsrc_type if rsrc_type not in lookups['resources_by_type']: lookups['resources_by_type'][rsrc_type] = [] lookups['resources_by_type'][rsrc_type].append(resource) # Group assignments for assignment in xer.activityresources: # By activity task_id = assignment.task_id if task_id not in lookups['assignments_by_activity']: lookups['assignments_by_activity'][task_id] = [] lookups['assignments_by_activity'][task_id].append(assignment) # By resource rsrc_id = assignment.rsrc_id if rsrc_id not in lookups['assignments_by_resource']: lookups['assignments_by_resource'][rsrc_id] = [] lookups['assignments_by_resource'][rsrc_id].append(assignment) return lookups # Usage # lookups = create_efficient_lookups(xer) # Fast access to project activities # project_activities = lookups['activities_by_project'].get(project_id, []) ``` -------------------------------- ### Load XER File Source: https://github.com/hassanemam/pyp6xer/blob/master/docs/source/quick_reference.md Loads an XER file using the `Reader` class from `xerparser.reader`. This is the primary method to start parsing project data. ```python from xerparser.reader import Reader # Load XER file xer = Reader("project.xer") ``` -------------------------------- ### Write XER Files Source: https://github.com/hassanemam/pyp6xer/blob/master/docs/source/examples.md Shows how to load an existing XER file, modify its data (placeholder for modification logic), and then write the changes to a new XER file. ```python from xerparser.reader import Reader # Load and modify data xer = Reader("input.xer") # Make modifications to the data... # (See modification examples below) # Write to a new file xer.write("output.xer") print("XER file written successfully") ``` -------------------------------- ### GitHub Pages Badges Source: https://github.com/hassanemam/pyp6xer/blob/master/PUBLISHING_GUIDE.md Markdown snippets for adding documentation status badges to your README.md file, linking to your GitHub Pages deployment and build status. ```markdown [![Documentation](https://img.shields.io/badge/docs-GitHub%20Pages-blue)](https://hassanemam.github.io/PyP6Xer/) [![Documentation Status](https://github.com/HassanEmam/PyP6Xer/workflows/Build%20and%20Deploy%20Documentation/badge.svg)](https://github.com/HassanEmam/PyP6Xer/actions) [![GitHub Pages](https://img.shields.io/badge/GitHub%20Pages-live-green)](https://hassanemam.github.io/PyP6Xer/) ``` -------------------------------- ### Install PyP6Xer Source: https://github.com/hassanemam/pyp6xer/blob/master/README.md Installs the PyP6Xer library using pip. Alternatively, you can clone the repository and install from source. ```bash pip install PyP6XER ``` ```bash git clone https://github.com/HassanEmam/PyP6Xer.git cd PyP6Xer pip install -e . ``` -------------------------------- ### Google-Style Docstring Example Source: https://github.com/hassanemam/pyp6xer/blob/master/docs/source/contributing.md Demonstrates the recommended Google-style docstring format for Python functions, including parameters, return values, and raised exceptions. ```python def function_name(param1: str, param2: int) -> bool: """Brief description of the function. Longer description if needed. Args: param1: Description of param1 param2: Description of param2 Returns: Description of return value Raises: ValueError: Description of when this is raised """ ``` -------------------------------- ### Export Project to JSON Source: https://github.com/hassanemam/pyp6xer/blob/master/docs/source/examples.md Exports project information and its activities to a JSON file. It includes a helper function to serialize datetime objects to ISO format and converts activity data into a dictionary structure. ```python import json from datetime import datetime def activity_to_dict(activity): """Convert activity to dictionary for JSON export.""" def serialize_date(obj): if isinstance(obj, datetime): return obj.isoformat() return obj return { 'task_id': activity.task_id, 'task_code': activity.task_code, 'task_name': activity.task_name, 'status_code': activity.status_code, 'duration_hours': activity.target_drtn_hr_cnt, 'start_date': serialize_date(activity.act_start_date), 'end_date': serialize_date(activity.act_end_date), 'percent_complete': activity.phys_complete_pct, 'total_float': activity.total_float_hr_cnt, 'wbs_id': activity.wbs_id } def export_project_to_json(project, filename): """Export project data to JSON.""" project_data = { 'project_info': { 'id': project.proj_id, 'short_name': project.proj_short_name, 'name': project.proj_name, 'status': project.status_code }, 'activities': [activity_to_dict(a) for a in project.activities] } with open(filename, 'w', encoding='utf-8') as jsonfile: json.dump(project_data, jsonfile, indent=2, ensure_ascii=False) print(f"Exported project to {filename}") # Usage # project = xer.projects[0] # export_project_to_json(project, "project_data.json") ``` -------------------------------- ### Install Development Dependencies Source: https://github.com/hassanemam/pyp6xer/blob/master/docs/source/contributing.md Installs the PyP6Xer package in editable mode along with essential development and testing tools like pytest and Sphinx. ```bash pip install -e . pip install pytest pytest-cov sphinx sphinx-rtd-theme ``` -------------------------------- ### Basic Test Structure Example Source: https://github.com/hassanemam/pyp6xer/blob/master/docs/source/contributing.md Provides an example of a Python unit test function using pytest, including a docstring explaining the test's purpose and an assertion. ```python def test_reader_loads_basic_xer_file(): """Test that Reader can load a basic XER file.""" reader = Reader("test_data/sample.xer") assert reader.projects.count > 0 assert len(reader.activities) > 0 ``` -------------------------------- ### Resource Utilization Report Source: https://github.com/hassanemam/pyp6xer/blob/master/docs/source/examples.md Generates a report detailing resource usage, comparing budgeted hours against actual hours for each resource in a project. It calculates and displays the utilization percentage for resources with budgeted hours. ```python def resource_utilization_report(xer_file): """Generate a resource utilization report.""" resources = xer_file.resources assignments = xer_file.activityresources print(f"RESOURCE UTILIZATION REPORT") print(f"{ '='*50}") for resource in resources: # Find all assignments for this resource resource_assignments = [a for a in assignments if a.rsrc_id == resource.rsrc_id] total_budget = sum(a.target_qty or 0 for a in resource_assignments) total_actual = sum(a.act_reg_qty or 0 for a in resource_assignments) print(f"\nResource: {resource.rsrc_name}") print(f" Type: {resource.rsrc_type}") print(f" Assignments: {len(resource_assignments)}") print(f" Budgeted Hours: {total_budget}") print(f" Actual Hours: {total_actual}") if total_budget > 0: utilization = (total_actual / total_budget) * 100 print(f" Utilization: {utilization:.1f}%") # Usage # resource_utilization_report(xer) ``` -------------------------------- ### Troubleshooting Deprecated GitHub Actions Source: https://github.com/hassanemam/pyp6xer/blob/master/PUBLISHING_GUIDE.md Bash command and comments illustrating how to update deprecated GitHub Actions versions in your workflow file. ```bash # If you see warnings about deprecated actions: # Error: actions/upload-artifact@v3 is deprecated # Solution: Update to latest versions in .github/workflows/docs.yml: # - actions/checkout@v4 # - actions/setup-python@v5 # - actions/cache@v4 # - actions/upload-artifact@v4 # - peaceiris/actions-gh-pages@v4 ``` -------------------------------- ### ValueError Example for Date Parsing Source: https://github.com/hassanemam/pyp6xer/blob/master/docs/source/troubleshooting.md Illustrates a ValueError that occurs when a date string does not match the expected format, specifically highlighting an invalid month and day. ```text ValueError: time data '2023-13-45 25:70' does not match format '%Y-%m-%d %H:%M' ``` -------------------------------- ### Load XER File and Display Basic Project Info Source: https://github.com/hassanemam/pyp6xer/blob/master/docs/source/getting_started.md Demonstrates how to load an XER file using the `Reader` class and display fundamental project details such as the number of projects, project name, start and end dates, and the total number of activities. ```python from xerparser.reader import Reader # Load the XER file xer_file = Reader("sample.xer") # Display basic information print(f"Found {xer_file.projects.count} project(s)") # Iterate through projects for project in xer_file.projects: print(f"\nProject: {project.proj_short_name}") print(f"Project Name: {project.proj_name}") print(f"Start Date: {project.plan_start_date}") print(f"Finish Date: {project.plan_end_date}") print(f"Number of Activities: {len(project.activities)}") ``` -------------------------------- ### Handle UnicodeDecodeError Source: https://github.com/hassanemam/pyp6xer/blob/master/docs/source/troubleshooting.md Addresses UnicodeDecodeError by attempting to read the XER file with different common encodings. PyP6Xer usually handles this automatically, but this provides a manual fallback. ```python import codecs # Try different encodings encodings_to_try = ['utf-8', 'latin-1', 'cp1252', 'iso-8859-1'] for encoding in encodings_to_try: try: with codecs.open("project.xer", 'r', encoding=encoding) as f: content = f.read() print(f"File readable with {encoding} encoding") break except UnicodeDecodeError: continue ``` -------------------------------- ### Manage Memory for Large XER Files Source: https://github.com/hassanemam/pyp6xer/blob/master/docs/source/troubleshooting.md Offers a strategy for handling MemoryError when processing very large XER files by forcing garbage collection before loading and suggesting alternative approaches. ```python import gc # For very large XER files, monitor memory usage def load_large_xer(filename): """Load large XER files with memory management.""" print("Loading large XER file...") # Force garbage collection before loading gc.collect() try: xer = Reader(filename) print(f"Loaded successfully: {len(xer.activities)} activities") return xer except MemoryError: print("File too large for available memory") print("Consider:") print("- Splitting the XER file") print("- Using a machine with more RAM") print("- Processing subsets of data") return None xer = load_large_xer("large_project.xer") ``` -------------------------------- ### XER File Export and Validation Source: https://github.com/hassanemam/pyp6xer/blob/master/docs/source/troubleshooting.md Demonstrates how to export modified XER files and validate the export by comparing the number of activities in the original and exported files. Ensures data integrity after modifications. ```python # Always provide filename for export try: xer.write("modified_project.xer") print("Export successful") except Exception as e: print(f"Export failed: {e}") # Validate export def validate_export(original_file, exported_file): """Validate exported XER file.""" try: original = Reader(original_file) exported = Reader(exported_file) print(f"Original activities: {len(original.activities)}") print(f"Exported activities: {len(exported.activities)}") if len(original.activities) == len(exported.activities): print("✅ Export validation passed") else: print("⚠️ Activity count mismatch") except Exception as e: print(f"Export validation failed: {e}") # Usage # xer.write("output.xer") # validate_export("input.xer", "output.xer") ``` -------------------------------- ### Set Up Virtual Environment Source: https://github.com/hassanemam/pyp6xer/blob/master/docs/source/contributing.md Creates and activates a Python virtual environment for isolating project dependencies. Includes commands for both Linux/macOS and Windows. ```bash python -m venv .venv source .venv/bin/activate # On Windows: .venv\Scripts\activate ``` -------------------------------- ### Safely Access Object Properties Source: https://github.com/hassanemam/pyp6xer/blob/master/docs/source/troubleshooting.md Demonstrates how to safely access object properties using `getattr` to avoid AttributeError when a property might be missing. It provides a default value if the property does not exist. ```python # Always check if properties exist before accessing def safe_get_property(obj, property_name, default=None): """Safely get object property.""" return getattr(obj, property_name, default) # Example usage for activity in xer.activities: duration = safe_get_property(activity, 'target_drtn_hr_cnt', 0) start_date = safe_get_property(activity, 'target_start_date') if start_date: print(f"Activity: {activity.task_name}, Start: {start_date}") ``` -------------------------------- ### Handle None Values in Calculations Source: https://github.com/hassanemam/pyp6xer/blob/master/docs/source/troubleshooting.md Provides methods to handle `None` values gracefully during calculations, preventing TypeErrors. It shows using a helper function for summation and using the `or` operator for default values. ```python # Handle None values in calculations def safe_sum(values): """Sum values, treating None as 0.""" return sum(v for v in values if v is not None) # Example: Calculate total cost total_cost = safe_sum([ assignment.target_cost for assignment in xer.activityresources ]) # Or use default values for assignment in xer.activityresources: cost = assignment.target_cost or 0 # Use 0 if None hours = assignment.target_qty or 0 ``` -------------------------------- ### Validate and Handle Corrupted XER Files Source: https://github.com/hassanemam/pyp6xer/blob/master/docs/source/troubleshooting.md Includes a function to validate the basic structure of an XER file before loading it, helping to prevent errors like 'AttributeError: 'NoneType' object has no attribute 'strip''. ```python def validate_xer_file(filename): """Validate XER file format.""" try: with open(filename, 'r', encoding='utf-8', errors='ignore') as f: first_line = f.readline() if not first_line.startswith('ERMHDR'): print("Warning: File doesn't appear to be a valid XER file") return False return True except Exception as e: print(f"File validation error: {e}") return False # Use validation before loading if validate_xer_file("project.xer"): xer = Reader("project.xer") else: print("Invalid XER file") ``` -------------------------------- ### Memory Optimization for Large XER Files Source: https://github.com/hassanemam/pyp6xer/blob/master/docs/source/troubleshooting.md Provides a method for processing large XER files efficiently by loading the file and then processing activities in chunks. It includes forcing garbage collection after each chunk to manage memory usage. ```python import gc def process_large_xer_efficiently(filename): """Process large XER files efficiently.""" # Load file xer = Reader(filename) # Process in chunks if needed chunk_size = 1000 activities = xer.activities for i in range(0, len(activities), chunk_size): chunk = activities[i:i + chunk_size] # Process chunk for activity in chunk: # Your processing here pass # Force garbage collection after each chunk gc.collect() return xer ``` -------------------------------- ### Basic PyP6Xer Usage Source: https://github.com/hassanemam/pyp6xer/blob/master/docs/source/index.md Demonstrates basic usage of the PyP6Xer library to load an XER file and access project, activity, resource, and relationship data. It shows how to iterate through these elements and print key information. ```python from xerparser.reader import Reader # Load an XER file xer = Reader("project.xer") # Access projects for project in xer.projects: print(f"Project: {project.proj_short_name}") # Access activities in the project for activity in project.activities: print(f" Activity: {activity.task_name}") print(f" Duration: {activity.target_drtn_hr_cnt} hours") print(f" Status: {activity.status_code}") # Access resources for resource in xer.resources: print(f"Resource: {resource.rsrc_name}") # Access relationships for relation in xer.relations: print(f"Relationship: {relation.pred_task_id} -> {relation.task_id}") ``` -------------------------------- ### Safe Date Parsing with Error Handling Source: https://github.com/hassanemam/pyp6xer/blob/master/docs/source/troubleshooting.md Safely parses date strings using a specified format, returning None for invalid or empty inputs. Handles ValueError during parsing by printing an error message. Useful for robust date handling in applications. ```python from datetime import datetime def safe_parse_date(date_string, format_string='%Y-%m-%d %H:%M'): """Safely parse date strings.""" if not date_string or date_string.strip() == '': return None try: return datetime.strptime(date_string.strip(), format_string) except ValueError as e: print(f"Date parsing error: {date_string} - {e}") return None # Use with activities # for activity in xer.activities: # if hasattr(activity, 'target_start_date') and activity.target_start_date: # # PyP6Xer handles this automatically, but for custom parsing: # start_date = safe_parse_date(str(activity.target_start_date)) ``` -------------------------------- ### Validate XER Data Integrity Source: https://github.com/hassanemam/pyp6xer/blob/master/docs/source/troubleshooting.md Validates the integrity of loaded XER data by checking for orphaned activities (activities not linked to a project) and missing resources (assignments referencing non-existent resources). It prints any found issues and returns a boolean indicating if validation passed. ```python def validate_xer_data(xer): """Validate XER data integrity.""" issues = [] # Check for orphaned activities project_ids = {p.proj_id for p in xer.projects} for activity in xer.activities: if activity.proj_id not in project_ids: issues.append(f"Orphaned activity: {activity.task_id}") # Check for missing resources resource_ids = {r.rsrc_id for r in xer.resources} for assignment in xer.activityresources: if assignment.rsrc_id not in resource_ids: issues.append(f"Missing resource: {assignment.rsrc_id}") # Check for circular dependencies # (Simplified check - full implementation would be more complex) if issues: print("Data validation issues found:") for issue in issues[:10]: # Show first 10 print(f" - {issue}") if len(issues) > 10: print(f" ... and {len(issues) - 10} more issues") else: print("✅ Data validation passed") return len(issues) == 0 # Usage # if xer: # validate_xer_data(xer) ``` -------------------------------- ### Access Projects Source: https://github.com/hassanemam/pyp6xer/blob/master/docs/source/quick_reference.md Iterates through all projects loaded from the XER file and prints their short names and the number of activities within each project. ```python # Get all projects for project in xer.projects: print(f"Project: {project.proj_short_name}") print(f"Activities: {len(project.activities)}") ```