xlwings-utils 0.0.7__tar.gz → 0.0.7.post1__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.

Potentially problematic release.


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

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: xlwings_utils
3
- Version: 0.0.7
3
+ Version: 0.0.7.post1
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
@@ -16,16 +16,20 @@ Requires-Dist: ssl
16
16
 
17
17
  ## Introduction
18
18
 
19
- This module provides some useful functions to be used in xlwings lite.
19
+ This module provides some useful functions to be used in xlwings (lite).
20
20
 
21
21
  ## Installation
22
22
 
23
- Just add xlwings-utils to the *requirement.txt* tab. It might be required to add ssl.
23
+ Just add xlwings-utils to the *requirements.txt* tab.
24
24
 
25
25
  In the script, add
26
26
 
27
27
  ```ìmport xlwings_utils as xwu```
28
28
 
29
+ > [!NOTE]
30
+ >
31
+ > The GitHub repository can be found on https://github.com/salabim/xlwings_utils .
32
+
29
33
  ## Dropbox support
30
34
 
31
35
  The xlwings lite system does not provide access to the local file system. With this module, files can be copied between Dropbox and the local pyodide file system, making it possible to indirectly use the local file system.
@@ -95,10 +99,26 @@ To assign a block to range, use
95
99
  range.value = block.value
96
100
  ```
97
101
 
98
- The property `block.highest`_used_row_number returns the
102
+ The property `block.highest_used_row_number` returns the row number of the highest non-None cell.
103
+
104
+ The property `block.highest_used_column_number` returns the column_number of the highest non-None cell.
99
105
 
100
106
  The method `block.minimized()` returns a block that has the dimensions of (highest_used_row_number, highest_used_column_number).
101
107
 
108
+ Particularly if we process an unknown number of lines, we can do something like:
109
+
110
+ ```
111
+ this_block = xwu.block(number_of_rows=10000, number_of_columns=2)
112
+ for row in range(1, 10001):
113
+ this_block[row,1]= ...
114
+ this_block[row,2]= ...
115
+ if ...: # end condition
116
+ break
117
+ sheet.range(10,1).value = this_block.minimized().value
118
+ ```
119
+
120
+ In this case, only the really processed rows are copied to the sheet.
121
+
102
122
  ## Capture stdout support
103
123
 
104
124
  The module has support for capturing stdout and -later- using showing the captured output on a sheet.
@@ -117,13 +137,17 @@ sheet.range(4,5).value = xwu.captured_stdout_as_value()
117
137
 
118
138
  Clearing the captured stdout buffer can be done with `xwu.clear_captured_std_out`.
119
139
 
120
- Normally, stdout will be also sent to the xlwings lite UI panel. This can be suppressed with
140
+ Normally, stdout will also be sent to the xlwings lite UI panel. This can be suppressed with
121
141
 
122
142
  ```
123
143
  with xwu.capture_stdout(include_print=False):
124
144
  ...
125
145
  ```
126
146
 
147
+ ## Contact info
148
+
149
+ You can contact Ruud van der Ham, the core developer, via ruud@salabim.org .
150
+
127
151
  ## Badges
128
152
 
129
153
  ![PyPI](https://img.shields.io/pypi/v/xlwings-utils) ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/xlwings-utils) ![PyPI - Implementation](https://img.shields.io/pypi/implementation/xlwings-utils)
@@ -1,132 +1,142 @@
1
- Metadata-Version: 2.4
2
- Name: xlwings_utils
3
- Version: 0.0.7
4
- Summary: xlwings_utils
5
- Author-email: Ruud van der Ham <rt.van.der.ham@gmail.com>
6
- Project-URL: Homepage, https://github.com/salabim/xlwings_utils
7
- Project-URL: Repository, https://github.com/salabim/xlwings_utils
8
- Classifier: Development Status :: 5 - Production/Stable
9
- Classifier: Programming Language :: Python :: 3 :: Only
10
- Requires-Python: >=3.9
11
- Description-Content-Type: text/markdown
12
- Requires-Dist: dropbox
13
- Requires-Dist: ssl
14
-
15
- <img src="https://www.salabim.org/xlwings_utils_logo2.png">
16
-
17
- ## Introduction
18
-
19
- This module provides some useful functions to be used in xlwings lite.
20
-
21
- ## Installation
22
-
23
- Just add xlwings-utils to the *requirement.txt* tab. It might be required to add ssl.
24
-
25
- In the script, add
26
-
27
- ```ìmport xlwings_utils as xwu```
28
-
29
- ## Dropbox support
30
-
31
- The xlwings lite system does not provide access to the local file system. With this module, files can be copied between Dropbox and the local pyodide file system, making it possible to indirectly use the local file system.
32
-
33
- It is only possible, as of now, to use full-access Dropbox apps.
34
-
35
- The easiest way to use the Dropbox functionality is to add the credentials to the environment variables. Add REFRESH_TOKEN, APP_KEY and APP_SECRET with their corresponding values to the environment variables.
36
-
37
- Then, it is possible to list all files in a specified folder with the function `list_dropbox`.
38
- It is also possible to get the folders and to access all underlying folders.
39
-
40
- The function `read_dropbox` can be used to read a Dropbox file's contents (bytes).
41
-
42
- The function `write_dropbox` can be used to write contents (bytes) to a Dropbox file.
43
-
44
- The functions `list_local`, `read_local` and `write_local` offer similar functionality for the local file system (on pyodide).
45
-
46
- So, a way to access a file on the system's drive (mapped to Dropbox) as a local file is:
47
-
48
- ```
49
- contents = xlwings_utils.read_dropbox('/downloads/file1.xls')
50
- xlwings_utils.write_local('file1.xlsx')
51
- df = pandas.read_excel"file1.xlsx")
52
- ...
53
- ```
54
- And the other direction:
55
- ```
56
- contents = xlwings_utils.read_local('file1.gif')
57
- xlwings_utils.write_dropbox('/downloads/file1.gif')
58
- ```
59
-
60
- ## Block support
61
-
62
- The module contains a useful 2-dimensional data structure: *block*.
63
- This can be useful to manipulate a range without accessing the range directly, which is expensive in terms of memory and execution time.
64
- 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.
65
- So, `my_block(lol)[row, col]` is roughly equivalent to `lol[row-1][col-1]`
66
-
67
- A block stores the values internally as a dictionary and will only convert these to a list of lists when using `block.value`.
68
-
69
- 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
70
-
71
- ```
72
- my_block = xwu.block.from_value(range.value)
73
- ```
74
- The dimensions (number of rows and number of columns) are automatically set.
75
-
76
- Setting of an individual item (one-based, like range) can be done like
77
- ```
78
- my_block[row, column] = x
79
- ```
80
- And, likewise, reading an individual item can be done like
81
- ```
82
- x = my_block[row, column]
83
- ```
84
- It is not allowed t,o read or write outside the block dimensions.
85
-
86
- It is also possible to define an empty block, like
87
- ```
88
- block = xlwings_utils.block(number_of_rows, number_columns)
89
- ```
90
- The dimensions can be queried or redefined with `block.number_of_rows` and
91
- `block.number_of_columns`.
92
-
93
- To assign a block to range, use
94
- ```
95
- range.value = block.value
96
- ```
97
-
98
- The property `block.highest`_used_row_number returns the
99
-
100
- The method `block.minimized()` returns a block that has the dimensions of (highest_used_row_number, highest_used_column_number).
101
-
102
- ## Capture stdout support
103
-
104
- The module has support for capturing stdout and -later- using showing the captured output on a sheet.
105
-
106
- To do that:
107
-
108
- ```makes it possible to capture stdout writes, which
109
- with xwu.capture_stdout():
110
- ...
111
- ```
112
- and then the captured output can be copied to the screen, like
113
-
114
- ```can then be copied to a worksheet in a later stage.
115
- sheet.range(4,5).value = xwu.captured_stdout_as_value()
116
- ```
117
-
118
- Clearing the captured stdout buffer can be done with `xwu.clear_captured_std_out`.
119
-
120
- Normally, stdout will be also sent to the xlwings lite UI panel. This can be suppressed with
121
-
122
- ```
123
- with xwu.capture_stdout(include_print=False):
124
- ...
125
- ```
126
-
127
- ## Badges
128
-
129
- ![PyPI](https://img.shields.io/pypi/v/xlwings-utils) ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/xlwings-utils) ![PyPI - Implementation](https://img.shields.io/pypi/implementation/xlwings-utils)
130
- ![PyPI - License](https://img.shields.io/pypi/l/xlwings-utils) ![ruff](https://img.shields.io/badge/style-ruff-41B5BE?style=flat)
131
- ![GitHub last commit](https://img.shields.io/github/last-commit/salabim/peek)
132
-
1
+ <img src="https://www.salabim.org/xlwings_utils_logo2.png">
2
+
3
+ ## Introduction
4
+
5
+ This module provides some useful functions to be used in xlwings (lite).
6
+
7
+ ## Installation
8
+
9
+ Just add xlwings-utils to the *requirements.txt* tab.
10
+
11
+ In the script, add
12
+
13
+ ```ìmport xlwings_utils as xwu```
14
+
15
+ > [!NOTE]
16
+ >
17
+ > The GitHub repository can be found on https://github.com/salabim/xlwings_utils .
18
+
19
+ ## Dropbox support
20
+
21
+ The xlwings lite system does not provide access to the local file system. With this module, files can be copied between Dropbox and the local pyodide file system, making it possible to indirectly use the local file system.
22
+
23
+ It is only possible, as of now, to use full-access Dropbox apps.
24
+
25
+ The easiest way to use the Dropbox functionality is to add the credentials to the environment variables. Add REFRESH_TOKEN, APP_KEY and APP_SECRET with their corresponding values to the environment variables.
26
+
27
+ Then, it is possible to list all files in a specified folder with the function `list_dropbox`.
28
+ It is also possible to get the folders and to access all underlying folders.
29
+
30
+ The function `read_dropbox` can be used to read a Dropbox file's contents (bytes).
31
+
32
+ The function `write_dropbox` can be used to write contents (bytes) to a Dropbox file.
33
+
34
+ The functions `list_local`, `read_local` and `write_local` offer similar functionality for the local file system (on pyodide).
35
+
36
+ So, a way to access a file on the system's drive (mapped to Dropbox) as a local file is:
37
+
38
+ ```
39
+ contents = xlwings_utils.read_dropbox('/downloads/file1.xls')
40
+ xlwings_utils.write_local('file1.xlsx')
41
+ df = pandas.read_excel"file1.xlsx")
42
+ ...
43
+ ```
44
+ And the other direction:
45
+ ```
46
+ contents = xlwings_utils.read_local('file1.gif')
47
+ xlwings_utils.write_dropbox('/downloads/file1.gif')
48
+ ```
49
+
50
+ ## Block support
51
+
52
+ The module contains a useful 2-dimensional data structure: *block*.
53
+ This can be useful to manipulate a range without accessing the range directly, which is expensive in terms of memory and execution time.
54
+ 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.
55
+ So, `my_block(lol)[row, col]` is roughly equivalent to `lol[row-1][col-1]`
56
+
57
+ A block stores the values internally as a dictionary and will only convert these to a list of lists when using `block.value`.
58
+
59
+ 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
60
+
61
+ ```
62
+ my_block = xwu.block.from_value(range.value)
63
+ ```
64
+ The dimensions (number of rows and number of columns) are automatically set.
65
+
66
+ Setting of an individual item (one-based, like range) can be done like
67
+ ```
68
+ my_block[row, column] = x
69
+ ```
70
+ And, likewise, reading an individual item can be done like
71
+ ```
72
+ x = my_block[row, column]
73
+ ```
74
+ It is not allowed t,o read or write outside the block dimensions.
75
+
76
+ It is also possible to define an empty block, like
77
+ ```
78
+ block = xlwings_utils.block(number_of_rows, number_columns)
79
+ ```
80
+ The dimensions can be queried or redefined with `block.number_of_rows` and
81
+ `block.number_of_columns`.
82
+
83
+ To assign a block to range, use
84
+ ```
85
+ range.value = block.value
86
+ ```
87
+
88
+ The property `block.highest_used_row_number` returns the row number of the highest non-None cell.
89
+
90
+ The property `block.highest_used_column_number` returns the column_number of the highest non-None cell.
91
+
92
+ The method `block.minimized()` returns a block that has the dimensions of (highest_used_row_number, highest_used_column_number).
93
+
94
+ Particularly if we process an unknown number of lines, we can do something like:
95
+
96
+ ```
97
+ this_block = xwu.block(number_of_rows=10000, number_of_columns=2)
98
+ for row in range(1, 10001):
99
+ this_block[row,1]= ...
100
+ this_block[row,2]= ...
101
+ if ...: # end condition
102
+ break
103
+ sheet.range(10,1).value = this_block.minimized().value
104
+ ```
105
+
106
+ In this case, only the really processed rows are copied to the sheet.
107
+
108
+ ## Capture stdout support
109
+
110
+ The module has support for capturing stdout and -later- using showing the captured output on a sheet.
111
+
112
+ To do that:
113
+
114
+ ```makes it possible to capture stdout writes, which
115
+ with xwu.capture_stdout():
116
+ ...
117
+ ```
118
+ and then the captured output can be copied to the screen, like
119
+
120
+ ```can then be copied to a worksheet in a later stage.
121
+ sheet.range(4,5).value = xwu.captured_stdout_as_value()
122
+ ```
123
+
124
+ Clearing the captured stdout buffer can be done with `xwu.clear_captured_std_out`.
125
+
126
+ Normally, stdout will also be sent to the xlwings lite UI panel. This can be suppressed with
127
+
128
+ ```
129
+ with xwu.capture_stdout(include_print=False):
130
+ ...
131
+ ```
132
+
133
+ ## Contact info
134
+
135
+ You can contact Ruud van der Ham, the core developer, via ruud@salabim.org .
136
+
137
+ ## Badges
138
+
139
+ ![PyPI](https://img.shields.io/pypi/v/xlwings-utils) ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/xlwings-utils) ![PyPI - Implementation](https://img.shields.io/pypi/implementation/xlwings-utils)
140
+ ![PyPI - License](https://img.shields.io/pypi/l/xlwings-utils) ![ruff](https://img.shields.io/badge/style-ruff-41B5BE?style=flat)
141
+ ![GitHub last commit](https://img.shields.io/github/last-commit/salabim/peek)
142
+
@@ -10,7 +10,7 @@ authors = [
10
10
  { name = "Ruud van der Ham", email = "rt.van.der.ham@gmail.com" },
11
11
  ]
12
12
  description = "xlwings_utils"
13
- version = "0.0.7"
13
+ version = "0.0.7.post1"
14
14
  readme = "README.md"
15
15
  requires-python = ">=3.9"
16
16
  dependencies = [
@@ -103,24 +103,34 @@ def test_raise():
103
103
 
104
104
 
105
105
  def test_capture_stdout(capsys):
106
- with xwu.capture_stdout():
107
- print("abc")
108
- print("def")
109
- assert xwu.captured_stdout_as_str() == "abc\ndef\n"
110
- assert xwu.captured_stdout_as_value() == [["abc"], ["def"]]
111
-
106
+ print("abc")
107
+ print("def")
112
108
  out, err = capsys.readouterr()
113
109
  assert out == "abc\ndef\n"
114
-
115
- xwu.clear_captured_stdout()
116
110
  assert xwu.captured_stdout_as_str() == ""
117
- with xwu.capture_stdout(include_print=False):
118
- print("ghi")
119
- print("jkl")
120
- assert xwu.captured_stdout_as_str() == "ghi\njkl\n"
121
- assert xwu.captured_stdout_as_value() == [["ghi"], ["jkl"]]
111
+ assert xwu.captured_stdout_as_value() == []
112
+
113
+ xwu.capture_stdout(do_capture=True)
114
+ print("abc")
115
+ print("def")
122
116
  out, err = capsys.readouterr()
123
- assert out == ""
117
+ assert out == "abc\ndef\n"
118
+
119
+ assert xwu.captured_stdout_as_str(clear=False) == "abc\ndef\n"
120
+ assert xwu.captured_stdout_as_value(clear=False) == [["abc"], ["def"]]
121
+
122
+ # out, err = capsys.readouterr()
123
+ # assert out == "abc\ndef\n"
124
+
125
+ # xwu.clear_captured_stdout()
126
+ # assert xwu.captured_stdout_as_str() == ""
127
+ # with xwu.capture_stdout(include_print=False):
128
+ # print("ghi")
129
+ # print("jkl")
130
+ # assert xwu.captured_stdout_as_str() == "ghi\njkl\n"
131
+ # assert xwu.captured_stdout_as_value() == [["ghi"], ["jkl"]]
132
+ # out, err = capsys.readouterr()
133
+ # assert out == ""
124
134
 
125
135
 
126
136
  if __name__ == "__main__":
@@ -13,7 +13,8 @@ from pathlib import Path
13
13
  import os
14
14
  import sys
15
15
 
16
- _captured_stdout = []
16
+ _org_stdout = sys.stdout
17
+
17
18
  dbx = None
18
19
  Pythonista = sys.platform == "ios"
19
20
 
@@ -217,7 +218,7 @@ def list_local(path, recursive=False, show_files=True, show_folders=False):
217
218
  show_folders : bool
218
219
  if True, show folder entries
219
220
  if False (default), do not show folder entries
220
-
221
+
221
222
  Returns
222
223
  -------
223
224
  files, relative to path : list
@@ -268,33 +269,32 @@ class block:
268
269
  block
269
270
  """
270
271
 
271
- def __init__(self, value=None, *, number_of_rows=None, number_of_columns=None,column_like=False):
272
+ def __init__(self, value=None, *, number_of_rows=None, number_of_columns=None, column_like=False):
272
273
  self.dict = {}
273
- self.column_like=column_like
274
+ self.column_like = column_like
274
275
  if value is None:
275
276
  if number_of_rows is None:
276
- number_of_rows=1
277
+ number_of_rows = 1
277
278
  if number_of_columns is None:
278
- number_of_columns=1
279
- self.number_of_rows=number_of_rows
280
- self.number_of_columns=number_of_columns
281
-
279
+ number_of_columns = 1
280
+ self.number_of_rows = number_of_rows
281
+ self.number_of_columns = number_of_columns
282
+
282
283
  else:
283
- if isinstance(value,block):
284
- value=value.value
285
- self.value=value
284
+ if isinstance(value, block):
285
+ value = value.value
286
+ self.value = value
286
287
  if number_of_rows is not None:
287
- self.number_of_rows=number_of_rows
288
+ self.number_of_rows = number_of_rows
288
289
  if number_of_columns is not None:
289
- self.number_of_columns=number_of_columns
290
+ self.number_of_columns = number_of_columns
290
291
 
291
-
292
292
  @property
293
293
  def value(self):
294
294
  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)]
295
-
295
+
296
296
  @value.setter
297
- def value(self,value):
297
+ def value(self, value):
298
298
  if not isinstance(value, list):
299
299
  value = [[value]]
300
300
  if not isinstance(value[0], list):
@@ -303,7 +303,6 @@ class block:
303
303
  else:
304
304
  value = [value]
305
305
 
306
-
307
306
  self.number_of_rows = len(value)
308
307
  self._number_of_columns = 0
309
308
 
@@ -311,8 +310,7 @@ class block:
311
310
  for column, item in enumerate(row_contents, 1):
312
311
  if item is not None:
313
312
  self.dict[row, column] = item
314
- self._number_of_columns = max(self.number_of_columns, column)
315
-
313
+ self._number_of_columns = max(self.number_of_columns, column)
316
314
 
317
315
  def __setitem__(self, row_column, value):
318
316
  row, column = row_column
@@ -329,7 +327,7 @@ class block:
329
327
  if column < 1 or column > self.number_of_columns:
330
328
  raise IndexError(f"column must be between 1 and {self.number_of_columns} not {column}")
331
329
  return self.dict.get((row, column))
332
-
330
+
333
331
  def minimized(self):
334
332
  return block(self, number_of_rows=self.highest_used_row_number, number_of_columns=self.highest_used_column_number)
335
333
 
@@ -358,7 +356,6 @@ class block:
358
356
  for row, column in list(self.dict):
359
357
  if column > self._number_of_columns:
360
358
  del self.dict[row, column]
361
-
362
359
 
363
360
  @property
364
361
  def highest_used_row_number(self):
@@ -378,14 +375,22 @@ class block:
378
375
  return f"block({self.value})"
379
376
 
380
377
 
381
- def clear_captured_stdout():
378
+ def clear_captured_stdout(clear=True):
382
379
  """
383
380
  empties the captured stdout
381
+
382
+ Parameters
383
+ ----------
384
+ clear : bool
385
+ if True (default), the capture buffer is emptied
386
+
387
+ if False: no action
384
388
  """
385
- _captured_stdout.clear()
389
+ if clear:
390
+ _buffer.clear()
386
391
 
387
392
 
388
- def captured_stdout_as_str():
393
+ def captured_stdout_as_str(clear=True):
389
394
  """
390
395
  returns the captured stdout as a string
391
396
 
@@ -394,64 +399,84 @@ def captured_stdout_as_str():
394
399
  captured stdout : list
395
400
  each line is an element of the list
396
401
  """
397
-
398
- return "".join(_captured_stdout)
402
+ result = "".join(_buffer)
403
+ clear_captured_stdout(clear)
404
+ return result
399
405
 
400
406
 
401
- def captured_stdout_as_value():
407
+ def captured_stdout_as_value(clear=True):
402
408
  """
403
409
  returns the captured stdout as a list of lists
404
410
 
405
411
  Returns
406
412
  -------
407
- captured stdout : list
413
+ captured stdout : list of lists
408
414
  each line is an element of the list
409
415
 
410
416
  Note
411
417
  ----
412
418
  This can be used directly to fill a xlwings range
413
419
  """
414
- return [[line] for line in captured_stdout_as_str().splitlines()]
420
+ return [[line] for line in captured_stdout_as_str(clear).splitlines()]
421
+
422
+
423
+ class handle_capture_stdout:
424
+ def __init__(self):
425
+ pass
426
+
427
+ def isatty(self):
428
+ return False
415
429
 
430
+ def write(self, data):
431
+ if _do_capture:
432
+ _buffer.append(data)
433
+ if _do_print:
434
+ _org_stdout.write(data)
416
435
 
417
- class capture_stdout:
436
+ def flush(self):
437
+ if _do_print:
438
+ _org_stdout.flush()
439
+ if _do_capture:
440
+ _buffer.append("\n")
441
+
442
+
443
+ def reset():
444
+ global _buffer
445
+ global _do_print
446
+ global _do_capture
447
+ _buffer = []
448
+ _do_print = True
449
+ _do_capture = False
450
+
451
+ sys.stdout = handle_capture_stdout()
452
+ reset()
453
+
454
+ def capture_stdout(do_print=True, do_capture=True, clear=True):
455
+ global _do_print
456
+ global _do_capture
418
457
  """
419
458
  start capture stdout
420
459
 
421
460
  Parameters
422
461
  ----------
423
- include_print : bool
424
- if True (default), the output is also printed out as normal
462
+ do_print : bool
463
+ if True (default), the output is (also) printed out as normal
425
464
 
426
465
  if False, no output is printed
427
466
 
428
- Note
429
- ----
430
- This function is normally used as a context manager, like ::
431
-
432
- with capture_stdout():
433
- ...
434
- """
435
-
436
- def __init__(self, include_print: bool = True):
437
- self.stdout = sys.stdout
438
- self.include_print = include_print
439
-
440
- def __enter__(self):
441
- sys.stdout = self
467
+ do_capture : bool
468
+ if True (default), the output is (also) captured to a buffer
442
469
 
443
- def __exit__(self, exc_type, exc_value, tb):
444
- sys.stdout = self.stdout
470
+ if False, no output is captured
445
471
 
446
- def write(self, data):
447
- _captured_stdout.append(data)
448
- if self.include_print:
449
- self.stdout.write(data)
450
-
451
- def flush(self):
452
- if self.include_print:
453
- self.stdout.flush()
454
- _captured_stdout.append("\n")
472
+ clear : bool
473
+ if True (default), the capture buffer is emptied
474
+ """
475
+ if not (do_print or do_capture):
476
+ raise ValueError("at least one of do_print and do_capture should be True")
477
+ clear_captured_stdout(clear)
478
+ _do_print = do_print
479
+ _do_capture = do_capture
455
480
 
456
481
 
457
482
  if __name__ == "__main__":
@@ -1,118 +1,156 @@
1
- <img src="https://www.salabim.org/xlwings_utils_logo2.png">
2
-
3
- ## Introduction
4
-
5
- This module provides some useful functions to be used in xlwings lite.
6
-
7
- ## Installation
8
-
9
- Just add xlwings-utils to the *requirement.txt* tab. It might be required to add ssl.
10
-
11
- In the script, add
12
-
13
- ```ìmport xlwings_utils as xwu```
14
-
15
- ## Dropbox support
16
-
17
- The xlwings lite system does not provide access to the local file system. With this module, files can be copied between Dropbox and the local pyodide file system, making it possible to indirectly use the local file system.
18
-
19
- It is only possible, as of now, to use full-access Dropbox apps.
20
-
21
- The easiest way to use the Dropbox functionality is to add the credentials to the environment variables. Add REFRESH_TOKEN, APP_KEY and APP_SECRET with their corresponding values to the environment variables.
22
-
23
- Then, it is possible to list all files in a specified folder with the function `list_dropbox`.
24
- It is also possible to get the folders and to access all underlying folders.
25
-
26
- The function `read_dropbox` can be used to read a Dropbox file's contents (bytes).
27
-
28
- The function `write_dropbox` can be used to write contents (bytes) to a Dropbox file.
29
-
30
- The functions `list_local`, `read_local` and `write_local` offer similar functionality for the local file system (on pyodide).
31
-
32
- So, a way to access a file on the system's drive (mapped to Dropbox) as a local file is:
33
-
34
- ```
35
- contents = xlwings_utils.read_dropbox('/downloads/file1.xls')
36
- xlwings_utils.write_local('file1.xlsx')
37
- df = pandas.read_excel"file1.xlsx")
38
- ...
39
- ```
40
- And the other direction:
41
- ```
42
- contents = xlwings_utils.read_local('file1.gif')
43
- xlwings_utils.write_dropbox('/downloads/file1.gif')
44
- ```
45
-
46
- ## Block support
47
-
48
- The module contains a useful 2-dimensional data structure: *block*.
49
- This can be useful to manipulate a range without accessing the range directly, which is expensive in terms of memory and execution time.
50
- 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.
51
- So, `my_block(lol)[row, col]` is roughly equivalent to `lol[row-1][col-1]`
52
-
53
- A block stores the values internally as a dictionary and will only convert these to a list of lists when using `block.value`.
54
-
55
- 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
56
-
57
- ```
58
- my_block = xwu.block.from_value(range.value)
59
- ```
60
- The dimensions (number of rows and number of columns) are automatically set.
61
-
62
- Setting of an individual item (one-based, like range) can be done like
63
- ```
64
- my_block[row, column] = x
65
- ```
66
- And, likewise, reading an individual item can be done like
67
- ```
68
- x = my_block[row, column]
69
- ```
70
- It is not allowed t,o read or write outside the block dimensions.
71
-
72
- It is also possible to define an empty block, like
73
- ```
74
- block = xlwings_utils.block(number_of_rows, number_columns)
75
- ```
76
- The dimensions can be queried or redefined with `block.number_of_rows` and
77
- `block.number_of_columns`.
78
-
79
- To assign a block to range, use
80
- ```
81
- range.value = block.value
82
- ```
83
-
84
- The property `block.highest`_used_row_number returns the
85
-
86
- The method `block.minimized()` returns a block that has the dimensions of (highest_used_row_number, highest_used_column_number).
87
-
88
- ## Capture stdout support
89
-
90
- The module has support for capturing stdout and -later- using showing the captured output on a sheet.
91
-
92
- To do that:
93
-
94
- ```makes it possible to capture stdout writes, which
95
- with xwu.capture_stdout():
96
- ...
97
- ```
98
- and then the captured output can be copied to the screen, like
99
-
100
- ```can then be copied to a worksheet in a later stage.
101
- sheet.range(4,5).value = xwu.captured_stdout_as_value()
102
- ```
103
-
104
- Clearing the captured stdout buffer can be done with `xwu.clear_captured_std_out`.
105
-
106
- Normally, stdout will be also sent to the xlwings lite UI panel. This can be suppressed with
107
-
108
- ```
109
- with xwu.capture_stdout(include_print=False):
110
- ...
111
- ```
112
-
113
- ## Badges
114
-
115
- ![PyPI](https://img.shields.io/pypi/v/xlwings-utils) ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/xlwings-utils) ![PyPI - Implementation](https://img.shields.io/pypi/implementation/xlwings-utils)
116
- ![PyPI - License](https://img.shields.io/pypi/l/xlwings-utils) ![ruff](https://img.shields.io/badge/style-ruff-41B5BE?style=flat)
117
- ![GitHub last commit](https://img.shields.io/github/last-commit/salabim/peek)
118
-
1
+ Metadata-Version: 2.4
2
+ Name: xlwings_utils
3
+ Version: 0.0.7.post1
4
+ Summary: xlwings_utils
5
+ Author-email: Ruud van der Ham <rt.van.der.ham@gmail.com>
6
+ Project-URL: Homepage, https://github.com/salabim/xlwings_utils
7
+ Project-URL: Repository, https://github.com/salabim/xlwings_utils
8
+ Classifier: Development Status :: 5 - Production/Stable
9
+ Classifier: Programming Language :: Python :: 3 :: Only
10
+ Requires-Python: >=3.9
11
+ Description-Content-Type: text/markdown
12
+ Requires-Dist: dropbox
13
+ Requires-Dist: ssl
14
+
15
+ <img src="https://www.salabim.org/xlwings_utils_logo2.png">
16
+
17
+ ## Introduction
18
+
19
+ This module provides some useful functions to be used in xlwings (lite).
20
+
21
+ ## Installation
22
+
23
+ Just add xlwings-utils to the *requirements.txt* tab.
24
+
25
+ In the script, add
26
+
27
+ ```ìmport xlwings_utils as xwu```
28
+
29
+ > [!NOTE]
30
+ >
31
+ > The GitHub repository can be found on https://github.com/salabim/xlwings_utils .
32
+
33
+ ## Dropbox support
34
+
35
+ The xlwings lite system does not provide access to the local file system. With this module, files can be copied between Dropbox and the local pyodide file system, making it possible to indirectly use the local file system.
36
+
37
+ It is only possible, as of now, to use full-access Dropbox apps.
38
+
39
+ The easiest way to use the Dropbox functionality is to add the credentials to the environment variables. Add REFRESH_TOKEN, APP_KEY and APP_SECRET with their corresponding values to the environment variables.
40
+
41
+ Then, it is possible to list all files in a specified folder with the function `list_dropbox`.
42
+ It is also possible to get the folders and to access all underlying folders.
43
+
44
+ The function `read_dropbox` can be used to read a Dropbox file's contents (bytes).
45
+
46
+ The function `write_dropbox` can be used to write contents (bytes) to a Dropbox file.
47
+
48
+ The functions `list_local`, `read_local` and `write_local` offer similar functionality for the local file system (on pyodide).
49
+
50
+ So, a way to access a file on the system's drive (mapped to Dropbox) as a local file is:
51
+
52
+ ```
53
+ contents = xlwings_utils.read_dropbox('/downloads/file1.xls')
54
+ xlwings_utils.write_local('file1.xlsx')
55
+ df = pandas.read_excel"file1.xlsx")
56
+ ...
57
+ ```
58
+ And the other direction:
59
+ ```
60
+ contents = xlwings_utils.read_local('file1.gif')
61
+ xlwings_utils.write_dropbox('/downloads/file1.gif')
62
+ ```
63
+
64
+ ## Block support
65
+
66
+ The module contains a useful 2-dimensional data structure: *block*.
67
+ This can be useful to manipulate a range without accessing the range directly, which is expensive in terms of memory and execution time.
68
+ 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.
69
+ So, `my_block(lol)[row, col]` is roughly equivalent to `lol[row-1][col-1]`
70
+
71
+ A block stores the values internally as a dictionary and will only convert these to a list of lists when using `block.value`.
72
+
73
+ 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
74
+
75
+ ```
76
+ my_block = xwu.block.from_value(range.value)
77
+ ```
78
+ The dimensions (number of rows and number of columns) are automatically set.
79
+
80
+ Setting of an individual item (one-based, like range) can be done like
81
+ ```
82
+ my_block[row, column] = x
83
+ ```
84
+ And, likewise, reading an individual item can be done like
85
+ ```
86
+ x = my_block[row, column]
87
+ ```
88
+ It is not allowed t,o read or write outside the block dimensions.
89
+
90
+ It is also possible to define an empty block, like
91
+ ```
92
+ block = xlwings_utils.block(number_of_rows, number_columns)
93
+ ```
94
+ The dimensions can be queried or redefined with `block.number_of_rows` and
95
+ `block.number_of_columns`.
96
+
97
+ To assign a block to range, use
98
+ ```
99
+ range.value = block.value
100
+ ```
101
+
102
+ The property `block.highest_used_row_number` returns the row number of the highest non-None cell.
103
+
104
+ The property `block.highest_used_column_number` returns the column_number of the highest non-None cell.
105
+
106
+ The method `block.minimized()` returns a block that has the dimensions of (highest_used_row_number, highest_used_column_number).
107
+
108
+ Particularly if we process an unknown number of lines, we can do something like:
109
+
110
+ ```
111
+ this_block = xwu.block(number_of_rows=10000, number_of_columns=2)
112
+ for row in range(1, 10001):
113
+ this_block[row,1]= ...
114
+ this_block[row,2]= ...
115
+ if ...: # end condition
116
+ break
117
+ sheet.range(10,1).value = this_block.minimized().value
118
+ ```
119
+
120
+ In this case, only the really processed rows are copied to the sheet.
121
+
122
+ ## Capture stdout support
123
+
124
+ The module has support for capturing stdout and -later- using showing the captured output on a sheet.
125
+
126
+ To do that:
127
+
128
+ ```makes it possible to capture stdout writes, which
129
+ with xwu.capture_stdout():
130
+ ...
131
+ ```
132
+ and then the captured output can be copied to the screen, like
133
+
134
+ ```can then be copied to a worksheet in a later stage.
135
+ sheet.range(4,5).value = xwu.captured_stdout_as_value()
136
+ ```
137
+
138
+ Clearing the captured stdout buffer can be done with `xwu.clear_captured_std_out`.
139
+
140
+ Normally, stdout will also be sent to the xlwings lite UI panel. This can be suppressed with
141
+
142
+ ```
143
+ with xwu.capture_stdout(include_print=False):
144
+ ...
145
+ ```
146
+
147
+ ## Contact info
148
+
149
+ You can contact Ruud van der Ham, the core developer, via ruud@salabim.org .
150
+
151
+ ## Badges
152
+
153
+ ![PyPI](https://img.shields.io/pypi/v/xlwings-utils) ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/xlwings-utils) ![PyPI - Implementation](https://img.shields.io/pypi/implementation/xlwings-utils)
154
+ ![PyPI - License](https://img.shields.io/pypi/l/xlwings-utils) ![ruff](https://img.shields.io/badge/style-ruff-41B5BE?style=flat)
155
+ ![GitHub last commit](https://img.shields.io/github/last-commit/salabim/peek)
156
+