as
This commit is contained in:
commit
f53e9cb6d6
241
README.md
Normal file
241
README.md
Normal 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
111
run_report.py
Normal 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)
|
Loading…
Reference in New Issue
Block a user