This commit is contained in:
maks 2023-11-19 22:41:55 +01:00
commit f53e9cb6d6
2 changed files with 352 additions and 0 deletions

241
README.md Normal file
View File

@ -0,0 +1,241 @@
## Zajęcia 1 16.10.2023
### Informacje na temat przedmiotu
Prowadzący: mgr inż. Bartosz Fijałkowski
mail: bf55466@st.amu.edu.pl
Gdyby była potrzeba przedyskutowania czegoś to możemy zostać po zajęciach. Można też kontaktować się ze mną mailowo.
W celu zaliczenia przedmiotu należy zdobyć punkty za zadania na laboratoriach oraz zaliczyć kolokwium.
Punktowane zadania będziemy wykonywać na laboratoriach oraz po nich (przed następnymi zajęciami), ich ilość determinuje ocenę.
Oprócz tego należy zaliczyć kolokwium z wyrażeń regularnych na ostatnich zajęciach. Sam wynik kolokwium
nie będzie wpływał na ocenę, ale bez zdanego kolowkium nie da się zaliczyć przedmiotu. Punktacja za zadania jest następująca:
- mniej niż 30 punktów - 2
- 30-34- 3
- 35-39- 3.5
- 40-44- 4
- 45-49- 4.5
- więcej niż 49- 5
#### Wysyłanie zadań
Proszę stworzyć prywatne repozytorium na https://git.wmi.amu.edu.pl/ o nazwie djfz-2023-sNRINDEKSU oraz dać
prawa do odczytu użytkownikowi bfijalkowski (prowadzący przedmiot). W NRINDEKSU proszę wpisać swój nr indeksu, np. djfz-2023-s123456.
Następnie w swoim repozytorium proszę zforkować niniejsze repozytorium: `git pull git@git.wmi.amu.edu.pl:bfijalkowski/DJFZ-2023.git`
W ten sposób będziemy aktualizować zadania co zajęcia.
Proszę rozwiązać zadanie TASKX02 lub TASKX03 w zależności od numeru indeksu. W tym celu należy dodać plik `run.py`
w odpowiednim katalogu. Za pomocą `run_reports.py` można sprawdzić ilość punktów.
Do repo proszę dodawać wyłącznie plik `run.py` w odpowiednim katalogu, chyba że w zadaniu jest zaznaczone inaczej.
Proszę również nie modyfikować innych plików.
Wszystkie zadania należy robić w terminie zaznaczonym w `description.txt`. Po terminie będę podawał punktację za pomocą USOSa w "sprawdziany".
Zadania robimy do dnia poprzedzającego następne zajęcia.
#### Aktualizacja repozytorium
We własnym repozytorium:
`git pull git@git.wmi.amu.edu.pl:bfijalkowski/DJFZ-2023.git`
## Zajęcia 1 16.10.2023 Automaty deterministyczne skończone
B00 - zadanie wykonywane wspólnie na zajęciach
B01-B04, B06-B09 - po jedno dla każdego
B05 - jedno dla wszystkich
## Zajęcia 2 30.10.2023 Automaty niedeterministyczne skończone
C00 - zadanie wykonywane wspólnie na zajęciach
C01-C03, C04-C06 - po jedno dla każdego
## Zajęcia 3 13.11.2023 Wyrażenia regularne
D01 - D04 - do wykonania przez każdego
Dokumentacja wyrażeń regularnych w python3: https://docs.python.org/3/library/re.html
### Podstawowe funkcje
search - zwraca pierwsze dopasowanie w napisie
findall - zwraca listę wszystkich dopasowań (nienakładających się na siebie)
match - zwraca dopasowanie od początku string
To tylko podstawowe funkcje, z których będziemy korzystać. W dokumentacji opisane są wszystkie.
### Obiekt match
```
import re
answer = re.search('na','banan')
print(answer)
print(type(answer))
print(answer.start())
print(answer.end())
print(answer.group())
answer = re.search('na','kabanos')
print(answer)
if answer:
print(answer.group())
else:
pass
```
### Metaznaki
- [] - zbiór znaków
- . - jakikolwiek znak
- ^ - początek napisu
- $ - koniec napisu
- ? - znak występuje lub nie występuje
- \* - zero albo więcej pojawień się
- \+ - jeden albo więcej pojawień się
- {} - dokładnie tyle pojawień się
- | - lub
- () - grupa
- \ -znak ucieczki
- \d digit
- \D nie digit
- \s whitespace
- \S niewhitespace
### Flagi
Można użyć specjalnych flag, np:
`re.search('ma', 'AlA Ma KoTa', re.IGNORECASE)`.
### Przykłady (objaśnienia na laboratoriach)
```
import re
text = 'Ala ma kota i hamak, oraz 150 bananów.'
re.search('ma',text)
re.match('ma',text)
re.match('Ala ma',text)
re.findall('ma',text)
re.findall('[mn]a',text)
re.findall('[0-9]',text)
re.findall('[0-9abc]',text)
re.findall('[a-z][a-z]ma[a-z]',text)
re.findall('[a-zA-Z][a-zA-Z]ma[a-zA-z0-9]',text)
re.findall('\d',text)
re.search('[0-9][0-9][0-9]',text)
re.search('[\d][\d][\d]',text)
re.search('\d{2}',text)
re.search('\d{3}',text)
re.search('\d+',text)
re.search('\d+ bananów',text)
re.search('\d* bananów','Ala ma dużo bananów')
re.search('\d* bananów',text)
re.search('ma \d? bananów','Ala ma 5 bananów')
re.search('ma ?\d? bananów','Ala ma bananów')
re.search('ma( \d)? bananów','Ala ma bananów')
re.search('\d+ bananów','Ala ma 10 bananów albo 20 bananów')
re.search('\d+ bananów$','Ala ma 10 bananów albo 20 bananów')
text = 'Ala ma kota i hamak, oraz 150 bananów.'
re.search('\d+ bananów',text)
re.search('\d+\sbananów',text)
re.search('kota . hamak',text)
re.search('kota . hamak','Ala ma kota z hamakiem')
re.search('kota .* hamak','Ala ma kota lub hamak')
re.search('\.',text)
re.search('kota|psa','Ala ma kota lub hamak')
re.findall('kota|psa','Ala ma kota lub psa')
re.search('kota (i|lub) psa','Ala ma kota lub psa')
re.search('mam (kota).*(kota|psa)','Ja mam kota. Ala ma psa.').group(0)
re.search('mam (kota).*(kota|psa)','Ja mam kota. Ala ma psa.').group(1)
re.search('mam (kota).*(kota|psa)','Ja mam kota. Ala ma psa.').group(2)
```
### Przykłady wyrażenia regularne 2 (objaśnienia na laboratoriach)
#### ^
```
re.search('[0-9]+', '123-456-789')
re.search('[^0-9][0-9]+[^0-9]', '123-456-789')
```
#### cudzysłów
'' oraz "" - oznaczają to samo w pythonie
' ala ma psa o imieniu "Burek"'
" ala ma psa o imieniu 'Burek' "
' ala ma psa o imieniu \'Burek\' '
" ala ma psa o imieniu \"Burek\" "
#### multiline string
#### raw string
przy raw string znaki \ traktowane są jako zwykłe znaki \
chociaż nawet w raw string nadal są escapowane (ale wtedy \ pozostają również w stringu bez zmian)
https://docs.python.org/3/reference/lexical_analysis.html
dobra praktyka - wszędzie escapować
```
'\\'
print('\\')
r'\\'
print(r'\\')
print("abcd")
print("ab\cd")
print(r"ab\cd")
print("ab\nd")
print(r"ab\nd")
print("\"")
print(r"\"")
print("\")
print(r"\")
re.search('\\', r'a\bc')
re.search(r'\\', r'a\bc')
re.search('\\\\', r'a\bc')
```

111
run_report.py Normal file
View File

@ -0,0 +1,111 @@
from pathlib import Path
import subprocess
def get_tasks_sets(dir):
return [str(a.name).replace('.in', '') for a in Path(dir).glob('*in')]
def execute_task(dir):
task_sets = get_tasks_sets(dir)
for task_set in task_sets:
try:
with open(Path(dir, f'{task_set}.in')) as f_in, open(Path(dir, f'{task_set}.out'), 'w') as f_out:
arg = [x for x in dir.iterdir() if str(x).endswith(f'{task_set}.arg')] # arg = [x for x in dir.iterdir() if str(x).endswith(f'{task_set}.arg')]
if not arg:
arg = [x for x in dir.iterdir() if str(x).endswith('fsa_description.arg')] # arg = Path(dir, 'fsa_description.arg') #
if str(dir).startswith('TaskH'):
compilation_command = ['thraxcompiler', f'--input_grammar={Path(dir, "grammar.grm")}',
f'--output_far={Path(dir, "grammar.far")}']
process = subprocess.Popen(compilation_command, stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL)
process.wait()
command = ['thraxrewrite-tester', f'--far={Path(dir, "grammar.far")}', f'--rules=FinalRule']
else:
command = ['python3', Path(dir, 'run.py')]
if len(arg) != 0:
command.append(arg[0])
process = subprocess.Popen(command,
stdin=f_in,
stdout=f_out,
stderr=subprocess.DEVNULL)
process.wait()
f_out.flush()
except:
pass
def get_index():
return int(Path.cwd().name.split('-')[-1][1:30])
def is_task_set_correct(dir, task_set):
try:
with open(Path(dir, f'{task_set}.out')) as f_out, open(Path(dir, f'{task_set}.exp')) as f_exp:
f_out_lines = ''.join(f_out.readlines())
f_exp_lines = ''.join(f_exp.readlines())
return f_out_lines == f_exp_lines
except:
pass
def is_task_correct(dir):
task_sets = get_tasks_sets(dir)
for task_set in task_sets:
if not is_task_set_correct(dir, task_set):
return False
return True
def does_task_match_index(dir, index):
with open(Path(dir, f'description.txt')) as f_in:
lines = f_in.readlines()
remainder_lines = [x for x in lines if x.startswith('REMAINDER')]
if len(remainder_lines) == 0:
return True
else:
remainder, modulus = remainder_lines[0].split(' ')[-1].split('/')
remainder = int(remainder)
modulus = int(modulus)
return (index % modulus) == remainder
def get_tasks(index):
all_tasks = Path('../djfz-2023-464933').glob('Task*')
return [task for task in all_tasks if does_task_match_index(task, index)]
def execute_all_tasks(tasks):
for task in tasks:
execute_task(task)
def get_task_points(dir):
with open(Path(dir, 'description.txt')) as f_in:
lines = f_in.readlines()
points = int([x for x in lines if x.startswith('POINTS')][0].split(' ')[-1].rstrip())
return points
def get_report(tasks):
report = dict()
for task in tasks:
if is_task_correct(task):
report[task] = get_task_points(task)
else:
report[task] = 0
return report
def print_report(report):
for k in sorted(report):
print(f'{k}: {report[k]}')
print('')
print(f'SUMMARY: {sum(report.values())}')
INDEX = get_index()
tasks = get_tasks(INDEX)
execute_all_tasks(tasks)
report = get_report(tasks)
print_report(report)