Giter Club home page Giter Club logo

Comments (10)

RiccardoM avatar RiccardoM commented on May 27, 2024 2

@bragaz I would change the implementation details based on the work that is being done inside #81.

Type definition

Inside post.go I would change how the Post type is defined:

type Post struct {
    // All current post data
  
    PollData *PollData `json:"poll,omitempty"`  // This contains the poll details, if existing
}

Inside post_poll_data.go I would define the new PollData type as well as the other types needed:

// PollData contains the information of a poll that is associated to a post
type PollData struct {
    Open                  bool         `json:"open"`                    // Tells if the poll is still accepting answers
    EndDate               Time         `json:"end_date"`                // Block height at which the poll will no longer accept new answers
    ProvidedAnswers       []PollAnswer `json:"available_answers"`       // Lists of answers provided by the creator
    AllowsMultipleAnswers bool         `json:"allows_multiple_answers"` // Tells if the poll is a single or multiple answers one
    AllowsAnswerEdits     bool         `json:"allows_answer_edits"`
}

// PollAnswer contains the data of a single poll answer inserted by the creator
type PollAnswer struct {
    Id   uint64 `json:"id"`   // Unique id inside the post
    Text string `json:"text"` // Text of the answer
}

Message definition

Poll creation

I would edit the MsgCreatePost adding a new PollDetails field:

type MsgCreatePost struct {
     // Current MsgCreatePost fields

    PollData *PollData `json:"poll,omitempty" // Contains the data of the poll to be associated with the post, if any
}

Poll closing

Requires to provide a types.PostID and sets the Open field to false

type MsgClosePollPost struct {
    PostID PostID `json:"post_id"`
    Message String `json:"message"` // (Optional) Message to be displayed upon the poll closing
}

Poll answering

Requires to provide a types.PostID and a slice of uint64 representing the answers ids. It adds the answers to the poll or edits any existing ones.

If the poll does not accept multiple answers from the same user, the slice must be of length one.

If the poll does not accept edits and the user tries to override his answer, an error must be thrown.

type MsgAnswerPollPost struct {
    PostID         PostID   `json:"post_id"`
    ProvidedAnswers []uint64 `json:"provided_answer"`
}

Storing the post

No changes should be made to the storage of posts.

Post query result

No changes should be made to the query of posts.

from desmos.

RiccardoM avatar RiccardoM commented on May 27, 2024 1

Context

If we browse some of the most known poll websites such as EasyPolls.net, Doodle and StrawPoll we can see that all of them have the same concept of poll.

By abstracting the common parts, we can see that a poll to be defined such, must:

  • Have one question in a textual form
  • Provide two or more answers to the question, in a textual form
  • Allow (or not) the user to select multiple answers (decided during the creation of the poll)

Poll Post implementation proposal

After seeing what are the requirements of a poll, here is my implementation proposal for a PollPost type.

// PollPost is a post that represents a poll
type PollPost struct {
    StdPost
    Open                  bool         `json:"open"`                    // Tells if the poll is still accepting answers
    EndDate               int64        `json:"end_date"`                // Block height at which the poll will no longer accept new answers
    ProvidedAnswers       []PollAnswer `json:"available_answers"`       // Lists of answers provided by the creator
    AllowsMultipleAnswers bool         `json:"allows_multiple_answers"` // Tells if the poll is a single or multiple answers one
    AllowsAnswerEdits     bool         `json:"allows_answer_edits"`     // Tells whether the user can edit an answer he already inserted
}

// PollAnswer contains the data of a single poll answer inserted by the creator
type PollAnswer struct {
    Id   uint64 `json:"id"`   // Unique id inside the post
    Text string `json:"text"` // Text of the answer
}

Other than implementing all the requirements above, by adding the EndDate field we can provide the creator the ability to specify a time range after which the poll will be automatically be closed and not accept any more answers.

Operations to provide

The operations to provide to the users are the following.

  1. Create a poll
    Requires to input the text of the poll, the answers to be provided, whether or not it accepts multiple answers and whether or not it allows answer edits.

  2. Close a poll
    Requires to provide a types.PostID and sets the Open field to false

  3. Answer to a poll
    Requires to provide a types.PostID and a slice of uint64 representing the answers ids. It adds the answers to the poll or edits any existing ones.
    If the poll does not accept multiple answers from the same user, the slice must be of length one.
    If the poll does not accept edits and the user tries to override his answer, an error must be thrown.

Storage

The best way to store posts is probably the following.

  • Posts are stored indexed by their PostID, like any other post.
    This allows for faster retrieval when wanting to read a post given his id, or when wanting to check whether a post exists or not.

  • Answers are stored index by the corresponding post id and contained inside a map. In short: types.PostID -> map[sdk.AccAddress][]uint64
    This way when wanting to get the answers of a user for a given Post, we can simply get the post by its id and later perform a quick O(1) check on the map to get the array of ids representing the answers of the user.

from desmos.

RiccardoM avatar RiccardoM commented on May 27, 2024 1

How the results of the poll will be tallied?

We can implement a simple query that aggregates the post information as well as all the answers that have been inserted returning an object that looks like the following:

type PollDetails struct {
	Poll    PollPost        `json:"poll"`
	Answers []AnswerDetails `json:"answers"`
}

type AnswerDetails struct {
	User    sdk.AccAddress `json:"user"`
	Answers []uint64       `json:"answers"`
}

The client can then simply flat map the answers to get the results. In Kotlin this would be

poll.Answers
   .flatMap { answerDetails -> answerDetails.Answers }
   .groupBy { answerId -> answerId }

Or it can be done though for loops, but anyway the client would have all the info necessary.

from desmos.

RiccardoM avatar RiccardoM commented on May 27, 2024 1

@RiccardoM Isn't PollDetails the same thing as PollData?
Couldn't we use PollDetails only?

Yes, you're right. Delete PollDetails and use PollData only. I've also edited my reply

from desmos.

RiccardoM avatar RiccardoM commented on May 27, 2024 1

@bragaz The first one seems more reasonable as well as easier to implement

from desmos.

kwunyeung avatar kwunyeung commented on May 27, 2024

How the results of the poll will be tallied?

from desmos.

leobragaz avatar leobragaz commented on May 27, 2024

With the lasts edits to the Post type I would summarize the implementation's proposal in order to be sure to start it properly:
Building a new type that encapsulate the actual Post

// PollPost is a post that represents a poll
type PollPost struct {
    StdPost
    Open                  bool         `json:"open"`                    // Tells if the poll is still accepting answers
    EndDate               Time        `json:"end_date"`                // Block height at which the poll will no longer accept new answers
    ProvidedAnswers       []PollAnswer `json:"available_answers"`       // Lists of answers provided by the creator
    AllowsMultipleAnswers bool         `json:"allows_multiple_answers"` // Tells if the poll is a single or multiple answers one
    AllowsAnswerEdits     bool         `json:"allows_answer_edits"`     // Tells whether the user can edit an answer he already inserted
}

// PollAnswer contains the data of a single poll answer inserted by the creator
type PollAnswer struct {
    Id   uint64 `json:"id"`   // Unique id inside the post
    Text string `json:"text"` // Text of the answer
}

Displaying queries result like this:

type PollDetails struct {
	Poll    PollPost        `json:"poll"`
	Answers []AnswerDetails `json:"answers"`
}

type AnswerDetails struct {
	User    sdk.AccAddress `json:"user"`
	Answers []uint64       `json:"answers"`
}

Providing these set of messages:

  1. Create a poll
    Requires to input the text of the poll, the answers to be provided, whether or not it accepts multiple answers and whether or not it allows answer edits.
type MsgCreatePollPost struct {
	MsgCreatePost
	Open                 bool         `json:"open"`
	EndDate              time.Time    `json:"end_date"`
	AvailableAnswers     []PollAnswer `json:"available_answers"`
	AllowsMultipleAnswer bool         `json:"allows_multiple_answer"`
	AllowsAnswerEdits    bool         `json:"allows_answer_edits"`
}
  1. Close a poll
    Requires to provide a types.PostID and sets the Open field to false
type MsgClosePollPost struct {
	PostID PostID `json:"post_id"`
}
  1. Answer to a poll
    Requires to provide a types.PostID and a slice of uint64 representing the answers ids. It adds the answers to the poll or edits any existing ones.
    If the poll does not accept multiple answers from the same user, the slice must be of length one.
    If the poll does not accept edits and the user tries to override his answer, an error must be thrown.
type MsgAnswerPollPost struct {
	PostID         PostID   `json:"post_id"`
	ProvidedAnswers []uint64 `json:"provided_answer"`
}

Store the post:
Here we have 2 different things to save:
1 - StdPost
2 - Remaining Poll infos
I have some doubts about how handle these two things, should we save all together or should we invoke maybe the SavePost function for the StdPost and save the rest linked to postID?

from desmos.

leobragaz avatar leobragaz commented on May 27, 2024

Awesome! This clear all my doubts! And seems definitely a far good implementation!

from desmos.

leobragaz avatar leobragaz commented on May 27, 2024

@RiccardoM Isn't PollDetails the same thing as PollData?
Couldn't we use PollDetails only?

from desmos.

leobragaz avatar leobragaz commented on May 27, 2024

I was thinking about the answer's editing and raise some doubts to myself:
Suppose that we have a poll that supports multiple answers:
E.g A poll with 4 possibile different answers

  1. At time t1 the user express a vote:
    • answer1
    • answer2
    • answer3
    • answer4
  2. At time t2 he wants to vote again, but to add another answer to the previous ones:
    • answer1
    • answer2
    • answer3
    • answer4

First road

Has the user/client going to make another MsgAnswerPollPost with the id of the previous answer and the one of the new one?

Second road

Or it will make another MsgAnswerPollPost with only the new answer's id?
And if so, how can we know if he wants to substitute the previous answer or just add another one?

Conclusions

If we follow the first road we can let the the things how we initially designed them.
With the second one we probably need to introduce new messages in order to add or remove an answer/more answers or it will be impossible to know user's intentions only with MsgAnswerPollPost.

from desmos.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.