ver Jan22ndv3
updated style metric to compare_table
This commit is contained in:
@@ -14,7 +14,8 @@ from openpyxl.worksheet.worksheet import Worksheet
|
||||
#from openpyxl.worksheet.cell_range import MultiCellRange
|
||||
from openpyxl.worksheet.datavalidation import DataValidation
|
||||
|
||||
from .utils import load_charts, load_sparklines, _match_value_to_rule
|
||||
from .utils import load_charts, load_sparklines, load_rows_or_cols, load_xlsx_styles
|
||||
from .utils import _match_value_to_rule
|
||||
|
||||
logger = logging.getLogger("desktopenv.metric.table")
|
||||
|
||||
@@ -160,18 +161,19 @@ def compare_table(result: str, expected: str, **options) -> float:
|
||||
logger.debug("Assertion: %s[chart] == %s[chart] - %s", r["sheet_idx0"], r["sheet_idx1"], metric)
|
||||
# }}} Compare Charts #
|
||||
|
||||
elif r["type"] == "number_format":
|
||||
# Compare Number Formats {{{ #
|
||||
elif r["type"] == "style":
|
||||
# Compare Style (Also Conditional Formatiing) {{{ #
|
||||
# sheet_idx0: 0 == "RI0" == "RNSheet1" | "EI0" == "ENSheet1"
|
||||
# sheet_idx1: as sheet_idx0
|
||||
# props: list of str indicating concerned styles
|
||||
|
||||
sheet1: Worksheet = _load_sheet(*parse_idx(r["sheet_idx0"], xlworkbookr, xlworkbooke))
|
||||
sheet2: Worksheet = _load_sheet(*parse_idx(r["sheet_idx1"], xlworkbookr, xlworkbooke))
|
||||
number_formats1: List[str] = [c.number_format.lower() for col in sheet1.iter_cols() for c in col if c.data_type=="n"]
|
||||
number_formats2: List[str] = [c.number_format.lower() for col in sheet2.iter_cols() for c in col if c.data_type=="n"]
|
||||
metric: bool = number_formats1 == number_formats2
|
||||
logger.debug("Assertion: %s.nf == %s.nf - %s", r["sheet_idx0"], r["sheet_idx1"], metric)
|
||||
# }}} Compare Number Formats #
|
||||
styles1: Dict[str, List[Any]] = load_xlsx_styles(*parse_idx(r["sheet_idx0"], xlworkbookr, xlworkbooke), **r)
|
||||
styles2: Dict[str, List[Any]] = load_xlsx_styles(*parse_idx(r["sheet_idx1"], xlworkbookr, xlworkbooke), **r)
|
||||
#number_formats1: List[str] = [c.number_format.lower() for col in sheet1.iter_cols() for c in col if c.value is not None and c.data_type=="n"]
|
||||
#number_formats2: List[str] = [c.number_format.lower() for col in sheet2.iter_cols() for c in col if c.value is not None and c.data_type=="n"]
|
||||
metric: bool = styles1 == styles2
|
||||
logger.debug("Assertion: %s.style == %s.style - %s", r["sheet_idx0"], r["sheet_idx1"], metric)
|
||||
# }}} Compare Style (Also Conditional Formatiing) #
|
||||
|
||||
elif r["type"] == "freeze":
|
||||
# Compare Freezing {{{ #
|
||||
@@ -243,6 +245,44 @@ def compare_table(result: str, expected: str, **options) -> float:
|
||||
metric: bool = total_metric
|
||||
# }}} Check Data Validation #
|
||||
|
||||
elif r["type"] == "row_props":
|
||||
# Check Row Properties {{{ #
|
||||
# sheet_idx0: 0 == "RI0" == "RNSheet1" | "EI0" == "ENSheet1"
|
||||
# sheet_idx1: as sheet_idx0
|
||||
# props: list of str, see utils.load_rows_or_cols
|
||||
|
||||
rows1: Dict[str, Any] = load_rows_or_cols( *parse_idx(r["sheet_idx0"], xlworkbookr, xlworkbooke)
|
||||
, obj="row"
|
||||
, **r
|
||||
)
|
||||
rows2: Dict[str, Any] = load_rows_or_cols( *parse_idx(r["sheet_idx1"], xlworkbookr, xlworkbooke)
|
||||
, obj="row"
|
||||
, **r
|
||||
)
|
||||
logger.debug("Rows1: %s", repr(rows1))
|
||||
logger.debug("Rows2: %s", repr(rows2))
|
||||
metric: bool = rows1 == rows2
|
||||
logger.debug("Assertion: %s[rows] == %s[rows] - %s", r["sheet_idx0"], r["sheet_idx1"], metric)
|
||||
# }}} Check Row Properties #
|
||||
|
||||
elif r["type"] == "col_props":
|
||||
# Check Row Properties {{{ #
|
||||
# sheet_idx0: 0 == "RI0" == "RNSheet1" | "EI0" == "ENSheet1"
|
||||
# sheet_idx1: as sheet_idx0
|
||||
# props: list of str, see utils.load_rows_or_cols
|
||||
|
||||
cols1: Dict[str, Any] = load_rows_or_cols( *parse_idx(r["sheet_idx0"], xlworkbookr, xlworkbooke)
|
||||
, obj="column"
|
||||
, **r
|
||||
)
|
||||
cols2: Dict[str, Any] = load_rows_or_cols( *parse_idx(r["sheet_idx1"], xlworkbookr, xlworkbooke)
|
||||
, obj="column"
|
||||
, **r
|
||||
)
|
||||
metric: bool = cols1 == cols2
|
||||
logger.debug("Assertion: %s[cols] == %s[cols] - %s", r["sheet_idx0"], r["sheet_idx1"], metric)
|
||||
# }}} Check Row Properties #
|
||||
|
||||
else:
|
||||
raise NotImplementedError("Unimplemented sheet check: {:}".format(r["type"]))
|
||||
|
||||
@@ -259,52 +299,43 @@ if __name__ == '__main__':
|
||||
|
||||
logger = logging.getLogger()
|
||||
logger.setLevel(logging.DEBUG)
|
||||
|
||||
|
||||
datetime_str: str = datetime.datetime.now().strftime("%Y%m%d@%H%M%S")
|
||||
|
||||
|
||||
file_handler = logging.FileHandler(os.path.join("logs", "normal-{:}.log".format(datetime_str)))
|
||||
debug_handler = logging.FileHandler(os.path.join("logs", "debug-{:}.log".format(datetime_str)))
|
||||
stdout_handler = logging.StreamHandler(sys.stdout)
|
||||
sdebug_handler = logging.FileHandler(os.path.join("logs", "sdebug-{:}.log".format(datetime_str)))
|
||||
|
||||
|
||||
file_handler.setLevel(logging.INFO)
|
||||
debug_handler.setLevel(logging.DEBUG)
|
||||
stdout_handler.setLevel(logging.INFO)
|
||||
sdebug_handler.setLevel(logging.DEBUG)
|
||||
|
||||
|
||||
formatter = logging.Formatter(fmt="\x1b[1;33m[%(asctime)s \x1b[31m%(levelname)s \x1b[32m%(module)s/%(lineno)d-%(processName)s\x1b[1;33m] \x1b[0m%(message)s")
|
||||
file_handler.setFormatter(formatter)
|
||||
debug_handler.setFormatter(formatter)
|
||||
stdout_handler.setFormatter(formatter)
|
||||
sdebug_handler.setFormatter(formatter)
|
||||
|
||||
|
||||
stdout_handler.addFilter(logging.Filter("desktopenv"))
|
||||
sdebug_handler.addFilter(logging.Filter("desktopenv"))
|
||||
|
||||
|
||||
logger.addHandler(file_handler)
|
||||
logger.addHandler(debug_handler)
|
||||
logger.addHandler(stdout_handler)
|
||||
logger.addHandler(sdebug_handler)
|
||||
|
||||
path1 = "../../任务数据/LibreOffice Calc/Order_Id_Mark_Pass_Fail.xlsx"
|
||||
path2 = "../../任务数据/LibreOffice Calc/Order_Id_Mark_Pass_Fail_gold.xlsx"
|
||||
path1 = "../../任务数据/LibreOffice Calc/Calendar_Highlight_Weekend_Days.xlsx"
|
||||
path2 = "../../任务数据/LibreOffice Calc/Calendar_Highlight_Weekend_Days_gold.xlsx"
|
||||
rules = [ { "type": "sheet_data"
|
||||
, "sheet_idx0": 0
|
||||
, "sheet_idx1": "EI0"
|
||||
}
|
||||
, { "type": "data_validation"
|
||||
, "sheet_idx": 0
|
||||
, "dv_props": [ { "ranges": { "method": "spreadsheet_range"
|
||||
, "ref": ["D2:D29", "D2:D1048576"]
|
||||
}
|
||||
, "type": { "method": "eq"
|
||||
, "ref": "list"
|
||||
}
|
||||
, "formula1": { "method": "str_set_eq"
|
||||
, "ref": ["Pass", "Fail", "Held"]
|
||||
}
|
||||
}
|
||||
]
|
||||
, { "type": "style"
|
||||
, "sheet_idx0": 0
|
||||
, "sheet_idx1": "EI0"
|
||||
, "props": ["bgcolor"]
|
||||
}
|
||||
]
|
||||
print( compare_table( path1, path2
|
||||
@@ -315,3 +346,32 @@ if __name__ == '__main__':
|
||||
, rules=rules
|
||||
)
|
||||
)
|
||||
|
||||
# Row Properties
|
||||
#path1 = "../../任务数据/LibreOffice Calc/Date_Budget_Variance_HideNA.xlsx"
|
||||
#path2 = "../../任务数据/LibreOffice Calc/Date_Budget_Variance_HideNA_gold.xlsx"
|
||||
#workbook: Workbook = openpyxl.load_workbook(filename=path1)
|
||||
#worksheet: Worksheet = workbook.active
|
||||
#for r_no, dms in worksheet.column_dimensions.items():
|
||||
#print(r_no, type(r_no), type(dms), dms.hidden)
|
||||
|
||||
# Conditional Formats
|
||||
#import formulas
|
||||
#path1 = "../../任务数据/LibreOffice Calc/Calendar_Highlight_Weekend_Days.xlsx"
|
||||
#path2 = "../../任务数据/LibreOffice Calc/Calendar_Highlight_Weekend_Days_gold.xlsx"
|
||||
#path3 = "../../任务数据/LibreOffice Calc/Calendar_Highlight_Weekend_Days_gold_test.xlsx"
|
||||
#workbook: Workbook = openpyxl.load_workbook(filename=path2)
|
||||
#worksheet: Worksheet = workbook.active
|
||||
#print(worksheet.conditional_formatting)
|
||||
#for itm in worksheet.conditional_formatting:
|
||||
#print(itm.cells)
|
||||
#for r in itm.rules:
|
||||
#print( r.type, r.formula, r.dxf.font.color.rgb
|
||||
#, r.dxf.fill.fgColor.rgb, r.dxf.fill.bgColor.rgb
|
||||
#)
|
||||
#condition = formulas.Parser().ast("=" + r.formula[0])[1].compile()
|
||||
##print(r.type, r.operator, r.dxfId, r.dxf)
|
||||
#for r in itm.cells:
|
||||
#for c in r.cells:
|
||||
#value = worksheet.cell(row=c[0], column=c[1]).value
|
||||
#print(value, condition(str(value)))
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import logging
|
||||
import zipfile
|
||||
from typing import Any, TypeVar, Union, Iterable, Optional
|
||||
from typing import Any, TypeVar, Union, Iterable, Optional, Callable
|
||||
from typing import Dict, List, Set, Match
|
||||
from urllib.parse import urlparse, urlunparse
|
||||
import re
|
||||
@@ -17,6 +17,12 @@ from openpyxl import Workbook
|
||||
from openpyxl.chart._chart import ChartBase
|
||||
from openpyxl.worksheet.worksheet import Worksheet
|
||||
from openpyxl.worksheet.cell_range import MultiCellRange
|
||||
from openpyxl.worksheet.dimensions import DimensionHolder
|
||||
from openpyxl.formatting.formatting import ConditionalFormattingList
|
||||
#from openpyxl.utils import get_column_letter
|
||||
from openpyxl.cell.cell import Cell
|
||||
from openpyxl.styles.differential import DifferentialStyle
|
||||
import formulas
|
||||
|
||||
V = TypeVar("Value")
|
||||
|
||||
@@ -31,9 +37,8 @@ _xlsx_ns_imapping = dict(map(lambda itm: (itm[1], itm[0]), _xlsx_namespaces))
|
||||
_sheet_name_selector = lxml.cssselect.CSSSelector("oo|sheets>oo|sheet", namespaces=_xlsx_ns_mapping)
|
||||
_sparklines_selector = lxml.cssselect.CSSSelector("x14|sparkline", namespaces=_xlsx_ns_mapping)
|
||||
def load_sparklines(xlsx_file: str, sheet_name: str) -> Dict[str, str]:
|
||||
# function load_sparklines {{{ #
|
||||
"""
|
||||
This function modifies data_frame in-place
|
||||
|
||||
Args:
|
||||
xlsx_file (str): path to xlsx
|
||||
sheet_name (str): sheet name
|
||||
@@ -64,6 +69,7 @@ def load_sparklines(xlsx_file: str, sheet_name: str) -> Dict[str, str]:
|
||||
)
|
||||
sparklines_dict[sparkline["x14:sparkline"]["xm:sqref"]] = sparkline["x14:sparkline"]["xm:f"]
|
||||
return sparklines_dict
|
||||
# }}} function load_sparklines #
|
||||
|
||||
|
||||
# Available Chart Properties:
|
||||
@@ -75,6 +81,7 @@ def load_sparklines(xlsx_file: str, sheet_name: str) -> Dict[str, str]:
|
||||
# direction: "bar" (hori) | "col" (vert)
|
||||
# xtitle, ytitle, ztitle: str
|
||||
def load_charts(xlsx_file: Workbook, sheet_name: str, **options) -> Dict[str, Any]:
|
||||
# function load_charts {{{ #
|
||||
"""
|
||||
Args:
|
||||
xlsx_file (Workbook): concerned excel book
|
||||
@@ -83,7 +90,12 @@ def load_charts(xlsx_file: Workbook, sheet_name: str, **options) -> Dict[str, An
|
||||
giving the concerned chart properties
|
||||
|
||||
Returns:
|
||||
Dict[str, Any]: information of charts
|
||||
Dict[str, Any]: information of charts, dict like
|
||||
{
|
||||
<str representing data source>: {
|
||||
<str as property>: anything
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
# workbook: Workbook = openpyxl.load_workbook(filename=xlsx_file)
|
||||
@@ -140,7 +152,132 @@ def load_charts(xlsx_file: Workbook, sheet_name: str, **options) -> Dict[str, An
|
||||
info["ztitle"] = ch.z_axis.title.tx.rich.p[0].r[0].t
|
||||
chart_set[series] = info
|
||||
return chart_set
|
||||
# }}} function load_charts #
|
||||
|
||||
# Supported Styles:
|
||||
# number_format
|
||||
# font_name - str
|
||||
# font_family - float
|
||||
# font_color - in aRGB, e.g., FF000000 is black
|
||||
# font_bold - bool
|
||||
# font_italic - bool
|
||||
# fill_type - "patternFill" | "gradientFill"
|
||||
# bgcolor - in aRGB, e.g., FFFF0000 is red
|
||||
# fgcolor - in aRGB, e.g., FF00FFFF is yellow
|
||||
def _read_cell_style(style_name: str, cell: Cell, diff_style: Optional[DifferentialStyle] = None) -> Any:
|
||||
if style_name=="number_format":
|
||||
return (cell.number_format if diff_style is None else diff_style.numFmt.formatCode)\
|
||||
if cell.value is not None and cell.data_type=="n" else None
|
||||
elif style_name=="font_name":
|
||||
return (diff_style or cell).font.name if cell.value is not None else None
|
||||
elif style_name=="font_family":
|
||||
return (diff_style or cell).font.family if cell.value is not None else None
|
||||
elif style_name=="font_color":
|
||||
return (diff_style or cell).font.color.rgb if cell.value is not None else None
|
||||
elif style_name=="font_bold":
|
||||
return (diff_style or cell).font.bold if cell.value is not None else None
|
||||
elif style_name=="font_italic":
|
||||
return (diff_style or cell).font.italic if cell.value is not None else None
|
||||
elif style_name=="fill_type":
|
||||
return (diff_style or cell).fill.tagname
|
||||
elif style_name=="bgcolor":
|
||||
return (diff_style or cell).fill.bgColor.rgb
|
||||
elif style_name=="fgcolor":
|
||||
return (diff_style or cell).fill.fgColor.rgb
|
||||
else:
|
||||
raise NotImplementedError("Unsupported Style: {:}".format(style_name))
|
||||
|
||||
def load_xlsx_styles(xlsx_file: Workbook, sheet_name: str, **options) -> Dict[str, List[Any]]:
|
||||
# function load_xlsx_styles {{{ #
|
||||
"""
|
||||
Args:
|
||||
xlsx_file (Workbook): concerned excel book
|
||||
sheet_name (str): sheet name
|
||||
options (Dict[str, List[str]): dick like {"props": list of str} giving
|
||||
the concerned styles
|
||||
|
||||
Returns:
|
||||
Dict[str, List[Any]]: dict like
|
||||
{
|
||||
<str as cell coordinates>: list of anything indicating concerned
|
||||
property values
|
||||
}
|
||||
"""
|
||||
|
||||
worksheet: Worksheet = xlsx_file[sheet_name]
|
||||
|
||||
style_dict: Dict[str, List[Any]] = {}
|
||||
concerned_styles: List[str] = options.get("props", [])
|
||||
|
||||
# Handles Cell Styles
|
||||
for col in worksheet.iter_cols():
|
||||
for c in col:
|
||||
style_list: List[Any] = []
|
||||
for st in concerned_styles:
|
||||
style_list.append(_read_cell_style(st, c))
|
||||
style_dict[c.coordinate] = style_list
|
||||
|
||||
# Handles Conditional Formatting
|
||||
conditional_formattings: ConditionalFormattingList = worksheet.conditional_formatting
|
||||
formula_parser = formulas.Parser()
|
||||
for fmt in conditional_formattings:
|
||||
for r in fmt.rules:
|
||||
active_cells: List[Cell] = []
|
||||
if r.type == "expression":
|
||||
condition: Callable[[str], bool] = formula_parser.ast("=" + r.formula[0])[1].compile()
|
||||
for rge in fmt.cells:
|
||||
for c in rge.cells:
|
||||
cell: Cell = worksheet.cell(row=c[0], column=c[1])
|
||||
if condition(str(cell.value)):
|
||||
active_cells.append(cell)
|
||||
else:
|
||||
raise NotImplementedError("Not Implemented Condition Type: {:}".format(r.type))
|
||||
|
||||
for c in active_cells:
|
||||
style_dict[c.coordinate] = [_read_cell_style(st, c, r.dxf) for st in concerned_styles]
|
||||
|
||||
return style_dict
|
||||
# }}} function load_xlsx_styles #
|
||||
|
||||
# Available Row Properties:
|
||||
# hidden
|
||||
# collapsed
|
||||
# height
|
||||
#
|
||||
# Available Column Properties:
|
||||
# width
|
||||
# auto_size
|
||||
# hidden
|
||||
# collapsed
|
||||
# min
|
||||
# max
|
||||
def load_rows_or_cols(xlsx_file: Workbook, sheet_name: str, **options)\
|
||||
-> Dict[Union[int, str], Dict[str, Any]]:
|
||||
# function load_rows_or_cols {{{ #
|
||||
"""
|
||||
Args:
|
||||
xlsx_file (Workbook): concerned excel book
|
||||
sheet_name (str): sheet name
|
||||
options (Dict[str, List[str]]): dict like
|
||||
{"obj": "row" | "column", "props": list of str} giving the concerned
|
||||
row/column properties
|
||||
|
||||
Returns:
|
||||
Dict[Union[int, str], Dict[str, Any]]: row/column information
|
||||
"""
|
||||
|
||||
worksheet: Worksheet = xlsx_file[sheet_name]
|
||||
objs: DimensionHolder = getattr(worksheet, "{:}_dimensions".format(options["obj"]))
|
||||
|
||||
obj_set: Dict[int, Any] = {}
|
||||
obj_props: Set[str] = set(options.get("props", []))
|
||||
for obj_no, obj_dms in objs.items():
|
||||
info_dict: Dict[str, Any] = {}
|
||||
for prop in obj_props:
|
||||
info_dict[prop] = getattr(obj_dms, prop)
|
||||
obj_set[obj_no] = info_dict
|
||||
return obj_set
|
||||
# }}} function load_rows_or_cols #
|
||||
|
||||
def _match_record(pattern: Dict[str, Any], item: Dict[str, Any]) -> bool:
|
||||
return all(k in item and item[k] == val for k, val in pattern.items())
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
{
|
||||
"id": "01b269ae-2111-4a07-81fd-3fcd711993b0",
|
||||
"snapshot": "libreoffice_calc",
|
||||
"instruction": "Fill all the blank cells with the value in the cell above it",
|
||||
"source": "https://www.youtube.com/shorts/VrUzPTIwQ04",
|
||||
"config": [
|
||||
{
|
||||
"type": "download",
|
||||
"parameters": {
|
||||
"files": [
|
||||
{
|
||||
"url": "https://drive.usercontent.google.com/download?id=1FuOZ-5YoKgLLwl_oZd4R3D8pZACf_ukS&export=download&authuser=0&confirm=t&uuid=2051e7a6-5930-4cef-8d77-20ebf66ec6e6&at=APZUnTX1fXqlxy6rluq-Kw-LUhS5:1705919461032",
|
||||
"path": "/home/user/Student_Level_Fill_Blank.xlsx"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "open",
|
||||
"parameters": {
|
||||
"path": "/home/user/Student_Level_Fill_Blank.xlsx"
|
||||
}
|
||||
}
|
||||
],
|
||||
"trajectory": "trajectories/01b269ae-2111-4a07-81fd-3fcd711993b0",
|
||||
"related_apps": [
|
||||
"libreoffice calc"
|
||||
],
|
||||
"evaluator": {
|
||||
"postconfig": [
|
||||
{
|
||||
"type": "activate_window",
|
||||
"parameters": {
|
||||
"window_name": "Student_Level_Fill_Blank.xlsx - LibreOffice Calc",
|
||||
"strict": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "sleep",
|
||||
"parameters": {
|
||||
"seconds": 0.5
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "execute",
|
||||
"parameters": {
|
||||
"command": [
|
||||
"python",
|
||||
"-c",
|
||||
"import pyautogui; pyautogui.press([\"ctrl\", \"s\"]);"
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"func": "compare_table",
|
||||
"expected": {
|
||||
"type": "cloud_file",
|
||||
"path": "https://drive.usercontent.google.com/download?id=1HTle3vgdZSjJIK_wjXyjtWwbiYJeguwv&export=download&authuser=0&confirm=t&uuid=c5d0868b-bed2-48fb-949b-8a9f3f61e8cf&at=APZUnTVqS9CTZFJ1rPqCGQPDCv3p:1705919542916",
|
||||
"dest": "Student_Level_Fill_Blank_gold.xlsx"
|
||||
},
|
||||
"result": {
|
||||
"type": "vm_file",
|
||||
"path": "/home/user/Student_Level_Fill_Blank.xlsx",
|
||||
"dest": "Student_Level_Fill_Blank.xlsx"
|
||||
},
|
||||
"options": {
|
||||
"rules": [
|
||||
{
|
||||
"type": "sheet_data",
|
||||
"sheet_idx0": 0,
|
||||
"sheet_idx1": "EI0"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
{
|
||||
"id": "4e6fcf72-daf3-439f-a232-c434ce416af6",
|
||||
"snapshot": "libreoffice_calc",
|
||||
"instruction": "Please calculate the ages of the employees according to their birthday.",
|
||||
"source": "https://www.youtube.com/shorts/0uxJccNCKcE",
|
||||
"config": [
|
||||
{
|
||||
"type": "download",
|
||||
"parameters": {
|
||||
"files": [
|
||||
{
|
||||
"url": "https://drive.usercontent.google.com/download?id=1WIyJbssCCscQ96be2hF9N7tXPz23JoBT&export=download&authuser=0&confirm=t&uuid=503cdbf3-2fe3-4019-bfd1-5d1faab8d049&at=APZUnTV-XLlF8KEx7zMjtX2kYSuM:1705909207212",
|
||||
"path": "/home/user/Employee_Age_By_Birthday.xlsx"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "open",
|
||||
"parameters": {
|
||||
"path": "/home/user/Employee_Age_By_Birthday.xlsx"
|
||||
}
|
||||
}
|
||||
],
|
||||
"trajectory": "trajectories/4e6fcf72-daf3-439f-a232-c434ce416af6",
|
||||
"related_apps": [
|
||||
"libreoffice calc"
|
||||
],
|
||||
"evaluator": {
|
||||
"postconfig": [
|
||||
{
|
||||
"type": "activate_window",
|
||||
"parameters": {
|
||||
"window_name": "Employee_Age_By_Birthday.xlsx - LibreOffice Calc",
|
||||
"strict": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "sleep",
|
||||
"parameters": {
|
||||
"seconds": 0.5
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "execute",
|
||||
"parameters": {
|
||||
"command": [
|
||||
"python",
|
||||
"-c",
|
||||
"import pyautogui; pyautogui.press([\"ctrl\", \"s\"]);"
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"func": "compare_table",
|
||||
"expected": {
|
||||
"type": "cloud_file",
|
||||
"path": "https://drive.usercontent.google.com/download?id=1sRI72UGfHiVBRFuV4uwhr173u3Sf46Y6&export=download&authuser=0&confirm=t&uuid=90da5e2b-39c0-449d-b753-09dfed73b509&at=APZUnTVFInccKo2QB9JNnIidFfG3:1705909465173",
|
||||
"dest": "Employee_Age_By_Birthday_gold.xlsx"
|
||||
},
|
||||
"result": {
|
||||
"type": "vm_file",
|
||||
"path": "/home/user/Employee_Age_By_Birthday.xlsx",
|
||||
"dest": "Employee_Age_By_Birthday.xlsx"
|
||||
},
|
||||
"options": {
|
||||
"rules": [
|
||||
{
|
||||
"type": "sheet_data",
|
||||
"sheet_idx0": 0,
|
||||
"sheet_idx1": "EI0"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
{
|
||||
"id": "6054afcb-5bab-4702-90a0-b259b5d3217c",
|
||||
"snapshot": "libreoffice_calc",
|
||||
"instruction": "Some data are missed by now and are filled by 'N/A' temporarily. Please hide them in the table for now. Do not delete them and filter is no needed.",
|
||||
"source": "https://www.youtube.com/shorts/JTbZ8sRxkdU",
|
||||
"config": [
|
||||
{
|
||||
"type": "download",
|
||||
"parameters": {
|
||||
"files": [
|
||||
{
|
||||
"url": "https://drive.usercontent.google.com/download?id=1e1Ccsr_CQau9-boF92GxzZ0RtEHPtfdX&export=download&authuser=0&confirm=t&uuid=a1d4518d-e085-4bfa-ae6f-2514ed48efba&at=APZUnTU_ng4YNBQO7u6Dsuj21Gmq:1705911243359",
|
||||
"path": "/home/user/Date_Budget_Variance_HideNA.xlsx"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "open",
|
||||
"parameters": {
|
||||
"path": "/home/user/Date_Budget_Variance_HideNA.xlsx"
|
||||
}
|
||||
}
|
||||
],
|
||||
"trajectory": "trajectories/6054afcb-5bab-4702-90a0-b259b5d3217c",
|
||||
"related_apps": [
|
||||
"libreoffice calc"
|
||||
],
|
||||
"evaluator": {
|
||||
"postconfig": [
|
||||
{
|
||||
"type": "activate_window",
|
||||
"parameters": {
|
||||
"window_name": "Date_Budget_Variance_HideNA.xlsx - LibreOffice Calc",
|
||||
"strict": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "sleep",
|
||||
"parameters": {
|
||||
"seconds": 0.5
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "execute",
|
||||
"parameters": {
|
||||
"command": [
|
||||
"python",
|
||||
"-c",
|
||||
"import pyautogui; pyautogui.press([\"ctrl\", \"s\"]);"
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"func": "compare_table",
|
||||
"expected": {
|
||||
"type": "cloud_file",
|
||||
"path": "https://drive.usercontent.google.com/download?id=1ReZexJAvbAAUng0JD3lEHN70J0WcS0_i&export=download&authuser=0&confirm=t&uuid=a11148b1-93e8-4634-a413-26e0e433c2c9&at=APZUnTV6KulVQf6LpHl4IVNqE5hA:1705914637572",
|
||||
"dest": "Date_Budget_Variance_HideNA_gold.xlsx"
|
||||
},
|
||||
"result": {
|
||||
"type": "vm_file",
|
||||
"path": "/home/user/Date_Budget_Variance_HideNA.xlsx",
|
||||
"dest": "Date_Budget_Variance_HideNA.xlsx"
|
||||
},
|
||||
"options": {
|
||||
"rules": [
|
||||
{
|
||||
"type": "sheet_data",
|
||||
"sheet_idx0": 0,
|
||||
"sheet_idx1": "EI0"
|
||||
},
|
||||
{
|
||||
"type": "row_props",
|
||||
"sheet_idx0": 0,
|
||||
"sheet_idx1": "EI0",
|
||||
"props": ["hidden"]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
{
|
||||
"id": "8b1ce5f2-59d2-4dcc-b0b0-666a714b9a14",
|
||||
"snapshot": "libreoffice_calc",
|
||||
"instruction": "Given a partial calendar, please highlight all the weekends (Satureday & Sunday) by setting the cell background as red (#ff0000).",
|
||||
"source": "https://www.youtube.com/shorts/Hbcwu6IQ1ns",
|
||||
"config": [
|
||||
{
|
||||
"type": "download",
|
||||
"parameters": {
|
||||
"files": [
|
||||
{
|
||||
"url": "https://drive.usercontent.google.com/download?id=1_gyig5Vs3VOuvkjRoLt2ZpXBIyCZfUmV&export=download&authuser=0&confirm=t&uuid=ed113cdd-4279-454b-a66d-07447e31c818&at=APZUnTVztf5DcbF0DjLJitkpUUxt:1705920417565",
|
||||
"path": "/home/user/Calendar_Highlight_Weekend_Days.xlsx"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "open",
|
||||
"parameters": {
|
||||
"path": "/home/user/Calendar_Highlight_Weekend_Days.xlsx"
|
||||
}
|
||||
}
|
||||
],
|
||||
"trajectory": "trajectories/8b1ce5f2-59d2-4dcc-b0b0-666a714b9a14",
|
||||
"related_apps": [
|
||||
"libreoffice calc"
|
||||
],
|
||||
"evaluator": {
|
||||
"postconfig": [
|
||||
{
|
||||
"type": "activate_window",
|
||||
"parameters": {
|
||||
"window_name": "Calendar_Highlight_Weekend_Days.xlsx - LibreOffice Calc",
|
||||
"strict": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "sleep",
|
||||
"parameters": {
|
||||
"seconds": 0.5
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "execute",
|
||||
"parameters": {
|
||||
"command": [
|
||||
"python",
|
||||
"-c",
|
||||
"import pyautogui; pyautogui.press([\"ctrl\", \"s\"]);"
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"func": "compare_table",
|
||||
"expected": {
|
||||
"type": "cloud_file",
|
||||
"path": "https://drive.usercontent.google.com/download?id=1URKsHvPdWDvB-qwsIZ-SqHAmiXaosXKW&export=download&authuser=0&confirm=t&uuid=849064c9-7402-48c5-87f6-e5c290e4bd24&at=APZUnTXarmqM0cO4I0z-Lv7MElzX:1705920495794",
|
||||
"dest": "Calendar_Highlight_Weekend_Days_gold.xlsx"
|
||||
},
|
||||
"result": {
|
||||
"type": "vm_file",
|
||||
"path": "/home/user/Calendar_Highlight_Weekend_Days.xlsx",
|
||||
"dest": "Calendar_Highlight_Weekend_Days.xlsx"
|
||||
},
|
||||
"options": {
|
||||
"rules": [
|
||||
{
|
||||
"type": "sheet_data",
|
||||
"sheet_idx0": 0,
|
||||
"sheet_idx1": "EI0"
|
||||
},
|
||||
{
|
||||
"type": "style",
|
||||
"sheet_idx0": 0,
|
||||
"sheet_idx1": "EI0",
|
||||
"props": "bgcolor"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
{
|
||||
"id": "abed40dc-063f-4598-8ba5-9fe749c0615d",
|
||||
"snapshot": "libreoffice_calc",
|
||||
"instruction": "Check the names in column \"Names with duplicates\" and put the unique ones in column \"Unique Names\". Keep the original order.",
|
||||
"source": "https://help.libreoffice.org/7.6/ro/text/scalc/guide/remove_duplicates.html?&DbPAR=SHARED&System=UNIX",
|
||||
"config": [
|
||||
{
|
||||
"type": "download",
|
||||
"parameters": {
|
||||
"files": [
|
||||
{
|
||||
"url": "https://drive.usercontent.google.com/download?id=1A3O37a2M_tkmXHUn6G8kYu73cUMRUZnt&export=download&authuser=0&confirm=t&uuid=9a44147f-15e4-426c-9235-74fdda7439dc&at=APZUnTU4MAD7rODyryb9r0YolrrN:1705918712764",
|
||||
"path": "/home/user/Names_Duplicate_Unique.xlsx"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "open",
|
||||
"parameters": {
|
||||
"path": "/home/user/Names_Duplicate_Unique.xlsx"
|
||||
}
|
||||
}
|
||||
],
|
||||
"trajectory": "trajectories/abed40dc-063f-4598-8ba5-9fe749c0615d",
|
||||
"related_apps": [
|
||||
"libreoffice calc"
|
||||
],
|
||||
"evaluator": {
|
||||
"postconfig": [
|
||||
{
|
||||
"type": "activate_window",
|
||||
"parameters": {
|
||||
"window_name": "Names_Duplicate_Unique.xlsx - LibreOffice Calc",
|
||||
"strict": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "sleep",
|
||||
"parameters": {
|
||||
"seconds": 0.5
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "execute",
|
||||
"parameters": {
|
||||
"command": [
|
||||
"python",
|
||||
"-c",
|
||||
"import pyautogui; pyautogui.press([\"ctrl\", \"s\"]);"
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"func": "compare_table",
|
||||
"expected": {
|
||||
"type": "cloud_file",
|
||||
"path": "https://drive.usercontent.google.com/download?id=1GYG97VdmPG9mlhSBjMlMpjsuDsEDWXNB&export=download&authuser=0&confirm=t&uuid=6dd49f77-6a87-4f99-9027-0c74bad23d6d&at=APZUnTWzHV6JFiTPuo2ICUSEZqq8:1705918802025",
|
||||
"dest": "Names_Duplicate_Unique_gold.xlsx"
|
||||
},
|
||||
"result": {
|
||||
"type": "vm_file",
|
||||
"path": "/home/user/Names_Duplicate_Unique.xlsx",
|
||||
"dest": "Names_Duplicate_Unique.xlsx"
|
||||
},
|
||||
"options": {
|
||||
"rules": [
|
||||
{
|
||||
"type": "sheet_data",
|
||||
"sheet_idx0": 0,
|
||||
"sheet_idx1": "EI0"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -33,3 +33,4 @@ pymupdf
|
||||
chardet
|
||||
playwright
|
||||
backoff
|
||||
formulas
|
||||
|
||||
Reference in New Issue
Block a user