.
This commit is contained in:
+10
-2
@@ -102,9 +102,17 @@ class Dinosaur(models.Model):
|
|||||||
"""Convert a 0-100 percent into a 0-5 star score in 0.5 increments."""
|
"""Convert a 0-100 percent into a 0-5 star score in 0.5 increments."""
|
||||||
if percent is None:
|
if percent is None:
|
||||||
return 0.0
|
return 0.0
|
||||||
val = float(percent) * 0.05 # scale 0-100 -> 0-5
|
pct = float(percent)
|
||||||
|
# scale 0-100 -> 0-5
|
||||||
|
val = pct * 0.05
|
||||||
# round to nearest 0.5
|
# round to nearest 0.5
|
||||||
return round(val * 2) / 2.0
|
rounded = round(val * 2) / 2.0
|
||||||
|
# Avoid promoting near-100 values to 5.0 via rounding. Only an
|
||||||
|
# exact 100% should map to a full 5.0. Anything less will be
|
||||||
|
# capped at 4.5 to keep 5-star visually reserved for true maxima.
|
||||||
|
if pct >= 100.0:
|
||||||
|
return 5.0
|
||||||
|
return min(rounded, 4.5)
|
||||||
|
|
||||||
def _stars_string(self, percent):
|
def _stars_string(self, percent):
|
||||||
"""Return a simple star string like '★★★★½' and trailing empty stars '☆'."""
|
"""Return a simple star string like '★★★★½' and trailing empty stars '☆'."""
|
||||||
|
|||||||
@@ -49,48 +49,48 @@
|
|||||||
<div style="padding:8px 10px; border-top:1px solid rgba(0,0,0,0.04); background:#fafafa;">
|
<div style="padding:8px 10px; border-top:1px solid rgba(0,0,0,0.04); background:#fafafa;">
|
||||||
<div style="display:flex; flex-direction:column; gap:6px;">
|
<div style="display:flex; flex-direction:column; gap:6px;">
|
||||||
{% with s=card.speed_percent w=card.weight_percent it=card.intelligence_percent h=card.height_percent %}
|
{% with s=card.speed_percent w=card.weight_percent it=card.intelligence_percent h=card.height_percent %}
|
||||||
<div style="display:flex; justify-content:space-between; align-items:center; {% if card.is_top_trump and 'speed' in card.best_stats %}box-shadow:inset 6px 0 0 #1abc9c; border-radius:4px;{% endif %}">
|
<div style="display:flex; justify-content:space-between; align-items:center; {% if card.is_top_trump and 'speed' in card.best_stats %}background:rgba(26,188,156,0.06); border-left:6px solid #1abc9c; border-radius:4px; padding:6px 8px;{% endif %}">
|
||||||
<div style="font-size:0.9rem; font-weight:700">Speed</div>
|
<div style="font-size:0.9rem; font-weight:700">Speed</div>
|
||||||
<div style="display:flex; align-items:center; gap:8px;">
|
<div style="display:flex; align-items:center; gap:8px;">
|
||||||
<div style="font-weight:800">{{ card.speed_display }}</div>
|
<div style="font-weight:800">{{ card.speed_display }}</div>
|
||||||
<div aria-hidden="true" style="display:flex; gap:2px;">
|
<div aria-hidden="true" style="display:flex; gap:2px;">
|
||||||
{% for t in card.speed_star_types %}
|
{% for t in card.speed_star_types_adj|default:card.speed_star_types %}
|
||||||
<span style="font-size:0.95rem; line-height:1; color: {% if t == 'full' %}#1abc9c{% elif t == 'half' %}#1abc9c; opacity:0.55{% else %}#ddd{% endif %};">{% if t == 'empty' %}☆{% else %}★{% endif %}</span>
|
<span style="font-size:0.95rem; line-height:1; color: {% if t == 'full' %}#1abc9c{% elif t == 'half' %}#1abc9c; opacity:0.55{% else %}#ddd{% endif %};">{% if t == 'empty' %}☆{% else %}★{% endif %}</span>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="display:flex; justify-content:space-between; align-items:center; {% if card.is_top_trump and 'weight' in card.best_stats %}box-shadow:inset 6px 0 0 #d35400; border-radius:4px;{% endif %}">
|
<div style="display:flex; justify-content:space-between; align-items:center; {% if card.is_top_trump and 'weight' in card.best_stats %}background:rgba(211,84,0,0.06); border-left:6px solid #d35400; border-radius:4px; padding:6px 8px;{% endif %}">
|
||||||
<div style="font-size:0.9rem; font-weight:700">Weight</div>
|
<div style="font-size:0.9rem; font-weight:700">Weight</div>
|
||||||
<div style="display:flex; align-items:center; gap:8px;">
|
<div style="display:flex; align-items:center; gap:8px;">
|
||||||
<div style="font-weight:800">{{ card.weight_display }}</div>
|
<div style="font-weight:800">{{ card.weight_display }}</div>
|
||||||
<div aria-hidden="true" style="display:flex; gap:2px;">
|
<div aria-hidden="true" style="display:flex; gap:2px;">
|
||||||
{% for t in card.weight_star_types %}
|
{% for t in card.weight_star_types_adj|default:card.weight_star_types %}
|
||||||
<span style="font-size:0.95rem; line-height:1; color: {% if t == 'full' %}#d35400{% elif t == 'half' %}#d35400; opacity:0.55{% else %}#ddd{% endif %};">{% if t == 'empty' %}☆{% else %}★{% endif %}</span>
|
<span style="font-size:0.95rem; line-height:1; color: {% if t == 'full' %}#d35400{% elif t == 'half' %}#d35400; opacity:0.55{% else %}#ddd{% endif %};">{% if t == 'empty' %}☆{% else %}★{% endif %}</span>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="display:flex; justify-content:space-between; align-items:center; {% if card.is_top_trump and 'intelligence' in card.best_stats %}box-shadow:inset 6px 0 0 #8e44ad; border-radius:4px;{% endif %}">
|
<div style="display:flex; justify-content:space-between; align-items:center; {% if card.is_top_trump and 'intelligence' in card.best_stats %}background:rgba(142,68,173,0.06); border-left:6px solid #8e44ad; border-radius:4px; padding:6px 8px;{% endif %}">
|
||||||
<div style="font-size:0.9rem; font-weight:700">Intelligence</div>
|
<div style="font-size:0.9rem; font-weight:700">Intelligence</div>
|
||||||
<div style="display:flex; align-items:center; gap:8px;">
|
<div style="display:flex; align-items:center; gap:8px;">
|
||||||
<div style="font-weight:800">{{ card.intelligence_display }}</div>
|
<div style="font-weight:800">{{ card.intelligence_display }}</div>
|
||||||
<div aria-hidden="true" style="display:flex; gap:2px;">
|
<div aria-hidden="true" style="display:flex; gap:2px;">
|
||||||
{% for t in card.intelligence_star_types %}
|
{% for t in card.intelligence_star_types_adj|default:card.intelligence_star_types %}
|
||||||
<span style="font-size:0.95rem; line-height:1; color: {% if t == 'full' %}#8e44ad{% elif t == 'half' %}#8e44ad; opacity:0.55{% else %}#ddd{% endif %};">{% if t == 'empty' %}☆{% else %}★{% endif %}</span>
|
<span style="font-size:0.95rem; line-height:1; color: {% if t == 'full' %}#8e44ad{% elif t == 'half' %}#8e44ad; opacity:0.55{% else %}#ddd{% endif %};">{% if t == 'empty' %}☆{% else %}★{% endif %}</span>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="display:flex; justify-content:space-between; align-items:center; {% if card.is_top_trump and 'height' in card.best_stats %}box-shadow:inset 6px 0 0 #27ae60; border-radius:4px;{% endif %}">
|
<div style="display:flex; justify-content:space-between; align-items:center; {% if card.is_top_trump and 'height' in card.best_stats %}background:rgba(39,174,96,0.06); border-left:6px solid #27ae60; border-radius:4px; padding:6px 8px;{% endif %}">
|
||||||
<div style="font-size:0.9rem; font-weight:700">Height</div>
|
<div style="font-size:0.9rem; font-weight:700">Height</div>
|
||||||
<div style="display:flex; align-items:center; gap:8px;">
|
<div style="display:flex; align-items:center; gap:8px;">
|
||||||
<div style="font-weight:800">{{ card.height_display }}</div>
|
<div style="font-weight:800">{{ card.height_display }}</div>
|
||||||
<div aria-hidden="true" style="display:flex; gap:2px;">
|
<div aria-hidden="true" style="display:flex; gap:2px;">
|
||||||
{% for t in card.height_star_types %}
|
{% for t in card.height_star_types_adj|default:card.height_star_types %}
|
||||||
<span style="font-size:0.95rem; line-height:1; color: {% if t == 'full' %}#27ae60{% elif t == 'half' %}#27ae60; opacity:0.55{% else %}#ddd{% endif %};">{% if t == 'empty' %}☆{% else %}★{% endif %}</span>
|
<span style="font-size:0.95rem; line-height:1; color: {% if t == 'full' %}#27ae60{% elif t == 'half' %}#27ae60; opacity:0.55{% else %}#ddd{% endif %};">{% if t == 'empty' %}☆{% else %}★{% endif %}</span>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
<div class="stat-value" style="margin-left:8px;font-weight:600">
|
<div class="stat-value" style="margin-left:8px;font-weight:600">
|
||||||
<div>{{ card.speed_display }}</div>
|
<div>{{ card.speed_display }}</div>
|
||||||
<div class="is-size-7" style="font-weight:500; display:flex; align-items:center; gap:8px;">
|
<div class="is-size-7" style="font-weight:500; display:flex; align-items:center; gap:8px;">
|
||||||
<div class="stars">{% for t in card.speed_star_types %}<span class="star {{ t }}">{% if t == 'full' %}★{% else %}☆{% endif %}</span>{% endfor %}</div>
|
<div class="stars">{% for t in card.speed_star_types_adj|default:card.speed_star_types %}<span class="star {{ t }}">{% if t == 'full' %}★{% else %}☆{% endif %}</span>{% endfor %}</div>
|
||||||
<span style="margin-left:6px">(orig: {{ card.speed_orig }})</span>
|
<span style="margin-left:6px">(orig: {{ card.speed_orig }})</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -44,7 +44,7 @@
|
|||||||
<div class="stat-value" style="margin-left:8px;font-weight:600">
|
<div class="stat-value" style="margin-left:8px;font-weight:600">
|
||||||
<div>{{ card.weight_display }}</div>
|
<div>{{ card.weight_display }}</div>
|
||||||
<div class="is-size-7" style="font-weight:500; display:flex; align-items:center; gap:8px;">
|
<div class="is-size-7" style="font-weight:500; display:flex; align-items:center; gap:8px;">
|
||||||
<div class="stars">{% for t in card.weight_star_types %}<span class="star {{ t }}">{% if t == 'full' %}★{% else %}☆{% endif %}</span>{% endfor %}</div>
|
<div class="stars">{% for t in card.weight_star_types_adj|default:card.weight_star_types %}<span class="star {{ t }}">{% if t == 'full' %}★{% else %}☆{% endif %}</span>{% endfor %}</div>
|
||||||
<span style="margin-left:6px">(orig: {{ card.weight_orig }})</span>
|
<span style="margin-left:6px">(orig: {{ card.weight_orig }})</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -53,7 +53,7 @@
|
|||||||
<div class="stat-label">Intelligence <small class="is-size-7">(score)</small></div>
|
<div class="stat-label">Intelligence <small class="is-size-7">(score)</small></div>
|
||||||
<div class="stat-value" style="margin-left:8px;font-weight:600">
|
<div class="stat-value" style="margin-left:8px;font-weight:600">
|
||||||
<div style="display:flex;align-items:center;gap:8px">
|
<div style="display:flex;align-items:center;gap:8px">
|
||||||
<div class="is-size-7" style="font-weight:600"><div class="stars">{% for t in card.intelligence_star_types %}<span class="star {{ t }}">{% if t == 'full' %}★{% else %}☆{% endif %}</span>{% endfor %}</div></div>
|
<div class="is-size-7" style="font-weight:600"><div class="stars">{% for t in card.intelligence_star_types_adj|default:card.intelligence_star_types %}<span class="star {{ t }}">{% if t == 'full' %}★{% else %}☆{% endif %}</span>{% endfor %}</div></div>
|
||||||
<div class="is-size-7" style="font-weight:500">(orig: {{ card.intelligence_orig }})</div>
|
<div class="is-size-7" style="font-weight:500">(orig: {{ card.intelligence_orig }})</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -41,20 +41,20 @@
|
|||||||
<div class="stat-label">Speed <small class="is-size-7">(km/h)</small></div>
|
<div class="stat-label">Speed <small class="is-size-7">(km/h)</small></div>
|
||||||
<div class="stat-value" style="margin-left:8px;font-weight:700">
|
<div class="stat-value" style="margin-left:8px;font-weight:700">
|
||||||
<div>{{ card.speed_display }}</div>
|
<div>{{ card.speed_display }}</div>
|
||||||
<div class="is-size-7" style="font-weight:500; display:flex; align-items:center; gap:8px;"><div class="stars">{% for t in card.speed_star_types %}<span class="star {{ t }}">{% if t == 'full' %}★{% else %}☆{% endif %}</span>{% endfor %}</div> <span style="margin-left:6px">(orig: {{ card.speed_orig }})</span></div>
|
<div class="is-size-7" style="font-weight:500; display:flex; align-items:center; gap:8px;"><div class="stars">{% for t in card.speed_star_types_adj|default:card.speed_star_types %}<span class="star {{ t }}">{% if t == 'full' %}★{% else %}☆{% endif %}</span>{% endfor %}</div> <span style="margin-left:6px">(orig: {{ card.speed_orig }})</span></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="stat-row">
|
<div class="stat-row">
|
||||||
<div class="stat-label">Weight <small class="is-size-7">(kg)</small></div>
|
<div class="stat-label">Weight <small class="is-size-7">(kg)</small></div>
|
||||||
<div class="stat-value" style="margin-left:8px;font-weight:700">
|
<div class="stat-value" style="margin-left:8px;font-weight:700">
|
||||||
<div>{{ card.weight_display }}</div>
|
<div>{{ card.weight_display }}</div>
|
||||||
<div class="is-size-7" style="font-weight:500; display:flex; align-items:center; gap:8px;"><div class="stars">{% for t in card.weight_star_types %}<span class="star {{ t }}">{% if t == 'full' %}★{% else %}☆{% endif %}</span>{% endfor %}</div> <span style="margin-left:6px">(orig: {{ card.weight_orig }})</span></div>
|
<div class="is-size-7" style="font-weight:500; display:flex; align-items:center; gap:8px;"><div class="stars">{% for t in card.weight_star_types_adj|default:card.weight_star_types %}<span class="star {{ t }}">{% if t == 'full' %}★{% else %}☆{% endif %}</span>{% endfor %}</div> <span style="margin-left:6px">(orig: {{ card.weight_orig }})</span></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="stat-row">
|
<div class="stat-row">
|
||||||
<div class="stat-label">Intelligence <small class="is-size-7">(score)</small></div>
|
<div class="stat-label">Intelligence <small class="is-size-7">(score)</small></div>
|
||||||
<div class="stat-value" style="margin-left:8px;font-weight:700">
|
<div class="stat-value" style="margin-left:8px;font-weight:700">
|
||||||
<div style="display:flex;align-items:center;gap:8px"><div class="is-size-7" style="font-weight:600"><div class="stars">{% for t in card.intelligence_star_types %}<span class="star {{ t }}">{% if t == 'full' %}★{% else %}☆{% endif %}</span>{% endfor %}</div></div>
|
<div style="display:flex;align-items:center;gap:8px"><div class="is-size-7" style="font-weight:600"><div class="stars">{% for t in card.intelligence_star_types_adj|default:card.intelligence_star_types %}<span class="star {{ t }}">{% if t == 'full' %}★{% else %}☆{% endif %}</span>{% endfor %}</div></div>
|
||||||
<div class="is-size-7" style="font-weight:500">(orig: {{ card.intelligence_orig }})</div></div>
|
<div class="is-size-7" style="font-weight:500">(orig: {{ card.intelligence_orig }})</div></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -62,7 +62,7 @@
|
|||||||
<div class="stat-label">Height <small class="is-size-7">(m)</small></div>
|
<div class="stat-label">Height <small class="is-size-7">(m)</small></div>
|
||||||
<div class="stat-value" style="margin-left:8px;font-weight:700">
|
<div class="stat-value" style="margin-left:8px;font-weight:700">
|
||||||
<div>{{ card.height_display }}</div>
|
<div>{{ card.height_display }}</div>
|
||||||
<div class="is-size-7" style="font-weight:500; display:flex; align-items:center; gap:8px;"><div class="stars">{% for t in card.height_star_types %}<span class="star {{ t }}">{% if t == 'full' %}★{% else %}☆{% endif %}</span>{% endfor %}</div> <span style="margin-left:6px">(orig: {{ card.height_orig }})</span></div>
|
<div class="is-size-7" style="font-weight:500; display:flex; align-items:center; gap:8px;"><div class="stars">{% for t in card.height_star_types_adj|default:card.height_star_types %}<span class="star {{ t }}">{% if t == 'full' %}★{% else %}☆{% endif %}</span>{% endfor %}</div> <span style="margin-left:6px">(orig: {{ card.height_orig }})</span></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,28 +3,28 @@
|
|||||||
<div class="stat-label">Speed <small class="is-size-7">(km/h)</small></div>
|
<div class="stat-label">Speed <small class="is-size-7">(km/h)</small></div>
|
||||||
<div style="text-align:right">
|
<div style="text-align:right">
|
||||||
<div style="font-weight:700">{{ card.speed_display }}</div>
|
<div style="font-weight:700">{{ card.speed_display }}</div>
|
||||||
<div class="is-size-7" style="font-weight:500; display:flex; align-items:center; gap:8px; justify-content:flex-end;"><div class="stars">{% for t in card.speed_star_types %}<span class="star {{ t }}">{% if t == 'full' %}★{% else %}☆{% endif %}</span>{% endfor %}</div> <span style="margin-left:6px">(orig: {{ card.speed_orig }})</span></div>
|
<div class="is-size-7" style="font-weight:500; display:flex; align-items:center; gap:8px; justify-content:flex-end;"><div class="stars">{% for t in card.speed_star_types_adj|default:card.speed_star_types %}<span class="star {{ t }}">{% if t == 'full' %}★{% else %}☆{% endif %}</span>{% endfor %}</div> <span style="margin-left:6px">(orig: {{ card.speed_orig }})</span></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style="display:flex; justify-content:space-between; align-items:center">
|
<div style="display:flex; justify-content:space-between; align-items:center">
|
||||||
<div class="stat-label">Weight <small class="is-size-7">(kg)</small></div>
|
<div class="stat-label">Weight <small class="is-size-7">(kg)</small></div>
|
||||||
<div style="text-align:right">
|
<div style="text-align:right">
|
||||||
<div style="font-weight:700">{{ card.weight_display }}</div>
|
<div style="font-weight:700">{{ card.weight_display }}</div>
|
||||||
<div class="is-size-7" style="font-weight:500; display:flex; align-items:center; gap:8px; justify-content:flex-end;"><div class="stars">{% for t in card.weight_star_types %}<span class="star {{ t }}">{% if t == 'full' %}★{% else %}☆{% endif %}</span>{% endfor %}</div> <span style="margin-left:6px">(orig: {{ card.weight_orig }})</span></div>
|
<div class="is-size-7" style="font-weight:500; display:flex; align-items:center; gap:8px; justify-content:flex-end;"><div class="stars">{% for t in card.weight_star_types_adj|default:card.weight_star_types %}<span class="star {{ t }}">{% if t == 'full' %}★{% else %}☆{% endif %}</span>{% endfor %}</div> <span style="margin-left:6px">(orig: {{ card.weight_orig }})</span></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style="display:flex; justify-content:space-between; align-items:center">
|
<div style="display:flex; justify-content:space-between; align-items:center">
|
||||||
<div class="stat-label">Intelligence <small class="is-size-7">(score)</small></div>
|
<div class="stat-label">Intelligence <small class="is-size-7">(score)</small></div>
|
||||||
<div style="text-align:right">
|
<div style="text-align:right">
|
||||||
<div style="font-weight:700">{{ card.intelligence_display }}</div>
|
<div style="font-weight:700">{{ card.intelligence_display }}</div>
|
||||||
<div class="is-size-7" style="font-weight:500; display:flex; align-items:center; gap:8px; justify-content:flex-end;"><div class="stars">{% for t in card.intelligence_star_types %}<span class="star {{ t }}">{% if t == 'full' %}★{% else %}☆{% endif %}</span>{% endfor %}</div> <span style="margin-left:6px">(orig: {{ card.intelligence_orig }})</span></div>
|
<div class="is-size-7" style="font-weight:500; display:flex; align-items:center; gap:8px; justify-content:flex-end;"><div class="stars">{% for t in card.intelligence_star_types_adj|default:card.intelligence_star_types %}<span class="star {{ t }}">{% if t == 'full' %}★{% else %}☆{% endif %}</span>{% endfor %}</div> <span style="margin-left:6px">(orig: {{ card.intelligence_orig }})</span></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style="display:flex; justify-content:space-between; align-items:center">
|
<div style="display:flex; justify-content:space-between; align-items:center">
|
||||||
<div class="stat-label">Height <small class="is-size-7">(m)</small></div>
|
<div class="stat-label">Height <small class="is-size-7">(m)</small></div>
|
||||||
<div style="text-align:right">
|
<div style="text-align:right">
|
||||||
<div style="font-weight:700">{{ card.height_display }}</div>
|
<div style="font-weight:700">{{ card.height_display }}</div>
|
||||||
<div class="is-size-7" style="font-weight:500; display:flex; align-items:center; gap:8px; justify-content:flex-end;"><div class="stars">{% for t in card.height_star_types %}<span class="star {{ t }}">{% if t == 'full' %}★{% else %}☆{% endif %}</span>{% endfor %}</div> <span style="margin-left:6px">(orig: {{ card.height_orig }})</span></div>
|
<div class="is-size-7" style="font-weight:500; display:flex; align-items:center; gap:8px; justify-content:flex-end;"><div class="stars">{% for t in card.height_star_types_adj|default:card.height_star_types %}<span class="star {{ t }}">{% if t == 'full' %}★{% else %}☆{% endif %}</span>{% endfor %}</div> <span style="margin-left:6px">(orig: {{ card.height_orig }})</span></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+89
-6
@@ -460,17 +460,100 @@ def print_preview(request):
|
|||||||
# For each card compute its best stat percent (0-100) and the stat(s)
|
# For each card compute its best stat percent (0-100) and the stat(s)
|
||||||
# that achieve that percent. Then find the global maximum best-value and
|
# that achieve that percent. Then find the global maximum best-value and
|
||||||
# mark any card whose best-value equals that maximum as a top-trump.
|
# mark any card whose best-value equals that maximum as a top-trump.
|
||||||
|
# Compute selection maxima for speed/weight/height/intelligence so we
|
||||||
|
# can scale these metrics relative to the selected cards. This prevents
|
||||||
|
# many large absolute values from all clamping to 100% and getting 5★.
|
||||||
|
max_speed = 0.0
|
||||||
|
max_weight = 0.0
|
||||||
|
max_height = 0.0
|
||||||
|
max_intel = 0.0
|
||||||
|
for c in ordered:
|
||||||
|
try:
|
||||||
|
sv = float(c.speed or 0)
|
||||||
|
except Exception:
|
||||||
|
sv = 0.0
|
||||||
|
try:
|
||||||
|
wv = float(c.weight or 0)
|
||||||
|
except Exception:
|
||||||
|
wv = 0.0
|
||||||
|
try:
|
||||||
|
hv = float(c.height or 0)
|
||||||
|
except Exception:
|
||||||
|
hv = 0.0
|
||||||
|
try:
|
||||||
|
iv = float(c.intelligence or 0)
|
||||||
|
except Exception:
|
||||||
|
iv = 0.0
|
||||||
|
if sv > max_speed:
|
||||||
|
max_speed = sv
|
||||||
|
if wv > max_weight:
|
||||||
|
max_weight = wv
|
||||||
|
if hv > max_height:
|
||||||
|
max_height = hv
|
||||||
|
if iv > max_intel:
|
||||||
|
max_intel = iv
|
||||||
|
|
||||||
all_best_values = []
|
all_best_values = []
|
||||||
for c in ordered:
|
for c in ordered:
|
||||||
# compute percents using model helpers
|
# raw values
|
||||||
s = c.speed_percent()
|
try:
|
||||||
w = c.weight_percent()
|
raw_s = float(c.speed or 0)
|
||||||
it = c.intelligence_percent()
|
except Exception:
|
||||||
h = c.height_percent()
|
raw_s = 0.0
|
||||||
# map names to values
|
try:
|
||||||
|
raw_w = float(c.weight or 0)
|
||||||
|
except Exception:
|
||||||
|
raw_w = 0.0
|
||||||
|
try:
|
||||||
|
raw_h = float(c.height or 0)
|
||||||
|
except Exception:
|
||||||
|
raw_h = 0.0
|
||||||
|
try:
|
||||||
|
raw_it = float(c.intelligence or 0)
|
||||||
|
except Exception:
|
||||||
|
raw_it = 0.0
|
||||||
|
|
||||||
|
# Compute selection-relative percents so the largest in the
|
||||||
|
# selection maps to 100% for each metric.
|
||||||
|
if max_speed > 0:
|
||||||
|
s = min(100, int(round((raw_s / max_speed) * 100)))
|
||||||
|
else:
|
||||||
|
s = 0
|
||||||
|
if max_weight > 0:
|
||||||
|
w = min(100, int(round((raw_w / max_weight) * 100)))
|
||||||
|
else:
|
||||||
|
w = 0
|
||||||
|
if max_height > 0:
|
||||||
|
h = min(100, int(round((raw_h / max_height) * 100)))
|
||||||
|
else:
|
||||||
|
h = 0
|
||||||
|
if max_intel > 0:
|
||||||
|
it = min(100, int(round((raw_it / max_intel) * 100)))
|
||||||
|
else:
|
||||||
|
it = 0
|
||||||
|
|
||||||
|
# Attach adjusted star visuals for the printable preview so
|
||||||
|
# templates reflect selection-relative scaling. These instance
|
||||||
|
# attributes shadow the class properties during template rendering.
|
||||||
|
setattr(c, 'speed_star_types_adj', c._star_types_from_percent(s))
|
||||||
|
setattr(c, 'speed_stars_adj', c._stars_string(s))
|
||||||
|
setattr(c, 'weight_star_types_adj', c._star_types_from_percent(w))
|
||||||
|
setattr(c, 'weight_stars_adj', c._stars_string(w))
|
||||||
|
setattr(c, 'height_star_types_adj', c._star_types_from_percent(h))
|
||||||
|
setattr(c, 'height_stars_adj', c._stars_string(h))
|
||||||
|
setattr(c, 'intelligence_star_types_adj', c._star_types_from_percent(it))
|
||||||
|
setattr(c, 'intelligence_stars_adj', c._stars_string(it))
|
||||||
|
|
||||||
|
setattr(c, 'speed_percent_adj', s)
|
||||||
|
setattr(c, 'weight_percent_adj', w)
|
||||||
|
setattr(c, 'height_percent_adj', h)
|
||||||
|
setattr(c, 'intelligence_percent_adj', it)
|
||||||
|
|
||||||
|
# map names to values (independent stats) using adjusted percents
|
||||||
stats = {'speed': s, 'weight': w, 'intelligence': it, 'height': h}
|
stats = {'speed': s, 'weight': w, 'intelligence': it, 'height': h}
|
||||||
max_val = max(stats.values())
|
max_val = max(stats.values())
|
||||||
best_stats = [name for name, val in stats.items() if val == max_val]
|
best_stats = [name for name, val in stats.items() if val == max_val]
|
||||||
|
|
||||||
# attach computed attributes so templates can read them
|
# attach computed attributes so templates can read them
|
||||||
setattr(c, 'best_value', max_val)
|
setattr(c, 'best_value', max_val)
|
||||||
setattr(c, 'best_stats', best_stats)
|
setattr(c, 'best_stats', best_stats)
|
||||||
|
|||||||
Reference in New Issue
Block a user