Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Locked thread
Knyteguy
Jul 6, 2005

YES to love
NO to shirts


Toilet Rascal

Hughmoris posted:

Since the OP hasn't been updated in 3 years, are there any new recommended books for people looking to pick up C# as a first language?

This was a pretty good book in my opinion: http://www.amazon.com/Stephens-Prog...24-Hour+Trainer

It walks you through how to use and setup visual studio, building program UIs, creating functions, manipulating variables, accessing the printer, making responsive dialogs, etc and they give you 1 main exercise and 4-5 extra exercises at the end of every chapter. At the end of the book you'll have written 1 pretty complicated program, and 40-50 main and extra programs.

The author writes in a very comfortable manner that makes it all easy to follow even if you've never learned a language. He doesn't just drop a shitload of code on you and expect you to copy it. Often he'll explain concepts and then challenge you to implement the knowledge yourself (though you can download exercise code from his website if you get stuck). Obviously you won't pick it all up in 24 hours, so the title was my only complaint about it

It will not cover more advanced things like multi-threading/task paralleling, but it's a great way to get into the language.

e: clarification

Knyteguy fucked around with this message at 23:55 on Sep 29, 2012

Adbot
ADBOT LOVES YOU

Bozart
Oct 28, 2006

Give me the finger.

Well that's sure cool as hell and answers my second question (use Array2d for matrix multiplication) but how do a take a list of lists as outlined before and get the item in the same position out of the inner list and put it into another list?

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

Bozart posted:

Well that's sure cool as hell and answers my second question (use Array2d for matrix multiplication) but how do a take a list of lists as outlined before and get the item in the same position out of the inner list and put it into another list?

I don't think a List<List<float>> would be a reasonable data structure to use for matrices, frankly.

Also, you're reinventing the wheel (which is fine if you're just learning); see http://msdn.microsoft.com/en-us/library/system.drawing.drawing2d.matrix(v=vs.110).aspx

New Yorp New Yorp fucked around with this message at 01:01 on Sep 30, 2012

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

That book looks like it's terribly organized. How can you spend 10 chapters talking about Winforms GUI stuff before introducing the concept of variables?

I wish Jon Skeet would get around to writing his book for beginners, because then there would be a book that I could wholeheartedly recommend.

Knyteguy
Jul 6, 2005

YES to love
NO to shirts


Toilet Rascal

Ithaqua posted:

That book looks like it's terribly organized. How can you spend 10 chapters talking about Winforms GUI stuff before introducing the concept of variables?

I wish Jon Skeet would get around to writing his book for beginners, because then there would be a book that I could wholeheartedly recommend.

I think he pretty much just explains how to actually build the UI, and then goes into the code side of it. I remember being a bit frustrated reading the book because I simply wanted to make a basic calculator and wasn't familiar with how to declare variables in C# :arghfist:. All-in-all it was extremely helpful for someone who had never touched Visual Studio though.

Knyteguy
Jul 6, 2005

YES to love
NO to shirts


Toilet Rascal

Ithaqua posted:

Yes. Do not submit this code to a potential employer as it is.

Here's my short list, without digging into the actual functionality:
  • You're not separating your concerns. Presentation logic and application logic should not be mixed. This is a huge problem -- it shows that either you lack a fundamental understanding of object oriented programming (which is bad), or that you don't give a poo poo about doing it right (which is worse).
  • Where are your unit tests? How do you know your application functions properly? How do you know that you're not breaking existing functionality when making changes? Having unit tests earns you points with a lot of employers. It certainly does with me!
  • You do not follow Microsoft's naming conventions. I'm a stickler for this one, especially in sample code. Other people will tell you it doesn't matter, but my position is that Microsoft took the trouble to create a style guide, it makes a lot of sense, and there are lots of tools that can help enforce it. If you have a good reason for not following the guide and can articulate it and convince me, that's fine. If you don't have a good reason, then I chalk it up to sloppiness and/or not giving a poo poo.

Question: Does your application even update the progress bar visually? You're blocking the UI thread as far as I can tell.

So after re-reading this I decided I'm probably just going to rewrite most of my inventory program tomorrow. I've never actually done unit tests, so I'm going to try a test-driven design with multi-threading and see how it goes.

I'm still not very familiar with OOP principals (I'm not formally taught and usually just try different things until they work), do you or does anyone else have a good book I could read on the subject? I feel a bit over my head with best practices regarding this.

Anyway here's another sample of code that I'm hoping is good as-is.
code:
private string parseLinks(string url)
{
	// Our HTML page has &amp; instead of &, which won't work for URLs
	url = url.Replace("&amp;", "&");
	if (!url.StartsWith("http"))
	{
		url = "http://REMOVED FOR EMPLOYER PRIVACY.com" + url;
	}
	string formattedUrl = url;
	HtmlAgilityPack.HtmlWeb htmlWeb = new HtmlAgilityPack.HtmlWeb();
	HtmlAgilityPack.HtmlDocument doc = htmlWeb.Load(formattedUrl);
	List<string> hrefTags = new List<string>();
	// Pull links from HTML
	foreach (HtmlNode link in doc.DocumentNode.SelectNodes("//a[@href]"))
	{
		if (link.Attributes["href"] != null)
		{
			HtmlAttribute linkElement = link.Attributes["href"];
			hrefTags.Add(linkElement.Value);
		}
	}
	
	for (int i = 0; i < hrefTags.Count(); i++)
	{
		if (hrefTags[i].Contains(".jpg") || hrefTags[i].Contains(".jpeg") || hrefTags[i].Contains(".tif"))
		{
			// Get the SKU code from the image
			string productCode = hrefTags[i];
			productCode = productCode.Replace(".jpg", "");
			productCode = productCode.Replace(".tif", "");
			productCode = productCode.Replace(".jpeg", "");
			// Get it ready for Excel: i.e.: 428-2006;[url]http://linktoimage.com/428-2006.jpg\n[/url]
			skuTextBox.AppendText(productCode + ";" + formattedUrl + hrefTags[i].ToString() 
				+ System.Environment.NewLine);
			// Make sure we don't follow this link later
			hrefTags[i] = null;
		}
		else
		{
			if (!hrefTags[i].StartsWith("?") && hrefTags[i] != "/")
			{
				// this is a link, add this to list so we can check it later for more images
				hrefTags[i] = formattedUrl;
			}
		}
	}
	return null;
}
It's not the most complicated thing, but if anyone would mind giving just a quick critique that would be great (I won't ask again for awhile:shobon:)

E: had to remove html special codes

Knyteguy fucked around with this message at 08:05 on Sep 30, 2012

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

Knyteguy posted:

So after re-reading this I decided I'm probably just going to rewrite most of my inventory program tomorrow. I've never actually done unit tests, so I'm going to try a test-driven design with multi-threading and see how it goes.

I'm still not very familiar with OOP principals (I'm not formally taught and usually just try different things until they work), do you or does anyone else have a good book I could read on the subject? I feel a bit over my head with best practices regarding this.

Anyway here's another sample of code that I'm hoping is good as-is.

It's not the most complicated thing, but if anyone would mind giving just a quick critique that would be great (I won't ask again for awhile:shobon:)

E: had to remove html special codes

* The code itself is meaningless. You're providing no background on why this code exists. What problem were you solving? Why did you approach it that way? Did you try any other approaches?

* The method name sucks. It's named "parseLinks", but it's doing a hell of a lot more than that. It probably should be two (or more) methods, each descriptively named. Don't be afraid to make really long method names, as long as it's descriptive.

* Why are you creating a new variable here?
code:
if (!url.StartsWith("http"))
{
	url = "http://REMOVED FOR EMPLOYER PRIVACY.com" + url;
}
string formattedUrl = url;
Just keep using url.

* Why does the method always return null? That makes no sense. If it doesn't return anything, it should be void.

* That for loop is looking pretty suspect. First off, be careful about using the Count() method -- it has to iterate over the entire collection to get that count. List<T> has a Count property, which you should be using in this case.

* This code makes no sense whatsoever:
code:
// Make sure we don't follow this link later
hrefTags[i] = null;
* This code also makes no sense:
code:
if (!hrefTags[i].StartsWith("?") && hrefTags[i] != "/")
{
    // this is a link, add this to list so we can check it later for more images
    hrefTags[i] = formattedUrl;
}
What do you mean "check it later"? There is no later in this method. It's pointless.

New Yorp New Yorp fucked around with this message at 08:37 on Sep 30, 2012

Knyteguy
Jul 6, 2005

YES to love
NO to shirts


Toilet Rascal

Ithaqua posted:

* The code itself is meaningless. You're providing no background on why this code exists. What problem were you solving? Why did you approach it that way? Did you try any other approaches?

* The method name sucks. It's named "parseLinks", but it's doing a hell of a lot more than that. It probably should be two (or more) methods, each descriptively named. Don't be afraid to make really long method names, as long as it's descriptive.

* Why are you creating a new variable here?
code:
if (!url.StartsWith("http"))
{
	url = "http://REMOVED FOR EMPLOYER PRIVACY.com" + url;
}
string formattedUrl = url;
Just keep using url.

* Why does the method always return null? That makes no sense. If it doesn't return anything, it should be void.

* That for loop is looking pretty suspect. First off, be careful about using the Count() method -- it has to iterate over the entire collection to get that count. List<T> has a Count property, which you should be using in this case.

* This code makes no sense whatsoever:
code:
// Make sure we don't follow this link later
hrefTags[i] = null;
* This code also makes no sense:
code:
if (!hrefTags[i].StartsWith("?") && hrefTags[i] != "/")
{
    // this is a link, add this to list so we can check it later for more images
    hrefTags[i] = formattedUrl;
}
What do you mean "check it later"? There is no later in this method. It's pointless.

Thanks Ithaqua. I'll be going over this tomorrow and seeing what I can get from it. I made this program back in April and need to go over all of the code to figure out what it's doing again apparently. On that note I probably need better comments too.

Okita
Aug 31, 2004
King of toilets.
Here's a slightly more concise(but more esoteric and cheeky) way of essentially doing what you did. Just trying to give you some ideas about ways you can go about doing this kind of stuff:
code:
//...

url = url.Replace("&amp;", "&");
if (!url.StartsWith("http"))
{
    url = "http://REMOVED FOR EMPLOYER PRIVACY.com" + url;
}

var validExtensions = new List<string> {".jpg", ".jpeg", ".tif"};
var links = GetLinks(url, link => validExtensions.Exists(link.EndsWith));

foreach (string link in links)
{
    string productCode = link.Substring(0, link.LastIndexOf('.'));
    skuTextBox.AppendText(string.Format("{0};{1}{2}", productCode, url + link, Environment.NewLine));
}

//...

private List<string> GetLinks(string url, Predicate<string> condition = null)
{
    var htmlWeb = new HtmlAgilityPack.HtmlWeb();
    var doc = htmlWeb.Load(url);

    var links = new List<string>();
    
    foreach (HtmlNode link in doc.DocumentNode.SelectNodes("//a[@href]"))
    {
        if (link.Attributes["href"] != null)
        {
            string value = link.Attributes["href"].Value;
            
            if ((condition != null) && (! condition.Invoke(value)))
            {
                continue;
            }

            links.Add(value);
        }
    }
       
    return links;
}

dwazegek
Feb 11, 2005

WE CAN USE THIS :byodood:

Ithaqua posted:

* That for loop is looking pretty suspect. First off, be careful about using the Count() method -- it has to iterate over the entire collection to get that count. List<T> has a Count property, which you should be using in this case.

This isn't entirely true. The IEnumerable.Count() extension method checks if the IEnumerable implements ICollection, and if it does, then it just returns the value of the ICollection.Count property. I'm not entirely sure, but I think it does the same check to see if it is an array type and then returns the Length. If it can't do either of those things, then it will enumerate the entire collection.

Granted, this is kinda moot as there is no reason to use the Count method above the Count property.

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

dwazegek posted:

This isn't entirely true. The IEnumerable.Count() extension method checks if the IEnumerable implements ICollection, and if it does, then it just returns the value of the ICollection.Count property. I'm not entirely sure, but I think it does the same check to see if it is an array type and then returns the Length. If it can't do either of those things, then it will enumerate the entire collection.


That makes sense. I checked the code for Count() and you're right, it does check if it's an ICollection and return the Count property. It doesn't do it for arrays, though.

Sedro
Dec 31, 2008
Arrays in C# implement ICollection so they will work with Enumerable.Count. Actually there are special cases in the CLR for casting arrays which you will be thankful for if you've ever worked with arrays in Java.

Orzo
Sep 3, 2004

IT! IT is confusing! Say your goddamn pronouns!

Ithaqua posted:

That makes sense. I checked the code for Count() and you're right, it does check if it's an ICollection and return the Count property. It doesn't do it for arrays, though.
Even so, you should still use Count instead of Count() if you can get away with it, since it's better to avoid type checking to ultimately call the Count property anyway.

mortarr
Apr 28, 2005

frozen meat at high speed
Has anyone built custom reports over TFS / TFS Express - I'm looking to find out stuff like:
- How many solutions we have
- What version of VS was used to create the solution (eg. VS05, VS08 BIDS, VS10)
- How many projects the solutions have
- What .net frameworks those projects are addressing (eg. 2, 3.5, 4, 4.5)

I'm doing some investigation into upgrading my teams development environment/toolset to VS12 / some kind of source control that isn't sourcesafe, and trying to get a handle on the size of the problem... I've got a copy of the VSS db moved into TFS express to play around with, but I'm struggling to make any headway on the analysis. If TFS express is no good, I think there is a 90-day eval option for TFS full which I can use.

If there's an SQL query, custom reports, or code anyone has that answer those questions I'm keen to hear about it.

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

mortarr posted:

Has anyone built custom reports over TFS / TFS Express - I'm looking to find out stuff like:
- How many solutions we have
- What version of VS was used to create the solution (eg. VS05, VS08 BIDS, VS10)
- How many projects the solutions have
- What .net frameworks those projects are addressing (eg. 2, 3.5, 4, 4.5)

I'm doing some investigation into upgrading my teams development environment/toolset to VS12 / some kind of source control that isn't sourcesafe, and trying to get a handle on the size of the problem... I've got a copy of the VSS db moved into TFS express to play around with, but I'm struggling to make any headway on the analysis. If TFS express is no good, I think there is a 90-day eval option for TFS full which I can use.

If there's an SQL query, custom reports, or code anyone has that answer those questions I'm keen to hear about it.

This isn't really a TFS question -- it has no awareness of any of the things you're looking to find out.

That said, you could write a program to recurse your source control tree, open up the .sln files, open up the .csproj files referenced, and parse out the information you're looking for.

Let me put it like this, though: No matter what, you're better off using TFS over SourceSafe. You're better off using anything over SourceSafe.

If you're serious about moving your organization to TFS and you have the budget to spend on good consulting on TFS setup and best practices, drop me a PM and I can get you in touch with someone. My employer does TFS consulting and we're very good at it.

CapnAndy
Feb 27, 2004

Some teeth long for ripping, gleaming wet from black dog gums. So you keep your eyes closed at the end. You don't want to see such a mouth up close. before the bite, before its oblivion in the goring of your soft parts, the speckled lips will curl back in a whinny of excitement. You just know it.

Knyteguy posted:

Anyway here's another sample of code that I'm hoping is good as-is.
You guys talking about the Count method are all missing the biggest issue, which is that it shouldn't be being called at all.
code:
foreach (string hrefTag in hrefTags)
This does exactly the same thing and is about a million times more elegant and has less potential for screwups.


Switching gears from telling to asking, fluent nhibernate apparently wasn't done with me just yet. I'm trying to implement inserts, and this is failing for me:
code:
using (ISession isession = iSeriesFactory.OpenSession())
{
	using (var trans = isession.BeginTransaction())
	{
		CFPAI newpai = new CFPAI
		{
			ACCTAI = 99,
			CNTIAI = "EM",
			CODEAI = "test"
		};
		isession.Save(newpai);
		trans.Commit();
	}
}
The error I'm getting is "could not insert: [CFPAI#CFPAI][SQL: INSERT INTO pplcasdvU.CFPAI (CNTIAI, ACCTAI, CODEAI) VALUES (?, ?, ?)]", which is pretty straightforward -- for some reason it's not actually reading the values I've got there, I guess. But I don't know why.

CFPAI is the name of the table I'm inserting into, those are its three fields, and the whole thing is defined and mapped in Entities and Mappings like it ought to be. I'm missing something -- probably something very basic.

wwb
Aug 17, 2004

Not that I've been much help on this one, but spidey sense says it isn't mapping fields correctly. IE, if one of those is CHAR(2) or whatever the DB2 equivalent is it might not be picking it up in the nhibernate mapping machinery. I'd probably turn up debugging or check out nh profiler to see what it is seeing there.

CapnAndy
Feb 27, 2004

Some teeth long for ripping, gleaming wet from black dog gums. So you keep your eyes closed at the end. You don't want to see such a mouth up close. before the bite, before its oblivion in the goring of your soft parts, the speckled lips will curl back in a whinny of excitement. You just know it.
I'm out of ideas, so maybe? Here's the Entity and Map.

code:
public class CFPAI
{
	public virtual int ACCTAI { get; set; }
	public virtual string CODEAI { get; set; }
	public virtual string CNTIAI { get; set; }

	public override bool Equals(object obj)
	{
		var other = obj as CFPAI;

		if (ReferenceEquals(null, other))
			return false;
		if (ReferenceEquals(this, other))
			return true;

		return (this.ACCTAI == other.ACCTAI && this.CODEAI == other.CODEAI);
	}

	public override int GetHashCode()
	{
		unchecked
		{
			int hash = GetType().GetHashCode();
			hash = (hash * 31) ^ ACCTAI.GetHashCode();
			hash = (hash * 31) ^ CODEAI.GetHashCode();

			return hash;
		}
	}
}
code:
public class CFPAIMap : ClassMap<CFPAI>
{
	public CFPAIMap()
	{
		Table("CFPAI");
		CompositeId()
			.KeyProperty(x => x.ACCTAI)
			.KeyProperty(x => x.CODEAI);
		Map(x => x.CNTIAI);
	}
}
Anything jump out at anybody? I did that composite ID because there isn't actually an id field (there's about a million ACCTAIs of 0 so I can't use that). Google is being spectacularly unhelpful here, by the way. Just a bunch of people having trouble getting their saves to cascade to related tables. Apparently I'm literally the only person to ever have had this problem.

CapnAndy fucked around with this message at 17:44 on Oct 1, 2012

raminasi
Jan 25, 2005

a last drink with no ice

Bozart posted:

I've got it stuck in my head to learn how to do matrix multiplication in a few different languages. I'm having some trouble with F# (which I am also learning):

code:
#light
module FSharpBlotter.MatrixMult
   // define two matrixes for multiplication
   let A = [[1; 2; 3]; 
            [3; 2; 1]]
   
   let B = [[1; 2]; 
            [3; 4]; 
            [5; 6]]
   
   // function to pull out a specific row and return as a list of int
   let Row (lst:_ list) (i: int) = 
      lst.[i]

   // function to pull out a specific column and return as a list of int
   let Col (lst:(int list) list) (i: int) = 
      [for R in lst do R.[i]]
      
   
   let A1 = A.[1]
   let A2 = Row A 1
   
   //error:
   //stdin(129,8): error FS0030: Value restriction. The value 'A3' has been inferred to have generic type
   let A3 = Col A 1
   
   // and then:
   // dot product function for two lists of ints
   
   // putting it together with a fold

Any ideas on how to get the Col function to work correctly? Also, while I want to implement this as a function of lists (and plan on completing this implementation) is there another way I should represent matrices in F#?

What development environment are you using? Because dropping this code into a .fs file in Visual Studio 2010 gives me the exact problem right away: "Value restriction. The value 'A3' has been inferred to have generic type. Either define 'A3' as a simple data term, make it a function with explicit arguments or, if you do not intend for it to be generic, add a type annotation." There's a specific MSDN page about this.

You can see the problem yourself by noticing the type that's been inferred for Col, which is int list list -> 'a list. (This is the number one way I debug F# type errors.) That's not right, as you definitely were expecting an int list. What's the problem? Well, again, Visual Studio has immediately noticed something wrong with this line:
code:
      [for R in lst do R.[i]]
which should actually be
code:
      [for R in lst -> R.[i]]
do is used for "throw away this result" operations. (I'm not actually sure why this didn't result in the type of Col being int list list -> unit list, but whatever.) Fixing your list comprehension fixed the type of Col which fixed your definition of A3.

Gilg
Oct 10, 2002

Munkeymon posted:

Unrelated to my response, I'm trying to make a (what I would think is) fairly simple XML transformation happen in a web.config for local debugging.

web.config

XML code:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
	<configSections>
		<section name="SomeConfigSource" blah blah blah/>
<!-- etc -->
	</configSections>
<!-- etc -->
	<SomeConfigSource application="bin\Moar.config" />
<configuration/>
web.debug.config

XML code:
<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
	<SomeConfigSource xdt:Transform="Replace" application="C:\Long\Path\To\My\Local\bin\Moar.config"/>
</configuration>
Am I nuts or should this work?
A couple days old, but I didn't see anyone respond, so I think you should look into SlowCheetah, a Visual Studio extension. The built-in Web.config transformation is only done during publishing, i.e. not when local debugging. SlowCheeath will cover that case and also allow you to use transforms with non-ASP.NET projects.

Knyteguy
Jul 6, 2005

YES to love
NO to shirts


Toilet Rascal

Okita posted:

Here's a slightly more concise(but more esoteric and cheeky) way of essentially doing what you did. Just trying to give you some ideas about ways you can go about doing this kind of stuff:
code:
//...

url = url.Replace("&amp;", "&");
if (!url.StartsWith("http"))
{
    url = "http://REMOVED FOR EMPLOYER PRIVACY.com" + url;
}

var validExtensions = new List<string> {".jpg", ".jpeg", ".tif"};
var links = GetLinks(url, link => validExtensions.Exists(link.EndsWith));

foreach (string link in links)
{
    string productCode = link.Substring(0, link.LastIndexOf('.'));
    skuTextBox.AppendText(string.Format("{0};{1}{2}", productCode, url + link, Environment.NewLine));
}

//...

private List<string> GetLinks(string url, Predicate<string> condition = null)
{
    var htmlWeb = new HtmlAgilityPack.HtmlWeb();
    var doc = htmlWeb.Load(url);

    var links = new List<string>();
    
    foreach (HtmlNode link in doc.DocumentNode.SelectNodes("//a[@href]"))
    {
        if (link.Attributes["href"] != null)
        {
            string value = link.Attributes["href"].Value;
            
            if ((condition != null) && (! condition.Invoke(value)))
            {
                continue;
            }

            links.Add(value);
        }
    }
       
    return links;
}

Thank you for the example. I hadn't thought of using a list for the extensions :). The rest of the code is very good as well, I'm going to check out the link you posted as well.

Thanks everyone else too, the help is appreciated.

raminasi
Jan 25, 2005

a last drink with no ice
I need someone to point me in the right direction regarding versioning. I don't even know the best practices for simple cases, and that's assuredly not what I'm working with.

My solution has nine projects: four native C++ projects, two C# projects, one F# project, one C++/CLI project, and a Setup & Deployment project. Some kind of automatic versioning would be great, if that's plausible, but I'd settle for keeping my version numbers in as few places as possible so that there aren't synchronization issues. I know that solutions for this sort of problem can go all the way to full-blown CI servers, but this is just me on a laptop and it's going to stay that way. Thus far it's been "remember to update all the disparate version entries with each release and hope you don't gently caress it up," and it's time to learn how to do things, if not right, at least better.

So: any suggestions for where to start?

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

GrumpyDoctor posted:

I need someone to point me in the right direction regarding versioning. I don't even know the best practices for simple cases, and that's assuredly not what I'm working with.

My solution has nine projects: four native C++ projects, two C# projects, one F# project, one C++/CLI project, and a Setup & Deployment project. Some kind of automatic versioning would be great, if that's plausible, but I'd settle for keeping my version numbers in as few places as possible so that there aren't synchronization issues. I know that solutions for this sort of problem can go all the way to full-blown CI servers, but this is just me on a laptop and it's going to stay that way. Thus far it's been "remember to update all the disparate version entries with each release and hope you don't gently caress it up," and it's time to learn how to do things, if not right, at least better.

So: any suggestions for where to start?

You on a laptop is fine, assuming you're a solo developer. I have TFS installed on my work laptop (of course, I am a TFS consultant...) and I use it all the time.

Install TFS express and branch your code for each release, then build and deploy from your release branch.

Here's what I recommend:

  • Dev (all new development happens here)
  • Integration (optional; only use if you have Version X in QA, while you work on version X+1)
  • Main (your "current version". This is the root of all your other branches; no code makes it to Main unless it's being published)
  • Release (branched from Main)
    • V1
    • V2
    • etc
So, basically, you check your current code in as Main. Then you branch it to integration, then from integration to dev. You code in dev, push down to integration, QA your code, and when everything is signed off, you push down to main. Once you've tested the code in main and you're sure it's stable, branch it for release.

If you find a bug during QA in the integration branch, you can fix it integration, then reverse integrate it up to Dev and merge the change into your dev codebase.

If you have the need to issue periodic hotfixes and maintain your older release versions, it's better to handle release branches like this:
  • Release
    • V1 Hotfix
      • V1.0
      • V1.1
      • V1.etc
This gets you the ability to branch from Release to V1 Hotfix, then to V1.0. When you have to hotfix something, you branch V1.1 from V1 Hotfix, hotfix it there, then reverse integrate the change all the way back up the tree.

Obviously, having good CI set up with automatic builds and unit test running makes all of this a little bit less painful, but it's not a necessary first step. If you're trying to keep track of releases of your software and you're not using source control, you're making your life so much more difficult.

New Yorp New Yorp fucked around with this message at 04:36 on Oct 2, 2012

raminasi
Jan 25, 2005

a last drink with no ice
I guess I wasn't clear, because that wasn't really my question. I have source control - I would have definitely committed suicide by now if not for that. I was just asking about the best way within Visual Studio (or however) to actually maintain version identifiers (e.g. "1.2.4.33") given the totally disparate ways of tracking them for different project types (C# has a handy properties window with both assembly and file versions, F# and C++/CLI require that you manually set up an AssemblyInfo source file, native C++ doesn't even have it in a standardized way, the Setup & Deployment versioning is totally different, et cetera). Automated is great, but even "something uniform" I'll take.

wwb
Aug 17, 2004

No idea what to do for the C++ stuff. Not exactly sure what the build system is for F# but this trick should work if it is using an assembly info file. Tricks were written for C# and I'm sure they work there as we use them across the board. At least across the board until teamcity added the assemblyinfo patcher.

What you want to do is create a central version info file someplace source controlled that everything can hit. In this file, at least for C#, you'd have the relevent parts of the AssemblyInfo.cs file -- eg:

code:
using System.Reflection;

// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version 
//      Build Number
//      Revision
//
// You can specify all the values or you can default the Build and Revision Numbers 
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.9.0.*")]
[assembly: AssemblyFileVersion("1.9.0.0")]

[assembly: AssemblyCompany("Whateavs")]
[assembly: AssemblyProduct("My lovely project")]
[assembly: AssemblyCopyright("Copyright © Whomever 2012")]
You should also remove these lines from each assembly info.

Then go to each project and choose add existing item and choose to link the file in. MsBuild will pull it in every time.

No idea how to do this with C++, F# should probably work similarly but I've never got anything working in F# large enough to worry about versioning.

Another approach might be DropKick, not quite a full-blown CI server but designed to handle scenarios like this.

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



Gilg posted:

A couple days old, but I didn't see anyone respond, so I think you should look into SlowCheetah, a Visual Studio extension. The built-in Web.config transformation is only done during publishing, i.e. not when local debugging. SlowCheeath will cover that case and also allow you to use transforms with non-ASP.NET projects.

That's pretty nice in that it confirms that A) I'm not crazy and B) it should work, but, of course, it just doesn't and doesn't say why, though I am getting some message-level errors that our custom config section isn't in the schema, so maybe I'll spend several hours figuring that out and it'll magically work :suicide:

Edit: wasted all morning making schemas and tweaking configs and schemas until everything built without any Warnings or Messages to indicate a problem with any XML, schema or config and it still simply doesn't happen even though SlowCheetah has no trouble figuring out the transformation. gently caress enterprisey XML bullshit forever.

Munkeymon fucked around with this message at 19:51 on Oct 2, 2012

raminasi
Jan 25, 2005

a last drink with no ice

wwb posted:

No idea what to do for the C++ stuff. Not exactly sure what the build system is for F# but this trick should work if it is using an assembly info file. Tricks were written for C# and I'm sure they work there as we use them across the board. At least across the board until teamcity added the assemblyinfo patcher.

What you want to do is create a central version info file someplace source controlled that everything can hit. In this file, at least for C#, you'd have the relevent parts of the AssemblyInfo.cs file -- eg:

code:
using System.Reflection;

// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version 
//      Build Number
//      Revision
//
// You can specify all the values or you can default the Build and Revision Numbers 
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.9.0.*")]
[assembly: AssemblyFileVersion("1.9.0.0")]

[assembly: AssemblyCompany("Whateavs")]
[assembly: AssemblyProduct("My lovely project")]
[assembly: AssemblyCopyright("Copyright © Whomever 2012")]
You should also remove these lines from each assembly info.

Then go to each project and choose add existing item and choose to link the file in. MsBuild will pull it in every time.

No idea how to do this with C++, F# should probably work similarly but I've never got anything working in F# large enough to worry about versioning.

Another approach might be DropKick, not quite a full-blown CI server but designed to handle scenarios like this.

Sure, but the F# project wants a .fs info file, and the C++/CLI project wants a .cpp info file. They can't all use the same file (because the syntaxes don't match), hence my question.

e: This also doesn't synchronize anything with the Setup & Deployment project version number. I might not want to do that anyway (I don't know best practices here) but if I don't how should I be handling that?

raminasi fucked around with this message at 18:07 on Oct 2, 2012

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

GrumpyDoctor posted:

Sure, but the F# project wants a .fs info file, and the C++/CLI project wants a .cpp info file. They can't all use the same file (because the syntaxes don't match), hence my question.

You could do something with T4 to generate the correct versioning files for C++ / F#, then use linked files.

Caveat: I don't know if C++ project files support linked files, but I know C# does.

http://support.microsoft.com/kb/306234

aBagorn
Aug 26, 2004
I really SHOULD grab at the 2012 Express editions of VS and TFS for my home laptop for some fuckery with it.

wwb
Aug 17, 2004

GrumpyDoctor posted:

Sure, but the F# project wants a .fs info file, and the C++/CLI project wants a .cpp info file. They can't all use the same file (because the syntaxes don't match), hence my question.

e: This also doesn't synchronize anything with the Setup & Deployment project version number. I might not want to do that anyway (I don't know best practices here) but if I don't how should I be handling that?

So, I was checking into TeamCity as I knew it did cpp and C# but I wasn't sure about F# and I found this
You'll have to monkey around with MSBuild a bit but it could be doable -- $(BUILDNUMBER) could easily be a variable set within the file. And said msbuild could be ported for all assembly files in your solution if you've just got 3.

That said, I think it might be worth setting up CI somewhere. You are working with a multi-language project that has a deployment feature, it is worth it. Even as a single dev CI keeps you honest and is a wonderful thing to have. F# is a bit tricky, but TeamCity definitely does most other stuff to the point you could be up and running in 5 minutes after downloading. You could even set it up in a vm and only fire that up when you needed it.

Munkeymon posted:

That's pretty nice in that it confirms that A) I'm not crazy and B) it should work, but, of course, it just doesn't and doesn't say why, though I am getting some message-level errors that our custom config section isn't in the schema, so maybe I'll spend several hours figuring that out and it'll magically work :suicide:

Edit: wasted all morning making schemas and tweaking configs and schemas until everything built without any Warnings or Messages to indicate a problem with any XML, schema or config and it still simply doesn't happen even though SlowCheetah has no trouble figuring out the transformation. gently caress enterprisey XML bullshit forever.

At least for smaller apps without boatloads of configuration going on we have started to work with a setup using keyed configurations that all traveled with the project. Configuration tools select either a configuration keyed with the machine name or a default. Was implemented for convenience between dev / ci / qa / prod. Turned out to be a really handy dev tool at times -- you could effectively setup localized CI setups to iron out specific issues without interfering with the main codebase.

This concept can be stretched a long ways -- you could probably choose to hook it up with yaml or json or ini files stuffed in a folder with the same sort of logic if you wanted. I've typically used xml config files mainly because that is the standard on the platform and there are well-known APIs.

Prefect Six
Mar 27, 2009

I'm dumb and obviously didn't pay close attention to the beginning variables chapter but why does
code:
double IceLoad = .25;
Console.WriteLine(IceLoad);
Produce the result .25, but
code:
double IceLoad = 1 / 4;
Console.WriteLine(IceLoad);
produce 0?

e,fb
Does it have to do with 1 and 4 being integers? Do I have to declare double x = 1 and double y = 4 and then do double IceLoad = x / y?

Quebec Bagnet
Apr 28, 2009

mess with the honk
you get the bonk
Lipstick Apathy

Prefect Six posted:

I'm dumb and obviously didn't pay close attention to the beginning variables chapter but why does
code:
double IceLoad = .25;
Console.WriteLine(IceLoad);
Produce the result .25, but
code:
double IceLoad = 1 / 4;
Console.WriteLine(IceLoad);
produce 0?

The result of dividing an integer by an integer is an integer.

Prefect Six
Mar 27, 2009

i barely GNU her! posted:

The result of dividing an integer by an integer is an integer.

So how do I make C# perform mathematical equations? Put everything in a variable?

e: yes this would be easier and already done in a spreadsheet, but I want to do it just to learn to code.

e2: Answer: add f to the end of integers. Thanks so much thread!

Prefect Six fucked around with this message at 02:19 on Oct 3, 2012

Quebec Bagnet
Apr 28, 2009

mess with the honk
you get the bonk
Lipstick Apathy

Prefect Six posted:

So how do I make C# perform mathematical equations? Put everything in a variable?

e: yes this would be easier and already done in a spreadsheet, but I want to do it just to learn to code.

e2: Answer: add f to the end of integers. Thanks so much thread!

Correct. You can specify 1f or 1.0f or 1.0 to create a double, or 1M or 1.0M to create a decimal. With no decimal point and no suffix the compiler will assume you mean an integer. In certain cases it will trigger a compiler error.

Bozart
Oct 28, 2006

Give me the finger.

GrumpyDoctor posted:

What development environment are you using? Because dropping this code into a .fs file in Visual Studio 2010 gives me the exact problem right away: "Value restriction. The value 'A3' has been inferred to have generic type. Either define 'A3' as a simple data term, make it a function with explicit arguments or, if you do not intend for it to be generic, add a type annotation." There's a specific MSDN page about this.

You can see the problem yourself by noticing the type that's been inferred for Col, which is int list list -> 'a list. (This is the number one way I debug F# type errors.) That's not right, as you definitely were expecting an int list. What's the problem? Well, again, Visual Studio has immediately noticed something wrong with this line:
code:
      [for R in lst do R.[i]]
which should actually be
code:
      [for R in lst -> R.[i]]
do is used for "throw away this result" operations. (I'm not actually sure why this didn't result in the type of Col being int list list -> unit list, but whatever.) Fixing your list comprehension fixed the type of Col which fixed your definition of A3.

Thanks for this - I'm still learning the F# syntax and I didn't / don't fully understand the difference between -> and do. I'll figure it out now.

raminasi
Jan 25, 2005

a last drink with no ice

Bozart posted:

Thanks for this - I'm still learning the F# syntax and I didn't / don't fully understand the difference between -> and do. I'll figure it out now.

If there's an overarching rule about the difference between them, I'm unaware of it, because they're both used in various, unrelated places. It's just that in list comprehensions specifically they have the difference I described.

The Gripper
Sep 14, 2004
i am winner

GrumpyDoctor posted:

If there's an overarching rule about the difference between them, I'm unaware of it, because they're both used in various, unrelated places. It's just that in list comprehensions specifically they have the difference I described.
It's pretty much what you said, any do block must return unit and in the list comprehension it will produce an empty list unless that expression yields a value, and I think the reason the type of Col was generic and not list unit was that unit isn't actually a type (in the same sense as int and list):

The list comprehension would work with a do if it were worded as [for R in list do yield R.[i]], since the block conforms to the requirements and the expression yields a result.

The Gripper fucked around with this message at 14:02 on Oct 3, 2012

ninjeff
Jan 19, 2004

The Gripper posted:

It's pretty much what you said, any do block must return unit and in the list comprehension it will produce an empty list unless that expression yields a value, and I think the reason the type of Col was generic and not list unit was that unit isn't actually a type (in the same sense as int and list):
code:
> int;;
val it : (int -> int) = <fun:it@106-2>
> unit;;

  unit;;
  ^^^^

stdin(107,1): error FS0039: The value or constructor 'unit' is not defined
The list comprehension would work with a do if it were worded as [for R in list do yield R.[i]], since the block conforms to the requirements and the expression yields a result.

I'm no F# expert, but I think you might have misunderstood what the first line of your code quote is telling you. It's saying that int is a function from int to int, which is true. int is also a type, but so is unit. If you want a value of type unit, try ().

I could be totally wrong and just embarrassing myself, though, in which case my bad.

The Gripper
Sep 14, 2004
i am winner

ninjeff posted:

I could be totally wrong and just embarrassing myself, though, in which case my bad.
You're right, I bonered it up in the interactive console and pasted the wrong thing after doing something else, then reasoned it based on that wrong paste.

Looking back at it it's likely just picked 'a list because the comprehension has returned an empty list with no type annotation, rather than a list [();();();] which you might assume it would.

Adbot
ADBOT LOVES YOU

Sab669
Sep 24, 2009

This is a dumb question, but is it possible / easy to "overload" a single form with too many controls? I just added a few new text boxes and combo boxes after a meeting with a customer, now when I run it it crashes and I get a stack overflow, but it doesn't say where- it just says "In System.Windows.Forms.dll". If I set a break point, it just crashes during the InitializeComponent() method of the form and it takes 5 minutes to step through and try to find it :psyduck:

edit: Oh okay, .NET. I just went back and made sure I renamed all of the labels I added, turns out there was still some generic "label1" floating around somehwere... and it seems to be fine now? I don't even.

Sab669 fucked around with this message at 15:34 on Oct 3, 2012

  • Locked thread