برنامه نویسی، داده کاوی ۱۹۱۱ بازدید

در این مطلب، روش ساخت داشبورد گزارش دهی در پایتون مورد بررسی قرار گرفته است. در واقع، در این پست یک راهنمای گام به گام پیرامون چگونگی ساخت یک داشبورد گزارش‌دهی با استفاده از «دَش» (Dash) مورد بررسی قرار گرفته است که چارچوبی برای «زبان برنامه‌نویسی پایتون» (Python Programming Language) به منظور ساخت برنامه‌های کاربردی تحلیل وب محسوب می‌شود.

در اینجا، به جای پرداختن به مباحث پایه‌ای برای ساخت یک برنامه Dash، به جزئیات راهنمایی پیرامون چگونگی ساخت داشبورد با جداول داده و نمودارها پرداخته شده است. داشبورد گزارش‌دهی به صورت یک برنامه کاربردی چند صفحه‌ای ساخته شده است. این کار به منظور شکستن داشبورد به صفحات مختلف و در نتیجه، ارائه داده‌ها به صورت سازمان یافته انجام شده است. همچنین، در این صورت داده‌ها به طور یک‌باره و غافلگیر کننده نیز ارائه نمی‌شوند.

در هر صفحه از داشبورد، دو جدول داده در انتخاب‌گر طیف داده‌ها، یک لینک دانلود داده‌ها و یک مجموعه از نمودارها زیر دو داشبورد وجود دارد. طی ساخت این داشبورد، با چالش‌های گوناگونی مواجهه انجام شده است که در همین مطلب، چگونگی غلبه بر آن‌ها تشریح شده است.

ساخت داشبورد گزارش دهی در پایتون

Dash یک چارچوب پایتون برای ساخت برنامه‌های کاربردی وب است. این چارچوب بر فراز «فلسک» (Flask)، «پلاتلی دات جی‌اس» (Plotly.js)، «ری‌اکت» (React) و «ری‌اکت جی‌اس» (React Js) ارائه شده است. این چارچوب به کاربران امکان ساخت داشبوردهایی را با استفاده از پایتون می‌دهد. Dash متن‌باز است و برنامه‌های آن روی مرورگر وب اجرا می‌شوند. در این راهنما، مبانی Dash به کاربر معرفی می‌شود. همچنین، فرض شده که کاربران از پیش تجربه کار با Plotly را داشته‌اند.

نصب دش (Dash)

به منظور آغاز استفاده از دش، باید چندین بسته نصب شوند که در ادامه، بیان شده‌اند.

  • بک‌اند هسته‌ای دش
  • فرانت‌اند دش
  • مولفه HTML دش
  • مولفه هسته‌ای دش
  • Plotly
pip install dash==0.21.1  
pip install dash-renderer==0.13.0  
pip install dash-html-components==0.11.0
pip install dash-core-components==0.23.0  
pip install plotly --upgrade

لایوت برنامه دش

یک برنامه کاربردی دش معمولا ترکیبی از دو بخش است. اولین بخش لایوت است و اینکه برنامه چگونه به نظر می‌رسد را مشخص می‌کند و دومین بخش، تعامل‌پذیری برنامه کاربردی را مشخص می‌کند. دش کلاس‌های HTML فراهم می‌کند که کاربر را قادر به تولید محتوای HTML با پایتون می‌سازد.

برای استفاده از این کلاس‌ها، باید dash_core_components و dash_html_components وارد (ایمپورت | Import) شوند. کاربران می‌توانند مولفه سفارشی مد نظر خود را با استفاده از «جاوااسکریپت» (JavaScript) و ری‌اکت جی‌اس بسازند. در این راستا، باید یک فایل به نام app.py با استفاده از ویرایشگر متن محبوب کاربر ساخته و سپس این پکیج‌ها ایمپورت شوند.

import dash
import dash_core_components as dcc
import dash_html_components as html

درست مانند فلسک، مقداردهی اولیه Dash با فراخوانی کلاس Dash از dash انجام می‌شوند. هنگامی که این کار انجام می‌شود، می‌توان قالبی برای برنامه ساخت. از کلاس Div از dash_html_components برای ساخت یک HTML Div استفاده می‌شود. سپس، از مولفه‌های HTML برای تولید مولفه‌های HTML مانند H2 ،H1 و دیگر موارد استفاده می‌شود.

dash_html_components حاوی همه تگ‌های HTML می‌شود. به منظور ساخت یک گراف روی این الگو، از کلاس گراف از dash_core_components استفاده می‌شود. Graph بصری‌سازی‌های داده را با استفاده از plotly.js رندر می‌کند. کلاس گراف نیاز به یک شی شکل با data برای رسم شدن و جزئیات layout دارد. همچنین، Dash به کاربر امکان قالب‌بندی‌هایی مانند تغییر رنگ پس‌زمینه و متن را می‌دهد. می‌توان پس‌زمینه را با استفاده از خصیصه style و پاس دادن شی با رنگ خاص مد نظر کاربر، ارائه کرد.

در این مثال، یک دیکشنری رنگ با پس‌زمینه و رنگ متنی که مد نظر است، تعریف شده‌اند. به طور مشابه، می‌توان پس‌زمینه لایوت را با استفاده از خصیصه plot_bgcolor تغییر داد. در HTML، خصوصیات قالب با استفاده از نقطه ویرگول تعیین می‌شود، ولی در Dash، یک دیکشنری برای این کار تهیه شده است. کلیدهای موجود در دیکشنری به صورت «نگارش شتری» (camelCased) هستند. به عنوان مثالی از این موارد می‌توان به textAlign، برای عبارت text-align اشاره کرد. به جای استفاده از کلاس‌هایی مانند آنچه در HTML وجود دارد، در Dash از className استفاده می‌شود.

app = dash.Dash()
colors = {
    'background': '#111111',
    'text': '#7FDBFF'
}
app.layout = html.Div(style={'backgroundColor': colors['background']}, children=[
    html.H1(
        children='Hello Dash',
        style={
            'textAlign': 'center',
            'color': colors['text']
        }
    ),
    html.Div(children='Dash: A web application framework for Python.', style={
        'textAlign': 'center',
        'color': colors['text']
    }),
    dcc.Graph(
        id='Graph1',
        figure={
            'data': [
                {'x': [1, 2, 3], 'y': [4, 1, 2], 'type': 'bar', 'name': 'SF'},
                {'x': [1, 2, 3], 'y': [2, 4, 5], 'type': 'bar', 'name': u'Montréal'},
            ],
            'layout': {
                'plot_bgcolor': colors['background'],
                'paper_bgcolor': colors['background'],
                'font': {
                    'color': colors['text']
                }
            }
        }
    )
])

به منظور نمایش دادن بصری‌سازی‌ها، نیاز به اجرای وب‌سرور درست به صورتی است که در Flask انجام می‌شود. باید به خاطر داشت که Dash بر فراز Flask ساخته شده است. همچنین، debug روی true تنظیم می‌شود تا اطمینان حاصل شود که در هر بار که تغییرات انجام می‌شوند، نیازی به رفرش کردن سرور نیست.

if __name__ == '__main__':
    app.run_server(debug=True)

سپس، به ترمینال رفته و سرور با نوشتن کد python app.py زیر راه‌اندازی می‌شود. این کار موجب می‌شود وب سرور در http://127.0.0.1:8050/‎ اجرا شود. اکنون می‌توان در اینجا داشبورد ساخته شده را مشاهده کرد.

ساخت نمودارهای نقطه‌ای

به منظور ترسیم یک نمودار نقطه‌ای، مولفه‌های نرمال Dash به صورتی که پیش از این نیز انجام شد، وارد (Import) می‌شوند. همچنین، نیاز به وارد (ایمپورت) کردن graph_objs از Plotly به منظور ترسیم نمودار نقطه‌ای است. چنانکه پیش از این اشاره شد، از کلاس Div و مولفه‌های Graph از Dash به منظور انجام این کار استفاده می‌شود. مولفه Graph شی شکل را که حاوی داده‌هایی پیرامون داده‌ها و توصیفات قالب است دریافت می‌کند. نمودار نقطه‌ای با استفاده از خصوصیت graph_objs ترسیم می‌شود. به منظور حصول اطمینان از اینکه نمودار یک نمودار نقطه‌ای است، خصیصه mode پاس داده و به عنوان مارکر تنظیم می‌شود. در غیر این صورت، خطوطی روی نمودار وجود خواهد داشت.

import dash
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
import plotly.graph_objs as go

app = dash.Dash()

df = pd.read_csv(
    'https://gist.githubusercontent.com/chriddyp/' +
    '5d1ea79569ed194d432e56108a04d188/raw/' +
    'a9f9e8076b837d541398e999dcbac2b2826a81f8/'+
    'gdp-life-exp-2007.csv')


app.layout = html.Div([
    dcc.Graph(
        id='life-exp-vs-gdp',
        figure={
            'data': [
                go.Scatter(
                    x=df[df['continent'] == i]['gdp per capita'],
                    y=df[df['continent'] == i]['life expectancy'],
                    text=df[df['continent'] == i]['country'],
                    mode='markers',
                    opacity=0.8,
                    marker={
                        'size': 15,
                        'line': {'width': 0.5, 'color': 'white'}
                    },
                    name=i
                ) for i in df.continent.unique()
            ],
            'layout': go.Layout(
                xaxis={'type': 'log', 'title': 'GDP Per Capita'},
                yaxis={'title': 'Life Expectancy'},
                margin={'l': 40, 'b': 40, 't': 10, 'r': 10},
                legend={'x': 0, 'y': 1},
                hovermode='closest'
            )
        }
    )
])

if __name__ == '__main__':
    app.run_server()

مارک‌داون (Markdown)

گاهی ممکن است که کاربر نیاز به استفاده از میزان زیادی متن در داشبورد خود داشته باشد. این کار را می‌توان با استفاده از خصیصه Markdown در dash_core_components به صورتی انجام داد که در زیر نمایش داده شده است.

import dash
import dash_core_components as dcc
import dash_html_components as html

app = dash.Dash()

markdown_text = '''
### Dash and Markdown
A lot of text
'''

app.layout = html.Div([
    dcc.Markdown(children=markdown_text)
])

if __name__ == '__main__':
    app.run_server()

مولفه‌های هسته‌ای

در ادامه، برخی از dash_core_components مورد بررسی قرار می‌گیرند که کاربر هنگام کار با Dash با آن‌ها مواجه می‌شود. همچنین، می‌توان یک منو کشویی را به صورتی که در ادامه نمایش داده شده است، تولید کرد. این کار با فراخوانی Dropdown off dash_core_components و پاس دادن گزینه‌ها به صورت یک لیست از دیکشنری‌ها انجام می‌شود. می‌توان مقدار پیش‌فرض را با استفاده از خصیصه values و پاس دادن گزینه پیش‌فرض انجام داد.

 dcc.Dropdown(
        options=[
            {'label': 'New York City', 'value': 'NYC'},
            {'label': u'Montréal', 'value': 'MTL'},
            {'label': 'San Francisco', 'value': 'SF'}
        ],
        value='MTL'
    )

ساخت یک منو کشویی multi-select مشابه با بالا است. تنها تغییرات لازم آن است که خصیصه multi روی true تنظیم شود، زیرا به صورت پیش‌فرض، False است. سپس، کاربر می‌تواند اقلامی که تمایل دارد چندتایی انتخاب شوند را به صورت پیش‌فرض با تعیین خصیصه values مشخص کند.

html.Label('Multi-Select Dropdown'),
    dcc.Dropdown(
        options=[
            {'label': 'New York City', 'value': 'NYC'},
            {'label': u'Montréal', 'value': 'MTL'},
            {'label': 'San Francisco', 'value': 'SF'}
        ],
        value=['MTL', 'SF'],
        multi=True
    )

«دکمه رادیویی» (Radio Buttons) را می‌توان با استفاده از خصیصه RadioItems تولید کرد. سپس، گزینه‌ها به صورت لیستی از دیکشنری‌ها پاس داده می‌شوند. همچنین، می‌توان یک مقدار پیش‌فرض را با تعیین خصیصه values تنظیم کرد.

  html.Label('Multi-Select Dropdown'),
    dcc.Dropdown(
        options=[
            {'label': 'New York City', 'value': 'NYC'},
            {'label': u'Montréal', 'value': 'MTL'},
            {'label': 'San Francisco', 'value': 'SF'}
        ],
        value=['MTL', 'SF'],
        multi=True
    )

دکمه‌های رادیویی را می‌توان با استفاده از خصیصه RadioItems ساخت. سپس، گزینه‌ها به عنوان لیستی از دیکشنری‌ها پاس داده می‌شوند. همچنین، می‌توان یک مقدار پیش‌فرض را با تعیین خصیصه values تنظیم کرد.

html.Label('Radio Items'),
    dcc.RadioItems(
        options=[
            {'label': 'New York City', 'value': 'NYC'},
            {'label': u'Montréal', 'value': 'MTL'},
            {'label': 'San Francisco', 'value': 'SF'}
        ],
        value='MTL'
    )

برای تولید چک‌باکس‌ها، خصیصه Checklist از dash_core_components فراخوانی می‌شود. گزینه‌ها و مقادیر پیش‌فرض به صورت بالا پاس داده می‌شود.

 html.Label('Checkboxes'),
    dcc.Checklist(
        options=[
            {'label': 'New York City', 'value': 'NYC'},
            {'label': u'Montréal', 'value': 'MTL'},
            {'label': 'San Francisco', 'value': 'SF'}
        ],
        values=['MTL', 'SF']
    )

قطعا نیاز به وارد کردن متن در برنامه‌کاربردی خواهد بود. برای تولید این متن، از خصیصه Input استفاده می‌شود. با استفاده از تگ Html Label، کاربر می‌تواند یک برچسب برای فیلد ورودی بسازد. با استفاده از خصیصه values، می‌توان متنی را در فیلد تعیین و برای مشخص کردن نوع از type استفاده کرد. بدین شکل مشخص شود که آیا یک فیلد متنی، عدد و یا دیگر موارد است.

html.Label('Text Box'),
    dcc.Input(value='MTL', type='text')

فراخوانی کمک

از آنجا که مولفه‌های Dash اعلانی هستند، فراخوانی دستور کمک روی هر یک از آن‌ها برای آن مولفه کمک ایجاد می‌کند.

help(dcc.Input)

تعامل‌پذیری

اکنون به چگونگی تعامل‌پذیر کردن برنامه Dash پرداخته شده است. به منظور انجام این کار، نیاز به وارد (import) کردن ورودی و خروجی از dash.dependencies وجود دارد. نباید این مورد را با ورودی HTML اشتباه گرفت، زیرا این دو مورد متفاوت هستند. ورودی HTML از طریق مولفه هسته‌ای Dash وارد می‌شود.

در ادامه، یک متن ورودی ساخته می‌شود و فراخوانی به آن مقید می‌شود؛ به طوری که هر بار فرد چیزی در جعبه متن نوشت، my-div به صورت آنی به روز رسانی شود. به منظور انجام این کار، Dash یک برنامه دکوراتور app@ دارد که امکان مقید کردن یک تابع فراخوانی برای my-div و یک فیلد ورودی HTML را فراهم می‌کند. شایان توجه است که از دکوراتور پیش از آنکه تابع update_output_div اعلان شود، استفاده می‌شود.

import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output

app = dash.Dash()

app.layout = html.Div([
    dcc.Input(id='my-id', value='Dash App', type='text'),
    html.Div(id='my-div')
])


@app.callback(
    Output(component_id='my-div', component_property='children'),
    [Input(component_id='my-id', component_property='value')]
)
def update_output_div(input_value):
    return 'You\'ve entered "{}"'.format(input_value)


if __name__ == '__main__':
    app.run_server()

احراز هویت

Dash امکان احراز هویت را از طریق یک بسته جدا به اسم dash-auth فراهم می‌کند. این بسته، دو حالت از احراز هویت HTTP Basic Auth و  Plotly OAuth را فراهم می‌کند. در Basic Auth، مجموعه‌ای از نام‌های کاربری و رمزهای عبور در برنامه کاربردی به صورت کد سخت قرار می‌گیرند. این روش چالش‌هایی دارد مانند آنکه کاربر نمی‌تواند از برنامه خارج شود، نمی‌تواند حساب کاربری بسازد و یا اطلاعات خود را به روز رسانی کند و توسعه‌دهنده مسئول ذخیره‌سازی امن نام‌های کاربری و رمزهای عبور در برنامه خودش است.

Plotly OAuth امکان احراز هویت را از طریق حساب کاربری آنلاین Plotly خود فراهم می‌کند و رایگان نیست. برای راه‌اندازی Basic Auth باید به صورت زیر عمل کرد. ابتدا، بسته‌های لازم نصب می‌شوند.

pip install dash==0.21.1
pip install dash-auth==1.0.0

پس از آن، جفت نام کاربری و رمز عبوری که کاربر تمایل دارد در برنامه خود داشته باشد باید تنظیم شوند.

VALID_USERNAME_PASSWORD_PAIRS = [
    ['hello', 'world']
]

ابزار dash_auth.BasicAuth از Dash هنگامی که جفت نام‌کاربری و رمز عبور تنظیم شد، مراقب احراز هویت است. تنها کاری که توسعه‌دهنده باید انجام دهد پاس دادن password pairs و نام برنامه کاربردی به dash_auth.BasicAuth است.

app = dash.Dash('auth')
auth = dash_auth.BasicAuth(
    app,
    VALID_USERNAME_PASSWORD_PAIRS
)

میزبانی داشبوردها در Heroku

میزبانی داشبورد در Heroku کار نسبتا آسانی است، اما چندین مرحله دارد. ابتدا، یک پوشه ساخته می‌شود که همه فایل‌های پروژه در آن نگهداری می‌شود. کاربر می‌تواند این کار را در سیستم‌عامل اوبونتو با استفاده از دستور mkdir انجام دهد.

$ mkdir my_dash_app
$ cd my_dash_app

سپس، اولیه‌سازی پوشه با git و virtualenv انجام می‌شود. گیت برای کنترل نسخه استفاده می‌شود و virtualenv ما را قادر به ساخت یک محیط مجازی برای نگه داشتن همه وابستگی‌های پایتون می‌کند. پس از ساخت محیط، باید آن را با استفاده از دستور source فعال کرد.

$ git init
$ virtualenv venv
$ source venv/bin/activate

سپس، همه بسته‌های مورد نیاز برای برنامه Dash به صورت زیر نصب می‌شوند.

$ pip install dash
$ pip install dash-renderer
$ pip install dash-core-components
$ pip install dash-html-components
$ pip install plotly

به منظور خدمت‌رسانی به برنامه کاربردی Dash، نیاز به یک وب‌سرور پایتون است. در اینجا هرگز از سرور توسعه «فلسک» (Flask) در تولید استفاده نمی‌شود. از وب سرور Gunicorn برای این تابع استفاده می‌شود. نصب آن به صورت زیر انجام می‌شود.

$ pip install gunicorn

سپس، نیاز به ساخت چند فایل در پوشه است:

  1. app.py باید در جایی ساخته شود که برنامه dash کدنویسی می‌شود.
  2. یک gitignore. باید به منظور حصول اطمینان از این ساخته شود که فایل‌های غیر لازم در تولید قرار نمی‌گیرد.
  3. یک فایل requirements.txt ساخته شود که حاوی همه وابستگی‌های پایتون و نسخه‌های آن است.
  4. یک پروفایل برای استقرار ساخته شود.

اکنون، کد زیر باید به app.py اضافه شود. این تنها یک نمونه کد است و افراد می‌توانند داشبورد Dash مورد نظر خودشان را استفاده کنند.

import os
import dash
import dash_core_components as dcc
import dash_html_components as html
app = dash.Dash(__name__)
server = app.server
app.layout = html.Div([
    html.H2('Hello World'),
    dcc.Dropdown(
        id='dropdown',
        options=[{'label': i, 'value': i} for i in ['LA', 'NYC', 'MTL']],
        value='LA'
    ),
    html.Div(id='display-value')
])
@app.callback(dash.dependencies.Output('display-value', 'children'),
              [dash.dependencies.Input('dropdown', 'value')])
def display_value(value):
    return 'You have selected "{}"'.format(value)
if __name__ == '__main__':
    app.run_server(debug=True)

باید به خاطر داشت که برنامه Dash، در هسته خود، یک برنامه Flask نیز هست. برای هدف استقرار، نیاز به دسترسی به نمونه‌های برنامه کاربردی فلسک است. Dash کاربر را قادر به انجام این کار با استفاده از app.server می‌سازد.

app = dash.Dash(__name__)
server = app.server

اکنون، توسعه‌دهنده باید فایل‌هایی که نمی‌خواهد در تولید قرار بگیرد را به فایل gitignore. اضافه کند. محتوای مربوط به یک فایل پایتون gitignore. خوب، در ادامه آمده است.

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
#  Usually these files are written by a python script from a template
#  before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
target/

# Jupyter Notebook
.ipynb_checkpoints

# IPython
profile_default/
ipython_config.py

# pyenv
.python-version

# pipenv
#   According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
#   However, in case of collaboration, if having platform-specific dependencies or dependencies
#   having no cross-platform support, pipenv may install dependencies that don't work, or not
#   install all needed dependencies.
#Pipfile.lock

# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/

# Celery stuff
celerybeat-schedule
celerybeat.pid

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# Pyre type checker
.pyre/

اکنون، اطلاعات توسعه در Procfile تعیین می‌شود. از متغیرهای وب برای تعیین سرور به عنوان gunicorn استفاده می‌شود. همچنین، جزئیات برنامه کاربردی با به کارگیری متغیر app تعیین می‌شود. app به نام فایل app.py و سرور آن به متغیر server درون آن فایل ارجاع دارد.

web: gunicorn app:server

همچنین، نیاز به نوشتن وابستگی‌های پایتون در فایل نیازمندی‌ها است. Heroku آن‌ها را در طول استقرار نصب می‌کند.

pip freeze > requirements.txt

در گام‌های بعدی فرض می‌شود که کاربر یک حساب کاربری Heroku دارد و Heroku CLI را نصب کرده است. در صورتی که این موارد توسط کاربر نصب نشده‌اند، باید به وب‌سایت Heroku مراجعه و آن‌ها را تنظیم کند. گام بعدی، ساخت یک برنامه کاربردی Heroku  در ترمینال و افزودن همه بسته‌های برنامه کاربردی به آن است. هنگامی که تغییرات وارد شدند، باید برنامه کاربردی را به Heroku Master پوش (Push) کرد. خروجی این دستور دارای لینکی به برنامه کاربردی Dash زنده ساخته شده توسط کاربر در Heroku است.

$ heroku create your-app-name
$ git add .
$ git commit -m 'Your-commit-message'
$ git push heroku master

این مطلب در واقع مقدمه‌ای پیرامون چگونگی ساخت یک داشبورد با پایتون استفاده از Dash توسط Plotly بود.

اگر نوشته بالا برای شما مفید بوده است، آموزش‌های زیر نیز به شما پیشنهاد می‌شوند:

^^

بر اساس رای ۳ نفر
آیا این مطلب برای شما مفید بود؟
شما قبلا رای داده‌اید!
اگر بازخوردی درباره این مطلب دارید یا پرسشی دارید که بدون پاسخ مانده است، آن را از طریق بخش نظرات مطرح کنید.

«الهام حصارکی»، فارغ‌التحصیل مقطع کارشناسی ارشد مهندسی فناوری اطلاعات، گرایش سیستم‌های اطلاعات مدیریت است. او در زمینه هوش مصنوعی و داده‌کاوی، به ویژه تحلیل شبکه‌های اجتماعی، فعالیت می‌کند.

نظر شما چیست؟

نشانی ایمیل شما منتشر نخواهد شد.