klr-um 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- klr_um-1.0.0/PKG-INFO +62 -0
- klr_um-1.0.0/README.md +55 -0
- klr_um-1.0.0/pyproject.toml +19 -0
- klr_um-1.0.0/setup.cfg +4 -0
- klr_um-1.0.0/src/klr/__init__.py +122 -0
- klr_um-1.0.0/src/klr/cli.py +41 -0
- klr_um-1.0.0/src/klr/data/exp1/.gitignore +48 -0
- klr_um-1.0.0/src/klr/data/exp1/.metadata +30 -0
- klr_um-1.0.0/src/klr/data/exp1/README.md +17 -0
- klr_um-1.0.0/src/klr/data/exp1/analysis_options.yaml +33 -0
- klr_um-1.0.0/src/klr/data/exp1/exp1.iml +17 -0
- klr_um-1.0.0/src/klr/data/exp1/lib/main.dart +155 -0
- klr_um-1.0.0/src/klr/data/exp1/pubspec.lock +213 -0
- klr_um-1.0.0/src/klr/data/exp1/pubspec.yaml +89 -0
- klr_um-1.0.0/src/klr/data/exp1/test/widget_test.dart +14 -0
- klr_um-1.0.0/src/klr/data/exp1/web/favicon.png +0 -0
- klr_um-1.0.0/src/klr/data/exp1/web/icons/Icon-192.png +0 -0
- klr_um-1.0.0/src/klr/data/exp1/web/icons/Icon-512.png +0 -0
- klr_um-1.0.0/src/klr/data/exp1/web/icons/Icon-maskable-192.png +0 -0
- klr_um-1.0.0/src/klr/data/exp1/web/icons/Icon-maskable-512.png +0 -0
- klr_um-1.0.0/src/klr/data/exp1/web/index.html +46 -0
- klr_um-1.0.0/src/klr/data/exp1/web/manifest.json +35 -0
- klr_um-1.0.0/src/klr/data/exp2/.gitignore +48 -0
- klr_um-1.0.0/src/klr/data/exp2/.metadata +30 -0
- klr_um-1.0.0/src/klr/data/exp2/README.md +17 -0
- klr_um-1.0.0/src/klr/data/exp2/analysis_options.yaml +33 -0
- klr_um-1.0.0/src/klr/data/exp2/exp2.iml +17 -0
- klr_um-1.0.0/src/klr/data/exp2/lib/main.dart +114 -0
- klr_um-1.0.0/src/klr/data/exp2/pubspec.lock +213 -0
- klr_um-1.0.0/src/klr/data/exp2/pubspec.yaml +89 -0
- klr_um-1.0.0/src/klr/data/exp2/test/widget_test.dart +38 -0
- klr_um-1.0.0/src/klr/data/exp2/web/favicon.png +0 -0
- klr_um-1.0.0/src/klr/data/exp2/web/icons/Icon-192.png +0 -0
- klr_um-1.0.0/src/klr/data/exp2/web/icons/Icon-512.png +0 -0
- klr_um-1.0.0/src/klr/data/exp2/web/icons/Icon-maskable-192.png +0 -0
- klr_um-1.0.0/src/klr/data/exp2/web/icons/Icon-maskable-512.png +0 -0
- klr_um-1.0.0/src/klr/data/exp2/web/index.html +46 -0
- klr_um-1.0.0/src/klr/data/exp2/web/manifest.json +35 -0
- klr_um-1.0.0/src/klr/data/exp3/.gitignore +48 -0
- klr_um-1.0.0/src/klr/data/exp3/.metadata +30 -0
- klr_um-1.0.0/src/klr/data/exp3/README.md +17 -0
- klr_um-1.0.0/src/klr/data/exp3/analysis_options.yaml +33 -0
- klr_um-1.0.0/src/klr/data/exp3/exp3.iml +17 -0
- klr_um-1.0.0/src/klr/data/exp3/lib/main.dart +148 -0
- klr_um-1.0.0/src/klr/data/exp3/pubspec.lock +213 -0
- klr_um-1.0.0/src/klr/data/exp3/pubspec.yaml +89 -0
- klr_um-1.0.0/src/klr/data/exp3/test/widget_test.dart +30 -0
- klr_um-1.0.0/src/klr/data/exp3/web/favicon.png +0 -0
- klr_um-1.0.0/src/klr/data/exp3/web/icons/Icon-192.png +0 -0
- klr_um-1.0.0/src/klr/data/exp3/web/icons/Icon-512.png +0 -0
- klr_um-1.0.0/src/klr/data/exp3/web/icons/Icon-maskable-192.png +0 -0
- klr_um-1.0.0/src/klr/data/exp3/web/icons/Icon-maskable-512.png +0 -0
- klr_um-1.0.0/src/klr/data/exp3/web/index.html +46 -0
- klr_um-1.0.0/src/klr/data/exp3/web/manifest.json +35 -0
- klr_um-1.0.0/src/klr/data/exp4/.gitignore +48 -0
- klr_um-1.0.0/src/klr/data/exp4/.metadata +30 -0
- klr_um-1.0.0/src/klr/data/exp4/README.md +17 -0
- klr_um-1.0.0/src/klr/data/exp4/analysis_options.yaml +33 -0
- klr_um-1.0.0/src/klr/data/exp4/exp4.iml +17 -0
- klr_um-1.0.0/src/klr/data/exp4/lib/main.dart +189 -0
- klr_um-1.0.0/src/klr/data/exp4/pubspec.lock +213 -0
- klr_um-1.0.0/src/klr/data/exp4/pubspec.yaml +89 -0
- klr_um-1.0.0/src/klr/data/exp4/test/widget_test.dart +45 -0
- klr_um-1.0.0/src/klr/data/exp4/web/favicon.png +0 -0
- klr_um-1.0.0/src/klr/data/exp4/web/icons/Icon-192.png +0 -0
- klr_um-1.0.0/src/klr/data/exp4/web/icons/Icon-512.png +0 -0
- klr_um-1.0.0/src/klr/data/exp4/web/icons/Icon-maskable-192.png +0 -0
- klr_um-1.0.0/src/klr/data/exp4/web/icons/Icon-maskable-512.png +0 -0
- klr_um-1.0.0/src/klr/data/exp4/web/index.html +46 -0
- klr_um-1.0.0/src/klr/data/exp4/web/manifest.json +35 -0
- klr_um-1.0.0/src/klr/data/exp5/.gitignore +48 -0
- klr_um-1.0.0/src/klr/data/exp5/.metadata +30 -0
- klr_um-1.0.0/src/klr/data/exp5/README.md +17 -0
- klr_um-1.0.0/src/klr/data/exp5/analysis_options.yaml +33 -0
- klr_um-1.0.0/src/klr/data/exp5/exp5.iml +17 -0
- klr_um-1.0.0/src/klr/data/exp5/lib/firebase_options.dart +11 -0
- klr_um-1.0.0/src/klr/data/exp5/lib/main.dart +132 -0
- klr_um-1.0.0/src/klr/data/exp5/pubspec.lock +290 -0
- klr_um-1.0.0/src/klr/data/exp5/pubspec.yaml +91 -0
- klr_um-1.0.0/src/klr/data/exp5/web/favicon.png +0 -0
- klr_um-1.0.0/src/klr/data/exp5/web/icons/Icon-192.png +0 -0
- klr_um-1.0.0/src/klr/data/exp5/web/icons/Icon-512.png +0 -0
- klr_um-1.0.0/src/klr/data/exp5/web/icons/Icon-maskable-192.png +0 -0
- klr_um-1.0.0/src/klr/data/exp5/web/icons/Icon-maskable-512.png +0 -0
- klr_um-1.0.0/src/klr/data/exp5/web/index.html +46 -0
- klr_um-1.0.0/src/klr/data/exp5/web/manifest.json +35 -0
- klr_um-1.0.0/src/klr/data/exp6/.gitignore +48 -0
- klr_um-1.0.0/src/klr/data/exp6/.metadata +30 -0
- klr_um-1.0.0/src/klr/data/exp6/README.md +17 -0
- klr_um-1.0.0/src/klr/data/exp6/analysis_options.yaml +33 -0
- klr_um-1.0.0/src/klr/data/exp6/exp6.iml +17 -0
- klr_um-1.0.0/src/klr/data/exp6/lib/firebase_options.dart +11 -0
- klr_um-1.0.0/src/klr/data/exp6/lib/main.dart +149 -0
- klr_um-1.0.0/src/klr/data/exp6/pubspec.lock +290 -0
- klr_um-1.0.0/src/klr/data/exp6/pubspec.yaml +91 -0
- klr_um-1.0.0/src/klr/data/exp6/web/favicon.png +0 -0
- klr_um-1.0.0/src/klr/data/exp6/web/icons/Icon-192.png +0 -0
- klr_um-1.0.0/src/klr/data/exp6/web/icons/Icon-512.png +0 -0
- klr_um-1.0.0/src/klr/data/exp6/web/icons/Icon-maskable-192.png +0 -0
- klr_um-1.0.0/src/klr/data/exp6/web/icons/Icon-maskable-512.png +0 -0
- klr_um-1.0.0/src/klr/data/exp6/web/index.html +46 -0
- klr_um-1.0.0/src/klr/data/exp6/web/manifest.json +35 -0
- klr_um-1.0.0/src/klr/data/extras/Flutter_Lab_Experiments.pdf +588 -0
- klr_um-1.0.0/src/klr/data/extras/make_pdf.py +391 -0
- klr_um-1.0.0/src/klr_um.egg-info/PKG-INFO +62 -0
- klr_um-1.0.0/src/klr_um.egg-info/SOURCES.txt +107 -0
- klr_um-1.0.0/src/klr_um.egg-info/dependency_links.txt +1 -0
- klr_um-1.0.0/src/klr_um.egg-info/entry_points.txt +2 -0
- klr_um-1.0.0/src/klr_um.egg-info/top_level.txt +1 -0
klr_um-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: klr-um
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Flutter lab study pack (experiments 1-6) bundled as a Python package.
|
|
5
|
+
Requires-Python: >=3.9
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
|
|
8
|
+
# klr-um
|
|
9
|
+
|
|
10
|
+
Flutter lab experiments 1 to 6, ready to print or save.
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
pip install klr-um
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Print an experiment's code
|
|
17
|
+
|
|
18
|
+
```python
|
|
19
|
+
import klr
|
|
20
|
+
print(klr.exp1) # complete main.dart of experiment 1
|
|
21
|
+
print(klr.exp4) # ... same for exp1 to exp6
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Save to disk
|
|
25
|
+
|
|
26
|
+
```python
|
|
27
|
+
klr.exp1.save() # full Flutter project -> ./exp1 (then: cd exp1 && flutter run)
|
|
28
|
+
klr.exp1.save_code() # just the code -> ./exp1_main.dart
|
|
29
|
+
klr.save_all() # exp1 ... exp6 project folders
|
|
30
|
+
klr.save_pdf() # Flutter_Lab_Experiments.pdf
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## More
|
|
34
|
+
|
|
35
|
+
```python
|
|
36
|
+
klr.list() # experiment titles
|
|
37
|
+
klr.exp5.files # files in the project
|
|
38
|
+
print(klr.exp5.show("lib/firebase_options.dart"))
|
|
39
|
+
klr.get(3) # same as klr.exp3
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Command line
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
klr # list experiments
|
|
46
|
+
klr 1 # print experiment 1 code
|
|
47
|
+
klr 1 --save # save experiment 1 project to ./exp1
|
|
48
|
+
klr all --save # save all projects
|
|
49
|
+
klr pdf # save the PDF
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
| # | Experiment |
|
|
53
|
+
|---|---|
|
|
54
|
+
| 1 | Widgets and Layouts (Student Profile) |
|
|
55
|
+
| 2 | Responsive UI |
|
|
56
|
+
| 3 | Input and Forms (Student Registration) |
|
|
57
|
+
| 4 | Form Validation (Sign Up) |
|
|
58
|
+
| 5 | Firestore Search (Search Products) |
|
|
59
|
+
| 6 | Firestore Update Product |
|
|
60
|
+
|
|
61
|
+
Experiments 5 and 6 use Firebase: replace the placeholder values in
|
|
62
|
+
`lib/firebase_options.dart` with your own project's values (e.g. via `flutterfire configure`).
|
klr_um-1.0.0/README.md
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# klr-um
|
|
2
|
+
|
|
3
|
+
Flutter lab experiments 1 to 6, ready to print or save.
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
pip install klr-um
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Print an experiment's code
|
|
10
|
+
|
|
11
|
+
```python
|
|
12
|
+
import klr
|
|
13
|
+
print(klr.exp1) # complete main.dart of experiment 1
|
|
14
|
+
print(klr.exp4) # ... same for exp1 to exp6
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Save to disk
|
|
18
|
+
|
|
19
|
+
```python
|
|
20
|
+
klr.exp1.save() # full Flutter project -> ./exp1 (then: cd exp1 && flutter run)
|
|
21
|
+
klr.exp1.save_code() # just the code -> ./exp1_main.dart
|
|
22
|
+
klr.save_all() # exp1 ... exp6 project folders
|
|
23
|
+
klr.save_pdf() # Flutter_Lab_Experiments.pdf
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## More
|
|
27
|
+
|
|
28
|
+
```python
|
|
29
|
+
klr.list() # experiment titles
|
|
30
|
+
klr.exp5.files # files in the project
|
|
31
|
+
print(klr.exp5.show("lib/firebase_options.dart"))
|
|
32
|
+
klr.get(3) # same as klr.exp3
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Command line
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
klr # list experiments
|
|
39
|
+
klr 1 # print experiment 1 code
|
|
40
|
+
klr 1 --save # save experiment 1 project to ./exp1
|
|
41
|
+
klr all --save # save all projects
|
|
42
|
+
klr pdf # save the PDF
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
| # | Experiment |
|
|
46
|
+
|---|---|
|
|
47
|
+
| 1 | Widgets and Layouts (Student Profile) |
|
|
48
|
+
| 2 | Responsive UI |
|
|
49
|
+
| 3 | Input and Forms (Student Registration) |
|
|
50
|
+
| 4 | Form Validation (Sign Up) |
|
|
51
|
+
| 5 | Firestore Search (Search Products) |
|
|
52
|
+
| 6 | Firestore Update Product |
|
|
53
|
+
|
|
54
|
+
Experiments 5 and 6 use Firebase: replace the placeholder values in
|
|
55
|
+
`lib/firebase_options.dart` with your own project's values (e.g. via `flutterfire configure`).
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "klr-um"
|
|
7
|
+
version = "1.0.0"
|
|
8
|
+
description = "Flutter lab study pack (experiments 1-6) bundled as a Python package."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
|
|
12
|
+
[project.scripts]
|
|
13
|
+
klr = "klr.cli:main"
|
|
14
|
+
|
|
15
|
+
[tool.setuptools.packages.find]
|
|
16
|
+
where = ["src"]
|
|
17
|
+
|
|
18
|
+
[tool.setuptools.package-data]
|
|
19
|
+
klr = ["data/**/*", "data/**/.*"]
|
klr_um-1.0.0/setup.cfg
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"""KLR - Flutter lab experiments 1 to 6.
|
|
2
|
+
|
|
3
|
+
import klr
|
|
4
|
+
|
|
5
|
+
print(klr.exp1) # full Dart code of experiment 1 (lib/main.dart)
|
|
6
|
+
klr.exp1.save() # writes the complete Flutter project to ./exp1
|
|
7
|
+
klr.exp1.save_code() # writes just main.dart to ./exp1_main.dart
|
|
8
|
+
klr.exp5.files # every file in the experiment's project
|
|
9
|
+
print(klr.exp5.show("lib/firebase_options.dart"))
|
|
10
|
+
|
|
11
|
+
klr.list() # all experiments with titles
|
|
12
|
+
klr.save_all() # writes exp1 ... exp6 as project folders
|
|
13
|
+
klr.save_pdf() # writes Flutter_Lab_Experiments.pdf
|
|
14
|
+
"""
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import shutil
|
|
18
|
+
from importlib.resources import files
|
|
19
|
+
from pathlib import Path
|
|
20
|
+
|
|
21
|
+
__version__ = "1.0.0"
|
|
22
|
+
|
|
23
|
+
_DATA = files("klr") / "data"
|
|
24
|
+
|
|
25
|
+
TITLES = {
|
|
26
|
+
1: "Widgets and Layouts (Student Profile)",
|
|
27
|
+
2: "Responsive UI",
|
|
28
|
+
3: "Input and Forms (Student Registration)",
|
|
29
|
+
4: "Form Validation (Sign Up)",
|
|
30
|
+
5: "Firestore Search (Search Products)",
|
|
31
|
+
6: "Firestore Update Product",
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _walk(node, prefix=""):
|
|
36
|
+
for child in sorted(node.iterdir(), key=lambda c: c.name):
|
|
37
|
+
rel = f"{prefix}{child.name}"
|
|
38
|
+
if child.is_dir():
|
|
39
|
+
if child.name != "__pycache__":
|
|
40
|
+
yield from _walk(child, rel + "/")
|
|
41
|
+
else:
|
|
42
|
+
yield rel, child
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class Experiment:
|
|
46
|
+
"""One lab experiment. ``print(exp)`` shows its full main.dart code."""
|
|
47
|
+
|
|
48
|
+
def __init__(self, number: int):
|
|
49
|
+
self.number = number
|
|
50
|
+
self.name = f"exp{number}"
|
|
51
|
+
self.title = TITLES[number]
|
|
52
|
+
self._root = _DATA / self.name
|
|
53
|
+
|
|
54
|
+
@property
|
|
55
|
+
def code(self) -> str:
|
|
56
|
+
"""The complete main.dart source."""
|
|
57
|
+
return self.show("lib/main.dart")
|
|
58
|
+
|
|
59
|
+
@property
|
|
60
|
+
def files(self) -> list[str]:
|
|
61
|
+
"""Relative paths of every file in the Flutter project."""
|
|
62
|
+
return [rel for rel, _ in _walk(self._root)]
|
|
63
|
+
|
|
64
|
+
def show(self, file: str) -> str:
|
|
65
|
+
"""Text of any file in the project, e.g. ``"pubspec.yaml"``."""
|
|
66
|
+
node = self._root.joinpath(*file.split("/"))
|
|
67
|
+
if not node.is_file():
|
|
68
|
+
raise FileNotFoundError(f"{self.name} has no file {file!r}. See {self.name}.files")
|
|
69
|
+
return node.read_text(encoding="utf-8")
|
|
70
|
+
|
|
71
|
+
def save(self, dest: str | Path | None = None) -> Path:
|
|
72
|
+
"""Write the complete Flutter project to ``dest`` (default ``./expN``)."""
|
|
73
|
+
dest = Path(dest or self.name)
|
|
74
|
+
for rel, node in _walk(self._root):
|
|
75
|
+
out = dest / rel
|
|
76
|
+
out.parent.mkdir(parents=True, exist_ok=True)
|
|
77
|
+
out.write_bytes(node.read_bytes())
|
|
78
|
+
return dest.resolve()
|
|
79
|
+
|
|
80
|
+
def save_code(self, dest: str | Path | None = None) -> Path:
|
|
81
|
+
"""Write only main.dart to ``dest`` (default ``./expN_main.dart``)."""
|
|
82
|
+
dest = Path(dest or f"{self.name}_main.dart")
|
|
83
|
+
dest.write_text(self.code, encoding="utf-8")
|
|
84
|
+
return dest.resolve()
|
|
85
|
+
|
|
86
|
+
def __str__(self) -> str:
|
|
87
|
+
return self.code
|
|
88
|
+
|
|
89
|
+
def __repr__(self) -> str:
|
|
90
|
+
return f"// Experiment {self.number}: {self.title}\n{self.code}"
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
exp1, exp2, exp3, exp4, exp5, exp6 = (Experiment(n) for n in range(1, 7))
|
|
94
|
+
experiments = [exp1, exp2, exp3, exp4, exp5, exp6]
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def get(number: int) -> Experiment:
|
|
98
|
+
"""Experiment by number, e.g. ``klr.get(3)``."""
|
|
99
|
+
if number not in TITLES:
|
|
100
|
+
raise ValueError(f"Experiments are numbered 1 to {len(TITLES)}.")
|
|
101
|
+
return experiments[number - 1]
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def list() -> None: # noqa: A001 - short name on purpose
|
|
105
|
+
"""Print every experiment with its title."""
|
|
106
|
+
for e in experiments:
|
|
107
|
+
print(f"exp{e.number}: {e.title}")
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def save_all(dest: str | Path = ".") -> Path:
|
|
111
|
+
"""Write every experiment project into ``dest`` as exp1 ... exp6."""
|
|
112
|
+
dest = Path(dest)
|
|
113
|
+
for e in experiments:
|
|
114
|
+
e.save(dest / e.name)
|
|
115
|
+
return dest.resolve()
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def save_pdf(dest: str | Path = "Flutter_Lab_Experiments.pdf") -> Path:
|
|
119
|
+
"""Write the lab manual PDF."""
|
|
120
|
+
dest = Path(dest)
|
|
121
|
+
dest.write_bytes((_DATA / "extras" / "Flutter_Lab_Experiments.pdf").read_bytes())
|
|
122
|
+
return dest.resolve()
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"""klr command line.
|
|
2
|
+
|
|
3
|
+
klr list experiments
|
|
4
|
+
klr 1 print the code of experiment 1
|
|
5
|
+
klr 1 --save write the full experiment 1 project to ./exp1
|
|
6
|
+
klr all --save write all six projects
|
|
7
|
+
klr pdf write the lab manual PDF
|
|
8
|
+
"""
|
|
9
|
+
import argparse
|
|
10
|
+
import sys
|
|
11
|
+
|
|
12
|
+
import klr
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def main(argv=None):
|
|
16
|
+
ap = argparse.ArgumentParser(prog="klr", description=__doc__,
|
|
17
|
+
formatter_class=argparse.RawDescriptionHelpFormatter)
|
|
18
|
+
ap.add_argument("target", nargs="?", help="experiment number 1-6, 'all' or 'pdf'")
|
|
19
|
+
ap.add_argument("--save", action="store_true", help="write the project to disk")
|
|
20
|
+
ap.add_argument("-o", "--out", help="output folder or file")
|
|
21
|
+
a = ap.parse_args(argv)
|
|
22
|
+
t = a.target
|
|
23
|
+
if t is None:
|
|
24
|
+
klr.list()
|
|
25
|
+
elif t == "pdf":
|
|
26
|
+
print(f"Saved {klr.save_pdf(a.out or 'Flutter_Lab_Experiments.pdf')}")
|
|
27
|
+
elif t == "all":
|
|
28
|
+
if a.save:
|
|
29
|
+
print(f"Saved all experiments in {klr.save_all(a.out or '.')}")
|
|
30
|
+
else:
|
|
31
|
+
for e in klr.experiments:
|
|
32
|
+
print(repr(e))
|
|
33
|
+
elif t.removeprefix("exp").isdigit() and int(t.removeprefix("exp")) in klr.TITLES:
|
|
34
|
+
e = klr.get(int(t.removeprefix("exp")))
|
|
35
|
+
print(f"Saved {e.save(a.out)}") if a.save else sys.stdout.write(e.code)
|
|
36
|
+
else:
|
|
37
|
+
sys.exit("klr: target must be 1-6, 'all' or 'pdf'")
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
if __name__ == "__main__":
|
|
41
|
+
main()
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Miscellaneous
|
|
2
|
+
*.class
|
|
3
|
+
*.log
|
|
4
|
+
*.pyc
|
|
5
|
+
*.swp
|
|
6
|
+
.DS_Store
|
|
7
|
+
.atom/
|
|
8
|
+
.build/
|
|
9
|
+
.buildlog/
|
|
10
|
+
.history
|
|
11
|
+
.svn/
|
|
12
|
+
.swiftpm/
|
|
13
|
+
migrate_working_dir/
|
|
14
|
+
|
|
15
|
+
# IntelliJ related
|
|
16
|
+
*.iml
|
|
17
|
+
*.ipr
|
|
18
|
+
*.iws
|
|
19
|
+
.idea/
|
|
20
|
+
|
|
21
|
+
# The .vscode folder contains launch configuration and tasks you configure in
|
|
22
|
+
# VS Code which you may wish to be included in version control, so this line
|
|
23
|
+
# is commented out by default.
|
|
24
|
+
#.vscode/
|
|
25
|
+
|
|
26
|
+
# Flutter/Dart/Pub related
|
|
27
|
+
**/doc/api/
|
|
28
|
+
**/ios/Flutter/.last_build_id
|
|
29
|
+
.dart_tool/
|
|
30
|
+
.flutter-plugins-dependencies
|
|
31
|
+
.pub-cache/
|
|
32
|
+
.pub/
|
|
33
|
+
/build/
|
|
34
|
+
/coverage/
|
|
35
|
+
|
|
36
|
+
# Symbolication related
|
|
37
|
+
app.*.symbols
|
|
38
|
+
|
|
39
|
+
# Obfuscation related
|
|
40
|
+
app.*.map.json
|
|
41
|
+
|
|
42
|
+
# Android Studio will place build artifacts here
|
|
43
|
+
/android/app/debug
|
|
44
|
+
/android/app/profile
|
|
45
|
+
/android/app/release
|
|
46
|
+
|
|
47
|
+
# Widget Preview related
|
|
48
|
+
.widget_preview/
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# This file tracks properties of this Flutter project.
|
|
2
|
+
# Used by Flutter tool to assess capabilities and perform upgrades etc.
|
|
3
|
+
#
|
|
4
|
+
# This file should be version controlled and should not be manually edited.
|
|
5
|
+
|
|
6
|
+
version:
|
|
7
|
+
revision: "c197ca5199e9ee5661e865596c9c07294dfab51c"
|
|
8
|
+
channel: "stable"
|
|
9
|
+
|
|
10
|
+
project_type: app
|
|
11
|
+
|
|
12
|
+
# Tracks metadata for the flutter migrate command
|
|
13
|
+
migration:
|
|
14
|
+
platforms:
|
|
15
|
+
- platform: root
|
|
16
|
+
create_revision: c197ca5199e9ee5661e865596c9c07294dfab51c
|
|
17
|
+
base_revision: c197ca5199e9ee5661e865596c9c07294dfab51c
|
|
18
|
+
- platform: web
|
|
19
|
+
create_revision: c197ca5199e9ee5661e865596c9c07294dfab51c
|
|
20
|
+
base_revision: c197ca5199e9ee5661e865596c9c07294dfab51c
|
|
21
|
+
|
|
22
|
+
# User provided section
|
|
23
|
+
|
|
24
|
+
# List of Local paths (relative to this file) that should be
|
|
25
|
+
# ignored by the migrate tool.
|
|
26
|
+
#
|
|
27
|
+
# Files that are not part of the templates will be ignored by default.
|
|
28
|
+
unmanaged_files:
|
|
29
|
+
- 'lib/main.dart'
|
|
30
|
+
- 'ios/Runner.xcodeproj/project.pbxproj'
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# exp1
|
|
2
|
+
|
|
3
|
+
A new Flutter project.
|
|
4
|
+
|
|
5
|
+
## Getting Started
|
|
6
|
+
|
|
7
|
+
This project is a starting point for a Flutter application.
|
|
8
|
+
|
|
9
|
+
A few resources to get you started if this is your first Flutter project:
|
|
10
|
+
|
|
11
|
+
- [Learn Flutter](https://docs.flutter.dev/get-started/learn-flutter)
|
|
12
|
+
- [Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
|
|
13
|
+
- [Flutter learning resources](https://docs.flutter.dev/reference/learning-resources)
|
|
14
|
+
|
|
15
|
+
For help getting started with Flutter development, view the
|
|
16
|
+
[online documentation](https://docs.flutter.dev/), which offers tutorials,
|
|
17
|
+
samples, guidance on mobile development, and a full API reference.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# This file configures the analyzer, which statically analyzes Dart code to
|
|
2
|
+
# check for errors, warnings, and lints.
|
|
3
|
+
#
|
|
4
|
+
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
|
|
5
|
+
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
|
|
6
|
+
# invoked from the command line by running `flutter analyze`.
|
|
7
|
+
|
|
8
|
+
# The following line activates a set of recommended lints for Flutter apps,
|
|
9
|
+
# packages, and plugins designed to encourage good coding practices.
|
|
10
|
+
include: package:flutter_lints/flutter.yaml
|
|
11
|
+
|
|
12
|
+
analyzer:
|
|
13
|
+
exclude:
|
|
14
|
+
- build/**
|
|
15
|
+
- web/**
|
|
16
|
+
|
|
17
|
+
linter:
|
|
18
|
+
# The lint rules applied to this project can be customized in the
|
|
19
|
+
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
|
|
20
|
+
# included above or to enable additional rules. A list of all available lints
|
|
21
|
+
# and their documentation is published at https://dart.dev/lints.
|
|
22
|
+
#
|
|
23
|
+
# Instead of disabling a lint rule for the entire project in the
|
|
24
|
+
# section below, it can also be suppressed for a single line of code
|
|
25
|
+
# or a specific dart file by using the `// ignore: name_of_lint` and
|
|
26
|
+
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
|
|
27
|
+
# producing the lint.
|
|
28
|
+
rules:
|
|
29
|
+
# avoid_print: false # Uncomment to disable the `avoid_print` rule
|
|
30
|
+
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
|
|
31
|
+
|
|
32
|
+
# Additional information about this file can be found at
|
|
33
|
+
# https://dart.dev/guides/language/analysis-options
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<module type="JAVA_MODULE" version="4">
|
|
3
|
+
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
|
4
|
+
<exclude-output />
|
|
5
|
+
<content url="file://$MODULE_DIR$">
|
|
6
|
+
<sourceFolder url="file://$MODULE_DIR$/lib" isTestSource="false" />
|
|
7
|
+
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
|
|
8
|
+
<excludeFolder url="file://$MODULE_DIR$/.dart_tool" />
|
|
9
|
+
<excludeFolder url="file://$MODULE_DIR$/.idea" />
|
|
10
|
+
<excludeFolder url="file://$MODULE_DIR$/build" />
|
|
11
|
+
</content>
|
|
12
|
+
<orderEntry type="sourceFolder" forTests="false" />
|
|
13
|
+
<orderEntry type="library" name="Dart SDK" level="project" />
|
|
14
|
+
<orderEntry type="library" name="Flutter Plugins" level="project" />
|
|
15
|
+
<orderEntry type="library" name="Dart Packages" level="project" />
|
|
16
|
+
</component>
|
|
17
|
+
</module>
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import 'package:flutter/material.dart';
|
|
2
|
+
|
|
3
|
+
void main() {
|
|
4
|
+
runApp(const MyApp());
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
class MyApp extends StatelessWidget {
|
|
8
|
+
const MyApp({super.key});
|
|
9
|
+
|
|
10
|
+
@override
|
|
11
|
+
Widget build(BuildContext context) {
|
|
12
|
+
return MaterialApp(
|
|
13
|
+
debugShowCheckedModeBanner: false,
|
|
14
|
+
title: 'Widgets and Layouts',
|
|
15
|
+
theme: ThemeData(colorSchemeSeed: Colors.indigo),
|
|
16
|
+
home: const ProfilePage(),
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
class ProfilePage extends StatelessWidget {
|
|
22
|
+
const ProfilePage({super.key});
|
|
23
|
+
|
|
24
|
+
@override
|
|
25
|
+
Widget build(BuildContext context) {
|
|
26
|
+
return Scaffold(
|
|
27
|
+
appBar: AppBar(title: const Text('Student Profile')),
|
|
28
|
+
body: Padding(
|
|
29
|
+
padding: const EdgeInsets.all(16),
|
|
30
|
+
child: Column(
|
|
31
|
+
crossAxisAlignment: CrossAxisAlignment.start,
|
|
32
|
+
children: [
|
|
33
|
+
// Row -> avatar and name side by side
|
|
34
|
+
Row(
|
|
35
|
+
children: [
|
|
36
|
+
// Stack -> small green dot placed over the avatar
|
|
37
|
+
Stack(
|
|
38
|
+
children: const [
|
|
39
|
+
CircleAvatar(
|
|
40
|
+
radius: 35,
|
|
41
|
+
child: Icon(Icons.person, size: 40),
|
|
42
|
+
),
|
|
43
|
+
Positioned(
|
|
44
|
+
right: 0,
|
|
45
|
+
bottom: 0,
|
|
46
|
+
child: CircleAvatar(
|
|
47
|
+
radius: 9,
|
|
48
|
+
backgroundColor: Colors.green,
|
|
49
|
+
),
|
|
50
|
+
),
|
|
51
|
+
],
|
|
52
|
+
),
|
|
53
|
+
const SizedBox(width: 16),
|
|
54
|
+
Column(
|
|
55
|
+
crossAxisAlignment: CrossAxisAlignment.start,
|
|
56
|
+
children: const [
|
|
57
|
+
Text(
|
|
58
|
+
'Your Name',
|
|
59
|
+
style: TextStyle(
|
|
60
|
+
fontSize: 22, fontWeight: FontWeight.bold),
|
|
61
|
+
),
|
|
62
|
+
Text('B.Tech CSE - 3rd Year'),
|
|
63
|
+
],
|
|
64
|
+
),
|
|
65
|
+
],
|
|
66
|
+
),
|
|
67
|
+
const SizedBox(height: 20),
|
|
68
|
+
|
|
69
|
+
// Container with decoration
|
|
70
|
+
Container(
|
|
71
|
+
width: double.infinity,
|
|
72
|
+
padding: const EdgeInsets.all(12),
|
|
73
|
+
decoration: BoxDecoration(
|
|
74
|
+
color: Colors.indigo.shade50,
|
|
75
|
+
borderRadius: BorderRadius.circular(10),
|
|
76
|
+
border: Border.all(color: Colors.indigo),
|
|
77
|
+
),
|
|
78
|
+
child: const Text(
|
|
79
|
+
'In Flutter, everything on the screen is a widget.'),
|
|
80
|
+
),
|
|
81
|
+
const SizedBox(height: 20),
|
|
82
|
+
|
|
83
|
+
// Expanded -> three boxes share the width equally
|
|
84
|
+
Row(
|
|
85
|
+
children: [
|
|
86
|
+
Expanded(child: infoBox('Subjects', '6', Colors.orange)),
|
|
87
|
+
const SizedBox(width: 8),
|
|
88
|
+
Expanded(child: infoBox('Labs', '4', Colors.green)),
|
|
89
|
+
const SizedBox(width: 8),
|
|
90
|
+
Expanded(child: infoBox('CGPA', '8.4', Colors.purple)),
|
|
91
|
+
],
|
|
92
|
+
),
|
|
93
|
+
const SizedBox(height: 20),
|
|
94
|
+
|
|
95
|
+
const Text(
|
|
96
|
+
'Skills',
|
|
97
|
+
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
|
|
98
|
+
),
|
|
99
|
+
// ListView inside Column must be wrapped in Expanded
|
|
100
|
+
Expanded(
|
|
101
|
+
child: ListView(
|
|
102
|
+
children: const [
|
|
103
|
+
Card(
|
|
104
|
+
child: ListTile(
|
|
105
|
+
leading: Icon(Icons.code),
|
|
106
|
+
title: Text('Dart'),
|
|
107
|
+
subtitle: Text('Programming language'),
|
|
108
|
+
),
|
|
109
|
+
),
|
|
110
|
+
Card(
|
|
111
|
+
child: ListTile(
|
|
112
|
+
leading: Icon(Icons.phone_android),
|
|
113
|
+
title: Text('Flutter'),
|
|
114
|
+
subtitle: Text('UI toolkit'),
|
|
115
|
+
),
|
|
116
|
+
),
|
|
117
|
+
Card(
|
|
118
|
+
child: ListTile(
|
|
119
|
+
leading: Icon(Icons.storage),
|
|
120
|
+
title: Text('Firebase'),
|
|
121
|
+
subtitle: Text('Backend and database'),
|
|
122
|
+
),
|
|
123
|
+
),
|
|
124
|
+
],
|
|
125
|
+
),
|
|
126
|
+
),
|
|
127
|
+
],
|
|
128
|
+
),
|
|
129
|
+
),
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// helper method that returns a small coloured box
|
|
134
|
+
Widget infoBox(String title, String value, Color color) {
|
|
135
|
+
return Container(
|
|
136
|
+
padding: const EdgeInsets.all(12),
|
|
137
|
+
decoration: BoxDecoration(
|
|
138
|
+
color: color,
|
|
139
|
+
borderRadius: BorderRadius.circular(8),
|
|
140
|
+
),
|
|
141
|
+
child: Column(
|
|
142
|
+
children: [
|
|
143
|
+
Text(
|
|
144
|
+
value,
|
|
145
|
+
style: const TextStyle(
|
|
146
|
+
fontSize: 20,
|
|
147
|
+
color: Colors.white,
|
|
148
|
+
fontWeight: FontWeight.bold),
|
|
149
|
+
),
|
|
150
|
+
Text(title, style: const TextStyle(color: Colors.white)),
|
|
151
|
+
],
|
|
152
|
+
),
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
}
|