Giter VIP home page Giter VIP logo

gift_circle's Introduction

gift_circle

Expanation

The gift_circle software reads a CSV file of gift circle participants and generates gift-recipient assignments.

You can use it to generate a simple list of recipients where no groups are involved, or you can use groups where each particiant will be assigned a person to get a gift for that is not within their own group.

The groups are assumed to be family groups where it would be difficult to purchase a gift for someone in that group and still keep it a secret given the proximity and exposure of the people in that group. You must invoke the -u/--use_groups flag to cause the program to use groups. If the flag is not invoked, it assumes no groups and randomly picks a recipent based upon everyone not previously picked.

The input file must be in UTF-8 or UTF-8-compatible encoding (e.g., ASCII is UTF-8 compatible, but Latin-1 is not).

Not Using Groups

  • Set up a plain CSV file with a header row and data rows, ensuring there is data for each column. You must use these exact column names, but you can choose to use either name only or name and email-address. All names must be unique and email-address is simply passed through to the output CSV. See example-participants-without-groups.csv for the format.

    -- name

    -- name,email_address

  • Invoke the program with the input file location, using the short or long option format. See the available options using -h/--help).

Invoking Without Groups

./gift_circle -i=path/to/participants.csv
./gift_circle --input=./participants.csv
#INFO: Found valid gift circle NOT USING groups in 1 attempts
name,email_address,assigned_person_name
Jane Hill,,Jack Brown
Jack Brown,,Joe Hill
Joe Hill,,Daisy Jones
Daisy Jones,,Bill Jones
Bill Jones,,Beverly Jones
Beverly Jones,,Kenya Hill
Kenya Hill,,Jessica Brown
Jessica Brown,,Billy Jones
Billy Jones,,Jane Hill

The output will include a column for email_address whether or not you include it. This is simply to allow you to include it or not in the input file.

You can redirect the output to a file using shell redirection. You might want to choose this since some information is written to stderr during processing and redirecting stdout to a file will exclude that processing info from your final output.

./gift_circle -i=path/to/participants.csv > gift-assignments.csv

Using Groups

Given that it is impossible to build a gift circle for certain combinations of groups, this software will make an initial determination of whether it's possible to proceed based upon whether the count of folks in the largest group, times two, is less than or equal to the total number of participants provided.

The format of the CSV must be as below, with this exact header row. You can leave out the email_address header and column info (along with its delimiting comma) if desired.

name,email_address,group_number
Joe Hill,[email protected],1
Jane Hill,[email protected],1
Kenya Hill,[email protected],1
Jack Brown,[email protected],2
Jessica Brown,[email protected],2
Bill Jones,[email protected],3
Beverly Jones,[email protected],3
Billy Jones,[email protected],3
Daisy Jones,[email protected],3

Invoking With Groups

./gift_circle -u -i=path/to/participants.csv
./gift_circle --use-groups --input=./participants.csv
./gift_circle -u -i=./participants.csv > ./gift-assignments.csv

The software will read the participants file, create a gift circle using those participants, and output a new CSV to stdout that includes a new column (assigned_person_name) showing the person they are assigned to get a gift for.

Here is an example output. Note the order of the group numbers.

#INFO: Found valid gift circle USING groups in 2 attempts
name,email_address,group_number,assigned_person_name
Jack Brown,[email protected],2,Joe Hill
Joe Hill,[email protected],1,Beverly Jones
Beverly Jones,[email protected],3,Jane Hill
Jane Hill,[email protected],1,Bill Jones
Bill Jones,[email protected],3,Jessica Brown
Jessica Brown,[email protected],2,Billy Jones
Billy Jones,[email protected],3,Kenya Hill
Kenya Hill,[email protected],1,Daisy Jones
Daisy Jones,[email protected],3,Jack Brown

gift_circle's People

Contributors

cwkingjr avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

edwardedmonds

gift_circle's Issues

improve output format to make assignments more intuitive

Improve output format such that the gift and theme assignments are intuitively obvious without any explanation. Might need something like: name, email_address, group, submitted_theme, gift_recipient_theme, gift_recipient_name.

figure out dependency licenses

https://crates.io/crates/cargo-deny?lid=35102

Got several license errors when running "cargo deny check", for example:

error[rejected]: failed to satisfy license requirements
┌─ windows_x86_64_msvc 0.52.0 (registry+https://github.com/rust-lang/crates.io-index):4:12

4 │ license = "MIT OR Apache-2.0"
│ ^^^----^^^^^^^^^^
│ │ │
│ │ rejected: license was not explicitly allowed
│ license expression retrieved via Cargo.toml license
│ rejected: license was not explicitly allowed

= MIT - MIT License:
= - OSI approved
= - FSF Free/Libre
= Apache-2.0 - Apache License 2.0:
= - OSI approved
= - FSF Free/Libre
= windows_x86_64_msvc v0.52.0
└── windows-targets v0.52.0
└── windows-sys v0.52.0
├── anstyle-query v1.0.2
│ └── anstream v0.6.11
│ └── clap_builder v4.5.0
│ └── clap v4.5.0
│ └── gift_circle v0.11.1
└── anstyle-wincon v3.0.2
└── anstream v0.6.11 (*)

advisories ok, bans ok, licenses FAILED, sources ok

Move people cloning into get_gift_circle

On lines 22 and 64 of gift_circle there are duplicate lines to clone the input vec of people to preserve the original list for multiple attempts. This should be moved into get_gift_circle.

Explore using custom error enum

Explore the need/desire to provide a custom error enum within the library module. Include tests to ensure all errors are fired and reported correctly to main.

Move recipient assignment to a people trait function

let last_person_name = gift_circle.last().unwrap().name.clone();

for (i, person) in gift_circle.clone().iter().enumerate() {
    if person.name == last_person_name {
        gift_circle[i].assigned_person_name = Some(gift_circle[0].name.clone());
    } else {
        gift_circle[i].assigned_person_name = Some(gift_circle[i + 1].name.clone());
    }
}

Investigate results of cargo mutant testing

gift_circle % cargo mutants
Found 55 mutants to test
ok Unmutated baseline in 14.2s build + 0.3s test
INFO Auto-set test timeout to 20s
MISSED src/main.rs:44:5: replace main with () in 0.7s build + 0.3s test
MISSED src/gift_circle.rs:119:23: replace += with *= in get_gift_circle in 0.7s build + 0.3s test
MISSED src/gift_circle.rs:30:74: replace > with == in generate_group_path in 0.6s build + 0.3s test
MISSED src/people.rs:64:45: replace * with + in ::has_possible_hamiltonian_path in 0.6s build + 0.3s test
MISSED src/gift_circle.rs:30:69: replace * with / in generate_group_path in 0.6s build + 0.3s test
MISSED src/people.rs:105:52: replace && with || in ::is_valid_gift_circle in 0.6s build + 0.3s test
MISSED src/gift_circle.rs:78:26: replace <= with > in get_gift_circle in 0.6s build + 0.3s test
TIMEOUT src/gift_circle.rs:11:30: replace != with == in move_person in 0.6s build + 20.1s test
MISSED src/gift_circle.rs:115:34: replace == with != in get_gift_circle in 0.7s build + 0.3s test
MISSED src/gift_circle.rs:30:74: replace > with < in generate_group_path in 0.6s build + 0.3s test
MISSED src/people.rs:32:60: replace + with * in ::assign_gift_recipients in 0.6s build + 0.3s test
MISSED src/gift_circle.rs:62:11: delete ! in generate_no_group_path in 0.6s build + 0.3s test
MISSED src/gift_circle.rs:30:69: replace * with + in generate_group_path in 0.6s build + 0.3s test
TIMEOUT src/gift_circle.rs:11:5: replace move_person with () in 0.7s build + 20.0s test
MISSED src/gift_circle.rs:122:22: replace == with != in get_gift_circle in 0.7s build + 0.3s test
MISSED src/person.rs:23:9: replace Person::new_no_group -> Self with Default::default() in 0.6s build + 0.3s test
MISSED src/gift_circle.rs:104:30: replace && with || in get_gift_circle in 0.6s build + 0.3s test
MISSED src/gift_circle.rs:60:5: replace generate_no_group_path -> People with Default::default() in 0.6s build + 0.3s test
MISSED src/main.rs:20:5: replace run -> Result<()> with Ok(()) in 0.9s build + 0.3s test
MISSED src/people.rs:105:9: replace ::is_valid_gift_circle -> bool with true in 0.7s build + 0.3s test
55 mutants tested in 1m 43s: 18 missed, 32 caught, 3 unviable, 2 timeouts

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.