# Steem Developer Portal

### PY: Vote On Content

How to vote on a post/comment using Python.

Full, runnable src of Vote On Content can be downloaded as part of the PY tutorials repository.

In this tutorial we will explain and show you how to to check if a user has voted on specified content and also how to submit a vote on the Steem blockchain using the `commit` class found within the steem-python library.

## Intro

Voting is a way of promoting good content via an `upvote` or reporting misuse, spam or other unfit content by `downvoting`. The Steem python library has a built-in function to transmit transactions to the blockchain. We are using the `vote` method found within the `commit` class in the the library. Before we vote on content we first check whether the user has already voted. This is not strictly necessary as a voting operation overrides the previous vote value. We use the `get_active_votes` function to check for this. This function only requires two parameters, the `author` and the `permlink` for the comment/post that the query is for. This returns a list of the current voters for that comment. The `vote` function has 3 parameters:

1. identifier - This is a combination of the author and permink of the post/comment that the vote will be on
2. weight - This value determines whether the vote is an upvote (+100.0) or a downvote (-100.0) but this value cannot be 0
3. username - The name of the account that is executing the vote

## Steps

1. App setup - Library install and import. Connection to testnet
2. User information and steem node - Input user information and connection to Steem node
3. Check vote status - Vote status of post/comment
4. Commit vote - Commit vote to the blockchain

#### 1. App setup

In this tutorial we use 3 packages:

- `steem` - steem-python library and interaction with Blockchain
- `pick` - helps select the query type interactively

We import the libraries and connect to the `testnet`.

    import steembase
    import steem
    from pick import pick

    steembase.chains.known_chains['STEEM'] = {
        'chain_id': '79276aea5d4877d9a25892eaa01b0adf019d3e5cb12a97478df3298ccdd01673',
        'prefix': 'STX', 'steem_symbol': 'STEEM', 'sbd_symbol': 'SBD', 'vests_symbol': 'VESTS'
    }

Because this tutorial alters the blockchain we connect to the testnet so we don’t create spam on the production server.

#### 2. User information and steem node

We also require the `private posting key` of the user that wishes to vote on the selected content so the action can be committed to the blockchain. This is why we have to specify this along with the `testnet` node. The values are supplied via the terminal/console before we initialise the steem class. We have supplied a test account, `cdemo` to use with this tutorial but any account set up on the testnet can be used.

    #capture user information
    username = input('Please enter your username: ')
    postingkey = input('Please enter your private posting key: ')

    #connect node and private posting key, demo account name: cdemo, posting key: 5JEZ1EiUjFKfsKP32b15Y7jybjvHQPhnvCYZ9BW62H1LDUnMvHz
    s = steem.Steem(nodes=['https://testnet.steem.vc'], keys=[postingkey])

#### 3. Check vote status

In order to give the user an educated choice we first check whether they have already voted on the given post/comment. The author and permlink for the post is supplied via the console/terminal. If you need to find something to vote on, you can try (https://condenser.steem.vc/) YMMV.

    #capture variables
    author = input('Author of post/comment that you wish to vote for: ')
    permlink = input('Permlink of the post/comment you wish to vote for: ')

The vote status check is done with a simple query to the blockchain.

    #check vote status
    result = s.get_active_votes(author, permlink)

This query returns a list of the current voters on the specified post/comment. The result is checked against the username to determine what the current status is.

    if result:
    	for vote in result :
    		if vote['voter'] == username:
    			title = "This post/comment has already been voted for"
    			break
    		else:
    			title = "No vote for this post/comment has been submitted"
    else:
    	title = "No vote for this post/comment has been submitted"

#### 4. Commit vote

The result from the previous step is used to give the user a choice in what the next step in the operation should be.

    #option to continue
    options = ['Add/Change vote', 'Cancel voting process']
    option, index = pick(options, title)

The user is given a choice to either continue with the vote or cancel the operation. If the user elects to continue, the `vote` function is executed. The weight of the vote is input from the UI and the identifier parameter is created by combining the author and permlink values.

It’s important to note that the http client in steem-python will retry IF it sends an appbase query and detects a older, non-appbase error

    #voting commit
    if option == 'Add/Change vote':
    	weight = input('\n'+'Please advise weight of vote between -100.0 and 100 (not zero): ')
    	identifier = ('@'+author+'/'+permlink)
    	try:
    		print('Sending vote. ...')
    		s.commit.vote(identifier, float(weight), username)
    		print('\n'+'Vote sent.')
    	except (RPCErrorRecoverable, RPCError) as err:
    		print('\n'+'Exception encountered. Unable to vote')

    else:
    	print('Voting has been cancelled')

When the function is executed the selected vote weight overrides any value previously recorded on the blockchain.

A simple confirmation of the chosen action is printed on the screen.

### To Run the tutorial

1. review dev requirements
2. clone this repo
3. `cd tutorials/17_vote_on_content`
4. `pip install -r requirements.txt`
5. `python index.py`
6. After a few moments, you should see a prompt for input in terminal screen.