Shorts: fuller slots and variety; guide and slot-details design for approval
Ported from the release line; design/shorts holds the proposed guide cell, slot details and on-air banner. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -850,7 +850,8 @@ internal fun extendWeighted(pool: List<PoolSeries>, cursor: ScheduleCursor, from
|
||||
}
|
||||
val open = unclashed.ifEmpty { available }.let { shows -> if (stories) shows.filter(::storyFits).ifEmpty { shows } else shows }
|
||||
// Inside a shorts slot only the shorts that fit it take part; none fits, and the slot closes where it is.
|
||||
val inSlot = slot?.let { s -> unclashed.filter { it.id != last && s.takes(start, following(it).durationMs) } }.orEmpty()
|
||||
fun slotShows(s: ShortsSlot) = unclashed.filter { it.id != last && s.takes(start, following(it).durationMs) }
|
||||
val inSlot = slot?.let { s -> slotShows(s).ifEmpty { if (s.stretchIfShort(start)) slotShows(s) else emptyList() } }.orEmpty()
|
||||
if (inSlot.isEmpty()) slot = null
|
||||
val clear = if (continuing == null && inSlot.isNotEmpty()) inSlot else open
|
||||
val rules = listOf<(PoolSeries) -> Boolean>(
|
||||
@@ -861,7 +862,8 @@ internal fun extendWeighted(pool: List<PoolSeries>, cursor: ScheduleCursor, from
|
||||
val low = eligible.minOf { tally[it.id]!! }
|
||||
clear.filter { it.id != last && it !in eligible }.forEach { tally[it.id] = maxOf(tally[it.id]!!, low) }
|
||||
val byTally = compareBy<PoolSeries> { tally[it.id]!! }.thenBy { pool.indexOf(it) }
|
||||
val preferred = eligible.minWith(byTally)
|
||||
// In a shorts slot, a show it hasn't had yet goes first when it's close behind in turn.
|
||||
val preferred = slot?.takeIf { continuing == null && inSlot.isNotEmpty() }?.varied(eligible.sortedWith(byTally)) { it.id } ?: eligible.minWith(byTally)
|
||||
// Before an appointment, the eligible show that leaves it on time, then any clear one, in tally order.
|
||||
val appointment = if (part?.onTime == true) null else nextAppointment(start, zone, partAt = ::partAt)
|
||||
val fitted = if (continuing != null) null else appointment?.let { at -> fun ends(show: PoolSeries) = start + lengthOf(show)
|
||||
@@ -999,7 +1001,8 @@ internal fun extendSchedule(pool: List<PoolSeries>, cursor: ScheduleCursor, from
|
||||
// A block carries on from its own last show. Starting from the channel's last show would begin each block at the same place every day.
|
||||
val after = if (blockRotation) blockLast[block] ?: last else last
|
||||
// Inside a shorts slot, the next short in turn that fits it; none fits, and the slot closes where it is.
|
||||
val inSlot = slot?.let { open -> turnOrder(pool, after).firstOrNull { show -> show.id != last && allowed(show) && open.takes(start, following(show).durationMs) && !avoid(show, start, start + following(show).durationMs) } }
|
||||
fun slotPick(open: ShortsSlot) = open.varied(turnOrder(pool, after).filter { show -> show.id != last && allowed(show) && open.takes(start, following(show).durationMs) && !avoid(show, start, start + following(show).durationMs) }) { it.id }
|
||||
val inSlot = slot?.let { open -> slotPick(open) ?: if (open.stretchIfShort(start)) slotPick(open) else null }
|
||||
if (inSlot == null) slot = null
|
||||
val picked = inSlot ?: turnOrder(pool, after).firstOrNull { show ->
|
||||
when {
|
||||
|
||||
@@ -24,6 +24,8 @@ import java.time.ZoneId
|
||||
internal const val SHORTS_MAX_MS = 8 * 60_000L
|
||||
internal const val SHORTS_SLOT_MIN_MS = 15 * 60_000L
|
||||
internal const val SHORTS_OVERRUN_MS = 2 * 60_000L
|
||||
/** How far down the turn order a slot looks for a show it hasn't had yet, before taking a show back. */
|
||||
internal const val SHORTS_VARIETY_TURNS = 1
|
||||
|
||||
/** A channel's shorts slots: what each is called at a given time. */
|
||||
internal class ShortsRule(val label: (startMs: Long, zone: ZoneId) -> String)
|
||||
@@ -35,8 +37,21 @@ internal val ToonZShorts = ShortsRule { _, _ -> "Cartoon Shorts" }
|
||||
internal fun isShort(durationMs: Long) = durationMs in 1..SHORTS_MAX_MS
|
||||
|
||||
/** One slot being filled: when it aims to end, and the tag its shorts carry. */
|
||||
internal class ShortsSlot(val startMs: Long, val targetMs: Long, val label: String) {
|
||||
internal class ShortsSlot(val startMs: Long, var targetMs: Long, val label: String) {
|
||||
val tag get() = shortsTag(startMs, label)
|
||||
/** The shows already in this slot: a show comes back only when no other short fits (Paul, 6 November 2026: variety first). */
|
||||
val shows = mutableSetOf<String>()
|
||||
/**
|
||||
* Variety without jumping the queue: [first] in turn order stands, unless it's already in the slot and a show that isn't
|
||||
* is close behind it (within [SHORTS_VARIETY_TURNS] places of [ordered]).
|
||||
*/
|
||||
fun <T> varied(ordered: List<T>, id: (T) -> String): T? = ordered.firstOrNull()?.let { first ->
|
||||
if (id(first) !in shows) first else ordered.take(SHORTS_VARIETY_TURNS + 1).firstOrNull { id(it) !in shows } ?: first }
|
||||
/**
|
||||
* A slot still under [SHORTS_SLOT_MIN_MS] that can't fit its next short by its target aims for the half hour after
|
||||
* instead, rather than closing as a fragment with another slot straight after it.
|
||||
*/
|
||||
fun stretchIfShort(atMs: Long): Boolean = (atMs - startMs < SHORTS_SLOT_MIN_MS).also { if (it) targetMs += 30 * 60_000L }
|
||||
/** Whether a short of [durationMs] starting at [atMs] belongs in this slot. */
|
||||
fun takes(atMs: Long, durationMs: Long) = isShort(durationMs) && atMs < targetMs && atMs + durationMs <= targetMs + SHORTS_OVERRUN_MS
|
||||
}
|
||||
@@ -80,6 +95,7 @@ internal fun shortsBlocks(entries: List<ScheduleEntry>): List<ShortsBlock> = bui
|
||||
internal fun shortsTagFor(rule: ShortsRule?, slot: ShortsSlot?, series: PoolSeries, episode: PoolEpisode, inBlock: Boolean, startMs: Long, zone: ZoneId): Pair<String, ShortsSlot?> {
|
||||
if (rule == null || series.isFilm || !inBlock || !isShort(episode.durationMs)) return "" to null
|
||||
val open = slot?.takeIf { it.takes(startMs, episode.durationMs) } ?: openShortsSlot(rule, startMs, zone)
|
||||
open.shows += series.id
|
||||
return open.tag to open
|
||||
}
|
||||
|
||||
|
||||
@@ -89,12 +89,19 @@ class ShortsReplayTest {
|
||||
val loose = after.count { isShort(it.media.durationMs) && it.group.isEmpty() }
|
||||
val lengths = blocks.map { it.endMs - it.startMs }.sorted()
|
||||
val repeats = blocks.sumOf { b -> b.entries.zipWithNext().count { (a, c) -> a.seriesId == c.seriesId } }
|
||||
assertEquals("${programming.name}: no show twice in a row in a slot", 0, repeats)
|
||||
val returns = blocks.sumOf { b -> b.entries.size - b.entries.map { it.seriesId }.distinct().size }
|
||||
val couldVary = blocks.count { b -> b.entries.size > b.entries.map { it.seriesId }.distinct().size }
|
||||
val shortSlots = blocks.filter { it.endMs - it.startMs < SHORTS_SLOT_MIN_MS }
|
||||
out.append("\n${programming.name} ($number)\n")
|
||||
out.append(" Programmes booked: ${before.size} before, ${after.size} after; shorts among them: $shortsBefore before, $shortsAfter after\n")
|
||||
out.append(" Shorts slots: ${blocks.size}, holding ${blocks.sumOf { it.entries.size }} shorts; $loose short(s) left on their own (a slot of one, or the block changed)\n")
|
||||
if (lengths.isNotEmpty()) out.append(" Slot length: shortest ${mins(lengths.first())} min, median ${mins(lengths[lengths.size / 2])}, longest ${mins(lengths.last())}; " +
|
||||
"${blocks.count { onHalfHour(it.endMs) }} of ${blocks.size} end within 2 min of :00 or :30\n")
|
||||
out.append(" Shows per slot: average ${"%.1f".format(blocks.map { it.shows.size }.average())}; the same show twice in a row inside a slot: $repeats time(s)\n")
|
||||
out.append(" Shows per slot: average ${"%.1f".format(blocks.map { it.shows.size }.average())}; the same show twice in a row inside a slot: $repeats time(s); a show back later in the same slot: $returns time(s), in $couldVary slot(s)\n")
|
||||
out.append(" Slots under 15 minutes: ${shortSlots.size}${if (shortSlots.isEmpty()) "" else ": " + shortSlots.take(6).joinToString { blk ->
|
||||
val next = after.firstOrNull { it.startMs == blk.endMs }
|
||||
"${clock(blk.startMs)} ${mins(blk.endMs - blk.startMs)} min, then ${next?.let(::name) ?: "?"} (${next?.let { mins(it.media.durationMs) } ?: "?"} min)" }}\n")
|
||||
out.append(" Programmes starting within 2 min of :00 or :30: ${before.count { onHalfHour(it.startMs) }} of ${before.size} before, ${after.count { onHalfHour(it.startMs) }} of ${after.size} after\n")
|
||||
out.append(" Labels: ${blocks.groupingBy { it.label }.eachCount()}\n")
|
||||
val airtime = { run: List<ScheduleEntry> -> run.groupBy(::name).mapValues { (_, v) -> v.sumOf { it.media.durationMs } / 60_000 } }
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Shorts slots in the guide, design proposal (Paul, 6 November 2026): how a slot of shorts shows in the TV Guide, what OK on
|
||||
it opens, and Tots Story Time as the evening's identity for single bedtime stories. Every short is still its own programme;
|
||||
the slot is only how they're shown. Times and titles from the seven-day replay of the box's own plans. For approval only."""
|
||||
import ast
|
||||
from pathlib import Path
|
||||
HERE = Path(__file__).resolve().parent
|
||||
SRC = HERE.parent / 'profiles' / 'build-profiles.py'
|
||||
tree = ast.parse(SRC.read_text())
|
||||
keep = []
|
||||
for n in tree.body:
|
||||
if isinstance(n, ast.Expr) and isinstance(n.value, ast.Constant): continue
|
||||
if isinstance(n, ast.Expr) and isinstance(n.value, ast.Call) and getattr(n.value.func, 'id', '') == 'screen': break
|
||||
keep.append(n)
|
||||
ns = {'__file__': str(SRC)}
|
||||
exec(compile(ast.Module(keep, []), str(SRC), 'exec'), ns)
|
||||
globals().update({k: v for k, v in ns.items() if k not in ('HERE', '__file__', 'save')})
|
||||
def save(name): ns['im'].resize((W, H), Image.LANCZOS).save(HERE / name); print(name)
|
||||
def D(): return ns['d']
|
||||
from PIL import Image
|
||||
GREEN = (110, 220, 170); LATER = (15, 44, 92); PINK = (255, 122, 198); LUNA = (167, 123, 255)
|
||||
|
||||
def stack(x, y, s=18, col=YELLOW):
|
||||
"""The shorts mark: three short bars, a slot of several programmes."""
|
||||
for k in range(3): D().rounded_rectangle((S(x), S(y + k * s * .38), S(x + s * (1 - k * .18)), S(y + k * s * .38 + s * .24)), S(3), fill=col)
|
||||
|
||||
def moon(x, y, s=16, col=LUNA):
|
||||
D().ellipse((S(x), S(y), S(x + s), S(y + s)), fill=col); D().ellipse((S(x + s * .35), S(y - s * .1), S(x + s * 1.2), S(y + s * .8)), fill=PANEL)
|
||||
|
||||
def guide_header(times, y=150, x0=420, step=290, day='Thursday'):
|
||||
box(60, y, 1800, 48, fill=BLUE, r=0); text((80, y + 8), day, semi(28), WHITE)
|
||||
for i, t in enumerate(times): text((x0 + i * step, y + 8), t, semi(28), WHITE)
|
||||
|
||||
def fit(s, f, w):
|
||||
"""Cut to fit [w] pixels, with an ellipsis, as the guide does."""
|
||||
if D().textlength(s, font=f) / SS <= w: return s
|
||||
while s and D().textlength(s + '…', font=f) / SS > w: s = s[:-1]
|
||||
return (s.rstrip() + '…') if s else ''
|
||||
|
||||
def cell(x, w, y, title, sub=None, fill=PANEL, focus=False, mark=None, h=100):
|
||||
box(x, y, w - 6, h, fill=NAVY if focus else fill, r=4, outline=YELLOW if focus else None, width=4)
|
||||
tx = x + 18
|
||||
if mark == 'stack': stack(tx, y + 22); tx += 30
|
||||
if mark == 'moon': moon(tx, y + 24); tx += 30
|
||||
text((tx, y + 18), fit(title, semi(26), x + w - 24 - tx), semi(26), WHITE)
|
||||
if sub: text((x + 18, y + 58), fit(sub, reg(21), w - 36), reg(21), MUTED)
|
||||
|
||||
def mins(m, step=290): return m / 30 * step
|
||||
|
||||
# 1. The guide: a ToonZ slot, a Tots slot, Tots' evening stories one by one, and a slot cut short by a block change.
|
||||
screen()
|
||||
text((80, 70), 'TV GUIDE', anton(44), WHITE); text((300, 84), 'A slot of shorts is one cell; the shorts in it are still each their own programme.', reg(26), MUTED)
|
||||
guide_header(['13:30', '14:00', '14:30', '15:00', '15:30'])
|
||||
x0 = 410; t0 = 13 * 60 + 30
|
||||
def X(hm): return x0 + mins(hm - t0)
|
||||
rows = [('605', 'TOONZ', [(13*60+30, 13*60+51, 'The Flintstones', 'S3 E12', None), (13*60+51, 14*60+31, 'Cartoon Shorts', 'Tom and Jerry, Yogi Bear, Popeye and 3 more · 40 min', 'stack'),
|
||||
(14*60+31, 14*60+55, 'Looney Tunes', 'The Looney Tunes Show', None), (14*60+55, 15*60+58, 'Wacky Races', 'S1 E4', None)]),
|
||||
('614', 'TOTS', [(13*60+30, 13*60+41, 'Fireman Sam', 'S9 E3', None), (13*60+41, 14*60+50, 'Andy\'s Wild Adventures', 'S2 E8', None),
|
||||
(14*60+50, 15*60+28, 'Tots Little Mix', 'Bluey, Numberblocks, Peppa Pig and 3 more · 38 min', 'stack'), (15*60+28, 16*60, 'Andy\'s Wild Adventures', 'S2 E9', None)])]
|
||||
for r, (num, name, progs) in enumerate(rows):
|
||||
y = 210 + r * 120
|
||||
box(60, y, 340, 100, fill=PANEL, r=0); text((80, y + 30), num, semi(30), YELLOW); text((170, y + 30), name, anton(34), WHITE)
|
||||
for a, b, title, sub, mark in progs:
|
||||
a2, b2 = max(a, t0), min(b, t0 + 150)
|
||||
if b2 <= a2: continue
|
||||
cell(X(a2), mins(b2 - a2), y, title, sub, focus=(mark == 'stack' and r == 0), mark=mark)
|
||||
# Evening: single bedtime stories carry Tots Story Time; a slot cut short by a block change shows its real length.
|
||||
guide_header(['18:00', '18:30', '19:00', '19:30', '20:00'], y=470)
|
||||
y = 530; box(60, y, 340, 100, fill=PANEL, r=0); text((80, y + 30), '614', semi(30), YELLOW); text((170, y + 30), 'TOTS', anton(34), WHITE)
|
||||
t1 = 18 * 60
|
||||
def X1(hm): return x0 + mins(hm - t1)
|
||||
for a, b, title, sub, mark in [(18*60, 18*60+5, 'Story', None, 'moon'), (18*60+5, 18*60+25, 'In The Night Garden', 'S1 E14', None), (18*60+25, 18*60+31, 'Story', None, 'moon'),
|
||||
(18*60+31, 18*60+50, 'Teletubbies', 'S2 E40', None), (18*60+50, 19*60+2, 'BeddyByes', 'S1 E9', None), (19*60+2, 19*60+7, 'Story', None, 'moon'),
|
||||
(19*60+7, 19*60+30, 'Clangers', 'S2 E3', None), (19*60+30, 20*60+30, 'In The Night Garden', 'S1 E15 · Tots Dreamtime from 19:00', None)]:
|
||||
cell(X1(a), mins(b - a), y, title if title != 'Story' else '', sub, mark=mark)
|
||||
box(420, 650, 1440, 110, fill=(10, 30, 66), r=10)
|
||||
moon(446, 676, 20)
|
||||
text((482, 668), 'Tots Story Time: each evening bedtime story is its own short programme, with the moon and the story\'s name when focused,', reg(23), MUTED)
|
||||
text((482, 700), 'for example "Tots Story Time: Kipper\'s Snowy Day, 5 min". No evening block: In The Night Garden and the wind-down keep their turns.', reg(23), MUTED)
|
||||
guide_header(['21:30', '22:00', '22:30', '23:00', '23:30'], y=790)
|
||||
y = 850; box(60, y, 340, 100, fill=PANEL, r=0); text((80, y + 30), '605', semi(30), YELLOW); text((170, y + 30), 'TOONZ', anton(34), WHITE)
|
||||
t2 = 21 * 60 + 30
|
||||
def X2(hm): return x0 + mins(hm - t2)
|
||||
for a, b, title, sub, mark, fill in [(21*60+30, 21*60+45, 'Danger Mouse', 'S4 E2', None, PANEL), (21*60+45, 22*60, 'Cartoon Shorts', '21:45 to 22:00 · 15 min', 'stack', PANEL),
|
||||
(22*60, 22*60+22, 'Futurama', 'ToonZ Late', None, (60, 30, 70)), (22*60+22, 23*60, 'King of the Hill', 'ToonZ Late', None, (60, 30, 70))]:
|
||||
cell(X2(a), mins(b - a), y, title, sub, fill=fill, mark=mark)
|
||||
text((80, 962), 'A slot that ends early (here at 22:00, when ToonZ Late takes over and has no shorts) is drawn at its real length, with its real times.', reg(24), MUTED)
|
||||
save('shorts-1-guide.png')
|
||||
|
||||
# 2. OK on the slot: every short, its times, and what's watchable.
|
||||
screen()
|
||||
for k in range(6): box(60, 160 + k * 120, 1800, 100, fill=(10, 27, 60), r=0)
|
||||
overlay = Image.new('RGBA', ns['im'].size, (7, 22, 50, 170)); ns['im'].paste(Image.alpha_composite(ns['im'].convert('RGBA'), overlay).convert('RGB')); ns['d'] = __import__('PIL.ImageDraw', fromlist=['x']).Draw(ns['im'])
|
||||
box(360, 120, 1200, 820, fill=DEEP, r=16, outline=BLUE, width=3)
|
||||
stack(400, 160, 26); text((446, 150), 'CARTOON SHORTS', anton(44), WHITE)
|
||||
text((400, 214), '605 ToonZ · Thursday 13:51 to 14:31 · 40 min · 6 shorts', semi(28), MUTED)
|
||||
shorts = [('13:51', 'Tom and Jerry', 'Mouse Trouble', '6 min', 'aired'), ('13:57', 'The Yogi Bear Show', 'Pie Pirates', '7 min', 'aired'),
|
||||
('14:04', 'Popeye the Sailor', 'Sea Sick Sailors', '6 min', 'now'), ('14:10', 'The Huckleberry Hound Show', 'Lion Hearted Huck', '7 min', 'next'),
|
||||
('14:18', 'The Pink Panther', 'Pink Pajamas', '6 min', 'next'), ('14:24', 'Looney Tunes', 'Rabbit Seasoning', '7 min', 'next')]
|
||||
for i, (t, show, ep, ln, state) in enumerate(shorts):
|
||||
y = 280 + i * 92; focus = i == 1
|
||||
box(400, y, 1120, 80, fill=NAVY if focus else PANEL, r=8, outline=YELLOW if focus else None, width=3)
|
||||
text((424, y + 22), t, semi(30), YELLOW)
|
||||
text((540, y + 10), show, semi(30), WHITE); text((540, y + 46), ep, reg(22), MUTED)
|
||||
text((1180, y + 22), ln, reg(26), MUTED)
|
||||
if state == 'aired': box(1290, y + 20, 200, 40, fill=GREEN, r=6); text((1390, y + 26), 'CATCH UP', semi(22), NAVY, 'ma')
|
||||
if state == 'now': box(1290, y + 20, 200, 40, fill=YELLOW, r=6); text((1390, y + 26), 'ON NOW', semi(22), NAVY, 'ma')
|
||||
text((400, 846), 'Each short is its own programme: Catch Up, where you\'ve got to, and Kids rules work short by short.', reg(24), MUTED)
|
||||
text((400, 880), 'The list is what\'s actually booked, so the title, times and shows always match what airs.', reg(24), MUTED)
|
||||
keys([('OK', 'Watch from this short'), ('▲▼', 'Shorts'), ('Back', 'Guide')])
|
||||
save('shorts-2-details.png')
|
||||
|
||||
# 3. While it's on: the info banner names the short and where it sits in the slot.
|
||||
screen()
|
||||
box(0, 0, W, H, fill=(30, 30, 30), r=0)
|
||||
for k in range(18): box(80 + k * 100, 120 + (k % 4) * 60, 60, 40, fill=(45, 45, 45), r=6)
|
||||
box(0, 780, W, 300, fill=(7, 22, 50), r=0)
|
||||
text((80, 810), '605', semi(36), YELLOW); text((170, 806), 'TOONZ', anton(40), WHITE)
|
||||
stack(80, 880, 22); text((118, 872), 'Cartoon Shorts · 3 of 6', semi(28), MUTED)
|
||||
text((80, 920), 'Popeye the Sailor: Sea Sick Sailors', semi(40), WHITE)
|
||||
text((80, 975), '14:04 to 14:10 · next: The Huckleberry Hound Show 14:10', reg(26), MUTED)
|
||||
box(1100, 900, 700, 10, fill=(40, 60, 100), r=5); box(1100, 900, 300, 10, fill=YELLOW, r=5)
|
||||
text((1100, 930), 'The short\'s own progress, not the slot\'s', reg(24), MUTED)
|
||||
save('shorts-3-banner.png')
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 282 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 217 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 72 KiB |
@@ -1,13 +1,14 @@
|
||||
Shorts grouping: seven days of new bookings after each committed plan, from the box's files (2026-11-06).
|
||||
|
||||
Tots (614)
|
||||
Programmes booked: 762 before, 767 after; shorts among them: 255 before, 263 after
|
||||
Shorts slots: 35, holding 156 shorts; 107 short(s) left on their own (a slot of one, or the block changed)
|
||||
Slot length: shortest 10.0 min, median 25.0, longest 42.1; 22 of 35 end within 2 min of :00 or :30
|
||||
Shows per slot: average 3.0; the same show twice in a row inside a slot: 0 time(s)
|
||||
Programmes starting within 2 min of :00 or :30: 136 of 762 before, 133 of 767 after
|
||||
Labels: {Tots Little Mix=35}
|
||||
Biggest airtime changes over the week (minutes): Teletubbies -21, Something Special -20, Bluey (2018) +15, Ben and Holly's Little Kingdom -11, Numberblocks +10, CBeebies Bedtime Stories +9, Hey Duggee +7, Peppa Pig +5
|
||||
Programmes booked: 762 before, 770 after; shorts among them: 255 before, 265 after
|
||||
Shorts slots: 32, holding 159 shorts; 106 short(s) left on their own (a slot of one, or the block changed)
|
||||
Slot length: shortest 17.0 min, median 29.7, longest 44.2; 22 of 32 end within 2 min of :00 or :30
|
||||
Shows per slot: average 3.3; the same show twice in a row inside a slot: 0 time(s); a show back later in the same slot: 52 time(s), in 26 slot(s)
|
||||
Slots under 15 minutes: 0
|
||||
Programmes starting within 2 min of :00 or :30: 136 of 762 before, 117 of 770 after
|
||||
Labels: {Tots Little Mix=32}
|
||||
Biggest airtime changes over the week (minutes): In The Night Garden -28, Bluey (2018) +22, Teletubbies -21, Something Special -20, Numberblocks +15, Andy's Wild Adventures -15, Floogals +11, Bob the Builder +10
|
||||
Example slot Thu 14:50 to 15:28 "Tots Little Mix: Bluey (2018), Numberblocks, Peppa Pig and more"
|
||||
14:50 Bluey (2018) (7.3 min)
|
||||
14:58 Numberblocks (5.0 min)
|
||||
@@ -32,13 +33,14 @@ Tots (614)
|
||||
After that first slot: 15:28 Andy's Wild Adventures, straight after the last short
|
||||
|
||||
ToonZ (605)
|
||||
Programmes booked: 757 before, 758 after; shorts among them: 416 before, 419 after
|
||||
Shorts slots: 94, holding 419 shorts; 0 short(s) left on their own (a slot of one, or the block changed)
|
||||
Slot length: shortest 12.6 min, median 32.3, longest 46.4; 58 of 94 end within 2 min of :00 or :30
|
||||
Shows per slot: average 3.6; the same show twice in a row inside a slot: 0 time(s)
|
||||
Programmes starting within 2 min of :00 or :30: 121 of 757 before, 136 of 758 after
|
||||
Labels: {Cartoon Shorts=94}
|
||||
Biggest airtime changes over the week (minutes): Duckman +22, Hong Kong Phooey -21, Wacky Races -12, Looney Tunes -9, Tom and Jerry +7, The Yogi Bear Show +7, Popeye the Sailor +7, The Pink Panther -6
|
||||
Programmes booked: 757 before, 754 after; shorts among them: 416 before, 413 after
|
||||
Shorts slots: 87, holding 413 shorts; 0 short(s) left on their own (a slot of one, or the block changed)
|
||||
Slot length: shortest 13.1 min, median 33.7, longest 49.0; 66 of 87 end within 2 min of :00 or :30
|
||||
Shows per slot: average 3.9; the same show twice in a row inside a slot: 0 time(s); a show back later in the same slot: 70 time(s), in 48 slot(s)
|
||||
Slots under 15 minutes: 3: Sat 21:45 14.9 min, then Futurama (21.7 min), Mon 08:24 13.9 min, then Looney Tunes (23.8 min), Tue 21:48 13.1 min, then Aqua Teen Hunger Force (11.5 min)
|
||||
Programmes starting within 2 min of :00 or :30: 121 of 757 before, 139 of 754 after
|
||||
Labels: {Cartoon Shorts=87}
|
||||
Biggest airtime changes over the week (minutes): The Jetsons -48, The Looney Tunes Show +44, The Flintstones -26, Danger Mouse +24, The Critic +23, Duckman +22, Tom and Jerry -14, Popeye the Sailor -13
|
||||
Example slot Thu 13:51 to 14:31 "Cartoon Shorts: Tom and Jerry, The Yogi Bear Show, Popeye the Sailor and more"
|
||||
13:51 Tom and Jerry (6.4 min)
|
||||
13:57 The Yogi Bear Show (7.1 min)
|
||||
@@ -50,8 +52,8 @@ ToonZ (605)
|
||||
16:08 Looney Tunes (6.7 min)
|
||||
16:15 Tom and Jerry (6.4 min)
|
||||
16:21 The Yogi Bear Show (7.2 min)
|
||||
Example slot Thu 17:42 to 17:59 "Cartoon Shorts: Popeye the Sailor, Bananaman"
|
||||
Example slot Thu 17:42 to 18:00 "Cartoon Shorts: Popeye the Sailor, Bananaman, Looney Tunes"
|
||||
17:42 Popeye the Sailor (6.2 min)
|
||||
17:48 Bananaman (4.6 min)
|
||||
17:53 Popeye the Sailor (6.7 min)
|
||||
17:53 Looney Tunes (7.8 min)
|
||||
After that first slot: 14:31 Looney Tunes, straight after the last short
|
||||
|
||||
Reference in New Issue
Block a user