Merge branch 'develop' into wip/rect_rework
This commit is contained in:
commit
6cbb15dc69
6 changed files with 136 additions and 12 deletions
|
@ -3,7 +3,7 @@ import random
|
|||
import re
|
||||
from datetime import date, datetime, timedelta
|
||||
from io import BytesIO
|
||||
from typing import Any, Self, Sequence, TypeVar
|
||||
from typing import Any, Iterable, Self, Sequence, TypeVar
|
||||
|
||||
from fastapi.responses import StreamingResponse
|
||||
from PIL import Image
|
||||
|
@ -32,6 +32,53 @@ def set_len(seq: Sequence[T], len: int) -> Sequence[T]:
|
|||
return list(itertools.islice(infinite, len))
|
||||
|
||||
|
||||
def spread(
|
||||
given: Iterable[int],
|
||||
n: int,
|
||||
rnd: Random | None = None,
|
||||
) -> list[int]:
|
||||
"""
|
||||
Zu `given` ganzen Zahlen `n` zusätzliche Zahlen hinzunehmen.
|
||||
|
||||
- Die neuen Werte sind im selben Zahlenbereich wie `given`
|
||||
- Zuerst werden alle Werte "zwischen" den `given` Werten genommen
|
||||
"""
|
||||
|
||||
if n == 0:
|
||||
return []
|
||||
|
||||
if len(set(given)) > 1:
|
||||
range_given = range(min(given), max(given) + 1)
|
||||
first_round = set(range_given) - set(given)
|
||||
|
||||
elif len(set(given)) == 1:
|
||||
if (a := next(iter(given))) > 0:
|
||||
range_given = range(1, a + 1)
|
||||
else:
|
||||
range_given = range(1, n + 1)
|
||||
|
||||
first_round = set(range_given) - set(given)
|
||||
|
||||
else:
|
||||
range_given = range(1, n + 1)
|
||||
first_round = range_given
|
||||
|
||||
result = sorted(first_round)[: min(n, len(first_round))]
|
||||
|
||||
full_rounds = (n - len(result)) // len(range_given)
|
||||
result += list(range_given) * full_rounds
|
||||
|
||||
remain = n - len(result)
|
||||
if rnd is None:
|
||||
result += list(range_given)[:remain]
|
||||
|
||||
else:
|
||||
result += rnd.sample(range_given, remain)
|
||||
rnd.shuffle(result)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
async def list_images_auto() -> list[str]:
|
||||
"""
|
||||
Finde alle Bilddateien im "automatisch"-Verzeichnis
|
||||
|
|
77
api/test/test_spread.py
Normal file
77
api/test/test_spread.py
Normal file
|
@ -0,0 +1,77 @@
|
|||
from advent22_api.core.helpers import spread
|
||||
|
||||
|
||||
def test_easy() -> None:
|
||||
assert spread([1, 4], 0) == []
|
||||
assert spread([1, 4], 1) == [2]
|
||||
assert spread([1, 4], 2) == [2, 3]
|
||||
assert spread([1, 4], 5) == [2, 3, 1, 2, 3]
|
||||
assert spread([1, 4], 10) == [2, 3, 1, 2, 3, 4, 1, 2, 3, 4]
|
||||
|
||||
|
||||
def test_tight() -> None:
|
||||
assert spread([1, 2], 0) == []
|
||||
assert spread([1, 2], 1) == [1]
|
||||
assert spread([1, 2], 2) == [1, 2]
|
||||
assert spread([1, 2], 5) == [1, 2, 1, 2, 1]
|
||||
assert spread([1, 2], 10) == [1, 2, 1, 2, 1, 2, 1, 2, 1, 2]
|
||||
|
||||
assert spread([1, 2, 3, 4, 5], 0) == []
|
||||
assert spread([1, 2, 3, 4, 5], 1) == [1]
|
||||
assert spread([1, 2, 3, 4, 5], 2) == [1, 2]
|
||||
assert spread([1, 2, 3, 4, 5], 5) == [1, 2, 3, 4, 5]
|
||||
assert spread([1, 2, 3, 4, 5], 10) == [1, 2, 3, 4, 5, 1, 2, 3, 4, 5]
|
||||
|
||||
|
||||
def test_more_given() -> None:
|
||||
assert spread([0, 5, 10], 0) == []
|
||||
assert spread([0, 5, 10], 1) == [1]
|
||||
assert spread([0, 5, 10], 2) == [1, 2]
|
||||
assert spread([0, 5, 10], 5) == [1, 2, 3, 4, 6]
|
||||
assert spread([0, 5, 10], 10) == [1, 2, 3, 4, 6, 7, 8, 9, 0, 1]
|
||||
|
||||
assert spread([0, 1, 2, 5, 10], 0) == []
|
||||
assert spread([0, 1, 2, 5, 10], 1) == [3]
|
||||
assert spread([0, 1, 2, 5, 10], 2) == [3, 4]
|
||||
assert spread([0, 1, 2, 5, 10], 5) == [3, 4, 6, 7, 8]
|
||||
assert spread([0, 1, 2, 5, 10], 10) == [3, 4, 6, 7, 8, 9, 0, 1, 2, 3]
|
||||
|
||||
|
||||
def test_one_given() -> None:
|
||||
assert spread([0], 0) == []
|
||||
assert spread([0], 1) == [1]
|
||||
assert spread([0], 2) == [1, 2]
|
||||
assert spread([0], 5) == [1, 2, 3, 4, 5]
|
||||
assert spread([0], 10) == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
|
||||
|
||||
assert spread([1], 0) == []
|
||||
assert spread([1], 1) == [1]
|
||||
assert spread([1], 2) == [1, 1]
|
||||
assert spread([1], 5) == [1, 1, 1, 1, 1]
|
||||
assert spread([1], 10) == [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
|
||||
|
||||
assert spread([2], 0) == []
|
||||
assert spread([2], 1) == [1]
|
||||
assert spread([2], 2) == [1, 1]
|
||||
assert spread([2], 5) == [1, 1, 2, 1, 2]
|
||||
assert spread([2], 10) == [1, 1, 2, 1, 2, 1, 2, 1, 2, 1]
|
||||
|
||||
assert spread([5], 0) == []
|
||||
assert spread([5], 1) == [1]
|
||||
assert spread([5], 2) == [1, 2]
|
||||
assert spread([5], 5) == [1, 2, 3, 4, 1]
|
||||
assert spread([5], 10) == [1, 2, 3, 4, 1, 2, 3, 4, 5, 1]
|
||||
|
||||
assert spread([10], 0) == []
|
||||
assert spread([10], 1) == [1]
|
||||
assert spread([10], 2) == [1, 2]
|
||||
assert spread([10], 5) == [1, 2, 3, 4, 5]
|
||||
assert spread([10], 10) == [1, 2, 3, 4, 5, 6, 7, 8, 9, 1]
|
||||
|
||||
|
||||
def test_none_given() -> None:
|
||||
assert spread([], 0) == []
|
||||
assert spread([], 1) == [1]
|
||||
assert spread([], 2) == [1, 2]
|
||||
assert spread([], 5) == [1, 2, 3, 4, 5]
|
||||
assert spread([], 10) == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
|
|
@ -23,10 +23,7 @@
|
|||
</div>
|
||||
<div class="level-right">
|
||||
<div class="level-item">
|
||||
<AdminButton
|
||||
v-model="is_admin"
|
||||
button_class="tag is-link is-outlined"
|
||||
/>
|
||||
<AdminButton class="tag is-link is-outlined" v-model="is_admin" />
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<LoginModal v-if="modal_visible" @submit="on_submit" @cancel="on_cancel" />
|
||||
|
||||
<BulmaButton
|
||||
:class="button_class"
|
||||
v-bind="$attrs"
|
||||
:icon="'fa-solid fa-toggle-' + (modelValue ? 'on' : 'off')"
|
||||
:busy="is_busy"
|
||||
text="Admin"
|
||||
|
@ -11,6 +11,7 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Credentials } from "@/lib/api";
|
||||
import { Options, Vue } from "vue-class-component";
|
||||
|
||||
import BulmaButton from "./bulma/Button.vue";
|
||||
|
@ -23,14 +24,12 @@ import LoginModal from "./LoginModal.vue";
|
|||
},
|
||||
props: {
|
||||
modelValue: Boolean,
|
||||
button_class: String,
|
||||
},
|
||||
emits: ["update:modelValue"],
|
||||
})
|
||||
export default class extends Vue {
|
||||
// true, iff Benutzer Admin ist
|
||||
public modelValue!: boolean;
|
||||
public button_class!: string;
|
||||
|
||||
public modal_visible = false;
|
||||
public is_busy = false;
|
||||
|
@ -38,7 +37,7 @@ export default class extends Vue {
|
|||
public on_click() {
|
||||
if (this.modelValue) {
|
||||
// logout
|
||||
this.$advent22.set_api_auth();
|
||||
this.$advent22.clear_api_auth();
|
||||
this.$emit("update:modelValue", false);
|
||||
} else {
|
||||
// show login modal
|
||||
|
@ -47,9 +46,9 @@ export default class extends Vue {
|
|||
}
|
||||
}
|
||||
|
||||
public on_submit(username: string, password: string) {
|
||||
public on_submit(creds: Credentials) {
|
||||
this.modal_visible = false;
|
||||
this.$advent22.api_auth = [username, password];
|
||||
this.$advent22.api_auth = creds;
|
||||
|
||||
this.$advent22
|
||||
.api_get<boolean>("admin/is_admin")
|
||||
|
|
|
@ -89,7 +89,7 @@ export default class extends Vue {
|
|||
}
|
||||
|
||||
public submit(): void {
|
||||
this.$emit("submit", this.username, this.password);
|
||||
this.$emit("submit", [this.username, this.password]);
|
||||
}
|
||||
|
||||
public cancel(): void {
|
||||
|
|
|
@ -94,6 +94,10 @@ export class Advent22 {
|
|||
this._api_auth = creds;
|
||||
}
|
||||
|
||||
public clear_api_auth(): void {
|
||||
this.set_api_auth();
|
||||
}
|
||||
|
||||
public set api_auth(creds: Credentials) {
|
||||
this.set_api_auth(creds);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue