Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Added APIs isalnum() and isnumeric() in string object #2572

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions integration_tests/test_str_attributes.py
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,69 @@ def is_space():
s = ""
assert s.isspace() == False

def is_alnum():
a: str = "helloworld"
b: str = "hj kl"
c: str = "a12(){}A"
d: str = " "
e: str = ""
f: str = "ab23"
g: str = "ab2%3"
res: bool = a.isalnum()
res2: bool = b.isalnum()
res3: bool = c.isalnum()
res4: bool = d.isalnum()
res5: bool = e.isalnum()
res6: bool = f.isalnum()
res7: bool = g.isalnum()

assert res == True
assert res2 == False
assert res3 == False
assert res4 == False
assert res5 == False
assert res6 == True
assert res7 == False

assert "helloworld".isalnum() == True
assert "hj kl".isalnum() == False
assert "a12(){}A".isalnum() == False
assert " ".isalnum() == False
assert "".isalnum() == False
assert "ab23".isalnum() == True
assert "ab2%3".isalnum() == False

def is_numeric():
a: str = "123"
b: str = "12 34"
c: str = "-123"
d: str = "12.3"
e: str = " "
f: str = ""
g: str = "ab2%3"
res: bool = a.isnumeric()
res2: bool = b.isnumeric()
res3: bool = c.isnumeric()
res4: bool = d.isnumeric()
res5: bool = e.isnumeric()
res6: bool = f.isnumeric()
res7: bool = g.isnumeric()

assert res == True
assert res2 == False
assert res3 == False
assert res4 == False
assert res5 == False
assert res6 == False
assert res7 == False

assert "123".isnumeric() == True
assert "12 34".isnumeric() == False
assert "-123".isnumeric() == False
assert "12.3".isnumeric() == False
assert " ".isnumeric() == False
assert "".isnumeric() == False
assert "ab2%3".isnumeric() == False

def check():
capitalize()
Expand All @@ -386,6 +448,8 @@ def check():
is_alpha()
is_title()
is_space()
is_alnum()
is_numeric()


check()
36 changes: 34 additions & 2 deletions src/lpython/semantics/python_ast_to_asr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6793,7 +6793,7 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
/*
String Validation Methods i.e all "is" based functions are handled here
*/
std::vector<std::string> validation_methods{"lower", "upper", "decimal", "ascii", "space", "alpha", "title"}; // Database of validation methods supported
std::vector<std::string> validation_methods{"lower", "upper", "decimal", "ascii", "space", "alpha", "title", "alnum", "numeric"}; // Database of validation methods supported
std::string method_name = attr_name.substr(2);

if(std::find(validation_methods.begin(),validation_methods.end(), method_name) == validation_methods.end()) {
Expand Down Expand Up @@ -7096,7 +7096,7 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
* islower() method is limited to English Alphabets currently
* TODO: We can support other characters from Unicode Library
*/
std::vector<std::string> validation_methods{"lower", "upper", "decimal", "ascii", "space", "alpha", "title"}; // Database of validation methods supported
std::vector<std::string> validation_methods{"lower", "upper", "decimal", "ascii", "space", "alpha", "title", "alnum", "numeric"}; // Database of validation methods supported
std::string method_name = attr_name.substr(2);
if(std::find(validation_methods.begin(),validation_methods.end(), method_name) == validation_methods.end()) {
throw SemanticError("String method not implemented: " + attr_name, loc);
Expand Down Expand Up @@ -7194,6 +7194,38 @@ we will have to use something else.
tmp = ASR::make_LogicalConstant_t(al, loc, is_space,
ASRUtils::TYPE(ASR::make_Logical_t(al, loc, 4)));
return;
} else if (attr_name == "isalnum") {
/*
* Specification -
Return True if all characters in the string are alphabets or numbers,
and there is at least one character in the string.
*/
bool is_alnum = (s_var.size() != 0);
for (auto &i : s_var) {
if (!((i >= 'A' && i <= 'Z') || (i >= 'a' && i <= 'z') || (i >= '0' && i <= '9'))) {
is_alnum = false;
break;
}
}
tmp = ASR::make_LogicalConstant_t(al, loc, is_alnum,
ASRUtils::TYPE(ASR::make_Logical_t(al, loc, 4)));
return;
} else if (attr_name == "isnumeric") {
/*
* Specification -
Return True if all characters in the string are alphabets or numbers,
and there is at least one character in the string.
*/
bool is_numeric = (s_var.size() != 0);
for (auto &i : s_var) {
if (!(i >= '0' && i <= '9')) {
is_numeric = false;
break;
}
}
tmp = ASR::make_LogicalConstant_t(al, loc, is_numeric,
ASRUtils::TYPE(ASR::make_Logical_t(al, loc, 4)));
return;
} else if (attr_name == "isalpha") {
/*
* Specification -
Expand Down
2 changes: 2 additions & 0 deletions src/lpython/semantics/python_comptime_eval.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ struct PythonIntrinsicProcedures {
{"_lpython_str_join", {m_builtin, &not_implemented}},
{"_lpython_str_find", {m_builtin, &not_implemented}},
{"_lpython_str_isalpha", {m_builtin, &not_implemented}},
{"_lpython_str_isalnum", {m_builtin, &not_implemented}},
{"_lpython_str_isnumeric", {m_builtin, &not_implemented}},
{"_lpython_str_title", {m_builtin, &not_implemented}},
{"_lpython_str_istitle", {m_builtin, &not_implemented}},
{"_lpython_str_rstrip", {m_builtin, &not_implemented}},
Expand Down
24 changes: 24 additions & 0 deletions src/runtime/lpython_builtin.py
Original file line number Diff line number Diff line change
Expand Up @@ -730,6 +730,30 @@ def _lpython_str_isalpha(s: str) -> bool:
return False
return True

def _lpython_str_isalnum(s: str) -> bool:
ch: str
if len(s) == 0: return False
for ch in s:
ch_ord: i32 = ord(ch)
if 65 <= ch_ord and ch_ord <= 90:
continue
if 97 <= ch_ord and ch_ord <= 122:
continue
if 48 <= ch_ord and ch_ord <= 57:
continue
return False
return True

def _lpython_str_isnumeric(s: str) -> bool:
ch: str
if len(s) == 0: return False
for ch in s:
ch_ord: i32 = ord(ch)
if 48 <= ch_ord and ch_ord <= 57:
continue
return False
return True

def _lpython_str_title(s: str) -> str:
result: str = ""
capitalize_next: bool = True
Expand Down
2 changes: 1 addition & 1 deletion tests/reference/asr-array_01_decl-39cf894.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"outfile": null,
"outfile_hash": null,
"stdout": "asr-array_01_decl-39cf894.stdout",
"stdout_hash": "5d4751789e2ddcd882c4d6026f801ba32cfc227fafff7395a788bdd9",
"stdout_hash": "f7f0747c5f92116ab0a6f20993b7d3cf9d45f0fbbe5436f9fb356fcb",
"stderr": null,
"stderr_hash": null,
"returncode": 0
Expand Down
Loading