Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
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<number> => { | |
return new Observable<number>((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")) | |
--- | |
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Click the Box Game</title> | |
<style> | |
body { | |
text-align: center; | |
font-family: Arial, sans-serif; | |
} | |
#game-container { | |
position: relative; | |
width: 300px; | |
height: 300px; | |
margin: 20px auto; | |
border: 2px solid black; | |
overflow: hidden; | |
} | |
#target { | |
width: 50px; | |
height: 50px; | |
background-color: red; | |
position: absolute; | |
cursor: pointer; | |
} | |
</style> | |
</head> | |
<body> | |
<h1>Click the Box!</h1> | |
<p>Score: <span id="score">0</span></p> | |
<div id="game-container"> | |
<div id="target"></div> | |
</div> | |
<script> | |
let score = 0; | |
const target = document.getElementById("target"); | |
const scoreDisplay = document.getElementById("score"); | |
const container = document.getElementById("game-container"); | |
function moveTarget() { | |
const maxX = container.clientWidth - target.clientWidth; | |
const maxY = container.clientHeight - target.clientHeight; | |
target.style.left = Math.random() * maxX + "px"; | |
target.style.top = Math.random() * maxY + "px"; | |
} | |
target.addEventListener("click", function() { | |
score++; | |
scoreDisplay.textContent = score; | |
moveTarget(); | |
}); | |
moveTarget(); | |
</script> | |
</body> | |
</html> | |