pointblank 0.8.7__py3-none-any.whl → 0.9.1__py3-none-any.whl

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.
pointblank/_constants.py CHANGED
@@ -39,6 +39,7 @@ ASSERTION_TYPE_METHOD_MAP = {
39
39
  "col_vals_expr": "expr",
40
40
  "col_exists": "col_exists",
41
41
  "rows_distinct": "rows_distinct",
42
+ "rows_complete": "rows_complete",
42
43
  "col_schema_match": "col_schema_match",
43
44
  "row_count_match": "row_count_match",
44
45
  "col_count_match": "col_count_match",
@@ -63,6 +64,7 @@ METHOD_CATEGORY_MAP = {
63
64
  "col_exists": "COL_EXISTS_HAS_TYPE",
64
65
  "expr": "COMPARE_EXPR",
65
66
  "rows_distinct": "ROWS_DISTINCT",
67
+ "rows_complete": "ROWS_COMPLETE",
66
68
  "col_schema_match": "COL_SCHEMA_MATCH",
67
69
  "row_count_match": "ROW_COUNT_MATCH",
68
70
  "col_count_match": "COL_COUNT_MATCH",
@@ -126,6 +128,7 @@ VALIDATION_REPORT_FIELDS = [
126
128
  "inclusive",
127
129
  "na_pass",
128
130
  "pre",
131
+ "segments",
129
132
  "thresholds",
130
133
  "label",
131
134
  "brief",
@@ -231,9 +234,9 @@ SVG_ICONS_FOR_ASSERTION_TYPES = {
231
234
  </svg>""",
232
235
  "col_vals_eq": """<?xml version="1.0" encoding="UTF-8"?>
233
236
  <svg width="67px" height="67px" viewBox="0 0 67 67" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
234
- <title>col_vals_equal</title>
237
+ <title>col_vals_eq</title>
235
238
  <g id="All-Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
236
- <g id="col_vals_equal" transform="translate(0.000000, 0.275862)">
239
+ <g id="col_vals_eq" transform="translate(0.000000, 0.275862)">
237
240
  <path d="M56.712234,1 C59.1975153,1 61.4475153,2.00735931 63.076195,3.63603897 C64.7048747,5.26471863 65.712234,7.51471863 65.712234,10 L65.712234,10 L65.712234,65 L10.712234,65 C8.22695259,65 5.97695259,63.9926407 4.34827294,62.363961 C2.71959328,60.7352814 1.71223397,58.4852814 1.71223397,56 L1.71223397,56 L1.71223397,10 C1.71223397,7.51471863 2.71959328,5.26471863 4.34827294,3.63603897 C5.97695259,2.00735931 8.22695259,1 10.712234,1 L10.712234,1 Z" id="rectangle" stroke="#000000" stroke-width="2" fill="#FFFFFF"></path>
238
241
  <path d="M52.712234,11 L14.712234,11 C13.05989,11 11.712234,12.347656 11.712234,14 L11.712234,52 C11.712234,53.652344 13.05989,55 14.712234,55 L52.712234,55 C54.364578,55 55.712234,53.652344 55.712234,52 L55.712234,14 C55.712234,12.347656 54.364578,11 52.712234,11 Z M46.712234,38 L20.712234,38 L20.712234,36 L46.712234,36 L46.712234,38 Z M46.712234,30 L20.712234,30 L20.712234,28 L46.712234,28 L46.712234,30 Z" id="equals" fill="#000000" fill-rule="nonzero"></path>
239
242
  </g>
@@ -241,9 +244,9 @@ SVG_ICONS_FOR_ASSERTION_TYPES = {
241
244
  </svg>""",
242
245
  "col_vals_ne": """<?xml version="1.0" encoding="UTF-8"?>
243
246
  <svg width="67px" height="67px" viewBox="0 0 67 67" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
244
- <title>col_vals_not_equal</title>
247
+ <title>col_vals_ne</title>
245
248
  <g id="All-Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
246
- <g id="col_vals_not_equal" transform="translate(0.000000, 0.758621)">
249
+ <g id="col_vals_ne" transform="translate(0.000000, 0.758621)">
247
250
  <path d="M56.712234,1 C59.1975153,1 61.4475153,2.00735931 63.076195,3.63603897 C64.7048747,5.26471863 65.712234,7.51471863 65.712234,10 L65.712234,10 L65.712234,65 L10.712234,65 C8.22695259,65 5.97695259,63.9926407 4.34827294,62.363961 C2.71959328,60.7352814 1.71223397,58.4852814 1.71223397,56 L1.71223397,56 L1.71223397,10 C1.71223397,7.51471863 2.71959328,5.26471863 4.34827294,3.63603897 C5.97695259,2.00735931 8.22695259,1 10.712234,1 L10.712234,1 Z" id="rectangle" stroke="#000000" stroke-width="2" fill="#FFFFFF"></path>
248
251
  <path d="M53.712234,12 L13.712234,12 C13.161453,12 12.712234,12.449219 12.712234,13 L12.712234,53 C12.712234,53.550781 13.161453,54 13.712234,54 L53.712234,54 C54.263015,54 54.712234,53.550781 54.712234,53 L54.712234,13 C54.712234,12.449219 54.263015,12 53.712234,12 Z M46.712234,30 L32.989578,30 L36.805984,36 L46.712234,36 L46.712234,38 L38.079422,38 L43.169265,46 L40.798172,46 L35.708328,38 L20.712234,38 L20.712234,36 L34.43489,36 L30.618484,30 L20.712234,30 L20.712234,28 L29.345047,28 L24.251297,20 L26.62239,20 L31.71614,28 L46.712234,28 L46.712234,30 Z" id="not_equal" fill="#000000" fill-rule="nonzero"></path>
249
252
  </g>
@@ -251,9 +254,9 @@ SVG_ICONS_FOR_ASSERTION_TYPES = {
251
254
  </svg>""",
252
255
  "col_vals_ge": """<?xml version="1.0" encoding="UTF-8"?>
253
256
  <svg width="67px" height="67px" viewBox="0 0 67 67" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
254
- <title>col_vals_gte</title>
257
+ <title>col_vals_ge</title>
255
258
  <g id="All-Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
256
- <g id="col_vals_gte" transform="translate(0.000000, 0.241379)">
259
+ <g id="col_vals_ge" transform="translate(0.000000, 0.241379)">
257
260
  <path d="M56.712234,1 C59.1975153,1 61.4475153,2.00735931 63.076195,3.63603897 C64.7048747,5.26471863 65.712234,7.51471863 65.712234,10 L65.712234,10 L65.712234,65 L10.712234,65 C8.22695259,65 5.97695259,63.9926407 4.34827294,62.363961 C2.71959328,60.7352814 1.71223397,58.4852814 1.71223397,56 L1.71223397,56 L1.71223397,10 C1.71223397,7.51471863 2.71959328,5.26471863 4.34827294,3.63603897 C5.97695259,2.00735931 8.22695259,1 10.712234,1 L10.712234,1 Z" id="rectangle" stroke="#000000" stroke-width="2" fill="#FFFFFF"></path>
258
261
  <path d="M49.712234,12 L17.712234,12 C14.952234,12 12.712234,14.24 12.712234,17 L12.712234,49 C12.712234,51.76 14.952234,54 17.712234,54 L49.712234,54 C52.472234,54 54.712234,51.76 54.712234,49 L54.712234,17 C54.712234,14.24 52.472234,12 49.712234,12 Z M44.712234,47 L22.712234,47 L22.712234,45 L44.712234,45 L44.712234,47 Z M24.182234,40.88 L23.242234,39.12 L40.562234,30 L23.242234,20.88 L24.182234,19.12 L44.862234,30 L24.182234,40.88 Z" id="greater_than_equal" fill="#000000" fill-rule="nonzero"></path>
259
262
  </g>
@@ -261,9 +264,9 @@ SVG_ICONS_FOR_ASSERTION_TYPES = {
261
264
  </svg>""",
262
265
  "col_vals_le": """<?xml version="1.0" encoding="UTF-8"?>
263
266
  <svg width="67px" height="67px" viewBox="0 0 67 67" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
264
- <title>col_vals_lte</title>
267
+ <title>col_vals_le</title>
265
268
  <g id="All-Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
266
- <g id="col_vals_lte" transform="translate(0.000000, 0.793103)">
269
+ <g id="col_vals_le" transform="translate(0.000000, 0.793103)">
267
270
  <path d="M56.712234,1 C59.1975153,1 61.4475153,2.00735931 63.076195,3.63603897 C64.7048747,5.26471863 65.712234,7.51471863 65.712234,10 L65.712234,10 L65.712234,65 L10.712234,65 C8.22695259,65 5.97695259,63.9926407 4.34827294,62.363961 C2.71959328,60.7352814 1.71223397,58.4852814 1.71223397,56 L1.71223397,56 L1.71223397,10 C1.71223397,7.51471863 2.71959328,5.26471863 4.34827294,3.63603897 C5.97695259,2.00735931 8.22695259,1 10.712234,1 L10.712234,1 Z" id="rectangle" stroke="#000000" stroke-width="2" fill="#FFFFFF"></path>
268
271
  <path d="M53.712234,12 L13.712234,12 C13.157547,12 12.712234,12.449219 12.712234,13 L12.712234,53 C12.712234,53.550781 13.157547,54 13.712234,54 L53.712234,54 C54.266922,54 54.712234,53.550781 54.712234,53 L54.712234,13 C54.712234,12.449219 54.266922,12 53.712234,12 Z M42.227859,19.125 L43.196609,20.875 L26.770828,30 L43.196609,39.125 L42.227859,40.875 L22.65364,30 L42.227859,19.125 Z M44.712234,47 L22.712234,47 L22.712234,45 L44.712234,45 L44.712234,47 Z" id="less_than_equal" fill="#000000" fill-rule="nonzero"></path>
269
272
  </g>
@@ -281,9 +284,9 @@ SVG_ICONS_FOR_ASSERTION_TYPES = {
281
284
  </svg>""",
282
285
  "col_vals_outside": """<?xml version="1.0" encoding="UTF-8"?>
283
286
  <svg width="67px" height="67px" viewBox="0 0 67 67" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
284
- <title>col_vals_not_between</title>
287
+ <title>col_vals_outside</title>
285
288
  <g id="All-Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
286
- <g id="col_vals_not_between" transform="translate(0.000000, 0.689655)">
289
+ <g id="col_vals_outside" transform="translate(0.000000, 0.689655)">
287
290
  <path d="M56.712234,1 C59.1975153,1 61.4475153,2.00735931 63.076195,3.63603897 C64.7048747,5.26471863 65.712234,7.51471863 65.712234,10 L65.712234,10 L65.712234,65 L10.712234,65 C8.22695259,65 5.97695259,63.9926407 4.34827294,62.363961 C2.71959328,60.7352814 1.71223397,58.4852814 1.71223397,56 L1.71223397,56 L1.71223397,10 C1.71223397,7.51471863 2.71959328,5.26471863 4.34827294,3.63603897 C5.97695259,2.00735931 8.22695259,1 10.712234,1 L10.712234,1 Z" id="rectangle" stroke="#000000" stroke-width="2" fill="#FFFFFF"></path>
288
291
  <g id="outside_range" transform="translate(11.000000, 21.000000)" fill="#000000">
289
292
  <path d="M12.993484,0.96875 C11.962234,1.082031 11.188797,1.964844 11.212234,3 L11.212234,21 C11.200515,21.722656 11.579422,22.390625 12.204422,22.753906 C12.825515,23.121094 13.598953,23.121094 14.220047,22.753906 C14.845047,22.390625 15.223953,21.722656 15.212234,21 L15.212234,3 C15.220047,2.457031 15.009109,1.9375 14.626297,1.554688 C14.243484,1.171875 13.723953,0.960938 13.180984,0.96875 C13.118484,0.964844 13.055984,0.964844 12.993484,0.96875 Z M32.993484,0.96875 C31.962234,1.082031 31.188797,1.964844 31.212234,3 L31.212234,21 C31.200515,21.722656 31.579422,22.390625 32.204422,22.753906 C32.825515,23.121094 33.598953,23.121094 34.220047,22.753906 C34.845047,22.390625 35.223953,21.722656 35.212234,21 L35.212234,3 C35.220047,2.457031 35.009109,1.9375 34.626297,1.554688 C34.243484,1.171875 33.723953,0.960938 33.180984,0.96875 C33.118484,0.964844 33.055984,0.964844 32.993484,0.96875 Z M17.212234,1 C16.661453,1 16.212234,1.449219 16.212234,2 C16.212234,2.550781 16.661453,3 17.212234,3 C17.763015,3 18.212234,2.550781 18.212234,2 C18.212234,1.449219 17.763015,1 17.212234,1 Z M21.212234,1 C20.661453,1 20.212234,1.449219 20.212234,2 C20.212234,2.550781 20.661453,3 21.212234,3 C21.763015,3 22.212234,2.550781 22.212234,2 C22.212234,1.449219 21.763015,1 21.212234,1 Z M25.212234,1 C24.661453,1 24.212234,1.449219 24.212234,2 C24.212234,2.550781 24.661453,3 25.212234,3 C25.763015,3 26.212234,2.550781 26.212234,2 C26.212234,1.449219 25.763015,1 25.212234,1 Z M29.212234,1 C28.661453,1 28.212234,1.449219 28.212234,2 C28.212234,2.550781 28.661453,3 29.212234,3 C29.763015,3 30.212234,2.550781 30.212234,2 C30.212234,1.449219 29.763015,1 29.212234,1 Z M17.212234,21 C16.661453,21 16.212234,21.449219 16.212234,22 C16.212234,22.550781 16.661453,23 17.212234,23 C17.763015,23 18.212234,22.550781 18.212234,22 C18.212234,21.449219 17.763015,21 17.212234,21 Z M21.212234,21 C20.661453,21 20.212234,21.449219 20.212234,22 C20.212234,22.550781 20.661453,23 21.212234,23 C21.763015,23 22.212234,22.550781 22.212234,22 C22.212234,21.449219 21.763015,21 21.212234,21 Z M25.212234,21 C24.661453,21 24.212234,21.449219 24.212234,22 C24.212234,22.550781 24.661453,23 25.212234,23 C25.763015,23 26.212234,22.550781 26.212234,22 C26.212234,21.449219 25.763015,21 25.212234,21 Z M29.212234,21 C28.661453,21 28.212234,21.449219 28.212234,22 C28.212234,22.550781 28.661453,23 29.212234,23 C29.763015,23 30.212234,22.550781 30.212234,22 C30.212234,21.449219 29.763015,21 29.212234,21 Z" id="small_range" fill-rule="nonzero"></path>
@@ -374,6 +377,19 @@ SVG_ICONS_FOR_ASSERTION_TYPES = {
374
377
  </g>
375
378
  </g>
376
379
  </g>
380
+ </svg>""",
381
+ "rows_complete": """<?xml version="1.0" encoding="UTF-8"?>
382
+ <svg width="67px" height="67px" viewBox="0 0 67 67" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
383
+ <title>rows_complete</title>
384
+ <g id="All-Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
385
+ <g id="rows_complete" transform="translate(0.000000, 0.965517)">
386
+ <path d="M56.712234,1 C59.1975153,1 61.4475153,2.00735931 63.076195,3.63603897 C64.7048747,5.26471863 65.712234,7.51471863 65.712234,10 L65.712234,10 L65.712234,65 L10.712234,65 C8.22695259,65 5.97695259,63.9926407 4.34827294,62.363961 C2.71959328,60.7352814 1.71223397,58.4852814 1.71223397,56 L1.71223397,56 L1.71223397,10 C1.71223397,7.51471863 2.71959328,5.26471863 4.34827294,3.63603897 C5.97695259,2.00735931 8.22695259,1 10.712234,1 L10.712234,1 Z" id="rectangle" stroke="#000000" stroke-width="2" fill="#FFFFFF"></path>
387
+ <g id="complete_me" transform="translate(12.500000, 9.500000)" fill="#000000">
388
+ <path d="M8,0 L8,10 L16,10 L16,18 L26,18 L26,10 L34,10 L34,0 L8,0 Z M10,2 L16,2 L16,8 L10,8 L10,2 Z M18,2 L24,2 L24,8 L18,8 L18,2 Z M26,2 L32,2 L32,8 L26,8 L26,2 Z M18,10 L24,10 L24,16 L18,16 L18,10 Z M0,21 L0,47 L42,47 L42,21 L32,21 L32,29 L24,29 L24,37 L18,37 L18,29 L10,29 L10,21 L0,21 Z M2,23 L8,23 L8,29 L2,29 L2,23 Z M34,23 L40,23 L40,29 L34,29 L34,23 Z M2,31 L8,31 L8,37 L2,37 L2,31 Z M10,31 L16,31 L16,37 L10,37 L10,31 Z M26,31 L32,31 L32,37 L26,37 L26,31 Z M34,31 L40,31 L40,37 L34,37 L34,31 Z M2,39 L8,39 L8,45 L2,45 L2,39 Z M10,39 L16,39 L16,45 L10,45 L10,39 Z M18,39 L24,39 L24,45 L18,45 L18,39 Z M26,39 L32,39 L32,45 L26,45 L26,39 Z M34,39 L40,39 L40,45 L34,45 L34,39 Z" id="Shape" fill-rule="nonzero"></path>
389
+ <path d="M22.4566476,18.35817 C22.9253976,18.29567 23.3746166,18.569108 23.5308666,19.01442 C23.6910226,19.459733 23.5152416,19.955826 23.1128976,20.20192 L23.1128976,20.20192 L20.2066476,22.38942 L25.7989286,22.3893123 L25.7989286,24.3893123 L20.2066476,24.38942 L23.1128976,26.57692 C23.5621166,26.912858 23.6519606,27.549576 23.3160226,27.998795 C22.9800856,28.448014 22.3433666,28.537858 21.8941476,28.20192 L21.8941476,28.20192 L16.6128976,24.20192 C16.3511786,24.01442 16.1949286,23.709733 16.1949286,23.38942 C16.1949286,23.069108 16.3511786,22.76442 16.6128976,22.57692 L16.6128976,22.57692 L21.8941476,18.57692 C22.0230536,18.479264 22.1714916,18.416764 22.3316476,18.38942 C22.3707106,18.377701 22.4136786,18.365983 22.4566476,18.35817 Z" id="arrow_right" transform="translate(20.997393, 23.377149) rotate(-90.000000) translate(-20.997393, -23.377149) "></path>
390
+ </g>
391
+ </g>
392
+ </g>
377
393
  </svg>""",
378
394
  "col_schema_match": """<?xml version="1.0" encoding="UTF-8"?>
379
395
  <svg width="67px" height="67px" viewBox="0 0 67 67" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
@@ -728,6 +728,114 @@ EXPECT_FAIL_TEXT = {
728
728
  "hi": "चयनित स्तंभों में पंक्तियां पूरी तरह से अलग नहीं थीं, ऐसे असफल परीक्षण इकाइयों की अधिकता।",
729
729
  "el": "Υπέρβαση αποτυχημένων μονάδων δοκιμής όπου δεν υπήρχαν διακριτές γραμμές στις επιλεγμένες στήλες.",
730
730
  },
731
+ "all_row_complete_expectation_text": {
732
+ "en": "Expect entirely complete rows across all columns.",
733
+ "fr": "On s'attend à des lignes entièrement complètes dans toutes les colonnes.",
734
+ "de": "Erwarten Sie vollständig komplette Zeilen über alle Spalten hinweg.",
735
+ "it": "Aspettati righe completamente complete su tutte le colonne.",
736
+ "es": "Se espera que las filas estén completamente completas en todas las columnas.",
737
+ "pt": "Espera-se linhas completamente preenchidas em todas as colunas.",
738
+ "ro": "Se așteaptă ca rândurile să fie complet complete în toate coloanele.",
739
+ "tr": "Tüm sütunlarda tamamen eksiksiz satırlar bekleyin.",
740
+ "zh-Hans": "预期所有列中的行都是完整的。",
741
+ "zh-Hant": "預期所有列中的行都是完整的。",
742
+ "ja": "すべての列で完全に完全な行を期待します。",
743
+ "ko": "모든 열에서 완전히 완성된 행을 기대합니다.",
744
+ "vi": "Kỳ vọng các hàng hoàn toàn đầy đủ trên tất cả các cột.",
745
+ "ru": "Ожидайте полностью заполненные строки по всем столбцам.",
746
+ "cs": "Očekávejte zcela kompletní řádky ve všech sloupcích.",
747
+ "pl": "Spodziewaj się w pełni kompletnych wierszy we wszystkich kolumnach.",
748
+ "da": "Forvent helt komplette rækker på tværs af alle kolonner.",
749
+ "sv": "Förvänta dig helt kompletta rader över alla kolumner.",
750
+ "nb": "Forvent helt komplette rader på tvers av alle kolonner.",
751
+ "nl": "Verwacht volledig complete rijen in alle kolommen.",
752
+ "fi": "Odota täysin täydellisiä rivejä kaikissa sarakkeissa.",
753
+ "is": "Væntir þess að allar raðir séu heildstæðar yfir alla dálka.",
754
+ "ar": "توقع صفوف مكتملة تمامًا عبر جميع الأعمدة.",
755
+ "hi": "सभी स्तंभों में पूरी तरह से पूर्ण पंक्तियों की अपेक्षा करें।",
756
+ "el": "Αναμένεται πλήρως ολοκληρωμένες γραμμές σε όλες τις στήλες.",
757
+ },
758
+ "all_row_complete_failure_text": {
759
+ "en": "Exceedance of failed test units where there weren't complete rows across all columns.",
760
+ "fr": "Dépassement des unités de test ayant échoué là où il n'y avait pas de lignes complètes dans toutes les colonnes.",
761
+ "de": "Überschreitung fehlgeschlagener Testeinheiten, bei denen nicht vollständige Zeilen über alle Spalten hinweg vorhanden waren.",
762
+ "it": "Superamento delle unità di test fallite in cui non c'erano righe complete su tutte le colonne.",
763
+ "es": "Se superó el número de unidades de prueba fallidas donde no había filas completas en todas las columnas.",
764
+ "pt": "Excedeu o número de unidades de teste com falha onde não havia linhas completas em todas as colunas.",
765
+ "ro": "Depășirea unităților de test eșuate unde nu au existat rânduri complete în toate coloanele.",
766
+ "tr": "Tüm sütunlarda eksiksiz satırların olmadığı başarısız test birimlerinin aşılması.",
767
+ "zh-Hans": "错误过多,其中在所有列中行不完整。",
768
+ "zh-Hant": "錯誤過多,在所有列中沒有完整的行。",
769
+ "ja": "すべての列で完全な行がないテスト単位の失敗の超過。",
770
+ "ko": "모든 열에 걸쳐 완전한 행이 아니었던 실패한 테스트 단위 초과.",
771
+ "vi": "Vượt quá số đơn vị kiểm tra thất bại trong đó không có các hàng đầy đủ trên tất cả các cột.",
772
+ "ru": "Превышение неудачных тестовых единиц, где не было полных строк по всем столбцам.",
773
+ "cs": "Překročení počtu neúspěšných testů, kde nebyly úplné řádky ve všech sloupcích.",
774
+ "pl": "Przekroczenie liczby niepomyślnych jednostek testowych, w których nie było kompletnych wierszy we wszystkich kolumnach.",
775
+ "da": "Overskridelse af antal fejlslagne enhedstests, hvor der ikke var komplette rækker på tværs af alle kolonner.",
776
+ "sv": "Överstiger antalet misslyckade enhetstest där det inte fanns kompletta rader över alla kolumner.",
777
+ "nb": "Overskridelse av mislykkede testenheter hvor det ikke var komplette rader på tvers av alle kolonner.",
778
+ "nl": "Overschrijding van mislukte testeenheden waarbij er geen complete rijen waren in alle kolommen.",
779
+ "fi": "Epäonnistuneiden testiyksikköjen ylitys, joissa ei ollut täydellisiä rivejä kaikissa sarakkeissa.",
780
+ "is": "Of mörg misheppnuð próf þar sem raðir voru ekki heildstæðar yfir alla dálka.",
781
+ "ar": "تجاوز وحدات الاختبار الفاشلة حيث لم تكن هناك صفوف مكتملة عبر جميع الأعمدة.",
782
+ "hi": "सभी स्तंभों में पूर्ण पंक्तियां नहीं थीं, ऐसे असफल परीक्षण इकाइयों की अधिकता।",
783
+ "el": "Υπέρβαση αποτυχημένων μονάδων δοκιμής όπου δεν υπήρχαν πλήρεις γραμμές σε όλες τις στήλες.",
784
+ },
785
+ "across_row_complete_expectation_text": {
786
+ "en": "Expect entirely complete rows across {column_text}.",
787
+ "fr": "On s'attend à des lignes entièrement complètes dans {column_text}.",
788
+ "de": "Erwarten Sie vollständig komplette Zeilen über {column_text} hinweg.",
789
+ "it": "Aspettati righe completamente complete su {column_text}.",
790
+ "es": "Se espera que las filas estén completamente completas en {column_text}.",
791
+ "pt": "Espera-se linhas completamente preenchidas em {column_text}.",
792
+ "ro": "Se așteaptă ca rândurile să fie complet complete în {column_text}.",
793
+ "tr": "{column_text} boyunca tamamen eksiksiz satırlar bekleyin.",
794
+ "zh-Hans": "预期在{column_text}中的行是完整的。",
795
+ "zh-Hant": "預期在{column_text}中的行是完整的。",
796
+ "ja": "{column_text}において完全に完全な行を期待します。",
797
+ "ko": "{column_text}에서 완전히 완성된 행을 기대합니다.",
798
+ "vi": "Kỳ vọng các hàng hoàn toàn đầy đủ trên {column_text}.",
799
+ "ru": "Ожидайте полностью заполненные строки в {column_text}.",
800
+ "cs": "Očekávejte zcela kompletní řádky v {column_text}.",
801
+ "pl": "Spodziewaj się w pełni kompletnych wierszy w {column_text}.",
802
+ "da": "Forvent helt komplette rækker på tværs af {column_text}.",
803
+ "sv": "Förvänta dig helt kompletta rader över {column_text}.",
804
+ "nb": "Forvent helt komplette rader på tvers av {column_text}.",
805
+ "nl": "Verwacht volledig complete rijen in {column_text}.",
806
+ "fi": "Odota täysin täydellisiä rivejä sarakkeissa {column_text}.",
807
+ "is": "Væntir þess að allar raðir séu heildstæðar yfir {column_text}.",
808
+ "ar": "توقع صفوف مكتملة تمامًا عبر {column_text}.",
809
+ "hi": "{column_text} में पूरी तरह से पूर्ण पंक्तियों की अपेक्षा करें।",
810
+ "el": "Αναμένεται πλήρως ολοκληρωμένες γραμμές στις στήλες {column_text}.",
811
+ },
812
+ "across_row_complete_failure_text": {
813
+ "en": "Exceedance of failed test units where there weren't complete rows across selected columns.",
814
+ "fr": "Dépassement des unités de test ayant échoué là où il n'y avait pas de lignes complètes dans les colonnes sélectionnées.",
815
+ "de": "Überschreitung fehlgeschlagener Testeinheiten, bei denen nicht vollständige Zeilen über die ausgewählten Spalten hinweg vorhanden waren.",
816
+ "it": "Superamento delle unità di test fallite in cui non c'erano righe complete nelle colonne selezionate.",
817
+ "es": "Se superó el número de unidades de prueba fallidas donde no había filas completas en las columnas seleccionadas.",
818
+ "pt": "Excedeu o número de unidades de teste com falha onde não havia linhas completas nas colunas selecionadas.",
819
+ "ro": "Depășirea unităților de test eșuate unde nu au existat rânduri complete în coloanele selectate.",
820
+ "tr": "Seçili sütunlarda eksiksiz satırların olmadığı başarısız test birimlerinin aşılması.",
821
+ "zh-Hans": "错误过多,其中在所选列中行不完整。",
822
+ "zh-Hant": "錯誤過多,在所選列中沒有完整的行。",
823
+ "ja": "選択された列で完全な行がないテスト単位の失敗の超過。",
824
+ "ko": "선택된 열에서 완전한 행이 아니었던 실패한 테스트 단위 초과.",
825
+ "vi": "Vượt quá số đơn vị kiểm tra thất bại trong đó không có các hàng đầy đủ trên các cột đã chọn.",
826
+ "ru": "Превышение неудачных тестовых единиц, где не было полных строк в выбранных столбцах.",
827
+ "cs": "Překročení počtu neúspěšných testů, kde nebyly úplné řádky ve vybraných sloupcích.",
828
+ "pl": "Przekroczenie liczby niepomyślnych jednostek testowych, w których nie było kompletnych wierszy w wybranych kolumnach.",
829
+ "da": "Overskridelse af antal fejlslagne enhedstests, hvor der ikke var komplette rækker på tværs af valgte kolonner.",
830
+ "sv": "Överstiger antalet misslyckade enhetstest där det inte fanns kompletta rader över valda kolumner.",
831
+ "nb": "Overskridelse av mislykkede testenheter hvor det ikke var komplette rader på tvers av valgte kolonner.",
832
+ "nl": "Overschrijding van mislukte testeenheden waarbij er geen complete rijen waren in geselecteerde kolommen.",
833
+ "fi": "Epäonnistuneiden testiyksikköjen ylitys, joissa ei ollut täydellisiä rivejä valituissa sarakkeissa.",
834
+ "is": "Of mörg misheppnuð próf þar sem raðir voru ekki heildstæðar yfir valda dálka.",
835
+ "ar": "تجاوز وحدات الاختبار الفاشلة حيث لم تكن هناك صفوف مكتملة عبر الأعمدة المحددة.",
836
+ "hi": "चयनित स्तंभों में पूर्ण पंक्तियां नहीं थीं, ऐसे असफल परीक्षण इकाइयों की अधिकता।",
837
+ "el": "Υπέρβαση αποτυχημένων μονάδων δοκιμής όπου δεν υπήρχαν πλήρεις γραμμές στις επιλεγμένες στήλες.",
838
+ },
731
839
  "col_schema_match_expectation_text": {
732
840
  "en": "Expect that column schemas match.",
733
841
  "fr": "On s'attend à ce que les schémas de colonnes correspondent.",
@@ -1735,6 +1843,60 @@ STEP_REPORT_TEXT = {
1735
1843
  "hi": "पंक्तियां स्तंभों के एक उपसमूह में अलग-अलग हैं",
1736
1844
  "el": "Οι γραμμές είναι διακριτές σε ένα υποσύνολο στηλών",
1737
1845
  },
1846
+ "rows_complete_all": {
1847
+ "en": "All rows are complete",
1848
+ "fr": "Toutes les lignes sont complètes",
1849
+ "de": "Alle Zeilen sind vollständig",
1850
+ "it": "Tutte le righe sono complete",
1851
+ "es": "Todas las filas están completas",
1852
+ "pt": "Todas as linhas estão completas",
1853
+ "ro": "Toate rândurile sunt complete",
1854
+ "tr": "Tüm satırlar eksiksizdir",
1855
+ "zh-Hans": "所有行都是完整的",
1856
+ "zh-Hant": "所有行都是完整的",
1857
+ "ja": "すべての行が完全です",
1858
+ "ko": "모든 행이 완전합니다",
1859
+ "vi": "Tất cả các hàng đều đầy đủ",
1860
+ "ru": "Все строки заполнены полностью",
1861
+ "cs": "Všechny řádky jsou úplné",
1862
+ "pl": "Wszystkie wiersze są kompletne",
1863
+ "da": "Alle rækker er komplette",
1864
+ "sv": "Alla rader är kompletta",
1865
+ "nb": "Alle rader er komplette",
1866
+ "nl": "Alle rijen zijn compleet",
1867
+ "fi": "Kaikki rivit ovat täydellisiä",
1868
+ "is": "Allar raðir eru heildstæðar",
1869
+ "ar": "جميع الصفوف مكتملة",
1870
+ "hi": "सभी पंक्तियां पूर्ण हैं",
1871
+ "el": "Όλες οι γραμμές είναι πλήρεις",
1872
+ },
1873
+ "rows_complete_subset": {
1874
+ "en": "Rows are complete across a subset of columns",
1875
+ "fr": "Les lignes sont complètes sur un sous-ensemble de colonnes",
1876
+ "de": "Zeilen sind in einer Teilmenge von Spalten vollständig",
1877
+ "it": "Le righe sono complete in un sottoinsieme di colonne",
1878
+ "es": "Las filas están completas en un subconjunto de columnas",
1879
+ "pt": "As linhas estão completas em um subconjunto de colunas",
1880
+ "ro": "Rândurile sunt complete într-un subset de coloane",
1881
+ "tr": "Satırlar, sütunların bir alt kümesinde eksiksizdir",
1882
+ "zh-Hans": "行在列的子集中是完整的",
1883
+ "zh-Hant": "行在列的子集中是完整的",
1884
+ "ja": "行は列のサブセット間で完全です",
1885
+ "ko": "행이 열의 하위 집합에서 완전합니다",
1886
+ "vi": "Các hàng đầy đủ trong một tập con của các cột",
1887
+ "ru": "Строки полностью заполнены в подмножестве столбцов",
1888
+ "cs": "Řádky jsou úplné napříč podmnožinou sloupců",
1889
+ "pl": "Wiersze są kompletne w podzbiorze kolumn",
1890
+ "da": "Rækker er komplette på tværs af en delmængde af kolonner",
1891
+ "sv": "Rader är kompletta över en delmängd av kolumner",
1892
+ "nb": "Rader er komplette på tvers av en delmengde av kolonner",
1893
+ "nl": "Rijen zijn compleet over een subset van kolommen",
1894
+ "fi": "Rivit ovat täydellisiä sarakkeiden osajoukossa",
1895
+ "is": "Raðir eru heildstæðar í undirsafni dálka",
1896
+ "ar": "الصفوف مكتملة عبر مجموعة فرعية من الأعمدة",
1897
+ "hi": "पंक्तियां स्तंभों के एक उपसमूह में पूर्ण हैं",
1898
+ "el": "Οι γραμμές είναι πλήρεις σε ένα υποσύνολο στηλών",
1899
+ },
1738
1900
  "report_for_step_i": {
1739
1901
  "en": "Report for Validation Step {i}",
1740
1902
  "fr": "Rapport pour l'étape de validation {i}",
@@ -1,5 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import functools
3
4
  from dataclasses import dataclass
4
5
  from typing import TYPE_CHECKING, Any
5
6
 
@@ -1219,6 +1220,36 @@ class Interrogator:
1219
1220
 
1220
1221
  return tbl.to_native()
1221
1222
 
1223
+ def rows_complete(self) -> FrameT | Any:
1224
+ # Ibis backends ---------------------------------------------
1225
+
1226
+ if self.tbl_type in IBIS_BACKENDS:
1227
+ tbl = self.x
1228
+
1229
+ # Determine the number of null values in each row (column subsets are handled in
1230
+ # the `_check_nulls_across_columns_ibis()` function)
1231
+ tbl = _check_nulls_across_columns_ibis(table=tbl, columns_subset=self.columns_subset)
1232
+
1233
+ # Failing rows will have the value `True` in the generated column, so we need to negate
1234
+ # the result to get the passing rows
1235
+ return tbl.mutate(pb_is_good_=~tbl["_any_is_null_"]).drop("_any_is_null_")
1236
+
1237
+ # Local backends (Narwhals) ---------------------------------
1238
+
1239
+ tbl = self.x
1240
+
1241
+ # Determine the number of null values in each row (column subsets are handled in
1242
+ # the `_check_nulls_across_columns_nw()` function)
1243
+ tbl = _check_nulls_across_columns_nw(table=tbl, columns_subset=self.columns_subset)
1244
+
1245
+ # Failing rows will have the value `True` in the generated column, so we need to negate
1246
+ # the result to get the passing rows
1247
+ tbl = tbl.with_columns(pb_is_good_=~nw.col("_any_is_null_"))
1248
+ tbl = tbl.drop("_any_is_null_")
1249
+
1250
+ # Convert the table to a native format
1251
+ return tbl.to_native()
1252
+
1222
1253
 
1223
1254
  @dataclass
1224
1255
  class ColValsCompareOne:
@@ -1794,6 +1825,58 @@ class RowsDistinct:
1794
1825
  return self.test_unit_res
1795
1826
 
1796
1827
 
1828
+ @dataclass
1829
+ class RowsComplete:
1830
+ """
1831
+ Check if rows in a DataFrame are complete.
1832
+
1833
+ Parameters
1834
+ ----------
1835
+ data_tbl
1836
+ A data table.
1837
+ columns_subset
1838
+ A list of columns to check for completeness.
1839
+ threshold
1840
+ The maximum number of failing test units to allow.
1841
+ tbl_type
1842
+ The type of table to use for the assertion.
1843
+
1844
+ Returns
1845
+ -------
1846
+ bool
1847
+ `True` when test units pass below the threshold level for failing test units, `False`
1848
+ otherwise.
1849
+ """
1850
+
1851
+ data_tbl: FrameT
1852
+ columns_subset: list[str] | None
1853
+ threshold: int
1854
+ tbl_type: str = "local"
1855
+
1856
+ def __post_init__(self):
1857
+ if self.tbl_type == "local":
1858
+ # Convert the DataFrame to a format that narwhals can work with, and:
1859
+ # - check if the `column=` exists
1860
+ # - check if the `column=` type is compatible with the test
1861
+ tbl = _column_subset_test_prep(df=self.data_tbl, columns_subset=self.columns_subset)
1862
+
1863
+ # TODO: For Ibis backends, check if the column exists and if the column type is compatible;
1864
+ # for now, just pass the table as is
1865
+ if self.tbl_type in IBIS_BACKENDS:
1866
+ tbl = self.data_tbl
1867
+
1868
+ # Collect results for the test units; the results are a list of booleans where
1869
+ # `True` indicates a passing test unit
1870
+ self.test_unit_res = Interrogator(
1871
+ x=tbl,
1872
+ columns_subset=self.columns_subset,
1873
+ tbl_type=self.tbl_type,
1874
+ ).rows_complete()
1875
+
1876
+ def get_test_results(self):
1877
+ return self.test_unit_res
1878
+
1879
+
1797
1880
  @dataclass
1798
1881
  class ColSchemaMatch:
1799
1882
  """
@@ -2207,6 +2290,40 @@ def _column_has_null_values(table: FrameT, column: str) -> bool:
2207
2290
  return True
2208
2291
 
2209
2292
 
2293
+ def _check_nulls_across_columns_ibis(table, columns_subset):
2294
+ # Get all column names from the table
2295
+ column_names = columns_subset if columns_subset else table.columns
2296
+
2297
+ # Build the expression by combining each column's isnull() with OR operations
2298
+ null_expr = functools.reduce(
2299
+ lambda acc, col: acc | table[col].isnull() if acc is not None else table[col].isnull(),
2300
+ column_names,
2301
+ None,
2302
+ )
2303
+
2304
+ # Add the expression as a new column to the table
2305
+ result = table.mutate(_any_is_null_=null_expr)
2306
+
2307
+ return result
2308
+
2309
+
2310
+ def _check_nulls_across_columns_nw(table, columns_subset):
2311
+ # Get all column names from the table
2312
+ column_names = columns_subset if columns_subset else table.columns
2313
+
2314
+ # Build the expression by combining each column's `is_null()` with OR operations
2315
+ null_expr = functools.reduce(
2316
+ lambda acc, col: acc | table[col].is_null() if acc is not None else table[col].is_null(),
2317
+ column_names,
2318
+ None,
2319
+ )
2320
+
2321
+ # Add the expression as a new column to the table
2322
+ result = table.with_columns(_any_is_null_=null_expr)
2323
+
2324
+ return result
2325
+
2326
+
2210
2327
  def _modify_datetime_compare_val(tgt_column: any, compare_val: any) -> any:
2211
2328
  tgt_col_dtype_str = str(tgt_column.dtype).lower()
2212
2329
 
pointblank/_typing.py CHANGED
@@ -1,10 +1,26 @@
1
1
  from __future__ import annotations
2
2
 
3
+ from typing import TypeAlias
4
+
3
5
  ## Absolute bounds, ie. plus or minus
4
- type AbsoluteBounds = tuple[int, int]
6
+ AbsoluteBounds: TypeAlias = tuple[int, int]
5
7
 
6
8
  ## Relative bounds, ie. plus or minus some percent
7
- type RelativeBounds = tuple[float, float]
9
+ RelativeBounds: TypeAlias = tuple[float, float]
8
10
 
9
11
  ## Tolerance afforded to some check
10
- type Tolerance = int | float | AbsoluteBounds | RelativeBounds
12
+ Tolerance: TypeAlias = int | float | AbsoluteBounds | RelativeBounds
13
+
14
+ ## Types for data segmentation
15
+
16
+ ## Value(s) that can be used in a segment tuple
17
+ SegmentValue: TypeAlias = str | list[str]
18
+
19
+ ## (column, value(s)) format for segments
20
+ SegmentTuple: TypeAlias = tuple[str, SegmentValue]
21
+
22
+ ## Individual segment item (string or tuple)
23
+ SegmentItem: TypeAlias = str | SegmentTuple
24
+
25
+ ## Full segment specification options
26
+ SegmentSpec: TypeAlias = str | SegmentTuple | list[SegmentItem]
pointblank/_utils.py CHANGED
@@ -485,6 +485,7 @@ def _get_api_text() -> str:
485
485
  "Validate.col_vals_expr",
486
486
  "Validate.col_exists",
487
487
  "Validate.rows_distinct",
488
+ "Validate.rows_complete",
488
489
  "Validate.col_schema_match",
489
490
  "Validate.row_count_match",
490
491
  "Validate.col_count_match",