Skip to content
Snippets Groups Projects
Commit 82458a20 authored by Millian Poquet's avatar Millian Poquet
Browse files

initial setup

parent 11879464
No related branches found
No related tags found
No related merge requests found
{ pkgs ? import (fetchTarball {
url = "https://github.com/NixOS/nixpkgs/archive/22.11.tar.gz";
sha256 = "sha256:11w3wn2yjhaa5pv20gbfbirvjq6i3m7pqrq2msf0g7cv44vijwgw";
}) {}
}:
let
pyPkgs = pkgs.python3Packages;
in rec {
ut3_survival = pyPkgs.buildPythonPackage {
pname = "ut3_survival";
version = "local";
format = "pyproject";
src = pkgs.lib.sourceByRegex ./. [
"pyproject\.toml"
"LICENSE"
"ut3_survival"
"ut3_survival/.*\.py"
"ut3_survival/cmd"
"ut3_survival/cmd/.*\.py"
];
buildInputs = with pyPkgs; [
flit
];
propagatedBuildInputs = with pyPkgs; [
xlrd
pandas
click
];
};
user-shell = pkgs.mkShell {
buildInputs = with pyPkgs; [
ipython
ut3_survival
];
};
dev-shell = pkgs.mkShell {
buildInputs = with pyPkgs; [
ipython
] ++ ut3_survival.propagatedBuildInputs;
};
}
{
"nodes": {
"flake-utils": {
"locked": {
"lastModified": 1667395993,
"narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1670952872,
"narHash": "sha256-tmhCNibwoviM+BHXBWUxO+XtAwbO84b2BHC4PrD7FrQ=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "16875b3e7be8380c29af192cc8ff1debae6d311a",
"type": "github"
},
"original": {
"owner": "NixOS",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs"
}
}
},
"root": "root",
"version": 7
}
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs?tag=22.11";
flake-utils.url = "github:numtide/flake-utils";
};
outputs = { self, nixpkgs, flake-utils }:
flake-utils.lib.eachDefaultSystem (system:
let pkgs = nixpkgs.legacyPackages.${system};
in rec {
packages = import ./default.nix { inherit pkgs; };
apps.xls-to-csv = flake-utils.lib.mkApp { drv = packages.ut3_survival; exePath = "/bin/xls-to-csv"; };
defaultPackage = packages.ut3_survival;
}
);
}
[build-system]
build-backend = "flit_core.buildapi"
requires = ["flit_core"]
[project]
name = "ut3_survival"
version = "0.1.0"
description = "Set of tools to stay sane while teaching at UT3"
authors = [
{name = "Millian Poquet", email="millian.poquet@irit.fr"},
]
license = {file = "LICENSE"}
requires-python = ">=3.9"
keywords = ["ut3"]
classifiers = [
"Topic :: Software Development",
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
"Programming Language :: Python",
"Programming Language :: Python :: 3.9",
]
dependencies = [
"pandas>=1.3.0",
"xlrd>=2.0.1",
"click>=8.0.0",
]
[project.scripts]
xls-to-csv = "ut3_survival.cmd.xls_to_csv:main"
#!/usr/bin/env python3
import sys
import click
import pandas
from ut3_survival import realist
@click.command()
@click.argument('xls_file', required=True, nargs=-1)
@click.option('-o', '--output', default=None, help='If set, parsed students are written as CSV to this file.')
def main(xls_file, output):
students = realist.read_parse_several_xls(xls_file)
output_file = sys.stdout
if output is not None:
output_file = open(output, 'wt', encoding='utf-8')
students_df = realist.student_entry_list_to_df(students)
students_df.sort_values(by=['group', 'lastname', 'firstname', 'id'], inplace=True)
students_df.to_csv(output_file, index=False)
if __name__ == "__main__":
main()
#!/usr/bin/env python3
'''
Student list parser from REALIST (usually accessed via SGCE).
'''
import sys
from collections import namedtuple
import pandas
import xlrd
student_columns = ['id', 'lastname', 'firstname', 'email', 'group']
StudentEntry = namedtuple('StudentEntry', student_columns)
def read_parse_xls(xls_filename: str) -> [StudentEntry]:
'''Read and parse a XLS file into a list of students.'''
students_xls = xlrd.open_workbook(xls_filename, logfile=sys.stderr)
group_names = students_xls.sheet_names()
group_names.pop(0) # first XLS sheet is useless
students = []
for group_name in group_names:
sheet = students_xls.sheet_by_name(group_name)
if sheet.cell_value(1,0) != "GROUPE : " + group_name:
raise AssertionError("SGCE's xls format has changed")
for row in range(3, sheet.nrows):
students.append(StudentEntry(
id=sheet.cell_value(row,0),
lastname=sheet.cell_value(row,1),
firstname=sheet.cell_value(row,2),
email=sheet.cell_value(row,3),
group=group_name,
))
return students
def read_parse_several_xls(xls_filenames: [str]) -> [StudentEntry]:
'''read_parse_xls wrapper when several files are to be used.'''
all_students = []
for xls_filename in xls_filenames:
try:
students = read_parse_xls(xls_filename)
all_students.extend(students)
except Exception as exception:
raise RuntimeError(f"could not read/parse xls file '{xls_filename}'") from exception
return all_students
def student_entry_list_to_df(students: [StudentEntry]) -> pandas.DataFrame:
'''Create a DataFrame from a student list.'''
return pandas.DataFrame(students, columns=student_columns)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment