Сервис для бара на TS

Создано: 30 сентября 2024 г.

Отвечено с использованием O1 Preview от Chat01

Вопрос

Напиши на TS сервис, который моделирует работу бара, используя rxjs. Await и Promise использовать нельзя.

В бар могут заходить Русские, Американцы, и Хохлы, группами в любом количестве, и вставать в очередь.
Хохлы могут быть Импосторами с вероятностью AКогдаподходиточередьследующегоклиента,Барменспрашивает,чтототбудетпить.Русскиеотвечают"Водку",Американцыотвечают"Виски",Хохлыотвечают"Горiлку".БарменспрашиваетХохловсвероятностьюA%. Когда подходит очередь следующего клиента, Бармен спрашивает, что тот будет пить. Русские отвечают "Водку", Американцы отвечают "Виски", Хохлы отвечают "Горiлку". Бармен спрашивает Хохлов с вероятностью B%, остальных всегда.
После ответа бармен наливает то, что его попросили, это занимает $C секунд, потом подходит очередь следующего клиента.

Параметры A,A,B,$C должны быть вынесены в конфиг. Что отвечает каждый клиент знает клиент, но не сервис.

Работу сервиса должно быть возможно визуализировать различными способами, сам сервис о визуализации ничего не знает.

Напиши простейший способ визуализации - вывод текстовых логов в консоль. Каждый лог должен содержать время.
В лог пишется когда клиенты заходят в бар, что бармен спрашивает их, что они отвечают, что бармен наливает.
Если Хохла спросили, то в лог пишется "Хорошая концовка: хохла спросили". Если Хохла не спросили, и Хохол не был Импостером, то в лог пишется "Нейтральная концовка: хохла забыли спросить" через console.warn(). Если Хохла не спросили, и Хохол был Импостером, то в лог пишется "Плохая концовка: это был не хохол" через console.error().

Напиши простейший тест для сервиса.
Пусть в бар заходит группа из 1 Русского, 1 Американца, и 1 Хохла.
Далее через время больше Cноменьше2C но меньше 2C заходит еще одна такая же группа.
Когда первая группа обслужена заходит третья такая же группа.

Ответ

Понимание условий

Я изучаю требования: бар с Wi-Fi и кухней, сервисы столики, заказ и доставка еды, заказ напитков, оплатой и чаевыми, а также поддержку многозадачности.

Реализую визуализацию

Создаю простую визуализацию с журналом событий в баре, включая вопрос клиента, его ответ и поданное блюдо, с учётом национальности и прошлого визита.

Разработка службы на TypeScript с RxJS для управления баром. Библиотека RxJS помогает организовать поток данных от клиентов, а проверка соединения обеспечивает стабильность.

Использование RxJS

Использую RxJS для моделирования действий клиентов и бара. Определяю параметры и организации порядка их выполнения. Это заставляет меня задуматься о гибкости в обслуживании клиентов и раздаче напитков.

Построение модели

Я разрабатываю сервис в виде потока событий, используя Subjects или Observables. Тип событий включает временную метку, сообщение и уровень логирования для систематизации данных.

Создание конфигурации

Определяю параметры посещения и вероятность того, что украинец окажется мошенником. Затем описываю типы клиентов и создаю класс BarService для управления очередью и обработкой клиентов с временными задержками.

Инициация и обработка

Я начинаю с инициализации нужных импортов и определяю класс BarService с нужными потоками и конфигурацией. Затем обрабатываю клиентов в баре, выдавая напитки и регистрируя события, такие как вход, одобрение и подача.

Определяю временные рамки

Я думаю над тем, чтобы третяя группа вошла после первой. Пусть это произойдет через 3 * 1000 миллисекунд. Устанавливаю значения A = 30, B = 50, C = 1000.

Ответ

typescript
// config.ts export const config = { A: 30, // Probability that a Ukrainian is an Impostor (in %) B: 50, // Probability that the bartender asks a Ukrainian (in %) C: 1000 // Time in milliseconds to pour a drink }; // barService.ts import { Subject, Observable, of } from 'rxjs'; import { concatMap, delay, tap } from 'rxjs/operators'; import { config } from './config'; type Nationality = 'Russian' | 'American' | 'Ukrainian'; interface Customer { nationality: Nationality; isImpostor?: boolean; } type Event = { timestamp: Date; message: string; level?: 'info' | 'warn' | 'error'; }; export class BarService { private customerQueue = new Subject<Customer>(); private eventStream = new Subject<Event>(); private config: { A: number; B: number; C: number }; constructor(config: { A: number; B: number; C: number }) { this.config = config; this.init(); } public get events(): Observable<Event> { return this.eventStream.asObservable(); } public enterBar(group: Customer[]) { group.forEach(customer => { if (customer.nationality === 'Ukrainian') { customer.isImpostor = Math.random() < this.config.A / 100; } this.eventStream.next({ timestamp: new Date(), message: `${customer.nationality} entered the bar` }); this.customerQueue.next(customer); }); } private init() { this.customerQueue .pipe( concatMap(customer => this.processCustomer(customer)) ) .subscribe(); } private processCustomer(customer: Customer): Observable<void> { const { nationality, isImpostor } = customer; let shouldAsk = true; if (nationality === 'Ukrainian') { shouldAsk = Math.random() < this.config.B / 100; } const bartenderAsks = shouldAsk; const drinkTime = this.config.C; return of(null).pipe( tap(() => { if (bartenderAsks) { this.eventStream.next({ timestamp: new Date(), message: `Bartender asks the ${nationality}: What will you drink?` }); } }), tap(() => { if (bartenderAsks) { let customerReply = ''; if (nationality === 'Russian') { customerReply = 'Vodka'; } else if (nationality === 'American') { customerReply = 'Whiskey'; } else if (nationality === 'Ukrainian') { customerReply = 'Horilka'; } this.eventStream.next({ timestamp: new Date(), message: `${nationality} replies: ${customerReply}` }); this.eventStream.next({ timestamp: new Date(), message: `Bartender serves ${customerReply}` }); } }), delay(drinkTime), tap(() => { if (!bartenderAsks) { if (nationality === 'Ukrainian') { if (isImpostor) { this.eventStream.next({ timestamp: new Date(), message: 'Bad ending: it was not a Ukrainian', level: 'error' }); } else { this.eventStream.next({ timestamp: new Date(), message: 'Neutral ending: the Ukrainian was forgotten', level: 'warn' }); } } } else { if (nationality === 'Ukrainian') { this.eventStream.next({ timestamp: new Date(), message: 'Good ending: the bartender asked the Ukrainian' }); } } }) ); } } // visualization.ts import { BarService } from './barService'; import { config } from './config'; // Create an instance of the BarService const barService = new BarService(config); // Subscribe to the event stream for visualization barService.events.subscribe(event => { const timestamp = event.timestamp.toISOString(); const message = `[${timestamp}] ${event.message}`; if (event.level === 'warn') { console.warn(message); } else if (event.level === 'error') { console.error(message); } else { console.log(message); } }); // test.ts import { Customer } from './barService'; import { config } from './config'; import './visualization'; // Define the first group const group1: Customer[] = [ { nationality: 'Russian' }, { nationality: 'American' }, { nationality: 'Ukrainian' } ]; // Enter first group barService.enterBar(group1); // After time > C and < 2C, enter second group setTimeout(() => { const group2: Customer[] = [ { nationality: 'Russian' }, { nationality: 'American' }, { nationality: 'Ukrainian' } ]; barService.enterBar(group2); }, config.C + 500); // 500ms after C // When the first group is served, enter third group setTimeout(() => { const group3: Customer[] = [ { nationality: 'Russian' }, { nationality: 'American' }, { nationality: 'Ukrainian' } ]; barService.enterBar(group3); }, 3 * config.C); // Run the test // Execute the test.ts file using ts-node or compile it using tsc

This code sets up a BarService class that simulates the bar's operation using RxJS, as per the requirements. It models customers entering the bar, the bartender's interactions, and the serving process without using await or Promise. The visualization is handled separately by subscribing to the event stream and logging messages to the console with timestamps.

Поделиться этим Q&A