import { Observable, of, from, interval, throwError } from 'rxjs'; import { map, filter, catchError, switchMap, take, tap } from 'rxjs/operators'; // Mock function to fetch stock prices (simulates API call) const fetchStockPrice = (ticker: string): Observable => { return new Observable((observer) => { const intervalId = setInterval(() => { if (Math.random() < 0.1) { // Simulating an error 10% of the time observer.error(`Error fetching stock price for ${ticker}`); } else { const price = parseFloat((Math.random() * 1000).toFixed(2)); observer.next(price); } }, 1000); return () => { clearInterval(intervalId); console.log(`Stopped fetching prices for ${ticker}`); }; }); }; // Example usage: Tracking stock price updates const stockTicker = 'AAPL'; const stockPrice$ = fetchStockPrice(stockTicker).pipe( map(price => ({ ticker: stockTicker, price })), // Transform data filter(data => data.price > 500), // Only keep prices above 500 tap(data => console.log(`Price update:`, data)), // Side effect: Logging catchError(err => { console.error(err); return of({ ticker: stockTicker, price: null }); // Fallback observable }) ); // Subscribe to the stock price updates const subscription = stockPrice$.subscribe({ next: data => console.log(`Subscriber received:`, data), error: err => console.error(`Subscription error:`, err), complete: () => console.log('Stream complete'), }); // Automatically unsubscribe after 10 seconds setTimeout(() => { subscription.unsubscribe(); console.log('Unsubscribed from stock price updates.'); }, 10000); --- class EnforceAttrsMeta(type): """ Metaclass that enforces the presence of specific attributes in a class and automatically decorates methods with a logging wrapper. """ required_attributes = ['name', 'version'] def __new__(cls, name, bases, class_dict): """ Create a new class with enforced attributes and method logging. :param name: Name of the class being created. :param bases: Tuple of base classes. :param class_dict: Dictionary of attributes and methods of the class. :return: Newly created class object. """ # Ensure required attributes exist for attr in cls.required_attributes: if attr not in class_dict: raise TypeError(f"Class '{name}' is missing required attribute '{attr}'") # Wrap all methods in a logging decorator for key, value in class_dict.items(): if callable(value): # Check if it's a method class_dict[key] = cls.log_calls(value) return super().__new__(cls, name, bases, class_dict) @staticmethod def log_calls(func): """ Decorator that logs method calls and arguments. :param func: Function to be wrapped. :return: Wrapped function with logging. """ def wrapper(*args, **kwargs): print(f"Calling {func.__name__} with args={args} kwargs={kwargs}") result = func(*args, **kwargs) print(f"{func.__name__} returned {result}") return result return wrapper class PluginBase(metaclass=EnforceAttrsMeta): """ Base class for plugins that enforces required attributes and logging. """ name = "BasePlugin" version = "1.0" def run(self, data): """ Process the input data. :param data: The data to be processed. :return: Processed result. """ return f"Processed {data}" class CustomPlugin(PluginBase): """ Custom plugin that extends PluginBase and adheres to enforced rules. """ name = "CustomPlugin" version = "2.0" def run(self, data): """ Custom processing logic. :param data: The data to process. :return: Modified data. """ return f"Custom processing of {data}" # Uncommenting the following class definition will raise a TypeError # because 'version' attribute is missing. # class InvalidPlugin(PluginBase): # name = "InvalidPlugin" if __name__ == "__main__": # Instantiate and use the plugin plugin = CustomPlugin() print(plugin.run("example data")) --- Click the Box Game

Click the Box!

Score: 0