Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

Python на страже кошелька

Anna | 15.06.2014 | нет комментариев
Некогда забрел я на сайт мобильного оператора в поисках чего-нибудь увлекательного. Увлекательным оказалось только присутствие большого числа разновидных тарифных планов на всякий вкус и цвет. Здесь — низкий тариф внутри сети, там — тарификация по продолжительности громка, а вот и фиксированная плата за громок. В всеобщем, маркетологи подзатрудились на славу. На сайтах других операторов картина была схожая. Мне стало увлекательно, насколько мои расходы на мобильную связь изменились бы в зависимости от выбранного тарифа. Но одной только силы мысли оказалось неудовлетворительно, Дабы проанализировать статистику звонков за последние месяцы и сопоставить их со всеми тарифами. Решив отложить это дело до наилучших времен, нажимаю Alt Tab и попадаю — верно, в консоль с заголовком Python 2.7.5 и манящим приглашением >>>
Сразу уточню, что на здешнем рынке каждого 3 основных оператора мобильной связи, следственно составить таблицу особенно симпатичных для меня тарифных планов не составило специального труда. Таковых оказалось даже целых 10:

Дальнейшим шагом было приобретение истории звонков за последние 3 месяца. Эта функция была доступна прямо с сайта, за что спасибо моему оператору. Скачав PDF, превратил его в текстовый файл с поддержкойPDFMiner (кстати, тоже написан на python). Итог получился недурной, но все же пара ошибок в тексте была подмечена, следственно взамен танцов с бубном вокруг этой утилиты данные были переведены в текстовый файл с поддержкой тривиального copy-paste прямо из PDF файла. Данный файл и был скормлен нашему питону:

#!/usr/bin/python

import MySQLdb as mysql

con = mysql.connect('localhost', 'mobile', 'mobile', 'mobile')
cur = con.cursor()

with open('calls.log') as f:
    for line in f:
        if 'MOC' in line:
            tokens = line.split()
            if len(tokens) == 11:
                cur.execute("INSERT INTO calls (operator, amount) VALUES('"   tokens[1]   "','"   tokens[6]   "')")
con.commit()

Рассматривая, что СМС я фактически не использую, выборка была сделана только по исходящим звонкам (mobile-originated call, MOC). В итоге лог звонков был сохранен в MySQL базе для дальнейших манипуляций.

Последующие манипуляции

Дальнейший шаг довольно предсказуем — подсчитать, сколько кровно нажитых непосильным трудом денег было бы потрачено с всякого из тарифных планов. Данные по звонкам и по тарифам теснее в базе. И вновь немножко python кода:

cur.execute("SELECT operator,plan,call_init,first_min_int,first_min_ext,min_int,min_ext FROM tariffs")
rows = cur.fetchall()

for row in rows:
    operator, plan, call_init, first_min_int, first_min_ext, min_int, min_ext = row

    # цена соединения
    cur.execute("SELECT COUNT(*) FROM calls") 
    total = call_init*cur.fetchone()[0] 

    # первая минута внутри сети 
    cur.execute("SELECT COALESCE(SUM(LEAST(amount,60)),0) FROM calls WHERE operator='"   operator   "'") 
    total  = cur.fetchone()[0]/60*first_min_int

    # внутри сети, без учета первой минуты 
    cur.execute("SELECT COALESCE(SUM(amount-60),0) FROM calls WHERE operator='"   operator   "' AND amount > 60") 
    total  = cur.fetchone()[0]/60*min_int

    # первая минута вне сети
    cur.execute("SELECT COALESCE(SUM(LEAST(amount,60)),0) FROM calls WHERE operator<>'"   operator   "'") 
    total  = cur.fetchone()[0]/60*first_min_ext

    # вне сети, без учета первой минуты
    cur.execute("SELECT COALESCE(SUM(amount-60),0) FROM calls WHERE operator<>'"   operator   "' AND amount > 60") 
    total  = cur.fetchone()[0]/60*min_ext

    print plan   " : "   str(round(total/100, 2))   " у.е."

Вот что имеем на выходе:

Magti Standard : 47.1 y.e.
Magti I Alternative : 56.5 y.e.
Bani Standard : 29.72 y.e.
Bani Zero  : 26.67 y.e.
Geocell 000 : 49.94 y.e.
Geocell 1-10 : 35.86 y.e.
Geocell 12 : 35.66 y.e.
Beeline 007 : 37.69 y.e.
Beeline Non Stop : 40.7 y.e.
Bani Universal : 39.21 y.e.

Эти же данные в виде диаграммы, для большей наглядности:

Итоги

Таким образом, если не рассматривать крайние значения, то среднеквадратичное отклонение получилось довольно маленьким, в том числе и среди различных операторов связи. Впрочем, даже такой примитивный обзор может содействовать экономии больше чем в 2 раза при выборе особенно выигрышного тарифного плана по сопоставлению с наименее выигрышным, рассматривая специфику определенного пользователя.

 

Некогда забрел я на сайт мобильного оператора в поисках чего-нибудь увлекательного. Увлекательным оказалось только присутствие большого числа разновидных тарифных планов на всякий вкус и цвет. Здесь — низкий тариф внутри сети, там — тарификация по продолжительности громка, а вот и фиксированная плата за громок. В всеобщем, маркетологи подзатрудились на славу. На сайтах других операторов картина была схожая. Мне стало увлекательно, насколько мои расходы на мобильную связь изменились бы в зависимости от выбранного тарифа. Но одной только силы мысли оказалось неудовлетворительно, Дабы проанализировать статистику звонков за последние месяцы и сопоставить их со всеми тарифами. Решив отложить это дело до наилучших времен, нажимаю Alt Tab и попадаю — верно, в консоль с заголовком Python 2.7.5 и манящим приглашением >>>

Сразу уточню, что на здешнем рынке каждого 3 основных оператора мобильной связи, следственно составить таблицу особенно симпатичных для меня тарифных планов не составило специального труда. Таковых оказалось даже целых 10:

Дальнейшим шагом было приобретение истории звонков за последние 3 месяца. Эта функция была доступна прямо с сайта, за что спасибо моему оператору. Скачав PDF, превратил его в текстовый файл с поддержкойPDFMiner (кстати, тоже написан на python). Итог получился недурной, но все же пара ошибок в тексте была подмечена, следственно взамен танцов с бубном вокруг этой утилиты данные были переведены в текстовый файл с поддержкой тривиального copy-paste прямо из PDF файла. Данный файл и был скормлен нашему питону:

#!/usr/bin/python

import MySQLdb as mysql

con = mysql.connect('localhost', 'mobile', 'mobile', 'mobile')
cur = con.cursor()

with open('calls.log') as f:
    for line in f:
        if 'MOC' in line:
            tokens = line.split()
            if len(tokens) == 11:
                cur.execute("INSERT INTO calls (operator, amount) VALUES('"   tokens[1]   "','"   tokens[6]   "')")
con.commit()

Рассматривая, что СМС я фактически не использую, выборка была сделана только по исходящим звонкам (mobile-originated call, MOC). В итоге лог звонков был сохранен в MySQL базе для дальнейших манипуляций.

Последующие манипуляции

Дальнейший шаг довольно предсказуем — подсчитать, сколько кровно нажитых непосильным трудом денег было бы потрачено с всякого из тарифных планов. Данные по звонкам и по тарифам теснее в базе. И вновь немножко python кода:

cur.execute("SELECT operator,plan,call_init,first_min_int,first_min_ext,min_int,min_ext FROM tariffs")
rows = cur.fetchall()

for row in rows:
    operator, plan, call_init, first_min_int, first_min_ext, min_int, min_ext = row

    # цена соединения
    cur.execute("SELECT COUNT(*) FROM calls") 
    total = call_init*cur.fetchone()[0] 

    # первая минута внутри сети 
    cur.execute("SELECT COALESCE(SUM(LEAST(amount,60)),0) FROM calls WHERE operator='"   operator   "'") 
    total  = cur.fetchone()[0]/60*first_min_int

    # внутри сети, без учета первой минуты 
    cur.execute("SELECT COALESCE(SUM(amount-60),0) FROM calls WHERE operator='"   operator   "' AND amount > 60") 
    total  = cur.fetchone()[0]/60*min_int

    # первая минута вне сети
    cur.execute("SELECT COALESCE(SUM(LEAST(amount,60)),0) FROM calls WHERE operator<>'"   operator   "'") 
    total  = cur.fetchone()[0]/60*first_min_ext

    # вне сети, без учета первой минуты
    cur.execute("SELECT COALESCE(SUM(amount-60),0) FROM calls WHERE operator<>'"   operator   "' AND amount > 60") 
    total  = cur.fetchone()[0]/60*min_ext

    print plan   " : "   str(round(total/100, 2))   " у.е."

Вот что имеем на выходе:

Magti Standard : 47.1 y.e.
Magti I Alternative : 56.5 y.e.
Bani Standard : 29.72 y.e.
Bani Zero  : 26.67 y.e.
Geocell 000 : 49.94 y.e.
Geocell 1-10 : 35.86 y.e.
Geocell 12 : 35.66 y.e.
Beeline 007 : 37.69 y.e.
Beeline Non Stop : 40.7 y.e.
Bani Universal : 39.21 y.e.

Эти же данные в виде диаграммы, для большей наглядности:

Итоги

Таким образом, если не рассматривать крайние значения, то среднеквадратичное отклонение получилось довольно маленьким, в том числе и среди различных операторов связи. Впрочем, даже такой примитивный обзор может содействовать экономии больше чем в 2 раза при выборе особенно выигрышного тарифного плана по сопоставлению с наименее выигрышным, рассматривая специфику определенного пользователя.

Источник: programmingmaster.ru

Оставить комментарий
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB