xlwings-utils 25.0.6.post4__py3-none-any.whl → 25.0.7__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.

Potentially problematic release.


This version of xlwings-utils might be problematic. Click here for more details.

@@ -5,7 +5,7 @@
5
5
  # /_/\_\|_| \_/\_/ |_||_| |_| \__, ||___/ _____ \__,_| \__||_||_||___/
6
6
  # |___/ |_____|
7
7
 
8
- __version__ = "25.0.6"
8
+ __version__ = "25.0.7"
9
9
 
10
10
 
11
11
  import dropbox
@@ -20,7 +20,6 @@ Pythonista = sys.platform == "ios"
20
20
  try:
21
21
  import xlwings
22
22
 
23
- xlwings = True
24
23
  except ImportError:
25
24
  xlwings = False
26
25
 
@@ -276,83 +275,212 @@ class block:
276
275
  Parameters
277
276
  ----------
278
277
  number_of_rows : int
279
- number of rows
278
+ number of rows (dedault 1)
280
279
 
281
280
  number_of_columns : int
282
- number of columns
281
+ number of columns (default 1)
283
282
 
284
283
  Returns
285
284
  -------
286
285
  block
287
286
  """
288
287
 
289
- def __init__(self, value=missing, *, number_of_rows=missing, number_of_columns=missing, column_like=False):
288
+ def __init__(self, number_of_rows=1, number_of_columns=1):
290
289
  self.dict = {}
291
- self.column_like = column_like
292
- if value is missing:
293
- if number_of_rows is missing:
294
- number_of_rows = 1
295
- if number_of_columns is missing:
296
- number_of_columns = 1
297
- self.number_of_rows = number_of_rows
298
- self.number_of_columns = number_of_columns
290
+ self.number_of_rows = number_of_rows
291
+ self.number_of_columns = number_of_columns
299
292
 
300
- else:
301
- if isinstance(value, block):
302
- value = value.value
303
- self.value = value
304
- if number_of_rows is not missing:
305
- self.number_of_rows = number_of_rows
306
- if number_of_columns is not missing:
307
- self.number_of_columns = number_of_columns
293
+ @classmethod
294
+ def from_value(cls, value, column_like=False):
295
+ """
296
+ makes a block from a given value
297
+
298
+ Parameters
299
+ ----------
300
+ value : scaler, list of scalars, list of lists of scalars or block
301
+ value to be used in block, possibly expanded to a list of lists of scalars
302
+
303
+ column_like : boolean
304
+ if value is a list of scalars, values is interpreted as a column if True, as a row otherwise
305
+
306
+ number_of_rows : int
307
+ if given, expand or shrink to the given number of rows
308
+
309
+ number_of_columns : int
310
+ if given, expand or shrink to the given number of columns
311
+
312
+ Returns
313
+ -------
314
+ block : block
315
+ """
316
+ if isinstance(value, block):
317
+ value = value.value
318
+ if not isinstance(value, list):
319
+ value = [[value]]
320
+ if not isinstance(value[0], list):
321
+ if column_like:
322
+ value = [[item] for item in value]
323
+ else:
324
+ value = [value]
325
+ bl = cls(len(value), 1)
326
+
327
+ for row, row_contents in enumerate(value, 1):
328
+ for column, item in enumerate(row_contents, 1):
329
+ if item and not (isinstance(item, float) and math.isnan(item)):
330
+ bl.dict[row, column] = item
331
+ bl._number_of_columns = max(bl.number_of_columns, column)
332
+ return bl
308
333
 
309
334
  @classmethod
310
- def from_xlrd_sheet(cls, sheet, number_of_rows=missing, number_of_columns=missing):
335
+ def from_range(cls, rng):
336
+ """
337
+ makes a block from a given range
338
+
339
+ Parameters
340
+ ----------
341
+ rng : xlwings.Range
342
+ range to be used be used in block
343
+
344
+ number_of_rows : int
345
+ if given, expand or shrink to the given number of rows
346
+
347
+ number_of_columns : int
348
+ if given, expand or shrink to the given number of columns
349
+
350
+ Returns
351
+ -------
352
+ block : block
353
+ """
354
+ number_of_rows, number_of_columns = rng.shape
355
+ bl = cls.from_value(rng.value, column_like=(number_of_columns == 1))
356
+ return bl
357
+
358
+ @classmethod
359
+ def from_xlrd_sheet(cls, sheet):
360
+ """
361
+ makes a block from a xlrd sheet
362
+
363
+ Parameters
364
+ ----------
365
+ sheet : xlrd sheet
366
+ sheet to be used be used in block
367
+
368
+ number_of_rows : int
369
+ if given, expand or shrink to the given number of rows
370
+
371
+ number_of_columns : int
372
+ if given, expand or shrink to the given number of columns
373
+
374
+ Returns
375
+ -------
376
+ block : block
377
+ """
311
378
  v = [sheet.row_values(row_idx)[0 : sheet.ncols] for row_idx in range(0, sheet.nrows)]
312
- return cls(v, number_of_rows=number_of_rows, number_of_columns=number_of_columns)
379
+ return cls.from_value(v)
313
380
 
314
381
  @classmethod
315
- def from_openpyxl_sheet(cls, sheet, number_of_rows=missing, number_of_columns=missing):
382
+ def from_openpyxl_sheet(cls, sheet):
316
383
  v = [[cell.value for cell in row] for row in sheet.iter_rows()]
317
- return cls(v, number_of_rows=number_of_rows, number_of_columns=number_of_columns)
384
+ return cls.from_value(v)
318
385
 
319
386
  @classmethod
320
- def from_file(cls, filename, number_of_rows=missing, number_of_columns=missing):
387
+ def from_file(cls, filename):
388
+ """
389
+ makes a block from a file
390
+
391
+ Parameters
392
+ ----------
393
+ filename : str
394
+ file to be used be used in block
395
+
396
+ number_of_rows : int
397
+ if given, expand or shrink to the given number of rows
398
+
399
+ number_of_columns : int
400
+ if given, expand or shrink to the given number of columns
401
+
402
+ Returns
403
+ -------
404
+ block : block
405
+ """
321
406
  with open(filename, "r") as f:
322
407
  v = [[line if line else missing] for line in f.read().splitlines()]
323
- return cls(v, number_of_rows=number_of_rows, number_of_columns=number_of_columns)
408
+ return cls.from_value(v)
324
409
 
325
410
  @classmethod
326
- def from_dataframe(cls, df, number_of_rows=missing, number_of_columns=missing):
411
+ def from_dataframe(cls, df):
412
+ """
413
+ makes a block from a given dataframe
414
+
415
+ Parameters
416
+ ----------
417
+ df : pandas dataframe
418
+ dataframe to be used be used in block
419
+
420
+ number_of_rows : int
421
+ if given, expand or shrink to the given number of rows
422
+
423
+ number_of_columns : int
424
+ if given, expand or shrink to the given number of columns
425
+
426
+ Returns
427
+ -------
428
+ block : block
429
+ """
327
430
  v = df.values.tolist()
328
- return cls(v, number_of_rows=number_of_rows, number_of_columns=number_of_columns)
431
+ return cls.from_value(v)
329
432
 
330
433
  def to_openpyxl_sheet(self, sheet):
434
+ """
435
+ makes a block from a given openpyxl sheet
436
+
437
+ Parameters
438
+ ----------
439
+ sheet: openpyxl sheet
440
+ sheet to be used be used in block
441
+
442
+ number_of_rows : int
443
+ if given, expand or shrink to the given number of rows
444
+
445
+ number_of_columns : int
446
+ if given, expand or shrink to the given number of columns
447
+
448
+ Returns
449
+ -------
450
+ block : block
451
+ """
331
452
  for row in self.value:
332
453
  sheet.append(row)
333
454
 
334
- @property
335
- def value(self):
336
- return [[self.dict.get((row, column)) for column in range(1, self.number_of_columns + 1)] for row in range(1, self.number_of_rows + 1)]
455
+ def reshape(self, number_of_rows=missing, number_of_columns=missing):
456
+ """
457
+ makes a new block with given dimensions
337
458
 
338
- @value.setter
339
- def value(self, value):
340
- if not isinstance(value, list):
341
- value = [[value]]
342
- if not isinstance(value[0], list):
343
- if self.column_like:
344
- value = [[item] for item in value]
345
- else:
346
- value = [value]
459
+ Parameters
460
+ ----------
461
+ number_of_rows : int
462
+ if given, expand or shrink to the given number of rows
347
463
 
348
- self.number_of_rows = len(value)
349
- self._number_of_columns = 0
464
+ number_of_columns : int
465
+ if given, expand or shrink to the given number of columns
350
466
 
351
- for row, row_contents in enumerate(value, 1):
352
- for column, item in enumerate(row_contents, 1):
353
- if item and not (isinstance(item, float) and math.isnan(item)):
354
- self.dict[row, column] = item
355
- self._number_of_columns = max(self.number_of_columns, column)
467
+ Returns
468
+ -------
469
+ block : block
470
+ """
471
+ if number_of_rows is missing:
472
+ number_of_rows = self.number_of_rows
473
+ if number_of_columns is missing:
474
+ number_of_columns = self.number_of_columns
475
+ bl = block(number_of_rows=number_of_rows, number_of_columns=number_of_columns)
476
+ for (row, column), value in self.dict.items():
477
+ if row <= number_of_columns and column <= number_of_columns:
478
+ bl.dict[row, column] = value
479
+ return bl
480
+
481
+ @property
482
+ def value(self):
483
+ return [[self.dict.get((row, column)) for column in range(1, self.number_of_columns + 1)] for row in range(1, self.number_of_rows + 1)]
356
484
 
357
485
  def __setitem__(self, row_column, value):
358
486
  row, column = row_column
@@ -377,7 +505,7 @@ class block:
377
505
  minimized block : block
378
506
  uses highest_used_row_number and highest_used_column_number to minimize the block
379
507
  """
380
- return block(self, number_of_rows=self.highest_used_row_number, number_of_columns=self.highest_used_column_number)
508
+ return self.reshape(number_of_rows=self.highest_used_row_number, number_of_columns=self.highest_used_column_number)
381
509
 
382
510
  @property
383
511
  def number_of_rows(self):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: xlwings_utils
3
- Version: 25.0.6.post4
3
+ Version: 25.0.7
4
4
  Summary: xlwings_utils
5
5
  Author-email: Ruud van der Ham <rt.van.der.ham@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/salabim/xlwings_utils
@@ -87,14 +87,20 @@ xwu.write_dropbox('/downloads/file1.gif')
87
87
  The module contains a useful 2-dimensional data structure: *block*.
88
88
  This can be useful for manipulating a range without accessing it directly, which is expensive in terms of memory and execution time.
89
89
  The advantage over an ordinary list of lists is that a block is index one-based, in line with range and addressing is done with a row, column tuple.
90
- So, `my_block(lol)[row, col]` is roughly equivalent to `lol[row-1][col-1]`
90
+ So, `my_block[row, col]` is roughly equivalent to `lol[row-1][col-1]`
91
91
 
92
- A block stores the values internally as a dictionary and will only convert these to a list of lists when using `block.value` or `block.value_keep`.
92
+ A block stores the values internally as a dictionary and will only convert these to a list of lists when using `block.value`.
93
93
 
94
- Converting the value of a range (usually a list of lists, but can also be a list or scalar) to a block can be done with
94
+ Converting of a range to a block can be done like
95
95
 
96
96
  ```
97
- my_block = xwu.block.from_value(range.value)
97
+ rng = book.sheets.active.range((5,7),(8,100))
98
+ my_block = xwu.block.from_range(rng
99
+ ```
100
+
101
+ A value of a range (list of lists, list of scalars or scalar can be converted to a block with
102
+ ```
103
+ my_block = xwu.block.from_value(rng.value)
98
104
  ```
99
105
  The dimensions (number of rows and number of columns) are automatically set.
100
106
 
@@ -115,9 +121,10 @@ block = xwu.block(number_of_rows, number_columns)
115
121
  The dimensions can be queried or redefined with `block.number_of_rows` and
116
122
  `block.number_of_columns`.
117
123
 
118
- To assign a block to range, use
124
+ It is also possible to get a copy of a block with different dimensions:
125
+
119
126
  ```
120
- range.value = block.value
127
+ bl = my.block.reshape(number_of_rows=2, number_of_columns=10)
121
128
  ```
122
129
 
123
130
  The property `block.highest_used_row_number` returns the row number of the highest non-None cell.
@@ -152,7 +159,7 @@ Of course, we could access the various input fields with absolute ranges, but if
152
159
  If we read the project sheet (partly) into a block, lookup methods are available to access *fields* easily and future-proof:
153
160
 
154
161
  ```
155
- bl = xwu.block.from_value(sheet.range((0,0),(100,10)).value)
162
+ bl = xwu.block.from_range(sheet.range(1,1),(100,10)))
156
163
  ```
157
164
 
158
165
  Let's see how this works with the above sheet. The corresponding block (bl) looks like
@@ -171,7 +178,8 @@ Let's see how this works with the above sheet. The corresponding block (bl) look
171
178
  9 |
172
179
  ```
173
180
  Now we can do
174
- ```project = bl.lookup("Project")
181
+ ```
182
+ project = bl.lookup("Project")
175
183
  project = bl.lookup("Project")
176
184
  start_date = bl.lookup("Start date")
177
185
  end_date = bl.lookup("End date")
@@ -194,11 +202,11 @@ We then read the following rows (using hlookups) and access the required values.
194
202
 
195
203
  ### Filling a block from other sources
196
204
 
197
- The advantage of using a block instead of accessing these sources is that they are one-based, just like in Excel.
205
+ The advantage of using a block instead of accessing these sources directly is that they are one-based, just like in Excel.
198
206
 
199
207
  It is possible to make a block from an xlrd worksheet with `block.from_xlrd_sheet`.
200
208
 
201
- It is possible to create a block from a Pandas DataFrame using `block.from_dataframe`. Ensure that, if the dataframe is created by reading from an Excel sheet, headers=None is specified, e.g., `df = pd.read_excel(filename, header=None)`.
209
+ It is possible to create a block from a panda dataFrame using `block.from_dataframe`. Ensure that, if the dataframe is created by reading from an Excel sheet, headers=None is specified, e.g., `df = pd.read_excel(filename, header=None)`.
202
210
 
203
211
  It is possible to make a block from an openpyxl worksheet with `block.from_openpyxl_sheet`.
204
212
 
@@ -293,7 +301,7 @@ Just add the .bas file to a worksheet and call like
293
301
  Sub MacroToExecute()
294
302
  DecodeFile(Me, 10, 1)
295
303
  ```
296
-
304
+
297
305
  In this example, the file *film1.mp4* will be downloaded into the current directory.
298
306
 
299
307
  The module xlwings_utils also contains code to encode a local file to a sheet:
@@ -0,0 +1,6 @@
1
+ xlwings_utils/__init__.py,sha256=FdaRztevSu5akGL7KBUBRzqwLMRTdvVUuS2Kfp2f1Uc,68
2
+ xlwings_utils/xlwings_utils.py,sha256=e8Lo40ceG0kSzSuytOpIT3cvJ_bhZRxLC2x69EE6k9Y,28725
3
+ xlwings_utils-25.0.7.dist-info/METADATA,sha256=NVLthhuk58Inh4nNVC9Bvue1VEUXuRUYdjJYKlhEqyA,12418
4
+ xlwings_utils-25.0.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
5
+ xlwings_utils-25.0.7.dist-info/top_level.txt,sha256=kf5SEv0gZiRObPhUoYcc1O_iX_wwTOPeUIYvzyYeAM4,14
6
+ xlwings_utils-25.0.7.dist-info/RECORD,,
@@ -1,6 +0,0 @@
1
- xlwings_utils/__init__.py,sha256=FdaRztevSu5akGL7KBUBRzqwLMRTdvVUuS2Kfp2f1Uc,68
2
- xlwings_utils/xlwings_utils.py,sha256=znZtMTebQuTZ4ZvLITbfDlZCdzba7Avlz9RCLXq5LYk,25788
3
- xlwings_utils-25.0.6.post4.dist-info/METADATA,sha256=O8dVqUWel4m__6PgnkWLR_08whGUUJGRuuy77FxfxRM,12255
4
- xlwings_utils-25.0.6.post4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
5
- xlwings_utils-25.0.6.post4.dist-info/top_level.txt,sha256=kf5SEv0gZiRObPhUoYcc1O_iX_wwTOPeUIYvzyYeAM4,14
6
- xlwings_utils-25.0.6.post4.dist-info/RECORD,,