Skoči na vsebino

P1 2021/22 - 09 Nacrt Napada - resitev Aljaz S.

"""
https://ucilnica.fri.uni-lj.si/mod/assign/view.php?id=47016

Videti je, da bo potrebno napisati tri funkcije.

preberi(ime_datoteke) dobi ime datoteke, kakršne proizvaja
Kozjančeva in, kot je sklepati iz testov, vrne slovar, katerega
ključi so koordinate naših ladij, pripadajoče vrednosti pa
seznami koordinat marsovskih ladij. Ime datoteke je načelno
poljubno.

vrstica(i, ladja, marsovec) vrne eno vrstico navodil za CRKnaV.
Iz testov lahko sklepamo, da i vsebuje zaporedno številko naše
ladje ali pa None. Če je i številka, jo izpiše, nato izpiše
koordinate naše in koordinate marsovske ladje. Če je i enak
None, pa ne izpiše ne številke na koordinat naše ladje, temveč
samo koordinato marsovske ladje. Torej: klic
vrstica(7, (4.25, 8.50), (5, 5)) vrne

    7:     4.2500     8.5000 ->     5.0000    12.3000

klic vrstica(None, (4.25, 8.50), (5, 12.3)) pa bi vrnil

                                    5.0000    12.3000

O tem, kako, točno mora biti oblikovan izpis, bo potrebno
sklepati iz testov. Good luck.

navodila(razpored, ime_datoteke) dobi slovar v takšni obliki,
kot ga vrača prva funkcija in ime datoteke, v katero izpiše
navodila, ki se do zadnje pike ujemajo s predvidenim formatom.

Sreča v nesreči: v tej nalogi se se dogaja samo v dveh dimenzijah.

"""

import unittest
import random
import string
import os
import warnings

from itertools import count


def parts(source, delimiter):
    return [ p.strip() for p in source.split(delimiter) ]

def mkCoords (source):
    return tuple(float(v) for v in parts(source, ","))

def preberi(ime_datoteke):
    with open(ime_datoteke) as f:
        lines = f.readlines()
        final = dict()
        for line in lines:
            index_, values_ = parts(line, ":")
            index = mkCoords(index_)
            values = [ mkCoords(part) for part in parts(values_, "|") ]
            final[index] = values
        return final


def vf(val):
    return f"{val:{10}.{4}f}"

def vrstica(index, l, m):
    lx, ly = l
    mx, my = m
    start = f"{index:4}: {vf(lx)} {vf(ly)} ->" if index else ""
    return f"{start:30} {vf(mx)} {vf(my)}"

def navodila(razpored, ime_datoteke):
    with open(ime_datoteke, 'a') as f:
        for i, ladja, marsovci in zip(count(start=1), razpored, razpored.values()):
            for j, marsovec in zip(count(), marsovci):
                args_ = (i, ladja, marsovec) if j == 0 else (None, ladja, marsovec)
                f.write(vrstica(*args_) + '\n')



class Test(unittest.TestCase):
    def setUp(self):
        warnings.simplefilter("ignore", ResourceWarning)

    def test_preberi(self):
        self.assertEqual(
            {(4.25, 8.5): [(5.0, 5.0), (8.125, -7.5), (3.5, -6.75)],
             (6.0, 1.25): [(15.5, 5.5), (1.5, -1.25), (2.5, -9.5625), (-3.0, -3.0)],
             (8.0, 1.0):  [(-2.0, 5.0)]},
            preberi("jozica-kozjanc.txt"))
        try:
            fname = "".join(random.choice(string.ascii_lowercase) for _ in range(8))
            os.rename("jozica-kozjanc.txt", fname)
            self.assertEqual(
                {(4.25, 8.5): [(5.0, 5.0), (8.125, -7.5), (3.5, -6.75)],
                 (6.0, 1.25): [(15.5, 5.5), (1.5, -1.25), (2.5, -9.5625), (-3.0, -3.0)],
                 (8.0, 1.0):  [(-2.0, 5.0)]},
                preberi(fname), "Datoteka ima lahko poljubno ime!")
        finally:
            os.rename(fname, "jozica-kozjanc.txt")

    def test_vrstica(self):
        self.assertEqual("   3:    13.1800    35.5600 ->    75.2000   182.7000",
                         vrstica(3, (13.18, 35.56), (75.2, 182.7)))
        self.assertEqual("                                  75.2000   182.7000",
                         vrstica(None, (13.18, 35.56), (75.2, 182.7)))
        self.assertEqual("   1:  1234.0123 -3456.3457 ->  1234.0123 -3456.3457",
                         vrstica(1, (1234.01234, -3456.34567), (1234.01234, -3456.34567)))
        self.assertEqual("                                1234.0123 -3456.3457",
                         vrstica(None, (1234.01234, -3456.34567), (1234.01234, -3456.34567)))

    def test_navodila(self):
        fname = "".join(random.choice(string.ascii_lowercase) for _ in range(8))
        navodila({(0.248178, 0.316933): [(0.15224490098349647, 0.3027892234548336),
                                         (0.3973177864167832, 0.3654278922345483),
                                         (0.20545151426835478, 0.19569730586370837),
                                         (0.23769794656220833, 0.4038193343898574)],
                  (0.424727, 0.747726): [(0.35862206766415905, 0.8140015847860539),
                                         (0.3408865299025396, 0.6766006339144215),
                                         (0.5069556562158851, 0.6907448494453249),
                                         (0.4069917161049393, 0.7048890649762283),
                                         (0.5101802994452705, 0.8523930269413629)],
                  (0.64884, 0.245202): [(0.6165935260149872, 0.355324881141046),
                                        (0.6020826314827531, 0.18963549920760692),
                                        (0.6730247825292308, 0.22600633914421553),
                                        (0.6182058476296798, 0.26237717908082403),
                                        (0.6826987122173869, 0.14518225039619648),
                                        (0.7004342499790063, 0.2926862123613312)],
                  (0.786425, 0.568835): [(0.8326446223838057, 0.5957765451664025),
                                         (0.8003981900899522, 0.5553645007923931),
                                         (0.7262313958140891, 0.5553645007923931)]},
                 fname)
        self.assertEqual("""
   1:     0.2482     0.3169 ->     0.1522     0.3028
                                   0.3973     0.3654
                                   0.2055     0.1957
                                   0.2377     0.4038
   2:     0.4247     0.7477 ->     0.3586     0.8140
                                   0.3409     0.6766
                                   0.5070     0.6907
                                   0.4070     0.7049
                                   0.5102     0.8524
   3:     0.6488     0.2452 ->     0.6166     0.3553
                                   0.6021     0.1896
                                   0.6730     0.2260
                                   0.6182     0.2624
                                   0.6827     0.1452
                                   0.7004     0.2927
   4:     0.7864     0.5688 ->     0.8326     0.5958
                                   0.8004     0.5554
                                   0.7262     0.5554""".strip("\n"),
                         open(fname).read().strip("\n"))
        os.remove(fname)

        navodila({(1234.23456, -12.44): [(1, 2), (3, 4), (5, 6)]}, fname)
        self.assertEqual("""
   1:  1234.2346   -12.4400 ->     1.0000     2.0000
                                   3.0000     4.0000
                                   5.0000     6.0000""".strip("\n"),
                         open(fname).read().strip("\n"))
        os.remove(fname)

        navodila({(4.25, 8.5): [(5.0, 5.0), (8.125, -7.5), (3.5, -6.75)],
                  (6.0, 1.25): [(15.5, 5.5), (1.5, -1.25), (2.5, -9.5625), (-3.0, -3.0)],
                  (8.0, 1.0):  [(-2.0, 5.0)]}, fname)
        self.assertEqual("""
   1:     4.2500     8.5000 ->     5.0000     5.0000
                                   8.1250    -7.5000
                                   3.5000    -6.7500
   2:     6.0000     1.2500 ->    15.5000     5.5000
                                   1.5000    -1.2500
                                   2.5000    -9.5625
                                  -3.0000    -3.0000
   3:     8.0000     1.0000 ->    -2.0000     5.0000""".strip("\n"),
                         open(fname).read().strip("\n"))
        os.remove(fname)


if __name__ == "__main__":
    unittest.main()

Zadnja posodobitev: May 7, 2022