demo2.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. // draws a single graph
  2. // uses plenv
  3. #include <Python.h>
  4. #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
  5. #include <numpy/arrayobject.h>
  6. #include <plplot/plplot.h>
  7. #include <stdio.h>
  8. #include <stdbool.h>
  9. #include <string.h>
  10. void plot_data (PyObject* stonk_datum, const char *ticker) {
  11. // prepare to plot
  12. int nd = PyArray_NDIM(
  13. (PyArrayObject *)stonk_datum
  14. );
  15. npy_intp *dims = PyArray_DIMS(
  16. (PyArrayObject *)stonk_datum
  17. );
  18. unsigned int rows = dims[0];
  19. double *x = (double*) malloc (rows * sizeof(double));
  20. double *y = (double*) malloc (rows * sizeof(double));
  21. #define TIMESTAMP_COL 0
  22. #define CLOSE_PRICE_COL 3
  23. // time, open, high, low, close, volume
  24. // 0 1 2 3 4 5
  25. double time, close, high, low;
  26. double ymax = 0;
  27. double ymin = -1;
  28. for (npy_intp i = 0; i < rows ; i++) {
  29. // just copy the tiem for x axis
  30. time = *(double *)PyArray_GETPTR2(
  31. (PyArrayObject *)stonk_datum, i, 0);
  32. x[i] = time;
  33. close = *(double *)PyArray_GETPTR2(
  34. (PyArrayObject *)stonk_datum, i, 4);
  35. y[i] = close;
  36. high = *(double *)PyArray_GETPTR2(
  37. (PyArrayObject *)stonk_datum, i, 2);
  38. if (high > ymax) {
  39. ymax = high;
  40. }
  41. low = *(double *)PyArray_GETPTR2(
  42. (PyArrayObject *)stonk_datum, i, 3);
  43. if (low < ymin || ymin == -1) {
  44. ymin = low;
  45. }
  46. }
  47. // printf("*(%.2f, %.2f)\n", ymin, ymax);
  48. double xmin = x[0];
  49. double xmax = x[rows-1];
  50. char title[256];
  51. strcat(title, ticker);
  52. plinit();
  53. plenv( xmin, xmax, ymin, ymax, 0, 0 );
  54. pllab( "x in unix time", "Price (USD)", title);
  55. plline(rows, x, y );
  56. plend();
  57. free(x);
  58. free(y);
  59. }
  60. void get_user_input(char *input) {
  61. printf("Enter a ticker: ");
  62. if (fgets(input, sizeof(input), stdin) != NULL) {
  63. input[strcspn(input, "\n")] = '\0';
  64. } else {
  65. perror("Error reading input");
  66. }
  67. size_t len = strlen(input);
  68. // turn to caps for aesthetics.
  69. for (unsigned int i=0; i < len; i++) {
  70. input[i] = toupper(input[i]);
  71. }
  72. return;
  73. }
  74. bool get_numpy_array(PyObject *script) {
  75. if (script == NULL) {
  76. return false;
  77. }
  78. bool is_ok = true;
  79. PyObject *pyfn = PyObject_GetAttrString(script, "invoke_from_c");
  80. if (pyfn == NULL || !PyCallable_Check(pyfn)) {
  81. if (PyErr_Occurred()) {
  82. PyErr_Print();
  83. }
  84. is_ok = false;
  85. goto free;
  86. }
  87. char s[16];
  88. get_user_input(s);
  89. PyObject *pargs = PyTuple_Pack(
  90. 1, PyUnicode_FromString(s)
  91. );
  92. PyObject *numpy_array = PyObject_CallObject(pyfn, pargs);
  93. Py_XDECREF(pargs);
  94. if (numpy_array == NULL) {
  95. if (PyErr_Occurred()) {
  96. PyErr_Print();
  97. }
  98. fprintf(stderr, "Call to invoke_from_c() failed\n");
  99. is_ok = false;
  100. goto free;
  101. }
  102. if (!PyArray_Check(numpy_array)) {
  103. fprintf(stderr, "did not get a numpy array from function");
  104. is_ok = false;
  105. goto free;
  106. }
  107. // Get the dimensions of the array
  108. int nd = PyArray_NDIM((PyArrayObject *)numpy_array);
  109. npy_intp *dims = PyArray_DIMS(
  110. (PyArrayObject *)numpy_array
  111. );
  112. printf("Array dimensions: %d x %d\n", dims[0], dims[1]);
  113. // Access the elements of the 2D array
  114. #define PREVIEW_ROWS_MAX 3
  115. #define PREVIEW_COLS_MAX 5
  116. for (npy_intp i = 0; i < PREVIEW_ROWS_MAX; i++) {
  117. for (npy_intp j = 0; j < PREVIEW_COLS_MAX; j++) {
  118. // Get the value at (i, j)
  119. double value = *(double *)PyArray_GETPTR2(
  120. (PyArrayObject *)numpy_array, i, j);
  121. printf("%.2lf, ", i, j, value);
  122. }
  123. printf("\n");
  124. }
  125. plot_data(numpy_array, s);
  126. free:
  127. if (pyfn) {
  128. Py_XDECREF(pyfn);
  129. }
  130. if (numpy_array) {
  131. Py_XDECREF(numpy_array);
  132. }
  133. return is_ok;
  134. }
  135. int main() {
  136. // Initialize the Python Interpreter
  137. Py_Initialize();
  138. // import_array(); // Necessary for NumPy
  139. import_array1(0); // same but less compiler complaints
  140. // Import the Python module
  141. PyObject *pName = PyUnicode_FromString("demo1_get-price"); // Name of your Python script without .py
  142. PyObject *pModule = PyImport_Import(pName);
  143. if (pModule == NULL) {
  144. PyErr_Print();
  145. fprintf(stderr, "Failed to load 'demo1'\n");
  146. goto end;
  147. }
  148. bool success = get_numpy_array(pModule);
  149. end:
  150. if (pModule) {
  151. Py_DECREF(pModule);
  152. }
  153. if (pName) {
  154. Py_DECREF(pName);
  155. }
  156. // Finalize the Python Interpreter
  157. Py_Finalize();
  158. return 0;
  159. }