Repository: biopython/biopython

Issue:
Adding str and int never works
> Can you actually trigger this type mismatch? Does it depend on a non-standard input file?

### Steps to reproduce

Yes, when I look at it I actually can reproduce it. Code example:

```
import io
from Bio import phenotype

f = io.StringIO('{"csv_data": {"Plate Type": "PM-999"}, "measurements": {"Hour": 9}}')

for x in phenotype.phen_micro.JsonIterator(f):
    print(x)

```

### Expected result (from naive fix of issue)
```
/home/user/.local/lib/python3.7/site-packages/Bio/phenotype/__init__.py:96: BiopythonExperimentalWarning: Bio.phenotype is an experimental submodule which may undergo significant changes prior to its future official release.
  BiopythonExperimentalWarning,
/home/user/.local/lib/python3.7/site-packages/Bio/phenotype/phen_micro.py:961: UserWarning: Non-standard plate ID found (PM-999), using PM999
  plateID, _platesPrefix, abs(int(pID)))
Plate ID: PM999
Well: 0
Rows: 0
Columns: 0
PlateRecord()
```

### Actual result
```
/home/user/.local/lib/python3.7/site-packages/Bio/phenotype/__init__.py:96: BiopythonExperimentalWarning: Bio.phenotype is an experimental submodule which may undergo significant changes prior to its future official release.
  BiopythonExperimentalWarning,
Traceback (most recent call last):
  File "./1.py", line 34, in <module>
    for x in phenotype.phen_micro.JsonIterator(f):
  File "/home/user/.local/lib/python3.7/site-packages/Bio/phenotype/phen_micro.py", line 961, in JsonIterator
    % (plateID, _platesPrefix + abs(int(pID)))
TypeError: can only concatenate str (not "int") to str
```


Discussion:
What do you think @mgalardini?
I mean it's probably easy to fix by replacing 4 instances of:

`abs(int(pID)))
`
with 
`
str(abs(int(pID)))`

But something like:

```
 warnings.warn("Non-standard plate ID found ({}), using {}{}".format(
               plateID, _platesPrefix, abs(int(pID))))
```
would probably feel cleaner. (I'm not gonna write any unit test for this).
Can you actually trigger this type mismatch? Does it depend on a non-standard input file?

Resolving patch:
diff --git a/Bio/phenotype/phen_micro.py b/Bio/phenotype/phen_micro.py
--- a/Bio/phenotype/phen_micro.py
+++ b/Bio/phenotype/phen_micro.py
@@ -957,10 +957,9 @@ def JsonIterator(handle):
                 )
             elif int(pID) < 0:
                 warnings.warn(
-                    "Non-standard plate ID found (%s), using %s"
-                    % (plateID, _platesPrefix + abs(int(pID)))
+                    f"Non-standard plate ID found ({plateID}), using {_platesPrefix}{abs(int(pID))}"
                 )
-                plateID = _platesPrefix + abs(int(pID))
+                plateID = _platesPrefix + str(abs(int(pID)))
             else:
                 if plateID.startswith(_platesPrefixMammalian):
                     plateID = _platesPrefixMammalian + "%02d" % int(pID)
@@ -1060,10 +1059,9 @@ def CsvIterator(handle):
                     )
                 elif int(pID) < 0:
                     warnings.warn(
-                        "Non-standard plate ID found (%s), using %s"
-                        % (plateID, _platesPrefix + abs(int(pID)))
+                        f"Non-standard plate ID found ({plateID}), using {_platesPrefix}{abs(int(pID))}"
                     )
-                    plateID = _platesPrefix + abs(int(pID))
+                    plateID = _platesPrefix + str(abs(int(pID)))
                 else:
                     if plateID.startswith(_platesPrefixMammalian):
                         plateID = _platesPrefixMammalian + "%02d" % int(pID)


Test patch:
diff --git a/Tests/test_phenotype.py b/Tests/test_phenotype.py
--- a/Tests/test_phenotype.py
+++ b/Tests/test_phenotype.py
@@ -311,6 +311,22 @@ def test_WellRecord(self):
 
         w[1] = 1
 
+    def test_JsonIterator(self):
+        """Test basic functionalities of JsonIterator file parser."""
+        # Parse file content big enough to trigger issue #3783
+        handle = StringIO(
+            '{"csv_data": {"Plate Type": "PM-999"}, "measurements": {"Hour": 9}}'
+        )
+        for w in phenotype.phen_micro.JsonIterator(handle):
+            self.assertEqual(w.id, "PM999")
+
+    def test_CsvIterator(self):
+        """Test basic functionalities of CsvIterator file parser."""
+        # Parse file content big enough to trigger issue #3783
+        handle = StringIO('"Data File",3\n"Plate Type",PM-33\n')
+        for w in phenotype.phen_micro.CsvIterator(handle):
+            self.assertEqual(w.id, "PM33")
+
 
 if __name__ == "__main__":
     runner = unittest.TextTestRunner(verbosity=2)