Skip to content

Commit 057fdec

Browse files
committed
fix: cleaner
1 parent a5583b7 commit 057fdec

14 files changed

+223
-126
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
__pycache__/
22
src/csv_to_custom_json.egg-info/
33
dist/
4+
.coverage

README.md

Lines changed: 97 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,105 @@
11
# csv-to-custom-json-python
22

3-
## Tests
3+
- [PyPi page](https://pypi.org/project/csv-to-custom-json/)
4+
- [PyPiStats](https://pypistats.org/packages/csv-to-custom-json)
5+
6+
## How to install
7+
8+
- [installation docs](./docs/How-to-install.md)
49

510
```sh
6-
python3 -m unittest
11+
python3 -m pip install csv-to-custom-json
12+
```
13+
14+
## Tests && coverage
15+
16+
Coverage is 100%
17+
18+
```sh
19+
# install
20+
python -m pip install coverage unittest
21+
22+
# only test
23+
python -m unittest
24+
25+
# coverage
26+
coverage run -m unittest && coverage report -m
727
```
828

29+
## How to use csv-to-custom-json
30+
31+
## Classic usage
32+
33+
Just import the function and use it !
34+
35+
```python
36+
from csv_to_custom_json import parseFile
37+
38+
result = parseFile("myfile.csv")
39+
```
40+
41+
## How to use the schema
42+
43+
Create a schema variable and put it as second parameter !
44+
45+
Exemple with a simple `csv` :
46+
47+
```csv
48+
num1,num2,num3
49+
1,2,3
50+
4,5,6
51+
7,8,9
52+
```
53+
54+
```python
55+
from csv_to_custom_json import parseFile
56+
57+
def callback(value):
58+
return None
59+
60+
schema = {
61+
num1: "string",
62+
callback,
63+
num3: "int"
64+
}
65+
66+
result = parseFile("myfile.csv", schema)
67+
```
68+
69+
> Caption :
70+
>
71+
> - ad you can see the schema can contains function, or string with the type
72+
> - the values with type will be parsed
73+
> - attribute of the object are the word in the first line of the csv
74+
75+
## More complexe schema
76+
77+
It's the same as a simple schema :
78+
79+
```python
80+
from csv_to_custom_json import parseFile
81+
82+
schema = {
83+
obj1: {
84+
obj2: {
85+
num4: "string"
86+
}
87+
},
88+
num2: "",
89+
num3: ""
90+
}
91+
result = parseFile("myfile.csv", schema)
92+
```
93+
94+
If you want to check some real case, check out the folder `test` in the [GitHub repository](https://github.com/Its-Just-Nans/csv-to-custom-json-python)
95+
96+
If you want to see and use options check that documentation: [How-to-options](./docs/How-to-options.md)
97+
98+
## See also
99+
100+
- [Tricks](./docs/How-to-know-more.md)
101+
- [How-to-options](./docs/How-to-options.md)
102+
9103
## License
10104

11-
Licensed under the MIT License - [LICENSE](LICENSE)
105+
Licensed under the MIT License - [LICENSE](LICENSE)

docs/How-to-use.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# How to use csv-to-custom-json
22

3-
## Classic usage
3+
## Classic usage
44

55
Just import the function and use it !
66

setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[metadata]
22
name = csv-to-custom-json
3-
version = 0.0.1
3+
version = 0.0.2
44
author = n4n5
55
author_email = [email protected]
66
description = Easily convert your CSV to custom JSON

src/csv_to_custom_json/__init__.py

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313

1414
def parseFile(path_to_file="", schema=None, options_user={}):
15-
"""Global function to parse a file"""
15+
""" Global function to parse a file """
1616
def check_options(options_user, attr, default_value):
1717
""" Check options or put default value """
1818
if attr in options_user:
@@ -26,7 +26,6 @@ def check_options(options_user, attr, default_value):
2626
"lineCallBack": check_options(options_user, "lineCallBack", None),
2727
"parse": check_options(options_user, "parse", True),
2828
"separator": check_options(options_user, "separator", ","),
29-
"privateSeparator": check_options(options_user, "privateSeparator", "..."),
3029
"overrideFirstLine": check_options(options_user, "overrideFirstLine", False),
3130
"avoidVoidLine": check_options(options_user, "avoidVoidLine", False)
3231
}
@@ -38,20 +37,18 @@ def check_options(options_user, attr, default_value):
3837
print("OPTIONS", JSONstringify(options))
3938
if options["error"] == "no":
4039
print("Useless informations : just use try catch if you don't want error :)")
41-
if isinstance(path_to_file, str):
42-
if not isfile(path_to_file):
43-
if options["error"] == "no":
44-
return []
45-
raise ValueError(
46-
"Can't access to the file : '{}'".format(path_to_file))
40+
if isinstance(path_to_file, str) and not isfile(path_to_file):
41+
if options["error"] == "no":
42+
return []
43+
raise ValueError(f"Can't access to the file : '{path_to_file}'")
4744

4845
if isinstance(path_to_file, str):
49-
csv_file = open(path_to_file)
46+
csv_file = open(path_to_file, encoding="utf-8")
5047
line_reader = CSVreader(csv_file, delimiter=options["separator"])
5148
elif isinstance(path_to_file, list):
5249
line_reader = path_to_file
5350

54-
def create_fields_binding(schema_object, first_line, start_path=""):
51+
def create_fields_binding(schema_object, first_line, start_path=[]):
5552
""" Create fields bindings """
5653
bindings = []
5754
for index, value in enumerate(schema_object):
@@ -61,11 +58,10 @@ def create_fields_binding(schema_object, first_line, start_path=""):
6158
one_element = index
6259
elif is_dict:
6360
one_element = value
64-
if start_path == "":
65-
path = '{}'.format(one_element)
66-
else:
67-
path = '{}{}{}'.format(
68-
start_path, options["privateSeparator"], one_element)
61+
path = []
62+
if len(start_path) != 0:
63+
path = start_path.copy()
64+
path.append(f"{one_element}")
6965
if isinstance(schema_object[one_element], (dict, list)):
7066
if isinstance(schema_object[one_element], list):
7167
bindings.append({
@@ -109,7 +105,7 @@ def parse_line(line, rows, first_line):
109105
for one_row in rows:
110106
one_path_row = one_row["path"]
111107
one_path_name = one_row["name"]
112-
all_path = one_path_row.split(options["privateSeparator"])
108+
all_path = one_path_row
113109
current_value = None
114110
if ('type' not in one_row) or ('type' in one_row and one_row["type"] is None):
115111
if 'value' not in one_row:
@@ -170,14 +166,12 @@ def parse_line(line, rows, first_line):
170166
good_place.append(current_value)
171167
elif isinstance(good_place, dict):
172168
good_place[one_path_name] = current_value
173-
else:
174-
good_place = current_value
175169
else:
176170
if isinstance(obj, list):
177-
place = int(one_path_row)
171+
place = int(one_path_row[0])
178172
obj.insert(place, current_value)
179173
elif isinstance(obj, dict):
180-
obj[one_path_row] = current_value
174+
obj[one_path_row[0]] = current_value
181175
return obj
182176

183177
def parse_first_line(first_line):
@@ -193,7 +187,7 @@ def dupli(element):
193187
"""" Duplicate the first line """
194188
return {
195189
"name": element,
196-
"path": element
190+
"path": [element]
197191
}
198192
cols = [dupli(x) for x in first_line]
199193
return cols

tests/test_callBack.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55

66
class Test(unittest.TestCase):
77
def test_callBack_force(self):
8-
def function1(values):
9-
return None
108

119
def function2(useless, useless2):
1210
return # return nothing
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import unittest
2+
3+
from src.csv_to_custom_json import parseFile
4+
5+
6+
class Test(unittest.TestCase):
7+
def test_callBack_force_2(self):
8+
def function1(values):
9+
return None
10+
11+
def function2(useless, useless2):
12+
return None
13+
test = parseFile("./tests/simple.csv", {
14+
"num1": "string",
15+
"num2": function1,
16+
"num3": "string"
17+
}, {
18+
"callBackForce": False,
19+
"lineCallBack": function2,
20+
"debug": True,
21+
})
22+
self.assertEqual(test, [
23+
{'num1': '1', 'num2': None, 'num3': '3'},
24+
{'num1': '4', 'num2': None, 'num3': '6'},
25+
{'num1': '7', 'num2': None, 'num3': '9'},
26+
])

tests/test_callBack_value.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55

66
class Test(unittest.TestCase):
77
def test_callBack_force_2(self):
8-
def function1(values):
9-
return None
108

119
def function2(parsedLine, useless2):
1210
name = list(parsedLine.keys())

tests/test_debug_2.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import unittest
2+
3+
from src.csv_to_custom_json import parseFile
4+
5+
6+
class Test(unittest.TestCase):
7+
def test_debug(self):
8+
test = parseFile("./tests/simple.csv", None, {
9+
"debug": True
10+
})
11+
self.assertEqual(test, [
12+
{
13+
"num1": "1",
14+
"num2": "2",
15+
"num3": "3"
16+
},
17+
{
18+
"num1": "4",
19+
"num2": "5",
20+
"num3": "6"
21+
},
22+
{
23+
"num1": "7",
24+
"num2": "8",
25+
"num3": "9"
26+
}
27+
])

tests/test_debug_3.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import unittest
2+
3+
from src.csv_to_custom_json import parseFile
4+
5+
6+
class Test(unittest.TestCase):
7+
def test_debug(self):
8+
test = parseFile("./tests/simple.csv", None, {
9+
"debug": True,
10+
"error": "no",
11+
})
12+
self.assertEqual(test, [
13+
{
14+
"num1": "1",
15+
"num2": "2",
16+
"num3": "3"
17+
},
18+
{
19+
"num1": "4",
20+
"num2": "5",
21+
"num3": "6"
22+
},
23+
{
24+
"num1": "7",
25+
"num2": "8",
26+
"num3": "9"
27+
}
28+
])

0 commit comments

Comments
 (0)