mirror of
https://github.com/tdulcet/Table-and-Graph-Libs.git
synced 2025-05-06 06:35:26 +08:00
Updated the style and color options to use Enums.
This commit is contained in:
parent
1d6c53c985
commit
73411c18cb
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@ -33,6 +33,8 @@ jobs:
|
|||||||
./graphs
|
./graphs
|
||||||
- name: Cppcheck
|
- name: Cppcheck
|
||||||
run: cppcheck --enable=all .
|
run: cppcheck --enable=all .
|
||||||
|
- name: Clang-Tidy
|
||||||
|
run: clang-tidy -checks='bugprone-*,-bugprone-easily-swappable-parameters,cert-*,clang-analyzer-*,misc-const-correctness,misc-redundant-expression,misc-unused-*,modernize-*,-modernize-use-trailing-return-type,performance-*,portability-*,readability-const-return-type,readability-container-*,readability-duplicate-include,readability-else-after-return,readability-non-const-parameter,readability-redundant-*,readability-simplify-*,readability-string-compare,readability-use-anyofallof' -header-filter='.*' *.cpp -- -Wall -O3 -std=c++17
|
||||||
|
|
||||||
Python:
|
Python:
|
||||||
name: Linux Python
|
name: Linux Python
|
||||||
|
103
README.md
103
README.md
@ -22,9 +22,8 @@ Requires support for C++14. See the [tables.hpp](tables.hpp) file for full usage
|
|||||||
Complete versions of all of the examples below and more can be found in the [tables.cpp](tables.cpp) file.
|
Complete versions of all of the examples below and more can be found in the [tables.cpp](tables.cpp) file.
|
||||||
|
|
||||||
Compile with:
|
Compile with:
|
||||||
|
* GCC: `g++ -std=c++14 -Wall -g -O3 tables.cpp -o tables`
|
||||||
GCC: `g++ -std=c++14 -Wall -g -O3 tables.cpp -o tables`\
|
* Clang: `clang++ -std=c++14 -Wall -g -O3 tables.cpp -o tables`
|
||||||
Clang: `clang++ -std=c++14 -Wall -g -O3 tables.cpp -o tables`
|
|
||||||
|
|
||||||
Run with: `./tables`
|
Run with: `./tables`
|
||||||
|
|
||||||
@ -313,12 +312,12 @@ int main()
|
|||||||
{
|
{
|
||||||
double xmin = -10;
|
double xmin = -10;
|
||||||
double xmax = 10;
|
double xmax = 10;
|
||||||
double xscl = 2;
|
double xstep = 0.5;
|
||||||
|
|
||||||
tables::options aoptions;
|
tables::options aoptions;
|
||||||
aoptions.headerrow = true;
|
aoptions.headerrow = true;
|
||||||
|
|
||||||
tables::function(xmin, xmax, xscl, afunction, aoptions);
|
tables::function(xmin, xmax, xstep, afunction, aoptions);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -335,7 +334,7 @@ int main()
|
|||||||
{
|
{
|
||||||
double xmin = -10;
|
double xmin = -10;
|
||||||
double xmax = 10;
|
double xmax = 10;
|
||||||
double xscl = 2;
|
double xstep = 0.5;
|
||||||
|
|
||||||
function<double(double)> afunction = [](auto x)
|
function<double(double)> afunction = [](auto x)
|
||||||
{ return x + 1; };
|
{ return x + 1; };
|
||||||
@ -343,7 +342,7 @@ int main()
|
|||||||
tables::options aoptions;
|
tables::options aoptions;
|
||||||
aoptions.headerrow = true;
|
aoptions.headerrow = true;
|
||||||
|
|
||||||
tables::function(xmin, xmax, xscl, afunction, aoptions);
|
tables::function(xmin, xmax, xstep, afunction, aoptions);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -375,7 +374,7 @@ int main()
|
|||||||
{
|
{
|
||||||
double xmin = -10;
|
double xmin = -10;
|
||||||
double xmax = 10;
|
double xmax = 10;
|
||||||
double xscl = 2;
|
double xstep = 0.5;
|
||||||
|
|
||||||
size_t numfunctions = 2;
|
size_t numfunctions = 2;
|
||||||
|
|
||||||
@ -385,7 +384,7 @@ int main()
|
|||||||
tables::options aoptions;
|
tables::options aoptions;
|
||||||
aoptions.headerrow = true;
|
aoptions.headerrow = true;
|
||||||
|
|
||||||
tables::functions(xmin, xmax, xscl, numfunctions, functions, aoptions);
|
tables::functions(xmin, xmax, xstep, numfunctions, functions, aoptions);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -403,7 +402,7 @@ int main()
|
|||||||
{
|
{
|
||||||
double xmin = -10;
|
double xmin = -10;
|
||||||
double xmax = 10;
|
double xmax = 10;
|
||||||
double xscl = 2;
|
double xstep = 0.5;
|
||||||
|
|
||||||
size_t numfunctions = 2;
|
size_t numfunctions = 2;
|
||||||
|
|
||||||
@ -416,7 +415,7 @@ int main()
|
|||||||
tables::options aoptions;
|
tables::options aoptions;
|
||||||
aoptions.headerrow = true;
|
aoptions.headerrow = true;
|
||||||
|
|
||||||
tables::functions(xmin, xmax, xscl, numfunctions, functions, aoptions);
|
tables::functions(xmin, xmax, xstep, numfunctions, functions, aoptions);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -460,8 +459,10 @@ Default value: `1`
|
|||||||
Option: `alignment`\
|
Option: `alignment`\
|
||||||
Values:
|
Values:
|
||||||
|
|
||||||
|
* `nullptr`
|
||||||
* `left` (default)
|
* `left` (default)
|
||||||
* `right`
|
* `right`
|
||||||
|
* `internal` (integer and floating-point types only)
|
||||||
|
|
||||||
#### bool to alpha
|
#### bool to alpha
|
||||||
|
|
||||||
@ -480,28 +481,35 @@ The title is word wrapped based on the current width of the terminal, using [thi
|
|||||||
Option: `style`\
|
Option: `style`\
|
||||||
Values:
|
Values:
|
||||||
|
|
||||||
0. ASCII
|
0. `style_ASCII`: ASCII
|
||||||
|
|
||||||

|

|
||||||
1. Basic
|
1. `style_basic`: Basic
|
||||||
|
|
||||||

|

|
||||||
2. Light (default)
|
2. `style_light`: Light (default)
|
||||||
|
|
||||||

|

|
||||||
3. Heavy
|
3. `style_heavy`: Heavy
|
||||||
|
|
||||||

|

|
||||||
4. Double
|
4. `style_double`: Double
|
||||||
|
|
||||||

|

|
||||||
5. Light Dashed
|
5. `style_light_dashed`: Light Dashed
|
||||||
|
|
||||||

|

|
||||||
6. Heavy Dashed
|
6. `style_heavy_dashed`: Heavy Dashed
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
#### Check size
|
||||||
|
|
||||||
|
Option: `check`\
|
||||||
|
Default value: `true`
|
||||||
|
|
||||||
|
Check that the width of the table is not greater then the width of the terminal.
|
||||||
|
|
||||||
### Other C++ Console Tables Libraries
|
### Other C++ Console Tables Libraries
|
||||||
|
|
||||||
* [C++ Text Table](https://github.com/haarcuba/cpp-text-table) (must specify every cell individually in their data structure, limited options, no Unicode support, no header row or column support)
|
* [C++ Text Table](https://github.com/haarcuba/cpp-text-table) (must specify every cell individually in their data structure, limited options, no Unicode support, no header row or column support)
|
||||||
@ -517,8 +525,8 @@ Requires support for C++14. See the [graphs.hpp](graphs.hpp) file for full usage
|
|||||||
Complete versions of all of the examples below and more can be found in the [graphs.cpp](graphs.cpp) file.
|
Complete versions of all of the examples below and more can be found in the [graphs.cpp](graphs.cpp) file.
|
||||||
|
|
||||||
Compile with:
|
Compile with:
|
||||||
GCC: `g++ -std=c++14 -Wall -g -O3 graphs.cpp -o graphs`\
|
* GCC: `g++ -std=c++14 -Wall -g -O3 graphs.cpp -o graphs`
|
||||||
Clang: `clang++ -std=c++14 -Wall -g -O3 graphs.cpp -o graphs`
|
* Clang: `clang++ -std=c++14 -Wall -g -O3 graphs.cpp -o graphs`
|
||||||
|
|
||||||
Run with: `./graphs`
|
Run with: `./graphs`
|
||||||
|
|
||||||
@ -756,25 +764,25 @@ The title is word wrapped based on the current width of the terminal, using [thi
|
|||||||
Option: `style`\
|
Option: `style`\
|
||||||
Values:
|
Values:
|
||||||
|
|
||||||
0. ASCII
|
0. `style_ASCII`: ASCII
|
||||||
|
|
||||||

|

|
||||||
1. Basic
|
1. `style_basic`: Basic
|
||||||
|
|
||||||

|

|
||||||
2. Light (default)
|
2. `style_light`: Light (default)
|
||||||
|
|
||||||

|

|
||||||
3. Heavy
|
3. `style_heavy`: Heavy
|
||||||
|
|
||||||

|

|
||||||
4. Double
|
4. `style_double`: Double
|
||||||
|
|
||||||

|

|
||||||
5. Light Dashed
|
5. `style_light_dashed`: Light Dashed
|
||||||
|
|
||||||

|

|
||||||
6. Heavy Dashed
|
6. `style_heavy_dashed`: Heavy Dashed
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@ -783,27 +791,25 @@ Values:
|
|||||||
Option: `color`\
|
Option: `color`\
|
||||||
Values:
|
Values:
|
||||||
|
|
||||||
0. System default
|
0. `color_default`: System default
|
||||||
1. Black
|
1. `color_black`: Black
|
||||||
2. Red (default)
|
2. `color_red`: Red (default)
|
||||||
3. Green
|
3. `color_green`: Green
|
||||||
4. Yellow
|
4. `color_yellow`: Yellow
|
||||||
5. Blue
|
5. `color_blue`: Blue
|
||||||
6. Cyan
|
6. `color_cyan`: Cyan
|
||||||
7. Light gray
|
7. `color_light_gray`: Light gray
|
||||||
8. Dark gray
|
8. `color_dark_gray`: Dark gray
|
||||||
9. Light red
|
9. `color_light_red`: Light red
|
||||||
10. Light green
|
10. `color_light_green`: Light green
|
||||||
11. Light yellow
|
11. `color_light_yellow`: Light yellow
|
||||||
12. Light blue
|
12. `color_light_blue`: Light blue
|
||||||
13. Light cyan
|
13. `color_light_cyan`: Light cyan
|
||||||
14. White
|
14. `color_white`: White
|
||||||
|
|
||||||
See [here](https://misc.flogisoft.com/bash/tip_colors_and_formatting#foreground_text) for examples of the colors.
|
See [here](https://misc.flogisoft.com/bash/tip_colors_and_formatting#foreground_text) for examples of the colors.
|
||||||
|
|
||||||
Only used for plots and when graphing a single function.
|
Only used when plotting a single array and when graphing a single function. When plotting multiple arrays or graphing multiple functions, colors 2 - 14 are used inorder. The system default color is used where the plots cross.
|
||||||
|
|
||||||
When graphing multiple functions, colors `2` - `14` are used inorder. Color `0` is used where the functions cross.
|
|
||||||
|
|
||||||
##### Plot
|
##### Plot
|
||||||
|
|
||||||
@ -813,6 +819,13 @@ When graphing multiple functions, colors `2` - `14` are used inorder. Color `0`
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
#### Check size
|
||||||
|
|
||||||
|
Option: `check`\
|
||||||
|
Default value: `true`
|
||||||
|
|
||||||
|
Check that the width and height of the graph are not greater then the respective width and height of the terminal.
|
||||||
|
|
||||||
### Other C++ Console Graphs/Plots Libraries
|
### Other C++ Console Graphs/Plots Libraries
|
||||||
|
|
||||||
* [C++ terminal plotting library](https://github.com/fbbdev/plot) (requires C++14, based on [UnicodePlots.jl](https://github.com/Evizero/UnicodePlots.jl), no documentation and very difficult to use, although supports animations)
|
* [C++ terminal plotting library](https://github.com/fbbdev/plot) (requires C++14, based on [UnicodePlots.jl](https://github.com/Evizero/UnicodePlots.jl), no documentation and very difficult to use, although supports animations)
|
||||||
|
42
graphs.cpp
42
graphs.cpp
@ -68,14 +68,14 @@ int main()
|
|||||||
|
|
||||||
graphs::options aoptions;
|
graphs::options aoptions;
|
||||||
|
|
||||||
for (unsigned int k = 0; k < graphs::size(graphs::styles); ++k)
|
for (const graphs::style_type style : graphs::style_types)
|
||||||
{
|
{
|
||||||
aoptions.style = k;
|
aoptions.style = style;
|
||||||
|
|
||||||
graphs::array(height, width, xmin, xmax, ymin, ymax, rows, array, aoptions);
|
graphs::array(height, width, xmin, xmax, ymin, ymax, rows, array, aoptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (array != nullptr)
|
if (array)
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < rows; ++i)
|
for (unsigned int i = 0; i < rows; ++i)
|
||||||
delete[] array[i];
|
delete[] array[i];
|
||||||
@ -92,9 +92,9 @@ int main()
|
|||||||
|
|
||||||
graphs::options aoptions;
|
graphs::options aoptions;
|
||||||
|
|
||||||
for (unsigned int k = 0; k < graphs::size(graphs::styles); ++k)
|
for (const graphs::style_type style : graphs::style_types)
|
||||||
{
|
{
|
||||||
aoptions.style = k;
|
aoptions.style = style;
|
||||||
|
|
||||||
graphs::array(height, width, xmin, xmax, ymin, ymax, aarray, aoptions);
|
graphs::array(height, width, xmin, xmax, ymin, ymax, aarray, aoptions);
|
||||||
}
|
}
|
||||||
@ -108,9 +108,9 @@ int main()
|
|||||||
|
|
||||||
graphs::options aoptions;
|
graphs::options aoptions;
|
||||||
|
|
||||||
for (unsigned int k = 0; k < graphs::size(graphs::styles); ++k)
|
for (const graphs::style_type style : graphs::style_types)
|
||||||
{
|
{
|
||||||
aoptions.style = k;
|
aoptions.style = style;
|
||||||
|
|
||||||
graphs::array(height, width, xmin, xmax, ymin, ymax, array, aoptions);
|
graphs::array(height, width, xmin, xmax, ymin, ymax, array, aoptions);
|
||||||
}
|
}
|
||||||
@ -120,9 +120,9 @@ int main()
|
|||||||
{
|
{
|
||||||
graphs::options aoptions;
|
graphs::options aoptions;
|
||||||
|
|
||||||
for (unsigned int k = 0; k < graphs::size(graphs::styles); ++k)
|
for (const graphs::style_type style : graphs::style_types)
|
||||||
{
|
{
|
||||||
aoptions.style = k;
|
aoptions.style = style;
|
||||||
|
|
||||||
graphs::function(height, width, xmin, xmax, ymin, ymax, afunction, aoptions);
|
graphs::function(height, width, xmin, xmax, ymin, ymax, afunction, aoptions);
|
||||||
}
|
}
|
||||||
@ -133,9 +133,9 @@ int main()
|
|||||||
|
|
||||||
graphs::options aoptions;
|
graphs::options aoptions;
|
||||||
|
|
||||||
for (unsigned int k = 0; k < graphs::size(graphs::styles); ++k)
|
for (const graphs::style_type style : graphs::style_types)
|
||||||
{
|
{
|
||||||
aoptions.style = k;
|
aoptions.style = style;
|
||||||
|
|
||||||
graphs::function(height, width, xmin, xmax, ymin, ymax, afunction, aoptions);
|
graphs::function(height, width, xmin, xmax, ymin, ymax, afunction, aoptions);
|
||||||
}
|
}
|
||||||
@ -147,11 +147,11 @@ int main()
|
|||||||
|
|
||||||
graphs::options aoptions;
|
graphs::options aoptions;
|
||||||
|
|
||||||
for (unsigned int k = 0; k < graphs::size(graphs::styles); ++k)
|
for (const graphs::style_type style : graphs::style_types)
|
||||||
{
|
{
|
||||||
aoptions.style = k;
|
aoptions.style = style;
|
||||||
|
|
||||||
graphs::functions(height, width, xmin, xmax, ymin, ymax, 2, functions, aoptions);
|
graphs::functions(height, width, xmin, xmax, ymin, ymax, graphs::size(functions), functions, aoptions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
@ -162,11 +162,11 @@ int main()
|
|||||||
|
|
||||||
graphs::options aoptions;
|
graphs::options aoptions;
|
||||||
|
|
||||||
for (unsigned int k = 0; k < graphs::size(graphs::styles); ++k)
|
for (const graphs::style_type style : graphs::style_types)
|
||||||
{
|
{
|
||||||
aoptions.style = k;
|
aoptions.style = style;
|
||||||
|
|
||||||
graphs::functions(height, width, xmin, xmax, ymin, ymax, 2, functions, aoptions);
|
graphs::functions(height, width, xmin, xmax, ymin, ymax, graphs::size(functions), functions, aoptions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
@ -181,11 +181,11 @@ int main()
|
|||||||
aoptions.axisunitslabel = false;
|
aoptions.axisunitslabel = false;
|
||||||
// graphs::options aoptions{.axisunitslabel = false};
|
// graphs::options aoptions{.axisunitslabel = false};
|
||||||
|
|
||||||
for (unsigned int k = 0; k < graphs::size(graphs::styles); ++k)
|
for (const graphs::style_type style : graphs::style_types)
|
||||||
{
|
{
|
||||||
aoptions.style = k;
|
aoptions.style = style;
|
||||||
|
|
||||||
graphs::functions(height, width, xmin, xmax, ymin, ymax, 3, functions, aoptions);
|
graphs::functions(height, width, xmin, xmax, ymin, ymax, graphs::size(functions), functions, aoptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* aoptions.style = 2;
|
/* aoptions.style = 2;
|
||||||
@ -195,7 +195,7 @@ int main()
|
|||||||
cout << "\e[1;1H"
|
cout << "\e[1;1H"
|
||||||
<< "\e[2J";
|
<< "\e[2J";
|
||||||
|
|
||||||
graphs::functions(k, k, xmin, xmax, ymin, ymax, 3, functions, aoptions);
|
graphs::functions(k, k, xmin, xmax, ymin, ymax, graphs::size(functions), functions, aoptions);
|
||||||
|
|
||||||
usleep(200000);
|
usleep(200000);
|
||||||
} */
|
} */
|
||||||
|
413
graphs.hpp
413
graphs.hpp
@ -22,6 +22,19 @@ namespace graphs
|
|||||||
{
|
{
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
enum style_type
|
||||||
|
{
|
||||||
|
style_ASCII,
|
||||||
|
style_basic,
|
||||||
|
style_light,
|
||||||
|
style_heavy,
|
||||||
|
style_double,
|
||||||
|
style_light_dashed,
|
||||||
|
style_heavy_dashed
|
||||||
|
};
|
||||||
|
|
||||||
|
enum style_type const style_types[] = {style_ASCII, style_basic, style_light, style_heavy, style_double, style_light_dashed, style_heavy_dashed};
|
||||||
|
|
||||||
const char *const styles[][11] = {
|
const char *const styles[][11] = {
|
||||||
{"-", "|", "+", "+", "+", "+", "+", "+", "+", "+", "+"}, // ASCII
|
{"-", "|", "+", "+", "+", "+", "+", "+", "+", "+", "+"}, // ASCII
|
||||||
{"—", "|", "+", "+", "+", "+", "+", "+", "+", "+", "+"}, // Basic
|
{"—", "|", "+", "+", "+", "+", "+", "+", "+", "+", "+"}, // Basic
|
||||||
@ -33,6 +46,27 @@ namespace graphs
|
|||||||
};
|
};
|
||||||
// {" ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "}};//No border
|
// {" ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "}};//No border
|
||||||
|
|
||||||
|
enum color_type
|
||||||
|
{
|
||||||
|
color_default,
|
||||||
|
color_black,
|
||||||
|
color_red,
|
||||||
|
color_green,
|
||||||
|
color_yellow,
|
||||||
|
color_blue,
|
||||||
|
color_cyan,
|
||||||
|
color_light_gray,
|
||||||
|
color_dark_gray,
|
||||||
|
color_light_red,
|
||||||
|
color_light_green,
|
||||||
|
color_light_yellow,
|
||||||
|
color_light_blue,
|
||||||
|
color_light_cyan,
|
||||||
|
color_white
|
||||||
|
};
|
||||||
|
|
||||||
|
enum color_type const color_types[] = {color_default, color_black, color_red, color_green, color_yellow, color_blue, color_cyan, color_light_gray, color_dark_gray, color_light_red, color_light_green, color_light_yellow, color_light_blue, color_light_cyan, color_white};
|
||||||
|
|
||||||
const char *const colors[] = {"\e[39m", "\e[30m", "\e[31m", "\e[32m", "\e[33m", "\e[34m", "\e[35m", "\e[36m", "\e[37m", "\e[90m", "\e[91m", "\e[92m", "\e[93m", "\e[94m", "\e[95m", "\e[96m", "\e[97m"};
|
const char *const colors[] = {"\e[39m", "\e[30m", "\e[31m", "\e[32m", "\e[33m", "\e[34m", "\e[35m", "\e[36m", "\e[37m", "\e[90m", "\e[91m", "\e[92m", "\e[93m", "\e[94m", "\e[95m", "\e[96m", "\e[97m"};
|
||||||
|
|
||||||
const char *const dots[] = {"⠀", "⠁", "⠂", "⠃", "⠄", "⠅", "⠆", "⠇", "⠈", "⠉", "⠊", "⠋", "⠌", "⠍", "⠎", "⠏", "⠐", "⠑", "⠒", "⠓", "⠔", "⠕", "⠖", "⠗", "⠘", "⠙", "⠚", "⠛", "⠜", "⠝", "⠞", "⠟", "⠠", "⠡", "⠢", "⠣", "⠤", "⠥", "⠦", "⠧", "⠨", "⠩", "⠪", "⠫", "⠬", "⠭", "⠮", "⠯", "⠰", "⠱", "⠲", "⠳", "⠴", "⠵", "⠶", "⠷", "⠸", "⠹", "⠺", "⠻", "⠼", "⠽", "⠾", "⠿", "⡀", "⡁", "⡂", "⡃", "⡄", "⡅", "⡆", "⡇", "⡈", "⡉", "⡊", "⡋", "⡌", "⡍", "⡎", "⡏", "⡐", "⡑", "⡒", "⡓", "⡔", "⡕", "⡖", "⡗", "⡘", "⡙", "⡚", "⡛", "⡜", "⡝", "⡞", "⡟", "⡠", "⡡", "⡢", "⡣", "⡤", "⡥", "⡦", "⡧", "⡨", "⡩", "⡪", "⡫", "⡬", "⡭", "⡮", "⡯", "⡰", "⡱", "⡲", "⡳", "⡴", "⡵", "⡶", "⡷", "⡸", "⡹", "⡺", "⡻", "⡼", "⡽", "⡾", "⡿", "⢀", "⢁", "⢂", "⢃", "⢄", "⢅", "⢆", "⢇", "⢈", "⢉", "⢊", "⢋", "⢌", "⢍", "⢎", "⢏", "⢐", "⢑", "⢒", "⢓", "⢔", "⢕", "⢖", "⢗", "⢘", "⢙", "⢚", "⢛", "⢜", "⢝", "⢞", "⢟", "⢠", "⢡", "⢢", "⢣", "⢤", "⢥", "⢦", "⢧", "⢨", "⢩", "⢪", "⢫", "⢬", "⢭", "⢮", "⢯", "⢰", "⢱", "⢲", "⢳", "⢴", "⢵", "⢶", "⢷", "⢸", "⢹", "⢺", "⢻", "⢼", "⢽", "⢾", "⢿", "⣀", "⣁", "⣂", "⣃", "⣄", "⣅", "⣆", "⣇", "⣈", "⣉", "⣊", "⣋", "⣌", "⣍", "⣎", "⣏", "⣐", "⣑", "⣒", "⣓", "⣔", "⣕", "⣖", "⣗", "⣘", "⣙", "⣚", "⣛", "⣜", "⣝", "⣞", "⣟", "⣠", "⣡", "⣢", "⣣", "⣤", "⣥", "⣦", "⣧", "⣨", "⣩", "⣪", "⣫", "⣬", "⣭", "⣮", "⣯", "⣰", "⣱", "⣲", "⣳", "⣴", "⣵", "⣶", "⣷", "⣸", "⣹", "⣺", "⣻", "⣼", "⣽", "⣾", "⣿"};
|
const char *const dots[] = {"⠀", "⠁", "⠂", "⠃", "⠄", "⠅", "⠆", "⠇", "⠈", "⠉", "⠊", "⠋", "⠌", "⠍", "⠎", "⠏", "⠐", "⠑", "⠒", "⠓", "⠔", "⠕", "⠖", "⠗", "⠘", "⠙", "⠚", "⠛", "⠜", "⠝", "⠞", "⠟", "⠠", "⠡", "⠢", "⠣", "⠤", "⠥", "⠦", "⠧", "⠨", "⠩", "⠪", "⠫", "⠬", "⠭", "⠮", "⠯", "⠰", "⠱", "⠲", "⠳", "⠴", "⠵", "⠶", "⠷", "⠸", "⠹", "⠺", "⠻", "⠼", "⠽", "⠾", "⠿", "⡀", "⡁", "⡂", "⡃", "⡄", "⡅", "⡆", "⡇", "⡈", "⡉", "⡊", "⡋", "⡌", "⡍", "⡎", "⡏", "⡐", "⡑", "⡒", "⡓", "⡔", "⡕", "⡖", "⡗", "⡘", "⡙", "⡚", "⡛", "⡜", "⡝", "⡞", "⡟", "⡠", "⡡", "⡢", "⡣", "⡤", "⡥", "⡦", "⡧", "⡨", "⡩", "⡪", "⡫", "⡬", "⡭", "⡮", "⡯", "⡰", "⡱", "⡲", "⡳", "⡴", "⡵", "⡶", "⡷", "⡸", "⡹", "⡺", "⡻", "⡼", "⡽", "⡾", "⡿", "⢀", "⢁", "⢂", "⢃", "⢄", "⢅", "⢆", "⢇", "⢈", "⢉", "⢊", "⢋", "⢌", "⢍", "⢎", "⢏", "⢐", "⢑", "⢒", "⢓", "⢔", "⢕", "⢖", "⢗", "⢘", "⢙", "⢚", "⢛", "⢜", "⢝", "⢞", "⢟", "⢠", "⢡", "⢢", "⢣", "⢤", "⢥", "⢦", "⢧", "⢨", "⢩", "⢪", "⢫", "⢬", "⢭", "⢮", "⢯", "⢰", "⢱", "⢲", "⢳", "⢴", "⢵", "⢶", "⢷", "⢸", "⢹", "⢺", "⢻", "⢼", "⢽", "⢾", "⢿", "⣀", "⣁", "⣂", "⣃", "⣄", "⣅", "⣆", "⣇", "⣈", "⣉", "⣊", "⣋", "⣌", "⣍", "⣎", "⣏", "⣐", "⣑", "⣒", "⣓", "⣔", "⣕", "⣖", "⣗", "⣘", "⣙", "⣚", "⣛", "⣜", "⣝", "⣞", "⣟", "⣠", "⣡", "⣢", "⣣", "⣤", "⣥", "⣦", "⣧", "⣨", "⣩", "⣪", "⣫", "⣬", "⣭", "⣮", "⣯", "⣰", "⣱", "⣲", "⣳", "⣴", "⣵", "⣶", "⣷", "⣸", "⣹", "⣺", "⣻", "⣼", "⣽", "⣾", "⣿"};
|
||||||
@ -40,23 +74,29 @@ namespace graphs
|
|||||||
const int values[][4] = {{0x1, 0x2, 0x4, 0x40}, {0x8, 0x10, 0x20, 0x80}};
|
const int values[][4] = {{0x1, 0x2, 0x4, 0x40}, {0x8, 0x10, 0x20, 0x80}};
|
||||||
|
|
||||||
const char *const fractions[] = {"¼", "½", "¾", "⅐", "⅑", "⅒", "⅓", "⅔", "⅕", "⅖", "⅗", "⅘", "⅙", "⅚", "⅛", "⅜", "⅝", "⅞"};
|
const char *const fractions[] = {"¼", "½", "¾", "⅐", "⅑", "⅒", "⅓", "⅔", "⅕", "⅖", "⅗", "⅘", "⅙", "⅚", "⅛", "⅜", "⅝", "⅞"};
|
||||||
|
|
||||||
const long double fractionvalues[] = {1.0L / 4.0L, 1.0L / 2.0L, 3.0L / 4.0L, 1.0L / 7.0L, 1.0L / 9.0L, 1.0L / 10.0L, 1.0L / 3.0L, 2.0L / 3.0L, 1.0L / 5.0L, 2.0L / 5.0L, 3.0L / 5.0L, 4.0L / 5.0L, 1.0L / 6.0L, 5.0L / 6.0L, 1.0L / 8.0L, 3.0L / 8.0L, 5.0L / 8.0L, 7.0L / 8.0L};
|
const long double fractionvalues[] = {1.0L / 4.0L, 1.0L / 2.0L, 3.0L / 4.0L, 1.0L / 7.0L, 1.0L / 9.0L, 1.0L / 10.0L, 1.0L / 3.0L, 2.0L / 3.0L, 1.0L / 5.0L, 2.0L / 5.0L, 3.0L / 5.0L, 4.0L / 5.0L, 1.0L / 6.0L, 5.0L / 6.0L, 1.0L / 8.0L, 3.0L / 8.0L, 5.0L / 8.0L, 7.0L / 8.0L};
|
||||||
|
|
||||||
|
const char *const constants[] = {"π", "e"};
|
||||||
|
const long double constantvalues[] = {M_PI, M_E};
|
||||||
|
|
||||||
|
const long double max_bit = scalbn(1.0L, LDBL_MANT_DIG - 1);
|
||||||
|
const long double MAX = max_bit + (max_bit - 1);
|
||||||
|
|
||||||
struct options
|
struct options
|
||||||
{
|
{
|
||||||
bool border = true;
|
bool border = true;
|
||||||
bool axislabel = true;
|
bool axislabel = true;
|
||||||
bool axisunitslabel = true;
|
bool axisunitslabel = true;
|
||||||
const char *title = nullptr;
|
const char *title = nullptr;
|
||||||
unsigned int style = 2;
|
style_type style = style_light;
|
||||||
unsigned int color = 2;
|
color_type color = color_red;
|
||||||
|
bool check = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const options defaultoptions;
|
const options defaultoptions;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
auto size(const T &array)
|
constexpr size_t size(const T &array)
|
||||||
{
|
{
|
||||||
return distance(begin(array), end(array));
|
return distance(begin(array), end(array));
|
||||||
}
|
}
|
||||||
@ -81,11 +121,11 @@ namespace graphs
|
|||||||
}
|
}
|
||||||
++length;
|
++length;
|
||||||
|
|
||||||
wchar_t *wcstring = new wchar_t[length];
|
auto *wcstring = new wchar_t[length];
|
||||||
|
|
||||||
if (mbstowcs(wcstring, str, length) == static_cast<size_t>(-1))
|
if (mbstowcs(wcstring, str, length) == static_cast<size_t>(-1))
|
||||||
{
|
{
|
||||||
if (wcstring != nullptr)
|
if (wcstring)
|
||||||
delete[] wcstring;
|
delete[] wcstring;
|
||||||
|
|
||||||
cerr << "\nError! mbstowcs failed. Invalid multibyte character.\n";
|
cerr << "\nError! mbstowcs failed. Invalid multibyte character.\n";
|
||||||
@ -99,7 +139,7 @@ namespace graphs
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wcstring != nullptr)
|
if (wcstring)
|
||||||
delete[] wcstring;
|
delete[] wcstring;
|
||||||
|
|
||||||
return width;
|
return width;
|
||||||
@ -110,8 +150,7 @@ namespace graphs
|
|||||||
// Adapted from: https://stackoverflow.com/a/42016346 and https://stackoverflow.com/a/13094734
|
// Adapted from: https://stackoverflow.com/a/42016346 and https://stackoverflow.com/a/13094734
|
||||||
string wrap(const char *const str, const size_t line_length)
|
string wrap(const char *const str, const size_t line_length)
|
||||||
{
|
{
|
||||||
char words[strlen(str) + 1];
|
string words = str;
|
||||||
strcpy(words, str);
|
|
||||||
string wrapped;
|
string wrapped;
|
||||||
|
|
||||||
size_t index = 0;
|
size_t index = 0;
|
||||||
@ -134,7 +173,7 @@ namespace graphs
|
|||||||
}
|
}
|
||||||
|
|
||||||
char temp[templinelen + 1];
|
char temp[templinelen + 1];
|
||||||
strncpy(temp, words + (index - linelen), templinelen);
|
strncpy(temp, words.data() + (index - linelen), templinelen);
|
||||||
temp[templinelen] = '\0';
|
temp[templinelen] = '\0';
|
||||||
|
|
||||||
size_t width = strcol(temp);
|
size_t width = strcol(temp);
|
||||||
@ -158,62 +197,54 @@ namespace graphs
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Convert fractions and constants to Unicode characters
|
// Convert fractions and constants to Unicode characters
|
||||||
size_t outputlabel(const long double label, ostringstream &strm)
|
size_t outputfraction(const long double number, ostringstream &strm)
|
||||||
{
|
{
|
||||||
bool output = false;
|
bool output = false;
|
||||||
|
|
||||||
long double intpart = 0;
|
const long double n = abs(number);
|
||||||
long double fractionpart = abs(modf(label, &intpart));
|
if (n <= MAX)
|
||||||
|
|
||||||
for (unsigned int i = 0; i < graphs::size(fractions) and !output; ++i)
|
|
||||||
{
|
{
|
||||||
if (abs(fractionpart - fractionvalues[i]) < DBL_EPSILON)
|
long double intpart = 0;
|
||||||
|
long double fractionpart = abs(modf(number, &intpart));
|
||||||
|
|
||||||
|
for (size_t i = 0; i < graphs::size(fractions) and !output; ++i)
|
||||||
{
|
{
|
||||||
if (intpart != 0)
|
if (abs(fractionpart - fractionvalues[i]) <= DBL_EPSILON * n)
|
||||||
strm << intpart;
|
{
|
||||||
|
if (intpart == 0 and number < 0)
|
||||||
|
strm << "-";
|
||||||
|
else if (intpart != 0)
|
||||||
|
strm << setprecision(LDBL_DIG) << intpart;
|
||||||
|
|
||||||
strm << fractions[i];
|
strm << fractions[i];
|
||||||
|
|
||||||
output = true;
|
output = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (abs(label) >= DBL_EPSILON)
|
if (n > DBL_EPSILON)
|
||||||
{
|
|
||||||
if (!output and fmod(label, M_PI) == 0)
|
|
||||||
{
|
{
|
||||||
const char symbol[] = "π";
|
for (size_t i = 0; i < graphs::size(constants) and !output; ++i)
|
||||||
|
{
|
||||||
|
if (abs(fmod(number, constantvalues[i])) <= DBL_EPSILON * n)
|
||||||
|
{
|
||||||
|
intpart = number / constantvalues[i];
|
||||||
|
|
||||||
intpart = label / M_PI;
|
if (intpart == -1)
|
||||||
|
strm << "-";
|
||||||
|
else if (intpart != 1)
|
||||||
|
strm << setprecision(LDBL_DIG) << intpart;
|
||||||
|
|
||||||
if (intpart == -1)
|
strm << constants[i];
|
||||||
strm << "-";
|
|
||||||
else if (intpart != 1)
|
|
||||||
strm << intpart;
|
|
||||||
|
|
||||||
strm << symbol;
|
output = true;
|
||||||
|
}
|
||||||
output = true;
|
}
|
||||||
}
|
|
||||||
else if (!output and fmod(label, M_E) == 0)
|
|
||||||
{
|
|
||||||
const char symbol[] = "e";
|
|
||||||
|
|
||||||
intpart = label / M_E;
|
|
||||||
|
|
||||||
if (intpart == -1)
|
|
||||||
strm << "-";
|
|
||||||
else if (intpart != 1)
|
|
||||||
strm << intpart;
|
|
||||||
|
|
||||||
strm << symbol;
|
|
||||||
|
|
||||||
output = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!output)
|
if (!output)
|
||||||
strm << label;
|
strm << number;
|
||||||
|
|
||||||
size_t length = strcol(strm.str().c_str());
|
size_t length = strcol(strm.str().c_str());
|
||||||
|
|
||||||
@ -230,10 +261,7 @@ namespace graphs
|
|||||||
const bool axislabel = aoptions.axislabel;
|
const bool axislabel = aoptions.axislabel;
|
||||||
const bool axisunitslabel = aoptions.axisunitslabel;
|
const bool axisunitslabel = aoptions.axisunitslabel;
|
||||||
const char *const title = aoptions.title;
|
const char *const title = aoptions.title;
|
||||||
const unsigned int style = aoptions.style;
|
const style_type style = aoptions.style;
|
||||||
|
|
||||||
if (style >= graphs::size(styles))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
if (height == 0)
|
if (height == 0)
|
||||||
return 1;
|
return 1;
|
||||||
@ -244,19 +272,22 @@ namespace graphs
|
|||||||
struct winsize w;
|
struct winsize w;
|
||||||
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
|
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
|
||||||
|
|
||||||
const int aheight = height / 4;
|
if (aoptions.check)
|
||||||
const int awidth = width / 2;
|
|
||||||
|
|
||||||
if (aheight > w.ws_row)
|
|
||||||
{
|
{
|
||||||
cerr << "The height of the graph (" << aheight << ") is greater then the height of the terminal (" << w.ws_row << ").\n";
|
const size_t aheight = height / 4;
|
||||||
return 1;
|
const size_t awidth = width / 2;
|
||||||
}
|
|
||||||
|
|
||||||
if (awidth > w.ws_col)
|
if (aheight > w.ws_row)
|
||||||
{
|
{
|
||||||
cerr << "The width of the graph (" << awidth << ") is greater then the width of the terminal (" << w.ws_col << ").\n";
|
cerr << "The height of the graph (" << aheight << ") is greater then the height of the terminal (" << w.ws_row << ").\n";
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (awidth > w.ws_col)
|
||||||
|
{
|
||||||
|
cerr << "The width of the graph (" << awidth << ") is greater then the width of the terminal (" << w.ws_col << ").\n";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xmin >= xmax)
|
if (xmin >= xmax)
|
||||||
@ -271,38 +302,39 @@ namespace graphs
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const long double xscl = width / (xmax - xmin);
|
const long double xstep = (xmax - xmin) / width;
|
||||||
const long double yscl = height / (ymax - ymin);
|
const long double ystep = (ymax - ymin) / height;
|
||||||
const long double xaxis = width - (xmax * xscl);
|
const long double xaxis = xmin > 0 ? 0 : xmax < 0 ? width
|
||||||
const long double yaxis = ymax * yscl;
|
: width - (xmax / xstep);
|
||||||
const int divisor = 2 * 4 * ((width / 160.0) > 1 ? (width / 160) + 1 : 1);
|
const long double yaxis = ymin > 0 ? height : ymax < 0 ? 0
|
||||||
|
: ymax / ystep;
|
||||||
|
const int xdivisor = 2 * 4 * ((width / 160) + 2);
|
||||||
|
const int ydivisor = 2 * 4 * ((height / 160) + 2);
|
||||||
|
|
||||||
setlocale(LC_CTYPE, "");
|
setlocale(LC_ALL, "");
|
||||||
|
|
||||||
if (title != nullptr and title[0] != '\0')
|
if (title and title[0] != '\0')
|
||||||
cout << wrap(title, w.ws_col) << "\n";
|
cout << wrap(title, width / 2) << "\n";
|
||||||
|
|
||||||
for (unsigned int i = 0; i < height; i += 4)
|
for (size_t i = 0; i < height; i += 4)
|
||||||
{
|
{
|
||||||
const bool ayaxis = (i <= yaxis and (i + 4) > yaxis);
|
const bool ayaxis = yaxis <= (height - 4) ? i <= yaxis and (i + 4) > yaxis : i < yaxis and (i + 4) >= yaxis;
|
||||||
const bool yaxislabel = (i <= (yaxis + 4) and (i + 4) > (yaxis + 4));
|
const bool yaxislabel = yaxis <= (height - 4) ? i <= (yaxis + 4) and (i + 4) > (yaxis + 4) : i < (yaxis - 4) and (i + 4) >= (yaxis - 4);
|
||||||
|
|
||||||
ostringstream ylabelstrm;
|
ostringstream ylabelstrm;
|
||||||
size_t ylabellength = 0;
|
size_t ylabellength = 0;
|
||||||
|
|
||||||
if (border and axislabel and axisunitslabel)
|
if (border and axislabel and axisunitslabel and yaxis >= 0 and yaxis <= height)
|
||||||
{
|
{
|
||||||
bool output = false;
|
bool output = false;
|
||||||
long double label = 0;
|
long double label = 0;
|
||||||
int adivisor = divisor;
|
int adivisor = i < yaxis ? -ydivisor : ydivisor;
|
||||||
if (i < yaxis)
|
|
||||||
adivisor = -adivisor;
|
|
||||||
|
|
||||||
for (long double k = yaxis + adivisor; ((i < yaxis and k >= i) or (i > yaxis and k < (i + 4))) and i >= 4 and !output; k += adivisor)
|
for (long double k = yaxis + adivisor; (i < yaxis ? k >= i : k < (i + 4)) and i >= 4 and !output; k += adivisor)
|
||||||
{
|
{
|
||||||
if (i <= k and (i + 4) > k)
|
if (i <= k and (i + 4) > k)
|
||||||
{
|
{
|
||||||
label = ymax - (k / yscl);
|
label = ymax - ((k > height ? height : k) * ystep);
|
||||||
|
|
||||||
output = true;
|
output = true;
|
||||||
}
|
}
|
||||||
@ -310,15 +342,15 @@ namespace graphs
|
|||||||
|
|
||||||
if (output)
|
if (output)
|
||||||
{
|
{
|
||||||
ylabellength = outputlabel(label, ylabelstrm);
|
ylabellength = outputfraction(label, ylabelstrm);
|
||||||
ylabellength *= 2;
|
ylabellength *= 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned int j = 0; j < width; j += 2)
|
for (size_t j = 0; j < width; j += 2)
|
||||||
{
|
{
|
||||||
const bool axaxis = (j <= xaxis and (j + 2) > xaxis);
|
const bool axaxis = xaxis >= 2 ? j < xaxis and (j + 2) >= xaxis : j <= xaxis and (j + 2) > xaxis;
|
||||||
const bool xaxislabel = (j <= (xaxis - 2) and (j + 2) > (xaxis - 2));
|
const bool xaxislabel = xaxis >= 2 ? j < (xaxis - 2) and (j + 2) >= (xaxis - 2) : j <= (xaxis + 2) and (j + 2) > (xaxis + 2);
|
||||||
|
|
||||||
bool output = false;
|
bool output = false;
|
||||||
|
|
||||||
@ -331,66 +363,72 @@ namespace graphs
|
|||||||
}
|
}
|
||||||
else if (axaxis)
|
else if (axaxis)
|
||||||
{
|
{
|
||||||
if (axislabel and axisunitslabel)
|
if (i == 0)
|
||||||
{
|
{
|
||||||
int adivisor = divisor;
|
cout << styles[style][4];
|
||||||
if (i < yaxis)
|
output = true;
|
||||||
adivisor = -adivisor;
|
}
|
||||||
|
else if (i >= (height - 4))
|
||||||
|
{
|
||||||
|
cout << styles[style][10];
|
||||||
|
output = true;
|
||||||
|
}
|
||||||
|
else if (axislabel and axisunitslabel)
|
||||||
|
{
|
||||||
|
int adivisor = i < yaxis ? -ydivisor : ydivisor;
|
||||||
|
|
||||||
for (long double k = yaxis + adivisor; ((i < yaxis and k >= i) or (i > yaxis and k < (i + 4))) and i >= 4 and !output; k += adivisor)
|
for (long double k = yaxis + adivisor; (i < yaxis ? k >= i : k < (i + 4)) and i >= 4 and !output; k += adivisor)
|
||||||
{
|
{
|
||||||
if (i <= k and (i + 4) > k)
|
if (i <= k and (i + 4) > k)
|
||||||
{
|
{
|
||||||
cout << styles[style][7];
|
cout << styles[style][xaxis >= 2 ? 7 : 5];
|
||||||
output = true;
|
output = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!output)
|
if (!output)
|
||||||
{
|
{
|
||||||
if (i == 0)
|
cout << styles[style][1];
|
||||||
cout << styles[style][4];
|
|
||||||
else if (i >= (height - 4))
|
|
||||||
cout << styles[style][10];
|
|
||||||
else
|
|
||||||
cout << styles[style][1];
|
|
||||||
output = true;
|
output = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (ayaxis)
|
else if (ayaxis)
|
||||||
{
|
{
|
||||||
if (axislabel and axisunitslabel)
|
if (j == 0)
|
||||||
{
|
{
|
||||||
int adivisor = divisor;
|
cout << styles[style][2];
|
||||||
if (j < xaxis)
|
output = true;
|
||||||
adivisor = -adivisor;
|
}
|
||||||
|
else if (j >= (width - 2))
|
||||||
|
{
|
||||||
|
cout << styles[style][4];
|
||||||
|
output = true;
|
||||||
|
}
|
||||||
|
else if (axislabel and axisunitslabel)
|
||||||
|
{
|
||||||
|
int adivisor = j < xaxis ? -xdivisor : xdivisor;
|
||||||
|
|
||||||
for (long double k = xaxis + adivisor; ((j < xaxis and k >= j) or (j > xaxis and k < (j + 2))) and j < (width - 4) and !output; k += adivisor)
|
for (long double k = xaxis + adivisor; (j < xaxis ? k >= j : k < (j + 2)) and j < (width - (2 * 2)) and !output; k += adivisor)
|
||||||
{
|
{
|
||||||
if (j <= k and (j + 2) > k)
|
if (j <= k and (j + 2) > k)
|
||||||
{
|
{
|
||||||
cout << styles[style][3];
|
cout << styles[style][yaxis <= (height - 4) ? 3 : 9];
|
||||||
output = true;
|
output = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!output)
|
if (!output)
|
||||||
{
|
{
|
||||||
if (j == 0)
|
cout << styles[style][0];
|
||||||
cout << styles[style][2];
|
|
||||||
else if (j >= (width - 2))
|
|
||||||
cout << styles[style][4];
|
|
||||||
else
|
|
||||||
cout << styles[style][0];
|
|
||||||
output = true;
|
output = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (yaxislabel and xaxislabel and axislabel and axisunitslabel)
|
else if (yaxislabel and xaxislabel and axislabel and axisunitslabel and ymin <= 0 and ymax >= 0 and xmin <= 0 and xmax >= 0)
|
||||||
{
|
{
|
||||||
cout << "0";
|
cout << "0";
|
||||||
output = true;
|
output = true;
|
||||||
}
|
}
|
||||||
else if (j >= (width - 2) and yaxislabel and axislabel)
|
else if ((xaxis <= (width - 2) ? j >= (width - 2) : j == 0) and yaxislabel and axislabel)
|
||||||
{
|
{
|
||||||
cout << "x";
|
cout << "x";
|
||||||
output = true;
|
output = true;
|
||||||
@ -398,18 +436,15 @@ namespace graphs
|
|||||||
else if (yaxislabel and axislabel and axisunitslabel)
|
else if (yaxislabel and axislabel and axisunitslabel)
|
||||||
{
|
{
|
||||||
long double label = 0;
|
long double label = 0;
|
||||||
int adivisor = divisor;
|
int adivisor = j < xaxis ? -xdivisor : xdivisor;
|
||||||
if (j < xaxis)
|
if (j < xaxis)
|
||||||
{
|
|
||||||
adivisor = -adivisor;
|
|
||||||
j += 2;
|
j += 2;
|
||||||
}
|
|
||||||
|
|
||||||
for (long double k = xaxis + adivisor; ((j < xaxis and k >= j) or (j > xaxis and k < (j + 2))) and j < (width - 2) and !output; k += adivisor)
|
for (long double k = xaxis + adivisor; (j < xaxis ? k >= j : k < (j + 2)) and j < (width - 2) and !output; k += adivisor)
|
||||||
{
|
{
|
||||||
if (j <= k and (j + 2) > k)
|
if (j <= k and (j + 2) > k)
|
||||||
{
|
{
|
||||||
label = (k / xscl) + xmin;
|
label = ((k > width ? width : k) * xstep) + xmin;
|
||||||
|
|
||||||
output = true;
|
output = true;
|
||||||
}
|
}
|
||||||
@ -423,9 +458,9 @@ namespace graphs
|
|||||||
output = false;
|
output = false;
|
||||||
|
|
||||||
ostringstream strm;
|
ostringstream strm;
|
||||||
size_t length = outputlabel(label, strm);
|
size_t length = outputfraction(label, strm);
|
||||||
length *= 2;
|
length *= 2;
|
||||||
if ((j >= xaxis or (j + length) < (xaxis - 4)) and (j + length) < (width - 2))
|
if ((j >= xaxis or (j + length) < (ymin <= 0 and ymax >= 0 and xmin <= 0 and xmax >= 0 ? xaxis - 4 : xaxis)) and (j + length) < (width - 2) and (xaxis <= (width - 2) or j > 2))
|
||||||
{
|
{
|
||||||
cout << strm.str();
|
cout << strm.str();
|
||||||
|
|
||||||
@ -439,12 +474,12 @@ namespace graphs
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (i == 0 and xaxislabel and axislabel)
|
else if ((yaxis >= 4 ? i == 0 : i >= (height - 4)) and xaxislabel and axislabel)
|
||||||
{
|
{
|
||||||
cout << "y";
|
cout << "y";
|
||||||
output = true;
|
output = true;
|
||||||
}
|
}
|
||||||
else if ((j <= (xaxis - ylabellength) and (j + 2) > (xaxis - ylabellength)) and axislabel and axisunitslabel)
|
else if (ylabellength and (xaxis < 2 ? xaxislabel : j < (xaxis - ylabellength) and (j + 2) >= (xaxis - ylabellength)) and (yaxis >= 4 or i < (height - 4)) and axislabel and axisunitslabel)
|
||||||
{
|
{
|
||||||
cout << ylabelstrm.str();
|
cout << ylabelstrm.str();
|
||||||
output = true;
|
output = true;
|
||||||
@ -455,21 +490,23 @@ namespace graphs
|
|||||||
|
|
||||||
if (!output)
|
if (!output)
|
||||||
{
|
{
|
||||||
unsigned int dot = 0;
|
size_t dot = 0;
|
||||||
unsigned short color = 0;
|
unsigned short color = 0;
|
||||||
|
|
||||||
for (unsigned int k = 0; k < 2 and k < (width - j); ++k)
|
for (size_t k = 0; k < 2 and k < (width - j); ++k)
|
||||||
{
|
{
|
||||||
for (unsigned int l = 0; l < 4 and l < (height - i); ++l)
|
for (size_t l = 0; l < 4 and l < (height - i); ++l)
|
||||||
{
|
{
|
||||||
dot += (array[j + k][i + l] ? 1 : 0) * values[k][l];
|
const unsigned short value = array[j + k][i + l];
|
||||||
|
if (value)
|
||||||
|
dot += values[k][l];
|
||||||
if (color)
|
if (color)
|
||||||
{
|
{
|
||||||
if (array[j + k][i + l] and color != array[j + k][i + l])
|
if (value and color != value)
|
||||||
color = 1;
|
color = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
color = array[j + k][i + l];
|
color = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -479,14 +516,15 @@ namespace graphs
|
|||||||
if (color)
|
if (color)
|
||||||
cout << colors[color];
|
cout << colors[color];
|
||||||
|
|
||||||
cout << "\e[1m" << dots[dot] << "\e[22m";
|
cout << dots[dot];
|
||||||
|
|
||||||
if (color)
|
if (color)
|
||||||
cout << colors[0];
|
cout << colors[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cout << "\n";
|
if (i < (height - 4))
|
||||||
|
cout << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
cout << endl;
|
cout << endl;
|
||||||
@ -505,14 +543,11 @@ namespace graphs
|
|||||||
{ return all_of(begin(array), end(array), [](const auto &x)
|
{ return all_of(begin(array), end(array), [](const auto &x)
|
||||||
{ return graphs::size(x) == 2; }); }))
|
{ return graphs::size(x) == 2; }); }))
|
||||||
{
|
{
|
||||||
cerr << "Error: The arrays must have two columns.";
|
cerr << "Error: The arrays must have two columns.\n";
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const unsigned int color = aoptions.color;
|
const color_type color = aoptions.color;
|
||||||
|
|
||||||
if (color >= graphs::size(colors))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
struct winsize w;
|
struct winsize w;
|
||||||
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
|
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
|
||||||
@ -523,19 +558,22 @@ namespace graphs
|
|||||||
if (width == 0)
|
if (width == 0)
|
||||||
width = w.ws_col * 2;
|
width = w.ws_col * 2;
|
||||||
|
|
||||||
const int aheight = height / 4;
|
if (aoptions.check)
|
||||||
const int awidth = width / 2;
|
|
||||||
|
|
||||||
if (aheight > w.ws_row)
|
|
||||||
{
|
{
|
||||||
cerr << "The height of the graph (" << aheight << ") is greater then the height of the terminal (" << w.ws_row << ").\n";
|
const size_t aheight = height / 4;
|
||||||
return 1;
|
const size_t awidth = width / 2;
|
||||||
}
|
|
||||||
|
|
||||||
if (awidth > w.ws_col)
|
if (aheight > w.ws_row)
|
||||||
{
|
{
|
||||||
cerr << "The width of the graph (" << awidth << ") is greater then the width of the terminal (" << w.ws_col << ").\n";
|
cerr << "The height of the graph (" << aheight << ") is greater then the height of the terminal (" << w.ws_row << ").\n";
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (awidth > w.ws_col)
|
||||||
|
{
|
||||||
|
cerr << "The width of the graph (" << awidth << ") is greater then the width of the terminal (" << w.ws_col << ").\n";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xmin == 0 and xmax == 0)
|
if (xmin == 0 and xmax == 0)
|
||||||
@ -570,32 +608,34 @@ namespace graphs
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const long double xscl = width / (xmax - xmin);
|
const long double xstep = (xmax - xmin) / width;
|
||||||
const long double yscl = height / (ymax - ymin);
|
const long double ystep = (ymax - ymin) / height;
|
||||||
const long double xaxis = width - (xmax * xscl);
|
const long double xaxis = width - (xmax / xstep);
|
||||||
const long double yaxis = ymax * yscl;
|
const long double yaxis = ymax / ystep;
|
||||||
|
|
||||||
vector<vector<unsigned short>> aarray(width, vector<unsigned short>(height, 0));
|
vector<vector<unsigned short>> aarray(width, vector<unsigned short>(height, 0));
|
||||||
|
|
||||||
for (unsigned int j = 0; j < graphs::size(arrays); ++j)
|
for (size_t j = 0; j < graphs::size(arrays); ++j)
|
||||||
{
|
{
|
||||||
auto array = arrays[j];
|
const auto &array = arrays[j];
|
||||||
const unsigned int color = (j % (graphs::size(colors) - 2)) + 3;
|
const unsigned int acolor = graphs::size(arrays) == 1 ? color + 1 : (j % (graphs::size(colors) - 2)) + 3;
|
||||||
|
|
||||||
for (unsigned int i = 0; i < graphs::size(array); ++i)
|
for (size_t i = 0; i < graphs::size(array); ++i)
|
||||||
{
|
{
|
||||||
if (array[i][0] >= xmin and array[i][0] < xmax and array[i][1] >= ymin and array[i][1] < ymax)
|
const auto &x = array[i][0], &y = array[i][1];
|
||||||
{
|
|
||||||
const long long x = (array[i][0] * xscl) + xaxis;
|
|
||||||
const long long y = (yaxis - (array[i][1] * yscl)) - 1;
|
|
||||||
|
|
||||||
if (aarray[x][y])
|
if (x >= xmin and x < xmax and y >= ymin and y < ymax)
|
||||||
|
{
|
||||||
|
const size_t ax = (x / xstep) + xaxis;
|
||||||
|
const size_t ay = (yaxis - (y / ystep)) - 1;
|
||||||
|
|
||||||
|
if (aarray[ax][ay])
|
||||||
{
|
{
|
||||||
if (aarray[x][y] != color)
|
if (aarray[ax][ay] != acolor)
|
||||||
aarray[x][y] = 1;
|
aarray[ax][ay] = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
aarray[x][y] = color;
|
aarray[ax][ay] = acolor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -621,7 +661,7 @@ namespace graphs
|
|||||||
|
|
||||||
const size_t columns = 2;
|
const size_t columns = 2;
|
||||||
vector<std::array<T, columns>> aaarray(rows);
|
vector<std::array<T, columns>> aaarray(rows);
|
||||||
for (unsigned int i = 0; i < rows; ++i)
|
for (size_t i = 0; i < rows; ++i)
|
||||||
copy(aarray[i], aarray[i] + columns, aaarray[i].begin());
|
copy(aarray[i], aarray[i] + columns, aaarray[i].begin());
|
||||||
|
|
||||||
return array(height, width, xmin, xmax, ymin, ymax, aaarray, aoptions);
|
return array(height, width, xmin, xmax, ymin, ymax, aaarray, aoptions);
|
||||||
@ -631,10 +671,7 @@ namespace graphs
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
int functions(size_t height, size_t width, const long double xmin, const long double xmax, const long double ymin, const long double ymax, const size_t numfunctions, function<T(T)> functions[], const options &aoptions = defaultoptions)
|
int functions(size_t height, size_t width, const long double xmin, const long double xmax, const long double ymin, const long double ymax, const size_t numfunctions, function<T(T)> functions[], const options &aoptions = defaultoptions)
|
||||||
{
|
{
|
||||||
const unsigned int color = aoptions.color;
|
const color_type color = aoptions.color;
|
||||||
|
|
||||||
if (color >= graphs::size(colors))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
if (numfunctions == 0)
|
if (numfunctions == 0)
|
||||||
return 1;
|
return 1;
|
||||||
@ -648,19 +685,22 @@ namespace graphs
|
|||||||
if (width == 0)
|
if (width == 0)
|
||||||
width = w.ws_col * 2;
|
width = w.ws_col * 2;
|
||||||
|
|
||||||
const int aheight = height / 4;
|
if (aoptions.check)
|
||||||
const int awidth = width / 2;
|
|
||||||
|
|
||||||
if (aheight > w.ws_row)
|
|
||||||
{
|
{
|
||||||
cerr << "The height of the graph (" << aheight << ") is greater then the height of the terminal (" << w.ws_row << ").\n";
|
const size_t aheight = height / 4;
|
||||||
return 1;
|
const size_t awidth = width / 2;
|
||||||
}
|
|
||||||
|
|
||||||
if (awidth > w.ws_col)
|
if (aheight > w.ws_row)
|
||||||
{
|
{
|
||||||
cerr << "The width of the graph (" << awidth << ") is greater then the width of the terminal (" << w.ws_col << ").\n";
|
cerr << "The height of the graph (" << aheight << ") is greater then the height of the terminal (" << w.ws_row << ").\n";
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (awidth > w.ws_col)
|
||||||
|
{
|
||||||
|
cerr << "The width of the graph (" << awidth << ") is greater then the width of the terminal (" << w.ws_col << ").\n";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xmin >= xmax)
|
if (xmin >= xmax)
|
||||||
@ -677,26 +717,27 @@ namespace graphs
|
|||||||
|
|
||||||
const size_t rows = width;
|
const size_t rows = width;
|
||||||
|
|
||||||
const long double xscl = width / (xmax - xmin);
|
const long double xstep = (xmax - xmin) / width;
|
||||||
const long double yscl = height / (ymax - ymin);
|
const long double ystep = (ymax - ymin) / height;
|
||||||
const long double xaxis = width - (xmax * xscl);
|
const long double xaxis = width - (xmax / xstep);
|
||||||
const long double yaxis = ymax * yscl;
|
const long double yaxis = ymax / ystep;
|
||||||
|
const size_t xres = 2;
|
||||||
|
|
||||||
vector<vector<unsigned short>> array(width, vector<unsigned short>(height, 0));
|
vector<vector<unsigned short>> array(width, vector<unsigned short>(height, 0));
|
||||||
|
|
||||||
for (unsigned int j = 0; j < numfunctions; ++j)
|
for (size_t j = 0; j < numfunctions; ++j)
|
||||||
{
|
{
|
||||||
unsigned short acolor = numfunctions == 1 ? color + 1 : (j % (graphs::size(colors) - 2)) + 3;
|
unsigned short acolor = numfunctions == 1 ? color + 1 : (j % (graphs::size(colors) - 2)) + 3;
|
||||||
|
|
||||||
for (long double i = 0; i < rows; i += 0.5)
|
for (size_t i = 0; i < rows * xres; ++i)
|
||||||
{
|
{
|
||||||
T x = (i / xscl) + xmin;
|
T x = ((i / (long double)xres) * xstep) + xmin;
|
||||||
T y = (functions[j])(x);
|
T y = (functions[j])(x);
|
||||||
|
|
||||||
if (x >= xmin and x < xmax and y >= ymin and y < ymax)
|
if (x >= xmin and x < xmax and y >= ymin and y < ymax)
|
||||||
{
|
{
|
||||||
const long long ax = (x * xscl) + xaxis;
|
const size_t ax = (x / xstep) + xaxis;
|
||||||
const long long ay = (yaxis - (y * yscl)) - 1;
|
const size_t ay = (yaxis - (y / ystep)) - 1;
|
||||||
|
|
||||||
if (array[ax][ay])
|
if (array[ax][ay])
|
||||||
{
|
{
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
### Usage
|
### Usage
|
||||||
|
|
||||||
Requires Python 3.5 or greater and the [wcwidth library](https://pypi.org/project/wcwidth/), which users can install with: `pip3 install wcwidth`. See the [tables.py](tables.py) file for full usage information.
|
Requires Python 3.6 or greater and the [wcwidth library](https://pypi.org/project/wcwidth/), which users can install with: `pip3 install wcwidth`. See the [tables.py](tables.py) file for full usage information.
|
||||||
|
|
||||||
Complete versions of all of the examples below and more can be found in the [test.py](test.py) file.
|
Complete versions of all of the examples below and more can be found in the [test.py](test.py) file.
|
||||||
|
|
||||||
@ -75,9 +75,9 @@ def afunction(x):
|
|||||||
|
|
||||||
xmin = -10
|
xmin = -10
|
||||||
xmax = 10
|
xmax = 10
|
||||||
xscl = 2
|
xstep = 0.5
|
||||||
|
|
||||||
tables.function(xmin, xmax, xscl, afunction, headerrow=True)
|
tables.function(xmin, xmax, xstep, afunction, headerrow=True)
|
||||||
```
|
```
|
||||||
|
|
||||||

|

|
||||||
@ -89,11 +89,11 @@ import tables
|
|||||||
|
|
||||||
xmin = -10
|
xmin = -10
|
||||||
xmax = 10
|
xmax = 10
|
||||||
xscl = 2
|
xstep = 0.5
|
||||||
|
|
||||||
afunction = lambda x: x + 1
|
afunction = lambda x: x + 1
|
||||||
|
|
||||||
tables.function(xmin, xmax, xscl, afunction, headerrow=True)
|
tables.function(xmin, xmax, xstep, afunction, headerrow=True)
|
||||||
```
|
```
|
||||||
|
|
||||||
Output same as example above.
|
Output same as example above.
|
||||||
@ -111,12 +111,12 @@ def function2(x):
|
|||||||
|
|
||||||
xmin = -10
|
xmin = -10
|
||||||
xmax = 10
|
xmax = 10
|
||||||
xscl = 2
|
xstep = 0.5
|
||||||
|
|
||||||
# Function parameter and return value can be any data type, as long as they are the same
|
# Function parameter and return value can be any data type, as long as they are the same
|
||||||
functions = [function1, function2]
|
functions = [function1, function2]
|
||||||
|
|
||||||
tables.functions(xmin, xmax, xscl, functions, headerrow=True)
|
tables.functions(xmin, xmax, xstep, functions, headerrow=True)
|
||||||
```
|
```
|
||||||
|
|
||||||

|

|
||||||
@ -128,12 +128,12 @@ import tables
|
|||||||
|
|
||||||
xmin = -10
|
xmin = -10
|
||||||
xmax = 10
|
xmax = 10
|
||||||
xscl = 2
|
xstep = 0.5
|
||||||
|
|
||||||
# Function parameter and return value can be any data type, as long as they are the same
|
# Function parameter and return value can be any data type, as long as they are the same
|
||||||
functions = [lambda x: 2 * x, lambda x: x ** 2]
|
functions = [lambda x: 2 * x, lambda x: x ** 2]
|
||||||
|
|
||||||
tables.functions(xmin, xmax, xscl, functions, headerrow=True)
|
tables.functions(xmin, xmax, xstep, functions, headerrow=True)
|
||||||
```
|
```
|
||||||
|
|
||||||
Output same as example above.
|
Output same as example above.
|
||||||
@ -174,7 +174,8 @@ Default value: `1`
|
|||||||
Option: `alignment`\
|
Option: `alignment`\
|
||||||
Values:
|
Values:
|
||||||
|
|
||||||
* `False` (left, default)
|
* `None` (default)
|
||||||
|
* `False` (left)
|
||||||
* `True` (right)
|
* `True` (right)
|
||||||
|
|
||||||
#### Title
|
#### Title
|
||||||
@ -189,33 +190,40 @@ The title is word wrapped based on the current width of the terminal. Handles ne
|
|||||||
Option: `style`\
|
Option: `style`\
|
||||||
Values:
|
Values:
|
||||||
|
|
||||||
0. ASCII
|
0. `style_types.ASCII`: ASCII
|
||||||
|
|
||||||

|

|
||||||
1. Basic
|
1. `style_types.basic`: Basic
|
||||||
|
|
||||||

|

|
||||||
2. Light (default)
|
2. `style_types.light`: Light (default)
|
||||||
|
|
||||||

|

|
||||||
3. Heavy
|
3. `style_types.heavy`: Heavy
|
||||||
|
|
||||||

|

|
||||||
4. Double
|
4. `style_types.double`: Double
|
||||||
|
|
||||||

|

|
||||||
5. Light Dashed
|
5. `style_types.light_dashed`: Light Dashed
|
||||||
|
|
||||||

|

|
||||||
6. Heavy Dashed
|
6. `style_types.heavy_dashed`: Heavy Dashed
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
#### Check size
|
||||||
|
|
||||||
|
Option: `check`\
|
||||||
|
Default value: `True`
|
||||||
|
|
||||||
|
Check that the width of the table is not greater then the width of the terminal.
|
||||||
|
|
||||||
## Graphs/Plots
|
## Graphs/Plots
|
||||||
|
|
||||||
### Usage
|
### Usage
|
||||||
|
|
||||||
Requires Python 3.5 or greater and the [wcwidth library](https://pypi.org/project/wcwidth/), which users can install with: `pip3 install wcwidth`. See the [graphs.py](graphs.py) file for full usage information.
|
Requires Python 3.6 or greater and the [wcwidth library](https://pypi.org/project/wcwidth/), which users can install with: `pip3 install wcwidth`. See the [graphs.py](graphs.py) file for full usage information.
|
||||||
|
|
||||||
Complete versions of all of the examples below and more can be found in the [test.py](test.py) file.
|
Complete versions of all of the examples below and more can be found in the [test.py](test.py) file.
|
||||||
|
|
||||||
@ -369,25 +377,25 @@ The title is word wrapped based on the current width of the terminal. Handles ne
|
|||||||
Option: `style`\
|
Option: `style`\
|
||||||
Values:
|
Values:
|
||||||
|
|
||||||
0. ASCII
|
0. `style_types.ASCII`: ASCII
|
||||||
|
|
||||||

|

|
||||||
1. Basic
|
1. `style_types.basic`: Basic
|
||||||
|
|
||||||

|

|
||||||
2. Light (default)
|
2. `style_types.light`: Light (default)
|
||||||
|
|
||||||

|

|
||||||
3. Heavy
|
3. `style_types.heavy`: Heavy
|
||||||
|
|
||||||

|

|
||||||
4. Double
|
4. `style_types.double`: Double
|
||||||
|
|
||||||

|

|
||||||
5. Light Dashed
|
5. `style_types.light_dashed`: Light Dashed
|
||||||
|
|
||||||

|

|
||||||
6. Heavy Dashed
|
6. `style_types.heavy_dashed`: Heavy Dashed
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@ -396,27 +404,25 @@ Values:
|
|||||||
Option: `color`\
|
Option: `color`\
|
||||||
Values:
|
Values:
|
||||||
|
|
||||||
0. System default
|
0. `color_types.default`: System default
|
||||||
1. Black
|
1. `color_types.black`: Black
|
||||||
2. Red (default)
|
2. `color_types.red`: Red (default)
|
||||||
3. Green
|
3. `color_types.green`: Green
|
||||||
4. Yellow
|
4. `color_types.yellow`: Yellow
|
||||||
5. Blue
|
5. `color_types.blue`: Blue
|
||||||
6. Cyan
|
6. `color_types.cyan`: Cyan
|
||||||
7. Light gray
|
7. `color_types.dark_gray`: Light gray
|
||||||
8. Dark gray
|
8. `color_types.dark_gray`: Dark gray
|
||||||
9. Light red
|
9. `color_types.light_red`: Light red
|
||||||
10. Light green
|
10. `color_types.light_green`: Light green
|
||||||
11. Light yellow
|
11. `color_types.light_yellow`: Light yellow
|
||||||
12. Light blue
|
12. `color_types.light_blue`: Light blue
|
||||||
13. Light cyan
|
13. `color_types.light_cyan`: Light cyan
|
||||||
14. White
|
14. `color_types.white`: White
|
||||||
|
|
||||||
See [here](https://misc.flogisoft.com/bash/tip_colors_and_formatting#foreground_text) for examples of the colors.
|
See [here](https://misc.flogisoft.com/bash/tip_colors_and_formatting#foreground_text) for examples of the colors.
|
||||||
|
|
||||||
Only used for plots and when graphing a single function.
|
Only used when plotting a single array and when graphing a single function. When plotting multiple arrays or graphing multiple functions, colors 2 - 14 are used inorder. The system default color is used where the plots cross.
|
||||||
|
|
||||||
When graphing multiple functions, colors `2` - `14` are used inorder. Color `0` is used where the functions cross.
|
|
||||||
|
|
||||||
##### Plot
|
##### Plot
|
||||||
|
|
||||||
@ -425,3 +431,10 @@ When graphing multiple functions, colors `2` - `14` are used inorder. Color `0`
|
|||||||
##### Graph
|
##### Graph
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
#### Check size
|
||||||
|
|
||||||
|
Option: `check`\
|
||||||
|
Default value: `True`
|
||||||
|
|
||||||
|
Check that the width and height of the graph are not greater then the respective width and height of the terminal.
|
||||||
|
382
python/graphs.py
382
python/graphs.py
@ -7,13 +7,26 @@ from __future__ import division, print_function, unicode_literals
|
|||||||
import sys
|
import sys
|
||||||
import math
|
import math
|
||||||
import shutil
|
import shutil
|
||||||
|
from fractions import Fraction
|
||||||
import textwrap
|
import textwrap
|
||||||
|
from enum import Enum, IntEnum, auto
|
||||||
from wcwidth import wcswidth
|
from wcwidth import wcswidth
|
||||||
from typing import List, Tuple, Optional, Sequence, Callable
|
from typing import List, Tuple, Optional, Sequence, Callable
|
||||||
import locale
|
import locale
|
||||||
|
|
||||||
locale.setlocale(locale.LC_ALL, '')
|
locale.setlocale(locale.LC_ALL, '')
|
||||||
|
|
||||||
|
|
||||||
|
class style_types(IntEnum):
|
||||||
|
ASCII = 0
|
||||||
|
basic = auto()
|
||||||
|
light = auto()
|
||||||
|
heavy = auto()
|
||||||
|
double = auto()
|
||||||
|
light_dashed = auto()
|
||||||
|
heavy_dashed = auto()
|
||||||
|
|
||||||
|
|
||||||
styles = [
|
styles = [
|
||||||
["-", "|", "+", "+", "+", "+", "+", "+", "+", "+", "+"], # ASCII
|
["-", "|", "+", "+", "+", "+", "+", "+", "+", "+", "+"], # ASCII
|
||||||
["—", "|", "+", "+", "+", "+", "+", "+", "+", "+", "+"], # Basic
|
["—", "|", "+", "+", "+", "+", "+", "+", "+", "+", "+"], # Basic
|
||||||
@ -25,33 +38,71 @@ styles = [
|
|||||||
]
|
]
|
||||||
# [" ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "]] #No border
|
# [" ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "]] #No border
|
||||||
|
|
||||||
colors = ["\033[39m", "\033[30m", "\033[31m", "\033[32m", "\033[33m", "\033[34m", "\033[35m", "\033[36m",
|
|
||||||
"\033[37m", "\033[90m", "\033[91m", "\033[92m", "\033[93m", "\033[94m", "\033[95m", "\033[96m", "\033[97m"]
|
|
||||||
|
|
||||||
dots = ["⠀", "⠁", "⠂", "⠃", "⠄", "⠅", "⠆", "⠇", "⠈", "⠉", "⠊", "⠋", "⠌", "⠍", "⠎", "⠏", "⠐", "⠑", "⠒", "⠓", "⠔", "⠕", "⠖", "⠗", "⠘", "⠙", "⠚", "⠛", "⠜", "⠝", "⠞", "⠟", "⠠", "⠡", "⠢", "⠣", "⠤", "⠥", "⠦", "⠧", "⠨", "⠩", "⠪", "⠫", "⠬", "⠭", "⠮", "⠯", "⠰", "⠱", "⠲", "⠳", "⠴", "⠵", "⠶", "⠷", "⠸", "⠹", "⠺", "⠻", "⠼", "⠽", "⠾", "⠿", "⡀", "⡁", "⡂", "⡃", "⡄", "⡅", "⡆", "⡇", "⡈", "⡉", "⡊", "⡋", "⡌", "⡍", "⡎", "⡏", "⡐", "⡑", "⡒", "⡓", "⡔", "⡕", "⡖", "⡗", "⡘", "⡙", "⡚", "⡛", "⡜", "⡝", "⡞", "⡟", "⡠", "⡡", "⡢", "⡣", "⡤", "⡥", "⡦", "⡧", "⡨", "⡩", "⡪", "⡫", "⡬", "⡭", "⡮", "⡯", "⡰", "⡱", "⡲", "⡳", "⡴", "⡵", "⡶", "⡷", "⡸", "⡹", "⡺", "⡻", "⡼", "⡽", "⡾",
|
class color_types(IntEnum):
|
||||||
"⡿", "⢀", "⢁", "⢂", "⢃", "⢄", "⢅", "⢆", "⢇", "⢈", "⢉", "⢊", "⢋", "⢌", "⢍", "⢎", "⢏", "⢐", "⢑", "⢒", "⢓", "⢔", "⢕", "⢖", "⢗", "⢘", "⢙", "⢚", "⢛", "⢜", "⢝", "⢞", "⢟", "⢠", "⢡", "⢢", "⢣", "⢤", "⢥", "⢦", "⢧", "⢨", "⢩", "⢪", "⢫", "⢬", "⢭", "⢮", "⢯", "⢰", "⢱", "⢲", "⢳", "⢴", "⢵", "⢶", "⢷", "⢸", "⢹", "⢺", "⢻", "⢼", "⢽", "⢾", "⢿", "⣀", "⣁", "⣂", "⣃", "⣄", "⣅", "⣆", "⣇", "⣈", "⣉", "⣊", "⣋", "⣌", "⣍", "⣎", "⣏", "⣐", "⣑", "⣒", "⣓", "⣔", "⣕", "⣖", "⣗", "⣘", "⣙", "⣚", "⣛", "⣜", "⣝", "⣞", "⣟", "⣠", "⣡", "⣢", "⣣", "⣤", "⣥", "⣦", "⣧", "⣨", "⣩", "⣪", "⣫", "⣬", "⣭", "⣮", "⣯", "⣰", "⣱", "⣲", "⣳", "⣴", "⣵", "⣶", "⣷", "⣸", "⣹", "⣺", "⣻", "⣼", "⣽", "⣾", "⣿"]
|
default = 0
|
||||||
|
black = auto()
|
||||||
|
red = auto()
|
||||||
|
green = auto()
|
||||||
|
yellow = auto()
|
||||||
|
blue = auto()
|
||||||
|
cyan = auto()
|
||||||
|
light_gray = auto()
|
||||||
|
dark_gray = auto()
|
||||||
|
light_red = auto()
|
||||||
|
light_green = auto()
|
||||||
|
light_yellow = auto()
|
||||||
|
light_blue = auto()
|
||||||
|
light_cyan = auto()
|
||||||
|
white = auto()
|
||||||
|
|
||||||
|
|
||||||
|
colors = ["\033[39m", "\033[30m", "\033[31m", "\033[32m", "\033[33m",
|
||||||
|
"\033[34m", "\033[35m", "\033[36m", "\033[37m", "\033[90m",
|
||||||
|
"\033[91m", "\033[92m", "\033[93m", "\033[94m", "\033[95m",
|
||||||
|
"\033[96m", "\033[97m"]
|
||||||
|
|
||||||
|
dots = [
|
||||||
|
"⠀", "⠁", "⠂", "⠃", "⠄", "⠅", "⠆", "⠇", "⠈", "⠉", "⠊", "⠋", "⠌", "⠍", "⠎",
|
||||||
|
"⠏", "⠐", "⠑", "⠒", "⠓", "⠔", "⠕", "⠖", "⠗", "⠘", "⠙", "⠚", "⠛", "⠜", "⠝",
|
||||||
|
"⠞", "⠟", "⠠", "⠡", "⠢", "⠣", "⠤", "⠥", "⠦", "⠧", "⠨", "⠩", "⠪", "⠫", "⠬",
|
||||||
|
"⠭", "⠮", "⠯", "⠰", "⠱", "⠲", "⠳", "⠴", "⠵", "⠶", "⠷", "⠸", "⠹", "⠺", "⠻",
|
||||||
|
"⠼", "⠽", "⠾", "⠿", "⡀", "⡁", "⡂", "⡃", "⡄", "⡅", "⡆", "⡇", "⡈", "⡉", "⡊",
|
||||||
|
"⡋", "⡌", "⡍", "⡎", "⡏", "⡐", "⡑", "⡒", "⡓", "⡔", "⡕", "⡖", "⡗", "⡘", "⡙",
|
||||||
|
"⡚", "⡛", "⡜", "⡝", "⡞", "⡟", "⡠", "⡡", "⡢", "⡣", "⡤", "⡥", "⡦", "⡧", "⡨",
|
||||||
|
"⡩", "⡪", "⡫", "⡬", "⡭", "⡮", "⡯", "⡰", "⡱", "⡲", "⡳", "⡴", "⡵", "⡶", "⡷",
|
||||||
|
"⡸", "⡹", "⡺", "⡻", "⡼", "⡽", "⡾", "⡿", "⢀", "⢁", "⢂", "⢃", "⢄", "⢅", "⢆",
|
||||||
|
"⢇", "⢈", "⢉", "⢊", "⢋", "⢌", "⢍", "⢎", "⢏", "⢐", "⢑", "⢒", "⢓", "⢔", "⢕",
|
||||||
|
"⢖", "⢗", "⢘", "⢙", "⢚", "⢛", "⢜", "⢝", "⢞", "⢟", "⢠", "⢡", "⢢", "⢣", "⢤",
|
||||||
|
"⢥", "⢦", "⢧", "⢨", "⢩", "⢪", "⢫", "⢬", "⢭", "⢮", "⢯", "⢰", "⢱", "⢲", "⢳",
|
||||||
|
"⢴", "⢵", "⢶", "⢷", "⢸", "⢹", "⢺", "⢻", "⢼", "⢽", "⢾", "⢿", "⣀", "⣁", "⣂",
|
||||||
|
"⣃", "⣄", "⣅", "⣆", "⣇", "⣈", "⣉", "⣊", "⣋", "⣌", "⣍", "⣎", "⣏", "⣐", "⣑",
|
||||||
|
"⣒", "⣓", "⣔", "⣕", "⣖", "⣗", "⣘", "⣙", "⣚", "⣛", "⣜", "⣝", "⣞", "⣟", "⣠",
|
||||||
|
"⣡", "⣢", "⣣", "⣤", "⣥", "⣦", "⣧", "⣨", "⣩", "⣪", "⣫", "⣬", "⣭", "⣮", "⣯",
|
||||||
|
"⣰", "⣱", "⣲", "⣳", "⣴", "⣵", "⣶", "⣷", "⣸", "⣹", "⣺", "⣻", "⣼", "⣽", "⣾",
|
||||||
|
"⣿"]
|
||||||
|
|
||||||
values = [[0x1, 0x2, 0x4, 0x40], [0x8, 0x10, 0x20, 0x80]]
|
values = [[0x1, 0x2, 0x4, 0x40], [0x8, 0x10, 0x20, 0x80]]
|
||||||
|
|
||||||
fractions = {
|
fractions = {
|
||||||
"¼": 1.0 / 4.0,
|
"¼": Fraction(1, 4),
|
||||||
"½": 1.0 / 2.0,
|
"½": Fraction(1, 2),
|
||||||
"¾": 3.0 / 4.0,
|
"¾": Fraction(3, 4),
|
||||||
"⅐": 1.0 / 7.0,
|
"⅐": Fraction(1, 7),
|
||||||
"⅑": 1.0 / 9.0,
|
"⅑": Fraction(1, 9),
|
||||||
"⅒": 1.0 / 10.0,
|
"⅒": Fraction(1, 10),
|
||||||
"⅓": 1.0 / 3.0,
|
"⅓": Fraction(1, 3),
|
||||||
"⅔": 2.0 / 3.0,
|
"⅔": Fraction(2, 3),
|
||||||
"⅕": 1.0 / 5.0,
|
"⅕": Fraction(1, 5),
|
||||||
"⅖": 2.0 / 5.0,
|
"⅖": Fraction(2, 5),
|
||||||
"⅗": 3.0 / 5.0,
|
"⅗": Fraction(3, 5),
|
||||||
"⅘": 4.0 / 5.0,
|
"⅘": Fraction(4, 5),
|
||||||
"⅙": 1.0 / 6.0,
|
"⅙": Fraction(1, 6),
|
||||||
"⅚": 5.0 / 6.0,
|
"⅚": Fraction(5, 6),
|
||||||
"⅛": 1.0 / 8.0,
|
"⅛": Fraction(1, 8),
|
||||||
"⅜": 3.0 / 8.0,
|
"⅜": Fraction(3, 8),
|
||||||
"⅝": 5.0 / 8.0,
|
"⅝": Fraction(5, 8),
|
||||||
"⅞": 7.0 / 8.0
|
"⅞": Fraction(7, 8)
|
||||||
}
|
}
|
||||||
|
|
||||||
constants = {
|
constants = {
|
||||||
@ -59,68 +110,75 @@ constants = {
|
|||||||
"e": math.e
|
"e": math.e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MAX = sys.float_info.radix ** sys.float_info.mant_dig - 1
|
||||||
|
|
||||||
def strcol(str: str) -> int:
|
|
||||||
|
def strcol(astr: str) -> int:
|
||||||
"""Returns the number of columns that the given string would take up if printed."""
|
"""Returns the number of columns that the given string would take up if printed."""
|
||||||
width = wcswidth(str)
|
width = wcswidth(astr)
|
||||||
if width == -1:
|
if width == -1:
|
||||||
print("\nError! wcswidth failed. Nonprintable wide character.", file=sys.stderr)
|
print(
|
||||||
|
"\nError! wcswidth failed. Nonprintable wide character.",
|
||||||
|
file=sys.stderr)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
return width
|
return width
|
||||||
# return len(str)
|
# return len(astr)
|
||||||
|
|
||||||
|
|
||||||
def outputlabel(label: float) -> Tuple[int, str]:
|
def outputfraction(number: float) -> Tuple[int, str]:
|
||||||
"""Outputs a label in a nice, human readable format."""
|
|
||||||
"""Convert fractions and constants to Unicode characters"""
|
"""Convert fractions and constants to Unicode characters"""
|
||||||
output = False
|
output = False
|
||||||
|
|
||||||
fractionpart, intpart = math.modf(label)
|
|
||||||
fractionpart = abs(fractionpart)
|
|
||||||
|
|
||||||
strm = ""
|
strm = ""
|
||||||
|
|
||||||
for fraction in fractions:
|
n = abs(number)
|
||||||
if abs(fractionpart - fractions[fraction]) < sys.float_info.epsilon:
|
|
||||||
if intpart != 0:
|
|
||||||
strm += str(intpart)
|
|
||||||
|
|
||||||
strm += fraction
|
if n <= MAX:
|
||||||
|
# fractionpart, intpart = math.modf(number)
|
||||||
|
# fractionpart = abs(fractionpart)
|
||||||
|
intpart, fractionpart = divmod(Fraction(number).limit_denominator(), 1)
|
||||||
|
|
||||||
output = True
|
for fraction, value in fractions.items():
|
||||||
break
|
if abs(fractionpart - value) <= sys.float_info.epsilon * n:
|
||||||
|
if intpart == 0 and number < 0:
|
||||||
if abs(label) >= sys.float_info.epsilon and not output:
|
|
||||||
for constant in constants:
|
|
||||||
if not output and label % constants[constant] == 0:
|
|
||||||
intpart = label / constants[constant]
|
|
||||||
|
|
||||||
if intpart == -1:
|
|
||||||
strm += "-"
|
strm += "-"
|
||||||
elif intpart != 1:
|
elif intpart != 0:
|
||||||
strm += str(intpart)
|
strm += "{0:n}".format(intpart)
|
||||||
|
|
||||||
strm += constant
|
strm += fraction
|
||||||
|
|
||||||
output = True
|
output = True
|
||||||
break
|
break
|
||||||
|
|
||||||
|
if n > sys.float_info.epsilon and not output:
|
||||||
|
for constant, value in constants.items():
|
||||||
|
if not output and number % value <= sys.float_info.epsilon * n:
|
||||||
|
intpart = number / value
|
||||||
|
|
||||||
|
if intpart == -1:
|
||||||
|
strm += "-"
|
||||||
|
elif intpart != 1:
|
||||||
|
strm += "{0:.{prec}n}".format(intpart,
|
||||||
|
prec=sys.float_info.dig)
|
||||||
|
|
||||||
|
strm += constant
|
||||||
|
|
||||||
|
output = True
|
||||||
|
break
|
||||||
|
|
||||||
if not output:
|
if not output:
|
||||||
strm += "{0:n}".format(label)
|
strm += "{0:n}".format(number)
|
||||||
|
|
||||||
length = strcol(strm)
|
length = strcol(strm)
|
||||||
|
|
||||||
return length, strm
|
return length, strm
|
||||||
|
|
||||||
|
|
||||||
def graph(height: int, width: int, xmin: float, xmax: float, ymin: float, ymax: float, array: List[List[int]], border: bool = True, axislabel: bool = True, axisunitslabel: bool = True, style: int = 2, title: Optional[str] = None) -> int:
|
def graph(height: int, width: int, xmin: float, xmax: float, ymin: float, ymax: float, array: List[List[int]], border: bool = True, axislabel: bool = True, axisunitslabel: bool = True, style: style_types = style_types.light, title: Optional[str] = None, check: bool = True) -> int:
|
||||||
"""Output graph"""
|
"""Output graph"""
|
||||||
if not array:
|
if not array:
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
if not (0 <= style < len(styles)):
|
|
||||||
return 1
|
|
||||||
|
|
||||||
if height == 0:
|
if height == 0:
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
@ -129,18 +187,19 @@ def graph(height: int, width: int, xmin: float, xmax: float, ymin: float, ymax:
|
|||||||
|
|
||||||
w = shutil.get_terminal_size()
|
w = shutil.get_terminal_size()
|
||||||
|
|
||||||
aheight = height // 4
|
if check:
|
||||||
awidth = width // 2
|
aheight = height // 4
|
||||||
|
awidth = width // 2
|
||||||
|
|
||||||
if aheight > w.lines:
|
if aheight > w.lines:
|
||||||
print("The height of the graph ({0}) is greater then the height of the terminal ({1}).".format(
|
print("The height of the graph ({0}) is greater then the height of the terminal ({1}).".format(
|
||||||
aheight, w.lines), file=sys.stderr)
|
aheight, w.lines), file=sys.stderr)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
if awidth > w.columns:
|
if awidth > w.columns:
|
||||||
print("The width of the graph ({0}) is greater then the width of the terminal ({1}).".format(
|
print("The width of the graph ({0}) is greater then the width of the terminal ({1}).".format(
|
||||||
awidth, w.columns), file=sys.stderr)
|
awidth, w.columns), file=sys.stderr)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
if xmin >= xmax:
|
if xmin >= xmax:
|
||||||
print("xmin must be less than xmax.", file=sys.stderr)
|
print("xmin must be less than xmax.", file=sys.stderr)
|
||||||
@ -150,46 +209,51 @@ def graph(height: int, width: int, xmin: float, xmax: float, ymin: float, ymax:
|
|||||||
print("ymin must be less than ymax.", file=sys.stderr)
|
print("ymin must be less than ymax.", file=sys.stderr)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
xscl = width / (xmax - xmin)
|
xstep = (xmax - xmin) / width
|
||||||
yscl = height / (ymax - ymin)
|
ystep = (ymax - ymin) / height
|
||||||
xaxis = width - (xmax * xscl)
|
xaxis = 0 if xmin > 0 else width if xmax < 0 else width - (xmax / xstep)
|
||||||
yaxis = ymax * yscl
|
yaxis = height if ymin > 0 else 0 if ymax < 0 else ymax / ystep
|
||||||
divisor = 2 * 4 * ((width // 160) + 1 if (width / 160.0) > 1 else 1)
|
xdivisor = 2 * 4 * ((width // 160) + 2)
|
||||||
|
ydivisor = 2 * 4 * ((height // 160) + 2)
|
||||||
|
|
||||||
if title:
|
if title:
|
||||||
print(textwrap.fill(title, width=w.columns))
|
print(textwrap.fill(title, width=width // 2))
|
||||||
|
|
||||||
strm = ""
|
strm = ""
|
||||||
|
|
||||||
i = 0
|
i = 0
|
||||||
while i < height:
|
while i < height:
|
||||||
ayaxis = i <= yaxis and (i + 4) > yaxis
|
ayaxis = i <= yaxis and (
|
||||||
yaxislabel = i <= (yaxis + 4) and (i + 4) > (yaxis + 4)
|
i + 4) > yaxis if yaxis <= (height - 4) else i < yaxis and (i + 4) >= yaxis
|
||||||
|
yaxislabel = i <= (yaxis + 4) and (i + 4) > (yaxis + 4) if yaxis <= (
|
||||||
|
height - 4) else i < (yaxis - 4) and (i + 4) >= (yaxis - 4)
|
||||||
|
|
||||||
ylabelstrm = ""
|
ylabelstrm = ""
|
||||||
ylabellength = 0
|
ylabellength = 0
|
||||||
|
|
||||||
if border and axislabel and axisunitslabel:
|
if border and axislabel and axisunitslabel and yaxis >= 0 and yaxis <= height:
|
||||||
output = False
|
output = False
|
||||||
label = 0.0
|
label = 0.0
|
||||||
adivisor = -divisor if i < yaxis else divisor
|
adivisor = -ydivisor if i < yaxis else ydivisor
|
||||||
|
|
||||||
k = yaxis + adivisor
|
k = yaxis + adivisor
|
||||||
while ((i < yaxis and k >= i) or (i > yaxis and k < (i + 4))) and i >= 4 and not output:
|
while (k >= i if i < yaxis else k < (i + 4)) and i >= 4 and not output:
|
||||||
if (i <= k and (i + 4) > k):
|
if (i <= k and (i + 4) > k):
|
||||||
label = ymax - (k / yscl)
|
label = ymax - ((height if k > height else k) * ystep)
|
||||||
|
|
||||||
output = True
|
output = True
|
||||||
k += adivisor
|
k += adivisor
|
||||||
|
|
||||||
if (output):
|
if (output):
|
||||||
ylabellength, ylabelstrm = outputlabel(label)
|
ylabellength, ylabelstrm = outputfraction(label)
|
||||||
ylabellength *= 2
|
ylabellength *= 2
|
||||||
|
|
||||||
j = 0
|
j = 0
|
||||||
while j < width:
|
while j < width:
|
||||||
axaxis = j <= xaxis and (j + 2) > xaxis
|
axaxis = j < xaxis and (
|
||||||
xaxislabel = j <= (xaxis - 2) and (j + 2) > (xaxis - 2)
|
j + 2) >= xaxis if xaxis >= 2 else j <= xaxis and (j + 2) > xaxis
|
||||||
|
xaxislabel = j < (xaxis - 2) and (j + 2) >= (
|
||||||
|
xaxis - 2) if xaxis >= 2 else j <= (xaxis + 2) and (j + 2) > (xaxis + 2)
|
||||||
|
|
||||||
output = False
|
output = False
|
||||||
|
|
||||||
@ -198,57 +262,61 @@ def graph(height: int, width: int, xmin: float, xmax: float, ymin: float, ymax:
|
|||||||
strm += styles[style][6]
|
strm += styles[style][6]
|
||||||
output = True
|
output = True
|
||||||
elif axaxis:
|
elif axaxis:
|
||||||
if axislabel and axisunitslabel:
|
if i == 0:
|
||||||
adivisor = -divisor if i < yaxis else divisor
|
strm += styles[style][4]
|
||||||
|
output = True
|
||||||
|
elif i >= (height - 4):
|
||||||
|
strm += styles[style][10]
|
||||||
|
output = True
|
||||||
|
elif axislabel and axisunitslabel:
|
||||||
|
adivisor = -ydivisor if i < yaxis else ydivisor
|
||||||
|
|
||||||
k = yaxis + adivisor
|
k = yaxis + adivisor
|
||||||
while ((i < yaxis and k >= i) or (i > yaxis and k < (i + 4))) and i >= 4 and not output:
|
while (k >= i if i < yaxis else k < (i + 4)) and i >= 4 and not output:
|
||||||
if i <= k and (i + 4) > k:
|
if i <= k and (i + 4) > k:
|
||||||
strm += styles[style][7]
|
strm += styles[style][7 if xaxis >= 2 else 5]
|
||||||
output = True
|
output = True
|
||||||
k += adivisor
|
k += adivisor
|
||||||
if not output:
|
if not output:
|
||||||
if i == 0:
|
strm += styles[style][1]
|
||||||
strm += styles[style][4]
|
|
||||||
elif i >= (height - 4):
|
|
||||||
strm += styles[style][10]
|
|
||||||
else:
|
|
||||||
strm += styles[style][1]
|
|
||||||
output = True
|
output = True
|
||||||
elif ayaxis:
|
elif ayaxis:
|
||||||
if axislabel and axisunitslabel:
|
if j == 0:
|
||||||
adivisor = -divisor if j < xaxis else divisor
|
strm += styles[style][2]
|
||||||
|
output = True
|
||||||
|
elif j >= (width - 2):
|
||||||
|
strm += styles[style][4]
|
||||||
|
output = True
|
||||||
|
elif axislabel and axisunitslabel:
|
||||||
|
adivisor = -xdivisor if j < xaxis else xdivisor
|
||||||
|
|
||||||
k = xaxis + adivisor
|
k = xaxis + adivisor
|
||||||
while ((j < xaxis and k >= j) or (j > xaxis and k < (j + 2))) and j < (width - 4) and not output:
|
while (k >= j if j < xaxis else k < (j + 2)) and j < (width - 4) and not output:
|
||||||
if j <= k and (j + 2) > k:
|
if j <= k and (j + 2) > k:
|
||||||
strm += styles[style][3]
|
strm += styles[style][3 if yaxis <=
|
||||||
|
(height - 4) else 9]
|
||||||
output = True
|
output = True
|
||||||
k += adivisor
|
k += adivisor
|
||||||
if not output:
|
if not output:
|
||||||
if j == 0:
|
strm += styles[style][0]
|
||||||
strm += styles[style][2]
|
|
||||||
elif j >= (width - 2):
|
|
||||||
strm += styles[style][4]
|
|
||||||
else:
|
|
||||||
strm += styles[style][0]
|
|
||||||
output = True
|
output = True
|
||||||
elif yaxislabel and xaxislabel and axislabel and axisunitslabel:
|
elif yaxislabel and xaxislabel and axislabel and axisunitslabel and ymin <= 0 and ymax >= 0 and xmin <= 0 and xmax >= 0:
|
||||||
strm += "0"
|
strm += "0"
|
||||||
output = True
|
output = True
|
||||||
elif j >= (width - 2) and yaxislabel and axislabel:
|
elif (j >= (width - 2) if xaxis <= (width - 2) else j == 0) and yaxislabel and axislabel:
|
||||||
strm += "x"
|
strm += "x"
|
||||||
output = True
|
output = True
|
||||||
elif yaxislabel and axislabel and axisunitslabel:
|
elif yaxislabel and axislabel and axisunitslabel:
|
||||||
label = 0.0
|
label = 0.0
|
||||||
adivisor = -divisor if j < xaxis else divisor
|
adivisor = -xdivisor if j < xaxis else xdivisor
|
||||||
if j < xaxis:
|
if j < xaxis:
|
||||||
j += 2
|
j += 2
|
||||||
|
|
||||||
k = xaxis + adivisor
|
k = xaxis + adivisor
|
||||||
while ((j < xaxis and k >= j) or (j > xaxis and k < (j + 2))) and j < (width - 2) and not output:
|
while (k >= j if j < xaxis else k < (j + 2)) and j < (width - 2) and not output:
|
||||||
if j <= k and (j + 2) > k:
|
if j <= k and (j + 2) > k:
|
||||||
label = (k / xscl) + xmin
|
label = ((width if k > width else k)
|
||||||
|
* xstep) + xmin
|
||||||
|
|
||||||
output = True
|
output = True
|
||||||
k += adivisor
|
k += adivisor
|
||||||
@ -259,7 +327,7 @@ def graph(height: int, width: int, xmin: float, xmax: float, ymin: float, ymax:
|
|||||||
if output:
|
if output:
|
||||||
output = False
|
output = False
|
||||||
|
|
||||||
length, astrm = outputlabel(label)
|
length, astrm = outputfraction(label)
|
||||||
length *= 2
|
length *= 2
|
||||||
if (j >= xaxis or (j + length) < (xaxis - 4)) and (j + length) < (width - 2):
|
if (j >= xaxis or (j + length) < (xaxis - 4)) and (j + length) < (width - 2):
|
||||||
strm += astrm
|
strm += astrm
|
||||||
@ -271,10 +339,10 @@ def graph(height: int, width: int, xmin: float, xmax: float, ymin: float, ymax:
|
|||||||
output = True
|
output = True
|
||||||
else:
|
else:
|
||||||
j += 2
|
j += 2
|
||||||
elif i == 0 and xaxislabel and axislabel:
|
elif (i == 0 if yaxis >= 4 else i >= (height - 4)) and xaxislabel and axislabel:
|
||||||
strm += "y"
|
strm += "y"
|
||||||
output = True
|
output = True
|
||||||
elif (j <= (xaxis - ylabellength) and (j + 2) > (xaxis - ylabellength)) and axislabel and axisunitslabel:
|
elif ylabellength and (xaxislabel if xaxis < 2 else j < (xaxis - ylabellength) and (j + 2) >= (xaxis - ylabellength)) and (yaxis >= 4 or i < (height - 4)) and axislabel and axisunitslabel:
|
||||||
strm += ylabelstrm
|
strm += ylabelstrm
|
||||||
output = True
|
output = True
|
||||||
if ylabellength > 2:
|
if ylabellength > 2:
|
||||||
@ -299,14 +367,15 @@ def graph(height: int, width: int, xmin: float, xmax: float, ymin: float, ymax:
|
|||||||
if color:
|
if color:
|
||||||
strm += colors[color]
|
strm += colors[color]
|
||||||
|
|
||||||
strm += "\033[1m" + dots[dot] + "\033[22m"
|
strm += dots[dot]
|
||||||
|
|
||||||
if color:
|
if color:
|
||||||
strm += colors[0]
|
strm += colors[0]
|
||||||
|
|
||||||
j += 2
|
j += 2
|
||||||
|
|
||||||
strm += "\n"
|
if i < (height - 4):
|
||||||
|
strm += "\n"
|
||||||
i += 4
|
i += 4
|
||||||
|
|
||||||
print(strm)
|
print(strm)
|
||||||
@ -314,7 +383,7 @@ def graph(height: int, width: int, xmin: float, xmax: float, ymin: float, ymax:
|
|||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
def arrays(height: int, width: int, xmin: float, xmax: float, ymin: float, ymax: float, aarrays: Sequence[Sequence[Sequence[float]]], border: bool = True, axislabel: bool = True, axisunitslabel: bool = True, style: int = 2, color: int = 2, title: Optional[str] = None) -> int:
|
def arrays(height: int, width: int, xmin: float, xmax: float, ymin: float, ymax: float, aarrays: Sequence[Sequence[Sequence[float]]], border: bool = True, axislabel: bool = True, axisunitslabel: bool = True, style: style_types = style_types.light, color: color_types = color_types.red, title: Optional[str] = None, check: bool = True) -> int:
|
||||||
"""Convert one or more arrays to graph and output"""
|
"""Convert one or more arrays to graph and output"""
|
||||||
if not aarrays:
|
if not aarrays:
|
||||||
return 1
|
return 1
|
||||||
@ -323,9 +392,6 @@ def arrays(height: int, width: int, xmin: float, xmax: float, ymin: float, ymax:
|
|||||||
print("Error: The arrays must have two columns.")
|
print("Error: The arrays must have two columns.")
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
if color < 0 or color >= len(colors):
|
|
||||||
return 1
|
|
||||||
|
|
||||||
w = shutil.get_terminal_size()
|
w = shutil.get_terminal_size()
|
||||||
|
|
||||||
if height == 0:
|
if height == 0:
|
||||||
@ -334,18 +400,19 @@ def arrays(height: int, width: int, xmin: float, xmax: float, ymin: float, ymax:
|
|||||||
if width == 0:
|
if width == 0:
|
||||||
width = w.columns * 2
|
width = w.columns * 2
|
||||||
|
|
||||||
aheight = height // 4
|
if check:
|
||||||
awidth = width // 2
|
aheight = height // 4
|
||||||
|
awidth = width // 2
|
||||||
|
|
||||||
if aheight > w.lines:
|
if aheight > w.lines:
|
||||||
print("The height of the graph ({0}) is greater then the height of the terminal ({1}).".format(
|
print("The height of the graph ({0}) is greater then the height of the terminal ({1}).".format(
|
||||||
aheight, w.lines), file=sys.stderr)
|
aheight, w.lines), file=sys.stderr)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
if awidth > w.columns:
|
if awidth > w.columns:
|
||||||
print("The width of the graph ({0}) is greater then the width of the terminal ({1}).".format(
|
print("The width of the graph ({0}) is greater then the width of the terminal ({1}).".format(
|
||||||
awidth, w.columns), file=sys.stderr)
|
awidth, w.columns), file=sys.stderr)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
if xmin == 0 and xmax == 0:
|
if xmin == 0 and xmax == 0:
|
||||||
xmin = min(i[0] for aarray in aarrays for i in aarray)
|
xmin = min(i[0] for aarray in aarrays for i in aarray)
|
||||||
@ -363,10 +430,10 @@ def arrays(height: int, width: int, xmin: float, xmax: float, ymin: float, ymax:
|
|||||||
print("ymin must be less than ymax.", file=sys.stderr)
|
print("ymin must be less than ymax.", file=sys.stderr)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
xscl = width / (xmax - xmin)
|
xstep = (xmax - xmin) / width
|
||||||
yscl = height / (ymax - ymin)
|
ystep = (ymax - ymin) / height
|
||||||
xaxis = width - (xmax * xscl)
|
xaxis = width - (xmax / xstep)
|
||||||
yaxis = ymax * yscl
|
yaxis = ymax / ystep
|
||||||
|
|
||||||
aaarray = [[0 for j in range(height)] for i in range(width)]
|
aaarray = [[0 for j in range(height)] for i in range(width)]
|
||||||
|
|
||||||
@ -376,8 +443,8 @@ def arrays(height: int, width: int, xmin: float, xmax: float, ymin: float, ymax:
|
|||||||
|
|
||||||
for i in aarray:
|
for i in aarray:
|
||||||
if i[0] >= xmin and i[0] < xmax and i[1] >= ymin and i[1] < ymax:
|
if i[0] >= xmin and i[0] < xmax and i[1] >= ymin and i[1] < ymax:
|
||||||
x = int((i[0] * xscl) + xaxis)
|
x = int((i[0] / xstep) + xaxis)
|
||||||
y = int((yaxis - (i[1] * yscl)) - 1)
|
y = int((yaxis - (i[1] / ystep)) - 1)
|
||||||
|
|
||||||
if aaarray[x][y]:
|
if aaarray[x][y]:
|
||||||
if aaarray[x][y] != acolor:
|
if aaarray[x][y] != acolor:
|
||||||
@ -385,19 +452,18 @@ def arrays(height: int, width: int, xmin: float, xmax: float, ymin: float, ymax:
|
|||||||
else:
|
else:
|
||||||
aaarray[x][y] = acolor
|
aaarray[x][y] = acolor
|
||||||
|
|
||||||
return graph(height, width, xmin, xmax, ymin, ymax, aaarray, border=border, axislabel=axislabel, axisunitslabel=axisunitslabel, style=style, title=title)
|
return graph(height, width, xmin, xmax, ymin, ymax, aaarray, border=border,
|
||||||
|
axislabel=axislabel, axisunitslabel=axisunitslabel, style=style, title=title)
|
||||||
|
|
||||||
|
|
||||||
def array(height: int, width: int, xmin: float, xmax: float, ymin: float, ymax: float, aarray: Sequence[Sequence[float]], border: bool = True, axislabel: bool = True, axisunitslabel: bool = True, style: int = 2, color: int = 2, title: Optional[str] = None) -> int:
|
def array(height: int, width: int, xmin: float, xmax: float, ymin: float, ymax: float, aarray: Sequence[Sequence[float]], border: bool = True, axislabel: bool = True, axisunitslabel: bool = True, style: style_types = style_types.light, color: color_types = color_types.red, title: Optional[str] = None) -> int:
|
||||||
"""Convert single array to graph and output"""
|
"""Convert single array to graph and output"""
|
||||||
return arrays(height, width, xmin, xmax, ymin, ymax, [aarray], border=border, axislabel=axislabel, axisunitslabel=axisunitslabel, style=style, color=color, title=title)
|
return arrays(height, width, xmin, xmax, ymin, ymax, [
|
||||||
|
aarray], border=border, axislabel=axislabel, axisunitslabel=axisunitslabel, style=style, color=color, title=title)
|
||||||
|
|
||||||
|
|
||||||
def functions(height: int, width: int, xmin: float, xmax: float, ymin: float, ymax: float, afunctions: Sequence[Callable[[float], float]], border: bool = True, axislabel: bool = True, axisunitslabel: bool = True, style: int = 2, color: int = 2, title: Optional[str] = None) -> int:
|
def functions(height: int, width: int, xmin: float, xmax: float, ymin: float, ymax: float, afunctions: Sequence[Callable[[float], float]], border: bool = True, axislabel: bool = True, axisunitslabel: bool = True, style: style_types = style_types.light, color: color_types = color_types.red, title: Optional[str] = None, check: bool = True) -> int:
|
||||||
"""Convert one or more functions to graph and output"""
|
"""Convert one or more functions to graph and output"""
|
||||||
if color < 0 or color >= len(colors):
|
|
||||||
return 1
|
|
||||||
|
|
||||||
if not afunctions:
|
if not afunctions:
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
@ -409,18 +475,19 @@ def functions(height: int, width: int, xmin: float, xmax: float, ymin: float, ym
|
|||||||
if width == 0:
|
if width == 0:
|
||||||
width = w.columns * 2
|
width = w.columns * 2
|
||||||
|
|
||||||
aheight = height // 4
|
if check:
|
||||||
awidth = width // 2
|
aheight = height // 4
|
||||||
|
awidth = width // 2
|
||||||
|
|
||||||
if aheight > w.lines:
|
if aheight > w.lines:
|
||||||
print("The height of the graph ({0}) is greater then the height of the terminal ({1}).".format(
|
print("The height of the graph ({0}) is greater then the height of the terminal ({1}).".format(
|
||||||
aheight, w.lines), file=sys.stderr)
|
aheight, w.lines), file=sys.stderr)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
if awidth > w.columns:
|
if awidth > w.columns:
|
||||||
print("The width of the graph ({0}) is greater then the width of the terminal ({1}).".format(
|
print("The width of the graph ({0}) is greater then the width of the terminal ({1}).".format(
|
||||||
awidth, w.columns), file=sys.stderr)
|
awidth, w.columns), file=sys.stderr)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
if xmin >= xmax:
|
if xmin >= xmax:
|
||||||
print("xmin must be less than xmax.", file=sys.stderr)
|
print("xmin must be less than xmax.", file=sys.stderr)
|
||||||
@ -432,10 +499,11 @@ def functions(height: int, width: int, xmin: float, xmax: float, ymin: float, ym
|
|||||||
|
|
||||||
rows = width
|
rows = width
|
||||||
|
|
||||||
xscl = width / (xmax - xmin)
|
xstep = (xmax - xmin) / width
|
||||||
yscl = height / (ymax - ymin)
|
ystep = (ymax - ymin) / height
|
||||||
xaxis = width - (xmax * xscl)
|
xaxis = width - (xmax / xstep)
|
||||||
yaxis = ymax * yscl
|
yaxis = ymax / ystep
|
||||||
|
xres = 2
|
||||||
|
|
||||||
array = [[0 for j in range(height)] for i in range(width)]
|
array = [[0 for j in range(height)] for i in range(width)]
|
||||||
|
|
||||||
@ -443,13 +511,13 @@ def functions(height: int, width: int, xmin: float, xmax: float, ymin: float, ym
|
|||||||
acolor = color + 1 if len(afunctions) == 1 else (j %
|
acolor = color + 1 if len(afunctions) == 1 else (j %
|
||||||
(len(colors) - 2)) + 3
|
(len(colors) - 2)) + 3
|
||||||
|
|
||||||
for i in (x / 2 for x in range(rows * 2)):
|
for i in (x / xres for x in range(rows * xres)):
|
||||||
x = (i / xscl) + xmin
|
x = (i * xstep) + xmin
|
||||||
y = function(x)
|
y = function(x)
|
||||||
|
|
||||||
if x >= xmin and x < xmax and y >= ymin and y < ymax:
|
if x >= xmin and x < xmax and y >= ymin and y < ymax:
|
||||||
ax = int((x * xscl) + xaxis)
|
ax = int((x / xstep) + xaxis)
|
||||||
ay = int((yaxis - (y * yscl)) - 1)
|
ay = int((yaxis - (y / ystep)) - 1)
|
||||||
|
|
||||||
if array[ax][ay]:
|
if array[ax][ay]:
|
||||||
if array[ax][ay] != acolor:
|
if array[ax][ay] != acolor:
|
||||||
@ -457,9 +525,11 @@ def functions(height: int, width: int, xmin: float, xmax: float, ymin: float, ym
|
|||||||
else:
|
else:
|
||||||
array[ax][ay] = acolor
|
array[ax][ay] = acolor
|
||||||
|
|
||||||
return graph(height, width, xmin, xmax, ymin, ymax, array, border=border, axislabel=axislabel, axisunitslabel=axisunitslabel, style=style, title=title)
|
return graph(height, width, xmin, xmax, ymin, ymax, array, border=border,
|
||||||
|
axislabel=axislabel, axisunitslabel=axisunitslabel, style=style, title=title)
|
||||||
|
|
||||||
|
|
||||||
def function(height, width, xmin: float, xmax: float, ymin: float, ymax: float, afunction: Callable[[float], float], border: bool = True, axislabel: bool = True, axisunitslabel: bool = True, style: int = 2, color: int = 2, title: Optional[str] = None) -> int:
|
def function(height, width, xmin: float, xmax: float, ymin: float, ymax: float, afunction: Callable[[float], float], border: bool = True, axislabel: bool = True, axisunitslabel: bool = True, style: style_types = style_types.light, color: color_types = color_types.red, title: Optional[str] = None) -> int:
|
||||||
"""Convert single function to function array and output"""
|
"""Convert single function to function array and output"""
|
||||||
return functions(height, width, xmin, xmax, ymin, ymax, [afunction], border=border, axislabel=axislabel, axisunitslabel=axisunitslabel, style=style, color=color, title=title)
|
return functions(height, width, xmin, xmax, ymin, ymax, [
|
||||||
|
afunction], border=border, axislabel=axislabel, axisunitslabel=axisunitslabel, style=style, color=color, title=title)
|
||||||
|
166
python/tables.py
166
python/tables.py
@ -8,12 +8,24 @@ import sys
|
|||||||
import shutil
|
import shutil
|
||||||
import re
|
import re
|
||||||
import textwrap
|
import textwrap
|
||||||
|
from enum import IntEnum, auto
|
||||||
from wcwidth import wcswidth
|
from wcwidth import wcswidth
|
||||||
from typing import List, Optional, Any, Sequence, Callable
|
from typing import List, Optional, Any, Sequence, Callable
|
||||||
import locale
|
import locale
|
||||||
|
|
||||||
locale.setlocale(locale.LC_ALL, '')
|
locale.setlocale(locale.LC_ALL, '')
|
||||||
|
|
||||||
|
|
||||||
|
class style_types(IntEnum):
|
||||||
|
ASCII = 0
|
||||||
|
basic = auto()
|
||||||
|
light = auto()
|
||||||
|
heavy = auto()
|
||||||
|
double = auto()
|
||||||
|
light_dashed = auto()
|
||||||
|
heavy_dashed = auto()
|
||||||
|
|
||||||
|
|
||||||
styles = [
|
styles = [
|
||||||
["-", "|", "+", "+", "+", "+", "+", "+", "+", "+", "+"], # ASCII
|
["-", "|", "+", "+", "+", "+", "+", "+", "+", "+", "+"], # ASCII
|
||||||
["—", "|", "+", "+", "+", "+", "+", "+", "+", "+", "+"], # Basic
|
["—", "|", "+", "+", "+", "+", "+", "+", "+", "+", "+"], # Basic
|
||||||
@ -28,25 +40,24 @@ styles = [
|
|||||||
ansi = re.compile(r'\x1B\[(?:[0-9]+(?:;[0-9]+)*)?m')
|
ansi = re.compile(r'\x1B\[(?:[0-9]+(?:;[0-9]+)*)?m')
|
||||||
|
|
||||||
|
|
||||||
def strcol(str: str) -> int:
|
def strcol(astr: str) -> int:
|
||||||
"""Returns the number of columns that the given string would take up if printed."""
|
"""Returns the number of columns that the given string would take up if printed."""
|
||||||
str = ansi.sub('', str)
|
astr = ansi.sub('', astr)
|
||||||
width = wcswidth(str)
|
width = wcswidth(astr)
|
||||||
if width == -1:
|
if width == -1:
|
||||||
print("\nError! wcswidth failed. Nonprintable wide character.", file=sys.stderr)
|
print(
|
||||||
|
"\nError! wcswidth failed. Nonprintable wide character.",
|
||||||
|
file=sys.stderr)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
return width
|
return width
|
||||||
# return len(str)
|
# return len(astr)
|
||||||
|
|
||||||
|
|
||||||
def table(array: List[List[str]], headerrow: bool = False, headercolumn: bool = False, tableborder: bool = True, cellborder: bool = False, padding: int = 1, alignment: bool = False, title: Optional[str] = None, style: int = 2) -> int:
|
def table(array: List[List[str]], headerrow: bool = False, headercolumn: bool = False, tableborder: bool = True, cellborder: bool = False, padding: int = 1, alignment: Optional[bool] = None, title: Optional[str] = None, style: style_types = style_types.light, check: bool = True) -> int:
|
||||||
"""Output char array as table"""
|
"""Output char array as table"""
|
||||||
if not array:
|
if not array:
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
if not (0 <= style < len(styles)):
|
|
||||||
return 1
|
|
||||||
|
|
||||||
rows = len(array)
|
rows = len(array)
|
||||||
columns = len(array[0])
|
columns = len(array[0])
|
||||||
|
|
||||||
@ -61,13 +72,14 @@ def table(array: List[List[str]], headerrow: bool = False, headercolumn: bool =
|
|||||||
else:
|
else:
|
||||||
width += (2 * padding) * columns
|
width += (2 * padding) * columns
|
||||||
|
|
||||||
if width > w.columns:
|
if check:
|
||||||
print("The width of the table ({0}) is greater then the width of the terminal ({1}).".format(
|
if width > w.columns:
|
||||||
width, w.columns), file=sys.stderr)
|
print("The width of the table ({0}) is greater then the width of the terminal ({1}).".format(
|
||||||
return 1
|
width, w.columns), file=sys.stderr)
|
||||||
|
return 1
|
||||||
|
|
||||||
if title:
|
if title:
|
||||||
print(textwrap.fill(title, width=w.columns))
|
print(textwrap.fill(title, width=width))
|
||||||
|
|
||||||
strm = ""
|
strm = ""
|
||||||
|
|
||||||
@ -77,18 +89,22 @@ def table(array: List[List[str]], headerrow: bool = False, headercolumn: bool =
|
|||||||
for j in range(columns):
|
for j in range(columns):
|
||||||
strm += styles[style][0] * ((2 * padding) + columnwidth[j])
|
strm += styles[style][0] * ((2 * padding) + columnwidth[j])
|
||||||
|
|
||||||
if j == (columns - 1):
|
if j < (columns - 1):
|
||||||
strm += styles[style][4] + "\n"
|
if cellborder or headerrow or (j == 0 and headercolumn):
|
||||||
elif cellborder or headerrow or (j == 0 and headercolumn):
|
strm += styles[style][3]
|
||||||
strm += styles[style][3]
|
else:
|
||||||
else:
|
strm += styles[style][0]
|
||||||
strm += styles[style][0]
|
|
||||||
|
strm += styles[style][4] + "\n"
|
||||||
|
|
||||||
for i in range(rows):
|
for i in range(rows):
|
||||||
|
if tableborder:
|
||||||
|
strm += styles[style][1]
|
||||||
|
|
||||||
for j in range(columns):
|
for j in range(columns):
|
||||||
if (j == 0 and tableborder) or (j > 0 and cellborder) or (i == 0 and j > 0 and headerrow) or (j == 1 and headercolumn):
|
if (j > 0 and cellborder) or (i == 0 and j > 0 and headerrow) or (j == 1 and headercolumn):
|
||||||
strm += styles[style][1]
|
strm += styles[style][1]
|
||||||
elif tableborder or (i > 0 and j > 0 and headerrow) or (j > 1 and headercolumn):
|
elif j > 0 and (tableborder or (i > 0 and headerrow) or headercolumn):
|
||||||
strm += " "
|
strm += " "
|
||||||
|
|
||||||
awidth = columnwidth[j] - (strcol(array[i][j]) - len(array[i][j]))
|
awidth = columnwidth[j] - (strcol(array[i][j]) - len(array[i][j]))
|
||||||
@ -102,7 +118,9 @@ def table(array: List[List[str]], headerrow: bool = False, headercolumn: bool =
|
|||||||
else:
|
else:
|
||||||
strm += " " * padding
|
strm += " " * padding
|
||||||
|
|
||||||
if alignment:
|
if alignment is None:
|
||||||
|
strm += "{0:{width}}".format(array[i][j], width=awidth)
|
||||||
|
elif alignment:
|
||||||
strm += array[i][j].rjust(awidth)
|
strm += array[i][j].rjust(awidth)
|
||||||
else:
|
else:
|
||||||
strm += array[i][j].ljust(awidth)
|
strm += array[i][j].ljust(awidth)
|
||||||
@ -127,17 +145,7 @@ def table(array: List[List[str]], headerrow: bool = False, headercolumn: bool =
|
|||||||
elif i < (rows - 1) and headercolumn:
|
elif i < (rows - 1) and headercolumn:
|
||||||
strm += " " * ((2 * padding) + columnwidth[j])
|
strm += " " * ((2 * padding) + columnwidth[j])
|
||||||
|
|
||||||
if j == (columns - 1):
|
if j < (columns - 1):
|
||||||
if tableborder:
|
|
||||||
if i == (rows - 1):
|
|
||||||
strm += styles[style][10]
|
|
||||||
elif cellborder or (i == 0 and headerrow):
|
|
||||||
strm += styles[style][7]
|
|
||||||
elif headercolumn:
|
|
||||||
strm += styles[style][1]
|
|
||||||
|
|
||||||
strm += "\n"
|
|
||||||
else:
|
|
||||||
if i == (rows - 1) and tableborder:
|
if i == (rows - 1) and tableborder:
|
||||||
if cellborder or (j == 0 and headercolumn):
|
if cellborder or (j == 0 and headercolumn):
|
||||||
strm += styles[style][9]
|
strm += styles[style][9]
|
||||||
@ -153,12 +161,23 @@ def table(array: List[List[str]], headerrow: bool = False, headercolumn: bool =
|
|||||||
else:
|
else:
|
||||||
strm += " "
|
strm += " "
|
||||||
|
|
||||||
|
if tableborder:
|
||||||
|
if i == (rows - 1):
|
||||||
|
strm += styles[style][10]
|
||||||
|
elif cellborder or (i == 0 and headerrow):
|
||||||
|
strm += styles[style][7]
|
||||||
|
elif headercolumn:
|
||||||
|
strm += styles[style][1]
|
||||||
|
|
||||||
|
if i < (rows - 1):
|
||||||
|
strm += "\n"
|
||||||
|
|
||||||
print(strm)
|
print(strm)
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
def array(aarray: Sequence[Sequence[Any]], aheaderrow: Optional[Sequence[Any]] = None, aheadercolumn: Optional[Sequence[Any]] = None, headerrow: bool = False, headercolumn: bool = False, tableborder: bool = True, cellborder: bool = False, padding: int = 1, alignment: bool = False, title: Optional[str] = None, style: int = 2) -> int:
|
def array(aarray: Sequence[Sequence[Any]], aheaderrow: Optional[Sequence[Any]] = None, aheadercolumn: Optional[Sequence[Any]] = None, headerrow: bool = False, headercolumn: bool = False, tableborder: bool = True, cellborder: bool = False, padding: int = 1, alignment: Optional[bool] = None, title: Optional[str] = None, style: style_types = style_types.light) -> int:
|
||||||
"""Convert array to char array and output as table"""
|
"""Convert array to char array and output as table"""
|
||||||
if not aarray:
|
if not aarray:
|
||||||
return 1
|
return 1
|
||||||
@ -167,7 +186,9 @@ def array(aarray: Sequence[Sequence[Any]], aheaderrow: Optional[Sequence[Any]] =
|
|||||||
columns = len(aarray[0])
|
columns = len(aarray[0])
|
||||||
|
|
||||||
if not all(len(x) == columns for x in aarray):
|
if not all(len(x) == columns for x in aarray):
|
||||||
print("Error: The rows of the array must have the same number of columns.", file=sys.stderr)
|
print(
|
||||||
|
"Error: The rows of the array must have the same number of columns.",
|
||||||
|
file=sys.stderr)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
if aheaderrow:
|
if aheaderrow:
|
||||||
@ -177,50 +198,36 @@ def array(aarray: Sequence[Sequence[Any]], aheaderrow: Optional[Sequence[Any]] =
|
|||||||
columns += 1
|
columns += 1
|
||||||
|
|
||||||
if aheaderrow and len(aheaderrow) != columns:
|
if aheaderrow and len(aheaderrow) != columns:
|
||||||
print("Error: The header row must have the same number of columns as the array.", file=sys.stderr)
|
print(
|
||||||
|
"Error: The header row must have the same number of columns as the array.",
|
||||||
|
file=sys.stderr)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
if aheadercolumn and len(aheadercolumn) != (rows - 1 if aheaderrow else rows):
|
if aheadercolumn and len(aheadercolumn) != (rows - 1 if aheaderrow else rows):
|
||||||
print("Error: The header column must have the same number of rows as the array.", file=sys.stderr)
|
print(
|
||||||
|
"Error: The header column must have the same number of rows as the array.",
|
||||||
|
file=sys.stderr)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
aaarray = [["" for j in range(columns)] for i in range(rows)]
|
aaarray = [["" for j in range(columns)] for i in range(rows)]
|
||||||
|
|
||||||
i = 0
|
|
||||||
|
|
||||||
if aheaderrow:
|
if aheaderrow:
|
||||||
for j in range(columns):
|
aaarray[0] = aheaderrow[:columns]
|
||||||
aaarray[i][j] = aheaderrow[j]
|
|
||||||
|
|
||||||
i += 1
|
for i in range(1 if aheaderrow else 0, rows):
|
||||||
|
ii = i - 1 if aheaderrow else i
|
||||||
|
|
||||||
j = 0
|
|
||||||
|
|
||||||
ii = 0
|
|
||||||
for i in range(i, rows):
|
|
||||||
if aheadercolumn:
|
if aheadercolumn:
|
||||||
aii = i
|
aaarray[i][0] = aheadercolumn[ii]
|
||||||
|
|
||||||
if aheaderrow:
|
j = 1 if aheadercolumn else 0
|
||||||
aii -= 1
|
aaarray[i][j:] = map(str, aarray[ii][:columns - j])
|
||||||
|
|
||||||
aaarray[i][j] = aheadercolumn[aii]
|
return table(aaarray, headerrow=headerrow, headercolumn=headercolumn, tableborder=tableborder,
|
||||||
|
cellborder=cellborder, padding=padding, alignment=alignment, title=title, style=style)
|
||||||
j += 1
|
|
||||||
|
|
||||||
jj = 0
|
|
||||||
for j in range(j, columns):
|
|
||||||
aaarray[i][j] = str(aarray[ii][jj])
|
|
||||||
|
|
||||||
jj += 1
|
|
||||||
|
|
||||||
j = 0
|
|
||||||
ii += 1
|
|
||||||
|
|
||||||
return table(aaarray, headerrow=headerrow, headercolumn=headercolumn, tableborder=tableborder, cellborder=cellborder, padding=padding, alignment=alignment, title=title, style=style)
|
|
||||||
|
|
||||||
|
|
||||||
def functions(xmin: float, xmax: float, xscl: float, afunctions: Sequence[Callable[[float], float]], headerrow: bool = False, headercolumn: bool = False, tableborder: bool = True, cellborder: bool = False, padding: int = 1, alignment: bool = False, title: Optional[str] = None, style: int = 2) -> int:
|
def functions(xmin: float, xmax: float, xstep: float, afunctions: Sequence[Callable[[float], float]], headerrow: bool = False, headercolumn: bool = False, tableborder: bool = True, cellborder: bool = False, padding: int = 1, alignment: Optional[bool] = None, title: Optional[str] = None, style: style_types = style_types.light) -> int:
|
||||||
"""Convert one or more functions to array and output as table"""
|
"""Convert one or more functions to array and output as table"""
|
||||||
if not afunctions:
|
if not afunctions:
|
||||||
return 1
|
return 1
|
||||||
@ -229,11 +236,11 @@ def functions(xmin: float, xmax: float, xscl: float, afunctions: Sequence[Callab
|
|||||||
print("xmin must be less than xmax.", file=sys.stderr)
|
print("xmin must be less than xmax.", file=sys.stderr)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
if xscl <= 0:
|
if xstep <= 0:
|
||||||
print("xscl must be greater than zero.", file=sys.stderr)
|
print("xstep must be greater than zero.", file=sys.stderr)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
rows = int(((xmax - xmin) * xscl)) + 1
|
rows = int(((xmax - xmin) / xstep)) + 1
|
||||||
columns = len(afunctions) + 1
|
columns = len(afunctions) + 1
|
||||||
|
|
||||||
aaheaderrow = ["x", "y"]
|
aaheaderrow = ["x", "y"]
|
||||||
@ -241,23 +248,24 @@ def functions(xmin: float, xmax: float, xscl: float, afunctions: Sequence[Callab
|
|||||||
|
|
||||||
aheaderrow = [""] * columns
|
aheaderrow = [""] * columns
|
||||||
|
|
||||||
for j in range(columns):
|
if len(afunctions) == 1:
|
||||||
if j < (length - 1) or len(afunctions) == 1:
|
aheaderrow = aaheaderrow
|
||||||
aheaderrow[j] = aaheaderrow[j]
|
else:
|
||||||
else:
|
aheaderrow = aaheaderrow[:-1] + [aaheaderrow[-1] +
|
||||||
aheaderrow[j] = aaheaderrow[length - 1] + str(j - length + 2)
|
str(j - length + 2) for j in range(1, columns)]
|
||||||
|
|
||||||
aarray = [[0 for j in range(columns)] for i in range(rows)]
|
aarray = [[0 for j in range(columns)] for i in range(rows)]
|
||||||
|
|
||||||
for i in range(rows):
|
for i in range(rows):
|
||||||
aarray[i][0] = (i / xscl) + xmin
|
aarray[i][0] = (i * xstep) + xmin
|
||||||
|
|
||||||
for j, function in enumerate(afunctions):
|
aarray[i][1:] = [function(aarray[i][0]) for function in afunctions]
|
||||||
aarray[i][j + 1] = function(aarray[i][0])
|
|
||||||
|
|
||||||
return array(aarray, aheaderrow, None, headerrow=headerrow, headercolumn=headercolumn, tableborder=tableborder, cellborder=cellborder, padding=padding, alignment=alignment, title=title, style=style)
|
return array(aarray, aheaderrow, None, headerrow=headerrow, headercolumn=headercolumn, tableborder=tableborder,
|
||||||
|
cellborder=cellborder, padding=padding, alignment=alignment, title=title, style=style)
|
||||||
|
|
||||||
|
|
||||||
def function(xmin: float, xmax: float, xscl: float, afunction: Callable[[float], float], headerrow: bool = False, headercolumn: bool = False, tableborder: bool = True, cellborder: bool = False, padding: int = 1, alignment: bool = False, title: Optional[str] = None, style: int = 2) -> int:
|
def function(xmin: float, xmax: float, xstep: float, afunction: Callable[[float], float], headerrow: bool = False, headercolumn: bool = False, tableborder: bool = True, cellborder: bool = False, padding: int = 1, alignment: Optional[bool] = None, title: Optional[str] = None, style: style_types = style_types.light) -> int:
|
||||||
"""Convert single function to array and output as table"""
|
"""Convert single function to array and output as table"""
|
||||||
return functions(xmin, xmax, xscl, [afunction], headerrow=headerrow, headercolumn=headercolumn, tableborder=tableborder, cellborder=cellborder, padding=padding, alignment=alignment, title=title, style=style)
|
return functions(xmin, xmax, xstep, [afunction], headerrow=headerrow, headercolumn=headercolumn,
|
||||||
|
tableborder=tableborder, cellborder=cellborder, padding=padding, alignment=alignment, title=title, style=style)
|
||||||
|
102
python/test.py
102
python/test.py
@ -21,17 +21,17 @@ columns = 5
|
|||||||
|
|
||||||
xmin = -10
|
xmin = -10
|
||||||
xmax = 10
|
xmax = 10
|
||||||
xscl = 2
|
xstep = 0.5
|
||||||
|
|
||||||
print("\nOutput array as table\n")
|
print("\nOutput array as table\n")
|
||||||
array = [[random.randint(0, sys.maxsize)
|
array = [[random.randint(0, sys.maxsize)
|
||||||
for j in range(columns)] for i in range(rows)]
|
for j in range(columns)] for i in range(rows)]
|
||||||
for k in range(len(tables.styles)):
|
for style in tables.style_types:
|
||||||
tables.array(array, None, None, style=k)
|
tables.array(array, None, None, style=style)
|
||||||
|
|
||||||
array = [[random.random() for j in range(columns)] for i in range(rows)]
|
array = [[random.random() for j in range(columns)] for i in range(rows)]
|
||||||
for k in range(len(tables.styles)):
|
for style in tables.style_types:
|
||||||
tables.array(array, None, None, style=k)
|
tables.array(array, None, None, style=style)
|
||||||
|
|
||||||
print("\nOutput char array as table\n")
|
print("\nOutput char array as table\n")
|
||||||
array = [["Header row/column 1", "Header row 2", "Header row 3", "Header row 4", "Header row 5"],
|
array = [["Header row/column 1", "Header row 2", "Header row 3", "Header row 4", "Header row 5"],
|
||||||
@ -39,8 +39,9 @@ array = [["Header row/column 1", "Header row 2", "Header row 3", "Header row 4",
|
|||||||
["Header column 3", "Data 5", "Data 6", "Data 7", "Data 8"],
|
["Header column 3", "Data 5", "Data 6", "Data 7", "Data 8"],
|
||||||
["Header column 4", "Data 9", "Data 10", "Data 11", "Data 12"],
|
["Header column 4", "Data 9", "Data 10", "Data 11", "Data 12"],
|
||||||
["Header column 5", "Data 13", "Data 14", "Data 15", "Data 16"]]
|
["Header column 5", "Data 13", "Data 14", "Data 15", "Data 16"]]
|
||||||
for k in range(len(tables.styles)):
|
for style in tables.style_types:
|
||||||
tables.array(array, None, None, headerrow=True, headercolumn=True, style=k)
|
tables.array(array, None, None, headerrow=True,
|
||||||
|
headercolumn=True, style=style)
|
||||||
|
|
||||||
print("\nOutput array as table with separate header row and column\n")
|
print("\nOutput array as table with separate header row and column\n")
|
||||||
array = [["Data {0:n}".format(i + j) for j in range(4)]
|
array = [["Data {0:n}".format(i + j) for j in range(4)]
|
||||||
@ -50,44 +51,52 @@ headerrow = ["Header row/column 1", "Header row 2",
|
|||||||
headercolumn = ["Header column 2", "Header column 3",
|
headercolumn = ["Header column 2", "Header column 3",
|
||||||
"Header column 4", "Header column 5"]
|
"Header column 4", "Header column 5"]
|
||||||
|
|
||||||
for k in range(len(tables.styles)):
|
for style in tables.style_types:
|
||||||
tables.array(array, headerrow, headercolumn, headerrow=True, headercolumn=True, cellborder=True, style=k)
|
tables.array(array, headerrow, headercolumn, headerrow=True,
|
||||||
tables.array(array, headerrow, headercolumn, headerrow=True, headercolumn=True, style=k)
|
headercolumn=True, cellborder=True, style=style)
|
||||||
tables.array(array, headerrow[:-1], None, headerrow=True, style=k)
|
tables.array(array, headerrow, headercolumn,
|
||||||
tables.array(array, None, [headerrow[0]] + headercolumn[:-1], headercolumn=True, style=k)
|
headerrow=True, headercolumn=True, style=style)
|
||||||
tables.array(array, None, None, cellborder=True, style=k)
|
tables.array(array, headerrow[:-1], None, headerrow=True, style=style)
|
||||||
tables.array(array, None, None, tableborder=False, style=k)
|
tables.array(array, None, [headerrow[0]] +
|
||||||
tables.array(array, headerrow, headercolumn, tableborder=False, headerrow=True, headercolumn=True, style=k)
|
headercolumn[:-1], headercolumn=True, style=style)
|
||||||
tables.array(array, headerrow[:-1], None, tableborder=False, headerrow=True, style=k)
|
tables.array(array, None, None, cellborder=True, style=style)
|
||||||
tables.array(array, None, [headerrow[0]] + headercolumn[:-1], tableborder=False, headercolumn=True, style=k)
|
tables.array(array, None, None, tableborder=False, style=style)
|
||||||
tables.array(array, None, None, tableborder=False, cellborder=True, style=k)
|
tables.array(array, headerrow, headercolumn, tableborder=False,
|
||||||
|
headerrow=True, headercolumn=True, style=style)
|
||||||
|
tables.array(array, headerrow[:-1], None,
|
||||||
|
tableborder=False, headerrow=True, style=style)
|
||||||
|
tables.array(array, None, [headerrow[0]] + headercolumn[:-1],
|
||||||
|
tableborder=False, headercolumn=True, style=style)
|
||||||
|
tables.array(array, None, None, tableborder=False,
|
||||||
|
cellborder=True, style=style)
|
||||||
|
|
||||||
array = [[bool(random.getrandbits(1)) for j in range(columns)]
|
array = [[bool(random.getrandbits(1)) for j in range(columns)]
|
||||||
for i in range(rows)]
|
for i in range(rows)]
|
||||||
for k in range(len(tables.styles)):
|
for style in tables.style_types:
|
||||||
tables.array(array, None, None, style=k)
|
tables.array(array, None, None, style=style)
|
||||||
|
|
||||||
print("\nOutput sorted array as table\n")
|
print("\nOutput sorted array as table\n")
|
||||||
array = ([random.randint(0, sys.maxsize)
|
array = ([random.randint(0, sys.maxsize)
|
||||||
for j in range(columns)] for i in range(rows))
|
for j in range(columns)] for i in range(rows))
|
||||||
sortdimension = 0
|
sortdimension = 0
|
||||||
array = sorted(array, key=lambda x: x[sortdimension])
|
array = sorted(array, key=lambda x: x[sortdimension])
|
||||||
for k in range(len(tables.styles)):
|
for style in tables.style_types:
|
||||||
tables.array(array, None, None, style=k)
|
tables.array(array, None, None, style=style)
|
||||||
|
|
||||||
print("\nOutput single function as table\n")
|
print("\nOutput single function as table\n")
|
||||||
for k in range(len(tables.styles)):
|
for style in tables.style_types:
|
||||||
tables.function(xmin, xmax, xscl, afunction, headerrow=True, style=k)
|
tables.function(xmin, xmax, xstep, afunction, headerrow=True, style=style)
|
||||||
for k in range(len(tables.styles)):
|
for style in tables.style_types:
|
||||||
tables.function(xmin, xmax, xscl, lambda x: x + 1, headerrow=True, style=k)
|
tables.function(xmin, xmax, xstep, lambda x: x +
|
||||||
|
1, headerrow=True, style=style)
|
||||||
|
|
||||||
print("\nOutput multiple functions as table\n")
|
print("\nOutput multiple functions as table\n")
|
||||||
for k in range(len(tables.styles)):
|
for style in tables.style_types:
|
||||||
tables.functions(xmin, xmax, xscl, [
|
tables.functions(xmin, xmax, xstep, [
|
||||||
function1, function2], headerrow=True, style=k)
|
function1, function2], headerrow=True, style=style)
|
||||||
for k in range(len(tables.styles)):
|
for style in tables.style_types:
|
||||||
tables.functions(xmin, xmax, xscl, [
|
tables.functions(xmin, xmax, xstep, [
|
||||||
lambda x: 2 * x, lambda x: x ** 2], headerrow=True, style=k)
|
lambda x: 2 * x, lambda x: x ** 2], headerrow=True, style=style)
|
||||||
|
|
||||||
height = 160
|
height = 160
|
||||||
width = 160
|
width = 160
|
||||||
@ -99,24 +108,25 @@ ymax = 20
|
|||||||
|
|
||||||
print("\nOutput single array as plot\n")
|
print("\nOutput single array as plot\n")
|
||||||
array = [range(i, i + 2) for i in range(10)]
|
array = [range(i, i + 2) for i in range(10)]
|
||||||
for k in range(len(graphs.styles)):
|
for style in graphs.style_types:
|
||||||
graphs.array(height, width, xmin, xmax, ymin, ymax, array, style=k)
|
graphs.array(height, width, xmin, xmax, ymin, ymax, array, style=style)
|
||||||
|
|
||||||
print("\nOutput single function as graph\n")
|
print("\nOutput single function as graph\n")
|
||||||
for k in range(len(graphs.styles)):
|
for style in graphs.style_types:
|
||||||
graphs.function(height, width, xmin, xmax, ymin, ymax, afunction, style=k)
|
|
||||||
for k in range(len(graphs.styles)):
|
|
||||||
graphs.function(height, width, xmin, xmax, ymin,
|
graphs.function(height, width, xmin, xmax, ymin,
|
||||||
ymax, lambda x: x + 1, style=k)
|
ymax, afunction, style=style)
|
||||||
|
for style in graphs.style_types:
|
||||||
|
graphs.function(height, width, xmin, xmax, ymin,
|
||||||
|
ymax, lambda x: x + 1, style=style)
|
||||||
|
|
||||||
print("\nOutput multiple functions as graph\n")
|
print("\nOutput multiple functions as graph\n")
|
||||||
for k in range(len(graphs.styles)):
|
for style in graphs.style_types:
|
||||||
graphs.functions(height, width, xmin, xmax, ymin,
|
graphs.functions(height, width, xmin, xmax, ymin, ymax,
|
||||||
ymax, [function1, function2], style=k)
|
[function1, function2], style=style)
|
||||||
for k in range(len(graphs.styles)):
|
for style in graphs.style_types:
|
||||||
graphs.functions(height, width, xmin, xmax, ymin, ymax, [
|
graphs.functions(height, width, xmin, xmax, ymin, ymax, [
|
||||||
lambda x: 2 * x, lambda x: x ** 2], style=k)
|
lambda x: 2 * x, lambda x: x ** 2], style=style)
|
||||||
|
|
||||||
for k in range(len(graphs.styles)):
|
for style in graphs.style_types:
|
||||||
graphs.functions(height, width, -(2 * math.pi), 2 * math.pi, -4,
|
graphs.functions(height, width, -(2 * math.pi), 2 * math.pi, -4, 4,
|
||||||
4, [math.sin, math.cos, math.tan], axisunitslabel=False, style=k)
|
[math.sin, math.cos, math.tan], axisunitslabel=False, style=style)
|
||||||
|
128
tables.cpp
128
tables.cpp
@ -77,7 +77,7 @@ int main()
|
|||||||
|
|
||||||
const long double xmin = -10;
|
const long double xmin = -10;
|
||||||
const long double xmax = 10;
|
const long double xmax = 10;
|
||||||
const long double xscl = 2; // 80 / (xmax - xmin);
|
const long double xstep = 0.5; // (xmax - xmin) / 80;
|
||||||
|
|
||||||
string *headerrow = nullptr;
|
string *headerrow = nullptr;
|
||||||
string *headercolumn = nullptr;
|
string *headercolumn = nullptr;
|
||||||
@ -96,14 +96,14 @@ int main()
|
|||||||
|
|
||||||
tables::options aoptions;
|
tables::options aoptions;
|
||||||
|
|
||||||
for (unsigned int k = 0; k < tables::size(tables::styles); ++k)
|
for (const tables::style_type style : tables::style_types)
|
||||||
{
|
{
|
||||||
aoptions.style = k;
|
aoptions.style = style;
|
||||||
|
|
||||||
tables::array(rows, columns, array, nullptr, nullptr, aoptions);
|
tables::array(rows, columns, array, nullptr, nullptr, aoptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (array != nullptr)
|
if (array)
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < rows; ++i)
|
for (unsigned int i = 0; i < rows; ++i)
|
||||||
delete[] array[i];
|
delete[] array[i];
|
||||||
@ -120,9 +120,9 @@ int main()
|
|||||||
|
|
||||||
tables::options aoptions;
|
tables::options aoptions;
|
||||||
|
|
||||||
for (unsigned int k = 0; k < tables::size(tables::styles); ++k)
|
for (const tables::style_type style : tables::style_types)
|
||||||
{
|
{
|
||||||
aoptions.style = k;
|
aoptions.style = style;
|
||||||
|
|
||||||
tables::array(aarray, headerrow, headercolumn, aoptions);
|
tables::array(aarray, headerrow, headercolumn, aoptions);
|
||||||
}
|
}
|
||||||
@ -136,9 +136,9 @@ int main()
|
|||||||
|
|
||||||
tables::options aoptions;
|
tables::options aoptions;
|
||||||
|
|
||||||
for (unsigned int k = 0; k < tables::size(tables::styles); ++k)
|
for (const tables::style_type style : tables::style_types)
|
||||||
{
|
{
|
||||||
aoptions.style = k;
|
aoptions.style = style;
|
||||||
|
|
||||||
tables::array(array, headerrow, headercolumn, aoptions);
|
tables::array(array, headerrow, headercolumn, aoptions);
|
||||||
}
|
}
|
||||||
@ -155,14 +155,14 @@ int main()
|
|||||||
|
|
||||||
tables::options aoptions;
|
tables::options aoptions;
|
||||||
|
|
||||||
for (unsigned int k = 0; k < tables::size(tables::styles); ++k)
|
for (const tables::style_type style : tables::style_types)
|
||||||
{
|
{
|
||||||
aoptions.style = k;
|
aoptions.style = style;
|
||||||
|
|
||||||
tables::array(rows, columns, array, nullptr, nullptr, aoptions);
|
tables::array(rows, columns, array, nullptr, nullptr, aoptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (array != nullptr)
|
if (array)
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < rows; ++i)
|
for (unsigned int i = 0; i < rows; ++i)
|
||||||
delete[] array[i];
|
delete[] array[i];
|
||||||
@ -179,9 +179,9 @@ int main()
|
|||||||
|
|
||||||
tables::options aoptions;
|
tables::options aoptions;
|
||||||
|
|
||||||
for (unsigned int k = 0; k < tables::size(tables::styles); ++k)
|
for (const tables::style_type style : tables::style_types)
|
||||||
{
|
{
|
||||||
aoptions.style = k;
|
aoptions.style = style;
|
||||||
|
|
||||||
tables::array(aarray, headerrow, headercolumn, aoptions);
|
tables::array(aarray, headerrow, headercolumn, aoptions);
|
||||||
}
|
}
|
||||||
@ -195,9 +195,9 @@ int main()
|
|||||||
|
|
||||||
tables::options aoptions;
|
tables::options aoptions;
|
||||||
|
|
||||||
for (unsigned int k = 0; k < tables::size(tables::styles); ++k)
|
for (const tables::style_type style : tables::style_types)
|
||||||
{
|
{
|
||||||
aoptions.style = k;
|
aoptions.style = style;
|
||||||
|
|
||||||
tables::array(array, headerrow, headercolumn, aoptions);
|
tables::array(array, headerrow, headercolumn, aoptions);
|
||||||
}
|
}
|
||||||
@ -217,9 +217,9 @@ int main()
|
|||||||
aoptions.headercolumn = true;
|
aoptions.headercolumn = true;
|
||||||
// tables::options aoptions{.headerrow = true, .headercolumn = true};
|
// tables::options aoptions{.headerrow = true, .headercolumn = true};
|
||||||
|
|
||||||
for (unsigned int k = 0; k < tables::size(tables::styles); ++k)
|
for (const tables::style_type style : tables::style_types)
|
||||||
{
|
{
|
||||||
aoptions.style = k;
|
aoptions.style = style;
|
||||||
|
|
||||||
tables::array(array, headerrow, headercolumn, aoptions);
|
tables::array(array, headerrow, headercolumn, aoptions);
|
||||||
}
|
}
|
||||||
@ -236,9 +236,9 @@ int main()
|
|||||||
aoptions.headercolumn = true;
|
aoptions.headercolumn = true;
|
||||||
// tables::options aoptions{.headerrow = true, .headercolumn = true};
|
// tables::options aoptions{.headerrow = true, .headercolumn = true};
|
||||||
|
|
||||||
for (unsigned int k = 0; k < tables::size(tables::styles); ++k)
|
for (const tables::style_type style : tables::style_types)
|
||||||
{
|
{
|
||||||
aoptions.style = k;
|
aoptions.style = style;
|
||||||
|
|
||||||
tables::array(aarray, headerrow, headercolumn, aoptions);
|
tables::array(aarray, headerrow, headercolumn, aoptions);
|
||||||
}
|
}
|
||||||
@ -263,9 +263,9 @@ int main()
|
|||||||
aoptions.headercolumn = true;
|
aoptions.headercolumn = true;
|
||||||
// tables::options aoptions{.headerrow = true, .headercolumn = true};
|
// tables::options aoptions{.headerrow = true, .headercolumn = true};
|
||||||
|
|
||||||
for (unsigned int k = 0; k < tables::size(tables::styles); ++k)
|
for (const tables::style_type style : tables::style_types)
|
||||||
{
|
{
|
||||||
aoptions.style = k;
|
aoptions.style = style;
|
||||||
|
|
||||||
tables::array(array, headerrow, headercolumn, aoptions);
|
tables::array(array, headerrow, headercolumn, aoptions);
|
||||||
}
|
}
|
||||||
@ -286,15 +286,15 @@ int main()
|
|||||||
vector<string> aheadercolumn(headerrow, headerrow + 1);
|
vector<string> aheadercolumn(headerrow, headerrow + 1);
|
||||||
aheadercolumn.insert(aheadercolumn.end(), headercolumn, headercolumn + columns - 1);
|
aheadercolumn.insert(aheadercolumn.end(), headercolumn, headercolumn + columns - 1);
|
||||||
|
|
||||||
for (unsigned int k = 0; k < tables::size(tables::styles); ++k)
|
for (const tables::style_type style : tables::style_types)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
tables::options aoptions;
|
tables::options aoptions;
|
||||||
aoptions.headerrow = true;
|
aoptions.headerrow = true;
|
||||||
aoptions.headercolumn = true;
|
aoptions.headercolumn = true;
|
||||||
aoptions.cellborder = true;
|
aoptions.cellborder = true;
|
||||||
aoptions.style = k;
|
aoptions.style = style;
|
||||||
// tables::options aoptions{.headerrow = true, .headercolumn = true, .cellborder = true, .style = k};
|
// tables::options aoptions{.headerrow = true, .headercolumn = true, .cellborder = true, .style = style};
|
||||||
|
|
||||||
tables::array(aarray, headerrow, headercolumn, aoptions);
|
tables::array(aarray, headerrow, headercolumn, aoptions);
|
||||||
}
|
}
|
||||||
@ -302,8 +302,8 @@ int main()
|
|||||||
tables::options aoptions;
|
tables::options aoptions;
|
||||||
aoptions.headerrow = true;
|
aoptions.headerrow = true;
|
||||||
aoptions.headercolumn = true;
|
aoptions.headercolumn = true;
|
||||||
aoptions.style = k;
|
aoptions.style = style;
|
||||||
// tables::options aoptions{.headerrow = true, .headercolumn = true, .style = k};
|
// tables::options aoptions{.headerrow = true, .headercolumn = true, .style = style};
|
||||||
|
|
||||||
tables::array(aarray, headerrow, headercolumn, aoptions);
|
tables::array(aarray, headerrow, headercolumn, aoptions);
|
||||||
}
|
}
|
||||||
@ -313,8 +313,8 @@ int main()
|
|||||||
|
|
||||||
tables::options aoptions;
|
tables::options aoptions;
|
||||||
aoptions.headerrow = true;
|
aoptions.headerrow = true;
|
||||||
aoptions.style = k;
|
aoptions.style = style;
|
||||||
// tables::options aoptions{.headerrow = true, .style = k};
|
// tables::options aoptions{.headerrow = true, .style = style};
|
||||||
|
|
||||||
tables::array(aarray, headerrow, headercolumn, aoptions);
|
tables::array(aarray, headerrow, headercolumn, aoptions);
|
||||||
}
|
}
|
||||||
@ -324,8 +324,8 @@ int main()
|
|||||||
|
|
||||||
tables::options aoptions;
|
tables::options aoptions;
|
||||||
aoptions.headercolumn = true;
|
aoptions.headercolumn = true;
|
||||||
aoptions.style = k;
|
aoptions.style = style;
|
||||||
// tables::options aoptions{.headercolumn = true, .style = k};
|
// tables::options aoptions{.headercolumn = true, .style = style};
|
||||||
|
|
||||||
tables::array(aarray, headerrow, headercolumn, aoptions);
|
tables::array(aarray, headerrow, headercolumn, aoptions);
|
||||||
}
|
}
|
||||||
@ -335,8 +335,8 @@ int main()
|
|||||||
|
|
||||||
tables::options aoptions;
|
tables::options aoptions;
|
||||||
aoptions.cellborder = true;
|
aoptions.cellborder = true;
|
||||||
aoptions.style = k;
|
aoptions.style = style;
|
||||||
// tables::options aoptions{.cellborder = true, .style = k};
|
// tables::options aoptions{.cellborder = true, .style = style};
|
||||||
|
|
||||||
tables::array(aarray, headerrow, headercolumn, aoptions);
|
tables::array(aarray, headerrow, headercolumn, aoptions);
|
||||||
}
|
}
|
||||||
@ -346,8 +346,8 @@ int main()
|
|||||||
|
|
||||||
tables::options aoptions;
|
tables::options aoptions;
|
||||||
aoptions.tableborder = false;
|
aoptions.tableborder = false;
|
||||||
aoptions.style = k;
|
aoptions.style = style;
|
||||||
// tables::options aoptions{.tableborder = false, .style = k};
|
// tables::options aoptions{.tableborder = false, .style = style};
|
||||||
|
|
||||||
tables::array(aarray, headerrow, headercolumn, aoptions);
|
tables::array(aarray, headerrow, headercolumn, aoptions);
|
||||||
}
|
}
|
||||||
@ -356,8 +356,8 @@ int main()
|
|||||||
aoptions.tableborder = false;
|
aoptions.tableborder = false;
|
||||||
aoptions.headerrow = true;
|
aoptions.headerrow = true;
|
||||||
aoptions.headercolumn = true;
|
aoptions.headercolumn = true;
|
||||||
aoptions.style = k;
|
aoptions.style = style;
|
||||||
// tables::options aoptions{.tableborder = false, .headerrow = true, .headercolumn = true, .style = k};
|
// tables::options aoptions{.tableborder = false, .headerrow = true, .headercolumn = true, .style = style};
|
||||||
|
|
||||||
tables::array(aarray, headerrow, headercolumn, aoptions);
|
tables::array(aarray, headerrow, headercolumn, aoptions);
|
||||||
}
|
}
|
||||||
@ -368,8 +368,8 @@ int main()
|
|||||||
tables::options aoptions;
|
tables::options aoptions;
|
||||||
aoptions.tableborder = false;
|
aoptions.tableborder = false;
|
||||||
aoptions.headerrow = true;
|
aoptions.headerrow = true;
|
||||||
aoptions.style = k;
|
aoptions.style = style;
|
||||||
// tables::options aoptions{.tableborder = false, .headerrow = true, .style = k};
|
// tables::options aoptions{.tableborder = false, .headerrow = true, .style = style};
|
||||||
|
|
||||||
tables::array(aarray, headerrow, headercolumn, aoptions);
|
tables::array(aarray, headerrow, headercolumn, aoptions);
|
||||||
}
|
}
|
||||||
@ -380,8 +380,8 @@ int main()
|
|||||||
tables::options aoptions;
|
tables::options aoptions;
|
||||||
aoptions.tableborder = false;
|
aoptions.tableborder = false;
|
||||||
aoptions.headercolumn = true;
|
aoptions.headercolumn = true;
|
||||||
aoptions.style = k;
|
aoptions.style = style;
|
||||||
// tables::options aoptions{.tableborder = false, .headercolumn = true, .style = k};
|
// tables::options aoptions{.tableborder = false, .headercolumn = true, .style = style};
|
||||||
|
|
||||||
tables::array(aarray, headerrow, headercolumn, aoptions);
|
tables::array(aarray, headerrow, headercolumn, aoptions);
|
||||||
}
|
}
|
||||||
@ -392,8 +392,8 @@ int main()
|
|||||||
tables::options aoptions;
|
tables::options aoptions;
|
||||||
aoptions.tableborder = false;
|
aoptions.tableborder = false;
|
||||||
aoptions.cellborder = true;
|
aoptions.cellborder = true;
|
||||||
aoptions.style = k;
|
aoptions.style = style;
|
||||||
// tables::options aoptions{.tableborder = false, .cellborder = true, .style = k};
|
// tables::options aoptions{.tableborder = false, .cellborder = true, .style = style};
|
||||||
|
|
||||||
tables::array(aarray, headerrow, headercolumn, aoptions);
|
tables::array(aarray, headerrow, headercolumn, aoptions);
|
||||||
}
|
}
|
||||||
@ -413,14 +413,14 @@ int main()
|
|||||||
aoptions.boolalpha = true;
|
aoptions.boolalpha = true;
|
||||||
// tables::options aoptions{.boolalpha = true};
|
// tables::options aoptions{.boolalpha = true};
|
||||||
|
|
||||||
for (unsigned int k = 0; k < tables::size(tables::styles); ++k)
|
for (const tables::style_type style : tables::style_types)
|
||||||
{
|
{
|
||||||
aoptions.style = k;
|
aoptions.style = style;
|
||||||
|
|
||||||
tables::array(rows, columns, array, nullptr, nullptr, aoptions);
|
tables::array(rows, columns, array, nullptr, nullptr, aoptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (array != nullptr)
|
if (array)
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < rows; ++i)
|
for (unsigned int i = 0; i < rows; ++i)
|
||||||
delete[] array[i];
|
delete[] array[i];
|
||||||
@ -448,14 +448,14 @@ int main()
|
|||||||
|
|
||||||
tables::options aoptions;
|
tables::options aoptions;
|
||||||
|
|
||||||
for (unsigned int k = 0; k < tables::size(tables::styles); ++k)
|
for (const tables::style_type style : tables::style_types)
|
||||||
{
|
{
|
||||||
aoptions.style = k;
|
aoptions.style = style;
|
||||||
|
|
||||||
tables::array(rows, columns, array, nullptr, nullptr, aoptions);
|
tables::array(rows, columns, array, nullptr, nullptr, aoptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (array != nullptr)
|
if (array)
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < rows; ++i)
|
for (unsigned int i = 0; i < rows; ++i)
|
||||||
delete[] array[i];
|
delete[] array[i];
|
||||||
@ -477,9 +477,9 @@ int main()
|
|||||||
|
|
||||||
tables::options aoptions;
|
tables::options aoptions;
|
||||||
|
|
||||||
for (unsigned int k = 0; k < tables::size(tables::styles); ++k)
|
for (const tables::style_type style : tables::style_types)
|
||||||
{
|
{
|
||||||
aoptions.style = k;
|
aoptions.style = style;
|
||||||
|
|
||||||
tables::array(aarray, headerrow, headercolumn, aoptions);
|
tables::array(aarray, headerrow, headercolumn, aoptions);
|
||||||
}
|
}
|
||||||
@ -498,9 +498,9 @@ int main()
|
|||||||
|
|
||||||
tables::options aoptions;
|
tables::options aoptions;
|
||||||
|
|
||||||
for (unsigned int k = 0; k < tables::size(tables::styles); ++k)
|
for (const tables::style_type style : tables::style_types)
|
||||||
{
|
{
|
||||||
aoptions.style = k;
|
aoptions.style = style;
|
||||||
|
|
||||||
tables::array(array, headerrow, headercolumn, aoptions);
|
tables::array(array, headerrow, headercolumn, aoptions);
|
||||||
}
|
}
|
||||||
@ -512,11 +512,11 @@ int main()
|
|||||||
aoptions.headerrow = true;
|
aoptions.headerrow = true;
|
||||||
// tables::options aoptions{.headerrow = true};
|
// tables::options aoptions{.headerrow = true};
|
||||||
|
|
||||||
for (unsigned int k = 0; k < tables::size(tables::styles); ++k)
|
for (const tables::style_type style : tables::style_types)
|
||||||
{
|
{
|
||||||
aoptions.style = k;
|
aoptions.style = style;
|
||||||
|
|
||||||
tables::function(xmin, xmax, xscl, afunction, aoptions);
|
tables::function(xmin, xmax, xstep, afunction, aoptions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
@ -527,11 +527,11 @@ int main()
|
|||||||
aoptions.headerrow = true;
|
aoptions.headerrow = true;
|
||||||
// tables::options aoptions{.headerrow = true};
|
// tables::options aoptions{.headerrow = true};
|
||||||
|
|
||||||
for (unsigned int k = 0; k < tables::size(tables::styles); ++k)
|
for (const tables::style_type style : tables::style_types)
|
||||||
{
|
{
|
||||||
aoptions.style = k;
|
aoptions.style = style;
|
||||||
|
|
||||||
tables::function(xmin, xmax, xscl, afunction, aoptions);
|
tables::function(xmin, xmax, xstep, afunction, aoptions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Output multiple functions as table
|
// Output multiple functions as table
|
||||||
@ -543,11 +543,11 @@ int main()
|
|||||||
aoptions.headerrow = true;
|
aoptions.headerrow = true;
|
||||||
// tables::options aoptions{.headerrow = true};
|
// tables::options aoptions{.headerrow = true};
|
||||||
|
|
||||||
for (unsigned int k = 0; k < tables::size(tables::styles); ++k)
|
for (const tables::style_type style : tables::style_types)
|
||||||
{
|
{
|
||||||
aoptions.style = k;
|
aoptions.style = style;
|
||||||
|
|
||||||
tables::functions(xmin, xmax, xscl, 2, functions, aoptions);
|
tables::functions(xmin, xmax, xstep, tables::size(functions), functions, aoptions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
@ -560,11 +560,11 @@ int main()
|
|||||||
aoptions.headerrow = true;
|
aoptions.headerrow = true;
|
||||||
// tables::options aoptions{.headerrow = true};
|
// tables::options aoptions{.headerrow = true};
|
||||||
|
|
||||||
for (unsigned int k = 0; k < tables::size(tables::styles); ++k)
|
for (const tables::style_type style : tables::style_types)
|
||||||
{
|
{
|
||||||
aoptions.style = k;
|
aoptions.style = style;
|
||||||
|
|
||||||
tables::functions(xmin, xmax, xscl, 2, functions, aoptions);
|
tables::functions(xmin, xmax, xstep, tables::size(functions), functions, aoptions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
194
tables.hpp
194
tables.hpp
@ -9,6 +9,7 @@
|
|||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
#include <numeric>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
@ -17,6 +18,19 @@ namespace tables
|
|||||||
{
|
{
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
enum style_type
|
||||||
|
{
|
||||||
|
style_ASCII,
|
||||||
|
style_basic,
|
||||||
|
style_light,
|
||||||
|
style_heavy,
|
||||||
|
style_double,
|
||||||
|
style_light_dashed,
|
||||||
|
style_heavy_dashed
|
||||||
|
};
|
||||||
|
|
||||||
|
enum style_type const style_types[] = {style_ASCII, style_basic, style_light, style_heavy, style_double, style_light_dashed, style_heavy_dashed};
|
||||||
|
|
||||||
const char *const styles[][11] = {
|
const char *const styles[][11] = {
|
||||||
{"-", "|", "+", "+", "+", "+", "+", "+", "+", "+", "+"}, // ASCII
|
{"-", "|", "+", "+", "+", "+", "+", "+", "+", "+", "+"}, // ASCII
|
||||||
{"—", "|", "+", "+", "+", "+", "+", "+", "+", "+", "+"}, // Basic
|
{"—", "|", "+", "+", "+", "+", "+", "+", "+", "+", "+"}, // Basic
|
||||||
@ -28,7 +42,7 @@ namespace tables
|
|||||||
};
|
};
|
||||||
// {" ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "}};//No border
|
// {" ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "}};//No border
|
||||||
|
|
||||||
regex ansi(R"(\x1B\[(?:[0-9]+(?:;[0-9]+)*)?m)");
|
const regex ansi(R"(\x1B\[(?:[0-9]+(?:;[0-9]+)*)?m)");
|
||||||
|
|
||||||
struct options
|
struct options
|
||||||
{
|
{
|
||||||
@ -40,13 +54,14 @@ namespace tables
|
|||||||
ios_base &(*alignment)(ios_base &) = left;
|
ios_base &(*alignment)(ios_base &) = left;
|
||||||
bool boolalpha = false;
|
bool boolalpha = false;
|
||||||
const char *title = nullptr;
|
const char *title = nullptr;
|
||||||
unsigned int style = 2;
|
style_type style = style_light;
|
||||||
|
bool check = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const options defaultoptions;
|
const options defaultoptions;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
auto size(const T &array)
|
constexpr size_t size(const T &array)
|
||||||
{
|
{
|
||||||
return distance(begin(array), end(array));
|
return distance(begin(array), end(array));
|
||||||
}
|
}
|
||||||
@ -74,11 +89,11 @@ namespace tables
|
|||||||
}
|
}
|
||||||
++length;
|
++length;
|
||||||
|
|
||||||
wchar_t *wcstring = new wchar_t[length];
|
auto *wcstring = new wchar_t[length];
|
||||||
|
|
||||||
if (mbstowcs(wcstring, str, length) == static_cast<size_t>(-1))
|
if (mbstowcs(wcstring, str, length) == static_cast<size_t>(-1))
|
||||||
{
|
{
|
||||||
if (wcstring != nullptr)
|
if (wcstring)
|
||||||
delete[] wcstring;
|
delete[] wcstring;
|
||||||
|
|
||||||
cerr << "\nError! mbstowcs failed. Invalid multibyte character.\n";
|
cerr << "\nError! mbstowcs failed. Invalid multibyte character.\n";
|
||||||
@ -92,7 +107,7 @@ namespace tables
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wcstring != nullptr)
|
if (wcstring)
|
||||||
delete[] wcstring;
|
delete[] wcstring;
|
||||||
|
|
||||||
return width;
|
return width;
|
||||||
@ -103,8 +118,7 @@ namespace tables
|
|||||||
// Adapted from: https://stackoverflow.com/a/42016346 and https://stackoverflow.com/a/13094734
|
// Adapted from: https://stackoverflow.com/a/42016346 and https://stackoverflow.com/a/13094734
|
||||||
string wrap(const char *const str, const size_t line_length)
|
string wrap(const char *const str, const size_t line_length)
|
||||||
{
|
{
|
||||||
char words[strlen(str) + 1];
|
string words = str;
|
||||||
strcpy(words, str);
|
|
||||||
string wrapped;
|
string wrapped;
|
||||||
|
|
||||||
size_t index = 0;
|
size_t index = 0;
|
||||||
@ -127,7 +141,7 @@ namespace tables
|
|||||||
}
|
}
|
||||||
|
|
||||||
char temp[templinelen + 1];
|
char temp[templinelen + 1];
|
||||||
strncpy(temp, words + (index - linelen), templinelen);
|
strncpy(temp, words.data() + (index - linelen), templinelen);
|
||||||
temp[templinelen] = '\0';
|
temp[templinelen] = '\0';
|
||||||
|
|
||||||
size_t width = strcol(temp);
|
size_t width = strcol(temp);
|
||||||
@ -163,76 +177,83 @@ namespace tables
|
|||||||
const bool cellborder = aoptions.cellborder;
|
const bool cellborder = aoptions.cellborder;
|
||||||
const unsigned int padding = aoptions.padding;
|
const unsigned int padding = aoptions.padding;
|
||||||
const char *const title = aoptions.title;
|
const char *const title = aoptions.title;
|
||||||
const unsigned int style = aoptions.style;
|
const style_type style = aoptions.style;
|
||||||
|
|
||||||
if (style >= tables::size(styles))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
const size_t rows = array.size();
|
const size_t rows = array.size();
|
||||||
const size_t columns = array[0].size();
|
const size_t columns = array[0].size();
|
||||||
|
|
||||||
int columnwidth[columns];
|
int columnwidth[columns];
|
||||||
for (unsigned int j = 0; j < columns; ++j)
|
for (size_t j = 0; j < columns; ++j)
|
||||||
columnwidth[j] = 0;
|
columnwidth[j] = 0;
|
||||||
|
|
||||||
int width = 0;
|
setlocale(LC_ALL, "");
|
||||||
|
|
||||||
setlocale(LC_CTYPE, "");
|
for (size_t j = 0; j < columns; ++j)
|
||||||
|
|
||||||
for (unsigned int j = 0; j < columns; ++j)
|
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < rows; ++i)
|
for (size_t i = 0; i < rows; ++i)
|
||||||
{
|
{
|
||||||
int cellwidth = strcol(array[i][j].c_str());
|
const int cellwidth = strcol(array[i][j].c_str());
|
||||||
if (cellwidth > columnwidth[j])
|
if (cellwidth > columnwidth[j])
|
||||||
columnwidth[j] = cellwidth;
|
columnwidth[j] = cellwidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
width += columnwidth[j];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct winsize w;
|
struct winsize w;
|
||||||
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
|
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
|
||||||
|
|
||||||
|
size_t width = accumulate(columnwidth, columnwidth + columns, 0ul);
|
||||||
|
|
||||||
if (tableborder or cellborder or headerrow or headercolumn)
|
if (tableborder or cellborder or headerrow or headercolumn)
|
||||||
width += (((2 * padding) + 1) * columns) + (tableborder ? 1 : -1);
|
width += (((2 * padding) + 1) * columns) + (tableborder ? 1 : -1);
|
||||||
else
|
else
|
||||||
width += (2 * padding) * columns;
|
width += (2 * padding) * columns;
|
||||||
|
|
||||||
if (width > w.ws_col)
|
if (aoptions.check)
|
||||||
{
|
{
|
||||||
cerr << "The width of the table (" << width << ") is greater then the width of the terminal (" << w.ws_col << ").\n";
|
if (width > w.ws_col)
|
||||||
return 1;
|
{
|
||||||
|
cerr << "The width of the table (" << width << ") is greater then the width of the terminal (" << w.ws_col << ").\n";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (title != nullptr and title[0] != '\0')
|
if (title and title[0] != '\0')
|
||||||
cout << wrap(title, w.ws_col) << "\n";
|
cout << wrap(title, width) << "\n";
|
||||||
|
|
||||||
|
if (aoptions.alignment)
|
||||||
|
cout << aoptions.alignment;
|
||||||
|
|
||||||
if (tableborder)
|
if (tableborder)
|
||||||
{
|
{
|
||||||
cout << styles[style][2];
|
cout << styles[style][2];
|
||||||
|
|
||||||
for (unsigned int j = 0; j < columns; ++j)
|
for (size_t j = 0; j < columns; ++j)
|
||||||
{
|
{
|
||||||
for (unsigned int k = 0; k < (2 * padding) + columnwidth[j]; ++k)
|
for (size_t k = 0; k < (2 * padding) + columnwidth[j]; ++k)
|
||||||
cout << styles[style][0];
|
cout << styles[style][0];
|
||||||
|
|
||||||
if (j == (columns - 1))
|
if (j < (columns - 1))
|
||||||
cout << styles[style][4] << "\n";
|
{
|
||||||
else if (cellborder or headerrow or (j == 0 and headercolumn))
|
if (cellborder or headerrow or (j == 0 and headercolumn))
|
||||||
cout << styles[style][3];
|
cout << styles[style][3];
|
||||||
else
|
else
|
||||||
cout << styles[style][0];
|
cout << styles[style][0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cout << styles[style][4] << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned int i = 0; i < rows; ++i)
|
for (size_t i = 0; i < rows; ++i)
|
||||||
{
|
{
|
||||||
for (unsigned int j = 0; j < columns; ++j)
|
if (tableborder)
|
||||||
|
cout << styles[style][1];
|
||||||
|
|
||||||
|
for (size_t j = 0; j < columns; ++j)
|
||||||
{
|
{
|
||||||
if ((j == 0 and tableborder) or (j > 0 and cellborder) or (i == 0 and j > 0 and headerrow) or (j == 1 and headercolumn))
|
if ((j and cellborder) or (i == 0 and j and headerrow) or (j == 1 and headercolumn))
|
||||||
cout << styles[style][1];
|
cout << styles[style][1];
|
||||||
else if (tableborder or (i > 0 and j > 0 and headerrow) or (j > 1 and headercolumn))
|
else if (j and (tableborder or (i and headerrow) or headercolumn))
|
||||||
cout << " ";
|
cout << " ";
|
||||||
|
|
||||||
const int difference = columnwidth[j] - strcol(array[i][j].c_str());
|
const int difference = columnwidth[j] - strcol(array[i][j].c_str());
|
||||||
@ -251,7 +272,7 @@ namespace tables
|
|||||||
{
|
{
|
||||||
cout << string(padding, ' ');
|
cout << string(padding, ' ');
|
||||||
|
|
||||||
cout << aoptions.alignment << setw(difference + array[i][j].length()) << array[i][j];
|
cout << setw(difference + array[i][j].length()) << array[i][j];
|
||||||
|
|
||||||
cout << string(padding, ' ');
|
cout << string(padding, ' ');
|
||||||
}
|
}
|
||||||
@ -272,29 +293,15 @@ namespace tables
|
|||||||
|
|
||||||
if ((i == (rows - 1) and tableborder) or (i < (rows - 1) and cellborder) or (i == 0 and headerrow) or (i < (rows - 1) and headercolumn))
|
if ((i == (rows - 1) and tableborder) or (i < (rows - 1) and cellborder) or (i == 0 and headerrow) or (i < (rows - 1) and headercolumn))
|
||||||
{
|
{
|
||||||
for (unsigned int j = 0; j < columns; ++j)
|
for (size_t j = 0; j < columns; ++j)
|
||||||
{
|
{
|
||||||
if ((i == (rows - 1) and tableborder) or (i < (rows - 1) and cellborder) or (i == 0 and headerrow) or (i < (rows - 1) and j == 0 and headercolumn))
|
if ((i == (rows - 1) and tableborder) or (i < (rows - 1) and cellborder) or (i == 0 and headerrow) or (i < (rows - 1) and j == 0 and headercolumn))
|
||||||
for (unsigned int k = 0; k < (2 * padding) + columnwidth[j]; ++k)
|
for (size_t k = 0; k < (2 * padding) + columnwidth[j]; ++k)
|
||||||
cout << styles[style][0];
|
cout << styles[style][0];
|
||||||
else if (i < (rows - 1) and headercolumn)
|
else if (i < (rows - 1) and headercolumn)
|
||||||
cout << string((2 * padding) + columnwidth[j], ' ');
|
cout << string((2 * padding) + columnwidth[j], ' ');
|
||||||
|
|
||||||
if (j == (columns - 1))
|
if (j < (columns - 1))
|
||||||
{
|
|
||||||
if (tableborder)
|
|
||||||
{
|
|
||||||
if (i == (rows - 1))
|
|
||||||
cout << styles[style][10];
|
|
||||||
else if (cellborder or (i == 0 and headerrow))
|
|
||||||
cout << styles[style][7];
|
|
||||||
else if (headercolumn)
|
|
||||||
cout << styles[style][1];
|
|
||||||
}
|
|
||||||
|
|
||||||
cout << "\n";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
if (i == (rows - 1) and tableborder)
|
if (i == (rows - 1) and tableborder)
|
||||||
{
|
{
|
||||||
@ -316,6 +323,19 @@ namespace tables
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tableborder)
|
||||||
|
{
|
||||||
|
if (i == (rows - 1))
|
||||||
|
cout << styles[style][10];
|
||||||
|
else if (cellborder or (i == 0 and headerrow))
|
||||||
|
cout << styles[style][7];
|
||||||
|
else if (headercolumn)
|
||||||
|
cout << styles[style][1];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i < (rows - 1))
|
||||||
|
cout << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -331,30 +351,30 @@ namespace tables
|
|||||||
if (!tables::size(aarray))
|
if (!tables::size(aarray))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
unsigned int i = 0;
|
size_t i = 0;
|
||||||
unsigned int j = 0;
|
size_t j = 0;
|
||||||
|
|
||||||
size_t rows = tables::size(aarray);
|
size_t rows = tables::size(aarray);
|
||||||
size_t columns = tables::size(aarray[0]);
|
size_t columns = tables::size(aarray[0]);
|
||||||
|
|
||||||
if (!all_of(begin(aarray), end(aarray), [columns](auto &x)
|
if (!all_of(begin(aarray), end(aarray), [columns](const auto &x)
|
||||||
{ return tables::size(x) == columns; }))
|
{ return tables::size(x) == columns; }))
|
||||||
{
|
{
|
||||||
cerr << "Error: The rows of the array must have the same number of columns.";
|
cerr << "Error: The rows of the array must have the same number of columns.\n";
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (headerrow != nullptr)
|
if (headerrow)
|
||||||
++rows;
|
++rows;
|
||||||
|
|
||||||
if (headercolumn != nullptr)
|
if (headercolumn)
|
||||||
++columns;
|
++columns;
|
||||||
|
|
||||||
vector<vector<string>> aaarray(rows, vector<string>(columns));
|
vector<vector<string>> aaarray(rows, vector<string>(columns));
|
||||||
|
|
||||||
if (headerrow != nullptr)
|
if (headerrow)
|
||||||
{
|
{
|
||||||
for (unsigned int j = 0; j < columns; ++j)
|
for (size_t j = 0; j < columns; ++j)
|
||||||
{
|
{
|
||||||
aaarray[i][j] = headerrow[j];
|
aaarray[i][j] = headerrow[j];
|
||||||
}
|
}
|
||||||
@ -362,13 +382,13 @@ namespace tables
|
|||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned int ii = 0; i < rows; ++i)
|
for (size_t ii = 0; i < rows; ++i)
|
||||||
{
|
{
|
||||||
if (headercolumn != nullptr)
|
if (headercolumn)
|
||||||
{
|
{
|
||||||
unsigned int ii = i;
|
size_t ii = i;
|
||||||
|
|
||||||
if (headerrow != nullptr)
|
if (headerrow)
|
||||||
--ii;
|
--ii;
|
||||||
|
|
||||||
aaarray[i][j] = headercolumn[ii];
|
aaarray[i][j] = headercolumn[ii];
|
||||||
@ -376,7 +396,7 @@ namespace tables
|
|||||||
++j;
|
++j;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned int jj = 0; j < columns; ++j)
|
for (size_t jj = 0; j < columns; ++j)
|
||||||
{
|
{
|
||||||
ostringstream strm;
|
ostringstream strm;
|
||||||
|
|
||||||
@ -400,7 +420,7 @@ namespace tables
|
|||||||
int array(const size_t rows, const size_t columns, T **aarray, const char *const headerrow[] = nullptr, const char *const headercolumn[] = nullptr, const options &aoptions = defaultoptions)
|
int array(const size_t rows, const size_t columns, T **aarray, const char *const headerrow[] = nullptr, const char *const headercolumn[] = nullptr, const options &aoptions = defaultoptions)
|
||||||
{
|
{
|
||||||
vector<vector<T>> aaarray(rows, vector<T>(columns));
|
vector<vector<T>> aaarray(rows, vector<T>(columns));
|
||||||
for (unsigned int i = 0; i < rows; ++i)
|
for (size_t i = 0; i < rows; ++i)
|
||||||
copy(aarray[i], aarray[i] + columns, aaarray[i].begin());
|
copy(aarray[i], aarray[i] + columns, aaarray[i].begin());
|
||||||
|
|
||||||
string *aheaderrow = nullptr;
|
string *aheaderrow = nullptr;
|
||||||
@ -434,7 +454,7 @@ namespace tables
|
|||||||
|
|
||||||
// Convert one or more functions to array and output as table
|
// Convert one or more functions to array and output as table
|
||||||
template <typename T>
|
template <typename T>
|
||||||
int functions(const long double xmin, const long double xmax, const long double xscl, const size_t numfunctions, function<T(T)> functions[], const options &aoptions = defaultoptions)
|
int functions(const long double xmin, const long double xmax, const long double xstep, const size_t numfunctions, function<T(T)> functions[], const options &aoptions = defaultoptions)
|
||||||
{
|
{
|
||||||
if (numfunctions == 0)
|
if (numfunctions == 0)
|
||||||
return 1;
|
return 1;
|
||||||
@ -445,13 +465,13 @@ namespace tables
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xscl <= 0)
|
if (xstep <= 0)
|
||||||
{
|
{
|
||||||
cerr << "xscl must be greater than zero.\n";
|
cerr << "xstep must be greater than zero.\n";
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t rows = ((xmax - xmin) * xscl) + 1;
|
const size_t rows = ((xmax - xmin) / xstep) + 1;
|
||||||
const size_t columns = numfunctions + 1;
|
const size_t columns = numfunctions + 1;
|
||||||
|
|
||||||
const char *const aheaderrow[] = {"x", "y"};
|
const char *const aheaderrow[] = {"x", "y"};
|
||||||
@ -459,9 +479,9 @@ namespace tables
|
|||||||
|
|
||||||
const size_t length = tables::size(aheaderrow);
|
const size_t length = tables::size(aheaderrow);
|
||||||
|
|
||||||
string *headerrow = new string[columns];
|
auto *headerrow = new string[columns];
|
||||||
|
|
||||||
for (unsigned int j = 0; j < columns; ++j)
|
for (size_t j = 0; j < columns; ++j)
|
||||||
{
|
{
|
||||||
if (j < (length - 1) or numfunctions == 1)
|
if (j < (length - 1) or numfunctions == 1)
|
||||||
{
|
{
|
||||||
@ -478,7 +498,7 @@ namespace tables
|
|||||||
string *headercolumn = nullptr;
|
string *headercolumn = nullptr;
|
||||||
// headercolumn = new string[rows + 1];
|
// headercolumn = new string[rows + 1];
|
||||||
|
|
||||||
// for (unsigned int i = 0; i < rows + 1; ++i)
|
// for (size_t i = 0; i < rows + 1; ++i)
|
||||||
// {
|
// {
|
||||||
// ostringstream strm;
|
// ostringstream strm;
|
||||||
// strm << i + 1;
|
// strm << i + 1;
|
||||||
@ -487,22 +507,22 @@ namespace tables
|
|||||||
|
|
||||||
vector<vector<T>> aarray(rows, vector<T>(columns));
|
vector<vector<T>> aarray(rows, vector<T>(columns));
|
||||||
|
|
||||||
for (unsigned int i = 0; i < rows; ++i)
|
for (size_t i = 0; i < rows; ++i)
|
||||||
{
|
{
|
||||||
aarray[i][0] = (i / xscl) + xmin;
|
aarray[i][0] = (i * xstep) + xmin;
|
||||||
|
|
||||||
for (unsigned int j = 0; j < numfunctions; ++j)
|
for (size_t j = 0; j < numfunctions; ++j)
|
||||||
aarray[i][j + 1] = (functions[j])(aarray[i][0]);
|
aarray[i][j + 1] = (functions[j])(aarray[i][0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
int code = array(aarray, headerrow, headercolumn, aoptions);
|
int code = array(aarray, headerrow, headercolumn, aoptions);
|
||||||
|
|
||||||
if (headerrow != nullptr)
|
if (headerrow)
|
||||||
{
|
{
|
||||||
delete[] headerrow;
|
delete[] headerrow;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (headercolumn != nullptr)
|
// if (headercolumn)
|
||||||
// {
|
// {
|
||||||
// delete[] headercolumn;
|
// delete[] headercolumn;
|
||||||
// }
|
// }
|
||||||
@ -512,20 +532,20 @@ namespace tables
|
|||||||
|
|
||||||
// Convert single function to array and output as table
|
// Convert single function to array and output as table
|
||||||
template <typename T>
|
template <typename T>
|
||||||
int function(const long double xmin, const long double xmax, const long double xscl, const function<T(T)> &afunction, const options &aoptions = defaultoptions)
|
int function(const long double xmin, const long double xmax, const long double xstep, const function<T(T)> &afunction, const options &aoptions = defaultoptions)
|
||||||
{
|
{
|
||||||
std::function<T(T)> afunctions[] = {afunction};
|
std::function<T(T)> afunctions[] = {afunction};
|
||||||
|
|
||||||
return functions(xmin, xmax, xscl, 1, afunctions, aoptions);
|
return functions(xmin, xmax, xstep, 1, afunctions, aoptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert single function to array and output as table
|
// Convert single function to array and output as table
|
||||||
template <typename T>
|
template <typename T>
|
||||||
int function(const long double xmin, const long double xmax, const long double xscl, T afunction(T), const options &aoptions = defaultoptions)
|
int function(const long double xmin, const long double xmax, const long double xstep, T afunction(T), const options &aoptions = defaultoptions)
|
||||||
{
|
{
|
||||||
std::function<T(T)> afunctions[] = {afunction};
|
std::function<T(T)> afunctions[] = {afunction};
|
||||||
|
|
||||||
return functions(xmin, xmax, xscl, 1, afunctions, aoptions);
|
return functions(xmin, xmax, xstep, 1, afunctions, aoptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user