k1a  1.1
Accelerated functionalities for k1lib
funcs.cpp
Go to the documentation of this file.
1 
6 #define PY_SSIZE_T_CLEAN
7 #include <Python.h>
8 
9 #include <string>
10 
11 #include "StrIterCat.h"
12 #include "StrIterInter.h"
13 #include "utils.h"
14 
15 namespace k1a {
16 
17 PyObject *k1a_system(PyObject *self, PyObject *args) {
18  const char *command;
19  int sts;
20 
21  if (!PyArg_ParseTuple(args, "s", &command)) return NULL;
22  sts = system(command);
23  if (sts < 0) {
24  // TODO: add exception string
25  return NULL;
26  }
27  return PyLong_FromLong(sts);
28 }
29 
30 PyObject *k1a_test(PyObject *self, PyObject *args) {
31  const char *str;
32  if (!PyArg_ParseTuple(args, "s", &str)) return NULL;
33  const std::string a = str;
34  auto b = (PyStrIterCat *)PyStrIterCat_new(a);
35  auto f1 = [](std::string x) { return x + " |end"; };
36  auto f2 = [](std::string x) { return "begin| " + x; };
37  return b->val->transform(std::vector<transformF>{f1, f2}, true)->pyObj;
38  // return PyUnicode_FromString("def");
39  // return PyUnicode_FromString((a + "end").c_str());
40 }
41 
52 PyObject *k1a_str_split(PyObject *self, PyObject *args) {
53  char *_str, *_delim, *str, *begin;
54  if (!PyArg_ParseTuple(args, "ss", &_str, &_delim)) return NULL;
55  char delim = _delim[0], quoteChar = '"';
56 
57  begin = str = (char *)malloc((strlen(_str) + 1) * sizeof(char));
58  strcpy(str, _str);
59  PyObject *plist = PyList_New(0);
60 
61  int i = 0;
62  bool inBlock = false;
63 
64  while (str[i] != NULL) {
65  char a = str[i];
66  if (a == delim && !inBlock) {
67  str[i] = NULL;
68  PyList_Append(plist, PyUnicode_FromString(begin));
69  begin = str + (i + 1);
70  } else if (!inBlock && (a == '"' || a == '\'')) { // new block
71  inBlock = true;
72  quoteChar = a;
73  } else if (inBlock && a == quoteChar)
74  inBlock = false; // exiting block
75  i++;
76  }
77  PyList_Append(plist, PyUnicode_FromString(begin));
78  free(str);
79  return plist;
80 }
81 
92 PyObject *k1a_str_alpha_numeric(PyObject *self, PyObject *args) {
93  char *_str, *str;
94  if (!PyArg_ParseTuple(args, "s", &_str)) return NULL;
95  str = (char *)malloc((strlen(_str) + 1) * sizeof(char));
96  int i = 0, j = 0;
97  bool stillSpecial = false;
98 
99  while (_str[i] != NULL) {
100  unsigned int a = _str[i];
101  if ((65 <= a && a <= 90) || (97 <= a && a <= 122) || (48 <= a && a <= 57)) { // legit characters
102  str[j] = a;
103  j++;
104  stillSpecial = false;
105  } else {
106  if (!stillSpecial) {
107  str[j] = ' ';
108  j++;
109  }
110  stillSpecial = true;
111  }
112  i++;
113  }
114  str[j] = '\0';
115  auto res = PyUnicode_FromString(str);
116  free(str);
117  return res;
118 }
119 
130 PyObject *k1a_str_kmers(PyObject *self, PyObject *args) {
131  char *str;
132  int k;
133  if (!PyArg_ParseTuple(args, "si", &str, &k)) return NULL;
134  PyObject *plist = PyList_New(0);
135 
136  bool inBlock = false;
137  int n = strlen(str);
138  if (n < k) return plist;
139 
140  for (int i = 0; i < n - (k - 1); i++) {
141  char tmp = str[i + k];
142  str[i + k] = '\0';
143  PyList_Append(plist, PyUnicode_FromString(str + i));
144  str[i + k] = tmp;
145  }
146  return plist;
147 }
148 
161 PyObject *k1a_str_has_number(PyObject *self, PyObject *args) {
162  char *str;
163  if (!PyArg_ParseTuple(args, "s", &str)) return NULL;
164  int i = 0;
165  while (str[i] != NULL) {
166  unsigned int a = str[i];
167  if (48 <= a && a <= 57) {
168  Py_INCREF(Py_True);
169  return Py_True;
170  }
171  i++;
172  }
173  Py_INCREF(Py_False);
174  return Py_False;
175 }
176 
177 PyMethodDef K1aMethods[] = {
178  {"system", k1a_system, METH_VARARGS, "Execute a shell command."},
179  {"test", k1a_test, METH_VARARGS,
180  "Test function for developing the library"},
181  {"clear", k1a_log_clear, METH_VARARGS, "Clear logs"},
182  {"str_split", k1a_str_split, METH_VARARGS,
183  "str_split(s, ch). Splits string into multiple fragments using a delimiter, respecting quotes."
184  "\n\nExample: k1a.str_split(\"'ab'cdb3\", \"b\") == [\"'ab'cd\", \"3\"]"},
185  {"str_alpha_numeric", k1a_str_alpha_numeric, METH_VARARGS, "str_alpha_numeric(s). Replaces characters that are not alpha numeric with white spaces. \n\nExample: str_alpha_numeric(\"4,.53-45ag\") == \"4 53 45ag\""},
186  {"str_kmers", k1a_str_kmers, METH_VARARGS, "str_kmers(s, k). Gets a string's k-mers. \n\nExample: k1a.str_kmers(\"abcde\", 2) == ['ab', 'bc', 'cd', 'de']"},
187  {"str_has_number", k1a_str_has_number, METH_VARARGS, "str_has_number(s). Returns whether the string has any numeric characters inside them."},
188  {NULL, NULL, 0, NULL} /* Sentinel */
189 };
190 
191 struct PyModuleDef k1amodule = {
192  PyModuleDef_HEAD_INIT, "k1a", /* name of module */
193  NULL, /* module documentation, may be NULL */
194  -1, /* size of per-interpreter state of the module,
195  or -1 if the module keeps state in global variables. */
196  K1aMethods};
197 
198 } // namespace k1a
Definition: funcs.cpp:15
PyObject * k1a_str_kmers(PyObject *self, PyObject *args)
Returns all k-mers for the given string.
Definition: funcs.cpp:130
PyObject * PyStrIterCat_new(std::string fileName)
Creates a new PyStrIterCat object.
Definition: StrIterCat.cpp:37
PyObject * k1a_str_split(PyObject *self, PyObject *args)
Splits a string up into multiple pieces, respecting quotation marks.
Definition: funcs.cpp:52
PyObject * k1a_test(PyObject *self, PyObject *args)
Definition: funcs.cpp:30
PyObject * k1a_str_alpha_numeric(PyObject *self, PyObject *args)
Gets rid of special characters and only retain alpha numeric characters.
Definition: funcs.cpp:92
PyObject * k1a_log_clear(PyObject *self, PyObject *args)
Definition: utils.cpp:23
PyObject * k1a_system(PyObject *self, PyObject *args)
Definition: funcs.cpp:17
PyMethodDef K1aMethods[]
Definition: funcs.cpp:177
PyObject * k1a_str_has_number(PyObject *self, PyObject *args)
Returns whether the string has any numeric characters inside them.
Definition: funcs.cpp:161
struct PyModuleDef k1amodule
Definition: funcs.cpp:191