Is this activity-diagram showing well how my method works by first checking if the input is valid, if it isn't throw an exception, if it is: create 4 objects containing lists?
Not quite sure if activity diagrams are meant for this? Im trying to illustrate this:
public void MyMethod(string fileName) {
if (condition) {
var file = ReadFile("Levels", fileName);
object1 = new object1();
object1.Parse(file);
object2 = new object2();
object2.Parse(file);
object3 = new object3();
object3.Parse(file);
object4 = new object4();
object4.Parse(file);
} else {
throw new ArgumentException("Parser cannot load");
}
}
I'm new to UML. Not sure if the activity diagram is valid this way and if it even makes sense to others.
This is not a valid UML activity diagram. There are a number of ways to get a valid diagram. Personally, I would make the following changes:
Put yes and no in square brackets: [yes] and [no].
Reverse the direction of the flow connected to Throw exception.
Add a so-called activity final node (a circle with a bullet inside) behind Throw exception and add a flow from Throw exception to the final node.
Remove the green part of your diagram completely and replace it with an action Let every object parse itself.
Add an activity final node below Let every object parse itself and add a flow from Let every object parse itself to the final node.
Related
Basically I'm trying to put a result of a query into a file path, into the image source.
Updated code. Now I actually get the string I want but I still have trouble with interpolating it into the Uri constructor.
Random rand = new Random();
var nrand = rand.Next(1, 4);
using (var db = new DungeonContext())
{
var query = db.Rooms.Where(b => b.RoomId == nrand).Select(b => b.RoomName);
foreach(string name in query)
{
nameOfRoom = name;
}
}
Somehow I have trouble setting images dir as Resources since I'm missing advancent properties for this folder.
roomScreen.Source = new BitmapImage(new Uri($"/images/{nameOfRoom}.png", UriKind.Relative));
Making Uri relative seemed to stop throwing exceptions, but the intended effect does not happen.
The way you're creating the URI is correct. The trouble is that you're trying to use what is likely meant to be readable text (the name of a room) in a URI and as a flle name. You didn't specify what nameOfRoom is, so I can't tell exactly why it's invalid.
There are ways around it. You could look at this answer which explains how to remove invalid characters from a file name.
But the best solution is not to have the problem. Don't use the name of the room as a file name. Your question indicates that a room has an ID, which is apparently an integer. Using that instead would be much easier:
using (var db = new DungeonContext())
{
room = db.Rooms.Where(b => b.RoomId == nrand);
}
and then
roomScreen.Source = new BitmapImage( new Uri($"/images/Room{room.RoomId}.png"));
If you want to use your code as-is, that's possible. When you do this:
nameOfRoom = db.Rooms.Where(b => b.RoomId == nrand).ToString();
you're calling ToString() on what is presumably a Room class. Unless you override that method, the result will always be the name of the class. (So it would be the same for every room.)
If you overrode the ToString method:
public override string ToString()
{
return $"Room{RoomId}";
}
then calling room.ToString() would return "Room1" or "Room2", etc.
String interpolation calls ToString(), so in that case you could just do
roomScreen.Source = new BitmapImage( new Uri($"/images/{room}.png"));
That works. One downside is that it's not explicit. Someone reading that line of code might not know that Room.ToString() is also the value used to create a file name. You might also want to use the ToString() method differently.
If you wanted to be really explicit and clear, you could create an extension method like this:
public static class RoomFileNameExtensions
{
public static string GetImageFileName(this Room room)
{
return $"Room{room.RoomId}.png";
}
}
Now the Room class isn't responsible for knowing how file names are created. You could do this:
roomScreen.Source = new BitmapImage( new Uri($"/images/{room.GetImageFileName()}"));
You can use that both when creating the file and when reading the file. It ensures that both operations will determine the file name the same way.
Apparently all I needed to do was add UriKInd.RelativeOrAbsolute to the constructor.
If it's in the project directory, utilizing the System.IO.Path namespace comes to mind - something like
Path.Combine(Environment.CurrentDirectory, $"/images/{nameOfRoom}.png")
I am working on a Task in which the code automatically opens a drawing selected by the user [in a UI] and selects all the objects in the drawing and starts to explode all the of them till they cant be exploded anymore. While doing this I face a problem, the original (un-exploded 3D object) is still present in the drawing, super imposed by the Exploded object. Every recursive call of the Explode function creates a new exploded 3D object of that object.
Here is a snippet of the code I working on:
PromptSelectionResult ss = ed.SelectAll();
using (DocumentLock acLckDoc = doc.LockDocument())
{
using (Transaction tr = db.TransactionManager.StartTransaction())
{
objs = new DBObjectCollection();
foreach (SelectedObject so in ss.Value)
{
Entity ent = (Entity)tr.GetObject(so.ObjectId, OpenMode.ForWrite);
if (!(ent is Solid3d))
{
ent.Explode(objs);
ent.UpgradeOpen();
ent.Erase();
}
}
tr.Commit();
}
}
As soon as the control comes on to the ent.Erase() statement - it throws an exception, eCannotBeErasedByCaller. I cant figure out why? I have unlocked all layers, opened the entity for Write, CommandFlags have been set to Session and UsePickSet (shuffled through all).
Anybody got any suggestions?
Looking at your description, you probably need a recursive explode. Sometime ago I did a code around this, for other type of entities, but you can adjust it.
private List<DBObject> FullExplode(Entity ent)
{
// final result
List<DBObject> fullList = new List<DBObject>();
// explode the entity
DBObjectCollection explodedObjects = new DBObjectCollection();
ent.Explode(explodedObjects);
foreach (Entity explodedObj in explodedObjects)
{
// if the exploded entity is a blockref or mtext
// then explode again
if (explodedObj.GetType() == typeof(BlockReference) ||
explodedObj.GetType() == typeof(MText))
{
fullList.AddRange(FullExplode(explodedObj));
}
else
fullList.Add(explodedObj);
}
return fullList;
}
source: http://adndevblog.typepad.com/infrastructure/2013/04/get-cogopoint-label-text.html
I finally found out the reason why the Original objects werent getting erased.
In the earlier part of the code, a AutoCAD Plant3D dwg is exported to AutoCAD (ExporttoAutoCAD / Saveas), this was creating Proxy items. These cant be deleted manually or via code.
Only way is to explode the PipeLines and Inline assets before exporting the file. This happens automatically if you export the file, but if you use saveas, you will have to explode the Pipe components before you export the file.
Wasted a lot of time understanding the cause, but finally got it!
So I have a cmdlet written in c#: Get-LivingCharacter. I want users to use this like Get-LivingCharacter -Name "Bran", but I would like to allow for the list of available characters to change. Maybe today, "Bran" is a valid name to pass in for Get-LivingCharacter, but maybe in the future it will not be. Things happen.
For convenience I want to allow tab-completion of this field. However, I can't seem to get that to work for non-const data sets. Dynamic fields don't even auto-complete the field name, nevermind the value, and I don't know a way to implement this for a non-dynamic field. Conceptually, I could generate a .ps1 file on startup given the current data set, and then load that ps1 as the module, but this feels a bit like killing a pup with a greatsword - lots of overkill. Is there a better option?
I had already implemented a similar function to the DynamicParam helper function, as reference in the comments. However, tab completion wasn't working. I was writing a minimal reproduction example, when...my tab completion worked.
It turns out, it reproducibly works/breaks based on the inclusion of a WriteDebug statement:
[Cmdlet("Get", "LivingCharacter")]
public class GetLivingCharacter : Cmdlet, IDynamicParameters
{
protected override void ProcessRecord()
{
}
public object GetDynamicParameters()
{
WriteDebug("Getting names"); // Tab completion won't work with this here - comment it out and it works.
^^^^^^^^^^
var chars = new List<String>() { "Bran", "Arya" };
var dict = new RuntimeDefinedParameterDictionary();
var attributes = new Collection<Attribute>
{
new ParameterAttribute
{
HelpMessage = "Enter a valid open name",
Mandatory = true
},
new ValidateSetAttribute(chars.ToArray()),
};
dict.Add("Name", new RuntimeDefinedParameter("Name", typeof(string), attributes));
return dict;
}
}
After some digging, the WriteDebug statement is throwing (which I assume is because it can't output while I'm typing). It then recreates the GetLivingCharacter class after I've finished the command to validate. It took a while to find since, because of the issue, I can't write the error to the console, so I had to append to a temp file instead.
I have a list of images like this:
public List<Image> imageList = new List<Image>();
I also have a picture class in order to collect and manipulate data about the images in the list:
public Class Pic {
// properties and stuff
}
And then I have a function that takes an integer as an argument. That integer corresponds to an image in the image list. What I want to do in the function is to check if an instance of the Pic class has been created for that particular image. If not, I want to create it, using the value of the variable passed into the function. The following code obviously doesn't work, but it shows what I want:
public void doStuffWithImage(int picNumber) {
// Check if instance called pic + picNumber exists
if(pic + picNumber.toString() == null) {
// Create an instance
Pic pic + picNumber.toString() = new Pic();
}
}
Suggestions on how to accomplish this?
It seems like you're trying to create individual variables pic1, pic2, etc. you'd be better off using a dictionary:
Dictionary<int, Pic> pics = new Dictionary<int, Pic>();
public void doStuffWithImage(int picNumber) {
// Check if instance called pic + picNumber exists
if(!pics.ContainsKey(picNumber)) {
// Create an instance
pics[picNumber] = new Pic();
}
}
You need to create a "registry" of known Pics. DIctionary<int,Pic> would be good collection to hold this registry. You need to store the registry itself somewhere - perhaps in the "factory" object that registers your pictures.
class PicFactory {
private readonly IDictionary<int,Pic> knownPics = new Dictionary<int,Pic>();
public Pic GetOrCreate(int id) {
Pic res;
if (knownPics.TryGetValue(id, out res)) {
return res;
}
res = new Pic(id.ToString()); // This assumes that Pic(string) exists
knownPics.Add(id, res);
return res;
}
}
This way of implementing a registry may be too primitive for your purposes - for example, if you need your registry to be concurrent, you would need to set up some sort if a locking scheme to protect the knownPics dictionary. The class that accesses pictures would need to create an instance of PicFactory, so that it could access pictures through the GetOrCreate(id) call.
If you are using .net 4.0 or more you can use Lazy type which:
Provides support for lazy initialization.
Which means that the object will be constructed not in the moment of declaration, but when first accessed.
So you can basically declare them like
List<Lazy<Pic>> ....
See Lazy<T> and the Lazy Loading Pattern in general - this is actually a common optimization technique as it defers what can add up to a lot at startup to microdelays during runtime.
Be wary about making sure the microdelays are worth it, and I advise leaving methods about which can force loading.
If you're grabbing from a list, preface with a .Any or .Contains check, and since you're looking up by name like that, consider using a Dictionary instead
I'm using AngleSharp to parse HTML5 at the moment what I'm doing is wrapping the elements I want to parse with a little bit of HTML to make it a valid HTML5 and then use the parser on that, is there a better of doing it? meaning, parsing specific elements directly and validate that the structure is indeed HTML5?
Hm, a little example would be nice. But AngleSharp does support fragment parsing, which sounds like the thing you want. In general fragment parsing is also applied when you set properties like InnerHtml, which transform strings to DOM nodes.
You can use the ParseFragment method of the HtmlParser class to get a list of nodes contained in the given source code. An example:
using AngleSharp.Parser.Html;
// ...
var source = "<div><span class=emphasized>Works!</span></div>";
var parser = new HtmlParser();
var nodes = parser.ParseFragment(source, null);//null = no context given
if (nodes.Length == 0)
Debug.WriteLine("Apparently something bad happened...");
foreach (var node in nodes)
{
// Examine the node
}
Usually all nodes will be IText or IElement types. Also comments (IComment) are possible. You will never see IDocument or IDocumentFragment nodes attached to such an INodeList. However, since HTML5 is quite robust it is very likely that you will never experience "errors" using this method.
What you can do is to look for (parsing) errors. You need to provide an IConfiguration that exposes an event aggregator, which collects such events. The simplest implementation for aggregating only such events (without possibility of adding / removing multiple handlers) is the following:
using AngleSharp.Events;
// ...
class SimpleEventAggregator : IEventAggregator
{
readonly List<HtmlParseErrorEvent> _errors = new List<HtmlParseErrorEvent>();
public void Publish<TEvent>(TEvent data)
{
var error = data as HtmlParseErrorEvent;
if (error != null)
_errors.Add(error);
}
public List<HtmlParseErrorEvent> Errors
{
get { return _errors; }
}
public void Subscribe<TEvent>(ISubscriber<TEvent> listener) { }
public void Unsubscribe<TEvent>(ISubscriber<TEvent> listener) { }
}
The simplest way to use the event aggregator with a configuration is to instantiate a new (provided) Configuration. Here as a sample snippet.
using AngleSharp;
// ...
var errorEvents = new SimpleEventAggregator();
var config = new Configuration(events: errorEvents);
Please note: Every error that is reported is an "official" error (according to W3C spec.). These errors do not indicate that the provided code is malicious or invalid, just that something is not following the spec and that a fallback had to be applied.
Hope this answers your question. If not, then please let me know.
Update Updated the answer for the latest version of AngleSharp.