Skip to content

Instantly share code, notes, and snippets.

@zurk
Created November 2, 2017 15:47
Show Gist options
  • Save zurk/b44bad958078db6f9b95e1d796609c60 to your computer and use it in GitHub Desktop.
Save zurk/b44bad958078db6f9b95e1d796609c60 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# xpath usage examples for Python"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {
"collapsed": true,
"scrolled": false
},
"outputs": [],
"source": [
"import bblfsh\n",
"from bblfsh import BblfshClient\n",
"import importlib\n",
"DESCRIPTOR = importlib.import_module(\n",
" \"bblfsh.gopkg.in.bblfsh.sdk.%s.uast.generated_pb2\" % bblfsh.sdkversion.VERSION).DESCRIPTOR\n",
"Node = importlib.import_module(\n",
" \"bblfsh.gopkg.in.bblfsh.sdk.%s.uast.generated_pb2\" % bblfsh.sdkversion.VERSION).Node\n",
"\n",
"def role_id(role_name):\n",
" return DESCRIPTOR.enum_types_by_name[\"Role\"].values_by_name[role_name].number\n",
"\n",
"def role_name(role_id):\n",
" return DESCRIPTOR.enum_types_by_name[\"Role\"].values_by_number[role_id].name\n",
"\n",
"def node2raw(node, internal_type=True):\n",
" token = \"|%s|\" % node.token[:20].replace(\"\\n\", \"\\\\n\")\n",
" roles = \", \".join([role_name(k) for k in node.roles])\n",
" internal_role = node.internal_type\n",
" positions = str(node.start_position.line) if node.start_position.line != 0 else \"\"\n",
" return [positions, token, internal_role, roles] if internal_type else [positions, token, roles]\n",
" \n",
"def uast_roles(uast) -> iter:\n",
" stack = [(0, uast)]\n",
" while stack:\n",
" level, node = stack.pop()\n",
" yield level, node\n",
" stack.extend((level+1, c) for c in node.children[::-1])\n",
"\n",
"def rreplace(s, old, new, times):\n",
" li = s.rsplit(old, times)\n",
" return new.join(li)\n",
" \n",
"def print_table(table):\n",
" col_size = [max(len(cell) for cell in table_col) for table_col in zip(*table)]\n",
" for raw in table:\n",
" print(\" \".join(cell.ljust(size) for cell, size in zip(raw, col_size)))\n",
" \n",
"def print_uast_structure(uast, internal_type=True):\n",
" if internal_type:\n",
" table = [[\"#\", \"Token\", \"Internal Role\", \"Roles Tree\"], [\"\", \"\", \"\", \"\"]]\n",
" else:\n",
" table = [[\"#\", \"Token\", \"Roles Tree\"], [\"\", \"\", \"\"]]\n",
" old_level = 0\n",
" for level, node in uast_roles(uast):\n",
" raw = node2raw(node, internal_type)\n",
" if level != 0:\n",
" raw[-1] = \"┃ \" * (level-1) + \"┣ \" + raw[-1]\n",
" if level < old_level:\n",
" table[-1][-1] = rreplace(table[-1][-1].replace(\"┣\", \"┗\"), \"┃\", \"┗\", old_level-level-1)\n",
" pass\n",
" table.append(raw)\n",
" old_level = level\n",
" table[-1][-1] = table[-1][-1].replace(\"┣\", \"┗\").replace(\"┃\", \"┗\")\n",
" print_table(table)\n",
" \n",
" \n",
"def print_nodes(nodes):\n",
" table = [[\"#\", \"Token\", \"Roles\"]]\n",
" for node in nodes:\n",
" table.append(node2raw(node, False))\n",
" print_table(table)"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"a = None\n"
]
}
],
"source": [
"filepath = \"example.py\"\n",
"with open(filepath) as f:\n",
" print(f.read())"
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {
"scrolled": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"# Token Internal Role Roles Tree \n",
" \n",
" || Module FILE \n",
"1 || Assign ┣ BINARY, ASSIGNMENT, EXPRESSION \n",
"1 |a| Name ┃ ┣ LEFT, IDENTIFIER, EXPRESSION \n",
"1 |<nil>| NoneLiteral ┗ ┗ LITERAL, NULL, EXPRESSION, RIGHT\n"
]
}
],
"source": [
"client = BblfshClient(\"0.0.0.0:9432\")\n",
"\n",
"response = client.parse(filepath)\n",
"uast = response.uast\n",
"print_uast_structure(uast)"
]
},
{
"cell_type": "code",
"execution_count": 46,
"metadata": {
"scrolled": true
},
"outputs": [
{
"data": {
"text/plain": [
"[]"
]
},
"execution_count": 46,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"def ids(uast):\n",
" \"\"\"\n",
" Get all identifier nodes in UAST\n",
" \"\"\"\n",
" return bblfsh.filter(uast, \"//*[@roleNull]\")\n",
"\n",
"bblfsh.filter(uast, \"//*[@roleNull]\")"
]
},
{
"cell_type": "code",
"execution_count": 45,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[]"
]
},
"execution_count": 45,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"bblfsh.filter(uast, \"//*[@roleNull]\")"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"# Token Roles \n",
" |lib1| IMPORT, PATHNAME, IDENTIFIER\n",
" |lib2.lib21| IMPORT, PATHNAME, IDENTIFIER\n",
" |lib3| IMPORT, PATHNAME, IDENTIFIER\n",
" |lib3_alias| IMPORT, ALIAS, IDENTIFIER \n",
" |lib4| IMPORT, PATHNAME, IDENTIFIER\n",
" |lib41| IMPORT, PATHNAME, IDENTIFIER\n",
" |lib5.lib51| IMPORT, PATHNAME, IDENTIFIER\n",
" |lib511| IMPORT, PATHNAME, IDENTIFIER\n",
" |lib6| IMPORT, PATHNAME, IDENTIFIER\n",
" |lib61| IMPORT, PATHNAME, IDENTIFIER\n",
" |lib611_alias| IMPORT, ALIAS, IDENTIFIER \n"
]
}
],
"source": [
"def imports(uast):\n",
" \"\"\"\n",
" Get all nodes of imports in UAST\n",
" \"\"\"\n",
" return bblfsh.filter(uast, \"//*[@roleImport and @roleIdentifier] | //*[@roleAlias and @roleIdentifier]\")\n",
"\n",
"print_nodes(imports(uast))"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [
{
"ename": "TypeError",
"evalue": "'NoneType' object is not iterable",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-24-65953f630e97>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m 6\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mbblfsh\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfilter\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0muast\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"//*[@roleAssignment]//*[@roleLeft and @roleIdentifier] | \"\u001b[0m \u001b[0;34m\"//*[@roleAssignment]//*[@roleLeft]//*[@roleIdentifier and not(@roleQualified)]\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 7\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 8\u001b[0;31m \u001b[0mprint_nodes\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvariables\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0muast\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;32m<ipython-input-17-385541aac1f5>\u001b[0m in \u001b[0;36mprint_nodes\u001b[0;34m(nodes)\u001b[0m\n\u001b[1;32m 57\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mprint_nodes\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnodes\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 58\u001b[0m \u001b[0mtable\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m\"#\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"Token\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"Roles\"\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 59\u001b[0;31m \u001b[0;32mfor\u001b[0m \u001b[0mnode\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mnodes\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 60\u001b[0m \u001b[0mtable\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnode2raw\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnode\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;32mFalse\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 61\u001b[0m \u001b[0mprint_table\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtable\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mTypeError\u001b[0m: 'NoneType' object is not iterable"
]
}
],
"source": [
"# Get all variable names in UAST\n",
"def variables(uast):\n",
" \"\"\"\n",
" Get all variable nodes in UAST\n",
" \"\"\"\n",
" return bblfsh.filter(uast, \"//*[@roleAssignment]//*[@roleLeft and @roleIdentifier] | \" \\\n",
" \"//*[@roleAssignment]//*[@roleLeft]//*[@roleIdentifier and not(@roleQualified)]\")\n",
"\n",
"print_nodes(variables(uast))"
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"# Token Roles \n",
"8 |var1| LEFT, IDENTIFIER, EXPRESSION\n",
"9 |var2| LEFT, IDENTIFIER, EXPRESSION\n"
]
}
],
"source": [
"def module_variables(uast):\n",
" \"\"\"\n",
" Get variables that were declared in the module, not in classes or functions.\n",
" \"\"\"\n",
" return bblfsh.filter(uast, \"/*[@roleFile]/*[@roleAssignment]//*[@roleLeft and @roleIdentifier] |\" \\\n",
" \"/*[@roleFile]/*[@roleAssignment]//*[@roleLeft]//*[@roleIdentifier and not(@roleQualified)]\")\n",
"\n",
"print_nodes(module_variables(uast))"
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"# Token Roles \n",
"11 |class1| ENTRY, DECLARATION, IDENTIFIER, STATEMENT\n",
"28 |class2| ENTRY, DECLARATION, IDENTIFIER, STATEMENT\n",
"38 |class3| ENTRY, DECLARATION, IDENTIFIER, STATEMENT\n"
]
}
],
"source": [
"def module_classes(uast):\n",
" \"\"\"\n",
" Returns class nodes that were declared in the module.\n",
" \"\"\"\n",
" return bblfsh.filter(uast, \"/*[@roleFile]/*[@roleDeclaration and @roleType]\")\n",
"\n",
"print_nodes(module_classes(uast))"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"# Token Internal Role Roles Tree \n",
" \n",
"12 |var11| Name LEFT, IDENTIFIER, EXPRESSION\n",
"10 || PreviousNoops ┣ INCOMPLETE \n",
"10 |\\n| NoopLine ┗ ┗ DOCUMENTATION \n"
]
}
],
"source": [
"\n",
"print_uast_structure((bblfsh.filter(class_node, \"/*[@roleDeclaration and @roleType]/*[@roleBody]/*[@roleExpression]/*[@roleLeft]\"))[0])"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"# Token Internal Role Roles Tree \n",
" \n",
"11 |class1| ClassDef ENTRY, DECLARATION, IDENTIFIER, STATEMENT \n",
" || ClassDef.body ┣ ENTRY, DECLARATION, BODY \n",
"12 || Assign ┃ ┣ BINARY, THIS, EXPRESSION \n",
"12 |var11| Name ┃ ┃ ┣ LEFT, IDENTIFIER, EXPRESSION \n",
"10 || PreviousNoops ┃ ┃ ┃ ┣ INCOMPLETE \n",
"10 |\\n| NoopLine ┃ ┃ ┃ ┗ ┗ DOCUMENTATION \n",
"12 |<nil>| NoneLiteral ┃ ┃ ┗ BYTE, NUMBER, EXPRESSION, RIGHT \n",
"14 |__init__| FunctionDef ┃ ┣ FUNCTION, DECLARATION, NAME, IDENTIFIER \n",
" || arguments ┃ ┃ ┣ FUNCTION, DECLARATION, ARGUMENT, NAME, IDENTIFIER \n",
"14 |self| arg ┃ ┃ ┃ ┣ FUNCTION, DECLARATION, ARGUMENT, NAME, IDENTIFIER \n",
"13 || PreviousNoops ┃ ┃ ┃ ┃ ┣ INCOMPLETE \n",
"13 |\\n| NoopLine ┃ ┃ ┃ ┗ ┗ ┗ DOCUMENTATION \n",
" || FunctionDef.body ┃ ┃ ┣ FUNCTION, DECLARATION, BODY \n",
"15 || Assign ┃ ┃ ┃ ┣ BINARY, THIS, EXPRESSION \n",
"15 |var1111| Attribute ┃ ┃ ┃ ┃ ┣ IDENTIFIER, EXPRESSION, LEFT \n",
"15 |lib111| Attribute ┃ ┃ ┃ ┃ ┃ ┣ IDENTIFIER, EXPRESSION \n",
"15 |lib11| Attribute ┃ ┃ ┃ ┃ ┃ ┃ ┣ IDENTIFIER, EXPRESSION \n",
"15 |lib1| Name ┃ ┃ ┃ ┃ ┃ ┗ ┗ ┗ IDENTIFIER, QUALIFIED, IDENTIFIER, EXPRESSION\n",
"15 |<nil>| NoneLiteral ┃ ┃ ┃ ┃ ┗ BYTE, NUMBER, EXPRESSION, RIGHT \n",
"16 || Assign ┃ ┃ ┃ ┣ BINARY, THIS, EXPRESSION \n",
"16 |var101| Attribute ┃ ┃ ┃ ┃ ┣ IDENTIFIER, EXPRESSION, LEFT \n",
"16 |self| Name ┃ ┃ ┃ ┃ ┃ ┗ IDENTIFIER, QUALIFIED, IDENTIFIER, EXPRESSION \n",
"16 |<nil>| NoneLiteral ┃ ┃ ┃ ┃ ┗ BYTE, NUMBER, EXPRESSION, RIGHT \n",
"17 || Assign ┃ ┃ ┃ ┣ BINARY, THIS, EXPRESSION \n",
"17 || Tuple ┃ ┃ ┃ ┃ ┣ BYTE, TYPE, EXPRESSION, LEFT \n",
"17 |var102| Name ┃ ┃ ┃ ┃ ┃ ┣ IDENTIFIER, EXPRESSION \n",
"17 |var103| Name ┃ ┃ ┃ ┃ ┃ ┗ IDENTIFIER, EXPRESSION \n",
"17 || Tuple ┃ ┃ ┃ ┃ ┣ BYTE, TYPE, EXPRESSION, RIGHT \n",
"17 |<nil>| NoneLiteral ┃ ┃ ┃ ┃ ┃ ┣ BYTE, NUMBER, EXPRESSION \n",
"17 |<nil>| NoneLiteral ┃ ┃ ┗ ┗ ┗ ┗ BYTE, NUMBER, EXPRESSION \n",
"19 |func11| FunctionDef ┃ ┣ FUNCTION, DECLARATION, NAME, IDENTIFIER \n",
" || arguments ┃ ┃ ┣ FUNCTION, DECLARATION, ARGUMENT, NAME, IDENTIFIER \n",
"19 |self| arg ┃ ┃ ┃ ┣ FUNCTION, DECLARATION, ARGUMENT, NAME, IDENTIFIER \n",
"18 || PreviousNoops ┃ ┃ ┃ ┃ ┣ INCOMPLETE \n",
"18 |\\n| NoopLine ┃ ┃ ┃ ┗ ┗ ┗ DOCUMENTATION \n",
" || FunctionDef.body ┃ ┃ ┣ FUNCTION, DECLARATION, BODY \n",
"20 || Assign ┃ ┃ ┃ ┣ BINARY, THIS, EXPRESSION \n",
"20 |var111| Attribute ┃ ┃ ┃ ┃ ┣ IDENTIFIER, EXPRESSION, LEFT \n",
"20 |class1| Name ┃ ┃ ┃ ┃ ┃ ┗ IDENTIFIER, QUALIFIED, IDENTIFIER, EXPRESSION \n",
"20 |<nil>| NoneLiteral ┃ ┃ ┃ ┃ ┗ BYTE, NUMBER, EXPRESSION, RIGHT \n",
"21 || Assign ┃ ┃ ┃ ┣ BINARY, THIS, EXPRESSION \n",
"21 |var112| Attribute ┃ ┃ ┃ ┃ ┣ IDENTIFIER, EXPRESSION, LEFT \n",
"21 |self| Name ┃ ┃ ┃ ┃ ┃ ┗ IDENTIFIER, QUALIFIED, IDENTIFIER, EXPRESSION \n",
"21 |<nil>| NoneLiteral ┃ ┃ ┃ ┃ ┗ BYTE, NUMBER, EXPRESSION, RIGHT \n",
"22 || Assign ┃ ┃ ┃ ┣ BINARY, THIS, EXPRESSION \n",
"22 |var113| Name ┃ ┃ ┃ ┃ ┣ LEFT, IDENTIFIER, EXPRESSION \n",
"22 |<nil>| NoneLiteral ┃ ┃ ┗ ┗ ┗ BYTE, NUMBER, EXPRESSION, RIGHT \n",
"24 |func12| FunctionDef ┃ ┣ FUNCTION, DECLARATION, NAME, IDENTIFIER \n",
" || FunctionDef.body ┃ ┃ ┣ FUNCTION, DECLARATION, BODY \n",
"25 |func121| FunctionDef ┃ ┃ ┃ ┣ FUNCTION, DECLARATION, NAME, IDENTIFIER \n",
" || FunctionDef.body ┃ ┃ ┃ ┃ ┣ FUNCTION, DECLARATION, BODY \n",
"26 |pass| Pass ┃ ┃ ┃ ┃ ┃ ┣ LITERAL, STATEMENT \n",
"23 || PreviousNoops ┃ ┃ ┃ ┃ ┃ ┃ ┣ INCOMPLETE \n",
"23 |\\n| NoopLine ┃ ┃ ┃ ┃ ┃ ┗ ┗ ┗ DOCUMENTATION \n",
" || arguments ┃ ┃ ┃ ┗ ┗ FUNCTION, DECLARATION, ARGUMENT, NAME, IDENTIFIER \n",
" || arguments ┗ ┗ ┗ FUNCTION, DECLARATION, ARGUMENT, NAME, IDENTIFIER \n"
]
}
],
"source": [
"print_uast_structure(class_node)"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {
"collapsed": true,
"scrolled": true
},
"outputs": [],
"source": [
"a = bblfsh.filter(class_node, \"/*[@roleDeclaration and @roleType]/*[@roleBody]\"\n",
" \"/*[@roleExpression]/*[@roleLeft]\")"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {
"collapsed": true,
"scrolled": false
},
"outputs": [],
"source": [
"def classes_static_variables(class_node):\n",
" \"\"\"\n",
" Returns variables that were declared in the class.\n",
" \n",
" :param class_uast: class UAST node \n",
" \"\"\"\n",
" #/*[@roleAssignment] when fix\n",
" return bblfsh.filter(class_node, \"/*[@roleDeclaration and @roleType]/*[@roleBody]\"\n",
" \"/*[@roleExpression]/*[@roleLeft]\")\n",
"\n",
"for class_node in module_classes(uast):\n",
" break\n",
" #print()\n",
" #print(class_node)\n",
" #print()\n",
" #print(classes_static_variables(class_node))\n",
" #print()\n",
" print(class_node.token +\":\")\n",
" sv = classes_static_variables(class_node)\n",
" print(print_nodes(sv))"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['function1', 'function2']\n"
]
}
],
"source": [
"def module_functions(uast):\n",
" \"\"\"\n",
" Returns functions that were declared in the module, not in classes or functions.\n",
" \"\"\"\n",
" return [node.token for node in bblfsh.filter(response.uast, \"/*[@roleFile]/*[@roleFunctionDeclaration]\")]\n",
"print(module_functions(response.uast))"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Class3 : ['var31', 'var32', 'var33', 'var34', 'var3']\n"
]
}
],
"source": [
"def classes_variables(class_uast):\n",
" \"\"\"\n",
" Returns variables that were declared in the class instance.\n",
" \n",
" :param class_uast: class UAST node\n",
" \"\"\"\n",
" assignments = bblfsh.filter(class_uast, \"/*[@roleTypeDeclaration]/*[@roleTypeDeclarationBody]\"\n",
" \"//*[@roleAssignment]/*[@roleAssignmentVariable]\")\n",
" variables = []\n",
" for x in assignments:\n",
" selfs = bblfsh.filter(x, \"/*[@roleAssignmentVariable]/*[@roleQualifiedIdentifier]\")\n",
" if len(selfs) > 0 and selfs[0].token == 'self':\n",
" variables.append(x.token)\n",
" \n",
" return variables\n",
"\n",
"for class_node in module_classes_nodes(response.uast)[2:]:\n",
" print(class_node.token, \":\", classes_variables(class_node))\n",
" break"
]
},
{
"cell_type": "code",
"execution_count": 72,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'roleQualified'"
]
},
"execution_count": 72,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"def ff(s):\n",
" return 'role' + ''.join(x.capitalize() for x in s.split(\"_\"))\n",
"ff(\"QUALIFIED\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.1"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment