I am new to C#, porting some code over to TypeScript from C#. In the C# code, it says this:
public TilingConfig( int p, int q, int maxTiles ) : this()
{
SetupConfig( p, q, maxTiles );
}
public TilingConfig( int p, int q ) : this()
{
if( Geometry2D.GetGeometry( p, q ) != Geometry.Spherical )
throw new System.ArgumentException();
SetupConfig( p, q, PlatonicSolids.NumFacets( p, q ) );
}
private void SetupConfig( int p, int q, int maxTiles )
{
P = p;
Q = q;
m.Unity();
MaxTiles = maxTiles;
Shrink = 1.0;
}
public int P { get; set; }
public int Q { get; set; }
/// <summary>
/// The induced geometry.
/// </summary>
public Geometry Geometry { get { return Geometry2D.GetGeometry( this.P, this.Q ); } }
/// <summary>
/// A Mobius transformation to apply while creating the tiling.
/// </summary>
public Mobius M { get { return m; } set { m = value; } }
private Mobius m;
/// <summary>
/// The max number of tiles to include in the tiling.
/// </summary>
public int MaxTiles { get; set; }
/// <summary>
/// A shrinkage to apply to the drawn portion of a tile.
/// Default is 1.0 (no shrinkage).
/// </summary>
public double Shrink { get; set; }
/// <summary>
/// Returns a Mobius transform that can be used to create a dual {q,p} tiling.
/// This Mobius transform will center the tiling on a vertex.
/// </summary>
public Mobius VertexCenteredMobius()
{
return VertexCenteredMobius( this.P, this.Q );
}
public static Mobius VertexCenteredMobius( int p, int q )
{
double angle = Math.PI / q;
if( Utils.Even( q ) )
angle *= 2;
Vector3D offset = new Vector3D( -1 * Geometry2D.GetNormalizedCircumRadius( p, q ), 0, 0 );
offset.RotateXY( angle );
Mobius m = new Mobius();
m.Isometry( Geometry2D.GetGeometry( p, q ), angle, offset.ToComplex() );
return m;
}
/// <summary>
/// This Mobius transform will center the tiling on an edge.
/// </summary>
public Mobius EdgeMobius()
{
Geometry g = Geometry2D.GetGeometry( this.P, this.Q );
Polygon poly = new Polygon();
poly.CreateRegular( this.P, this.Q );
Segment seg = poly.Segments[0];
Vector3D offset = seg.Midpoint;
double angle = Math.PI / this.P;
offset.RotateXY( -angle );
Mobius m = new Mobius();
m.Isometry( g, -angle, -offset );
return m;
}
}
Specifically the line in SetupConfig, which says:
m.Unity();
Where is that m instantiated? Is it a default of some sort? If so, where is the default specified for Mobius type? Here is the full source code.
In this source code you can check that the Mobius is a struct.
Struct can be define without constructor.
Docs.
Related
How to get a sum of all the results.parent1? I am using linqpad. the dump function puts it in a table but i would like to printed via console.write. How can i achieve the same?
void Main()
{
List<parent> a = new List<parent>();
a.Add(new parent(2, true));
a.Add(new parent(3, false));
a.Add(new parent(4, true));
List<parent> results = a.FindAll(
delegate (parent p)
{
return p.child1 == true;
});
if (results.Count > 0)
{
//how do i find the sum of all the results.parent1?
results.Dump();
Console.Write("sum of all the results.parent1? ");
}
}
/// <summary>
/// This file holds all user defined indicator methods.
/// </summary>
public class parent
{
int v;
public parent(double d, bool b)
{
this.parent1 = d;
this.child1 = b;
}
public double parent1 { get; set; }
public bool child1 { get; set; }
}
I apologize if I irritate you as I am still very new to programming programming.
I am currently learning to work with Astar Pathfinding in Unity.
I am also currently referencing code for several Astar algorithms, many of which also introduce map generation code.
This question is about that map generation code, but I would appreciate it if you could answer it in connection with Astar Pathfinding, if possible.
The following code is introduced by a Japanese programmer.
I have a question about "public static Coord operator +(Coord a, Coord b) {return new Coord(a.x +a.y, b.x + b.y); }" in public struct Coord in the following code.
What do the "a and b" in a.x and b.x mean?
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class AStarGrid
{
public enum GroundType
{
NotRoad,
Road,
}
/// <summary>
/// 座標
/// </summary>
[System.Serializable]
public struct Coord
{
public int x;
public int y;
public static Coord zero = new Coord(){ x = 0, y = 0 };
public static Coord one = new Coord(){ x = 1, y = 1 };
public static Coord left = new Coord(){ x = -1, y = 0 };
public static Coord up = new Coord(){ x = 0, y = 1 };
public static Coord right = new Coord(){ x = 1, y = 0 };
public static Coord down = new Coord(){ x = 0, y = -1 };
public static Coord operator +(Coord a, Coord b)
{ return new Coord(a.x + b.x, a.y + b.y); }
public static Coord operator -(Coord a, Coord b)
{ return new Coord(a.x - b.x, a.y - b.y); }
public float SqrMagnitude { get { return x * x + y * y; } }
public float Magnitude { get { return Mathf.Sqrt(SqrMagnitude); } }
public Coord(int x, int y)
{
this.x = x;
this.y = x;
}
}
/// <summary>
/// Cell
/// </summary>
[System.Serializable]
public class Cell
{
public Coord coord;
public GroundType groundType;
}
[SerializeField]
private List<Cell> _cells;
public List<Cell> Cells { get { return _cells; } }
[SerializeField]
private int _columnCount;
public int ColumnCount { get { return _columnCount; } }
[SerializeField]
private int _rowCount;
public int RowCount { get { return _rowCount; } }
[SerializeField]
private Coord _startCellCoord;
public Cell StartCell { get { return GetCell(_startCellCoord); } set { _startCellCoord = value.coord; } }
[SerializeField]
private Coord _goalCellCoord;
public Cell GoalCell { get { return GetCell(_goalCellCoord); } set { _goalCellCoord = value.coord; } }
public AStarGrid(int columnCount, int rowCount)
{
_columnCount = columnCount;
_rowCount = rowCount;
_cells = new List<Cell>();
for (int i = 0; i < columnCount * rowCount; i++) {
var column = Mathf.FloorToInt(i / rowCount);
var row = i % rowCount;
var coord = new Coord(){ x = column, y = row };
_cells.Add(new Cell(){ coord = coord });
}
}
/// <summary>
/// get cell
/// </summary>
public Cell GetCell(Coord coord){
return GetCell(coord.x, coord.y);
}
/// <summary>
/// get cell
/// </summary>
public Cell GetCell(int x, int y)
{
if (IsValidCoord(x, y)) {
var index = x * _rowCount + y;
return _cells[index];
}
else {
return null;
}
}
/// <summary>
/// Does the cell exist?
/// </summary>
public bool IsValidCoord(int x, int y)
{
return x >= 0 && x < _columnCount && y >= 0 && y < _rowCount;
}
/// <summary>
/// get neighbor cells
/// </summary>
public List<Cell> GetAdjacences(int x, int y)
{
var adjacences = new List<Cell>();
var offsets = new Coord[] { Coord.left, Coord.up, Coord.right, Coord.down };
for (int i = 0; i < offsets.Length; i++) {
var cell = GetCell(x + offsets[i].x, y + offsets[i].y);
if (cell != null) {
adjacences.Add(cell);
}
}
return adjacences;
}
}
a and b are references to instances of Cord struct witch contains x and y variables witch you have access to by using . After name of instance of a class/struct also these a and b means if u use - between two cords it will do the math of x of a minus x of b and so on
string carPrice = driver.FindElement(By.XPath("//body/main[1]/article[1]/section[1]/section[1]/section[4]/div[1]/div[1]/div[1]/div[1]/div[2]/div[1]/div[1]/h3[1]")).Text;
string basePrice = "USD1000";
carPrice is dynamic value which contains currency and comma such USD42,000
Here are several language extension methods to assist, ignore the array extensions, I had several of these hanging around already.
Full source
public static class Extensions
{
/// <summary>
/// Convert string to decimal
/// </summary>
/// <param name="sender">assumed value has one or more digest</param>
/// <returns>decimal value or will throw an exception if can not convert e.g. an empty string</returns>
public static decimal ToDecimal(this string sender) =>
decimal.Parse(Regex.Replace(sender, #"[^\d.]", ""));
/// <summary>
/// Any value in array greater than checkValue
/// </summary>
/// <param name="sender">valid decimal array</param>
/// <param name="checkValue">check if an element in sender is greater than this value</param>
/// <returns>true if condition is met, false if not met</returns>
public static bool GreaterThan(this decimal[] sender, decimal checkValue) =>
sender.Any(value => value > checkValue);
/// <summary>
/// Is sender greater than checkValue
/// </summary>
/// <param name="sender">valid decimal value</param>
/// <param name="checkValue">is sender greater than this value</param>
/// <returns>true if condition is met, false if not met</returns>
public static bool GreaterThan(this decimal sender, decimal checkValue) =>
sender > checkValue;
public static decimal[] ToDecimalArray(this string[] sender)
{
var decimalArray = Array
.ConvertAll(sender,
(input) => new
{
IsDecimal = decimal.TryParse(Regex.Replace(input, #"[^\d.]", ""), out var doubleValue),
Value = doubleValue
})
.Where(result => result.IsDecimal)
.Select(result => result.Value)
.ToArray();
return decimalArray;
}
}
Unit test
using ConvertingUnitTest.Base;
using ConvertingUnitTest.Classes;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace ConvertingUnitTest
{
[TestClass]
public partial class MainTest : TestBase
{
[TestMethod]
[TestTraits(Trait.SingleConvert)]
public void TestToDecimal()
{
string mockedBasePrice = "USD1000";
decimal basePrice = mockedBasePrice.ToDecimal();
decimal expected = 1000;
Assert.AreEqual(basePrice, expected);
}
[TestMethod]
[TestTraits(Trait.SingleConvert)]
public void TestStringValueIsNotGreaterThan()
{
string mockedBasePrice = "USD1000";
decimal basePrice = mockedBasePrice.ToDecimal();
string value = "USD999";
Assert.IsFalse(value.ToDecimal() > basePrice);
}
[TestMethod]
[TestTraits(Trait.SingleConvert)]
public void TestStringValueIsGreaterThan()
{
string mockedBasePrice = "USD1000";
decimal basePrice = mockedBasePrice.ToDecimal();
string value = "USD1001";
Assert.IsTrue(value.ToDecimal() > basePrice);
}
[TestMethod]
[TestTraits(Trait.SingleConvert)]
public void TestStringWithWhiteSpace()
{
string mockedBasePrice = "USD1000";
decimal basePrice = mockedBasePrice.ToDecimal();
string value = "USD10 01";
Assert.IsTrue(value.ToDecimal() > basePrice);
}
[TestMethod]
[TestTraits(Trait.ArrayConvert)]
public void TestStringArrayNotGreaterThan()
{
string mockedBasePrice = "USD1000";
decimal basePrice = mockedBasePrice.ToDecimal();
string[] values = { "USD999", "", "USD20" };
var onlyDecimalArray = values.ToDecimalArray();
Assert.IsFalse(onlyDecimalArray.GreaterThan(basePrice));
}
[TestMethod]
[TestTraits(Trait.ArrayConvert)]
public void TestStringArrayIsGreaterThan()
{
string mockedBasePrice = "USD1000";
decimal basePrice = mockedBasePrice.ToDecimal();
string[] values = { "USD999", "USD2020", "USD20" };
var onlyDecimalArray = values.ToDecimalArray();
Assert.IsTrue(onlyDecimalArray.GreaterThan(basePrice));
Assert.IsTrue(onlyDecimalArray[1].GreaterThan(basePrice));
}
}
}
If your pricing format is fixed you can use this //USD42,000
char[] delimiterChars = {',','U','S','D'};
string[] values =carPrice.Split(delimiterChars);
string join = string.Join("", values);
int price = int.parse(join);
int price = int.parse(join);
The above should be:
int price = int.Parse(join);
Just a simple capital P for Parse.
I have a class with fields - Id , name, company and another 29 fields.
public class Employee
{
[XmlAttribute("textbox1")]
public int Id { get; set; }
[XmlAttribute("textbox11")]
public string Name { get; set; }
[XmlAttribute("textbox21")]
public string Company { get; set; }
[XmlAttribute("textbox22")]
public bool Val1 { get; set; }
[XmlAttribute("textbox23")]
public bool Val2 { get; set; }
public bool TestSomething{get;set;}
}
public class ParseData()
{
List<Employee> employee = new List<Employee>();
XmlSerialiser serializer = new XmlSerializer();
using(FileStream stream = new FileStream("test.xml", FileMode.Open))
{
employees = (Employee)serializer.Deserialize(stream);
}
//Todo: Add the new calculated value TestSomething
}
I'm deserialising the values from the xml data ( which has around 100 employees).
Now I have a new field 'TestSomething' which is not deserialised but will be result of deserialised value as shown below. Is there a way I could add calculated values to the existing list employees ?
foreach(var i in employees)
{
employee.TestSomething = (Val1 == true) ? Val1 : Val2;
}
Any suggestion on this will be appreciated.
The code snippets below are extension methods I use to serialize and deserialize xml strings. Note these need to be put in a static class and referenced in the class for use.
/// <summary>
/// Serializes the object to xml string.
/// </summary>
/// <returns>xml serialization.</returns>
public static string SerializeToXml<T>(this T instance)
where T : class, new()
{
string result;
var format = new XmlSerializer(typeof(T));
using (var strmr = new StringWriter())
{
format.Serialize(strmr, instance);
result = strmr.ToString();
}
return result;
}
/// <summary>
/// Deserializes xml serialized objects.
/// </summary>
/// <param name="xmlDocument">serialized string.</param>
/// <param name="result">out parameter.</param>
/// <returns>Instance object.</returns>
public static bool TryParseXml<T>(this string xmlDocument, out T result)
where T : class, new()
{
result = null;
if (string.IsNullOrWhiteSpace(xmlDocument))
{
return false;
}
try
{
using (TextReader str = new StringReader(xmlDocument))
{
var format = new XmlSerializer(typeof(T));
XmlReader xmlReader = XmlReader.Create(str);
if (format.CanDeserialize(xmlReader))
{
result = format.Deserialize(xmlReader) as T;
}
}
}
catch (InvalidOperationException)
{
return false;
}
return !(result is null);
}
In practice you would have a class of some type that has properties that you would like to store to a disk or database etc. Lets say I have a class:
public class MyPoint
{
public double X { get; set;}
public double Y { get; set;}
}
If I wanted to store a list of MyPoint without much heavy lifting I could serialize the class directly using the SerializeToXml method above.
var myPoints = new List<MyPoint>{new MyPoint{ X= 1, Y = 2}, new MyPoint{X = 3, Y = 4}};
var xmlString = myPoints.SerializeToXml();
Everything is fine and dandy, my info is saved as xml in some file somewhere. But then my boss says, "Dang, sorry about this but we need a Z value now that is computed from the X and Y of each using Z = X * X + Y * Y."
Adding properties to the serialized class isn't a problem (taking properties out is!!
The serializer will try to assign a value to a property that doesn't exist and throw an exception.). But in this case we don't need to worry. I go to the original MyPoint class and add a Z.
public class MyPoint
{
public double X { get; set;}
public double Y { get; set;}
public double Z { get; set;} // <---- Here
}
Now when I parse the xml I will get classes with the new property. Using the TryParseXml I get my list of points.
// assume I have a string already from the xml document to use.
List<MyPoint> points = null;
if(serializedPoints.TryParse(out points))
{
foreach(var point in points)
{
point.Z = X * X + Y * Y;
}
}
var serializedPointsWithZ = points.SerializeToXml();
Now serializedPointsWithZ is just a string that can be written to a file etc.
Given a node like
class Node
{
public int Val { get; set; }
public Node Parent { get; set; }
public List<Node> Children { get; set; } = new List<Node>();
/// <summary>
/// Sum of values in descendant nodes
/// </summary>
public int DescendantsSum { get; set; } = 0;
/// <summary>
/// Sum of values in tree whose root is this node
/// </summary>
public int TreeSum { get { return Val + DescendantsSum; } }
}
and a tree of Nodes with Vals that have been set, what I'm trying to do is what is described in the summary of the following method I wrote
/// <summary>
/// Given a tree like
///
/// Val=100
/// \
/// Val=200
/// / \
/// / Val=100
/// Val=100
/// / \
/// Val=500 Val=600
///
/// set a field for each node showing the sum of the values
/// in the subtree whose root is that node, making it into
///
/// Val=100
/// Sum=1600
/// \
/// Val=200
/// Sum=1500
/// / \
/// / Val=100
/// / Sum=100
/// Val=100
/// Sum=1200
/// / \
/// Val=500 Val=600
/// Sum=500 Sum=600
///
/// </summary>
static void SetSums(Node[] nodes)
{
foreach(var leaf in nodes.Where(node => node.Children.Count == 0))
for(var cur = leaf; cur.Parent != null; cur = cur.Parent)
cur.Parent.DescendantsSum += cur.TreeSum;
}
However, this is leading to incorrectly large values like 3400 where it should be 1600. I've thought over my algorithm and I can't see where it is flawed. Any hints?
When you are working with trees it's sometimes easier to go from the top to the buttom and not the other way as you did.
I think this should work for your needs:
public class Node
{
public int Val { get; set; }
public Node Parent { get; set; }
public List<Node> Children { get; set; } = new List<Node>();
/// <summary>
/// Sum of values in descendant nodes
/// </summary>
public int DescendantsSum
{
get
{
var sum = 0;
foreach(var child in Children)
{
sum += child.TreeSum;
//You can do this instead
//sum += child.Val;
//sum += child.DescendantsSum;
}
return sum;
}
}
/// <summary>
/// Sum of values in tree whose root is this node
/// </summary>
public int TreeSum { get { return Val + DescendantsSum; } }
}
Or by using LINQ:
public int DescendantsSum
{
get
{
return Children.Sum(child => child.TreeSum);
}
}
I'm not going to discuss the top-down vs bottom-up algorithms. You have chosen the bottom-up, fine, so where is the flaw?
Consider the following simple tree:
child1
\
parent - grandparent
/
child2
Your algorithm will do:
parent.DescendantsSum += child1.TreeSum;
grandparent.DescendantsSum += parent.TreeSum;
parent.DescendantsSum += child2.TreeSum;
grandparent.DescendantsSum += parent.TreeSum;
As you can see, parent.TreeSum is added twice to the grandparent.DescendantsSum which leads to the incorrect results.
Since the DescendantsSum is effectively the sum of the Val of all descendant nodes, one way to fix the algorithm is to process all nodes and add the node Val to each node parent.
static void SetSums(Node[] nodes)
{
foreach (var node in nodes)
node.DescendantsSum = 0;
foreach (var node in nodes)
for (var parent = node.Parent; parent != null; parent = parent.Parent)
parent.DescendantsSum += node.Val;
}
You need a recursive function.
This works fine:
class NodeTest
{
public static void Run()
{
var root = new Node() { Val = 1 };
var a1 = new Node() { Val = 2 };
var a2 = new Node() { Val = 3 };
var a11 = new Node() { Val = 4 };
var a12 = new Node() { Val = 5 };
var a13 = new Node() { Val = 6 };
var a21 = new Node() { Val = 7 };
var a22 = new Node() { Val = 8 };
a1.Children.AddRange(new Node[] { a11, a12, a13 });
a2.Children.AddRange(new Node[] { a21, a22 });
root.Children.AddRange(new Node[] { a1, a2 });
Console.WriteLine(root.DescendantsSum);
Console.WriteLine(root.TreeSum);
Console.WriteLine();
Console.WriteLine(a1.DescendantsSum);
Console.WriteLine(a1.TreeSum);
}
}
class Node
{
public int Val { get; set; }
public List<Node> Children { get; set; }
/// <summary>
/// Sum of values in descendant nodes
/// </summary>
public int DescendantsSum
{
get
{
return TreeSum - Val;
}
}
/// <summary>
/// Sum of values in tree whose root is this node
/// </summary>
public int TreeSum
{
get
{
return GetTreeSum(this);
}
}
public Node()
{
Children = new List<Node>();
}
private int GetTreeSum(Node node)
{
int result = 0;
if (node.Children.Count > 0)
{
result += node.Val;
node.Children.ForEach(c => { result += GetTreeSum(c); });
}
else
result += node.Val;
return result;
}
}