Repository: PyThaiNLP/pythainlp (python)

Issue:
bug: tone_detector wrongly detect falling tone for ครับ
### Description

`print(tone_detector("ครับ"))`
result: f

`print(tone_detector("ค่ะ"))`
result: h

### Expected results

"ครับ" should be high tone
"ค่ะ" should be falling tone

### Current results

"ครับ": falling tone
"ค่ะ": high tone

### Steps to reproduce

`print(tone_detector("ครับ"))`
`print(tone_detector("ค่ะ"))`

### PyThaiNLP version

5.0.4

### Python version

3.10.15

### Operating system and version

macOS 15.1.1 

### More info

_No response_

### Possible solution

the falling tone result for "ครับ" is derived from below code block in syllable.py
`    elif (
        initial_consonant_type == "low"
        and syllable_check_length == "long"
        and syllable_check == "close"
        and s == "dead"
    ):
        r = "f"`

### Files

_No response_

Pull request:
Fixed #1004
### What does this changes

Fixed tone_detector bug

### How this fixes it

<!--- Description of how the changes fix the issue. -->

Fixes #1004

### Your checklist for this pull request

<!--- Please review the guidelines for contributing to this repository at: -->
<!--- https://github.com/PyThaiNLP/pythainlp/blob/dev/CONTRIBUTING.md -->

- [x] Passed code styles and structures
- [x] Passed code linting checks and unit test


Patch:
diff --git a/pythainlp/util/syllable.py b/pythainlp/util/syllable.py
index 9d480d81..bf3d4be4 100644
--- a/pythainlp/util/syllable.py
+++ b/pythainlp/util/syllable.py
@@ -184,7 +184,7 @@ def syllable_length(syllable: str) -> str:
         # output: short
     """
     consonants = [i for i in syllable if i in list(thai_consonants)]
-    if len(consonants) < 3 and any((c in set(short)) for c in syllable):
+    if len(consonants) <= 3 and any((c in set(short)) for c in syllable):
         return "short"
     elif bool(re_short.search(syllable)):
         return "short"
@@ -259,8 +259,6 @@ def tone_detector(syllable: str) -> str:
             and tone_mark == "่"
         ):
             r = "l"
-        elif initial_consonant == "อ" and consonant_ending and s == "dead":
-            r = "l"
         elif (
             initial_consonant == "ห"
             and consonant_ending
@@ -268,6 +266,8 @@ def tone_detector(syllable: str) -> str:
             and tone_mark == "่"
         ):
             r = "l"
+        elif initial_consonant == "อ" and consonant_ending and s == "dead":
+            r = "l"
         elif (
             initial_consonant == "ห"
             and consonant_ending
@@ -279,6 +279,22 @@ def tone_detector(syllable: str) -> str:
             r = "l"
         elif initial_consonant == "ห" and consonant_ending and s == "live":
             r = "r"
+    elif initial_consonant_type == "high" and s == "live" and tone_mark == "่":
+        r = "l"
+    elif initial_consonant_type == "mid" and s == "live" and tone_mark == "่":
+        r = "l"
+    elif initial_consonant_type == "low" and tone_mark == "้":
+        r = "h"
+    elif initial_consonant_type == "mid" and tone_mark == "๋":
+        r = "r"
+    elif initial_consonant_type == "mid" and tone_mark == "๊":
+        r = "h"
+    elif initial_consonant_type == "low" and tone_mark == "่":
+        r = "f"
+    elif initial_consonant_type == "mid" and tone_mark == "้":
+        r = "f"
+    elif initial_consonant_type == "high" and tone_mark == "้":
+        r = "f"
     elif (
         initial_consonant_type == "low"
         and syllable_check_length == "short"
@@ -299,22 +315,6 @@ def tone_detector(syllable: str) -> str:
         and syllable_check == "open"
     ):
         r = "h"
-    elif initial_consonant_type == "high" and s == "live" and tone_mark == "่":
-        r = "l"
-    elif initial_consonant_type == "mid" and s == "live" and tone_mark == "่":
-        r = "l"
-    elif initial_consonant_type == "low" and tone_mark == "้":
-        r = "h"
-    elif initial_consonant_type == "mid" and tone_mark == "๋":
-        r = "r"
-    elif initial_consonant_type == "mid" and tone_mark == "๊":
-        r = "h"
-    elif initial_consonant_type == "low" and tone_mark == "่":
-        r = "f"
-    elif initial_consonant_type == "mid" and tone_mark == "้":
-        r = "f"
-    elif initial_consonant_type == "high" and tone_mark == "้":
-        r = "f"
     elif initial_consonant_type == "mid" and s == "dead":
         r = "l"
     elif initial_consonant_type == "high" and s == "dead":


Test patch:
diff --git a/tests/core/test_util.py b/tests/core/test_util.py
index de7a7a9d..aef11e09 100644
--- a/tests/core/test_util.py
+++ b/tests/core/test_util.py
@@ -708,6 +708,8 @@ class UtilTestCase(unittest.TestCase):
             ("f", "ไหม้"),
             ("f", "ต้น"),
             ("f", "ผู้"),
+            ("h", "ครับ"),
+            ("f", "ค่ะ"),
         ]
         for i, j in data:
             self.assertEqual(tone_detector(j), i)