Skip to content

Commit

Permalink
Merge rank variant feature branch with dev.
Browse files Browse the repository at this point in the history
  • Loading branch information
Kinematics committed Jun 23, 2016
2 parents 658d9ba + 40c34bb commit f9bc936
Show file tree
Hide file tree
Showing 34 changed files with 2,910 additions and 40 deletions.
38 changes: 38 additions & 0 deletions NetTally/Config/BindingConverters.cs
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,44 @@ public object ConvertBack(object value, Type targetType, object parameter, Cultu
}
}

/// <summary>
/// Data binding conversion class to convert a PartitionMode enum to
/// an index value or back.
/// </summary>
[ValueConversion(typeof(RankVoteCounterMethod), typeof(int))]
public class RankCountingModeConverter : IValueConverter
{
/// <summary>
/// Convert from source (property enum) to target (control index).
/// </summary>
/// <returns>Returns whether the specified target control value should be on or off.</returns>
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is RankVoteCounterMethod)
{
return (int)value;
}

return -1;
}

/// <summary>
/// Convert from target (control index) to source (property enum).
/// </summary>
/// <returns>Returns what the source property value should be set to
/// based on the target value.</returns>
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is int)
{
return (RankVoteCounterMethod)value;
}

return RankVoteCounterMethod.Default;
}
}



/// <summary>
/// Data binding conversion class to return the OR state of all the objects
Expand Down
67 changes: 42 additions & 25 deletions NetTally/GlobalOptionsWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:NetTally"
mc:Ignorable="d"
Title="Global Options" Height="480" Width="640" ResizeMode="NoResize" WindowStartupLocation="CenterOwner" Icon="CheckVoteWin.ico" ShowInTaskbar="False">
Title="Global Options" Height="440.339" Width="640" ResizeMode="NoResize" WindowStartupLocation="CenterOwner" Icon="CheckVoteWin.ico" ShowInTaskbar="False">

<Window.Resources>
<local:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter"></local:BoolToVisibilityConverter>
<local:RankCountingModeConverter x:Key="RankCountingModeConverter"></local:RankCountingModeConverter>
</Window.Resources>

<Grid>
Expand All @@ -17,46 +18,62 @@
<ColumnDefinition Width="6*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="90" />
<RowDefinition Height="10" />
<RowDefinition Height="1*" />
<RowDefinition Height="50" />
</Grid.RowDefinitions>

<TextBlock Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2" x:Name="windowDescription" Margin="10,10,10,0" TextWrapping="Wrap"
Text="The following are options that change how the program works, at a mechanical level. Most of the time you should leave them at the default, but occasionally situations may arise that require adjustments to the parsing behavior. This allows you to make those adjustments when needed, with the understanding that it may cause extra work on the back-end of things, with merging votes and voters." VerticalAlignment="Top"/>

<Label x:Name="labelGeneral" Content="General" HorizontalAlignment="Left" Margin="10,2,0,0" Grid.Row="1" Height="26" VerticalAlignment="Top"/>
<CheckBox Grid.Column="0" Grid.Row="1" x:Name="allowRankedVotes" Content="Allow Ranked Votes" HorizontalAlignment="Left" Margin="10,28,0,0" VerticalAlignment="Top"
IsChecked="{Binding Path=AllowRankedVotes}" />
IsChecked="{Binding Path=Options.AllowRankedVotes}" />
<ComboBox x:Name="rankedVoteAlgorithm" Margin="33,49,0,0" Grid.Column="0" Grid.Row="1" VerticalAlignment="Top" Height="30" HorizontalAlignment="Left" Width="145" Padding="8,2,4,3"
ItemsSource="{Binding Path=RankVoteCountingModes}" SelectedIndex="{Binding Path=Options.RankVoteCounterMethod, Converter={StaticResource RankCountingModeConverter}}"
VerticalContentAlignment="Center" IsEnabled="{Binding ElementName=allowRankedVotes, Path=IsChecked}">
<ComboBox.ItemContainerStyle>
<Style TargetType="ComboBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
</Style>
</ComboBox.ItemContainerStyle>
</ComboBox>

<Label x:Name="labelFormatting" Content="Formatting" HorizontalAlignment="Left" Margin="10,49,0,0" Grid.Row="1" VerticalAlignment="Top" RenderTransformOrigin="-0.605,0.231"/>
<CheckBox x:Name="forbidVoteLabelPlanNames" Content="Forbid Vote Label Plan Names" HorizontalAlignment="Left" Margin="10,75,0,0" Grid.Row="1" VerticalAlignment="Top"
IsChecked="{Binding Path=ForbidVoteLabelPlanNames}"/>
<CheckBox Grid.Column="0" Grid.Row="1" x:Name="whitespaceAndPunctuationIsSignificant" Content="Whitespace &amp; Punctuation is Significant" HorizontalAlignment="Left" Margin="10,96,0,0" VerticalAlignment="Top"
IsChecked="{Binding Path=WhitespaceAndPunctuationIsSignificant}" />
<CheckBox x:Name="disableProxyVotes" Content="Disable User Proxy Votes" HorizontalAlignment="Left" Margin="10,117,0,0" Grid.Row="1" VerticalAlignment="Top"
IsChecked="{Binding Path=DisableProxyVotes}"/>
<CheckBox x:Name="forcePinnedProxyVotes" Content="Force Pinned Proxy Votes" HorizontalAlignment="Left" Margin="10,138,0,0" Grid.Row="1" VerticalAlignment="Top"
IsChecked="{Binding Path=ForcePinnedProxyVotes}"/>
<CheckBox Grid.Column="0" Grid.Row="1" x:Name="ignoreSpoilers" Content="Ignore Spoilers" HorizontalAlignment="Left" Margin="10,159,0,0" VerticalAlignment="Top"
IsChecked="{Binding Path=IgnoreSpoilers}" />
<CheckBox Grid.Column="0" Grid.Row="1" x:Name="trimExtendedText" Content="Trim Extended Vote Descriptions" HorizontalAlignment="Left" Margin="10,180,0,0" VerticalAlignment="Top"
IsChecked="{Binding Path=TrimExtendedText}" />
<Label x:Name="labelFormatting" Content="Formatting" HorizontalAlignment="Left" Margin="10,86,0,0" Grid.Row="1" VerticalAlignment="Top" RenderTransformOrigin="-0.605,0.231"/>
<CheckBox x:Name="forbidVoteLabelPlanNames" Content="Forbid Vote Label Plan Names" HorizontalAlignment="Left" Margin="10,112,0,0" Grid.Row="1" VerticalAlignment="Top"
IsChecked="{Binding Path=Options.ForbidVoteLabelPlanNames}"/>
<CheckBox Grid.Column="0" Grid.Row="1" x:Name="whitespaceAndPunctuationIsSignificant" Content="Whitespace &amp; Punctuation is Significant" HorizontalAlignment="Left" Margin="10,133,0,0" VerticalAlignment="Top"
IsChecked="{Binding Path=Options.WhitespaceAndPunctuationIsSignificant}" />
<CheckBox x:Name="disableProxyVotes" Content="Disable User Proxy Votes" HorizontalAlignment="Left" Margin="10,154,0,0" Grid.Row="1" VerticalAlignment="Top"
IsChecked="{Binding Path=Options.DisableProxyVotes}"/>
<CheckBox x:Name="forcePinnedProxyVotes" Content="Force Pinned Proxy Votes" HorizontalAlignment="Left" Margin="10,175,0,0" Grid.Row="1" VerticalAlignment="Top"
IsChecked="{Binding Path=Options.ForcePinnedProxyVotes}"/>
<CheckBox Grid.Column="0" Grid.Row="1" x:Name="ignoreSpoilers" Content="Ignore Spoilers" HorizontalAlignment="Left" Margin="10,196,0,0" VerticalAlignment="Top"
IsChecked="{Binding Path=Options.IgnoreSpoilers}" />
<CheckBox Grid.Column="0" Grid.Row="1" x:Name="trimExtendedText" Content="Trim Extended Vote Descriptions" HorizontalAlignment="Left" Margin="10,217,0,0" VerticalAlignment="Top"
IsChecked="{Binding Path=Options.TrimExtendedText}" />

<Label x:Name="labelOutput" Content="Output" HorizontalAlignment="Left" Margin="10,201,0,0" Grid.Row="1" VerticalAlignment="Top"/>
<CheckBox x:Name="globalSpoilers" Content="Always Use Full Spoilers" HorizontalAlignment="Left" Margin="10,227,0,0" Grid.Row="1" VerticalAlignment="Top"
IsChecked="{Binding Path=GlobalSpoilers}"/>
<Label x:Name="labelOutput" Content="Output" HorizontalAlignment="Left" Margin="10,238,0,0" Grid.Row="1" VerticalAlignment="Top"/>
<CheckBox x:Name="globalSpoilers" Content="Always Use Full Spoilers" HorizontalAlignment="Left" Margin="10,264,0,0" Grid.Row="1" VerticalAlignment="Top"
IsChecked="{Binding Path=Options.GlobalSpoilers}"/>

<Label x:Name="labelMisc" Content="Misc" HorizontalAlignment="Left" Margin="10,248,0,0" Grid.Row="1" VerticalAlignment="Top"/>
<CheckBox Grid.Column="0" Grid.Row="1" x:Name="debugMode" Content="Debug Mode" HorizontalAlignment="Left" Margin="10,274,0,0" VerticalAlignment="Top"
IsChecked="{Binding Path=DebugMode}" />
<Label x:Name="labelMisc" Content="Misc" HorizontalAlignment="Left" Margin="10,285,0,0" Grid.Row="1" VerticalAlignment="Top"/>
<CheckBox Grid.Column="0" Grid.Row="1" x:Name="debugMode" Content="Debug Mode" HorizontalAlignment="Left" Margin="10,311,0,0" VerticalAlignment="Top"
IsChecked="{Binding Path=Options.DebugMode}" />

<!-- External Tooltip Descriptions -->
<StackPanel Grid.Column="1" Grid.Row="1" Margin="0,0,5,0" Visibility="{Binding ElementName=allowRankedVotes, Path=IsMouseOver, Converter={StaticResource BoolToVisibilityConverter}, Mode=OneWay}">
<TextBlock TextWrapping="Wrap" FontWeight="Bold" Margin="0,0,0,5" Text="Allow Ranked Votes"/>
<TextBlock TextWrapping="Wrap" Text="When set, this allows ranked votes to be tallied. If ranked votes are interfering with your tally, you can turn it off here."/>
<TextBlock TextWrapping="Wrap" Margin="0,5,0,0" Text="Defaults to true."/>
</StackPanel>
<StackPanel Grid.Column="1" Grid.Row="1" Margin="0,0,5,0" Visibility="{Binding ElementName=rankedVoteAlgorithm, Path=IsMouseOver, Converter={StaticResource BoolToVisibilityConverter}, Mode=OneWay}">
<TextBlock TextWrapping="Wrap" FontWeight="Bold" Margin="0,0,0,5" Text="Ranked Vote Algorithm"/>
<TextBlock TextWrapping="Wrap" Text="Specify the algorithm to use when tallying ranked votes. This may be temporarily changed from the default. Changing this value updates the current tally immediately."/>
<TextBlock TextWrapping="Wrap" Margin="0,5,0,0" Text="Options include:"/>
<TextBlock TextWrapping="Wrap" Margin="0,5,0,0" Text="Ranked Instant Runoff (default) - A system that uses Wilson scoring to determine the top two options, and then does a runoff between those two."/>
<TextBlock TextWrapping="Wrap" Margin="0,5,0,0" Text="Baldwin - An improved version of the method used in earlier versions of NetTally. This is an instant runoff method, like Coombs."/>
<TextBlock TextWrapping="Wrap" Margin="0,5,0,0" Text="Schulze - A Condorcet method that may be used to verify Condorcet ranking order. Uses the Schulze algorithm."/>
<TextBlock TextWrapping="Wrap" Margin="0,5,0,0" Text="Wilson - A scoring mechanism that may be used to compare the scoring order of options. Uses Wilson's Bournelli limit method."/>
</StackPanel>

<StackPanel Grid.Column="1" Grid.Row="1" Margin="0,0,5,0" Visibility="{Binding ElementName=forbidVoteLabelPlanNames, Path=IsMouseOver, Converter={StaticResource BoolToVisibilityConverter}, Mode=OneWay}">
<TextBlock TextWrapping="Wrap" FontWeight="Bold" Margin="0,0,0,5" Text="Forbid Vote Labels as Plan Names"/>
Expand Down
1 change: 1 addition & 0 deletions NetTally/GlobalOptionsWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ private void closeButton_Click(object sender, RoutedEventArgs e)
private void resetAllButton_Click(object sender, RoutedEventArgs e)
{
allowRankedVotes.IsChecked = true;
rankedVoteAlgorithm.SelectedIndex = 0;

forbidVoteLabelPlanNames.IsChecked = false;
whitespaceAndPunctuationIsSignificant.IsChecked = false;
Expand Down
1 change: 0 additions & 1 deletion NetTally/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:NetTally"
mc:Ignorable="d"
Title="{Binding MyTitle, RelativeSource={RelativeSource Mode=Self}}"
Height="617.588" Width="926" MinWidth="857" Closing="Window_Closing" MinHeight="200" Icon="CheckVoteWin.ico" KeyUp="Window_KeyUp">

<Window.Resources>
Expand Down
2 changes: 1 addition & 1 deletion NetTally/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ private void globalOptionsButton_Click(object sender, RoutedEventArgs e)
GlobalOptionsWindow options = new GlobalOptionsWindow
{
Owner = Application.Current.MainWindow,
DataContext = MainViewModel.Options
DataContext = MainViewModel
};

options.ShowDialog();
Expand Down
4 changes: 2 additions & 2 deletions NetTally/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,5 @@
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.7.0.0")]
[assembly: AssemblyFileVersion("1.7.3.2")]
[assembly: AssemblyInformationalVersion("1.7.3.2")]
[assembly: AssemblyFileVersion("1.7.4.0")]
[assembly: AssemblyInformationalVersion("1.7.4")]
18 changes: 18 additions & 0 deletions TallyCore/Global/AdvancedOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
DisplayMode displayMode = DisplayMode.Normal;

bool allowRankedVotes = true;
RankVoteCounterMethod rankVoteCounterMethod = RankVoteCounterMethod.Default;

[Obsolete("Invert usage")]
bool allowVoteLabelPlanNames = true;
Expand All @@ -56,6 +57,7 @@ protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
#region Constants for string descriptions
public const string _displayMode = "displayMode";
public const string _allowRankedVotes = "allowRankedVotes";
public const string _rankVoteCounterMethod = "rankVoteCounterMethod";
public const string _forbidVoteLabelPlanNames = "forbidVoteLabelPlanNames";
public const string _whitespaceAndPunctuationIsSignificant = "whitespaceAndPunctuationIsSignificant";
public const string _disableProxyVotes = "disableProxyVotes";
Expand All @@ -79,6 +81,22 @@ public bool AllowRankedVotes
OnPropertyChanged();
}
}

/// <summary>
/// Gets or sets the rank vote counter method.
/// </summary>
/// <value>
/// The rank vote counter method.
/// </value>
public RankVoteCounterMethod RankVoteCounterMethod
{
get { return rankVoteCounterMethod; }
set
{
rankVoteCounterMethod = value;
OnPropertyChanged();
}
}
#endregion

#region Formatting Options
Expand Down
45 changes: 44 additions & 1 deletion TallyCore/Global/Enumerations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,50 @@ public enum VoteType
{
Vote,
Plan,
Rank
Rank,
Approval
}

public enum RankVoteCounterMethod
{
[EnumDescription("Default (RIR)")]
Default,
[EnumDescription("Wilson Scoring")]
Wilson,
[EnumDescription("Schulze (Condorcet)")]
Schulze,
[EnumDescription("Baldwin Runoff")]
Baldwin,
[EnumDescription("Rated Instant Runoff")]
RIRV,
//[EnumDescription("Borda Count")]
//Borda,
//[EnumDescription("Borda Normalized")]
//BordaNormalized,
//[EnumDescription("Borda Fraction")]
//BordaFraction,
//[EnumDescription("Distance Scoring")]
//Distance,
//[EnumDescription("Distance Scoring (U0)")]
//DistanceU0,
//[EnumDescription("Instant Runoff")]
//InstantRunoff,
//[EnumDescription("Coombs' Method")]
//Coombs,
//[EnumDescription("Legacy Coombs")]
//LegacyCoombs,
//[EnumDescription("Pairwise Elimination")]
//Pairwise,
}

public enum StandardVoteCounterMethod
{
Default
}

public enum ApprovalVoteCounterMethod
{
Default
}

public enum ReferenceType
Expand Down
18 changes: 18 additions & 0 deletions TallyCore/NetTally.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,24 @@
<Compile Include="ViewModels\Utility\ExceptionEventArgs.cs" />
<Compile Include="ViewModels\ViewModelBase.cs" />
<Compile Include="ViewModels\ViewModelLocator.cs" />
<Compile Include="VoteCounting\RankVoteCounting\BaldwinRankVoteCounter.cs" />
<Compile Include="VoteCounting\RankVoteCounting\BaseRankVoteCounter.cs" />
<Compile Include="VoteCounting\RankVoteCounting\BordaFractionRankVoteCounter.cs" />
<Compile Include="VoteCounting\RankVoteCounting\BordaNormalizedRankVoteCounter.cs" />
<Compile Include="VoteCounting\RankVoteCounting\BordaRankVoteCounter.cs" />
<Compile Include="VoteCounting\RankVoteCounting\CoombsRankVoteCounter.cs" />
<Compile Include="VoteCounting\IBaseVoteCounter.cs" />
<Compile Include="VoteCounting\RankVoteCounting\DistanceRankVoteCounter.cs" />
<Compile Include="VoteCounting\RankVoteCounting\DistanceU0RankVoteCounter.cs" />
<Compile Include="VoteCounting\RankVoteCounting\InstantRunoffRankVoteCounter.cs" />
<Compile Include="VoteCounting\RankVoteCounting\LegacyCoombsRankVoteCounter.cs" />
<Compile Include="VoteCounting\RankVoteCounting\PairwiseRankVoteCounter.cs" />
<Compile Include="VoteCounting\RankVoteCounting\RIRVRankVoteCounter.cs" />
<Compile Include="VoteCounting\RankVoteCounting\SchulzeRankVoteCounter.cs" />
<Compile Include="VoteCounting\RankVoteCounting\Utility\GroupRankVotes.cs" />
<Compile Include="VoteCounting\RankVoteCounting\Utility\RankScoring.cs" />
<Compile Include="VoteCounting\RankVoteCounting\WilsonRankVoteCounter.cs" />
<Compile Include="VoteCounting\VoteCounterLocator.cs" />
<Compile Include="Votes\Utility\UndoAction.cs" />
<Compile Include="Votes\Utility\VoteCounterSingleton.cs" />
<Compile Include="Votes\Objects\VoteLineSequence.cs" />
Expand Down
11 changes: 8 additions & 3 deletions TallyCore/Output/TallyOutput.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@

namespace NetTally.Output
{
// Task (string), Ordered list of ranked votes
using RankResultsByTask = Dictionary<string, List<string>>;

/// <summary>
/// Class to handle generating the output of a tally run, for display in the text box.
/// </summary>
Expand Down Expand Up @@ -80,11 +83,13 @@ private void ConstructRankedOutput()
{
if (VoteCounter.Instance.HasRankedVotes)
{
// Get ranked results, and order them by task name
var results = RankVotes.Rank().OrderBy(a => a.Key);
VoteCounting.IRankVoteCounter counter = VoteCounting.VoteCounterLocator.GetRankVoteCounter(AdvancedOptions.Instance.RankVoteCounterMethod);
RankResultsByTask results = counter.CountVotes(VoteCounter.Instance.GetVotesCollection(VoteType.Rank));

var orderedRes = results.OrderBy(a => a.Key);

// Output the ranking results for each task
foreach (var task in results)
foreach (var task in orderedRes)
{
AddRankTask(task);
sb.AppendLine("");
Expand Down
4 changes: 2 additions & 2 deletions TallyCore/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,5 @@
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.7.0.0")]
[assembly: AssemblyFileVersion("1.7.3.2")]
[assembly: AssemblyInformationalVersion("1.7.3.2")]
[assembly: AssemblyFileVersion("1.7.4.0")]
[assembly: AssemblyInformationalVersion("1.7.4")]
2 changes: 1 addition & 1 deletion TallyCore/Tally.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ private void PageProvider_StatusChanged(object sender, MessageEventArgs e)
/// <param name="e"></param>
private void Options_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "DisplayMode")
if (e.PropertyName == "DisplayMode" || e.PropertyName == "RankVoteCounterMethod")
UpdateResults();
}

Expand Down
Loading

0 comments on commit f9bc936

Please sign in to comment.