\n",
1247 | "\u001b[36mintX\u001b[39m: \u001b[32mEquiv\u001b[39m[\u001b[32mInt\u001b[39m] = scala.math.Equiv$$anon$4@274f015a"
1248 | ]
1249 | },
1250 | "execution_count": 9,
1251 | "metadata": {},
1252 | "output_type": "execute_result"
1253 | }
1254 | ],
1255 | "source": [
1256 | "val strX: Equiv[String] = fromComparator(CASE_INSENSITIVE_ORDER)\n",
1257 | "val f: (Int => String) = _.toString\n",
1258 | "val intX: Equiv[Int] = fromFunction((x, y) => strX.equiv(f(x), f(y)))"
1259 | ]
1260 | },
1261 | {
1262 | "cell_type": "markdown",
1263 | "metadata": {},
1264 | "source": [
1265 | "Как и в случае с ковариантным функтором, контравариантному функтору кроме метода с сигнатурой необходимо следовать двум правилам."
1266 | ]
1267 | },
1268 | {
1269 | "cell_type": "markdown",
1270 | "metadata": {},
1271 | "source": [
1272 | "Первое правило (Identity Law) гласит: для всякого контравариантного функтора fun должно выполняться IdentityLaw.case0(fun) тождественно равно IdentityLaw.case1(fun)"
1273 | ]
1274 | },
1275 | {
1276 | "cell_type": "markdown",
1277 | "metadata": {},
1278 | "source": [
1279 | "```object IdentityLaw {\n",
1280 | " def case0[T](fun: Contravariant[T]): Contravariant[T] = identity(fun) \n",
1281 | " def case1[T](fun: Contravariant[T]): Contravariant[T] = fun.contramap(identity)\n",
1282 | "}```"
1283 | ]
1284 | },
1285 | {
1286 | "cell_type": "markdown",
1287 | "metadata": {},
1288 | "source": [
1289 | "\n",
1290 | "То есть отображение контравариантного функтора единичной функцией не меняет его."
1291 | ]
1292 | },
1293 | {
1294 | "cell_type": "markdown",
1295 | "metadata": {},
1296 | "source": [
1297 | "Второе правило (Composition Law) гласит: для всякого контравариантного функтора fun[T] и произвольной пары функций f: Q => R и g: R => T пары должно быть IdentityLaw.case0(fun) тождественно равно IdentityLaw.case1(fun)"
1298 | ]
1299 | },
1300 | {
1301 | "cell_type": "markdown",
1302 | "metadata": {},
1303 | "source": [
1304 | "```object CompositionLaw {\n",
1305 | " def case0[Q, R, T](fun: Contravariant[T], f: Q => R, g: R => T): Contravariant[Q] =\n",
1306 | " (fun contramap g) contramap f\n",
1307 | " def case1[Q, R, T](fun: Contravariant[T], f: Q => R, g: R => T): Contravariant[Q] =\n",
1308 | " fun contramap (f andThen g)\n",
1309 | "}```"
1310 | ]
1311 | },
1312 | {
1313 | "cell_type": "markdown",
1314 | "metadata": {},
1315 | "source": [
1316 | "То есть отображение контравариантного функтора последовательно парой функций эквивалентно единичному отображению композицией функций (инвертированной).\n"
1317 | ]
1318 | },
1319 | {
1320 | "cell_type": "markdown",
1321 | "metadata": {},
1322 | "source": [
1323 | "\n",
1324 | "Понятия ко- и контра-вариантного функтора являются только стартовой точкой для серьезного изучения применения абстракций из теории категорий в функциональном программировании (в терминах Scala — переход к использованию библиотек Scalaz, Cats). \n",
1325 | "\n",
1326 | "Дальнейшие шаги включают:\n",
1327 | "1. Изучение композиций ко- и контра- вариантных функторов (BiFunctor, ProFunctor, Exponential (Invariant) Functor)\n",
1328 | "2. Изучение более специализированных конструкций (Applicative Functor, Arrow, Monad), которые уже действительно составляют новую парадигму работы с вычислениями, вводом-выводом, обработкой ошибок, мутирующим состоянием. Укажу хотя бы на то, что всякая монада является ковариантным функтором."
1329 | ]
1330 | },
1331 | {
1332 | "cell_type": "markdown",
1333 | "metadata": {},
1334 | "source": [
1335 | "Литература для создания тетрадки\n",
1336 | "\n",
1337 | "1. [Functors and things using Scala](http://blog.tmorris.net/posts/functors-and-things-using-scala/index.html)\n",
1338 | "2. [Функторы, аппликативные функторы и монады в картинках](https://habrahabr.ru/post/183150/)\n",
1339 | "3. [First steps with monads in Scala](https://darrenjw.wordpress.com/2016/04/15/first-steps-with-monads-in-scala/)\n",
1340 | "4. [FP на Scala: Что такое функтор?](https://habrahabr.ru/company/golovachcourses/blog/266905/)\n",
1341 | "5. [Scala's Either, Try and the M word](https://mauricio.github.io/2014/02/17/scala-either-try-and-the-m-word.html)\n",
1342 | "\n",
1343 | "[Если вы классный](http://homepages.inf.ed.ac.uk/wadler/papers/marktoberdorf/baastad.pdf)
\n",
1344 | "\n",
1345 | "[Очень-очень классный](https://bartoszmilewski.com/2014/10/28/category-theory-for-programmers-the-preface/)
\n"
1346 | ]
1347 | }
1348 | ],
1349 | "metadata": {
1350 | "kernelspec": {
1351 | "display_name": "Scala",
1352 | "language": "scala",
1353 | "name": "scala"
1354 | },
1355 | "language_info": {
1356 | "codemirror_mode": "text/x-scala",
1357 | "file_extension": ".scala",
1358 | "mimetype": "text/x-scala",
1359 | "name": "scala211",
1360 | "nbconvert_exporter": "script",
1361 | "pygments_lexer": "scala",
1362 | "version": "2.11.11"
1363 | }
1364 | },
1365 | "nbformat": 4,
1366 | "nbformat_minor": 2
1367 | }
1368 |
--------------------------------------------------------------------------------
/day3/akka.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": 1,
6 | "metadata": {
7 | "collapsed": false,
8 | "scrolled": true
9 | },
10 | "outputs": [
11 | {
12 | "data": {
13 | "text/plain": [
14 | "\u001b[32mimport \u001b[39m\u001b[36m$ivy.$ \u001b[39m"
15 | ]
16 | },
17 | "execution_count": 1,
18 | "metadata": {},
19 | "output_type": "execute_result"
20 | }
21 | ],
22 | "source": [
23 | "// Скачаем Akka\n",
24 | "import $ivy.`com.typesafe.akka:akka-actor_2.11:2.5.3`"
25 | ]
26 | },
27 | {
28 | "cell_type": "markdown",
29 | "metadata": {},
30 | "source": [
31 | "# Akka и с чем его едят\n",
32 | "\n",
33 | "В акторной модели – которая была изобретена в 1973 году Карлом Хьюиттом и др. — акторы представляют собой «фундаментальные единицы вычислений, реализующие обработку, хранение и коммуникацию». "
34 | ]
35 | },
36 | {
37 | "cell_type": "markdown",
38 | "metadata": {},
39 | "source": [
40 | ""
41 | ]
42 | },
43 | {
44 | "cell_type": "markdown",
45 | "metadata": {},
46 | "source": [
47 | "Если не вдаваться в подробности, то разработка на акторах исходит из философии, что все круг акторы. Так же как и ООП исходит из философии, что все круг объекты. Принципиальные отличия же состоят в том, что акторы выполняются параллельно. В то время как ООП код выполняется последовательно и для параллельного исполнения надо делать дополнительные и далеко не всегда простые действия. А так же акторы взаимодействуют между собой не через вызовы методов у объектов, как в ООП, а через отправку сообщений. В акторе есть очередь этих сообщений (mailbox). Сообщения обрабатываются строго по очереди."
48 | ]
49 | },
50 | {
51 | "cell_type": "markdown",
52 | "metadata": {
53 | "collapsed": true
54 | },
55 | "source": [
56 | "Кроме того, необходимо отметить, что отправка сообщения актору и обработка этого сообщения актором — это две отдельных операции, которые, скорее всего, происходят в разных потоках. Разумеется, Akka обеспечивает необходимую синхронизацию, чтобы гарантировать, что любые изменения состояния будут видимы всем потокам. \n"
57 | ]
58 | },
59 | {
60 | "cell_type": "code",
61 | "execution_count": 8,
62 | "metadata": {
63 | "collapsed": false
64 | },
65 | "outputs": [
66 | {
67 | "data": {
68 | "text/plain": [
69 | "\u001b[32mimport \u001b[39m\u001b[36makka.actor._\u001b[39m"
70 | ]
71 | },
72 | "execution_count": 8,
73 | "metadata": {},
74 | "output_type": "execute_result"
75 | }
76 | ],
77 | "source": [
78 | "import akka.actor._"
79 | ]
80 | },
81 | {
82 | "cell_type": "code",
83 | "execution_count": 3,
84 | "metadata": {
85 | "collapsed": false
86 | },
87 | "outputs": [
88 | {
89 | "data": {
90 | "text/plain": [
91 | "defined \u001b[32mclass\u001b[39m \u001b[36mPubSubMediator\u001b[39m"
92 | ]
93 | },
94 | "execution_count": 3,
95 | "metadata": {},
96 | "output_type": "execute_result"
97 | }
98 | ],
99 | "source": [
100 | "class PubSubMediator extends Actor {\n",
101 | " override def receive = Actor.emptyBehavior\n",
102 | "}"
103 | ]
104 | },
105 | {
106 | "cell_type": "markdown",
107 | "metadata": {},
108 | "source": [
109 | "Метод receive возвращает так называемое исходное поведение актора. Это просто частично вычислимая функция, используемая Akka для обработки сообщений, отправляемых актору."
110 | ]
111 | },
112 | {
113 | "cell_type": "markdown",
114 | "metadata": {},
115 | "source": [
116 | "При создании акторной системы, Akka — на внутреннем уровне использующая множество так называемых «системных акторов» — создает три актора: это «корневой страж» (root guardian), расположенный в корне акторной иерархии, а также системный и пользовательский стражи. Пользовательский страж — зачастую именуемый просто «страж» — является родительским элементом для всех создаваемых нами акторов верхнего уровня (в данном контексте имеется в виду «наивысший уровень, к которому мы имеем доступ»).\n"
117 | ]
118 | },
119 | {
120 | "cell_type": "code",
121 | "execution_count": 4,
122 | "metadata": {
123 | "collapsed": false
124 | },
125 | "outputs": [
126 | {
127 | "data": {
128 | "text/plain": [
129 | "\u001b[36msystem\u001b[39m: \u001b[32mActorSystem\u001b[39m = akka://pub-sub-mediator-spec-system"
130 | ]
131 | },
132 | "execution_count": 4,
133 | "metadata": {},
134 | "output_type": "execute_result"
135 | }
136 | ],
137 | "source": [
138 | "// Создадим систему акторов\n",
139 | "val system = ActorSystem(\"pub-sub-mediator-spec-system\")"
140 | ]
141 | },
142 | {
143 | "cell_type": "markdown",
144 | "metadata": {},
145 | "source": [
146 | "А зачем мы вообще создаем ActorSystem? Почему бы просто не создавать акторы? Последнее невозможно, поскольку при непосредственном вызове конструктора актора система выбросит исключение. Вместо этого нам придется использовать фабричный метод, предоставляемый — вы угадали — ActorSystem для создания актора верхнего уровня:"
147 | ]
148 | },
149 | {
150 | "cell_type": "code",
151 | "execution_count": 5,
152 | "metadata": {
153 | "collapsed": false
154 | },
155 | "outputs": [
156 | {
157 | "data": {
158 | "text/plain": [
159 | "\u001b[36mres4\u001b[39m: \u001b[32mActorRef\u001b[39m = Actor[akka://pub-sub-mediator-spec-system/user/pub-sub-mediator#-8146321]"
160 | ]
161 | },
162 | "execution_count": 5,
163 | "metadata": {},
164 | "output_type": "execute_result"
165 | }
166 | ],
167 | "source": [
168 | "system.actorOf(Props(new PubSubMediator), \"pub-sub-mediator\")"
169 | ]
170 | },
171 | {
172 | "cell_type": "code",
173 | "execution_count": 6,
174 | "metadata": {
175 | "collapsed": false
176 | },
177 | "outputs": [
178 | {
179 | "data": {
180 | "text/plain": [
181 | "defined \u001b[32mobject\u001b[39m \u001b[36mPubSubMediator\u001b[39m"
182 | ]
183 | },
184 | "execution_count": 6,
185 | "metadata": {},
186 | "output_type": "execute_result"
187 | }
188 | ],
189 | "source": [
190 | "object PubSubMediator {\n",
191 | " \n",
192 | " final val Name = \"pub-sub-mediator\"\n",
193 | " \n",
194 | " def props: Props = Props(new PubSubMediator)\n",
195 | "}"
196 | ]
197 | },
198 | {
199 | "cell_type": "markdown",
200 | "metadata": {},
201 | "source": [
202 | "А что за такая штуковина Props? Это просто конфигурационный объект для актора. Он принимает конструктор как параметр, передаваемый по имени (то есть, лениво) и может содержать другую важную информацию – например, о маршрутизации или развертывании. "
203 | ]
204 | },
205 | {
206 | "cell_type": "code",
207 | "execution_count": 10,
208 | "metadata": {
209 | "collapsed": false
210 | },
211 | "outputs": [
212 | {
213 | "ename": "",
214 | "evalue": "",
215 | "output_type": "error",
216 | "traceback": [
217 | "\u001b[31makka.actor.InvalidActorNameException: actor name [pub-sub-mediator] is not unique!\u001b[39m",
218 | " akka.actor.dungeon.ChildrenContainer$NormalChildrenContainer.reserve(\u001b[32mChildrenContainer.scala\u001b[39m:\u001b[32m129\u001b[39m)",
219 | " akka.actor.dungeon.Children$class.reserveChild(\u001b[32mChildren.scala\u001b[39m:\u001b[32m134\u001b[39m)",
220 | " akka.actor.ActorCell.reserveChild(\u001b[32mActorCell.scala\u001b[39m:\u001b[32m370\u001b[39m)",
221 | " akka.actor.dungeon.Children$class.makeChild(\u001b[32mChildren.scala\u001b[39m:\u001b[32m272\u001b[39m)",
222 | " akka.actor.dungeon.Children$class.attachChild(\u001b[32mChildren.scala\u001b[39m:\u001b[32m48\u001b[39m)",
223 | " akka.actor.ActorCell.attachChild(\u001b[32mActorCell.scala\u001b[39m:\u001b[32m370\u001b[39m)",
224 | " akka.actor.ActorSystemImpl.actorOf(\u001b[32mActorSystem.scala\u001b[39m:\u001b[32m717\u001b[39m)",
225 | " $sess.cmd9Wrapper$Helper.(\u001b[32mcmd9.sc\u001b[39m:\u001b[32m1\u001b[39m)",
226 | " $sess.cmd9Wrapper.(\u001b[32mcmd9.sc\u001b[39m:\u001b[32m223\u001b[39m)",
227 | " $sess.cmd9$.(\u001b[32mcmd9.sc\u001b[39m:\u001b[32m189\u001b[39m)",
228 | " $sess.cmd9$.(\u001b[32mcmd9.sc\u001b[39m:\u001b[32m-1\u001b[39m)"
229 | ]
230 | }
231 | ],
232 | "source": [
233 | "// Если мы захотим создать актор с таким же именем\n",
234 | "// Мы этого не сможем сделать\n",
235 | "// Ибо у каждого актора должно быть уникальное имя\n",
236 | "system.actorOf(PubSubMediator.props, PubSubMediator.Name)"
237 | ]
238 | }
239 | ],
240 | "metadata": {
241 | "kernelspec": {
242 | "display_name": "Scala",
243 | "language": "scala",
244 | "name": "scala"
245 | },
246 | "language_info": {
247 | "codemirror_mode": "text/x-scala",
248 | "file_extension": ".scala",
249 | "mimetype": "text/x-scala",
250 | "name": "scala211",
251 | "nbconvert_exporter": "script",
252 | "pygments_lexer": "scala",
253 | "version": "2.11.11"
254 | }
255 | },
256 | "nbformat": 4,
257 | "nbformat_minor": 2
258 | }
259 |
--------------------------------------------------------------------------------
/little-projects/Bank.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": 35,
6 | "metadata": {},
7 | "outputs": [
8 | {
9 | "data": {
10 | "text/plain": [
11 | "\u001b[32mimport \u001b[39m\u001b[36mscala.collection.mutable.ListBuffer\n",
12 | "\u001b[39m\n",
13 | "\u001b[32mimport \u001b[39m\u001b[36mscala.collection.mutable.Map\n",
14 | "\u001b[39m\n",
15 | "\u001b[32mimport \u001b[39m\u001b[36mscala.util.Random\n",
16 | "\u001b[39m\n",
17 | "\u001b[32mimport \u001b[39m\u001b[36mjava.util.Calendar\u001b[39m"
18 | ]
19 | },
20 | "execution_count": 35,
21 | "metadata": {},
22 | "output_type": "execute_result"
23 | }
24 | ],
25 | "source": [
26 | "// Зависимости\n",
27 | "import scala.collection.mutable.ListBuffer\n",
28 | "import scala.collection.mutable.Map\n",
29 | "import scala.util.Random\n",
30 | "import java.util.Calendar"
31 | ]
32 | },
33 | {
34 | "cell_type": "code",
35 | "execution_count": 36,
36 | "metadata": {},
37 | "outputs": [
38 | {
39 | "data": {
40 | "text/plain": [
41 | "defined \u001b[32mclass\u001b[39m \u001b[36mAccountType\u001b[39m\n",
42 | "defined \u001b[32mclass\u001b[39m \u001b[36mHelpers\u001b[39m\n",
43 | "defined \u001b[32mclass\u001b[39m \u001b[36mBank\u001b[39m\n",
44 | "defined \u001b[32mclass\u001b[39m \u001b[36mTransaction\u001b[39m\n",
45 | "defined \u001b[32mclass\u001b[39m \u001b[36mCustomer\u001b[39m\n",
46 | "defined \u001b[32mclass\u001b[39m \u001b[36mAccount\u001b[39m\n",
47 | "defined \u001b[32mclass\u001b[39m \u001b[36mContribution\u001b[39m\n",
48 | "defined \u001b[32mclass\u001b[39m \u001b[36mCredit\u001b[39m"
49 | ]
50 | },
51 | "execution_count": 36,
52 | "metadata": {},
53 | "output_type": "execute_result"
54 | }
55 | ],
56 | "source": [
57 | "case class AccountType(val name:String, val credit_percent:Double, val deposit_percent:Double, \n",
58 | " val giveaway_percent:Double, val contribution_percent:Double)\n",
59 | "\n",
60 | "\n",
61 | "class Helpers{\n",
62 | " def printTransactionInfo(trans:Transaction){ \n",
63 | " println(\"type: \" + trans.kind + \" amount: \" + trans.amount + \" date: \" + trans.datetime.getTime)\n",
64 | " }\n",
65 | " \n",
66 | " def printContributionInfo(contr:Contribution){\n",
67 | " println(\"amount: \" + contr.amount + \" years: \" + contr.years + \" start date: \" + contr.startTime.getTime + \" percent: \" + contr.account.accountType.contribution_percent)\n",
68 | " }\n",
69 | " \n",
70 | " def printCreditInfo(credit:Credit){\n",
71 | " println(\"amount: \" + credit.amount + \" months: \" + credit.months + \" start date: \" + credit.startTime.getTime + \" percent: \" + credit.account.accountType.credit_percent)\n",
72 | " }\n",
73 | " \n",
74 | " def printContributionsList(allcontr:ListBuffer[Contribution]){\n",
75 | " println(\"Contributions:\")\n",
76 | " for(i <- allcontr)\n",
77 | " printContributionInfo(i)\n",
78 | " }\n",
79 | " def printCreditList(allcred:ListBuffer[Credit]){\n",
80 | " println(\"Credits:\")\n",
81 | " for(i <- allcred)\n",
82 | " printCreditInfo(i)\n",
83 | " }\n",
84 | " \n",
85 | " def printTransactionsList(alltrans:ListBuffer[Transaction]){\n",
86 | " println(\"Transactions:\")\n",
87 | " for(i <- alltrans)\n",
88 | " printTransactionInfo(i)\n",
89 | " }\n",
90 | "\n",
91 | " def printAccountInfo(account:Account){\n",
92 | " print (\"balance: \" + account.balance + \" Type: \" + account.accountType.name + \"\\n\")\n",
93 | " printTransactionsList(account.transactions)\n",
94 | " printContributionsList(account.contributions)\n",
95 | " printCreditList(account.credits)\n",
96 | " }\n",
97 | " def printCustomerInfo(user:Customer){\n",
98 | " print(\"name: \" + user.name + \"\\nAccounts:\\n\")\n",
99 | " for(i <- user.accounts){\n",
100 | " printAccountInfo(i)\n",
101 | " print(\"\\n\")\n",
102 | " }\n",
103 | " }\n",
104 | "}\n",
105 | "class Bank {\n",
106 | " // Клиенты банка\n",
107 | " var customers = new ListBuffer[Customer]\n",
108 | "\n",
109 | " // Добавить клиента\n",
110 | " def addCustomer(customer: Customer) { customers += customer }\n",
111 | " \n",
112 | " //типы аккаунтов, у разных типов разные проценты на депозиты, переводы, кредиты и вклады\n",
113 | " var accTypes:Map[String, AccountType] = Map(\"basic\" -> new AccountType(\"basic\", 1.2, 0.9, 0.9, 1.10),\n",
114 | " \"VIP\" -> new AccountType(\"VIP\", 1.1, 0.95, 0.95, 1.20),\n",
115 | " \"premier\" -> new AccountType(\"premier\", 1.05,0.99, 0.99,1.30)) \n",
116 | " def getAccType(accType:String):AccountType={\n",
117 | " return accTypes(accType)\n",
118 | " }\n",
119 | " def getAllUsers():ListBuffer[Customer]={\n",
120 | " return customers\n",
121 | " }\n",
122 | " \n",
123 | " //симуляция работы банка\n",
124 | " def work()={\n",
125 | " var help = new Helpers()\n",
126 | " var flag = true\n",
127 | " for(user <- customers){\n",
128 | " for(account <- user.accounts){\n",
129 | " for(contribution <- account.contributions){\n",
130 | " contribution.startTime = Calendar.getInstance\n",
131 | " }\n",
132 | " for(credit <- account.credits){\n",
133 | " credit.startTime = Calendar.getInstance\n",
134 | " }\n",
135 | " }\n",
136 | " }\n",
137 | " var iteration = 1\n",
138 | " while(flag == true){\n",
139 | " flag = false\n",
140 | " for(user <- customers){\n",
141 | " for(account <- user.accounts){\n",
142 | " for(contribution <- account.contributions){\n",
143 | " if(iteration%12 == 0){\n",
144 | " println(\"Contrbutions\")\n",
145 | " help.printContributionInfo(contribution)\n",
146 | " contribution.upgrade()\n",
147 | " }\n",
148 | " flag = true\n",
149 | " }\n",
150 | " for(credit <- account.credits){\n",
151 | " println(\"credits\")\n",
152 | " help.printCreditInfo(credit)\n",
153 | " credit.upgrade()\n",
154 | " flag = true\n",
155 | " }\n",
156 | " }\n",
157 | " }\n",
158 | " if(flag == true){\n",
159 | " println(\"Прошел месяц....\")\n",
160 | " Thread.sleep(1000)\n",
161 | " }\n",
162 | " iteration+=1\n",
163 | " }\n",
164 | " }\n",
165 | " \n",
166 | " def block_account(account:Account)=account.blocked = true\n",
167 | " \n",
168 | " def unblock_account(account:Account)=account.blocked = false\n",
169 | " \n",
170 | " //оплатить весь долг по кредиту(менеджер)\n",
171 | " def pay_for_credit(credit:Credit){\n",
172 | " credit.payAll()\n",
173 | " }\n",
174 | " \n",
175 | " //вывести деньги из вклада(менеджер)\n",
176 | " def get_contribution_back(contribution:Contribution){\n",
177 | " contribution.getMoneyBack()\n",
178 | " }\n",
179 | "}\n",
180 | "\n",
181 | "class Transaction(val kind:String, val amount:Double){\n",
182 | " val datetime = Calendar.getInstance()\n",
183 | "}\n",
184 | "\n",
185 | "// Пользователи\n",
186 | "\n",
187 | "class Customer(val name: String) {\n",
188 | "\n",
189 | " // Аккаунты пользователя\n",
190 | " val accounts: ListBuffer[Account] = ListBuffer()\n",
191 | " // Создать новый счёт\n",
192 | " def openAccount(account: Account): Customer = {\n",
193 | " accounts += account\n",
194 | " this\n",
195 | " }\n",
196 | "\n",
197 | " def get_all_transactions(account:Account):ListBuffer[Transaction] = {\n",
198 | " return account.transactions\n",
199 | " } \n",
200 | " \n",
201 | " def delete_account(account:Account)={\n",
202 | " accounts -= account\n",
203 | " }\n",
204 | " \n",
205 | " //перевод средств на другой счет\n",
206 | " def give_money(from_account:Account, to_account:Account, sum:Double) = {\n",
207 | " if(from_account.balance < sum)\n",
208 | " throw new IllegalArgumentException(\"Не достаточно денег на счете\")\n",
209 | " else{\n",
210 | " from_account.balance -= sum\n",
211 | " to_account.balance += sum*from_account.accountType.giveaway_percent\n",
212 | " }\n",
213 | " from_account.transactions.append(new Transaction(\"giveaway\", -sum))\n",
214 | " to_account.transactions.append(new Transaction(\"addition\", sum*from_account.accountType.giveaway_percent))\n",
215 | " }\n",
216 | "}\n",
217 | "\n",
218 | "class Account(val accountType:AccountType) {\n",
219 | " // Баланс аккаунта\n",
220 | " var balance = 0.0\n",
221 | " val contributions: ListBuffer[Contribution] = ListBuffer()\n",
222 | " val credits: ListBuffer[Credit] = ListBuffer()\n",
223 | " val transactions:ListBuffer[Transaction] = ListBuffer()\n",
224 | " // Uid аккаунта\n",
225 | " val uid = java.util.UUID.randomUUID.toString\n",
226 | " var blocked = false\n",
227 | "\n",
228 | " // Добавление денег на аккаунт\n",
229 | " def deposit(amount: Double) {\n",
230 | " if(blocked)\n",
231 | " println(\"Аккаунт заблокирован, невозможно произвести операцию\")\n",
232 | " else if (amount <= 0)\n",
233 | " throw new IllegalArgumentException(\"У вас должно быть больше денег чем 0\")\n",
234 | " else\n",
235 | " // Добавить денег\n",
236 | " balance += amount*accountType.deposit_percent\n",
237 | " transactions.append(new Transaction(\"deposit\", amount*accountType.deposit_percent))\n",
238 | " }\n",
239 | " \n",
240 | " //вывод средств со счета\n",
241 | " def remove_money(amount: Double){\n",
242 | " if(blocked)\n",
243 | " println(\"Аккаунт заблокирован, невозможно произвести операцию\")\n",
244 | " if(amount > balance)\n",
245 | " throw new IllegalArgumentException(\"Не достаточно денег на счете\")\n",
246 | " else{\n",
247 | " balance -= amount\n",
248 | " transactions.append(new Transaction(\"windraw\", -amount))\n",
249 | " }\n",
250 | " }\n",
251 | " \n",
252 | " \n",
253 | " def new_contribution(amount:Double, years:Int)={\n",
254 | " if(blocked)\n",
255 | " println(\"Аккаунт заблокирован, невозможно произвести операцию\")\n",
256 | " if(amount > balance)\n",
257 | " throw new IllegalArgumentException(\"Не достаточно денег на счете\")\n",
258 | " else{\n",
259 | " balance -= amount\n",
260 | " contributions.append(new Contribution(amount, years, this))\n",
261 | " transactions.append(new Transaction(\"contribution\", -amount))\n",
262 | " }\n",
263 | " }\n",
264 | " \n",
265 | " def new_credit(amount:Double, years:Int){\n",
266 | " if(blocked)\n",
267 | " println(\"Аккаунт заблокирован, невозможно произвести операцию\")\n",
268 | " balance+=amount\n",
269 | " credits.append(new Credit(amount, years, this))\n",
270 | " transactions.append(new Transaction(\"credit\", amount))\n",
271 | " }\n",
272 | " //оплатить весь долг по кредиту(клиент)\n",
273 | " def pay_for_credit(credit:Credit){\n",
274 | " credit.payAll()\n",
275 | " }\n",
276 | " \n",
277 | " //вывести деньги из вклада(клиент)\n",
278 | " def get_contribution_back(contribution:Contribution){\n",
279 | " contribution.getMoneyBack()\n",
280 | " }\n",
281 | "}\n",
282 | "\n",
283 | "class Contribution(var amount:Double, var years:Int, val account:Account){\n",
284 | " var startTime = Calendar.getInstance()\n",
285 | " //обновление вклада(каждый месяц)\n",
286 | " def upgrade() = {\n",
287 | " if(years==0){\n",
288 | " getMoneyBack()\n",
289 | " }\n",
290 | " else\n",
291 | " amount*=account.accountType.contribution_percent\n",
292 | " years-=1\n",
293 | " }\n",
294 | " //забрать все деньги из вклада\n",
295 | " def getMoneyBack(){\n",
296 | " account.balance += amount\n",
297 | " account.contributions -= this\n",
298 | " account.transactions.append(new Transaction(\"from contribution\", amount))\n",
299 | " }\n",
300 | "}\n",
301 | "\n",
302 | "class Credit (var amount:Double, var years:Int, val account:Account){\n",
303 | " var months = years*12\n",
304 | " var startTime = Calendar.getInstance()\n",
305 | " val sumToPay:Double = amount*account.accountType.credit_percent/months\n",
306 | " \n",
307 | " //обновление кредита(каждый месяц)\n",
308 | " def upgrade(){\n",
309 | " if(months==0){\n",
310 | " account.credits -= this\n",
311 | " }\n",
312 | " else\n",
313 | " {\n",
314 | " if(sumToPay > account.balance)\n",
315 | " print(\"Теперь вы должны банку денег\")\n",
316 | " account.balance -= sumToPay\n",
317 | " account.transactions.append(new Transaction(\"credit pay\", -sumToPay))\n",
318 | " }\n",
319 | " months-=1\n",
320 | " }\n",
321 | " \n",
322 | " //заплатить весь долг за кредит\n",
323 | " def payAll(){\n",
324 | " if(account.balance < sumToPay*months)\n",
325 | " print(\"Не достаточно средств на счете, чтобы оплатить кредит\")\n",
326 | " else{\n",
327 | " account.balance -= sumToPay*months\n",
328 | " account.credits -= this\n",
329 | " account.transactions.append(new Transaction(\"credit pay\", -sumToPay*months))\n",
330 | " }\n",
331 | " }\n",
332 | "}"
333 | ]
334 | },
335 | {
336 | "cell_type": "code",
337 | "execution_count": 37,
338 | "metadata": {
339 | "scrolled": true
340 | },
341 | "outputs": [
342 | {
343 | "data": {
344 | "text/plain": [
345 | "\u001b[36mbank\u001b[39m: \u001b[32mBank\u001b[39m = $sess.cmd35Wrapper$Helper$Bank@16a0f564"
346 | ]
347 | },
348 | "execution_count": 37,
349 | "metadata": {},
350 | "output_type": "execute_result"
351 | }
352 | ],
353 | "source": [
354 | "val bank = new Bank"
355 | ]
356 | },
357 | {
358 | "cell_type": "code",
359 | "execution_count": 38,
360 | "metadata": {},
361 | "outputs": [
362 | {
363 | "data": {
364 | "text/plain": [
365 | "\u001b[36mhelp\u001b[39m: \u001b[32mHelpers\u001b[39m = $sess.cmd35Wrapper$Helper$Helpers@43c5cba2\n",
366 | "\u001b[36muser\u001b[39m: \u001b[32mCustomer\u001b[39m = $sess.cmd35Wrapper$Helper$Customer@437163f2\n",
367 | "\u001b[36maccount\u001b[39m: \u001b[32mAccount\u001b[39m = $sess.cmd35Wrapper$Helper$Account@492f6796\n",
368 | "\u001b[36mres37_4\u001b[39m: \u001b[32mCustomer\u001b[39m = $sess.cmd35Wrapper$Helper$Customer@437163f2\n",
369 | "\u001b[36maccount2\u001b[39m: \u001b[32mAccount\u001b[39m = $sess.cmd35Wrapper$Helper$Account@48097be0\n",
370 | "\u001b[36mres37_6\u001b[39m: \u001b[32mCustomer\u001b[39m = $sess.cmd35Wrapper$Helper$Customer@437163f2"
371 | ]
372 | },
373 | "execution_count": 38,
374 | "metadata": {},
375 | "output_type": "execute_result"
376 | }
377 | ],
378 | "source": [
379 | "var help = new Helpers //объект класса - помощник по выводу\n",
380 | "var user = new Customer(\"Даня Ололоев\")\n",
381 | "bank.addCustomer(user)\n",
382 | "var account = new Account(bank.getAccType(\"basic\"))\n",
383 | "user.openAccount(account) \n",
384 | "var account2 = new Account(bank.getAccType(\"VIP\"))\n",
385 | "user.openAccount(account2)"
386 | ]
387 | },
388 | {
389 | "cell_type": "code",
390 | "execution_count": 39,
391 | "metadata": {
392 | "collapsed": true
393 | },
394 | "outputs": [],
395 | "source": [
396 | "account.deposit(400)\n",
397 | "account2.deposit(400)"
398 | ]
399 | },
400 | {
401 | "cell_type": "code",
402 | "execution_count": 40,
403 | "metadata": {},
404 | "outputs": [
405 | {
406 | "name": "stdout",
407 | "output_type": "stream",
408 | "text": [
409 | "name: Даня Ололоев\n",
410 | "Accounts:\n",
411 | "balance: 360.0 Type: basic\n",
412 | "Transactions:\n",
413 | "type: deposit amount: 360.0 date: Mon Jun 19 10:02:39 MSK 2017\n",
414 | "Contributions:\n",
415 | "Credits:\n",
416 | "\n",
417 | "balance: 380.0 Type: VIP\n",
418 | "Transactions:\n",
419 | "type: deposit amount: 380.0 date: Mon Jun 19 10:02:39 MSK 2017\n",
420 | "Contributions:\n",
421 | "Credits:\n",
422 | "\n"
423 | ]
424 | }
425 | ],
426 | "source": [
427 | "help.printCustomerInfo(user)"
428 | ]
429 | },
430 | {
431 | "cell_type": "code",
432 | "execution_count": 41,
433 | "metadata": {
434 | "collapsed": true
435 | },
436 | "outputs": [],
437 | "source": [
438 | "bank.block_account(account)"
439 | ]
440 | },
441 | {
442 | "cell_type": "code",
443 | "execution_count": 42,
444 | "metadata": {},
445 | "outputs": [
446 | {
447 | "name": "stdout",
448 | "output_type": "stream",
449 | "text": [
450 | "Аккаунт заблокирован, невозможно произвести операцию\n"
451 | ]
452 | }
453 | ],
454 | "source": [
455 | "account.deposit(400)"
456 | ]
457 | },
458 | {
459 | "cell_type": "code",
460 | "execution_count": 43,
461 | "metadata": {
462 | "collapsed": true
463 | },
464 | "outputs": [],
465 | "source": [
466 | "bank.unblock_account(account)"
467 | ]
468 | },
469 | {
470 | "cell_type": "code",
471 | "execution_count": 44,
472 | "metadata": {
473 | "collapsed": true
474 | },
475 | "outputs": [],
476 | "source": [
477 | "user.give_money(account, account2, 100)"
478 | ]
479 | },
480 | {
481 | "cell_type": "code",
482 | "execution_count": 45,
483 | "metadata": {},
484 | "outputs": [
485 | {
486 | "name": "stdout",
487 | "output_type": "stream",
488 | "text": [
489 | "name: Даня Ололоев\n",
490 | "Accounts:\n",
491 | "balance: 260.0 Type: basic\n",
492 | "Transactions:\n",
493 | "type: deposit amount: 360.0 date: Mon Jun 19 10:02:39 MSK 2017\n",
494 | "type: deposit amount: 360.0 date: Mon Jun 19 10:02:41 MSK 2017\n",
495 | "type: giveaway amount: -100.0 date: Mon Jun 19 10:02:42 MSK 2017\n",
496 | "Contributions:\n",
497 | "Credits:\n",
498 | "\n",
499 | "balance: 470.0 Type: VIP\n",
500 | "Transactions:\n",
501 | "type: deposit amount: 380.0 date: Mon Jun 19 10:02:39 MSK 2017\n",
502 | "type: addition amount: 90.0 date: Mon Jun 19 10:02:42 MSK 2017\n",
503 | "Contributions:\n",
504 | "Credits:\n",
505 | "\n"
506 | ]
507 | }
508 | ],
509 | "source": [
510 | "help.printCustomerInfo(user)"
511 | ]
512 | },
513 | {
514 | "cell_type": "code",
515 | "execution_count": 46,
516 | "metadata": {
517 | "collapsed": true
518 | },
519 | "outputs": [],
520 | "source": [
521 | "account2.remove_money(80)"
522 | ]
523 | },
524 | {
525 | "cell_type": "code",
526 | "execution_count": 47,
527 | "metadata": {
528 | "collapsed": true
529 | },
530 | "outputs": [],
531 | "source": [
532 | "account2.new_credit(100, 2)\n",
533 | "account2.new_contribution(100, 3)"
534 | ]
535 | },
536 | {
537 | "cell_type": "code",
538 | "execution_count": 48,
539 | "metadata": {},
540 | "outputs": [
541 | {
542 | "name": "stdout",
543 | "output_type": "stream",
544 | "text": [
545 | "name: Даня Ололоев\n",
546 | "Accounts:\n",
547 | "balance: 260.0 Type: basic\n",
548 | "Transactions:\n",
549 | "type: deposit amount: 360.0 date: Mon Jun 19 10:02:39 MSK 2017\n",
550 | "type: deposit amount: 360.0 date: Mon Jun 19 10:02:41 MSK 2017\n",
551 | "type: giveaway amount: -100.0 date: Mon Jun 19 10:02:42 MSK 2017\n",
552 | "Contributions:\n",
553 | "Credits:\n",
554 | "\n",
555 | "balance: 390.0 Type: VIP\n",
556 | "Transactions:\n",
557 | "type: deposit amount: 380.0 date: Mon Jun 19 10:02:39 MSK 2017\n",
558 | "type: addition amount: 90.0 date: Mon Jun 19 10:02:42 MSK 2017\n",
559 | "type: windraw amount: -80.0 date: Mon Jun 19 10:02:43 MSK 2017\n",
560 | "type: credit amount: 100.0 date: Mon Jun 19 10:02:43 MSK 2017\n",
561 | "type: contribution amount: -100.0 date: Mon Jun 19 10:02:43 MSK 2017\n",
562 | "Contributions:\n",
563 | "amount: 100.0 years: 3 start date: Mon Jun 19 10:02:43 MSK 2017 percent: 1.2\n",
564 | "Credits:\n",
565 | "amount: 100.0 months: 24 start date: Mon Jun 19 10:02:43 MSK 2017 percent: 1.1\n",
566 | "\n"
567 | ]
568 | }
569 | ],
570 | "source": [
571 | "help.printCustomerInfo(user)"
572 | ]
573 | },
574 | {
575 | "cell_type": "code",
576 | "execution_count": 49,
577 | "metadata": {},
578 | "outputs": [],
579 | "source": [
580 | "bank.pay_for_credit(account2.credits(0)) //сразу отдаем весь долг по кредиту\n",
581 | "bank.get_contribution_back(account2.contributions(0)) //забираем деньги из вклада"
582 | ]
583 | },
584 | {
585 | "cell_type": "code",
586 | "execution_count": 50,
587 | "metadata": {
588 | "scrolled": false
589 | },
590 | "outputs": [
591 | {
592 | "name": "stdout",
593 | "output_type": "stream",
594 | "text": [
595 | "name: Даня Ололоев\n",
596 | "Accounts:\n",
597 | "balance: 260.0 Type: basic\n",
598 | "Transactions:\n",
599 | "type: deposit amount: 360.0 date: Mon Jun 19 10:02:39 MSK 2017\n",
600 | "type: deposit amount: 360.0 date: Mon Jun 19 10:02:41 MSK 2017\n",
601 | "type: giveaway amount: -100.0 date: Mon Jun 19 10:02:42 MSK 2017\n",
602 | "Contributions:\n",
603 | "Credits:\n",
604 | "\n",
605 | "balance: 380.0 Type: VIP\n",
606 | "Transactions:\n",
607 | "type: deposit amount: 380.0 date: Mon Jun 19 10:02:39 MSK 2017\n",
608 | "type: addition amount: 90.0 date: Mon Jun 19 10:02:42 MSK 2017\n",
609 | "type: windraw amount: -80.0 date: Mon Jun 19 10:02:43 MSK 2017\n",
610 | "type: credit amount: 100.0 date: Mon Jun 19 10:02:43 MSK 2017\n",
611 | "type: contribution amount: -100.0 date: Mon Jun 19 10:02:43 MSK 2017\n",
612 | "type: credit pay amount: -110.00000000000001 date: Mon Jun 19 10:02:44 MSK 2017\n",
613 | "type: from contribution amount: 100.0 date: Mon Jun 19 10:02:44 MSK 2017\n",
614 | "Contributions:\n",
615 | "Credits:\n",
616 | "\n"
617 | ]
618 | }
619 | ],
620 | "source": [
621 | "help.printCustomerInfo(user)"
622 | ]
623 | },
624 | {
625 | "cell_type": "code",
626 | "execution_count": 51,
627 | "metadata": {
628 | "collapsed": true
629 | },
630 | "outputs": [],
631 | "source": [
632 | "account2.new_credit(100, 2)\n",
633 | "account2.new_contribution(100, 3)"
634 | ]
635 | },
636 | {
637 | "cell_type": "code",
638 | "execution_count": 52,
639 | "metadata": {},
640 | "outputs": [
641 | {
642 | "name": "stdout",
643 | "output_type": "stream",
644 | "text": [
645 | "credits\n",
646 | "amount: 100.0 months: 24 start date: Mon Jun 19 10:02:45 MSK 2017 percent: 1.1\n",
647 | "Прошел месяц....\n",
648 | "credits\n",
649 | "amount: 100.0 months: 23 start date: Mon Jun 19 10:02:45 MSK 2017 percent: 1.1\n",
650 | "Прошел месяц....\n",
651 | "credits\n",
652 | "amount: 100.0 months: 22 start date: Mon Jun 19 10:02:45 MSK 2017 percent: 1.1\n",
653 | "Прошел месяц....\n",
654 | "credits\n",
655 | "amount: 100.0 months: 21 start date: Mon Jun 19 10:02:45 MSK 2017 percent: 1.1\n",
656 | "Прошел месяц....\n",
657 | "credits\n",
658 | "amount: 100.0 months: 20 start date: Mon Jun 19 10:02:45 MSK 2017 percent: 1.1\n",
659 | "Прошел месяц....\n",
660 | "credits\n",
661 | "amount: 100.0 months: 19 start date: Mon Jun 19 10:02:45 MSK 2017 percent: 1.1\n",
662 | "Прошел месяц....\n",
663 | "credits\n",
664 | "amount: 100.0 months: 18 start date: Mon Jun 19 10:02:45 MSK 2017 percent: 1.1\n",
665 | "Прошел месяц....\n",
666 | "credits\n",
667 | "amount: 100.0 months: 17 start date: Mon Jun 19 10:02:45 MSK 2017 percent: 1.1\n",
668 | "Прошел месяц....\n",
669 | "credits\n",
670 | "amount: 100.0 months: 16 start date: Mon Jun 19 10:02:45 MSK 2017 percent: 1.1\n",
671 | "Прошел месяц....\n",
672 | "credits\n",
673 | "amount: 100.0 months: 15 start date: Mon Jun 19 10:02:45 MSK 2017 percent: 1.1\n",
674 | "Прошел месяц....\n",
675 | "credits\n",
676 | "amount: 100.0 months: 14 start date: Mon Jun 19 10:02:45 MSK 2017 percent: 1.1\n",
677 | "Прошел месяц....\n",
678 | "Contrbutions\n",
679 | "amount: 100.0 years: 3 start date: Mon Jun 19 10:02:45 MSK 2017 percent: 1.2\n",
680 | "credits\n",
681 | "amount: 100.0 months: 13 start date: Mon Jun 19 10:02:45 MSK 2017 percent: 1.1\n",
682 | "Прошел месяц....\n",
683 | "credits\n",
684 | "amount: 100.0 months: 12 start date: Mon Jun 19 10:02:45 MSK 2017 percent: 1.1\n",
685 | "Прошел месяц....\n",
686 | "credits\n",
687 | "amount: 100.0 months: 11 start date: Mon Jun 19 10:02:45 MSK 2017 percent: 1.1\n",
688 | "Прошел месяц....\n",
689 | "credits\n",
690 | "amount: 100.0 months: 10 start date: Mon Jun 19 10:02:45 MSK 2017 percent: 1.1\n",
691 | "Прошел месяц....\n",
692 | "credits\n",
693 | "amount: 100.0 months: 9 start date: Mon Jun 19 10:02:45 MSK 2017 percent: 1.1\n",
694 | "Прошел месяц....\n",
695 | "credits\n",
696 | "amount: 100.0 months: 8 start date: Mon Jun 19 10:02:45 MSK 2017 percent: 1.1\n",
697 | "Прошел месяц....\n",
698 | "credits\n",
699 | "amount: 100.0 months: 7 start date: Mon Jun 19 10:02:45 MSK 2017 percent: 1.1\n",
700 | "Прошел месяц....\n",
701 | "credits\n",
702 | "amount: 100.0 months: 6 start date: Mon Jun 19 10:02:45 MSK 2017 percent: 1.1\n",
703 | "Прошел месяц....\n",
704 | "credits\n",
705 | "amount: 100.0 months: 5 start date: Mon Jun 19 10:02:45 MSK 2017 percent: 1.1\n",
706 | "Прошел месяц....\n",
707 | "credits\n",
708 | "amount: 100.0 months: 4 start date: Mon Jun 19 10:02:45 MSK 2017 percent: 1.1\n",
709 | "Прошел месяц....\n",
710 | "credits\n",
711 | "amount: 100.0 months: 3 start date: Mon Jun 19 10:02:45 MSK 2017 percent: 1.1\n",
712 | "Прошел месяц....\n",
713 | "credits\n",
714 | "amount: 100.0 months: 2 start date: Mon Jun 19 10:02:45 MSK 2017 percent: 1.1\n",
715 | "Прошел месяц....\n",
716 | "Contrbutions\n",
717 | "amount: 120.0 years: 2 start date: Mon Jun 19 10:02:45 MSK 2017 percent: 1.2\n",
718 | "credits\n",
719 | "amount: 100.0 months: 1 start date: Mon Jun 19 10:02:45 MSK 2017 percent: 1.1\n",
720 | "Прошел месяц....\n",
721 | "credits\n",
722 | "amount: 100.0 months: 0 start date: Mon Jun 19 10:02:45 MSK 2017 percent: 1.1\n",
723 | "Прошел месяц....\n",
724 | "Прошел месяц....\n",
725 | "Прошел месяц....\n",
726 | "Прошел месяц....\n",
727 | "Прошел месяц....\n",
728 | "Прошел месяц....\n",
729 | "Прошел месяц....\n",
730 | "Прошел месяц....\n",
731 | "Прошел месяц....\n",
732 | "Прошел месяц....\n",
733 | "Прошел месяц....\n",
734 | "Contrbutions\n",
735 | "amount: 144.0 years: 1 start date: Mon Jun 19 10:02:45 MSK 2017 percent: 1.2\n",
736 | "Прошел месяц....\n",
737 | "Прошел месяц....\n",
738 | "Прошел месяц....\n",
739 | "Прошел месяц....\n",
740 | "Прошел месяц....\n",
741 | "Прошел месяц....\n",
742 | "Прошел месяц....\n",
743 | "Прошел месяц....\n",
744 | "Прошел месяц....\n",
745 | "Прошел месяц....\n",
746 | "Прошел месяц....\n",
747 | "Прошел месяц....\n",
748 | "Contrbutions\n",
749 | "amount: 172.79999999999998 years: 0 start date: Mon Jun 19 10:02:45 MSK 2017 percent: 1.2\n",
750 | "Прошел месяц....\n"
751 | ]
752 | }
753 | ],
754 | "source": [
755 | "bank.work //симулятор работы банка\n",
756 | " //кредит отдаётся каждый месяц (сумма зависит от суммы кредита, процентной ставки и срока)\n",
757 | " //вклад пополняется каждый год, начисление на счет происходит только после закрытия вклада"
758 | ]
759 | },
760 | {
761 | "cell_type": "code",
762 | "execution_count": 53,
763 | "metadata": {},
764 | "outputs": [
765 | {
766 | "name": "stdout",
767 | "output_type": "stream",
768 | "text": [
769 | "name: Даня Ололоев\n",
770 | "Accounts:\n",
771 | "balance: 260.0 Type: basic\n",
772 | "Transactions:\n",
773 | "type: deposit amount: 360.0 date: Mon Jun 19 10:02:39 MSK 2017\n",
774 | "type: deposit amount: 360.0 date: Mon Jun 19 10:02:41 MSK 2017\n",
775 | "type: giveaway amount: -100.0 date: Mon Jun 19 10:02:42 MSK 2017\n",
776 | "Contributions:\n",
777 | "Credits:\n",
778 | "\n",
779 | "balance: 442.8000000000004 Type: VIP\n",
780 | "Transactions:\n",
781 | "type: deposit amount: 380.0 date: Mon Jun 19 10:02:39 MSK 2017\n",
782 | "type: addition amount: 90.0 date: Mon Jun 19 10:02:42 MSK 2017\n",
783 | "type: windraw amount: -80.0 date: Mon Jun 19 10:02:43 MSK 2017\n",
784 | "type: credit amount: 100.0 date: Mon Jun 19 10:02:43 MSK 2017\n",
785 | "type: contribution amount: -100.0 date: Mon Jun 19 10:02:43 MSK 2017\n",
786 | "type: credit pay amount: -110.00000000000001 date: Mon Jun 19 10:02:44 MSK 2017\n",
787 | "type: from contribution amount: 100.0 date: Mon Jun 19 10:02:44 MSK 2017\n",
788 | "type: credit amount: 100.0 date: Mon Jun 19 10:02:44 MSK 2017\n",
789 | "type: contribution amount: -100.0 date: Mon Jun 19 10:02:44 MSK 2017\n",
790 | "type: credit pay amount: -4.583333333333334 date: Mon Jun 19 10:02:45 MSK 2017\n",
791 | "type: credit pay amount: -4.583333333333334 date: Mon Jun 19 10:02:46 MSK 2017\n",
792 | "type: credit pay amount: -4.583333333333334 date: Mon Jun 19 10:02:47 MSK 2017\n",
793 | "type: credit pay amount: -4.583333333333334 date: Mon Jun 19 10:02:48 MSK 2017\n",
794 | "type: credit pay amount: -4.583333333333334 date: Mon Jun 19 10:02:49 MSK 2017\n",
795 | "type: credit pay amount: -4.583333333333334 date: Mon Jun 19 10:02:50 MSK 2017\n",
796 | "type: credit pay amount: -4.583333333333334 date: Mon Jun 19 10:02:51 MSK 2017\n",
797 | "type: credit pay amount: -4.583333333333334 date: Mon Jun 19 10:02:52 MSK 2017\n",
798 | "type: credit pay amount: -4.583333333333334 date: Mon Jun 19 10:02:53 MSK 2017\n",
799 | "type: credit pay amount: -4.583333333333334 date: Mon Jun 19 10:02:54 MSK 2017\n",
800 | "type: credit pay amount: -4.583333333333334 date: Mon Jun 19 10:02:55 MSK 2017\n",
801 | "type: credit pay amount: -4.583333333333334 date: Mon Jun 19 10:02:56 MSK 2017\n",
802 | "type: credit pay amount: -4.583333333333334 date: Mon Jun 19 10:02:57 MSK 2017\n",
803 | "type: credit pay amount: -4.583333333333334 date: Mon Jun 19 10:02:58 MSK 2017\n",
804 | "type: credit pay amount: -4.583333333333334 date: Mon Jun 19 10:02:59 MSK 2017\n",
805 | "type: credit pay amount: -4.583333333333334 date: Mon Jun 19 10:03:00 MSK 2017\n",
806 | "type: credit pay amount: -4.583333333333334 date: Mon Jun 19 10:03:01 MSK 2017\n",
807 | "type: credit pay amount: -4.583333333333334 date: Mon Jun 19 10:03:02 MSK 2017\n",
808 | "type: credit pay amount: -4.583333333333334 date: Mon Jun 19 10:03:03 MSK 2017\n",
809 | "type: credit pay amount: -4.583333333333334 date: Mon Jun 19 10:03:04 MSK 2017\n",
810 | "type: credit pay amount: -4.583333333333334 date: Mon Jun 19 10:03:05 MSK 2017\n",
811 | "type: credit pay amount: -4.583333333333334 date: Mon Jun 19 10:03:06 MSK 2017\n",
812 | "type: credit pay amount: -4.583333333333334 date: Mon Jun 19 10:03:07 MSK 2017\n",
813 | "type: credit pay amount: -4.583333333333334 date: Mon Jun 19 10:03:08 MSK 2017\n",
814 | "type: from contribution amount: 172.79999999999998 date: Mon Jun 19 10:03:32 MSK 2017\n",
815 | "Contributions:\n",
816 | "Credits:\n",
817 | "\n"
818 | ]
819 | }
820 | ],
821 | "source": [
822 | "help.printCustomerInfo(user)"
823 | ]
824 | },
825 | {
826 | "cell_type": "code",
827 | "execution_count": 54,
828 | "metadata": {},
829 | "outputs": [
830 | {
831 | "data": {
832 | "text/plain": [
833 | "\u001b[36mres53\u001b[39m: \u001b[32mListBuffer\u001b[39m[\u001b[32mAccount\u001b[39m] = \u001b[33mListBuffer\u001b[39m($sess.cmd35Wrapper$Helper$Account@492f6796)"
834 | ]
835 | },
836 | "execution_count": 54,
837 | "metadata": {},
838 | "output_type": "execute_result"
839 | }
840 | ],
841 | "source": [
842 | "user.delete_account(account2)"
843 | ]
844 | },
845 | {
846 | "cell_type": "code",
847 | "execution_count": 55,
848 | "metadata": {},
849 | "outputs": [
850 | {
851 | "name": "stdout",
852 | "output_type": "stream",
853 | "text": [
854 | "name: Даня Ололоев\n",
855 | "Accounts:\n",
856 | "balance: 260.0 Type: basic\n",
857 | "Transactions:\n",
858 | "type: deposit amount: 360.0 date: Mon Jun 19 10:02:39 MSK 2017\n",
859 | "type: deposit amount: 360.0 date: Mon Jun 19 10:02:41 MSK 2017\n",
860 | "type: giveaway amount: -100.0 date: Mon Jun 19 10:02:42 MSK 2017\n",
861 | "Contributions:\n",
862 | "Credits:\n",
863 | "\n"
864 | ]
865 | }
866 | ],
867 | "source": [
868 | "help.printCustomerInfo(user)"
869 | ]
870 | },
871 | {
872 | "cell_type": "code",
873 | "execution_count": 56,
874 | "metadata": {},
875 | "outputs": [
876 | {
877 | "data": {
878 | "text/plain": [
879 | "\u001b[36mres55\u001b[39m: \u001b[32mListBuffer\u001b[39m[\u001b[32mCustomer\u001b[39m] = \u001b[33mListBuffer\u001b[39m($sess.cmd35Wrapper$Helper$Customer@437163f2)"
880 | ]
881 | },
882 | "execution_count": 56,
883 | "metadata": {},
884 | "output_type": "execute_result"
885 | }
886 | ],
887 | "source": [
888 | "bank.getAllUsers()//API банка, через user-ов можно получить их счета и переводить на них деньги"
889 | ]
890 | },
891 | {
892 | "cell_type": "code",
893 | "execution_count": null,
894 | "metadata": {
895 | "collapsed": true
896 | },
897 | "outputs": [],
898 | "source": []
899 | },
900 | {
901 | "cell_type": "code",
902 | "execution_count": null,
903 | "metadata": {
904 | "collapsed": true
905 | },
906 | "outputs": [],
907 | "source": []
908 | }
909 | ],
910 | "metadata": {
911 | "kernelspec": {
912 | "display_name": "Scala",
913 | "language": "scala",
914 | "name": "scala"
915 | },
916 | "language_info": {
917 | "codemirror_mode": "text/x-scala",
918 | "file_extension": ".scala",
919 | "mimetype": "text/x-scala",
920 | "name": "scala211",
921 | "nbconvert_exporter": "script",
922 | "pygments_lexer": "scala",
923 | "version": "2.11.11"
924 | }
925 | },
926 | "nbformat": 4,
927 | "nbformat_minor": 2
928 | }
929 |
--------------------------------------------------------------------------------