Wednesday, April 15, 2015

CODE!  Finally, I know.

So.  I started this blog ("blog") with the intention of using it to post and discuss my various coding projects.  But!  As school has the tendency to do, I have much to busy with school projects to do much, or any, of my own coding.  Maybe I'll try merging the two...

public static IEnumerable<ITweet> TEST_GetUserTimeLine(string user)
{
     IEnumerable<ITweet> userTimelineTweets = null;
     TwitterCredentials.ExecuteOperationWithCredentials(Instance.credentials, () =>
     {
          int page = 0;
          const int maxId = 3200;
          string query = String.Format("https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name={0}&count={1}&page={2}", user, maxId, page);
          string result = TwitterAccessor.ExecuteJsonGETQuery(query);
          IJsonObjectConverter searchQueryHelper = TweetinviContainer.Resolve<IJsonObjectConverter>();
          List<ITweetDTO> tweetDTOs = searchQueryHelper.DeserializeObject<List<ITweetDTO>>(result);
 
          if (tweetDTOs != null && tweetDTOs.Count() != 0)
          {
              userTimelineTweets = Tweet.TweetFactory.GenerateTweetsFromDTO(tweetDTOs);
              for (int y = 1; y < 16; y++)
              {
                   query = String.Format("https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name={0}&count={1}&page={2}", user, maxId, y);
                   result = TwitterAccessor.ExecuteJsonGETQuery(query);
                   tweetDTOs = searchQueryHelper.DeserializeObject<List<ITweetDTO>>(result);
                   IEnumerable<ITweet> tweeters = Tweet.TweetFactory.GenerateTweetsFromDTO(tweetDTOs);
                   if (tweeters != null && tweeters.Count() != 0)
                   {
                        userTimelineTweets = userTimelineTweets.Union(tweeters);
                   }
                   else
                   {
                        break;
                   }
               }
          }
     });
     return userTimelineTweets;
}

This semester I am taking a class on mining social media.  We have a lab almost every week, two data set problems that span a month each and then a large final project.  This chunk of code is from that final project.

The final project, at least MY final project, involves mining Twitter for user information.  Part of that is getting as much of a given users tweet history (their timeline) as possible.  Unfortunately that amounts to a max of 3200 tweets which is a limitation of the Twitter API.  The Twitter lib I'm using is Tweetinvi and it has a method called GetUserTimeLine(x) in which x is the amount of tweets you want.  Unfortunately it doesn't seem to work as I get a max of 40 tweets regardless of how many the user has on their timeline.

Now this isn't exactly MY code, and I wish I could remember where I got it to give credit where credit is due, but I did fix it up a little.  With each ExecuteJsonGetQuery call you can get a max of 200 tweets meaning it takes 16 calls to get the full 3200 tweet max.  Originally, the way the code was written it would query the Twitter API 16 times whether you had downloaded all of the users timeline or not.  Since Twitter has a 300 calls per 15 minutes rate limit for downloading timelines, 16 per user means you're wasting calls if it doesn't require that many to get all their tweets.

Kind of a side note:  For my project I've downloaded user information for 20,000+ Twitter users.  Not knowing at the time (and not being smart enough to check) that GetUsertimeLine(x) didn't work properly.  So now I'm having to go back through all 20,000+ users and download their timelines again.

Wish me luck...

Wednesday, June 4, 2014

Ooooooor maybe not?

SO!  All that work on the mediator only to find out it only handles functions and not class methods.  A little disappointing as C# (my new love) handles both without problem. I have a solution done that I will post later. 

Kind of a personal update.  I would be coding (and posting code) more but I've been a little busy lately.  Trying to find a summer internship has taken up some time.  I've had a few interviews but nothing solid has come of them.  It's actually been a little discouraging.  When I was leaving the Navy I didn't expect finding a technical job to be this difficult.  Kind of flies in the face of everything they promise you when you join.  O'well.

School projects!  More code to come.

Saturday, May 24, 2014

Mediator in C++

New class, new project, same old people and they just can't get enough of my crazy singleton mediator goodness.  Now in exciting new C++ flavors!!

class Mediator
{
private:
 Mediator() {/*Filler!!*/}
 
 Mediator(const Mediator&) {/*Filler!!*/ }
 
 Mediator& operator = (const Mediator&) {/*Filler!!*/ }
 
 ~Mediator() {/*Filler!!*/ }
 
 static Mediator& Instance()
 {
  static Mediator instance;
  return instance;
 }
 
 std::map<std::string, std::vector<void (*)(void*)>> MediatorMap;
public:
 
 static void Register(std::string Key, void (*Function)(void*))
 {
  Instance().MediatorMap[Key].push_back(Function);
 }
 
 static void Unregister(std::string Key, void(*Function)(void*))
 {
  if (Instance().MediatorMap.count(Key) != 0)
  {
   Instance().MediatorMap[Key].erase(std::find(Instance().MediatorMap[Key].begin(),
         Instance().MediatorMap[Key].end(),
         Function));
  }
  if (Instance().MediatorMap[Key].size() == 0)
  {
   Instance().MediatorMap.erase(Instance().MediatorMap.find(Key));
  }
 }
 
 static void Call (std::string Key, void* Object = nullptr)
 {
  if (Instance().MediatorMap.count(Key) != 0)
  {
   for (std::vector<void(*)(void*)>::iterator It = Instance().MediatorMap[Key].begin();
        It != Instance().MediatorMap[Key].end();
               ++It)
   {
    (*It)(Object);
   }
  }
 }
 
 static void Clear()
 {
 Instance().MediatorMap.clear();
 }  
};

I started writing it as a template but the mixture of template and singleton were to much for my currently sick and heavily medicated self to figure out.  So, for now, instead of being able to use whatever kind of key you want you're currently stuck with using a string.

You might also be wondering why there are 230920934 Instance() calls.  Mostly so you can do the following:

Mediator::Register("Test", &TestFunction);
Mediator::Call("Test", "SPOOOON!!");
Mediator::Unregister("Test", &TestFunction);

For those of you new to singletons, normally you would have to do:

Mediator::Instance.Register("Test", &TestFunction);

But I don't like having to include the Instance method in the complete call.  Having all my methods static and referencing class variables through Instance() allows me to forgo that.  It's ugly, and there are probably better way to go about it but it is what it is.


[Edit/Update]

Changed the code just a little bit.  Changed the second parameter of our Call method to:

static void Call (std::string Key, void* Object = nullptr)

 This allows us to not have to send anything if our registered functions do not require an input.

Also added the Clear method.  This will completely empty our MediatorMap in the event this is ever required.  When will that be?  I don't know, but it's there if we need it.

As usual I am open to suggestions, comments, etc.  Thanks!

Wednesday, May 21, 2014

Expandable Enum Experiments

I approached this in response to a problem we had in a project last semester.  Yes I'm in college and 'we' means the people in my group.  The problem had to do with using strings as the keys for our Mediator class which is, in part, why I went with a template as apposed to hard coding it.  We came across a few cases where we had registered ...mediators (is that what they're called here?) with one string and tried to Call them with another.  The difference ended up being a capitalization issue but it took us a while to figure out why it wasn't working.

After the project was completed we discussed ways we could have done it better and we agreed that using enumerables would have been a better choice.  Outside of making sure you're using the right one there is no real possibility of spelling or capitalization mistakes.   MY main problem with this approach was the need to completely define our Enum in a centralized location.  If we ever added additional functionality to our project we would have to go and expand that Enum as needed.  I want the ability to expand out Enum as needed while maintaining the main purpose of an Enum.  So I came up with the following:

public class EnumBase
{
    // I don't know why we would want to count the number of objects
    // genereated from our EnumBase but it's here if we ever want it.
    private static int _Count = 0;
 
    // Class constructor.  Basic stuff.  Post increments Count,
    // and thus _Count, every time it's called.
    public EnumBase()
    {
        Count++;
    }
 
    // Our public interface to _Count.  Provides a public 'get'
    // and a private 'set' for access to our _Count.
    public static int Count
    {
        get
        {
            return _Count;
        }
        private set
        {
            _Count = value;
        }
    }
}


Pretty straight forward, and most of the guts of this class are unneeded, but it allows you to do the following:

public class EnumFoo
{
    public static readonly EnumBase One = new EnumBase();
    public static readonly EnumBase Two = new EnumBase();
}
 
public class EnumBar
{
    public static readonly EnumBase Red = new EnumBase();
    public static readonly EnumBase Blue = new EnumBase();
}


Which in turn allows you to the following:

Dictionary<EnumBaseList<Action<Object>>> Diction 
    = new Dictionary<EnumBaseList<Action<object>>>();
 
Diction.Add(EnumFoo.One, Func);
Diction.Add(EnumFoo.Two, Func2);
Diction.Add(EnumBar.Red, Func3);

I'm using the Dictionary from my Mediator class as an example, assuming we passed EnumBase to the template.  Using this method allows us to expand our list of unique "enumerables" as needed without having to continually expand a centralized Enum.

As always comments and suggestions are welcome!

Monday, May 19, 2014

Mediator Pattern/Class

 This is my Mediator class.  Right now I'm using it like a singleton but it can be changed back to a normal class easily.  The template "T" allows you to use whatever kind of key you like.  You can use any number of keys and have any number of Actions (functions/methods) registered under them.  Using the Call method allows you to execute all functions/methods under the given Key and pass to them (the functions/methods) any object you desire.

public class Mediator<T>
 {
     private static Mediator<T> _Instance = new Mediator<T>();
 
     private Dictionary<T, List<Action<object>>> 
         _Callbacks = new Dictionary<T, List<Action<object>>>();
 
     private Mediator() { }
 
     public static Mediator<T> Instance
     {
         get
         {
             return _Instance;
         }
     }
 
     public static void Register(T Key, Action<object> Action)
     {
         if (!Instance._Callbacks.ContainsKey(Key))
         {
             Instance._Callbacks[Key] = new List<Action<object>>();
         }
 
         Instance._Callbacks[Key].Add(Action);
     }
 
     public static void Unregister(T Key, Action<object> Action)
     {
         Instance._Callbacks[Key].Remove(Action);
 
         if (Instance._Callbacks[Key].Count == 0)
         {
             Instance._Callbacks.Remove(Key);
         }
     }
 
     public static void Call(T Key, object Message = null)
     {
         if (Instance._Callbacks.ContainsKey(Key))
         {
             Instance._Callbacks[Key].ForEach(Action => Action(Message));
         }
     }
 }


A couple side notes:

First, not having code specific formatting is making my ass twitch.  I need to find a way to remedy that to make the code easier to read.  At least it's keeping the tabbing, right?

Second, since this is my first code post I would like to make it clear that I am open to any and all suggestions in regards to improving my code.  Constructive criticism, while sometimes hard to swallow, is almost always welcome.

[Edit]

So the solutions to the code specific formatting appears to be installing Productivity Power Tools for MSVS 20## (whatever version you're using.)  This is done and now you can see my code in all its colorful glory!

New Beginnings!

So here it is.  I started this blog a few years back, posted a few times about things I don't care to explore again and now I'm coming back.  This time I will be posting about my coding adventures which is going to be painful I think.  I, like a lot of coders (I'm assured), am never satisfied with my code.  I always feel like there is a better way I could be doing things.  By feel I mean know.  Especially since I started college, working on my BACS and have learned just how much I don't know which is substantial.  But we all start somewhere, right?