Ecoer Logo

@sarven

37

Software developer, blogger

steemit.com/@sarven
VOTING POWER100.00%
DOWNVOTE POWER100.00%
RESOURCE CREDITS100.00%
REPUTATION PROGRESS93.02%
Net Worth
1.213USD
STEEM
0.000STEEM
SBD
2.575SBD
Effective Power
5.007SP
├── Own SP
1.996SP
└── Incoming Deleg
+3.011SP

Detailed Balance

STEEM
balance
0.000STEEM
market_balance
0.000STEEM
savings_balance
0.000STEEM
reward_steem_balance
0.000STEEM
STEEM POWER
Own SP
1.996SP
Delegated Out
0.000SP
Delegation In
3.011SP
Effective Power
5.007SP
Reward SP (pending)
0.000SP
SBD
sbd_balance
2.575SBD
sbd_conversions
0.000SBD
sbd_market_balance
0.000SBD
savings_sbd_balance
0.000SBD
reward_sbd_balance
0.000SBD
{
  "balance": "0.000 STEEM",
  "savings_balance": "0.000 STEEM",
  "reward_steem_balance": "0.000 STEEM",
  "vesting_shares": "3246.252150 VESTS",
  "delegated_vesting_shares": "0.000000 VESTS",
  "received_vesting_shares": "4897.407656 VESTS",
  "sbd_balance": "2.575 SBD",
  "savings_sbd_balance": "0.000 SBD",
  "reward_sbd_balance": "0.000 SBD",
  "conversions": []
}

Account Info

namesarven
id484902
rank1,274,921
reputation21163185908
created2017-12-09T11:49:33
recovery_accountsteem
proxyNone
post_count10
comment_count0
lifetime_vote_count0
witnesses_voted_for0
last_post2018-01-11T21:26:09
last_root_post2018-01-11T21:26:09
last_vote_time2018-01-07T19:45:45
proxied_vsf_votes0, 0, 0, 0
can_vote1
voting_power0
delayed_votes0
balance0.000 STEEM
savings_balance0.000 STEEM
sbd_balance2.575 SBD
savings_sbd_balance0.000 SBD
vesting_shares3246.252150 VESTS
delegated_vesting_shares0.000000 VESTS
received_vesting_shares4897.407656 VESTS
reward_vesting_balance0.000000 VESTS
vesting_balance0.000 STEEM
vesting_withdraw_rate0.000000 VESTS
next_vesting_withdrawal1969-12-31T23:59:59
withdrawn0
to_withdraw0
withdraw_routes0
savings_withdraw_requests0
last_account_recovery1970-01-01T00:00:00
reset_accountnull
last_owner_update1970-01-01T00:00:00
last_account_update2017-12-09T12:09:09
minedNo
sbd_seconds2,439,124,779
sbd_last_interest_payment2018-01-11T21:00:30
savings_sbd_last_interest_payment1970-01-01T00:00:00
{
  "active": {
    "account_auths": [],
    "key_auths": [
      [
        "STM4xmenqUjxALSuRvqAZ4XBqksGv5Lx5xug4RZDFjeRjoFHBfDir",
        1
      ]
    ],
    "weight_threshold": 1
  },
  "balance": "0.000 STEEM",
  "can_vote": true,
  "comment_count": 0,
  "created": "2017-12-09T11:49:33",
  "curation_rewards": 1,
  "delegated_vesting_shares": "0.000000 VESTS",
  "downvote_manabar": {
    "current_mana": 2035914951,
    "last_update_time": 1779084669
  },
  "guest_bloggers": [],
  "id": 484902,
  "json_metadata": "{\"profile\":{\"profile_image\":\"https://www.wykop.pl/cdn/c3397992/sarveniusz_rzbNo7SvZk,q150.jpg\",\"name\":\"sarven\",\"about\":\"Software developer, blogger\",\"location\":\"Poland\",\"website\":\"https://sarvendev.com\"}}",
  "last_account_recovery": "1970-01-01T00:00:00",
  "last_account_update": "2017-12-09T12:09:09",
  "last_owner_update": "1970-01-01T00:00:00",
  "last_post": "2018-01-11T21:26:09",
  "last_root_post": "2018-01-11T21:26:09",
  "last_vote_time": "2018-01-07T19:45:45",
  "lifetime_vote_count": 0,
  "market_history": [],
  "memo_key": "STM7n3WAf3w5d2UnGv5YCvS9nEKLZSfBYsM7R33VmjdWEF12CdkZ3",
  "mined": false,
  "name": "sarven",
  "next_vesting_withdrawal": "1969-12-31T23:59:59",
  "other_history": [],
  "owner": {
    "account_auths": [],
    "key_auths": [
      [
        "STM7YZykm7TzMCDtY41f7AxVo5pNfkQxbni1coS7UX1SrEZ84rhU9",
        1
      ]
    ],
    "weight_threshold": 1
  },
  "pending_claimed_accounts": 0,
  "post_bandwidth": 0,
  "post_count": 10,
  "post_history": [],
  "posting": {
    "account_auths": [],
    "key_auths": [
      [
        "STM66dMQCrS7ErbuSLgxxNChpMmf74k4EUTrahs97ePF1S6kde26n",
        1
      ]
    ],
    "weight_threshold": 1
  },
  "posting_json_metadata": "{\"profile\":{\"profile_image\":\"https://www.wykop.pl/cdn/c3397992/sarveniusz_rzbNo7SvZk,q150.jpg\",\"name\":\"sarven\",\"about\":\"Software developer, blogger\",\"location\":\"Poland\",\"website\":\"https://sarvendev.com\"}}",
  "posting_rewards": 2160,
  "proxied_vsf_votes": [
    0,
    0,
    0,
    0
  ],
  "proxy": "",
  "received_vesting_shares": "4897.407656 VESTS",
  "recovery_account": "steem",
  "reputation": "21163185908",
  "reset_account": "null",
  "reward_sbd_balance": "0.000 SBD",
  "reward_steem_balance": "0.000 STEEM",
  "reward_vesting_balance": "0.000000 VESTS",
  "reward_vesting_steem": "0.000 STEEM",
  "savings_balance": "0.000 STEEM",
  "savings_sbd_balance": "0.000 SBD",
  "savings_sbd_last_interest_payment": "1970-01-01T00:00:00",
  "savings_sbd_seconds": "0",
  "savings_sbd_seconds_last_update": "1970-01-01T00:00:00",
  "savings_withdraw_requests": 0,
  "sbd_balance": "2.575 SBD",
  "sbd_last_interest_payment": "2018-01-11T21:00:30",
  "sbd_seconds": "2439124779",
  "sbd_seconds_last_update": "2018-01-23T10:00:09",
  "tags_usage": [],
  "to_withdraw": 0,
  "transfer_history": [],
  "vesting_balance": "0.000 STEEM",
  "vesting_shares": "3246.252150 VESTS",
  "vesting_withdraw_rate": "0.000000 VESTS",
  "vote_history": [],
  "voting_manabar": {
    "current_mana": "8143659806",
    "last_update_time": 1779084669
  },
  "voting_power": 0,
  "withdraw_routes": 0,
  "withdrawn": 0,
  "witness_votes": [],
  "witnesses_voted_for": 0,
  "rank": 1274921
}

Withdraw Routes

IncomingOutgoing
Empty
Empty
{
  "incoming": [],
  "outgoing": []
}
From Date
To Date
steemdelegated 3.011 SP to @sarven
2026/05/18 06:11:09
delegatorsteem
delegateesarven
vesting shares4897.407656 VESTS
Transaction InfoBlock #106150536/Trx bc913168be0836714fee5f924afe1854a8c71725
View Raw JSON Data
{
  "trx_id": "bc913168be0836714fee5f924afe1854a8c71725",
  "block": 106150536,
  "trx_in_block": 0,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2026-05-18T06:11:09",
  "op": [
    "delegate_vesting_shares",
    {
      "delegator": "steem",
      "delegatee": "sarven",
      "vesting_shares": "4897.407656 VESTS"
    }
  ]
}
steemdelegated 1.344 SP to @sarven
2026/05/13 03:59:00
delegatorsteem
delegateesarven
vesting shares2185.197251 VESTS
Transaction InfoBlock #106004615/Trx 2e930962252e9e8af224afb4156adc8c0f8d0943
View Raw JSON Data
{
  "trx_id": "2e930962252e9e8af224afb4156adc8c0f8d0943",
  "block": 106004615,
  "trx_in_block": 0,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2026-05-13T03:59:00",
  "op": [
    "delegate_vesting_shares",
    {
      "delegator": "steem",
      "delegatee": "sarven",
      "vesting_shares": "2185.197251 VESTS"
    }
  ]
}
steemdelegated 3.019 SP to @sarven
2026/04/26 05:23:00
delegatorsteem
delegateesarven
vesting shares4909.923412 VESTS
Transaction InfoBlock #105518022/Trx e7f0893072823fde9d9008560a3b78c5f79de6b7
View Raw JSON Data
{
  "trx_id": "e7f0893072823fde9d9008560a3b78c5f79de6b7",
  "block": 105518022,
  "trx_in_block": 0,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2026-04-26T05:23:00",
  "op": [
    "delegate_vesting_shares",
    {
      "delegator": "steem",
      "delegatee": "sarven",
      "vesting_shares": "4909.923412 VESTS"
    }
  ]
}
steemdelegated 1.369 SP to @sarven
2026/01/23 23:47:21
delegatorsteem
delegateesarven
vesting shares2226.744070 VESTS
Transaction InfoBlock #102870963/Trx 10e3cb79fd9baebb2afcd278c234ecb7a4fcd5fc
View Raw JSON Data
{
  "trx_id": "10e3cb79fd9baebb2afcd278c234ecb7a4fcd5fc",
  "block": 102870963,
  "trx_in_block": 3,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2026-01-23T23:47:21",
  "op": [
    "delegate_vesting_shares",
    {
      "delegator": "steem",
      "delegatee": "sarven",
      "vesting_shares": "2226.744070 VESTS"
    }
  ]
}
steemdelegated 1.470 SP to @sarven
2024/12/17 18:57:03
delegatorsteem
delegateesarven
vesting shares2390.963267 VESTS
Transaction InfoBlock #91317170/Trx 0fbf290b9a394040b29d63288388802d07723fa4
View Raw JSON Data
{
  "trx_id": "0fbf290b9a394040b29d63288388802d07723fa4",
  "block": 91317170,
  "trx_in_block": 6,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2024-12-17T18:57:03",
  "op": [
    "delegate_vesting_shares",
    {
      "delegator": "steem",
      "delegatee": "sarven",
      "vesting_shares": "2390.963267 VESTS"
    }
  ]
}
steemdelegated 1.574 SP to @sarven
2023/11/14 10:38:39
delegatorsteem
delegateesarven
vesting shares2560.096799 VESTS
Transaction InfoBlock #79871331/Trx 3523dd222dbd912df450e14e144556073739b94e
View Raw JSON Data
{
  "trx_id": "3523dd222dbd912df450e14e144556073739b94e",
  "block": 79871331,
  "trx_in_block": 2,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2023-11-14T10:38:39",
  "op": [
    "delegate_vesting_shares",
    {
      "delegator": "steem",
      "delegatee": "sarven",
      "vesting_shares": "2560.096799 VESTS"
    }
  ]
}
steemdelegated 3.380 SP to @sarven
2023/09/22 10:16:57
delegatorsteem
delegateesarven
vesting shares5497.005585 VESTS
Transaction InfoBlock #78362734/Trx a072ceb07d39ab7ce21ff81bab251bb7d06c9f30
View Raw JSON Data
{
  "trx_id": "a072ceb07d39ab7ce21ff81bab251bb7d06c9f30",
  "block": 78362734,
  "trx_in_block": 2,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2023-09-22T10:16:57",
  "op": [
    "delegate_vesting_shares",
    {
      "delegator": "steem",
      "delegatee": "sarven",
      "vesting_shares": "5497.005585 VESTS"
    }
  ]
}
steemdelegated 3.516 SP to @sarven
2022/11/03 17:45:06
delegatorsteem
delegateesarven
vesting shares5719.057023 VESTS
Transaction InfoBlock #69120485/Trx 2381491b029e9c46737636dbd153377ff9d4125e
View Raw JSON Data
{
  "trx_id": "2381491b029e9c46737636dbd153377ff9d4125e",
  "block": 69120485,
  "trx_in_block": 0,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2022-11-03T17:45:06",
  "op": [
    "delegate_vesting_shares",
    {
      "delegator": "steem",
      "delegatee": "sarven",
      "vesting_shares": "5719.057023 VESTS"
    }
  ]
}
steemdelegated 3.652 SP to @sarven
2022/01/17 22:57:15
delegatorsteem
delegateesarven
vesting shares5939.164624 VESTS
Transaction InfoBlock #60823738/Trx 59a9496133fbbc06d318b5b4412c6f8856db77fa
View Raw JSON Data
{
  "trx_id": "59a9496133fbbc06d318b5b4412c6f8856db77fa",
  "block": 60823738,
  "trx_in_block": 32,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2022-01-17T22:57:15",
  "op": [
    "delegate_vesting_shares",
    {
      "delegator": "steem",
      "delegatee": "sarven",
      "vesting_shares": "5939.164624 VESTS"
    }
  ]
}
steemdelegated 3.765 SP to @sarven
2021/06/14 06:08:33
delegatorsteem
delegateesarven
vesting shares6123.358912 VESTS
Transaction InfoBlock #54614071/Trx e1af5bd4511c74d4514f5ddb0e01ac292f47b611
View Raw JSON Data
{
  "trx_id": "e1af5bd4511c74d4514f5ddb0e01ac292f47b611",
  "block": 54614071,
  "trx_in_block": 4,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2021-06-14T06:08:33",
  "op": [
    "delegate_vesting_shares",
    {
      "delegator": "steem",
      "delegatee": "sarven",
      "vesting_shares": "6123.358912 VESTS"
    }
  ]
}
steemdelegated 3.880 SP to @sarven
2020/12/11 16:20:57
delegatorsteem
delegateesarven
vesting shares6310.780886 VESTS
Transaction InfoBlock #49361339/Trx 0208c05d0f2e6b87de720e17dc7db19b3fdea135
View Raw JSON Data
{
  "trx_id": "0208c05d0f2e6b87de720e17dc7db19b3fdea135",
  "block": 49361339,
  "trx_in_block": 3,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2020-12-11T16:20:57",
  "op": [
    "delegate_vesting_shares",
    {
      "delegator": "steem",
      "delegatee": "sarven",
      "vesting_shares": "6310.780886 VESTS"
    }
  ]
}
steemdelegated 1.176 SP to @sarven
2020/12/06 09:56:39
delegatorsteem
delegateesarven
vesting shares1912.543513 VESTS
Transaction InfoBlock #49212862/Trx a4dbfbdcc9378a3fe4aed40bbb18b8fe61999618
View Raw JSON Data
{
  "trx_id": "a4dbfbdcc9378a3fe4aed40bbb18b8fe61999618",
  "block": 49212862,
  "trx_in_block": 7,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2020-12-06T09:56:39",
  "op": [
    "delegate_vesting_shares",
    {
      "delegator": "steem",
      "delegatee": "sarven",
      "vesting_shares": "1912.543513 VESTS"
    }
  ]
}
steemdelegated 3.884 SP to @sarven
2020/12/05 19:58:39
delegatorsteem
delegateesarven
vesting shares6316.988740 VESTS
Transaction InfoBlock #49196420/Trx f4eaf06d02fdedabb51de6e977119e6519f3878b
View Raw JSON Data
{
  "trx_id": "f4eaf06d02fdedabb51de6e977119e6519f3878b",
  "block": 49196420,
  "trx_in_block": 1,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2020-12-05T19:58:39",
  "op": [
    "delegate_vesting_shares",
    {
      "delegator": "steem",
      "delegatee": "sarven",
      "vesting_shares": "6316.988740 VESTS"
    }
  ]
}
steemdelegated 1.181 SP to @sarven
2020/11/03 02:28:51
delegatorsteem
delegateesarven
vesting shares1920.017158 VESTS
Transaction InfoBlock #48270567/Trx e2a348b60389b713fa62b3eecbc9d5b896290874
View Raw JSON Data
{
  "trx_id": "e2a348b60389b713fa62b3eecbc9d5b896290874",
  "block": 48270567,
  "trx_in_block": 0,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2020-11-03T02:28:51",
  "op": [
    "delegate_vesting_shares",
    {
      "delegator": "steem",
      "delegatee": "sarven",
      "vesting_shares": "1920.017158 VESTS"
    }
  ]
}
steemdelegated 4.009 SP to @sarven
2020/05/09 10:59:33
delegatorsteem
delegateesarven
vesting shares6519.794099 VESTS
Transaction InfoBlock #43223185/Trx 81faf95b0c7d8a18b773898780f6480a47b330db
View Raw JSON Data
{
  "trx_id": "81faf95b0c7d8a18b773898780f6480a47b330db",
  "block": 43223185,
  "trx_in_block": 12,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2020-05-09T10:59:33",
  "op": [
    "delegate_vesting_shares",
    {
      "delegator": "steem",
      "delegatee": "sarven",
      "vesting_shares": "6519.794099 VESTS"
    }
  ]
}
steemdelegated 1.201 SP to @sarven
2020/05/08 15:22:57
delegatorsteem
delegateesarven
vesting shares1953.311140 VESTS
Transaction InfoBlock #43200213/Trx 98cc2b9389b7b3ea02284df759eac69bfd78d5eb
View Raw JSON Data
{
  "trx_id": "98cc2b9389b7b3ea02284df759eac69bfd78d5eb",
  "block": 43200213,
  "trx_in_block": 12,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2020-05-08T15:22:57",
  "op": [
    "delegate_vesting_shares",
    {
      "delegator": "steem",
      "delegatee": "sarven",
      "vesting_shares": "1953.311140 VESTS"
    }
  ]
}
steemdelegated 4.017 SP to @sarven
2020/04/16 03:12:54
delegatorsteem
delegateesarven
vesting shares6532.681547 VESTS
Transaction InfoBlock #42569060/Trx 9d8bf6a09adcf08cd86c3dffd0c967bf8c0fae34
View Raw JSON Data
{
  "trx_id": "9d8bf6a09adcf08cd86c3dffd0c967bf8c0fae34",
  "block": 42569060,
  "trx_in_block": 14,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2020-04-16T03:12:54",
  "op": [
    "delegate_vesting_shares",
    {
      "delegator": "steem",
      "delegatee": "sarven",
      "vesting_shares": "6532.681547 VESTS"
    }
  ]
}
2019/12/09 13:09:48
parent authorsarven
parent permlinktworzenie-tla-z-poruszajacymi-sie-czasteczkami
authorsteemitboard
permlinksteemitboard-notify-sarven-20191209t130948000z
title
bodyCongratulations @sarven! You received a personal award! <table><tr><td>https://steemitimages.com/70x70/http://steemitboard.com/@sarven/birthday2.png</td><td>Happy Birthday! - You are on the Steem blockchain for 2 years!</td></tr></table> <sub>_You can view [your badges on your Steem Board](https://steemitboard.com/@sarven) and compare to others on the [Steem Ranking](https://steemitboard.com/ranking/index.php?name=sarven)_</sub> ###### [Vote for @Steemitboard as a witness](https://v2.steemconnect.com/sign/account-witness-vote?witness=steemitboard&approve=1) to get one more award and increased upvotes!
json metadata{"image":["https://steemitboard.com/img/notify.png"]}
Transaction InfoBlock #38886899/Trx 477a27c3b9f2a5d053f1990bfa5e61b1c2bb2ebc
View Raw JSON Data
{
  "trx_id": "477a27c3b9f2a5d053f1990bfa5e61b1c2bb2ebc",
  "block": 38886899,
  "trx_in_block": 7,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2019-12-09T13:09:48",
  "op": [
    "comment",
    {
      "parent_author": "sarven",
      "parent_permlink": "tworzenie-tla-z-poruszajacymi-sie-czasteczkami",
      "author": "steemitboard",
      "permlink": "steemitboard-notify-sarven-20191209t130948000z",
      "title": "",
      "body": "Congratulations @sarven! You received a personal award!\n\n<table><tr><td>https://steemitimages.com/70x70/http://steemitboard.com/@sarven/birthday2.png</td><td>Happy Birthday! - You are on the Steem blockchain for 2 years!</td></tr></table>\n\n<sub>_You can view [your badges on your Steem Board](https://steemitboard.com/@sarven) and compare to others on the [Steem Ranking](https://steemitboard.com/ranking/index.php?name=sarven)_</sub>\n\n\n###### [Vote for @Steemitboard as a witness](https://v2.steemconnect.com/sign/account-witness-vote?witness=steemitboard&approve=1) to get one more award and increased upvotes!",
      "json_metadata": "{\"image\":[\"https://steemitboard.com/img/notify.png\"]}"
    }
  ]
}
steemdelegated 4.137 SP to @sarven
2019/05/12 20:20:00
delegatorsteem
delegateesarven
vesting shares6728.298360 VESTS
Transaction InfoBlock #32852001/Trx 81947a592cec6c7c5b5af038f4e3e7c8f6cd9449
View Raw JSON Data
{
  "trx_id": "81947a592cec6c7c5b5af038f4e3e7c8f6cd9449",
  "block": 32852001,
  "trx_in_block": 20,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2019-05-12T20:20:00",
  "op": [
    "delegate_vesting_shares",
    {
      "delegator": "steem",
      "delegatee": "sarven",
      "vesting_shares": "6728.298360 VESTS"
    }
  ]
}
2018/12/09 12:12:09
parent authorsarven
parent permlinktworzenie-tla-z-poruszajacymi-sie-czasteczkami
authorsteemitboard
permlinksteemitboard-notify-sarven-20181209t121208000z
title
bodyCongratulations @sarven! You received a personal award! <table><tr><td>https://steemitimages.com/70x70/http://steemitboard.com/@sarven/birthday1.png</td><td>1 Year on Steemit</td></tr></table> <sub>_[Click here to view your Board of Honor](https://steemitboard.com/@sarven)_</sub> **Do not miss the last post from @steemitboard:** <table><tr><td><a href="https://steemit.com/steemitboard/@steemitboard/5jrq2c-steemitboard-saint-nicholas-day"><img src="https://steemitimages.com/64x128/http://i.cubeupload.com/mGo2Zd.png"></a></td><td><a href="https://steemit.com/steemitboard/@steemitboard/5jrq2c-steemitboard-saint-nicholas-day">Saint Nicholas challenge for good boys and girls</a></td></tr></table> > Support [SteemitBoard's project](https://steemit.com/@steemitboard)! **[Vote for its witness](https://v2.steemconnect.com/sign/account-witness-vote?witness=steemitboard&approve=1)** and **get one more award**!
json metadata{"image":["https://steemitboard.com/img/notify.png"]}
Transaction InfoBlock #28411819/Trx 7a625a01a4cd829b0e98d9aa9dc645214d1dd1af
View Raw JSON Data
{
  "trx_id": "7a625a01a4cd829b0e98d9aa9dc645214d1dd1af",
  "block": 28411819,
  "trx_in_block": 9,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-12-09T12:12:09",
  "op": [
    "comment",
    {
      "parent_author": "sarven",
      "parent_permlink": "tworzenie-tla-z-poruszajacymi-sie-czasteczkami",
      "author": "steemitboard",
      "permlink": "steemitboard-notify-sarven-20181209t121208000z",
      "title": "",
      "body": "Congratulations @sarven! You received a personal award!\n\n<table><tr><td>https://steemitimages.com/70x70/http://steemitboard.com/@sarven/birthday1.png</td><td>1 Year on Steemit</td></tr></table>\n\n<sub>_[Click here to view your Board of Honor](https://steemitboard.com/@sarven)_</sub>\n\n\n**Do not miss the last post from @steemitboard:**\n<table><tr><td><a href=\"https://steemit.com/steemitboard/@steemitboard/5jrq2c-steemitboard-saint-nicholas-day\"><img src=\"https://steemitimages.com/64x128/http://i.cubeupload.com/mGo2Zd.png\"></a></td><td><a href=\"https://steemit.com/steemitboard/@steemitboard/5jrq2c-steemitboard-saint-nicholas-day\">Saint Nicholas challenge for good boys and girls</a></td></tr></table>\n\n> Support [SteemitBoard's project](https://steemit.com/@steemitboard)! **[Vote for its witness](https://v2.steemconnect.com/sign/account-witness-vote?witness=steemitboard&approve=1)** and **get one more award**!",
      "json_metadata": "{\"image\":[\"https://steemitboard.com/img/notify.png\"]}"
    }
  ]
}
steemdelegated 4.260 SP to @sarven
2018/05/17 02:38:45
delegatorsteem
delegateesarven
vesting shares6927.813452 VESTS
Transaction InfoBlock #22497475/Trx 320b05d1b88e92301ddf0f81b50196282f6bb848
View Raw JSON Data
{
  "trx_id": "320b05d1b88e92301ddf0f81b50196282f6bb848",
  "block": 22497475,
  "trx_in_block": 57,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-05-17T02:38:45",
  "op": [
    "delegate_vesting_shares",
    {
      "delegator": "steem",
      "delegatee": "sarven",
      "vesting_shares": "6927.813452 VESTS"
    }
  ]
}
steemdelegated 16.870 SP to @sarven
2018/02/05 02:28:12
delegatorsteem
delegateesarven
vesting shares27437.723836 VESTS
Transaction InfoBlock #19591517/Trx 135d13d225bff49b50bf326468eff16a2db2995d
View Raw JSON Data
{
  "trx_id": "135d13d225bff49b50bf326468eff16a2db2995d",
  "block": 19591517,
  "trx_in_block": 2,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-02-05T02:28:12",
  "op": [
    "delegate_vesting_shares",
    {
      "delegator": "steem",
      "delegatee": "sarven",
      "vesting_shares": "27437.723836 VESTS"
    }
  ]
}
sarvenclaimed reward balance: 0.054 SBD, 0.018 SP
2018/01/23 10:00:09
accountsarven
reward steem0.000 STEEM
reward sbd0.054 SBD
reward vests28.663383 VESTS
Transaction InfoBlock #19226546/Trx 9ddde83d5580f30529718315647af2e2cbb56d47
View Raw JSON Data
{
  "trx_id": "9ddde83d5580f30529718315647af2e2cbb56d47",
  "block": 19226546,
  "trx_in_block": 50,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-23T10:00:09",
  "op": [
    "claim_reward_balance",
    {
      "account": "sarven",
      "reward_steem": "0.000 STEEM",
      "reward_sbd": "0.054 SBD",
      "reward_vests": "28.663383 VESTS"
    }
  ]
}
sarvenreceived 0.054 SBD, 0.018 SP author reward for @sarven / tworzenie-tla-z-poruszajacymi-sie-czasteczkami
2018/01/18 21:26:09
authorsarven
permlinktworzenie-tla-z-poruszajacymi-sie-czasteczkami
sbd payout0.054 SBD
steem payout0.000 STEEM
vesting payout28.663383 VESTS
Transaction InfoBlock #19096325/Virtual Operation #9
View Raw JSON Data
{
  "trx_id": "0000000000000000000000000000000000000000",
  "block": 19096325,
  "trx_in_block": 4294967295,
  "op_in_trx": 0,
  "virtual_op": 9,
  "timestamp": "2018-01-18T21:26:09",
  "op": [
    "author_reward",
    {
      "author": "sarven",
      "permlink": "tworzenie-tla-z-poruszajacymi-sie-czasteczkami",
      "sbd_payout": "0.054 SBD",
      "steem_payout": "0.000 STEEM",
      "vesting_payout": "28.663383 VESTS"
    }
  ]
}
sarvenclaimed reward balance: 0.220 SBD, 0.055 SP
2018/01/15 19:24:24
accountsarven
reward steem0.000 STEEM
reward sbd0.220 SBD
reward vests90.110620 VESTS
Transaction InfoBlock #19007519/Trx 2f95c5437c6fa13d4dd6cd079a8c0d1e090e1305
View Raw JSON Data
{
  "trx_id": "2f95c5437c6fa13d4dd6cd079a8c0d1e090e1305",
  "block": 19007519,
  "trx_in_block": 21,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-15T19:24:24",
  "op": [
    "claim_reward_balance",
    {
      "account": "sarven",
      "reward_steem": "0.000 STEEM",
      "reward_sbd": "0.220 SBD",
      "reward_vests": "90.110620 VESTS"
    }
  ]
}
sarvenreceived 0.017 SBD, 0.005 SP author reward for @sarven / codingame-czyli-rywalizuj-z-innymi-programujac
2018/01/15 19:20:30
authorsarven
permlinkcodingame-czyli-rywalizuj-z-innymi-programujac
sbd payout0.017 SBD
steem payout0.000 STEEM
vesting payout8.190790 VESTS
Transaction InfoBlock #19007440/Virtual Operation #7
View Raw JSON Data
{
  "trx_id": "0000000000000000000000000000000000000000",
  "block": 19007440,
  "trx_in_block": 4294967295,
  "op_in_trx": 0,
  "virtual_op": 7,
  "timestamp": "2018-01-15T19:20:30",
  "op": [
    "author_reward",
    {
      "author": "sarven",
      "permlink": "codingame-czyli-rywalizuj-z-innymi-programujac",
      "sbd_payout": "0.017 SBD",
      "steem_payout": "0.000 STEEM",
      "vesting_payout": "8.190790 VESTS"
    }
  ]
}
2018/01/14 21:45:06
voterlukmarcus
authorsarven
permlinktworzenie-tla-z-poruszajacymi-sie-czasteczkami
weight500 (5.00%)
Transaction InfoBlock #18981566/Trx bd94c4896355ab4a86233fee8ff17f7391ce3d2f
View Raw JSON Data
{
  "trx_id": "bd94c4896355ab4a86233fee8ff17f7391ce3d2f",
  "block": 18981566,
  "trx_in_block": 21,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-14T21:45:06",
  "op": [
    "vote",
    {
      "voter": "lukmarcus",
      "author": "sarven",
      "permlink": "tworzenie-tla-z-poruszajacymi-sie-czasteczkami",
      "weight": 500
    }
  ]
}
sarvenreceived 0.203 SBD, 0.050 SP author reward for @sarven / jak-sie-rozwijac-w-kierunku-it-i-nie-zwariowac
2018/01/12 19:53:00
authorsarven
permlinkjak-sie-rozwijac-w-kierunku-it-i-nie-zwariowac
sbd payout0.203 SBD
steem payout0.000 STEEM
vesting payout81.919830 VESTS
Transaction InfoBlock #18921788/Virtual Operation #11
View Raw JSON Data
{
  "trx_id": "0000000000000000000000000000000000000000",
  "block": 18921788,
  "trx_in_block": 4294967295,
  "op_in_trx": 0,
  "virtual_op": 11,
  "timestamp": "2018-01-12T19:53:00",
  "op": [
    "author_reward",
    {
      "author": "sarven",
      "permlink": "jak-sie-rozwijac-w-kierunku-it-i-nie-zwariowac",
      "sbd_payout": "0.203 SBD",
      "steem_payout": "0.000 STEEM",
      "vesting_payout": "81.919830 VESTS"
    }
  ]
}
2018/01/12 15:27:27
parent authorsarven
parent permlinktworzenie-tla-z-poruszajacymi-sie-czasteczkami
authorcheetah
permlinkcheetah-re-sarventworzenie-tla-z-poruszajacymi-sie-czasteczkami
title
bodyHi! I am a robot. I just upvoted you! I found similar content that readers might be interested in: https://sarvendev.com/2017/03/tworzenie-tla-z-poruszajacymi-sie-czasteczkami/
json metadata
Transaction InfoBlock #18916490/Trx d135a921a7150b30866aecd954aeac91552f1356
View Raw JSON Data
{
  "trx_id": "d135a921a7150b30866aecd954aeac91552f1356",
  "block": 18916490,
  "trx_in_block": 32,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-12T15:27:27",
  "op": [
    "comment",
    {
      "parent_author": "sarven",
      "parent_permlink": "tworzenie-tla-z-poruszajacymi-sie-czasteczkami",
      "author": "cheetah",
      "permlink": "cheetah-re-sarventworzenie-tla-z-poruszajacymi-sie-czasteczkami",
      "title": "",
      "body": "Hi! I am a robot. I just upvoted you! I found similar content that readers might be interested in:\nhttps://sarvendev.com/2017/03/tworzenie-tla-z-poruszajacymi-sie-czasteczkami/",
      "json_metadata": ""
    }
  ]
}
2018/01/12 07:31:09
voterjacekw
authorsarven
permlinktworzenie-tla-z-poruszajacymi-sie-czasteczkami
weight10000 (100.00%)
Transaction InfoBlock #18906984/Trx a75b9dda9e83aa954d5c8ea8debc3013743dac21
View Raw JSON Data
{
  "trx_id": "a75b9dda9e83aa954d5c8ea8debc3013743dac21",
  "block": 18906984,
  "trx_in_block": 30,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-12T07:31:09",
  "op": [
    "vote",
    {
      "voter": "jacekw",
      "author": "sarven",
      "permlink": "tworzenie-tla-z-poruszajacymi-sie-czasteczkami",
      "weight": 10000
    }
  ]
}
2018/01/11 21:57:57
voterpolbot
authorsarven
permlinktworzenie-tla-z-poruszajacymi-sie-czasteczkami
weight2500 (25.00%)
Transaction InfoBlock #18895530/Trx 5c2c9049fe6766b90be9de2e939fc749bd833761
View Raw JSON Data
{
  "trx_id": "5c2c9049fe6766b90be9de2e939fc749bd833761",
  "block": 18895530,
  "trx_in_block": 50,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-11T21:57:57",
  "op": [
    "vote",
    {
      "voter": "polbot",
      "author": "sarven",
      "permlink": "tworzenie-tla-z-poruszajacymi-sie-czasteczkami",
      "weight": 2500
    }
  ]
}
2018/01/11 21:27:42
voterkamixi
authorsarven
permlinktworzenie-tla-z-poruszajacymi-sie-czasteczkami
weight10000 (100.00%)
Transaction InfoBlock #18894925/Trx 47eb7742c6740e59434edb585f2b796b9bdad95b
View Raw JSON Data
{
  "trx_id": "47eb7742c6740e59434edb585f2b796b9bdad95b",
  "block": 18894925,
  "trx_in_block": 12,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-11T21:27:42",
  "op": [
    "vote",
    {
      "voter": "kamixi",
      "author": "sarven",
      "permlink": "tworzenie-tla-z-poruszajacymi-sie-czasteczkami",
      "weight": 10000
    }
  ]
}
2018/01/11 21:26:09
parent author
parent permlinkpolish
authorsarven
permlinktworzenie-tla-z-poruszajacymi-sie-czasteczkami
titleTworzenie tła z poruszającymi się cząsteczkami
bodyhttps://sarvendev.com/wp-content/uploads/2017/03/particles-953x536.png W tym wpisie przedstawię w jaki sposób stworzyć tło z poruszającymi się cząsteczkami. Całość oparta będzie o element canvas oraz ES6. Wykorzystam tutaj kod, który już kiedyś stworzyłem jako część gry [Paper Soccer](https://paper--soccer.herokuapp.com/). # Cel Celem jest stworzenie tła wykorzystanego tutaj Paper Soccer. Oczywiście mam już ten kod gotowy, jednak chciałbym stworzyć coś na kształt biblioteki, która pozwoli w łatwy sposób podpiąć się pod dany element canvas i utworzyć w nim takie tło oraz umożliwić konfigurację parametrów takich jak: * kolor * wielkość cząsteczek * ilość cząsteczek * grubość linii * etc. # Lecimy z tematem Biblioteka nie będzie wymagała żadnych zależności, jedynie do stworzenia produkcyjnej wersji wykorzystany zostanie webpack oraz babel do kompiliacji ES6 do ES5. Struktura katalogów prezentuje się następująco: * /demo – przykład wykorzystania * /dist – skompilowana do ES5 biblioteka oraz zminifikowana * /src – pliki zawierające poszczególne klasy * /test – testy Najbardziej interesuje nas tutaj katalog /src, w którym zawarty będzie kod podzielony na poszczególne moduły(klasy): * Particle – klasa reprezentująca pojedynczą cząsteczkę * ParticleCreator – klasa mająca za zadanie tworzenie cząsteczek o określonych parametrach * Drawer – klasa odpowiedzialna za rysowanie linii oraz cząsteczek * Background – klasa odpowiedzialna za całe sterowanie, tworząca obiekty klas ParticleCreator oraz Drawer Standard ES6 według mnie usprawnił tworzenie klas, przynajmniej teraz to wygląda bardziej ludzko oraz w podobnej do innych języków składni. ## Reprezentacja pojedynczej cząsteczki ``` class Particle { /** * Particle constructor * * @param int x * @param int y * @param array vel * @param int radius */ constructor(x, y, vel, radius) { this.x = x; this.y = y; this.vel = vel; this.radius = radius; } /** * Move particle with set velocity * * @param int maxX * @param int maxY */ move(maxX, maxY) { this.x += this.vel.x; this.y += this.vel.y; if (this.isOffXEdge(maxX)) { this.vel.x = -this.vel.x; } if (this.isOffYEdge(maxY)) { this.vel.y = -this.vel.y; } } /** * Check that particle is off the X edge. * * @param int maxX * @return bool */ isOffXEdge(maxX) { return this.x > maxX || this.x < 0; } /** * Check that particle is off the Y edge. * * @param maxY * @return bool */ isOffYEdge(maxY) { return this.y > maxY || this.y < 0 } } export default Particle; ``` Powyższy kod przedstawia klasę reprezentującą pojedynczą cząsteczkę. Mamy tutaj konstruktor, który ustawia kilka wartości: współrzędne, prędkość oraz promień. Metoda move() odpowiedzialna jest za wykonanie ruchu cząsteczki, czyli zwiększenie współrzędnych o odpowiednie wartości określone przez atrybut vel. Wywoływana ona będzie w klasie Background, podczas odświeżania animacji, co w efekcie powodowało będzie ruch cząsteczki. Prędkość jest tutaj przedstawiana za pomocą obiektu z dwiema wartościami x oraz y, o które podczas wywołania metody move() zwiększane są odpowiednio współrzędne cząsteczki. W przypadku, gdy cząsteczka wyjdzie poza daną krawędź ekranu zmienia zwrot na przeciwny i porusza się w drugą stronę, co tworzy wrażenie odbijania się cząsteczki od krawędzi. Warunki tego wyjścia poza ekran sprawdzane są w dwóch instrukcjach warunkowych dla każdej z osi. ## Tworzenie cząsteczek ``` import Particle from './Particle'; class ParticleCreator { /** * ParticleCreator constructor. * * @param object settings * @param object canvas */ constructor(settings, canvas) { this.settings = settings; this.canvas = canvas; } /** * Create many particles with specified count. * * @param int count * @return Particle[] */ createMany(count) { let particles = []; for (let i = 0; i < count; i++) { particles.push(this.create()); } return particles; } /** * Create single particle. * * @return Particle */ create() { return new Particle( Math.random() * this.canvas.width, Math.random() * this.canvas.height, { x: (Math.random() - 0.5) * 5, // [-2.5, 2.5) y: (Math.random() - 0.5) * 5 // [-2.5, 2.5) }, this.settings.particleRadius ); } } export default ParticleCreator; ``` Powyższa klasa odpowiedzialna jest za utworzenie cząsteczek o określonych parametrach, wykorzystywana jest tutaj klasa omówiona wcześniej – Particle. Konstruktor przyjmuje tutaj dwa parametry: settings oraz canvas. Pierwszy z nich to tablica z ustawieniami biblioteki, która zawiera dane określające ile cząsteczek stworzyć oraz o jakim promieniu. Drugi parametr(canvas) to po prostu element canvas, który tutaj wykorzystywany jest do pobrania maksymalnej szerokości oraz wysokości. Jak już wcześniej napisałem promień pobierany jest z ustawień biblioteki, natomiast współrzędne oraz prędkość losowane są z odpowiednich przedziałów. Math.random() zwraca losową wartość z przedziału [0, 1), więc przedziały dla współrzędnych będą następujące: * x – [0, szerokość okna) * y – [0, wysokość okna) Przedziały dla prędkości zostały zapisane w komentarzu obok. ## Rysowanie ``` class Drawer { /** * Drawer constructor * * @param object settings * @param object ctx */ constructor(settings, ctx) { this.settings = settings; this.ctx = ctx; } /** * Draw lines from this particle to other particles where distance between them is lower than specified distance * * @param Particle[] particles * @param Particle particle */ drawLines(particles, particle) { this.ctx.beginPath(); particles.forEach(secondParticle => { const dist = Math.hypot(particle.x - secondParticle.x, particle.y - secondParticle.y); if (dist < this.settings.particleDistance) { this.drawLine(particle, secondParticle); } }); this.ctx.stroke(); } /** * Draw line between two particles * * @param firstParticle * @param secondParticle */ drawLine(firstParticle, secondParticle) { this.ctx.strokeStyle = this.settings.lineColor; this.ctx.lineWidth = this.settings.lineWidth; this.ctx.moveTo(firstParticle.x, firstParticle.y); this.ctx.lineTo(secondParticle.x, secondParticle.y); } /** * Draw Particle * * @param Particle particle */ drawParticle(particle) { this.ctx.beginPath(); this.ctx.arc(particle.x, particle.y, particle.radius, 0, Math.PI * 2); this.ctx.fillStyle = this.settings.particleColor; this.ctx.fill(); } } export default Drawer; ``` W powyższym kodzie zawarta została klasa odpowiedzialna za rysowanie cząsteczek oraz linii między nimi. Konstruktor przyjmuje tutaj również dwa parametry. Settings zostało już wspomniane, są to po prostu ustawienia biblioteki. Natomiast ctx to: ``` this.ctx = this.canvas.getContext('2d'); ``` czyli kontekst umożliwiający rysowanie. > The HTMLCanvasElement.getContext() method returns a drawing context on the canvas > https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/getContext Metody drawLine() oraz drawParticle() odpowiedzialne są po prostu za rysowanie odpowiednio linii oraz koła. Po wyjaśnienie instrukcji tam zawartych odsyłam do dokumentacji, jest to po prostu zwykłe API służące do rysowania tych elementów. Linie pomiędzy cząsteczkami rysowane są w taki sposób, że przy każdym odświeżeniu animacji dla każdej cząsteczki sprawdzana jest odległość jej samej z pozostałymi cząsteczkami, jeśli jest ona mniejsza niż wartość określona przez właściwość particleDistance obiektu settings to rysowana jest linia pomiędzy tymi punktami. Metoda Math.hypot() służy do obliczenia pierwiastka kwadratowego sumy kwadratów argumentów. Dzięki niej łatwo oblicza się odległość między punktami. Metoda drawLines() odpowiada za wysokie zużycie procesora, gdyż jeśli animacja odświeżana jest 60 razy na sekundę, a ta metoda jest wywoływana przy każdym odświeżeniu, to przy założeniu, że mamy 100 cząsteczek na sekundę wykonywane jest wtedy 60*100*100 = 600 000 obliczeń. ## Sterowanie ``` import ParticleCreator from './ParticleCreator'; import Drawer from './Drawer'; class Background { /** * Background constructor, get canvas element, set options * * @param string canvasID * @param object settings */ constructor(canvasID, settings) { this.setSettings(settings); this.canvas = document.getElementById(canvasID); this.ctx = this.canvas.getContext('2d'); this.particleCreator = new ParticleCreator(this.settings, this.canvas); this.drawer = new Drawer(this.settings, this.ctx); this.canvas.width = window.innerWidth; this.canvas.height = window.innerHeight; this.particles = []; this.init(); } /** * Set settings * * @param object settings */ setSettings(settings) { this.settings = { particleColor: this.getOption(settings, 'particleColor', '#000000'), particleRadius: this.getOption(settings, 'particleRadius', 3), particleDistance: this.getOption(settings, 'particleDistance', 100), particlesCount: this.getOption(settings, 'particlesCount', 300), lineColor: this.getOption(settings, 'lineColor', '#000000'), lineWidth: this.getOption(settings, 'lineWidth', 1) }; } /** * Get option * * @param object settings * @param string name * @param mixed default */ getOption(settings, name, defaultValue) { return settings.hasOwnProperty(name) ? settings[name] : defaultValue; } /** * Create particles and start loop */ init() { this.particles = this.particleCreator.createMany(this.settings.particlesCount); this.loop(); } /** * Loop, clear and drawParticles */ loop() { this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); this.particles.forEach(particle => { particle.move(this.canvas.width, this.canvas.height); this.drawer.drawLines(this.particles, particle); this.drawer.drawParticle(particle); }); window.requestAnimationFrame(this.loop.bind(this)); } } export default Background; ``` Powyżej przedstawiona została ostatnia klasa, która jest klasą główną. Konstruktor przyjmuje tutaj dwa parametry: ID elementu canvas oraz tablicę z ustawieniami. Klasa zawiera w sobie ustawienie właściwości, jeśli nie są one przekazywane z zewnątrz to w metodzie setSettings() ustawiane są wartości domyślne. Kolejno w konstruktorze mamy: * pobranie elementu canvas na podstawie ID * pobranie kontekstu * utworzenie obiektu klasy ParticleCreator do tworzenia cząsteczek * utworzenie obiektu klasy Drawer do rysowanie linii oraz cząsteczek * ustawienie wymiarów elementu canvas – fullscreen * inicjalizacja tablicy przechwowującej cząsteczki * wywołanie metody init Metoda init() za pomocą obiektu particleCreator tworzy cząsteczki, następnie wywołuje metodę loop(), w której to: * czyszczony jest cały ekran * rysowane są cząsteczki, linie oraz wykonywany jest ruch (zmiana współrzędnych o określoną wartość) Następnie metoda loop() przekazywana jest jako argument do Window.requestAnimationFrame(), która wykonuje metodę loop() przed odświeżeniem animacji. Dodatkowo w katalogu /src jest jeszcze plik: ``` import Background from './modules/Background'; export function create(canvasID, settings) { return new Background(canvasID, settings); }; ``` Eksportowana jest tutaj funkcja, która ma za zadanie przyjąć parametry oraz utworzyć obiekt klasy Background. Dzięki temu w poniższy prosty sposób możemy skorzystać z tej biblioteki: ``` EasyParticlesBackground.create('background', { particleColor: 'rgba(236, 208, 120, 1)', particleRadius: 3, particleDistance: 100, particlesCount: 200, lineColor: 'rgba(236, 208, 120, 1)', lineWidth: 1 }); ``` Dokładniejszy przykład użycia można znaleźć w linkach poniżej. ## Finalny efekt [Github](https://github.com/sarven/easy-particles-background) [Demo](http://projects.sarvendev.com/particles/index.html)
json metadata{"tags":["polish","programming","javascript","es6"],"image":["https://sarvendev.com/wp-content/uploads/2017/03/particles-953x536.png"],"links":["https://paper--soccer.herokuapp.com/","https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/getContext","https://github.com/sarven/easy-particles-background","http://projects.sarvendev.com/particles/index.html"],"app":"steemit/0.1","format":"markdown"}
Transaction InfoBlock #18894894/Trx 23a122255e4613918a5c2638e7f96b3b1e2b34a8
View Raw JSON Data
{
  "trx_id": "23a122255e4613918a5c2638e7f96b3b1e2b34a8",
  "block": 18894894,
  "trx_in_block": 55,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-11T21:26:09",
  "op": [
    "comment",
    {
      "parent_author": "",
      "parent_permlink": "polish",
      "author": "sarven",
      "permlink": "tworzenie-tla-z-poruszajacymi-sie-czasteczkami",
      "title": "Tworzenie tła z poruszającymi się cząsteczkami",
      "body": "https://sarvendev.com/wp-content/uploads/2017/03/particles-953x536.png\n\nW tym wpisie przedstawię w jaki sposób stworzyć tło z poruszającymi się cząsteczkami. Całość oparta będzie o element canvas oraz ES6. Wykorzystam tutaj kod, który już kiedyś stworzyłem jako część gry [Paper Soccer](https://paper--soccer.herokuapp.com/).\n\n# Cel\nCelem jest stworzenie tła wykorzystanego tutaj Paper Soccer. Oczywiście mam już ten kod gotowy, jednak chciałbym stworzyć coś na kształt biblioteki, która pozwoli w łatwy sposób podpiąć się pod dany element canvas i utworzyć w nim takie tło oraz umożliwić konfigurację parametrów takich jak:\n\n* kolor\n* wielkość cząsteczek\n* ilość cząsteczek\n* grubość linii\n* etc.\n\n# Lecimy z tematem\nBiblioteka nie będzie wymagała żadnych zależności, jedynie do stworzenia produkcyjnej wersji wykorzystany zostanie webpack oraz  babel do kompiliacji ES6 do ES5. Struktura katalogów prezentuje się następująco:\n\n* /demo – przykład wykorzystania\n* /dist – skompilowana  do ES5 biblioteka oraz zminifikowana\n* /src – pliki zawierające poszczególne klasy\n* /test – testy\n\nNajbardziej interesuje nas tutaj katalog /src, w którym zawarty będzie kod podzielony na poszczególne moduły(klasy):\n\n* Particle – klasa reprezentująca pojedynczą cząsteczkę\n* ParticleCreator – klasa mająca za zadanie tworzenie cząsteczek o określonych parametrach\n* Drawer – klasa odpowiedzialna za rysowanie linii oraz cząsteczek\n* Background – klasa odpowiedzialna za całe sterowanie, tworząca obiekty klas ParticleCreator oraz Drawer\n\nStandard ES6 według mnie usprawnił tworzenie klas, przynajmniej teraz to wygląda bardziej ludzko oraz w podobnej do innych języków składni.\n\n## Reprezentacja pojedynczej cząsteczki\n\n```\nclass Particle {\n  /**\n   * Particle constructor\n   *\n   * @param int x\n   * @param int y\n   * @param array vel\n   * @param int radius\n   */\n  constructor(x, y, vel, radius) {\n    this.x = x;\n    this.y = y;\n    this.vel = vel;\n    this.radius = radius;\n  }\n  /**\n   * Move particle with set velocity\n   *\n   * @param int maxX\n   * @param int maxY\n   */\n  move(maxX, maxY) {\n    this.x += this.vel.x;\n    this.y += this.vel.y;\n    if (this.isOffXEdge(maxX)) {\n      this.vel.x = -this.vel.x;\n    }\n    if (this.isOffYEdge(maxY)) {\n      this.vel.y = -this.vel.y;\n    }\n  }\n  /**\n   * Check that particle is off the X edge.\n   *\n   * @param int maxX\n   * @return bool\n   */\n  isOffXEdge(maxX) {\n    return this.x > maxX || this.x < 0;\n  }\n  /**\n   * Check that particle is off the Y edge.\n   *\n   * @param maxY\n   * @return bool\n   */\n  isOffYEdge(maxY) {\n    return this.y > maxY || this.y < 0\n  }\n}\nexport default Particle;\n```\n\nPowyższy kod przedstawia klasę reprezentującą pojedynczą cząsteczkę. Mamy tutaj konstruktor, który ustawia kilka wartości: współrzędne, prędkość oraz promień. Metoda move() odpowiedzialna jest za wykonanie ruchu cząsteczki, czyli zwiększenie współrzędnych o odpowiednie wartości określone przez atrybut vel. Wywoływana ona będzie w klasie Background, podczas odświeżania animacji, co w efekcie powodowało będzie ruch cząsteczki. Prędkość jest tutaj przedstawiana za pomocą obiektu z dwiema wartościami x oraz y, o które podczas wywołania metody move() zwiększane są odpowiednio współrzędne cząsteczki. W przypadku, gdy cząsteczka wyjdzie poza daną krawędź ekranu zmienia zwrot na przeciwny i porusza się  w drugą stronę, co tworzy wrażenie odbijania się cząsteczki od krawędzi. Warunki tego wyjścia poza ekran sprawdzane są w dwóch instrukcjach warunkowych dla każdej z osi.\n\n## Tworzenie cząsteczek\n\n```\nimport Particle from './Particle';\nclass ParticleCreator {\n  /**\n   * ParticleCreator constructor.\n   *\n   * @param object settings\n   * @param object canvas\n   */\n  constructor(settings, canvas) {\n    this.settings = settings;\n    this.canvas = canvas;\n  }\n  /**\n   * Create many particles with specified count.\n   *\n   * @param int count\n   * @return Particle[]\n   */\n  createMany(count) {\n    let particles = [];\n    for (let i = 0; i < count; i++) {\n      particles.push(this.create());\n    }\n    return particles;\n  }\n  /**\n   * Create single particle.\n   *\n   * @return Particle\n   */\n  create() {\n    return new Particle(\n      Math.random() * this.canvas.width,\n      Math.random() * this.canvas.height, {\n        x: (Math.random() - 0.5) * 5, // [-2.5, 2.5)\n        y: (Math.random() - 0.5) * 5 // [-2.5, 2.5)\n      },\n      this.settings.particleRadius\n    );\n  }\n}\nexport default ParticleCreator;\n```\n\nPowyższa klasa odpowiedzialna jest za utworzenie cząsteczek o określonych parametrach, wykorzystywana jest tutaj klasa omówiona wcześniej – Particle. Konstruktor przyjmuje tutaj dwa parametry: settings oraz canvas. Pierwszy z nich to tablica z ustawieniami biblioteki, która zawiera dane określające ile cząsteczek stworzyć oraz o jakim promieniu. Drugi parametr(canvas) to po prostu element canvas, który tutaj wykorzystywany jest do pobrania maksymalnej szerokości oraz wysokości. Jak już wcześniej napisałem promień pobierany jest z ustawień biblioteki, natomiast współrzędne oraz prędkość losowane są z odpowiednich przedziałów. Math.random() zwraca losową wartość z przedziału [0, 1), więc przedziały dla współrzędnych będą następujące:\n\n* x – [0, szerokość okna)\n* y  – [0, wysokość okna)\n\nPrzedziały dla prędkości zostały zapisane w komentarzu obok.\n\n## Rysowanie\n\n```\nclass Drawer {\n  /**\n   * Drawer constructor\n   *\n   * @param object settings\n   * @param object ctx\n   */\n  constructor(settings, ctx) {\n    this.settings = settings;\n    this.ctx = ctx;\n  }\n  /**\n   * Draw lines from this particle to other particles where distance between them is lower than specified distance\n   *\n   * @param Particle[] particles\n   * @param Particle particle\n   */\n  drawLines(particles, particle) {\n    this.ctx.beginPath();\n    particles.forEach(secondParticle => {\n      const dist = Math.hypot(particle.x - secondParticle.x, particle.y - secondParticle.y);\n      if (dist < this.settings.particleDistance) {\n        this.drawLine(particle, secondParticle);\n      }\n    });\n    this.ctx.stroke();\n  }\n  /**\n   * Draw line between two particles\n   *\n   * @param firstParticle\n   * @param secondParticle\n   */\n  drawLine(firstParticle, secondParticle) {\n    this.ctx.strokeStyle = this.settings.lineColor;\n    this.ctx.lineWidth = this.settings.lineWidth;\n    this.ctx.moveTo(firstParticle.x, firstParticle.y);\n    this.ctx.lineTo(secondParticle.x, secondParticle.y);\n  }\n  /**\n   * Draw Particle\n   *\n   * @param Particle particle\n   */\n  drawParticle(particle) {\n    this.ctx.beginPath();\n    this.ctx.arc(particle.x, particle.y, particle.radius, 0, Math.PI * 2);\n    this.ctx.fillStyle = this.settings.particleColor;\n    this.ctx.fill();\n  }\n}\nexport default Drawer;\n```\n\nW powyższym kodzie zawarta została klasa odpowiedzialna za rysowanie cząsteczek oraz linii między nimi. Konstruktor przyjmuje tutaj również dwa parametry. Settings zostało już wspomniane, są to po prostu ustawienia biblioteki. Natomiast ctx to:\n\n```\nthis.ctx = this.canvas.getContext('2d');\n```\n\nczyli kontekst umożliwiający rysowanie.\n\n> The HTMLCanvasElement.getContext() method returns a drawing context on the canvas\n> https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/getContext\n\nMetody drawLine() oraz drawParticle() odpowiedzialne są po prostu za rysowanie odpowiednio linii oraz koła. Po wyjaśnienie instrukcji tam zawartych odsyłam do dokumentacji, jest to po prostu zwykłe API służące do rysowania tych elementów.\n\nLinie pomiędzy cząsteczkami rysowane są w taki sposób, że przy każdym odświeżeniu animacji dla każdej cząsteczki sprawdzana jest odległość jej samej z pozostałymi cząsteczkami, jeśli jest ona mniejsza niż wartość określona przez właściwość particleDistance obiektu settings to rysowana jest linia pomiędzy tymi punktami. Metoda Math.hypot() służy do obliczenia pierwiastka kwadratowego sumy kwadratów argumentów. Dzięki niej łatwo oblicza się odległość między punktami.\n\nMetoda drawLines() odpowiada za wysokie zużycie procesora, gdyż jeśli animacja odświeżana jest 60 razy na sekundę, a ta metoda jest wywoływana przy każdym odświeżeniu, to przy założeniu, że mamy 100 cząsteczek na sekundę wykonywane jest wtedy 60*100*100 = 600 000 obliczeń.\n\n## Sterowanie\n\n```\nimport ParticleCreator from './ParticleCreator';\nimport Drawer from './Drawer';\nclass Background {\n  /**\n   * Background constructor, get canvas element, set options\n   *\n   * @param string canvasID\n   * @param object settings\n   */\n  constructor(canvasID, settings) {\n    this.setSettings(settings);\n    this.canvas = document.getElementById(canvasID);\n    this.ctx = this.canvas.getContext('2d');\n    this.particleCreator = new ParticleCreator(this.settings, this.canvas);\n    this.drawer = new Drawer(this.settings, this.ctx);\n    this.canvas.width = window.innerWidth;\n    this.canvas.height = window.innerHeight;\n    this.particles = [];\n    this.init();\n  }\n  /**\n   * Set settings\n   *\n   * @param object settings\n   */\n  setSettings(settings) {\n    this.settings = {\n      particleColor: this.getOption(settings, 'particleColor', '#000000'),\n      particleRadius: this.getOption(settings, 'particleRadius', 3),\n      particleDistance: this.getOption(settings, 'particleDistance', 100),\n      particlesCount: this.getOption(settings, 'particlesCount', 300),\n      lineColor: this.getOption(settings, 'lineColor', '#000000'),\n      lineWidth: this.getOption(settings, 'lineWidth', 1)\n    };\n  }\n  /**\n   * Get option\n   *\n   * @param object settings\n   * @param string name\n   * @param mixed default\n   */\n  getOption(settings, name, defaultValue) {\n    return settings.hasOwnProperty(name) ? settings[name] : defaultValue;\n  }\n  /**\n   * Create particles and start loop\n   */\n  init() {\n    this.particles = this.particleCreator.createMany(this.settings.particlesCount);\n    this.loop();\n  }\n  /**\n   * Loop, clear and drawParticles\n   */\n  loop() {\n    this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n    this.particles.forEach(particle => {\n      particle.move(this.canvas.width, this.canvas.height);\n      this.drawer.drawLines(this.particles, particle);\n      this.drawer.drawParticle(particle);\n    });\n    window.requestAnimationFrame(this.loop.bind(this));\n  }\n}\nexport default Background;\n```\n\nPowyżej przedstawiona została ostatnia klasa, która jest klasą główną. Konstruktor przyjmuje tutaj dwa parametry: ID elementu canvas oraz tablicę z ustawieniami. Klasa zawiera w sobie ustawienie właściwości, jeśli nie są one przekazywane z zewnątrz to w metodzie setSettings() ustawiane są wartości domyślne. Kolejno w konstruktorze mamy:\n\n* pobranie elementu canvas na podstawie ID\n* pobranie kontekstu\n* utworzenie obiektu klasy ParticleCreator do tworzenia cząsteczek\n* utworzenie obiektu klasy Drawer do rysowanie linii oraz cząsteczek\n* ustawienie wymiarów elementu canvas – fullscreen\n* inicjalizacja tablicy przechwowującej cząsteczki\n* wywołanie metody init\n\nMetoda init() za pomocą obiektu particleCreator tworzy cząsteczki, następnie wywołuje metodę loop(), w której to:\n\n* czyszczony jest cały ekran\n* rysowane są cząsteczki, linie oraz wykonywany jest ruch (zmiana współrzędnych o określoną wartość)\n\nNastępnie metoda loop() przekazywana jest jako argument do Window.requestAnimationFrame(), która wykonuje metodę loop() przed odświeżeniem animacji.\n\nDodatkowo w katalogu /src jest jeszcze plik:\n```\nimport Background from './modules/Background';\nexport function create(canvasID, settings) {\n  return new Background(canvasID, settings);\n};\n```\n\nEksportowana jest tutaj funkcja, która ma za zadanie przyjąć parametry oraz utworzyć obiekt klasy Background. Dzięki temu w poniższy prosty sposób możemy skorzystać z tej biblioteki:\n\n```\nEasyParticlesBackground.create('background', {\n particleColor: 'rgba(236, 208, 120, 1)',\n particleRadius: 3,\n particleDistance: 100,\n particlesCount: 200,\n lineColor: 'rgba(236, 208, 120, 1)',\n lineWidth: 1\n});\n```\n\nDokładniejszy przykład użycia można znaleźć w linkach poniżej.\n\n## Finalny efekt\n[Github](https://github.com/sarven/easy-particles-background)\n[Demo](http://projects.sarvendev.com/particles/index.html)",
      "json_metadata": "{\"tags\":[\"polish\",\"programming\",\"javascript\",\"es6\"],\"image\":[\"https://sarvendev.com/wp-content/uploads/2017/03/particles-953x536.png\"],\"links\":[\"https://paper--soccer.herokuapp.com/\",\"https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/getContext\",\"https://github.com/sarven/easy-particles-background\",\"http://projects.sarvendev.com/particles/index.html\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}"
    }
  ]
}
sarvenclaimed reward balance: 0.130 SBD, 0.028 SP
2018/01/11 21:00:30
accountsarven
reward steem0.000 STEEM
reward sbd0.130 SBD
reward vests45.062970 VESTS
Transaction InfoBlock #18894381/Trx 9abd3db2c66090e41b9b79a564e49d66266d2737
View Raw JSON Data
{
  "trx_id": "9abd3db2c66090e41b9b79a564e49d66266d2737",
  "block": 18894381,
  "trx_in_block": 48,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-11T21:00:30",
  "op": [
    "claim_reward_balance",
    {
      "account": "sarven",
      "reward_steem": "0.000 STEEM",
      "reward_sbd": "0.130 SBD",
      "reward_vests": "45.062970 VESTS"
    }
  ]
}
2018/01/10 06:54:21
curatorsarven
reward2.048251 VESTS
comment authorunknow
comment permlinkunknownews-zestawienie-ciekawych-linkow-technologicznych-po-dlugiej-przerwie
Transaction InfoBlock #18848668/Virtual Operation #19
View Raw JSON Data
{
  "trx_id": "0000000000000000000000000000000000000000",
  "block": 18848668,
  "trx_in_block": 4294967295,
  "op_in_trx": 0,
  "virtual_op": 19,
  "timestamp": "2018-01-10T06:54:21",
  "op": [
    "curation_reward",
    {
      "curator": "sarven",
      "reward": "2.048251 VESTS",
      "comment_author": "unknow",
      "comment_permlink": "unknownews-zestawienie-ciekawych-linkow-technologicznych-po-dlugiej-przerwie"
    }
  ]
}
sarvenreceived 0.130 SBD, 0.026 SP author reward for @sarven / kompozycja-ponad-dziedziczenie
2018/01/09 14:28:48
authorsarven
permlinkkompozycja-ponad-dziedziczenie
sbd payout0.130 SBD
steem payout0.000 STEEM
vesting payout43.014719 VESTS
Transaction InfoBlock #18828966/Virtual Operation #4
View Raw JSON Data
{
  "trx_id": "0000000000000000000000000000000000000000",
  "block": 18828966,
  "trx_in_block": 4294967295,
  "op_in_trx": 0,
  "virtual_op": 4,
  "timestamp": "2018-01-09T14:28:48",
  "op": [
    "author_reward",
    {
      "author": "sarven",
      "permlink": "kompozycja-ponad-dziedziczenie",
      "sbd_payout": "0.130 SBD",
      "steem_payout": "0.000 STEEM",
      "vesting_payout": "43.014719 VESTS"
    }
  ]
}
2018/01/09 14:16:06
parent authorthemarhio
parent permlinkre-sarven-codingame-czyli-rywalizuj-z-innymi-programujac-20180108t192622629z
authorsarven
permlinkre-themarhio-re-sarven-codingame-czyli-rywalizuj-z-innymi-programujac-20180109t141602020z
title
bodyNie jest płatne.
json metadata{"tags":["polish"],"app":"steemit/0.1"}
Transaction InfoBlock #18828713/Trx 3881cacda39ce5f536c79534bea3c55803b24fb7
View Raw JSON Data
{
  "trx_id": "3881cacda39ce5f536c79534bea3c55803b24fb7",
  "block": 18828713,
  "trx_in_block": 0,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-09T14:16:06",
  "op": [
    "comment",
    {
      "parent_author": "themarhio",
      "parent_permlink": "re-sarven-codingame-czyli-rywalizuj-z-innymi-programujac-20180108t192622629z",
      "author": "sarven",
      "permlink": "re-themarhio-re-sarven-codingame-czyli-rywalizuj-z-innymi-programujac-20180109t141602020z",
      "title": "",
      "body": "Nie jest płatne.",
      "json_metadata": "{\"tags\":[\"polish\"],\"app\":\"steemit/0.1\"}"
    }
  ]
}
2018/01/08 23:23:15
parent authorsarven
parent permlinkcodingame-czyli-rywalizuj-z-innymi-programujac
authorcheetah
permlinkcheetah-re-sarvencodingame-czyli-rywalizuj-z-innymi-programujac
title
bodyHi! I am a robot. I just upvoted you! I found similar content that readers might be interested in: https://sarvendev.com/2017/04/codingame-czyli-rywalizuj-innymi-programujac/
json metadata
Transaction InfoBlock #18810879/Trx a6a77831bc5ae9805d005586aae4f0aa9e210041
View Raw JSON Data
{
  "trx_id": "a6a77831bc5ae9805d005586aae4f0aa9e210041",
  "block": 18810879,
  "trx_in_block": 14,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-08T23:23:15",
  "op": [
    "comment",
    {
      "parent_author": "sarven",
      "parent_permlink": "codingame-czyli-rywalizuj-z-innymi-programujac",
      "author": "cheetah",
      "permlink": "cheetah-re-sarvencodingame-czyli-rywalizuj-z-innymi-programujac",
      "title": "",
      "body": "Hi! I am a robot. I just upvoted you! I found similar content that readers might be interested in:\nhttps://sarvendev.com/2017/04/codingame-czyli-rywalizuj-innymi-programujac/",
      "json_metadata": ""
    }
  ]
}
2018/01/08 23:23:09
votercheetah
authorsarven
permlinkcodingame-czyli-rywalizuj-z-innymi-programujac
weight8 (0.08%)
Transaction InfoBlock #18810877/Trx b74dcbcbe8a4f78228d8d18d9f6047ec61247297
View Raw JSON Data
{
  "trx_id": "b74dcbcbe8a4f78228d8d18d9f6047ec61247297",
  "block": 18810877,
  "trx_in_block": 38,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-08T23:23:09",
  "op": [
    "vote",
    {
      "voter": "cheetah",
      "author": "sarven",
      "permlink": "codingame-czyli-rywalizuj-z-innymi-programujac",
      "weight": 8
    }
  ]
}
2018/01/08 21:09:18
voterdotsconnecting
authorsarven
permlinkcodingame-czyli-rywalizuj-z-innymi-programujac
weight10000 (100.00%)
Transaction InfoBlock #18808204/Trx 45c919b110c05b7cdd3470a536250e0b11964034
View Raw JSON Data
{
  "trx_id": "45c919b110c05b7cdd3470a536250e0b11964034",
  "block": 18808204,
  "trx_in_block": 1,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-08T21:09:18",
  "op": [
    "vote",
    {
      "voter": "dotsconnecting",
      "author": "sarven",
      "permlink": "codingame-czyli-rywalizuj-z-innymi-programujac",
      "weight": 10000
    }
  ]
}
2018/01/08 19:51:33
voterpolbot
authorsarven
permlinkcodingame-czyli-rywalizuj-z-innymi-programujac
weight5000 (50.00%)
Transaction InfoBlock #18806652/Trx 09d49a598e7c185cb70610938c9122114594512d
View Raw JSON Data
{
  "trx_id": "09d49a598e7c185cb70610938c9122114594512d",
  "block": 18806652,
  "trx_in_block": 13,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-08T19:51:33",
  "op": [
    "vote",
    {
      "voter": "polbot",
      "author": "sarven",
      "permlink": "codingame-czyli-rywalizuj-z-innymi-programujac",
      "weight": 5000
    }
  ]
}
steemdelegated 16.996 SP to @sarven
2018/01/08 19:36:09
delegatorsteem
delegateesarven
vesting shares27642.584823 VESTS
Transaction InfoBlock #18806344/Trx ee1d64411723d2a09f6a09f500856dbb8587894a
View Raw JSON Data
{
  "trx_id": "ee1d64411723d2a09f6a09f500856dbb8587894a",
  "block": 18806344,
  "trx_in_block": 29,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-08T19:36:09",
  "op": [
    "delegate_vesting_shares",
    {
      "delegator": "steem",
      "delegatee": "sarven",
      "vesting_shares": "27642.584823 VESTS"
    }
  ]
}
2018/01/08 19:26:30
voterthemarhio
authorsarven
permlinkcodingame-czyli-rywalizuj-z-innymi-programujac
weight10000 (100.00%)
Transaction InfoBlock #18806152/Trx 690153a9180c7c436199c0557a11ee43fabd1891
View Raw JSON Data
{
  "trx_id": "690153a9180c7c436199c0557a11ee43fabd1891",
  "block": 18806152,
  "trx_in_block": 24,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-08T19:26:30",
  "op": [
    "vote",
    {
      "voter": "themarhio",
      "author": "sarven",
      "permlink": "codingame-czyli-rywalizuj-z-innymi-programujac",
      "weight": 10000
    }
  ]
}
2018/01/08 19:26:24
parent authorsarven
parent permlinkcodingame-czyli-rywalizuj-z-innymi-programujac
authorthemarhio
permlinkre-sarven-codingame-czyli-rywalizuj-z-innymi-programujac-20180108t192622629z
title
bodyA czy jest płatne gdy przechodzi się do dalszych etapów? Bo korzystałem kiedyś z czegoś podobnego i później trzeba było już subskrypcje wykupić.
json metadata{"tags":["polish"],"app":"steemit/0.1"}
Transaction InfoBlock #18806150/Trx 9576e75b2cfa8a56c2a6ef5407d8d1f30d4e82f0
View Raw JSON Data
{
  "trx_id": "9576e75b2cfa8a56c2a6ef5407d8d1f30d4e82f0",
  "block": 18806150,
  "trx_in_block": 10,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-08T19:26:24",
  "op": [
    "comment",
    {
      "parent_author": "sarven",
      "parent_permlink": "codingame-czyli-rywalizuj-z-innymi-programujac",
      "author": "themarhio",
      "permlink": "re-sarven-codingame-czyli-rywalizuj-z-innymi-programujac-20180108t192622629z",
      "title": "",
      "body": "A czy jest płatne gdy przechodzi się do dalszych etapów? Bo korzystałem kiedyś z czegoś podobnego i później trzeba było już subskrypcje wykupić.",
      "json_metadata": "{\"tags\":[\"polish\"],\"app\":\"steemit/0.1\"}"
    }
  ]
}
2018/01/08 19:20:30
parent author
parent permlinkpolish
authorsarven
permlinkcodingame-czyli-rywalizuj-z-innymi-programujac
titleCodinGame – czyli rywalizuj z innymi programując
bodyhttps://sarvendev.com/wp-content/uploads/2017/04/codingame.png Rozwiązywanie ciekawych problemów jest dla programistów dobrą zabawą jak i również świetną nauką. W czasach kiedy zaczynałem swoją przygodę z tą branżą, popularnym portalem zawierającym zadania do rozwiązania w różnych językach programowania był [SPOJ](http://pl.spoj.com/). Jednak według mnie nie wciągał on na dłużej, a samo rozwiązywanie coraz większej liczby zadań było mało ciekawe. Brakowało tutaj elementu bezpośredniej rywalizacji z innymi, co czyni „grę” oraz zajmowanie coraz wyższych pozycji w rankingu niesamowitym wyzwaniem. Chęć bycia lepszym od innych i wygrywaniem jest tym co przyciąga nas do gry na dłużej. Jakiś czas temu trafiłem na portal [CodinGame](https://www.codingame.com/) i na prawdę żałuję, że gdy zaczynałem i miałem mnóstwo czasu na rozwijanie się, nie było takiego serwisu. # Czym jest CodinGame? CodinGame jest platformą dla programistów o różnym poziomie zaawansowania (każdy znajdzie coś dla siebie) umożliwiającą rozgrywkę, która polega na rozwiązywaniu różnych zadań. Do wyboru jest kilka trybów: * „Practice” – łamigłówki do samodzielnego rozwiązania * „Clash of Code” – szybka rozgrywka polegająca na rozwiązaniu prostego problemu * „Contest” – dłuższa rozgrywka trwająca kilka dni, polegająca na zaprogramowaniu bota, który rywalizuje z botami stworzonymi przez innych graczy Rozwiązania nadsyłać można w różnych językach. Wybór jest naprawdę ogromny. Za wykonywane zadania dostajemy punkty doświadczenia co pozwala wbijać kolejne poziomy. Do odblokowania są rozmaite osiągnięcia np.: https://sarvendev.com/wp-content/uploads/2017/04/javascript-lover.png # Practice Ten tryb rozgrywki jest w zasadzie identyczny jak na [SPOJ](http://pl.spoj.com/) i służy raczej jako trening do gry przeciwko innym graczom. Mamy tutaj do wykonania zadania o różnym poziomie trudności. W zależności od złożoności problemu danego zadania dostajemy odpowiednią ilość punktów doświadczenia. # Clash of Code W tym trybie rozgrywki mamy do rozwiązania prosty problem w określonym czasie. Każdy z graczy może utworzyć taką rozgrywkę, do której następnie dołączają gracze. Maksymalnie dołączyć może ich ośmiu, jednak aby grę rozpocząć potrzebnych jest minimalnie dwóch graczy. Czas na rozwiązanie zadania zawiera się w przedziale od 5 do 15 minut. Zadania są podzielone na trzy typy: * Fastest – najszybsze przesłanie gotowego rozwiązania * Shortest – najkrótszy kod * Reverse – dostajemy wejście oraz wyjście i na ich podstawie musimy się domyślić jaki kod napisać Warto tutaj dodać, że przy typie zadań na najkrótszy napisany kod niektóre języki programowania mają przewagę nad pozostałymi. Przykładowo kod napisany w pythonie lub rubym będzie dużo bardziej zwięzły niż java czy c++. Należy więc wybierać odpowiednie narzędzia do danego problemu, a nie ograniczać się tylko do jednego języka. # Contest Rozgrywka w tym trybie organizowana jest co jakiś czas i trwa kilka dni (najbliższa zaplanowana jest na 10 dni). Tutaj do wygrania są już nagrody, jak i również możliwość aplikowania po konkursie na stanowiska dodane przez firmy. https://sarvendev.com/wp-content/uploads/2017/04/prizes.png Rozgrywka polega na napisaniu bota, który będzie rywalizował z botami stworzonymi przez innych graczy. # Jak przebiega rozwiązywanie zadań? Poniżej przedstawiony został ekran rozwiązywania zadania w trybie Practice. Po lewej stronie jest opis problemu, w środku znajduje się edytor, gdzie możemy wybrać dany język programowania oraz automatycznie wstawiany jest szkielet programu, czyli obsługa wejścia/wyjścia, co ułatwia start. Pod edytorem znajdują się testy, które możemy odpalać w dowolnej kolejności, jak i zbiorowo wszystkie naraz. Gdy nasze rozwiązanie jest gotowe, przesyłamy je. https://sarvendev.com/wp-content/uploads/2017/04/codingame-screen.png # Podsumowanie Według mnie CodinGame jest świetną platformą do nauki jak i rozrywki. Rozwiązywanie problemów i rywalizacja z innymi wciąga bardzo. Zachęcam więc do spróbowania swoich sił!
json metadata{"tags":["polish","programming","programowanie","codingame"],"image":["https://sarvendev.com/wp-content/uploads/2017/04/codingame.png","https://sarvendev.com/wp-content/uploads/2017/04/javascript-lover.png","https://sarvendev.com/wp-content/uploads/2017/04/prizes.png","https://sarvendev.com/wp-content/uploads/2017/04/codingame-screen.png"],"links":["http://pl.spoj.com/","https://www.codingame.com/"],"app":"steemit/0.1","format":"markdown"}
Transaction InfoBlock #18806033/Trx 89278aaa9ce5e0896a17e5e0a83765d4c2664a50
View Raw JSON Data
{
  "trx_id": "89278aaa9ce5e0896a17e5e0a83765d4c2664a50",
  "block": 18806033,
  "trx_in_block": 41,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-08T19:20:30",
  "op": [
    "comment",
    {
      "parent_author": "",
      "parent_permlink": "polish",
      "author": "sarven",
      "permlink": "codingame-czyli-rywalizuj-z-innymi-programujac",
      "title": "CodinGame – czyli rywalizuj z innymi programując",
      "body": "https://sarvendev.com/wp-content/uploads/2017/04/codingame.png\n\nRozwiązywanie ciekawych problemów jest dla programistów dobrą zabawą jak i również świetną nauką. W czasach kiedy zaczynałem swoją przygodę z tą branżą, popularnym portalem zawierającym zadania do rozwiązania w różnych językach programowania był [SPOJ](http://pl.spoj.com/). Jednak według mnie nie wciągał on na dłużej, a samo rozwiązywanie coraz większej liczby zadań było mało ciekawe. Brakowało tutaj elementu bezpośredniej rywalizacji z innymi, co czyni „grę” oraz zajmowanie coraz wyższych pozycji w rankingu niesamowitym wyzwaniem. Chęć bycia lepszym od innych i wygrywaniem jest tym co przyciąga nas do gry na dłużej.  Jakiś czas temu trafiłem na portal [CodinGame](https://www.codingame.com/) i na prawdę żałuję, że gdy zaczynałem i miałem mnóstwo czasu na rozwijanie się, nie było takiego serwisu.\n\n# Czym jest CodinGame?\nCodinGame jest platformą dla programistów o różnym poziomie zaawansowania (każdy znajdzie coś dla siebie) umożliwiającą rozgrywkę, która polega na rozwiązywaniu różnych zadań. Do wyboru jest kilka trybów:\n\n* „Practice” – łamigłówki do samodzielnego rozwiązania\n* „Clash of Code” – szybka rozgrywka polegająca na rozwiązaniu prostego problemu\n* „Contest” – dłuższa rozgrywka trwająca kilka dni, polegająca na zaprogramowaniu bota, który rywalizuje z botami stworzonymi przez innych graczy\n\nRozwiązania nadsyłać można w różnych językach. Wybór jest naprawdę ogromny. Za wykonywane zadania dostajemy punkty doświadczenia co pozwala wbijać kolejne poziomy. Do odblokowania są rozmaite osiągnięcia np.:\n\nhttps://sarvendev.com/wp-content/uploads/2017/04/javascript-lover.png\n\n# Practice\nTen tryb rozgrywki jest w zasadzie identyczny jak na [SPOJ](http://pl.spoj.com/) i służy raczej jako trening do gry przeciwko innym graczom. Mamy tutaj do wykonania zadania o różnym poziomie trudności. W zależności od złożoności problemu danego zadania dostajemy odpowiednią ilość punktów doświadczenia.\n\n# Clash of Code\nW tym trybie rozgrywki mamy do rozwiązania prosty problem w określonym czasie. Każdy z graczy może utworzyć taką rozgrywkę, do której następnie dołączają gracze. Maksymalnie dołączyć może ich ośmiu, jednak aby grę rozpocząć potrzebnych jest minimalnie dwóch graczy. Czas na rozwiązanie zadania zawiera się w przedziale od 5 do 15 minut. Zadania są podzielone na trzy typy:\n\n* Fastest – najszybsze przesłanie gotowego rozwiązania\n* Shortest – najkrótszy kod\n* Reverse – dostajemy wejście oraz wyjście i na ich podstawie musimy się domyślić jaki kod napisać\n\nWarto tutaj dodać, że przy typie zadań na najkrótszy napisany kod niektóre języki programowania mają przewagę nad pozostałymi. Przykładowo kod napisany w pythonie lub rubym będzie dużo bardziej zwięzły niż java czy c++. Należy więc wybierać odpowiednie narzędzia do danego problemu, a nie ograniczać się tylko do jednego języka.\n\n# Contest\nRozgrywka w tym trybie organizowana jest co jakiś czas i trwa kilka dni (najbliższa  zaplanowana jest na 10 dni). Tutaj do wygrania są już nagrody, jak i również możliwość aplikowania po konkursie na stanowiska dodane przez firmy.\n\nhttps://sarvendev.com/wp-content/uploads/2017/04/prizes.png\n\nRozgrywka polega na napisaniu bota, który będzie rywalizował z botami stworzonymi przez innych graczy.\n\n# Jak przebiega rozwiązywanie zadań?\nPoniżej przedstawiony został ekran rozwiązywania zadania w trybie Practice. Po lewej stronie jest opis problemu, w środku znajduje się edytor, gdzie możemy wybrać dany język programowania oraz automatycznie wstawiany jest szkielet programu, czyli obsługa wejścia/wyjścia, co ułatwia start. Pod edytorem znajdują się testy, które możemy odpalać w dowolnej kolejności, jak i zbiorowo wszystkie naraz. Gdy nasze rozwiązanie jest gotowe, przesyłamy je.\n\nhttps://sarvendev.com/wp-content/uploads/2017/04/codingame-screen.png\n\n# Podsumowanie\nWedług mnie CodinGame jest świetną platformą do nauki jak i rozrywki. Rozwiązywanie problemów i rywalizacja z innymi wciąga bardzo. Zachęcam więc do spróbowania swoich sił!",
      "json_metadata": "{\"tags\":[\"polish\",\"programming\",\"programowanie\",\"codingame\"],\"image\":[\"https://sarvendev.com/wp-content/uploads/2017/04/codingame.png\",\"https://sarvendev.com/wp-content/uploads/2017/04/javascript-lover.png\",\"https://sarvendev.com/wp-content/uploads/2017/04/prizes.png\",\"https://sarvendev.com/wp-content/uploads/2017/04/codingame-screen.png\"],\"links\":[\"http://pl.spoj.com/\",\"https://www.codingame.com/\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}"
    }
  ]
}
2018/01/07 23:31:45
voterlukmarcus
authorsarven
permlinkjak-sie-rozwijac-w-kierunku-it-i-nie-zwariowac
weight1000 (10.00%)
Transaction InfoBlock #18782298/Trx c77a1b9cf52149db75f716f709cb2d11d1b18866
View Raw JSON Data
{
  "trx_id": "c77a1b9cf52149db75f716f709cb2d11d1b18866",
  "block": 18782298,
  "trx_in_block": 19,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-07T23:31:45",
  "op": [
    "vote",
    {
      "voter": "lukmarcus",
      "author": "sarven",
      "permlink": "jak-sie-rozwijac-w-kierunku-it-i-nie-zwariowac",
      "weight": 1000
    }
  ]
}
sarvenfollowed @jamzed
2018/01/07 19:45:57
required auths[]
required posting auths["sarven"]
idfollow
json["follow",{"follower":"sarven","following":"jamzed","what":["blog"]}]
Transaction InfoBlock #18777783/Trx c841eff590cafc3bd9efb80422f9f397089635c2
View Raw JSON Data
{
  "trx_id": "c841eff590cafc3bd9efb80422f9f397089635c2",
  "block": 18777783,
  "trx_in_block": 18,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-07T19:45:57",
  "op": [
    "custom_json",
    {
      "required_auths": [],
      "required_posting_auths": [
        "sarven"
      ],
      "id": "follow",
      "json": "[\"follow\",{\"follower\":\"sarven\",\"following\":\"jamzed\",\"what\":[\"blog\"]}]"
    }
  ]
}
2018/01/07 19:45:45
votersarven
authorjamzed
permlinkre-sarven-jak-sie-rozwijac-w-kierunku-it-i-nie-zwariowac-20180105t223413977z
weight10000 (100.00%)
Transaction InfoBlock #18777779/Trx 124443de656f90f49342da1c948cbbdac6c6c8d4
View Raw JSON Data
{
  "trx_id": "124443de656f90f49342da1c948cbbdac6c6c8d4",
  "block": 18777779,
  "trx_in_block": 50,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-07T19:45:45",
  "op": [
    "vote",
    {
      "voter": "sarven",
      "author": "jamzed",
      "permlink": "re-sarven-jak-sie-rozwijac-w-kierunku-it-i-nie-zwariowac-20180105t223413977z",
      "weight": 10000
    }
  ]
}
2018/01/06 00:31:30
voterwub.sporttips
authorsarven
permlinkeksperyment-steemit
weight10000 (100.00%)
Transaction InfoBlock #18725945/Trx 0bb477ed855637b9b2e438061422f7a935f04191
View Raw JSON Data
{
  "trx_id": "0bb477ed855637b9b2e438061422f7a935f04191",
  "block": 18725945,
  "trx_in_block": 32,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-06T00:31:30",
  "op": [
    "vote",
    {
      "voter": "wub.sporttips",
      "author": "sarven",
      "permlink": "eksperyment-steemit",
      "weight": 10000
    }
  ]
}
2018/01/06 00:31:03
voterwub.sporttips
authorsarven
permlinkjak-sie-rozwijac-w-kierunku-it-i-nie-zwariowac
weight10000 (100.00%)
Transaction InfoBlock #18725936/Trx ff8c08ede61b7f84cb5685eadddd8181911b3b0e
View Raw JSON Data
{
  "trx_id": "ff8c08ede61b7f84cb5685eadddd8181911b3b0e",
  "block": 18725936,
  "trx_in_block": 34,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-06T00:31:03",
  "op": [
    "vote",
    {
      "voter": "wub.sporttips",
      "author": "sarven",
      "permlink": "jak-sie-rozwijac-w-kierunku-it-i-nie-zwariowac",
      "weight": 10000
    }
  ]
}
2018/01/05 23:56:36
voterfervi
authorsarven
permlinkjak-sie-rozwijac-w-kierunku-it-i-nie-zwariowac
weight1500 (15.00%)
Transaction InfoBlock #18725247/Trx f442291db4a0c0064b2323a3652c411cae9d2f1f
View Raw JSON Data
{
  "trx_id": "f442291db4a0c0064b2323a3652c411cae9d2f1f",
  "block": 18725247,
  "trx_in_block": 12,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-05T23:56:36",
  "op": [
    "vote",
    {
      "voter": "fervi",
      "author": "sarven",
      "permlink": "jak-sie-rozwijac-w-kierunku-it-i-nie-zwariowac",
      "weight": 1500
    }
  ]
}
2018/01/05 23:33:21
voterkaysh
authorsarven
permlinkjak-sie-rozwijac-w-kierunku-it-i-nie-zwariowac
weight10000 (100.00%)
Transaction InfoBlock #18724782/Trx 3e4a0f779f7b6cda6061a9d2d551228db2be2519
View Raw JSON Data
{
  "trx_id": "3e4a0f779f7b6cda6061a9d2d551228db2be2519",
  "block": 18724782,
  "trx_in_block": 32,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-05T23:33:21",
  "op": [
    "vote",
    {
      "voter": "kaysh",
      "author": "sarven",
      "permlink": "jak-sie-rozwijac-w-kierunku-it-i-nie-zwariowac",
      "weight": 10000
    }
  ]
}
2018/01/05 23:30:54
voterjacekw
authorsarven
permlinkjak-sie-rozwijac-w-kierunku-it-i-nie-zwariowac
weight10000 (100.00%)
Transaction InfoBlock #18724733/Trx 6ce0a0f5ea4fb767ca2b50339cb007610b0024c4
View Raw JSON Data
{
  "trx_id": "6ce0a0f5ea4fb767ca2b50339cb007610b0024c4",
  "block": 18724733,
  "trx_in_block": 40,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-05T23:30:54",
  "op": [
    "vote",
    {
      "voter": "jacekw",
      "author": "sarven",
      "permlink": "jak-sie-rozwijac-w-kierunku-it-i-nie-zwariowac",
      "weight": 10000
    }
  ]
}
2018/01/05 22:34:18
parent authorsarven
parent permlinkjak-sie-rozwijac-w-kierunku-it-i-nie-zwariowac
authorjamzed
permlinkre-sarven-jak-sie-rozwijac-w-kierunku-it-i-nie-zwariowac-20180105t223413977z
title
bodyHej, fajnie opisany problem szerokiej branzy IT :-) ja mam podobne odczucia, branza rozwija sie tak dynamicznie, ze nie da sie uczyc "na zapas". Chyba jedyne co nam zostaje to nauczyc sie szybkiego przyswajania nowej wiedzy. W moim przypadku pomaga mi solidna znajomosc podstaw i pozniej w razie potrzeby doczytanie szczegolow. Powodzenia ;-)
json metadata{"tags":["polish"],"app":"steemit/0.1"}
Transaction InfoBlock #18723602/Trx eae9c82976314d429f56cdf824ecaaf3ecade7cf
View Raw JSON Data
{
  "trx_id": "eae9c82976314d429f56cdf824ecaaf3ecade7cf",
  "block": 18723602,
  "trx_in_block": 25,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-05T22:34:18",
  "op": [
    "comment",
    {
      "parent_author": "sarven",
      "parent_permlink": "jak-sie-rozwijac-w-kierunku-it-i-nie-zwariowac",
      "author": "jamzed",
      "permlink": "re-sarven-jak-sie-rozwijac-w-kierunku-it-i-nie-zwariowac-20180105t223413977z",
      "title": "",
      "body": "Hej, fajnie opisany problem szerokiej branzy IT :-) ja mam podobne odczucia, branza rozwija sie tak dynamicznie, ze nie da sie uczyc \"na zapas\". Chyba jedyne co nam zostaje to nauczyc sie szybkiego przyswajania nowej wiedzy. W moim przypadku pomaga mi solidna znajomosc podstaw i pozniej w razie potrzeby doczytanie szczegolow. Powodzenia ;-)",
      "json_metadata": "{\"tags\":[\"polish\"],\"app\":\"steemit/0.1\"}"
    }
  ]
}
2018/01/05 22:24:21
voterjamzed
authorsarven
permlinkjak-sie-rozwijac-w-kierunku-it-i-nie-zwariowac
weight10000 (100.00%)
Transaction InfoBlock #18723403/Trx 51a9b08f8c7d863239e0fe1f5c73688add439d7f
View Raw JSON Data
{
  "trx_id": "51a9b08f8c7d863239e0fe1f5c73688add439d7f",
  "block": 18723403,
  "trx_in_block": 23,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-05T22:24:21",
  "op": [
    "vote",
    {
      "voter": "jamzed",
      "author": "sarven",
      "permlink": "jak-sie-rozwijac-w-kierunku-it-i-nie-zwariowac",
      "weight": 10000
    }
  ]
}
2018/01/05 20:51:06
voterspooks
authorsarven
permlinkjak-sie-rozwijac-w-kierunku-it-i-nie-zwariowac
weight10000 (100.00%)
Transaction InfoBlock #18721539/Trx 0e4cb4fe00a192bde8694142aad5c33c7cdbba83
View Raw JSON Data
{
  "trx_id": "0e4cb4fe00a192bde8694142aad5c33c7cdbba83",
  "block": 18721539,
  "trx_in_block": 23,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-05T20:51:06",
  "op": [
    "vote",
    {
      "voter": "spooks",
      "author": "sarven",
      "permlink": "jak-sie-rozwijac-w-kierunku-it-i-nie-zwariowac",
      "weight": 10000
    }
  ]
}
2018/01/05 19:53:00
parent author
parent permlinkpolish
authorsarven
permlinkjak-sie-rozwijac-w-kierunku-it-i-nie-zwariowac
titleJak się rozwijać w kierunku IT i nie zwariować?
bodyhttps://sarvendev.com/wp-content/uploads/2017/06/oprogramowanie.png IT rozwija się niesamowicie szybko, w związku z tym pracując w branży należy śledzić zmiany, aby po prostu z niej nie wypaść. Jednak czyhają tutaj na nas pewne pułapki, w które samemu niestety udało mi się wpaść. W tym wpisie chciałbym przedstawić swoje przemyślenia na ten temat. # Szerokie zainteresowania Zawsze interesowałem się wieloma rzeczami, nie tylko IT, bo lubię również poczytać coś na temat biologii, fizyki czy tam chemii, czyli takie naukowe rzeczy. Jednak w tym wpisie chciałbym skupić się tylko i wyłącznie na branży, w której się poruszam. Moim problemem do pewnego czasu było niesprecyzowanie priorytetów tj. co jest dla mnie ważne, wydawało mi się, że jestem w stanie ogarnąć wszystko. I tak znajdując ciekawy artykuł, nagrania z konferencji zapisywałem te materiały do sprawdzenia w późniejszym czasie. Masowo dodawałem kanały RSS do obserwowanych, zapisywałem się do różnych newsletterów (weekly etc.), kupowałem książki z różnej tematyki, tworzyłem plany projektów, które chciałbym zrealizować oraz plany rzeczy do nauki. Problemem jest tutaj czas, nie sposób wszystkiego ogarnąć. Należy sprecyzować w jakiej poddziedzinie IT chcemy się poruszać i skupiać się głównie na tych tematach. Podkreślam tutaj słowo głównie, bo oczywiście przesadzanie w drugą stronę również jest niewskazane i od nadmiernego zawężenia również można zwariować, poza tym dobrze jest czasem poszerzyć horyzonty i przyswoić sobie coś nowego, niekoniecznie związanego z naszą codzienną pracą. # Prokrastynacja Jeśli zaczynamy gromadzić rzeczy do wykonania tak jak opisałem to w poprzednim punkcie, czyli wydaje nam się, że możemy wszystko to często okazuje się, że nie wykonujemy nic, wszystko odkładamy na później. Miałem tak również przez jakiś okres czasu. Planów do zrealizowania, rzeczy do przeczytania było tak dużo, że nie wiedziałem co ruszyć najpierw, przez co oprócz pracy czy tam studiów, czyli rzeczy, które musiałem wykonać, nie robiłem nic. Ta ilość po prostu była przytłaczająca. Obecnie również mam zaplanowane projekty czy zapisane artykuły do przeczytania, których pewnie nigdy nie ruszę, jednak ilość nie jest gigantyczna, nie przytłacza mnie. Wybieram po prostu projekt, który w danym momencie realizuje i nie przejmuję się resztą. To samo z przeglądaniem RSS, subskrypcji na Youtube etc., patrzę co mnie interesuje i to czytam, ewentualnie dodaje do aplikacji Pocket (Jeśli ktoś nie kojarzy to polecam, bardzo użyteczne narzędzie do odkładania materiałów na później), resztą się kompletnie nie przejmuję. # Perfekcja Swego czasu miewałem również problem z zaczęciem projektu z obawy, że nie będzie on perfekcyjny, czyli przyczyną prokrastynacji była w tym wypadku obawa, że to co stworzę nie będzie idealne, co powodowało odkładanie tego na później. Obecnie zdarza mi się nad jakimś problemem w kodzie tak siedzieć, bo nie chcę tego rozwiązać w sposób, który wydaje mi się zbyt mało idealny. Trzeba jednak z tym walczyć. Lepiej przecież, aby coś było nie do końca idealne, ale jednak działało. # Just in time learning Ważne jest, aby nie uczyć się rzeczy na zapas, też już przez to przechodziłem. Wygląda to tak, że uczymy się przykładowo jakiegoś nowego frameworka Javascript, które jak wiemy wychodzą codziennie nowe 😀 , a nigdy nie mamy okazji go użyć. Następnie może okazać się, że dany fw nie jest już rozwijany, albo wyszła nowa wersja i nasza wiedza jest nieaktualna. Oczywiście powinniśmy posiadać jakiś własny stack technologiczny, w którym się poruszamy. Przykładowo u mnie jest to głównie PHP – Symfony i JS – Vue. Jeśli niestety dostanę w pracy projekt w Laravelu to wtedy na podstawie dokumentacji ogarnę co i jak. # Podsumowanie Podsumowując – priorytety, priorytety i jeszcze raz priorytety. Jak to wygląda w moim przypadku? Obecnie biorąc pod uwagę te rzeczy, które opisałem staram, się przyswajać informacje głównie z tematów ogólnego programowania, czyli wzorce, czysty kod itp., dopiero w następnej kolejności jest PHP, JS oraz inne powiązane rzeczy, następnie reszta tematów, które mnie interesują.
json metadata{"tags":["polish","it","programming","learning"],"image":["https://sarvendev.com/wp-content/uploads/2017/06/oprogramowanie.png"],"app":"steemit/0.1","format":"markdown"}
Transaction InfoBlock #18720378/Trx 83cd548e2bce47af05870b0237972743aee0d6fd
View Raw JSON Data
{
  "trx_id": "83cd548e2bce47af05870b0237972743aee0d6fd",
  "block": 18720378,
  "trx_in_block": 11,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-05T19:53:00",
  "op": [
    "comment",
    {
      "parent_author": "",
      "parent_permlink": "polish",
      "author": "sarven",
      "permlink": "jak-sie-rozwijac-w-kierunku-it-i-nie-zwariowac",
      "title": "Jak się rozwijać w kierunku IT i nie zwariować?",
      "body": "https://sarvendev.com/wp-content/uploads/2017/06/oprogramowanie.png\n\nIT rozwija się niesamowicie szybko, w związku z tym pracując w branży należy śledzić zmiany, aby po prostu z niej nie wypaść. Jednak czyhają tutaj na nas pewne pułapki, w  które samemu niestety udało mi się wpaść. W tym wpisie chciałbym przedstawić swoje przemyślenia na ten temat.\n\n\n# Szerokie zainteresowania\nZawsze interesowałem się wieloma rzeczami, nie tylko IT, bo lubię również poczytać coś na temat biologii, fizyki czy tam chemii, czyli takie naukowe rzeczy. Jednak w tym wpisie chciałbym skupić się tylko i wyłącznie na branży, w której się poruszam.\n\nMoim problemem do pewnego czasu było niesprecyzowanie priorytetów tj. co jest dla mnie ważne, wydawało mi się, że jestem w stanie ogarnąć wszystko. I tak znajdując ciekawy artykuł, nagrania z konferencji zapisywałem te materiały do sprawdzenia w późniejszym czasie. Masowo dodawałem kanały RSS do obserwowanych, zapisywałem się do różnych newsletterów (weekly etc.), kupowałem książki z różnej tematyki, tworzyłem plany projektów, które chciałbym zrealizować oraz plany rzeczy do nauki. Problemem jest tutaj czas, nie sposób wszystkiego ogarnąć. Należy sprecyzować w jakiej poddziedzinie IT chcemy się poruszać i skupiać się głównie na tych tematach. Podkreślam tutaj słowo głównie, bo oczywiście przesadzanie w drugą stronę również jest niewskazane i od nadmiernego zawężenia również można zwariować, poza tym dobrze jest czasem poszerzyć horyzonty i przyswoić sobie coś nowego, niekoniecznie związanego z naszą codzienną pracą.\n\n# Prokrastynacja\nJeśli zaczynamy gromadzić rzeczy do wykonania tak jak opisałem to w poprzednim punkcie, czyli wydaje nam się, że możemy wszystko to często okazuje się, że nie wykonujemy nic, wszystko odkładamy na później. Miałem tak również przez jakiś okres czasu. Planów do zrealizowania, rzeczy do przeczytania było tak dużo, że nie wiedziałem co ruszyć najpierw, przez co oprócz pracy czy tam studiów, czyli rzeczy, które musiałem wykonać, nie robiłem nic. Ta ilość po prostu była przytłaczająca.\n\nObecnie również mam zaplanowane projekty czy zapisane artykuły do przeczytania, których pewnie nigdy nie ruszę, jednak ilość nie jest gigantyczna, nie przytłacza mnie. Wybieram po prostu projekt, który w danym momencie realizuje i nie przejmuję się resztą. To samo z przeglądaniem RSS, subskrypcji na Youtube etc., patrzę co mnie interesuje i to czytam, ewentualnie dodaje do aplikacji Pocket (Jeśli ktoś nie kojarzy to polecam, bardzo użyteczne narzędzie do odkładania materiałów na później), resztą się kompletnie nie przejmuję.\n\n# Perfekcja\nSwego czasu miewałem również problem z zaczęciem projektu z obawy, że nie będzie on perfekcyjny, czyli przyczyną prokrastynacji była w tym wypadku obawa, że to co stworzę nie będzie idealne, co powodowało odkładanie tego na później. Obecnie zdarza mi się nad jakimś problemem w kodzie tak siedzieć, bo nie chcę tego rozwiązać w sposób, który wydaje mi się zbyt mało idealny. Trzeba jednak z tym walczyć. Lepiej przecież, aby coś było nie do końca idealne, ale jednak działało.\n\n# Just in time learning\nWażne jest, aby nie uczyć się rzeczy na zapas, też już przez to przechodziłem. Wygląda to tak, że uczymy się przykładowo jakiegoś nowego frameworka Javascript, które jak wiemy wychodzą codziennie nowe 😀 , a nigdy nie mamy okazji go użyć. Następnie może okazać się, że dany fw nie jest już rozwijany, albo wyszła nowa wersja i nasza wiedza jest nieaktualna. Oczywiście powinniśmy posiadać jakiś własny stack technologiczny, w którym się poruszamy. Przykładowo u mnie jest to głównie PHP – Symfony i JS – Vue. Jeśli niestety dostanę w pracy projekt w Laravelu to wtedy na podstawie dokumentacji ogarnę co i jak.\n\n# Podsumowanie\nPodsumowując – priorytety, priorytety i jeszcze raz priorytety. Jak to wygląda w moim przypadku? Obecnie biorąc pod uwagę te rzeczy, które opisałem staram, się przyswajać informacje głównie z tematów ogólnego programowania, czyli wzorce, czysty kod itp., dopiero w następnej kolejności jest PHP, JS oraz inne powiązane rzeczy, następnie reszta tematów, które mnie interesują.",
      "json_metadata": "{\"tags\":[\"polish\",\"it\",\"programming\",\"learning\"],\"image\":[\"https://sarvendev.com/wp-content/uploads/2017/06/oprogramowanie.png\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}"
    }
  ]
}
2018/01/03 22:08:09
voterlukmarcus
authorsarven
permlinkkompozycja-ponad-dziedziczenie
weight1000 (10.00%)
Transaction InfoBlock #18665499/Trx a28b2bfc5c59ac9b808e9f4ce0f5c35277952688
View Raw JSON Data
{
  "trx_id": "a28b2bfc5c59ac9b808e9f4ce0f5c35277952688",
  "block": 18665499,
  "trx_in_block": 36,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-03T22:08:09",
  "op": [
    "vote",
    {
      "voter": "lukmarcus",
      "author": "sarven",
      "permlink": "kompozycja-ponad-dziedziczenie",
      "weight": 1000
    }
  ]
}
2018/01/03 09:06:06
votersarven
authorunknow
permlinkunknownews-zestawienie-ciekawych-linkow-technologicznych-po-dlugiej-przerwie
weight10000 (100.00%)
Transaction InfoBlock #18649863/Trx dcbf2c3aaafda0193637c1f681639b0d03115b6e
View Raw JSON Data
{
  "trx_id": "dcbf2c3aaafda0193637c1f681639b0d03115b6e",
  "block": 18649863,
  "trx_in_block": 23,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-03T09:06:06",
  "op": [
    "vote",
    {
      "voter": "sarven",
      "author": "unknow",
      "permlink": "unknownews-zestawienie-ciekawych-linkow-technologicznych-po-dlugiej-przerwie",
      "weight": 10000
    }
  ]
}
sarvenclaimed reward balance: 2.171 SBD, 1.265 SP
2018/01/03 09:03:21
accountsarven
reward steem0.000 STEEM
reward sbd2.171 SBD
reward vests2056.674395 VESTS
Transaction InfoBlock #18649808/Trx 3d7b1661a9d561adce092ee8966c158b2aa369b6
View Raw JSON Data
{
  "trx_id": "3d7b1661a9d561adce092ee8966c158b2aa369b6",
  "block": 18649808,
  "trx_in_block": 11,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-03T09:03:21",
  "op": [
    "claim_reward_balance",
    {
      "account": "sarven",
      "reward_steem": "0.000 STEEM",
      "reward_sbd": "2.171 SBD",
      "reward_vests": "2056.674395 VESTS"
    }
  ]
}
2018/01/02 19:58:18
votermumshinv
authorsarven
permlinkkompozycja-ponad-dziedziczenie
weight10000 (100.00%)
Transaction InfoBlock #18634114/Trx 2c524cbd14797e23307d95713f1f15e3993485bb
View Raw JSON Data
{
  "trx_id": "2c524cbd14797e23307d95713f1f15e3993485bb",
  "block": 18634114,
  "trx_in_block": 79,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-02T19:58:18",
  "op": [
    "vote",
    {
      "voter": "mumshinv",
      "author": "sarven",
      "permlink": "kompozycja-ponad-dziedziczenie",
      "weight": 10000
    }
  ]
}
2018/01/02 19:58:18
votervedabeshina
authorsarven
permlinkkompozycja-ponad-dziedziczenie
weight10000 (100.00%)
Transaction InfoBlock #18634114/Trx 4a17d8fe3771f59cbae33b3e60fe608952cfe826
View Raw JSON Data
{
  "trx_id": "4a17d8fe3771f59cbae33b3e60fe608952cfe826",
  "block": 18634114,
  "trx_in_block": 48,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-02T19:58:18",
  "op": [
    "vote",
    {
      "voter": "vedabeshina",
      "author": "sarven",
      "permlink": "kompozycja-ponad-dziedziczenie",
      "weight": 10000
    }
  ]
}
2018/01/02 19:58:18
voterlegioner135
authorsarven
permlinkkompozycja-ponad-dziedziczenie
weight10000 (100.00%)
Transaction InfoBlock #18634114/Trx 48c38b09fd24d3e0fc607e29550612c39d2ccfdf
View Raw JSON Data
{
  "trx_id": "48c38b09fd24d3e0fc607e29550612c39d2ccfdf",
  "block": 18634114,
  "trx_in_block": 13,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-02T19:58:18",
  "op": [
    "vote",
    {
      "voter": "legioner135",
      "author": "sarven",
      "permlink": "kompozycja-ponad-dziedziczenie",
      "weight": 10000
    }
  ]
}
2018/01/02 19:45:39
voterjacekw
authorsarven
permlinkkompozycja-ponad-dziedziczenie
weight6000 (60.00%)
Transaction InfoBlock #18633861/Trx aebd51c22ed14d8647c747d208cbf9becf7fe52d
View Raw JSON Data
{
  "trx_id": "aebd51c22ed14d8647c747d208cbf9becf7fe52d",
  "block": 18633861,
  "trx_in_block": 12,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-02T19:45:39",
  "op": [
    "vote",
    {
      "voter": "jacekw",
      "author": "sarven",
      "permlink": "kompozycja-ponad-dziedziczenie",
      "weight": 6000
    }
  ]
}
2018/01/02 18:52:18
voterzilinckijviktor
authorsarven
permlinkkompozycja-ponad-dziedziczenie
weight10000 (100.00%)
Transaction InfoBlock #18632794/Trx 9c2d78b08530d0033f176d641b4afc1b5c4ef687
View Raw JSON Data
{
  "trx_id": "9c2d78b08530d0033f176d641b4afc1b5c4ef687",
  "block": 18632794,
  "trx_in_block": 10,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-02T18:52:18",
  "op": [
    "vote",
    {
      "voter": "zilinckijviktor",
      "author": "sarven",
      "permlink": "kompozycja-ponad-dziedziczenie",
      "weight": 10000
    }
  ]
}
2018/01/02 18:52:18
voterbashmak
authorsarven
permlinkkompozycja-ponad-dziedziczenie
weight10000 (100.00%)
Transaction InfoBlock #18632794/Trx d27611d5db36ff719f5c704c67397eb86020b8be
View Raw JSON Data
{
  "trx_id": "d27611d5db36ff719f5c704c67397eb86020b8be",
  "block": 18632794,
  "trx_in_block": 0,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-02T18:52:18",
  "op": [
    "vote",
    {
      "voter": "bashmak",
      "author": "sarven",
      "permlink": "kompozycja-ponad-dziedziczenie",
      "weight": 10000
    }
  ]
}
2018/01/02 18:52:15
voterdverka
authorsarven
permlinkkompozycja-ponad-dziedziczenie
weight10000 (100.00%)
Transaction InfoBlock #18632793/Trx eb26fe065b39adf957f091dc0c745b20271638ac
View Raw JSON Data
{
  "trx_id": "eb26fe065b39adf957f091dc0c745b20271638ac",
  "block": 18632793,
  "trx_in_block": 45,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-02T18:52:15",
  "op": [
    "vote",
    {
      "voter": "dverka",
      "author": "sarven",
      "permlink": "kompozycja-ponad-dziedziczenie",
      "weight": 10000
    }
  ]
}
2018/01/02 18:52:15
votersamitoev
authorsarven
permlinkkompozycja-ponad-dziedziczenie
weight10000 (100.00%)
Transaction InfoBlock #18632793/Trx b5ff9080f0a40204473e5cfeb74b12a983aa39e1
View Raw JSON Data
{
  "trx_id": "b5ff9080f0a40204473e5cfeb74b12a983aa39e1",
  "block": 18632793,
  "trx_in_block": 33,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-02T18:52:15",
  "op": [
    "vote",
    {
      "voter": "samitoev",
      "author": "sarven",
      "permlink": "kompozycja-ponad-dziedziczenie",
      "weight": 10000
    }
  ]
}
2018/01/02 18:24:03
voterbabinovsvetka
authorsarven
permlinkkompozycja-ponad-dziedziczenie
weight10000 (100.00%)
Transaction InfoBlock #18632229/Trx 1d578cb7a0170e99800f99046e905e603b543041
View Raw JSON Data
{
  "trx_id": "1d578cb7a0170e99800f99046e905e603b543041",
  "block": 18632229,
  "trx_in_block": 12,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-02T18:24:03",
  "op": [
    "vote",
    {
      "voter": "babinovsvetka",
      "author": "sarven",
      "permlink": "kompozycja-ponad-dziedziczenie",
      "weight": 10000
    }
  ]
}
2018/01/02 14:34:48
parent authorsarven
parent permlinkkompozycja-ponad-dziedziczenie
authorcheetah
permlinkcheetah-re-sarvenkompozycja-ponad-dziedziczenie
title
bodyHi! I am a robot. I just upvoted you! I found similar content that readers might be interested in: https://sarvendev.com/2017/10/kompozycja-ponad-dziedziczenie/
json metadata
Transaction InfoBlock #18627646/Trx 17c9f09f4a6c9d8c113e30db66a00c1aa426b918
View Raw JSON Data
{
  "trx_id": "17c9f09f4a6c9d8c113e30db66a00c1aa426b918",
  "block": 18627646,
  "trx_in_block": 9,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-02T14:34:48",
  "op": [
    "comment",
    {
      "parent_author": "sarven",
      "parent_permlink": "kompozycja-ponad-dziedziczenie",
      "author": "cheetah",
      "permlink": "cheetah-re-sarvenkompozycja-ponad-dziedziczenie",
      "title": "",
      "body": "Hi! I am a robot. I just upvoted you! I found similar content that readers might be interested in:\nhttps://sarvendev.com/2017/10/kompozycja-ponad-dziedziczenie/",
      "json_metadata": ""
    }
  ]
}
2018/01/02 14:34:42
votercheetah
authorsarven
permlinkkompozycja-ponad-dziedziczenie
weight8 (0.08%)
Transaction InfoBlock #18627644/Trx f21cf1780ea810f971aa9d33b9f035b98219d01b
View Raw JSON Data
{
  "trx_id": "f21cf1780ea810f971aa9d33b9f035b98219d01b",
  "block": 18627644,
  "trx_in_block": 27,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-02T14:34:42",
  "op": [
    "vote",
    {
      "voter": "cheetah",
      "author": "sarven",
      "permlink": "kompozycja-ponad-dziedziczenie",
      "weight": 8
    }
  ]
}
2018/01/02 14:28:48
parent author
parent permlinkpolish
authorsarven
permlinkkompozycja-ponad-dziedziczenie
titleKompozycja ponad dziedziczenie
bodyJedną z możliwości programowania obiektowego jest dziedziczenie. Daje nam ono możliwość powtórnego wykorzystania kodu poprzez tworzenie podklas. Warto mieć na uwadze, że nie jest ono złotym środkiem, a jednak bywa ono często nadużywane. # Definicje **Dziedziczenie** – mechanizm programowania obiektowego, służący do współdzielenia metod oraz składowych pomiędzy klasami. Klasa podrzędna dziedziczy po klasie bazowej, co oznacza, że oprócz własnych właściwości oraz zachowań, zawiera również te z klasy bazowej. **Kompozycja** – tak jak dziedziczenie jest metodą pozwalającą na powtórne wykorzystanie danego rozwiązania. Z tym, że w przypadku kompozycji mamy do czynienia ze składaniem obiektów. Klasa zbudowana jest z innych klas, co znaczy, że obiekt takiej klasy agreguje obiekty innych klas i deleguje odpowiednie działania do nich. # Co jest nie tak z dziedziczeniem? Dziedziczenie klas definiowane jest statycznie, co znaczy, że nie mamy możliwości zmiany implementacji w czasie wykonywania aplikacji. Implementacja podklas zależna jest od implementacji klasy bazowej, więc zmiany w klasie bazowej często wymuszają również zmiany w podklasach. Rozbudowane hierarchie dziedziczenia wpływają również negatywnie na testowanie kodu oraz analizę danego rozwiązania. # Dlaczego kompozycja jest lepsza niż dziedziczenie? Poprzez zastosowanie kompozycji zyskujemy pewną elastyczność. W razie potrzeby możemy dynamicznie w czasie wykonywania aplikacji zmienić implementację jakiej używamy. Kolejnym plusem jest rozbicie klas na mniejsze, co pozwala nam na dostarczanie rozwiązań zgodnych z zasadami programowania obiektowego SOLID. Załóżmy, że musimy zaprojektować system, w którym do czynienia będziemy mieli z pracownikami podzielonymi na poszczególne stanowiska np. Developer, Project Manager itp. Każdy pracownik będzie miał imię, nazwisko, jednak różnica będzie taka, że do developera będziemy mogli przypisać jego główny język programowania, natomiast do Project Managera będzie możliwość dodania projektów jakimi zarządza. Do tego momentu oczywiście myślimy o dziedziczeniu. Jednak dodatkowo każdy pracownik może rozliczać swoje wynagrodzenie na różne sposoby np. umowa o pracę lub własna działalność(b2b). Czy widzisz tutaj jakiś dobry sposób dziedziczenia? Z racji, że zarówno Developer jak i Project Manager może wybrać dowolny sposób rozliczania, to najwygodniej jest tutaj zastosować kompozycję. Chcąc załatwić sprawę za pomocą dziedziczenia, nie jesteśmy w stanie dostarczyć rozwiązania łatwego w późniejszym utrzymaniu. Przejdźmy zatem do implementacji. Zaczniemy najpierw od abstrakcyjnej klasy bazowej pracownika oraz odpowiednich interfejsów. Abstrakcyjnej dlatego, że zakładamy iż nie będzie „zwykłego” pracownika, a jedynie pracownicy z odpowiednimi tytułami: Developer etc., mającymi własne cechy charakterystyczne. ```php <?php namespace App\Employee; use App\Salary\SalaryCalculatorInterface; abstract class Employee implements SalaryCalculable { /** * @var string */ protected $firstName; /** * @var string */ protected $lastName; /** * @var float */ protected $netSalaryPerHour; /** * @var SalaryCalculatorInterface */ protected $salaryCalculator; public function __construct(SalaryCalculatorInterface $salaryCalculator) { $this->salaryCalculator = $salaryCalculator; $this->netSalaryPerHour = 0; } public function getFirstName(): string { return $this->firstName; } public function setFirstName(string $firstName): Employee { $this->firstName = $firstName; return $this; } public function getLastName(): string { return $this->lastName; } public function setLastName(string $lastName): Employee { $this->lastName = $lastName; return $this; } public function getNetSalaryPerHour(): float { return $this->netSalaryPerHour; } public function setNetSalaryPerHour(float $netSalaryPerHour): Employee { $this->netSalaryPerHour = $netSalaryPerHour; return $this; } public function getSalary(): float { $this->salaryCalculator->calcSalary($this->netSalaryPerHour); } } ``` ```php <?php namespace App\Employee; interface SalaryCalculable { public function getSalary(): float; } ``` ```php <?php namespace App\Salary; interface SalaryCalculatorInterface { public function calcSalary(float $netPerHour): float; } ``` Interfejs **SalaryCalculatorInterface** implementowany będzie przez klasy odpowiedzialne za różne sposoby rozliczania wynagrodzenia. Następnie implementujemy klasy reprezentujące konkretnych pracowników według założeń opisanych wyżej. ```php <?php namespace App\Employee; class Developer extends Employee { /** * @var string */ protected $programmingLanguage; /** * @return string */ public function getProgrammingLanguage(): string { return $this->programmingLanguage; } /** * @param string $programmingLanguage * @return Developer */ public function setProgrammingLanguage($programmingLanguage): Developer { $this->programmingLanguage = $programmingLanguage; return $this; } } ``` ```php <?php namespace App\Employee; class ProjectManager extends Employee { /** * @var string[] */ protected $projects; /** * @return string[] */ public function getProjects(): array { return $this->projects; } public function addProject(string $project): ProjectManager { if (!in_array($project, $this->projects)) { $this->projects[] = $project; } return $this; } public function removeProject(string $project): ProjectManager { if ($index = array_search($project, $this->projects)) { unset($this->projects[$index]); } return $this; } } ``` Pozostała nam jedynie szczegółowa implementacja klas odpowiedzialnych za metody rozliczania. ```php <?php namespace App\Salary; final class EmploymentContractSalaryCalculator implements SalaryCalculatorInterface { public function calcSalary(float $netPerHour): float { return 15000; } } ``` ```php <?php namespace App\Salary; final class B2bSalaryCalculator implements SalaryCalculatorInterface { public function calcSalary(float $netPerHour): float { return 30000; } } ``` Dla uproszczenia przykłady nie zagłębiamy się w szczegóły, tylko podajemy stałe kwoty. W prawdziwym projekcie warto byłoby jednak nazwać dokładniej czy zwracana kwota to brutto czy netto. Przedstawione klasy użyć możemy w następujący sposób: ```php <?php use App\Employee\Developer; use App\Employee\ProjectManager; use App\Salary\B2bSalaryCalculator; use App\Salary\EmploymentContractSalaryCalculator; $firstDeveloper = new Developer(new B2bSalaryCalculator()); $secondDeveloper = new Developer(new EmploymentContractSalaryCalculator()); $projectManager = new ProjectManager(new EmploymentContractSalaryCalculator()); ``` # Podsumowanie Stosując kompozycję aplikacja przez większą liczbę klas będzie sprawiała wrażenie bardziej złożonej. Po głębszej analizie powinno okazać się jednak, że łatwiej jest przewidzieć zachowanie danego kodu niż ma to miejsce przy rozbudowanym dziedziczeniu. Oczywiście kompozycja oraz dziedziczenie powinny ze sobą współgrać, a dostarczone rozwiązanie powinno zostać przemyślane pod kątem przyszłych zmian. Warto jednak pamiętać, że idealnych rozwiązań nie ma i często jest tak, że nie jesteśmy w stanie przewidzieć, że coś się zmieni. Ciężko jest również napisać kod przygotowany na wszystkie zmiany. Dążenie do perfekcji nie jest niczym dobrym, należy po prostu w razie wystąpienia zmian, których nie przewidzieliśmy dostosować odpowiednio kod i zostawić go lepszym niż zastaliśmy.
json metadata{"tags":["polish","programming","programowanie","php"],"app":"steemit/0.1","format":"markdown"}
Transaction InfoBlock #18627526/Trx 96d38f051ebcc6e1f86ca49c932307335a90424a
View Raw JSON Data
{
  "trx_id": "96d38f051ebcc6e1f86ca49c932307335a90424a",
  "block": 18627526,
  "trx_in_block": 1,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2018-01-02T14:28:48",
  "op": [
    "comment",
    {
      "parent_author": "",
      "parent_permlink": "polish",
      "author": "sarven",
      "permlink": "kompozycja-ponad-dziedziczenie",
      "title": "Kompozycja ponad dziedziczenie",
      "body": "Jedną z możliwości programowania obiektowego jest dziedziczenie. Daje nam ono możliwość powtórnego wykorzystania kodu poprzez tworzenie podklas. Warto mieć na uwadze, że nie jest ono złotym środkiem, a jednak bywa ono często nadużywane.\n\n# Definicje\n\n**Dziedziczenie** – mechanizm programowania obiektowego, służący do współdzielenia metod oraz składowych pomiędzy klasami. Klasa podrzędna dziedziczy po klasie bazowej, co oznacza, że oprócz własnych właściwości oraz zachowań, zawiera również te z klasy bazowej.\n\n**Kompozycja** – tak jak dziedziczenie jest metodą pozwalającą na powtórne wykorzystanie danego rozwiązania. Z tym, że w przypadku kompozycji mamy do czynienia ze składaniem obiektów. Klasa zbudowana jest z innych klas, co znaczy, że obiekt takiej klasy agreguje obiekty innych klas i deleguje odpowiednie działania do nich.\n\n# Co jest nie tak z dziedziczeniem?\n\nDziedziczenie klas definiowane jest statycznie, co znaczy, że nie mamy możliwości zmiany implementacji w czasie wykonywania aplikacji. Implementacja podklas zależna jest od implementacji klasy bazowej, więc zmiany w klasie bazowej często wymuszają również zmiany w podklasach. Rozbudowane hierarchie dziedziczenia wpływają również negatywnie na testowanie kodu oraz analizę danego rozwiązania.\n\n# Dlaczego kompozycja jest lepsza niż dziedziczenie?\nPoprzez zastosowanie kompozycji zyskujemy pewną elastyczność.  W razie potrzeby możemy dynamicznie w czasie wykonywania aplikacji zmienić implementację jakiej używamy. Kolejnym plusem jest rozbicie klas na mniejsze, co pozwala nam na dostarczanie rozwiązań zgodnych z zasadami programowania obiektowego SOLID.\n\nZałóżmy, że musimy zaprojektować system, w którym do czynienia będziemy mieli z pracownikami podzielonymi na poszczególne stanowiska np. Developer, Project Manager itp.  Każdy pracownik będzie miał imię, nazwisko, jednak różnica będzie taka, że do developera będziemy mogli przypisać jego główny język programowania, natomiast do Project Managera będzie możliwość dodania projektów jakimi zarządza. Do tego momentu oczywiście myślimy o dziedziczeniu.\n\nJednak dodatkowo każdy pracownik może rozliczać swoje wynagrodzenie na różne sposoby np. umowa o pracę lub własna działalność(b2b). Czy widzisz tutaj jakiś dobry sposób dziedziczenia? Z racji, że zarówno Developer jak i Project Manager może wybrać dowolny sposób rozliczania, to najwygodniej jest tutaj zastosować kompozycję. Chcąc załatwić sprawę za pomocą dziedziczenia, nie jesteśmy w stanie dostarczyć rozwiązania łatwego w późniejszym utrzymaniu.\n\nPrzejdźmy zatem do implementacji. Zaczniemy najpierw od abstrakcyjnej klasy bazowej pracownika oraz odpowiednich interfejsów. Abstrakcyjnej dlatego, że zakładamy iż nie będzie „zwykłego” pracownika, a jedynie pracownicy z odpowiednimi tytułami: Developer etc., mającymi własne cechy charakterystyczne.\n\n```php\n<?php\n\nnamespace App\\Employee;\n\nuse App\\Salary\\SalaryCalculatorInterface;\n\nabstract class Employee implements SalaryCalculable\n{\n    /**\n     * @var string\n     */\n    protected $firstName;\n\n    /**\n     * @var string\n     */\n    protected $lastName;\n\n    /**\n     * @var float\n     */\n    protected $netSalaryPerHour;\n\n    /**\n     * @var SalaryCalculatorInterface\n     */\n    protected $salaryCalculator;\n\n    public function __construct(SalaryCalculatorInterface $salaryCalculator)\n    {\n        $this->salaryCalculator = $salaryCalculator;\n        $this->netSalaryPerHour = 0;\n    }\n\n    public function getFirstName(): string\n    {\n        return $this->firstName;\n    }\n\n    public function setFirstName(string $firstName): Employee\n    {\n        $this->firstName = $firstName;\n        return $this;\n    }\n\n    public function getLastName(): string\n    {\n        return $this->lastName;\n    }\n\n    public function setLastName(string $lastName): Employee\n    {\n        $this->lastName = $lastName;\n        return $this;\n    }\n\n    public function getNetSalaryPerHour(): float\n    {\n        return $this->netSalaryPerHour;\n    }\n\n    public function setNetSalaryPerHour(float $netSalaryPerHour): Employee\n    {\n        $this->netSalaryPerHour = $netSalaryPerHour;\n        return $this;\n    }\n\n    public function getSalary(): float\n    {\n        $this->salaryCalculator->calcSalary($this->netSalaryPerHour);\n    }\n}\n```    \n```php\n<?php\n\nnamespace App\\Employee;\n\ninterface SalaryCalculable\n{\n    public function getSalary(): float;\n}\n\n```   \n\n```php\n<?php\n\nnamespace App\\Salary;\n\ninterface SalaryCalculatorInterface\n{\n    public function calcSalary(float $netPerHour): float;\n}\n```   \n\nInterfejs **SalaryCalculatorInterface** implementowany będzie przez klasy odpowiedzialne za różne sposoby rozliczania wynagrodzenia. Następnie implementujemy klasy reprezentujące konkretnych pracowników według założeń opisanych wyżej.\n\n```php\n<?php\n\nnamespace App\\Employee;\n\nclass Developer extends Employee\n{\n    /**\n     * @var string\n     */\n    protected $programmingLanguage;\n\n    /**\n     * @return string\n     */\n    public function getProgrammingLanguage(): string\n    {\n        return $this->programmingLanguage;\n    }\n\n    /**\n     * @param string $programmingLanguage\n     * @return Developer\n     */\n    public function setProgrammingLanguage($programmingLanguage): Developer\n    {\n        $this->programmingLanguage = $programmingLanguage;\n        return $this;\n    }\n}\n```    \n\n```php\n<?php\n\nnamespace App\\Employee;\n\nclass ProjectManager extends Employee\n{\n    /**\n     * @var string[]\n     */\n    protected $projects;\n\n    /**\n     * @return string[]\n     */\n    public function getProjects(): array\n    {\n        return $this->projects;\n    }\n\n    public function addProject(string $project): ProjectManager\n    {\n        if (!in_array($project, $this->projects)) {\n            $this->projects[] = $project;\n        }\n        return $this;\n    }\n\n    public function removeProject(string $project): ProjectManager\n    {\n        if ($index = array_search($project, $this->projects)) {\n            unset($this->projects[$index]);\n        }\n        return $this;\n    }\n}\n```    \nPozostała nam jedynie szczegółowa implementacja klas odpowiedzialnych za metody rozliczania.\n\n```php\n<?php\n\nnamespace App\\Salary;\n\nfinal class EmploymentContractSalaryCalculator implements SalaryCalculatorInterface\n{\n    public function calcSalary(float $netPerHour): float\n    {\n        return 15000;\n    }\n}\n```   \n\n```php\n<?php\n\nnamespace App\\Salary;\n\nfinal class B2bSalaryCalculator implements SalaryCalculatorInterface\n{\n    public function calcSalary(float $netPerHour): float\n    {\n        return 30000;\n    }\n}\n```\n\nDla uproszczenia przykłady nie zagłębiamy się w szczegóły, tylko podajemy stałe kwoty. W prawdziwym projekcie warto byłoby jednak nazwać dokładniej czy zwracana kwota to brutto czy netto. Przedstawione klasy użyć możemy w następujący sposób:\n```php\n<?php\n\nuse App\\Employee\\Developer;\nuse App\\Employee\\ProjectManager;\nuse App\\Salary\\B2bSalaryCalculator;\nuse App\\Salary\\EmploymentContractSalaryCalculator;\n\n$firstDeveloper = new Developer(new B2bSalaryCalculator());\n$secondDeveloper = new Developer(new EmploymentContractSalaryCalculator());\n\n$projectManager = new ProjectManager(new EmploymentContractSalaryCalculator());\n```\n\n# Podsumowanie\nStosując kompozycję aplikacja przez większą liczbę klas będzie sprawiała wrażenie bardziej złożonej. Po głębszej analizie powinno okazać się jednak, że łatwiej jest przewidzieć zachowanie danego kodu niż ma to miejsce przy rozbudowanym dziedziczeniu.\n\nOczywiście kompozycja oraz dziedziczenie powinny ze sobą współgrać, a dostarczone rozwiązanie powinno zostać przemyślane pod kątem przyszłych zmian. Warto jednak pamiętać, że idealnych rozwiązań nie ma i często jest tak, że nie jesteśmy w stanie przewidzieć, że coś się zmieni. Ciężko jest również napisać kod przygotowany na wszystkie zmiany. Dążenie do perfekcji nie jest niczym dobrym, należy po prostu w razie wystąpienia zmian, których nie przewidzieliśmy dostosować odpowiednio kod i zostawić go lepszym niż zastaliśmy.",
      "json_metadata": "{\"tags\":[\"polish\",\"programming\",\"programowanie\",\"php\"],\"app\":\"steemit/0.1\",\"format\":\"markdown\"}"
    }
  ]
}
sarvenreceived 0.235 SBD, 0.129 SP author reward for @sarven / prywatnosc-a-komu-to-potrzebne
2017/12/19 20:10:51
authorsarven
permlinkprywatnosc-a-komu-to-potrzebne
sbd payout0.235 SBD
steem payout0.000 STEEM
vesting payout209.143319 VESTS
Transaction InfoBlock #18231552/Virtual Operation #9
View Raw JSON Data
{
  "trx_id": "0000000000000000000000000000000000000000",
  "block": 18231552,
  "trx_in_block": 4294967295,
  "op_in_trx": 0,
  "virtual_op": 9,
  "timestamp": "2017-12-19T20:10:51",
  "op": [
    "author_reward",
    {
      "author": "sarven",
      "permlink": "prywatnosc-a-komu-to-potrzebne",
      "sbd_payout": "0.235 SBD",
      "steem_payout": "0.000 STEEM",
      "vesting_payout": "209.143319 VESTS"
    }
  ]
}
sarvenreceived 1.936 SBD, 1.136 SP author reward for @sarven / eksperyment-steemit
2017/12/18 18:37:15
authorsarven
permlinkeksperyment-steemit
sbd payout1.936 SBD
steem payout0.000 STEEM
vesting payout1847.531076 VESTS
Transaction InfoBlock #18200885/Virtual Operation #11
View Raw JSON Data
{
  "trx_id": "0000000000000000000000000000000000000000",
  "block": 18200885,
  "trx_in_block": 4294967295,
  "op_in_trx": 0,
  "virtual_op": 11,
  "timestamp": "2017-12-18T18:37:15",
  "op": [
    "author_reward",
    {
      "author": "sarven",
      "permlink": "eksperyment-steemit",
      "sbd_payout": "1.936 SBD",
      "steem_payout": "0.000 STEEM",
      "vesting_payout": "1847.531076 VESTS"
    }
  ]
}
2017/12/18 14:52:21
votersarven
authorblockchain-wroc
permlinkblockchain-wroclaw-meetup-noisy-mowi-o-tym-czym-jest-blockchain-i-jak-dziala
weight10000 (100.00%)
Transaction InfoBlock #18196388/Trx 9d608e4824e5da56b1eb20a2b204b1168ef1bde8
View Raw JSON Data
{
  "trx_id": "9d608e4824e5da56b1eb20a2b204b1168ef1bde8",
  "block": 18196388,
  "trx_in_block": 7,
  "op_in_trx": 0,
  "virtual_op": 0,
  "timestamp": "2017-12-18T14:52:21",
  "op": [
    "vote",
    {
      "voter": "sarven",
      "author": "blockchain-wroc",
      "permlink": "blockchain-wroclaw-meetup-noisy-mowi-o-tym-czym-jest-blockchain-i-jak-dziala",
      "weight": 10000
    }
  ]
}

Account Metadata

POSTING JSON METADATA
profile{"profile_image":"https://www.wykop.pl/cdn/c3397992/sarveniusz_rzbNo7SvZk,q150.jpg","name":"sarven","about":"Software developer, blogger","location":"Poland","website":"https://sarvendev.com"}
JSON METADATA
profile{"profile_image":"https://www.wykop.pl/cdn/c3397992/sarveniusz_rzbNo7SvZk,q150.jpg","name":"sarven","about":"Software developer, blogger","location":"Poland","website":"https://sarvendev.com"}
{
  "posting_json_metadata": {
    "profile": {
      "profile_image": "https://www.wykop.pl/cdn/c3397992/sarveniusz_rzbNo7SvZk,q150.jpg",
      "name": "sarven",
      "about": "Software developer, blogger",
      "location": "Poland",
      "website": "https://sarvendev.com"
    }
  },
  "json_metadata": {
    "profile": {
      "profile_image": "https://www.wykop.pl/cdn/c3397992/sarveniusz_rzbNo7SvZk,q150.jpg",
      "name": "sarven",
      "about": "Software developer, blogger",
      "location": "Poland",
      "website": "https://sarvendev.com"
    }
  }
}

Auth Keys

Owner
Single Signature
Public Keys
STM7YZykm7TzMCDtY41f7AxVo5pNfkQxbni1coS7UX1SrEZ84rhU91/1
Active
Single Signature
Public Keys
STM4xmenqUjxALSuRvqAZ4XBqksGv5Lx5xug4RZDFjeRjoFHBfDir1/1
Posting
Single Signature
Public Keys
STM66dMQCrS7ErbuSLgxxNChpMmf74k4EUTrahs97ePF1S6kde26n1/1
Memo
STM7n3WAf3w5d2UnGv5YCvS9nEKLZSfBYsM7R33VmjdWEF12CdkZ3
{
  "owner": {
    "account_auths": [],
    "key_auths": [
      [
        "STM7YZykm7TzMCDtY41f7AxVo5pNfkQxbni1coS7UX1SrEZ84rhU9",
        1
      ]
    ],
    "weight_threshold": 1
  },
  "active": {
    "account_auths": [],
    "key_auths": [
      [
        "STM4xmenqUjxALSuRvqAZ4XBqksGv5Lx5xug4RZDFjeRjoFHBfDir",
        1
      ]
    ],
    "weight_threshold": 1
  },
  "posting": {
    "account_auths": [],
    "key_auths": [
      [
        "STM66dMQCrS7ErbuSLgxxNChpMmf74k4EUTrahs97ePF1S6kde26n",
        1
      ]
    ],
    "weight_threshold": 1
  },
  "memo": "STM7n3WAf3w5d2UnGv5YCvS9nEKLZSfBYsM7R33VmjdWEF12CdkZ3"
}

Witness Votes

0 / 30
No active witness votes.
[]