Skip to content
Snippets Groups Projects
Commit c18ec95c authored by tuhe's avatar tuhe
Browse files

updatse

parent 0a2d50f2
No related branches found
No related tags found
No related merge requests found
Requirement already satisfied: codesnipper in c:\users\tuhe\appdata\local\programs\python\python310\lib\site-packages (0.1.11)
Requirement already satisfied: wexpect in c:\users\tuhe\appdata\local\programs\python\python310\lib\site-packages (from codesnipper) (4.0.0)
Requirement already satisfied: pybtex in c:\users\tuhe\appdata\local\programs\python\python310\lib\site-packages (from codesnipper) (0.24.0)
Requirement already satisfied: pexpect in c:\users\tuhe\appdata\local\programs\python\python310\lib\site-packages (from codesnipper) (4.8.0)
Requirement already satisfied: ptyprocess>=0.5 in c:\users\tuhe\appdata\local\programs\python\python310\lib\site-packages (from pexpect->codesnipper) (0.7.0)
Requirement already satisfied: six in c:\users\tuhe\appdata\local\programs\python\python310\lib\site-packages (from pybtex->codesnipper) (1.16.0)
Requirement already satisfied: latexcodec>=1.0.4 in c:\users\tuhe\appdata\local\programs\python\python310\lib\site-packages (from pybtex->codesnipper) (2.0.1)
Requirement already satisfied: PyYAML>=3.01 in c:\users\tuhe\appdata\local\programs\python\python310\lib\site-packages (from pybtex->codesnipper) (6.0)
Requirement already satisfied: pywin32>=220 in c:\users\tuhe\appdata\local\programs\python\python310\lib\site-packages (from wexpect->codesnipper) (304)
Requirement already satisfied: psutil>=5.0.0 in c:\users\tuhe\appdata\local\programs\python\python310\lib\site-packages (from wexpect->codesnipper) (5.9.1)
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
# Use: pipreqs.exe slider --no-pin --force for requirements_pip.txt # Use: pipreqs.exe slider --no-pin --force for requirements_pip.txt
# https://packaging.python.org/tutorials/packaging-projects/ # https://packaging.python.org/tutorials/packaging-projects/
# py -m build && twine upload dist/* # py -m build && twine upload dist/*
# Linux> python -m build && twine upload dist/*
# Local install: sudo pip install -e ./
import setuptools import setuptools
import pkg_resources import pkg_resources
......
Metadata-Version: 2.1 Metadata-Version: 2.1
Name: codesnipper Name: codesnipper
Version: 0.1.11 Version: 0.1.14
Summary: A lightweight framework for censoring student solutions files and extracting code + output Summary: A lightweight framework for censoring student solutions files and extracting code + output
Home-page: https://lab.compute.dtu.dk/tuhe/snipper Home-page: https://lab.compute.dtu.dk/tuhe/snipper
Author: Tue Herlau Author: Tue Herlau
......
pexpect pexpect
wexpect wexpect
pybtex pybtex
numpy
...@@ -37,7 +37,12 @@ def block_split(lines, tag): ...@@ -37,7 +37,12 @@ def block_split(lines, tag):
def get_tag_args(line): def get_tag_args(line):
# line = line.strip() # line = line.strip()
k = line.find(" ") k = line.find(" ")
if 'nodoc' in line:
print("Nodoc!!")
tag_args = ((line[:k + 1] if k >= 0 else line)[len(tag):] ).strip().split(";") tag_args = ((line[:k + 1] if k >= 0 else line)[len(tag):] ).strip().split(";")
if 'nodoc' in tag_args:
print("nodoc.")
tag_args = [t.strip() for t in tag_args] tag_args = [t.strip() for t in tag_args]
# if len(tag_args) == 0: # if len(tag_args) == 0:
# return {'': ''} # No name. # return {'': ''} # No name.
...@@ -46,7 +51,8 @@ def block_split(lines, tag): ...@@ -46,7 +51,8 @@ def block_split(lines, tag):
if '' not in tag_args: if '' not in tag_args:
tag_args[''] = '' tag_args[''] = ''
if "dse" in tag_args:
print("DSE!!!")
return tag_args return tag_args
if i is None: if i is None:
......
...@@ -11,7 +11,8 @@ def fix_citations(lines, references, strict=True, file=None): ...@@ -11,7 +11,8 @@ def fix_citations(lines, references, strict=True, file=None):
""" """
if str(file).endswith(".rst"): if str(file).endswith(".rst"):
print(file) print(file)
lines = fix_aux(lines, aux=references.get('aux', {}) ) # lines = fix_aux(lines, )
lines = fix_single_reference(lines, aux=references.get('aux', {}), cmd="\\ref", strict=True)
for cm in references.get('commands', []): for cm in references.get('commands', []):
# Probably just go with this one. # Probably just go with this one.
lines = fix_aux_special(lines, aux=cm['aux'], command=cm['command'], output=cm['output']) lines = fix_aux_special(lines, aux=cm['aux'], command=cm['command'], output=cm['output'])
...@@ -29,11 +30,10 @@ def fix_aux_special(lines, aux, command='\\nref', output='\cite[%s]{my_bibtex_en ...@@ -29,11 +30,10 @@ def fix_aux_special(lines, aux, command='\\nref', output='\cite[%s]{my_bibtex_en
l2 = fix_single_reference(lines, aux=daux, cmd=command, strict=True) l2 = fix_single_reference(lines, aux=daux, cmd=command, strict=True)
return l2 return l2
def fix_aux(lines, aux, strict=True): # def fix_aux(lines, aux, strict=True):
print("fix_cite.py/fix_aux() deprecated...") # print("fix_cite.py/fix_aux() deprecated...")
l2 = fix_single_reference(lines, aux=aux, cmd="\\ref", strict=True)
# print("\n".join(l2)) # print("\n".join(l2))
return l2 # return l2
def fix_bibtex(lines, bibtex, rst_mode=False): def fix_bibtex(lines, bibtex, rst_mode=False):
...@@ -64,7 +64,7 @@ def fix_bibtex(lines, bibtex, rst_mode=False): ...@@ -64,7 +64,7 @@ def fix_bibtex(lines, bibtex, rst_mode=False):
s = s[:i] + rtxt + s[j+1:] s = s[:i] + rtxt + s[j+1:]
i = i + len(rtxt) i = i + len(rtxt)
if len(all_refs) > 0: if len(all_refs) > 0 and not rst_mode: # Don't add the license head in RST mode. The user is responsible for including references in sphinx conf.py.
if not s.startswith(COMMENT): if not s.startswith(COMMENT):
s = f"{COMMENT}\n{COMMENT}\n" + s s = f"{COMMENT}\n{COMMENT}\n" + s
i = s.find(COMMENT, s.find(COMMENT)+1) i = s.find(COMMENT, s.find(COMMENT)+1)
......
...@@ -9,28 +9,48 @@ else: ...@@ -9,28 +9,48 @@ else:
import pexpect as we import pexpect as we
def run_i(lines, file, output): def rsession(analyzer, lines, extra):
extra = dict(python=None, output=output, evaluated_lines=0) l2 = []
def block_fun(lines, start_extra, end_extra, art, head="", tail="", output=None, extra=None): dbug = False
outf = output + ("_" + art if art is not None and len(art) > 0 else "") + ".shell" # analyzer = we.spawn("python", encoding="utf-8", timeout=20)
lines = full_strip(lines) # analyzer.expect([">>>"])
s = "\n".join(lines) if "BetterBasicDog" in "\n".join(lines) and False:
s.replace("...", "..") # passive-aggressively truncate ... because of #issues. print("\n".join(lines))
lines = textwrap.dedent(s).strip().splitlines() print("-"*50)
for k in extra['session_results']:
print(k['input'])
print(k['output'])
if extra['python'] is None: import time
an = we.spawn("python", encoding="utf-8", timeout=20) an = we.spawn("python", encoding="utf-8", timeout=20)
an.expect([">>>"]) an.expect([">>>"])
extra['python'] = an l3 = """
import numpy as np
from scipy.linalg import norm
x = np.asarray([3, 4])
x # What is x?
norm(x)"""
lines2 = l3.strip().splitlines()
for l in lines2:
an.sendline(l)
an.expect_exact([">>>", "..."])
print("INPUT", l)
print(">>>", an.before.strip())
if len(an.after.strip()) > 4:
print(">>>>>>>>>>>>> That was a long after?")
# analyzer.be
print('*' * 50)
# analyzer = an
dbug = True
lines = "\n".join(lines).replace("\r", "").splitlines()
analyzer = extra['python']
def rsession(analyzer, lines):
l2 = []
for i, l in enumerate(lines): for i, l in enumerate(lines):
l2.append(l) l2.append(l)
if l.startswith(" ") and i < len(lines)-1 and not lines[i+1].startswith(" "): if l.startswith(" ") and i < len(lines)-1 and not lines[i+1].startswith(" "):
if not lines[i+1].strip().startswith("else:") and not lines[i+1].strip().startswith("elif") : if not lines[i+1].strip().startswith("else:") and not lines[i+1].strip().startswith("elif") :
l2.append("\n") l2.append("") # Empty line instead?
lines = l2 lines = l2
alines = [] alines = []
...@@ -38,16 +58,36 @@ def run_i(lines, file, output): ...@@ -38,16 +58,36 @@ def run_i(lines, file, output):
if len(lines[-1]) > 0 and (lines[-1].startswith(" ") or lines[-1].startswith("\t")): if len(lines[-1]) > 0 and (lines[-1].startswith(" ") or lines[-1].startswith("\t")):
lines += [""] lines += [""]
for i, word in enumerate(lines): for i, word in enumerate(lines):
analyzer.sendline(word) if dbug:
print("> Sending...", word)
analyzer.sendline(word.rstrip())
import time
before = "" before = ""
while True: while True:
time.sleep(0.05)
analyzer.expect_exact([">>>", "..."]) analyzer.expect_exact([">>>", "..."])
if dbug and "total_cost" in word:
aaa = 23234
before += analyzer.before before += analyzer.before
# if dbug:
print("> analyzer.before...", analyzer.before.strip(), "...AFTER...", analyzer.after.strip())
# AFTER =
if analyzer.before.endswith("\n"): if analyzer.before.endswith("\n"):
print("> BREAKING LOOP")
break break
pass
else: else:
before += analyzer.after before += analyzer.after
break
# print("Before is", before)
abefore = analyzer.before.rstrip()
# Sanitize by removing garbage binary stuff the terminal puts in
abefore = "\n".join([l for l in abefore.splitlines() if not l.startswith('\x1b')] )
dotmode = analyzer.after == "..." dotmode = analyzer.after == "..."
if 'dir(s)' in word: if 'dir(s)' in word:
...@@ -55,19 +95,39 @@ def run_i(lines, file, output): ...@@ -55,19 +95,39 @@ def run_i(lines, file, output):
if 'help(s.find)' in word: if 'help(s.find)' in word:
pass pass
if dotmode: if dotmode:
alines.append(">>>" + analyzer.before.rstrip() if not in_dot_mode else "..." + analyzer.before.rstrip()) alines.append(">>>" +abefore.rstrip() if not in_dot_mode else "..." + abefore.rstrip())
in_dot_mode = True in_dot_mode = True
else: else:
alines.append( ("..." if in_dot_mode else ">>>") + analyzer.before.rstrip()) alines.append( ("..." if in_dot_mode else ">>>") + abefore.rstrip())
in_dot_mode = False in_dot_mode = False
if dbug:
print("-"*50)
print("\n".join(alines))
extra['session_results'].append({'input': '\n'.join(lines), 'output': '\n'.join(alines)})
return alines return alines
for l in (head[extra['evaluated_lines']:] + ["\n"]):
analyzer.sendline(l)
analyzer.expect_exact([">>>", "..."])
def run_i(lines, file, output):
extra = dict(python=None, output=output, evaluated_lines=0, session_results=[])
def block_fun(lines, start_extra, end_extra, art, head="", tail="", output=None, extra=None):
outf = output + ("_" + art if art is not None and len(art) > 0 else "") + ".shell"
lines = full_strip(lines)
s = "\n".join(lines)
s.replace("...", "..") # passive-aggressively truncate ... because of #issues.
lines = textwrap.dedent(s).strip().splitlines()
# an.setecho(True) # TH January 2023: Seems to fix an issue on linux with truncated lines. May cause problems on windows?
if extra['python'] is None:
an = we.spawn("python", encoding="utf-8", timeout=20)
an.expect([">>>"])
extra['python'] = an
alines = rsession(analyzer, lines) # analyzer = extra['python']
# What does this do?
# for l in (head[extra['evaluated_lines']:] + ["\n"]):
# analyzer.sendline(l)
# analyzer.expect_exact([">>>", "..."])
alines = rsession(extra['python'], lines, extra) # give it the analyzer
extra['evaluated_lines'] += len(head) + len(lines) extra['evaluated_lines'] += len(head) + len(lines)
lines = alines lines = alines
return lines, [outf, lines] return lines, [outf, lines]
...@@ -81,6 +141,8 @@ def run_i(lines, file, output): ...@@ -81,6 +141,8 @@ def run_i(lines, file, output):
for outf in kvs: for outf in kvs:
out = "\n".join( ["\n".join(v[1]) for v in c if v[0] == outf] ) out = "\n".join( ["\n".join(v[1]) for v in c if v[0] == outf] )
out = out.replace("\r", "") out = out.replace("\r", "")
if outf.endswith("python0B_e4.shell"):
print(outf)
with open(outf, 'w') as f: with open(outf, 'w') as f:
f.write(out) f.write(out)
......
...@@ -2,6 +2,8 @@ from collections import defaultdict ...@@ -2,6 +2,8 @@ from collections import defaultdict
import os import os
from snipper.block_parsing import block_iterate from snipper.block_parsing import block_iterate
from snipper.snipper_main import full_strip from snipper.snipper_main import full_strip
from snipper.block_parsing import indent
def get_s(lines): def get_s(lines):
""" Return snips from 'lines' """ """ Return snips from 'lines' """
...@@ -13,7 +15,11 @@ def get_s(lines): ...@@ -13,7 +15,11 @@ def get_s(lines):
else: else:
# In this case the #! tags are kept in. # In this case the #! tags are kept in.
pass pass
# print("keepting tags.") if 'dse' in c['start_tag_args']:
print("asdfasdfs")
print(c['start_tag_args'])
if 'nodoc' in c['start_tag_args'] and c['start_tag_args']['nodoc']:
print("No documentation!")
blocks[c['name']].append(c) blocks[c['name']].append(c)
output = {} output = {}
...@@ -23,9 +29,54 @@ def get_s(lines): ...@@ -23,9 +29,54 @@ def get_s(lines):
# c['block']['args'] # c['block']['args']
# slines = slines[ 23] # slines = slines[ 23]
# co. # co.
# if slines[f.lineno].strip().startswith('"' * 3):
# print("got a docstrnig")
# for k in range(f.lineno, f.end_lineno + 1):
# l = slines[k] if k != f.lineno else slines[k].strip()[3:]
# if l.find('"' * 3) >= 0:
# break
# else:
# k = -1
# if k > 0:
# print("Docstring detected")
# for i in range(f.lineno, k + 1):
# ll2[i] = None
output[name] = slines output[name] = slines
return output return output
def rm_docstring(lines):
source = "\n".join(slines)
import ast
node = ast.parse(source)
classes = [n for n in node.body if isinstance(n, ast.ClassDef)]
functions = [n for n in node.body if isinstance(n, ast.FunctionDef)]
ll2 = slines.copy()
def rm_ds(f, ll2):
if slines[f.lineno].strip().startswith('"' * 3):
# print("got a docstrnig")
for k in range(f.lineno, f.end_lineno + 1):
l = slines[k] if k != f.lineno else slines[k].strip()[3:]
if l.find('"' * 3) >= 0:
break
else:
k = -1
if k > 0:
# print("Docstring detected")
for i in range(f.lineno, k + 1):
ll2[i] = None
for f in functions:
rm_ds(f, ll2)
for c in classes:
for f in c.body:
rm_ds(f, ll2)
return [l for l in ll2 if l is not None]
# def _s_block_process(): # def _s_block_process():
# #
# pass # pass
...@@ -39,12 +90,23 @@ def save_s(lines, output_dir, file_path): # save file snips to disk ...@@ -39,12 +90,23 @@ def save_s(lines, output_dir, file_path): # save file snips to disk
for name, ll in content.items(): for name, ll in content.items():
if file_path is not None: if file_path is not None:
file_path = file_path.replace("\\", "/") file_path = file_path.replace("\\", "/")
ll = [f"# {file_path}"] + ll ll = [f"{indent(ll[0])}# {file_path}"] + ll
out = "\n".join(ll) out = "\n".join(ll)
with open(output_dir + "/" + os.path.basename(file_path)[:-3] + ("_" + name if len(name) > 0 else name) + ".py", 'w') as f: fname = output_dir + "/" + os.path.basename(file_path)[:-3] + ("_" + name if len(name) > 0 else name) + ".py"
with open(fname, 'w') as f:
f.write(out) f.write(out)
# Dedent it for better plotting.
fname_stripped = fname[:-3] + "_stripped.py"
id = [indent(l) for l in ll if len(l.strip()) > 0]
id_len = [len(i) for i in id]
mindex = id_len[id_len.index(min(id_len))]
out2 = "\n".join([l[mindex:] for l in ll])
with open(fname_stripped, 'w') as f:
f.write(out2)
s1 = """ s1 = """
L1 L1
......
__version__ = "0.1.12" __version__ = "0.1.15"
# /builds/02465material/02465public
# /builds/02465material/02465public
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment