Coverage for gpaw/utilities/nbrun.py: 17%

36 statements  

« prev     ^ index     » next       coverage.py v7.7.1, created at 2025-07-12 00:18 +0000

1"""Code for summerschool notebooks.""" 

2import json 

3import sys 

4from pathlib import Path 

5from typing import Dict, Any, Optional 

6 

7 

8def py2ipynb(path: Path, 

9 kernel: Optional[Dict[str, str]] = None, 

10 teachermode: Optional[bool] = False) -> None: 

11 """Convert Python script to ipynb file. 

12 

13 Hides cells marked with "# teacher" and replaces lines marked with 

14 "# student: ...":: 

15 

16 answer = 42 # student: answer = ... 

17 

18 gives:: 

19 

20 answer = ... 

21 

22 """ 

23 cells = [] 

24 text = path.read_text() 

25 assert text.startswith('# %%\n') 

26 chunks = text[5:].split('\n\n# %%\n') 

27 

28 for chunk in chunks: 

29 cell_type = 'code' 

30 if chunk.startswith(('"""', 'r"""')): 

31 chunk = chunk.strip('r\n') 

32 chunk = chunk.strip('"') 

33 cell_type = 'markdown' 

34 

35 cell: Dict[str, Any] = { 

36 'cell_type': cell_type, 

37 'metadata': {}, 

38 'source': chunk.splitlines(True)} 

39 

40 if cell_type == 'code': 

41 cell['outputs'] = [] 

42 cell['execution_count'] = None 

43 lines = cell['source'] 

44 for i, line in enumerate(lines): 

45 if ' # student:' in line and not teachermode: 

46 a, b = (x.strip() for x in line.split('# student:')) 

47 lines[i] = line.split(a)[0] + b + '\n' 

48 elif line.startswith('# magic: '): 

49 lines[i] = line[9:] 

50 elif line.lower().startswith('# teacher') and not teachermode: 

51 del lines[i:] 

52 break 

53 

54 cells.append(cell) 

55 

56 outpath = path.with_suffix('.ipynb') 

57 if kernel is None: 

58 kernel = {'display_name': 'Python 3', 

59 'language': 'python', 

60 'name': 'python3'} 

61 outpath.write_text( 

62 json.dumps( 

63 {'cells': cells, 

64 'metadata': { 

65 'kernelspec': kernel, 

66 'language_info': { 

67 'codemirror_mode': {'name': 'ipython', 'version': 3}, 

68 'file_extension': '.py', 

69 'mimetype': 'text/x-python', 

70 'name': 'python', 

71 'nbconvert_exporter': 'python', 

72 'pygments_lexer': 'ipython3', 

73 'version': '3.6.1'}}, 

74 'nbformat': 4, 

75 'nbformat_minor': 1}, 

76 indent=2)) 

77 

78 

79if __name__ == '__main__': 

80 py2ipynb(Path(sys.argv[1]))