AIRS 2016

这周和本科毕设的指导老师去北京参加了AIRS 2016 (Asia Information Retrieval Societies),这是第一次参加学术会议,见到了领域内的几位leading researchers,看到了大家交流问题的方式,非常有感触。除了接触到了领域内的很多高频概念之外,还听到了一些很直观,但我又从未考虑过的idea,包括李航博士提到的 Generative QA。之后毕设也会做和 IR 相关的,希望能在这个领域内有一点成绩。

视频搬运服务

已经半年多没有更新博文了,这次更新是因为写了一个有意思的东西,是一个视频搬运的服务,可以定时爬取YouTube上指定Channel的视频,将新视频下载下来,再上传到优酷。这个服务分为三个部分,VideoCrawler,VideoDownloader和VideoUploader。这样不挂代理,就可以看到那些我喜欢的YouTuber上传的最新视频啦。

VideoCrawler

这个是一个基于Scrapy的爬虫,可以爬取我喜欢的Channel的视频列表,将视频名字、描述、URL等等信息存到数据库中,方便后续的视频下载。我利用Crontab定期执行这个爬虫,爬取增量信息,也就是新上传的视频。增量的部分是这样处理的:表中url字段加上唯一性约束(unique index),然后插入时用 insert ignore into

VideoDownloader

查询数据库,找到 download_finished = 0 的URL,依次下载,文件用数据库中的 id 命名。下载这里用的是 PyTube

VideoUploader

查询数据库,找到 download_finished = 1 and upload_finished = 0 的文件名,依次上传,上传使用的是优酷提供的API,选优酷的原因就是它是唯一一个提供API的视频网站,上传这个地方我也找到了别人写好的模块,叫youku

三者的联系

这三个模块互相没有调用的关系,VideoCrawler在每天自动执行一次,很快就可以爬完增量信息,而VideoDownloader和VideoUploader是启动后就一直执行,如果数据库中没有符合条件的,就休眠一小会。这次这个服务是部署在腾讯云上的那个学生主机,由于带宽有限,而且下载还要走代理,所以下载速度异常的慢,上传速度还好。

项目地址:TransVideos

动态规划:Range Sum Query - Immutable

动态规划 (Dynamic Programming)

动态规划类的问题有两个突出的属性:

  • Overlapping subproblems: 可以分解为若干个子问题,并且解决这些子问题的方法有重复性
  • Memoization: 可以反复应用以前的结果,无需再次计算

Range Sum Query - Immutable

Range Sum Query - ImmutableLeetCode OJ 上的一道题,它能很好的展现上面两个思想。

Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive.

Example:
Given nums = [-2, 0, 3, -5, 2, -1]

sumRange(0, 2) -> 1
sumRange(2, 5) -> -1
sumRange(0, 5) -> -3

Note:
You may assume that the array does not change.
There are many calls to sumRange function.

算法

There are many calls to sumRange function.

这句提示就决定了这是一个动态规划问题。
定义一个数组 partialSum , 将从第 0 到第 j 项的和存在 partialSum[j] 中,以便以后直接调用,无需再次求和。

Java


public class NumArray {
    private int[] nums;
    private ArrayList<Integer> partialSum = new ArrayList();

    public NumArray(int[] nums) {
        this.nums = nums;
        getPartialSum();
    }

    private void getPartialSum() {
        if(nums.length > 0)
            partialSum.add(nums[0]);
        for(int i = 1; i < nums.length; i++)
            partialSum.add(partialSum.get(i - 1) + nums[i]);
    }

    public int sumRange(int i, int j) {
        int sum = partialSum.get(j);
        if(i > 0)
            sum -= partialSum.get(i - 1);
        return sum;
    }
}


// Your NumArray object will be instantiated and called as such:
// NumArray numArray = new NumArray(nums);
// numArray.sumRange(0, 1);
// numArray.sumRange(1, 2);

Python


class NumArray(object):
    def __init__(self, nums):
        """
        initialize your data structure here.
        :type nums: List[int]
        """
        self.nums = nums
        self.partialSum = []
        self.getPartialSum()

    def getPartialSum(self):
        if len(self.nums) > 0:
            self.partialSum.append(self.nums[0])
        for i in range(1, len(self.nums)):
            self.partialSum.append(self.partialSum[i - 1] + self.nums[i])

    def sumRange(self, i, j):
        """
        sum of elements nums[i..j], inclusive.
        :type i: int
        :type j: int
        :rtype: int
        """
        sum = self.partialSum[j]
        if i >= 1:
            sum -= self.partialSum[i - 1]
        return sum


# Your NumArray object will be instantiated and called as such:
# numArray = NumArray(nums)
# numArray.sumRange(0, 1)
# numArray.sumRange(1, 2)

安卓开发:上传图片到服务器

本篇博文总结自该视频

概览

将图片上传至服务器分为两个部分:安卓客户端和服务器端。本文的演示将以上传到SAE为例。

服务器端

上传图片采用 http post,需要先将照片进行 base64 编码,所以在服务器上需先进行解码,再存储。

PHP源码

<?php
	// 获取提交的参数
	$name = $_POST["name"];
	$id = $_POST["id"];
	$image = $_POST["image"];

	// base64解码
	$decodedImage = base64_decode($image);

	// 存入SAE的Storage,其中"picture"是建好的domain,pic.jpg是domain中已经有的照片
	// 也就是说,每次存储都会更改同一张照片
	file_put_contents('saestor://picture/pic.jpg', $decodedImage);

	// 如果要还给客户端返回信息,可以写在下面
?>

安卓客户端

现将图片转为 Bitmap,进行 base64 编码后再使用 AsyncTask 上传至服务器。

注意

这里使用到的 Apache HTTP Client 在 Android 6.0 中已被去除,如果仍要使用的话,需在 build.gradle 中做如下声明:

android {
    useLibrary 'org.apache.http.legacy'
}

具体可以看官方的说明

Java源码

MainActivity.java

安卓开发:图片全屏显示 Demo

本文转载自 fishorbird 博客

这个 Demo 可以从手机内存中读取一张图片,在一个全屏的 activity 中显示。

Java 代码


import java.io.File;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.os.Bundle;
import android.os.Environment;
import android.util.DisplayMetrics;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;

public class MainActivity extends Activity {
	ImageView img;
	String path;
	String filepath;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
				WindowManager.LayoutParams.FLAG_FULLSCREEN);//不显示标题栏
		setContentView(R.layout.activity_main);
		img = (ImageView) findViewById(R.id.imageView1);
		File sd = Environment.getExternalStorageDirectory();
		path = sd.getPath();//获得手机内存storage的位置
		filepath = path + "/picturereceive/beautiful2.jpg";//storage下需要全屏显示的图片路径(要根据自己手机中需要显示图片路径位置进行修改)
		File file = new File(filepath);
		System.out.println("<<<<<<<<<<<<<<<<<<<<<<<<"+filepath);
		if (file.exists()) {
			System.out.println("<<<<<<<<<<<<<<<<<<<<<<<4");
			Bitmap bm = BitmapFactory.decodeFile(filepath);//获得设置路径下图片并编码为Bitmap格式
			bm = big(bm);//放大图片至全屏
			System.out.println("<<<<<<<<<<<<<<<<<5");
			img.setImageBitmap(bm);//设置图片为背景图
		}
		else {
			System.err.println("<<<<<<<<<<<<<Not Found");//控制台输出没找到图片
		}
	}

	public Bitmap big(Bitmap bitmap) {  				//修改bitmap大小
		DisplayMetrics dm = new DisplayMetrics();
		getWindowManager().getDefaultDisplay().getMetrics(dm);  
		int screenWidth = dm.widthPixels;				//获取当前屏幕宽度  
		int screenHeight = dm.heightPixels;				//获取当前屏幕高度
		float w = (float) screenWidth / bitmap.getWidth();	//计算当前图片要全屏幕,宽度需要放大尺寸
		float h = (float) screenHeight / bitmap.getHeight();//计算当前图片要全屏,高度需要放大尺寸
		if (w >= h)//选取较小尺寸进行放大
			w = h;
		Matrix matrix = new Matrix();
		matrix.postScale(w, w);//设置宽高放大比例(这里为等比例放大)
		Bitmap resizeBmp = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
				bitmap.getHeight(), matrix, true);//对现有bitmap进行放大
		return resizeBmp;
	}
}

XML布局文件代码


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#000000"//设置背景为黑色
    tools:context=".MainActivity" >

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:src="@drawable/ic_launcher" />

</RelativeLayout>

注意

注意一定要加上手机读内存权限,在manifest文件中写入
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

Demo 下载

下载地址