Author Topic: Code Academy Learning Path?  (Read 25008 times)

0 Members and 1 Guest are viewing this topic.

Offline fuzzy

JetBrains recently released a new version of PyCharm Edu.  PyCharm is a fantastic Python IDE, and the Edu edition is a free version loaded up with Python courses and exercises to get you up-to-speed.

Because PyCharm Edu is built on top of a real working Python IDE, you also get the benefits of code inspection, pop-up documentation, and more.  It's like Code Academy on steroids.  You can also browse and download new lessons directly from PyCharm Edu.

Here's a video of PyCharm Edu in action:
https://youtu.be/ztXR9tP1KVc

You can download PyCharm Edu here:
https://www.jetbrains.com/pycharm-edu/download/

Disclaimer:  I haven't used PyCharm Edu, but I am a professional Python developer and have used several IDEs over the past several years, and I can attest to the exceptional quality of JetBrains products.  If PyCharm Edu is built on top of the PyCharm IDE (it is), then I'm confident that it is really good.

You are a badass man...can i upvote you?  wait... :(
WhaleShares==DKP; BitShares is our Community! 
ShareBits and WhaleShares = Love :D

Offline 70231f697a2b3c2b

  • Full Member
  • ***
  • Posts: 61
    • View Profile
JetBrains recently released a new version of PyCharm Edu.  PyCharm is a fantastic Python IDE, and the Edu edition is a free version loaded up with Python courses and exercises to get you up-to-speed.

Because PyCharm Edu is built on top of a real working Python IDE, you also get the benefits of code inspection, pop-up documentation, and more.  It's like Code Academy on steroids.  You can also browse and download new lessons directly from PyCharm Edu.

Here's a video of PyCharm Edu in action:
https://youtu.be/ztXR9tP1KVc

You can download PyCharm Edu here:
https://www.jetbrains.com/pycharm-edu/download/

Disclaimer:  I haven't used PyCharm Edu, but I am a professional Python developer and have used several IDEs over the past several years, and I can attest to the exceptional quality of JetBrains products.  If PyCharm Edu is built on top of the PyCharm IDE (it is), then I'm confident that it is really good.
« Last Edit: August 11, 2016, 11:17:38 pm by 70231f697a2b3c2b »

unreadPostsSinceLastVisit

  • Guest
Hey sorry for the vanishing act. Lost control of my life... again...

Offline 70231f697a2b3c2b

  • Full Member
  • ***
  • Posts: 61
    • View Profile
If you want a really cool intro to Python and cryptography, work your way through https://inventwithpython.com/hacking/chapters/ .  It will help you get up to speed with Python, and you'll be learning by writing programs to implement and break cryptographic ciphers.

Once you're feeling confident, then move onto https://cryptopals.com/ .

You are awesome....

555 Well, I'll take a teeny bit of credit for posting the links, but I am really amazed at the knowledge (and generosity) demonstrated by the creators of those projects.

Incidentally, anyone who's interested in working through these exercises collaboratively, send me a PM.

Offline fuzzy

If you want a really cool intro to Python and cryptography, work your way through https://inventwithpython.com/hacking/chapters/ .  It will help you get up to speed with Python, and you'll be learning by writing programs to implement and break cryptographic ciphers.

Once you're feeling confident, then move onto https://cryptopals.com/ .

You are awesome....
WhaleShares==DKP; BitShares is our Community! 
ShareBits and WhaleShares = Love :D

Offline 70231f697a2b3c2b

  • Full Member
  • ***
  • Posts: 61
    • View Profile
If you want a really cool intro to Python and cryptography, work your way through https://inventwithpython.com/hacking/chapters/ .  It will help you get up to speed with Python, and you'll be learning by writing programs to implement and break cryptographic ciphers.

Once you're feeling confident, then move onto https://cryptopals.com/ .

Offline 70231f697a2b3c2b

  • Full Member
  • ***
  • Posts: 61
    • View Profile
I'm mostly following, I think. In step 6, how does it interpret that part? I'm thinking I only need lines 248, 251, and 257 in airsign _main_.py to do what I need to do if I instantiate my own rpc object.

Start with a simple example:

Code: [Select]
the_answer = 42

class Test1(object):
  def __getattr__(self, name):
    return the_answer

t1 = Test1()

t1.foo # 42
t1.bar # 42

t1.foo + t1.bar # 84

In the first example, wherever you see `t.something`, you can substitute `the_answer`, and that's more or less what Python does, too.

Now let's make it a little more interesting:

Code: [Select]
def get_the_answer():
  return 42

get_the_answer # <function get_the_answer at 0x10906ec80>
get_the_answer() # 42

Once you define a function, you can treat it just like any other variable.  `the_answer` is a reference to a variable containing the value `42`, and `get_the_answer` is a reference to a function that returns `42` when invoked.

Code: [Select]
class Test2(object):
  def __getattr__(self, name):
    return get_the_answer

t2 = Test2()

t2.foo # <function get_the_answer at 0x10906ec80>
t2.bar # <function get_the_answer at 0x10906ec80>

t2.foo() # 42

`Test2.__getattr__` returns a reference to the `get_the_answer` function, so wherever you see `t2.something`, you can substitute `get_the_answer`:

t2.foo => get_the_answer => <function get_the_answer at 0x10906ec80>
t2.foo() => get_the_answer() => 42

One more example to bring it closer to what you saw in airsign:

Code: [Select]
class Test3(object):
  def __getattr__(self, name):
    def create_request(*args):
      return {'params': [name, args], 'method': 'query'}
    return create_request

t3 = Test3()

t3.foo # <function create_request at 0x10906ec80>
t3.bar # <function create_request at 0x109088668>

t3.foo() # {'params': ['foo', ()], 'method': 'query'}
t3.bar(1, 2, 3) # {'params': ['bar, (1, 2, 3)], 'method': 'query'}

Unlike `Test2.__getattr__` where it returned a reference to the same function every time, `Test3.__getattr__` creates a function on the fly and returns that, but otherwise the idea is the same.

__getattr__ seems like a method for choosing from a variety of methods based on the input, does that seem accurate?

Not quite.  In this case, `GrapheneWebsocketRPC.__getattr__` literally creates a new function every time you call it, similar to `Test3.__getattr__`.  You can verify this by checking the object ID of the resulting function:

Code: [Select]
t2.foo # <... at 0x10906ec80>
t2.foo # <... at 0x10906ec80> (same)

t3.foo # <... at 0x10907ccf8>
t3.foo # <... at 0x109075758> (different)

(if you run the code on your system, the exact values will be slightly different, but the result will be the same; `t2.foo` always returns the same instance, but `t3.foo` always returns a different one)

Note:  when you write your own classes, you don't have to use `__getattr__` this way.  It has many uses; generating a function on the fly is just one of them.

unreadPostsSinceLastVisit

  • Guest
So far it looks like you're on the right track.

The tricky part is that GrapheneWebsocketRPC defines a magic method called __getattr__.

When you try to access an attribute that does not exist, Python will try to call that object's `__getattr__` method instead (if the object doesn't have a `__getattr__`, Python will raise an `AttributeError`).

Here's what's going on when you call `rpc.get_account_balances(account["id"], [])`:

  • First, Python has to resolve `rpc.get_account_balances`.  Ignore the `(account["id"], [])` part for now.
  • Python looks for `rpc.get_account_balances`, but it doesn't exist.
  • Python looks for `rpc.__getattr__`, which does exist.*
  • Python invokes `rpc.__getattr__('get_account_balances')` (note that it passes the name of the attribute it's trying to resolve, not the parameters `account["id"], []` )
  • `rpc.__getattr__` returns a function that will send a `get_account_balances` API request when invoked.
  • Now that Python has resolved `rpc.get_account_balances`, it can now interpret the `(account["id"], [])` part.
  • Python effectively replaces `rpc.get_account_balances` with the function from step 5, and it then invokes the function using the parameters `(account["id"], [])`.

The end result is an API request that looks something like this (I think "xeroc" is actually replaced by a numeric ID, but otherwise this should be correct; I'm interpreting the code manually):

Code: [Select]
{
  "method": "query",
  "params": [0, get_account_balances, ["xeroc", []]],
  "jsonrpc": "2.0",
  "id": 0
}

You can verify this by adding `print query` just before `self.rpcexec(query)`

* (it's actually a little more complicated than this, but the extra bits aren't important here, so I omitted them for KISS)

I'm mostly following, I think. In step 6, how does it interpret that part? I'm thinking I only need lines 248, 251, and 257 in airsign _main_.py to do what I need to do if I instantiate my own rpc object.

__getattr__ seems like a method for choosing from a variety of methods based on the input, does that seem accurate?
« Last Edit: June 20, 2016, 07:15:34 pm by merockstar »

Offline xeroc

  • Board Moderator
  • Hero Member
  • *****
  • Posts: 12922
  • ChainSquad GmbH
    • View Profile
    • ChainSquad GmbH
  • BitShares: xeroc
  • GitHub: xeroc
@70231f697a2b3c2b is right here. The `rpc` (or somethimes also `ws`) are objects whose methods are wrapped around a RPC-call and get forwarded to the witness node (or cli wallet).
I use this kind of syntax because it makes it very easy to use ANY method that is implemented in the witness node. If there was a new call added (like `foobar`) you could use it right away by calling `rpc.foobar()` without waiting for me to update the library ..

Offline 70231f697a2b3c2b

  • Full Member
  • ***
  • Posts: 61
    • View Profile
So far it looks like you're on the right track.

The tricky part is that GrapheneWebsocketRPC defines a magic method called __getattr__.

When you try to access an attribute that does not exist, Python will try to call that object's `__getattr__` method instead (if the object doesn't have a `__getattr__`, Python will raise an `AttributeError`).

Here's what's going on when you call `rpc.get_account_balances(account["id"], [])`:

  • First, Python has to resolve `rpc.get_account_balances`.  Ignore the `(account["id"], [])` part for now.
  • Python looks for `rpc.get_account_balances`, but it doesn't exist.
  • Python looks for `rpc.__getattr__`, which does exist.*
  • Python invokes `rpc.__getattr__('get_account_balances')` (note that it passes the name of the attribute it's trying to resolve, not the parameters `account["id"], []` )
  • `rpc.__getattr__` returns a function that will send a `get_account_balances` API request when invoked.
  • Now that Python has resolved `rpc.get_account_balances`, it can now interpret the `(account["id"], [])` part.
  • Python effectively replaces `rpc.get_account_balances` with the function from step 5, and it then invokes the function using the parameters `(account["id"], [])`.

The end result is an API request that looks something like this (I think "xeroc" is actually replaced by a numeric ID, but otherwise this should be correct; I'm interpreting the code manually):

Code: [Select]
{
  "method": "query",
  "params": [0, get_account_balances, ["xeroc", []]],
  "jsonrpc": "2.0",
  "id": 0
}

You can verify this by adding `print query` just before `self.rpcexec(query)`

* (it's actually a little more complicated than this, but the extra bits aren't important here, so I omitted them for KISS)
« Last Edit: June 20, 2016, 03:08:31 am by 70231f697a2b3c2b »

unreadPostsSinceLastVisit

  • Guest
trying to figure out how to pull the balance for whatever account name is entered.

i was looking at two ways.

in airsign I see that lines 247-260 seem to accomplish this. So I'm thinking I need to figure out a way to simplify that code into something usable for me. It seems to be working with an object called "rpc," which is an instance of GrapheneWebSocketRPC from the graphenenewsrpc api (lines 204, and 6). So I went to scope out this code to see what airsign was referring to and I'm not finding a get_accounts_balance like in the airsign code of line 251.

the return balances call in the examples you just linked may help, xeroc, but then I'll have to figure out a way to get just the BTS balance to show up on screen. I'd also have to change account name "xeroc" to an argument in the class config example.

Am I on the right track?
« Last Edit: June 19, 2016, 10:42:30 pm by merockstar »

Offline xeroc

  • Board Moderator
  • Hero Member
  • *****
  • Posts: 12922
  • ChainSquad GmbH
    • View Profile
    • ChainSquad GmbH
  • BitShares: xeroc
  • GitHub: xeroc
... there is also a youtube live coding for the exchange stuff

Offline xeroc

  • Board Moderator
  • Hero Member
  • *****
  • Posts: 12922
  • ChainSquad GmbH
    • View Profile
    • ChainSquad GmbH
  • BitShares: xeroc
  • GitHub: xeroc

unreadPostsSinceLastVisit

  • Guest
@70231f697a2b3c2b

Here's what I've gotten so far. I haven't tried to compile yet, figure I'll bugfix once the whole thing's written.

I'm currently perusing xeroc's libraries to try and figure out how I should proceed

Code: [Select]
# passes in a Bitshares name,
# returns corresponding balance from blockchain
def bal(name):
name = string(name)
if name == "" or name == " "
print("No name entered.")
#code to make program exit
else
balance = #something goes here, probably a call to one of xerocs libraries which I should import, right?
return balance

# greet the user, get a name
name = input("Greetings, please enter a Bitshares name, leave blank to exit: /n")

# pass name to bal function to return balance
balance = bal(name)
print("BTS balance: " + balance)

@xeroc 
I can't find airsign in your github repo, where would it be? found it
« Last Edit: June 19, 2016, 08:16:35 pm by merockstar »

unreadPostsSinceLastVisit

  • Guest
Am working on that project right now, but I had a follow up question regarding how compilers turn code into bytecode.

Is it ever possible, at a certain level of simplicity maybe, for two different programming languages to compile the same bytecode?