Essential utility classes and helper methods for common programming tasks including validation, file operations, and mathematical computations.
Recent Improvements (v0.2.0):
- Enhanced Validation: Improved validation utilities with better error messages
- File Operations: Safer file handling with automatic directory creation
- Math Functions: Enhanced mathematical utilities with edge case protection
- Better Testing: Comprehensive unit test coverage for all utility methods
- Package ID:
PowerCSharp.Utilities - Version: 0.2.0
- Target Frameworks: .NET 8.0, .NET Standard 2.0
- Dependencies:
PowerCSharp.Corev0.3.0 (for shared interfaces)
dotnet add package PowerCSharp.UtilitiesSafe and reliable file operations with error handling and automatic directory creation.
- Safe file operations with comprehensive error handling
- Automatic directory creation when writing files
- Human-readable file size formatting
- Graceful error recovery without exceptions
using PowerCSharp.Utilities;
// Safe file reading
string content = FileHelper.SafeReadAllText("config.json");
// Returns empty string if file doesn't exist or can't be read
// Safe file writing with automatic directory creation
bool success = FileHelper.SafeWriteAllText("logs/app.log", "Application started");
// Creates directory if needed, returns success/failure
// Human-readable file sizes
string size1 = FileHelper.GetFileSize(1024); // "1 KB"
string size2 = FileHelper.GetFileSize(1024 * 1024); // "1 MB"
string size3 = FileHelper.GetFileSize(1024 * 1024 * 1024); // "1 GB"public class LogManager
{
private readonly string _logDirectory;
public LogManager(string logDirectory)
{
_logDirectory = logDirectory;
}
public void LogError(string message, Exception exception = null)
{
string timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
string logEntry = $"[{timestamp}] ERROR: {message}";
if (exception != null)
{
logEntry += $"\nException: {exception}";
}
string logFile = Path.Combine(_logDirectory, $"error_{DateTime.Now:yyyyMMdd}.log");
bool success = FileHelper.SafeWriteAllText(logFile, logEntry + "\n", append: true);
if (!success)
{
// Fallback logging
Console.WriteLine($"Failed to write to log file: {logFile}");
}
}
public string GetLogDirectorySize()
{
var directory = new DirectoryInfo(_logDirectory);
long totalSize = directory.GetFiles("*.*", SearchOption.AllDirectories)
.Sum(f => f.Length);
return FileHelper.GetFileSize(totalSize);
}
}Mathematical operations and utilities for common calculations.
- Value clamping within specified ranges
- Range checking for numeric values
- Percentage calculations with zero-division protection
- Angle conversions between degrees and radians
- Parity checking for even/odd numbers
using PowerCSharp.Utilities;
// Value clamping
int value = 150;
int clamped = MathHelper.Clamp(value, 0, 100); // 100
// Range checking
bool inRange = MathHelper.IsInRange(75, 0, 100); // true
bool outOfRange = MathHelper.IsInRange(150, 0, 100); // false
// Percentage calculations
double percentage = MathHelper.Percentage(25, 100); // 25.0
double safePercentage = MathHelper.Percentage(25, 0); // 0.0 (no division by zero)
// Angle conversions
double radians = MathHelper.ToRadians(180); // π (3.14159...)
double degrees = MathHelper.ToDegrees(Math.PI); // 180.0
// Parity checking
bool isEven = MathHelper.IsEven(4); // true
bool isOdd = MathHelper.IsOdd(3); // truepublic class DataAnalyzer
{
public class Statistics
{
public double Min { get; set; }
public double Max { get; set; }
public double Average { get; set; }
public double StandardDeviation { get; set; }
}
public Statistics CalculateStatistics(IEnumerable<double> values)
{
var valueList = values.ToList();
if (valueList.IsNullOrEmpty())
{
return new Statistics { Min = 0, Max = 0, Average = 0, StandardDeviation = 0 };
}
double min = valueList.Min();
double max = valueList.Max();
double average = valueList.Average();
// Calculate standard deviation
double variance = valueList.Sum(x => Math.Pow(x - average, 2)) / valueList.Count;
double stdDev = Math.Sqrt(variance);
return new Statistics { Min = min, Max = max, Average = average, StandardDeviation = stdDev };
}
public List<double> NormalizeValues(IEnumerable<double> values, double newMin = 0, double newMax = 100)
{
var stats = CalculateStatistics(values);
double range = stats.Max - stats.Min;
if (range == 0) return values.Select(v => newMin).ToList();
return values.Select(v =>
{
double normalized = (v - stats.Min) / range;
return MathHelper.Clamp(normalized * (newMax - newMin) + newMin, newMin, newMax);
}).ToList();
}
public double CalculateGrowthRate(double oldValue, double newValue)
{
if (oldValue == 0) return 0;
return MathHelper.Percentage(newValue - oldValue, oldValue);
}
}public class FileProcessor
{
private readonly string _inputDirectory;
private readonly string _outputDirectory;
public FileProcessor(string inputDir, string outputDir)
{
_inputDirectory = inputDir;
_outputDirectory = outputDir;
}
public void ProcessAllFiles()
{
var inputDir = new DirectoryInfo(_inputDirectory);
var files = inputDir.GetFiles("*.txt");
Console.WriteLine($"Processing {files.Length} files...");
foreach (var file in files)
{
string content = FileHelper.SafeReadAllText(file.FullName);
if (string.IsNullOrEmpty(content))
{
Console.WriteLine($"Skipping empty file: {file.Name}");
continue;
}
// Process content
string processedContent = ProcessContent(content);
// Write to output
string outputPath = Path.Combine(_outputDirectory, file.Name);
bool success = FileHelper.SafeWriteAllText(outputPath, processedContent);
if (success)
{
Console.WriteLine($"Processed: {file.Name}");
}
else
{
Console.WriteLine($"Failed to process: {file.Name}");
}
}
// Report total size
var outputDir = new DirectoryInfo(_outputDirectory);
long totalSize = outputDir.GetFiles("*.*", SearchOption.AllDirectories).Sum(f => f.Length);
Console.WriteLine($"Total output size: {FileHelper.GetFileSize(totalSize)}");
}
private string ProcessContent(string content)
{
// Your processing logic here
return content.ToUpperInvariant();
}
}public class DataValidator
{
public class ValidationResult
{
public bool IsValid { get; set; }
public List<string> Errors { get; set; } = new List<string>();
public List<string> Warnings { get; set; } = new List<string>();
}
public ValidationResult ValidateNumericData(IEnumerable<double> values)
{
var result = new ValidationResult { IsValid = true };
var valueList = values.ToList();
if (valueList.IsNullOrEmpty())
{
result.IsValid = false;
result.Errors.Add("No data provided");
return result;
}
// Check for outliers (values beyond 3 standard deviations)
var stats = new DataAnalyzer().CalculateStatistics(valueList);
double threshold = stats.StandardDeviation * 3;
var outliers = valueList.Where(v => Math.Abs(v - stats.Average) > threshold).ToList();
if (outliers.Any())
{
result.Warnings.Add($"Found {outliers.Count} potential outliers");
}
// Check for negative values if they shouldn't exist
var negativeValues = valueList.Where(v => v < 0).ToList();
if (negativeValues.Any())
{
result.Warnings.Add($"Found {negativeValues.Count} negative values");
}
// Check data range
double range = stats.Max - stats.Min;
if (range == 0)
{
result.Warnings.Add("All values are identical");
}
return result;
}
public void NormalizeDataSet(string inputFile, string outputFile)
{
string csvContent = FileHelper.SafeReadAllText(inputFile);
var lines = csvContent.Split('\n', StringSplitOptions.RemoveEmptyEntries);
if (lines.Length < 2)
{
Console.WriteLine("Invalid CSV file");
return;
}
// Parse numeric data (assuming first column is numeric)
var numericValues = lines.Skip(1)
.Select(line => double.TryParse(line.Split(',')[0], out double val) ? val : 0)
.ToList();
// Normalize values
var analyzer = new DataAnalyzer();
var normalizedValues = analyzer.NormalizeValues(numericValues);
// Create output CSV
var outputLines = new List<string> { "Original,Normalized,Percentage" };
for (int i = 0; i < numericValues.Count; i++)
{
double original = numericValues[i];
double normalized = normalizedValues[i];
double percentage = MathHelper.Percentage(original, numericValues.Max());
outputLines.Add($"{original},{normalized:F2},{percentage:F1}%");
}
string outputContent = string.Join('\n', outputLines);
bool success = FileHelper.SafeWriteAllText(outputFile, outputContent);
if (success)
{
Console.WriteLine($"Data normalized and saved to {outputFile}");
}
}
}public class ConfigManager
{
private readonly string _configPath;
private readonly Dictionary<string, string> _settings;
public ConfigManager(string configPath)
{
_configPath = configPath;
_settings = new Dictionary<string, string>();
LoadConfiguration();
}
private void LoadConfiguration()
{
string content = FileHelper.SafeReadAllText(_configPath);
if (string.IsNullOrEmpty(content))
{
CreateDefaultConfiguration();
return;
}
var lines = content.Split('\n', StringSplitOptions.RemoveEmptyEntries);
foreach (var line in lines)
{
var parts = line.Split('=', 2);
if (parts.Length == 2)
{
_settings[parts[0].Trim()] = parts[1].Trim();
}
}
}
private void CreateDefaultConfiguration()
{
_settings["MaxRetries"] = "3";
_settings["Timeout"] = "30";
_settings["LogLevel"] = "Information";
_settings["EnableCaching"] = "true";
SaveConfiguration();
}
public T GetSetting<T>(string key, T defaultValue = default)
{
if (!_settings.TryGetValue(key, out string value))
{
return defaultValue;
}
try
{
return (T)Convert.ChangeType(value, typeof(T));
}
catch
{
return defaultValue;
}
}
public void SetSetting<T>(string key, T value)
{
_settings[key] = value?.ToString() ?? string.Empty;
SaveConfiguration();
}
private void SaveConfiguration()
{
var lines = _settings.Select(kvp => $"{kvp.Key}={kvp.Value}");
string content = string.Join('\n', lines);
bool success = FileHelper.SafeWriteAllText(_configPath, content);
if (!success)
{
Console.WriteLine($"Failed to save configuration to {_configPath}");
}
}
public void ValidateConfiguration()
{
int maxRetries = GetSetting("MaxRetries", 3);
if (!MathHelper.IsInRange(maxRetries, 1, 10))
{
Console.WriteLine("Warning: MaxRetries should be between 1 and 10");
SetSetting("MaxRetries", MathHelper.Clamp(maxRetries, 1, 10));
}
int timeout = GetSetting("Timeout", 30);
if (!MathHelper.IsInRange(timeout, 5, 300))
{
Console.WriteLine("Warning: Timeout should be between 5 and 300 seconds");
SetSetting("Timeout", MathHelper.Clamp(timeout, 5, 300));
}
}
}PowerCSharp.Utilities has minimal dependencies:
- PowerCSharp.Core - Shared interfaces and base functionality
This lightweight dependency profile makes PowerCSharp.Utilities ideal for inclusion in any project without adding significant overhead.
PowerCSharp.Utilities includes comprehensive unit tests. Run tests with:
dotnet test src/PowerCSharp.Utilities.Tests- Main PowerCSharp Documentation - Complete ecosystem overview
- PowerCSharp.Core - Core interfaces and architecture
- PowerCSharp.Extensions - Extension methods
- PowerCSharp.Helpers - Specialized helpers
- Contributing Guide - How to contribute
- Workflow Documentation - Development workflow
Contributions are welcome! Please read our Contributing Guidelines for details.
- Clone the repository
- Navigate to PowerCSharp.Utilities project
- Restore dependencies:
dotnet restore - Run tests:
dotnet test - Make your changes
- Add tests for new functionality
- Submit a Pull Request
When adding new utility classes:
- Choose the right category - File, Math, Validation, etc.
- Follow naming conventions - Use descriptive, PascalCase class names
- Add XML documentation - Include comprehensive XML docs
- Write unit tests - Cover all scenarios and edge cases
- Handle edge cases - Null checks, division by zero, etc.
- Provide examples - Include usage examples in documentation
This project is licensed under the MIT License - see the LICENSE file for details.
- PowerCSharp.Core - Core interfaces and architecture
- PowerCSharp.Extensions - Extension methods
- PowerCSharp.Helpers - Specialized helper classes
PowerCSharp.Utilities - Essential utilities for everyday C# development! 🚀
